// ---------------------------------------------------------------------------------------------------- bool PlatformInterfaceDBDMA_Mapped::init ( IOService* device, AppleOnboardAudio* provider, UInt32 inDBDMADeviceIndex ) { bool result = FALSE; IOService* theService; IORegistryEntry *macio; IORegistryEntry *gpio; IORegistryEntry *i2s; IORegistryEntry *i2sParent; IOMemoryMap *map; debugIOLog ( 3, "+ PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d )", device, provider, inDBDMADeviceIndex ); FailIf ( NULL == provider, Exit ); FailIf ( NULL == device, Exit ); result = super::init ( device, provider, inDBDMADeviceIndex ); if ( result ) { mKeyLargoService = IOService::waitForService ( IOService::serviceMatching ( "KeyLargo" ) ); debugIOLog ( 3, " sound's name is %s", ( (IORegistryEntry*)device)->getName () ); i2s = ( ( IORegistryEntry*)device)->getParentEntry ( gIODTPlane ); FailWithAction ( 0 == i2s, result = false, Exit ); debugIOLog ( 3, " parent name is '%s'", i2s->getName () ); if ( 0 == strcmp ( "i2s-a", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell0; } else if ( 0 == strcmp ( "i2s-b", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell1; } else if ( 0 == strcmp ( "i2s-c", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell2; } else if ( 0 == strcmp ( "i2s-d", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell3; } else if ( 0 == strcmp ( "i2s-e", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell4; } else if ( 0 == strcmp ( "i2s-f", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell5; } else if ( 0 == strcmp ( "i2s-g", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell6; } else if ( 0 == strcmp ( "i2s-h", i2s->getName () ) ) { mI2SInterfaceNumber = kUseI2SCell7; } debugIOLog ( 5, " mI2SInterfaceNumber = %d", mI2SInterfaceNumber ); i2sParent = i2s->getParentEntry ( gIODTPlane ); FailWithAction ( 0 == i2sParent, result = false, Exit ); debugIOLog ( 3, " parent name of '%s' is %s", i2s->getName (), i2sParent->getName () ); macio = i2sParent->getParentEntry ( gIODTPlane ); FailWithAction ( 0 == macio, result = false, Exit ); debugIOLog ( 3, " macio name is %s", macio->getName () ); gpio = macio->childFromPath ( kGPIODTEntry, gIODTPlane); FailWithAction ( !gpio, result = false, Exit); debugIOLog ( 3, " gpio name is %s", gpio->getName () ); theService = ( OSDynamicCast ( IOService, i2s ) ); FailWithAction ( !theService, result = false, Exit ); map = theService->mapDeviceMemoryWithIndex ( inDBDMADeviceIndex ); FailWithAction ( 0 == map, result = false, Exit ); // cache the config space mSoundConfigSpace = (UInt8 *)map->getPhysicalAddress(); // sets the clock base address figuring out which I2S cell we're on if ((((UInt32)mSoundConfigSpace ^ kI2S0BaseOffset) & 0x0001FFFF) == 0) { // [3060321] ioBaseAddress is required by this object in order to enable the target // I2S I/O Module for which this object is to service. The I2S I/O Module // enable occurs through the configuration registers which reside in the // first block of ioBase. rbm 2 Oct 2002 mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S0BaseOffset); mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S0BaseOffset), 256); mI2SInterfaceNumber = kUseI2SCell0; } else if ((((UInt32)mSoundConfigSpace ^ kI2S1BaseOffset) & 0x0001FFFF) == 0) { // [3060321] ioBaseAddress is required by this object in order to enable the target // I2S I/O Module for which this object is to service. The I2S I/O Module // enable occurs through the configuration registers which reside in the // first block of ioBase. rbm 2 Oct 2002 mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S1BaseOffset); mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S1BaseOffset), 256); mI2SInterfaceNumber = kUseI2SCell1; } else { debugIOLog (3, " AudioI2SControl::init ERROR: unable to setup ioBaseAddress and i2SInterfaceNumber"); } FailIf (NULL == mIOBaseAddressMemory, Exit); // [3060321] ioConfigurationBaseAddress is required by this object in order to enable the target // I2S I/O Module for which this object is to service. The I2S I/O Module // enable occurs through the configuration registers which reside in the // first block of ioBase. rbm 2 Oct 2002 mIOConfigurationBaseAddress = (void *)mIOBaseAddressMemory->map()->getVirtualAddress(); FailIf ( NULL == mIOConfigurationBaseAddress, Exit ); // // There are three sections of memory mapped I/O that are directly accessed by the Apple02Audio. These // include the GPIOs, I2S DMA Channel Registers and I2S control registers. They fall within the memory map // as follows: // ~ ~ // |______________________________| // | | // | I2S Control | // |______________________________| <- soundConfigSpace = ioBase + i2s0BaseOffset ...OR... ioBase + i2s1BaseOffset // | | // ~ ~ // ~ ~ // |______________________________| // | | // | I2S DMA Channel | // |______________________________| <- i2sDMA = ioBase + i2s0_DMA ...OR... ioBase + i2s1_DMA // | | // ~ ~ // ~ ~ // |______________________________| // | FCRs | // | GPIO | <- gpio = ioBase + gpioOffsetAddress // | ExtIntGPIO | <- fcr = ioBase + fcrOffsetAddress // |______________________________| <- ioConfigurationBaseAddress // | | // ~ ~ // // The I2S DMA Channel is mapped in by the Apple02DBDMAAudioDMAEngine. Only the I2S control registers are // mapped in by the AudioI2SControl. The Apple I/O Configuration Space (i.e. FCRs, GPIOs and ExtIntGPIOs) // are mapped in by the subclass of Apple02Audio. The FCRs must also be mapped in by the AudioI2SControl // object as the init method must enable the I2S I/O Module for which the AudioI2SControl object is // being instantiated for. // // The physical addresses for memory mapped I/O within the KeyLargo system I/O controller are as follows: // // // // ______________________________ // /| | // / | | // / |______________________________| // ______________________________ / | | // | | | I2S 1 ('i2s-b') | // | | |______________________________|....0xnnn11000 [0x80011000] // | | | | // | | | I2S 0 ('i2s-a') | // | | |______________________________|....0xnnn10000 [0x80001000] // | Device Registers | / // | | / // | | / ______________________________ // | |/ /| | // |______________________________|__/ | | // | | |______________________________| // | | | | // | | | I2S 1 Rx DMA ('i2s-b') | // | | |______________________________|....0xnnn08300 [0x80008300] // | DMA Channel Registers | | | // | | | I2S 1 Tx DMA ('i2s-b') | // | | |______________________________|....0xnnn08200 [0x80008200] // | | | | // |______________________________| | I2S 0 Rx DMA ('i2s-a') | // | |\ |______________________________|....0xnnn08100 [0x80008100] // | | \ | | // | Reserved: read "0" | \ | I2S 0 Tx DMA ('i2s-a') | // | | \|______________________________|....0xnnn08000 [0x80008000] // |______________________________| // | | // | | // | Apple I/O Configuration | // | | // |______________________________|....0xnnn00000 [0x80011000] // // Map the I2S configuration registers mIOI2SBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace), kI2S_IO_CONFIGURATION_SIZE); FailIf ( NULL == mIOI2SBaseAddressMemory, Exit ); mI2SBaseAddress = (void *)mIOI2SBaseAddressMemory->map()->getVirtualAddress(); FailIf (NULL == mI2SBaseAddress, Exit); debugIOLog (3, " mI2SInterfaceNumber = %d", mI2SInterfaceNumber); debugIOLog (3, " mIOI2SBaseAddressMemory = %p", mIOI2SBaseAddressMemory); debugIOLog (3, " mI2SBaseAddress = %p", mI2SBaseAddress); debugIOLog (3, " mIOBaseAddressMemory = %p", mIOBaseAddressMemory); debugIOLog (3, " mIOConfigurationBaseAddress = %p", mIOConfigurationBaseAddress); } Exit: debugIOLog ( 3, "- PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d ) returns %lX", device, provider, inDBDMADeviceIndex, result ); return result; }