#include <IOKit/IOLib.h>
#include <IOKit/IODeviceTreeSupport.h>
#include "I2CGPIO.h"
#define super IOService
OSDefineMetaClassAndStructors(I2CGPIO, IOService)
bool I2CGPIO::init(OSDictionary *dict)
{
UInt32 i;
if (!super::init(dict)) return(false);
fI2CBus = 0;
fI2CAddress = 0;
fI2CInterface = 0;
fRegisteredWithI2C = false;
fRegisteredWithI2CLock = 0;
fBayIndex = 0;
fIntAddrInfo = 0;
fIntRegState = 0;
fCurrentPowerState = 0;
fConfigReg = 0xFF; fPolarityReg = 0x00;
#ifdef I2CGPIO_DEBUG
fWriteCookie = 0;
fReadCookie = 0;
#endif
for (i=0; i<kNumGPIOs; i++)
fClients[i] = 0;
return(true);
}
void I2CGPIO::free(void)
{
super::free();
}
IOService *I2CGPIO::probe(IOService *provider, SInt32 *score)
{
if (provider->getProperty(kI2CGPIOCombined))
{
*score = 0;
return(0);
}
return(this);
}
bool I2CGPIO::start(IOService *provider)
{
IOService *parentDev;
OSData *regprop, *combined, *cfgData;
UInt32 fullAddr, index, length;
UInt32 *quadlet;
OSCollectionIterator *siblings;
bool found;
IORegistryEntry *entry;
mach_timespec_t waitTimeout;
static const IOPMPowerState powerStates[kI2CGPIONumPowerStates] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 }
};
if (provider->getProperty(kI2CGPIOCombined))
{
return(false);
}
if (!super::start(provider)) return(false);
if ((regprop = OSDynamicCast(OSData, provider->getProperty("reg"))) == 0)
return(false);
else
{
fullAddr = *((UInt32 *)regprop->getBytesNoCopy());
fI2CBus = (UInt8)((fullAddr >> 8) & 0x000000ff);
fI2CAddress = (UInt8)(fullAddr & 0x000000fe);
DLOG("I2CGPIO::start fI2CBus = %02x fI2CAddress = %02x\n",
fI2CBus, fI2CAddress);
}
parentDev = OSDynamicCast(IOService,
provider->getParentEntry(gIODTPlane));
if (!parentDev) return(false);
OSData *data;
if ( data = OSDynamicCast( OSData, parentDev->getProperty("name") ) )
{
char resourceName[256] = "PPCI2CInterface.";
strncat( resourceName, (char *)data->getBytesNoCopy(), data->getLength() );
IOService *resource;
waitTimeout.tv_sec = 30;
waitTimeout.tv_nsec = 0;
if ( NULL == ( resource = OSDynamicCast( IOService, waitForService( resourceMatching( resourceName ), &waitTimeout ) ) ) )
{
kprintf( "I2CGPIO::start timeout waiting for IOResources \"%s\" property\n", resourceName );
return false;
}
if ( NULL == ( fI2CInterface = OSDynamicCast( IOService, resource->getProperty( resourceName ) ) ) )
{
kprintf( "I2CGPIO::start failed to find IOResources \"%s\" property\n", resourceName );
return false;
}
}
else
{
kprintf( "I2CGPIO::start failed to find PPCI2CInterface provider node name\n" );
return false;
}
fullAddr <<= 8;
if ((siblings =
IODTFindMatchingEntries(parentDev, kIODTExclusive, 0)) == 0)
return(false);
found = false;
while ((entry = OSDynamicCast(IORegistryEntry,
siblings->getNextObject())) != 0)
{
if ((combined = OSDynamicCast(OSData,
entry->getProperty(kI2CGPIOCombined))) == 0)
continue;
length = combined->getLength() / sizeof(UInt32);
quadlet = (UInt32 *)combined->getBytesNoCopy();
for (index = 0; index < length; index++)
{
if (fullAddr == *quadlet)
{
const char *compat;
if (cfgData = OSDynamicCast(OSData, entry->getProperty("compatible")))
if (compat = (const char *)cfgData->getBytesNoCopy())
if (0 == strcmp(compat, "PCA9554M"))
fC3Mapping = true;
fBayIndex = index;
regprop = OSDynamicCast(OSData, entry->getProperty("reg"));
fIntAddrInfo = *((UInt32 *)regprop->getBytesNoCopy());
fIntAddrInfo <<= 8; fIntAddrInfo |= 0x00000100; found = true;
DLOG("I2CGPIO %x fIntAddrInfo = %08x fBayIndex = %u\n",
fI2CAddress, fIntAddrInfo, fBayIndex);
break;
}
quadlet++;
}
if (found) break;
}
if (siblings) siblings->release();
if (!found)
{
DLOG("I2CGPIO %x couldn't find combined gpio node, bailing...\n",
fI2CAddress);
return(false);
}
waitTimeout.tv_sec = 30;
waitTimeout.tv_nsec = 0;
fKeyswitch = waitForService(serviceMatching("AppleKeyswitch"),
&waitTimeout);
fCurrentPowerState = kI2CGPIOPowerOn;
cfgData = OSDynamicCast(OSData, provider->getProperty("config-reg"));
if (cfgData)
fConfigReg = (UInt8)*((UInt32 *)cfgData->getBytesNoCopy());
cfgData = OSDynamicCast(OSData, provider->getProperty("polarity-reg"));
if (cfgData)
fPolarityReg = (UInt8)*((UInt32 *)cfgData->getBytesNoCopy());
DLOG("I2CGPIO %x fConfigReg = %u fPolarityReg = %u\n", fI2CAddress, fConfigReg, fPolarityReg);
PMinit();
provider->joinPMtree(this);
DLOG("I2CGPIO::start %u registering as power controller\n", fI2CAddress);
if (registerPowerDriver(this, (IOPMPowerState *)powerStates,
kI2CGPIONumPowerStates) != kIOReturnSuccess)
{
DLOG("I2CGPIO::start PM init failed\n");
return(false);
}
fRegisteredWithI2CLock = IOLockAlloc();
fSymOpenI2CBus = OSSymbol::withCString(kOpenI2CBus);
fSymReadI2CBus = OSSymbol::withCString(kReadI2CBus);
fSymWriteI2CBus = OSSymbol::withCString(kWriteI2CBus);
fSymCloseI2CBus = OSSymbol::withCString(kCloseI2CBus);
fSymSetCombinedMode = OSSymbol::withCString(kSetCombinedMode);
fSymSetStandardSubMode = OSSymbol::withCString(kSetStandardSubMode);
fSymRegisterForInts = OSSymbol::withCString(kRegisterForInts);
fSymDeRegisterForInts = OSSymbol::withCString(kDeRegisterForInts);
publishBelow(provider);
DLOG("I2CGPIO::start %u succeeded\n", fI2CAddress);
return(true);
}
void I2CGPIO::stop(IOService *provider)
{
UInt32 i;
for (i=0; i<kNumGPIOs; i++)
{
if (fClients[i] != 0)
{
IOFree(fClients[i], sizeof(I2CGPIOCallbackInfo));
fClients[i] = 0;
}
}
unregisterWithI2C();
IOLockFree(fRegisteredWithI2CLock);
fRegisteredWithI2CLock = 0;
PMstop();
super::stop(provider);
}
IOReturn I2CGPIO::doI2CWrite(UInt8 busNo, UInt8 addr, UInt8 subAddr, UInt8 value, UInt8 mask)
{
UInt8 eightBitAddr, tmp, data, retries;
unsigned tmpInt1, tmpInt2;
IOReturn retval, result = kIOReturnSuccess;
#ifdef I2CGPIO_DEBUG
UInt32 myCookie = fWriteCookie++;
#endif
eightBitAddr = addr;
DLOG("+I2CGPIO::doI2CWrite(%s) bus:%x addr:%x sub:%x cookie:%u value:%x mask:%x\n",
getProvider()->getName(), busNo, eightBitAddr, subAddr, myCookie, value, mask);
addr >>= 1;
tmpInt1 = (unsigned)busNo;
if ((retval = fI2CInterface->callPlatformFunction(fSymOpenI2CBus,
false, (void *)tmpInt1, 0, 0, 0)) != kIOReturnSuccess)
return(retval);
do {
fI2CInterface->callPlatformFunction(fSymSetCombinedMode, false,
0, 0, 0, 0);
tmpInt1 = (unsigned)addr;
tmpInt2 = (unsigned)subAddr;
retries = kI2CReadRetryCount;
do {
if (retries < kI2CReadRetryCount)
IOLog("I2CGPIO::doI2CWrite I2C read failed, retrying...\n");
retval = fI2CInterface->callPlatformFunction(fSymReadI2CBus, false,
(void *)tmpInt1, (void *)tmpInt2, (void *)&data,
(void *)1);
retries--;
} while ((retval != kIOReturnSuccess) && (retries > 0));
if (retval != kIOReturnSuccess)
{
result = retval;
break;
}
tmp = (data & ~mask) | (value & mask);
fI2CInterface->callPlatformFunction(fSymSetStandardSubMode, false,
0, 0, 0, 0);
tmpInt1 = (unsigned)addr;
tmpInt2 = (unsigned)subAddr;
retries = kI2CWriteRetryCount;
do
{
if (retries < kI2CWriteRetryCount)
IOLog("I2CGPIO::doI2CWrite I2C write failed, retrying...\n");
retval = fI2CInterface->callPlatformFunction(fSymWriteI2CBus, false,
(void *)tmpInt1, (void *)tmpInt2, (void *)&tmp,
(void *)1);
retries--;
} while ((retval != kIOReturnSuccess) && (retries > 0));
if (retval != kIOReturnSuccess)
{
result = retval;
break;
}
} while(false);
fI2CInterface->callPlatformFunction(fSymCloseI2CBus, false, 0, 0, 0, 0);
#ifdef I2CGPIO_DEBUG
const char *debug_status;
if (result == kIOReturnSuccess)
{
debug_status = "-I2CGPIO::doI2CWrite(%s) bus:%x addr:%x sub:%x cookie:%u\n";
}
else
{
debug_status = "-I2CGPIO::doI2CWrite(%s) FAILED!! bus:%x addr:%x sub:%x cookie:%u\n";
}
#endif
DLOG(debug_status, getProvider()->getName(), busNo, eightBitAddr, subAddr, myCookie);
if (result != kIOReturnSuccess)
{
IOLog("I2CGPIO::doI2CWrite I2C bus transaction failed!!\n");
}
return(result);
}
IOReturn I2CGPIO::doI2CRead(UInt8 busNo, UInt8 addr, UInt8 subAddr, UInt8 *value)
{
IOReturn retval, result = kIOReturnSuccess;
UInt8 retries, eightBitAddr;
unsigned tmpInt1, tmpInt2;
#ifdef I2CGPIO_DEBUG
UInt32 myCookie = fReadCookie++;
#endif
eightBitAddr = addr;
DLOG("+I2CGPIO::doI2CRead(%s) bus:%x addr:%x sub:%x cookie:%u\n",
getProvider()->getName(), busNo, eightBitAddr, subAddr, myCookie);
addr >>= 1;
tmpInt1 = (unsigned)busNo;
if ((retval = fI2CInterface->callPlatformFunction(fSymOpenI2CBus,
false, (void *)tmpInt1, 0, 0, 0)) != kIOReturnSuccess)
return(retval);
fI2CInterface->callPlatformFunction(fSymSetCombinedMode, false, 0, 0, 0, 0);
tmpInt1 = (unsigned)addr;
tmpInt2 = (unsigned)subAddr;
retries = kI2CReadRetryCount;
do {
if (retries < kI2CReadRetryCount)
IOLog("I2CGPIO::doI2CRead I2C read failed, retrying...\n");
retval = fI2CInterface->callPlatformFunction(fSymReadI2CBus, false,
(void *)tmpInt1, (void *)tmpInt2, (void *)value,
(void *)1);
retries--;
} while ((retval != kIOReturnSuccess) && (retries > 0));
if (retval != kIOReturnSuccess) result = retval;
fI2CInterface->callPlatformFunction(fSymCloseI2CBus, false, 0, 0, 0, 0);
#ifdef I2CGPIO_DEBUG
const char *debug_status;
if (result == kIOReturnSuccess)
{
debug_status = "-I2CGPIO::doI2CRead(%s) bus:%x addr:%x sub:%x cookie:%u value:%x\n";
}
else
{
debug_status = "-I2CGPIO::doI2CRead(%s) FAILED!! bus:%x addr:%x sub:%x cookie:%u value:%x\n";
}
#endif
DLOG(debug_status, getProvider()->getName(), busNo, eightBitAddr, subAddr, myCookie, *value);
if (result != kIOReturnSuccess)
{
IOLog("I2CGPIO::doI2CRead I2C bus transaction failed!!\n");
}
return(result);
}
bool I2CGPIO::registerClient(void *param1, void *param2,
void *param3, void *param4)
{
UInt32 id;
id = (UInt32)param1;
if ((id >= kNumGPIOs) || (fClients[id] != 0)) return(false);
if (!registerWithI2C()) return(false);
if ((fClients[id] =
(I2CGPIOCallbackInfo *)IOMalloc(sizeof(I2CGPIOCallbackInfo))) == 0)
return(false);
fClients[id]->handler = (GPIOEventHandler)param3;
fClients[id]->self = param4;
fClients[id]->isEnabled = false;
return(true);
}
bool I2CGPIO::unregisterClient(void *param1, void *param2,
void *param3, void *param4)
{
UInt32 id, count;
bool isClient;
DLOG("I2CGPIO::unregisterClient %08lx %08lx %08lx %08lx\n",
(UInt32)param1, (UInt32)param2, (UInt32)param3, (UInt32)param4);
id = (UInt32)param1;
if ((id >= kNumGPIOs) || (fClients[id] == 0))
{
return(false);
}
IOFree(fClients[id], sizeof(I2CGPIOCallbackInfo));
fClients[id] = 0;
isClient = false;
for (count=0; count<kNumGPIOs; count++)
{
if (fClients[count] != 0)
{
isClient = true;
break;
}
}
if (!isClient) unregisterWithI2C();
return(true);
}
bool I2CGPIO::enableClient(void *param1, void *param2, void *param3,
void *param4)
{
UInt32 id = (UInt32)param1;
if ((id >= kNumGPIOs) || (fClients[id] == 0))
{
return(false);
}
if (fClients[id]->isEnabled)
{
DLOG("I2CGPIO::enableClient events already enabled\n");
}
else
{
fClients[id]->isEnabled = true;
DLOG("I2CGPIO::enableClient enabled events\n");
}
return(true);
}
bool I2CGPIO::disableClient(void *param1, void *param2, void *param3,
void *param4)
{
UInt32 id = (UInt32)param1;
if ((id >= kNumGPIOs) || (fClients[id] == 0))
{
return(false);
}
if (fClients[id]->isEnabled)
{
fClients[id]->isEnabled = false;
DLOG("I2CGPIO::disableClient disabled events\n");
}
else
{
DLOG("I2CGPIO::disableClient events already disabled\n");
}
return(true);
}
void I2CGPIO::handleEvent(UInt32 addressInfo, UInt32 length, UInt8 *buffer)
{
UInt8 newState, diff;
UInt32 value;
GPIOEventHandler client;
OSBoolean *locked = NULL;
if (length == 0) return;
newState = *buffer;
if (newState == fIntRegState)
{
DLOG("I2CGPIO::handleEvent 0x%02x orig = 0x%02x new = 0x%02x, disregarding...\n",
fI2CAddress, newState, fIntRegState);
return;
}
diff = newState ^ fIntRegState;
DLOG("I2CGPIO::handleEvent 0x%02x orig = 0x%02x new = 0x%02x xor = 0x%02x\n",
fI2CAddress, fIntRegState, newState, diff);
fIntRegState = newState;
int bitOffset;
bitOffset = (fC3Mapping) ? (fBayIndex * 2) : fBayIndex;
if (diff & (1 << bitOffset))
{
DLOG("I2CGPIO 0x%02x got button event\n", fI2CAddress);
if ((fClients[kSwitch] == 0) || (!fClients[kSwitch]->isEnabled))
return;
if (fKeyswitch)
locked = OSDynamicCast(OSBoolean, fKeyswitch->getProperty("Keyswitch"));
if (locked != NULL && locked->isTrue())
return;
value = (UInt32)((newState >> bitOffset) & 0x01);
value ^= 0x1;
client = fClients[kSwitch]->handler;
client((void *)fClients[kSwitch]->self, (void *)value, 0, 0);
}
bitOffset = (fC3Mapping) ? ((fBayIndex * 2) + 1) : (4 + fBayIndex);
if (diff & (1 << bitOffset))
{
DLOG("I2CGPIO 0x%02x got insertion/removal event\n", fI2CAddress);
if ((fClients[kPresent] == 0) || (!fClients[kPresent]->isEnabled))
return;
value = (UInt32)((newState >> (bitOffset)) & 0x01);
value ^= 0x1;
client = fClients[kPresent]->handler;
client((void *)fClients[kPresent]->self, (void *)value, 0, 0);
}
}
IOReturn I2CGPIO::callPlatformFunction(const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4)
{
const char *functionNameStr;
UInt8 data = 0, mask, value;
IOReturn result = kIOReturnUnsupported;
unsigned tmpInt;
if (functionName == 0) return kIOReturnBadArgument;
functionNameStr = functionName->getCStringNoCopy();
DLOG("I2CGPIO::callPlatformFunction %s %s %08lx %08lx %08lx %08lx\n",
functionNameStr, waitForFunction ? "TRUE" : "FALSE",
(UInt32)param1, (UInt32)param2, (UInt32)param3, (UInt32)param4);
if (fCurrentPowerState == kI2CGPIOPowerOff)
{
result = kIOReturnNotReady;
}
else if (strcmp(functionNameStr, kSymGPIOParentIntCapable) == 0)
{
*((UInt32 *)param1) = 1;
result = kIOReturnSuccess;
}
else if (strcmp(functionNameStr, kSymGPIOParentWriteGPIO) == 0)
{
tmpInt = (unsigned)param2;
value = (UInt8)tmpInt;
tmpInt = (unsigned)param3;
mask = (UInt8)tmpInt;
result = doI2CWrite(fI2CBus, fI2CAddress, k9554OutputPort, value, mask);
}
else if (strcmp(functionNameStr, kSymGPIOParentReadGPIO) == 0)
{
result = doI2CRead(fI2CBus, fI2CAddress, k9554InputPort, &data);
*(UInt32 *)param2 = (UInt32)data;
}
else if (strcmp(functionNameStr, kSymGPIOParentRegister) == 0)
{
if (registerClient(param1, param2, param3, param4))
result = kIOReturnSuccess;
else
result = kIOReturnError;
}
else if (strcmp(functionNameStr, kSymGPIOParentUnregister) == 0)
{
if (unregisterClient(param1, param2, param3, param4))
result = kIOReturnSuccess;
else
result = kIOReturnBadArgument;
}
else if (strcmp(functionNameStr, kSymGPIOParentEvtEnable) == 0)
{
if (enableClient(param1, param2, param3, param4))
result = kIOReturnSuccess;
else
result = kIOReturnBadArgument;
}
else if (strcmp(functionNameStr, kSymGPIOParentEvtDisable) == 0)
{
if (disableClient(param1, param2, param3, param4))
result = kIOReturnSuccess;
else
result = kIOReturnBadArgument;
}
else
{
result = super::callPlatformFunction(functionName, waitForFunction,
param1, param2, param3, param4);
}
return result;
}
IOReturn I2CGPIO::callPlatformFunction( const char *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4 )
{
return(super::callPlatformFunction(functionName,
waitForFunction, param1, param2, param3, param4));
}
void I2CGPIO::sI2CEventOccured(I2CGPIO *client, UInt32 addressInfo,
UInt32 length, UInt8 *buffer)
{
if (client == 0) return;
client->handleEvent(addressInfo, length, buffer);
}
bool I2CGPIO::registerWithI2C(void)
{
UInt8 tmpBus;
UInt8 tmpAddr;
IOReturn retval;
DLOG("I2CGPIO::registerWithI2C registering for %08lx...\n", fIntAddrInfo);
IOLockLock(fRegisteredWithI2CLock);
if (fRegisteredWithI2C)
{
DLOG("I2CGPIO::registerWithI2C already registered\n");
IOLockUnlock(fRegisteredWithI2CLock);
return(true); }
tmpBus = (UInt8)(fIntAddrInfo >> 16);
tmpAddr = (UInt8)(fIntAddrInfo >> 8);
if ((retval = doI2CRead(tmpBus, tmpAddr, k9554InputPort, &fIntRegState))
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::registerWithI2C failed to fetch initial state\n");
IOLockUnlock(fRegisteredWithI2CLock);
return(false);
}
if ((retval = fI2CInterface->callPlatformFunction(fSymRegisterForInts, false,
(void *)fIntAddrInfo, (void *)&sI2CEventOccured, (void *)this, 0))
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::registerWithI2C failed to register\n");
IOLockUnlock(fRegisteredWithI2CLock);
return(false);
}
fRegisteredWithI2C = true;
IOLockUnlock(fRegisteredWithI2CLock);
DLOG("I2CGPIO::registerWithI2C succeeded\n");
return(true);
}
void I2CGPIO::unregisterWithI2C(void)
{
IOLockLock(fRegisteredWithI2CLock);
if (!fRegisteredWithI2C)
{
DLOG("I2CPGIO::unregisterWithI2C not registered\n");
IOLockUnlock(fRegisteredWithI2CLock);
return;
}
fI2CInterface->callPlatformFunction(fSymDeRegisterForInts, false,
(void *)fIntAddrInfo, (void *)this, 0, 0);
fRegisteredWithI2C = false;
IOLockUnlock(fRegisteredWithI2CLock);
}
IOService *I2CGPIO::createNub( IORegistryEntry * from )
{
IOService *nub;
nub = new I2CGPIODevice;
if (nub && !nub->init( from, gIODTPlane ))
{
nub->free();
nub = 0;
}
return(nub);
}
void I2CGPIO::processNub(IOService *myNub)
{
}
void I2CGPIO::publishBelow(IORegistryEntry *root)
{
OSCollectionIterator *kids;
IORegistryEntry *next;
IOService *nub;
OSData *compat;
bool gpio;
int strLen;
const char *strStart, *strCur;
kids = IODTFindMatchingEntries( root, kIODTRecursive | kIODTExclusive, 0);
if (kids)
{
while((next = (IORegistryEntry *)kids->getNextObject()) != 0)
{
compat = OSDynamicCast(OSData, next->getProperty("compatible"));
if (!compat)
{
DLOG("Failed to get kid's compatible property!!\n");
continue;
}
strLen = compat->getLength();
strStart = strCur = (const char *)compat->getBytesNoCopy();
gpio = false;
while ((strCur - strStart) < strLen)
{
if (strcmp(strCur, "gpio") == 0)
{
gpio = true;
break; }
strCur += strlen(strCur) + 1;
}
if(!gpio || ((nub = createNub(next)) == 0))
{
DLOG("Not creating nub for %s\n", next->getName());
continue;
}
nub->attach( this );
processNub(nub);
nub->registerService();
}
kids->release();
}
}
IOReturn I2CGPIO::setPowerState(unsigned long powerStateOrdinal,
IOService *whatDevice)
{
DLOG("I2CGPIO::setPowerState current = %u new = %u\n",
fCurrentPowerState, powerStateOrdinal);
if ((powerStateOrdinal == fCurrentPowerState) ||
(powerStateOrdinal >= kI2CGPIONumPowerStates))
{
DLOG("I2CGPIO::setPowerState new state is invalid\n");
}
else
{
switch (powerStateOrdinal)
{
case kI2CGPIOPowerOff:
doPowerDown();
break;
case kI2CGPIOPowerOn:
doPowerUp();
break;
default:
break;
}
}
DLOG("I2CGPIO::setPowerState %x finished\n", fI2CAddress);
return(IOPMAckImplied);
}
void I2CGPIO::doPowerDown(void)
{
DLOG("I2CGPIO::doPowerDown %x\n", fI2CAddress);
fCurrentPowerState = kI2CGPIOPowerOff;
#if 1
if (doI2CRead(fI2CBus, fI2CAddress, k9554OutputPort, &fOutputReg) != kIOReturnSuccess)
{
fOutputReg = 0x00;
DLOG("I2CGPIO::doPowerDown failed to save output state\n");
}
#endif
}
void I2CGPIO::doPowerUp(void)
{
DLOG("I2CGPIO::doPowerUp %x\n", fI2CAddress);
#if 0
if (doI2CWrite(fI2CBus, fI2CAddress, k9554OutputPort, 0x00 , 0xFF )
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::doPowerUp failed to zero outputs\n");
}
#endif
#if 1
if (doI2CWrite(fI2CBus, fI2CAddress, k9554OutputPort, fOutputReg , 0xFF )
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::doPowerUp failed to restore outputs\n");
}
#endif
if (doI2CWrite(fI2CBus, fI2CAddress, k9554PolarityInv, fPolarityReg, 0xFF)
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::doPowerUp failed to program polarity inversion reg\n");
}
if (doI2CWrite(fI2CBus, fI2CAddress, k9554Config, fConfigReg, 0xFF)
!= kIOReturnSuccess)
{
DLOG("I2CGPIO::doPowerUp failed to configure gpio\n");
}
if (doI2CRead((UInt8)(fIntAddrInfo >> 16), (UInt8)(fIntAddrInfo >> 8), k9554InputPort, &fIntRegState) != kIOReturnSuccess)
{
DLOG("I2CGPIO::doPowerUp failed to cache monitor state\n");
}
fCurrentPowerState = kI2CGPIOPowerOn;
}
#ifdef super
#undef super
#endif
#define super IOService
OSDefineMetaClassAndStructors(I2CGPIODevice, IOService)
bool I2CGPIODevice::compareName(OSString *name, OSString **matched = 0) const
{
return(IODTCompareNubName(this, name, matched)
|| super::compareName(name, matched));
}