AppleUSBOpticalMouse.cpp [plain text]
#include <IOKit/usb/IOUSBLog.h>
#include <IOKit/IOMessage.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#define FORMOUSETESTING 0
#include "AppleUSBOpticalMouse.h"
#define super IOUSBHIDDriver
#define kDefaultFixedResolution (400 << 16)
OSDefineMetaClassAndStructors(AppleUSBOpticalMouse, super)
static bool switchTo800dpi = true;
IOReturn
AppleUSBOpticalMouse::StartFinalProcessing()
{
OSNumber *curResPtr, *resPrefPtr;
UInt32 curResInt, resPrefInt;
IOFixed curRes, resPref;
IOReturn err = kIOReturnSuccess;
OSBoolean * boolObj;
USBLog(3, "%s[%p]::StartFinalProcessing", getName(), this);
boolObj = OSDynamicCast( OSBoolean, getProperty("SwitchTo800DPI") );
if ( boolObj && boolObj->isTrue() )
{
_switchTo800dpiFlag = true;
}
boolObj = OSDynamicCast( OSBoolean, getProperty("SwitchTo2000FPS") );
if ( boolObj && boolObj->isTrue() )
{
_switchTo2000fpsFlag = true;
}
if ( _switchTo2000fpsFlag )
{
IOUSBDevRequest devReq;
devReq.bmRequestType = 0x40;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0xd810;
devReq.wLength = 0x0000;
devReq.pData = NULL;
err = _device->DeviceRequest(&devReq, 5000, 0);
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - sending 1st part of FPS change received error 0x%x", getName(), this, err);
else
{
devReq.bmRequestType = 0x40;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0xdc11;
devReq.wLength = 0x0000;
devReq.pData = NULL;
err = _device->DeviceRequest(&devReq, 5000, 0);
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - sending 2nd part of FPS change received error 0x%x", getName(), this, err);
}
#if FORMOUSETESTING
UInt8 hi,lo;
UInt16 fps;
devReq.bmRequestType = 0xc0;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0x0011;
devReq.wLength = 1;
devReq.pData = &hi;
err = _device->DeviceRequest(&devReq, 5000, 0);
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - error reading hi byte: 0x%x", getName(), this, err);
devReq.bmRequestType = 0xc0;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0x0010;
devReq.wLength = 1;
devReq.pData = &lo;
err = _device->DeviceRequest(&devReq, 5000, 0);
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - read reading lo byte: 0x%x", getName(), this, err);
fps = hi;
fps = (fps << 8) | lo;
USBLog(3, "%s[%p]::StartFinalProcessing - read : 0x%x", getName(), this, fps );
#endif
err = super::StartFinalProcessing();
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - super returned error 0x%x", getName(), this, err);
}
if ( _switchTo800dpiFlag )
{
curResPtr = (OSNumber*)getProperty(kIOHIDPointerResolutionKey);
if (curResPtr)
{
curResInt = curResPtr->unsigned32BitValue();
USBLog(3, "%s[%p]::StartFinalProcessing - found current resolution property - value %x", getName(), this, curResInt);
}
else
{
curResInt = kDefaultFixedResolution;
USBLog(3, "%s[%p]::StartFinalProcessing - no current property found - using default %x", getName(), this, curResInt);
}
resPrefPtr = (OSNumber *)getProperty("xResolutionPref");
if (resPrefPtr)
resPrefInt = resPrefPtr->unsigned32BitValue();
else
{
resPrefInt = kDefaultFixedResolution * 2;
USBLog(3, "%s[%p]::StartFinalProcessing - no preference property found - using default %x", getName(), this, resPrefInt);
}
resPref = (IOFixed) resPrefInt;
curRes = (IOFixed) curResInt;
if (resPref != curRes)
{
if (switchTo800dpi)
{
IOUSBDevRequest devReq;
devReq.bmRequestType = 0x40;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0x0452;
devReq.wLength = 0x0000;
devReq.pData = NULL;
err = _device->DeviceRequest(&devReq, 5000, 0);
if (err)
USBLog(3, "%s[%p]::StartFinalProcessing - error (%x) setting resolution", getName(), this, err);
else
USBLog(3, "%s[%p]::StartFinalProcessing - waiting for click mouse termination", getName(), this);
}
}
else
{
USBLog(3, "%s[%p]::StartFinalProcessing - registering PowerDownHandler", getName(), this);
_notifier = registerPrioritySleepWakeInterest(PowerDownHandler, this, 0);
err = super::StartFinalProcessing();
if (err)
{
if (_notifier)
_notifier->remove();
_notifier = NULL;
}
}
}
return err;
}
IOReturn
AppleUSBOpticalMouse::PowerDownHandler(void *target, void *refCon, UInt32 messageType, IOService *service,
void *messageArgument, vm_size_t argSize )
{
IOUSBDevRequest devReq;
IOReturn err = kIOReturnUnsupported;
AppleUSBOpticalMouse * me = OSDynamicCast(AppleUSBOpticalMouse, (OSObject *)target);
if (!me)
return err;
switch (messageType)
{
case kIOMessageSystemWillRestart:
switchTo800dpi = false;
devReq.bmRequestType = 0x40;
devReq.bRequest = 0x01;
devReq.wValue = 0x05AC;
devReq.wIndex = 0x0052; devReq.wLength = 0x0000;
devReq.pData = NULL;
err = (me)->_device->DeviceRequest(&devReq, 5000, 0);
break;
default:
break;
}
return err;
}
bool
AppleUSBOpticalMouse::willTerminate( IOService * provider, IOOptionBits options )
{
USBLog(3, "%s[%p]::willTerminate isInactive = %d", getName(), this, isInactive());
if ( _notifier )
_notifier->remove();
_notifier = NULL;
return super::willTerminate(provider, options);
}