#include <ppc/proc_reg.h>
#include <IOKit/IOLib.h>
#include <IOKit/IODeviceTreeSupport.h>
#include <IOKit/IODeviceMemory.h>
#include <IOKit/IOPlatformExpert.h>
#include <IOKit/ppc/IODBDMA.h>
#include <IOKit/pci/IOPCIDevice.h>
#include "IOPlatformFunction.h"
#include "KeyLargo.h"
#include "AppleKeyLargo.h"
#define super KeyLargo
OSDefineMetaClassAndStructors(AppleKeyLargo, KeyLargo);
AppleKeyLargo *gHostKeyLargo = NULL;
bool AppleKeyLargo::init(OSDictionary * properties)
{
savedKeyLargoState.thisStateIsValid = false;
cardStatus.cardPower = true;
return super::init(properties);
}
bool AppleKeyLargo::start(IOService *provider)
{
OSData *tmpData;
const OSSymbol *instantiate = OSSymbol::withCString("InstantiatePlatformFunctions");
IOReturn retval;
UInt32 flags;
IOPlatformFunction *func;
UInt32 i;
fProvider = provider;
tmpData = (OSData *) fProvider->getProperty( "AAPL,phandle" );
if(tmpData)
fPHandle = *((UInt32 *) tmpData->getBytesNoCopy());
tmpData = OSDynamicCast(OSData, provider->getProperty("name"));
if (tmpData == 0) return false;
if (tmpData->isEqualTo ("mac-io", strlen ("mac-io")))
gHostKeyLargo = this;
if (OSDynamicCast(OSData, provider->getProperty("include-k2-support")) == 0)
gPreserveIODeviceTree = FALSE;
else
gPreserveIODeviceTree = TRUE;
keyLargo_resetUniNEthernetPhy = OSSymbol::withCString("keyLargo_resetUniNEthernetPhy");
keyLargo_restoreRegisterState = OSSymbol::withCString("keyLargo_restoreRegisterState");
keyLargo_syncTimeBase = OSSymbol::withCString("keyLargo_syncTimeBase");
keyLargo_recalibrateBusSpeeds = OSSymbol::withCString("keyLargo_recalibrateBusSpeeds");
keyLargo_saveRegisterState = OSSymbol::withCString("keyLargo_saveRegisterState");
keyLargo_turnOffIO = OSSymbol::withCString("keyLargo_turnOffIO");
keyLargo_writeRegUInt8 = OSSymbol::withCString("keyLargo_writeRegUInt8");
keyLargo_safeWriteRegUInt8 = OSSymbol::withCString("keyLargo_safeWriteRegUInt8");
keyLargo_safeReadRegUInt8 = OSSymbol::withCString("keyLargo_safeReadRegUInt8");
keyLargo_safeWriteRegUInt32 = OSSymbol::withCString("keyLargo_safeWriteRegUInt32");
keyLargo_safeReadRegUInt32 = OSSymbol::withCString("keyLargo_safeReadRegUInt32");
keyLargo_powerMediaBay = OSSymbol::withCString("powerMediaBay");
keyLargo_getHostKeyLargo = OSSymbol::withCString("keyLargo_getHostKeyLargo");
keyLargo_powerI2S = OSSymbol::withCString("keyLargo_powerI2S");
keyLargo_setPowerSupply = OSSymbol::withCString("setPowerSupply");
keyLargo_EnableI2SModem = OSSymbol::withCString("EnableI2SModem");
mac_io_publishChildren = OSSymbol::withCString("mac-io-publishChildren");
mac_io_publishChild = OSSymbol::withCString("mac-io-publishChild");
if (!super::start(provider))
return false;
setReferenceCounts ();
enableCells();
initForPM(provider);
publishBelow(provider);
mediaIsOn = true;
keepSCCenabledInSleep = false;
registerService();
for (i = 0; i < fNumUSB; i++) {
usbBus[i] = new USBKeyLargo;
if (usbBus[i] != NULL) {
if ( usbBus[i]->init() && usbBus[i]->attach(this))
usbBus[i]->initForBus(fBaseUSBID+i, keyLargoDeviceId);
else
usbBus[i]->release();
}
}
if (gPreserveIODeviceTree == TRUE) {
fPlatformFuncArray = NULL;
UInt32 count;
retval = provider->getPlatform()->callPlatformFunction(instantiate, true,
(void *)provider, (void *)&fPlatformFuncArray, (void *)0, (void *)0);
if (retval == kIOReturnSuccess && (fPlatformFuncArray != NULL)) {
if ((count = fPlatformFuncArray->getCount()) > 0) {
for (i = 0; i < count; i++) {
if (func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i))) {
flags = func->getCommandFlags();
if (flags & kIOPFFlagOnInit) {
performFunction(func, (void *)1, (void *)0, (void *)0, (void *)0);
}
if ((flags & kIOPFFlagOnDemand) || ((flags & kIOPFFlagIntGen))) {
func->publishPlatformFunction(this);
}
}
else {
kprintf("AppleKeyLargo::start() - functionCheck - not an IOPlatformFunction object\n");
}
}
}
}
}
return true;
}
void AppleKeyLargo::stop(IOService *provider)
{
UInt32 i;
for (i = 0; i < fNumUSB; i++) {
if (usbBus[i] != NULL)
usbBus[i]->release();
}
if (keyLargoService)
keyLargoService->release();
if (mutex != NULL)
IOSimpleLockFree( mutex );
return;
}
void AppleKeyLargo::turnOffKeyLargoIO(bool restart)
{
UInt32 regTemp;
IOInterruptState intState = NULL;
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
if (!restart) {
kprintf("AppleKeyLargo::turnOffIO( --FALSE-- )\n");
}
if (!restart) {
regTemp = readRegUInt32(kKeyLargoFCR0);
regTemp |= kKeyLargoFCR0SleepBitsSet;
writeRegUInt32(kKeyLargoFCR0, regTemp);
IODelay(1000);
}
regTemp = readRegUInt32(kKeyLargoFCR0);
regTemp |= kKeyLargoFCR0SleepBitsSet;
regTemp &= ~kKeyLargoFCR0SleepBitsClear;
writeRegUInt32(kKeyLargoFCR0, regTemp);
if (keyLargoDeviceId == kKeyLargoDeviceId22) { regTemp = readRegUInt32(kKeyLargoMediaBay);
regTemp |= kKeyLargoMB0DevEnable;
writeRegUInt32(kKeyLargoMediaBay, regTemp);
}
regTemp = readRegUInt32(kKeyLargoFCR1);
regTemp |= kKeyLargoFCR1SleepBitsSet;
regTemp &= ~kKeyLargoFCR1SleepBitsClear;
writeRegUInt32(kKeyLargoFCR1, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR2);
regTemp |= kKeyLargoFCR2SleepBitsSet;
regTemp &= ~kKeyLargoFCR2SleepBitsClear;
writeRegUInt32(kKeyLargoFCR2, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR3);
if (keyLargoVersion >= kKeyLargoVersion2) {
regTemp |= kKeyLargoFCR3ShutdownPLL2X;
if (!restart) {
regTemp |= kKeyLargoFCR3ShutdownPLLTotal;
}
}
if (restart) {
regTemp |= kKeyLargoFCR3RestartBitsSet;
regTemp &= ~kKeyLargoFCR3RestartBitsClear;
} else {
regTemp |= kKeyLargoFCR3SleepBitsSet;
regTemp &= ~kKeyLargoFCR3SleepBitsClear;
}
writeRegUInt32(kKeyLargoFCR3, regTemp);
if (restart) {
regTemp = readRegUInt32(kKeyLargoFCR0);
regTemp &= ~kKeyLargoFCR0USBRefSuspend;
writeRegUInt32(kKeyLargoFCR0, regTemp);
IODelay(1000);
enableCells();
}
if (restart) {
kprintf("AppleKeyLargo::turnOffIO( --TRUE-- )\n");
}
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::turnOffPangeaIO(bool restart)
{
UInt32 regTemp;
IOInterruptState intState = NULL;
bool usingSCCA;
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
regTemp = readRegUInt32(kKeyLargoFCR0);
usingSCCA = (regTemp & kKeyLargoFCR0SccAEnable);
regTemp |= kPangeaFCR0SleepBitsSet;
regTemp &= ~kPangeaFCR0SleepBitsClear;
if(keepSCCenabledInSleep && usingSCCA)
{
regTemp |= (kKeyLargoFCR0SccAEnable | kKeyLargoFCR0SccCellEnable);
}
writeRegUInt32(kKeyLargoFCR0, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR1);
regTemp |= kPangeaFCR1SleepBitsSet;
if (hostIsMobile) regTemp &= ~kKeyLargoFCR1UIDEReset;
regTemp &= ~kPangeaFCR1SleepBitsClear;
writeRegUInt32(kKeyLargoFCR1, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR2);
regTemp |= kPangeaFCR2SleepBitsSet;
regTemp &= ~kPangeaFCR2SleepBitsClear;
writeRegUInt32(kKeyLargoFCR2, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR3);
regTemp |= kPangeaFCR3SleepBitsSet;
regTemp &= ~kPangeaFCR3SleepBitsClear;
writeRegUInt32(kKeyLargoFCR3, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR4);
regTemp |= kPangeaFCR4SleepBitsSet;
regTemp &= ~kPangeaFCR4SleepBitsClear;
writeRegUInt32(kKeyLargoFCR4, regTemp);
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::turnOffIntrepidIO(bool restart)
{
UInt32 regTemp;
IOInterruptState intState = NULL;
bool usingSCCA;
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
regTemp = readRegUInt32(kKeyLargoFCR0);
usingSCCA = (regTemp & kKeyLargoFCR0SccAEnable);
regTemp |= kIntrepidFCR0SleepBitsSet;
regTemp &= ~kIntrepidFCR0SleepBitsClear;
if(keepSCCenabledInSleep && usingSCCA)
{
regTemp |= (kKeyLargoFCR0SccAEnable | kKeyLargoFCR0SccCellEnable);
}
writeRegUInt32(kKeyLargoFCR0, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR1);
regTemp |= kIntrepidFCR1SleepBitsSet;
if (hostIsMobile) regTemp &= ~kKeyLargoFCR1EIDE0Reset;
regTemp &= ~kIntrepidFCR1SleepBitsClear;
writeRegUInt32(kKeyLargoFCR1, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR2);
regTemp |= kIntrepidFCR2SleepBitsSet;
regTemp &= ~kIntrepidFCR2SleepBitsClear;
writeRegUInt32(kKeyLargoFCR2, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR3);
regTemp |= kIntrepidFCR3SleepBitsSet;
regTemp &= ~kIntrepidFCR3SleepBitsClear;
writeRegUInt32(kKeyLargoFCR3, regTemp);
regTemp = readRegUInt32(kKeyLargoFCR4);
regTemp |= kIntrepidFCR4SleepBitsSet;
regTemp &= ~kIntrepidFCR4SleepBitsClear;
writeRegUInt32(kKeyLargoFCR4, regTemp);
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::powerMediaBay(bool powerOn, UInt8 powerDevice)
{
UInt32 regTemp;
UInt32 whichDevice = powerDevice;
IOInterruptState intState = NULL;
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog("AppleKeyLargo::powerMediaBay(%s) 0x%02x\n", (powerOn ? "TRUE" : "FALSE"), powerDevice);
#endif
if (mediaIsOn == powerOn) {
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog("AppleKeyLargo::powerMediaBay mbreg = 0x%08lx\n",readRegUInt32(kKeyLargoMediaBay));
#endif
return;
}
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 0 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp &= (~(kKeyLargoMB0DevReset));
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 1 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
if (powerOn) {
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 2 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp &= (~(kKeyLargoMB0DevPower));
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 3 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
IODelay(500);
}
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 4 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp &= (~(kKeyLargoMB0DevEnable));
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 5 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
IODelay(500);
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 6 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp |= (whichDevice << 11);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 7 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
IODelay(500);
if (!powerOn) {
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 8 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp |= kKeyLargoMB0DevPower;
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 9 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
}
else {
regTemp = readRegUInt32(kKeyLargoMediaBay);
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 10 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
regTemp |= kKeyLargoMB0DevReset;
#ifdef LOG_MEDIA_BAY_TRANSACTIONS
IOLog(" 11 AppleKeyLargo::powerMediaBay = 0x%08lx\n",regTemp);
#endif
writeRegUInt32(kKeyLargoMediaBay, regTemp);
IODelay(500);
regTemp = readRegUInt32(kKeyLargoFCR1);
regTemp |= kKeyLargoFCR1EIDE0Reset;
writeRegUInt32(kKeyLargoFCR1, regTemp);
}
IODelay(500);
mediaIsOn = powerOn;
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::powerWireless(bool powerOn)
{
IOInterruptState intState = NULL;
if (cardStatus.cardPower == powerOn)
return;
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
if (powerOn) {
writeRegUInt8(kKeyLargoExtIntGPIOBase + 10, cardStatus.wirelessCardReg[0]);
writeRegUInt8(kKeyLargoExtIntGPIOBase + 13, cardStatus.wirelessCardReg[1]);
writeRegUInt8(kKeyLargoGPIOBase + 13, cardStatus.wirelessCardReg[2]);
writeRegUInt8(kKeyLargoGPIOBase + 14, cardStatus.wirelessCardReg[3]);
writeRegUInt8(kKeyLargoGPIOBase + 15, cardStatus.wirelessCardReg[4]);
} else {
cardStatus.wirelessCardReg[0] = readRegUInt8(kKeyLargoExtIntGPIOBase + 10);
cardStatus.wirelessCardReg[1] = readRegUInt8(kKeyLargoExtIntGPIOBase + 13);
cardStatus.wirelessCardReg[2] = readRegUInt8(kKeyLargoGPIOBase + 13);
cardStatus.wirelessCardReg[3] = readRegUInt8(kKeyLargoGPIOBase + 14);
cardStatus.wirelessCardReg[4] = readRegUInt8(kKeyLargoGPIOBase + 15);
writeRegUInt8(kKeyLargoExtIntGPIOBase + 10, 0);
writeRegUInt8(kKeyLargoExtIntGPIOBase + 13, 0);
writeRegUInt8(kKeyLargoGPIOBase + 13, 0);
writeRegUInt8(kKeyLargoGPIOBase + 14, 0);
writeRegUInt8(kKeyLargoGPIOBase + 15, 0);
}
cardStatus.cardPower = powerOn;
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::setReferenceCounts (void)
{
UInt32 fcr0, fcr1, fcr3, fcr5 = 0;
bool chooseSCCA, chooseSCCB = false, chooseI2S0, chooseI2S1, chooseAudio;
clk31RefCount = 0;
clk45RefCount = 0;
clk49RefCount = 0;
clk32RefCount = 0;
fcr0 = readRegUInt32(kKeyLargoFCR0);
fcr1 = readRegUInt32(kKeyLargoFCR1);
fcr3 = readRegUInt32(kKeyLargoFCR3);
if (keyLargoDeviceId == kKeyLargoDeviceId22) { chooseSCCB = (fcr0 & kKeyLargoFCR0ChooseSCCB);
fcr5 = 0;
} else if (keyLargoDeviceId == kPangeaDeviceId25 ||
keyLargoDeviceId == kIntrepidDeviceId3e) {
chooseSCCB = true;
fcr5 = readRegUInt32(kKeyLargoFCR5);
}
chooseSCCA = (fcr0 & kKeyLargoFCR0ChooseSCCA);
chooseI2S1 = !chooseSCCA;
chooseAudio = (fcr1 & kKeyLargoFCR1ChooseAudio);
chooseI2S0 = !chooseAudio;
if (chooseSCCA && (fcr0 & kKeyLargoFCR0SccAEnable)) {
if (keyLargoDeviceId != kIntrepidDeviceId3e)
clk31RefCount++;
clk45RefCount++;
}
if (chooseSCCB && (fcr0 & kKeyLargoFCR0SccBEnable)) {
if (keyLargoDeviceId != kIntrepidDeviceId3e)
clk31RefCount++;
clk45RefCount++;
}
if (chooseI2S0 && (fcr1 & kKeyLargoFCR1I2S0Enable)) {
if (keyLargoDeviceId != kIntrepidDeviceId3e)
clk49RefCount++;
clk45RefCount++;
fI2SState[0] = true;
}
if (chooseI2S1 && (fcr1 & kKeyLargoFCR1I2S1Enable)) {
if (keyLargoDeviceId != kIntrepidDeviceId3e)
clk49RefCount++;
clk45RefCount++;
fI2SState[1] = true;
}
if (chooseAudio && (fcr1 & kKeyLargoFCR1AudioCellEnable)) {
if (keyLargoDeviceId != kIntrepidDeviceId3e)
clk49RefCount++;
clk45RefCount++;
}
if (fcr3 & kKeyLargoFCR3ViaClk16Enable)
if (keyLargoDeviceId == kKeyLargoDeviceId22 || ((keyLargoDeviceId == kPangeaDeviceId25) && (fcr5 & kPangeaFCR5ViaUseClk31)))
clk31RefCount++;
if (fcr5 & kPangeaFCR5Clk32Enable) {
if (keyLargoDeviceId == kPangeaDeviceId25) {
if ((fcr3 & kKeyLargoFCR3ViaClk16Enable) && (!(fcr5 & kPangeaFCR5ViaUseClk31)))
clk32RefCount++;
if (!(fcr5 & kPangeaFCR5SCCUseClk31)) {
if (chooseSCCA && (fcr0 & kKeyLargoFCR0SccAEnable))
clk32RefCount++;
if (chooseSCCB && (fcr0 & kKeyLargoFCR0SccBEnable))
clk32RefCount++;
}
} else
if (keyLargoDeviceId == kIntrepidDeviceId3e) {
if (fcr3 & kIntrepidFCR3ViaClk32Enable)
clk32RefCount++;
if (chooseSCCA && (fcr0 & kKeyLargoFCR0SccAEnable))
clk32RefCount++;
if (chooseSCCB && (fcr0 & kKeyLargoFCR0SccBEnable))
clk32RefCount++;
}
}
#define DEBUGREFCOUNTS 0
#if DEBUGREFCOUNTS
#define DLOG IOLog
#define PRINTBOOL(b) (b) ? "true" : "false"
#define PRINTNOT(n) (n) ? "" : "NOT"
DLOG ("AppleKeyLargo::setReferenceCounts - chooseSCCA %s and %s enabled\n",
PRINTBOOL(chooseSCCA), PRINTNOT(fcr0 & kKeyLargoFCR0SccAEnable));
DLOG ("AppleKeyLargo::setReferenceCounts - chooseSCCB %s and %s enabled\n",
PRINTBOOL(chooseSCCB), PRINTNOT(fcr0 & kKeyLargoFCR0SccBEnable));
DLOG ("AppleKeyLargo::setReferenceCounts - chooseI2S0 %s and %s enabled\n",
PRINTBOOL(chooseI2S0), PRINTNOT(fcr1 & kKeyLargoFCR1I2S0Enable));
DLOG ("AppleKeyLargo::setReferenceCounts - chooseI2S1 %s and %s enabled\n",
PRINTBOOL(chooseI2S1), PRINTNOT(fcr1 & kKeyLargoFCR1I2S1Enable));
DLOG ("AppleKeyLargo::setReferenceCounts - chooseAudio %s and %s enabled\n",
PRINTBOOL(chooseAudio), PRINTNOT(fcr1 & kKeyLargoFCR1AudioCellEnable));
DLOG ("AppleKeyLargo::setReferenceCounts - VIA %s enabled\n",
PRINTNOT(fcr3 & kKeyLargoFCR3ViaClk16Enable));
DLOG ("AppleKeyLargo::setReferenceCounts - clk31RefCount = %d, clk45RefCount = %d, clk49RefCount = %d\n",
clk31RefCount, clk45RefCount, clk49RefCount);
#endif
return;
}
void AppleKeyLargo::enableCells()
{
unsigned int debugFlags;
if (!PE_parse_boot_arg("debug", &debugFlags))
debugFlags = 0;
if( debugFlags & 0x18) {
safeWriteRegUInt32( (unsigned long)kKeyLargoFCR0, kKeyLargoFCR0SccCellEnable |
kKeyLargoFCR0SccAEnable |
kKeyLargoFCR0ChooseSCCA,
kKeyLargoFCR0SccCellEnable |
kKeyLargoFCR0SccAEnable |
kKeyLargoFCR0ChooseSCCA );
}
safeWriteRegUInt32( (unsigned long)kKeyLargoFCR2, kKeyLargoFCR2MPICEnable, kKeyLargoFCR2MPICEnable );
return;
}
void AppleKeyLargo::saveRegisterState(void)
{
saveKeyLargoState();
saveVIAState(savedKeyLargoState.savedVIAState);
powerWireless(false);
savedKeyLargoState.thisStateIsValid = true;
return;
}
void AppleKeyLargo::restoreRegisterState(void)
{
if (savedKeyLargoState.thisStateIsValid) {
restoreKeyLargoState();
restoreVIAState(savedKeyLargoState.savedVIAState);
powerWireless(true);
}
savedKeyLargoState.thisStateIsValid = false;
return;
}
void AppleKeyLargo::safeWriteRegUInt32(unsigned long offset, UInt32 mask, UInt32 data)
{
IOInterruptState intState = NULL;
if ( mutex != NULL )
intState = IOSimpleLockLockDisableInterrupt(mutex);
UInt32 currentReg = readRegUInt32(offset);
currentReg = (currentReg & ~mask) | (data & mask);
writeRegUInt32(offset, currentReg);
if ( mutex != NULL )
IOSimpleLockUnlockEnableInterrupt(mutex, intState);
return;
}
void AppleKeyLargo::initForPM (IOService *provider)
{
PMinit(); provider->joinPMtree(this);
#define kNumberOfPowerStates 3
static IOPMPowerState ourPowerStates[kNumberOfPowerStates] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, IOPMSoftSleep, IOPMSoftSleep, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 }
};
if (pm_vars != NULL)
registerPowerDriver(this, ourPowerStates, kNumberOfPowerStates);
return;
}
IOReturn AppleKeyLargo::setPowerState(unsigned long powerStateOrdinal, IOService* whatDevice)
{
if (powerStateOrdinal >= kNumberOfPowerStates)
return IOPMAckImplied;
if ( powerStateOrdinal == 0 ) {
kprintf("KeyLargo would be powered off here\n");
}
if ( powerStateOrdinal == 1 ) {
kprintf("KeyLargo would be powered on here\n");
}
if(watchDogTimer)
watchDogTimer->setSleeping(powerStateOrdinal < 2);
return IOPMAckImplied;
}
void AppleKeyLargo::saveKeyLargoState(void)
{
KeyLargoMPICState* savedKeyLargoMPICState;
KeyLargoGPIOState* savedKeyLargoGPIOState;
KeyLargoConfigRegistersState* savedKeyLargoConfigRegistersState;
KeyLargoDBDMAState* savedKeyLargoDBDMAState;
KeyLargoAudioState* savedKeyLargoAudioState;
KeyLargoI2SState* savedKeyLargoI2SState;
UInt32 channelOffset;
int i;
UInt8* keyLargoBaseAddr = (UInt8*)keyLargoBaseAddress;
UInt8* mpicBaseAddr = (UInt8*)keyLargoBaseAddress + kKeyLargoMPICBaseOffset;
savedKeyLargoGPIOState = &savedKeyLargoState.savedGPIOState;
savedKeyLargoGPIOState->gpioLevels[0] = *(UInt32 *)(keyLargoBaseAddr + kKeyLargoGPIOLevels0);
savedKeyLargoGPIOState->gpioLevels[1] = *(UInt32 *)(keyLargoBaseAddr + kKeyLargoGPIOLevels1);
for (i = 0; i < kKeyLargoExtIntGPIOCount; i++)
{
savedKeyLargoGPIOState->extIntGPIO[i] = *(UInt8 *)(keyLargoBaseAddr + kKeyLargoExtIntGPIORegBase + i);
}
for (i = 0; i < kKeyLargoGPIOCount; i++)
{
savedKeyLargoGPIOState->gpio[i] = *(UInt8 *)(keyLargoBaseAddr + kKeyLargoGPIOBase + i);
}
savedKeyLargoAudioState = &savedKeyLargoState.savedAudioState;
for (i = 0, channelOffset = 0; i < kKeyLargoAudioRegisterCount; i++, channelOffset += kKeyLargoAudioRegisterStride)
{
savedKeyLargoAudioState->audio[i] = *(UInt32 *) (keyLargoBaseAddr + kKeyLargoAudioBaseOffset + channelOffset);
}
savedKeyLargoI2SState = &savedKeyLargoState.savedI2SState;
for (i = 0, channelOffset = 0; i < kKeyLargoI2SRegisterCount; i++, channelOffset += kKeyLargoI2SRegisterStride)
{
savedKeyLargoI2SState->i2s[i] = *(UInt32 *) (keyLargoBaseAddr + kKeyLargoI2S0BaseOffset + channelOffset);
savedKeyLargoI2SState->i2s[i + 1] = *(UInt32 *) (keyLargoBaseAddr + kKeyLargoI2S1BaseOffset + channelOffset);
}
savedKeyLargoDBDMAState = &savedKeyLargoState.savedDBDMAState;
for (i = 0, channelOffset = 0; i < kKeyLargoDBDMAChannelCount; i++, channelOffset += kKeyLargoDBDMAChannelStride)
{
volatile DBDMAChannelRegisters* currentChannel;
currentChannel = (volatile DBDMAChannelRegisters *) (keyLargoBaseAddr + kKeyLargoDBDMABaseOffset + channelOffset);
savedKeyLargoDBDMAState->dmaChannel[i].commandPtrLo = IOGetDBDMACommandPtr(currentChannel);
savedKeyLargoDBDMAState->dmaChannel[i].interruptSelect = IOGetDBDMAInterruptSelect(currentChannel);
savedKeyLargoDBDMAState->dmaChannel[i].branchSelect = IOGetDBDMABranchSelect(currentChannel);
savedKeyLargoDBDMAState->dmaChannel[i].waitSelect = IOGetDBDMAWaitSelect(currentChannel);
}
savedKeyLargoConfigRegistersState = &savedKeyLargoState.savedConfigRegistersState;
if(keyLargoDeviceId == kKeyLargoDeviceId22)
{
savedKeyLargoConfigRegistersState->mediaBay = *(UInt32 *)(keyLargoBaseAddr + kKeyLargoMediaBay);
for (i = 0; i < kKeyLargoFCRCount; i++)
{
savedKeyLargoConfigRegistersState->featureControl[i] = ((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i];
}
} else if(keyLargoDeviceId == kPangeaDeviceId25)
{
for (i = 0; i < kPangeaFCRCount; i++)
{
savedKeyLargoConfigRegistersState->featureControl[i] = ((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i];
}
} else
{
for (i = 0; i < kIntrepidFCRCount; i++)
{
savedKeyLargoConfigRegistersState->featureControl[i] = ((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i];
}
}
savedKeyLargoMPICState = &savedKeyLargoState.savedMPICState;
savedKeyLargoMPICState->mpicGlobal0 = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICGlobal0);
savedKeyLargoMPICState->mpicIPI[0] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI0);
savedKeyLargoMPICState->mpicIPI[1] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI1);
savedKeyLargoMPICState->mpicIPI[2] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI2);
savedKeyLargoMPICState->mpicIPI[3] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI3);
savedKeyLargoMPICState->mpicSpuriousVector = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICSpuriousVector);
savedKeyLargoMPICState->mpicTimerFrequencyReporting = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICTimeFreq);
UInt32 timerAddresses[kKeyLargoMPICTimerCount] = {kKeyLargoMPICTimerBase0,
kKeyLargoMPICTimerBase1,
kKeyLargoMPICTimerBase2,
kKeyLargoMPICTimerBase3};
UInt32 *MPICRegPtr;
MPICTimers *SavedMPICReg;
for (i = 0; i < kKeyLargoMPICTimerCount; i++)
{
SavedMPICReg = &savedKeyLargoMPICState->mpicTimers[i];
MPICRegPtr = (UInt32 *)(mpicBaseAddr + timerAddresses[i] - 0x10);
SavedMPICReg->currentCountRegister = *(MPICRegPtr + 0);
SavedMPICReg->baseCountRegister = *(MPICRegPtr + 0x4);
SavedMPICReg->vectorPriorityRegister = *(MPICRegPtr + 0x8);
SavedMPICReg->destinationRegister = *(MPICRegPtr + 0xc);
#if 1
kprintf("&KeyLargoMPICTimerBase0: %p data: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
MPICRegPtr, *(MPICRegPtr + 0), *(MPICRegPtr + 4), *(MPICRegPtr + 8), *(MPICRegPtr + 12));
kprintf("&savedKeyLargoMPICState->mpicTimers[0]: %p data: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
SavedMPICReg, SavedMPICReg->currentCountRegister, SavedMPICReg->baseCountRegister,
SavedMPICReg->vectorPriorityRegister, SavedMPICReg->destinationRegister);
#endif
}
for (i = 0; i < kKeyLargoMPICVectorsCount; i++)
{
savedKeyLargoMPICState->mpicInterruptSourceVectorPriority[i] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIntSrcVectPriBase + i * kKeyLargoMPICIntSrcSize) & (~0x00000040);
savedKeyLargoMPICState->mpicInterruptSourceDestination[i] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIntSrcDestBase + i * kKeyLargoMPICIntSrcSize);
}
savedKeyLargoMPICState->mpicCurrentTaskPriorities[0] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP0CurrTaskPriority);
savedKeyLargoMPICState->mpicCurrentTaskPriorities[1] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP1CurrTaskPriority);
savedKeyLargoMPICState->mpicCurrentTaskPriorities[2] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP2CurrTaskPriority);
savedKeyLargoMPICState->mpicCurrentTaskPriorities[3] = *(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP3CurrTaskPriority);
return;
}
void AppleKeyLargo::restoreKeyLargoState(void)
{
KeyLargoMPICState* savedKeyLargoMPICState;
KeyLargoGPIOState* savedKeyLargoGPIOState;
KeyLargoConfigRegistersState* savedKeyLargoConfigRegistersState;
KeyLargoDBDMAState* savedKeyLargoDBDMAState;
KeyLargoAudioState* savedKeyLargoAudioState;
KeyLargoI2SState* savedKeyLargoI2SState;
UInt32 channelOffset;
int i;
UInt8* keyLargoBaseAddr = (UInt8*)keyLargoBaseAddress;
UInt8* mpicBaseAddr = (UInt8*)keyLargoBaseAddress + kKeyLargoMPICBaseOffset;
savedKeyLargoMPICState = &savedKeyLargoState.savedMPICState;
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICGlobal0) = savedKeyLargoMPICState->mpicGlobal0;
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI0) = savedKeyLargoMPICState->mpicIPI[0];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI1) = savedKeyLargoMPICState->mpicIPI[1];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI2) = savedKeyLargoMPICState->mpicIPI[2];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIPI3) = savedKeyLargoMPICState->mpicIPI[3];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICSpuriousVector) = savedKeyLargoMPICState->mpicSpuriousVector;
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICTimeFreq) = savedKeyLargoMPICState->mpicTimerFrequencyReporting;
eieio();
UInt32 timerAddresses[kKeyLargoMPICTimerCount] = {kKeyLargoMPICTimerBase0,
kKeyLargoMPICTimerBase1,
kKeyLargoMPICTimerBase2,
kKeyLargoMPICTimerBase3};
UInt32 *MPICRegPtr;
MPICTimers *savedMPICReg;
for (i = 0; i < kKeyLargoMPICTimerCount; i++)
{
savedMPICReg = &savedKeyLargoMPICState->mpicTimers[i];
MPICRegPtr = (UInt32 *)(mpicBaseAddr + timerAddresses[i] - 0x10);
*(MPICRegPtr + 0x0) = savedMPICReg->currentCountRegister; eieio();
*(MPICRegPtr + 0x4) = savedMPICReg->baseCountRegister; eieio();
*(MPICRegPtr + 0x8) = savedMPICReg->vectorPriorityRegister; eieio();
*(MPICRegPtr + 0xc) = savedMPICReg->destinationRegister; eieio();
}
for (i = 0; i < kKeyLargoMPICVectorsCount; i++)
{
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIntSrcVectPriBase + i * kKeyLargoMPICIntSrcSize) = savedKeyLargoMPICState->mpicInterruptSourceVectorPriority[i];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICIntSrcDestBase + i * kKeyLargoMPICIntSrcSize) = savedKeyLargoMPICState->mpicInterruptSourceDestination[i];
eieio();
}
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP0CurrTaskPriority) = savedKeyLargoMPICState->mpicCurrentTaskPriorities[0];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP1CurrTaskPriority) = savedKeyLargoMPICState->mpicCurrentTaskPriorities[1];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP2CurrTaskPriority) = savedKeyLargoMPICState->mpicCurrentTaskPriorities[2];
eieio();
*(UInt32 *)(mpicBaseAddr + kKeyLargoMPICP3CurrTaskPriority) = savedKeyLargoMPICState->mpicCurrentTaskPriorities[3];
eieio();
savedKeyLargoConfigRegistersState = &savedKeyLargoState.savedConfigRegistersState;
if (keyLargoDeviceId == kKeyLargoDeviceId22)
{
*(UInt32 *)(keyLargoBaseAddr + kKeyLargoMediaBay) = savedKeyLargoConfigRegistersState->mediaBay;
eieio();
for (i = 0; i < kKeyLargoFCRCount; i++)
{
((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i] = savedKeyLargoConfigRegistersState->featureControl[i];
eieio();
}
} else if(keyLargoDeviceId == kPangeaDeviceId25)
{
for (i = 0; i < kPangeaFCRCount; i++)
{
((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i] = savedKeyLargoConfigRegistersState->featureControl[i];
eieio();
}
} else
{
for (i = 0; i < kIntrepidFCRCount; i++)
{
((UInt32 *)(keyLargoBaseAddr + kKeyLargoFCR0))[i] = savedKeyLargoConfigRegistersState->featureControl[i];
eieio();
}
}
IODelay(250);
savedKeyLargoDBDMAState = &savedKeyLargoState.savedDBDMAState;
for (i = 0, channelOffset = 0; i < kKeyLargoDBDMAChannelCount; i++, channelOffset += kKeyLargoDBDMAChannelStride)
{
volatile DBDMAChannelRegisters* currentChannel;
currentChannel = (volatile DBDMAChannelRegisters *) (keyLargoBaseAddr + kKeyLargoDBDMABaseOffset + channelOffset);
IODBDMAReset((IODBDMAChannelRegisters*)currentChannel);
IOSetDBDMACommandPtr(currentChannel, savedKeyLargoDBDMAState->dmaChannel[i].commandPtrLo);
IOSetDBDMAInterruptSelect(currentChannel, savedKeyLargoDBDMAState->dmaChannel[i].interruptSelect);
IOSetDBDMABranchSelect(currentChannel, savedKeyLargoDBDMAState->dmaChannel[i].branchSelect);
IOSetDBDMAWaitSelect(currentChannel, savedKeyLargoDBDMAState->dmaChannel[i].waitSelect);
}
savedKeyLargoAudioState = &savedKeyLargoState.savedAudioState;
for (i = 0, channelOffset = 0; i < kKeyLargoAudioRegisterCount; i++, channelOffset += kKeyLargoAudioRegisterStride)
{
*(UInt32 *) (keyLargoBaseAddr + kKeyLargoAudioBaseOffset + channelOffset) = savedKeyLargoAudioState->audio[i];
eieio();
}
savedKeyLargoI2SState = &savedKeyLargoState.savedI2SState;
for (i = 0, channelOffset = 0; i < kKeyLargoI2SRegisterCount; i++, channelOffset += kKeyLargoI2SRegisterStride)
{
*(UInt32 *) (keyLargoBaseAddr + kKeyLargoI2S0BaseOffset + channelOffset) = savedKeyLargoI2SState->i2s[i];
eieio();
*(UInt32 *) (keyLargoBaseAddr + kKeyLargoI2S1BaseOffset + channelOffset) = savedKeyLargoI2SState->i2s[i + 1];
eieio();
}
savedKeyLargoGPIOState = &savedKeyLargoState.savedGPIOState;
*(UInt32 *)(keyLargoBaseAddr + kKeyLargoGPIOLevels0) = savedKeyLargoGPIOState->gpioLevels[0];
eieio();
*(UInt32 *)(keyLargoBaseAddr + kKeyLargoGPIOLevels1) = savedKeyLargoGPIOState->gpioLevels[1];
eieio();
for (i = 0; i < kKeyLargoExtIntGPIOCount; i++)
{
*(UInt8 *)(keyLargoBaseAddr + kKeyLargoExtIntGPIORegBase + i) = savedKeyLargoGPIOState->extIntGPIO[i];
eieio();
}
for (i = 0; i < kKeyLargoGPIOCount; i++)
{
*(UInt8 *)(keyLargoBaseAddr + kKeyLargoGPIOBase + i) = savedKeyLargoGPIOState->gpio[i];
eieio();
}
return;
}
IOReturn AppleKeyLargo::callPlatformFunction(const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4)
{
if ((fPlatformFuncArray) && (gPreserveIODeviceTree == TRUE)) {
UInt32 i;
IOPlatformFunction *pfFunc;
UInt32 count = fPlatformFuncArray->getCount();
for (i = 0; i < count; i++) {
if (pfFunc = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i))) {
if (pfFunc->platformFunctionMatch (functionName, kIOPFFlagOnDemand, NULL)) {
return (performFunction (pfFunc, param1, param2, param3, param4) ? kIOReturnSuccess : kIOReturnBadArgument);
}
}
}
}
if (functionName == keyLargo_resetUniNEthernetPhy)
{
resetUniNEthernetPhy();
return kIOReturnSuccess;
}
if (functionName == keyLargo_restoreRegisterState)
{
restoreRegisterState();
return kIOReturnSuccess;
}
if (functionName == keyLargo_syncTimeBase)
{
syncTimeBase();
return kIOReturnSuccess;
}
if (functionName == keyLargo_recalibrateBusSpeeds)
{
recalibrateBusSpeeds();
return kIOReturnSuccess;
}
if (functionName == keyLargo_saveRegisterState)
{
saveRegisterState();
return kIOReturnSuccess;
}
if (functionName == keyLargo_turnOffIO)
{
if (keyLargoDeviceId == kKeyLargoDeviceId22)
turnOffKeyLargoIO((bool)param1);
else if (keyLargoDeviceId == kPangeaDeviceId25)
turnOffPangeaIO((bool)param1);
else
turnOffIntrepidIO((bool)param1);
return kIOReturnSuccess;
}
if (functionName == keyLargo_writeRegUInt8)
{
writeRegUInt8(*(unsigned long *)param1, (UInt32)param2);
return kIOReturnSuccess;
}
if (functionName == keyLargo_safeWriteRegUInt8)
{
safeWriteRegUInt8((unsigned long)param1, (UInt32)param2, (UInt32)param3);
return kIOReturnSuccess;
}
if (functionName == keyLargo_safeReadRegUInt8)
{
UInt8 *returnval = (UInt8 *)param2;
*returnval = safeReadRegUInt8((unsigned long)param1);
return kIOReturnSuccess;
}
if (functionName == keyLargo_safeWriteRegUInt32)
{
safeWriteRegUInt32((unsigned long)param1, (UInt32)param2, (UInt32)param3);
return kIOReturnSuccess;
}
if (functionName == keyLargo_safeReadRegUInt32)
{
UInt32 *returnval = (UInt32 *)param2;
*returnval = safeReadRegUInt32((unsigned long)param1);
return kIOReturnSuccess;
}
if (functionName == keyLargo_powerMediaBay)
{
bool powerOn = (param1 != NULL);
if (keyLargoDeviceId == kPangeaDeviceId25 || keyLargoDeviceId == kIntrepidDeviceId3e)
return kIOReturnUnsupported;
powerMediaBay(powerOn, (UInt32)param2);
return kIOReturnSuccess;
}
if (functionName->isEqualTo("EnableSCC"))
{
EnableSCC((bool)param1, (UInt32)param2, (bool)param3);
return kIOReturnSuccess;
}
if (functionName->isEqualTo("PowerModem"))
{
PowerModem((bool)param1);
return kIOReturnSuccess;
}
if (functionName->isEqualTo("ModemResetLow"))
{
ModemResetLow();
return kIOReturnSuccess;
}
if (functionName->isEqualTo("ModemResetHigh"))
{
ModemResetHigh();
return kIOReturnSuccess;
}
if (functionName == keyLargo_getHostKeyLargo)
{
UInt32 *returnVal = (UInt32 *)param1;
*returnVal = (UInt32) gHostKeyLargo;
return kIOReturnSuccess;
}
if (functionName == keyLargo_powerI2S)
{
PowerI2S((bool)param1, (UInt32)param2);
return kIOReturnSuccess;
}
if (functionName == keyLargo_setPowerSupply)
{
return SetPowerSupply((bool)param1);
}
if (functionName->isEqualTo("keepSCCEnabledInSleep"))
{
keepSCCenabledInSleep = (bool)param1;
return kIOReturnSuccess;
}
if (gPreserveIODeviceTree == TRUE) {
if (functionName == mac_io_publishChildren) {
if (publishChildren((IOService *)param1,(IOService *(*)(IORegistryEntry *))param2)) {
return kIOReturnSuccess;
}
return kIOReturnError;
}
if (functionName == mac_io_publishChild) {
if (publishChild((IOService *)param1, (IORegistryEntry *)param2,
(IOService *(*)(IORegistryEntry *))param3)) {
return kIOReturnSuccess;
}
return kIOReturnError;
}
}
if (functionName == keyLargo_EnableI2SModem)
{
EnableI2SModem((bool)param1);
return kIOReturnSuccess;
}
return super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4);
}
void AppleKeyLargo::EnableSCC(bool state, UInt8 device, bool type)
{
UInt32 bitsToSet, bitsToClear, currentReg, currentReg3, currentReg5;
IOInterruptState intState = NULL;
bitsToSet = bitsToClear = currentReg = currentReg3 = currentReg5 = 0;
if (state) { if(device == 0) { bitsToSet = kKeyLargoFCR0SccCellEnable;
if(type) { bitsToClear |= kKeyLargoFCR0ChooseSCCA; bitsToClear |= kKeyLargoFCR0SccAEnable; }
else { bitsToSet |= kKeyLargoFCR0ChooseSCCA; bitsToSet |= kKeyLargoFCR0SccAEnable; }
} else if(device == 1) { if (keyLargoDeviceId == kKeyLargoDeviceId22) { bitsToSet = kKeyLargoFCR0SccCellEnable; bitsToSet |= kKeyLargoFCR0SccBEnable; if(type) { bitsToSet |= kKeyLargoFCR0IRDAClk19Enable; bitsToSet |= kKeyLargoFCR0IRDAClk32Enable; bitsToSet |= kKeyLargoFCR0IRDAEnable; bitsToClear |= kKeyLargoFCR0IRDAFastCon; bitsToClear |= kKeyLargoFCR0IRDADefault0; bitsToClear |= kKeyLargoFCR0IRDADefault1; bitsToSet |= kKeyLargoFCR0UseIRSource1; bitsToClear |= kKeyLargoFCR0UseIRSource2; bitsToClear |= kKeyLargoFCR0HighBandFor1MB; bitsToClear |= kKeyLargoFCR0ChooseSCCB; } else bitsToSet |= kKeyLargoFCR0ChooseSCCB; } else
return; } else
return;
if ( mutex != NULL ) intState = IOSimpleLockLockDisableInterrupt(mutex);
currentReg = readRegUInt32( (UInt32)kKeyLargoFCR0);
if (!(currentReg & bitsToSet & (kKeyLargoFCR0SccAEnable | kKeyLargoFCR0SccBEnable))) {
currentReg3 = readRegUInt32( (UInt32)kKeyLargoFCR3);
if ((keyLargoDeviceId != kIntrepidDeviceId3e) && (!(clk31RefCount++))) {
currentReg3 |= kKeyLargoFCR3Clk31Enable; }
if (!(clk45RefCount++)) {
currentReg3 |= kKeyLargoFCR3Clk45Enable; }
writeRegUInt32( (UInt32)kKeyLargoFCR3, (UInt32)currentReg3 );
if (keyLargoDeviceId == kPangeaDeviceId25) {
currentReg5 = readRegUInt32( (UInt32)kKeyLargoFCR5);
if (!(currentReg5 & kPangeaFCR5SCCUseClk31) && !(clk32RefCount++)) {
currentReg5 |= kPangeaFCR5Clk32Enable; writeRegUInt32( (UInt32)kKeyLargoFCR5, (UInt32)currentReg5 );
}
}
if (keyLargoDeviceId == kIntrepidDeviceId3e) {
currentReg5 = readRegUInt32( (UInt32)kKeyLargoFCR5);
if (!(clk32RefCount++)) {
currentReg5 |= kPangeaFCR5Clk32Enable; writeRegUInt32( (UInt32)kKeyLargoFCR5, (UInt32)currentReg5 );
}
}
}
currentReg |= bitsToSet;
currentReg &= ~bitsToClear;
writeRegUInt32( (UInt32)kKeyLargoFCR0, (UInt32)currentReg );
if(device == 1 && (type) && keyLargoDeviceId == kKeyLargoDeviceId22) { currentReg |= kKeyLargoFCR0IRDASWReset;
writeRegUInt32( (UInt32)kKeyLargoFCR0, (UInt32)currentReg );
IODelay(15000);
currentReg &= ~kKeyLargoFCR0IRDASWReset;
writeRegUInt32( (UInt32)kKeyLargoFCR0, (UInt32)currentReg );
}
if ( mutex != NULL ) IOSimpleLockUnlockEnableInterrupt(mutex, intState);
#if DEBUGREFCOUNTS
DLOG ("AppleKeyLargo::EnableSCC (enable) - clk31RefCount = %d, clk45RefCount = %d, clk49RefCount = %d\n",
clk31RefCount, clk45RefCount, clk49RefCount);
#endif
} else { if(device == 0)
bitsToClear |= kKeyLargoFCR0SccAEnable;
else if(device == 1) {
if (keyLargoDeviceId == kKeyLargoDeviceId22) { bitsToClear |= kKeyLargoFCR0SccBEnable; if (type) {
bitsToClear |= kKeyLargoFCR0IRDAClk19Enable; bitsToClear |= kKeyLargoFCR0IRDAClk32Enable; bitsToClear |= kKeyLargoFCR0IRDAEnable; bitsToClear |= kKeyLargoFCR0IRDAFastCon; bitsToClear |= kKeyLargoFCR0IRDADefault0; bitsToClear |= kKeyLargoFCR0IRDADefault1; bitsToClear |= kKeyLargoFCR0UseIRSource1; bitsToClear |= kKeyLargoFCR0UseIRSource2; bitsToClear |= kKeyLargoFCR0HighBandFor1MB; }
} else
return; } else
return;
if ( mutex != NULL ) intState = IOSimpleLockLockDisableInterrupt(mutex);
currentReg = readRegUInt32( (UInt32)kKeyLargoFCR0);
if (!(currentReg & ~bitsToClear & (kKeyLargoFCR0SccAEnable | kKeyLargoFCR0SccBEnable))) {
bitsToClear |= kKeyLargoFCR0SccCellEnable;
}
if (currentReg & bitsToClear & (kKeyLargoFCR0SccAEnable | kKeyLargoFCR0SccBEnable)) {
currentReg3 = readRegUInt32( (UInt32)kKeyLargoFCR3);
if ((keyLargoDeviceId != kIntrepidDeviceId3e) && clk31RefCount && !(--clk31RefCount)) {
currentReg3 &= ~kKeyLargoFCR3Clk31Enable; }
if (clk45RefCount && !(--clk45RefCount)) {
currentReg3 &= ~kKeyLargoFCR3Clk45Enable; }
writeRegUInt32( (UInt32)kKeyLargoFCR3, (UInt32)currentReg3 );
if (keyLargoDeviceId == kPangeaDeviceId25) {
currentReg5 = readRegUInt32( (UInt32)kKeyLargoFCR5);
if (!(currentReg5 & kPangeaFCR5SCCUseClk31) && clk32RefCount && !(--clk32RefCount)) {
currentReg5 &= ~kPangeaFCR5Clk32Enable ; writeRegUInt32( (UInt32)kKeyLargoFCR5, (UInt32)currentReg5 );
}
}
if (keyLargoDeviceId == kIntrepidDeviceId3e) {
currentReg5 = readRegUInt32( (UInt32)kKeyLargoFCR5);
if ( clk32RefCount && !(--clk32RefCount)) {
currentReg5 &= ~kPangeaFCR5Clk32Enable; writeRegUInt32( (UInt32)kKeyLargoFCR5, (UInt32)currentReg5 );
}
}
}
currentReg |= bitsToSet;
currentReg &= ~bitsToClear;
writeRegUInt32( (UInt32)kKeyLargoFCR0, (UInt32)currentReg );
if ( mutex != NULL ) IOSimpleLockUnlockEnableInterrupt(mutex, intState);
#if DEBUGREFCOUNTS
DLOG ("AppleKeyLargo::EnableSCC (disable) - clk31RefCount = %d, clk45RefCount = %d, clk49RefCount = %d\n",
clk31RefCount, clk45RefCount, clk49RefCount);
#endif
}
return;
}
void AppleKeyLargo::PowerModem(bool state)
{
if(fHasSoftModem) {
if(state) {
safeWriteRegUInt32 (kKeyLargoFCR1, kKeyLargoFCR1I2S1ClkEnable,
kKeyLargoFCR1I2S1ClkEnable);
}
else {
safeWriteRegUInt32 (kKeyLargoFCR1, kKeyLargoFCR1I2S1ClkEnable, 0);
}
}
if (keyLargoDeviceId == kPangeaDeviceId25 || keyLargoDeviceId == kIntrepidDeviceId3e) { if (state) {
writeRegUInt8(kKeyLargoGPIOBase + 0x2, 0x4); eieio();
} else {
writeRegUInt8(kKeyLargoGPIOBase + 0x2, 0x5); eieio();
}
} else if (keyLargoDeviceId == kKeyLargoDeviceId22) { if (state)
safeWriteRegUInt32( (unsigned long)kKeyLargoFCR2, (UInt32)kKeyLargoFCR2AltDataOut, (UInt32)(0) );
else
safeWriteRegUInt32( (unsigned long)kKeyLargoFCR2, (UInt32)kKeyLargoFCR2AltDataOut, (UInt32)kKeyLargoFCR2AltDataOut );
}
return;
}
void AppleKeyLargo::ModemResetLow()
{
*(UInt8*)(keyLargoBaseAddress + kKeyLargoGPIOBase + 0x3) |= 0x04; eieio();
*(UInt8*)(keyLargoBaseAddress + kKeyLargoGPIOBase + 0x3) &= ~0x01; eieio();
return;
}
void AppleKeyLargo::ModemResetHigh()
{
*(UInt8*)(keyLargoBaseAddress + kKeyLargoGPIOBase + 0x3) |= 0x04; eieio();
*(UInt8*)(keyLargoBaseAddress + kKeyLargoGPIOBase + 0x3) |= 0x01; eieio();
return;
}
void AppleKeyLargo::PowerI2S (bool powerOn, UInt32 cellNum)
{
UInt32 fcr1Bits, fcr3Bits;
if (cellNum == 0) {
fcr1Bits = kKeyLargoFCR1I2S0CellEnable |
kKeyLargoFCR1I2S0ClkEnable |
kKeyLargoFCR1I2S0Enable;
fcr3Bits = kKeyLargoFCR3I2S0Clk18Enable;
} else if (cellNum == 1) {
fcr1Bits = kKeyLargoFCR1I2S1CellEnable |
kKeyLargoFCR1I2S1ClkEnable |
kKeyLargoFCR1I2S1Enable;
fcr3Bits = kKeyLargoFCR3I2S1Clk18Enable;
} else
return;
if(fI2SState[cellNum] == powerOn)
return;
if (powerOn) {
if (!(clk45RefCount++)) {
fcr3Bits |= kKeyLargoFCR3Clk45Enable; }
if(keyLargoDeviceId != kIntrepidDeviceId3e)
{
if (!(clk49RefCount++))
{
fcr3Bits |= kKeyLargoFCR3Clk49Enable; }
}
safeWriteRegUInt32 (kKeyLargoFCR1, fcr1Bits, fcr1Bits);
safeWriteRegUInt32 (kKeyLargoFCR3, fcr3Bits, fcr3Bits);
} else {
if (clk45RefCount && !(--clk45RefCount)) {
fcr3Bits |= kKeyLargoFCR3Clk45Enable; }
if(keyLargoDeviceId != kIntrepidDeviceId3e)
{
if (clk49RefCount && !(--clk49RefCount))
{
fcr3Bits |= kKeyLargoFCR3Clk49Enable; }
}
safeWriteRegUInt32 (kKeyLargoFCR1, fcr1Bits, 0);
safeWriteRegUInt32 (kKeyLargoFCR3, fcr3Bits, 0);
}
fI2SState[cellNum] = powerOn;
return;
}
IOReturn AppleKeyLargo::SetPowerSupply (bool powerHi)
{
char value;
UInt32 delay;
OSIterator *childIterator;
IORegistryEntry *childEntry;
OSData *regData;
if (gPreserveIODeviceTree == TRUE) { IORegistryIterator *recursiveChildIterator;
IORegistryEntry *recursiveChildEntry = IORegistryEntry::fromPath("mac-io/gpio", gIODTPlane);
if (!keyLargoCPUVCoreSelectGPIO) {
if ((recursiveChildIterator = IORegistryIterator::iterateOver (recursiveChildEntry, gIOServicePlane, kIORegistryIterateRecursively)) != NULL) {
while ((recursiveChildEntry = (IORegistryEntry *)(recursiveChildIterator->getNextObject ())) != NULL) {
if (!strcmp ("cpu-vcore-select", recursiveChildEntry->getName(gIOServicePlane))) {
regData = OSDynamicCast( OSData, recursiveChildEntry->getProperty( "reg" ));
if (regData) {
keyLargoCPUVCoreSelectGPIO = *(UInt32 *) regData->getBytesNoCopy();
break;
}
}
}
recursiveChildIterator->release();
}
if (!keyLargoCPUVCoreSelectGPIO) return (kIOReturnUnsupported);
}
}
else {
if (!keyLargoCPUVCoreSelectGPIO) {
if ((childIterator = getChildIterator (gIOServicePlane)) != NULL) {
while ((childEntry = (IORegistryEntry *)(childIterator->getNextObject ())) != NULL) {
if (!strcmp ("cpu-vcore-select", childEntry->getName(gIOServicePlane))) {
regData = OSDynamicCast( OSData, childEntry->getProperty( "reg" ));
if (regData) {
keyLargoCPUVCoreSelectGPIO = *(UInt32 *) regData->getBytesNoCopy();
break;
}
}
}
childIterator->release();
}
if (!keyLargoCPUVCoreSelectGPIO) return (kIOReturnUnsupported);
}
}
value = kKeyLargoGPIOOutputEnable | (powerHi ? kKeyLargoGPIOData : 0);
writeRegUInt8 (keyLargoCPUVCoreSelectGPIO, value);
delay = 200;
assert_wait_timeout((event_t)assert_wait_timeout, THREAD_UNINT, delay, NSEC_PER_USEC);
thread_block(0);
return (kIOReturnSuccess);
}
void AppleKeyLargo::resetUniNEthernetPhy(void)
{
writeRegUInt8(kKeyLargoGPIOBase + 16, kKeyLargoGPIOOutputEnable);
IOSleep(10);
writeRegUInt8(kKeyLargoGPIOBase + 16, kKeyLargoGPIOData);
IOSleep(10);
return;
}
void AppleKeyLargo::EnableI2SModem(bool enable)
{
UInt32 fcr0ToClear = kKeyLargoFCR0ChooseSCCA | kKeyLargoFCR0SccAEnable;
UInt32 fcr1ToSet = kKeyLargoFCR1I2S1CellEnable | kKeyLargoFCR1I2S1Enable;
UInt32 fcr3ToSet = kKeyLargoFCR3I2S1Clk18Enable;
if(enable) {
safeWriteRegUInt32 (kKeyLargoFCR0, fcr0ToClear, 0);
safeWriteRegUInt32 (kKeyLargoFCR3, fcr3ToSet, fcr3ToSet);
safeWriteRegUInt32 (kKeyLargoFCR1, fcr1ToSet, fcr1ToSet);
}
else {
safeWriteRegUInt32 (kKeyLargoFCR0, fcr0ToClear, fcr0ToClear);
safeWriteRegUInt32 (kKeyLargoFCR3, fcr3ToSet, 0);
safeWriteRegUInt32 (kKeyLargoFCR1, fcr1ToSet, 0);
}
}
void AppleKeyLargo::processNub(IOService * nub)
{
super::processNub(nub);
if(keyLargoDeviceId == kIntrepidDeviceId3e) {
const char * name = nub->getName();
if( strcmp("via-pmu", name) == 0) {
static UInt8 data[] = {0x06, 0x0B, 0x01, 0x41, 0x4e, 0x44, 0x59};
OSData *existing = OSDynamicCast(OSData, nub->getProperty("pmu-info"));
if(existing)
existing->appendBytes(data, sizeof(data));
else
nub->setProperty("pmu-info", data, sizeof(data));
}
else if(strcmp("power-mgt", name) == 0)
nub->removeProperty("clock-spreading-info");
}
if (gPreserveIODeviceTree == TRUE)
nub->setProperty("preserveIODeviceTree", true);
}
void AppleKeyLargo::publishBelow( IORegistryEntry * root )
{
if (gPreserveIODeviceTree == TRUE)
publishChildren( this );
else
super::publishBelow( root );
}
IOService * AppleKeyLargo::createNub( IORegistryEntry * from )
{
IOService * nub;
if (gPreserveIODeviceTree == true) {
nub = new AppleK2Device;
if( nub && !nub->init( from, gIODTPlane )) {
nub->free();
nub = 0;
}
}
else
nub = super::createNub(from);
return( nub);
}
bool AppleKeyLargo::performFunction(IOPlatformFunction *func, void *pfParam1,
void *pfParam2, void *pfParam3, void *pfParam4)
{
IOPlatformFunctionIterator *iter;
UInt32 cmd, cmdLen, result, param1, param2, param3, param4, param5,
param6, param7, param8, param9, param10;
if (!func)
return false;
if (!(iter = func->getCommandIterator()))
return false;
while (iter->getNextCommand (&cmd, &cmdLen, ¶m1, ¶m2, ¶m3, ¶m4,
¶m5, ¶m6, ¶m7, ¶m8, ¶m9, ¶m10, &result)) {
if (result != kIOPFNoError) {
iter->release();
return false;
}
switch (cmd) {
case kCommandWriteReg32:
safeWriteRegUInt32(param1, param3, param2);
break;
case kCommandReadReg32:
*(UInt32 *)pfParam1 = safeReadRegUInt32(param1);
break;
case kCommandWriteReg8:
safeWriteRegUInt8(param1, param3, param2);
break;
case kCommandReadReg8:
*(UInt8 *)pfParam1 = safeReadRegUInt8(param1);
break;
case kCommandReadReg32MaskShRtXOR:
*(UInt32 *)pfParam1 = ((safeReadRegUInt32(param1) & param2) >> param3) ^ param4;
break;
case kCommandReadReg8MaskShRtXOR:
*(UInt8 *)pfParam1 = ((safeReadRegUInt8(param1) & param2) >> param3) ^ param4;
break;
case kCommandWriteReg32ShLtMask:
safeWriteRegUInt32(param1, param3, ((UInt32)pfParam1)<<param2);
break;
case kCommandWriteReg8ShLtMask:
safeWriteRegUInt8(param1, param3, ((UInt32)pfParam1)<<param2);
break;
default:
kprintf ("AppleKeyLargo::performFunction - bad command %ld\n", cmd);
return false;
}
}
iter->release();
return true;
}
OSDefineMetaClassAndStructors(AppleK2Device, AppleMacIODevice);
bool AppleK2Device::compareName( OSString * name,
OSString ** matched ) const
{
return( IODTCompareNubName( this, name, matched )
|| IORegistryEntry::compareName( name, matched ) );
}
IOReturn AppleK2Device::getResources( void )
{
IOService *mac_io = this;
if( getDeviceMemory())
return( kIOReturnSuccess );
while (mac_io && ((mac_io = mac_io->getProvider()) != 0))
if (strcmp("mac-io", mac_io->getName()) == 0)
break;
if (mac_io == 0)
return kIOReturnError;
IODTResolveAddressing( this, "reg", mac_io->getDeviceMemoryWithIndex(0) );
return( kIOReturnSuccess);
}