2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * Start IOKit version.
27 #include "AppleADBKeyboard.h"
28 #include <IOKit/hidsystem/IOHIDTypes.h>
29 #include <IOKit/IOLib.h>
30 #include <IOKit/IODeviceTreeSupport.h>
31 #define super IOHIKeyboard
32 OSDefineMetaClassAndStructors(AppleADBKeyboard
,IOHIKeyboard
)
35 static void new_kbd_data ( IOService
* us
, UInt8 adbCommand
, IOByteCount length
, UInt8
* data
);
36 static void asyncSetLEDFunc ( thread_call_param_t
, thread_call_param_t
);
38 //Convert raw ADB codes to MacOS 9 KMAP virtual key codes in dispatchKeyboardEvent()
39 static unsigned char kmapConvert
[] =
41 //00,00,00,00, These 4 are in System resource, but are unused
42 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
43 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
44 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
45 0x30,0x31,0x32,0x33,0x34,0x35,0x3B,0x37,0x38,0x39,0x3A,0x7B,0x7C,0x7D,0x7E,0x3F,
46 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
47 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
48 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
49 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x3C,0x3D,0x3E,0x36,0x7F,
54 // **********************************************************************************
57 // **********************************************************************************
58 bool AppleADBKeyboard::start ( IOService
* theNub
)
61 adbDevice
= (IOADBDevice
*)theNub
;
62 if( !adbDevice
->seizeForClient(this, new_kbd_data
) ) {
63 IOLog("%s: Seize failed\n", getName());
67 turnLEDon
= ADBKS_LED_CAPSLOCK
| ADBKS_LED_NUMLOCK
| ADBKS_LED_SCROLLLOCK
; //negative logic
68 setAlphaLockFeedback(false);
69 setNumLockFeedback(false);
72 clock_interval_to_absolutetime_interval( 4, kSecondScale
, &rebootTime
);
73 clock_interval_to_absolutetime_interval( 1, kSecondScale
, &debuggerTime
);
75 return super::start(theNub
);
79 // **********************************************************************************
82 // **********************************************************************************
83 UInt32
AppleADBKeyboard::interfaceID ( void )
85 return NX_EVS_DEVICE_INTERFACE_ADB
;
89 // **********************************************************************************
92 // **********************************************************************************
93 UInt32
AppleADBKeyboard::deviceType ( void )
95 UInt32 id
; //We need handler ID to remap adjustable JIS keyboard
97 id
= adbDevice
->handlerID();
98 if (id
== 18) //Adjustable JIS
100 kmapConvert
[0x32] = 0x35; //tilde to ESC
102 IORegistryEntry
*regEntry
;
106 id
= adbDevice
->handlerID();
107 if (id
== 18) //Adjustable JIS
109 kmapConvert
[0x32] = 0x35; //tilde to ESC
112 if ((id
== kgestaltPwrBkEKDomKbd
) || (id
== kgestaltPwrBkEKISOKbd
) || (id
== kgestaltPwrBkEKJISKbd
))
114 if( (regEntry
= IORegistryEntry::fromPath( "/pci@f2000000/mac-io/via-pmu/adb/keyboard", gIODTPlane
)))
116 data
= OSDynamicCast(OSData
, regEntry
->getProperty( "keyboard-id", gIODTPlane
, kIORegistryIterateRecursively
));
119 dataptr
= (UInt32
*)data
->getBytesNoCopy();
120 id
= *dataptr
; //make sure no byte swapping
130 // **********************************************************************************
131 // setAlphaLockFeedback
132 // This is usually called on a call-out thread after the caps-lock key is pressed.
133 // ADB operations to PMU are synchronous, and this is must not be done
134 // on the call-out thread since that is the PMU driver workloop thread, and
135 // it will block itself.
137 // Therefore, we schedule the ADB write to disconnect the call-out thread
138 // and the one that initiates the ADB write.
140 // **********************************************************************************
141 void AppleADBKeyboard::setAlphaLockFeedback ( bool to
)
144 turnLEDon
&= ~ADBKS_LED_CAPSLOCK
; //Inverse logic applies here
146 turnLEDon
|= ADBKS_LED_CAPSLOCK
;
148 thread_call_func(asyncSetLEDFunc
, (thread_call_param_t
)this, true);
151 void AppleADBKeyboard::setNumLockFeedback ( bool to
)
153 if (to
) //LED on means clear that bit
154 turnLEDon
&= ~ ADBKS_LED_NUMLOCK
;
156 turnLEDon
|= ADBKS_LED_NUMLOCK
;
158 thread_call_func(asyncSetLEDFunc
, (thread_call_param_t
)this, true);
163 // **********************************************************************************
166 // Called asynchronously to turn on/off the capslock and numlock LED
168 // **********************************************************************************
169 static void asyncSetLEDFunc ( thread_call_param_t self
, thread_call_param_t
)
173 IOByteCount length
= sizeof( UInt16
);
176 value
= ((AppleADBKeyboard
*)self
)->turnLEDon
;
177 ((AppleADBKeyboard
*)self
)->adbDevice
->writeRegister(2, (UInt8
*)&value
, &length
);
180 /**********************************************************************
181 Get LED status by reading hardware. Register 2 has 16 bits.
182 **********************************************************************/
183 unsigned AppleADBKeyboard::getLEDStatus (void )
185 UInt8 data
[8]; //8 bytes max for ADB read (talk) operation
186 IOByteCount length
= 8;
190 adbDevice
->readRegister(2, data
, &length
);
192 if ((data
[1] & ADBKS_LED_NUMLOCK
) == 0)
193 LEDStatus
|= ADBKS_LED_NUMLOCK
;
194 if ((data
[1] & ADBKS_LED_CAPSLOCK
) == 0)
195 LEDStatus
|= ADBKS_LED_CAPSLOCK
;
196 if ((data
[1] & ADBKS_LED_SCROLLLOCK
) == 0)
197 LEDStatus
|= ADBKS_LED_SCROLLLOCK
;
202 // **********************************************************************************
205 // **********************************************************************************
206 static void new_kbd_data ( IOService
* us
, UInt8 adbCommand
, IOByteCount length
, UInt8
* data
)
208 ((AppleADBKeyboard
*)us
)->packet(data
,length
,adbCommand
);
211 // **********************************************************************************
212 // dispatchKeyboardEvent
214 // **********************************************************************************
216 void Debugger( const char * );
217 void boot(int paniced
, int howto
, char * command
);
218 #define RB_HALT 0x08 /* don't reboot, just halt */
221 static void AppleADBKeyboardReboot( thread_call_param_t arg
, thread_call_param_t
)
223 boot( 0, (int) arg
, 0 );
226 void AppleADBKeyboard::dispatchKeyboardEvent(unsigned int keyCode
,
227 /* direction */ bool goingDown
,
228 /* timeStamp */ AbsoluteTime time
)
230 if( !goingDown
&& programmerKey
) {
231 programmerKey
= false;
232 EVK_KEYUP( ADBK_CONTROL
, _keyState
);
233 SUB_ABSOLUTETIME( &time
, &programmerKeyTime
);
234 if( CMP_ABSOLUTETIME( &time
, &rebootTime
) >= 0) {
236 thread_call_func( AppleADBKeyboardReboot
,
237 (void *) RB_HALT
, true );
238 } else if( CMP_ABSOLUTETIME( &time
, &debuggerTime
) >= 0) {
239 Debugger("Programmer Key");
242 } else if( (keyCode
== ADBK_POWER
)
243 && (EVK_IS_KEYDOWN( ADBK_CONTROL
, _keyState
))) {
245 if( !programmerKey
) {
246 programmerKey
= true;
247 programmerKeyTime
= time
;
252 super::dispatchKeyboardEvent( kmapConvert
[keyCode
], goingDown
, time
);
256 // **********************************************************************************
259 // **********************************************************************************
260 IOReturn
AppleADBKeyboard::packet (UInt8
* data
, IOByteCount
, UInt8 adbCommand
)
262 unsigned int keycode1
, keycode2
;
267 down
= ((keycode1
& 0x80) == 0);
269 if(keycode1
== 0x7e) keycode1
= ADBK_POWER
;
270 clock_get_uptime(&now
);
272 dispatchKeyboardEvent(keycode1
,down
,now
);
274 keycode2
= *(data
+ 1);
275 if( keycode2
!= 0xff ) {
276 down
= ((keycode2
& 0x80) == 0);
278 if( keycode2
== 0x7e) keycode2
= ADBK_POWER
;
279 if( (keycode1
!= ADBK_POWER
) || (keycode2
!= ADBK_POWER
))
280 dispatchKeyboardEvent(keycode2
,down
,now
);
283 return kIOReturnSuccess
;
287 // **********************************************************************************
290 // **********************************************************************************
291 UInt32
AppleADBKeyboard::maxKeyCodes ( void )
296 //Get key values from ev_keymap.h
297 bool AppleADBKeyboard:: doesKeyLock ( unsigned key
)
300 case NX_KEYTYPE_CAPS_LOCK
:
302 case NX_KEYTYPE_NUM_LOCK
:
310 // **********************************************************************************
311 // defaultKeymapOfLength
313 // **********************************************************************************
314 const unsigned char * AppleADBKeyboard::defaultKeymapOfLength (UInt32
* length
)
316 static const unsigned char appleUSAKeyMap
[] = {
318 0x08, //8 modifier keys
319 0x00,0x01,0x39, //NX_MODIFIERKEY_ALPHALOCK
320 0x01,0x01,0x38, //NX_MODIFIERKEY_SHIFT virtual from KMAP
321 0x02,0x01,0x3b, //NX_MODIFIERKEY_CONTROL
322 0x03,0x01,0x3a, //NX_MODIFIERKEY_ALTERNATE
323 0x04,0x01,0x37, //NX_MODIFIERKEY_COMMAND
324 0x05,0x15,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
325 0x43,0x4b,0x51,0x7b,0x7d,0x7e,0x7c,0x4e,0x59, //NX_MODIFIERKEY_NUMERICPAD
326 0x06,0x01,0x72, //NX_MODIFIERKEY_HELP 7th modifier here
327 0x07,0x01,0x3f, //NX_MODIFIERKEY_SECONDARYFN 8th modifier
329 0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01,0x0d,0x00,
330 0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13,0x0d,
331 0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04,
332 0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,
333 0x06,0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,
334 0x18,0x00,0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,
335 0x07,0x00,0x07,0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,
336 0x00,0x1a,0x00,0x1a,0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,
337 0xce,0x00,0x18,0x00,0x18,0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,
338 0x01,0xd3,0x00,0x03,0x00,0x03,0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,
339 0xd6,0x01,0xe0,0x00,0x16,0x00,0x16,0x02,0x00,0x3c,0x00,0x3e,0x0d,0x00,0x62,0x00,
340 0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02,0x0d,0x00,0x71,
341 0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11,0x0d,0x00,
342 0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17,0x0d,
343 0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05,
344 0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,
345 0x12,0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,
346 0x00,0x19,0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,
347 0x14,0x00,0x14,0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1,0x0e,0x00,0x32,0x00,
348 0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00,0x0a,0x00,0x33,
349 0x00,0x23,0x00,0xa3,0x01,0xba,0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8,0x0e,
350 0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e,
351 0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd,0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,
352 0x01,0xb1,0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab,0x0a,0x00,0x37,0x00,0x26,
353 0x01,0xb0,0x01,0xab,0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,
354 0xd0,0x00,0x1f,0x00,0x1f,0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4,0x0a,0x00,
355 0x30,0x00,0x29,0x00,0xad,0x00,0xbb,0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,
356 0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d,0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,
357 0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f,0x0d,0x00,0x75,0x00,0x55,0x00,0x15,
358 0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15,0x0e,0x00,0x5b,0x00,0x7b,0x00,
359 0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b,0x0d,0x00,0x69,0x00,0x49,
360 0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09,0x0d,0x00,0x70,0x00,
361 0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10,0x10,0x00,0x0d,
362 0x00,0x03,0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,
363 0x0c,0x00,0x0c,0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,
364 0x00,0x0a,0x00,0x0a,0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae,0x0d,0x00,0x6b,
365 0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b,0x0a,0x00,
366 0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2,0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,
367 0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c,0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,
368 0xa3,0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf,0x0d,0x00,0x6e,0x00,0x4e,0x00,
369 0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e,0x0d,0x00,0x6d,0x00,0x4d,
370 0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d,0x0a,0x00,0x2e,0x00,
371 0x3e,0x00,0xbc,0x01,0xb3,0x02,0x00,0x09,0x00,0x19,0x0c,0x00,0x20,0x00,0x00,0x00,
372 0x80,0x00,0x00,0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb,0x02,0x00,0x7f,0x00,
373 0x08,0xff,0x02,0x00,0x1b,0x00,0x7e,0xff,0xff,0xff,0xff,0xff,
376 0x01,0xae,0x00,0x01,0xaf,0x00,0x01,0xad,
378 0xff, 0xff, 0xff, 0xff,
379 0xff,0xff,0x00,0x00,0x2e,0xff,0x00,0x00,
380 0x2a,0xff,0x00,0x00,0x2b,0xff,0x00,0x00,0x1b,0xff,0xff,0xff,0x0e,0x00,0x2f,0x00,
381 0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00,0x00,0x00,0x0d, //XX03
382 0xff,0x00,0x00,0x2d,0xff,0xff,0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,
383 0x3d,0x00,0x7c,0x00,0x00,0x18,0x46,0x00,0x00,0x30,0x00,0x00,0x31,0x00,0x00,0x32,
384 0x00,0x00,0x33,0x00,0x00,0x34,0x00,0x00,0x35,0x00,0x00,0x36,0x00,0x00,0x37,0xff,
385 0x00,0x00,0x38,0x00,0x00,0x39,0xff,0xff,0xff,0x00,0xfe,0x24,0x00,0xfe,0x25,0x00,
386 0xfe,0x26,0x00,0xfe,0x22,0x00,0xfe,0x27,0x00,0xfe,0x28,0xff,0x00,0xfe,0x2a,0xff,
387 0x00,0xfe,0x32,0xff,0x00,0xfe,0x33,0xff,0x00,0xfe,0x29,0xff,0x00,0xfe,0x2b,0xff,
388 0x00,0xfe,0x34,0xff,0x00,0xfe,0x2e,0x00,0xfe,0x30,0x00,0xfe,0x2d,0x00,0xfe,0x23,
389 0x00,0xfe,0x2f,0x00,0xfe,0x21,0x00,0xfe,0x31,0x00,0xfe,0x20,
390 //A.W. Added following 4 lines to fix wakeup on PowerBooks.
391 0x00,0x01,0xac, //ADB=0x7b is left arrow
392 0x00,0x01,0xae, //ADB = 0x7c is right arrow
393 0x00,0x01,0xaf, //ADB=0x7d is down arrow.
394 0x00,0x01,0xad, //ADB=0x7e is up arrow
396 0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
397 0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
398 0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
399 0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
400 0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,
401 0x06, // following are 6 special keys
402 0x05,0x72, //NX_KEYTYPE_HELP is 5, ADB code is 0x72
403 0x06,0x7f, //NX_POWER_KEY is 6, ADB code is 0x7f
404 0x07,0x4a, //NX_KEYTYPE_MUTE is 7, ADB code is 0x4a
405 0x08,0x3e, //NX_UP_ARROW_KEY is 8, ADB is 3e raw, 7e virtual (KMAP)
406 0x09,0x3d, //NX_DOWN_ARROW_KEY is 9, ADB is 0x3d raw, 7d virtual
407 0x0a,0x47 //NX_KEYTYPE_NUM_LOCK is 10, ADB combines with CLEAR key for numlock
410 *length
= sizeof(appleUSAKeyMap
);
411 return appleUSAKeyMap
;