]> git.saurik.com Git - apple/xnu.git/blame - iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBMouse.cpp
xnu-124.13.tar.gz
[apple/xnu.git] / iokit / Drivers / hidsystem / drvAppleADBDevices / AppleADBMouse.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
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)
27 */
28
29#include "AppleADBMouse.h"
30#include <IOKit/hidsystem/IOHIDTypes.h>
31#include <IOKit/IOLib.h>
32#include <IOKit/IOPlatformExpert.h>
33
34// Globals to remember enhanced trackpad values @ sleep and restore @ wake.
35UInt8 glob_clicking = 0x19;
36UInt8 glob_dragging = 0x14;
37UInt8 glob_draglock = 0xB2;
38
39// ****************************************************************************
40// NewMouseData
41//
42// ****************************************************************************
43static void NewMouseData(IOService * target, UInt8 adbCommand, IOByteCount length, UInt8 * data)
44{
45 ((AppleADBMouse *)target)->packet(adbCommand, length, data);
46}
47
48
49// ****************************************************************************
50
51#undef super
52#define super IOHIPointing
53
54OSDefineMetaClassAndStructors(AppleADBMouse, IOHIPointing);
55
56
57// ****************************************************************************
58// probe
59//
60// ****************************************************************************
61IOService * AppleADBMouse::probe(IOService * provider, SInt32 * score)
62{
63 adbDevice = (IOADBDevice *)provider;
64
65 return this;
66}
67
68
69// ****************************************************************************
70// start
71//
72// ****************************************************************************
73bool AppleADBMouse::start(IOService * provider)
74{
75 if(!super::start(provider)) return false;
76
77 if(!adbDevice->seizeForClient(this, NewMouseData)) {
78 IOLog("%s: Seize failed\n", getName());
79 return false;
80 }
81
82 return true;
83}
84
85
86// ****************************************************************************
87// interfaceID
88//
89// ****************************************************************************
90UInt32 AppleADBMouse::interfaceID(void)
91{
92 return NX_EVS_DEVICE_INTERFACE_ADB;
93}
94
95
96// ****************************************************************************
97// deviceType
98//
99// ****************************************************************************
100UInt32 AppleADBMouse::deviceType ( void )
101{
102 return adbDevice->handlerID();
103}
104
105
106// ****************************************************************************
107// resolution
108//
109// ****************************************************************************
110IOFixed AppleADBMouse::resolution(void)
111{
112 return _resolution;
113}
114
115
116// ****************************************************************************
117// buttonCount
118//
119// ****************************************************************************
120IOItemCount AppleADBMouse::buttonCount(void)
121{
122 return _buttonCount;
123}
124
125
126// ****************************************************************************
127// packet
128//
129// ****************************************************************************
130void AppleADBMouse::packet(UInt8 /*adbCommand*/,
131 IOByteCount /*length*/, UInt8 * data)
132{
133 int dx, dy;
134 UInt32 buttonState = 0;
135 AbsoluteTime now;
136
137 dy = data[0] & 0x7f;
138 dx = data[1] & 0x7f;
139
140 if (dy & 0x40) dy |= 0xffffffc0;
141 if (dx & 0x40) dx |= 0xffffffc0;
142
143 if ((data[0] & 0x80) == 0) buttonState |= 1;
144
145 clock_get_uptime(&now);
146 dispatchRelativePointerEvent(dx, dy, buttonState, now);
147}
148
149
150// ****************************************************************************
151
152#undef super
153#define super AppleADBMouse
154
155OSDefineMetaClassAndStructors(AppleADBMouseType1, AppleADBMouse);
156
157IOService * AppleADBMouseType1::probe(IOService * provider, SInt32 * score)
158{
159 if (!super::probe(provider, score)) return 0;
160
161 return this;
162}
163
164bool AppleADBMouseType1::start(IOService * provider)
165{
166 if (adbDevice->setHandlerID(1) != kIOReturnSuccess) return false;
167
168 _resolution = 100 << 16;
169 _buttonCount = 1;
170
171 return super::start(provider);
172}
173
174
175// ****************************************************************************
176
177#undef super
178#define super AppleADBMouse
179
180OSDefineMetaClassAndStructors(AppleADBMouseType2, AppleADBMouse);
181
182IOService * AppleADBMouseType2::probe(IOService * provider, SInt32 * score)
183{
184 if (!super::probe(provider, score)) return 0;
185
186 if (adbDevice->setHandlerID(2) != kIOReturnSuccess) return 0;
187
188 return this;
189}
190
191bool AppleADBMouseType2::start(IOService * provider)
192{
193 if (adbDevice->setHandlerID(2) != kIOReturnSuccess) return false;
194
195 _resolution = 200 << 16;
196 _buttonCount = 1;
197
198 return super::start(provider);
199}
200
201
202// ****************************************************************************
203
204#undef super
205#define super AppleADBMouse
206
207OSDefineMetaClassAndStructors(AppleADBMouseType4, AppleADBMouse);
208
209IOService * AppleADBMouseType4::probe(IOService * provider, SInt32 * score)
210{
211 UInt8 data[8];
212 IOByteCount length = 8;
213
214 if (!super::probe(provider, score)) return 0;
215
216 if (adbDevice->setHandlerID(4) != kIOReturnSuccess) {
217 adbDevice->setHandlerID(adbDevice->defaultHandlerID());
218 return 0;
219 }
220
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;
224
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];
230
231 return this;
232}
233
234bool AppleADBMouseType4::start(IOService * provider)
235{
236 UInt8 adbdata[8];
237 IOByteCount adblength = 8;
238 typeTrackpad = FALSE;
239
240 if (adbDevice->setHandlerID(4) != kIOReturnSuccess) return false;
241
242 _resolution = deviceResolution << 16;
243 _buttonCount = deviceNumButtons;
244
245 adbDevice->readRegister(1, adbdata, &adblength);
246 if( (adbdata[0] == 't') && (adbdata[1] = 'p') && (adbdata[2] == 'a') && (adbdata[3] == 'd') )
247 {
248 IOLog("Trackpad detected, ");
249 typeTrackpad = TRUE;
250 enableEnhancedMode();
251 }
252
253 return super::start(provider);
254}
255
256void AppleADBMouseType4::packet(UInt8 /*adbCommand*/, IOByteCount length, UInt8 * data)
257{
258 int dx, dy, cnt, numExtraBytes;
259 UInt32 buttonState = 0;
260 AbsoluteTime now;
261
262 numExtraBytes = length - 2;
263
264 dy = data[0] & 0x7f;
265 dx = data[1] & 0x7f;
266
267 if ((data[0] & 0x80) == 0) buttonState |= 1;
268 if ((deviceNumButtons > 1) && ((data[1] & 0x80) == 0))
269 {
270 if(typeTrackpad == TRUE)
271 buttonState |= 1;
272 else
273 buttonState |= 2;
274 }
275
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));
279
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);
284 }
285
286 if (dy & (0x40 << (numExtraBytes * 3)))
287 dy |= (0xffffffc0 << (numExtraBytes * 3));
288 if (dx & (0x40 << (numExtraBytes * 3)))
289 dx |= (0xffffffc0 << (numExtraBytes * 3));
290
291 clock_get_uptime(&now);
292 dispatchRelativePointerEvent(dx, dy, buttonState, now);
293}
294
295OSData * AppleADBMouseType4::copyAccelerationTable()
296{
297 char keyName[10];
298
299 strcpy( keyName, "accl" );
300 keyName[4] = (deviceSignature >> 24);
301 keyName[5] = (deviceSignature >> 16);
302 keyName[6] = (deviceSignature >> 8);
303 keyName[7] = (deviceSignature >> 0);
304 keyName[8] = 0;
305
306 OSData * data = OSDynamicCast( OSData,
307 getProperty( keyName ));
308 if( data)
309 data->retain();
310 else
311 data = super::copyAccelerationTable();
312
313 return( data );
314}
315
316// ****************************************************************************
317// enableEnhancedMode
318//
319// ****************************************************************************
320
321bool AppleADBMouseType4::enableEnhancedMode()
322{
323 UInt8 adbdata[8];
324 IOByteCount adblength = 8;
325
326 IOLog("enableEnhancedMode called.\n");
327 adbDevice->readRegister(1, adbdata, &adblength);
328
329 if((adbdata[6] != 0x0D))
330 {
331 adbdata[6] = 0xD;
332 if (adbDevice->writeRegister(1, adbdata, &adblength) != 0)
333 return FALSE;
334 if (adbDevice->readRegister(1, adbdata, &adblength) != 0)
335 return FALSE;
336 if (adbdata[6] != 0x0D)
337 {
338 IOLog("AppleADBMouseType4 deviceClass = %d (non-Extended Mode)\n", adbdata[6]);
339 return FALSE;
340 }
341 IOLog("AppleADBMouseType4 deviceClass = %d (Extended Mode)\n", adbdata[6]);
342
343 // Set ADB Extended Features to default values.
344 //adbdata[0] = 0x19;
345 adbdata[0] = glob_clicking;
346 //adbdata[1] = 0x14;
347 adbdata[1] = glob_dragging;
348 adbdata[2] = 0x19;
349 //adbdata[3] = 0xB2;
350 adbdata[3] = glob_draglock;
351 adbdata[4] = 0xB2;
352 adbdata[5] = 0x8A;
353 adbdata[6] = 0x1B;
354 adbdata[7] = 0x50;
355 adblength = 8;
356
357 adbDevice->writeRegister(2, adbdata, &adblength);
358
359 /* Add IORegistry entries for Enhanced mode */
360 Clicking = FALSE;
361 Dragging = FALSE;
362 DragLock = FALSE;
363
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);
367
368 return TRUE;
369 }
370
371 return FALSE;
372}
373
374// ****************************************************************************
375// setParamProperties
376//
377// ****************************************************************************
378IOReturn AppleADBMouseType4::setParamProperties( OSDictionary * dict )
379{
380 OSData * data;
381 IOReturn err = kIOReturnSuccess;
382 UInt8 adbdata[8];
383 IOByteCount adblength;
384
385 //IOLog("AppleADBMouseType4::setParamProperties starting here\n");
386
387 if( (data = OSDynamicCast(OSData, dict->getObject("Clicking"))) && (typeTrackpad == TRUE) )
388 {
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);
395 }
396
397 if( (data = OSDynamicCast(OSData, dict->getObject("Dragging"))) && (typeTrackpad == TRUE) )
398 {
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);
405 }
406
407 if( (data = OSDynamicCast(OSData, dict->getObject("DragLock"))) && (typeTrackpad == TRUE) )
408 {
409 adblength = sizeof(adbdata);
410 adbDevice->readRegister(2, adbdata, &adblength);
411 adbdata[3] = *((UInt8 *) data->getBytesNoCopy());
412
413 if(adbdata[3])
414 {
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);
420 }
421 else
422 {
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);
428 }
429 }
430
431#if 0
432 // For debugging purposes
433 adblength = 8;
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]);
443#endif
444
445 if (err == kIOReturnSuccess)
446 {
447 //IOLog("AppleADBMouseType4::setParamProperties ending here\n");
448 return super::setParamProperties(dict);
449 }
450
451 IOLog("AppleADBMouseType4::setParamProperties failing here\n");
452 return( err );
453}
454