sl@0: // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // template\template_variant\specific\variant.cpp sl@0: // sl@0: // sl@0: sl@0: #include "variant.h" sl@0: #include "mconf.h" sl@0: #include sl@0: #include sl@0: #include "template_power.h" sl@0: sl@0: //These constants define Custom Restart Reasons in SuperPage::iHwStartupReason sl@0: const TUint KHtCustomRestartMax = 0xff; sl@0: const TUint KHtCustomRestartShift = 8; sl@0: const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift; sl@0: sl@0: const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant sl@0: const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant sl@0: const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift; sl@0: sl@0: void TemplateVariantFault(TInt aLine) sl@0: { sl@0: Kern::Fault("TemplateVariant",aLine); sl@0: } sl@0: sl@0: #define V_FAULT() TemplateVariantFault(__LINE__) sl@0: sl@0: // Debug output sl@0: #define XON 17 sl@0: #define XOFF 19 sl@0: #define DEBUG_XON_XOFF 0 // Non-zero if we want XON-XOFF handshaking sl@0: sl@0: GLDEF_D Template TheVariant; sl@0: TUint32 Variant::iBaseAddress=0; sl@0: sl@0: TUint32 Template::HandlerData[3]; sl@0: SInterruptHandler Template::Handlers[ENumXInts]; sl@0: sl@0: extern void XIntDispatch(TAny*); sl@0: sl@0: EXPORT_C Asic* VariantInitialise() sl@0: { sl@0: return &TheVariant; sl@0: } sl@0: sl@0: Template::Template() sl@0: { sl@0: iDebugInitialised=EFalse; sl@0: } sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Specify the RAM zone configuration. sl@0: // sl@0: // The lowest addressed zone must have the highest preference as the bootstrap sl@0: // will always allocate from the lowest address up. Once the kernel has initialised sl@0: // then the zone preferences will decide from which RAM zone memory is allocated. sl@0: // sl@0: // const TUint KVariantRamZoneCount = ?; sl@0: // static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] = sl@0: // iBase iSize iID iPref iFlags sl@0: // { sl@0: // __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), sl@0: // ... sl@0: // __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), sl@0: // __SRAM_ZONE_END, // end of zone list sl@0: // }; sl@0: // sl@0: sl@0: TInt Template::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks) sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Handle RAM zone operations requested by the kernel. sl@0: // sl@0: return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks); sl@0: } sl@0: sl@0: sl@0: TInt Template::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks) sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Handle RAM zone operations requested by the kernel. sl@0: // sl@0: // Three types of operation need to be supported: sl@0: // ERamZoneOp_Init: Update power state of the RAM zones after the sl@0: // kernel has initialised. sl@0: // ERamZoneOp_PowerUp: A RAM zone changing from used to empty. sl@0: // ERamZoneOp_PowerDown: A RAM zone changing from empty to used. sl@0: // sl@0: sl@0: switch (aOp) sl@0: { sl@0: case ERamZoneOp_Init: sl@0: break; sl@0: case ERamZoneOp_PowerUp: sl@0: break; sl@0: case ERamZoneOp_PowerDown: sl@0: break; sl@0: default: sl@0: return KErrNotSupported; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void Template::Init1() sl@0: { sl@0: __KTRACE_OPT(KBOOT,Kern::Printf("Template::Init1()")); sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap) sl@0: // sl@0: __KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done")); sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig(). sl@0: // For devices that wish to reduce power consumption of the RAM IC(s) the callback functions sl@0: // RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed sl@0: // to Epoc::SetRamZoneConfig() as the parameter aCallback. sl@0: // The kernel will assume that all RAM ICs are fully intialised and ready for use from boot. sl@0: // sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap sl@0: // sl@0: // if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap), sl@0: // the address of the idle code is writen at this location by the Bootstrap sl@0: // e.g. sl@0: // iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000); sl@0: // sl@0: TemplateAssp::Init1(); sl@0: } sl@0: sl@0: void Template::Init3() sl@0: { sl@0: __KTRACE_OPT(KBOOT,Kern::Printf("Template::Init3()")); sl@0: sl@0: TemplateAssp::Init3(); sl@0: sl@0: Variant::Init3(); sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Initialise other accessor classes, if required sl@0: // sl@0: sl@0: InitInterrupts(); sl@0: } sl@0: sl@0: void Variant::Init3() sl@0: // sl@0: // Phase 3 initialisation sl@0: // sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf(">Variant::Init3")); sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Initialise any Variant class data members here, map in Variant and external hardware addresses sl@0: // sl@0: DPlatChunkHw* pC=NULL; sl@0: TInt r=DPlatChunkHw::New(pC,KHwVariantPhysBase,0x2000,EMapAttrSupRw|EMapAttrFullyBlocking); sl@0: __ASSERT_ALWAYS(r==KErrNone,V_FAULT()); sl@0: iBaseAddress=pC->LinearAddress(); sl@0: } sl@0: sl@0: EXPORT_C TUint Variant::BaseLinAddress() sl@0: { sl@0: return((TUint)iBaseAddress); sl@0: } sl@0: sl@0: EXPORT_C void Variant::MarkDebugPortOff() sl@0: { sl@0: TheVariant.iDebugInitialised=EFalse; sl@0: } sl@0: sl@0: EXPORT_C void Variant::UartInit() sl@0: { sl@0: NKern::Lock(); sl@0: if (!TheVariant.iDebugInitialised) sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Reset and initialise the UART used to output debug strings sl@0: // sl@0: TheVariant.iDebugInitialised=ETrue; sl@0: } sl@0: NKern::Unlock(); sl@0: } sl@0: sl@0: void Template::DebugInit() sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Initialise the UART used for outputting Debug Strings (no Interrupts), as in the following EXAMPLE ONLY: sl@0: // sl@0: Variant::UartInit(); sl@0: TTemplate::BootWaitMilliSeconds(10); // wait loop to ensure that the port is fully initialised and output buffer empty sl@0: } sl@0: sl@0: void Template::DebugOutput(TUint aLetter) sl@0: // sl@0: // Output a character to the debug port sl@0: // sl@0: { sl@0: if (!iDebugInitialised) sl@0: { sl@0: DebugInit(); sl@0: } sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Write the character aLetter to the UART output register and wait until sent (do NOT use interrupts!) sl@0: // sl@0: } sl@0: sl@0: void Template::Idle() sl@0: // sl@0: // The NULL thread idle loop sl@0: // sl@0: { sl@0: // Idle the CPU, suppressing the system tick if possible sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Idle Tick supression: sl@0: // 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime()) sl@0: // 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer sl@0: // to only interrupt again when the corresponding time has expired. sl@0: // 2.1- the calculation of the new value to program the Hardware Timer with should take in sl@0: // consideration the rounding value (NTimerQ::iRounding) sl@0: // 3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction) sl@0: // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to sl@0: // timer expiration (system time for new match<=current system time MapSleepMode(aTicksLeft*MsTickPeriod()); sl@0: // ... sl@0: // Find out the state of some particular resources sl@0: // TBool aResourceState = aManager -> GetResourceState(TemplateResourceManager::AsynchBinResourceUsedByZOnly); sl@0: // TUint aResourceLevel = aManager -> GetResourceLevel(TemplateResourceManager::SynchMlResourceUsedByXOnly); sl@0: // ... sl@0: } sl@0: sl@0: TInt Template::VariantHal(TInt aFunction, TAny* a1, TAny* a2) sl@0: { sl@0: TInt r=KErrNone; sl@0: switch(aFunction) sl@0: { sl@0: case EVariantHalVariantInfo: sl@0: { sl@0: TVariantInfoV01Buf infoBuf; sl@0: TVariantInfoV01& info=infoBuf(); sl@0: info.iRomVersion=Epoc::RomHeader().iVersion; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Fill in the TVariantInfoV01 info structure sl@0: // info.iMachineUniqueId=; sl@0: // info.iLedCapabilities=; sl@0: // info.iProcessorClockInKHz=; sl@0: // info.iSpeedFactor=; sl@0: // sl@0: Kern::InfoCopy(*(TDes8*)a1,infoBuf); sl@0: break; sl@0: } sl@0: case EVariantHalDebugPortSet: sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY: sl@0: // sl@0: TUint32 thePort = (TUint32)a1; sl@0: switch(thePort) sl@0: { sl@0: case 1: sl@0: case 2: sl@0: case 3: sl@0: TheVariant.iDebugInitialised=EFalse; sl@0: case (TUint32)KNullDebugPort: sl@0: Kern::SuperPage().iDebugPort = thePort; sl@0: break; sl@0: default: sl@0: r=KErrNotSupported; sl@0: } sl@0: break; sl@0: } sl@0: case EVariantHalDebugPortGet: sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Obtain the Linear address of the Uart used for outputting Debug strings as in the following EXAMPLE ONLY: sl@0: // sl@0: sl@0: TUint32 thePort = TTemplate::DebugPortAddr(); sl@0: kumemput32(a1, &thePort, sizeof(TUint32)); sl@0: break; sl@0: } sl@0: case EVariantHalSwitches: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the state of any switches, as in the following EXAMPLE ONLY: sl@0: // sl@0: TUint32 x = Variant::Switches(); sl@0: kumemput32(a1, &x, sizeof(x)); sl@0: break; sl@0: } sl@0: case EVariantHalLedMaskSet: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Set the state of any on-board LEDs, e.g: sl@0: // TUint32 aLedMask=(TUint32)a1; sl@0: // Variant::ModifyLedState(~aLedMask,aLedMask); sl@0: // sl@0: break; sl@0: } sl@0: case EVariantHalLedMaskGet: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the state of any on-board LEDs, e.g: sl@0: // TUint32 x = Variant::LedState(); sl@0: // kumemput32(a1, &x, sizeof(x)); sl@0: // sl@0: break; sl@0: } sl@0: sl@0: case EVariantHalCustomRestartReason: sl@0: { sl@0: //Restart reason is stored in super page sl@0: TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ; sl@0: kumemput32(a1, &x, sizeof(TInt)); sl@0: break; sl@0: } sl@0: sl@0: case EVariantHalCustomRestart: sl@0: { sl@0: if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart"))) sl@0: return KErrPermissionDenied; sl@0: if ((TUint)a1 > KHtCustomRestartMax) sl@0: return KErrArgument; sl@0: Kern::Restart((TInt)a1 << KHtCustomRestartShift); sl@0: } sl@0: break; sl@0: sl@0: case EVariantHalCaseState: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the state of the case, e.g: sl@0: // TUint32 x = Variant::CaseState(); sl@0: // kumemput32(a1, &x, sizeof(x)); sl@0: // sl@0: break; sl@0: } sl@0: sl@0: case EVariantHalPersistStartupMode: sl@0: { sl@0: if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) sl@0: return KErrPermissionDenied; sl@0: sl@0: if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value sl@0: return KErrArgument; sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Store the restart reason locally, sl@0: // which will eventually be picked up by sl@0: // the power controller, e.g: sl@0: // iCustomRestartReason = (TUint)a1; sl@0: break; sl@0: } sl@0: sl@0: sl@0: case EVariantHalGetPersistedStartupMode: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the restart startup mode, e.g: sl@0: // TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift; sl@0: // kumemput32(a1, &startup, sizeof(TInt)); sl@0: break; sl@0: } sl@0: sl@0: case EVariantHalGetMaximumCustomRestartReasons: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the maximum custom restart reason, e.g: sl@0: // kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint)); sl@0: break; sl@0: } sl@0: sl@0: sl@0: case EVariantHalGetMaximumRestartStartupModes: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the maximum restart startup mode, e.g: sl@0: // kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint)); sl@0: break; sl@0: } sl@0: sl@0: case EVariantHalProfilingDefaultInterruptBase: sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: //Set the default interrupt number for the sampling profiler. sl@0: //TInt interruptNumber = KIntCpuProfilingDefaultInterruptBase; sl@0: //kumemput(a1,&interruptNumber,sizeof(interruptNumber)); sl@0: break; sl@0: } sl@0: sl@0: default: sl@0: r=KErrNotSupported; sl@0: break; sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TPtr8 Template::MachineConfiguration() sl@0: { sl@0: return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig)); sl@0: } sl@0: sl@0: TInt Template::VideoRamSize() sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Return the size of the area of RAM used to store the Video Buffer, as in the following EXAMPLE ONLY: sl@0: // sl@0: return 0x28000; sl@0: } sl@0: sl@0: EXPORT_C void Variant::PowerReset() sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Reset all power supplies sl@0: // sl@0: } sl@0: sl@0: EXPORT_C TUint Variant::Switches() sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Read the state of on-board switches sl@0: // sl@0: return 0; // EXAMPLE ONLY sl@0: } sl@0: sl@0: /****************************************************************************** sl@0: * Interrupt handling/dispatch sl@0: ******************************************************************************/ sl@0: TInt Template::InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr) sl@0: { sl@0: TUint id=anId&0x7fffffff; // mask off second-level interrupt mask sl@0: if (id>=ENumXInts) sl@0: return KErrArgument; sl@0: TInt r=KErrNone; sl@0: SInterruptHandler& h=Handlers[id]; sl@0: TInt irq=NKern::DisableAllInterrupts(); sl@0: if (h.iIsr!=Spurious) sl@0: r=KErrInUse; sl@0: else sl@0: { sl@0: h.iIsr=anIsr; sl@0: h.iPtr=aPtr; sl@0: } sl@0: NKern::RestoreInterrupts(irq); sl@0: return r; sl@0: } sl@0: sl@0: TInt Template::InterruptUnbind(TInt anId) sl@0: { sl@0: TUint id=anId&0x7fffffff; // mask off second-level interrupt mask sl@0: if (id>=ENumXInts) sl@0: return KErrArgument; sl@0: InterruptDisable(anId); sl@0: InterruptClear(anId); sl@0: TInt r=KErrNone; sl@0: SInterruptHandler& h=Handlers[id]; sl@0: TInt irq=NKern::DisableAllInterrupts(); sl@0: if (h.iIsr!=Spurious) sl@0: { sl@0: h.iIsr=Spurious; sl@0: h.iPtr=(TAny*)id; sl@0: } sl@0: NKern::RestoreInterrupts(irq); sl@0: return r; sl@0: } sl@0: sl@0: TInt Template::InterruptEnable(TInt anId) sl@0: { sl@0: TUint id=anId&0x7fffffff; // mask off second-level interrupt mask sl@0: if (id>=ENumXInts) sl@0: return KErrArgument; sl@0: TInt r=KErrNone; sl@0: SInterruptHandler& h=Handlers[id]; sl@0: TInt irq=NKern::DisableAllInterrupts(); sl@0: if (h.iIsr==Spurious) sl@0: r=KErrNotReady; sl@0: else sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Enable the hardware interrupt in the source, e.g. sl@0: // Variant::EnableInt(anId); sl@0: // sl@0: } sl@0: NKern::RestoreInterrupts(irq); sl@0: return r; sl@0: } sl@0: sl@0: TInt Template::InterruptDisable(TInt anId) sl@0: { sl@0: TUint id=anId&0x7fffffff; // mask off second-level interrupt mask sl@0: if (id>=ENumXInts) sl@0: return KErrArgument; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Disable the hardware interrupt in the source, e.g. sl@0: // Variant::DisableInt(anId); sl@0: // sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt Template::InterruptClear(TInt anId) sl@0: { sl@0: TUint id=anId&0x7fffffff; sl@0: if (id>=ENumXInts) sl@0: return KErrArgument; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Clear the hardware interrupt in the source, e.g. sl@0: // Variant::ClearInt(anId); sl@0: // sl@0: return KErrNone; sl@0: } sl@0: sl@0: void Template::InitInterrupts() sl@0: { sl@0: // Set up the variant interrupt dispatcher sl@0: sl@0: // all interrupts initially unbound sl@0: TInt i; sl@0: for (i=0; i<(TInt)ENumXInts; i++) sl@0: { sl@0: Handlers[i].iPtr=(TAny*)i; sl@0: Handlers[i].iIsr=Spurious; sl@0: } sl@0: sl@0: // Set up data for 2nd level interrupt dispatcher sl@0: HandlerData[0]=Variant::BaseLinAddress(); // Linear Base address of 2nd level Int Controller sl@0: HandlerData[1]=(TUint32)&Handlers[0]; // Pointer to handler array sl@0: HandlerData[2]=0; // sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // set up ASSP expansion interrupt to generate interrupts whenever a 2nd level interrupt occurrs sl@0: // sl@0: sl@0: // bind Template ASSP expansion interrupt input to our interrupt dispatcher sl@0: TInt r=Interrupt::Bind(KIntIdExpansion, XIntDispatch, HandlerData); sl@0: __ASSERT_ALWAYS(r==KErrNone,V_FAULT()); sl@0: Interrupt::Enable(KIntIdExpansion); // enable expansion interrupt sl@0: } sl@0: sl@0: void Template::Spurious(TAny* aId) sl@0: { sl@0: TUint32 id=((TUint32)aId)|0x80000000u; sl@0: Kern::Fault("SpuriousInt",id); sl@0: } sl@0: sl@0: sl@0: // USB Client controller sl@0: sl@0: TBool Template::UsbClientConnectorDetectable() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorDetectable")); sl@0: sl@0: // TO DO: The return value should reflect the actual situation. sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: TBool Template::UsbClientConnectorInserted() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorInserted")); sl@0: sl@0: // TO DO: Query cable status here. The return value should reflect the actual current state. sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: TInt Template::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr) sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::RegisterUsbClientConnectorCallback")); sl@0: sl@0: iUsbClientConnectorCallback = aCallback; sl@0: iUsbClientConnectorCallbackArg = aPtr; sl@0: sl@0: // TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here. sl@0: // (Register UsbClientConnectorIsr.) sl@0: sl@0: // TO DO: The return value should reflect the actual situation. sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void Template::UnregisterUsbClientConnectorCallback() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UnregisterUsbClientConnectorCallback")); sl@0: sl@0: // TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here. sl@0: sl@0: iUsbClientConnectorCallback = NULL; sl@0: iUsbClientConnectorCallbackArg = NULL; sl@0: } sl@0: sl@0: sl@0: TBool Template::UsbSoftwareConnectable() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbSoftwareConnectable")); sl@0: sl@0: // TO DO: The return value should reflect the actual situation. sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: TInt Template::UsbConnect() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbConnect")); sl@0: sl@0: // TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host). sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt Template::UsbDisconnect() sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbDisconnect")); sl@0: sl@0: // TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the sl@0: // host). sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void Template::UsbClientConnectorIsr(TAny *aPtr) sl@0: // sl@0: // Services the USB cable interrupt. sl@0: // sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorIsr()")); sl@0: sl@0: Template* tm = static_cast(aPtr); sl@0: sl@0: // TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc. sl@0: sl@0: if (tm->UsbClientConnectorInserted()) sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted.")); sl@0: } sl@0: else sl@0: { sl@0: __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed.")); sl@0: } sl@0: sl@0: // Important: Inform the USB stack. sl@0: if (tm->iUsbClientConnectorCallback) sl@0: { sl@0: (*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg); sl@0: } sl@0: } sl@0: sl@0: sl@0: //---eof