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@
23 * 18 June 1998 Start IOKit version.
24 * 18 Nov 1998 suurballe port to C++
25 * 4 Oct 1999 decesare Revised for Type 4 support and sub-classed drivers.
26 * 1 Feb 2000 tsherman Added extended mouse functionality (implemented in setParamProperties)
29 #include "AppleADBMouse.h"
30 #include <IOKit/hidsystem/IOHIDTypes.h>
31 #include <IOKit/IOLib.h>
32 #include <IOKit/IOPlatformExpert.h>
34 // Globals to remember enhanced trackpad values @ sleep and restore @ wake.
35 UInt8 glob_clicking
= 0x19;
36 UInt8 glob_dragging
= 0x14;
37 UInt8 glob_draglock
= 0xB2;
39 // ****************************************************************************
42 // ****************************************************************************
43 static void NewMouseData(IOService
* target
, UInt8 adbCommand
, IOByteCount length
, UInt8
* data
)
45 ((AppleADBMouse
*)target
)->packet(adbCommand
, length
, data
);
49 // ****************************************************************************
52 #define super IOHIPointing
54 OSDefineMetaClassAndStructors(AppleADBMouse
, IOHIPointing
);
57 // ****************************************************************************
60 // ****************************************************************************
61 IOService
* AppleADBMouse::probe(IOService
* provider
, SInt32
* score
)
63 adbDevice
= (IOADBDevice
*)provider
;
69 // ****************************************************************************
72 // ****************************************************************************
73 bool AppleADBMouse::start(IOService
* provider
)
75 if(!super::start(provider
)) return false;
77 if(!adbDevice
->seizeForClient(this, NewMouseData
)) {
78 IOLog("%s: Seize failed\n", getName());
86 // ****************************************************************************
89 // ****************************************************************************
90 UInt32
AppleADBMouse::interfaceID(void)
92 return NX_EVS_DEVICE_INTERFACE_ADB
;
96 // ****************************************************************************
99 // ****************************************************************************
100 UInt32
AppleADBMouse::deviceType ( void )
102 return adbDevice
->handlerID();
106 // ****************************************************************************
109 // ****************************************************************************
110 IOFixed
AppleADBMouse::resolution(void)
116 // ****************************************************************************
119 // ****************************************************************************
120 IOItemCount
AppleADBMouse::buttonCount(void)
126 // ****************************************************************************
129 // ****************************************************************************
130 void AppleADBMouse::packet(UInt8
/*adbCommand*/,
131 IOByteCount
/*length*/, UInt8
* data
)
134 UInt32 buttonState
= 0;
140 if (dy
& 0x40) dy
|= 0xffffffc0;
141 if (dx
& 0x40) dx
|= 0xffffffc0;
143 if ((data
[0] & 0x80) == 0) buttonState
|= 1;
145 clock_get_uptime(&now
);
146 dispatchRelativePointerEvent(dx
, dy
, buttonState
, now
);
150 // ****************************************************************************
153 #define super AppleADBMouse
155 OSDefineMetaClassAndStructors(AppleADBMouseType1
, AppleADBMouse
);
157 IOService
* AppleADBMouseType1::probe(IOService
* provider
, SInt32
* score
)
159 if (!super::probe(provider
, score
)) return 0;
164 bool AppleADBMouseType1::start(IOService
* provider
)
166 if (adbDevice
->setHandlerID(1) != kIOReturnSuccess
) return false;
168 _resolution
= 100 << 16;
171 return super::start(provider
);
175 // ****************************************************************************
178 #define super AppleADBMouse
180 OSDefineMetaClassAndStructors(AppleADBMouseType2
, AppleADBMouse
);
182 IOService
* AppleADBMouseType2::probe(IOService
* provider
, SInt32
* score
)
184 if (!super::probe(provider
, score
)) return 0;
186 if (adbDevice
->setHandlerID(2) != kIOReturnSuccess
) return 0;
191 bool AppleADBMouseType2::start(IOService
* provider
)
193 if (adbDevice
->setHandlerID(2) != kIOReturnSuccess
) return false;
195 _resolution
= 200 << 16;
198 return super::start(provider
);
202 // ****************************************************************************
205 #define super AppleADBMouse
207 OSDefineMetaClassAndStructors(AppleADBMouseType4
, AppleADBMouse
);
209 IOService
* AppleADBMouseType4::probe(IOService
* provider
, SInt32
* score
)
212 IOByteCount length
= 8;
214 if (!super::probe(provider
, score
)) return 0;
216 if (adbDevice
->setHandlerID(4) != kIOReturnSuccess
) {
217 adbDevice
->setHandlerID(adbDevice
->defaultHandlerID());
221 // To be a Type 4 Extended Mouse, register 1 must return 8 bytes.
222 if (adbDevice
->readRegister(1, data
, &length
) != kIOReturnSuccess
) return 0;
223 if (length
!= 8) return 0;
225 // Save the device's Extended Mouse Info.
226 deviceSignature
= ((UInt32
*)data
)[0];
227 deviceResolution
= ((UInt16
*)data
)[2];
228 deviceClass
= data
[6];
229 deviceNumButtons
= data
[7];
234 bool AppleADBMouseType4::start(IOService
* provider
)
237 IOByteCount adblength
= 8;
238 typeTrackpad
= FALSE
;
240 if (adbDevice
->setHandlerID(4) != kIOReturnSuccess
) return false;
242 _resolution
= deviceResolution
<< 16;
243 _buttonCount
= deviceNumButtons
;
245 adbDevice
->readRegister(1, adbdata
, &adblength
);
246 if( (adbdata
[0] == 't') && (adbdata
[1] = 'p') && (adbdata
[2] == 'a') && (adbdata
[3] == 'd') )
248 IOLog("Trackpad detected, ");
250 enableEnhancedMode();
253 return super::start(provider
);
256 void AppleADBMouseType4::packet(UInt8
/*adbCommand*/, IOByteCount length
, UInt8
* data
)
258 int dx
, dy
, cnt
, numExtraBytes
;
259 UInt32 buttonState
= 0;
262 numExtraBytes
= length
- 2;
267 if ((data
[0] & 0x80) == 0) buttonState
|= 1;
268 if ((deviceNumButtons
> 1) && ((data
[1] & 0x80) == 0))
270 if(typeTrackpad
== TRUE
)
276 for (cnt
= 0; cnt
< numExtraBytes
; cnt
++) {
277 dy
|= ((data
[2 + cnt
] >> 4) & 7) << (7 + (cnt
* 3));
278 dx
|= ((data
[2 + cnt
]) & 7) << (7 + (cnt
* 3));
280 if ((deviceNumButtons
> (cnt
+ 2)) && ((data
[2 + cnt
] & 0x80) == 0))
281 buttonState
|= 4 << (cnt
* 2);
282 if ((deviceNumButtons
> (cnt
+ 2 + 1)) && ((data
[2 + cnt
] & 0x08) == 0))
283 buttonState
|= 4 << (cnt
* 2 + 1);
286 if (dy
& (0x40 << (numExtraBytes
* 3)))
287 dy
|= (0xffffffc0 << (numExtraBytes
* 3));
288 if (dx
& (0x40 << (numExtraBytes
* 3)))
289 dx
|= (0xffffffc0 << (numExtraBytes
* 3));
291 clock_get_uptime(&now
);
292 dispatchRelativePointerEvent(dx
, dy
, buttonState
, now
);
295 OSData
* AppleADBMouseType4::copyAccelerationTable()
299 strcpy( keyName
, "accl" );
300 keyName
[4] = (deviceSignature
>> 24);
301 keyName
[5] = (deviceSignature
>> 16);
302 keyName
[6] = (deviceSignature
>> 8);
303 keyName
[7] = (deviceSignature
>> 0);
306 OSData
* data
= OSDynamicCast( OSData
,
307 getProperty( keyName
));
311 data
= super::copyAccelerationTable();
316 // ****************************************************************************
317 // enableEnhancedMode
319 // ****************************************************************************
321 bool AppleADBMouseType4::enableEnhancedMode()
324 IOByteCount adblength
= 8;
326 IOLog("enableEnhancedMode called.\n");
327 adbDevice
->readRegister(1, adbdata
, &adblength
);
329 if((adbdata
[6] != 0x0D))
332 if (adbDevice
->writeRegister(1, adbdata
, &adblength
) != 0)
334 if (adbDevice
->readRegister(1, adbdata
, &adblength
) != 0)
336 if (adbdata
[6] != 0x0D)
338 IOLog("AppleADBMouseType4 deviceClass = %d (non-Extended Mode)\n", adbdata
[6]);
341 IOLog("AppleADBMouseType4 deviceClass = %d (Extended Mode)\n", adbdata
[6]);
343 // Set ADB Extended Features to default values.
345 adbdata
[0] = glob_clicking
;
347 adbdata
[1] = glob_dragging
;
350 adbdata
[3] = glob_draglock
;
357 adbDevice
->writeRegister(2, adbdata
, &adblength
);
359 /* Add IORegistry entries for Enhanced mode */
364 setProperty("Clicking", (unsigned long long)Clicking
, sizeof(Clicking
)*8);
365 setProperty("Dragging", (unsigned long long)Dragging
, sizeof(Dragging
)*8);
366 setProperty("DragLock", (unsigned long long)DragLock
, sizeof(DragLock
)*8);
374 // ****************************************************************************
375 // setParamProperties
377 // ****************************************************************************
378 IOReturn
AppleADBMouseType4::setParamProperties( OSDictionary
* dict
)
381 IOReturn err
= kIOReturnSuccess
;
383 IOByteCount adblength
;
385 //IOLog("AppleADBMouseType4::setParamProperties starting here\n");
387 if( (data
= OSDynamicCast(OSData
, dict
->getObject("Clicking"))) && (typeTrackpad
== TRUE
) )
389 adblength
= sizeof(adbdata
);
390 adbDevice
->readRegister(2, adbdata
, &adblength
);
391 glob_clicking
= (adbdata
[0] & 0x7F) | (*( (UInt8
*) data
->getBytesNoCopy() ))<<7;
392 adbdata
[0] = glob_clicking
;
393 setProperty("Clicking", (unsigned long long)((adbdata
[0]&0x80)>>7), sizeof(adbdata
[0])*8);
394 adbDevice
->writeRegister(2, adbdata
, &adblength
);
397 if( (data
= OSDynamicCast(OSData
, dict
->getObject("Dragging"))) && (typeTrackpad
== TRUE
) )
399 adblength
= sizeof(adbdata
);
400 adbDevice
->readRegister(2, adbdata
, &adblength
);
401 glob_dragging
= (adbdata
[1] & 0x7F) | (*( (UInt8
*) data
->getBytesNoCopy() ))<<7;
402 adbdata
[1] = glob_dragging
;
403 setProperty("Dragging", (unsigned long long)((adbdata
[1]&0x80)>>7), sizeof(adbdata
[1])*8);
404 adbDevice
->writeRegister(2, adbdata
, &adblength
);
407 if( (data
= OSDynamicCast(OSData
, dict
->getObject("DragLock"))) && (typeTrackpad
== TRUE
) )
409 adblength
= sizeof(adbdata
);
410 adbDevice
->readRegister(2, adbdata
, &adblength
);
411 adbdata
[3] = *((UInt8
*) data
->getBytesNoCopy());
415 setProperty("DragLock", (unsigned long long)adbdata
[3], sizeof(adbdata
[3])*8);
416 glob_draglock
= 0xFF;
417 adbdata
[3] = glob_draglock
;
418 adblength
= sizeof(adbdata
);
419 adbDevice
->writeRegister(2, adbdata
, &adblength
);
423 setProperty("DragLock", (unsigned long long)adbdata
[3], sizeof(adbdata
[3])*8);
424 glob_draglock
= 0xB2;
425 adbdata
[3] = glob_draglock
;
426 adblength
= sizeof(adbdata
);
427 adbDevice
->writeRegister(2, adbdata
, &adblength
);
432 // For debugging purposes
434 adbDevice
->readRegister(2, adbdata
, &adblength
);
435 IOLog("adbdata[0] = 0x%x\n", adbdata
[0]);
436 IOLog("adbdata[1] = 0x%x\n", adbdata
[1]);
437 IOLog("adbdata[2] = 0x%x\n", adbdata
[2]);
438 IOLog("adbdata[3] = 0x%x\n", adbdata
[3]);
439 IOLog("adbdata[4] = 0x%x\n", adbdata
[4]);
440 IOLog("adbdata[5] = 0x%x\n", adbdata
[5]);
441 IOLog("adbdata[6] = 0x%x\n", adbdata
[6]);
442 IOLog("adbdata[7] = 0x%x\n", adbdata
[7]);
445 if (err
== kIOReturnSuccess
)
447 //IOLog("AppleADBMouseType4::setParamProperties ending here\n");
448 return super::setParamProperties(dict
);
451 IOLog("AppleADBMouseType4::setParamProperties failing here\n");