# HG changeset patch # User Pat Downey # Date 1255607994 -3600 # Node ID 6663340f3fc9aede40bffbcb4dbef05dc3aafab5 Add EPL'd beagleboard code diff -r 000000000000 -r 6663340f3fc9 omap3530/Building_the_beagle_baseport.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/Building_the_beagle_baseport.html Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,92 @@ + + + + Symbian^2 on the Beagle Board + + + + +

Symbian^2 on the Beagle Board

+ +

Purpose and Scope

+ + This document is a guide to running the the Symbian^2 on the Beagle board. + +

Getting the Symbian^2 release

+ +

The beagle board base port will only work in conjuntion with the SOSCO patched version of Symbian^2. This assumes the following release opps_baseline sf_2.0.b_003_SOSCO_OPPS_003_TMP. This release must be installed acording to the by following the steps on the OPP database.

+ +

Ensure that the Syborg rom builds and boots before proceeding.

+ + +

Getting the Beagle board baseport

+ +

At the time of writing the Beagle board baseport is only available in the SOSCO perforce repositary. The source is located at:

+ +
//LPD/development/baseporting/clean/beagleboard/personal/andrewps/foundation_latest/src/cedar/generic/base/omap3530/
+ +

There should be a CBR release coming soon.

+ + +

Compiling the Beagle board baseport

+ +

Get the base source code by calling getsource on all components found using envinfo | findstr base_.

+ +

To compile the beagle board baseport use the metabld script omap3530/buildscripts/reallycleanbuild.mbc:

+ +
metabld reallycleanbuild.mbc
+ +

I usually collect a log by doing something like

+ +
metabld reallycleanbuild.mbc 2>&1 | tee 20090714_1641_build_the_beagle_bsp.txt
+ + +

Building a Beagle board textshell image

+ +

To build a textshell rom the following lines have to be commented out of \epoc32\include\bldvariant.hrh.

+ +
+#include <bldcodeline.hrh>		
+#include <bldprivate.hrh>
+#include <bldpublic.hrh>
+#include <bldregional.hrh> 
+		
+ +

Note that these lines must be put back to build a GUI image.

+ +

Use the standard textshell build comand:

+ +
rom -v=beagle -i=armv5
+ +
rombuild rom.oby
+ + +

Booting a Beagle board ROM

+ +

Copy your image to an MMC or SD card and call it BEAGLEARMV5D.IMG. If your Beagle board is not setup to autoboot from removable media then you must connect to the bootloader configuration shell over the beagle boards serial connection and type the following:

+ +
set bootcmd 'mmcinit ; fatload mmc 0:1 0x81000000 BEAGLEARMV5D.IMG ; go 0x81000000'; saveenv
+ +

When you reboot the beagle board the textshell rom should be automatically loaded.

+ + +

Building a Beagle board S60 image

+ +

Ensure that \epoc32\include\bldvariant.hrh is clean.

+ +

Update \epoc32\rom\lpd_override\base.iby to include the Beagle baseport:

+ +
+#elif defined(__BEAGLE__)
+#include <base_beagle.iby>
+		
+ +

Copy the files beagle.oby and base_beagle.iby from \epoc32\rom\include into \epoc32\rom\lpd_override\.

+ +

Build the s60 image using the following command:

+ +
call \epoc32\tools\buildrom_lpd.cmd beagle Symbian2.oby -D_EABI=ARMV5 -DCOLOR  -DSYMBIAN_EXCLUDE_IPSEC -D_PORTRAIT_ -es60ibymacros -nosymbols -D__LOCALES_01_IBY__
+ + + + \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,33 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS + +./inc/assp.mmh assp/omap3530_assp/ // +./inc/omap3530_assp_priv.h assp/omap3530_assp/ // +./inc/omap3530_irqmap.h assp/omap3530_assp/ // +./inc/omap3530_hardware_base.h assp/omap3530_assp/ // +./inc/omap3530_timer.h assp/omap3530_assp/ // +./inc/omap3530_ktrace.h assp/omap3530_assp/ // +./inc/omap3530_asspreg.h assp/omap3530_assp/ // +./inc/locks.h assp/omap3530_assp/ // + + +PRJ_MMPFILES +./src/kaomap3530 diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/def/eabi/kaomap3530.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/def/eabi/kaomap3530.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,32 @@ +EXPORTS + _Z14AsicInitialisev @ 1 NONAME + _Z14TestInterruptsiPFvPvE @ 2 NONAME + _Z28ClearAndDisableTestInterrupti @ 3 NONAME + _ZN12AsspRegister6Read64Em @ 4 NONAME + _ZN12AsspRegister7Modify8Emhh @ 5 NONAME + _ZN12AsspRegister7Write64Emy @ 6 NONAME + _ZN12AsspRegister8Modify16Emtt @ 7 NONAME + _ZN12AsspRegister8Modify32Emmm @ 8 NONAME + _ZN12AsspRegister8Modify64Emyy @ 9 NONAME + _ZN12Omap3530Assp12MsTickPeriodEv @ 10 NONAME + _ZN12Omap3530Assp15DebugPortNumberEv @ 11 NONAME + _ZN12Omap3530Assp13StartupReasonEv @ 12 NONAME + _ZN12Omap3530Assp15ArmCpuVersionIdER9TArmCpuId @ 13 NONAME + _ZN12Omap3530Assp16GetXtalFrequencyEv @ 14 NONAME + _ZN12Omap3530Assp19NanoWaitCalibrationEv @ 15 NONAME + _ZN12Omap3530Assp19ProcessorPeriodInPsEv @ 16 NONAME + _ZN12Omap3530Assp20BootWaitMilliSecondsEi @ 17 NONAME + _ZN12Omap3530Assp5Init1Ev @ 18 NONAME + _ZN12Omap3530Assp5Init3Ev @ 19 NONAME + _ZN12Omap3530AsspC2Ev @ 20 NONAME + _ZN17Omap3530Interrupt18IsInterruptEnabledEi @ 21 NONAME + _ZN9Interrupt11SetPriorityEii @ 22 NONAME + _ZN9Interrupt4BindEiPFvPvES0_ @ 23 NONAME + _ZN9Interrupt5ClearEi @ 24 NONAME + _ZN9Interrupt6EnableEi @ 25 NONAME + _ZN9Interrupt6UnbindEi @ 26 NONAME + _ZN9Interrupt7DisableEi @ 27 NONAME + _ZTI12Omap3530Assp @ 28 NONAME + _ZTV12Omap3530Assp @ 29 NONAME + _ZN20MInterruptDispatcher8RegisterE14TIrqRangeIndex @ 30 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/assp.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/assp.mmh Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,141 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_assp/assp.mmh +// TO DO: (mandatory) +// Add here a definition for your CPU (list in CONFIG.INC) +// macro __CPU_CORTEX_A8__ +// + +macro __CPU_CORTEX_A8N__ + +// TO DO: (mandatory) +// +// Add here a definition for your Memory Model +// +#define MM_MULTIPLE + +// TO DO: (mandatory) +// +// Macro which generates the names for the binaries for this platform +// +#define AsspTarget(name,ext) _omap3530_##name##.##ext + +//Include debug support. Some e32 tests require debug support +macro __DEBUGGER_SUPPORT__ + +// +// TO DO: +// +// If euser is built from the variant, uncomment the following line to build it +// as ARM rather than Thumb +// +// #define __BUILD_VARIANT_EUSER_AS_ARM__ + +// TO DO: (optional) +// +// To replace some of the generic utility functions with variant specific +// versions (eg to replace memcpy with a version optimised for the hardware), +// uncomment the two lines below and edit the files in the replacementUtils +// directory. +// +// #define REPLACE_GENERIC_UTILS +// #define VariantReplacementUtilsPath beagle/beagle_variant/replacement_utils + +// TO DO: (optional) +// +// Enable BTrace support in release versions of the kernel by adding +// the following BTRACE macro declarations +// +// macro BTRACE_KERNEL_ALL + +// TO DO: +// +// Uncomment the following line if using the r1p0 release or later of the ARM1136 processor. +// +// macro __CPU_ARM1136_IS_R1__ + +// TO DO: +// +// Include the following line if default memory mapping should use shared memory. +// Should be on for multicore (SMP) devices. +// +// macro __CPU_USE_SHARED_MEMORY +// + +// TO DO: +// +// Uncomment the next line if using the ARM1136 processor and ARM1136 Erratum 406973 +// "CLREX instruction might be ignored during data cache line fill" +// is fixed on this hardware. +// +// macro __CPU_ARM1136_ERRATUM_406973_FIXED + +// Uncomment next line if: +// 1) using the ARM1136 processor and ARM1136 Erratum 408022 "Cancelled write to CONTEXTID register might update ASID" +// is fixed on this hardware, or +// 2) using the ARM1176 processor and ARM1176 Erratum 415047 "Cancelled write to CONTEXTID register might update ASID" +// is fixed on this hardware. +// +// macro __CPU_ARM1136_ERRATUM_408022_FIXED + +// Uncomment if: +// 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill" +// is fixed on this hardware, or +// 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill +// is fixed on this hardware. +// Workaround: +// 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +// 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +// If this macro is enabled, it should be accompanied by: +// "GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +// +// macro __CPU_ARM1136_ERRATUM_411920_FIXED + +// Uncomment the following line if Page Tables/Dirs have to be updated in main memory. +// Standard platforms shouldn't have this feature switched on. +// This must be accompanied by __ARM_L210_CACHE__ or __ARM_L220_CACHE__ macro. +// Omission:: The solution doesn't update temporary mappings +// of inter-process communication (IPC) - aka aliasing. +// +// macro __FLUSH_PT_INTO_RAM__ + +// Uncomment the following line if Symbian OS is running in TrustZone non-secure state and the +// secure state has prevented code executing in non-secure state from being able to mask FIQs by +// setting the SCR.FW bit in the secure configuration register. +// +// macro __FIQ_RESERVED_FOR_SECURE_STATE__ + +// Various PlatSec configuration options cannot be disabled even by clearing the appropriate +// bits in the kernel configuration flags - they are enforced at compile time. Uncomment the +// following to allow the clearing of bits in the kernel config flags to disable the relevant +// options at run time. +// +//macro __PLATSEC_UNLOCKED__ + +// If this macro is enabled then EMapAttrBufferedNC memory will be remapped as EMapAttrFullyBlocking +//macro FAULTY_NONSHARED_DEVICE_MEMORY + +// Uncomment the following line if L210/20 cache is running in forced-WT mode. +// (Forced_WT bit set in Debug Control Register of L210/20 cache controller.) +// macro __ARM_L2_CACHE_WT_MODE + +// For the status of errata of L210 & L220 cache, see the header of source file: +// e32\kernel\arm\cachel2.cpp + +#if defined(__USING_USING_ASSP_REGISTER_API__) || defined(__USING_INTERRUPT_API__) || defined(__USING_ASSP_REGISTER_API__) +library AsspTarget(kaomap3530,lib) +#endif + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/locks.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/locks.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,140 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#ifndef __95_locks_h__ +#define __95_locks_h__ + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_IRQ_R(lock) ((void)NKern::DisableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_IRQ_R(lock) (NKern::EnableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_IRQ_R(lock) (NKern::EnableAllInterrupts(),(void)NKern::DisableAllInterrupts(),((TBool)TRUE)) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_IRQ_W(lock) ((void)NKern::DisableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_IRQ_W(lock) (NKern::EnableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_IRQ_W(lock) (NKern::EnableAllInterrupts(),(void)NKern::DisableAllInterrupts(),((TBool)TRUE)) + + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_R(lock) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_R(lock) + +/** +@internalComponent +*/ +#define __SPIN_FLASH_R(lock) ((TBool)FALSE) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_W(lock) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_W(lock) + +/** +@internalComponent +*/ +#define __SPIN_FLASH_W(lock) ((TBool)FALSE) + + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_IRQSAVE_R(lock) (NKern::DisableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_IRQRESTORE_R(lock,irq) (NKern::RestoreInterrupts(irq)) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_IRQRESTORE_R(lock,irq) (NKern::RestoreInterrupts(irq),((void)NKern::DisableAllInterrupts()),((TBool)TRUE)) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_LOCK_IRQSAVE_W(lock) (NKern::DisableAllInterrupts()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_UNLOCK_IRQRESTORE_W(lock,irq) (NKern::RestoreInterrupts(irq)) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_IRQRESTORE_W(lock,irq) (NKern::RestoreInterrupts(irq),((void)NKern::DisableAllInterrupts()),((TBool)TRUE)) + + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_PREEMPT_R(lock) ((TBool)NKern::PreemptionPoint()) + +/** +@publishedPartner +@prototype +*/ +#define __SPIN_FLASH_PREEMPT_W(lock) ((TBool)NKern::PreemptionPoint()) + +#endif \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_assp_priv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_assp_priv.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,203 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_assp_priv.h +// + +#ifndef __OMAP3530_PRIV_H__ +#define __OMAP3530_PRIV_H__ + +#include +#include +#include +#include +#include +#include + +/** +* IRQ/FIQ dispatchers +*/ +static void IrqDispatch(); +static void FiqDispatch(); + +class TArmCpuId { +public: + TInt Implementor; // Indicates the implementor, ARM: + TInt Variant; //Indicates the variant number, or major revision, of the processor: + TInt Architecture; //Indicates that the architecture is given in the feature registers: + TInt Primary; //part number Indicates the part number, Cortex-A8: + TInt Revision; +}; + +class Omap3530Interrupt : public Interrupt + { +public: + /** + * These functions are required to initialise the Interrupt controller,or perform housekeeping + * functions, or dispatch the incoming IRQ or FIQ interrupts. + */ + + /** + * initialisation + */ + static void Init1(); + static void Init3(); + + /** + * Housekeeping (disable and clear all hardware interrupt sources) + */ + static void DisableAndClearAll(); + IMPORT_C static TInt IsInterruptEnabled(TInt anId); + static void dumpINTCState(); + static void dumpIVTState(); + static TInt GetRegisterAndBitOffset(TInt anId,TInt &aReg,TInt &aOffset); + static void Spurious(TAny* anId); + + static SInterruptHandler Handlers[KNumOmap3530Ints]; + + TSpinLock Omap3530INTCLock; + TSpinLock Omap3530IVTLock; +private: + + + }; + + + +class Omap3530Assp : public Asic + { +public: + IMPORT_C Omap3530Assp(); + +public: + IMPORT_C virtual TInt MsTickPeriod(); + /** + * Obtain System Time from the RTC + * @return System Time in seconds from 00:00 hours of 1/1/2000 + */ + virtual TInt SystemTimeInSecondsFrom2000(TInt& aTime)=0; + /** + * Obtain Adjust the RTC with new System Time (from 00:00 hours of 1/1/2000) + * @return System wide error code + */ + virtual TInt SetSystemTimeInSecondsFrom2000(TInt aTime)=0; + /** + * Obtain the time it takes to execute two processor instructions + * @return Time in nanoseconds it takes two execute 2 instructions at the processor clock speed + */ + IMPORT_C virtual TUint32 NanoWaitCalibration(); + + /** + * initialisation + */ + IMPORT_C virtual void Init1(); + IMPORT_C virtual void Init3(); + /** + * Active waiting loop (not to be used after System Tick timer has been set up - Init3() + * @param aDuration A wait time in milliseconds + */ + IMPORT_C static void BootWaitMilliSeconds(TInt aDuration); + /** + * Read and return the Startup reason of the Hardware + * @return A TMachineStartupType enumerated value + */ + IMPORT_C virtual TMachineStartupType StartupReason(); + /** + * Read and return the the CPU ID + * @return An integer containing the CPU ID string read off the hardware + */ + IMPORT_C static void ArmCpuVersionId(TArmCpuId &id); + /** + * Get debug port number enumeration + * @return An integer containing the Omap3530Uart::TUartNumber value, with value ENone if debug port isn't a UART + */ + IMPORT_C static Omap3530Uart::TUartNumber DebugPortNumber(); + /** + * Read CPU clock period in picoseconds + * @return An integer containing the CPU clock period in picoseconds + */ + IMPORT_C static TUint ProcessorPeriodInPs(); + /** + * Read the current time of the RTC + * @return A value that is the real time as given by a RTC + */ + //IMPORT_C static TUint RtcData(); + /** + * Set the RTC time + * @param aValue The real time to set the RTC + */ + //IMPORT_C static void SetRtcData(TUint aValue); + /** + * Obtain the physical start address of Video Buffer + * @return the physical start address of Video Buffer + */ + + IMPORT_C static TUint64 GetXtalFrequency(); + +private: + /** + * Assp-specific implementation for Kern::NanoWait function + */ + static void NanoWait(TUint32 aInterval); + TInt StartMsTick(); + static void MsTickIsr(TAny* aPtr); + + +public: + /** + * for derivation by Variant + */ + + /** + * external interrupt handling + * used by second-level interrupt controllers at Variant level + */ + virtual TInt InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr)=0; + virtual TInt InterruptUnbind(TInt anId)=0; + virtual TInt InterruptEnable(TInt anId)=0; + virtual TInt InterruptDisable(TInt anId)=0; + virtual TInt InterruptClear(TInt anId)=0; + virtual TInt IsExternalInterrupt(TInt anId)=0; + + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the Variant. + * Pure virtual functions called by the USB PSL, to be implemented by the Variant (derived class). + * If this functionality is part of the ASSP then these functions can be removed and calls to them + * in the PSL (./pa_usbc.cpp) replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable()=0; + virtual TBool UsbClientConnectorInserted()=0; + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)=0; + virtual void UnregisterUsbClientConnectorCallback()=0; + virtual TBool UsbSoftwareConnectable()=0; + virtual TInt UsbConnect()=0; + virtual TInt UsbDisconnect()=0; + + /** Return the frequency in Hz of the SYSCLK source clock */ + virtual TUint SysClkFrequency() const = 0; + + /** Return the frequency in Hz of the SYSCLK32K source clock */ + virtual TUint SysClk32kFrequency() const = 0; + + /** Return the frequency in Hz of the ALTCLK source clock */ + virtual TUint AltClkFrequency() const = 0; + +public: + static Omap3530Assp * Variant; + TBool iDebugInitialised; + +private: + }; + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_asspcia.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_asspcia.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,33 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_asspcia.h +// + +#ifndef __TEMPLATE_ASSPCIA_H__ +#define __TEMPLATE_ASSPCIA_H__ + +// CIA symbols for ASSP code +#if defined(__GCC32__) +// CIA symbol macros for Gcc98r2 +#define CSM_ZN7NTimerQ4TickEv " Tick__7NTimerQ" +#elif defined(__ARMCC__) +// CIA symbol macros for RVCT +#define CSM_ZN7NTimerQ4TickEv " __cpp(NTimerQ::Tick)" +#else +// CIA symbol macros for EABI assemblers +#define CSM_ZN7NTimerQ4TickEv " _ZN7NTimerQ4TickEv" +#endif + + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_asspreg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_asspreg.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,158 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#ifndef __ASSPREG_H__ +#define __ASSPREG_H__ + +/** +@publishedPartner +@prototype + +A class that exports ASSP register access functionality to +device drivers and other kernel-side code. + +Although Symbian OS defines this class, it does not implement all +the functions within it. An implementation for each of the register +modification functions defined by this class must be provided by +the baseport. +*/ +class AsspRegister + { +public: + + /** + Return the contents of an 8-bit register. + + @param aAddr The address of the register to be read. + @return The contents of the register. + @pre Can be called in any context. + */ + static inline TUint8 Read8(TLinAddr aAddr) + { return *(volatile TUint8*)aAddr; } + + /** + Store a new value in an 8-bit register. This will change + the entire contents of the register concerned. + + @param aAddr The address of the register to be written. + @param aValue The new value to be written to the register. + @pre Can be called in any context. + */ + static inline void Write8(TLinAddr aAddr, TUint8 aValue) + { *(volatile TUint8*)aAddr = aValue; } + + /** + Modify the contents of an 8-bit register. + + @param aAddr The address of the register to be modified. + @param aClearMask A mask of the bits to be cleared in the register. + @param aSetMask A mask of the bits to be set in the register after the clear. + @pre Can be called in any context. + */ + IMPORT_C static void Modify8(TLinAddr aAddr, TUint8 aClearMask, TUint8 aSetMask); + + /** + Return the contents of an 16-bit register. + + @param aAddr The address of the register to be read. + @return The contents of the register. + @pre Can be called in any context. + */ + static inline TUint16 Read16(TLinAddr aAddr) + { return *(volatile TUint16*)aAddr; } + + /** + Store a new value in a 16-bit register. This will change + the entire contents of the register concerned. + + @param aAddr The address of the register to be written. + @param aValue The new value to be written to the register. + @pre Can be called in any context. + */ + static inline void Write16(TLinAddr aAddr, TUint16 aValue) + { *(volatile TUint16*)aAddr = aValue; } + + /** + Modify the contents of a 16-bit register. + + @param aAddr The address of the register to be modified. + @param aClearMask A mask of the bits to be cleared in the register. + @param aSetMask A mask of the bits to be set in the register after the clear. + @pre Can be called in any context. + */ + IMPORT_C static void Modify16(TLinAddr aAddr, TUint16 aClearMask, TUint16 aSetMask); + + /** + Return the contents of a 32-bit register. + + @param aAddr The address of the register to be read. + @return The contents of the register. + @pre Can be called in any context. + */ + static inline TUint32 Read32(TLinAddr aAddr) + { return *(volatile TUint32*)aAddr; } + + /** + Store a new value in a 32-bit register. This will change + the entire contents of the register concerned. + + @param aAddr The address of the register to be written. + @param aValue The new value to be written to the register. + @pre Can be called in any context. + */ + static inline void Write32(TLinAddr aAddr, TUint32 aValue) + { *(volatile TUint32*)aAddr = aValue; } + + /** + Modify the contents of a 32-bit register. + + @param aAddr The address of the register to be modified. + @param aClearMask A mask of the bits to be cleared in the register. + @param aSetMask A mask of the bits to be set in the register after the clear. + @pre Can be called in any context. + */ + IMPORT_C static void Modify32(TLinAddr aAddr, TUint32 aClearMask, TUint32 aSetMask); + + /** + Return the contents of a 64-bit register. + + @param aAddr The address of the register to be read. + @return The contents of the register. + @pre Can be called in any context. + */ + IMPORT_C static TUint64 Read64(TLinAddr aAddr); + + /** + Store a new value in a 64-bit register. This will change + the entire contents of the register concerned. + + @param aAddr The address of the register to be written. + @param aValue The new value to be written to the register. + @pre Can be called in any context. + */ + IMPORT_C static void Write64(TLinAddr aAddr, TUint64 aValue); + + /** + Modify the contents of a 64-bit register. + + @param aAddr The address of the register to be modified. + @param aClearMask A mask of the bits to be cleared in the register. + @param aSetMask A mask of the bits to be set in the register after the clear. + @pre Can be called in any context. + */ + IMPORT_C static void Modify64(TLinAddr aAddr, TUint64 aClearMask, TUint64 aSetMask); + }; + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_hardware_base.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_hardware_base.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,569 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_hardware_base.h +// Linear base addresses for hardware peripherals on the beagle board. +// This file is part of the Beagle Base port +// + +#ifndef OMAP3530_HARDWARE_BASE_H__ +# define OMAP3530_HARDWARE_BASE_H__ + +#include // for TPhysAddr, AsspRegister +#include + +namespace TexasInstruments + { + + namespace Omap3530 + { + + /** + Define constants for the various physical address blocks used on the OMAP3530 + */ + enum TPhysicalAddresses + { + KKiloByte = 1024, + KMegaByte = (1024 * KKiloByte), + KL4_Core_PhysicalBase = 0x48000000, + KL4_Core_PhysicalSize = (4 * KMegaByte), + KL4_Core_PhysicalEnd = (KL4_Core_PhysicalBase + KL4_Core_PhysicalSize), + + KL4_WakeUp_PhysicalBase = 0x48300000, + KL4_WakeUp_PhysicalSize = (256 * KKiloByte ), + KL4_WakeUp_PhysicalEnd = (KL4_WakeUp_PhysicalBase + KL4_WakeUp_PhysicalSize), + + KL4_Per_PhysicalBase = 0x49000000, + KL4_Per_PhysicalSize = (1 * KMegaByte), + KL4_Per_PhysicalEnd = (KL4_Per_PhysicalBase + KL4_Per_PhysicalSize), + + KL4_Sgx_PhysicalBase = 0x50000000, + KL4_Sgx_PhysicalSize = (64 * KKiloByte), + KL4_Sgx_PhysicalEnd = (KL4_Sgx_PhysicalBase + KL4_Sgx_PhysicalSize), + + KL4_Emu_PhysicalBase = 0x54000000, + KL4_Emu_PhysicalSize = (8 * KMegaByte), + KL4_Emu_PhysicalEnd = (KL4_Emu_PhysicalBase + KL4_Emu_PhysicalSize), + + KL3_Control_PhysicalBase = 0x68000000, + KL3_Control_PhysicalSize = (1 * KMegaByte), + KL3_Control_PhysicalEnd = (KL3_Control_PhysicalBase + KL3_Control_PhysicalSize), + + KL3_Gpmc_PhysicalBase = 0x6e000000, + KL3_Gpmc_PhysicalSize = (1 * KMegaByte), + KL3_Gpmc_PhysicalEnd = (KL3_Gpmc_PhysicalBase + KL3_Gpmc_PhysicalSize) + } ; + + /** + Define constants for the virtual address mappings used on the OMAP3530 + */ + enum TLinearAddresses + { + KL4_Core_LinearBase = 0xC6000000, + KL4_Core_LinearSize = KL4_Core_PhysicalSize, + KL4_Core_LinearEnd = (KL4_Core_LinearBase + KL4_Core_LinearSize), + + KL4_WakeUp_LinearBase = (KL4_Core_LinearBase + (KL4_WakeUp_PhysicalBase - KL4_Core_PhysicalBase)), + KL4_WakeUp_LinearSize = KL4_WakeUp_PhysicalSize, + KL4_WakeUp_LinearEnd = (KL4_WakeUp_LinearBase + KL4_WakeUp_LinearSize), + + KL4_Per_LinearBase = KL4_Core_LinearEnd, + KL4_Per_LinearSize = KL4_Per_PhysicalSize, + KL4_Per_LinearEnd = (KL4_Per_LinearBase + KL4_Per_LinearSize), + + KL4_Sgx_LinearBase = KL4_Per_LinearEnd, + KL4_Sgx_LinearSize = KL4_Sgx_PhysicalSize, + KL4_Sgx_LinearEnd = (KL4_Sgx_LinearBase + KL4_Sgx_LinearSize), + + KL4_Emu_LinearBase = KL4_Sgx_LinearBase + KMegaByte, + KL4_Emu_LinearSize = KL4_Emu_PhysicalSize, + KL4_Emu_LinearEnd = (KL4_Emu_LinearBase + KL4_Emu_LinearSize), + + KL3_Control_LinearBase = KL4_Emu_LinearEnd, + KL3_Control_LinearSize = KL3_Control_PhysicalSize, + KL3_Control_LinearEnd = (KL3_Control_LinearBase + KL3_Control_LinearSize), + + KL3_Gpmc_LinearBase = KL3_Control_LinearEnd, + KL3_Gpmc_LinearSize = KL3_Gpmc_PhysicalSize, + KL3_Gpmc_LinearEnd = (KL3_Gpmc_LinearBase + KL3_Gpmc_LinearSize) + } ; + + /** + A template to provide the virtual address of a given physical address. + @example + @code + enum TTimerBaseAddress + { + KGPTIMER1_Base = Omap3530HwBase::TVirtual<0x48318000>::Value, + } ; + */ + template + struct TVirtual + { + enum TConstants + { + KIsL4Core = ((aDdReSs >= KL4_Core_PhysicalBase) && (aDdReSs < KL4_Core_PhysicalEnd)), + KIsL4WakeUp = ((aDdReSs >= KL4_WakeUp_PhysicalBase) && (aDdReSs < KL4_WakeUp_PhysicalEnd)), // Subset of L4Core + KIsL4Per = ((aDdReSs >= KL4_Per_PhysicalBase) && (aDdReSs < KL4_Per_PhysicalEnd)), + KIsL4Sgx = ((aDdReSs >= KL4_Sgx_PhysicalBase) && (aDdReSs < KL4_Sgx_PhysicalEnd)), + KIsL4Emu = ((aDdReSs >= KL4_Emu_PhysicalBase) && (aDdReSs < KL4_Emu_PhysicalEnd)), + KIsL3Control = ((aDdReSs >= KL3_Control_PhysicalBase) && (aDdReSs < KL3_Control_PhysicalEnd)), + KIsL3Gpmc = ((aDdReSs >= KL3_Gpmc_PhysicalBase) && (aDdReSs < KL3_Gpmc_PhysicalEnd)), + KIsConvertable = (KIsL4Core || KIsL4Per || KIsL4Sgx || KIsL4Emu || KIsL3Control || KIsL3Gpmc), + KIsMapped = (KIsL4Core || KIsL4Per || KIsL4Sgx || KIsL4Emu || KIsL3Control || KIsL3Gpmc), + KOffset = ((KIsL4Core) ? (aDdReSs - KL4_Core_PhysicalBase) + : ((KIsL4Per) ? (aDdReSs - KL4_Per_PhysicalBase) + : ((KIsL4Sgx) ? (aDdReSs - KL4_Sgx_PhysicalBase) + : ((KIsL4Emu) ? (aDdReSs - KL4_Emu_PhysicalBase) + : ((KIsL3Control) ? (aDdReSs - KL3_Control_PhysicalBase) + : ((KIsL3Gpmc) ? (aDdReSs - KL3_Gpmc_PhysicalBase) + : (0))))))), + // TODO: Change to give compile time error if address not mapped + KLinearBase = ((KIsL4Core) ? (KL4_Core_LinearBase) + : ((KIsL4Per) ? (KL4_Per_LinearBase) + : ((KIsL4Sgx) ? (KL4_Sgx_LinearBase) + : ((KIsL4Emu) ? (KL4_Emu_LinearBase) + : ((KIsL3Control) ? (KL3_Control_LinearBase) + : ((KIsL3Gpmc) ? (KL3_Gpmc_LinearBase) + : (0))))))), + /** + Returns the Linear address mapping for a specific Physical address + */ + Value = (KLinearBase + KOffset) + } ; + } ; + + template + struct TLinearCheck + { + enum TConstants + { + KIsL4Core = ((aDdReSs >= KL4_Core_LinearBase) && (aDdReSs < KL4_Core_LinearEnd)), + KIsL4Per = ((aDdReSs >= KL4_Per_LinearBase) && (aDdReSs < KL4_Per_LinearEnd)), + KIsL4Sgx = ((aDdReSs >= KL4_Sgx_LinearBase) && (aDdReSs < KL4_Sgx_LinearEnd)), + KIsL4Emu = ((aDdReSs >= KL4_Emu_LinearBase) && (aDdReSs < KL4_Emu_LinearEnd)), + KIsL3Control = ((aDdReSs >= KL3_Control_LinearBase) && (aDdReSs < KL3_Control_LinearBase)), + KIsL3Gpmc = ((aDdReSs >= KL3_Gpmc_LinearBase) && (aDdReSs < KL3_Gpmc_LinearBase)), + KIsMapped = (KIsL4Core || KIsL4Per || KIsL4Sgx || KIsL4Emu || KIsL3Control || KIsL3Gpmc) + } ; + } ; + +# ifdef __MEMMODEL_MULTIPLE__ + const TUint KL4_Core = KL4_Core_LinearBase; // KPrimaryIOBase + const TUint KL4_Per = KL4_Per_LinearBase; + const TUint KSgx = KL4_Sgx_LinearBase; + const TUint KL4_Emu = KL4_Emu_LinearBase; + const TUint KL3_Control = KL3_Control_LinearBase; + const TUint KL3_Gpmc = KL3_Gpmc_LinearBase; +//const TUint KIva2_2Ss = KL4_Core + 0x01910000; +//const TUint KL3ControlRegisters = KL4_Core + 0x04910000; +//const TUint KSmsRegisters = KL4_Core + 0x05910000; +//const TUint KSdrcRegisters = KL4_Core + 0x06910000; +//const TUint KGpmcRegisters = KL4_Core + 0x07910000; + +//#elif __MEMMODEL_FLEXIBLE__ +// define flexible memery model hw base addresses + +# else // unknown memery model +# error hardware_base.h: Constants may need changing +# endif // memory model + +// Register Access types. + + typedef TUint32 TRegValue; + typedef TUint32 TRegValue32; + typedef TUint16 TRegValue16; + typedef TUint8 TRegValue8; + + /** + An interface template for read-only registers. + */ + template + class TReg32_R + { + public : + static inline TRegValue Read() + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + return AsspRegister::Read32(aDdReSs) ; + } + } ; + + template + class TReg16_R + { + public : + static inline TRegValue16 Read() + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + return AsspRegister::Read16(aDdReSs) ; + } + } ; + + template + class TReg8_R + { + public : + static inline TRegValue8 Read() + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + return AsspRegister::Read8(aDdReSs) ; + } + } ; + + /** + An interface template for read-write registers. + */ + template + class TReg32_RW : public TReg32_R
+ { + public : + static inline void Write(const TRegValue aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write32(aDdReSs, aValue) ; + } + static inline void Modify(const TRegValue aClearMask, const TRegValue aSetMask) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Modify32(aDdReSs, aClearMask, aSetMask) ; + } + } ; + + template + class TReg16_RW : public TReg16_R
+ { + public : + static inline void Write(const TRegValue16 aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write16(aDdReSs, aValue) ; + } + static inline void Modify(const TRegValue16 aClearMask, const TRegValue16 aSetMask) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Modify16(aDdReSs, aClearMask, aSetMask) ; + } + } ; + + template + class TReg8_RW : public TReg8_R
+ { + public : + static inline void Write(const TRegValue8 aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write8(aDdReSs, aValue) ; + } + static inline void Modify(const TRegValue8 aClearMask, const TRegValue8 aSetMask) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Modify8(aDdReSs, aClearMask, aSetMask) ; + } + } ; + + /** + An interface template for write-only registers. + */ + template + class TReg32_W + { + public : + static inline void Write(const TRegValue aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write32(aDdReSs, aValue) ; + } + } ; + + template + class TReg16_W + { + public : + static inline void Write(const TRegValue16 aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write16(aDdReSs, aValue) ; + } + } ; + + template + class TReg8_W + { + public : + static inline void Write(const TRegValue8 aValue) + { + __ASSERT_COMPILE((TLinearCheck
::KIsMapped)) ; + AsspRegister::Write8(aDdReSs, aValue) ; + } + } ; + + /** Class for registers that have dynamic base address */ + template + class TDynReg8_R + { + public : + static inline TRegValue8 Read( const T& aOwner ) + { + return AsspRegister::Read8( aOwner.Base() + OfFsEt ) ; + } + } ; + + template + class TDynReg16_R + { + public : + static inline TRegValue16 Read( const T& aOwner ) + { + return AsspRegister::Read16( aOwner.Base() + OfFsEt ) ; + } + } ; + + template + class TDynReg32_R + { + public : + static inline TRegValue32 Read( const T& aOwner ) + { + return AsspRegister::Read32( aOwner.Base() + OfFsEt ) ; + } + } ; + + + template + class TDynReg8_RW : public TDynReg8_R + { + public : + static inline void Write( T& aOwner, const TRegValue8 aValue) + { + AsspRegister::Write8( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue8 aClearMask, const TRegValue8 aSetMask) + { + AsspRegister::Modify8( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + template + class TDynReg16_RW : public TDynReg16_R + { + public : + static inline void Write( T& aOwner, const TRegValue16 aValue) + { + AsspRegister::Write16( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue16 aClearMask, const TRegValue16 aSetMask) + { + AsspRegister::Modify16( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + template + class TDynReg32_RW : public TDynReg32_R + { + public : + static inline void Write( T& aOwner, const TRegValue32 aValue) + { + AsspRegister::Write32( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue32 aClearMask, const TRegValue32 aSetMask) + { + AsspRegister::Modify32( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + template + class TDynReg8_W + { + public : + static inline void Write( T& aOwner, const TRegValue8 aValue) + { + AsspRegister::Write8( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue8 aClearMask, const TRegValue8 aSetMask) + { + AsspRegister::Modify8( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + template + class TDynReg16_W + { + public : + static inline void Write( T& aOwner, const TRegValue16 aValue) + { + AsspRegister::Write16( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue16 aClearMask, const TRegValue16 aSetMask) + { + AsspRegister::Modify16( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + template + class TDynReg32_W + { + public : + static inline void Write( T& aOwner, const TRegValue32 aValue) + { + AsspRegister::Write32( aOwner.Base() + OfFsEt, aValue) ; + } + static inline void Modify( T& aOwner, const TRegValue32 aClearMask, const TRegValue32 aSetMask) + { + AsspRegister::Modify32( aOwner.Base() + OfFsEt, aClearMask, aSetMask) ; + } + } ; + + /** + An Null class for when no register access is required. + */ + class TNull_Reg + { + public : + static inline TRegValue Read() + { + return 0 ; + } + static inline void Write(const TRegValue) + { + } + static inline void Modify(const TRegValue, const TRegValue) + { + } + } ; + + template + class TBit + { + public : + enum TConstants + { + KValue = (1 << aBiTpOsItIoN) + } ; + } ; + + template + class TBitFieldBase + { + public : + enum TConstants + { + KShift = aBiTpOsItIoN, + KValueMask = (TBit::KValue - 1), + KFieldMask = (KValueMask << KShift), + KValueMax = KValueMask + } ; + } ; + + template + class TBitFieldValue : public TBitFieldBase + { + public : + using TBitFieldBase::KShift ; + using TBitFieldBase::KValueMask ; + using TBitFieldBase::KFieldMask ; + using TBitFieldBase::KValueMax ; + + enum TValues + { + KValue = ((KValueMask & aVaLuE) << KShift) + } ; + } ; + + template + class TBitField : public TBitFieldBase + { + using TBitFieldBase::KShift ; + using TBitFieldBase::KValueMask ; + using TBitFieldBase::KFieldMask ; + using TBitFieldBase::KValueMax ; + public : + template + class TConstVal : public TBitFieldValue + { + public : + using TBitFieldValue::KValue ; + } ; + + inline TBitField(const TRegValue aValue) + : iValue((KValueMask & aValue) << KShift) {} + + inline TBitField(const TRegValue * aValuePtr) + : iValue(KFieldMask & *aValuePtr) {} + + template + inline TBitField(const TReg32_R
& aReg) + : iValue(KFieldMask & aReg.Read()) {} + + inline TRegValue Value() const {return (KValueMask & (iValue >> KShift)) ;} + + inline TRegValue RegField() const {return (iValue) ;} + + private : + TRegValue iValue ; + } ; + + template + class TSingleBitField : public TBitField + { + public : + enum TConstants + { + KOff = 0, + KOn = (1 << aBiTpOsItIoN), + KClear = KOff, + KSet = KOn, + KMask = KOn, + } ; + } ; + + } ; // namespace Omap3530 + + } ; // namespace TexasInstruments + + +namespace TI = TexasInstruments ; + +namespace OMAP3530 = TexasInstruments::Omap3530 ; + +namespace Omap3530HwBase = TexasInstruments::Omap3530 ; + +// **** TEST CODE **** +//# define HEADER_OMAP3530_HARDWARE_BASE_H_DO_COMPILE_TIME_CHECK_TESTS 1 +# ifdef HEADER_OMAP3530_HARDWARE_BASE_H_DO_COMPILE_TIME_CHECK_TESTS + inline void CompileTimeChecks(void) + { + __ASSERT_COMPILE((Omap3530HwBase::TVirtual<0x48318000>::KIsL4Core)) ; + __ASSERT_COMPILE((TI::Omap3530::TVirtual<0x48318000>::KIsL4WakeUp)) ; + __ASSERT_COMPILE((!Omap3530HwBase::TVirtual<0x48318000>::KIsL4Emu)) ; + __ASSERT_COMPILE((!Omap3530HwBase::TVirtual<0x0000FFFF>::KIsConvertable)) ; + __ASSERT_COMPILE((Omap3530HwBase::TLinearCheck< Omap3530HwBase::TVirtual<0x48318000>::Value >::KIsMapped)) ; + __ASSERT_COMPILE((!Omap3530HwBase::TLinearCheck< Omap3530HwBase::TVirtual<0x0000FFFF>::Value >::KIsMapped)) ; + const TLinAddr mapped(Omap3530HwBase::TVirtual<0x48318000>::Value) ; + const TLinAddr unmapped(Omap3530HwBase::TVirtual<0x0000FFFF>::Value) ; + __ASSERT_COMPILE((Omap3530HwBase::TLinearCheck< mapped >::KIsMapped)) ; + __ASSERT_COMPILE((!Omap3530HwBase::TLinearCheck< unmapped >::KIsMapped)) ; + __ASSERT_COMPILE((0)) ; // Prove that testing is happening + } +# endif + +const TUint KSetNone = 0; +const TUint KSetAll = 0xffffffff; +const TUint KClearNone = 0; +const TUint KClearAll = 0xffffffff; +const TUint KHOmapClkULPD48Mhz = 48000000; + +#endif // !OMAP3530_HARDWARE_BASE_H__ + + + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_hardware_base.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_hardware_base.inl Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,128 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_hardware_base.h +// Linear base addresses for hardware peripherals on the beagle board. +// This file is part of the Beagle Base port +// + +#ifndef OMAP3530_HARDWARE_BASE_INL__ +# define OMAP3530_HARDWARE_BASE_INL__ + + +// **** TEST CODE **** +//# define HEADER_OMAP3530_HARDWARE_BASE_H_DO_COMPILE_TIME_CHECK_TESTS 1 +# ifdef HEADER_OMAP3530_HARDWARE_BASE_H_DO_COMPILE_TIME_CHECK_TESTS +# warning HEADER_OMAP3530_HARDWARE_BASE_H_DO_COMPILE_TIME_CHECK_TESTS defined in __FILE__ +namespace OMAP3530 + { + + namespace CompileTimeTest + { + + inline void CompileTimeChecks(void) + { + __ASSERT_COMPILE((OMAP3530::TBit<0>::KValue == 0x00000001)) ; + __ASSERT_COMPILE((OMAP3530::TBit<1>::KValue == 0x00000002)) ; + __ASSERT_COMPILE((OMAP3530::TBit<30>::KValue == 0x40000000)) ; + __ASSERT_COMPILE((OMAP3530::TBit<31>::KValue == 0x80000000u)) ; + + __ASSERT_COMPILE((0 == OMAP3530::TBitFieldBase<0, 1>::KShift)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<0, 1>::KValueMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<0, 1>::KFieldMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<0, 1>::KValueMax)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<0, 1>::KFieldMax)) ; + + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<1, 1>::KShift)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<1, 1>::KValueMask)) ; + __ASSERT_COMPILE((0x00000002 == OMAP3530::TBitFieldBase<1, 1>::KFieldMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<1, 1>::KValueMax)) ; + __ASSERT_COMPILE((0x00000002 == OMAP3530::TBitFieldBase<1, 1>::KFieldMax)) ; + + __ASSERT_COMPILE((16 == OMAP3530::TBitFieldBase<16, 1>::KShift)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<16, 1>::KValueMask)) ; + __ASSERT_COMPILE((0x00010000 == OMAP3530::TBitFieldBase<16, 1>::KFieldMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<16, 1>::KValueMax)) ; + __ASSERT_COMPILE((0x00010000 == OMAP3530::TBitFieldBase<16, 1>::KFieldMax)) ; + + __ASSERT_COMPILE((30 == OMAP3530::TBitFieldBase<30, 1>::KShift)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<30, 1>::KValueMask)) ; + __ASSERT_COMPILE((0x40000000 == OMAP3530::TBitFieldBase<30, 1>::KFieldMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<30, 1>::KValueMax)) ; + __ASSERT_COMPILE((0x40000000 == OMAP3530::TBitFieldBase<30, 1>::KFieldMax)) ; + + __ASSERT_COMPILE((31 == OMAP3530::TBitFieldBase<31, 1>::KShift)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<31, 1>::KValueMask)) ; + __ASSERT_COMPILE((0x80000000 == OMAP3530::TBitFieldBase<31, 1>::KFieldMask)) ; + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<31, 1>::KValueMax)) ; + __ASSERT_COMPILE((0x80000000 == OMAP3530::TBitFieldBase<31, 1>::KFieldMax)) ; + + __ASSERT_COMPILE((0 == OMAP3530::TBitFieldBase<0, 3>::KShift)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<0, 3>::KValueMask)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<0, 3>::KFieldMask)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<0, 3>::KValueMax)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<0, 3>::KFieldMax)) ; + + __ASSERT_COMPILE((1 == OMAP3530::TBitFieldBase<1, 2>::KShift)) ; + __ASSERT_COMPILE((3 == OMAP3530::TBitFieldBase<1, 2>::KValueMask)) ; + __ASSERT_COMPILE((0x00000006 == OMAP3530::TBitFieldBase<1, 2>::KFieldMask)) ; + __ASSERT_COMPILE((3 == OMAP3530::TBitFieldBase<1, 2>::KValueMax)) ; + __ASSERT_COMPILE((0x00000006 == OMAP3530::TBitFieldBase<1, 2>::KFieldMax)) ; + + __ASSERT_COMPILE((29 == OMAP3530::TBitFieldBase<29, 3>::KShift)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<29, 3>::KValueMask)) ; + __ASSERT_COMPILE((0xE0000000 == OMAP3530::TBitFieldBase<29, 3>::KFieldMask)) ; + __ASSERT_COMPILE((7 == OMAP3530::TBitFieldBase<29, 3>::KValueMax)) ; + __ASSERT_COMPILE((0xE0000000 == OMAP3530::TBitFieldBase<29, 3>::KFieldMax)) ; + + __ASSERT_COMPILE((0x00000000 == OMAP3530::TBitFieldValue<15, 3, 0>::KValue)) ; + __ASSERT_COMPILE((0x00008000 == OMAP3530::TBitFieldValue<15, 3, 1>::KValue)) ; + __ASSERT_COMPILE((0x00038000 == OMAP3530::TBitFieldValue<15, 3, 7>::KValue)) ; + + typedef OMAP3530::TBitField<8, 2> TBitField89 ; + __ASSERT_COMPILE((0 == TBitField89::TConstVal<0>::KValue)) ; + __ASSERT_COMPILE((0x00000100 == TBitField89::TConstVal<1>::KValue)) ; + __ASSERT_COMPILE((0x00000300 == TBitField89::TConstVal<3>::KValue)) ; + + typedef OMAP3530::TSingleBitField<0> TBit0 ; + __ASSERT_COMPILE((0 == TBit0::KOff)) ; + __ASSERT_COMPILE((1 == TBit0::KOn)) ; + typedef OMAP3530::TSingleBitField<1> TBit1 ; + __ASSERT_COMPILE((0 == TBit1::KOff)) ; + __ASSERT_COMPILE((2 == TBit1::KOn)) ; + typedef OMAP3530::TSingleBitField<16> TBit16 ; + __ASSERT_COMPILE((0 == TBit16::KOff)) ; + __ASSERT_COMPILE((0x00010000 == TBit16::KOn)) ; + typedef OMAP3530::TSingleBitField<31> TBit31 ; + __ASSERT_COMPILE((0 == TBit31::KOff)) ; + __ASSERT_COMPILE((0x80000000 == TBit31::KOn)) ; + + __ASSERT_COMPILE((Omap3530HwBase::TVirtual<0x48318000>::KIsL4Core)) ; + __ASSERT_COMPILE((OMAP3530::TVirtual<0x48318000>::KIsL4WakeUp)) ; + __ASSERT_COMPILE((!OMAP3530::TVirtual<0x48318000>::KIsL4Emu)) ; + __ASSERT_COMPILE((!OMAP3530::TVirtual<0x0000FFFF>::KIsConvertable)) ; + __ASSERT_COMPILE((OMAP3530::TLinearCheck< OMAP3530::TVirtual<0x48318000>::Value >::KIsMapped)) ; + __ASSERT_COMPILE((!OMAP3530::TLinearCheck< OMAP3530::TVirtual<0x0000FFFF>::Value >::KIsMapped)) ; + const TLinAddr mapped(OMAP3530::TVirtual<0x48318000>::Value) ; + const TLinAddr unmapped(OMAP3530::TVirtual<0x0000FFFF>::Value) ; + __ASSERT_COMPILE((OMAP3530::TLinearCheck< mapped >::KIsMapped)) ; + __ASSERT_COMPILE((!OMAP3530::TLinearCheck< unmapped >::KIsMapped)) ; + __ASSERT_COMPILE((0)) ; // Prove that testing is happening + } + + } ; // namespace CompileTimeTest + + } ; // namespace OMAP3530 +# endif + +#endif // !OMAP3530_HARDWARE_BASE_INL__ diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_irqmap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_irqmap.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,419 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_irqmap.h +// + +#ifndef OMAP3530_IRQMAP_H +#define OMAP3530_IRQMAP_H + +#include + + +#define INTCPS_BASE Omap3530HwBase::KL4_Core + 0x200000 +#define INTCPS_SYSCONFIG INTCPS_BASE + 0x10 +#define INTCPS_SYSSTATUS INTCPS_BASE + 0x14 +#define INTCPS_PROTECTION INTCPS_BASE + 0x4c +#define INTCPS_IRQ_PRIORITY INTCPS_BASE + 0x60 +#define INTCPS_FIQ_PRIORITY INTCPS_BASE + 0x64 + + +#define INTCPS_ITR(n) (INTCPS_BASE + 0x80 +( 0x20 *n)) +#define INTCPS_THRESHOLD INTCPS_BASE + 0x64 +#define INTCPS_IDLE INTCPS_BASE + 0x50 +//#define INTC_INIT_REGISTER1 0x470C8010 +//#define INTC_INIT_REGISTER2 0x470C8050 +#define INTCPS_ILRM(n) (INTCPS_BASE + 0x100 +(0x04 *n)) + +//current interrupt vector & clear regs +#define INTCPS_SIR_IRQ INTCPS_BASE + 0x40 +#define INTCPS_SIR_FIQ INTCPS_BASE + 0x44 +#define INTCPS_CONTROL INTCPS_BASE + 0x48 + + +#define INTCPS_PENDING_IRQ(n) (INTCPS_BASE + 0x98 + (0x20 * n)) +#define INTCPS_PENDING_FIQ(n) (INTCPS_BASE + 0x9c + (0x20 * n)) +//masks on /off +#define INTCPS_MIRn(n) (INTCPS_BASE + 0x084 + (n *0x20)) +#define INTCPS_MIR_SETn(n) (INTCPS_BASE + 0x08c + (n * 0x20)) +#define INTCPS_MIR_CLEARn(n) (INTCPS_BASE + 0x088 + (n *0x20)) + + +#define INTCPS_ISRSET(n) (INTCPS_BASE + 0x090 + (n *0x20)) +#define INTCPS_ISR_CLEAR(n) (INTCPS_BASE + 0x094 + (n *0x20)) + +//regvals +#define INTCPS_SYSCONFIG_AUTOIDLE 0x1 +#define INTCPS_IDLE_FUNCIDLE 0x0 +#define INTCPS_IDLE_TURBO 0x1 +#define INTCPS_ILRM_DEF_PRI (0x1 <<2) +#define INTCPS_ILRM_ROUTE_FIQ 0x1 +#define INTCPS_ILRM_ROUTE_IRQ 0x00 +#define INTCPS_MIR_ALL_UNSET 0x00000000 +#define INTCPS_MIR_ALL_SET 0xffffffff + +#define INTCPS_CONTROL_IRQ_CLEAR 0x1 +#define INTCPS_CONTROL_FIQ_CLEAR (0x1 << 1) +#define INTCPS_INIT_RG_LOW_PWR 0x1 +#define INTCPS_PENDING_MASK 0x7f + + + +// Base of each interrupt range supported within the ASSP layer +// Used to index the correct interrupt handler object +enum TIrqRangeIndex + { + EIrqRangeBaseCore, // main interrupt controller + EIrqRangeBasePrcm, // PRCM sub-controller interrupt sources + EIrqRangeBaseGpio, // GPIO sub-controller interrupt sources + EIrqRangeBasePsu, // Place-holder for off-board PSU device, reserved here because + // we know there will always be one (probably a TPD65950 or similar) + + KIrqRangeCount + }; + +const TInt KIrqRangeIndexShift = 16; +const TInt KIrqNumberMask = 0xFFFF; + +/** Class defining an interrupt dispatcher */ +class MInterruptDispatcher + { + public: + IMPORT_C void Register( TIrqRangeIndex aIndex ); + + virtual TInt Bind(TInt aId, TIsr aIsr, TAny* aPtr) = 0; + virtual TInt Unbind(TInt aId) = 0; + virtual TInt Enable(TInt aId) = 0; + virtual TInt Disable(TInt aId) = 0; + virtual TInt Clear(TInt aId) = 0; + virtual TInt SetPriority(TInt aId, TInt aPriority) = 0; + }; + +/* +(1) All the IRQ signals are active at low level. +(2) These interrupts are internally generated within the MPU subsystem. + +Table 10-4. Interrupt Mapping to the MPU Subsystem (continued) +*/ +enum TOmap3530_IRQ { + + EOmap3530_IRQ0_EMUINT = (EIrqRangeBaseCore << KIrqRangeIndexShift), //MPU emulation(2) + EOmap3530_IRQ1_COMMTX, //MPU emulation(2) + EOmap3530_IRQ2_COMMRX, //MPU emulation(2) + EOmap3530_IRQ3_BENCH, //MPU emulation(2) + EOmap3530_IRQ4_MCBSP2_ST_IRQ, //Sidetone MCBSP2 overflow + EOmap3530_IRQ5_MCBSP3_ST_IRQ, //Sidetone MCBSP3 overflow + EOmap3530_IRQ6_SSM_ABORT_IRQ, //MPU subsystem secure state-machine abort (2) + EOmap3530_IRQ7_SYS_NIRQ, //External source (active low) + EOmap3530_IRQ8_RESERVED, //RESERVED + EOmap3530_IRQ9_SMX_DBG_IRQ, //SMX error for debug + EOmap3530_IRQ10_SMX_APP_IRQ, //SMX error for application + EOmap3530_IRQ11_PRCM_MPU_IRQ, //PRCM module IRQ + EOmap3530_IRQ12_SDMA_IRQ0, //System DMA request 0(3) + EOmap3530_IRQ13_SDMA_IRQ1, //System DMA request 1(3) + EOmap3530_IRQ14_SDMA_IRQ2, //System DMA request 2 + EOmap3530_IRQ15_SDMA_IRQ3, //System DMA request 3 + EOmap3530_IRQ16_MCBSP1_IRQ, //McBSP module 1 IRQ (3) + EOmap3530_IRQ17_MCBSP2_IRQ, //McBSP module 2 IRQ (3) + EOmap3530_IRQ18_SR1_IRQ, //SmartReflex™ 1 + EOmap3530_IRQ19_SR2_IRQ, //SmartReflex™ 2 + EOmap3530_IRQ20_GPMC_IRQ, //General-purpose memory controller module + EOmap3530_IRQ21_SGX_IRQ, //2D/3D graphics module + EOmap3530_IRQ22_MCBSP3_IRQ, //McBSP module 3(3) + EOmap3530_IRQ23_MCBSP4_IRQ, //McBSP module 4(3) + EOmap3530_IRQ24_CAEM_IRQ0, //Camera interface request 0 + EOmap3530_IRQ25_DSS_IRQ, //Display subsystem module(3) + EOmap3530_IRQ26_MAIL_U0_MPU_IRQ, //Mailbox user 0 request + EOmap3530_IRQ27_MCBSP5_IRQ, //McBSP module 5 (3) + EOmap3530_IRQ28_IVA2_MMU_IRQ, //IVA2 MMU + EOmap3530_IRQ29_GPIO1_MPU_IRQ, //GPIO module 1(3) + EOmap3530_IRQ30_GPIO2_MPU_IRQ, //GPIO module 2(3) + EOmap3530_IRQ31_GPIO3_MPU_IRQ, //GPIO module 3(3) + EOmap3530_IRQ32_GPIO4_MPU_IRQ, //GPIO module 4(3) + EOmap3530_IRQ33_GPIO5_MPU_IRQ, //GPIO module 5(3) + EOmap3530_IRQ34_GPIO6_MPU_IRQ, //GPIO module 6(3) + EOmap3530_IRQ35_USIEM_IRQ, //USIM interrupt (HS devices only) (4) + EOmap3530_IRQ36_WDT3_IRQ, //Watchdog timer module 3 overflow + EOmap3530_IRQ37_GPT1_IRQ, //General-purpose timer module 1 + EOmap3530_IRQ38_GPT2_IRQ, //General-purpose timer module 2 + EOmap3530_IRQ39_GPT3_IRQ, //General-purpose timer module 3 + EOmap3530_IRQ40_GPT4_IRQ, //General-purpose timer module 4 + EOmap3530_IRQ41_GPT5_IRQ, //General-purpose timer module 5(3) + EOmap3530_IRQ42_GPT6_IRQ, //General-purpose timer module 6(3) + EOmap3530_IRQ43_GPT7_IRQ, //General-purpose timer module 7(3) + EOmap3530_IRQ44_GPT8_IRQ, //General-purpose timer module 8(3) + EOmap3530_IRQ45_GPT9_IRQ, //General-purpose timer module 9 + EOmap3530_IRQ46_GPT10_IRQ, //General-purpose timer module 10 + EOmap3530_IRQ47_GPT11_IRQ, //General-purpose timer module 11 + EOmap3530_IRQ48_SPI4_IRQ, //McSPI module 4 + EOmap3530_IRQ49_SHA1MD5_IRQ2, //SHA-1/MD5 crypto-accelerator 2 (HS devices only)(4) + EOmap3530_IRQ50_FPKA_IRQREADY_N, //PKA crypto-accelerator (HS devices only) (4) + EOmap3530_IRQ51_SHA2MD5_IRQ, //SHA-2/MD5 crypto-accelerator 1 (HS devices only) (4) + EOmap3530_IRQ52_RNG_IRQ, //RNG module (HS devices only) (4) + EOmap3530_IRQ53_MG_IRQ, //MG function (3) + EOmap3530_IRQ54_MCBSP4_IRQTX, //McBSP module 4 transmit(3) + EOmap3530_IRQ55_MCBSP4_IRQRX, //McBSP module 4 receive(3) + EOmap3530_IRQ56_I2C1_IRQ, //I2C module 1 + EOmap3530_IRQ57_I2C2_IRQ, //I2C module 2 + EOmap3530_IRQ58_HDQ_IRQ, //HDQ/One-wire + EOmap3530_IRQ59_McBSP1_IRQTX, //McBSP module 1 transmit(3) + EOmap3530_IRQ60_McBSP1_IRQRX, //McBSP module 1 receive(3) + EOmap3530_IRQ61_I2C3_IRQ, //I2C module 3 + EOmap3530_IRQ62_McBSP2_IRQTX, //McBSP module 2 transmit(3) + EOmap3530_IRQ63_McBSP2_IRQRX, //McBSP module 2 receive(3) + EOmap3530_IRQ64_FPKA_IRQRERROR_N, //PKA crypto-accelerator (HS devices only) (4) + EOmap3530_IRQ65_SPI1_IRQ, //McSPI module 1 + EOmap3530_IRQ66_SPI2_IRQ, //McSPI module 2 + EOmap3530_IRQ67_RESERVED, //RESERVED + EOmap3530_IRQ68_RESERVED, //RESERVED + EOmap3530_IRQ69_RESERVED, //RESERVED + EOmap3530_IRQ70_RESERVED, //RESERVED + EOmap3530_IRQ71_RESERVED, //RESERVED + EOmap3530_IRQ72_UART1_IRQ, //UART module 1 + EOmap3530_IRQ73_UART2_IRQ, //UART module 2 + EOmap3530_IRQ74_UART3_IRQ, //UART module 3 (also infrared)(3) + EOmap3530_IRQ75_PBIAS_IRQ, //Merged interrupt for PBIASlite1 and 2 + EOmap3530_IRQ76_OHCI_IRQ, //OHCI controller HSUSB MP Host Interrupt + EOmap3530_IRQ77_EHCI_IRQ, //EHCI controller HSUSB MP Host Interrupt + EOmap3530_IRQ78_TLL_IRQ, //HSUSB MP TLL Interrupt + EOmap3530_IRQ79_PARTHASH_IRQ, //SHA2/MD5 crypto-accelerator 1 (HS devices only) (4) + EOmap3530_IRQ80_RESERVED, //Reserved + EOmap3530_IRQ81_MCBSP5_IRQTX, //McBSP module 5 transmit(3) + EOmap3530_IRQ82_MCBSP5_IRQRX, //McBSP module 5 receive(3) + EOmap3530_IRQ83_MMC1_IRQ, //MMC/SD module 1 + EOmap3530_IRQ84_MS_IRQ, //MS-PRO module + EOmap3530_IRQ85_RESERVED, //Reserved + EOmap3530_IRQ86_MMC2_IRQ, //MMC/SD module 2 + EOmap3530_IRQ87_MPU_ICR_IRQ, //MPU ICR + EOmap3530_IRQ88_RESERVED, //RESERVED + EOmap3530_IRQ89_MCBSP3_IRQTX, //McBSP module 3 transmit(3) + EOmap3530_IRQ90_MCBSP3_IRQRX, //McBSP module 3 receive(3) + EOmap3530_IRQ91_SPI3_IRQ, //McSPI module 3 + EOmap3530_IRQ92_HSUSB_MC_NINT, //High-Speed USB OTG controller + EOmap3530_IRQ93_HSUSB_DMA_NINT, //High-Speed USB OTG DMA controller + EOmap3530_IRQ94_MMC3_IRQ, //MMC/SD module 3 + EOmap3530_IRQ95_GPT12_IRQ, //General-purpose timer module 12 + +// IRQ virtual IDs + EOmap3530_GPIOIRQ_FIRST, + + EOmap3530_GPIOIRQ_PIN_0, + EOmap3530_GPIOIRQ_PIN_1, + EOmap3530_GPIOIRQ_PIN_2, + EOmap3530_GPIOIRQ_PIN_3, + EOmap3530_GPIOIRQ_PIN_4, + EOmap3530_GPIOIRQ_PIN_5, + EOmap3530_GPIOIRQ_PIN_6, + EOmap3530_GPIOIRQ_PIN_7, + EOmap3530_GPIOIRQ_PIN_8, + EOmap3530_GPIOIRQ_PIN_9, + EOmap3530_GPIOIRQ_PIN_10, + EOmap3530_GPIOIRQ_PIN_11, + EOmap3530_GPIOIRQ_PIN_12, + EOmap3530_GPIOIRQ_PIN_13, + EOmap3530_GPIOIRQ_PIN_14, + EOmap3530_GPIOIRQ_PIN_15, + EOmap3530_GPIOIRQ_PIN_16, + EOmap3530_GPIOIRQ_PIN_17, + EOmap3530_GPIOIRQ_PIN_18, + EOmap3530_GPIOIRQ_PIN_19, + EOmap3530_GPIOIRQ_PIN_20, + EOmap3530_GPIOIRQ_PIN_21, + EOmap3530_GPIOIRQ_PIN_22, + EOmap3530_GPIOIRQ_PIN_23, + EOmap3530_GPIOIRQ_PIN_24, + EOmap3530_GPIOIRQ_PIN_25, + EOmap3530_GPIOIRQ_PIN_26, + EOmap3530_GPIOIRQ_PIN_27, + EOmap3530_GPIOIRQ_PIN_28, + EOmap3530_GPIOIRQ_PIN_29, + EOmap3530_GPIOIRQ_PIN_30, + EOmap3530_GPIOIRQ_PIN_31, + EOmap3530_GPIOIRQ_PIN_32, + EOmap3530_GPIOIRQ_PIN_33, + EOmap3530_GPIOIRQ_PIN_34, + EOmap3530_GPIOIRQ_PIN_35, + EOmap3530_GPIOIRQ_PIN_36, + EOmap3530_GPIOIRQ_PIN_37, + EOmap3530_GPIOIRQ_PIN_38, + EOmap3530_GPIOIRQ_PIN_39, + EOmap3530_GPIOIRQ_PIN_40, + EOmap3530_GPIOIRQ_PIN_41, + EOmap3530_GPIOIRQ_PIN_42, + EOmap3530_GPIOIRQ_PIN_43, + EOmap3530_GPIOIRQ_PIN_44, + EOmap3530_GPIOIRQ_PIN_45, + EOmap3530_GPIOIRQ_PIN_46, + EOmap3530_GPIOIRQ_PIN_47, + EOmap3530_GPIOIRQ_PIN_48, + EOmap3530_GPIOIRQ_PIN_49, + EOmap3530_GPIOIRQ_PIN_50, + EOmap3530_GPIOIRQ_PIN_51, + EOmap3530_GPIOIRQ_PIN_52, + EOmap3530_GPIOIRQ_PIN_53, + EOmap3530_GPIOIRQ_PIN_54, + EOmap3530_GPIOIRQ_PIN_55, + EOmap3530_GPIOIRQ_PIN_56, + EOmap3530_GPIOIRQ_PIN_57, + EOmap3530_GPIOIRQ_PIN_58, + EOmap3530_GPIOIRQ_PIN_59, + EOmap3530_GPIOIRQ_PIN_60, + EOmap3530_GPIOIRQ_PIN_61, + EOmap3530_GPIOIRQ_PIN_62, + EOmap3530_GPIOIRQ_PIN_63, + EOmap3530_GPIOIRQ_PIN_64, + EOmap3530_GPIOIRQ_PIN_65, + EOmap3530_GPIOIRQ_PIN_66, + EOmap3530_GPIOIRQ_PIN_67, + EOmap3530_GPIOIRQ_PIN_68, + EOmap3530_GPIOIRQ_PIN_69, + EOmap3530_GPIOIRQ_PIN_70, + EOmap3530_GPIOIRQ_PIN_71, + EOmap3530_GPIOIRQ_PIN_72, + EOmap3530_GPIOIRQ_PIN_73, + EOmap3530_GPIOIRQ_PIN_74, + EOmap3530_GPIOIRQ_PIN_75, + EOmap3530_GPIOIRQ_PIN_76, + EOmap3530_GPIOIRQ_PIN_77, + EOmap3530_GPIOIRQ_PIN_78, + EOmap3530_GPIOIRQ_PIN_79, + EOmap3530_GPIOIRQ_PIN_80, + EOmap3530_GPIOIRQ_PIN_81, + EOmap3530_GPIOIRQ_PIN_82, + EOmap3530_GPIOIRQ_PIN_83, + EOmap3530_GPIOIRQ_PIN_84, + EOmap3530_GPIOIRQ_PIN_85, + EOmap3530_GPIOIRQ_PIN_86, + EOmap3530_GPIOIRQ_PIN_87, + EOmap3530_GPIOIRQ_PIN_88, + EOmap3530_GPIOIRQ_PIN_89, + EOmap3530_GPIOIRQ_PIN_90, + EOmap3530_GPIOIRQ_PIN_91, + EOmap3530_GPIOIRQ_PIN_92, + EOmap3530_GPIOIRQ_PIN_93, + EOmap3530_GPIOIRQ_PIN_94, + EOmap3530_GPIOIRQ_PIN_95, + EOmap3530_GPIOIRQ_PIN_96, + EOmap3530_GPIOIRQ_PIN_97, + EOmap3530_GPIOIRQ_PIN_98, + EOmap3530_GPIOIRQ_PIN_99, + EOmap3530_GPIOIRQ_PIN_100, + EOmap3530_GPIOIRQ_PIN_101, + EOmap3530_GPIOIRQ_PIN_102, + EOmap3530_GPIOIRQ_PIN_103, + EOmap3530_GPIOIRQ_PIN_104, + EOmap3530_GPIOIRQ_PIN_105, + EOmap3530_GPIOIRQ_PIN_106, + EOmap3530_GPIOIRQ_PIN_107, + EOmap3530_GPIOIRQ_PIN_108, + EOmap3530_GPIOIRQ_PIN_109, + EOmap3530_GPIOIRQ_PIN_110, + EOmap3530_GPIOIRQ_PIN_111, + EOmap3530_GPIOIRQ_PIN_112, + EOmap3530_GPIOIRQ_PIN_113, + EOmap3530_GPIOIRQ_PIN_114, + EOmap3530_GPIOIRQ_PIN_115, + EOmap3530_GPIOIRQ_PIN_116, + EOmap3530_GPIOIRQ_PIN_117, + EOmap3530_GPIOIRQ_PIN_118, + EOmap3530_GPIOIRQ_PIN_119, + EOmap3530_GPIOIRQ_PIN_120, + EOmap3530_GPIOIRQ_PIN_121, + EOmap3530_GPIOIRQ_PIN_122, + EOmap3530_GPIOIRQ_PIN_123, + EOmap3530_GPIOIRQ_PIN_124, + EOmap3530_GPIOIRQ_PIN_125, + EOmap3530_GPIOIRQ_PIN_126, + EOmap3530_GPIOIRQ_PIN_127, + EOmap3530_GPIOIRQ_PIN_128, + EOmap3530_GPIOIRQ_PIN_129, + EOmap3530_GPIOIRQ_PIN_130, + EOmap3530_GPIOIRQ_PIN_131, + EOmap3530_GPIOIRQ_PIN_132, + EOmap3530_GPIOIRQ_PIN_133, + EOmap3530_GPIOIRQ_PIN_134, + EOmap3530_GPIOIRQ_PIN_135, + EOmap3530_GPIOIRQ_PIN_136, + EOmap3530_GPIOIRQ_PIN_137, + EOmap3530_GPIOIRQ_PIN_138, + EOmap3530_GPIOIRQ_PIN_139, + EOmap3530_GPIOIRQ_PIN_140, + EOmap3530_GPIOIRQ_PIN_141, + EOmap3530_GPIOIRQ_PIN_142, + EOmap3530_GPIOIRQ_PIN_143, + EOmap3530_GPIOIRQ_PIN_144, + EOmap3530_GPIOIRQ_PIN_145, + EOmap3530_GPIOIRQ_PIN_146, + EOmap3530_GPIOIRQ_PIN_147, + EOmap3530_GPIOIRQ_PIN_148, + EOmap3530_GPIOIRQ_PIN_149, + EOmap3530_GPIOIRQ_PIN_150, + EOmap3530_GPIOIRQ_PIN_151, + EOmap3530_GPIOIRQ_PIN_152, + EOmap3530_GPIOIRQ_PIN_153, + EOmap3530_GPIOIRQ_PIN_154, + EOmap3530_GPIOIRQ_PIN_155, + EOmap3530_GPIOIRQ_PIN_156, + EOmap3530_GPIOIRQ_PIN_157, + EOmap3530_GPIOIRQ_PIN_158, + EOmap3530_GPIOIRQ_PIN_159, + EOmap3530_GPIOIRQ_PIN_160, + EOmap3530_GPIOIRQ_PIN_161, + EOmap3530_GPIOIRQ_PIN_162, + EOmap3530_GPIOIRQ_PIN_163, + EOmap3530_GPIOIRQ_PIN_164, + EOmap3530_GPIOIRQ_PIN_165, + EOmap3530_GPIOIRQ_PIN_166, + EOmap3530_GPIOIRQ_PIN_167, + EOmap3530_GPIOIRQ_PIN_168, + EOmap3530_GPIOIRQ_PIN_169, + EOmap3530_GPIOIRQ_PIN_170, + EOmap3530_GPIOIRQ_PIN_171, + EOmap3530_GPIOIRQ_PIN_172, + EOmap3530_GPIOIRQ_PIN_173, + EOmap3530_GPIOIRQ_PIN_174, + EOmap3530_GPIOIRQ_PIN_175, + EOmap3530_GPIOIRQ_PIN_176, + EOmap3530_GPIOIRQ_PIN_177, + EOmap3530_GPIOIRQ_PIN_178, + EOmap3530_GPIOIRQ_PIN_179, + EOmap3530_GPIOIRQ_PIN_180, + EOmap3530_GPIOIRQ_PIN_181, + EOmap3530_GPIOIRQ_PIN_182, + EOmap3530_GPIOIRQ_PIN_183, + EOmap3530_GPIOIRQ_PIN_184, + EOmap3530_GPIOIRQ_PIN_185, + EOmap3530_GPIOIRQ_PIN_186, + EOmap3530_GPIOIRQ_PIN_187, + EOmap3530_GPIOIRQ_PIN_188, + EOmap3530_GPIOIRQ_PIN_189, + EOmap3530_GPIOIRQ_PIN_190, + EOmap3530_GPIOIRQ_PIN_191, + + EOmap3530_GPIOIRQ_TOTAL, + + EOmap3530_TOTAL_IRQS +}; + + + +const TInt KNumOmap3530Ints = (EOmap3530_GPIOIRQ_FIRST -1); + +const TInt KOmap3530MaxIntPriority =0; +const TInt KOmap3530MinIntPriority =63; +const TInt KOmap3530DefIntPriority =KOmap3530MinIntPriority /2; +IMPORT_C void ClearAndDisableTestInterrupt(TInt anId); +IMPORT_C void TestInterrupts(TInt id,TIsr func); + + +#endif /*Omap3530_IRQMAP_H*/ diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_ktrace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_ktrace.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,27 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// /omap3530/assp/inc/omap3530_ktrace.h +// KTRACE defines +// This file is part of the Beagle Base port +// + +#ifndef OMAP3530_KTRACE_H +#define OMAP3530_KTRACE_H + +#define KI2C 253 +#define KGPIO 252 +#define KPRCM 251 + +#endif // #ifndef OMAP3530_KTRACE_H + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_timer.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,817 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// /omap3530/assp/inc/omap3530_timer.h +// + +#ifndef HEADER_OMAP3530_TIMER_H_INCLUDED +# define HEADER_OMAP3530_TIMER_H_INCLUDED + +/** +@file + omap3530_timer.h header file +This file provides timer handling for the omap3530 timers +@publishedAll +@released +*/ + +#include +#include + +namespace TexasInstruments + { + + namespace Omap3530 + { + + + namespace GPTimer + { + + namespace TIOCP_CFG + { + /** + 0 AUTOIDLE Internal L4 interface clock gating strategy 0 + 0x0: L4 interface clock is free-running. + 0x1: Automatic L4 interface clock gating strategy isapplied, based on the L4 interface activity. + */ + typedef TSingleBitField<0> T_AUTOIDLE ; + + /** + 1 SOFTRESET Software reset. This bit is automatically reset by the RW 0 hardware. During reads, it always returns 0. + 0x0: Normal mode + 0x1: The module is reset. + */ + typedef TSingleBitField<1> T_SOFTRESET ; + + /** + 2 ENAWAKEUP Wake-up feature global control RW 0 + 0x0: No wake-up line assertion in idle mode + 0x1: Wake-up line assertion enabled in smart-idle mode + */ + typedef TSingleBitField<2> T_ENAWAKEUP ; + + /** + 4:3 IDLEMODE Power management, req/ack control RW 0x0 + 0x0: Force-idle. An idle request is acknowledged unconditionally. + 0x1: No-idle. An idle request is never acknowledged. + 0x2: Smart-idle. Acknowledgement to an idle request is given based on the internal activity of the module. + 0x3: Reserved. Do not use. + */ + class T_IDLEMODE : public TBitField<3, 2> + { + public : + enum TConstants + { + KForceIdle = TConstVal<0>::KValue, + KNoIdle = TConstVal<1>::KValue, + KSmartIdle = TConstVal<2>::KValue + } ; + } ; + + /** + 5 EMUFREE Emulation mode RW 0 + 0x0: Timer counter frozen in emulation + 0x1: Timer counter free-running in emulation + */ + typedef TSingleBitField<5> T_EMUFREE ; + + /** + 9:8 CLOCKACTIVITY Clock activity during wakeup mode period: RW 0x0 + 0x0: L4 interface and Functional clocks can be switched off. + 0x1: L4 interface clock is maintained during wake-up period; Functional clock can be switched off. + 0x2: L4 interface clock can be switched off; Functional clock is maintained during wake-up period. + 0x3: L4 interface and Functional clocks are maintained during wake-up period. + */ + class T_CLOCKACTIVITY : public TBitField<8, 2> + { + public : + enum TConstants + { + KMaintainNeither = TConstVal<0>::KValue, + KMaintainIfClock = TConstVal<1>::KValue, + KMaintainFuncClock = TConstVal<2>::KValue, + KMaintainBoth = TConstVal<3>::KValue + } ; + } ; + + } ; // namespace TIOCP_CFG + + namespace TISTAT + { + /** + 0 RESETDONE Internal reset monitoring R 0 + 0x0: Internal module reset is ongoing. + 0x1: Reset completed + */ + typedef TSingleBitField<0> T_RESETDONE ; + + } ; // namespace TISTAT + + namespace TISR + { + /** + 0 MAT_IT_FLAG Pending match interrupt status RW 0 + Read 0x0: No match interrupt pending + Write 0x0: Status unchanged + Read 0x1: Match interrupt pending + Write 0x1: Status bit cleared + */ + typedef TSingleBitField<0> T_MAT_IT_FLAG ; + + /** + 1 OVF_IT_FLAG Pending overflow interrupt status RW 0 + Read 0x0: No overflow interrupt pending + Write 0x0: Status unchanged + Read 0x1: Overflow interrupt pending + Write 0x1: Status bit cleared + */ + typedef TSingleBitField<1> T_OVF_IT_FLAG ; + + /** + 2 TCAR_IT_FLAG Pending capture interrupt status RW 0 + Read 0x0: No capture interrupt event pending + Write 0x0: Status unchanged + Read 0x1: Capture interrupt event pending + Write 0x1: Status bit cleared + */ + typedef TSingleBitField<2> T_TCAR_IT_FLAG ; + + } ; // namespace TISR + + namespace TIER + { + /** + 0 MAT_IT_ENA Enable match interrupt RW 0 + 0x0: Disable match interrupt. + 0x1: Enable match interrupt. + */ + typedef TSingleBitField<0> T_MAT_IT_ENA ; + + /** + 1 OVF_IT_ENA Enable overflow interrupt RW 0 + 0x0: Disable overflow interrupt. + 0x1: Enable overflow interrupt. + */ + typedef TSingleBitField<1> T_OVF_IT_ENA ; + + /** + 2 TCAR_IT_ENA Enable capture interrupt RW 0 + 0x0: Disable capture interrupt. + 0x1: Enable capture interrupt. + */ + typedef TSingleBitField<2> T_TCAR_IT_ENA ; + + } ; // namespace TIER + + namespace TWER + { + /** + 0 MAT_WUP_ENA Enable match wake-up RW 0 + 0x0: Disable match wake-up. + 0x1: Enable match wake-up. + */ + typedef TSingleBitField<0> T_MAT_WUP_ENA ; + + /** + 1 OVF_WUP_ENA Enable overflow wake-up RW 0 + 0x0: Disable overflow wake-up. + 0x1: Enable overflow wake-up. + */ + typedef TSingleBitField<1> T_OVF_WUP_ENA ; + + /** + 2 TCAR_WUP_ENA Enable capture wake-up RW 0 + 0x0: Disable capture wake-up. + 0x1: Enable capture wake-up. + */ + typedef TSingleBitField<2> T_TCAR_WUP_ENA ; + + } ; // namespace TWER + + namespace TCLR + { + /** + 0 ST Start/stop timer control RW 0 + 0x0: Stop the timer + 0x1: Start the timer + */ + typedef TSingleBitField<0> T_ST ; + + /** + 1 AR Autoreload mode RW 0 + 0x0: One-shot mode overflow + 0x1: Autoreload mode overflow + */ + typedef TSingleBitField<1> T_AR ; + + /** + 4:2 PTV Trigger output mode + 0x0: The timer counter is prescaled with the value: RW 0x0 + 2(PTV+1). Example: PTV = 3, counter increases value (if started) after 16 functional clock periods. + */ + class T_PTV : public TBitField<2, 3> + { + public : + enum TConstants + { + KPS_2 = TConstVal<0>::KValue, + KPS_4 = TConstVal<1>::KValue, + KPS_8 = TConstVal<2>::KValue, + KPS_16 = TConstVal<3>::KValue, + KPS_32 = TConstVal<4>::KValue, + KPS_64 = TConstVal<5>::KValue, + KPS_128 = TConstVal<6>::KValue, + KPS_256 = TConstVal<7>::KValue + } ; + } ; + + /** + 5 PRE Prescaler enable RW 0 + 0x0: Prescaler disabled + 0x1: Prescaler enabled + */ + typedef TSingleBitField<5> T_PRE ; + + /** + 6 CE Compare enable RW 0 + 0x0: Compare disabled + 0x1: Compare enabled + */ + typedef TSingleBitField<6> T_CE ; + + /** + 7 SCPWM Pulse-width-modulation output pin default setting when RW 0 + counter is stopped or trigger output mode is set to no trigger. + 0x0: Default value of PWM_out output: 0 + 0x1: Default value of PWM_out output: 1 + */ + typedef TSingleBitField<7> T_SCPWM ; + + /** + 9:8 TCM Transition capture mode RW 0x0 + 0x0: No capture + 0x1: Capture on rising edges of EVENT_CAPTURE pin. + 0x2: Capture on falling edges of EVENT_CAPTURE pin. + 0x3: Capture on both edges of EVENT_CAPTURE pin. + */ + class T_TCM : public TBitField<8, 2> + { + public : + enum TConstants + { + KNoCapture = TConstVal<0>::KValue, + KRisingEdge = TConstVal<1>::KValue, + KFallingEdge = TConstVal<2>::KValue, + KBothEdges = TConstVal<3>::KValue + } ; + } ; + + /** + 11:10 TRG Trigger output mode RW 0x0 + 0x0: No trigger + 0x1: Overflow trigger + 0x2: Overflow and match trigger + 0x3: Reserved + */ + class T_IDLEMODE : public TBitField<10, 2> + { + public : + enum TConstants + { + KNoTrigger = TConstVal<0>::KValue, + KOverflow = TConstVal<1>::KValue, + KOverflowAndMatch = TConstVal<2>::KValue + } ; + } ; + + /** + 12 PT Pulse or toggle select bit RW 0 + 0x0: Pulse modulation + 0x1: Toggle modulation + */ + typedef TSingleBitField<12> T_PT ; + + /** + 13 CAPT_MODE Capture mode select bit (first/second) RW 0 + 0x0: Capture the first enabled capture event in TCAR1. + 0x1: Capture the second enabled capture event in TCAR2. + */ + typedef TSingleBitField<13> T_CAPT_MODE ; + + /** + 14 GPO_CFG PWM output/event detection input pin direction control: RW 0 + 0x0: Configures the pin as an output (needed when PWM mode is required) + 0x1: Configures the pin as an input (needed when capture mode is required) + */ + typedef TSingleBitField<14> T_GPO_CFG ; + + } ; // namespace TCLR + + namespace TWPS + { + /** + 0 W_PEND_TCLR Write pending for register GPT_TCLR R 0 + 0x0: Control register write not pending + 0x1: Control register write pending + */ + typedef TSingleBitField<0> T_W_PEND_TCLR ; + + /** + 1 W_PEND_TCRR Write pending for register GPT_TCRR R 0 + 0x0: Counter register write not pending + 0x1: Counter register write pending + */ + typedef TSingleBitField<1> T_W_PEND_TCRR ; + + /** + 2 W_PEND_TLDR Write pending for register GPT_TLDR R 0 + 0x0: Load register write not pending + 0x1: Load register write pending + */ + typedef TSingleBitField<2> T_W_PEND_TLDR ; + + /** + 3 W_PEND_TTGR Write pending for register GPT_TTGR R 0 + 0x0: Trigger register write not pending + 0x1: Trigger register write pending + */ + typedef TSingleBitField<3> T_W_PEND_TTGR ; + + /** + 4 W_PEND_TMAR Write pending for register GPT_TMAR R 0 + 0x0: Match register write not pending + 0x1: Match register write pending + */ + typedef TSingleBitField<4> T_W_PEND_TMAR; + + /** + 5 W_PEND_TPIR Write pending for register GPT_TPIR R 0 + Reserved for instances 3, 4, 5, 6, 7, 8, 9, 11, 12 Read returns reset value. R 0 + 0x0: Positive increment register write not pending + 0x1: Positive increment register write pending + */ + typedef TSingleBitField<5> T_W_PEND_TPIR ; + + /** + 6 W_PEND_TNIR Write pending for register GPT_TNIR R 0 + 0x0: Negative increment register write not pending + 0x1: Negative increment register write pending + Reserved for instances 3, 4, 5, 6, 7, 8, 9, 11, 12 Read returns reset value. R 0 + */ + typedef TSingleBitField<6> T_W_PEND_TNIR ; + + /** + 7 W_PEND_TCVR Write pending for register GPT_TCVR R 0 + 0x0: Counter value register write not pending + 0x1: Counter value register write pending + Reserved for instances 3, 4, 5, 6, 7, 8, 9, 11, 12 Read returns reset value. R 0 + */ + typedef TSingleBitField<7> T_W_PEND_TCVR ; + + /** + 8 W_PEND_TOCR Write pending for register GPT_TOCR R 0 + 0x0: Overflow counter register write not pending + 0x1: Overflow counter register write pending + Reserved for instances 3, 4, 5, 6, 7, 8, 9, 11, 12 Read returns reset value. R 0 + */ + typedef TSingleBitField<8> T_W_PEND_TOCR ; + + /** + 9 W_PEND_TOWR Write pending for register GPT_TOWR R 0 + 0x0: Overflow wrapping register write not pending + 0x1: Overflow wrapping register write pending + Reserved for instances 3, 4, 5, 6, 7, 8, 9, 11, 12 Read returns reset value. R 0 + */ + typedef TSingleBitField<9> T_W_PEND_TOWR ; + + } ; // namespace TWPS + + namespace TSICR + { + /** + 1 SFT Reset software functional registers. This bit is automatically reset RW 0 + by the hardware. During reads, it always returns 0. + 0x0: Normal functional mode + 0x1: The functional registers are reset. + */ + typedef TSingleBitField<1> T_SFT ; + + /** + 2 POSTED Posted mode selection RW 1 + 0x0: Non-posted mode selected + 0x1: Posted mode selected + */ + typedef TSingleBitField<2> T_POSTED ; + + } ; // namespace TSICR + + namespace TOCR + { + /** + 23:0 OVF_COUNTER_VALUE The number of overflow events. RW 0x00000000 + */ + class T_OVF_COUNTER_VALUE : public TBitField<0, 24> + { + public : + enum TConstants + { + } ; + } ; + + } ; // namespace TOCR + + namespace TOWR + { + /** + 23:0 OVF_WRAPPING_VALUE The number of masked interrupts. RW 0x00000000 + */ + class T_OVF_WRAPPING_VALUE : public TBitField<0, 24> + { + public : + enum TConstants + { + } ; + } ; + + } ; // namespace TOWR + + enum TBaseAddress + { + KGPTIMER1_Base = TVirtual<0x48318000>::Value, + KGPTIMER2_Base = TVirtual<0x49032000>::Value, + KGPTIMER3_Base = TVirtual<0x49034000>::Value, + KGPTIMER4_Base = TVirtual<0x49036000>::Value, + KGPTIMER5_Base = TVirtual<0x49038000>::Value, + KGPTIMER6_Base = TVirtual<0x4903A000>::Value, + KGPTIMER7_Base = TVirtual<0x4903C000>::Value, + KGPTIMER8_Base = TVirtual<0x4903E000>::Value, + KGPTIMER9_Base = TVirtual<0x49040000>::Value, + KGPTIMER10_Base = TVirtual<0x48086000>::Value, + KGPTIMER11_Base = TVirtual<0x48088000>::Value, + KGPTIMER12_Base = TVirtual<0x48304000>::Value, + } ; + + enum TTimerNumber + { + EGpTimer1, + EGpTimer2, + EGpTimer3, + EGpTimer4, + EGpTimer5, + EGpTimer6, + EGpTimer7, + EGpTimer8, + EGpTimer9, + EGpTimer10, + EGpTimer11, + EGpTimer12 + }; + + typedef void (*TTimerIsr)(TAny*) ; + + template + struct TTimerTraits + { + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER1_Base, + KIrq = EOmap3530_IRQ37_GPT1_IRQ, + KClockSelMask = TSingleBitField<7>::KMask, + KClockSelValue = TSingleBitField<7>::KOn, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER2_Base, + KIrq = EOmap3530_IRQ38_GPT2_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER3_Base, + KIrq = EOmap3530_IRQ39_GPT3_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER4_Base, + KIrq = EOmap3530_IRQ40_GPT4_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER5_Base, + KIrq = EOmap3530_IRQ41_GPT5_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER6_Base, + KIrq = EOmap3530_IRQ42_GPT6_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER7_Base, + KIrq = EOmap3530_IRQ43_GPT7_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER8_Base, + KIrq = EOmap3530_IRQ44_GPT8_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER9_Base, + KIrq = EOmap3530_IRQ45_GPT9_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER10_Base, + KIrq = EOmap3530_IRQ46_GPT10_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER11_Base, + KIrq = EOmap3530_IRQ47_GPT11_IRQ, + } ; + } ; + + template<> + struct TTimerTraits + { + enum TraitValues + { + KBaseAddress = KGPTIMER12_Base, + KIrq = EOmap3530_IRQ95_GPT12_IRQ, + KClockSelReg = 0, + KClockSelMask = 0, + KClockSel32K = 0, + KClockSelSys = 0, + KClockSelValue = KClockSel32K + } ; + } ; + + /** + An interface template for OMAP3530 General Purpose timer functionality. + */ + template + class TGPT + { + protected : + enum TRegisterOffsets + { + KTIOCP_CFG_Offset = 0x010, + KTISTAT_Offset = 0x014, + KTISR_Offset = 0x018, + KTIER_Offset = 0x01C, + KTWER_Offset = 0x020, + KTCLR_Offset = 0x024, + KTCRR_Offset = 0x028, + KTLDR_Offset = 0x02C, + KTTGR_Offset = 0x030, + KTWPS_Offset = 0x034, + KTMAR_Offset = 0x038, + KTCAR1_Offset = 0x03C, + KTSICR_Offset = 0x040, + KTCAR2_Offset = 0x044 + } ; + enum TConstants + { + KHz = 1000, + KClockInputFrequency = 32768, + } ; + + public : + static inline TOmap3530_IRQ Irq() + { + return TOmap3530_IRQ(TTimerTraits::KIrq) ; + } + static inline TBool CanWriteTCLR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCLR::KOn)) ; + } + static inline TBool CanWriteTCRR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCRR::KOn)) ; + } + static inline TBool CanWriteTLDR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TLDR::KOn)) ; + } + static inline TBool CanWriteTTGR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TTGR::KOn)) ; + } + static inline TBool CanWriteTMAR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TMAR::KOn)) ; + } + static inline void Reset() + { + iTIOCP_CFG.Write(TIOCP_CFG::T_SOFTRESET::KOn) ; + } + static inline TBool ResetComplete() + { + return (TISTAT::T_RESETDONE::KOn & iTISTAT.Read()) ; + } + static inline TBool WriteOutstanding() + { + return (iTWPS.Read()) ; + } + + public : + static TReg32_RW<(TTimerTraits::KBaseAddress + KTIOCP_CFG_Offset)> iTIOCP_CFG ; + static TReg32_R<(TTimerTraits::KBaseAddress + KTISTAT_Offset)> iTISTAT ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTISR_Offset)> iTISR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTIER_Offset)> iTIER ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTWER_Offset)> iTWER ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTCLR_Offset)> iTCLR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTCRR_Offset)> iTCRR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTLDR_Offset)> iTLDR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTTGR_Offset)> iTTGR ; + static TReg32_R<(TTimerTraits::KBaseAddress + KTWPS_Offset)> iTWPS ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTMAR_Offset)> iTMAR ; + static TReg32_R<(TTimerTraits::KBaseAddress + KTCAR1_Offset)> iTCAR1 ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTSICR_Offset)> iTSICR ; + static TReg32_R<(TTimerTraits::KBaseAddress + KTCAR2_Offset)> iTCAR2 ; + } ; // class TGPTi + + /** + + An interface template for OMAP3530 Microsecond aligned timer functionality. + Encapsulates the extra registers provided for timers 1, 2 and 10. + */ + template + class TMsSyncTimer : public TGPT + { + using TGPT::iTWPS ; + using TGPT::iTLDR ; + + protected : + enum TRegisterOffsets + { + KTPIR_Offset = 0x048, + KTNIR_Offset = 0x04C, + KTCVR_Offset = 0x050, + KTOCR_Offset = 0x054, + KTOWR_Offset = 0x058 + } ; + + public : + enum TRegisterValues + { + KInitialLoad = 0xFFFFFFE0, + KInitialPIR = 0x38A40, + KInitialNIR = 0xFFF44800 + } ; + + static inline TBool CanWriteTPIR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TPIR::KOn)) ; + } + static inline TBool CanWriteTNIR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TNIR::KOn)) ; + } + static inline TBool CanWriteTCVR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCVR::KOn)) ; + } + static inline TBool CanWriteTOCR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TOCR::KOn)) ; + } + static inline TBool CanWriteTOWR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TOWR::KOn)) ; + } + + static inline void ConfigureFor1Ms() + { + iTLDR.Write( KInitialLoad ); + iTPIR.Write( KInitialPIR ); + iTNIR.Write( KInitialNIR ); + } + + public : + static TReg32_RW<(TTimerTraits::KBaseAddress + KTPIR_Offset)> iTPIR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTNIR_Offset)> iTNIR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTCVR_Offset)> iTCVR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTOCR_Offset)> iTOCR ; + static TReg32_RW<(TTimerTraits::KBaseAddress + KTOWR_Offset)> iTOWR ; + } ; // class TMsSyncTimer + + + } // namespage GPTimer + + typedef GPTimer::TMsSyncTimer TGpTimer1 ; + typedef GPTimer::TMsSyncTimer TGpTimer2 ; + typedef GPTimer::TGPT TGpTimer3 ; + typedef GPTimer::TGPT TGpTimer4 ; + typedef GPTimer::TGPT TGpTimer5 ; + typedef GPTimer::TGPT TGpTimer6 ; + typedef GPTimer::TGPT TGpTimer7 ; + typedef GPTimer::TGPT TGpTimer8 ; + typedef GPTimer::TGPT TGpTimer9 ; + typedef GPTimer::TMsSyncTimer TGpTimer10 ; + typedef GPTimer::TGPT TGpTimer11 ; + typedef GPTimer::TGPT TGpTimer12 ; + + + /** + An interface template for OMAP3530 32-KHz aligned timer functionality. + */ + class T32KhzSyncTimer + { + protected : + enum TRegisterAddress + { + KREG_32KSYNCNT_SYSCONFIG = TVirtual<0x48320004>::Value, + KREG_32KSYNCNT_CR = TVirtual<0x48320010>::Value + } ; + + public : + static TReg32_RW iSysConfig ; + static TReg32_R iCR ; + + private : + } ; // class TMsSyncTimer + + } // namespace Omap3530 + + } // namespace TexasInstruments + + +// **** TEST CODE **** +//# define HEADER_OMAP3530_TIMER_H_DO_COMPILE_TIME_CHECK_TESTS 1 +# ifdef HEADER_OMAP3530_TIMER_H_DO_COMPILE_TIME_CHECK_TESTS + inline void CompileTimeChecks(void) + { + __ASSERT_COMPILE((TI::Omap3530::GPTimer::TIOCP_CFG::T_IDLEMODE::KSmartIdle == (2 << 3))) ; + __ASSERT_COMPILE((TI::Omap3530::GPTimer::TIOCP_CFG::T_CLOCKACTIVITY::KMaintainIfClock == (1 << 8))) ; + __ASSERT_COMPILE((TI::Omap3530::GPTimer::KGPTIMER1_Base == (0xC6318000))) ; + __ASSERT_COMPILE((0)) ; // Prove that testing is happening + } +# endif +#endif /* ndef HEADER_OMAP3530_TIMER_H_INCLUDED */ diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/inc/omap3530_timer.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/inc/omap3530_timer.inl Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,136 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/inc/omap3530_timer.inl +// + + +#ifndef __OMAP3530_TIMER_INL__ +# define _OMAP3530_TIMER_INL__ + +/** +@file + omap3530_timer.inl header file +This file provides timer handling for the omap3530 timers +@publishedAll +@released +*/ + +# include + +inline void CompileTimeChecks(void) ; + +namespace OMAP3530 + { + + namespace GPTimer + { + + template + inline TOmap3530_IRQ TGPTi::Irq() + { + return TOmap3530_IRQ(TTimerTraits::KIrq) ; + } + + template + inline void TGPTi::SelectClock() + { + typename TTimerTraits::TClockSelReg reg ; + reg.Modify(!TTimerTraits::KClockSelMask, + TTimerTraits::KClockSelValue) ; + } + + template + inline TBool TGPTi::CanWriteTCLR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCLR::KOn)) ; + } + + template + inline TBool TGPTi::CanWriteTCRR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCRR::KOn)) ; + } + + template + inline TBool TGPTi::CanWriteTLDR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TLDR::KOn)) ; + } + + template + inline TBool TGPTi::CanWriteTTGR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TTGR::KOn)) ; + } + + template + inline TBool TGPTi::CanWriteTMAR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TMAR::KOn)) ; + } + + template + inline void TGPTi::Reset() + { + iTIOCP_CFG.Write(TIOCP_CFG::T_SOFTRESET::KOn) ; + } + + template + inline TBool TGPTi::ResetComplete() + { + return (TISTAT::T_RESETDONE::KOn & iTISTAT.Read()) ; + } + + template + inline ::TBool TGPTi::WriteOutstanding() + { + return (iTWPS.Read()) ; + } + + + template + inline TBool TMsSyncTimer::CanWriteTPIR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TPIR::KOn)) ; + } + + template + inline TBool TMsSyncTimer::CanWriteTNIR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TNIR::KOn)) ; + } + + template + inline TBool TMsSyncTimer::CanWriteTCVR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TCVR::KOn)) ; + } + + template + inline TBool TMsSyncTimer::CanWriteTOCR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TOCR::KOn)) ; + } + + template + inline TBool TMsSyncTimer::CanWriteTOWR() + { + return (0 == (iTWPS.Read() & TWPS::T_W_PEND_TOWR::KOn)) ; + } + + } // namespace GPTimer + + } // namespace OMAP3530 + +#endif /* ndef __OMAP3530_TIMER_INL__ */ diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/src/assp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/src/assp.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,173 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/src/assp.cpp +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PS_PER_SECOND 1000000000000 +#define US_PER_SECOND 1000000 + + +Omap3530Assp* Omap3530Assp::Variant; + + +DECLARE_STANDARD_ASSP() + +EXPORT_C Omap3530Assp::Omap3530Assp() + { + Kern::Printf("%s::%s",__FUNCTION__,__FUNCTION__); + + } + +EXPORT_C TMachineStartupType Omap3530Assp::StartupReason() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Assp::StartupReason")); +#ifdef _DEBUG // REMOVE THIS + TUint s = Kern::SuperPage().iHwStartupReason; + __KTRACE_OPT(KBOOT,Kern::Printf("CPU page value %08x", s)); +#endif // REMOVE THIS + // + // TO DO: (mandatory) + // + // Map the startup reason read from the Super Page to one of TMachineStartupType enumerated values + // and return this + // + return EStartupCold; // EXAMPLE ONLY + } + +EXPORT_C void Omap3530Assp::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Assp::Init1()")); + + Variant = (Omap3530Assp*)Arch::TheAsic(); + __ASSERT_ALWAYS( Variant != NULL, Kern::Fault( "assp Init1: no variant", 0 ) ); + + Omap3530Interrupt::Init1(); // initialise the ASSP interrupt controller + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Assp::Init1() OUT")); + } + + + + + +EXPORT_C TUint64 Omap3530Assp::GetXtalFrequency() + { + return Prcm::ClockFrequency( Prcm::EClkSysClk ); + } + + +EXPORT_C void Omap3530Assp::Init3() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Assp::Init3() >")); + + Prcm::Init3(); + + TArmCpuId id={0}; + ArmCpuVersionId(id); + Omap3530Assp::NanoWaitCalibration(); + TUint64 hz = Prcm::ClockFrequency( Prcm::EClkMpu ); + Kern::Printf("CPU at %d MHz",(TInt)hz/1000000); + Kern::SetNanoWaitHandler(NanoWait); + Omap3::MsTick::Start(); + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Assp::Init3() <")); + } + + +/* + * Returns the number of microseconds for the system millisecond tick; + * */ +EXPORT_C TInt Omap3530Assp::MsTickPeriod() + { + return 1000; + } + + + + +EXPORT_C TUint32 Omap3530Assp::NanoWaitCalibration() + { + // Return the minimum time in nano-seconds that it takes to execute the following code: + // nanowait_loop: + // subs r0, r0, r1 + // bhi nanowait_loop + //THE cpu frequency can change so this calibration must be achieved each time the power management modifies the cpu freq. + + TInt cycles_ns = Prcm::ClockFrequency( Prcm::EClkMpu ) /1000000000 ; + + + return 2 * cycles_ns; // 2 cycles approx 3.333ns at 600MHz + } + + + +EXPORT_C void Omap3530Assp::ArmCpuVersionId(TArmCpuId &id) +// +// Read and return the the CPU ID +// + { + TUint armString = Kern::SuperPage().iCpuId; + + id.Implementor = (armString & 0xFF000000) >>24; + id.Variant = (armString & 0x00F00000) >>20; + id.Architecture = (armString & 0x000F0000) >>16; + id.Primary = (armString & 0x0000FFF0)>> 4; + id.Revision = (armString & 0x0000000F); + + Kern::Printf("%s %s Rev:%d",__FUNCTION__,(id.Primary ==0xc08)?"CORTEX_A8":"UNKNOWN",id.Revision); + } + +EXPORT_C Omap3530Uart::TUartNumber Omap3530Assp::DebugPortNumber() +// +// Return index of the debug UART Omap3530Uart::EUart([0-2]|None) +// + { + Omap3530Uart::TUartNumber debugPort; + switch (Kern::SuperPage().iDebugPort) + { + case 0: + debugPort = Omap3530Uart::EUart0; + break; + case 1: + debugPort = Omap3530Uart::EUart1; + break; + case 2: + debugPort = Omap3530Uart::EUart2; + break; + + default: + debugPort = Omap3530Uart::EUartNone; + break; + } + return debugPort; + } + + + +EXPORT_C TUint Omap3530Assp::ProcessorPeriodInPs() +// +// Return CPU clock period in picoseconds +// + { + TUint64 cycleTime = (Prcm::ClockFrequency( Prcm::EClkMpu ) * US_PER_SECOND) / PS_PER_SECOND ; + return (TUint) cycleTime; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/src/interrupts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/src/interrupts.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,630 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/src/interrupts.cpp +// Template ASSP interrupt control and dispatch +// + +#include +#include +#include + +SInterruptHandler Omap3530Interrupt::Handlers[KNumOmap3530Ints]; +MInterruptDispatcher* TheDispatchers[ KIrqRangeCount ]; + +#define OMAP3530_INTERRUPTS_INC + +#ifndef OMAP3530_INTERRUPTS_INC +//TODO: Implement the asm IRQ & FIQ dispatcher +#include "interrupts.cia" + +#else + +void IrqDispatch() +{ + CHECK_PRECONDITIONS( MASK_INTERRUPTS_DISABLED ,Kern::Fault("IRQS ENABLED While reading IVT",__FILE__)); + + TUint irqVector = AsspRegister::Read32(INTCPS_SIR_IRQ) &INTCPS_PENDING_MASK; + + TUint irqFlags = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock); + SInterruptHandler handler = Omap3530Interrupt::Handlers[irqVector]; + __SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irqFlags); + + //may be useful in the interim but dont want a print in every dispatch + //__KTRACE_OPT(KHARDWARE,Kern::Printf("IRQDISPATCH V %x isr %x ptr %x",irqVector,handler.iIsr,handler.iPtr)); + //execute handler now + ((TIsr)*handler.iIsr)(handler.iPtr); + + AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR); +} + +void FiqDispatch() +{ + Omap3530Interrupt::Spurious((TAny*)KErrNotFound); +} + +#endif + +#ifndef _DEBUG + +void Omap3530Interrupt::dumpINTCState(){} +void Omap3530Interrupt::dumpIVTState(){} +void TestHandler(TAny * wibble){} +EXPORT_C void TestInterrupts(TInt id,TIsr func){} +void TestExternalInterrupts(){} +EXPORT_C void ClearAndDisableTestInterrupt(TInt anId){} +void TestPriorities(){} +#else + +void Omap3530Interrupt::dumpINTCState() +{ + Kern::Printf("INTCPS_SYSCONFIG %x",AsspRegister::Read32(INTCPS_SYSCONFIG)); + Kern::Printf("INTCPS_SYSSTATUS %x",AsspRegister::Read32(INTCPS_SYSSTATUS)); + Kern::Printf("INTCPS_SIR_IRQ %x",AsspRegister::Read32(INTCPS_SIR_IRQ)); + Kern::Printf("INTCPS_SIR_FIQ %x",AsspRegister::Read32(INTCPS_SIR_FIQ)); + Kern::Printf("INTCPS_CONTROL %x",AsspRegister::Read32(INTCPS_CONTROL)); + Kern::Printf("INTCPS_PROTECTION %x",AsspRegister::Read32(INTCPS_PROTECTION)); + Kern::Printf("INTCPS_IDLE %x",AsspRegister::Read32(INTCPS_IDLE)); + Kern::Printf("INTCPS_IRQ_PRIORITY %x",AsspRegister::Read32(INTCPS_IRQ_PRIORITY)); + Kern::Printf("INTCPS_FIQ_PRIORITY %x",AsspRegister::Read32(INTCPS_FIQ_PRIORITY)); + Kern::Printf("INTCPS_THRESHOLD %x",AsspRegister::Read32(INTCPS_THRESHOLD)); + Kern::Printf("INTCPS_ITR0 %x",AsspRegister::Read32(INTCPS_ITR(0))); + Kern::Printf("INTCPS_ITR1 %x",AsspRegister::Read32(INTCPS_ITR(1))); + Kern::Printf("INTCPS_ITR 2%x",AsspRegister::Read32(INTCPS_ITR(2))); + Kern::Printf("INTCPS_MIR0 %x",AsspRegister::Read32(INTCPS_MIRn(0))); + Kern::Printf("INTCPS_MIR1 %x",AsspRegister::Read32(INTCPS_MIRn(1))); + Kern::Printf("INTCPS_MIR2 %x",AsspRegister::Read32(INTCPS_MIRn(2))); + Kern::Printf("INTCPS_PENDING_IRQ0 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(0))); + Kern::Printf("INTCPS_PENDING_IRQ1 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(1))); + Kern::Printf("INTCPS_PENDING_IRQ2 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(2))); + Kern::Printf("INTCPS_PENDING_FIQ1 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(0))); + Kern::Printf("INTCPS_PENDING_FIQ0 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(1))); + Kern::Printf("INTCPS_PENDING_FIQ2 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(2))); + Kern::Printf("INTCPS_ILR0 %x",AsspRegister::Read32(INTCPS_ILRM(0))); + Kern::Printf("INTCPS_ILR1 %x",AsspRegister::Read32(INTCPS_ILRM(1))); + Kern::Printf("INTCPS_ILR2 %x",AsspRegister::Read32(INTCPS_ILRM(2))); + Kern::Printf("INTCPS_ISRSET0 %x", AsspRegister::Read32(INTCPS_ISRSET(0))); + Kern::Printf("INTCPS_ISRSET1 %x", AsspRegister::Read32(INTCPS_ISRSET(1))); + Kern::Printf("INTCPS_ISRSET2 %x", AsspRegister::Read32(INTCPS_ISRSET(2))); +} + + +void Omap3530Interrupt::dumpIVTState() +{ + //NOTE NOT THREAD SAFE ! + TInt reg; + TInt bit; + + __KTRACE_OPT(KHARDWARE,Kern::Printf("Omap3530Interrupt::dumpIVTState")); + + for(TInt i=0;i> bit),priVal >> 2); + } +} + +void TestHandler(TAny * wibble) +{ + TInt irq = (TInt)wibble; + __KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler IN IRQ %d",irq)); + Omap3530Interrupt::dumpINTCState(); + ClearAndDisableTestInterrupt(irq); + Omap3530Interrupt::dumpINTCState(); + __KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler Interrupts OK ",irq)); +} + + + +void TestPriHandler(TAny * wibble) +{ + TInt irq = (TInt)wibble; + __KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler PRI IN IRQ %d",irq)); + Omap3530Interrupt::dumpINTCState(); + ClearAndDisableTestInterrupt(irq); + Omap3530Interrupt::dumpINTCState(); + + __KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler Interrupts OK ",irq)); +} + + +EXPORT_C void ClearAndDisableTestInterrupt(TInt anId) +{ + TInt reg,bit; + TInt irq = (TInt)anId; + __KTRACE_OPT(KHARDWARE,Kern::Printf("ClearAndDisableTestInterrupt IN IRQ %d",irq)); + + Omap3530Interrupt::GetRegisterAndBitOffset(irq,reg,bit); + + AsspRegister::Write32(INTCPS_ISR_CLEAR(reg),1 << bit); + + Interrupt::Clear(irq); + + Interrupt::Disable(irq); + + Interrupt::Unbind(irq); + + + +} + +void TestPriorities() +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Priorities")); + Interrupt::Bind(EOmap3530_IRQ4_MCBSP2_ST_IRQ,TestPriHandler,(TAny*)EOmap3530_IRQ4_MCBSP2_ST_IRQ); + Interrupt::Bind(EOmap3530_IRQ5_MCBSP3_ST_IRQ,TestPriHandler,(TAny*)EOmap3530_IRQ5_MCBSP3_ST_IRQ); + + + TInt r = Interrupt::SetPriority(EOmap3530_IRQ4_MCBSP2_ST_IRQ,0); + if(r != KErrNone) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("%s SP1 r %d ",__FUNCTION__,r)); + } + + r = Interrupt::SetPriority(EOmap3530_IRQ5_MCBSP3_ST_IRQ,0); + if(r != KErrNone) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("%s SP2 r %d ",__FUNCTION__,r)); + } + + Omap3530Interrupt::dumpINTCState(); + + Interrupt::Enable(EOmap3530_IRQ4_MCBSP2_ST_IRQ); + Interrupt::Enable(EOmap3530_IRQ5_MCBSP3_ST_IRQ); + + + Omap3530Interrupt::dumpIVTState(); + TInt reg,bit,bit1; + Omap3530Interrupt::GetRegisterAndBitOffset(EOmap3530_IRQ5_MCBSP3_ST_IRQ,reg,bit); + Omap3530Interrupt::GetRegisterAndBitOffset(EOmap3530_IRQ4_MCBSP2_ST_IRQ,reg,bit1); + + AsspRegister::Write32(INTCPS_ISRSET(reg),((1 << bit) | ( 1 << bit1))); +} + +EXPORT_C void TestInterrupts(TInt id,TIsr func) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("TestInterrupts")); + Interrupt::Bind(id,func,(TAny*)id); + + Omap3530Interrupt::dumpIVTState(); + + Interrupt::Enable(id); + Omap3530Interrupt::dumpIVTState(); + + TInt reg,bit; + Omap3530Interrupt::GetRegisterAndBitOffset(id,reg,bit); + + AsspRegister::Write32(INTCPS_ISRSET(reg),1 << bit); + Omap3530Interrupt::dumpINTCState(); +} + + + +#endif + + +void Omap3530Interrupt::DisableAndClearAll() +{ + // Disable then clear all Hardware Interrupt sources + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll 0 %x 1 %x 2 %x", + INTCPS_MIR_SETn(0), + INTCPS_MIR_SETn(1), + INTCPS_MIR_SETn(2))); + + //first we mask all vectors + AsspRegister::Write32(INTCPS_MIR_SETn(0),INTCPS_MIR_ALL_SET); + AsspRegister::Write32(INTCPS_MIR_SETn(1),INTCPS_MIR_ALL_SET); + AsspRegister::Write32(INTCPS_MIR_SETn(2),INTCPS_MIR_ALL_SET); + + AsspRegister::Write32(INTCPS_ISR_CLEAR(0),0xffffffff); + AsspRegister::Write32(INTCPS_ISR_CLEAR(1),0xffffffff); + AsspRegister::Write32(INTCPS_ISR_CLEAR(2),0xffffffff); + + + AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR|INTCPS_CONTROL_FIQ_CLEAR); + + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll INTCPS_SIR_IRQ %x at %x",AsspRegister::Read32(INTCPS_SIR_IRQ),INTCPS_BASE )); + + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll OUT")); +} + +void Omap3530Interrupt::Init1() +{ + + __KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::Init1()")); + + //make sure everything is off first + + DisableAndClearAll(); + + //Initialise the IVT to the spurious handler + //interrupts are not enabled yet but take mutex on the IVT anyway + + TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530IVTLock); + for (TInt i=0; i= (TUint)KNumOmap3530Ints) + { + return KErrArgument; + } + else + { + aOffset = (anId % 32); + aReg = (anId / 32); + } + return KErrNone; + +} +// +// The APIs below assume ther is a second level Interrupt controller located at Omap3530Assp::Variant level which handles +// interrupts generated by hardware at that level. +// + +EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind id=%d func=%08x ptr=%08x Var %x",aId,aIsr,aPtr,Omap3530Assp::Omap3530Assp::Variant)); + TInt r; + // if ID indicates a chained interrupt, call Omap3530Assp::Variant... + + TInt index = aId >> KIrqRangeIndexShift; + if( index == 0 ) + { + if ((TUint)aId >= (TUint)KNumOmap3530Ints) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind id OOB %d MAX %d",aId,KNumOmap3530Ints)); + r = KErrArgument; + } + else + { + TUint irq = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock); + SInterruptHandler& h=Omap3530Interrupt::Handlers[aId]; + + if (h.iIsr != Omap3530Interrupt::Spurious) + { + r=KErrInUse; + __SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq); + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind Cant Bind irq (IN_USE %d",aId)); + } + else + { + __SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq); + TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530IVTLock); + h.iPtr=aPtr; + h.iIsr=aIsr; + __SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530IVTLock,irq); + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind BOUND %d",aId)); + r = KErrNone; + } + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind OUT")); + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->Bind( aId, aIsr, aPtr ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind extint %d",aId)); + return Omap3530Assp::Variant->InterruptBind(aId,aIsr,aPtr); + } + else + { + r = KErrArgument; + } + + return r; + } + +EXPORT_C TInt Interrupt::Unbind(TInt aId) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind id=%d",aId)); + TInt r; + TInt index = aId >> KIrqRangeIndexShift; + + if( index == 0 ) + { + if ((TUint)aId >= (TUint)KNumOmap3530Ints) + { + r=KErrArgument; + } + else + { + TUint irq = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock); + SInterruptHandler& h=Omap3530Interrupt::Handlers[aId]; + __SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq); + + if (h.iIsr == Omap3530Interrupt::Spurious) + { + r=KErrGeneral; + } + else + { + TInt isrBitOffset=0; + TInt reg=0; + Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset); +#ifdef _DEBUG + TUint val = AsspRegister::Read32(INTCPS_MIRn(reg)); + if( ! (val & (0x1 << isrBitOffset))) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind THIS IRQ IS STILL ENABLED - update your code")); + } + + TUint irqVector = AsspRegister::Read32(INTCPS_SIR_IRQ) &INTCPS_PENDING_MASK; + if(irqVector == aId ) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind THIS IRQ IS STILL PENDING - update your code")); + } +#endif + TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530INTCLock); + h.iPtr=(TAny*)aId; + h.iIsr=Omap3530Interrupt::Spurious; + __SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530INTCLock,irq); + + //calculate the register and bit offset for this id + //and disable the corresponding Hardware Interrupt source + + AsspRegister::Write32(INTCPS_MIR_SETn(reg),(1 << isrBitOffset)); + r = KErrNone; + } + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->Unbind( aId ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + r = Omap3530Assp::Variant->InterruptUnbind(aId); + } + else + { + r = KErrArgument; + } + + return r; + } + +EXPORT_C TInt Interrupt::Enable(TInt aId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Enable id=%d",aId)); + TInt r; + TInt index = aId >> KIrqRangeIndexShift; + + if( index == 0 ) + { + if ((TUint)aId>=(TUint)KNumOmap3530Ints) + { + r=KErrArgument; + } + else if (Omap3530Interrupt::Handlers[aId].iIsr==Omap3530Interrupt::Spurious) + { + r=KErrNotReady; + } + else + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Enable %d",aId)); + // Enable the corresponding Hardware Interrupt source + TInt isrBitOffset=0; + TInt reg=0; + Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset); + AsspRegister::Write32(INTCPS_MIR_CLEARn(reg),(1 << isrBitOffset)); + r = KErrNone; + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->Enable( aId ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + r = Omap3530Assp::Variant->InterruptEnable(aId); + } + else + { + r = KErrArgument; + } + return r; + } + +EXPORT_C TInt Interrupt::Disable(TInt aId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Disable id=%d",aId)); + TInt r; + TInt index = aId >> KIrqRangeIndexShift; + + if( index == 0 ) + { + if ((TUint)aId >= (TUint)KNumOmap3530Ints) + { + r=KErrArgument; + } + else + { + // Disable the corresponding Hardware Interrupt source + TInt isrBitOffset=0; + TInt reg=0; + Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset); + AsspRegister::Write32(INTCPS_MIR_SETn(reg),(1 << isrBitOffset)); + r = KErrNone; + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->Disable( aId ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + r = Omap3530Assp::Variant->InterruptDisable(aId); + } + else + { + r = KErrArgument; + } + + return r; + } + +EXPORT_C TInt Interrupt::Clear(TInt aId) + { + //__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Clear id=%d",aId)); + TInt r = KErrUnknown; + TInt index = aId >> KIrqRangeIndexShift; + + if( index == 0 ) + { + if ((TUint)aId >= (TUint)KNumOmap3530Ints) + { + r=KErrArgument; + } + else + { + TInt curVector = AsspRegister::Read32(INTCPS_SIR_IRQ); + // Clear the corresponding Hardware Interrupt source + if(curVector == aId) + { + //TODO: determine whether we are dealing with a FIQ or IRQ source + // for now assuming all are IRQS + //__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Clear id=%d x %x",aId,curVector )); + AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR); + } + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->Clear( aId ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + r = Omap3530Assp::Variant->InterruptClear(aId); + } + else + { + r = KErrArgument; + } + + return r; + } + +EXPORT_C TInt Interrupt::SetPriority(TInt aId, TInt aPriority) + { + // If Interrupt priorities are supported the dispatchers need to take this in consideration + + // (IrqDispatch/FiqDispatch) + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::SetPriority id=%d pri=%d",aId,aPriority)); + + TInt r; + TInt index = aId >> KIrqRangeIndexShift; + + if( index == 0 ) + { + if ((TUint)aId >= (TUint)KNumOmap3530Ints) + { + r = KErrArgument; + } + else + { + TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530INTCLock); + TUint curIRLMi = AsspRegister::Read32(INTCPS_ILRM(aId)); + curIRLMi = ( curIRLMi & 0x000000003) | (aPriority << 0x2) ; + AsspRegister::Write32(INTCPS_ILRM(aId),curIRLMi); + __SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530INTCLock,irq); + r = KErrNone; + } + } + else if( index > 0 ) + { + r = TheDispatchers[ index ]->SetPriority( aId, aPriority ); + } + else if (Omap3530Assp::Variant->IsExternalInterrupt(aId)) + { + r = KErrNotSupported; + } + else + { + r = KErrArgument; + } + + return r; + } + + +EXPORT_C void MInterruptDispatcher::Register( TIrqRangeIndex aIndex ) + { + __ASSERT_ALWAYS( TheDispatchers[ aIndex ] == NULL, Kern::Fault( "interrupts.cpp", __LINE__ ) ); + TheDispatchers[ aIndex ] = this; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/src/kaomap3530.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/src/kaomap3530.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,42 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/src/komap3530.mmp +// + +#include +#include + + +target AsspTarget(kaomap3530,dll) +targettype kext +linkas kaomap3530.dll + +source interrupts.cpp assp.cpp register.cpp + +source omap3530_assp.cia + +deffile ../def/~/kaomap3530.def + +LIBRARY AsspTarget(prcm, lib) +LIBRARY _omap3XXX_mstick.lib + +nostrictdef + +epocallowdlldata + +uid 0x1000008d 0x100000b9 + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/src/omap3530_assp.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/src/omap3530_assp.cia Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,66 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/src/omap3530_assp.cia +// omap3530ASSP architecture layer +// + + + +#include +#include + +__NAKED__ TUint64 DoRead64(TLinAddr /*aAddr*/) + { + asm("ldmia r0, {r0-r1} "); + __JUMP(,lr); + } + + +__NAKED__ void DoWrite64(TLinAddr aAddr, TUint64 aValue) + { +#ifdef __EABI__ + asm("stmia r0, {r2-r3} "); +#else + asm("stmia r0, {r1-r2} "); +#endif + __JUMP(,lr); + } + +EXPORT_C __NAKED__ void Omap3530Assp::BootWaitMilliSeconds(TInt aDuration) +// +// Active waiting loop (not to be used after System Tick timer has been set up - Init3() +// + { + // + // TO DO: (optional) + // + // Program a Hardware Timer to generate the required duration, and then loop until the timer expires. + // Do NOT use interrupts! + // + } + + +__NAKED__ void Omap3530Assp::NanoWait(TUint32 aInterval) +// +// Wait for aInterval nanoseconds +// + { + // TO DO: work out the correct values for the hardware + + asm("sub r0, r0, #100"); + asm("1:"); + asm("subs r0, r0, #20"); + asm("bgt 1b"); + __JUMP(,lr); + } diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/src/register.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/assp/src/register.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,107 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/src/register.cpp +// + +#include +#include + +#ifdef __SMP__ +TSpinLock AsspLock(TSpinLock::EOrderGenericIrqLow1); +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// MHA - Modular Hardware Adaption +// +// Register Access +// +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// We need spin locks around read, modify, write operations because another CPU +// may access the same memory in between operations and potentially cause +// memory corruption. +/////////////////////////////////////////////////////////////////////////////// +EXPORT_C void AsspRegister::Modify8(TLinAddr aAddr, TUint8 aClearMask, TUint8 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint8 value = *(volatile TUint8 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint8 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify16(TLinAddr aAddr, TUint16 aClearMask, TUint16 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint16 value = *(volatile TUint16 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint16 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify32(TLinAddr aAddr, TUint32 aClearMask, TUint32 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint32 value = *(volatile TUint32 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint32 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +/////////////////////////////////////////////////////////////////////////////// +// 64 bit operations may be more complex than 8/16/32 bit operations, depending +// upon hardware support for 64 bit accesses. +// +// For example, one platform required an assembly language function to prevent +// the compliler optimising the accesses into 2 x 32 bit accesses and causing a +// bus error. +// +// Spinlocks are required for non-atomic operations and are therefore +// recommended for 64 bit accesses on current platforms. +/////////////////////////////////////////////////////////////////////////////// +extern TUint64 DoRead64(TLinAddr aAddr); + +EXPORT_C TUint64 AsspRegister::Read64(TLinAddr aAddr) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint64 value = DoRead64(aAddr); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + return value; + } + +extern void DoWrite64(TLinAddr aAddr, TUint64 aValue); + +EXPORT_C void AsspRegister::Write64(TLinAddr aAddr, TUint64 aValue) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + DoWrite64(aAddr, aValue); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify64(TLinAddr aAddr, TUint64 aClearMask, TUint64 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint64 value = DoRead64(aAddr); + value &= ~aClearMask; + value |= aSetMask; + DoWrite64(aAddr, value); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/assp/tranasm-symbols.log diff -r 000000000000 -r 6663340f3fc9 omap3530/base_beagle.mrp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/base_beagle.mrp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,49 @@ +component base_beagle + +source \sf\adaptation\beagleboard\omap3530 + +binary \sf\adaptation\beagleboard\omap3530\assp all +binary \sf\adaptation\beagleboard\omap3530\beagleboard all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\hal all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\keytran all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\lcd all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\led all +# binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\prm all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\serialmouse all +binary \sf\adaptation\beagleboard\omap3530\beagle_drivers\usbv all +binary \sf\adaptation\beagleboard\omap3530\kernel all +binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\gpio all +binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\i2c all +binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\prcm all +# binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\prm all +binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\uart all +binary \sf\adaptation\beagleboard\omap3530\omap3530_drivers\usbcc all +binary \sf\adaptation\beagleboard\omap3530\shared\monitor all +binary \sf\adaptation\beagleboard\omap3530\shared\mstick all +binary \sf\adaptation\beagleboard\omap3530\shared\serialkeyb all +binary \sf\adaptation\beagleboard\omap3530\shared\tps65950 all + +exports \sf\adaptation\beagleboard\omap3530\assp +exports \sf\adaptation\beagleboard\omap3530\beagleboard +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\hal +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\keytran +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\lcd +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\led +# exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\prm +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\serialmouse +exports \sf\adaptation\beagleboard\omap3530\beagle_drivers\usbv +exports \sf\adaptation\beagleboard\omap3530\kernel +exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\gpio +exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\i2c +exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\prcm +# exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\prm +exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\uart +exports \sf\adaptation\beagleboard\omap3530\omap3530_drivers\usbcc +exports \sf\adaptation\beagleboard\omap3530\shared\monitor +exports \sf\adaptation\beagleboard\omap3530\shared\mstick +exports \sf\adaptation\beagleboard\omap3530\shared\serialkeyb +exports \sf\adaptation\beagleboard\omap3530\shared\tps65950 + +notes_source \sf\adaptation\beagleboard\omap3530\release.src + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/hal/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/hal/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,34 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// beagle/beagle_drivers/hal/bld.inf +// This must be built as ARMv5 because of assumptions in other IBY files +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXTENSIONS +start extension base/config + +option HALPATH $(EXTENSION_ROOT)/../../../../../../../sf/os/kernelhwsrv/halservices +option PREFIX _beagle_ +option SOURCE $(EXTENSION_ROOT)/. + +end + +PRJ_MMPFILES +hal + + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/hal/config.hcf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/hal/config.hcf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,99 @@ +EManufacturer=0 +EManufacturerHardwareRev=0 +EManufacturerSoftwareRev=0 +EManufacturerSoftwareBuild=0 +EModel=0 +EMachineUid=0 +EDeviceFamily=0 +EDeviceFamilyRev=0 +ECPU=0 +ECPUArch=0 +ECPUABI=0 +ECPUSpeed=GetCPUSpeed +ESystemStartupReason=GetSystemStartupReason +ESystemException=GetSystemException +ESystemTickPeriod=0 +EMemoryRAM=GetRAMSize +EMemoryRAMFree=GetFreeRAM +EMemoryROM=GetROMSize +EMemoryPageSize=0 +EPowerGood=GetPowerGoodState +EAccessoryPower=GetAccessoryPowerPresent +EPowerBatteryStatus=GetBatteryStatus +EPowerBackup=GetBackupPresent +EPowerBackupStatus=GetBackupStatus +EPowerExternal=GetPowerExternalState +EKeyboard=ProcessKeyboardInfo +EKeyboardState : set = ProcessKeyboardState +EKeyboardDeviceKeys=ProcessKeyboardInfo +EKeyboardAppKeys=ProcessKeyboardInfo +EKeyboardClick=GetKeyboardClickPresent +EKeyboardClickState : set = ProcessKeyboardClickState +EKeyboardClickVolume : set = ProcessKeyboardClickVolume +EKeyboardClickVolumeMax=GetKeyboardClickVolumeMax +EDisplayXPixels=ProcessDisplayCurrentModeInfo +EDisplayYPixels=ProcessDisplayCurrentModeInfo +EDisplayXTwips=ProcessDisplayCurrentModeInfo +EDisplayYTwips=ProcessDisplayCurrentModeInfo +EDisplayColors=ProcessDisplayColors +EDisplayState : set = ProcessDisplayState +EDisplayContrast : set = ProcessDisplayContrast +EDisplayContrastMax=ProcessDisplayMaxContrast +EBacklight=GetBacklightPresent +EBacklightState :set = ProcessBacklightState +EPen=GetPenPresent +EPenX=ProcessPenInfo +EPenY=ProcessPenInfo +EPenState : set = ProcessPenState +EPenDisplayOn : set = ProcessPenDisplayOnState +EPenClick=GetPenClickPresent +EPenClickState : set = ProcessPenClickState +EPenClickVolume : set = ProcessPenClickVolume +EPenClickVolumeMax=GetPenClickVolumeMax +EMouse=GetMousePresent +EMouseX=ProcessMouseInfo +EMouseY=ProcessMouseInfo +EMouseButtons=ProcessMouseInfo +EMouseState : set = ProcessMouseState +EMouseSpeed : set = ProcessMouseSpeed +EMouseAcceleration : set = ProcessMouseAcceleration +EMouseButtonState=GetMouseButtonState +ECaseState=0 +ECaseSwitch=0 +ECaseSwitchDisplayOn=ProcessCaseSwitchDisplayOnState +ECaseSwitchDisplayOff=ProcessCaseSwitchDisplayOffState +ELEDs=GetLedCaps +ELEDmask : set = ProcessLEDMask +ESwitches=GetSwitches +EIntegratedPhone=0 +EDisplayBrightness : set = ProcessDisplayBrightness +EDisplayBrightnessMax=ProcessDisplayMaxBrightness +EKeyboardBacklightState=0 +ELanguageIndex : set = 0 +EKeyboardIndex : set = 0 +EMaxRAMDriveSize=0 +EDisplayIsMono=ProcessDisplaySpecifiedModeInfo +EDisplayIsPalettized=ProcessDisplaySpecifiedModeInfo +EDisplayBitsPerPixel=ProcessDisplaySpecifiedModeInfo +EDisplayNumModes=ProcessDisplayNumModes +EDisplayMemoryAddress=ProcessDisplayCurrentModeInfo +EDisplayOffsetToFirstPixel=ProcessDisplaySpecifiedModeInfo +EDisplayOffsetBetweenLines=ProcessDisplaySpecifiedModeInfo +EDisplayPaletteEntry : set = ProcessDisplayPaletteEntry +EDisplayIsPixelOrderRGB=ProcessDisplayCurrentModeInfo +EDisplayIsPixelOrderLandscape=ProcessDisplayCurrentModeInfo +EDisplayMode : set = ProcessDisplayMode +EDebugPort : set = ProcessDebugPort +ELocaleLoaded=0 +EClipboardDrive=0 +ECustomRestart : set = ProcessCustomRestart +ECustomRestartReason=ProcessCustomRestartReason +ESystemDrive : set = 0 +ENanoTickPeriod=0 +EFastCounterFrequency=0 +EFastCounterCountsUp=0 +EPersistStartupModeKernel : set = ProcessPersistStartupMode +EMaximumCustomRestartReasons = GetMaximumCustomRestartReasons +EMaximumRestartStartupModes = GetMaximumRestartStartupModes +ECustomResourceDrive : set = 0 +EDisplayNumberOfScreens=0 diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/hal/hal.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/hal/hal.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,37 @@ +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// beagle\beagle_variant\hal\hal.mmp +// + +#include "beagle/variant.mmh" +target VariantTarget(hal,dll) +targettype dll +linkas hal.dll +noexportlibrary + +sourcepath ../../../../../../../sf/os/kernelhwsrv/halservices/hal/src +source hal_main.cpp userhal.cpp + +systeminclude +/include ../../../../../../../sf/os/kernelhwsrv/halservices/hal/inc +sourcepath +/build/generatedcpp/hal +source VariantTarget(values,cpp) VariantTarget(config,cpp) + +library euser.lib + +deffile ../../../../../../../sf/os/kernelhwsrv/halservices/hal/~/hal.def + +uid 0x1000008d 0x100039e8 + +capability all +vendorid 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/hal/values.hda --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/hal/values.hda Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,29 @@ +EManufacturer=psion +EManufacturerHardwareRev=0 +EManufacturerSoftwareRev=0 +EManufacturerSoftwareBuild=0 +EModel=0 +EMachineUid=0 +EDeviceFamily=crystal +EDeviceFamilyRev=0 +ECPU=arm +ECPUArch=0 +ECPUABI=arm4 +ESystemTickPeriod=15625 +EMemoryPageSize=0x1000 +ECaseState=0 +ECaseSwitch=0 +EIntegratedPhone=0 +EKeyboardBacklightState=0 +ELanguageIndex=0 +EKeyboardIndex=0 +EMaxRAMDriveSize=0x1000000 +ESystemDrive=0xffff +ELocaleLoaded=0 +EClipboardDrive=2 +ENanoTickPeriod=1000 +EFastCounterFrequency=1000 +EFastCounterCountsUp=1 +EPersistStartupModeKernel=0 +ECustomResourceDrive=0xffff +EDisplayNumberOfScreens=1 diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/keytran/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/keytran/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,26 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// beagle/beagle_drivers/keytran/bld.inf +// This must be built as ARMv5 because of assumptions in other IBY files +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +keymap + + + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/keytran/keymap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/keytran/keymap.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2227 @@ +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/keytran/keymap.cpp +// This file is part of the Beagle Base port +// The keyboard lookup tables giving the function to be carried out +// and the new state of the keyboard +// + + +#include + +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + + +// +// Scancode conversion tables +// -------------------------- +// The scancode conversion is arranged as a tree of tables which are used to +// convert a scancode to a keycode, taking into account the modifier state +// (shift, control, fn) +// +// How the tables work: +// -------------------- +// Firstly, there is a distinction between the "scancodes" used in scanning +// the keyboard, and the "scancodes" used in this files. +// +// Typically the keyboard driver already contains a table to convert hardware +// key location codes produced during keyboard scanning into EPOC "scancodes". +// EPOC scancodes are defined for "standard" keys like shift, backspace, +// escape, in the TStdScanCode enum (see E32KEYS.H), and should be ASCII codes +// for normal characters. The keyboard driver should add these EPOC scancodes +// to the event queue, not hardware-dependant key locations. +// +// For now on "scancode" refers to EPOC scancodes: +// +// The keyboard is divided into a number of "blocks" of contiguous scancodes +// +// Blocks map to keycodes in a keycode table, and several blocks can be +// grouped and map to a single keycode table. Blocks map into the keycode +// table in the order they are declared. For example, if two scancode blocks +// with a range of 5 scancodes map to a single 10-entry keycode table, scancodes +// which fall in the first block will map to the first 5 entries in the keycode +// table, scancodes falling in the second block map the the next 5 entries in +// the keycode table. +// +// In theory it is possible to have multiple [keycode,scancode blocks] groups +// but there is little point doing this - grouping all the scancode blocks +// with a single keycode table holding all possible keycode values is usually +// sufficient (and simpler). However, there are some special cases where this +// is useful - the most obvious example is handling of shift and caps lock. +// The shift key implies everything that the caps-lock key does (upper case +// letters) plus some shifted characters for other keys. This is done by +// defining two tables - the first handles only caps-lock (upper case), the +// second handles all other keys that are affected only by shift. If caps- +// lock is active, only the caps-lock table is used. If shift is pressed both +// the caps-lock and shift tables are scanned for the conversion. This allows +// a base table to be extended with "extras", much like deriving a class from +// base class and extending it. +// +// +// There is one or more [keycode table, scancode blocks] group for each +// modifier state - e.g. a lower-case table, upper-case, ctrl, ctrl-shift. +// This is the root of the table. +// +// When converting a scancode the key translator first obtains the correct +// conversion tables for the modifier state. It then traverses all the scancode +// blocks looking for one which contains the scancode being converted. Once +// a matching scancode range is located, the key translator maps this into +// its position in the associated keycode table to obtain the converted keycode. +// +// The key tables below appear more complicated than they really are because of +// the intermediate structures that hold pointers to other structures. The +// important structures are: +// SScanCodeBlock - contains a "start" and "end" for a scancode range +// SConvSubTable - groups a number of scanode blocks with a keycode table +// SConvTableNode - points to SConvSubTables for each modifier state +// SConvTable - the root of the translation table - points to 1..n SConvTableNode +// +// The keycode tables are just an array of TUint16. +// + + +// +// TO DO: (optional) +// +// Keys which are not affected by modifier state +// + +// +// This is a simple example of scancode to keycode mapping. The first block +// in scanCodeBlock_unmodifiable is a range of several scancodes, so maps to +// several entries in the keycode table convKeyCodes_unmodifiable. +// EStdKeyLeftShift -> maps to -> EKeyLeftShift +// EStdKeyRightShift -> maps to -> EKeyRightShift +// ... +// EStdKeyScrollLock -> maps to -> EKeyScrollLock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_unmodifiable[]= + { + {EStdKeyLeftShift, EStdKeyScrollLock}, // range 1: left shift to scroll lock + }; + +LOCAL_D const TUint16 convKeyCodes_unmodifiable[]= + { + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock + }; + + + +// +// TO DO: (optional) +// +// Base conversion table +// this table traps all of the keyboard's scanCodes except those in +// convKeyCodes_unmodifiable. It appears last in the top-level table and +// is used to convert any scancode that is not converted by any of the +// other tables +// +LOCAL_D const SScanCodeBlock scanCodeBlock_base[]= + { + {EStdKeyNull, EStdKeyDownArrow}, // scancode range 1 + {'0', '9'}, // scancode range 2 + {'A', 'Z'}, // scancode range 3 + {EStdKeyF1, EStdKeyDictaphoneRecord}, // scancode range 4 + }; + +LOCAL_D const TUint16 convKeyCodes_base[]= + { + EKeyNull, // scancode range 1 mapping starts here + EKeyBackspace, + EKeyTab, + EKeyEnter, + EKeyEscape, + ' ', + EKeyPrintScreen, + EKeyPause, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + EKeyInsert, + EKeyDelete, + EKeyLeftArrow, + EKeyRightArrow, + EKeyUpArrow, + EKeyDownArrow, + '0', // scancode range 2 mapping starts here + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'a', // scancode range 3 mapping starts here + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + EKeyF1, // scancode range 4 mapping starts here + EKeyF2, + EKeyF3, + EKeyF4, + EKeyF5, + EKeyF6, + EKeyF7, + EKeyF8, + EKeyF9, + EKeyF10, + EKeyF11, + EKeyF12, + EKeyF13, + EKeyF14, + EKeyF15, + EKeyF16, + EKeyF17, + EKeyF18, + EKeyF19, + EKeyF20, + EKeyF21, + EKeyF22, + EKeyF23, + EKeyF24, + '`', + ',', + '.', + '/', + '\\', + ';', + '\'', + '#', + '[', + ']', + '-', + '=', + '/', + '*', + '-', + '+', + EKeyEnter, + EKeyEnd, + EKeyDownArrow, + EKeyPageDown, + EKeyLeftArrow, + EKeyNull, // numeric keypad '5' + EKeyRightArrow, + EKeyHome, + EKeyUpArrow, + EKeyPageUp, + EKeyInsert, + EKeyDelete, + EKeyMenu, + EKeyBacklightOn, + EKeyBacklightOff, + EKeyBacklightToggle, + EKeyIncContrast, + EKeyDecContrast, + EKeySliderDown, + EKeySliderUp, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord + }; + + +// +// TO DO: (optional) +// +// caps-lock: this table traps those scanCodes which are affected by caps-lock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_capsLock[]= + { + {'A', 'Z'} // only alpha keys are affected by caps-lock + }; + +LOCAL_D const TUint16 convKeyCodes_capsLock[]= + { + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z' + }; + +// +// TO DO: (optional) +// +// shift: this table traps those scanCodes which are affected +// by normal shift key EXCEPT for those scanCodes affected by caps-lock +// + +LOCAL_D const SScanCodeBlock scanCodeBlock_shift[]= + { + {'0', '9'}, + {EStdKeyXXX, EStdKeyEquals}, + }; + +LOCAL_D const TUint16 convKeyCodes_shift[]= + { + ')', + '!', + '@',/*'"',*/ + '#', /*ELatin1Pound,*/ + '$', + '%', + '^', + '&', + '*', + '(', + '~', /*ELatin1LogicNot,*/ + '<', + '>', + '?', + '|', + ':', + '"', + '|', /*'~',*/ + '{', + '}', + '_', + '+' + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by the func key but not shift +// +LOCAL_D const SScanCodeBlock scanCodeBlock_func[]= + { + {EStdKeyEscape, EStdKeyEscape}, + {'M', 'M'}, + {EStdKeyComma, EStdKeyComma}, + {EStdKeyLeftArrow, EStdKeyDownArrow}, + }; + +LOCAL_D const TUint16 convKeyCodes_func[]= + { + EKeyOff, + EKeyDecContrast, + EKeyIncContrast, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func pressed, shift not pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcUnshifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcUnshifted[]= +// { +// ELatin1LcEacute, +// }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func and shift both pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcShifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcShifted[]= +// { +// ELatin1UcEacute, +// }; + +// +// TO DO: (optional) +// +// ctrl: this table traps those scanCodes which are affected by ctrl +// +LOCAL_D const SScanCodeBlock scanCodeBlock_ctrl[]= + { + // + // NOTE: The space key gets handled elsewhere, otherwise it gets + // thrown away as a NULL key + // {EStdKeySpace, EStdKeySpace}, + + {'A', 'Z'}, + {EStdKeyComma, EStdKeyComma}, + }; + +LOCAL_D const TUint16 convKeyCodes_ctrl[]= + { +// 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + ',', + }; + + + +// +// TO DO: (optional) +// +// Each set of scancode+keycode tables must be grouped into a SConvSubTable. +// The lines below define a number of SConvSubTables for each of the groups +// above. +// +LOCAL_D const SConvSubTable + convSubTable_unmodifiable= // table for unmodifiable keys + { + &convKeyCodes_unmodifiable[0], // the keycode table + { + ARRAY_LENGTH(scanCodeBlock_unmodifiable), // number of scancode blocks + &scanCodeBlock_unmodifiable[0] // pointer to scancode blocks + } + }, + convSubTable_base= // table for base keys + { + &convKeyCodes_base[0], // keycode table + { + ARRAY_LENGTH(scanCodeBlock_base), // number of scancode blocks + &scanCodeBlock_base[0] // pointer to scancode blocks + } + }, + convSubTable_capsLock= + { + &convKeyCodes_capsLock[0], + { + ARRAY_LENGTH(scanCodeBlock_capsLock), + &scanCodeBlock_capsLock[0] + } + }, + convSubTable_shift= + { + &convKeyCodes_shift[0], + { + ARRAY_LENGTH(scanCodeBlock_shift), + &scanCodeBlock_shift[0] + } + }, + convSubTable_func= + { + &convKeyCodes_func[0], + { + ARRAY_LENGTH(scanCodeBlock_func), + &scanCodeBlock_func[0] + } + }, +// convSubTable_funcUnshifted= +// { +// &convKeyCodes_funcUnshifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcUnshifted), +// &scanCodeBlock_funcUnshifted[0] +// } +// }, +// convSubTable_funcShifted= +// { +// &convKeyCodes_funcShifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcShifted), +// &scanCodeBlock_funcShifted[0] +// } +// }, + convSubTable_ctrl= + { + &convKeyCodes_ctrl[0], + { + ARRAY_LENGTH(scanCodeBlock_ctrl), + &scanCodeBlock_ctrl[0] + } + }; + +// +// TO DO: (optional) +// +// We need to declare arrays of SConvSubTable for each modifier state we +// are going to handle. As mentioned above, it is possible to have several +// [keycode table, scancode blocks] groups scanned for each keyboard state. +// +// Some modifier states use more than one conversion group. The simple example +// is handling of caps-lock and shift. +// +// Caps-lock means all letters are upper-case +// shift means all letters are upper case AND some other keys return control characters +// +// Obviously the shift key means everything cpas-lock means PLUS a bit more. So +// we define two tables, the caps-lock table defines only the uppercase conversion, +// and the shift table defines all OTHER shifted keys not already handled by +// caps-lock. The caps-lock modifier state then only scans the caps-lock table, and +// the shift state scans both tables. +// +LOCAL_D const SConvSubTable + * const convSubTableArray_unmodifiable[]={&convSubTable_unmodifiable}, + * const convSubTableArray_base[]={&convSubTable_base}, + + // + // The caps-lock state scans only the caps-lock table, to handle + // conversion to upper case + // + * const convSubTableArray_capsLock[]={&convSubTable_capsLock}, + // + // The shift table scans the caps-lock table to handle upper case, + // and also the shift table which handles some keys that are not affected + // by caps lock (such as 0-9). + // + * const convSubTableArray_shift[]={&convSubTable_capsLock, &convSubTable_shift}, + // + // Pressing shift with caps-lock active reverts to lower-case letters, + // but other keys remain shifted. This time we only scan the shift table + // so only the non-alpha keys will be shifted + // + * const convSubTableArray_capsLockShift[]={&convSubTable_shift}, + + // + // Like the shift/caps-lock situation, the function key has two states, + // shifted and unshifted. Also, some keys may be independant of whether + // the shift key is pressed. So there are three tables defined. One declares + // all keys that are independant of shift state, the other two tables handle + // shifted and unshifted func. + // + // Unshifted func uses the independant set + funcUnshifted + // + // * const convSubTableArray_func[]={&convSubTable_func, &convSubTable_funcUnshifted}, + * const convSubTableArray_func[]={&convSubTable_func}, + // + // Shifted func uses the independant set + funcShifted + // + // * const convSubTableArray_funcShift[]={&convSubTable_func,&convSubTable_funcShifted}, + // + // This keyboard table makes control independant of func and shift + // + * const convSubTableArray_ctrl[]={&convSubTable_ctrl}; + +// +// TO DO: (optional) +// +// This is the top of the scancode conversion tree. It is a set of pointers +// to the SConvSubTable arrays declared above. +// +// The order of these nodes is VITAL, as the scanCode/modifiers are +// searched for a match in this order +// +// The modifier state is matched by using a mask and a compare value. This is +// used as follows: +// +// match is true if ( (modifierState & mask) == compareValue +// +// For example, if the mask is (EModifierFunc|EModifierShift) and the +// compare value is EModifierFunc, this will match ANY combination of +// modifiers that has func pressed and shift not pressed +// +LOCAL_D const SConvTableNode convTableNodes[]= + { + { + { + 0, // modifier mask = no modifiers + 0 // modifier compare = no modifiers + }, + ARRAY_LENGTH(convSubTableArray_unmodifiable), // number of SConvSubTables + &convSubTableArray_unmodifiable[0] // pointer to SConvSubTable array + }, + { + { + EModifierCtrl, // modifier mask = check for ctrl + EModifierCtrl // modifier compare = anything with ctrl pressed + }, + ARRAY_LENGTH(convSubTableArray_ctrl), + &convSubTableArray_ctrl[0] + }, + { + { + // + // Check for Func pressed + // + EModifierFunc, + EModifierFunc + }, + ARRAY_LENGTH(convSubTableArray_func), + &convSubTableArray_func[0] + }, + { + { + // + // Check for caps-lock pressed, shift not pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock + }, + ARRAY_LENGTH(convSubTableArray_capsLock), + &convSubTableArray_capsLock[0] + }, + { + { + // + // Check for caps-lock not pressed, shift pressed + // + EModifierShift|EModifierCapsLock, + EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_shift), + &convSubTableArray_shift[0] + }, + { + { + // + // Check for caps-lock pressed, shift pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock|EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_capsLockShift), + &convSubTableArray_capsLockShift[0] + }, + { + // + // This is the base table. It must appear last so that it can + // provide a default conversion for any scancodes that are not + // handled by any of the tables above + // + { + 0, + 0 + }, + ARRAY_LENGTH(convSubTableArray_base), + &convSubTableArray_base[0] + } + }; + +// +// The top-level exported data structure of all the conversion tables +// This just points to the SConvTableNodes above +// +LOCAL_D const SConvTable ConvTable= + { + ARRAY_LENGTH(convTableNodes), + &convTableNodes[0] + }; + +// The list of scan-codes on the numeric keypad +LOCAL_D const SScanCodeBlock keypadScanCodeBlockArray[]= + { + {EStdKeyNumLock, EStdKeyNumLock}, + {EStdKeyNkpForwardSlash, EStdKeyNkpFullStop} + }; + +LOCAL_D const SScanCodeBlockList ConvTableKeypadScanCodes= + { + ARRAY_LENGTH(keypadScanCodeBlockArray), + &keypadScanCodeBlockArray[0] + }; + +// +// TO DO: (optional) +// +// List of keycodes that do not autorepeat +// +// These are usually control keys like shift, ctrl, escape +// +LOCAL_D const TUint16 nonAutorepKeyCodeArray[]= + { + EKeyEscape, + EKeyPrintScreen, + EKeyPause, + EKeyInsert, + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock, + EKeyMenu, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord + }; + +// +// TO DO: (optional) +// +// Declare blocks of non-autorepeating keycodes +// +LOCAL_D const SKeyCodeList ConvTableNonAutorepKeyCodes= + { + ARRAY_LENGTH(nonAutorepKeyCodeArray), // number of keycode arrays + &nonAutorepKeyCodeArray[0] // pointer to arrays + }; + + + + + + +///////////////////////////////////////////////////////////////////// +// Keyboard state tables +// + +// What these tables do +// -------------------- +// +// These tables control the way "special" keystrokes modify the behaviour +// of the keyboard. There are two major uses for this: +// +// - handling modifier keys e.g. caps-lock, shift, alt, fn and defining +// what modifier flags are affected by these keypresses +// +// - switching the keyboard into special states (see below) +// +// Keyboard states +// --------------- +// +// Keyboard states are used to switch the keyboard into a special mode where it +// can be used to enter unusual characters. There are two uses for this: +// +// - entering numeric codes, by pressing ctrl and typing the decimal code +// - entering accented characters by pressing a key combination which +// enters "accented mode" then pressing a key. There can be multiple +// accented modes. +// +// You can see an example of accented modes on a Psion Series 5 by +// pressing Fn+Z, followed by A - this will produce an a with an umlaut (ä) +// +// These tables are also used to select simpler states such as caps-lock +// and num-lock. +// +// +// The main data structure is a SFuncTableEntry. Each of these contains +// three fields: +// +// 1. modifier match - this works the same way as the scancode conversion +// tables above, there is a mask and a compare value +// +// 2. a keycode patters - this is used to match with the keycode or keycodes +// that the state should respond to. This is a TKeyCodePattern structure +// which defines what sort of match should be performed. +// +// 3. a function and state change structure, SFuncAndState. This defines the +// state to change to, the function to perform, and a parameter for the +// function if required. +// +// TKeyCodePattern structures have two fields. The first is a keycode value +// and is only used for some match types. The second field select the type +// of match to perform: +// +// EAnyKey - match any key +// EAnyAlphaNumeric - match any alpha or numeric key +// EAnyAlpha - match any alpha key +// EAnyAlphaLowerCase - match any lower-case key +// EAnyAlphaUpperCase - match any upper-case key +// EAnyDecimalDigit - match any decimal digit +// EAnyModifierKey - match any modifier key (e.g. alt, fn, ctrl) +// EMatchKey - match if equal to keycode value in first field +// EMatchLeftOrRight - match if equal to keycode value or (keycode value + 1) +// EMatchKeyCaseInsens - like EMatchKey but perform case-insensitive comparison +// +// + +// the "array" parameter must be a true array and not a pointer +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + +#define TABLE_ENTRY_ANOTHER_CTRL_DIGIT \ + { \ + { \ + EModifierKeyUp|EModifierFunc, \ + 0 \ + }, \ + { \ + EKeyNull, \ + EAnyDigitGivenRadix \ + }, \ + { \ + EStateCtrlDigits, \ + EAddOnCtrlDigit, \ + 0 \ + } \ + } + +// +// TO DO: (optional) +// +// This table is searched for a match if a match has not been +// found in the current state's table +// + +LOCAL_D const SFuncTableEntry defaultTable[]= + { + { + // + // prevent key up events generating keycodes + // + { + EModifierKeyUp, // mask = key up + EModifierKeyUp // match = key up - i.e. accept any key up event + }, + { + EKeyNull, // dummy value, not used + EAnyKey // accept any key + }, + { + EStateUnchanged, // state will not change + EDoNothing, // no action to perform + 0 + } + }, + { + // + // prevent any modifier key (e.g. shift, ctrl) from changing state + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyModifierKey // match any modifier key + }, + { + EStateUnchanged, // don't change state + EDoNothing, // nothing to do + 0 + } + }, + { + // + // filter out any unprocessed codes + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyKey // match any key + }, + { + EStateNormal, // switch back to normal keyboard state + EDoNothing, // nothing to do + 0 + } + } + }; + +// +// TO DO: (optional) +// +// This table controls which keys change which modifiers; +// NOTE: the state field in this table is ignored +// + +LOCAL_D const SFuncTableEntry modifierTable[]= + { + { + { + EModifierKeyUp, // check key-up modifier flag + 0 // make sure it's zero (i.e. ignore key-up events) + }, + { + // + // Here we want to match only the caps-lock key. We specify the + // keycode we are looking for in the first field, and EMatchKey + // in the second field + // + EKeyCapsLock, // we want to respond to caps-lock key + EMatchKey // match caps-lock only + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierCapsLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyNumLock, // this one matched num-lock + EMatchKey // match only num-lock + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierNumLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyScrollLock, // match scroll-lock key + EMatchKey + }, + { + EStateUnchanged, + EToggleModifier, // function = toggle modifier + EModifierScrollLock // modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyLeftAlt, // match left alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on a modifier + EModifierAlt|EModifierLeftAlt // alt turns on this modifier combination + } + }, + { + { + EModifierKeyUp, // goes with previous table, this handles the alt + EModifierKeyUp // key being released + }, + { + EKeyLeftAlt, // match left alt key again + EMatchKey + }, + { + EStateUnchanged, + ETurnOffModifier, // function = turn off the modifier + EModifierLeftAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierLeftFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, this matched the + EModifierKeyUp // left-fn key up event + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierLeftShift // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left shift + EModifierKeyUp // key up event + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // turn off modifier + EModifierLeftShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierLeftCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left ctrl + EModifierKeyUp // key up event + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftCtrl // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierAlt|EModifierRightAlt // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right alt + EModifierKeyUp // key up event + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierRightFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right fn + EModifierKeyUp // key up event + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierRightShift // modifier combinatoin to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, handles right shift + EModifierKeyUp // key up event + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierRightCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matched right ctrl + EModifierKeyUp // key up event + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightCtrl // modifier to turn off + } + } + }; + + +// +// TO DO: (optional) +// +// Tables corresponding to keyboard states. +// +// There are 13 keyboard states. States 0 to 9 can be used to create alternative +// keyboard layouts for entering accented or unusual characters. Switching into +// these states is done by a keypress. Implementation of the states is optional +// depending on how many special state you want - you may implement 10 states, +// you might decide not to implement any. +// +// State 10 is the normal state. The table for state 10 defines which keypresses +// change to other states. +// +// States 11 and 12 are used when entering the numeric code of a character. State +// 11 is for entering a specific number of digits. State 12 is for accepting +// digits until Ctrl is released. +// +// +// As before, each SFuncTableEntry entry defines: +// - modifier conditions that must be matched +// - a keycode match pattern (typically an exact key match) +// - the function to perform and new state +// +// Switching into states 0..9,11,12 is done by entries in table10 +// + +//LOCAL_D const SFuncTableEntry table0[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table1[]= + { + // + // Table for special keyboard state 1 + // This state is entered by pressing Fn+q (see table10) + // + // The table makes certain keys return accented characters + // + { + { + // + // Function must be release, and this must be a key down event + // + EModifierFunc|EModifierKeyUp, + 0 + }, + { + // + // match an 'e' keypress, convert to an ae ligature (æ) + // + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, // switch back to state normal (table10) + EPassSpecialKeyThru, // turn keypress into a special character + ELatin1LcAe // this is the character to pass on + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'c', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcCcedilla + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 's', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1EsTset + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOslash + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'd', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcThorn + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 't', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSoftTh + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'l', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LeftChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'r', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1RightChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'x', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvExclam + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'q', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvQuest + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAo + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'p', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1Pound + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table2[]= + { + // + // Table for special keyboard state 2 + // This state is entered by pressing Fn+z (see table10) + // + // The table makes certain keys return accented characters + // See table1 for an explanation of the contents + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceUmlaut + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table3[]= + { + // + // Table for special keyboard state 3 + // This state is entered by pressing Fn+x (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceGrave + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table4[]= + { + // + // Table for special keyboard state 4 + // This state is entered by pressing Fn+c (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceAcute + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table5[]= + { + // + // Table for special keyboard state 5 + // This state is entered by pressing Fn+v (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'n', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcNtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceTilde + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table6[]= + { + // + // Table for special keyboard state 6 + // This state is entered by pressing Fn+b (see table6) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceCirc + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +// +// TO DO: (optional) +// +// State 7,8,9 aren't used in this example. +// You can implement them if you want more special states +// + +//LOCAL_D const SFuncTableEntry table7[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table8[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table9[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + + +LOCAL_D const SFuncTableEntry table10[]= + { + // + // TO DO: (optional) + // + // Table keyboard state 10 - the normal state + // + // This table controls which keys switch into the special states + // 0-9, 11 and 12. + // + + { + // + // Make sure key-up events are ignored by handling them first and + // doing nothing + // + { + EModifierKeyUp, + EModifierKeyUp + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EDoNothing, + 0 + } + }, + { + // + // Check for ctrl-number presses + // This will enter state EStateCtrlDigits (state 12) which allows + // entry of a numeric keycode + // + { + EModifierCtrl|EModifierFunc|EModifierKeyUp, + EModifierCtrl + }, + { + EKeyNull, + EAnyDecimalDigit + }, + { + EStateDerivedFromDigitEntered, + EAddOnCtrlDigit, + 0 + } + }, + { + // + // Any other key events that have not been trapped are just + // passed through unchanged + // + { + 0, + 0 + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EPassKeyThru, + 0 + } + } + }; + +//LOCAL_D const SFuncTableEntry table11[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table12[]= + { + // + // Table 12 handles entring digit codes. The keyboard will remain in this + // state until the Ctrl key is released + // + { + { + // + // Look for a key up event + // + EModifierKeyUp, + EModifierKeyUp + }, + { + // + // Match either left or right Ctrl key (i.e. this matches a Ctrl key release) + // + EKeyLeftCtrl, + EMatchLeftOrRight + }, + { + EStateNormal, // return to normal state (table10) + EPassCtrlDigitsThru, // and pass through the numeric code we have accumulated + 0 + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + + +// +// TO DO: (optional) +// +// Array of state control tables above. If a state is not used set the array +// size to zero and the pointer to NULL +// +// The tables must be declared here in order from table 0 to table 12 +// +LOCAL_D const SFuncTable genFuncTables[]= + { + { + // + // state 0 + // + 0, // state 0 not used, size = 0 + NULL // state 0 not used, pointer = NULL + }, + { + // + // state 1 + // + ARRAY_LENGTH(table1), // size of table 1 + &table1[0] // pointer to table 1 + }, + { + // + // state 2 + // + ARRAY_LENGTH(table2), + &table2[0] + }, + { + // + // state 3 + // + ARRAY_LENGTH(table3), + &table3[0] + }, + { + // + // state 4 + // + ARRAY_LENGTH(table4), + &table4[0] + }, + { + // + // state 5 + // + ARRAY_LENGTH(table5), + &table5[0] + }, + { + // + // state 6 + // + ARRAY_LENGTH(table6), + &table6[0] + }, + { + // + // state 7 + // + 0, + NULL + }, + { + // + // state 8 + // + 0, + NULL + }, + { + // + // state 9 + // + 0, + NULL + }, + { + // + // state 10 + // + ARRAY_LENGTH(table10), + &table10[0] + }, + { + // + // state 11 + // + 0, + NULL + }, + { + // + // state 12 + // + ARRAY_LENGTH(table12), + &table12[0] + } + }; + + +// +// Root of the state modifier tables +// +LOCAL_D const SFuncTables FuncTables= + { + { + // + // The default processing table + // + ARRAY_LENGTH(defaultTable), + &defaultTable[0] + }, + { + // + // The modifier control table + // + ARRAY_LENGTH(modifierTable), + &modifierTable[0] + }, + // + // The state control tables + // + ARRAY_LENGTH(genFuncTables), + &genFuncTables[0] + }; + + +// +// The following exported functions give the key translator access to +// the control tables above +// +EXPORT_C void KeyDataSettings(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount, + TInt &aMaximumCtrlDigitsMaxCount) + { + aRadix=EDecimal; + aCtrlDigitsTermination=ETerminationByCtrlUp; + aDefaultCtrlDigitsMaxCount=3; + aMaximumCtrlDigitsMaxCount=10; + } + +EXPORT_C void KeyDataFuncTable(SFuncTables &aFuncTables) + { + aFuncTables=FuncTables; + } + +EXPORT_C void KeyDataConvTable(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode, + SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes) + { + aConvTable=ConvTable; + aConvTableFirstScanCode=scanCodeBlock_base[0].firstScanCode; + aConvTableLastScanCode=scanCodeBlock_base[ARRAY_LENGTH(scanCodeBlock_base)-1].lastScanCode; + aKeypadScanCode=ConvTableKeypadScanCodes; + aNonAutorepKeyCodes=ConvTableNonAutorepKeyCodes; + } diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/keytran/keymap.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/keytran/keymap.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,49 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/keytran/keymap.mmp +// ekdata.dll Beagle keyboard look-up tables +// + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include "beagle/variant.mmh" + +target VariantTarget(ekdata,dll) +targettype dll +linkas ekdata.dll + +systeminclude +/include + +sourcepath . +source keymap.cpp + +library euser.lib + +deffile ../../../../../../../sf/os/kernelhwsrv/kernel/eka/~/ekdata.def + +nostrictdef +noexportlibrary + +uid 0x1000008d 0x100039e0 + +capability all +vendorid 0x70000001 + +unpaged diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/lcd/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/lcd/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,20 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +lcd diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/lcd/lcd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/lcd/lcd.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,1241 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/lcd/lcd.cpp +// Implementation of an LCD driver. +// This file is part of the Beagle Base port +// N.B. This sample code assumes that the display supports setting the backlight on or off, +// as well as adjusting the contrast and the brightness. +// + + + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DSS_SYSCONFIG 0x48050010 +#define DISPC_SYSSTATUS 0x48050414 + +#define DISPC_SYSCONFIG 0x48050410 +#define DISPC_CONFIG 0x48050444 +#define DISPC_DEFAULT_COLOR0 0x4805044c +#define DISPC_TRANS_COLOR0 0x48050454 + +#define DISPC_TIMING_H 0x48050464 +#define DISPC_TIMING_V 0x48050468 +#define DISPC_POL_FREQ 0x4805046c +#define DISPC_DIVISOR 0x48050470 +#define DISPC_SIZE_LCD 0x4805047c + +#define DISPC_GFX_BA1 0x48050480 +#define DISPC_GFX_BA2 0x48050484 +#define DISPC_GFX_POSITION 0x48050488 +#define DISPC_GFX_SIZE 0x4805048c +#define DISPC_GFX_ATTRIBUTES 0x480504a0 + +#define DISPC_GFX_FIFO_THRESHOLD 0x480504a4 +#define DISPC_GFX_FIFO_SIZE_STATUS 0x480504a8 +#define DISPC_GFX_ROW_INC 0x480504ac +#define DISPC_GFX_PIXEL_INC 0x480504b0 +#define DISPC_GFX_WINDOW_SKIP 0x480504b4 +#define DISPC_GFX_TABLE_BA 0x480504b8 + +#define DISPC_CONTROL 0x48050440 + +#define GET_REGISTER(Reg) *( (TUint *) Omap3530HwBase::TVirtual::Value ) +#define SET_REGISTER(Reg,Val) *( (TUint *) Omap3530HwBase::TVirtual::Value ) = Val + +#define _MODE_1280x1024_ +//#define _MODE_1024x768_ +#ifdef _MODE_800x600_ +// ModeLine "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync +// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html +# define PIXEL_CLK 40000 +# define H_DISP 800 +# define H_FPORCH 40 +# define H_SYNC 128 +# define H_BPORCH 88 +# define H_SYNC_POL 1 +# define V_DISP 600 +# define V_FPORCH 1 +# define V_SYNC 4 +# define V_BPORCH 23 +# define V_SYNC_POL 1 +# define INTERLACE_ENABLE 0 +#endif +#ifdef _MODE_1024x768_ +// ModeLine "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync +// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html +# define PIXEL_CLK 65000 +# define H_DISP 1024 +# define H_FPORCH 24 +# define H_SYNC 136 +# define H_BPORCH 160 +# define H_SYNC_POL 0 +# define V_DISP 768 +# define V_FPORCH 3 +# define V_SYNC 6 +# define V_BPORCH 29 +# define V_SYNC_POL 0 +# define INTERLACE_ENABLE 0 +#endif +#ifdef _MODE_1280x1024_ +// ModeLine "1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync +// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html +# define PIXEL_CLK 108000 +# define H_DISP 1280 +# define H_FPORCH 48 +# define H_SYNC 112 +# define H_BPORCH 248 +# define H_SYNC_POL 1 +# define V_DISP 1024 +# define V_FPORCH 1 +# define V_SYNC 3 +# define V_BPORCH 38 +# define V_SYNC_POL 1 +# define INTERLACE_ENABLE 0 +#endif + + + +// TO DO: (mandatory) +// If the display supports Contrast and/or Brightness control then supply the following defines: +// This is only example code... you may need to modify it for your hardware +const TInt KConfigInitialDisplayContrast = 128; +const TInt KConfigLcdMinDisplayContrast = 1; +const TInt KConfigLcdMaxDisplayContrast = 255; +const TInt KConfigInitialDisplayBrightness = 128; +const TInt KConfigLcdMinDisplayBrightness = 1; +const TInt KConfigLcdMaxDisplayBrightness = 255; + +// TO DO: (mandatory) +// define a macro to calculate the screen buffer size +// This is only example code... you may need to modify it for your hardware +// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and +// aLpp number of lines per panel +#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp) (aBpp*aPpl*aLpp)/8 + + +// TO DO: (mandatory) +// define the physical screen dimensions +// This is only example code... you need to modify it for your hardware +const TUint KConfigLcdWidth = 360;//640; // 640 pixels per line +const TUint KConfigLcdHeight = 640;//480; // 480 lines per panel + +// TO DO: (mandatory) +// define the characteristics of the LCD display +// This is only example code... you need to modify it for your hardware +const TBool KConfigLcdIsMono = EFalse; +const TBool KConfigLcdPixelOrderLandscape = ETrue; +const TBool KConfigLcdPixelOrderRGB = ETrue; +const TInt KConfigLcdMaxDisplayColors = 65536; //24bit: 16777216; + + +// TO DO: (mandatory) +// define the display dimensions in TWIPs +// A TWIP is a 20th of a point. A point is a 72nd of an inch +// Therefore a TWIP is a 1440th of an inch +// This is only example code... you need to modify it for your hardware +const TInt KConfigLcdWidthInTwips = 9638;//10800; // = 6.69 inches //15*1440; +const TInt KConfigLcdHeightInTwips = 7370;//11232;//5616; // = 5.11 inches //12*1440; + +// TO DO: (mandatory) +// define the available display modes +// This is only example code... you need to modify it for your hardware +const TInt KConfigLcdNumberOfDisplayModes = 1; +const TInt KConfigLcdInitialDisplayMode = 0; +struct SLcdConfig + { + TInt iMode; + TInt iOffsetToFirstVideoBuffer; + TInt iLenghtOfVideoBufferInBytes; + TInt iOffsetBetweenLines; + TBool iIsPalettized; + TInt iBitsPerPixel; + }; +static const SLcdConfig Lcd_Mode_Config[KConfigLcdNumberOfDisplayModes]= + { + { + 0, // iMode + 0, // iOffsetToFirstVideoBuffer + FRAME_BUFFER_SIZE(16, KConfigLcdWidth, KConfigLcdHeight), // iLenghtOfVideoBufferInBytes + KConfigLcdWidth*2, // iOffsetBetweenLines + EFalse, // iIsPalettized + 16 // iBitsPerPixel + } + }; + + + +_LIT(KLitLcd,"LCD"); + +// +// TO DO: (optional) +// +// Add any private functions and data you require +// +NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler + { +public: + DLcdPowerHandler(); + + // from DPowerHandler + void PowerDown(TPowerState); + void PowerUp(); + + void PowerUpDfc(); + void PowerDownDfc(); + + TInt Create(); + void DisplayOn(); + void DisplayOff(); + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); + + void PowerUpLcd(TBool aSecure); + void PowerDownLcd(); + + void ScreenInfo(TScreenInfoV01& aInfo); + void WsSwitchOnScreen(); + void WsSwitchOffScreen(); + void HandleMsg(); + void SwitchDisplay(TBool aSecure); + + void SetBacklightState(TBool aState); + void BacklightOn(); + void BacklightOff(); + TInt SetContrast(TInt aContrast); + TInt SetBrightness(TInt aBrightness); + +private: + TInt SetPaletteEntry(TInt aEntry, TInt aColor); + TInt GetPaletteEntry(TInt aEntry, TInt* aColor); + TInt NumberOfPaletteEntries(); + TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure); + TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo); + TInt SetDisplayMode(TInt aMode); + void SplashScreen(); + TInt GetDisplayColors(TInt* aColors); + +private: + TBool iIsPalettized; + TBool iDisplayOn; // to prevent a race condition with WServer trying to power up/down at the same time + DPlatChunkHw* iChunk; + DPlatChunkHw* iSecureChunk; + TBool iWsSwitchOnScreen; + TBool iSecureDisplay; + TDfcQue* iDfcQ; + TMessageQue iMsgQ; + TDfc iPowerUpDfc; + TDfc iPowerDownDfc; + TVideoInfoV01 iVideoInfo; + TVideoInfoV01 iSecureVideoInfo; + NFastMutex iLock; // protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo + TPhysAddr ivRamPhys; + TPhysAddr iSecurevRamPhys; + + TBool iBacklightOn; + TInt iContrast; + TInt iBrightness; + }; + + +/** +HAL handler function + +@param aPtr a pointer to an instance of DLcdPowerHandler +@param aFunction the function number +@param a1 an arbitrary parameter +@param a2 an arbitrary parameter +*/ +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + +/** +DFC for receiving messages from the power handler +@param aPtr a pointer to an instance of DLcdPowerHandler +*/ +void rxMsg(TAny* aPtr) + { + DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr; + h.HandleMsg(); + } + +/** +DFC for powering up the device + +@param aPtr aPtr a pointer to an instance of DLcdPowerHandler +*/ +void power_up_dfc(TAny* aPtr) + { + ((DLcdPowerHandler*)aPtr)->PowerUpDfc(); + } + +/** +DFC for powering down the device + +@param aPtr aPtr a pointer to an instance of DLcdPowerHandler +*/ +void power_down_dfc(TAny* aPtr) + { + ((DLcdPowerHandler*)aPtr)->PowerDownDfc(); + } + + +/** +Default constructor +*/ +DLcdPowerHandler::DLcdPowerHandler() : + DPowerHandler(KLitLcd), + iMsgQ(rxMsg,this,NULL,1), + iPowerUpDfc(&power_up_dfc,this,6), + iPowerDownDfc(&power_down_dfc,this,7), + iBacklightOn(EFalse), + iContrast(KConfigInitialDisplayContrast), + iBrightness(KConfigInitialDisplayBrightness) + { + } + + +/** +Second-phase constructor + +Called by factory function at ordinal 0 +*/ +TInt DLcdPowerHandler::Create() + { + iDfcQ=Kern::DfcQue0(); // use low priority DFC queue for this driver + + // map the video RAM + + //TPhysAddr videoRamPhys; + TInt vSize = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iLenghtOfVideoBufferInBytes; //KConfigLcdWidth*KConfigLcdHeight*3; //VideoRamSize(); + TInt r = Epoc::AllocPhysicalRam( 2*vSize, ivRamPhys ); + if ( r!=KErrNone ) + { + Kern::Fault( "AllocVRam", r ); + } + + //TInt vSize = ((Omap3530BoardAssp*)Arch::TheAsic())->VideoRamSize(); + //ivRamPhys = TOmap3530Assp::VideoRamPhys(); // EXAMPLE ONLY: assume TOmap3530Assp interface class + r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if (r != KErrNone) + return r; + + //create "secure" screen immediately after normal one + iSecurevRamPhys = ivRamPhys + vSize; + TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if (r2 != KErrNone) + return r2; + + TUint* pV=(TUint*)iChunk->LinearAddress(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV)); + + // TO DO: (mandatory) + // initialise the palette for the initial display mode + // NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer) + // or could be offered as part of the hardware block that implemenst the lcd control + // + + TUint* pV2=(TUint*)iSecureChunk->LinearAddress(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2)); + + // TO DO: (mandatory) + // initialise the secure screen's palette for the initial display mode + // + + // setup the video info structure, this'll be used to remember the video settings + iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode; + iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer; + iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized; + iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines; + iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel; + + iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; + iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; + iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; + iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; + iVideoInfo.iIsMono = KConfigLcdIsMono; + iVideoInfo.iVideoAddress=(TInt)pV; + iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape; + iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB; + + iSecureVideoInfo = iVideoInfo; + iSecureVideoInfo.iVideoAddress = (TInt)pV2; + + iDisplayOn = EFalse; + iSecureDisplay = EFalse; + + // install the HAL function + r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this); + if (r!=KErrNone) + return r; + + iPowerUpDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + // install the power handler + // power up the screen + Add(); + DisplayOn(); + + SplashScreen(); + + return KErrNone; + } + +/** +Turn the display on +May be called as a result of a power transition or from the HAL +If called from HAL, then the display may be already be on (iDisplayOn == ETrue) +*/ +void DLcdPowerHandler::DisplayOn() + { + __KTRACE_OPT(KBOOT, Kern::Printf("DisplayOn %d", iDisplayOn)); + if (!iDisplayOn) // may have been powered up already + { + iDisplayOn = ETrue; + PowerUpLcd(iSecureDisplay); + SetContrast(iContrast); + SetBrightness(iBrightness); + } + } + +/** +Turn the display off +May be called as a result of a power transition or from the HAL +If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse) +if the platform is in silent running mode +*/ +void DLcdPowerHandler::DisplayOff() + { + __KTRACE_OPT(KBOOT, Kern::Printf("DisplayOff %d", iDisplayOn)); + if (iDisplayOn) + { + iDisplayOn = EFalse; + PowerDownLcd(); + } + } + +/** +Switch between secure and non-secure displays + +@param aSecure ETrue if switching to secure display +*/ +void DLcdPowerHandler::SwitchDisplay(TBool aSecure) + { + if (aSecure) + { + if (!iSecureDisplay) + { + //switch to secure display + DisplayOff(); + iSecureDisplay = ETrue; + DisplayOn(); + } + } + else + { + if (iSecureDisplay) + { + //switch from secure display + DisplayOff(); + iSecureDisplay = EFalse; + DisplayOn(); + } + } + } + +/** +DFC to power up the display +*/ +void DLcdPowerHandler::PowerUpDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc")); + DisplayOn(); + + PowerUpDone(); // must be called from a different thread than PowerUp() + } + +/** +DFC to power down the display +*/ +void DLcdPowerHandler::PowerDownDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc")); + DisplayOff(); + PowerDownDone(); // must be called from a different thread than PowerUp() + } + +/** +Schedule the power-down DFC +*/ +void DLcdPowerHandler::PowerDown(TPowerState) + { + iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +/** +Schedule the power-up DFC +*/ +void DLcdPowerHandler::PowerUp() + { + iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +/** +Power up the display + +@param aSecure ETrue if powering up the secure display +*/ +void DLcdPowerHandler::PowerUpLcd(TBool aSecure) + { + + TUint32 l = 0x0; + + // Set up the Display Subsystem to control a DVI monitor + + // The following four lines need to be replaced by a call to the GPIO driver which should call the PowerClock driver +// PowerClock::GpioActive(0, PowerClock::E1s, PowerClock::ECpu10, PowerClock::EBus10); +// PowerClock::GpioAccess(0, PowerClock::EAuto); + Prcm::SetClockState( Prcm::EClkGpio1_F, Prcm::EClkOn ); + Prcm::SetClockState( Prcm::EClkGpio1_I, Prcm::EClkAuto ); + *( (TUint *) Omap3530HwBase::TVirtual<0x48310034>::Value ) = 0xfefffedf; //GPIO1 output enable p3336 + *( (TUint *) Omap3530HwBase::TVirtual<0x48310094>::Value ) = 0x01000120; //GPIO1 set data out p3336 +// const TUint KCM_CLKSEL_DSS = Omap3530HwBase::TVirtual<0x48004E40>::Value; +// Prcm::Set(KCM_CLKSEL_DSS, 0xffffffffu, 0x00001006); + + Prcm::SetDivider( Prcm::EClkDss1_F, 2 ); + Prcm::SetDivider( Prcm::EClkTv_F, 1 ); + + + SET_REGISTER( DSS_SYSCONFIG, 0x00000010 ); // Display Subsystem reset + while ( !( GET_REGISTER( DISPC_SYSSTATUS ) & 1 ) ); // Spin until reset complete + + TInt8 MIDLEMODE = 0x2; // Smart Standby. MStandby is asserted based on the internal activity of the module. + TInt8 CLOCKACTIVITY = 0x0; // interface and functional clocks can be switched off. + TInt8 SIDLEMODE = 0x2; // Smart idle. Idle request is acknowledged based on the internal activity of the module + TInt8 ENWAKEUP = 0x1; // Wakeup is enabled. + TInt8 SOFTRESET = 0x0; // Normal mode + TInt8 AUTOIDLE = 0x1; // Automatic L3 and L4 interface clock gating strategy is applied based on interface activity + l = MIDLEMODE<<12 | CLOCKACTIVITY<<8 | SIDLEMODE<<3 | ENWAKEUP<<2 | SOFTRESET<<1 | AUTOIDLE; + SET_REGISTER( DISPC_SYSCONFIG, l ); + + TInt8 LOADMOAD = 0x2; //Frame data only loaded every frame + l = LOADMOAD<<1; + SET_REGISTER( DISPC_CONFIG, l ); + + SET_REGISTER( DISPC_DEFAULT_COLOR0, 0xFFFFFFFF ); + SET_REGISTER( DISPC_TRANS_COLOR0, 0x00000000 ); + + TUint8 hbp = H_BPORCH - 1; // Horizontal Back Porch + TUint8 hfp = H_FPORCH - 1; // Horizontal front porch + TUint8 hsw = H_SYNC - 1; // Horizontal synchronization pulse width + if ( hsw > 63 ) + { + hsw = 63; + Kern::Printf("[LCD] H_SYNC too big"); + } + l = hbp<<20 | hfp<<8 | hsw; + SET_REGISTER( DISPC_TIMING_H, l ); + + TUint8 vbp = V_BPORCH; // Vertical back porch + TUint8 vfp = V_FPORCH; // Vertical front porch + TUint8 vsw = V_SYNC; // Vertical synchronization pulse width + __ASSERT_ALWAYS( vbp<=255, Kern::Fault("LCD", 1) ); + __ASSERT_ALWAYS( vfp<=255, Kern::Fault("LCD", 1) ); + __ASSERT_ALWAYS( vsw>=1 && vsw<=255, Kern::Fault("LCD", 1) ); + l = vbp<<20 | vfp<<8 | vsw; + SET_REGISTER( DISPC_TIMING_V, l ); + + TUint8 onoff= 0; + TUint8 rf = 0; + TUint8 ieo = 0; + TUint8 ipc = 1; // Invert Pixel Clock + TUint8 ihs = H_SYNC_POL ? 0 : 1; // Invert HSYNC (0: Positive Sync polarity, 1: Negative Sync polarity) + TUint8 ivs = V_SYNC_POL ? 0 : 1; // Invert VSYNC (0: Positive Sync polarity, 1: Negative Sync polarity) + TUint8 acbi = 0; + TUint16 acb = 0x28; // AC-bias pin frequency + l = onoff<<17 | rf<<16 | ieo<<15 | ipc<<14 | ihs<<13 | ivs<<12 | acbi<<8 | acb; + SET_REGISTER( DISPC_POL_FREQ, l ); + + TUint8 lcd = 1; // Display Controller Logic Clock Divisor + TUint8 pcd = ( 432000 + (PIXEL_CLK - 1) ) / PIXEL_CLK; // Pixel Clock Divisor - add (PIXEL_CLK - 1) to avoid rounding error + __ASSERT_ALWAYS( lcd>=1 && lcd<=255, Kern::Fault("LCD", 1) ); + __ASSERT_ALWAYS( pcd>=2 && pcd<=255, Kern::Fault("LCD", 1) ); + l = lcd<<16 | pcd; + SET_REGISTER( DISPC_DIVISOR, l ); + + TUint16 ppl = H_DISP - 1; // Pixels per line + TUint16 llp = V_DISP - 1; // Lines per panel + __ASSERT_ALWAYS( ppl>=1 && ppl<=2048, Kern::Fault("LCD", 1) ); + __ASSERT_ALWAYS( llp>=1 && llp<=2048, Kern::Fault("LCD", 1) ); + l = llp<<16 | ppl; + SET_REGISTER( DISPC_SIZE_LCD, l ); + + + // Setup a graphics region (GFX) + + // Set GFX frame buffer + SET_REGISTER( DISPC_GFX_BA1, ivRamPhys ); + + // Center the GFX + TInt16 gfxposy = ( V_DISP - KConfigLcdHeight ) / 2; + TInt16 gfxposx = ( H_DISP - KConfigLcdWidth ) / 2; + l = ( gfxposy << 16 ) | gfxposx; + SET_REGISTER( DISPC_GFX_POSITION, l ); + + // Set the GFX dimensions + TInt16 gfxsizey = KConfigLcdHeight - 1; + TInt16 gfxsizex = KConfigLcdWidth - 1; + l = gfxsizey<<16 | gfxsizex; + SET_REGISTER( DISPC_GFX_SIZE, l ); + + TInt8 GFXSELFREFRESH = 0x0; + TInt8 GFXARBITRATION = 0x0; + TInt8 GFXROTATION = 0x0; + TInt8 GFXFIFOPRELOAD = 0x0; + TInt8 GFXENDIANNESS = 0x0; + TInt8 GFXNIBBLEMODE = 0x0; + TInt8 GFXCHANNELOUT = 0x0; + TInt8 GFXBURSTSIZE = 0x2; // 16x32bit bursts + TInt8 GFXREPLICATIONENABLE = 0x0; // Disable Graphics replication logic + TInt8 GFXFORMAT = 0x6; // RGB16=0x6, RGB24-unpacked=0x8, RGB24-packed=0x9 + TInt8 GFXENABLE = 0x1; // Graphics enabled + l = GFXSELFREFRESH<<15 | GFXARBITRATION<<14 | GFXROTATION<<12 | GFXFIFOPRELOAD<<11 | GFXENDIANNESS<<10 | GFXNIBBLEMODE<<9 | GFXCHANNELOUT<8 | GFXBURSTSIZE<<6 | GFXREPLICATIONENABLE<<5 | GFXFORMAT<<1 | GFXENABLE; + SET_REGISTER( DISPC_GFX_ATTRIBUTES, l ); + + TInt16 GFXFIFOHIGHTHRESHOLD = 0x3fc; // Graphics FIFO High Threshold + TInt16 GFXFIFOLOWTHRESHOLD = 0x3BC; // Graphics FIFO Low Threshold + l = GFXFIFOHIGHTHRESHOLD<<16 | GFXFIFOLOWTHRESHOLD; + SET_REGISTER(DISPC_GFX_FIFO_THRESHOLD, l); + + TInt16 GFXFIFOSIZE = 0x400; // Number of bytes defining the FIFO value + l = GFXFIFOSIZE; + SET_REGISTER(DISPC_GFX_FIFO_SIZE_STATUS, l); + + TInt32 GFXROWINC = 0x1; + l = GFXROWINC; + SET_REGISTER(DISPC_GFX_ROW_INC, l); + + TInt16 GFXPIXELINC = 0x1; + l = GFXPIXELINC; + SET_REGISTER(DISPC_GFX_PIXEL_INC, l); + + TInt32 GFXWINDOWSKIP = 0x0; + l = GFXWINDOWSKIP; + SET_REGISTER(DISPC_GFX_WINDOW_SKIP, l); + + // TO DO: Sort out the Gamma table + pallets + TInt32 GFXTABLEBA = 0x807ff000; + l = GFXTABLEBA; + SET_REGISTER(DISPC_GFX_TABLE_BA, l); + + + // Propigate all the shadowed registers + + TInt8 SPATIALTEMPORALDITHERINGFRAMES = 0; + TInt8 LCDENABLEPOL = 0; + TInt8 LCDENABLESIGNAL = 0; + TInt8 PCKFREEENABLE = 0; + TInt8 TDMUNUSEDBITS = 0; + TInt8 TDMCYCLEFORMAT = 0; + TInt8 TDMPARALLELMODE = 0; + TInt8 TDMENABLE = 0; + TInt8 HT = 0; + TInt8 GPOUT1 = 1; + TInt8 GPOUT0 = 1; + TInt8 GPIN1 = 0; + TInt8 GPIN0 = 0; + TInt8 OVERLAYOPTIMIZATION = 0; + TInt8 RFBIMODE = 0; + TInt8 SECURE = 0; + TInt8 TFTDATALINES = 0x3; + TInt8 STDITHERENABLE = 0; + TInt8 GODIGITAL = 1; + TInt8 GOLCD = 1; + TInt8 M8B = 0; + TInt8 STNTFT = 1; + TInt8 MONOCOLOR = 0; + TInt8 DIGITALENABLE = 1; + TInt8 LCDENABLE = 1; + l = SPATIALTEMPORALDITHERINGFRAMES<<30 | LCDENABLEPOL<<29 | LCDENABLESIGNAL<<28 | PCKFREEENABLE<<27 | + TDMUNUSEDBITS<<25 | TDMCYCLEFORMAT<<23 | TDMPARALLELMODE<<21 | TDMENABLE<<20 | HT<<17 | GPOUT1<<16 | + GPOUT0<<15 | GPIN1<<14 | GPIN0<<13 | OVERLAYOPTIMIZATION<<12 | RFBIMODE<<11 | SECURE<<10 | + TFTDATALINES<<8 | STDITHERENABLE<<7 | GODIGITAL<<6 | GOLCD<<5 | M8B<<4 | STNTFT<<3 | + MONOCOLOR<<2 | DIGITALENABLE<<1 | LCDENABLE; + NKern::Sleep(1); + SET_REGISTER(DISPC_CONTROL, l); + NKern::Sleep(1); + + } + + +/** +Power down the display and the backlight +*/ +void DLcdPowerHandler::PowerDownLcd() + { + SetBacklightState(EFalse); + + // TO DO: (mandatory) + // Power down the display & disable LCD DMA. + // May need to wait until the current frame has been output + // + + SET_REGISTER(DISPC_CONTROL, 0); + + } + +/** +Set the Lcd contrast + +@param aValue the contrast setting +*/ +TInt DLcdPowerHandler::SetContrast(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue)); + + if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast) + { + iContrast=aValue; + + // TO DO: (mandatory) + // set the contrast + // + return KErrNone; + } + + return KErrArgument; + } + +/** +Set the Lcd brightness + +@param aValue the brightness setting +*/ +TInt DLcdPowerHandler::SetBrightness(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue)); + + if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness) + { + iBrightness=aValue; + + // TO DO: (mandatory) + // set the brightness + // + return KErrNone; + } + return KErrArgument; + } + +/** +Turn the backlight on +*/ +void DLcdPowerHandler::BacklightOn() + { + // TO DO: (mandatory) + // turn the backlight on + // + } + +/** +Turn the backlight off +*/ +void DLcdPowerHandler::BacklightOff() + { + // TO DO: (mandatory) + // turn the backlight off + // + } + +/** +Set the state of the backlight + +@param aState ETrue if setting the backlight on +*/ +void DLcdPowerHandler::SetBacklightState(TBool aState) + { + iBacklightOn=aState; + if (iBacklightOn) + BacklightOn(); + else + BacklightOff(); + } + +void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo")); + anInfo.iWindowHandleValid=EFalse; + anInfo.iWindowHandle=NULL; + anInfo.iScreenAddressValid=ETrue; + anInfo.iScreenAddress=(TAny *)(iChunk->LinearAddress()); + anInfo.iScreenSize.iWidth=KConfigLcdWidth; + anInfo.iScreenSize.iHeight=KConfigLcdHeight; + } + +/** +Handle a message from the power handler +*/ +void DLcdPowerHandler::HandleMsg(void) + { + + TMessageBase* msg = iMsgQ.iMessage; + if (msg == NULL) + return; + + if (msg->iValue) + DisplayOn(); + else + DisplayOff(); + msg->Complete(KErrNone,ETrue); + } + +/** +Send a message to the power-handler message queue to turn the display on +*/ +void DLcdPowerHandler::WsSwitchOnScreen() + { + TThreadMessage& m=Kern::Message(); + m.iValue = ETrue; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up + } + +/** +Send a message to the power-handler message queue to turn the display off +*/ +void DLcdPowerHandler::WsSwitchOffScreen() + { + TThreadMessage& m=Kern::Message(); + m.iValue = EFalse; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down + } + +/** +Return information about the current display mode + +@param aInfo a structure supplied by the caller to be filled by this function. +@param aSecure ETrue if requesting information about the secure display +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo")); + NKern::FMWait(&iLock); + if (aSecure) + aInfo = iSecureVideoInfo; + else + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + return KErrNone; + } + +/** +Return information about the specified display mode + +@param aMode the display mode to query +@param aInfo a structure supplied by the caller to be filled by this function. +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetSpecifiedDisplayModeInfo mode is %d",aMode)); + + if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) + return KErrArgument; + + NKern::FMWait(&iLock); + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + + if (aMode != aInfo.iDisplayMode) + { + aInfo.iOffsetToFirstPixel=Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer; + aInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized; + aInfo.iOffsetBetweenLines=Lcd_Mode_Config[aMode].iOffsetBetweenLines; + aInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel; + } + return KErrNone; + } + +/** +Set the display mode + +@param aMode the display mode to set +*/ +TInt DLcdPowerHandler::SetDisplayMode(TInt aMode) + { + + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode = %d", aMode)); + + if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) + return KErrArgument; + + NKern::FMWait(&iLock); + + // store the current mode + iVideoInfo.iDisplayMode = aMode; + iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer; + iVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized; + iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines; + iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel; + + // store the current mode for secure screen + iSecureVideoInfo.iDisplayMode = aMode; + iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer; + iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized; + iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines; + iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel; + + // TO DO: (mandatory) + // set bits per pixel on hardware + // May need to reconfigure DMA if video buffer size and location have changed + // + NKern::FMSignal(&iLock); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode mode = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d", + aMode, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines)); + + return KErrNone; + } + +/** +Fill the video memory with an initial pattern or image +This will be displayed on boot-up +*/ +void DLcdPowerHandler::SplashScreen() + { + // TO DO: (optional) + // replace the example code below to display a different spash screen + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen +")); + TUint* pV=(TUint*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel); + __KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen FB @ %x",pV)); + + //Fill the framebuffer with bars + + for (TInt y = 0; y> 3); + + TUint16* px = reinterpret_cast(pV) + y*KConfigLcdWidth + x; + *px = rgb; + } + } + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen -")); + } + + +/** +Get the size of the pallete + +@return the number of pallete entries +*/ +TInt DLcdPowerHandler::NumberOfPaletteEntries() //only call when holding mutex + { + // TO DO: (mandatory) + // Calculate the number of Palette entries - this is normally + // calculated from the bits per-pixel. + // This is only example code... you may need to modify it for your hardware + // + TInt num = iVideoInfo.iIsPalettized ? 1<= NumberOfPaletteEntries())) + { + NKern::FMSignal(&iLock); + return KErrArgument; + } + + // TO DO: (mandatory) + // read the RGB value of the palette entry into aColor + // NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer) + // or could be offered as part of the hardware block that implemenst the lcd control + // + NKern::FMSignal(&iLock); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor)); + + return KErrNone; + } + +/** +Set the palette entry at a particular offset + +@param aEntry the palette index +@param aColor the RGB color to store +@return KErrNone if successful + KErrNotSupported if the current vide mode does not support a palette + KErrArgument if aEntry is out of range +*/ +TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor) + { + + NKern::FMWait(&iLock); + if (!iVideoInfo.iIsPalettized) + { + NKern::FMSignal(&iLock); + return KErrNotSupported; + } + + if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries())) //check entry in range + { + NKern::FMSignal(&iLock); + return KErrArgument; + } + + // TO DO: (mandatory) + // update the palette entry for the secure and non-secure screen + // NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer) + // or could be offered as part of the hardware block that implemenst the lcd control + // + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor )); + + return KErrNone; + } + +/** +a HAL entry handling function for HAL group attribute EHalGroupDisplay + +@param a1 an arbitrary argument +@param a2 an arbitrary argument +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EDisplayHalScreenInfo: + { + TPckgBuf vPckg; + ScreenInfo(vPckg()); + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + + case EDisplayHalWsRegisterSwitchOnScreenHandling: + iWsSwitchOnScreen=(TBool)a1; + break; + + case EDisplayHalWsSwitchOnScreen: + WsSwitchOnScreen(); + break; + + case EDisplayHalMaxDisplayContrast: + { + TInt mc=KConfigLcdMaxDisplayContrast; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + case EDisplayHalSetDisplayContrast: + __KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayContrast")); + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast"))) + return KErrPermissionDenied; + r=SetContrast(TInt(a1)); + break; + + case EDisplayHalDisplayContrast: + kumemput32(a1,&iContrast,sizeof(iContrast)); + break; + + case EDisplayHalMaxDisplayBrightness: + { + TInt mc=KConfigLcdMaxDisplayBrightness; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + + case EDisplayHalSetDisplayBrightness: + __KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayBrightness")); + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness"))) + return KErrPermissionDenied; + r=SetBrightness(TInt(a1)); + break; + + case EDisplayHalDisplayBrightness: + kumemput32(a1,&iBrightness,sizeof(iBrightness)); + break; + + case EDisplayHalSetBacklightOn: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + return KErrPermissionDenied; + if (Kern::MachinePowerStatus() vPckg; + r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2); + if (KErrNone == r) + Kern::InfoCopy(*(TDes8*)a1,vPckg); + } + break; + + case EDisplayHalSpecifiedModeInfo: + { + TPckgBuf vPckg; + TInt mode; + kumemget32(&mode, a1, sizeof(mode)); + r = GetSpecifiedDisplayModeInfo(mode, vPckg()); + if (KErrNone == r) + Kern::InfoCopy(*(TDes8*)a2,vPckg); + } + break; + + case EDisplayHalSecure: + kumemput32(a1, &iSecureDisplay, sizeof(TBool)); + break; + + case EDisplayHalSetSecure: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure"))) + return KErrPermissionDenied; + SwitchDisplay((TBool)a1); + } + break; + + default: + r=KErrNotSupported; + break; + } + return r; + } + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager")); + + // create LCD power handler + TInt r=KErrNoMemory; + DLcdPowerHandler* pH=new DLcdPowerHandler; + if (pH) + r=pH->Create(); + + __KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r)); + return r; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/lcd/lcd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/lcd/lcd.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,51 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// beagle/beagle_drivers/lcd.mmp +// lcd.dll Beagle LCD driver +// + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include "beagle/variant.mmh" +#include "kernel/kern_ext.mmh" + +target VariantTarget(lcd,dll) +targettype kext +romtarget lcd.dll + +sourcepath . +source lcd.cpp + +userinclude . + +library VariantTarget(ecust,lib) +LIBRARY AsspTarget(prcm, lib) +//LIBRARY AsspTarget(i2c, lib) +//LIBRARY AsspTarget(kaomap3530, lib) + +noexportlibrary + +epocallowdlldata + +uid 0x1000008d 0x100039e8 + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/led/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/led/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,20 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +led diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/led/led.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/led/led.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,94 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/led/led.cpp +// + +#include +#include +#include +#include +#include +#include // GPIO interrupts + +#include // Required for definition of TIsr + +static NTimer * heartBeatTimer; + + + +static void ledIsr(TAny* aPtr) + { + //make sure the led is always in the sma estate when we crash + + GPIO::SetOutputState(KGPIO_LED1, GPIO::ELow); + Kern::Fault("User invoked crash via keypad",KErrDied); + } + +static void beatLedHeartBeat(TAny * ptr) + { + GPIO::TGpioState ledState; + GPIO::GetOutputState(KGPIO_LED1, ledState); + + if(GPIO::EHigh == ledState) + { + GPIO::SetOutputState(KGPIO_LED1, GPIO::ELow); + } + else + { + GPIO::SetOutputState(KGPIO_LED1, GPIO::EHigh); + } + + heartBeatTimer->Again(Variant::GetMsTickPeriod()); + } + + +DECLARE_STANDARD_EXTENSION() + { + + //Set up the button to proivde a panic button invoking Fault() + if(KErrNone != GPIO::SetPinDirection(KGPIO_UserButton, GPIO::EInput)) + return KErrArgument; + + GPIO::SetPinMode(KGPIO_UserButton, GPIO::EEnabled); + GPIO::SetDebounceTime(KGPIO_UserButton, 500); + + if(KErrNone !=GPIO::BindInterrupt(KGPIO_UserButton, ledIsr,NULL)) + return KErrArgument; + + if(KErrNone !=GPIO::SetInterruptTrigger(KGPIO_UserButton, GPIO::EEdgeRising)) + return KErrArgument; + + if(KErrNone !=GPIO::EnableInterrupt(KGPIO_UserButton)) + { + GPIO::UnbindInterrupt(KGPIO_UserButton); + return KErrInUse; + } + + //setup the Led to flash at the system tick rate ( heartbeat) + heartBeatTimer = new NTimer(beatLedHeartBeat,NULL); + + if(KErrNone != GPIO::SetPinDirection(KGPIO_LED1, GPIO::EOutput)) + return KErrArgument; + + if(KErrNone != GPIO::SetPinDirection(KGPIO_LED0, GPIO::EOutput)) + return KErrArgument; + + GPIO::SetPinMode(KGPIO_LED0, GPIO::EEnabled); + GPIO::SetPinMode(KGPIO_LED1, GPIO::EEnabled); + GPIO::SetOutputState(KGPIO_LED0, GPIO::ELow); + + heartBeatTimer->OneShot(Variant::GetMsTickPeriod(),ETrue); + return KErrNone; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/led/led.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/led/led.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,43 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// oamp3530/beagle_drivers/led/led.mmp +// led.dll Beagle LED driver +// + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include "beagle/variant.mmh" +#include "kernel/kern_ext.mmh" + +target VariantTarget(led,dll) +targettype kext +romtarget led.dll + +sourcepath . +source led.cpp + +library VariantTarget(ecust,lib) +library AsspTarget(gpio,lib) +library AsspTarget(prcm, lib) + +VENDORID 0x70000001 + +capability none +EPOCALLOWDLLDATA diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,23 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/serialmouse/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +serialmouse +serialmouse_tshell + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/serialmouse.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/serialmouse.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,434 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/serialmouse/serialmouse.cpp +// Serial mouse driver +// + + + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include + +#include +//#include +#include +//#include + +#include "serialmouse.h" + +_LIT( KName, "SERMOUSE" ); + +#ifdef _FRAME_BUFFER_CURSOR_ +# define CURSOR_SIZE 5 +#endif + + +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + TSerialMouse* pH=(TSerialMouse*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + +TSerialMouse::TSerialMouse() + : iKeyDfc( KeyDfcFn, this, Kern::DfcQue0(), 1 ), iState(ENormal), + iUart( Omap3530Uart::EUart2 ) + { + Kern::Printf("+TSerialMouse::TSerialMouse"); + +# ifdef _FRAME_BUFFER_CURSOR_ + iCursorBuffer = new TUint16[CURSOR_SIZE*CURSOR_SIZE]; +# endif + + } + +TSerialMouse::~TSerialMouse() + { +# ifdef _FRAME_BUFFER_CURSOR_ + delete[] iCursorBuffer; +# endif + } + +TInt TSerialMouse::Create() + { + + GetScreenInfo(); + + TInt r=Kern::AddHalEntry(EHalGroupMouse, halFunction, this); + if (r!=KErrNone) + return r; + + + __KTRACE_OPT(KBOOT,Kern::Printf("+TSerialMouse::Init")) ; + + iDebugPort = Kern::SuperPage().iDebugPort; // Get the debug port number + if( Arm::EDebugPortJTAG == iDebugPort ) + { + __KTRACE_OPT(KBOOT,Kern::Printf("-TSerialMouse::Init: JTAG not supported")); + // We don't want to return an error here, just don't bother to initialize + return KErrNone; + } + else if( 2 != iDebugPort ) + { + __KTRACE_OPT(KBOOT,Kern::Printf("-TSerialMouse::Init: Only UART3 supported")); + // We don't want to return an error here, just don't bother to initialize + return KErrNone; + } + + + // Register with the power resource manager + //r = PowerResourceManager::RegisterClient( iPrmClientId, KName ); + //if( r != KErrNone ) + // { + // return r; + // } + + //__KTRACE_OPT(KBOOT,Kern::Printf("+TSerialMouse::Init:PRM client ID=%x", iPrmClientId )) ; + + r =Interrupt::Bind( iUart.InterruptId(),Isr,this); + if ( r < 0 ) + { + Kern::Printf("TSerialMouse::Create Cant Bind to Interrupt %d ret %d",iUart.InterruptId(), r ); + return r; + } + + // Ask power resource manager to turn on clocks to the UART + // (this could take some time but we're not in any hurry) + //r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmFunctionClk(), Prcm::EClkAuto ); + //if( KErrNone != r ) + // { + // return r; + // } + + //r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmInterfaceClk(), Prcm::EClkAuto ); + //if( KErrNone != r ) + // { + // return r; + // } + + iUart.Init(); + iUart.DefineMode( Omap3530Uart::TUart::EUart ); + iUart.SetBaud( Omap3530Uart::TUart::E1200 ); + iUart.SetDataFormat( Omap3530Uart::TUart::E7Data, Omap3530Uart::TUart::E1Stop, Omap3530Uart::TUart::ENone ); + iUart.EnableFifo( Omap3530Uart::TUart::EEnabled, Omap3530Uart::TUart::ETriggerUnchanged, Omap3530Uart::TUart::ETrigger8 ); + iUart.EnableInterrupt( Omap3530Uart::TUart::EIntRhr ); + iUart.Enable(); + + Interrupt::Enable(iUart.InterruptId()); + + return KErrNone; + } + + +void TSerialMouse::Isr( TAny* aPtr ) + // + // Interrupt service routine. Called when we receive an interrupt + // on the IRQ line it is bound to. If it's a receive, queues DFC + // to post the event into the event queue. + // + { + TSerialMouse* self = (TSerialMouse*)aPtr; + + const TUint iir = Omap3530Uart::IIR::iMem.Read( self->iUart ); + + if ( 0 == (iir bitand Omap3530Uart::IIR::IT_PENDING::KMask) ) + { + const TUint pending = iir bitand Omap3530Uart::IIR::IT_TYPE::KFieldMask; + + // Although the TI datasheet descrivwed IT_TYPE as being an enumerated priority-decoded interrupt + // it appears to actually be a bitmask of active interrupt sources + if ( (pending bitand Omap3530Uart::IIR::IT_TYPE::ERHR) || (pending bitand Omap3530Uart::IIR::IT_TYPE::ERxLineStatus) ) + { + TUint byte = self->iUart.Read(); + + self->iKey = byte; + self->iKeyDfc.Add(); + Interrupt::Disable( self->iUart.InterruptId() ); + } + } + } + +void TSerialMouse::KeyDfcFn( TAny* aPtr ) + // + // DFC function. Just calls inline function KeyDfc() + // + { + ((TSerialMouse*)aPtr)->KeyDfc(); + } + +inline void TSerialMouse::KeyDfc() + // + // Processes received characters + // + { + + const TUint8 b = iKey; + + if ( b & 1<<6 ) + { + // Beginning of a new frame + iByteIndex = 0; + iB0 = b; + } + else if ( iByteIndex == 0 ) + { + iByteIndex = 1; + iB1 = b; + } + else if ( iByteIndex == 1 ) + { + iByteIndex = -1; + iB2 = b; + + const TInt8 x_increment = (iB0 & 0x3)<<6 | (iB1 & 0x3f); + const TInt8 y_increment = (iB0 & 0xC)<<4 | (iB2 & 0x3f); + const TBool isLeftButtonDown = iB0& 1<<5; + const TBool isRightButtonDown = iB0& 1<<4; + +# ifdef _FRAME_BUFFER_CURSOR_ + iLastX = iX; + iLastY = iY; +# endif + + iX += x_increment; //Scale ( x_increment ); + iY += y_increment; //Scale ( y_increment ); + + Clip( iX, iY ); + + //DBG_PRINT4(_L("\nx:%d y:%d (%d,%d)"), x_increment, y_increment, iX, iY ); + + TBool rightButtonEvent = (isRightButtonDown != iLastRightButtonDown); + TBool leftButtonEvent = (isLeftButtonDown != iLastLeftButtonDown); + iLastLeftButtonDown = isLeftButtonDown; + iLastRightButtonDown = isRightButtonDown; + + TRawEvent e; + + if ( rightButtonEvent ) + { + e.Set( isRightButtonDown ? TRawEvent::EButton2Down : TRawEvent::EButton2Up, iX, iY ); + Kern::AddEvent(e); + //DBG_PRINT1(_L(" right:%S"), isRightButtonDown?&_L("down"):&_L("up") ); + } + + if ( leftButtonEvent ) + { + e.Set( isLeftButtonDown ? TRawEvent::EButton1Down : TRawEvent::EButton1Up, iX, iY ); + Kern::AddEvent(e); + //DBG_PRINT1(_L(" left:%S"), isLeftButtonDown?&_L("down"):&_L("up") ); + } + + if ( !rightButtonEvent && !leftButtonEvent ) + { +# ifdef _TRACK_COORDINATES_ + // Reoprt the exact coordinate to the windowserver + e.Set(TRawEvent::EPointerMove,iX,iY); +# else + // Report the change in coordinates to the windowserver + e.Set(TRawEvent::EPointerMove,x_increment,y_increment); +# endif + Kern::AddEvent(e); + } + +# ifdef _FRAME_BUFFER_CURSOR_ + DrawCursor(iX,iY); +# endif + + } + + Interrupt::Enable(iUart.InterruptId()); // Can handle new chars now + } /* end of function - KeyDfc - */ + + +/* +Perform 2:1 scaling on a mosue movement. +*/ +TInt TSerialMouse::Scale(const TInt& aVal) + { + switch (aVal) + { + case 0: return 0; + case 1: + case 2: return 1; + case 3: return 3; + case 4: return 6; + case 5: return 9; + case -1: + case -2: return -1; + case -3: return -3; + case -4: return -6; + case -5: return -9; + default: return 2*aVal; + } + } + +/* +Clip the mouse coordinates into the dimensions of the screen +*/ +void TSerialMouse::Clip(TInt& aX, TInt& aY) + { + if ( aX < 0 ) aX = 0; + if ( aX >= iScreenWidth ) aX = iScreenWidth - 1; + if ( aY < 0 ) aY = 0; + if ( aY >= iScreenHeight ) aY = iScreenHeight - 1; + } + +void TSerialMouse::GetScreenInfo() + { + TScreenInfoV01 screenInfo; + TPckg sI(screenInfo); + Kern::HalFunction(EHalGroupDisplay,EDisplayHalScreenInfo,(TAny*)&sI,NULL); + iScreenWidth = screenInfo.iScreenSize.iWidth; + iScreenHeight = screenInfo.iScreenSize.iHeight; +# ifdef _FRAME_BUFFER_CURSOR_ + iVideoAddress = (TUint8*)screenInfo.iScreenAddress; +# endif + } + +#ifdef _FRAME_BUFFER_CURSOR_ +void TSerialMouse::Blit(TInt x, TInt y, TUint16 aColour) + { + + TUint16* fb = (TUint16*)iVideoAddress; + fb += (iLastY * iScreenWidth) + iLastX; + for (TInt i = 0; i= iScreenHeight) break; + + for (TInt j = 0; j= iScreenHeight) break; + + for (TInt j = 0; j cur; + cur.FillZ(); + TUint8* cursor = &cur[0]; + + for (TInt i = 0; i= iScreenHeight) break; + + TInt bytes_to_copy = Min( cursorSize, iScreenWidth*2 - x*2 ); + + Mem::Copy(fb, cursor, bytes_to_copy ); + + cursor += cursorSize; + + }*/ + + } + +void TSerialMouse::DrawCursor(TInt x, TInt y) + { + TUint16 cursorColour = iLastLeftButtonDown ? 0x1F : 0x00; + Blit(x, y, cursorColour); + } +#endif + + +TInt TSerialMouse::HalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/) + { + TInt r=KErrNone; + switch(aFunction) + { + case EMouseHalMouseInfo: + { + TPckgBuf vPckg; + TMouseInfoV01& xyinfo=vPckg(); + xyinfo.iMouseButtons=2; + xyinfo.iMouseAreaSize.iWidth=iScreenWidth; + xyinfo.iMouseAreaSize.iHeight=iScreenHeight; + xyinfo.iOffsetToDisplay.iX=0; + xyinfo.iOffsetToDisplay.iY=0; + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + default: + r=KErrNotSupported; + break; + } + return r; + } + +void DoCreate( TAny* aParam ) + { + TInt r = reinterpret_cast< TSerialMouse* >( aParam )->Create(); + __ASSERT_ALWAYS( r == KErrNone, Kern::Fault( "SERKEY-Cr", r ) ); + } + + +// +// Kernel Extension entry point +// +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Starting mouse driver")); + + // create mouse driver + TInt r=KErrNoMemory; + TSerialMouse* mouse = new TSerialMouse; + if ( mouse ) + { + // Because the Power Resource Manager doesn't finish initializing until after it + // has run a DFC on SvMsgQue, we need to defer our initialization until after that + // so we know that the PRM is ready for us to use it + static TDfc createDfc( &DoCreate, NULL ); + new( &createDfc ) TDfc( &DoCreate, mouse, Kern::SvMsgQue(), KMaxDfcPriority-2 ); + createDfc.Enque(); + r = KErrNone; + } + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/serialmouse.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/serialmouse.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,75 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\beagle_variant\inc\serialmouse.h +// Header for serial mouse driver +// + +#ifndef __VSERIALMOUSE_H__ +#define __VSERIALMOUSE_H__ + +#include +#include + + +class TSerialMouse +{ +public: + TSerialMouse(); + ~TSerialMouse(); + TInt Create(); + static void Isr(TAny* aPtr); + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); + +private: + static void KeyDfcFn(TAny* aPtr); + inline void KeyDfc(); + + TInt Scale(const TInt& aVal); + void Clip(TInt& aX, TInt& aY); + void GetScreenInfo(); + + enum TState { ENormal, EEscapingStart, EEscapingType1, EEscapingType2 }; +private: + TDfc iKeyDfc; + TUint iKey; + TInt iDebugPort; + TState iState; + Omap3530Uart::TUart iUart; + TUint iPrmClientId; + +private: + TInt iScreenWidth; + TInt iScreenHeight; + TInt iByteIndex; + TUint8 iB0; + TUint8 iB1; + TUint8 iB2; + TInt iX; + TInt iY; + TInt iLastX; + TInt iLastY; + TBool iLastLeftButtonDown; + TBool iLastRightButtonDown; + +#ifdef _FRAME_BUFFER_CURSOR_ + void DrawCursor(TInt x, TInt y); + void Blit(TInt x, TInt y, TUint16 aColour); + TUint8* iVideoAddress; + TUint16* iCursorBuffer; +#endif + +}; + + +#endif /* __VSERIALMOUSE_H__ */ diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/serialmouse.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/serialmouse.mmh Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,36 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/serialmouse.mmh +// + +#include "beagle/variant.mmh" +#include "kernel/kern_ext.mmh" + +epocallowdlldata + +library VariantTarget(ecust,lib) +library AsspTarget(kaomap3530,lib) +library AsspTarget(uart,lib) +//library resman.lib + +systeminclude +/include/drivers + +targettype kext + +sourcepath . +source serialmouse.cpp + +uid 0x1000008d 0x100039e8 +capability all +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/serialmouse.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/serialmouse.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,23 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/serialmouse.mmp +// + +macro _FRAME_BUFFER_CURSOR_ + +#include "serialmouse.mmh" + +target VariantTarget(serialmouse,dll) +romtarget eserialmouse.dll + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/serialmouse/serialmouse_tshell.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/serialmouse/serialmouse_tshell.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,24 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/serialmouse.mmp +// + +macro _FRAME_BUFFER_CURSOR_ +macro _TRACK_COORDINATES + +#include "serialmouse.mmh" + +target VariantTarget(serialmouse_tshell,dll) +romtarget eserialmouse.dll + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/usbv/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/usbv/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,21 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/usbv/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +usbv diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/usbv/usbv.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/usbv/usbv.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,202 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/usb/usbv.cpp +// + +#include +#include +// Platform-dependent USB client controller layer (USB PSL). +#include +#include +#include + + +// I2C Bit definitions +// PHY_CLK_CTRL +const TUint KCLK32K_EN = KBit1; +const TUint KREQ_PHY_DPLL_CLK = KBit0; +// PHY_CLK_STS +const TUint KPHY_DPLL_CLK = KBit0; +// MCPC_CTRL2 +const TUint KMPC_CLK_EN = KBit0; +// FUNC_CTRL +const TUint KXCVRSELECT_HS = 0x0; +const TUint KXCVRSELECT_FS = KBit0; +const TUint KXCVRSELECT_MASK = 0x3; +const TUint KTERMSELECT = KBit2; +const TUint KOPMODE_DISABLED = KBit4; +const TUint KOPMODE_MASK = KBit3 | KBit4; +// MCPC_IO_CTRL +const TUint KRXD_PU = KBit3; +// OTG_CTRL +const TUint KDPPULLDOWN = KBit1; +const TUint KDMPULLDOWN = KBit2; +// POWER_CTRL +const TUint KOTG_EN = KBit5; +// VUSB???_DEV_GRP +const TUint KDEV_GRP_P1 = KBit5; +// CFG_BOOT +const TUint KHFCLK_FREQ_26Mhz = KBit1; + + +NONSHARABLE_CLASS( TBeagleUsbPhy ) : public MOmap3530UsbPhy + { +public: + TBeagleUsbPhy(); + TInt Construct(); + + virtual void StartPHY(); + virtual void SetPHYMode( DOmap3530Usbcc::TPHYMode aMode ); + virtual void EnablePHY(); + virtual void DisablePHY(); + +private: + TInt iPHYEnabled; + }; + + + +TBeagleUsbPhy::TBeagleUsbPhy() + { + } + +TInt TBeagleUsbPhy::Construct() + { + return KErrNone; + } + + +void TBeagleUsbPhy::StartPHY() + { + // PHY clock must be enabled before this point (can't enable it in this function as it is called from an ISR context) + TPS65950::DisableProtect(); + + // Enable the USB LDO's (low-dropout regulators) + TPS65950::ClearSetSync(TPS65950::Register::VUSB1V5_DEV_GRP,0x00,KDEV_GRP_P1); + TPS65950::ClearSetSync(TPS65950::Register::VUSB1V8_DEV_GRP,0x00,KDEV_GRP_P1); + TPS65950::ClearSetSync(TPS65950::Register::VUSB3V1_DEV_GRP,0x00,KDEV_GRP_P1); + + TPS65950::ClearSetSync(TPS65950::Register::CFG_BOOT,0x00, KHFCLK_FREQ_26Mhz); + + TPS65950::RestoreProtect(); + } + +void TBeagleUsbPhy::SetPHYMode( DOmap3530Usbcc::TPHYMode aMode ) + { + EnablePHY(); + switch(aMode) + { + // Configure trancever (see swcu05b.pdf table 15-21 D+/D- Termination settings) + case DOmap3530Usbcc::ENormal: + TPS65950::WriteSync(TPS65950::Register::MCPC_CTRL2_CLR, KMPC_CLK_EN); // Not UART Mode + TPS65950::WriteSync(TPS65950::Register::FUNC_CTRL_CLR,(KXCVRSELECT_MASK | KTERMSELECT | KOPMODE_DISABLED )); // XCVRSELECT high speed mode (HS), TERM SELECT=0, OPMODE=0 (normal operation) + TPS65950::WriteSync(TPS65950::Register::MCPC_IO_CTRL_CLR, KRXD_PU); + TPS65950::WriteSync(TPS65950::Register::OTG_CTRL_CLR, KDPPULLDOWN | KDMPULLDOWN); // Disable DP pulldown + TPS65950::WriteSync(TPS65950::Register::POWER_CTRL_SET, KOTG_EN); + break; + case DOmap3530Usbcc::EPowerUp: + // Power up or VBUS0) + { + iPHYEnabled--; + } + } + + +EXPORT_C MOmap3530UsbPhy* MOmap3530UsbPhy::New() + { + __KTRACE_OPT(KUSB, Kern::Printf(" > Initializing USB PHY")); + + TBeagleUsbPhy* const phy = new TBeagleUsbPhy; + if (!phy) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for TBeagleUsbPhy failed")); + return NULL; + } + + TInt r; + if ((r = phy->Construct()) != KErrNone) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Construction of TBeagleUsbPhy failed (%d)", r)); + delete phy; + return NULL; + } + + return phy; + } + + +DECLARE_STANDARD_EXTENSION() + { + return KErrNone; + } + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/usbv/usbv.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/usbv/usbv.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,40 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/usbv/usbv.mmp +// + +#include "beagle/variant.mmh" +#include "kernel/kern_ext.mmh" + +target VariantTarget(usbv,dll) +targettype kext +linkas usbv.dll +noexportlibrary + +systeminclude +/include/drivers + +sourcepath . +source usbv.cpp + +library AsspTarget(kaomap3530,lib) +library tps65950.lib + +nostrictdef +deffile +/include/assp/omap3530_assp/~/usbv.def + +epocallowdlldata + +capability all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,61 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/bld.inf +// Master build description file for beagle variant +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS +./variant.mmh beagle/ +inc/iolines.h beagle/ +inc/mconf.h beagle/ +inc/variantmediadef.h beagle/ +inc/beagle_gpio.h beagle/ +inc/variant.h beagle/ + +rom/beagle.oby ../rom/include/ +rom/base_beagle.iby ../rom/include/ +rom/header.iby ../rom/beagle/ +rom/kernel.iby ../rom/beagle/ +rom/test.iby ../rom/beagle/ + +PRJ_MMPFILES +src/vbeagle + +// Build MEDINT.PDD - this depends on our variantmediadef.h +../../../../../../sf/os/kernelhwsrv/kernel/eka/drivers/medint/medint + + +// +// Call the makefile to build the bootstrap +// + +PRJ_EXTENSIONS +start extension base/bootstrap + +option NAME _beagle_bootrom +option CPU arm +option MEMMODEL multiple +option SOURCES beagle.s +option EXTRA_SRC_PATH $(EXTENSION_ROOT)/bootstrap +option EXTRA_INC_PATH $(EXTENSION_ROOT)/bootstrap +option INCLUDES $(EXTENSION_ROOT)/bootstrap/config.inc +option E32PATH $(EXTENSION_ROOT)/../../../../../../sf/os/kernelhwsrv/kernel + +end + + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bootstrap/autoload.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bootstrap/autoload.cmm Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,43 @@ +// Autoload script, called by TRACE32 if symbols are to be loaded + +// define local macros + local &filename &basename &progname &symfilename &filepath &code &data &space &databsslinear &basename + +// get filename and relocation information + // these parameters are passed when calling this skript + + entry &filename &code &data &databsslinear &space + + // &filename: name of process/file + // &code: text segment address + // &data: data segment address (not used in Symbian OS) + // &databsslinear: combined data & bss segment address + // &space: space id of process (not used here) + +// get symbol file name and program name + &basename=string.cut(&filename,-string.len(os.file.extension(&filename))) + &symfilename="&basename"+".sym" + &progname=os.file.name("&basename") + +// delete program if it already exists or other code is already there + y.delete &code + if y.exist("\\&progname") + y.delete \\&progname + +// search file in source search path and open dialog when not there + &filepath=y.searchfile("&symfilename") + if !os.file("&filepath") + ( + local &file + &file=os.file.name("&symfilename") + winpos ,,,,,, filebox normal "Searching symbols for &filename" + dialog.file "*\&file" + entry %line &filepath + if "&filepath"=="" + enddo + ) + +// load symbol file (options for sourcepath, e.g. /STRIPPART may need to be added when required) + d.load.elf "&filepath" /noclear /cpp /nocode /reloc ER_RO at &code /reloc ER_RW at &databsslinear /reloc ER_ZI after ER_RW + + enddo diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bootstrap/aware.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bootstrap/aware.cmm Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,28 @@ + + + local &system + +; Check if system is running +; Store present state to restore back later + + if run() + ( + &system="run" + Break + ) + + +; Initialize Symbian OS Support + + print "initializing Symbian OS support..." + + TASK.CONFIG symbian2 ; loads Symbian OS awareness (symbian2.t32) + MENU.ReProgram symbian2 ; loads Symbian OS menu (symbian2.men) + HELP.FILTER.Add rtossymbian2 ; add Symbian OS awareness manual to help filter + +; Ok, we're done, let's continue Symbian OS + + if "&system"=="run" + Go + + enddo diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bootstrap/beagle.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bootstrap/beagle.cmm Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,118 @@ + +screen.always +SYStem.CPU OMAP3530 +SYStem.JtagClock 10.0MHz + +Break.Delete +MAP.RESet +TASK.RESet +sYmbol.RESet +Data.PROLOG.RESet +Data.EPILOG.RESet +sYmbol.AutoLoad.CHECK OFF ; disable dynamic autoloader +sYmbol.AutoLoad.RESet ; reset autoloader list + +TrOnchip.Set FIQ OFF ; FIQ be handled by Symbian OS +TrOnchip.Set IRQ OFF ; IRQ be handled by Symbian OS +TrOnchip.Set DABORT ON +TrOnchip.Set PABORT ON +TrOnchip.Set SWI OFF ; SWI be handled by Symbian OS +TrOnchip.Set UNDEF ON +TrOnchip.Set RESET ON + +MAP.RESet +TASK.RESet +sYmbol.RESet +Data.PROLOG.RESet +Data.EPILOG.RESet +sYmbol.AutoLoad.CHECK OFF ; disable dynamic autoloader +sYmbol.AutoLoad.RESet ; reset autoloader list + +SYStem.Mode Attach + +Break + +&drive="P:" + +d.load.b "&drive\sf\os\kernelhwsrv\kernel\eka\rombuild\BEAGLEARMV5D.IMG" 0x81000000 + +; Before mmu enabled +d.load.elf "&drive\epoc32\release\armv5\_beagle_bootrom.sym" /nocode /rvct /reloc ER_RO at 0x81000000 +; After MMU enabled +;d.load.elf "&drive\epoc32\release\armv5\_beagle_bootrom.sym" /nocode /rvct /reloc ER_RO at 0x80000000 + +&_SYMBOL_FILE="&drive\sf\os\kernelhwsrv\kernel\eka\rombuild\ROMBUILD.LOG" +&basepath="&drive\" +if "&_SYMBOL_FILE"!="" + ( + ; Search paths for symbol files: + symbol.SourcePATH.setrecursedir &drive\sf\os\boardsupport\omap3530 + symbol.SourcePATH.setrecursedir &drive\sf\os\kernelhwsrv\kernel\eka\e32 + symbol.SourcePATH.setrecursedir &drive\sf\os\kernelhwsrv\kerneltest\e32test + symbol.SourcePATH.setrecursedir &drive\sf\os\kernelhwsrv\kerneltest\e32utils + + print "Selected symbol file: &_SYMBOL_FILE" + symbol.AutoLoad.LOADEPOC &_SYMBOL_FILE "do "+os.ppd()+"/autoload " + ; define dynamic autoloader + symbol.AutoLoad.CHECKEPOC "do "+os.ppd()+"/autoload " + + ; switch off automatic process detection (slows down debugger execution) + symbol.AutoLoad.CHECK OFF + + ; Load symbols for following: + symbol.AutoLoad.TOUCH "*kaomap3530.dll" + symbol.AutoLoad.TOUCH "*ekern.exe" + symbol.AutoLoad.TOUCH "*btracex.ldd" + symbol.AutoLoad.TOUCH "*ecust.dll" + symbol.AutoLoad.TOUCH "*exmoncommon.dll" + symbol.AutoLoad.TOUCH "*exmondebug.dll" + symbol.AutoLoad.TOUCH "*power.dll" + symbol.AutoLoad.TOUCH "*dma.dll" + symbol.AutoLoad.TOUCH "*lcd.dll" + symbol.AutoLoad.TOUCH "*ekeyb.dll" + symbol.AutoLoad.TOUCH "*ekdata.dll" + symbol.AutoLoad.TOUCH "*exyin.dll" + symbol.AutoLoad.TOUCH "*euart.pdd" + symbol.AutoLoad.TOUCH "*esdrv.pdd" + symbol.AutoLoad.TOUCH "*soundsc.pdd" +; symbol.AutoLoad.TOUCH "*elocd.ldd" + symbol.AutoLoad.TOUCH "*medint.pdd" +; symbol.AutoLoad.TOUCH "*ecomm.ldd" +; symbol.AutoLoad.TOUCH "*esound.ldd" +; symbol.AutoLoad.TOUCH "*pipelib.ldd" +; symbol.AutoLoad.TOUCH "*esoundsc.ldd" +; symbol.AutoLoad.TOUCH "*exstart.dll" +; symbol.AutoLoad.TOUCH "*usbc.ldd" + symbol.AutoLoad.TOUCH "*exyin.dll" + symbol.AutoLoad.TOUCH "*i2c.dll" + symbol.AutoLoad.TOUCH "*usbcc.dll" + symbol.AutoLoad.TOUCH "*prcm.dll" + symbol.AutoLoad.TOUCH "*gpio.dll" + symbol.AutoLoad.TOUCH "*led.dll" + +; symbol.CLEANUP + ) +else + ( + print "No symbol file selected, symbols not loaded" + ) + + + +R.S PC 0x81000000 + +b.s Fault /p /onchip +b.s NKCrashHandler /p /onchip +; b.s I2c::Open /p /onchip +; b.s \\t_i2c\t_i2c\InitExtension /p /onchip +; b.s I2c::TheDfc /p /onchip +; b.s I2c::TI2c::Isr /p /onchip +; b.s \\t_prcm\t_prcm\InitExtension /p /onchip +; b.s Prcm::Init3 /p /onchip +; b.s DLcdPowerHandler::PowerUpLcd /p /onchip +; b.s \\_BEAGLE_LED\led\InitExtension /p /onchip + +m.h +d.l + +enddo diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bootstrap/beagle.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bootstrap/beagle.s Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,660 @@ +; Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of the License "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; omap3530/beagleboard/bootstrap/beagle.s +; Template for platform specific boot code +; + + GBLL __VARIANT_S__ ; indicates that this is platform-specific code + GBLL __BEAGLEBOARD_S__ ; indicates which source file this is + + INCLUDE bootcpu.inc + +; +;******************************************************************************* +; +; Platform specific constant definitions + +DRamBankBase EQU 0x80000000 ; 128M of DRAM +DRamBankMaxSize EQU 0x08000000 + +; HW used by bootstrap +Serial0PhysBase EQU 0x4806A000 +Serial1PhysBase EQU 0x4806C000 +Serial2PhysBase EQU 0x49020000 +PrimaryIOBase EQU 0xC6000000 ; c.f. KPrimaryIOBase in mmboot.h +Serial0LinBase EQU PrimaryIOBase + 0x0006A000 +Serial1LinBase EQU PrimaryIOBase + 0x0006C000 +Serial2LinBase EQU PrimaryIOBase + 0x00420000 + +SuperPageAddr EQU 0x85000000 ; boot stack goes just after this +TheHwvd EQU 0x09080001 ; this is arbitary 0908 are CPU and ASSP 01 is variant + +; +;******************************************************************************* +; + + AREA |Boot$$Code|, CODE, READONLY, ALIGN=6 + +; +;******************************************************************************* +; + + + + +;******************************************************************************* +; Initialise Hardware +; Initialise CPU registers +; Determine the hardware configuration +; Determine the reset reason. If it is wakeup from a low power mode, perform +; whatever reentry sequence is required and jump back to the kernel. +; Set up the memory controller so that at least some RAM is available +; Set R10 to point to the super page or to a temporary version of the super page +; with at least the following fields valid: +; iBootTable, iCodeBase, iActiveVariant, iCpuId +; In debug builds initialise the debug serial port +; +; Enter with: +; R12 points to TRomHeader +; NO STACK +; R14 = return address (as usual) +; +; All registers may be modified by this call +;******************************************************************************* + IF CFG_BootLoader + ; For bootloader we only get here on a full reset + ; Other resets will simply jump back into the previously-loaded image + EXPORT DoInitialiseHardware +DoInitialiseHardware ROUT + ELSE + EXPORT InitialiseHardware +InitialiseHardware ROUT + ENDIF + MOV r13, lr ; save return address + ADRL r1, ParameterTable ; pass address of parameter table + BL InitCpu ; initialise CPU/MMU registers + + ; Put your hardware initialising code here + + IF CFG_DebugBootRom + BL InitDebugPort + ENDIF + +; Set up the required super page values + LDR r10, =SuperPageAddr ; initial super page + LDR r0, =TheHwvd ; variant code + STR r0, [r10, #SSuperPageBase_iActiveVariant] + STR r0, [r10, #SSuperPageBase_iHwStartupReason] ; reset reason (from hardware) + ADD r1, r10, #CpuPageOffset + STR r1, [r10, #SSuperPageBase_iMachineData] + ADRL r0, BootTable + STR r0, [r10, #SSuperPageBase_iBootTable] ; Set the boot function table + STR r12, [r10, #SSuperPageBase_iCodeBase] ; Set the base address of bootstrap code + MRC p15, 0, r0, c0, c0, 0 ; read CPU ID from CP15 (remove if no CP15) + STR r0, [r10, #SSuperPageBase_iCpuId] + + MOV pc, r13 ; return + + + + + +;******************************************************************************* +; Notify an unrecoverable error during the boot process +; +; Enter with: +; R14 = address at which fault detected +; +; Don't return +;******************************************************************************* + EXPORT Fault +Fault ROUT + B BasicFaultHandler ; generic handler dumps registers via debug + ; serial port + + + + + +;******************************************************************************* +; Reboot the system +; +; Enter with: +; R0 = reboot reason code +; +; Don't return (of course) +;******************************************************************************* + ALIGN 32, 0 + EXPORT RestartEntry +RestartEntry ROUT + ; save R0 parameter in HW dependent register which is preserved over reset + ; put HW specific code here to reset system + SUB pc, pc, #8 + + + + + +;******************************************************************************* +; Get a pointer to the list of RAM banks +; +; The pointer returned should point to a list of {BASE; MAXSIZE;} pairs, where +; BASE is the physical base address of the bank and MAXSIZE is the maximum +; amount of RAM which may be present in that bank. MAXSIZE should be a power of +; 2 and BASE should be a multiple of MAXSIZE. The generic code will examine the +; specified range of addresses and determine the actual amount of RAM if any +; present in the bank. The list is terminated by an entry with zero size. +; +; The pointer returned will usually be to constant data, but could equally well +; point to RAM if dynamic determination of the list is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetRamBanks ROUT + ADR r0, %FT1 + MOV pc, lr +1 + ; DRAM has been set-up by boot loader so no need to configure or probe + DCD DRamBankBase | RAM_VERBATIM, DRamBankMaxSize + DCD 0,0 ; terminator + + + + + +;******************************************************************************* +; Get a pointer to the list of ROM banks +; +; The pointer returned should point to a list of entries of SRomBank structures, +; usually declared with the ROM_BANK macro. +; The list is terminated by a zero size entry (four zero words) +; +; ROM_BANK PB, SIZE, LB, W, T, RS, SS +; PB = physical base address of bank +; SIZE = size of bank +; LB = linear base if override required - usually set this to 0 +; W = bus width (ROM_WIDTH_8, ROM_WIDTH_16, ROM_WIDTH_32) +; T = type (see TRomType enum in kernboot.h) +; RS = random speed +; SS = sequential speed +; +; Only PB, SIZE, LB are used by the rest of the bootstrap. +; The information given here can be modified by the SetupRomBank call, if +; dynamic detection and sizing of ROMs is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetRomBanks ROUT + ADR r0, %FT1 + MOV pc, lr +1 + DCD 0,0,0,0 ; terminator + + + + + +;******************************************************************************* +; Get a pointer to the list of hardware banks +; +; The pointer returned should point to a list of hardware banks declared with +; the HW_MAPPING and/or HW_MAPPING_EXT macros. A zero word terminates the list. +; For the direct memory model, all hardware on the system should be mapped here +; and the mapping will set linear address = physical address. +; For the moving or multiple model, only the hardware required to boot the kernel +; and do debug tracing needs to be mapped here. The linear addresses used will +; start at KPrimaryIOBase and step up as required with the order of banks in +; the list being maintained in the linear addresses used. +; +; HW_MAPPING PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are the standard I/O permissions (BTP_Hw). +; +; HW_MAPPING_EXT PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are determined by a BTP_ENTRY macro +; immediately following this macro in the HW bank list or by a DCD directive +; specifying a different standard permission type. +; +; HW_MAPPING_EXT2 PB, SIZE, MULT, LIN +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; is specified by the LIN parameter. +; The permissions used for the mapping are the standard I/O permissions (BTP_Hw). +; +; HW_MAPPING_EXT3 PB, SIZE, MULT, LIN +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; is specified by the LIN parameter. +; The permissions used for the mapping are determined by a BTP_ENTRY macro +; immediately following this macro in the HW bank list or by a DCD directive +; specifying a different standard permission type. +; +; Configurations without an MMU need not implement this function. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetHwBanks ROUT + ADR r0, %FT1 + MOV pc, lr +1 + HW_MAPPING 0x48000000, 4, HW_MULT_1M ; L4-Core KPrimaryIOBase + HW_MAPPING 0x49000000, 1, HW_MULT_1M ; L4-Per KPrimaryIOBase + 0x00400000 + HW_MAPPING 0x50000000, 1, HW_MULT_64K ; SGX Graphic accelerator slave port KPrimaryIOBase + 0x00500000 + HW_MAPPING 0x54000000, 8, HW_MULT_1M ; L4-Emu KPrimaryIOBase + 0x00600000 + HW_MAPPING 0x68000000, 1, HW_MULT_1M ; L3 Control Registers KPrimaryIOBase + 0x00E00000 + HW_MAPPING 0x6E000000, 1, HW_MULT_1M ; GPMC registers KPrimaryIOBase + 0x00F00000 + +; HW_MAPPING 0x5C000000, 48, HW_MULT_1M ; IVA2.2 SS KPrimaryIOBase + 0x01910000 +; HW_MAPPING 0x70000000,128, HW_MULT_1M ; SDRC-SMS virtual address space 0 KPrimaryIOBase + 0x08910000 +; HW_MAPPING 0x78000000,128, HW_MULT_1M ; Continued + + DCD 0 ; terminator + +;******************************************************************************* +; Set up RAM bank +; +; Do any additional RAM controller initialisation for each RAM bank which wasn't +; done by InitialiseHardware. +; Called twice for each RAM bank :- +; First with R3 = 0xFFFFFFFF before bank has been probed +; Then, if RAM is present, with R3 indicating validity of each byte lane, ie +; R3 bit 0=1 if D0-7 are valid, bit1=1 if D8-15 are valid etc. +; For each call R1 specifies the bank physical base address. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R1 = physical base address of bank +; R3 = width (bottom 4 bits indicate validity of byte lanes) +; 0xffffffff = preliminary initialise +; +; Leave with : +; No registers modified +;******************************************************************************* +SetupRamBank ROUT + MOV pc, lr + + + + + +;******************************************************************************* +; Set up ROM bank +; +; Do any required autodetection and autosizing of ROMs and any additional memory +; controller initialisation for each ROM bank which wasn't done by +; InitialiseHardware. +; +; The first time this function is called R11=0 and R0 points to the list of +; ROM banks returned by the BTF_RomBanks call. This allows any preliminary setup +; before autodetection begins. +; +; This function is subsequently called once for each ROM bank with R11 pointing +; to the current information held about that ROM bank (SRomBank structure). +; The structure pointed to by R11 should be updated with the size and width +; determined. The size should be set to zero if there is no ROM present in the +; bank. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R11 points to SRomBank info for this bank +; R11 = 0 for preliminary initialise (all banks) +; +; Leave with : +; Update SRomBank info with detected size/width +; Set the size field to 0 if the ROM bank is absent +; Can modify R0-R4 but not other registers +; +;******************************************************************************* +SetupRomBank ROUT + MOV pc, lr + + + + + +;******************************************************************************* +; Reserve physical memory +; +; Reserve any physical RAM needed for platform-specific purposes before the +; bootstrap begins allocating RAM for page tables/kernel data etc. +; +; There are two methods for this: +; 1. The function ExciseRamArea may be used. This will remove a contiguous +; region of physical RAM from the RAM bank list. That region will never +; again be identified as RAM. +; 2. A list of excluded physical address ranges may be written at [R11]. +; This should be a list of (base,size) pairs terminated by a (0,0) entry. +; This RAM will still be identified as RAM by the kernel but will not +; be allocated by the bootstrap and will subsequently be marked as +; allocated by the kernel immediately after boot. +; +; Enter with : +; R10 points to super page +; R11 indicates where preallocated RAM list should be written. +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R3 may be modified. Other registers should be preserved. +;******************************************************************************* +ReservePhysicalMemory ROUT + MOV pc, lr + + + + + +;******************************************************************************* +; Return parameter specified by R0 (see TBootParam enum) +; +; Enter with : +; R0 = parameter number +; +; Leave with : +; If parameter value is supplied, R0 = value and N flag clear +; If parameter value is not supplied, N flag set. In this case the +; parameter may be defaulted or the system may fault. +; R0,R1,R2 modified. No other registers modified. +; +;******************************************************************************* +GetParameters ROUT + ADR r1, ParameterTable + B FindParameter +ParameterTable + ; Include any parameters specified in TBootParam enum here + ; if you want to override them. + DCD BPR_UncachedLin, 0 ; parameter number, parameter value + IF :DEF: CFG_CPU_ARM1136 :LAND: (:LNOT: :DEF: CFG_CPU_ARM1136_ERRATUM_364296_FIXED) + DCD BPR_FinalMMUCRSet, ExtraMMUCR + MMUCR_FI + DCD BPR_AuxCRSet, DefaultAuxCRSet + 0x80000000 + ENDIF + DCD -1 ; terminator + + + + + +;******************************************************************************* +; Do final platform-specific initialisation before booting the kernel +; +; Typical uses for this call would be: +; 1. Mapping cache flushing areas +; 2. Setting up pointers to routines in the bootstrap which are used by +; the variant or drivers (eg idle code). +; +; Enter with : +; R10 points to super page +; R11 points to TRomImageHeader for the kernel +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R9 may be modified. Other registers should be preserved. +; +;******************************************************************************* +FinalInitialise ROUT + STMFD sp!, {lr} + LDMFD sp!, {pc} + + + + +KHwUartSsr EQU 0x44 ; Supplementary status register +KTxFifoFullMask EQU 0x01 +KHwUartThr EQU 0x00 ; Transmit holding register + +KHwUartSysC EQU 0x54 ; System configuration register +KSoftResetMask EQU 0x02 +KHwUartLcr EQU 0x0C ; Line control register +KConfigurationModeB EQU 0xBF +KConfigurationModeA EQU 0x80 +KOperationMode EQU 0x00 +K8BitsNoParity1Stop EQU 0x03 +KHwUartEfr EQU 0x08 ; Enhanced feature register +KEnhancedEnMask EQU 0x10 +KHwUartMcr EQU 0x10 +KTcrTlr EQU 0x40 +KHwUartFcr EQU 0x08 +KFifoConfiguration EQU 0x01 ; 8 deep Rx, 8 deep Tx, FIFO Enable +KHwUartDll EQU 0x00 ; Divisor latch low +K115k2L EQU 0x1A +K230k4L EQU 0x0D +K460k8L EQU 0x08 +K921k6L EQU 0x04 +KHwUartMdr1 EQU 0x20 ; Mode definition register 1 +KUART16XMode EQU 0x00 + +;******************************************************************************* +; Output a character to the debug port +; +; Enter with : +; R0 = character to output +; R13 points to valid stack +; +; Leave with : +; nothing modified +;******************************************************************************* +DoWriteC ROUT + IF CFG_DebugBootRom + STMFD sp!, {r1,lr} + BL GetDebugPortBase + +1 LDR lr, [r1, #KHwUartSsr] ; Check status + TST lr, #KTxFifoFullMask ; If transmit data full, wait + BNE %BT1 + STR r0, [r1, #KHwUartThr] ; Store to data register + + LDMFD sp!, {r1,pc} + ELSE + MOV pc, lr + ENDIF + + IF CFG_DebugBootRom + +;******************************************************************************* +; Initialise the debug port +; +; Enter with : +; R12 points to ROM header +; There is no valid stack +; +; Leave with : +; R0-R2 modified +; Other registers unmodified +;******************************************************************************* +InitDebugPort ROUT ; Based on the OMAP3530TRM 17.5.1.1 Quick Start + MOV r0, lr + BL GetDebugPortBase ; r1 = base address of debug port + MOV lr, r0 + + MOV r2, #KSoftResetMask + STR r2, [r1, #KHwUartSysC] ; Perform a soft reset of the UART + + MOV r2, #KConfigurationModeB + STR r2, [r1, #KHwUartLcr] ; UART to configuration mode B + + LDR r2, [r1, #KHwUartEfr] + ORR r2, #KEnhancedEnMask + STR r2, [r1, #KHwUartEfr] ; Enable the IER, FCR, MCR + + MOV r2, #KConfigurationModeA + STR r2, [r1, #KHwUartLcr] ; UART to configuration mode A + + LDR r2, [r1, #KHwUartMcr] + ORR r2, #KTcrTlr + STR r2, [r1, #KHwUartMcr] ; Enable the TCR, TLR + + MOV r2, #KFifoConfiguration + STR r2, [r1, #KHwUartFcr] ; FIFO + + MOV r2, #KConfigurationModeB + STR r2, [r1, #KHwUartLcr] ; UART to configuration mode B + + LDR r2, [r1, #KHwUartEfr] + AND r2, #~KEnhancedEnMask + STR r2, [r1, #KHwUartEfr] ; Disable the IER, FCR, MCR + + MOV r2, #KConfigurationModeA + STR r2, [r1, #KHwUartLcr] ; UART to configuration mode A + + LDR r2, [r1, #KHwUartMcr] + AND r2, #~KTcrTlr + STR r2, [r1, #KHwUartMcr] ; Disable the TCR, TLR + + MOV r2, #KOperationMode + STR r2, [r1, #KHwUartLcr] ; UART to operation mode + + ; 17.5.1.1.3 + + ; MDR1[2:0] is 0x7(Disable) from reset + + MOV r2, #KConfigurationModeB + STR r2, [r1, #KHwUartLcr] ; UART to configuration mode B + + LDR r2, [r1, #KHwUartEfr] + ORR r2, #KEnhancedEnMask + STR r2, [r1, #KHwUartEfr] ; Enable the IER, FCR, MCR + + ; IER is clear from Reset + + MOV r2, #K115k2L + STR r2, [r1, #KHwUartDll] ; Set baud rate + ; DLH is 00 from Reset + + ; IER is clear from Reset + + MOV r2, #K8BitsNoParity1Stop + STR r2, [r1, #KHwUartLcr] + + MOV r2, #KUART16XMode + STR r2, [r1, #KHwUartMdr1] + + + MOV r1, #0x19000 ; Set up delay loop to allow line to settle + SUBS r1, r1, #1 + SUBNE pc, pc, #12 + + MOV pc, lr + +;******************************************************************************* +; Get the base address of the debug UART +; +; Enter with : +; R12 points to ROM header +; There may be no stack +; +; Leave with : +; R1 = base address of port +; No other registers modified +;******************************************************************************* +GetDebugPortBase ROUT + LDR r1, [r12, #TRomHeader_iDebugPort] + CMP r1, #42 ; JTAG? + MOVEQS r1, #0 + MOVEQ pc, lr ; yes - return 0 and set Z + + CMP r1, #2 + BNE %FA1 ; skip if not port 2 + GET_ADDRESS r1, Serial2PhysBase, Serial2LinBase + MOVS r1, r1 ; clear Z + MOV pc, lr +1 + CMP r1, #1 + BNE %FA1 ; skip if not port 1 + GET_ADDRESS r1, Serial1PhysBase, Serial1LinBase + MOVS r1, r1 ; clear Z + MOV pc, lr +1 + GET_ADDRESS r1, Serial0PhysBase, Serial0LinBase + MOVS r1, r1 ; clear Z + MOV pc, lr + + ENDIF ; CFG_DebugBootRom + + + + + +;******************************************************************************* +; BOOT FUNCTION TABLE +;******************************************************************************* + +BootTable + DCD DoWriteC ; output a debug character + DCD GetRamBanks ; get list of RAM banks + DCD SetupRamBank ; set up a RAM bank + DCD GetRomBanks ; get list of ROM banks + DCD SetupRomBank ; set up a ROM bank + DCD GetHwBanks ; get list of HW banks + DCD ReservePhysicalMemory ; reserve physical RAM if required + DCD GetParameters ; get platform dependent parameters + DCD FinalInitialise ; Final initialisation before booting the kernel + DCD HandleAllocRequest ; allocate memory + DCD GetPdeValue ; usually in generic code + DCD GetPteValue ; usually in generic code + DCD PageTableUpdate ; usually in generic code + DCD EnableMmu ; Enable the MMU (usually in generic code) + +; These entries specify the standard MMU permissions for various areas +; They can be omitted if MMU is absent + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; ROM + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; kernel data/stack/heap + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; super page/CPU page + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page directory/tables + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; exception vectors + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; hardware registers + DCD 0 ; unused (minicache flush) + DCD 0 ; unused (maincache flush) + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page table info + BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; user RAM + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_STRONGLY_ORDERED, 1, 1, 0, 0 ; temporary identity mapping + BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; uncached + + END diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/bootstrap/config.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/bootstrap/config.inc Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,166 @@ +; Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of the License "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; Beagle bootstrap configuration file + +; Include to enable tracing +; GBLL CFG_DebugBootRom + +; Include one of these to select the CPU +; GBLL CFG_CPU_GENERIC_ARM4 +; GBLL CFG_CPU_ARM710T +; GBLL CFG_CPU_ARM720T +; GBLL CFG_CPU_SA1 +; GBLL CFG_CPU_ARM920T +; GBLL CFG_CPU_ARM925T +; GBLL CFG_CPU_ARM926J +; GBLL CFG_CPU_XSCALE +; GBLL CFG_CPU_ARM1136 +; GBLL CFG_CPU_ARM1176 +; GBLL CFG_CPU_CORTEX_A8 + GBLL CFG_CPU_CORTEX_A8N + +; Include the following line if this is a bootloader bootstrap +; GBLL CFG_BootLoader +; The following line needs to be removed for target hardware + GBLL CFG_Beagle + +; If you want to supply a custom set of initial vectors (including reset vector) include the following line +; GBLL CFG_CustomVectors +; +; and provide a custom_vectors.inc file + +; Variant Number, just an example: + INIT_NUMERIC_CONSTANT CFG_HWVD, 0x09080001 + +; On ARM architecture 6 processors, include the following line to override the threshold +; on total physical RAM size at which the multiple memory model switches into large address space mode +; i.e. size>threshold -> 2Gb per process, size<=threshold -> 1Gb per process +; Defaults to 32Mb. +; INIT_NUMERIC_CONSTANT CFG_ARMV6_LARGE_CONFIG_THRESHOLD, + +; For the direct memory model only, include the following line if you wish the exception vectors at the +; start of the bootstrap to be used at all times. This is only relevant if an MMU is present - this option +; is mandatory if not. +; GBLL CFG_UseBootstrapVectors +; +; If the above option is in use (including if no MMU is present) the following symbol should be defined +; to specify the offset from the bootstrap to the kernel image. + INIT_NUMERIC_CONSTANT KernelCodeOffset, 0x4000 + +; Include the following line if you wish to include the ROM autodetection code based on data bus +; capacitance and image repeats. +; GBLL CFG_AutoDetectROM + +; Include the following line to minimise the initial kernel heap size +; On the direct memory model the size of the kernel data area (super page to end of kernel heap) +; is rounded up to the next 1Mb if this is not included, 4K if it is. +; On the moving and multiple models, the size of the initial kernel heap area is rounded up to +; the next 64K if this is not included, 4K if it is. +; GBLL CFG_MinimiseKernelHeap + +; Include the following line if default memory mapping should use shared memory. +; Should be defined on multicore (SMP) devices. +; GBLL CFG_USE_SHARED_MEMORY + +; On the moving or multiple memory models, include either or both of the following lines to +; specify the size of the initial kernel heap +; INIT_NUMERIC_CONSTANT CFG_KernelHeapMultiplier, +; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, +; +; The initial kernel heap size is MAX( + * N / 16, value specified in ROMBUILD ) +; where N is the total physical RAM size in pages. +; defaults to 24K and defaults to 9*16 (ie 9 bytes per page). + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 353494 +; "Rare conditions can cause corruption of the Instruction Cache" +; is fixed on this hardware. +; +; NOTE: The boot table should use this macro to determine whether RONO or RORO permissions +; are used for the exception vectors. If the erratum is not fixed, RORO must be used. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_353494_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 364296 +; "Possible Cache Data Corruption with Hit-Under-Miss" +; is fixed on this hardware. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_364296_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 399234 +; "Write back data cache entry evicted by write through entry causes data corruption" +; is fixed on this hardware. +; Workaround +; The erratum may be avoided by marking all cacheable memory as one of write through or write back. +; This requires the memory attributes described in the translation tables to be modified by software +; appropriately, or the use of the remapping capability to remap write through regions to non cacheable. +; +; If this macro is enabled, it should be accompanied by: +; "macro __CPU_ARM1136_ERRATUM_399234_FIXED" in variant.mmh +; GBLL CFG_CPU_ARM1136_ERRATUM_399234_FIXED + + +; Uncomment if: +; 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill" +; is fixed on this hardware, or +; 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill +; is fixed on this hardware. +; Workaround: +; 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +; If this macro is enabled, it should be accompanied by: +; "macro __CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +; +; GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED + + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 415662: "Invalidate Instruction Cache by +; Index might corrupt cache when used with background prefetch range" is fixed on this hardware. +; Workaround: +; Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_415662_FIXED + + + +; These are deduced from the supplied configuration +; CFG_ARMV6 +; CFG_MMUPresent +; CFG_CachePresent +; CFG_WriteBufferPresent +; CFG_SplitCache +; CFG_SplitTLB +; CFG_AltDCachePresent +; CFG_WriteBackCache +; CFG_CacheWriteAllocate +; CFG_CachePhysicalTag +; CFG_CacheFlushByDataRead +; CFG_CacheFlushByWaySetIndex +; CFG_CacheFlushByLineAlloc +; CFG_CachePolicyInPTE +; CFG_TEX +; CFG_SingleEntryDCacheFlush +; CFG_SingleEntryICacheFlush +; CFG_SingleEntryITLBFlush +; CFG_SingleEntryTLBFlush +; CFG_CacheTypeReg +; CFG_BTBPresent +; CFG_CARPresent +; CFG_PrefetchBuffer +; CFG_FCSE_Present +; CFG_ASID_Present +; CFG_IncludeRAMAllocator + + END diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/def/eabi/vbeagle.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/def/eabi/vbeagle.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,11 @@ +EXPORTS + _Z17VariantInitialisev @ 1 NONAME + _ZN6Beagle27SystemTimeInSecondsFrom2000ERi @ 2 NONAME + _ZN6Beagle30SetSystemTimeInSecondsFrom2000Ei @ 3 NONAME + _ZN7Variant10PowerResetEv @ 4 NONAME + _ZN7Variant14BaseLinAddressEv @ 5 NONAME + _ZN7Variant15GetMsTickPeriodEv @ 6 NONAME + _ZN7Variant16MarkDebugPortOffEv @ 7 NONAME + _ZN7Variant8SwitchesEv @ 8 NONAME + _ZN7Variant8UartInitEv @ 9 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/inc/beagle_gpio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/inc/beagle_gpio.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,32 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/inc/gpio.h +// + +#ifndef __BEAGLE_GPIO_H__ +#define __BEAGLE_GPIO_H__ + +#include + +const TUint KGPIOINT_UserButton = EGPIOIRQ_PIN_7; +const TUint KGPIOINT_LED0 = EGPIOIRQ_PIN_149; +const TUint KGPIOINT_LED1 = EGPIOIRQ_PIN_150; +const TUint KGPIOINT_TFP410_POWERDOWN = EGPIOIRQ_PIN_170;//DVI_PUP Controls the DVI-D interface. A Hi = DVI-D enabled. +const TUint KGPIOINT_MMC1_WP = EGPIOIRQ_PIN_29; // I MMC1_WP SD/MMC card slot Write protect + +const TUint KGPIO_UserButton = 7; +const TUint KGPIO_LED0 = 149; +const TUint KGPIO_LED1 = 150; + +#endif //__BEAGLE_GPIO_H__ diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/inc/iolines.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/inc/iolines.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,117 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/inc/iolines.h +// Variant layer header for Beagle Platform +// + + + +#ifndef __V32TEMPLATEV1_H__ +#define __V32TEMPLATEV1_H__ +#include +#include +#include + +//---------------------------------------------------------------------------- +// Variant-specific constants: use #define if constant dependencies are not +// declared within this file (this breaks the dependency on other header files) +//---------------------------------------------------------------------------- + +// Examples of what goes in here include: +// +// - General-purpose I/O allocation such as +// #define KtVariantGpio32KHzClkOut KHtGpioPort1 +// #define KtVariantGpioRClkOut KHtGpioPort0 +// +// #define KmVariantPinDirectionIn Sleep 0 +// +// - Memory constants (type, geometry, wait states, etc) such as: +// #define KwVariantRom0Type TTemplate::ERomTypeBurst4Rom +// #define KwVariantRom0Width TTemplate::ERomWidth32 +// const TUint KwVariantRom0WaitNs = 150; +// const TUint KwVariantRom0PageNs = 30; +// const TUint KwVariantRom0RecoverNs = 55; +// +// - Specific Peripherals (Keyboard, LCD, CODECS, Serial Ports) such as +// const TUint KwVariantKeyColLshift = 7; +// #define KwVariantLcdBpp TTemplate::ELcd8BitsPerPixel +// const TUint KwVariantLcdMaxColors = 4096; +// const TUint KwVariantCodecMaxVolume = 0; +// +// - Off-chip hardware control blocks (addresses, register make-up) +// +// - Interrupts (second-level Interrupt controller base address, register make-up): +// (EXAMPLE ONLY:) +const TUint32 KHwVariantPhysBase = 0x40000000; +const TUint32 KHoVariantRegSpacing = 0x200; + +const TUint32 KHoBaseIntCont = 0x0B*KHoVariantRegSpacing; + +const TUint32 KHoIntContEnable = 0x00; // offsets from KHwVariantPhysBase+KHoBaseIntCont +const TUint32 KHoIntContPending = 0x04; +// other Variant and external blocks Base adrress offsets to KHwVariantPhysBase + + +const TInt KIntIdKeyboard=0; + + +class GpioPin; + +class Variant + { + // below is a selection of functions usually implemented at this level. This do not constitute a mandatory + // set and it might not be relevant for your hardware... +public: + /** + * initialisation + */ + static void Init3(); + /** + * Returns the Linear Base address of the Variant Hardware + */ + IMPORT_C static TUint BaseLinAddress(); + /** + * When invoked, turns off all power supplies + */ + IMPORT_C static void PowerReset(); + /** + * When invoked, it marks the Serial port used for outputting debug strings as requiring re-initialisation + * As in, for example, the serial port was used by a device driver or the system is coming back from Standby + */ + IMPORT_C static void MarkDebugPortOff(); + /** + * When invoked, initialises the Serial Port hardware for the serial port used to output Debug strings + * Called by Template::DebugInit() + */ + IMPORT_C static void UartInit(); + /** + * When invoked, read the state of on-board switches + * @return A bitmask with the state of on-board switches + */ + IMPORT_C static TUint Switches(); + // other functions to access hardware not covered by specific device-drivres, which may be called from drivers + // or platform-specifc code + // ... + IMPORT_C static TInt SetGPIOPin(TInt aId,GpioPin *aPin); + IMPORT_C static TInt GetGPIOPin(TInt aId,GpioPin * aPin); + IMPORT_C static TInt GetMsTickPeriod(); + +public: + static TUint32 iBaseAddress; + // (optional): May need to have a follower variable to store the value of a read only register initialised at boot time + // static TUint aFollower; + }; + +#endif + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/inc/mconf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/inc/mconf.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,54 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard\inc\mconf.h +// Beagle Persistent Machine Configuration +// + + + +#ifndef __MCONF_H__ +#define __MCONF_H__ +#include + +class TDigitizerCalibrateValues + { +public: + TInt iR11; + TInt iR12; + TInt iR21; + TInt iR22; + TInt iTx; + TInt iTy; + }; + +class TBeagleMachineConfig : public TMachineConfig + { +public: + TSoundInfoV1 iSoundInfo; + TOnOffInfoV1 iOnOffInfo; + TTimeK iMainBatteryInsertionTime; + Int64 iMainBatteryInUseMicroSeconds; + Int64 iExternalPowerInUseMicroSeconds; + Int64 iMainBatteryMilliAmpTicks; + TDigitizerCalibrateValues iCalibration; + TDigitizerCalibrateValues iCalibrationSaved; + TDigitizerCalibrateValues iCalibrationFactory; + }; + +typedef TBeagleMachineConfig TActualMachineConfig; + +inline TActualMachineConfig& TheActualMachineConfig() + {return (TActualMachineConfig&)Kern::MachineConfig();} + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/inc/variant.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/inc/variant.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,151 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/inc/variant.h +// Beagle Variant Header +// + + + +#ifndef __VA_STD_H__ +#define __VA_STD_H__ +#include +#include +#include +#include +#include + +void ExtIrqDispatch(TAny * ptr); + +#define DEC_TO_BCD(dec) (((dec/10)<<4)+(dec%10)) +#define BCD_TO_DEC(bcd) (((bcd>>4)*10)+bcd%16) + + +NONSHARABLE_CLASS(Beagle) : public Omap3530Assp + { +public: + Beagle(); + + static inline Beagle& Variant(); + +public: + /** + * These are the mandatory Asic class functions which need to be implemented here. The other mandatory + * functions are implemented in TemplateAssp + */ + + /** + * initialisation + */ + virtual void Init1(); + virtual void Init3(); + + /** + * power management + * Device specific Idle: prepares the CPU to go into Idle and sets out the conditions to come out of it + */ + virtual void Idle(); + + /** + * debug + * @param aChar Character to be output by debug serial port + */ + virtual void DebugOutput(TUint aChar); + + /** + * HAL + * @param aFunction A TVariantHalFunction enumerated value + * @param a1 Optional input/output parameter + * @param a2 Optional input/output parameter + * @return System wide error code. + * @see TVariantHalFunction + */ + virtual TInt VariantHal(TInt aFunction, TAny* a1, TAny* a2); + + /** + * Machine configuration + * @return Pointer to a device configuration information + * @see TTemplateMachineConfig + */ + virtual TPtr8 MachineConfiguration(); + +public: + virtual TInt IsExternalInterrupt(TInt anId); + virtual TInt InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr); + virtual TInt InterruptUnbind(TInt anId); + virtual TInt InterruptEnable(TInt anId); + virtual TInt InterruptDisable(TInt anId); + virtual TInt InterruptClear(TInt anId); + + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the Variant. + * These virtual functions are called by the USB PSL (pa_usbc.cpp). + * If this functionality is part of the ASSP then these functions can be removed as calls to them + * in the PSL will have been replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable(); + virtual TBool UsbClientConnectorInserted(); + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr); + virtual void UnregisterUsbClientConnectorCallback(); + virtual TBool UsbSoftwareConnectable(); + virtual TInt UsbConnect(); + virtual TInt UsbDisconnect(); + + virtual TInt SystemTimeInSecondsFrom2000(TInt& aTime); + /** + * Obtain Adjust the RTC with new System Time (from 00:00 hours of 1/1/2000) + * @return System wide error code + */ + virtual TInt SetSystemTimeInSecondsFrom2000(TInt aTime); + + + /** + * RAM zone callback functions that will be invoked by the kernel when a RAM zone + * operation should be performed. + */ + static TInt RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks); + TInt DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks); + + /** Input clock frequency information */ + virtual TUint SysClkFrequency() const; + virtual TUint SysClk32kFrequency() const; + virtual TUint AltClkFrequency() const; + +private: + void DebugInit(); + static void UsbClientConnectorIsr(TAny *); + + +public: + TDfc * iExtInterruptDfc; + // TLinAddr iIdleFunction; // may be used to point to a Bootstrap routine which prepares the CPU to Sleep + TBool iDebugInitialised; + +private: + TInt (*iUsbClientConnectorCallback)(TAny*); + TAny* iUsbClientConnectorCallbackArg; + + TInt32 iFrameBufferSize; + TPhysAddr iFrameBufferRamPhys; + }; + +GLREF_D Beagle TheVariant; + + +inline Beagle& Beagle::Variant() + { + return *reinterpret_cast< Beagle* >( Arch::TheAsic() ); + } + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/inc/variantmediadef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/inc/variantmediadef.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,51 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/inc/variantmediadef.h +// Media definitions for Beagle variant. +// Each Media Driver requires the following definitions +// DRIVECOUNT - The total number of local drive object to be assigned to the Media Driver (1-KMaxLocalDrives) +// DRIVELIST - A list of the local drive numbers (each separated with a comma) to be assigned to the Media Driver. +// Each in the range 0 - (KMaxLocalDrives-1). Total number of drive numbers must equal the value +// of DRIVECOUNT. +// NUMMEDIA - The total number of media objects to be assigned to the Media Driver. +// DRIVENAME - A name for the drive group. +// For the complete set of media definitions +// - The total number of local drive objects assigned should not exceed KMaxLocalDrives. +// - Each Media Driver should be assigned a unique set of drive numbers - no conflicts between Media Drivers. +// - The total number of media objects assigned should not exceed KMaxLocalDrives. +// + +#ifndef __VARIANTMEDIADEF_H__ +#define __VARIANTMEDIADEF_H__ + +// Variant parameters for IRAM Media Driver (MEDINT.PDD) +#define IRAM_DRIVECOUNT 1 +#define IRAM_DRIVELIST 0 +#define IRAM_NUMMEDIA 1 +#define IRAM_DRIVENAME "IRam" + +// Variant parameters for the MMC Controller (EPBUSMMC.DLL) +#define MMC0_DRIVECOUNT 1 +#define MMC0_DRIVELIST 3 +#define MMC0_NUMMEDIA 1 +#define MMC0_DRIVENAME "MultiMediaCard0" + +// Variant parameters for the NAND media driver (MEDNAND.PDD) +// Note that the NANDLOADER code expects the are to be 2 drives/partitions +#define NAND_DRIVECOUNT 2 +#define NAND_DRIVELIST 6,7 +#define NAND_NUMMEDIA 1 +#define NAND_DRIVENAME "Nand" + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/base.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/base.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,164 @@ +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\rombuild\base.iby +// + +#ifndef __BASE_IBY__ +#define __BASE_IBY__ + +REM Base operating system, including all assp-specific files + +#if defined(__MISA__) +#include +#elif defined(__MI920__) +#include +#elif defined(__NI1136__) +#include +#elif defined(__MCOT__) +#include +#elif defined(__TEMPLATE__) +#include +#elif defined(__MOMAP16XX_H2__) +#include +#elif defined(__MOMAP24XX_H4HRP__) +#include +#elif defined(__X86PCHRP__) +#include +#elif defined(__NE1_TB__) +#include +#elif defined(__SYBORG__) +#include +#elif defined(__G3EVM__) +#include +#elif defined(__BEAGLE__) +#include +#endif + + +//#include + +#if !defined(GENERIC_MARM) +file=ABI_DIR\DEBUG_DIR\drtaeabi.dll \sys\bin\DRTAEABI.dll +#if !defined(RVCT2_1) && defined(VFPHELPERS) && !defined(NOVFPHELPERS) +file=ABI_DIR\DEBUG_DIR\dfpaeabi_vfpv2.dll \sys\bin\DFPAEABI.dll +#else +file=ABI_DIR\DEBUG_DIR\dfpaeabi.dll \sys\bin\DFPAEABI.dll +#endif +#ifdef RVCT2_1 +// RVCT 2.1 specific intrinsics and helpers +file=ABI_DIR\DEBUG_DIR\drtrvct2_1.dll \sys\bin\DRTRVCT2_1.dll +file=ABI_DIR\DEBUG_DIR\dfprvct2_1.dll \sys\bin\DFPRVCT2_1.dll +file=ABI_DIR\DEBUG_DIR\dfprvct2_1-thunk.dll \sys\bin\dfprvct2_1-thunk.dll +#else +// RVCT 2.2 specific intrinsics and helpers +#if defined(VFPHELPERS) && !defined(NOVFPHELPERS) +file=ABI_DIR\DEBUG_DIR\drtrvct2_2_vfpv2.dll \sys\bin\DRTRVCT2_2.dll +file=ABI_DIR\DEBUG_DIR\dfprvct2_2_vfpv2.dll \sys\bin\DFPRVCT2_2.dll +#else +file=ABI_DIR\DEBUG_DIR\drtrvct2_2.dll \sys\bin\DRTRVCT2_2.dll +file=ABI_DIR\DEBUG_DIR\dfprvct2_2.dll \sys\bin\DFPRVCT2_2.dll +#endif +file=ABI_DIR\DEBUG_DIR\dfprvct2_2-thunk.dll \sys\bin\dfprvct2_2-thunk.dll +file=ABI_DIR\DEBUG_DIR\scppnwdl.dll \sys\bin\SCPPNWDL.dll +// alias these to support existing 2.1 derived binaries +alias \sys\bin\DRTRVCT2_2.dll \sys\bin\DRTRVCT2_1.dll +alias \sys\bin\DFPRVCT2_2.dll \sys\bin\DFPRVCT2_1.dll +alias \sys\bin\dfprvct2_2-thunk.dll \sys\bin\dfprvct2_1-thunk.dll +#endif +#endif + + + + +#if defined(GENERIC_MARM) +file=ABI_DIR\DEBUG_DIR\eka1_entry_stub.dll \sys\bin\Eka1_Entry_Stub.dll +#endif + +#if !defined(EUSER_DLL) || defined(GENERIC_EUSER) +#undef EUSER_DLL +#define EUSER_DLL EUSER.DLL +#endif + +file=ABI_DIR\DEBUG_DIR\EUSER_DLL \sys\bin\EUser.dll +file=ABI_DIR\DEBUG_DIR\RPIPE.DLL \sys\bin\rpipe.dll + +file=ABI_DIR\DEBUG_DIR\ektran.dll \sys\bin\EKTran.dll +file=ABI_DIR\DEBUG_DIR\HAL_DLL \sys\bin\Hal.dll + +#ifndef SYMBIAN_EXCLUDE_KEYMAP +file=ABI_DIR\DEBUG_DIR\KEYMAP_FILE.dll \sys\bin\EKData.dll +#endif //SYMBIAN_EXCLUDE_KEYMAP + +secondary=ABI_DIR\DEBUG_DIR\efile.exe \sys\bin\efile.exe FIXED HEAPMAX(0x40000) +file=ABI_DIR\DEBUG_DIR\efsrv.dll \sys\bin\EFSrv.dll + +#ifndef CUSTOM_ELOCAL +#ifdef WITH_FAT32 +file=ABI_DIR\DEBUG_DIR\efat32.fsy \sys\bin\ELocal.fsy +#else +file=ABI_DIR\DEBUG_DIR\elocal.fsy \sys\bin\ELocal.fsy +#endif +#endif + +#ifdef WITH_LFFS +file=ABI_DIR\DEBUG_DIR\elffs.fsy \sys\bin\ELffs.fsy +#endif + +#ifdef WITH_NAND +file=ABI_DIR\BUILD_DIR\nandftl.fxt \sys\bin\nandftl.fxt +file=ABI_DIR\BUILD_DIR\ecomp.fsy \sys\bin\ecomp.fsy +file=ABI_DIR\BUILD_DIR\erofs.fsy \sys\bin\erofs.fsy +#endif + +#ifdef WITH_NAND2 +file=ABI_DIR\BUILD_DIR\ecomp.fsy \sys\bin\ecomp.fsy +file=ABI_DIR\BUILD_DIR\erofs.fsy \sys\bin\erofs.fsy +#endif + +#ifdef WITH_ISO9660 +file=ABI_DIR\DEBUG_DIR\iso9660.fsy \sys\bin\Iso9660.fsy +#endif + +#ifdef WITH_NTFS +file=ABI_DIR\DEBUG_DIR\ntfs.fsy \sys\bin\Ntfs.fsy +#endif + +#ifdef WITH_MASS_STORAGE +file=ABI_DIR\DEBUG_DIR\msfs.fsy \sys\bin\msfs.fsy +#endif + +// now include customised ESTART file +// file=ABI_DIR\DEBUG_DIR\_##VARIANT##_e32strt.exe \sys\bin\estart.exe HEAPMAX(0x10000) +file=ABI_DIR\DEBUG_DIR\ESTART_EXE \sys\bin\EStart.exe HEAPMAX(0x10000) + +file=ABI_DIR\DEBUG_DIR\domainSrv.exe \sys\bin\domainSrv.exe +file=ABI_DIR\DEBUG_DIR\domainCli.dll \sys\bin\domainCli.dll +file=ABI_DIR\DEBUG_DIR\domainPolicy.dll \sys\bin\domainPolicy.dll + +#if defined(_NAND) || defined(_NAND2) +#if !defined PAGED_ROM || defined EFFICIENT_ROM_PAGING || defined CODE_PAGING_FROM_ROFS +REM Start of ROFS image +ROM_IMAGE[1] { +#endif +#endif + +#ifndef SYMBIAN_EXCLUDE_D_EXC +file=ABI_DIR\DEBUG_DIR\d_exc.exe \sys\bin\d_exc.exe +#endif //SYMBIAN_EXCLUDE_D_EXC + +#ifndef SYMBIAN_EXCLUDE_SCDV +file=ABI_DIR\DEBUG_DIR\SCDV_DLL \sys\bin\ScDv.dll +#endif // SYMBIAN_EXCLUDE_SCDV + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/base_beagle.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/base_beagle.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,138 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// beagle\beagle_variant\rom\base_beagle.iby +// I M P O R T A N T * +// Mirror all changes to this file in beagle_variant\rom\kernel.iby and * +// check that "rom -v=beagle -i=armv5" still builds * +// + + + +#ifdef _FULL_DEBUG +#ifndef _DEBUG +#define _DEBUG // _FULL_DEBUG implies _DEBUG +#endif +define BUILD_DIR udeb +#else +define BUILD_DIR urel +#endif + +#ifndef _EABI +# ifdef _ARM4 +# define _EABI ARM4 + ECHO Defaulting to ARM4 +# elif defined(_ARMV5) +# define _EABI ARMV5 + ECHO Defaulting to ARMV5 +# elif defined _X86GCC +# define _EABI x86gcc +# endif +#endif + +# ifdef _PLAT +# undef _EABI +# define _EABI _PLAT + ECHO Defaulting to _EABI +# endif + +# ifdef _GCCE +# undef _EABI +# define _EABI GCCE +# elif defined(ABIV2) || defined(ABIv2) +# undef _EABI +# define _EABI ARMV5_ABIV2 +# endif + +#ifndef _KABI +#define _KABI _EABI +#endif + +define ABI_DIR EPOCROOT##epoc32\release\##_EABI +define KERNEL_DIR EPOCROOT##epoc32\release\##_KABI + +#define HEAPMAX(x) +#define FIXED + +kerneltrace 0x80000000 +debugport 2 + +multikernel +nowrapper + +bootbinary=\epoc32\release\ARMV5\_beagle_bootrom.bin + +memmodel multiple 0x100000 + +romsize=0x20000000 +romlinearbase=0x80000000 +romalign=0x10 +kerneldataaddress=0xC8000000 +kernelheapmin=0x08000 +kernelheapmax=0x00FFC000 +dataaddress=0x400000 +defaultstackreserve=0x200000 +romchecksum=0x12345678 + +primary[VARID] =\epoc32\release\ARMV5\BUILD_DIR\_omap3530_ekern.exe \sys\bin\ekern.exe +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_kaomap3530.dll \sys\bin\kaomap3530.dll +#include <..\omapshared\mstick.iby> +//extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_BTRACEX.LDD \sys\bin\btracex.ldd + +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_prcm.dll \sys\bin\prcm.dll +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_uart.dll \sys\bin\uart.dll + +variant[VARID] =\epoc32\release\ARMV5\BUILD_DIR\_beagle_ecust.dll \sys\bin\ecust.dll + +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_exmoncommon.dll \sys\bin\exmoncommon.dll +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_exmondebug.dll \sys\bin\exmondebug.dll + +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_gpio.dll \sys\bin\gpio.dll + +//extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_resman.pdd \sys\bin\resman.pdd +extension[VARID]=KERNEL_DIR\BUILD_DIR\resman.ldd \sys\bin\resman.ldd + +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_i2c.dll \sys\bin\i2c.dll +#include <../omapshared/tps65950.iby> + +#ifdef TSHELL_SERIAL + //Use VT100 Over Serial +# define EDISP_DRV \EDISP_VT100.DLL + device[VARID]=KERNEL_DIR\BUILD_DIR\_omap3530_EUART.PDD \sys\bin\euart.pdd + device[VARID]=KERNEL_DIR\BUILD_DIR\ECOMM.LDD \sys\bin\ecomm.ldd +#else + extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_lcd.dll \sys\bin\lcd.dll +# ifdef TSHELL_SERIALMOUSE + extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_serialmouse.DLL \sys\bin\eserialmouse.dll +# else +// extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_serialkeyboard.DLL \sys\bin\ekeyb.dll +# endif +#endif +extension[VARID]=KERNEL_DIR\BUILD_DIR\elocd.ldd \sys\bin\elocd.ldd +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_medint.pdd \sys\bin\medint.pdd +device[VARID] =KERNEL_DIR\BUILD_DIR\pipelib.ldd \sys\bin\pipelib.ldd +//device[VARID] =KERNEL_DIR\BUILD_DIR\minkda.ldd \sys\bin\minkda.ldd +extension[VARID]=KERNEL_DIR\BUILD_DIR\exstart.dll \sys\bin\exstart.dll +//extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_led.dll \sys\bin\led.dll +#ifdef INCLUDE_USB +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_usbcc.dll \sys\bin\usbcc.dll +device[VARID]= KERNEL_DIR\BUILD_DIR\usbc.ldd \sys\bin\eusbc.ldd +extension[VARID]= \epoc32\release\ARMV5\BUILD_DIR\_beagle_usbv.dll \sys\bin\usbv.DLL +#endif + +#ifdef SYNAPTICS_TOUCH_PAD +extension[VARID]= \epoc32\release\ARMV5\BUILD_DIR\synapticsclearpad.dll \sys\bin\synapticsclearpad.dll +#endif + +//extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_ekeyb.dll \sys\bin\ekeyb.dll +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_serialkeyboard.DLL \sys\bin\ekeyb.dll \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/beagle.oby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/beagle.oby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,74 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#ifndef __BEAGLE_OBY__ +#define __BEAGLE_OBY__ + +define LANGID 01 +define BUILDNO 0 +define VERSION 0.01 + +DEFAULT_LANGUAGE 01 + +REM Definitions specific to Beagle Board + +#undef _ARMV5 +#define _ARMV5 + +#define __BEAGLE__ + +//define BEAGLE 0x09080001 +define VARIANT beagle +define VARID 0x09080001 +define ASSP_DIR EPOCROOT##epoc32\release\mbeagle +define ROMMEGS 80 /* !! HEX !! */ +define PLATFORM_NAME beagle + +#define COLOR + +#define EUSER_DLL ../../armv5/BUILD_DIR/_omap3530_euser.dll + + +define HAL_DLL _beagle_hal.dll +define ESTART_EXE e32strt.exe +define KEYMAP_FILE _beagle_ekdata +define SCDV_DLL _omapqvga_scdv.dll + +//#define WITH_LFFS + +// Not supported! Need gce aware lcd driver and display0.ldd +//#define SYMBIAN_BASE_USE_GCE +//#define SYMBIAN_GRAPHICS_USE_GCE + +//#define SYMBIAN_EXCLUDE_LOCATION // <- Can't exclude from s60 images + +#define SYMBIAN_EXCLUDE_OMA_DEVMAN +#define SYMBIAN_EXCLUDE_OMA_DATASYNC +#define SYMBIAN_EXCLUDE_MTP +#define SYMBIAN_EXCLUDE_USB + +REM defines for IrDA options +REM Uncomment the line below to enable IrDA to use a Jeteye ESI09680 pod with serial card adapter +REM #define _ENABLE_IRDA_POD_ +REM define which port IrDA uses +define IRPOD_ESK irda_port1.esk + +REM define which serial port Bluetooth protocol uses +REM define BLUETOOTH_ESK bt_port2.esk + +REM Define whether or not to include USB client support: +#define EUSBC + +#endif //__BEAGLE_OBY__ diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/build_beagle.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/build_beagle.bat Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,4 @@ + +call \epoc32\tools\buildrom_lpd.cmd beagle Symbian2.oby -D_EABI=ARMV5 -DCOLOR -DSYMBIAN_EXCLUDE_IPSEC -D_PORTRAIT_ -es60ibymacros -nosymbols -D__LOCALES_01_IBY__ + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/build_beagle_touchpad.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/build_beagle_touchpad.bat Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,4 @@ + +call \epoc32\tools\buildrom_lpd.cmd beagle Symbian2.oby -D_EABI=ARMV5 -DCOLOR -DSYMBIAN_EXCLUDE_IPSEC -D_PORTRAIT_ -es60ibymacros -nosymbols -D__LOCALES_01_IBY__ -DSYNAPTICS_TOUCH_PAD + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/header.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/header.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,63 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/rom/header.iby +// + +#define BASE_TEXT_SHELL_BUILD + +// Relative variant path from base +#define VARIANT_PATH beagle\beagle_variant + +// The Variant ID +#define VARID 0x09080001 +#define MAGIC 0x09080001 +#define ALL 0x09080001 +version=0.01 + +trace 0x10 +collapse arm gcc 0 + +#define HEAPMAX(x) + +#define FIXED + +kerneltrace 0x80000000 +debugport 2 + +multikernel +nowrapper + +version=0.01 +bootbinary=\Epoc32\Release\ARMV5\_beagle_bootrom.bin +memmodel multiple 0x100000 + +// These values in super page are for multiple memory model: +romsize=0x2000000 +romlinearbase=0x80000000 +romalign=0x10 +kerneldataaddress=0xC8000000 +kernelheapmin=0x1000 // calculated at boot time +kernelheapmax=0x00FFF000 +dataaddress=0x400000 +defaultstackreserve=0x200000 +romchecksum=0x12345678 + +//#define WITH_LFFS +//#define WITH_EXTENSION +//#define WITH_ROFS +//#define WITH_COMP + +#ifdef UNICODE +unicode +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/kernel.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/kernel.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,82 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/rom/kernel.iby +// I M P O R T A N T * +// Mirror all changes to this file in beagle_variant\rom\base_beagle.iby and * +// check that "buildrom beagle base_beagle textshell" still builds * +// + + + +primary[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_EKERN.EXE \sys\bin\ekern.exe +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_KAOMAP3530.DLL \sys\bin\kaomap3530.dll +#include + +//extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_BTRACEX.LDD \sys\bin\btracex.ldd + +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_prcm.dll \sys\bin\prcm.dll +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_uart.dll \sys\bin\uart.dll + +variant[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_##VARIANT##_ECUST.DLL \sys\bin\ecust.dll + +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_EXMONCOMMON.DLL \sys\bin\exmoncommon.dll +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_EXMONDEBUG.DLL \sys\bin\exmondebug.dll + +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_GPIO.DLL \sys\bin\gpio.dll + +//extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_LED.DLL \sys\bin\led.dll + +//extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_##VARIANT##_resman.pdd \sys\bin\resman.pdd +//extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\resman.ldd \sys\bin\resman.ldd + +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3530_I2C.DLL \sys\bin\I2C.DLL + +#include + +#ifdef TSHELL_SERIAL + //Use VT100 Over Serial +# define EDISP_DRV \EDISP_VT100.DLL + device[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_EUART.PDD \sys\bin\euart.pdd + device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\ECOMM.LDD \sys\bin\ecomm.ldd +#else + extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_lcd.dll \sys\bin\lcd.dll +# ifdef SERIALMOUSE +# ifdef BASE_ROM + extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_serialmouse_tshell.DLL \sys\bin\eserialmouse.dll +# else + extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_serialmouse.DLL \sys\bin\eserialmouse.dll +# endif +# else + extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_omap3530_serialkeyboard.DLL \sys\bin\ekeyb.dll +# endif +#endif +file[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_EKDATA.DLL \sys\bin\ekdata.dll +extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\ELOCD.LDD \sys\bin\elocd.ldd +extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_MEDINT.PDD \sys\bin\medint.pdd +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\PIPELIB.LDD \sys\bin\pipelib.ldd +extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\EXSTART.DLL \sys\bin\exstart.dll + +#ifdef INCLUDE_USB +extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_omap3530_USBCC.DLL \sys\bin\USBCC.DLL +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\USBC.LDD \sys\bin\EUSBC.LDD +extension[VARID]= \epoc32\release\ARMV5\##BUILD##\_##VARIANT##_USBV.DLL \sys\bin\usbv.DLL +#endif + +#define EUSER_DLL ../../ARMV5/##BUILD##/_omap3530_euser.dll + +#ifdef TEST_ROM +# include +#endif + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/rom/test.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/rom/test.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,17 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\beagle_variant\rom\test.iby +// + +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_mcbsp.ldd \sys\bin\d_mcbsp.ldd \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/src/variant.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/src/variant.cia Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,63 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagleboard/src/variant.cia +// + +#include +#include +#include + +/****************************************************************************** + * Interrupt handling/dispatch + ******************************************************************************/ +__NAKED__ void XIntDispatch(TAny*) + { + // Service second-level Variant Interrupts + // Enter with r0->{Variant int controller base; Handlers;} + asm("stmfd sp!, {r4,lr} "); + asm("ldmia r0, {r3,r4} "); // r3=Variant interrupt controller base, r4->handlers + asm("0: "); + asm("ldr r0, [r3, #%a0]" : : "i" ((TInt)KHoIntContEnable)); // r0=bitmask with enabled interrupts + asm("ldr r1, [r3, #%a0]" : : "i" ((TInt)KHoIntContPending)); // r1=bitmask with pending interrupts + asm("mov r2, #31 "); // int id + asm("and r0, r0, r1 "); + asm("bics r0, r0, #0xf8000000 "); // mask unused bits (only 26 2nd-level ints defined) + asm("ldmeqfd sp!, {r4,pc} "); // if no 2nd level interrupts pending, exit + asm("cmp r0, #0x00010000 "); + asm("movcc r0, r0, lsl #16 "); + asm("subcc r2, r2, #16 "); + asm("cmp r0, #0x01000000 "); + asm("movcc r0, r0, lsl #8 "); + asm("subcc r2, r2, #8 "); + asm("cmp r0, #0x10000000 "); + asm("movcc r0, r0, lsl #4 "); + asm("subcc r2, r2, #4 "); + asm("cmp r0, #0x40000000 "); + asm("movcc r0, r0, lsl #2 "); + asm("subcc r2, r2, #2 "); + asm("cmp r0, #0x80000000 "); + asm("subcc r2, r2, #1 "); // r2=bit no. of MS 1 + asm("add r0, r4, r2, lsl #3 "); // r0->handler for this interrupt + asm("adr lr, 0b "); // look again after calling handler + asm("ldmia r0, {r0,pc} "); // jump to handler + } + +__NAKED__ void ArmWaitForInterrupt() + { + //ARM_WFI; + asm(".word %a0" : : "i" ((TInt)(0x0320f003 | ((14)<<28) )) ) + asm(" bx lr"); + } + + diff -r 000000000000 -r 6663340f3fc9 omap3530/beagleboard/src/variant.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagleboard/src/variant.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,780 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beaglboard/src/variant.cpp +// + +#include +#include +#include +#include +#include +#include +#include + +#define ENABLE_WFI +#define IDLE_TICK_SUPPRESSION + + +#ifdef IDLE_TICK_SUPPRESSION +#include +#endif + + +GLREF_C void ArmWaitForInterrupt(); + + +//These constants define Custom Restart Reasons in SuperPage::iHwStartupReason +const TUint KHtCustomRestartMax = 0xff; +const TUint KHtCustomRestartShift = 8; +const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift; + +//TODO: unncomment when referenced +const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant +//const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant +//const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift; + +void BeagleVariantFault(TInt aLine) + { + Kern::Fault("BeagleVariant",aLine); + } + +#define V_FAULT() BeagleVariantFault(__LINE__) + +// Debug output +#define XON 17 +#define XOFF 19 +#define DEBUG_XON_XOFF 0 // Non-zero if we want XON-XOFF handshaking + +GLDEF_D Beagle TheVariant; +TUint32 Variant::iBaseAddress=0; + + + + + +EXPORT_C Asic* VariantInitialise() + { + return &TheVariant; + } + +Beagle::Beagle() + { + iDebugInitialised=EFalse; + } + +// +// TO DO: (optional) +// +// Specify the RAM zone configuration. +// +// The lowest addressed zone must have the highest preference as the bootstrap +// will always allocate from the lowest address up. Once the kernel has initialised +// then the zone preferences will decide from which RAM zone memory is allocated. +// +// const TUint KVariantRamZoneCount = ?; +// static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] = +// iBase iSize iID iPref iFlags +// { +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), +// ... +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), +// __SRAM_ZONE_END, // end of zone list +// }; +// + +TInt Beagle::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks) + { + // + // TO DO: (optional) + // + // Handle RAM zone operations requested by the kernel. + // + return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks); + } + + +TInt Beagle::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks) + { + // + // TO DO: (optional) + // + // Handle RAM zone operations requested by the kernel. + // + // Three types of operation need to be supported: + // ERamZoneOp_Init: Update power state of the RAM zones after the + // kernel has initialised. + // ERamZoneOp_PowerUp: A RAM zone changing from used to empty. + // ERamZoneOp_PowerDown: A RAM zone changing from empty to used. + // + + switch (aOp) + { + case ERamZoneOp_Init: + break; + case ERamZoneOp_PowerUp: + break; + case ERamZoneOp_PowerDown: + break; + default: + return KErrNotSupported; + } + return KErrNone; + } + +TUint Beagle::SysClkFrequency() const + { + return 26000000; + } + +TUint Beagle::SysClk32kFrequency() const + { + return 32768; + } + +TUint Beagle::AltClkFrequency() const + { + // Doesn't appear to be connected on Beagle + return 0; + } + +void Beagle::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Beagle::Init1()")); + Omap3530Assp::Init1(); + } + + +EXPORT_C TInt Variant::GetMsTickPeriod() + { + return TheVariant.MsTickPeriod(); + + } + +void Beagle::Init3() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Beagle::Init3()")); + + Omap3530Assp::Init3(); + + Variant::Init3(); + } + +void Variant::Init3() +// +// Phase 3 initialisation +// + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(">Variant::Init3")); + } + +EXPORT_C TUint Variant::BaseLinAddress() + { + return((TUint)iBaseAddress); + } + +EXPORT_C void Variant::MarkDebugPortOff() + { + TheVariant.iDebugInitialised=EFalse; + } + +EXPORT_C void Variant::UartInit() + { + if (!TheVariant.iDebugInitialised) + { + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + Omap3530Uart::TUart uart( portNumber ); + + uart.Init(); + uart.DefineMode( Omap3530Uart::TUart::EUart ); + uart.SetBaud( Omap3530Uart::TUart::E115200 ); + uart.SetDataFormat( Omap3530Uart::TUart::E8Data, Omap3530Uart::TUart::E1Stop, Omap3530Uart::TUart::ENone ); + uart.Enable(); + + TheVariant.iDebugInitialised=ETrue; + } + } + } + +void Beagle::DebugInit() + { + Variant::UartInit(); + } + +void Beagle::DebugOutput(TUint aLetter) +// +// Output a character to the debug port +// + { + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + if (!iDebugInitialised) + { + DebugInit(); + } + Omap3530Uart::TUart uart( portNumber ); + // If the FIFO is full we need to wait.. + while( uart.TxFifoFull() ); + uart.Write( aLetter ); + } + } + +void Beagle::Idle() +// +// The NULL thread idle loop +// + { + // Idle the CPU, suppressing the system tick if possible + + // + // TO DO: (optional) + // + // Idle Tick supression: + // 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime()) + // 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer + // to only interrupt again when the corresponding time has expired. + // 2.1- the calculation of the new value to program the Hardware Timer with should take in + // consideration the rounding value (NTimerQ::iRounding) + // 3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction) + // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to + // timer expiration (system time for new match<=current system time MapSleepMode(aTicksLeft*MsTickPeriod()); + // ... + // Find out the state of some particular resources + // TBool aResourceState = aManager -> GetResourceState(TemplateResourceManager::AsynchBinResourceUsedByZOnly); + // TUint aResourceLevel = aManager -> GetResourceLevel(TemplateResourceManager::SynchMlResourceUsedByXOnly); + // ... + +#ifdef ENABLE_WFI + TInt irq = NKern::DisableAllInterrupts(); + +# ifdef IDLE_TICK_SUPPRESSION + TInt maxSleepTicks = NTimerQ::IdleTime(); + TInt suppressedTicks = Omap3::MsTick::SuppressIdleTicks( maxSleepTicks ); +# endif + + ArmWaitForInterrupt(); + + +# ifdef IDLE_TICK_SUPPRESSION + if( suppressedTicks > 0 ) + { + suppressedTicks = Omap3::MsTick::EndIdleTickSuppression( suppressedTicks ); + if( suppressedTicks > 0 ) + { + NTimerQ::Advance( suppressedTicks ); + } + } +# endif + + NKern::RestoreInterrupts( irq ); +#endif // ifdef ENABLE_WFI + } + +TInt Beagle::VariantHal(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EVariantHalVariantInfo: + { + TVariantInfoV01Buf infoBuf; + TVariantInfoV01& info=infoBuf(); + info.iRomVersion=Epoc::RomHeader().iVersion; + + // + // TO DO: (mandatory) + // + // Fill in the TVariantInfoV01 info structure + // info.iMachineUniqueId=; + // info.iLedCapabilities=; + // info.iProcessorClockInKHz=; + // info.iSpeedFactor=; + // + Kern::InfoCopy(*(TDes8*)a1,infoBuf); + break; + } + case EVariantHalDebugPortSet: + { + // + // TO DO: (mandatory) + // + // Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY: + // + TUint32 thePort = (TUint32)a1; + switch(thePort) + { + case 1: + case 2: + case 3: + TheVariant.iDebugInitialised=EFalse; + case (TUint32)KNullDebugPort: + Kern::SuperPage().iDebugPort = thePort; + break; + default: + r=KErrNotSupported; + } + break; + } + case EVariantHalDebugPortGet: + { + kumemput32(a1, &Kern::SuperPage().iDebugPort, sizeof(TUint32)); + break; + } + case EVariantHalSwitches: + { + // + // TO DO: (optional) + // + // Read the state of any switches, as in the following EXAMPLE ONLY: + // + TUint32 x = Variant::Switches(); + kumemput32(a1, &x, sizeof(x)); + break; + } + case EVariantHalLedMaskSet: + { + // + // TO DO: (optional) + // + // Set the state of any on-board LEDs, e.g: + // TUint32 aLedMask=(TUint32)a1; + // Variant::ModifyLedState(~aLedMask,aLedMask); + // + break; + } + case EVariantHalLedMaskGet: + { + // + // TO DO: (optional) + // + // Read the state of any on-board LEDs, e.g: + // TUint32 x = Variant::LedState(); + // kumemput32(a1, &x, sizeof(x)); + // + break; + } + + case EVariantHalCustomRestartReason: + { + //Restart reason is stored in super page + TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ; + kumemput32(a1, &x, sizeof(TInt)); + break; + } + + case EVariantHalCustomRestart: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart"))) + return KErrPermissionDenied; + if ((TUint)a1 > KHtCustomRestartMax) + return KErrArgument; + Kern::Restart((TInt)a1 << KHtCustomRestartShift); + } + break; + + case EVariantHalCaseState: + { + // + // TO DO: (optional) + // + // Read the state of the case, e.g: + // TUint32 x = Variant::CaseState(); + // kumemput32(a1, &x, sizeof(x)); + // + break; + } + + case EVariantHalPersistStartupMode: + { + if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + return KErrPermissionDenied; + + if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value + return KErrArgument; + // + // TO DO: (optional) + // + // Store the restart reason locally, + // which will eventually be picked up by + // the power controller, e.g: + // iCustomRestartReason = (TUint)a1; + break; + } + + + case EVariantHalGetPersistedStartupMode: + { + // + // TO DO: (optional) + // + // Read the restart startup mode, e.g: + // TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift; + // kumemput32(a1, &startup, sizeof(TInt)); + break; + } + + case EVariantHalGetMaximumCustomRestartReasons: + { + // + // TO DO: (optional) + // + // Read the maximum custom restart reason, e.g: + // kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint)); + break; + } + + + case EVariantHalGetMaximumRestartStartupModes: + { + // + // TO DO: (optional) + // + // Read the maximum restart startup mode, e.g: + // kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint)); + break; + } + + + default: + r=KErrNotSupported; + break; + } + return r; + } + +TPtr8 Beagle::MachineConfiguration() + { + return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig)); + } + + +EXPORT_C void Variant::PowerReset() + { + // + // TO DO: (optional) + // + // Reset all power supplies + // + } + +EXPORT_C TUint Variant::Switches() + { + // + // TO DO: (optional) + // + // Read the state of on-board switches + // + return 0; // EXAMPLE ONLY + } + +// USB Client controller + +TBool Beagle::UsbClientConnectorDetectable() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbClientConnectorDetectable")); + + // TO DO: The return value should reflect the actual situation. + return ETrue; + } + + +TBool Beagle::UsbClientConnectorInserted() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbClientConnectorInserted")); + + // TO DO: Query cable status here. The return value should reflect the actual current state. + return ETrue; + } + + +TInt Beagle::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::RegisterUsbClientConnectorCallback")); + + iUsbClientConnectorCallback = aCallback; + iUsbClientConnectorCallbackArg = aPtr; + + // TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here. + // (Register UsbClientConnectorIsr.) + + // TO DO: The return value should reflect the actual situation. + return KErrNone; + } + + +void Beagle::UnregisterUsbClientConnectorCallback() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UnregisterUsbClientConnectorCallback")); + + // TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here. + + iUsbClientConnectorCallback = NULL; + iUsbClientConnectorCallbackArg = NULL; + } + + +TBool Beagle::UsbSoftwareConnectable() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbSoftwareConnectable")); + + // TO DO: The return value should reflect the actual situation. + return ETrue; + } + + +TInt Beagle::UsbConnect() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbConnect")); + + // TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host). + + return KErrNone; + } + + +TInt Beagle::UsbDisconnect() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbDisconnect")); + + // TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the + // host). + + return KErrNone; + } + + +void Beagle::UsbClientConnectorIsr(TAny *aPtr) +// +// Services the USB cable interrupt. +// + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("Beagle::UsbClientConnectorIsr()")); + + Beagle* tm = static_cast(aPtr); + + // TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc. + + if (tm->UsbClientConnectorInserted()) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted.")); + } + else + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed.")); + } + + // Important: Inform the USB stack. + if (tm->iUsbClientConnectorCallback) + { + (*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg); + } + } + +// Used to convert time to BCD and vice-versa +const TInt KSecsPerMin = 60; +const TInt KSecsPerHour = 60*KSecsPerMin; +const TInt KSecsPerDay = 24*KSecsPerHour; +//const TInt KSecsPerLeapYr = 366*KSecsPerDay; +const TInt KSecsPerYr = 365*KSecsPerDay; +const TInt KSecsDaysPer4Years = (3*KSecsPerYr)+ 366*KSecsPerDay; + +//#define BCDTONUM0_3_4_7(a) ((a&0xf)+(((a)>>4)*10)) +#define BCDTONUM0_3_4_6(a) ((a&0xf)+((((a)>>4)&7)*10)) + +// Days in each month +LOCAL_D const TInt8 mTab[2][12]= + { + {31,28,31,30,31,30,31,31,30,31,30,31}, // 28 days in Feb + {31,29,31,30,31,30,31,31,30,31,30,31} // 29 days in Feb + }; + +void GetMonthData(TInt aDayInYear, TBool aLeap, TUint8& aMonth, TUint8& aDay ) +/** + Work out day of the month and month + @param aDayInYear Day of the year + @param aLeap True if it is a leap year + @param aMonth Return month (range 01-12) + @param aDay Return day of the month (range 01-31) + */ +{ + TInt i; + TInt runtot=0; + for (i=0; i<12; i++) + { + if ((aDayInYear>=runtot) && (aDayInYear < mTab[aLeap][i]+runtot)) + { + // Month and day of the month both start from 1, rather than + // zero (hence the +1) + aMonth=i+1; + aDay=aDayInYear-runtot+1; + break; + } + runtot+=mTab[aLeap][i]; + } +} + +LOCAL_C void SecondsToYMD( const TInt aTime, TUint8& aYear, TUint8& aMonth, TUint8& aDay ) +/** + Work out year, day of the month and month + @param aTime Time in secs from year 2000 + @param aYear Return year number + @param aMonth Return month (range 01-12) + @param aDay Return day of the month (range 01-31) + */ +{ + // Work out year within 4 years first + aYear = (aTime / KSecsDaysPer4Years)*4; + aDay=0; + aMonth=0; + TInt adjyear = aTime % KSecsDaysPer4Years; + + + if (adjyear +#include +#include +#include + +#include +//#include +#include + +GLREF_C TInt InitGpioInterrupts(); + + +TSpinLock GPIOModeLock(/*TSpinLock::EOrderNone*/); +TSpinLock GPIOWakeLock(/*TSpinLock::EOrderNone*/); +TSpinLock GPIOLevelLock(/*TSpinLock::EOrderNone*/); + +GPIO::TGpioMode ThePinMode[ KHwGpioPinMax ]; +TUint32 ThePinIsEnabled[ KHwGpioBanks ]; +__ASSERT_COMPILE( KHwGpioPinsPerBank <= 32 ); + +#if 0 +static void dumpGpioBank(TUint aBankAddr) + { + Kern::Printf("GPIO_SYSCONFIG at %x is %x",aBankAddr +KGPIO_SYSCONFIG,AsspRegister::Read32(aBankAddr +KGPIO_SYSCONFIG) ); + Kern::Printf("GPIO_SYSSTATUS at %x is %x",aBankAddr +KGPIO_SYSSTATUS,AsspRegister::Read32(aBankAddr +KGPIO_SYSSTATUS)); + Kern::Printf("GPIO_IRQSTATUS1 at %x is %x",aBankAddr +KGPIO_IRQSTATUS1,AsspRegister::Read32(aBankAddr +KGPIO_IRQSTATUS1) ); + Kern::Printf("GPIO_IRQENABLE1 at %x is %x",aBankAddr +KGPIO_IRQENABLE1,AsspRegister::Read32(aBankAddr +KGPIO_IRQENABLE1) ); + Kern::Printf("GPIO_WAKEUPENABLE at %x is %x",aBankAddr +KGPIO_WAKEUPENABLE,AsspRegister::Read32(aBankAddr +KGPIO_WAKEUPENABLE) ); + Kern::Printf("GPIO_CTRL at %x is %x",aBankAddr +KGPIO_CTRL,AsspRegister::Read32(aBankAddr +KGPIO_CTRL) ); + Kern::Printf("GPIO_OE at %x is %x",aBankAddr +KGPIO_CTRL,AsspRegister::Read32(aBankAddr +KGPIO_OE) ); + } +#endif + + +EXPORT_C TInt GPIO::SetPinMode(TInt aId, TGpioMode aMode) + { + TInt irq = __SPIN_LOCK_IRQSAVE(GPIOModeLock); + if(ThePinMode[ aId ] != aMode) + { + ThePinMode[ aId ] = aMode; + TUint bank = GPIO_PIN_BANK( aId ); + TUint pinMask = 1 << GPIO_PIN_OFFSET( aId ); + + if( aMode == GPIO::EEnabled) + { + if( 0 == ThePinIsEnabled[ bank ] ) + { + // First enabled pin in bank + AsspRegister::Modify32(GPIO_BASE_ADDRESS( aId ) +KGPIO_CTRL,KClearNone,0x1); + } + + ThePinIsEnabled[ bank ] |= pinMask; + } + else + { + ThePinIsEnabled[ bank ] &= ~pinMask; + + if( 0 == ThePinIsEnabled[ bank ] ) + { + // Bank can be disabled + AsspRegister::Modify32(GPIO_BASE_ADDRESS( aId ) +KGPIO_CTRL,0x1, KSetNone); + } + } + } + __SPIN_UNLOCK_IRQRESTORE(GPIOModeLock,irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinMode(TInt aId, TGpioMode & aMode) + { + aMode = ThePinMode[ aId ]; + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinDirection(TInt aId, TGpioDirection aDirection) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::SetPinBias OOB ",KErrArgument)); + + if (aDirection == ETriStated) + { + return KErrNotSupported; + } + + if (aDirection == EInput) + { + AsspRegister::Modify32(GPIO_BASE_ADDRESS(aId)+KGPIO_OE, KClearNone, GPIO_PIN_OFFSET(aId)); + } + else + { + AsspRegister::Modify32(GPIO_BASE_ADDRESS(aId)+KGPIO_OE, GPIO_PIN_OFFSET(aId), KSetNone); + } + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinDirection(TInt aId, TGpioDirection& aDirection) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetPinDirection OOB ",KErrArgument)); + + if(AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_OE) & GPIO_PIN_OFFSET(aId)) + aDirection=EInput; + else + aDirection=EOutput; + + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinBias(TInt aId, TGpioBias aBias) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::SetPinBias OOB ",KErrArgument)); + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::GetPinBias(TInt aId, TGpioBias& aBias) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetPinBias OOB ",KErrArgument)); + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetPinIdleConfigurationAndState(TInt aId, TInt /*aConf*/) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::SetPinIdleConfigurationAndState OOB ",KErrArgument)); + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::GetPinIdleConfigurationAndState(TInt aId, TInt& aBias) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetPinIdleConfigurationAndState OOB ",KErrArgument)); + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::BindInterrupt(TInt aId, TGpioIsr aIsr, TAny* aPtr) + { + return Interrupt::Bind( EGPIOIRQ_FIRST + aId,aIsr,aPtr); + } + +EXPORT_C TInt GPIO::UnbindInterrupt(TInt aId) + { + return Interrupt::Unbind( EGPIOIRQ_FIRST + aId ); + } + +EXPORT_C TInt GPIO::EnableInterrupt(TInt aId) + { + return Interrupt::Enable( EGPIOIRQ_FIRST + aId ); + } + +EXPORT_C TInt GPIO::DisableInterrupt(TInt aId) + { + return Interrupt::Disable( EGPIOIRQ_FIRST + aId ); + } + +EXPORT_C TInt GPIO::ClearInterrupt(TInt aId) + { + return Interrupt::Clear( EGPIOIRQ_FIRST + aId ); + } + +EXPORT_C TInt GPIO::IsInterruptEnabled(TInt aId, TBool& aEnable) + { + aEnable = AsspRegister::Read32(GPIO_BASE_ADDRESS( aId ) + KGPIO_IRQENABLE1) & GPIO_PIN_OFFSET(aId); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetMaskedInterruptState(TInt aId, TBool& aActive) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetMaskedInterruptState OOB ",KErrArgument)); + aActive = AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_IRQSTATUS1) & GPIO_PIN_OFFSET(aId); + + return KErrNone; + } + +EXPORT_C TInt GPIO::GetRawInterruptState(TInt aId, TBool& aActive) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetRawInterruptState OOB ",KErrArgument)); + + aActive = AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_IRQSTATUS1) & GPIO_PIN_OFFSET(aId); + + return KErrNone; + } + +EXPORT_C TInt GPIO::SetInterruptTrigger(TInt aId, TGpioDetectionTrigger aTrigger) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::SetInterruptTrigger OOB ",KErrArgument)); + + TInt baseAddr = GPIO_BASE_ADDRESS(aId); + TUint irqFlags=0; + //first we clear the current trigger(s) + //then set the new for each case + switch (aTrigger) + { + case ELevelLow: + + irqFlags = NKern::DisableAllInterrupts();//__SPIN_LOCK_IRQSAVE_W(GPIOLevelSpinLock); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT1, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_FALLINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_RISINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT0, KClearNone, GPIO_PIN_OFFSET(aId)); + NKern::RestoreInterrupts(irqFlags);//__SPIN_UNLOCK_IRQRESTORE_W(GPIOLevelSpinLock,irqFlags); + break; + case ELevelHigh: + + irqFlags = NKern::DisableAllInterrupts();//__SPIN_LOCK_IRQSAVE_W(GPIOLevelSpinLock); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT0, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_FALLINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_RISINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT1, KClearNone, GPIO_PIN_OFFSET(aId)); + NKern::RestoreInterrupts(irqFlags);//__SPIN_UNLOCK_IRQRESTORE_W(GPIOLevelSpinLock,irqFlags); + + break; + case EEdgeFalling: + + irqFlags = NKern::DisableAllInterrupts();//__SPIN_LOCK_IRQSAVE_W(GPIOLevelSpinLock); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT0, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT1, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_RISINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + + AsspRegister::Modify32(baseAddr+KGPIO_FALLINGDETECT, KClearNone, GPIO_PIN_OFFSET(aId)); + NKern::RestoreInterrupts(irqFlags);//__SPIN_UNLOCK_IRQRESTORE_W(GPIOLevelSpinLock,irqFlags); + break; + case EEdgeRising: + + irqFlags = NKern::DisableAllInterrupts();//__SPIN_LOCK_IRQSAVE_W(GPIOLevelSpinLock); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT0, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT1, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_FALLINGDETECT, GPIO_PIN_OFFSET(aId),KSetNone); + + AsspRegister::Modify32(baseAddr+KGPIO_RISINGDETECT, KClearNone, GPIO_PIN_OFFSET(aId)); + NKern::RestoreInterrupts(irqFlags);//__SPIN_UNLOCK_IRQRESTORE_W(GPIOLevelSpinLock,irqFlags); + break; + case EEdgeBoth: + + irqFlags = NKern::DisableAllInterrupts();//__SPIN_LOCK_IRQSAVE_W(GPIOLevelSpinLock); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT0, GPIO_PIN_OFFSET(aId),KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_LEVELDETECT1, GPIO_PIN_OFFSET(aId),KSetNone); + + AsspRegister::Modify32(baseAddr+KGPIO_FALLINGDETECT, KClearNone, GPIO_PIN_OFFSET(aId)); + AsspRegister::Modify32(baseAddr+KGPIO_RISINGDETECT, KClearNone, GPIO_PIN_OFFSET(aId)); + NKern::RestoreInterrupts(irqFlags);//__SPIN_UNLOCK_IRQRESTORE_W(GPIOLevelSpinLock,irqFlags); + + break; + default: + return KErrArgument; + } + + return KErrNone; + } + + +EXPORT_C TInt GPIO::EnableWakeup(TInt aId) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::EnableWakeup OOB ",KErrArgument)); + + TInt baseAddr = GPIO_BASE_ADDRESS(aId); + + TInt irq = __SPIN_LOCK_IRQSAVE(GPIOWakeLock); + AsspRegister::Modify32(baseAddr+KGPIO_SYSCONFIG,KClearNone, 1 << 2 ); + AsspRegister::Modify32(baseAddr+KGPIO_SETWKUENA,KClearNone ,GPIO_PIN_OFFSET(aId)); + __SPIN_UNLOCK_IRQRESTORE(GPIOWakeLock,irq); + + return KErrNone; + } + +EXPORT_C TInt GPIO::DisableWakeup(TInt aId) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::DisableWakeup OOB ",KErrArgument)); + + TInt baseAddr = GPIO_BASE_ADDRESS(aId); + + TInt irq = __SPIN_LOCK_IRQSAVE(GPIOWakeLock); + AsspRegister::Modify32(baseAddr+KGPIO_SYSCONFIG,1 << 2 ,KSetNone); + AsspRegister::Modify32(baseAddr+KGPIO_CLEARWKUENA,KClearNone,GPIO_PIN_OFFSET(aId)); + __SPIN_UNLOCK_IRQRESTORE(GPIOWakeLock,irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::IsWakeupEnabled(TInt aId, TBool& aEnable) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::IsWakeupEnabled OOB ",KErrArgument)); + + aEnable = AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_WAKEUPENABLE) & GPIO_PIN_OFFSET(aId); + return KErrNone; + } + +EXPORT_C TInt GPIO::SetWakeupTrigger(TInt aId, TGpioDetectionTrigger aTrigger) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::SetWakeupTrigger OOB ",KErrArgument)); + return KErrNotSupported; + } + +// WARNING: Changing debouncing time will change it for all pins in the bank +EXPORT_C TInt GPIO::SetDebounceTime(TInt aId, TInt aTime) + { + TGpioDirection direction; + GetPinDirection(aId, direction); + + if(direction==EOutput) + { + // The pin must be configured as input. + return KErrNotSupported; + } + + //convert the Ms input time into units of 31us + TInt timeSteps = aTime / 31; + if(timeSteps>127) + { +#ifdef _DEBUG + Kern::Printf("Warning: Tried to set the GPIO debounce time to %dus, \ + which is greater than the maximum supported 3937us.", aTime); +#endif + timeSteps=127; // The maximum debounce value. + } + + TInt baseAddr = GPIO_BASE_ADDRESS(aId); + + TUint irqFlags = __SPIN_LOCK_IRQSAVE(gpio::GPIODebounceSpinLock); + AsspRegister::Write32(baseAddr+KGPIO_DEBOUNCINGTIME, timeSteps & KGPIO_DEBOUNCE_TIME_MASK); + AsspRegister::Modify32(baseAddr+KGPIO_DEBOUNCENABLE, KClearNone, GPIO_PIN_OFFSET(aId)); + __SPIN_UNLOCK_IRQRESTORE(gpio::GPIODebounceSpinLock,irqFlags); + + return KErrNone; + } + +EXPORT_C TInt GPIO::GetDebounceTime(TInt aId, TInt& aTime) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetDebounceTime OOB ",KErrArgument)); + aTime=AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_DEBOUNCINGTIME); // The time in in multiples of 31 microseconds. We should probably use a nicer unit.. + + return KErrNone; + } + +EXPORT_C TInt GPIO::SetOutputState(TInt aId, TGpioState aState) + { + if(aState==GPIO::ELow) + { + AsspRegister::Modify32(GPIO_BASE_ADDRESS(aId) + KGPIO_DATAOUT, GPIO_PIN_OFFSET(aId), KSetNone); + } + else + { + AsspRegister::Modify32(GPIO_BASE_ADDRESS(aId) + KGPIO_DATAOUT, KClearNone, GPIO_PIN_OFFSET(aId)); + } + return KErrNone; + } + +EXPORT_C TInt GPIO::GetInputState(TInt aId, TGpioState& aState) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetInputState OOB ",KErrArgument)); + + aState= ( AsspRegister::Read32(GPIO_BASE_ADDRESS(aId) + KGPIO_DATAIN) & GPIO_PIN_OFFSET(aId) ? + GPIO::EHigh: + GPIO::ELow); + + return KErrNone; + } + +EXPORT_C TInt GPIO::GetOutputState(TInt aId, TGpioState& aState) + { + __ASSERT_ALWAYS(GPIO_PIN_BOUNDS(aId),Kern::Fault(" GPIO::GetOutputState OOB ",KErrArgument)); + + aState = (AsspRegister::Read32(GPIO_BASE_ADDRESS(aId)+KGPIO_DATAOUT)& GPIO_PIN_OFFSET(aId) ? + aState=GPIO::EHigh: + aState=GPIO::ELow); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetInputState(TInt aId, TGpioCallback* /*aCb*/) + { + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetOutputState(TInt aId, TGpioState aState, TGpioCallback* /*aCb*/) + { + return KErrNotSupported; + } + + +DECLARE_STANDARD_EXTENSION() + { + + TInt i=0; + for(;iiCallback(pCb->iPinId, pCb->iState, pCb->iResult, pCb->iParam); + } +public: + TInt iPinId; // the Id of the pin on which the asynchronous operation is performed + GPIO::TGpioState iState; // either the state the output pin should be moved to or the state the input pin is at + TInt iResult; // the result of this transaction as a system wide error + TAny* iParam; + TGpioCbFn iCallback; + }; +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/gpio/gpio.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/gpio/gpio.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,37 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/gpio/gpio.mmp +// + +#include +#include + +target AsspTarget(gpio,dll) +targettype kext +linkas gpio.dll + +sourcepath . +source gpio.cpp gpio_interrupts.cpp + +library AsspTarget(kaomap3530,lib) + +deffile ./def/~/gpio.def + +nostrictdef + +epocallowdlldata + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/gpio/gpio_interrupts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/gpio/gpio_interrupts.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,275 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/gpio/gpio_interrupts.cpp +// + +#include +#include +#include +#include +#include +#include +#include + +NONSHARABLE_CLASS( TGpioDispatcher ) : public MInterruptDispatcher + { + public: + TGpioDispatcher(); + + TInt Init(); + + virtual TInt Bind(TInt aId, TIsr aIsr, TAny* aPtr); + virtual TInt Unbind(TInt aId); + virtual TInt Enable(TInt aId); + virtual TInt Disable(TInt aId); + virtual TInt Clear(TInt aId); + virtual TInt SetPriority(TInt aId, TInt aPriority); + + private: + static void Spurious( TAny* aParam ); + static void DispatchIsr( TAny* aParam ); + + static TInt GetGPIOPin( TInt aId,GpioPin *aPin ); + static TInt SetGPIOPin(TInt aId,GpioPin *aPin); + + static FORCE_INLINE TBool IsValidId( TInt aId ); + }; + +TSpinLock GPIOpinsDescLock(/*TSpinLock::EOrderGenericIrqLow0*/); +static GpioPin GpioPins[KHwGpioPinMax]; + + +TGpioDispatcher::TGpioDispatcher() + { + for (TInt32 i = 0; i < KHwGpioPinMax; i++) + { + GpioPins[i].iMode = GPIO::EIdle; + GpioPins[i].irq.iIsr = Spurious; + GpioPins[i].irq.iPtr = &GpioPins[i]; + GpioPins[i].iBankAddr = GPIO_BASE_ADDRESS(i); + GpioPins[i].iBank = i / KHwGpioPinsPerBank; + GpioPins[i].iIrqVector = EOmap3530_IRQ29_GPIO1_MPU_IRQ +GpioPins[i].iBank; + } + } + + +TInt TGpioDispatcher::Init() + { + for(TInt i=0; i < KHwGpioBanks; i++) + { + TInt r = Interrupt::Bind(EOmap3530_IRQ29_GPIO1_MPU_IRQ+i,DispatchIsr,(TAny*) i); + // Pass in a pointer to the first pin in the bank - shouldn't use addition on the constant here + __ASSERT_ALWAYS(r==KErrNone,Kern::Fault("ExternalInterrupt::%s Cant Bind to %d",EOmap3530_IRQ29_GPIO1_MPU_IRQ+i)); + } + + Register( EIrqRangeBaseGpio ); + + return KErrNone; + } + + + +TInt TGpioDispatcher::GetGPIOPin(TInt aId,GpioPin *aPin) + { + + if(! ( aId >= 0 && aId < KHwGpioPinMax) ) + return KErrArgument; + + TInt irq = /*NKern::DisableAllInterrupts();*/__SPIN_LOCK_IRQSAVE_R(GPIOpinsDescLock); + memcpy(aPin,&GpioPins[aId],sizeof(GpioPin)); + /*NKern::RestoreInterrupts(irq);*/__SPIN_UNLOCK_IRQRESTORE_R(GPIOpinsDescLock,irq); + + return KErrNone; + } + +TInt TGpioDispatcher::SetGPIOPin(TInt aId,GpioPin *aPin) + { + + if(! ( aId >= 0 && aId < KHwGpioPinMax) ) + return KErrArgument; + + TInt irq = /*NKern::DisableAllInterrupts();*/__SPIN_LOCK_IRQSAVE_W(GPIOpinsDescLock); + memcpy(&GpioPins[aId],aPin,sizeof(GpioPin )); + /*NKern::RestoreInterrupts(irq);*/__SPIN_UNLOCK_IRQRESTORE_W(GPIOpinsDescLock,irq); + + return KErrNone; + } + +FORCE_INLINE TBool TGpioDispatcher::IsValidId( TInt aId ) + { + return ((TUint)aId < EGPIOIRQ_END && (TUint)aId>=EGPIOIRQ_FIRST); + } + + +void TGpioDispatcher::Spurious(TAny* aId) + { + Kern::Fault("SpuriousExtInt",(TInt)aId); + } + + +void TGpioDispatcher::DispatchIsr(TAny *aPtr) + { + Interrupt::Disable(EOmap3530_IRQ29_GPIO1_MPU_IRQ + (TInt) aPtr); + + //need to spinlock the gpio here..... + TUint32 highVectors = AsspRegister::Read32(KGPIO_BASE_ADDRESSES[(TInt) aPtr] + KGPIO_IRQSTATUS1); + AsspRegister::Write32(KGPIO_BASE_ADDRESSES[(TInt) aPtr] + KGPIO_IRQSTATUS1, highVectors); + + GpioPin pin; + for (TInt i = 0; i < KHwGpioPinsPerBank ; i++,highVectors >>=1) + { + if(highVectors & 0x1) + { + GetGPIOPin(i+(TInt)aPtr*KHwGpioPinsPerBank, &pin); + (*pin.irq.iIsr)(pin.irq.iPtr); // dispatch this pin's ISR + } + } + Interrupt::Enable(EOmap3530_IRQ29_GPIO1_MPU_IRQ + (TInt)aPtr); + } + + +TInt TGpioDispatcher::Bind(TInt anId, TIsr anIsr, TAny* aPtr) + { + if(IsValidId(anId)) + { + //we want to bind the callers isrfunc to the pin dispatch here + GpioPin pin; + GetGPIOPin(anId- EGPIOIRQ_FIRST,&pin); + pin.irq.iIsr = anIsr; + pin.irq.iPtr = aPtr; + SetGPIOPin(anId- EGPIOIRQ_FIRST,&pin); + return KErrNone; + } + else + { + return KErrArgument; + } + } + +TInt TGpioDispatcher::Unbind(TInt anId) + { + __KTRACE_OPT(KGPIO,Kern::Printf("GPIO:%s id=%d",__FUNCTION__,anId)); + + if(IsValidId(anId)) + { + GpioPin pin; + TInt pinNr = anId - EGPIOIRQ_FIRST; + GetGPIOPin(pinNr,&pin); + pin.irq.iIsr=Spurious; + pin.irq.iPtr=NULL; + SetGPIOPin(pinNr,&pin); + return KErrNone; + } + else + { + return KErrArgument; + } + } + + +TInt TGpioDispatcher::Enable(TInt anId) + { + __KTRACE_OPT(KGPIO,Kern::Printf("GPIO:%s id=%d +",__FUNCTION__,anId)); + CHECK_PRECONDITIONS(MASK_NO_FAST_MUTEX,"GPIO::InterruptEnable Cant Hold Mutex in Blocking function"); + + if(IsValidId(anId)) + { + GpioPin pin; + TInt pinNr = anId - EGPIOIRQ_FIRST; + GetGPIOPin(pinNr,&pin); + + if(Spurious == pin.irq.iIsr) + { + + __KTRACE_OPT(KGPIO,Kern::Printf("GPIO:%s id=%d NOT BOUND",__FUNCTION__,anId)); + return KErrNotReady; + } + AsspRegister::Write32(pin.iBankAddr+KGPIO_SETIRQENABLE1,GPIO_PIN_OFFSET( pinNr)); + + if(!Omap3530Interrupt::IsInterruptEnabled(pin.iIrqVector)) + Interrupt::Enable(pin.iIrqVector); + + return KErrNone; + } + else + { + return KErrArgument; + } + } + +TInt TGpioDispatcher::Disable(TInt anId) + { + + __KTRACE_OPT(KGPIO,Kern::Printf("GPIO:%s id=%d",__FUNCTION__,anId)); + CHECK_PRECONDITIONS(MASK_NO_FAST_MUTEX,"GPIO::InterruptDisable Cant Hold Mutex in Blocking function"); + if(IsValidId(anId)) + { + TInt pinNr = anId- EGPIOIRQ_FIRST; + GpioPin pin; + GetGPIOPin(pinNr, &pin); + + AsspRegister::Write32(pin.iBankAddr+KGPIO_CLEARIRQENABLE1, GPIO_PIN_OFFSET(pinNr)); + + //is this the last one for this bank ? then unmap + if(0x00 == AsspRegister::Read32(pin.iBankAddr+KGPIO_IRQENABLE1)) + { + Interrupt::Disable(pin.iIrqVector); + } + return KErrNone; + } + else + { + return KErrArgument; + } + } + +TInt TGpioDispatcher::Clear(TInt anId) + { + + __KTRACE_OPT(KGPIO,Kern::Printf("GPIO:%s id=%d",__FUNCTION__,anId)); + CHECK_PRECONDITIONS(MASK_NO_FAST_MUTEX,"GPIO::InterruptDisable Cant Hold Mutex in Blocking function"); + + if(IsValidId(anId)) + { + TInt pinNr = anId- EGPIOIRQ_FIRST; + GpioPin myPin; + GetGPIOPin(pinNr, &myPin); + + AsspRegister::Write32((myPin.iBankAddr+KGPIO_IRQSTATUS1), GPIO_PIN_OFFSET(pinNr)); + //if that was the only high bit clear the mainline as well + if(0 == AsspRegister::Read32(myPin.iBankAddr+KGPIO_IRQSTATUS1)) + { + Interrupt::Clear(myPin.iIrqVector); + } + } + return KErrNone; + } + +TInt TGpioDispatcher::SetPriority(TInt aId, TInt aPriority) + { + return KErrNotSupported; + } + + +GLDEF_C TInt InitGpioInterrupts() + { + TInt r = KErrNoMemory; + + TGpioDispatcher* dispatcher = new TGpioDispatcher; + if( dispatcher ) + { + r = dispatcher->Init(); + } + return r; + } diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/gpio/omap3530_gpio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/gpio/omap3530_gpio.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,295 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/gpio/omap3530_gpio.h +// This file is part of the Beagle Base port +// + +#ifndef __OMAP3530_GPIO_H__ +#define __OMAP3530_GPIO_H__ + +#include +#include +//#include + +#include +#include + +const TUint KGPIO1 = Omap3530HwBase::TVirtual<0x48310000>::Value; +const TUint KGPIO2 = Omap3530HwBase::TVirtual<0x49050000>::Value; +const TUint KGPIO3 = Omap3530HwBase::TVirtual<0x49052000>::Value; +const TUint KGPIO4 = Omap3530HwBase::TVirtual<0x49054000>::Value; +const TUint KGPIO5 = Omap3530HwBase::TVirtual<0x49056000>::Value; +const TUint KGPIO6 = Omap3530HwBase::TVirtual<0x49058000>::Value; + + +const TUint KGPIO_REVISION = 0x000; +const TUint KGPIO_SYSCONFIG = 0x010; +const TUint KGPIO_SYSSTATUS = 0x014; +const TUint KGPIO_IRQSTATUS1 = 0x018; +const TUint KGPIO_IRQENABLE1 = 0x01C; +const TUint KGPIO_WAKEUPENABLE = 0x020; +const TUint KGPIO_IRQSTATUS2 = 0x028; +const TUint KGPIO_IRQENABLE2 = 0x02C; +const TUint KGPIO_CTRL = 0x030; +const TUint KGPIO_OE = 0x034; +const TUint KGPIO_DATAIN = 0x038; +const TUint KGPIO_DATAOUT = 0x03C; +const TUint KGPIO_LEVELDETECT0 = 0x040; +const TUint KGPIO_LEVELDETECT1 = 0x044; +const TUint KGPIO_RISINGDETECT = 0x048; +const TUint KGPIO_FALLINGDETECT = 0x04C; +const TUint KGPIO_DEBOUNCENABLE = 0x050; +const TUint KGPIO_DEBOUNCINGTIME = 0x054; +const TUint KGPIO_CLEARIRQENABLE1 = 0x060; +const TUint KGPIO_SETIRQENABLE1 = 0x064; +const TUint KGPIO_CLEARIRQENABLE2 = 0x070; +const TUint KGPIO_SETIRQENABLE2 = 0x074; +const TUint KGPIO_CLEARWKUENA = 0x080; +const TUint KGPIO_SETWKUENA = 0x084; +const TUint KGPIO_CLEARDATAOUT = 0x090; +const TUint KGPIO_SETDATAOUT = 0x094; + +const TUint KGPIO_DEBOUNCE_TIME_MASK = 0xF; + + +enum TGPIO_InterruptId + { + EGPIOIRQ_FIRST = (EIrqRangeBaseGpio << KIrqRangeIndexShift), + EGPIOIRQ_PIN_0 = EGPIOIRQ_FIRST, + EGPIOIRQ_PIN_1, + EGPIOIRQ_PIN_2, + EGPIOIRQ_PIN_3, + EGPIOIRQ_PIN_4, + EGPIOIRQ_PIN_5, + EGPIOIRQ_PIN_6, + EGPIOIRQ_PIN_7, + EGPIOIRQ_PIN_8, + EGPIOIRQ_PIN_9, + EGPIOIRQ_PIN_10, + EGPIOIRQ_PIN_11, + EGPIOIRQ_PIN_12, + EGPIOIRQ_PIN_13, + EGPIOIRQ_PIN_14, + EGPIOIRQ_PIN_15, + EGPIOIRQ_PIN_16, + EGPIOIRQ_PIN_17, + EGPIOIRQ_PIN_18, + EGPIOIRQ_PIN_19, + EGPIOIRQ_PIN_20, + EGPIOIRQ_PIN_21, + EGPIOIRQ_PIN_22, + EGPIOIRQ_PIN_23, + EGPIOIRQ_PIN_24, + EGPIOIRQ_PIN_25, + EGPIOIRQ_PIN_26, + EGPIOIRQ_PIN_27, + EGPIOIRQ_PIN_28, + EGPIOIRQ_PIN_29, + EGPIOIRQ_PIN_30, + EGPIOIRQ_PIN_31, + EGPIOIRQ_PIN_32, + EGPIOIRQ_PIN_33, + EGPIOIRQ_PIN_34, + EGPIOIRQ_PIN_35, + EGPIOIRQ_PIN_36, + EGPIOIRQ_PIN_37, + EGPIOIRQ_PIN_38, + EGPIOIRQ_PIN_39, + EGPIOIRQ_PIN_40, + EGPIOIRQ_PIN_41, + EGPIOIRQ_PIN_42, + EGPIOIRQ_PIN_43, + EGPIOIRQ_PIN_44, + EGPIOIRQ_PIN_45, + EGPIOIRQ_PIN_46, + EGPIOIRQ_PIN_47, + EGPIOIRQ_PIN_48, + EGPIOIRQ_PIN_49, + EGPIOIRQ_PIN_50, + EGPIOIRQ_PIN_51, + EGPIOIRQ_PIN_52, + EGPIOIRQ_PIN_53, + EGPIOIRQ_PIN_54, + EGPIOIRQ_PIN_55, + EGPIOIRQ_PIN_56, + EGPIOIRQ_PIN_57, + EGPIOIRQ_PIN_58, + EGPIOIRQ_PIN_59, + EGPIOIRQ_PIN_60, + EGPIOIRQ_PIN_61, + EGPIOIRQ_PIN_62, + EGPIOIRQ_PIN_63, + EGPIOIRQ_PIN_64, + EGPIOIRQ_PIN_65, + EGPIOIRQ_PIN_66, + EGPIOIRQ_PIN_67, + EGPIOIRQ_PIN_68, + EGPIOIRQ_PIN_69, + EGPIOIRQ_PIN_70, + EGPIOIRQ_PIN_71, + EGPIOIRQ_PIN_72, + EGPIOIRQ_PIN_73, + EGPIOIRQ_PIN_74, + EGPIOIRQ_PIN_75, + EGPIOIRQ_PIN_76, + EGPIOIRQ_PIN_77, + EGPIOIRQ_PIN_78, + EGPIOIRQ_PIN_79, + EGPIOIRQ_PIN_80, + EGPIOIRQ_PIN_81, + EGPIOIRQ_PIN_82, + EGPIOIRQ_PIN_83, + EGPIOIRQ_PIN_84, + EGPIOIRQ_PIN_85, + EGPIOIRQ_PIN_86, + EGPIOIRQ_PIN_87, + EGPIOIRQ_PIN_88, + EGPIOIRQ_PIN_89, + EGPIOIRQ_PIN_90, + EGPIOIRQ_PIN_91, + EGPIOIRQ_PIN_92, + EGPIOIRQ_PIN_93, + EGPIOIRQ_PIN_94, + EGPIOIRQ_PIN_95, + EGPIOIRQ_PIN_96, + EGPIOIRQ_PIN_97, + EGPIOIRQ_PIN_98, + EGPIOIRQ_PIN_99, + EGPIOIRQ_PIN_100, + EGPIOIRQ_PIN_101, + EGPIOIRQ_PIN_102, + EGPIOIRQ_PIN_103, + EGPIOIRQ_PIN_104, + EGPIOIRQ_PIN_105, + EGPIOIRQ_PIN_106, + EGPIOIRQ_PIN_107, + EGPIOIRQ_PIN_108, + EGPIOIRQ_PIN_109, + EGPIOIRQ_PIN_110, + EGPIOIRQ_PIN_111, + EGPIOIRQ_PIN_112, + EGPIOIRQ_PIN_113, + EGPIOIRQ_PIN_114, + EGPIOIRQ_PIN_115, + EGPIOIRQ_PIN_116, + EGPIOIRQ_PIN_117, + EGPIOIRQ_PIN_118, + EGPIOIRQ_PIN_119, + EGPIOIRQ_PIN_120, + EGPIOIRQ_PIN_121, + EGPIOIRQ_PIN_122, + EGPIOIRQ_PIN_123, + EGPIOIRQ_PIN_124, + EGPIOIRQ_PIN_125, + EGPIOIRQ_PIN_126, + EGPIOIRQ_PIN_127, + EGPIOIRQ_PIN_128, + EGPIOIRQ_PIN_129, + EGPIOIRQ_PIN_130, + EGPIOIRQ_PIN_131, + EGPIOIRQ_PIN_132, + EGPIOIRQ_PIN_133, + EGPIOIRQ_PIN_134, + EGPIOIRQ_PIN_135, + EGPIOIRQ_PIN_136, + EGPIOIRQ_PIN_137, + EGPIOIRQ_PIN_138, + EGPIOIRQ_PIN_139, + EGPIOIRQ_PIN_140, + EGPIOIRQ_PIN_141, + EGPIOIRQ_PIN_142, + EGPIOIRQ_PIN_143, + EGPIOIRQ_PIN_144, + EGPIOIRQ_PIN_145, + EGPIOIRQ_PIN_146, + EGPIOIRQ_PIN_147, + EGPIOIRQ_PIN_148, + EGPIOIRQ_PIN_149, + EGPIOIRQ_PIN_150, + EGPIOIRQ_PIN_151, + EGPIOIRQ_PIN_152, + EGPIOIRQ_PIN_153, + EGPIOIRQ_PIN_154, + EGPIOIRQ_PIN_155, + EGPIOIRQ_PIN_156, + EGPIOIRQ_PIN_157, + EGPIOIRQ_PIN_158, + EGPIOIRQ_PIN_159, + EGPIOIRQ_PIN_160, + EGPIOIRQ_PIN_161, + EGPIOIRQ_PIN_162, + EGPIOIRQ_PIN_163, + EGPIOIRQ_PIN_164, + EGPIOIRQ_PIN_165, + EGPIOIRQ_PIN_166, + EGPIOIRQ_PIN_167, + EGPIOIRQ_PIN_168, + EGPIOIRQ_PIN_169, + EGPIOIRQ_PIN_170, + EGPIOIRQ_PIN_171, + EGPIOIRQ_PIN_172, + EGPIOIRQ_PIN_173, + EGPIOIRQ_PIN_174, + EGPIOIRQ_PIN_175, + EGPIOIRQ_PIN_176, + EGPIOIRQ_PIN_177, + EGPIOIRQ_PIN_178, + EGPIOIRQ_PIN_179, + EGPIOIRQ_PIN_180, + EGPIOIRQ_PIN_181, + EGPIOIRQ_PIN_182, + EGPIOIRQ_PIN_183, + EGPIOIRQ_PIN_184, + EGPIOIRQ_PIN_185, + EGPIOIRQ_PIN_186, + EGPIOIRQ_PIN_187, + EGPIOIRQ_PIN_188, + EGPIOIRQ_PIN_189, + EGPIOIRQ_PIN_190, + EGPIOIRQ_PIN_191, + + EGPIOIRQ_END + }; + + + +const TInt32 KHwGpioPinMax = 192; // 32*6 pins +const TInt32 KHwGpioPinsPerBank = 32; +const TInt32 KHwGpioBanks = KHwGpioPinMax / KHwGpioPinsPerBank ; + +// Utility code to convert a pin number to a GPIO bank +const TUint KGPIO_BASE_ADDRESSES[] = { KGPIO1, KGPIO2, KGPIO3, KGPIO4, KGPIO5, KGPIO6 }; + + + + + +inline TUint GPIO_BASE_ADDRESS(TInt aPin) {return KGPIO_BASE_ADDRESSES[(TInt)(aPin/KHwGpioPinsPerBank)];}; +#define GPIO_PIN_BANK(aId) ((aId)/KHwGpioPinsPerBank) +#define GPIO_PIN_OFFSET(aId) (1 << (aId%KHwGpioPinsPerBank)) +#define GPIO_PIN_BOUNDS(aId)((aId > 0) && (aId + +#include +#include +#include +//#include +#include +#include +#include +//#include + +_LIT(KDfcName, "I2C_DFC"); // Not used by the I2c dfc! +DECLARE_STANDARD_EXTENSION() + { + return KErrNone; + } + +namespace I2c +{ +const TInt KMaxDevicesPerUnit = 8; // arbitary - change if required +const TInt KNumUnits = E3 + 1; + +// Each unit has KMaxDevicesPerUnit of these structures. At least one for each slave device on it's bus. +struct TDeviceControl + { + TDeviceAddress iAddress; // the slave devices address; 7 or 10 bits + TDfcQue* iDfcQueue; // calling driver's DFC thread + NFastSemaphore iSyncSem; // used to block the calling thread during synchronous transfers + }; + +// There are three instances of this structure - one for each I2C bus on the OMAP3530 +struct TUnitControl + { + TUnitControl(); + + TSpinLock iLock; // prevents concurrent access to the request queue + DMutex* iOpenMutex; + + enum + { + EIdle, + ERead, + EWrite + } iState; + + // Configuration stored and checked during Open() + TRole iRole; + TMode iMode; + void* iExclusiveClient; + TRate iRate; + TDeviceAddress iOwnAddress; + + // The DFC for this unit - it runs on the thread associated with the active transfer + TDfc iDfc; + + // the slave devices on this unit's bus + TDeviceControl iDevice[KMaxDevicesPerUnit]; + TInt iNumDevices; + + // The queue of requested transfers - the active transfer is the head of the queue + TTransferPb* iTransferQ; + TTransferPb* iTransferQTail; // the last transfer on the queue + + // the current phase of the sctive transfer + TTransferPb* iCurrentPhase; + }; + +// The OMAP3530 register address +const TUint KI2C_IE[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070004>::Value, Omap3530HwBase::TVirtual<0x48072004>::Value, Omap3530HwBase::TVirtual<0x48060004>::Value}; +const TUint KI2C_STAT[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070008>::Value, Omap3530HwBase::TVirtual<0x48072008>::Value, Omap3530HwBase::TVirtual<0x48060008>::Value}; +//const TUint KI2C_WE[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x4807000C>::Value, Omap3530HwBase::TVirtual<0x4807200C>::Value, Omap3530HwBase::TVirtual<0x4806000C>::Value}; +const TUint KI2C_SYSS[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070010>::Value, Omap3530HwBase::TVirtual<0x48072010>::Value, Omap3530HwBase::TVirtual<0x48060010>::Value}; +const TUint KI2C_BUF[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070014>::Value, Omap3530HwBase::TVirtual<0x48072014>::Value, Omap3530HwBase::TVirtual<0x48060014>::Value}; +const TUint KI2C_CNT[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070018>::Value, Omap3530HwBase::TVirtual<0x48072018>::Value, Omap3530HwBase::TVirtual<0x48060018>::Value}; +const TUint KI2C_DATA[KNumUnits] = + {Omap3530HwBase::TVirtual<0x4807001C>::Value, Omap3530HwBase::TVirtual<0x4807201C>::Value, Omap3530HwBase::TVirtual<0x4806001C>::Value}; +const TUint KI2C_SYSC[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070020>::Value, Omap3530HwBase::TVirtual<0x48072020>::Value, Omap3530HwBase::TVirtual<0x48060020>::Value}; +const TUint KI2C_CON[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070024>::Value, Omap3530HwBase::TVirtual<0x48072024>::Value, Omap3530HwBase::TVirtual<0x48060024>::Value}; +//const TUint KI2C_OA0[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x48070028>::Value, Omap3530HwBase::TVirtual<0x48072028>::Value, Omap3530HwBase::TVirtual<0x48060028>::Value}; +const TUint KI2C_SA[KNumUnits] = + {Omap3530HwBase::TVirtual<0x4807002C>::Value, Omap3530HwBase::TVirtual<0x4807202C>::Value, Omap3530HwBase::TVirtual<0x4806002C>::Value}; +const TUint KI2C_PSC[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070030>::Value, Omap3530HwBase::TVirtual<0x48072030>::Value, Omap3530HwBase::TVirtual<0x48060030>::Value}; +const TUint KI2C_SCLL[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070034>::Value, Omap3530HwBase::TVirtual<0x48072034>::Value, Omap3530HwBase::TVirtual<0x48060034>::Value}; +const TUint KI2C_SCLH[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070038>::Value, Omap3530HwBase::TVirtual<0x48072038>::Value, Omap3530HwBase::TVirtual<0x48060038>::Value}; +//const TUint KI2C_SYSTEST[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x4807003C>::Value, Omap3530HwBase::TVirtual<0x4807203C>::Value, Omap3530HwBase::TVirtual<0x4806003C>::Value}; +const TUint KI2C_BUFSTAT[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070040>::Value, Omap3530HwBase::TVirtual<0x48072040>::Value, Omap3530HwBase::TVirtual<0x48060040>::Value}; +const TUint KI2C_OA1[KNumUnits] = + {Omap3530HwBase::TVirtual<0x48070044>::Value, Omap3530HwBase::TVirtual<0x48072044>::Value, Omap3530HwBase::TVirtual<0x48060044>::Value}; +//const TUint KI2C_OA2[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x48070048>::Value, Omap3530HwBase::TVirtual<0x48072048>::Value, Omap3530HwBase::TVirtual<0x48060048>::Value}; +//const TUint KI2C_OA3[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x4807004C>::Value, Omap3530HwBase::TVirtual<0x4807204C>::Value, Omap3530HwBase::TVirtual<0x4806004C>::Value}; +//const TUint KI2C_ACTOA[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x48070050>::Value, Omap3530HwBase::TVirtual<0x48072050>::Value, Omap3530HwBase::TVirtual<0x48060050>::Value}; +//const TUint KI2C_SBLOCK[KNumUnits] = +// {Omap3530HwBase::TVirtual<0x48070054>::Value, Omap3530HwBase::TVirtual<0x48072054>::Value, Omap3530HwBase::TVirtual<0x48060054>::Value}; +const TUint KCM_ICLKEN1_CORE = Omap3530HwBase::TVirtual<0x48004A10>::Value; +const TUint KCM_FCLKEN1_CORE = Omap3530HwBase::TVirtual<0x48004A00>::Value; + +// the Id's used when binding the interrupts +const TOmap3530_IRQ KIrqId[KNumUnits] = {EOmap3530_IRQ56_I2C1_IRQ, EOmap3530_IRQ57_I2C2_IRQ, EOmap3530_IRQ61_I2C3_IRQ}; + +// The three unit control blocks; one for each unit +TUnitControl gUcb[KNumUnits]; +//TUint prmClientId; + +TUnit RawUnit(THandle aHandle); +TUnit Unit(THandle aHandle); +TUnitControl& UnitCb(THandle aHandle); +TDeviceAddress Device(THandle aHandle); +TDeviceControl& DeviceCb(THandle aHandle); +THandle Handle(TUnit aUnit, TDeviceAddress aDeviceAddress); +void Complete(TUnitControl& aUnit, TInt aResult); +void Configure(TUnit); // reset and configure an I2C unit +void Deconfigure(TUnit); +void TheIsr(void*); +void TheDfc(TAny* aUnit); + +EXPORT_C TConfigPb::TConfigPb() : + iUnit((TUnit)-1), // ensure that an un-initialised cpb will return KErrArgument from Open() + iExclusiveClient(0), + iDeviceAddress(1) + {} + +EXPORT_C TTransferPb::TTransferPb() : + iNextPhase(0) + {} + +EXPORT_C THandle Open(const TConfigPb& aConfig) + { + //TInt r = PowerResourceManager::RegisterClient( prmClientId, KDfcName ); + //__NK_ASSERT_ALWAYS(r==KErrNone); + THandle h; + __NK_ASSERT_ALWAYS(aConfig.iVersion == I2C_VERSION); + if (aConfig.iUnit >= E1 && aConfig.iUnit <= E3) + { + TUnitControl& unit = gUcb[aConfig.iUnit]; + Kern::MutexWait( *unit.iOpenMutex ); + + if (unit.iNumDevices == 0) + { + if (aConfig.iRole == EMaster && + aConfig.iMode == E7Bit && + aConfig.iRate >= E100K && aConfig.iRate <= E400K) + { + unit.iRole = aConfig.iRole; + unit.iMode = aConfig.iMode; + unit.iExclusiveClient = aConfig.iExclusiveClient; + unit.iRate = aConfig.iRate; + unit.iDevice[unit.iNumDevices].iAddress = aConfig.iDeviceAddress; + unit.iDevice[unit.iNumDevices++].iDfcQueue = aConfig.iDfcQueue; + h = Handle(aConfig.iUnit, aConfig.iDeviceAddress); + Configure(aConfig.iUnit); + TInt r = Interrupt::Bind(KIrqId[aConfig.iUnit], TheIsr, (void*) aConfig.iUnit); + __NK_ASSERT_DEBUG(r == KErrNone); + } + else + { + h = KErrArgument; + } + } + else // unit is already open + { + if (unit.iNumDevices < KMaxDevicesPerUnit) + { + if (unit.iRole == aConfig.iRole && + unit.iMode == aConfig.iMode && + unit.iExclusiveClient == aConfig.iExclusiveClient && + unit.iRate == aConfig.iRate) + { + h = 0; + for (TInt i = 0; i < unit.iNumDevices; i++) + { + if (unit.iDevice[i].iAddress == aConfig.iDeviceAddress) + { + h = KErrInUse; + break; + } + } + if (h == 0) + { + unit.iDevice[unit.iNumDevices].iAddress = aConfig.iDeviceAddress; + unit.iDevice[unit.iNumDevices++].iDfcQueue = aConfig.iDfcQueue; + h = Handle(aConfig.iUnit, aConfig.iDeviceAddress); + } + } + else + { + h = KErrInUse; + } + } + else + { + h = KErrTooBig; + } + } + Kern::MutexSignal( *unit.iOpenMutex ); + } + else + { + h = KErrArgument; + } + return h; + } + +EXPORT_C void Close(THandle& aHandle) + { + TUnit unitI = RawUnit(aHandle); + + if (unitI >= E1 && unitI <= E3) + { + TUnitControl& unit = gUcb[unitI]; + Kern::MutexWait( *unit.iOpenMutex ); + + TInt i = 0; + for (; i < unit.iNumDevices; i++) + { + if (unit.iDevice[i].iAddress == Device(aHandle)) + { + unit.iNumDevices--; + break; + } + } + for (; i < unit.iNumDevices; i++) + { + unit.iDevice[i] = unit.iDevice[i + 1]; + } + + if (unit.iNumDevices == 0) + { + (void) Interrupt::Unbind(KIrqId[unitI]); + Deconfigure(TUnit(unitI)); + } + Kern::MutexSignal( *unit.iOpenMutex ); + } + aHandle = -1; + //PowerResourceManager::DeRegisterClient(prmClientId); + //prmClientId=0; + } + +void AddToQueue( TUnitControl& aUnit, TDeviceControl& aDcb, TTransferPb& aWcb ) + { + TInt irq = __SPIN_LOCK_IRQSAVE(aUnit.iLock); + + if (aUnit.iTransferQ == 0) + { + __NK_ASSERT_DEBUG(aUnit.iState == TUnitControl::EIdle); + aUnit.iTransferQ = &aWcb; + aUnit.iCurrentPhase = &aWcb; + aUnit.iTransferQTail = &aWcb; + aUnit.iDfc.SetDfcQ(aDcb.iDfcQueue); + aUnit.iDfc.Enque(); + } + else + { + __NK_ASSERT_DEBUG(aUnit.iTransferQTail->iNextTransfer == 0); + aUnit.iTransferQTail->iNextTransfer = &aWcb; + aUnit.iTransferQTail = &aWcb; + } + __SPIN_UNLOCK_IRQRESTORE(unit.iLock, irq); + } + + +EXPORT_C TInt TransferS(THandle aHandle, TTransferPb& aWcb) + { + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("+I2C:TransferS"))); + + CHECK_PRECONDITIONS(MASK_NOT_ISR, "I2c::TransferS"); + + aWcb.iNextTransfer = 0; + aWcb.iCompletionDfc = 0; // indicate that it is a sync transfer and the FSM needs to Signal the semaphore + TDeviceControl& dcb = DeviceCb(aHandle); + aWcb.iDcb = &dcb; + aWcb.iResult = (TInt)&dcb.iSyncSem; // use the async tranfer result member to store the semaphore // Todo: store ptr to dcb in aWcb + + NKern::FSSetOwner(&dcb.iSyncSem, 0); + + TUnitControl& unit = UnitCb(aHandle); + + AddToQueue( unit, dcb, aWcb ); + + NKern::FSWait(&dcb.iSyncSem); + + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("-I2C:TransferS:%d", aWcb.iResult))); + + return aWcb.iResult; + } + +EXPORT_C void TransferA(THandle aHandle, TTransferPb& aWcb) + { + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("+I2C:TransferA"))); + + CHECK_PRECONDITIONS(MASK_NOT_ISR, "I2c::TransferA"); + + aWcb.iNextTransfer = 0; + TDeviceControl& dcb = DeviceCb(aHandle); + aWcb.iDcb = &dcb; + TUnitControl& unit = UnitCb(aHandle); + + AddToQueue( unit, dcb, aWcb ); + + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("-I2C:TransferA"))); + } + +EXPORT_C void CancelATransfer(THandle) + { + } + +inline TBool BitSet(TUint32 aWord, TUint32 aMask) + { + return (aWord & aMask) != 0; + } +const TUint32 KStatBb = 1 << 12; +const TUint32 KStatNack = 1 << 1; +const TUint32 KStatAl = 1 << 0; +const TUint32 KStatArdy = 1 << 2; +const TUint32 KStatRdr = 1 << 13; +const TUint32 KStatRRdy = 1 << 3; +const TUint32 KStatXdr = 1 << 14; +const TUint32 KStatXrdy = 1 << 4; +const TUint32 KStatBf = 1 << 8; +const TUint32 KStatInterupts = KStatXdr | KStatRdr | KStatBf | KStatXrdy | KStatRRdy | KStatArdy | KStatNack | KStatAl; + +const TUint32 KConMst = 1 << 10; +const TUint32 KConI2cEn = 1 << 15; +const TUint32 KConTrx = 1 << 9; +const TUint32 KConStp = 1 << 1; +const TUint32 KConStt = 1 << 0; + +void TheDfc(TAny* aUnit) + { + TUnit unitI = (TUnit)(TInt)aUnit; + TUnitControl& unit = gUcb[unitI]; + + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("I2C:DFC:S%d", unit.iState)) ); + + switch (unit.iState) + { + case TUnitControl::EIdle: + { +// 18.5.1.1.2 +// 1 + TTransferPb& tpb = *unit.iTransferQ; + TTransferPb& ppb = *unit.iCurrentPhase; + + TUint32 con = KConI2cEn | KConMst; + if (ppb.iType == TTransferPb::EWrite) + { + con |= KConTrx; + } + AsspRegister::Write16(KI2C_CON[unitI], con); +// 18.5.1.1.3 + TUint32 sa = AsspRegister::Read16(KI2C_SA[unitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:SA[%d]: 0x%04x<-0x%04x", unitI, sa, tpb.iDcb->iAddress)); + AsspRegister::Write16(KI2C_SA[unitI], tpb.iDcb->iAddress); + TUint32 cnt = AsspRegister::Read16(KI2C_CNT[unitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:CNT[%d]: 0x%04x<-0x%04x", unitI, cnt, ppb.iLength)); + AsspRegister::Write16(KI2C_CNT[unitI], ppb.iLength); +// 18.5.1.1.4 + if (ppb.iNextPhase == 0) // last phase + { + con |= KConStp; // STP + } + con |= KConStt; // STT + if (&tpb == &ppb) // first phase + { + TInt im = NKern::DisableAllInterrupts(); // ensure that the transaction is started while the bus is free + TUint32 stat = AsspRegister::Read16(KI2C_STAT[unitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:STAT[%d]: 0x%04x", unitI, stat)); + __NK_ASSERT_ALWAYS(!BitSet(stat, KStatBb)); // if multi-master then need a polling state with a timeout + AsspRegister::Write16(KI2C_CON[unitI], con); + NKern::RestoreInterrupts(im); + } + else // a follow on phase + { + AsspRegister::Write16(KI2C_CON[unitI], con); + } + __KTRACE_OPT(KI2C, Kern::Printf("I2C:CON[%d]: 0x%04x", unitI, con)); +__KTRACE_OPT(KI2C, Kern::Printf("I2C:..CNT[%d]: 0x%04x", unitI, AsspRegister::Read16(KI2C_CNT[unitI]))); + + if (ppb.iType == TTransferPb::ERead) + { + unit.iState = TUnitControl::ERead; + } + else + { + unit.iState = TUnitControl::EWrite; + } + } + break; + case TUnitControl::ERead: + case TUnitControl::EWrite: + { + TTransferPb& ppb = *unit.iCurrentPhase; + TUint32 stat = AsspRegister::Read16(KI2C_STAT[unitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:STAT[%d]: 0x%04x", unitI, stat)); + do + { + if (BitSet(stat, KStatNack)) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C:N")); + Configure(unitI); // reset the whole unit. Need more testing to determine the correct behavior. + __KTRACE_OPT(KI2C, Kern::Printf("I2C:CON|STAT[%d]: 0x%04x|0x%04x", unitI, AsspRegister::Read16(KI2C_CON[unitI]), AsspRegister::Read16(KI2C_STAT[unitI]))); + Complete(unit, KErrGeneral); + return; + } + if (BitSet(stat, KStatAl)) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C:A")); + AsspRegister::Write16(KI2C_STAT[unitI], KStatAl); + + if((AsspRegister::Read16(KI2C_CON[unitI]) & (KConMst | KConStp)) == 0) + { + AsspRegister::Modify16(KI2C_CON[unitI], KClearNone, KConStp); + Complete(unit, KErrGeneral); + return; + } + } + if (BitSet(stat, KStatArdy)) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C:Y")); + AsspRegister::Write16(KI2C_STAT[unitI], KStatArdy); + + if (ppb.iNextPhase != 0) + { + unit.iCurrentPhase = ppb.iNextPhase; + unit.iState = TUnitControl::EIdle; + unit.iDfc.Enque(); + return; + } + else + { + Complete(unit, KErrNone); + return; + } + } + if (BitSet(stat, KStatRdr)) + { + __NK_ASSERT_DEBUG(unit.iState == TUnitControl::ERead); + TUint32 rxstat = AsspRegister::Read16(KI2C_BUFSTAT[unitI]) >> 8; + rxstat &= 0x3f; + __KTRACE_OPT(KI2C, Kern::Printf("I2C:R%d", rxstat)); + for (TUint i = 0; i < rxstat; i++) + { + TUint8* d = const_cast(ppb.iData++); + *d = (TUint8) AsspRegister::Read16(KI2C_DATA[unitI]); + } + AsspRegister::Write16(KI2C_STAT[unitI], KStatRdr); + } + else if (BitSet(stat, KStatRRdy)) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C:..BUF:%x BUFSTAT:%x", AsspRegister::Read16(KI2C_BUF[unitI]), AsspRegister::Read16(KI2C_BUFSTAT[unitI]))); + __NK_ASSERT_DEBUG(unit.iState == TUnitControl::ERead); + TUint32 rtrsh = AsspRegister::Read16(KI2C_BUF[unitI]) >> 8; + rtrsh &= 0x3f; + __KTRACE_OPT(KI2C, Kern::Printf("I2C:RD%d", rtrsh + 1)); + for (TUint i = 0; i < rtrsh + 1; i++) + { + TUint8* d = const_cast(ppb.iData++); + *d = (TUint8) AsspRegister::Read16(KI2C_DATA[unitI]); + } + AsspRegister::Write16(KI2C_STAT[unitI], KStatRRdy); + } + if (BitSet(stat, KStatXdr)) + { + __NK_ASSERT_DEBUG(unit.iState == TUnitControl::EWrite); + TUint32 txstat = AsspRegister::Read16(KI2C_BUFSTAT[unitI]); + txstat &= 0x3f; + __KTRACE_OPT(KI2C, Kern::Printf("I2C:W%d", txstat)); + for (TUint i = 0; i < txstat; i++) + { + AsspRegister::Write16(KI2C_DATA[unitI], *ppb.iData++); + } + AsspRegister::Write16(KI2C_STAT[unitI], KStatXdr); + } + else if (BitSet(stat, KStatXrdy)) + { + __NK_ASSERT_DEBUG(unit.iState == TUnitControl::EWrite); + TUint32 xtrsh = AsspRegister::Read16(KI2C_BUF[unitI]); + xtrsh &= 0x3f; + __KTRACE_OPT(KI2C, Kern::Printf("I2C:WD%d", xtrsh + 1)); + for (TUint i = 0; i < xtrsh + 1; i++) + { + AsspRegister::Write16(KI2C_DATA[unitI], *ppb.iData++); + } + AsspRegister::Write16(KI2C_STAT[unitI], KStatXrdy); + } +/* if (stat == KStatBf) + { + __KTRACE_OPT(KI2C, Kern::Printf("F")); + __NK_ASSERT_ALWAYS(ppb.iNextPhase == 0); + AsspRegister::Write16(KI2C_STAT[unitI], KStatBf); + Complete(unit, KErrNone); + return; + } +*/ stat = AsspRegister::Read16(KI2C_STAT[unitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:STAT[%d]: 0x%04x", unitI, stat)); + } while (BitSet(stat, KStatInterupts)); + } + break; + } + Interrupt::Enable(KIrqId[unitI]); + } + +TUnitControl::TUnitControl() : + iLock(/*TSpinLock::EOrderGenericIrqLow1*/), + iDfc(TheDfc, 0, 1), + iNumDevices(0), + iTransferQ(0) + { + iDfc.iPtr = (void*)(this - gUcb); // unit index + __ASSERT_ALWAYS( Kern::MutexCreate( iOpenMutex, KNullDesC, KMutexOrdGeneral0 ) == KErrNone, Kern::Fault( "I2C", __LINE__ ) ); + } + +void TheIsr(void* aUnit) + { + TUnit unitI = (TUnit)(TInt)aUnit; + Interrupt::Disable(KIrqId[unitI]); + + TUnitControl& unit = gUcb[unitI]; + __KTRACE_OPT(KI2C, __KTRACE_OPT(KI2C, Kern::Printf("=I2C:DFC:u%x", &unit ))); + unit.iDfc.Add(); + } + +void Configure(TUnit aUnitI) + { + __ASSERT_NO_FAST_MUTEX; + __NK_ASSERT_ALWAYS(aUnitI<3); +// 18.5.1.1.1 +// 1 + //TInt r = PowerResourceManager::ChangeResourceState( prmClientId, Omap3530Prm::EPrmClkI2c1_F+aUnitI, Prcm::EClkOn ); + //r = PowerResourceManager::ChangeResourceState( prmClientId, Omap3530Prm::EPrmClkI2c1_I+aUnitI, Prcm::EClkOn ); + TUint32 iClkEn = AsspRegister::Read16(KCM_ICLKEN1_CORE); + TUint32 fClkEn = AsspRegister::Read16(KCM_FCLKEN1_CORE); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:CM_I|FCLKEN1[%d]: 0x%04x|0x%04x", aUnitI, iClkEn, fClkEn)); + AsspRegister::Modify32(KCM_ICLKEN1_CORE, 0, 1 << 15 + aUnitI); + AsspRegister::Modify32(KCM_FCLKEN1_CORE, 0, 1 << 15 + aUnitI); +// Reset + AsspRegister::Write16(KI2C_SYSC[aUnitI], 0x0002); + + if (gUcb[aUnitI].iRate == E100K) + { +// 2 + AsspRegister::Write16(KI2C_PSC[aUnitI], 23); +// 3 + 4 + AsspRegister::Write16(KI2C_SCLL[aUnitI], 0x000d); // 100kHz F/S, 400kHz HS + AsspRegister::Write16(KI2C_SCLH[aUnitI], 0x000f); + } + else if (gUcb[aUnitI].iRate == E400K) + { +// 2 + AsspRegister::Write16(KI2C_PSC[aUnitI], 9); +// 3 + 4 + AsspRegister::Write16(KI2C_SCLL[aUnitI], 0x0005); // 400kHz F/S, 400kHz HS + AsspRegister::Write16(KI2C_SCLH[aUnitI], 0x0007); + } +// 6 + AsspRegister::Write16(KI2C_OA1[aUnitI], gUcb[aUnitI].iOwnAddress); +// 7 + TUint32 buf = AsspRegister::Read16(KI2C_BUF[aUnitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:I2C_BUF[%d]: 0x%04x", aUnitI, buf)); +// 8 + TUint32 con = AsspRegister::Read16(KI2C_CON[aUnitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:I2C_CON[%d]: 0x%04x<-0x%04x", aUnitI, con, con | 1 << 15)); + AsspRegister::Modify16(KI2C_CON[aUnitI], 0, 1 << 15); + + TUint32 syss = AsspRegister::Read16(KI2C_SYSS[aUnitI]); + __NK_ASSERT_DEBUG(syss == 0x1); + + // set-up interrupts + TUint32 ie = AsspRegister::Read16(KI2C_IE[aUnitI]); + __KTRACE_OPT(KI2C, Kern::Printf("I2C:IE[%d]: 0x%04x<-0x%04x", aUnitI, ie, KStatInterupts)); + AsspRegister::Write16(KI2C_IE[aUnitI], KStatInterupts); + } + +void Deconfigure(TUnit aUnitI) + { + __ASSERT_NO_FAST_MUTEX; + __NK_ASSERT_ALWAYS(aUnitI<3); + //TInt r = PowerResourceManager::ChangeResourceState( prmClientId, Omap3530Prm::EPrmClkI2c1_F+aUnitI, Prcm::EClkOff ); + //__KTRACE_OPT(KBOOT, Kern::Printf("EPrmClkI2c%d_F DIS %d", aUnitI, r)); + //r = PowerResourceManager::ChangeResourceState( prmClientId, Omap3530Prm::EPrmClkI2c1_I+aUnitI, Prcm::EClkOff ); + //__KTRACE_OPT(KBOOT, Kern::Printf("EPrmClkI2c%d_I DIS %d", aUnitI, r)); + AsspRegister::Modify32(KCM_ICLKEN1_CORE, 1 << 15 + aUnitI, 0); + AsspRegister::Modify32(KCM_FCLKEN1_CORE, 1 << 15 + aUnitI, 0); + } + +THandle Handle(TUnit aUnit, TDeviceAddress aDeviceAddress) + { + return THandle(aUnit << 16 | aDeviceAddress); + } + +TUnit RawUnit(THandle aHandle) + { + TUnit r = TUnit(aHandle >> 16); + return r; + } + +TUnit Unit(THandle aHandle) + { + TUnit r = RawUnit(aHandle); + if (r < E1 || r > E3) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C Unit out of range: %d", r)); + r = E1; + } + return r; + } + +TUnitControl& UnitCb(THandle aHandle) + { + return gUcb[Unit(aHandle)]; + } + +TDeviceAddress Device(THandle aHandle) + { + TDeviceAddress r = TDeviceAddress(aHandle & 0x0000ffff); + if (r < 0 || r > 1023) + { + __KTRACE_OPT(KI2C, Kern::Printf("I2C Device out of range: %d", r)); + } + return r; + } + +TDeviceControl& DeviceCb(THandle aHandle) + { + TUnitControl& unit = UnitCb(aHandle); + TDeviceAddress device = Device(aHandle); + TInt i = 0; + for (; i < unit.iNumDevices; i++) + { + if (unit.iDevice[i].iAddress == device) + { + break; + } + } + return unit.iDevice[i]; + } + +void Complete(TUnitControl& aUnit, TInt aResult) + { + aUnit.iTransferQ->iResult = aResult; + aUnit.iState = TUnitControl::EIdle; + + TInt irq = __SPIN_LOCK_IRQSAVE(aUnit.iLock); + TTransferPb& tpb = *aUnit.iTransferQ; + aUnit.iTransferQ = aUnit.iTransferQ->iNextTransfer; + __SPIN_UNLOCK_IRQRESTORE(aUnit.iLock, irq); + + if (tpb.iCompletionDfc == 0) + { + NKern::FSSignal(&tpb.iDcb->iSyncSem); + } + else + { + tpb.iCompletionDfc->Enque(); + } + } + +} // namespace I2c + +namespace I2cReg +{ +EXPORT_C TUint8 ReadB(I2c::THandle aH, TUint8 aAddr) + { + const TUint8 KAddress = aAddr; + I2c::TTransferPb addressPhase; + addressPhase.iType = I2c::TTransferPb::EWrite; + addressPhase.iLength = 1; + addressPhase.iData = &KAddress; + + TUint8 readData; + I2c::TTransferPb dataPhase; + dataPhase.iType = I2c::TTransferPb::ERead; + dataPhase.iLength = 1; + dataPhase.iData = &readData; + + addressPhase.iNextPhase = &dataPhase; // link into a two phase transfer + + TInt r = KErrNone; + TInt retryCount = 0; + + do + { + r=I2c::TransferS(aH, addressPhase); + retryCount++; + } + while (r != KErrNone && retryCount < 5); + + __NK_ASSERT_ALWAYS(r == KErrNone); + + return readData; + } + +EXPORT_C void WriteB(I2c::THandle aH, TUint8 aAddr, TUint8 aData) + { + const TUint8 KAddrData[2] = {aAddr, aData}; + I2c::TTransferPb fullTransfer; + fullTransfer.iType = I2c::TTransferPb::EWrite; + fullTransfer.iLength = 2; + fullTransfer.iData = KAddrData; + + TInt r = KErrNone; + TInt retryCount = 0; + + do + { + r=I2c::TransferS(aH, fullTransfer); + retryCount++; + } + while (r != KErrNone && retryCount < 5); + + __NK_ASSERT_ALWAYS(r == KErrNone); + } +} // namespace I2cReg diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/i2c/i2c.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/i2c/i2c.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,40 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/i2c/i2c.mmp +// + +#include +#include + +TARGET AsspTarget(i2c, dll) +TARGETTYPE kext +LINKAS i2c.dll +DEFFILE ./def/~/i2c.def +NOSTRICTDEF + +SOURCEPATH . +SOURCE i2c.cpp + +USERINCLUDE . +SYSTEMINCLUDE +\include\assp\omap3530_assp\ +SYSTEMINCLUDE +\include\drivers + +LIBRARY AsspTarget(kaomap3530, lib) +//library resman.lib + +EPOCALLOWDLLDATA + +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/i2c/omap3530_i2c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/i2c/omap3530_i2c.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,114 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/i2c/omap3530_i2c.h +// I2C driver interface. +// This file is part of the Beagle Base port +// + +#ifndef OMAP3530_I2C_H_ +#define OMAP3530_I2C_H_ + +#include + +#define I2C_VERSION 0 // update if TConfigPb or TTransferPb change + +class TDfc; +class TDfcQue; + +namespace I2c +{ +class TDeviceControl; + +enum TUnit + { + E1, // EMaster, ESlave + E2, // EMaster, ESlave, ESccb + E3 // EMaster, ESlave, ESccb + }; +enum TRole + { + EMaster +// ESlave - TBI + }; +enum TMode + { + E7Bit +// E10Bit - TBI +// EHs - TBI +// ESccb - TBI + }; +enum TRate + { + E100K, + E400K +// E3M31 - TBI + }; +typedef TInt TDeviceAddress; // range 0..1023 or 0..128 +struct TVersion + { + inline TVersion() : iVersion(I2C_VERSION){} + TInt iVersion; + }; +struct TConfigPb : TVersion // the parameter block used by Open() + { + IMPORT_C TConfigPb(); + + TUnit iUnit; + TRole iRole; + TMode iMode; + void* iExclusiveClient; // Clients magic number - zero if the client doesn't require exclusive access otherwise use an owned object, code, stack or data address. + TRate iRate; + TDeviceAddress iOwnAddress; + TDeviceAddress iDeviceAddress; // if role is master + TDfcQue* iDfcQueue; // clients thread + }; +typedef TInt THandle; // returned from Open() +struct TTransferPb // the parameter block used by Transfer*() + { + IMPORT_C TTransferPb(); + + enum + { + ERead, + EWrite + } iType; + + TInt iLength; // in bytes. + const TUint8* iData; // only truly const for writes, i.e. *iData is modified bye Read transfers + + TTransferPb* iNextPhase; // zero if a full transfer or last phase of a multiphase transfer + + // only for asynchronous transfers i.e. WriteA() or ReadA(); + TDfc* iCompletionDfc; + TInt iResult; + + // reserved for use by I2C driver + TTransferPb* iNextTransfer; + TDeviceControl* iDcb; + }; + +// call Open() for each slave device. +// returns: +// KErrArgument if a combination of iUnit, iRole, iMode or iRate are not supported +// KErrInUse if already open exclusively, the configuration doesn't match or the device is already open. +// KErrTooBig if there are already KMaxDevicesPerUnit (currently 8) slave devices open +// a positive value if successful +IMPORT_C THandle Open(const TConfigPb&); +IMPORT_C void Close(THandle&); +IMPORT_C TInt TransferS(THandle, TTransferPb&); +IMPORT_C void TransferA(THandle, TTransferPb&); // TBI +IMPORT_C void CancelATransfer(THandle); // TBI +} + +#endif // !OMAP3530_I2C_H_ diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/i2c/omap3530_i2creg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/i2c/omap3530_i2creg.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,29 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/i2c/omap3530_i2creg.h +// I2C register interface - uses the I2C driver main interface +// This file is part of the Beagle Base port +// + +#ifndef OMAP3530_I2CREG_H_ +#define OMAP3530_I2CREG_H_ + +#include // for I2c::THandle +namespace I2cReg +{ +IMPORT_C TUint8 ReadB(I2c::THandle, TUint8 aAddr); // Synchronous read of a single byte at address aAddr +IMPORT_C void WriteB(I2c::THandle, TUint8 aAddr, TUint8 aData); // Synchronous write of a single byte, aData, at address aAddr +} + +#endif // !OMAP3530_I2CREG_H_ diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/i2c/test/t_i2c.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/i2c/test/t_i2c.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,220 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/test/t_i2c.cpp +// Test code for I2C Driver +// This file is part of the Beagle Base port +// + +#include + +#include +#include +#include + +DECLARE_STANDARD_EXTENSION() + { + _LIT(K, "T_I2C"); + + TDynamicDfcQue* dfcQueue; + TInt r = Kern::DynamicDfcQCreate(dfcQueue, 24, K); + __NK_ASSERT_ALWAYS(r == KErrNone); + + I2c::TConfigPb ccb; + ccb.iUnit = I2c::E1; + ccb.iRole = I2c::EMaster; + ccb.iMode = I2c::E7Bit; + ccb.iExclusiveClient = (void*) InitExtension; + ccb.iRate = I2c::E400K; + ccb.iOwnAddress = 0x01; + ccb.iDfcQueue = dfcQueue; + ccb.iDeviceAddress = 0x4b; + I2c::THandle h4b = I2c::Open(ccb); + __NK_ASSERT_ALWAYS(h4b >= KErrNone); + + ccb.iDeviceAddress = 0x49; + I2c::THandle h49 = I2c::Open(ccb); + __NK_ASSERT_ALWAYS(h49 >= KErrNone); + + ccb.iUnit = I2c::E3; + ccb.iRate = I2c::E100K; + ccb.iDeviceAddress = 0x50; + I2c::THandle hEdid = I2c::Open(ccb); + __NK_ASSERT_ALWAYS(hEdid >= KErrNone); + + const TUint8 KTotalRead = 128; + const TUint8 KReadPerTransfer = 16; + + I2c::TTransferPb addressPhase; + addressPhase.iType = I2c::TTransferPb::EWrite; + addressPhase.iLength = 1; + + I2c::TTransferPb dataPhase; + dataPhase.iType = I2c::TTransferPb::ERead; + dataPhase.iLength = KReadPerTransfer; + + addressPhase.iNextPhase = &dataPhase; // a two phase transfer + + TUint8 data[128]; + + for (TUint8 address = 0; address < KTotalRead; address += KReadPerTransfer) + { + addressPhase.iData = &address; + dataPhase.iData = &data[address]; + + r = I2c::TransferS(hEdid, addressPhase); + if (r != KErrNone) + { + Kern::Printf("*** Check that the DVI cable is connected ***"); + break; + } + } + + I2c::Close(hEdid); + + for (TInt i = 0; i < KTotalRead; i += 16) + { + Kern::Printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + i, data[i + 0], data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6], data[i + 7], + data[i + 8], data[i + 9], data[i + 10], data[i + 11], data[i + 12], data[i + 13], data[i + 14], data[i + 15]); + } + + TUint8 rd = I2cReg::ReadB(h4b, 0x7a); Kern::Printf("expect 0x20:%d", rd); + rd = I2cReg::ReadB(h4b, 0x7a); Kern::Printf("expect 0x03:%d", rd); + rd = I2cReg::ReadB(h4b, 0x8E); Kern::Printf("expect 0xE0:%d", rd); + rd = I2cReg::ReadB(h4b, 0x91); Kern::Printf("expect 0x05:%d", rd); + rd = I2cReg::ReadB(h49, 0x01); Kern::Printf("expect 0x03:%d", rd); + rd = I2cReg::ReadB(h49, 0x02); Kern::Printf("expect 0xc0:%d", rd); + rd = I2cReg::ReadB(h49, 0x03); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x04); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x05); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x06); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x07); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x08); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x09); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0a); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0b); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0c); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0d); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0e); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x0f); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x10); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x11); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x12); Kern::Printf("expect 0x6c:%d", rd); + rd = I2cReg::ReadB(h49, 0x13); Kern::Printf("expect 0x6c:%d", rd); + rd = I2cReg::ReadB(h49, 0x14); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x15); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x16); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x17); Kern::Printf("expect 0x0c:%d", rd); + rd = I2cReg::ReadB(h49, 0x18); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x19); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x1a); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x1b); Kern::Printf("expect 0x2b:%d", rd); + rd = I2cReg::ReadB(h49, 0x1c); Kern::Printf("expect 0x2b:%d", rd); + rd = I2cReg::ReadB(h49, 0x1d); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x1e); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x1f); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x20); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x21); Kern::Printf("expect 0x00:%d", rd); + rd = I2cReg::ReadB(h49, 0x22); Kern::Printf("expect 0x24:%d", rd); + rd = I2cReg::ReadB(h49, 0x23); Kern::Printf("expect 0x0a:%d", rd); + rd = I2cReg::ReadB(h49, 0x24); Kern::Printf("expect 0x42:%d", rd); + rd = I2cReg::ReadB(h49, 0x25); Kern::Printf("expect 0x00:%d", rd); + + rd = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + I2cReg::WriteB(h4b, 0x2a, 0x80); + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + + rd = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", rd); + I2cReg::WriteB(h4b, 0x29, 0x01); + rd = I2cReg::ReadB(h4b, 0x3f); Kern::Printf("CFG_PWRANA2:%d", rd); + + Kern::Printf("RTC_CTRL_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + + rd = I2cReg::ReadB(h4b, 0x1c); Kern::Printf("SECONDS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1d); Kern::Printf("MINUTES_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1e); Kern::Printf("HOURS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1f); Kern::Printf("DAYS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x20); Kern::Printf("MONTHS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x21); Kern::Printf("YEARS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x22); Kern::Printf("WEEKS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x23); Kern::Printf("ALARM_SECONDS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x24); Kern::Printf("ALARM_MINUTES_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x25); Kern::Printf("ALARM_HOURS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x26); Kern::Printf("ALARM_DAYS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x27); Kern::Printf("ALARM_MONTHS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x28); Kern::Printf("ALARM_YEARS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2b); Kern::Printf("RTC_INTERRUPTS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2c); Kern::Printf("RTC_COMP_LSB_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2d); Kern::Printf("RTC_COMP_MSB_REG:%d", rd); + + TUint8 ctrl = I2cReg::ReadB(h4b, 0x29); + ctrl &= ~0x01; + I2cReg::WriteB(h4b, 0x29, ctrl); + ctrl = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", ctrl); + + I2cReg::WriteB(h4b, 0x28, 0x08); + I2cReg::WriteB(h4b, 0x27, 0x12); + I2cReg::WriteB(h4b, 0x26, 0x17); + I2cReg::WriteB(h4b, 0x25, 0x10); + I2cReg::WriteB(h4b, 0x24, 0x00); + I2cReg::WriteB(h4b, 0x23, 0x00); + I2cReg::WriteB(h4b, 0x22, 0x00); + I2cReg::WriteB(h4b, 0x21, 0x08); + I2cReg::WriteB(h4b, 0x20, 0x12); + I2cReg::WriteB(h4b, 0x1f, 0x16); + I2cReg::WriteB(h4b, 0x1e, 0x10); + I2cReg::WriteB(h4b, 0x1d, 0x17); + I2cReg::WriteB(h4b, 0x1c, 0x30); + + ctrl |= 0x01; + I2cReg::WriteB(h4b, 0x29, ctrl); + ctrl = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", ctrl); + + NKern::Sleep(2000); + + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + + ctrl |= 0x40; + I2cReg::WriteB(h4b, 0x29, ctrl); + ctrl = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", ctrl); + + rd = I2cReg::ReadB(h4b, 0x1c); Kern::Printf("SECONDS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1d); Kern::Printf("MINUTES_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1e); Kern::Printf("HOURS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x1f); Kern::Printf("DAYS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x20); Kern::Printf("MONTHS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x21); Kern::Printf("YEARS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x22); Kern::Printf("WEEKS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x23); Kern::Printf("ALARM_SECONDS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x24); Kern::Printf("ALARM_MINUTES_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x25); Kern::Printf("ALARM_HOURS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x26); Kern::Printf("ALARM_DAYS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x27); Kern::Printf("ALARM_MONTHS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x28); Kern::Printf("ALARM_YEARS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x29); Kern::Printf("RTC_CTRL_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2a); Kern::Printf("RTC_STATUS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2b); Kern::Printf("RTC_INTERRUPTS_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2c); Kern::Printf("RTC_COMP_LSB_REG:%d", rd); + rd = I2cReg::ReadB(h4b, 0x2d); Kern::Printf("RTC_COMP_MSB_REG:%d", rd); + + I2c::Close(h4b); + I2c::Close(h49); + dfcQueue->Destroy(); + + return KErrNone; + } diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/i2c/test/t_i2c.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/i2c/test/t_i2c.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,33 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/assp/test/t_i2c.mmp +// + +#include +#include "kernel/kern_ext.mmh" + +TARGET t_i2c.dll +TARGETTYPE kext + +SOURCEPATH . +SOURCE t_i2c.cpp + +LIBRARY AsspTarget(i2c, lib) +LIBRARY AsspTarget(kaomap3530, lib) + +EPOCALLOWDLLDATA + +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,26 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\omap3530_drivers\bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS + +omap3530_prcm.h assp/omap3530_assp/ // + +PRJ_MMPFILES +prcm + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/def/eabi/prcm.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/def/eabi/prcm.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,39 @@ +EXPORTS + _ZN4Prcm10ClockStateENS_6TClockE @ 1 NONAME + _ZN4Prcm10SetPllModeENS_4TPllENS_8TPllModeE @ 2 NONAME + _ZN4Prcm10WakeupModeENS_6TClockE @ 3 NONAME + _ZN4Prcm13SetClockStateENS_6TClockENS_11TClockStateE @ 4 NONAME + _ZN4Prcm13SetWakeupModeENS_6TClockENS_11TWakeupModeE @ 5 NONAME + _ZN4Prcm14GptClockSourceENS_4TGptE @ 6 NONAME + _ZN4Prcm17SetGptClockSourceENS_4TGptENS_15TGptClockSourceE @ 7 NONAME + _ZN4Prcm5Init3Ev @ 8 NONAME + _ZN4Prcm7PllModeENS_4TPllE @ 9 NONAME + _ZN4Prcm10SetDividerENS_6TClockEj @ 10 NONAME + _ZN4Prcm15IsInWakeupGroupENS_6TClockENS_12TWakeupGroupE @ 11 NONAME + _ZN4Prcm16AddToWakeupGroupENS_6TClockENS_12TWakeupGroupE @ 12 NONAME + _ZN4Prcm16IsInWakeupDomainENS_6TClockENS_13TWakeupDomainE @ 13 NONAME + _ZN4Prcm17AddToWakeupDomainENS_6TClockENS_13TWakeupDomainE @ 14 NONAME + _ZN4Prcm21RemoveFromWakeupGroupENS_6TClockENS_12TWakeupGroupE @ 15 NONAME + _ZN4Prcm22RemoveFromWakeupDomainENS_6TClockENS_13TWakeupDomainE @ 16 NONAME + _ZN4Prcm7DividerENS_6TClockE @ 17 NONAME + _ZN4Prcm12SetPllConfigENS_4TPllERKNS_17TPllConfigurationE @ 18 NONAME + _ZN4Prcm5PllLpENS_4TPllE @ 19 NONAME + _ZN4Prcm8SetPllLpENS_4TPllENS_7TLpModeE @ 20 NONAME + _ZN4Prcm9PllConfigENS_4TPllERNS_17TPllConfigurationE @ 21 NONAME + _ZN4Prcm7PrmNameENS_6TClockE @ 22 NONAME + _ZN4Prcm11SetClockMuxENS_6TClockES0_ @ 23 NONAME + _ZN4Prcm14ClockFrequencyENS_6TClockE @ 24 NONAME + _ZN4Prcm8ClockMuxENS_6TClockE @ 25 NONAME + _ZN4Prcm11UsimDividerEv @ 26 NONAME + _ZN4Prcm15UsimClockSourceEv @ 27 NONAME + _ZN4Prcm15PowerDomainModeENS_12TPowerDomainE @ 28 NONAME + _ZN4Prcm18SetPowerDomainModeENS_12TPowerDomainENS_16TPowerDomainModeE @ 29 NONAME + _ZN4Prcm11PllIsLockedENS_4TPllE @ 30 NONAME + _ZN4Prcm14WaitForPllLockENS_4TPllE @ 31 NONAME + _ZN4Prcm16AutoSetPllLpModeENS_4TPllE @ 32 NONAME + _ZN4Prcm16PllBypassDividerENS_4TPllE @ 33 NONAME + _ZN4Prcm19SetPllBypassDividerENS_4TPllENS_14TBypassDividerE @ 34 NONAME + _ZN4Prcm21CalcPllFrequencyRangeENS_4TPllERNS_17TPllConfigurationE @ 35 NONAME + _ZN4Prcm15SysClkFrequencyEv @ 36 NONAME + _ZN4Prcm18SetSysClkFrequencyENS_16TSysClkFrequencyE @ 37 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/omap3530_prcm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/omap3530_prcm.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,621 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// \omap3530\omap3530_assp\prcm.h +// Access to PRCM. +// This file is part of the Beagle Base port +// + +#ifndef PRCM_H__ +#define PRCM_H__ + +#include +#include + +namespace Prcm +{ +enum TPanic + { + ESetPllConfigBadPll, ///< bad PLL ID in SetPllConfiguration() + EGetPllConfigBadPll, ///< bad PLL ID in PllConfiguration() + ESetPllConfigBadFreqRange, ///< bad PLL frequency range in SetPllConfiguration() + ESetPllConfigBadRamp, ///< bad PLL ramp setting in SetPllConfiguration() + ESetPllConfigBadDrift, ///< bad PLL drift setting in SetPllConfiguration() + ESetPllConfigBadDivider, ///< bad divider setting in SetPllConfiguration() + ESetPllConfigBadMultiplier, ///< bad divider setting in SetPllConfiguration() + ESetPllLpBadPll, ///< bad PLL ID in SetPllLp() + EGetPllLpBadPll, ///< bad PLL ID in PllLp() + ESetPllLpBadMode, ///< bad PLL LP mode in SetPllLp() + ESetDividerBadClock, ///< bad clock ID in SetDivider() + EGetDividerBadClock, ///< bad clock ID in Divider() + ESetStateBadClock, ///< bad clock ID in SetClockState() + ESetWakeupBadClock, ///< bad clock ID in SetWakeupMode() + ESetPllModeBadClock, + ESetPllModeBadMode, + EGetStateBadClock, ///< bad clock ID in ClockState() + EGetWakeupBadClock, ///< bad clock ID in WakeupMode() + ESetGptClockBadGpt, ///< bad GPT ID in SetGptClockSource() + EGetWakeupGroupBadClock, + EGetWakeupGroupBadGroup, + EAddWakeupGroupBadClock, + EAddWakeupGroupBadGroup, + ERemoveWakeupGroupBadClock, + ERemoveWakeupGroupBadGroup, + EAddDomainBadClock, ///< bad clock in call to AddToWakeupDomain() + ERemoveDomainBadClock, ///< bad clock in call to RemoveFromWakeupDomain() + ECheckDomainBadClock, ///< bad clock in call to IsInWakeupDomain() + EAddDomainBadDomain, ///< bad domain in call to AddToWakeupDomain() + ERemoveDomainBadDomain, ///< bad domain in call to RemoveFromWakeupDomain() + ECheckDomainBadDomain, ///< bad domain in call to IsInWakeupDomain() + ESetDividerUnsupportedClock, ///< attempt to set divider on clock that does not have divider + ESetDividerBadDivider, ///< bad divider value in SetDivider() + EGetNameBadClock, ///< bad clock ID in PrmName() + EClockFrequencyBadClock, ///< bad clock ID in ClockFrequency() + ESetClockMuxBadClock, ///< bad clock ID in SetClockMux() + ESetClockMuxBadSource, ///< bad source clock ID in SetClockMux() + EGetClockMuxBadClock, ///< bad clock ID in ClockMux() + ESetDomainModeBadDomain, ///< bad domain in SetPowerDomainMode() + ESetDomainModeBadMode, ///< bad mode in SetPowerDomainMode() + EGetDomainModeBadDomain, ///< bad domain in PowerDomainMode() + ESetDomainModeUnsupportedMode, ///< mode requested in SetPowerDomainMode() not supported by that domain + EPllIsLockedBadPll, ///< bad PLL ID in PllIsLocked() + EWaitForPllLockBadPll, ///< bad PLL ID in WaitForPllLocked() + ESetPllBypassDividerBadPll, ///< bad PLL ID in SetPllBypassDivider() + EPllBypassDividerBadPll, ///< bad PLL ID in PllBypassDivider() + ESetPllBypassDividerBadDivider, ///< bad dividier value in SetPllBypassDivider() + EPllInternalFrequencyOutOfRange ///< PLL internal frequency out of range in AutoSetPllFrequencyRange() + }; + +enum TClock + { + EClkMpu, ///< DPLL1 + EClkIva2Pll, ///< DPLL2 + EClkCore, ///< DPLL3 + EClkPeriph, ///< DPLL4 + EClkPeriph2, ///< DPLL5 + + EClkPrcmInterface, + + EClkEmu, ///< Emulation clock + EClkNeon, + + EClkL3Domain, + EClkL4Domain, + + EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + EClkRM_F, ///< Reset manager functional clock + EClk96M, ///< 96MHz clock + EClk120M, ///< 120MHz clock + EClkSysOut, + + // Functional clocks + EClkTv_F, ///< TV functional clock, same as 54MHz FCLK + EClkDss1_F, + EClkDss2_F, + EClkCsi2_F, + EClkCam_F, + EClkIva2_F, + EClkMmc1_F, + EClkMmc2_F, + EClkMmc3_F, + EClkMsPro_F, + EClkHdq_F, + EClkMcBsp1_F, + EClkMcBsp2_F, + EClkMcBsp3_F, + EClkMcBsp4_F, + EClkMcBsp5_F, + EClkMcSpi1_F, + EClkMcSpi2_F, + EClkMcSpi3_F, + EClkMcSpi4_F, + EClkI2c1_F, + EClkI2c2_F, + EClkI2c3_F, + EClkUart1_F, + EClkUart2_F, + EClkUart3_F, + EClkGpt1_F, + EClkGpt2_F, + EClkGpt3_F, + EClkGpt4_F, + EClkGpt5_F, + EClkGpt6_F, + EClkGpt7_F, + EClkGpt8_F, + EClkGpt9_F, + EClkGpt10_F, + EClkGpt11_F, + EClkUsbTll_F, + EClkTs_F, + EClkCpeFuse_F, + + EClkSgx_F, + + EClkUsim_F, + EClkSmartReflex2_F, + EClkSmartReflex1_F, + EClkWdt2_F, + EClkWdt3_F, + EClkGpio1_F, + EClkGpio2_F, + EClkGpio3_F, + EClkGpio4_F, + EClkGpio5_F, + EClkGpio6_F, + + EClkUsb120_F, ///< USB host 120MHz functional clock + EClkUsb48_F, ///< USB host 48MHz functional clock + + + // Interface clocks + EClkDss_I, + EClkCam_I, + EClkIcr_I, + EClkMmc1_I, + EClkMmc2_I, + EClkMmc3_I, + EClkMsPro_I, + EClkHdq_I, + EClkAes1_I, + EClkAes2_I, + EClkSha11_I, + EClkSha12_I, + EClkDes1_I, + EClkDes2_I, + EClkMcBsp1_I, + EClkMcBsp2_I, + EClkMcBsp3_I, + EClkMcBsp4_I, + EClkMcBsp5_I, + EClkI2c1_I, + EClkI2c2_I, + EClkI2c3_I, + EClkUart1_I, + EClkUart2_I, + EClkUart3_I, + EClkMcSpi1_I, + EClkMcSpi2_I, + EClkMcSpi3_I, + EClkMcSpi4_I, + EClkGpt1_I, + EClkGpt2_I, + EClkGpt3_I, + EClkGpt4_I, + EClkGpt5_I, + EClkGpt6_I, + EClkGpt7_I, + EClkGpt8_I, + EClkGpt9_I, + EClkGpt10_I, + EClkGpt11_I, + EClkGpt12_I, + EClkMailboxes_I, + EClkOmapSCM_I, + EClkHsUsbOtg_I, + EClkSdrc_I, + EClkPka_I, + EClkRng_I, + EClkUsbTll_I, + + EClkSgx_I, + + EClkUsim_I, + EClkWdt1_I, + EClkWdt2_I, + EClkWdt3_I, + EClkGpio1_I, + EClkGpio2_I, + EClkGpio3_I, + EClkGpio4_I, + EClkGpio5_I, + EClkGpio6_I, + EClk32Sync_I, + + EClkUsb_I, ///< USB host interface clock + + EClk48M, ///< 48MHz clock + EClk12M, ///< 12MHz clock + + // These cannot be modified, they just represent the input clocks + // They must remain last in the table + EClkSysClk, ///< SYSCLK input clock + EClkAltClk, ///< SYSCLK32k input clock + EClkSysClk32k, ///< ALTCLK input clock + + KSupportedClockCount + }; + +enum TInterruptIds + { + EIntWkUp = (EIrqRangeBasePrcm << KIrqRangeIndexShift), + EIntUnused1, + EIntEvGenOn, + EIntEvGenOff, + EIntTransition, + EIntCoreDpll, + EIntPeriphDpll, + EIntMpuDpll, + EIntIvaDpll, + EIntIo, + EIntVp1OpChangeDone, + EIntVp1MinVdd, + EIntVp1MaxVdd, + EIntVp1NoSmpsAck, + EIntVp1EqValue, + EIntVp1TranDone, + EIntVp2OpChangeDone, + EIntVp2MinVdd, + EIntVp2MaxVdd, + EIntVp2NoSmpsAck, + EIntVp2EqValue, + EIntVp2TranDone, + EIntVcSaErr, + EIntVcRaErr, + EIntVcTimeoutErr, + EIntSndPeriphDpll, + + KPrcmLastInterruptPlusOne + }; +const TInt KInterruptCount = KPrcmLastInterruptPlusOne - EIrqRangeBasePrcm; + + +/** GPT reference enumeration */ +enum TGpt + { + EGpt1, + EGpt2, + EGpt3, + EGpt4, + EGpt5, + EGpt6, + EGpt7, + EGpt8, + EGpt9, + EGpt10, + EGpt11, + EGpt12, + + KSupportedGptCount + }; + +/** Enumeration of supported PLLs */ +enum TPll + { + EDpll1, + EDpll2, + EDpll3, + EDpll4, + EDpll5, + + KSupportedPllCount + }; + +enum TGptClockSource + { + EGptClockSysClk, + EGptClock32k + }; + +enum TClockState + { + EClkOff, ///< clock is disabled + EClkOn, ///< clock is enabled + EClkAuto ///< clock is in auto mode (enabled when required) + }; + +enum TWakeupMode + { + EWakeupDisabled, + EWakeupEnabled, + }; + +enum TLpMode + { + ENormalMode, + ELpMode + }; + +enum TPowerSaveMode + { + EPowerSaveOff, + EPowerSaveIdle, + EPowerSaveStandby + }; + +enum TPllMode + { + EPllStop, + EPllBypass, + EPllRun, + EPllFastRelock, + EPllAuto + }; + +enum TBypassDivider + { + EBypassDiv1, + EBypassDiv2, + EBypassDiv4 + }; + +enum TPowerDomainMode + { + EPowerOff, + EPowerRetention, + EPowerReserved, + EPowerOn, + }; + +enum TPowerDomain + { + EPowerDomainMpu, + EPowerDomainIva2, + EPowerDomainNeon, + EPowerDomainCore, + EPowerDomainSgx, + EPowerDomainDss, + EPowerDomainCamera, + EPowerDomainUsb, + EPowerDomainPer, + + KSupportedPowerDomainCount + }; + +enum TWakeupDomain + { + EWakeDomainMpu, + EWakeDomainCore, + EWakeDomainIva2, + EWakeDomainPeripheral, + EWakeDomainDss, + EWakeDomainWakeup, + + KSupportedWakeupDomainCount + }; + +enum TWakeupGroup + { + EWakeGroupMpu, + EWakeGroupIva2, + + KSupportedWakeupGroupCount + }; + +/** Indicates how to handle a request to set a clock frequency */ +enum TClockRoundMode + { + EExactOnly, ///< only set clock if requested frequency can be set exactly + ENearest, ///< always set clock to nearest possible frequency higher or lower than requested + ENearestLower, ///< set to nearest frequency <=requested, fail if no frequency <= requested is possible + ENearestHigher, ///< set to nearest frequency >=requested, fail if no frequency >= requested is possible + }; + +/** Enumeration of valid Pll frequency ranges */ +enum TPllFrequencyRange + { + EPllRange_075_100 = 0x3, ///< 0.75 - 1.0 MHz + EPllRange_100_125 = 0x4, ///< <1.0 MHz - 1.25 MHz + EPllRange_125_150 = 0x5, ///< <1.25 MHz - 1.5 MHz + EPllRange_150_175 = 0x6, ///< <1.5 MHz - 1.75 MHz + EPllRange_175_210 = 0x7, ///< <1.75 MHz - 2.1 MHz + EPllRange_750_1000 = 0xB, ///< <7.5 MHz - 10 MHz + EPllRange_1000_1250 = 0xC, ///< <10 MHz - 12.5 MHz + EPllRange_1250_1500 = 0xD, ///< <12.5 MHz - 15 MHz + EPllRange_1500_1750 = 0xE, ///< <15 MHz - 17.5 MHz + EPllRange_1750_2100 = 0xF ///< <17.5 MHz - 21 MHz + }; + +/** Enumeration of valid PLL ramp settings */ +enum TPllRamp + { + EPllRampDisabled = 0x0, + EPllRamp4us = 0x1, + EPllRam20us = 0x2, + EPllRamp40us = 0x3 + }; + +/** Enumeration of vali PLL driftguard settings */ +enum TPllDrift + { + EPllDriftGuardDisabled, + EPllDriftGuardEnabled + }; + +/** Structure containing configuration for a PLL */ +struct TPllConfiguration + { + TUint iMultiplier; ///< Multiple value + TUint iDivider; ///< Divider value (this is actual divider, hardware is programmed with iDivider-1) + TPllFrequencyRange iFreqRange : 8; + TPllRamp iRamp : 8; + TPllDrift iDrift : 8; + TUint8 __spare; + }; + +/** Enumeration of supported SysClk frequency configurations */ +enum TSysClkFrequency + { + ESysClk12MHz, + ESysClk13MHz, + ESysClk16_8MHz, + ESysClk19_2MHz, + ESysClk26MHz, + ESysClk38_4MHz + }; + +// called during start-up +IMPORT_C void Init3(); // PRCM (disable every peripheral leaving DSS (and UART3 in debug) running) + +IMPORT_C void SetPllConfig( TPll aPll, const TPllConfiguration& aConfig ); +IMPORT_C void PllConfig( TPll aPll, TPllConfiguration& aConfigResult ); + + +/** Configure PLL frequency */ +IMPORT_C void SetPllMode( TPll aPll, TPllMode aPllMode ); + +/** Return PLL frequency configuration */ +IMPORT_C TPllMode PllMode( TPll aPll ); + +/** Test whether a PLL is locked */ +IMPORT_C TBool PllIsLocked( TPll aPll ); + +/** Wait for a PLL to lock */ +IMPORT_C void WaitForPllLock( TPll aPll ); + +/** Calculate the correct FreqRange setting for the given pll + * Updates the iFreqRange parameter of the given TPllConfiguration + */ +IMPORT_C void CalcPllFrequencyRange( TPll aPll, TPllConfiguration& aConfig ); + +/** Enable LP mode on a DLL if it is within LP frequency range */ +IMPORT_C void AutoSetPllLpMode( TPll aPll ); + +/** Enable or disable PLL LP mode */ +IMPORT_C void SetPllLp( TPll aPll, TLpMode aLpMode ); + +/** Get LP mode setting for a PLL */ +IMPORT_C TLpMode PllLp( TPll aPll ); + +/** Set the bypass divider for a PLL */ +IMPORT_C void SetPllBypassDivider( TPll aPll, TBypassDivider aDivider ); + +/** Get the current bypass divider for a PLL */ +IMPORT_C TBypassDivider PllBypassDivider( TPll aPll ); + +/** Set the divider value for the given clock + * aDivider is the required divide value - e.g. to divide by 4 + * aDivider=4. + * + * Note that not all clocks support division by any number, and + * only some clocks have a divider. Attempting to set a divider + * on a clock without a divider will have no effect in UREL and + * will panic in UDEB with ESetDividerUnsupportedClock. + * Attempting to set a divider value not supported by the clock + * will have no effect in UREL and will panic in UDEB with + * ESetDividerBadDivider. + * + * Note 1: for EClkSgx_F the value valued of aDivide are 0, 3, 4, 6. + * 0 sets the clock to be the 96MHz clock + * 3, 4, 6 set it to be CORE_CLK divided by 3, 4, or 6 + * + * Note 2: you cannot use this function to set EClkUsim_F, use + * SetUsimClockDivider(). + */ +IMPORT_C void SetDivider( TClock aClock, TUint aDivide ); + +/** Get the current divider value of the given clock */ +IMPORT_C TUint Divider( TClock aClock ); + +//IMPORT_C void SetUsimClockDivider( TUint TUsimDivideMode aMode ); +//IMPORT_C TUsimDivideMode UsimClockDivider(); + +/** Controls power to a power domain */ +IMPORT_C void SetPowerDomainMode( TPowerDomain aDomain, TPowerDomainMode aMode ); + +/** Gets the current mode of a power domain power control */ +IMPORT_C TPowerDomainMode PowerDomainMode( TPowerDomain aDomain ); + +//IMPORT_C void SetPowerSaveMode( TClock aClock, TPowerSaveMode aMode ); +//IMPORT_C TPowerSaveMode PowerSaveMode( TClock aClock ); + +//IMPORT_C TBool DomainClockActive( TClock aClock ); + +// Set clock enable/disable +/** Set the clock state of a given clock */ +IMPORT_C void SetClockState( TClock aClock, TClockState aState ); + +/** Get the configured clock state of a given clock */ +IMPORT_C TClockState ClockState( TClock aClock ); + +// Configure wakeup mode for clocks +/** Configure wakeup mode for a clock + * Note - for peripheral blocks with an interface and functional clock, it is + * the interface clock which is configured for wakeup. Attempting to configure + * wakeup on the functional clock has no effect + */ +IMPORT_C void SetWakeupMode( TClock aClock, TWakeupMode aMode ); + +/** Get configured wakeup mode for a clock */ +IMPORT_C TWakeupMode WakeupMode( TClock aClock ); + +/** Add a peripheral interface clock to the specified wakeup group */ +IMPORT_C void AddToWakeupGroup( TClock aClock, TWakeupGroup aGroup ); + +/** Remove a peripheral interface clock from the specified wakeup group */ +IMPORT_C void RemoveFromWakeupGroup( TClock aClock, TWakeupGroup aGroup ); + +/** Test whether a peripheral interface clock is in the specified wakeup group */ +IMPORT_C TBool IsInWakeupGroup( TClock aClock, TWakeupGroup aGroup ); + +/** Add a clock to the given wakeup domain */ +IMPORT_C void AddToWakeupDomain( TClock aClock, TWakeupDomain aDomain ); + +/** Remove a clock from the given wakeup domain */ +IMPORT_C void RemoveFromWakeupDomain( TClock aClock, TWakeupDomain aDomain ); + +/** Test whether a clock is in the specified wakeup domain */ +IMPORT_C TBool IsInWakeupDomain( TClock aClock, TWakeupDomain aDomain ); + + +// Functions for configuring clock sources + +/** Set the clock source for a GPT timer */ +IMPORT_C void SetGptClockSource( TGpt aGpt, TGptClockSource aSource ); + +/** Get the current clock source of a GPT */ +IMPORT_C TGptClockSource GptClockSource( TGpt aGpt ); + +/** Get the USIM divider factor */ +IMPORT_C TUint UsimDivider(); + +/** Get the USIM source clock */ +IMPORT_C TClock UsimClockSource(); + +/** Sets the current input clock into the clock mux for the specified clock + * aClock must refer to a clock that has a mux for selecting input clock + * and aSource must be a possible input clock for aClock + */ +IMPORT_C void SetClockMux( TClock aClock, TClock aSource ); + + +/** Gets the current input clock into the clock mux for the specified clock + * aClock must refer to a clock that has a mux for selecting input clock + */ +IMPORT_C TClock ClockMux( TClock aClock ); + +/** Get the currently configured frequency of the specified clock + * Note that this is regardless of whether the clock is currently running. + * That is, if a clock is configured to run at 8MHz, then this function + * will return 8000000 whether the clock is currently enabled or disabled. + * + * @param aClock clock required + * @return Frequency in Hz + */ +IMPORT_C TUint ClockFrequency( TClock aClock ); + +/** Set the correct SysClock frequency */ +IMPORT_C void SetSysClkFrequency( TSysClkFrequency aFrequency ); + +/** Get the currently configured SysClk frequency */ +IMPORT_C TSysClkFrequency SysClkFrequency(); + +/** Function to get the name to be passed to the Power Resource Manager + * to refer to the given clock source + */ +IMPORT_C const TDesC& PrmName( TClock aClock ); + +} + +#endif // !defined PRCM_H__ diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/prcm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/prcm.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,3291 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// \omap3530\omap3530_assp\prcm.cpp +// Access to PRCM. And implimentation of device driver's power and clock control API +// This file is part of the Beagle Base port +// + +#include +#include +#include +#include +#include +#include +#include + +#include "prcm_regs.h" + +// Dummy location for redirecting writes which have no effect on a particular clock +// More efficient than having to test for it in code +TUint32 __dummypoke; +#define KDummy (TUint32)&__dummypoke + +namespace +{ + +// PLL modes +const TUint32 KPllModeStop = 0x1; +const TUint32 KPllModeBypass = 0x5; +const TUint32 KPllModeFastRelock = 0x6; +const TUint32 KPllModeLock = 0x7; +const TUint32 KPllModeMask = 0x7; +const TUint32 KPllAutoOff = 0x0; +const TUint32 KPllAutoOn = 0x1; +const TUint32 KPllAutoMask = 0x7; + +#ifdef _DEBUG // to stop warings about unused definitions +const TUint KPllMaximumDivider = 127; +const TUint KPllMaximumMultiplier = 2047; +#endif +const TUint KPllDividerMask = 127; +const TUint KPllMultiplierMask = 2047; +const TUint KPllFreqRangeMask = 15; +const TUint KPllRampMask = 3; + +const TUint KPllLpModeMaximumFrequency = 600000000; + +// TPll to TClock lookup table +static const Prcm::TClock KPllToClock [] = + { + Prcm::EClkMpu, + Prcm::EClkIva2Pll, + Prcm::EClkCore, + Prcm::EClkPeriph, + Prcm::EClkPeriph2 + }; + +// struct of info on how to configure each PLL +// this doesn't include settings which are the same for all PLLs +struct TPllControlInfo + { + TUint32 iConfigRegister; // register containing configuration settings + TUint32 iMulDivRegister; // register containing multiplier and divider setting + TUint32 iStatusRegister; // register containing PLL status + TUint iMultShift; // shift to move multiplier into position + TUint iDivShift; // shift to move divider into position + TUint iFreqSelShift; // shift to move frequency range selection into position + TUint iRampShift; // shift to move ramp bits into position + TUint iDriftShift; // shift to move driftsel into position + TUint iLpShift; // shift to move LP bit into position + TUint iLockBit; // bit number of lock flag in iStatusRegister + }; + +static const TPllControlInfo KPllControlInfo[ Prcm::KSupportedPllCount ] = + { + // ConfReg MulDivReg StatusReg MulShift DivShift FreqShift RampShift DriftShift LpShift LockBit + { KCM_CLKEN_PLL_MPU, KCM_CLKSEL1_PLL_MPU, KCM_IDLEST_PLL_MPU, 8, 0, 4, 8, 3, 10, 0 }, // DPLL1 (mpu) + { KCM_CLKEN_PLL_IVA2, KCM_CLKSEL1_PLL_IVA2, KCM_IDLEST_PLL_IVA2, 8, 0, 4, 8, 3, 10, 0 }, // DPLL2 (iva2) + { KCM_CLKEN_PLL, KCM_CLKSEL1_PLL, KCM_IDLEST_CKGEN, 16, 8, 4, 8, 3, 10, 0 }, // DPLL3 (core) + { KCM_CLKEN_PLL, KCM_CLKSEL2_PLL, KCM_IDLEST_CKGEN, 8, 0, 20, 24, 19, 26, 1 }, // DPLL4 (periph) + { KCM_CLKEN2_PLL, KCM_CLKSEL4_PLL, KCM_IDLEST2_CKGEN, 8, 0, 4, 8, 3, 10, 0 } // DPLL5 (periph2) + }; +__ASSERT_COMPILE( (sizeof(KPllControlInfo) / sizeof( KPllControlInfo[0] )) == Prcm::KSupportedPllCount ); + +struct TPllModeInfo + { + TUint32 iModeRegister; + TUint32 iAutoRegister; + TUint8 iModeShift; + TUint8 iAutoShift; + TUint8 _spare[2]; + }; + +static const TPllModeInfo KPllMode[] = + { + // iModeRegister iAutoRegister iModeShift iAutoShift + { KCM_CLKEN_PLL_MPU, KCM_AUTOIDLE_PLL_MPU, 0, 0 }, + { KCM_CLKEN_PLL_IVA2, KCM_AUTOIDLE_PLL_IVA2, 0, 0 }, + { KCM_CLKEN_PLL, KCM_AUTOIDLE_PLL, 0, 0 }, + { KCM_CLKEN_PLL, KCM_AUTOIDLE_PLL, 16, 3 }, + { KCM_CLKEN2_PLL, KCM_AUTOIDLE2_PLL, 0, 3 } + }; +__ASSERT_COMPILE( (sizeof(KPllMode) / sizeof( KPllMode[0] )) == Prcm::KSupportedPllCount ); + + +// All dividers in the PRCM fall into one of these classes +// Some are unique to a particular peripheral but some +// are used by multiple peripherals so we can share that implementation +enum TDivType + { + EDivNotSupported, + EDiv_1_2, + EDivCore_1_2_4, + EDivCore_3_4_6_96M, + EDivPll_1_To_16, + EDivPll_1_To_31, + EDivUsimClk, + EDivClkOut_1_2_4_8_16, + }; + +struct TDividerInfo + { + TUint32 iRegister; + TUint32 iMask; // mask of bits to modify in register + TDivType iDivType : 8; + TUint8 iShift; // number of bits to shift to move divide value into position + }; + +static const TDividerInfo KDividerInfo[] = + { + { KCM_CLKSEL2_PLL_MPU, 0x1F, EDivPll_1_To_16, 0 }, // EClkMpu, ///< DPLL1 + { KCM_CLKSEL2_PLL_IVA2, 0x1F, EDivPll_1_To_16, 0 }, + { KCM_CLKSEL1_PLL, 0x1FU << 27, EDivPll_1_To_31, 27 }, // EClkCore, ///< DPLL3 + { KDummy, 0, EDivNotSupported, 0 }, // EClkPeriph, ///< DPLL4 + { KDummy, 0, EDivNotSupported, 0 }, // EClkPeriph2, ///< DPLL5 + + { KDummy, 0, EDivNotSupported, 0 }, // EClkPrcmInterface, + + { KDummy, 0, EDivNotSupported, 0 }, // EClkEmu, ///< Emulation clock + { KDummy, 0, EDivNotSupported, 0 }, // EClkNeon, + + { KCM_CLKSEL_CORE, KBit0 | KBit1, EDiv_1_2, 0 }, // EClkL3Domain, + { KCM_CLKSEL_CORE, KBit2 | KBit3, EDiv_1_2, 2 }, // EClkL4Domain, + + { KCM_CLKSEL1_PLL_MPU, KBit19 | KBit20 | KBit21, EDivCore_1_2_4, 19 }, // EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + { KCM_CLKSEL1_PLL_IVA2, KBit19 | KBit20 | KBit21, EDivCore_1_2_4, 19 }, // EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + { KCM_CLKSEL_WKUP, KBit1 | KBit2, EDiv_1_2, 1 }, // EClkRM_F, ///< Reset manager functional clock + { KCM_CLKSEL3_PLL, 0x1F, EDivPll_1_To_16, 0 }, // EClk96M ///< 96MHz clock + { KCM_CLKSEL5_PLL, 0x1F, EDivPll_1_To_16, 0 }, // EClk120M ///< 120MHz clock + { KCM_CLKOUT_CTRL, KBit3 | KBit4 | KBit5, EDivClkOut_1_2_4_8_16, 3 }, // EClkSysOut + + // Functional clocks + { KCM_CLKSEL_DSS, 0x1FU << 8, EDivPll_1_To_16, 8 }, // EClkTv_F, + { KCM_CLKSEL_DSS, 0x1F, EDivPll_1_To_16, 0 }, // EClkDss1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkDss2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkCsi2_F, + { KCM_CLKSEL_CAM, 0x1F, EDivPll_1_To_16, 0 }, // EClkCam_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkIva2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMsPro_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkHdq_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp4_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp5_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi4_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt4_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt5_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt6_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt7_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt8_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt9_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt10_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt11_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsbTll_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkTs_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkCpeFuse_F, + + { KCM_CLKSEL_SGX, KBit0 | KBit1 | KBit2, EDivCore_3_4_6_96M, 0 }, // EClkSgx_F, + + { KCM_CLKSEL_WKUP, KBit3 | KBit4 | KBit5 | KBit6, EDivUsimClk, 3 }, // EClkUsim_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSmartReflex2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSmartReflex1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkWdt2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkWdt3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio1_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio2_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio3_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio4_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio5_F, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio6_F, + + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsb120_F, ///< USB host 120MHz functional clock + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsb48_F, ///< USB host 48MHz functional clock + + + // Interface clocks + { KDummy, 0, EDivNotSupported, 0 }, // EClkDss_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkCam_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkIcr_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMmc3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMsPro_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkHdq_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkAes1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkAes2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSha11_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSha12_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkDes1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkDes2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp4_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcBsp5_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkI2c3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUart3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMcSpi4_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt4_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt5_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt6_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt7_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt8_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt9_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt10_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt11_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpt12_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkMailboxes_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkOmapSCM_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkHsUsbOtg_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSdrc_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkPka_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkRng_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsbTll_I, + + { KDummy, 0, EDivNotSupported, 0 }, // EClkSgx_I, + + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsim_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkWdt1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkWdt2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkWdt3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio1_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio2_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio3_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio4_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio5_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClkGpio6_I, + { KDummy, 0, EDivNotSupported, 0 }, // EClk32Sync_I, + + { KDummy, 0, EDivNotSupported, 0 }, // EClkUsb_I, ///< USB host interface clock + + { KDummy, 0, EDivNotSupported, 0 }, // EClk48M + { KDummy, 0, EDivNotSupported, 0 }, // EClk12M + + { KDummy, 0, EDivNotSupported, 0 }, // EClkSysClk, + { KDummy, 0, EDivNotSupported, 0 }, // EClkAltClk, + { KDummy, 0, EDivNotSupported, 0 }, // EClkSysClk32k, + }; +__ASSERT_COMPILE( (sizeof(KDividerInfo) / sizeof( KDividerInfo[0] )) == Prcm::KSupportedClockCount ); + +// Special case divider and mux info for USIM +struct TUsimDivMuxInfo + { + Prcm::TClock iClock : 8; // source clock + TUint8 iDivider; // divider factor + }; +static const TUsimDivMuxInfo UsimDivMuxInfo[16] = + { + { Prcm::EClkSysClk, 1 }, // 0x0 + { Prcm::EClkSysClk, 1 }, // 0x1 + { Prcm::EClkSysClk, 2 }, // 0x2 + { Prcm::EClk96M, 2 }, // 0x3 + { Prcm::EClk96M, 4 }, // 0x4 + { Prcm::EClk96M, 8 }, // 0x5 + { Prcm::EClk96M, 10 }, // 0x6 + { Prcm::EClk120M, 4 }, // 0x7 + { Prcm::EClk120M, 8 }, // 0x8 + { Prcm::EClk120M, 16 }, // 0x9 + { Prcm::EClk120M, 20 }, // 0xA + { Prcm::EClkSysClk, 1 }, // 0xB + { Prcm::EClkSysClk, 1 }, // 0xC + { Prcm::EClkSysClk, 1 }, // 0xD + { Prcm::EClkSysClk, 1 }, // 0xE + { Prcm::EClkSysClk, 1 } // 0xF + }; + +// Structure representing a register, mask and enable/disable values +struct TRegisterBitDef + { + TUint32 iRegister; + TUint32 iMask; + TUint32 iEnablePattern; + TUint32 iDisablePattern; + }; + +// Structure for holding information on clock enable and auto mode +struct TClockEnableAutoInfo + { + TRegisterBitDef iGate; + TRegisterBitDef iAuto; + }; + +const TUint32 KDummyReadAsDisabled = 1; +const TUint32 KDummyReadAsEnabled = 0; +const TUint32 KBit012 = KBit0 | KBit1 | KBit2; +const TUint32 KBit345 = KBit3 | KBit4 | KBit5; +const TUint32 KBit16_17_18 = KBit16 | KBit17 | KBit18; + +// Table of bits to set to enable each clock +// Note where a function doesn't exist, use { KDummy, 0, V, 0 } which will cause a write to harmlessly write +// to __dummypoke and a read to find that the item is disabled if V==KDummyReadAsDisabled and enabled if V=KDummyReadAsEnabled +static const TClockEnableAutoInfo KClockControlTable[] = + { + { { KDummy, 0, 0, 0 }, { KCM_AUTOIDLE_PLL_MPU, KBit012, 1, 0 } }, // EClkMpu, + { { KCM_CLKEN_PLL_IVA2, KBit012, 7, 1 }, { KCM_AUTOIDLE_PLL_IVA2, KBit0, 1, 0 } }, // EClkIva2Pll, + { { KCM_CLKEN_PLL, KBit012, 0x7, 0x5 }, { KCM_AUTOIDLE_PLL, KBit012, 1, 0 } }, // EClkCore, ///< DPLL3 + { { KCM_CLKEN_PLL, KBit16_17_18, KBit16_17_18, KBit16 }, { KCM_AUTOIDLE_PLL, KBit345, KBit3, 0 } }, // EClkPeriph, ///< DPLL4 + { { KCM_CLKEN2_PLL, KBit012, 0x7, 0x1 }, { KCM_AUTOIDLE2_PLL, KBit012, 1, 0 } }, // EClkPeriph2, ///< DPLL5 + + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkPrcmInterface, + { { KDummy, 0, 0, 0 }, { KCM_CLKSTCTRL_EMU, KBit0 | KBit1, 3, 2 } }, // EClkEmu, ///< Emulation clock + { { KCM_IDLEST_NEON, KBit0, 0, 1 }, { KCM_CLKSTCTRL_NEON, KBit0 | KBit1, 3, 2 } }, // EClkNeon, + + { { KDummy, 0, 0, 0 }, { KCM_CLKSTCTRL_CORE, KBit0 | KBit1, KBit0 | KBit1, 0 } }, // EClkL3Domain, + { { KDummy, 0, 0, 0 }, { KCM_CLKSTCTRL_CORE, KBit2 | KBit3, KBit2 | KBit3, 0 } }, // EClkL4Domain, + + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkRM_F, ///< Reset manager functional clock + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClk96M, ///< 96MHz clock + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClk120M, ///< 120MHz clock + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSysOut, + + // Functional clocks + { { KCM_FCLKEN_DSS, KBit2, KBit2, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkTv_F, + { { KCM_FCLKEN_DSS, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDss1_F, + { { KCM_FCLKEN_DSS, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDss2_F, + { { KCM_FCLKEN_CAM, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCsi2_F, + { { KCM_FCLKEN_CAM, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCam_F, + { { KCM_FCLKEN_IVA2, KBit0, KBit0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkIva2_F, + { { KCM_FCLKEN1_CORE, KBit24, KBit24, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc1_F, + { { KCM_FCLKEN1_CORE, KBit25, KBit25, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc2_F, + { { KCM_FCLKEN1_CORE, KBit30, KBit30, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc3_F, + { { KCM_FCLKEN1_CORE, KBit23, KBit23, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMsPro_F, + { { KCM_FCLKEN1_CORE, KBit22, KBit22, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkHdq_F, + { { KCM_FCLKEN1_CORE, KBit9, KBit9, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBSP1_F, + { { KCM_FCLKEN_PER, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBSP2_F, + { { KCM_FCLKEN_PER, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBSP3_F, + { { KCM_FCLKEN_PER, KBit2, KBit2, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBSP4_F, + { { KCM_FCLKEN1_CORE, KBit10, KBit10, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBSP5_F, + { { KCM_FCLKEN1_CORE, KBit18, KBit18, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi1_F, + { { KCM_FCLKEN1_CORE, KBit19, KBit19, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi2_F, + { { KCM_FCLKEN1_CORE, KBit20, KBit20, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi3_F, + { { KCM_FCLKEN1_CORE, KBit21, KBit21, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi4_F, + { { KCM_FCLKEN1_CORE, KBit15, KBit15, 0}, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c1_F, + { { KCM_FCLKEN1_CORE, KBit16, KBit16, 0}, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c2_F, + { { KCM_FCLKEN1_CORE, KBit17, KBit17, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c3_F, + { { KCM_FCLKEN1_CORE, KBit13, KBit13, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart1_F, + { { KCM_FCLKEN1_CORE, KBit14, KBit14, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart2_F, + { { KCM_FCLKEN_PER, KBit11, KBit11, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart3_F, + { { KCM_FCLKEN_WKUP, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt1_F, + { { KCM_FCLKEN_PER, KBit3, KBit3, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt2_F, + { { KCM_FCLKEN_PER, KBit4, KBit4, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt3_F, + { { KCM_FCLKEN_PER, KBit5, KBit5, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt4_F, + { { KCM_FCLKEN_PER, KBit6, KBit6, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt5_F, + { { KCM_FCLKEN_PER, KBit7, KBit7, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt6_F, + { { KCM_FCLKEN_PER, KBit8, KBit8, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt7_F, + { { KCM_FCLKEN_PER, KBit9, KBit9, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt8_F, + { { KCM_FCLKEN_PER, KBit10, KBit10, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt9_F, + { { KCM_FCLKEN1_CORE, KBit11, KBit11, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt10_F, + { { KCM_FCLKEN1_CORE, KBit12, KBit12, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt11_F, + { { KCM_FCLKEN3_CORE, KBit2, KBit2, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsbTll_F, + { { KCM_FCLKEN3_CORE, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkTs_F, + { { KCM_FCLKEN3_CORE, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCpeFuse_F, + + { { KCM_FCLKEN_SGX, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSgx_F, + + { { KCM_FCLKEN_WKUP, KBit9, KBit9, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsim_F, + { { KCM_FCLKEN_WKUP, KBit7, KBit7, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSmartReflex2_F, + { { KCM_FCLKEN_WKUP, KBit6, KBit6, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSmartReflex1_F, + { { KCM_FCLKEN_WKUP, KBit5, KBit5, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt2_F, + { { KCM_FCLKEN_PER, KBit12, KBit12, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt3_F, + { { KCM_FCLKEN_WKUP, KBit3, KBit3, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio1_F, + { { KCM_FCLKEN_PER, KBit13, KBit13, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio2_F, + { { KCM_FCLKEN_PER, KBit14, KBit14, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio3_F, + { { KCM_FCLKEN_PER, KBit15, KBit15, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio4_F, + { { KCM_FCLKEN_PER, KBit16, KBit16, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio5_F, + { { KCM_FCLKEN_PER, KBit17, KBit17, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio6_F, + + { { KCM_FCLKEN_USBHOST, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsb120_F, + { { KCM_FCLKEN_USBHOST, KBit0, KBit0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsb48_F, + + + // Interface clocks + { { KCM_ICLKEN_DSS, KBit0, KBit0, 0 }, { KCM_AUTOIDLE_DSS, KBit0, KBit0, 0 } }, // EClkDss_I, + { { KCM_ICLKEN_CAM, KBit0,KBit0, 0 }, { KCM_AUTOIDLE_CAM, KBit0, KBit0, 0 } }, // EClkCam_I, + { { KCM_ICLKEN1_CORE, KBit29, KBit29, 0 }, { KCM_AUTOIDLE1_CORE, KBit29, KBit29, 0 } }, // EClkIcr_I, + { { KCM_ICLKEN1_CORE, KBit24, KBit24, 0 }, { KCM_AUTOIDLE1_CORE, KBit24, KBit24, 0 } }, // EClkMmc1_I, + { { KCM_ICLKEN1_CORE, KBit25, KBit25, 0 }, { KCM_AUTOIDLE1_CORE, KBit25, KBit25, 0 } }, // EClkMmc2_I, + { { KCM_ICLKEN1_CORE, KBit30, KBit30, 0 }, { KCM_AUTOIDLE1_CORE, KBit30, KBit30, 0 } }, // EClkMmc3_I, + { { KCM_ICLKEN1_CORE, KBit23, KBit23, 0 }, { KCM_AUTOIDLE1_CORE, KBit23, KBit23, 0 } }, // EClkMsPro_I, + { { KCM_ICLKEN1_CORE, KBit22, KBit22, 0 }, { KCM_AUTOIDLE1_CORE, KBit22, KBit22, 0 } }, // EClkHdq_I, + { { KCM_ICLKEN2_CORE, KBit3, KBit3, 0 }, { KCM_AUTOIDLE2_CORE, KBit3, KBit3, 0 } }, // EClkAes1_I, + { { KCM_ICLKEN1_CORE, KBit28, KBit28, 0 }, { KCM_AUTOIDLE1_CORE, KBit28, KBit28, 0 } }, // EClkAes2_I, + { { KCM_ICLKEN2_CORE, KBit1, KBit1, 0 }, { KCM_AUTOIDLE2_CORE, KBit1, KBit1, 0 } }, // EClkSha11_I, + { { KCM_ICLKEN1_CORE, KBit28, KBit27, 0 }, { KCM_AUTOIDLE1_CORE, KBit27, KBit27, 0 } }, // EClkSha12_I, + { { KCM_ICLKEN2_CORE, KBit0, KBit0, 0 }, { KCM_AUTOIDLE2_CORE, KBit0, KBit0, 0 } }, // EClkDes1_I, + { { KCM_ICLKEN1_CORE, KBit26, KBit26, 0 }, { KCM_AUTOIDLE1_CORE, KBit26, KBit26, 0 } }, // EClkDes2_I, + { { KCM_ICLKEN1_CORE, KBit9, KBit9, 0 }, { KCM_AUTOIDLE1_CORE, KBit9, KBit9, 0 } }, // EClkMcBSP1_I, + { { KCM_ICLKEN_PER, KBit0, KBit0, 0}, { KCM_AUTOIDLE_PER, KBit0, KBit0, 0 } }, // EClkMcBSP2_I, + { { KCM_ICLKEN_PER, KBit1, KBit1, 0 }, { KCM_AUTOIDLE_PER, KBit1, KBit1, 0 } }, // EClkMcBSP3_I, + { { KCM_ICLKEN_PER, KBit2, KBit2, 0 }, { KCM_AUTOIDLE_PER, KBit2, KBit2, 0 } }, // EClkMcBSP4_I, + { { KCM_ICLKEN1_CORE, KBit10, KBit10, 0 }, { KCM_AUTOIDLE1_CORE, KBit10, KBit10, 0 } }, // EClkMcBSP5_I, + { { KCM_ICLKEN1_CORE, KBit15, KBit15, 0 }, { KCM_AUTOIDLE1_CORE, KBit15, KBit15, 0 } }, // EClkI2c1_I, + { { KCM_ICLKEN1_CORE, KBit16, KBit16, 0 }, { KCM_AUTOIDLE1_CORE, KBit16, KBit16, 0 } }, // EClkI2c2_I, + { { KCM_ICLKEN1_CORE, KBit17, KBit17, 0 }, { KCM_AUTOIDLE1_CORE, KBit17, KBit17, 0 } }, // EClkI2c3_I, + { { KCM_ICLKEN1_CORE, KBit13, KBit13, 0 }, { KCM_AUTOIDLE1_CORE, KBit13, KBit13, 0 } }, // EClkUart1_I, + { { KCM_ICLKEN1_CORE, KBit14, KBit14, 0 }, { KCM_AUTOIDLE1_CORE, KBit14, KBit14, 0 } }, // EClkUart2_I, + { { KCM_ICLKEN_PER, KBit11, KBit11, 0 }, { KCM_AUTOIDLE_PER, KBit11, KBit11, 0 } }, // EClkUart3_I, + { { KCM_ICLKEN1_CORE, KBit18, KBit18, 0 }, { KCM_AUTOIDLE1_CORE, KBit18, KBit18, 0 } }, // EClkMcSpi1_I, + { { KCM_ICLKEN1_CORE, KBit19, KBit19, 0 }, { KCM_AUTOIDLE1_CORE, KBit19, KBit19, 0 } }, // EClkMcSpi2_I, + { { KCM_ICLKEN1_CORE, KBit20, KBit20, 0 }, { KCM_AUTOIDLE1_CORE, KBit20, KBit20, 0 } }, // EClkMcSpi3_I, + { { KCM_ICLKEN1_CORE, KBit21, KBit21, 0 }, { KCM_AUTOIDLE1_CORE, KBit21, KBit21, 0 } }, // EClkMcSpi4_I, + { { KCM_ICLKEN_WKUP, KBit0, KBit0, 0 }, { KCM_AUTOIDLE_WKUP, KBit0, KBit0, 0 } }, // EClkGpt1_I, + { { KCM_ICLKEN_PER, KBit3, KBit3, 0 }, { KCM_AUTOIDLE_PER, KBit3, KBit3, 0 } }, // EClkGpt2_I, + { { KCM_ICLKEN_PER, KBit4, KBit4, 0 }, { KCM_AUTOIDLE_PER, KBit4, KBit4, 0 } }, // EClkGpt3_I, + { { KCM_ICLKEN_PER, KBit5, KBit5, 0 }, { KCM_AUTOIDLE_PER, KBit5, KBit5, 0 } }, // EClkGpt4_I, + { { KCM_ICLKEN_PER, KBit6, KBit6, 0 }, { KCM_AUTOIDLE_PER, KBit6, KBit6, 0 } }, // EClkGpt5_I, + { { KCM_ICLKEN_PER, KBit7, KBit7, 0 }, { KCM_AUTOIDLE_PER, KBit7, KBit7, 0 } }, // EClkGpt6_I, + { { KCM_ICLKEN_PER, KBit8, KBit8, 0 }, { KCM_AUTOIDLE_PER, KBit8, KBit8, 0 } }, // EClkGpt7_I, + { { KCM_ICLKEN_PER, KBit9, KBit9, 0 }, { KCM_AUTOIDLE_PER, KBit9, KBit9, 0 } }, // EClkGpt8_I, + { { KCM_ICLKEN_PER, KBit10, KBit10, 0 }, { KCM_AUTOIDLE_PER, KBit10, KBit10, 0 } }, // EClkGpt9_I, + { { KCM_ICLKEN1_CORE, KBit11, KBit11, 0 }, { KCM_AUTOIDLE1_CORE, KBit11, KBit11, 0 } }, // EClkGpt10_I, + { { KCM_ICLKEN1_CORE, KBit12, KBit12, 0 }, { KCM_AUTOIDLE1_CORE, KBit12, KBit12, 0 } }, // EClkGpt11_I, + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt12_I, + { { KCM_ICLKEN1_CORE, KBit7, KBit7, 0 }, { KCM_AUTOIDLE1_CORE, KBit7, KBit7, 0 } }, // EClkMailboxes_I, + { { KCM_ICLKEN1_CORE, KBit6, KBit6, 0 }, { KCM_AUTOIDLE1_CORE, KBit6, KBit6, 0 } }, // EClkOmapSCM_I, + { { KCM_ICLKEN1_CORE, KBit4, KBit4, 0 }, { KCM_AUTOIDLE1_CORE, KBit4, KBit4, 0 } }, // EClkHsUsbOtg_I, + { { KCM_ICLKEN1_CORE, KBit1, KBit1, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSdrc_I, + { { KCM_ICLKEN2_CORE, KBit4, KBit4, 0 }, { KCM_AUTOIDLE2_CORE, KBit4, KBit4, 0 } }, // EClkPka_I, + { { KCM_ICLKEN2_CORE, KBit2, KBit2, 0 }, { KCM_AUTOIDLE2_CORE, KBit2, KBit2, 0 } }, // EClkRng_I, + { { KCM_ICLKEN3_CORE, KBit2, KBit2, 0 }, { KCM_AUTOIDLE3_CORE, KBit2, KBit2, 0 } }, // EClkUsbTll_I, + + { { KCM_ICLKEN_SGX, KBit0, KBit0, 0 }, { KCM_CLKSTCTRL_SGX, KBit0 | KBit1, 0x3, 0x0 } }, // EClkSgx_I, + + { { KCM_ICLKEN_WKUP, KBit9, KBit9, 0 }, { KCM_AUTOIDLE_WKUP, KBit9, KBit9, 0 } }, // EClkUsim_I, + { { KCM_ICLKEN_WKUP, KBit4, KBit4, 0 }, { KCM_AUTOIDLE_WKUP, KBit4, KBit4, 0 } }, // EClkWdt1_I, + { { KCM_ICLKEN_WKUP, KBit5, KBit5, 0 }, { KCM_AUTOIDLE_WKUP, KBit5, KBit5, 0 } }, // EClkWdt2_I, + { { KCM_ICLKEN_PER, KBit12, KBit12, 0 }, { KCM_AUTOIDLE_PER, KBit12, KBit12, 0 } }, // EClkWdt3_I, + { { KCM_ICLKEN_WKUP, KBit3, KBit3, 0 }, { KCM_AUTOIDLE_WKUP, KBit3, KBit3, 0 } }, // EClkGpio1_I, + { { KCM_ICLKEN_PER, KBit13, KBit13, 0 }, { KCM_AUTOIDLE_PER, KBit13, KBit13, 0 } }, // EClkGpio2_I, + { { KCM_ICLKEN_PER, KBit14, KBit14, 0 }, { KCM_AUTOIDLE_PER, KBit14, KBit14, 0 } }, // EClkGpio3_I, + { { KCM_ICLKEN_PER, KBit15, KBit15, 0 }, { KCM_AUTOIDLE_PER, KBit15, KBit15, 0 } }, // EClkGpio4_I, + { { KCM_ICLKEN_PER, KBit16, KBit16, 0 }, { KCM_AUTOIDLE_PER, KBit16, KBit16, 0 } }, // EClkGpio5_I, + { { KCM_ICLKEN_PER, KBit17, KBit17, 0 }, { KCM_AUTOIDLE_PER, KBit17, KBit17, 0 } }, // EClkGpio6_I, + { { KCM_ICLKEN_WKUP, KBit2, KBit2, 0 }, { KCM_AUTOIDLE_WKUP, KBit2, KBit2, 0 } }, // EClk32Sync_I, + + { { KCM_ICLKEN_USBHOST, KBit0, KBit0, 0 }, { KCM_AUTOIDLE_USBHOST, KBit0, KBit0, 0 } }, // EClkUsb_I, ///< USB host interface clock + + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClk48M + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClk12M + + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkSysClk + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkAltClk + { { KDummy, 0, 0, 0 }, { KDummy, 0, KDummyReadAsEnabled, 0 } }, // EClkSysClk32k + }; +__ASSERT_COMPILE( (sizeof(KClockControlTable) / sizeof( KClockControlTable[0] )) == Prcm::KSupportedClockCount ); + +static const TRegisterBitDef KClockWakeupTable[] = + { + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMpu, ///< DPLL1 + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkIva2Pll, ///< DPLL2 + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkCore, ///< DPLL3 + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkPeriph, ///< DPLL4 + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkPeriph2, ///< DPLL5 + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkPrcmInterface, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkEmu, ///< Emulation clock + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkNeon, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkL3Domain, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkL4Domain, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkRM_F, ///< Reset manager functional clock + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClk96M, ///< 96MHz clock + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClk120M, ///< 120MHz clock + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSysOut, + + // Functional clocks + // NOTE - functional clocks aren't mapped to a wakeup event, these just clock the internals + // Use the interface clocks to register a wakeup + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkTv_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkDss1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkDss2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkCsi2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkCam_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkIva2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMmc1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMmc2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMmc3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMsPro_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkHdq_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcBSP1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcBSP2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcBSP3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcBSP4_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcBSP5_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcSpi1_F + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcSpi2_F + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcSpi3_F + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMcSpi4_F + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkI2c1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkI2c2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkI2c3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUart1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUart2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUart3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt4_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt5_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt6_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt7_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt8_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt9_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt10_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpt11_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUsbTll_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkTs_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkCpeFuse_F, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSgx_F, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUsim_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSmartReflex2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSmartReflex1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkWdt2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkWdt3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio1_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio2_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio3_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio4_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio5_F, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkGpio6_F, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUsb120_F, ///< USB host 120MHz functional clock + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkUsb48_F, ///< USB host 48MHz functional clock + + + // Interface clocks + { KPM_WKEN_DSS, KBit0, KBit0, 0 }, // EClkDss_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkCam_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkIcr_I, + { KPM_WKEN1_CORE, KBit24, KBit24, 0 }, // EClkMmc1_I, + { KPM_WKEN1_CORE, KBit25, KBit25, 0 }, // EClkMmc2_I, + { KPM_WKEN1_CORE, KBit30, KBit30, 0 }, // EClkMmc3_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMsPro_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkHdq_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkAes1_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkAes2_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSha11_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSha12_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkDes1_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkDes2_I, + { KPM_WKEN1_CORE, KBit9, KBit9, 0 }, // EClkMcBSP1_I, + { KPM_WKEN_PER, KBit0, KBit0, 0 }, // EClkMcBSP2_I, + { KPM_WKEN_PER, KBit1, KBit1, 0 }, // EClkMcBSP3_I, + { KPM_WKEN_PER, KBit2, KBit2, 0 }, // EClkMcBSP4_I, + { KPM_WKEN1_CORE, KBit10, KBit10, 0 }, // EClkMcBSP5_I, + { KPM_WKEN1_CORE, KBit15, KBit15, 0 }, // EClkI2c1_I, + { KPM_WKEN1_CORE, KBit16, KBit16, 0 }, // EClkI2c2_I, + { KPM_WKEN1_CORE, KBit17, KBit17, 0 }, // EClkI2c3_I, + { KPM_WKEN1_CORE, KBit13, KBit13, 0 }, // EClkUart1_I, + { KPM_WKEN1_CORE, KBit14, KBit14, 0 }, // EClkUart2_I, + { KPM_WKEN_PER, KBit11, KBit11, 0 }, // EClkUart3_I, + { KPM_WKEN1_CORE, KBit18, KBit18, 0 }, // EClkMcSpi1_I + { KPM_WKEN1_CORE, KBit19, KBit19, 0 }, // EClkMcSpi2_I + { KPM_WKEN1_CORE, KBit20, KBit20, 0 }, // EClkMcSpi3_I + { KPM_WKEN1_CORE, KBit21, KBit21, 0 }, // EClkMcSpi4_I + { KPM_WKEN_WKUP, KBit0, KBit0, 0 }, // EClkGpt1_I, + { KPM_WKEN_PER, KBit3, KBit3, 0 }, // EClkGpt2_I, + { KPM_WKEN_PER, KBit4, KBit4, 0 }, // EClkGpt3_I, + { KPM_WKEN_PER, KBit5, KBit5, 0 }, // EClkGpt4_I, + { KPM_WKEN_PER, KBit6, KBit6, 0 }, // EClkGpt5_I, + { KPM_WKEN_PER, KBit7, KBit7, 0 }, // EClkGpt6_I, + { KPM_WKEN_PER, KBit8, KBit8, 0 }, // EClkGpt7_I, + { KPM_WKEN_PER, KBit9, KBit9, 0 }, // EClkGpt8_I, + { KPM_WKEN_PER, KBit10, KBit10, 0 }, // EClkGpt9_I, + { KPM_WKEN1_CORE, KBit11, KBit11, 0 }, // EClkGpt10_I, + { KPM_WKEN1_CORE, KBit12, KBit12, 0 }, // EClkGpt11_I, + { KPM_WKEN_WKUP, KBit1, KBit1, 0 }, // EClkGpt12_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkMailboxes_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkOmapSCM_I, + { KPM_WKEN1_CORE, KBit4, KBit4, 0 }, // EClkHsUsbOtg_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSdrc_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkPka_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkRng_I, + { KPM_WKEN3_CORE, KBit2, KBit2, 0 }, // EClkUsbTll_I, + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSgx_I, + + { KPM_WKEN_WKUP, KBit9, KBit9, 0 }, // EClkUsim_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkWdt1_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkWdt2_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkWdt3_I, + { KPM_WKEN_WKUP, KBit3, KBit3, 0 }, // EClkGpio1_I, + { KPM_WKEN_PER, KBit13, KBit13, 0 }, // EClkGpio2_I, + { KPM_WKEN_PER, KBit14, KBit14, 0 }, // EClkGpio3_I, + { KPM_WKEN_PER, KBit15, KBit15, 0 }, // EClkGpio4_I, + { KPM_WKEN_PER, KBit16, KBit16, 0 }, // EClkGpio5_I, + { KPM_WKEN_PER, KBit17, KBit17, 0 }, // EClkGpio6_I, + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClk32Sync_I, + + { KPM_WKEN_USBHOST, KBit0, KBit0, 0 }, // EClkUsb_I, ///< USB host interface clock + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClk48M + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClk12M + + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkSysClk + { KDummy, 0, KDummyReadAsDisabled, 0 }, // EClkAltClk + { KDummy, 0, KDummyReadAsDisabled, 0 } // EClkSysClk32k + + }; +__ASSERT_COMPILE( (sizeof(KClockWakeupTable) / sizeof( KClockWakeupTable[0] )) == Prcm::KSupportedClockCount ); + + +__ASSERT_COMPILE( Prcm::EWakeGroupMpu == 0 ); +__ASSERT_COMPILE( Prcm::EWakeGroupIva2 == 1 ); +static const TRegisterBitDef KClockWakeupGroupTable[ Prcm::KSupportedClockCount ][ Prcm::KSupportedWakeupGroupCount ] = + { + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMpu, ///< DPLL1 + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkIva2Pll, ///< DPLL2 + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCore, ///< DPLL3 + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkPeriph, ///< DPLL4 + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkPeriph2, ///< DPLL5 + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkPrcmInterface, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkEmu, ///< Emulation clock + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkNeon, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkL3Domain, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkL4Domain, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkRM_F, ///< Reset manager functional clock + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClk96M, ///< 96MHz clock + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClk120M, ///< 120MHz clock + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSysOut, + + // Functional clocks + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkTv_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDss1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDss2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCsi2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCam_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkIva2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMmc3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMsPro_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkHdq_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBsp1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBsp2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBsp3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBsp4_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcBsp5_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMcSpi4_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkI2c3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUart3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt4_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt5_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt6_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt7_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt8_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt9_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt10_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpt11_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsbTll_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkTs_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCpeFuse_F, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSgx_F, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsim_F, + { { KPM_MPUGRPSEL_WKUP, KBit7, KBit7, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSmartReflex2_F, + { { KPM_MPUGRPSEL_WKUP, KBit6, KBit6, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSmartReflex1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio1_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio2_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio3_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio4_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio5_F, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkGpio6_F, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsb120_F, ///< USB host 120MHz functional clock + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkUsb48_F, ///< USB host 48MHz functional clock + + + // Interface clocks + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDss_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkCam_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkIcr_I, + { { KPM_MPUGRPSEL1_CORE, KBit24, KBit24, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit24, KBit24, 0 } }, // EClkMmc1_I, + { { KPM_MPUGRPSEL1_CORE, KBit25, KBit25, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit25, KBit25, 0 } }, // EClkMmc2_I, + { { KPM_MPUGRPSEL1_CORE, KBit30, KBit30, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit30, KBit30, 0 } }, // EClkMmc3_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMsPro_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkHdq_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkAes1_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkAes2_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSha11_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSha12_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDes1_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkDes2_I, + { { KPM_MPUGRPSEL1_CORE, KBit9, KBit9, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit9, KBit9, 0 } }, // EClkMcBsp1_I, + { { KPM_MPUGRPSEL_PER, KBit0, KBit0, 0 }, { KPM_IVA2GRPSEL_PER, KBit0, KBit0, 0 } }, // EClkMcBsp2_I, + { { KPM_MPUGRPSEL_PER, KBit1, KBit1, 0 }, { KPM_IVA2GRPSEL_PER, KBit1, KBit1, 0 } }, // EClkMcBsp3_I, + { { KPM_MPUGRPSEL_PER, KBit2, KBit2, 0 }, { KPM_IVA2GRPSEL_PER, KBit2, KBit2, 0 } }, // EClkMcBsp4_I, + { { KPM_MPUGRPSEL1_CORE, KBit10, KBit10, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit10, KBit10, 0 } }, // EClkMcBsp5_I, + { { KPM_MPUGRPSEL1_CORE, KBit15, KBit15, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit15, KBit15, 0 } }, // EClkI2c1_I, + { { KPM_MPUGRPSEL1_CORE, KBit16, KBit16, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit16, KBit16, 0 } }, // EClkI2c2_I, + { { KPM_MPUGRPSEL1_CORE, KBit17, KBit17, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit17, KBit17, 0 } }, // EClkI2c3_I, + { { KPM_MPUGRPSEL1_CORE, KBit13, KBit13, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit13, KBit13, 0 } }, // EClkUart1_I, + { { KPM_MPUGRPSEL1_CORE, KBit14, KBit14, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit14, KBit14, 0 } }, // EClkUart2_I, + { { KPM_MPUGRPSEL_PER, KBit11, KBit11, 0 }, { KPM_IVA2GRPSEL_PER, KBit11, KBit11, 0 } }, // EClkUart3_I, + { { KPM_MPUGRPSEL1_CORE, KBit18, KBit18, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit18, KBit18, 0 } }, // EClkMcSpi1_I, + { { KPM_MPUGRPSEL1_CORE, KBit19, KBit19, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit19, KBit19, 0 } }, // EClkMcSpi2_I, + { { KPM_MPUGRPSEL1_CORE, KBit20, KBit20, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit20, KBit20, 0 } }, // EClkMcSpi3_I, + { { KPM_MPUGRPSEL1_CORE, KBit21, KBit21, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit21, KBit21, 0 } }, // EClkMcSpi4_I, + { { KPM_MPUGRPSEL_WKUP, KBit0, KBit0, 0 }, { KPM_IVA2GRPSEL_WKUP, KBit0, KBit0, 0 } }, // EClkGpt1_I, + { { KPM_MPUGRPSEL_PER, KBit3, KBit3, 0 }, { KPM_IVA2GRPSEL_PER, KBit3, KBit3, 0 } }, // EClkGpt2_I, + { { KPM_MPUGRPSEL_PER, KBit4, KBit4, 0 }, { KPM_IVA2GRPSEL_PER, KBit4, KBit4, 0 } }, // EClkGpt3_I, + { { KPM_MPUGRPSEL_PER, KBit5, KBit5, 0 }, { KPM_IVA2GRPSEL_PER, KBit5, KBit5, 0 } }, // EClkGpt4_I, + { { KPM_MPUGRPSEL_PER, KBit6, KBit6, 0 }, { KPM_IVA2GRPSEL_PER, KBit6, KBit6, 0 } }, // EClkGpt5_I, + { { KPM_MPUGRPSEL_PER, KBit7, KBit7, 0 }, { KPM_IVA2GRPSEL_PER, KBit7, KBit7, 0 } }, // EClkGpt6_I, + { { KPM_MPUGRPSEL_PER, KBit8, KBit9, 0 }, { KPM_IVA2GRPSEL_PER, KBit8, KBit8, 0 } }, // EClkGpt7_I, + { { KPM_MPUGRPSEL_PER, KBit9, KBit9, 0 }, { KPM_IVA2GRPSEL_PER, KBit9, KBit9, 0 } }, // EClkGpt8_I, + { { KPM_MPUGRPSEL_PER, KBit10, KBit10, 0 }, { KPM_IVA2GRPSEL_PER, KBit10, KBit10, 0 } }, // EClkGpt9_I, + { { KPM_MPUGRPSEL1_CORE, KBit11, KBit11, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit11, KBit11, 0 } }, // EClkGpt10_I, + { { KPM_MPUGRPSEL1_CORE, KBit12, KBit12, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit12, KBit12, 0 } }, // EClkGpt11_I, + { { KPM_MPUGRPSEL_WKUP, KBit1, KBit1, 0 }, { KPM_IVA2GRPSEL_WKUP, KBit1, KBit1, 0 } }, // EClkGpt12_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkMailboxes_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkOmapSCM_I, + { { KPM_MPUGRPSEL1_CORE, KBit4, KBit4, 0 }, { KPM_IVA2GRPSEL1_CORE, KBit4, KBit4, 0 } }, // EClkHsUsbOtg_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSdrc_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkPka_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkRng_I, + { { KPM_MPUGRPSEL3_CORE, KBit2, KBit2, 0 }, { KPM_IVA2GRPSEL3_CORE, KBit2, KBit2, 0 } }, // EClkUsbTll_I, + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSgx_I, + + { { KPM_MPUGRPSEL_WKUP, KBit9, KBit9, 0 }, { KPM_IVA2GRPSEL_WKUP, KBit9, KBit9, 0 } }, // EClkUsim_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt1_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt2_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkWdt3_I, + { { KPM_MPUGRPSEL_WKUP, KBit3, KBit3, 0 }, { KPM_IVA2GRPSEL_WKUP, KBit3, KBit3, 0 } }, // EClkGpio1_I, + { { KPM_MPUGRPSEL_PER, KBit13, KBit13, 0 }, { KPM_IVA2GRPSEL_PER, KBit13, KBit13, 0 } }, // EClkGpio2_I, + { { KPM_MPUGRPSEL_PER, KBit14, KBit14, 0 }, { KPM_IVA2GRPSEL_PER, KBit14, KBit14, 0 } }, // EClkGpio3_I, + { { KPM_MPUGRPSEL_PER, KBit15, KBit15, 0 }, { KPM_IVA2GRPSEL_PER, KBit15, KBit15, 0 } }, // EClkGpio4_I, + { { KPM_MPUGRPSEL_PER, KBit16, KBit16, 0 }, { KPM_IVA2GRPSEL_PER, KBit16, KBit16, 0 } }, // EClkGpio5_I, + { { KPM_MPUGRPSEL_PER, KBit17, KBit17, 0 }, { KPM_IVA2GRPSEL_PER, KBit17, KBit17, 0 } }, // EClkGpio6_I, + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClk32Sync_I, + + { { KPM_MPUGRPSEL_USBHOST, KBit0, KBit0, 0 }, { KPM_IVA2GRPSEL_USBHOST, KBit0, KBit0, 0 } }, // EClkUsb_I, ///< USB host interface clock + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClk48M + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClk12M + + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkSysClk + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } }, // EClkAltClk + { { KDummy, 0, KDummyReadAsDisabled, 0 }, { KDummy, 0, KDummyReadAsDisabled, 0 } } // EClkSysClk32k + }; + + __ASSERT_COMPILE( Prcm::EWakeDomainMpu == 0 ); + __ASSERT_COMPILE( Prcm::EWakeDomainCore == 1 ); + __ASSERT_COMPILE( Prcm::EWakeDomainIva2 == 2 ); + __ASSERT_COMPILE( Prcm::EWakeDomainPeripheral == 3 ); + __ASSERT_COMPILE( Prcm::EWakeDomainDss == 4 ); + __ASSERT_COMPILE( Prcm::EWakeDomainWakeup == 5 ); + __ASSERT_COMPILE( Prcm::KSupportedWakeupDomainCount == 6 ); + +struct TWakeupDomainInfo + { + // To save space, there's an assumption here that all domain dependency configuration for + // a single clock is in one register, and a single bit defines the dependency, + // 1 = dependant, 0 = independant + // The bits are defined here by bit number rather than by mask + TUint32 iRegister; + TInt8 iBitNumber[ Prcm::KSupportedWakeupDomainCount ]; ///< bit number to modify, -1 if not supported + }; + +static const TWakeupDomainInfo KClockWakeupDomainTable[ Prcm::KSupportedClockCount ] = + { + // REGISTER MPU CORE IVA2 PER DSS WAKE + { KPM_WKDEP_MPU, {-1, 0, 2, 7, 5, -1 } }, // EClkMpu, ///< DPLL1 + { KPM_WKDEP_IVA2, {1, 0, -1, 7, 5, 4 } }, // EClkIva2Pll, ///< DPLL2 + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkCore, ///< DPLL3 + { KPM_WKDEP_PER, {1, 0, 2, -1, -1, 4 } }, // EClkPeriph, ///< DPLL4 + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkPeriph2, ///< DPLL5 + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkPrcmInterface, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkEmu, ///< Emulation clock + { KPM_WKDEP_NEON, {1, -1, -1, -1, -1, -1 } }, // EClkNeon, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkL3Domain, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkL4Domain, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMpuPll_Bypass, ///< DPLL1 bypass frequency + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkIva2Pll_Bypass, ///< DPLL2 bypass frequency + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkRM_F, ///< Reset manager functional clock + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClk96M, ///< 96MHz clock + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClk120M, ///< 120MHz clock + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSysOut, + + // Functional clocks + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkTv_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkDss1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkDss2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkCsi2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkCam_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkIva2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMsPro_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkHdq_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp4_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp5_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi4_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt4_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt5_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt6_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt7_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt8_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt9_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt10_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt11_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsbTll_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkTs_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkCpeFuse_F, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSgx_F, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsim_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSmartReflex2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSmartReflex1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkWdt2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkWdt3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio1_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio2_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio3_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio4_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio5_F, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio6_F, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsb120_F, ///< USB host 120MHz functional clock + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsb48_F, ///< USB host 48MHz functional clock + + + // Interface clocks + { KPM_WKDEP_DSS, {1, -1, 2, -1, -1, 4 } }, // EClkDss_I, + { KPM_WKDEP_CAM, {1, -1, 2, -1, -1, 4 } }, // EClkCam_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkIcr_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMmc3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMsPro_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkHdq_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkAes1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkAes2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSha11_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSha12_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkDes1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkDes2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp4_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcBsp5_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkI2c3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUart3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMcSpi4_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt4_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt5_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt6_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt7_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt8_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt9_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt10_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt11_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpt12_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkMailboxes_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkOmapSCM_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkHsUsbOtg_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSdrc_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkPka_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkRng_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsbTll_I, + + { KPM_WKDEP_SGX, {1, -1, 2, -1, -1, 4 } }, // EClkSgx_I, + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkUsim_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkWdt1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkWdt2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkWdt3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio1_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio2_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio3_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio4_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio5_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkGpio6_I, + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClk32Sync_I, + + { KPM_WKDEP_USBHOST, {1, 0, 2, -1, -1, 4 } }, // EClkUsb_I, ///< USB host interface clock + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClk48M + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClk12M + + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSysClk + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkAltClk + { KDummy, {-1, -1, -1, -1, -1, -1 } }, // EClkSysClk32k + // REGISTER MPU CORE IVA2 PER DSS WAKE + }; + +struct TPowerDomainControl + { + TUint32 iRegister; + TUint8 iShift; ///< shift to move bits into position + TUint8 iAllowedMask; ///< mask of which modes are supported + TUint8 __spare[2]; + }; + +const TUint8 KPowerAllowedOff = 1 << Prcm::EPowerOff; +const TUint8 KPowerAllowedOn = 1 << Prcm::EPowerOn; +const TUint8 KPowerAllowedRetention = 1 << Prcm::EPowerRetention; +const TUint8 KPowerAllowedOnOffRetention = (KPowerAllowedOff bitor KPowerAllowedOn bitor KPowerAllowedRetention); +const TUint8 KPowerModeMask = 0x3; + +static const TPowerDomainControl KPowerDomainControl[] = + { + // iRegister iShift iAllowedMask + { KPM_PWSTCTRL_MPU, 0, KPowerAllowedOnOffRetention }, // EPowerDomainMpu, + { KPM_PWSTCTRL_IVA2, 0, KPowerAllowedOnOffRetention }, // EPowerDomainIva2, + { KPM_PWSTCTRL_NEON, 0, KPowerAllowedOnOffRetention }, // EPowerDomainNeon, + { KPM_PWSTCTRL_CORE, 0, KPowerAllowedOnOffRetention }, // EPowerDomainCore, + { KPM_PWSTCTRL_SGX, 0, KPowerAllowedOnOffRetention }, // EPowerDomainSgx, + { KPM_PWSTCTRL_DSS, 0, KPowerAllowedOnOffRetention }, // EPowerDomainDss, + { KPM_PWSTCTRL_CAM, 0, KPowerAllowedOnOffRetention }, // EPowerDomainCamera, + { KPM_PWSTCTRL_USBHOST, 0, KPowerAllowedOnOffRetention }, // EPowerDomainUsb, + { KPM_PWSTCTRL_PER, 0, KPowerAllowedOnOffRetention } // EPowerDomainPer, + }; +__ASSERT_COMPILE( (sizeof(KPowerDomainControl) / sizeof( KPowerDomainControl[0] )) == Prcm::KSupportedPowerDomainCount ); + +struct TGptClkSelInfo + { + TUint32 iRegister; + TUint32 iMask; + }; + +static const TGptClkSelInfo KGptClockSourceInfo[ Prcm::KSupportedGptCount ] = + { + { KCM_CLKSEL_WKUP, KBit0 }, // EGpt1, + { KCM_CLKSEL_PER, KBit0 }, // EGpt2, + { KCM_CLKSEL_PER, KBit1 }, // EGpt3, + { KCM_CLKSEL_PER, KBit2 }, // EGpt4, + { KCM_CLKSEL_PER, KBit3 }, // EGpt5, + { KCM_CLKSEL_PER, KBit4 }, // EGpt6, + { KCM_CLKSEL_PER, KBit5 }, // EGpt7, + { KCM_CLKSEL_PER, KBit6 }, // EGpt8, + { KCM_CLKSEL_PER, KBit7 }, // EGpt9, + { KCM_CLKSEL_CORE, KBit6 }, // EGpt10, + { KCM_CLKSEL_CORE, KBit7 }, // EGpt11, + { KDummy, 0 }, // EGpt12 - clocked from security block + }; + +// This table is used to find the source clock for a given clock. That is, by looking up a +// specific clock in this table, you can find out which DPLL/divider it was derived from. +// Following the chain backwards to SYSCLK allows building of the total multiply and +// divide applied to SYSCLK to get the given clock +enum TClockSourceType + { + EIgnore, // not implemented yet... + EDpll, // this clock is derived from a PLL + EDivider, // this clock is divied from a given clock + EDivMux, // divider fed by mux-selectable input clock + EMux, // fed by mux-selectable input clock + EDuplicate, // this clock is a duplicate of another clock + E96MMux, // 96MHz mux-selected clock source + E54MMux, // 54MHz mux-selected clock source + E48MMux, // 48MHz mux-selected clock source + EDiv4, // specified clock source divided by 4 + }; + +struct TClockSourceInfo + { + TClockSourceType iType : 8; // type of the source for this clock + union { + Prcm::TClock iClock : 8; // the clock that feeds this divider, or which this is a duplicate of + Prcm::TPll iPll : 8; // the PLL that generates this clock + Prcm::TGpt iGpt : 8; // conversion to TGpt type for the clock we are interested in + }; + }; + +static const TClockSourceInfo KClockSourceInfo[] = + { + { EDpll, (Prcm::TClock)Prcm::EDpll1 }, // EClkMpu, + { EDpll, (Prcm::TClock)Prcm::EDpll2 }, // EClkIva2Pll, + { EDpll, (Prcm::TClock)Prcm::EDpll3 }, // EClkCore, + { EDpll, (Prcm::TClock)Prcm::EDpll4 }, // EClkPeriph, + { EDpll, (Prcm::TClock)Prcm::EDpll5 }, // EClkPeriph2, + { EDuplicate, Prcm::EClkSysClk }, // EClkPrcmInterface, + { EIgnore, (Prcm::TClock)0 }, // EClkEmu, + { EDuplicate, Prcm::EClkMpu }, // EClkNeon, + { EDivider, Prcm::EClkCore }, // EClkL3Domain, + { EDivider, Prcm::EClkL3Domain }, // EClkL4Domain, + { EDivider, Prcm::EClkCore }, // EClkMpuPll_Bypass, + { EDivider, Prcm::EClkCore }, // EClkIva2Pll_Bypass, + { EDivider, Prcm::EClkL4Domain }, // EClkRM_F, + { E96MMux, Prcm::EClkPeriph }, // EClk96M, + { EDivider, Prcm::EClkPeriph2 }, // EClk120M, + { EDivMux, (Prcm::TClock)0 }, // EClkSysOut, + + // Functional clocks + { E54MMux, Prcm::EClkPeriph }, + { EDivider, Prcm::EClkPeriph }, // EClkDss1_F, + { EDuplicate, Prcm::EClkSysClk }, // EClkDss2_F, + { EDuplicate, Prcm::EClk96M }, // EClkCsi2_F, + { EDivider, Prcm::EClkPeriph }, // EClkCam_F, + { EDuplicate, Prcm::EClkIva2Pll }, // EClkIva2_F, + { EDuplicate, Prcm::EClk96M }, // EClkMmc1_F, + { EDuplicate, Prcm::EClk96M }, // EClkMmc2_F, + { EDuplicate, Prcm::EClk96M }, // EClkMmc3_F, + { EDuplicate, Prcm::EClk96M }, // EClkMsPro_F, + { EDuplicate, Prcm::EClk12M }, // EClkHdq_F, + { EDuplicate, Prcm::EClk96M }, // EClkMcBsp1_F, + { EDuplicate, Prcm::EClk96M }, // EClkMcBsp2_F, + { EDuplicate, Prcm::EClk96M }, // EClkMcBsp3_F, + { EDuplicate, Prcm::EClk96M }, // EClkMcBsp4_F, + { EDuplicate, Prcm::EClk96M }, // EClkMcBsp5_F, + { EDuplicate, Prcm::EClk48M }, // EClkMcSpi1_F, + { EDuplicate, Prcm::EClk48M }, // EClkMcSpi2_F, + { EDuplicate, Prcm::EClk48M }, // EClkMcSpi3_F, + { EDuplicate, Prcm::EClk48M }, // EClkMcSpi4_F, + { EDuplicate, Prcm::EClk96M }, // EClkI2c1_F, + { EDuplicate, Prcm::EClk96M }, // EClkI2c2_F, + { EDuplicate, Prcm::EClk96M }, // EClkI2c3_F, + { EDuplicate, Prcm::EClk48M }, // EClkUart1_F, + { EDuplicate, Prcm::EClk48M }, // EClkUart2_F, + { EDuplicate, Prcm::EClk48M }, // EClkUart3_F, + { EMux, (Prcm::TClock)Prcm::EGpt1 }, // EClkGpt1_F, + { EMux, (Prcm::TClock)Prcm::EGpt2 }, // EClkGpt2_F, + { EMux, (Prcm::TClock)Prcm::EGpt3 }, // EClkGpt3_F, + { EMux, (Prcm::TClock)Prcm::EGpt4 }, // EClkGpt4_F, + { EMux, (Prcm::TClock)Prcm::EGpt5 }, // EClkGpt5_F, + { EMux, (Prcm::TClock)Prcm::EGpt6 }, // EClkGpt6_F, + { EMux, (Prcm::TClock)Prcm::EGpt7 }, // EClkGpt7_F, + { EMux, (Prcm::TClock)Prcm::EGpt8 }, // EClkGpt8_F, + { EMux, (Prcm::TClock)Prcm::EGpt9 }, // EClkGpt9_F, + { EMux, (Prcm::TClock)Prcm::EGpt10 }, // EClkGpt10_F, + { EMux, (Prcm::TClock)Prcm::EGpt11 }, // EClkGpt11_F, + { EDuplicate, Prcm::EClk120M }, // EClkUsbTll_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkTs_F, + { EDuplicate, Prcm::EClkSysClk }, // EClkCpeFuse_F, + { EDivMux, (Prcm::TClock)0 }, // EClkSgx_F, + { EDivMux, Prcm::EClkSysClk }, // EClkUsim_F, + { EDuplicate, Prcm::EClkSysClk }, // EClkSmartReflex2_F, + { EDuplicate, Prcm::EClkSysClk }, // EClkSmartReflex1_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkWdt2_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkWdt3_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio1_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio2_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio3_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio4_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio5_F, + { EDuplicate, Prcm::EClkSysClk32k }, // EClkGpio6_F, + { EDuplicate, Prcm::EClk120M }, // EClkUsb120_F, + { EDuplicate, Prcm::EClk48M }, // EClkUsb48_F, + + // Interface clocks + { EDuplicate, Prcm::EClkL4Domain }, // EClkDss_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkCam_I, + { }, // EClkIcr_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMmc1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMmc2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMmc3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMsPro_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkHdq_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkAes1_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkAes2_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkSha11_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkSha12_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkDes1_I, + { EDuplicate, Prcm::EClkL4Domain}, // EClkDes2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcBsp1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcBsp2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcBsp3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcBsp4_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcBsp5_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkI2c1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkI2c2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkI2c3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkUart1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkUart2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkUart3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcSpi1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcSpi2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcSpi3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMcSpi4_I, + { EDuplicate, Prcm::EClkSysClk }, // EClkGpt1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt4_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt5_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt6_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt7_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt8_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt9_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt10_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt11_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpt12_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkMailboxes_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkOmapSCM_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkHsUsbOtg_I, + { EDuplicate, Prcm::EClkL3Domain }, // EClkSdrc_I, + { EDuplicate, Prcm::EClkL3Domain }, // EClkPka_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkRng_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkUsbTll_I, + { EDuplicate, Prcm::EClkL3Domain }, // EClkSgx_I, + { EDuplicate, Prcm::EClkSysClk }, // EClkUsim_I, + { EDuplicate, Prcm::EClkSysClk }, // EClkWdt1_I, + { EDuplicate, Prcm::EClkSysClk }, // EClkWdt2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkWdt3_I, + { EDuplicate, Prcm::EClkSysClk }, // EClkGpio1_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpio2_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpio3_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpio4_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpio5_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkGpio6_I, + { EDuplicate, Prcm::EClkSysClk }, // EClk32Sync_I, + { EDuplicate, Prcm::EClkL4Domain }, // EClkUsb_I, + + { E48MMux, Prcm::EClk96M }, // EClk48M, + { EDiv4, Prcm::EClk48M }, // EClk12M, + + { EDuplicate, Prcm::EClkSysClk }, // EClkSysClk + { EDuplicate, Prcm::EClkAltClk }, // EClkAltClk + { EDuplicate, Prcm::EClkSysClk32k }, // EClkSysClk32k + + }; + +__ASSERT_COMPILE( sizeof( KClockSourceInfo ) / sizeof( KClockSourceInfo[0] ) == Prcm::KSupportedClockCount ); + + +// Bit of hackery to enable creation of a const table of pointer to _LITs. +// Taking the address of a _LIT will cause the compiler to invoke its operator&() +// function, which forces the compiler to generate the table in code. But hiding +// it inside a dummy struct allows taking of the address of the struct instead, +// avoiding the operator&() problem. + +template< TInt S > +struct THiddenLit8 + { + TLitC8 iLit; + }; + +#define __PLIT8(name,s) const static THiddenLit8 name={{sizeof(s)-1,s}}; + +// List of identifer strings for each clock source - used for PRM +__PLIT8(KClkMpu, "a.MPU" ); +__PLIT8(KClkIva2Pll, "a.IVA" ); +__PLIT8(KClkCore, "a.CORE" ); +__PLIT8(KClkPeriph, "a.PER" ); +__PLIT8(KClkPeriph2, "a.PER2" ); +__PLIT8(KClkPrcmInterface, "a.PRCM" ); +__PLIT8(KClkEmu, "a.EMU" ); +__PLIT8(KClkNeon, "a.NEON" ); +__PLIT8(KClkL3Domain, "a.L3" ); +__PLIT8(KClkL4Domain, "a.L4" ); +__PLIT8(KClkMpuPll_Bypass, "a.MPUB" ); +__PLIT8(KClkIva2Pll_Bypass, "a.IVAB" ); +__PLIT8(KClkRM_F, "a.RMf" ); +__PLIT8(KClk96M, "a.96" ); +__PLIT8(KClk120M, "a.120" ); +__PLIT8(KClkSysOut, "a.OUT" ); +__PLIT8(KClkTv_F, "a.TVf" ); +__PLIT8(KClkDss1_F, "a.DSS1f" ); +__PLIT8(KClkDss2_F, "a.DSS2f" ); +__PLIT8(KClkCsi2_F, "a.CSI2f" ); +__PLIT8(KClkCam_F, "a.CAMf" ); +__PLIT8(KClkIva2_F, "a.IVA2f" ); +__PLIT8(KClkMmc1_F, "a.MMC1f" ); +__PLIT8(KClkMmc2_F, "a.MMC2f" ); +__PLIT8(KClkMmc3_F, "a.MMC3f" ); +__PLIT8(KClkMsPro_F, "a.MSPf" ); +__PLIT8(KClkHdq_F, "a.HDQf" ); +__PLIT8(KClkMcBsp1_F, "a.BSP1f" ); +__PLIT8(KClkMcBsp2_F, "a.BSP2f" ); +__PLIT8(KClkMcBsp3_F, "a.BSP3f" ); +__PLIT8(KClkMcBsp4_F, "a.BSP4f" ); +__PLIT8(KClkMcBsp5_F, "a.BSP5f" ); +__PLIT8(KClkMcSpi1_F, "a.SPI1f" ); +__PLIT8(KClkMcSpi2_F, "a.SPI2f" ); +__PLIT8(KClkMcSpi3_F, "a.SPI3f" ); +__PLIT8(KClkMcSpi4_F, "a.SPI4f" ); +__PLIT8(KClkI2c1_F, "a.I2C1f" ); +__PLIT8(KClkI2c2_F, "a.I2C2f" ); +__PLIT8(KClkI2c3_F, "a.I2C3f" ); +__PLIT8(KClkUart1_F, "a.UART1f" ); +__PLIT8(KClkUart2_F, "a.UART2f" ); +__PLIT8(KClkUart3_F, "a.UART3f" ); +__PLIT8(KClkGpt1_F, "a.GPT1f" ); +__PLIT8(KClkGpt2_F, "a.GPT2f" ); +__PLIT8(KClkGpt3_F, "a.GPT3f" ); +__PLIT8(KClkGpt4_F, "a.GPT4f" ); +__PLIT8(KClkGpt5_F, "a.GPT5f" ); +__PLIT8(KClkGpt6_F, "a.GPT6f" ); +__PLIT8(KClkGpt7_F, "a.GPT7f" ); +__PLIT8(KClkGpt8_F, "a.GPT8f" ); +__PLIT8(KClkGpt9_F, "a.GPT9f" ); +__PLIT8(KClkGpt10_F, "a.GPTAf" ); +__PLIT8(KClkGpt11_F, "a.GPTBf" ); +__PLIT8(KClkUsbTll_F, "a.UTLLf" ); +__PLIT8(KClkTs_F, "a.TSf" ); +__PLIT8(KClkCpeFuse_F, "a.FUSEf" ); +__PLIT8(KClkSgx_F, "a.SGXf" ); +__PLIT8(KClkUsim_F, "a.USIMf" ); +__PLIT8(KClkSmartReflex2_F, "a.SMRF2f" ); +__PLIT8(KClkSmartReflex1_F, "a.SMRF1f" ); +__PLIT8(KClkWdt2_F, "a.WDT2f" ); +__PLIT8(KClkWdt3_F, "a.WDT3f" ); +__PLIT8(KClkGpio1_F, "a.GPIO1f" ); +__PLIT8(KClkGpio2_F, "a.GPIO2f" ); +__PLIT8(KClkGpio3_F, "a.GPIO3f" ); +__PLIT8(KClkGpio4_F, "a.GPIO4f" ); +__PLIT8(KClkGpio5_F, "a.GPIO5f" ); +__PLIT8(KClkGpio6_F, "a.GPIO6f" ); +__PLIT8(KClkUsb120_F, "a.U120f" ); +__PLIT8(KClkUsb48_F, "a.U48f" ); +__PLIT8(KClkDss_I, "a.DSSi" ); +__PLIT8(KClkCam_I, "a.CAMi" ); +__PLIT8(KClkIcr_I, "a.ICRi" ); +__PLIT8(KClkMmc1_I, "a.MMC1i" ); +__PLIT8(KClkMmc2_I, "a.MMC2i" ); +__PLIT8(KClkMmc3_I, "a.MMC3i" ); +__PLIT8(KClkMsPro_I, "a.MSi" ); +__PLIT8(KClkHdq_I, "a.HDQi" ); +__PLIT8(KClkAes1_I, "a.AES1i" ); +__PLIT8(KClkAes2_I, "a.AES2i" ); +__PLIT8(KClkSha11_I, "a.SHA1i" ); +__PLIT8(KClkSha12_I, "a.SHA2i" ); +__PLIT8(KClkDes1_I, "a.DES1i" ); +__PLIT8(KClkDes2_I, "a.DES2i" ); +__PLIT8(KClkMcBsp1_I, "a.BSP1i" ); +__PLIT8(KClkMcBsp2_I, "a.BSP2i" ); +__PLIT8(KClkMcBsp3_I, "a.BSP3i" ); +__PLIT8(KClkMcBsp4_I, "a.BSP4i" ); +__PLIT8(KClkMcBsp5_I, "a.BSP5i" ); +__PLIT8(KClkI2c1_I, "a.I2C1i" ); +__PLIT8(KClkI2c2_I, "a.I2C2i" ); +__PLIT8(KClkI2c3_I, "a.I2C3i" ); +__PLIT8(KClkUart1_I, "a.UART1i" ); +__PLIT8(KClkUart2_I, "a.UART2i" ); +__PLIT8(KClkUart3_I, "a.UART3i" ); +__PLIT8(KClkMcSpi1_I, "a.SPI1i" ); +__PLIT8(KClkMcSpi2_I, "a.SPI2i" ); +__PLIT8(KClkMcSpi3_I, "a.SPI3i" ); +__PLIT8(KClkMcSpi4_I, "a.SPI4i" ); +__PLIT8(KClkGpt1_I, "a.GPT1i" ); +__PLIT8(KClkGpt2_I, "a.GPT2i" ); +__PLIT8(KClkGpt3_I, "a.GPT3i" ); +__PLIT8(KClkGpt4_I, "a.GPT4i" ); +__PLIT8(KClkGpt5_I, "a.GPT5i" ); +__PLIT8(KClkGpt6_I, "a.GPT6i" ); +__PLIT8(KClkGpt7_I, "a.GPT7i" ); +__PLIT8(KClkGpt8_I, "a.GPT8i" ); +__PLIT8(KClkGpt9_I, "a.GPT9i" ); +__PLIT8(KClkGpt10_I, "a.GPTAi" ); +__PLIT8(KClkGpt11_I, "a.GPTBi" ); +__PLIT8(KClkGpt12_I, "a.GPTCi" ); +__PLIT8(KClkMailboxes_I, "a.MBi" ); +__PLIT8(KClkOmapSCM_I, "a.SCMi" ); +__PLIT8(KClkHsUsbOtg_I, "a.OTGi" ); +__PLIT8(KClkSdrc_I, "a.SDRCi" ); +__PLIT8(KClkPka_I, "a.PKAi" ); +__PLIT8(KClkRng_I, "a.RNGi" ); +__PLIT8(KClkUsbTll_I, "a.TLLi" ); +__PLIT8(KClkSgx_I, "a.SGXi" ); +__PLIT8(KClkUsim_I, "a.USIMi" ); +__PLIT8(KClkWdt1_I, "a.WDT1i" ); +__PLIT8(KClkWdt2_I, "a.WDT2i" ); +__PLIT8(KClkWdt3_I, "a.WDT3i" ); +__PLIT8(KClkGpio1_I, "a.GPIO1i" ); +__PLIT8(KClkGpio2_I, "a.GPIO2i" ); +__PLIT8(KClkGpio3_I, "a.GPIO3i" ); +__PLIT8(KClkGpio4_I, "a.GPIO4i" ); +__PLIT8(KClkGpio5_I, "a.GPIO5i" ); +__PLIT8(KClkGpio6_I, "a.GPIO6i" ); +__PLIT8(KClk32Sync_I, "a.32SYNi" ); +__PLIT8(KClkUsb_I, "a.USBi" ); +__PLIT8(KClk48M, "a.48" ); +__PLIT8(KClk12M, "a.12" ); +__PLIT8(KClkSysClk, "a.SYSCLK" ); +__PLIT8(KClkAltClk, "a.ALTCLK" ); +__PLIT8(KClkSysClk32k, "a.SYS32K" ); + + +// Table converting clock sources to string identifiers for PRM +static const TDesC8* const KNames[] = + { + (const TDesC8*)( &KClkMpu ), // EClkMpu + (const TDesC8*)( &KClkIva2Pll ), // EClkIva2Pll + (const TDesC8*)( &KClkCore ), // EClkCore + (const TDesC8*)( &KClkPeriph ), // EClkPeriph + (const TDesC8*)( &KClkPeriph2 ), // EClkPeriph2 + (const TDesC8*)( &KClkPrcmInterface ), // EClkPrcmInterface + (const TDesC8*)( &KClkEmu ), // EClkEmu + (const TDesC8*)( &KClkNeon ), // EClkNeon + (const TDesC8*)( &KClkL3Domain ), // EClkL3Domain + (const TDesC8*)( &KClkL4Domain ), // EClkL4Domain + (const TDesC8*)( &KClkMpuPll_Bypass ), // EClkMpuPll_Bypass + (const TDesC8*)( &KClkIva2Pll_Bypass ), // EClkIva2Pll_Bypass + (const TDesC8*)( &KClkRM_F ), // EClkRM_F + (const TDesC8*)( &KClk96M ), // EClk96M + (const TDesC8*)( &KClk120M ), // EClk120M + (const TDesC8*)( &KClkSysOut ), // EClkSysOut + (const TDesC8*)( &KClkTv_F ), // EClkTv_F + (const TDesC8*)( &KClkDss1_F ), // EClkDss1_F + (const TDesC8*)( &KClkDss2_F ), // EClkDss2_F + (const TDesC8*)( &KClkCsi2_F ), // EClkCsi2_F + (const TDesC8*)( &KClkCam_F ), // EClkCam_F + (const TDesC8*)( &KClkIva2_F ), // EClkIva2_F + (const TDesC8*)( &KClkMmc1_F ), // EClkMmc1_F + (const TDesC8*)( &KClkMmc2_F ), // EClkMmc2_F + (const TDesC8*)( &KClkMmc3_F ), // EClkMmc3_F + (const TDesC8*)( &KClkMsPro_F ), // EClkMsPro_F + (const TDesC8*)( &KClkHdq_F ), // EClkHdq_F + (const TDesC8*)( &KClkMcBsp1_F ), // EClkMcBsp1_F + (const TDesC8*)( &KClkMcBsp2_F ), // EClkMcBsp2_F + (const TDesC8*)( &KClkMcBsp3_F ), // EClkMcBsp3_F + (const TDesC8*)( &KClkMcBsp4_F ), // EClkMcBsp4_F + (const TDesC8*)( &KClkMcBsp5_F ), // EClkMcBsp5_F + (const TDesC8*)( &KClkMcSpi1_F ), // EClkMcSpi1_F + (const TDesC8*)( &KClkMcSpi2_F ), // EClkMcSpi2_F + (const TDesC8*)( &KClkMcSpi3_F ), // EClkMcSpi3_F + (const TDesC8*)( &KClkMcSpi4_F ), // EClkMcSpi4_F + (const TDesC8*)( &KClkI2c1_F ), // EClkI2c1_F + (const TDesC8*)( &KClkI2c2_F ), // EClkI2c2_F + (const TDesC8*)( &KClkI2c3_F ), // EClkI2c3_F + (const TDesC8*)( &KClkUart1_F ), // EClkUart1_F + (const TDesC8*)( &KClkUart2_F ), // EClkUart2_F + (const TDesC8*)( &KClkUart3_F ), // EClkUart3_F + (const TDesC8*)( &KClkGpt1_F ), // EClkGpt1_F + (const TDesC8*)( &KClkGpt2_F ), // EClkGpt2_F + (const TDesC8*)( &KClkGpt3_F ), // EClkGpt3_F + (const TDesC8*)( &KClkGpt4_F ), // EClkGpt4_F + (const TDesC8*)( &KClkGpt5_F ), // EClkGpt5_F + (const TDesC8*)( &KClkGpt6_F ), // EClkGpt6_F + (const TDesC8*)( &KClkGpt7_F ), // EClkGpt7_F + (const TDesC8*)( &KClkGpt8_F ), // EClkGpt8_F + (const TDesC8*)( &KClkGpt9_F ), // EClkGpt9_F + (const TDesC8*)( &KClkGpt10_F ), // EClkGpt10_F + (const TDesC8*)( &KClkGpt11_F ), // EClkGpt11_F + (const TDesC8*)( &KClkUsbTll_F ), // EClkUsbTll_F + (const TDesC8*)( &KClkTs_F ), // EClkTs_F + (const TDesC8*)( &KClkCpeFuse_F ), // EClkCpeFuse_F + (const TDesC8*)( &KClkSgx_F ), // EClkSgx_F + (const TDesC8*)( &KClkUsim_F ), // EClkUsim_F + (const TDesC8*)( &KClkSmartReflex2_F ), // EClkSmartReflex2_F + (const TDesC8*)( &KClkSmartReflex1_F ), // EClkSmartReflex1_F + (const TDesC8*)( &KClkWdt2_F ), // EClkWdt2_F + (const TDesC8*)( &KClkWdt3_F ), // EClkWdt3_F + (const TDesC8*)( &KClkGpio1_F ), // EClkGpio1_F + (const TDesC8*)( &KClkGpio2_F ), // EClkGpio2_F + (const TDesC8*)( &KClkGpio3_F ), // EClkGpio3_F + (const TDesC8*)( &KClkGpio4_F ), // EClkGpio4_F + (const TDesC8*)( &KClkGpio5_F ), // EClkGpio5_F + (const TDesC8*)( &KClkGpio6_F ), // EClkGpio6_F + (const TDesC8*)( &KClkUsb120_F ), // EClkUsb120_F + (const TDesC8*)( &KClkUsb48_F ), // EClkUsb48_F + (const TDesC8*)( &KClkDss_I ), // EClkDss_I + (const TDesC8*)( &KClkCam_I ), // EClkCam_I + (const TDesC8*)( &KClkIcr_I ), // EClkIcr_I + (const TDesC8*)( &KClkMmc1_I ), // EClkMmc1_I + (const TDesC8*)( &KClkMmc2_I ), // EClkMmc2_I + (const TDesC8*)( &KClkMmc3_I ), // EClkMmc3_I + (const TDesC8*)( &KClkMsPro_I ), // EClkMsPro_I + (const TDesC8*)( &KClkHdq_I ), // EClkHdq_I + (const TDesC8*)( &KClkAes1_I ), // EClkAes1_I + (const TDesC8*)( &KClkAes2_I ), // EClkAes2_I + (const TDesC8*)( &KClkSha11_I ), // EClkSha11_I + (const TDesC8*)( &KClkSha12_I ), // EClkSha12_I + (const TDesC8*)( &KClkDes1_I ), // EClkDes1_I + (const TDesC8*)( &KClkDes2_I ), // EClkDes2_I + (const TDesC8*)( &KClkMcBsp1_I ), // EClkMcBsp1_I + (const TDesC8*)( &KClkMcBsp2_I ), // EClkMcBsp2_I + (const TDesC8*)( &KClkMcBsp3_I ), // EClkMcBsp3_I + (const TDesC8*)( &KClkMcBsp4_I ), // EClkMcBsp4_I + (const TDesC8*)( &KClkMcBsp5_I ), // EClkMcBsp5_I + (const TDesC8*)( &KClkI2c1_I ), // EClkI2c1_I + (const TDesC8*)( &KClkI2c2_I ), // EClkI2c2_I + (const TDesC8*)( &KClkI2c3_I ), // EClkI2c3_I + (const TDesC8*)( &KClkUart1_I ), // EClkUart1_I + (const TDesC8*)( &KClkUart2_I ), // EClkUart2_I + (const TDesC8*)( &KClkUart3_I ), // EClkUart3_I + (const TDesC8*)( &KClkMcSpi1_I ), // EClkMcSpi1_I + (const TDesC8*)( &KClkMcSpi2_I ), // EClkMcSpi2_I + (const TDesC8*)( &KClkMcSpi3_I ), // EClkMcSpi3_I + (const TDesC8*)( &KClkMcSpi4_I ), // EClkMcSpi4_I + (const TDesC8*)( &KClkGpt1_I ), // EClkGpt1_I + (const TDesC8*)( &KClkGpt2_I ), // EClkGpt2_I + (const TDesC8*)( &KClkGpt3_I ), // EClkGpt3_I + (const TDesC8*)( &KClkGpt4_I ), // EClkGpt4_I + (const TDesC8*)( &KClkGpt5_I ), // EClkGpt5_I + (const TDesC8*)( &KClkGpt6_I ), // EClkGpt6_I + (const TDesC8*)( &KClkGpt7_I ), // EClkGpt7_I + (const TDesC8*)( &KClkGpt8_I ), // EClkGpt8_I + (const TDesC8*)( &KClkGpt9_I ), // EClkGpt9_I + (const TDesC8*)( &KClkGpt10_I ), // EClkGpt10_I + (const TDesC8*)( &KClkGpt11_I ), // EClkGpt11_I + (const TDesC8*)( &KClkGpt12_I ), // EClkGpt12_I + (const TDesC8*)( &KClkMailboxes_I ), // EClkMailboxes_I + (const TDesC8*)( &KClkOmapSCM_I ), // EClkOmapSCM_I + (const TDesC8*)( &KClkHsUsbOtg_I ), // EClkHsUsbOtg_I + (const TDesC8*)( &KClkSdrc_I ), // EClkSdrc_I + (const TDesC8*)( &KClkPka_I ), // EClkPka_I + (const TDesC8*)( &KClkRng_I ), // EClkRng_I + (const TDesC8*)( &KClkUsbTll_I ), // EClkUsbTll_I + (const TDesC8*)( &KClkSgx_I ), // EClkSgx_I + (const TDesC8*)( &KClkUsim_I ), // EClkUsim_I + (const TDesC8*)( &KClkWdt1_I ), // EClkWdt1_I + (const TDesC8*)( &KClkWdt2_I ), // EClkWdt2_I + (const TDesC8*)( &KClkWdt3_I ), // EClkWdt3_I + (const TDesC8*)( &KClkGpio1_I ), // EClkGpio1_I + (const TDesC8*)( &KClkGpio2_I ), // EClkGpio2_I + (const TDesC8*)( &KClkGpio3_I ), // EClkGpio3_I + (const TDesC8*)( &KClkGpio4_I ), // EClkGpio4_I + (const TDesC8*)( &KClkGpio5_I ), // EClkGpio5_I + (const TDesC8*)( &KClkGpio6_I ), // EClkGpio6_I + (const TDesC8*)( &KClk32Sync_I ), // EClk32Sync_I + (const TDesC8*)( &KClkUsb_I ), // EClkUsb_I + (const TDesC8*)( &KClk48M ), // EClk48M + (const TDesC8*)( &KClk12M ), // EClk12M + (const TDesC8*)( &KClkSysClk ), // EClkSysClk + (const TDesC8*)( &KClkAltClk ), // EClkAltClk + (const TDesC8*)( &KClkSysClk32k ), // EClkSysClk32k + }; + +} +__ASSERT_COMPILE( (sizeof( KNames ) / sizeof( KNames[0] )) == Prcm::KSupportedClockCount ); + +namespace Prcm +{ +TSpinLock iLock(/*TSpinLock::EOrderGenericIrqLow0*/); // prevents concurrent access to the prcm hardware registers + +void Panic( TPanic aPanic ) + { + Kern::Fault( "PRCM", aPanic ); + } + +void InternalPanic( TInt aLine ) + { + Kern::Fault( "PRCMINT", aLine ); + } + +FORCE_INLINE void _BitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask ) + { + volatile TUint32* pR = (volatile TUint32*)aRegister; + *pR = (*pR & ~aClearMask) | aSetMask; + } + +FORCE_INLINE void _LockedBitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask ) + { + volatile TUint32* pR = (volatile TUint32*)aRegister; + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + *pR = (*pR & ~aClearMask) | aSetMask; + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + + +EXPORT_C void SetPllConfig( TPll aPll, const TPllConfiguration& aConfig ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllConfig(%x)", aPll ) ); + + __ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllConfigBadPll ) ); + + const TPllControlInfo& inf = KPllControlInfo[ aPll ]; + + __ASSERT_DEBUG( aConfig.iDivider <= KPllMaximumDivider, Panic( ESetPllConfigBadDivider ) ); + __ASSERT_DEBUG( aConfig.iMultiplier <= KPllMaximumMultiplier, Panic( ESetPllConfigBadMultiplier ) ); + __ASSERT_DEBUG( ((TUint)aConfig.iFreqRange <= EPllRange_1750_2100) + && ((TUint)aConfig.iFreqRange >= EPllRange_075_100), Panic( ESetPllConfigBadFreqRange ) ); + __ASSERT_DEBUG( ((TUint)aConfig.iRamp <= EPllRamp40us), Panic( ESetPllConfigBadRamp ) ); + __ASSERT_DEBUG( (TUint)aConfig.iDrift <= EPllDriftGuardEnabled, Panic( ESetPllConfigBadDrift ) ); + + TUint mult = (aConfig.iMultiplier bitand KPllMultiplierMask) << inf.iMultShift; + TUint div = ((aConfig.iDivider - 1) bitand KPllDividerMask) << inf.iDivShift; + TUint range = (aConfig.iFreqRange bitand KPllFreqRangeMask) << inf.iFreqSelShift; + TUint ramp = (aConfig.iRamp bitand KPllRampMask) << inf.iRampShift; + TUint drift = (aConfig.iDrift == EPllDriftGuardEnabled) ? (1 << inf.iDriftShift) : 0; + + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + // We must apply frequency range setting before new multuplier and divider + TUint clearMaskConfig = (KPllFreqRangeMask << inf.iFreqSelShift) + bitor (KPllRampMask << inf.iRampShift) + bitor (1 << inf.iDriftShift); + _BitClearSet( inf.iConfigRegister, clearMaskConfig, range | ramp | drift ); + + TUint clearMaskMulDiv = (KPllMultiplierMask << inf.iMultShift) bitor (KPllDividerMask << inf.iDivShift); + _BitClearSet( inf.iMulDivRegister, clearMaskMulDiv, mult | div ); + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +EXPORT_C void PllConfig( TPll aPll, TPllConfiguration& aConfigResult ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllConfig(%x)", aPll ) ); + + __ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllConfigBadPll ) ); + + const TPllControlInfo& inf = KPllControlInfo[ aPll ]; + + TUint32 config = AsspRegister::Read32( inf.iConfigRegister ); + TUint32 muldiv = AsspRegister::Read32( inf.iMulDivRegister ); + + aConfigResult.iMultiplier = (muldiv >> inf.iMultShift) bitand KPllMultiplierMask; + aConfigResult.iDivider = 1 + ((muldiv >> inf.iDivShift) bitand KPllDividerMask); + aConfigResult.iFreqRange = static_cast((config >> inf.iFreqSelShift) bitand KPllFreqRangeMask); + aConfigResult.iRamp = static_cast((config >> inf.iRampShift ) bitand KPllRampMask); + aConfigResult.iDrift = (config >> inf.iDriftShift ) bitand 1 ? EPllDriftGuardEnabled : EPllDriftGuardDisabled; + + __KTRACE_OPT( KPRCM, Kern::Printf( "DPLL%d: m=%d, d=%d, fr=%d, r=%d, dr=%d", + aPll + 1, + aConfigResult.iMultiplier, + aConfigResult.iDivider, + aConfigResult.iFreqRange, + aConfigResult.iRamp, + aConfigResult.iDrift ) ); + } + +EXPORT_C void SetPllLp( TPll aPll, TLpMode aLpMode ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllLp(%x)", aPll ) ); + + __ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllLpBadPll ) ); + __ASSERT_DEBUG( (aLpMode == ENormalMode) + || (aLpMode == ELpMode), Panic( ESetPllLpBadMode ) ); + + const TPllControlInfo& inf = KPllControlInfo[ aPll ]; + + TUint32 clear = 1 << inf.iLpShift; + TUint32 set = 0; + + if( ELpMode == aLpMode ) + { + set = clear; + clear = 0; + } + + _LockedBitClearSet( inf.iConfigRegister, clear, set ); + } + +EXPORT_C TLpMode PllLp( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllLp(%x)", aPll ) ); + + __ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllLpBadPll ) ); + + const TPllControlInfo& inf = KPllControlInfo[ aPll ]; + + TUint32 config = AsspRegister::Read32( inf.iConfigRegister ); + if( 0 == ((config >> inf.iLpShift) bitand 1) ) + { + return ENormalMode; + } + else + { + return ELpMode; + } + } + + +EXPORT_C void SetPllMode( TPll aPll, TPllMode aPllMode ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllMode(%x;%x)", aPll, aPllMode ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) ); + + TUint32 newMode; + TUint32 newAuto = KPllAutoOff; + + switch( aPllMode ) + { + default: + __DEBUG_ONLY( Panic( ESetPllModeBadMode ) ); + return; + + case EPllStop: + newMode = KPllModeStop; + break; + + case EPllBypass: + newMode = KPllModeBypass; + break; + + case EPllAuto: + newAuto = KPllAutoOn; + // fall through... + + case EPllRun: + newMode = KPllModeLock; + break; + + case EPllFastRelock: + newMode = KPllModeFastRelock; + break; + } + + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + + _BitClearSet( KPllMode[ aPll ].iModeRegister, + KPllModeMask << KPllMode[ aPll ].iModeShift, + newMode << KPllMode[ aPll ].iModeShift ); + + _BitClearSet( KPllMode[ aPll ].iAutoRegister, + KPllAutoMask << KPllMode[ aPll ].iAutoShift, + newAuto << KPllMode[ aPll ].iAutoShift ); + + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + + +EXPORT_C TPllMode PllMode( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) ); + + TUint32 mode = (AsspRegister::Read32( KPllMode[ aPll ].iModeRegister ) >> KPllMode[ aPll ].iModeShift) bitand KPllModeMask; + TUint32 autoSet = (AsspRegister::Read32( KPllMode[ aPll ].iAutoRegister ) >> KPllMode[ aPll ].iAutoShift) bitand KPllAutoMask; + + static const TPllMode modeTable[8][2] = + { // auto disabled auto enabled + { EPllStop, EPllStop }, // not possible + { EPllStop, EPllStop }, + { EPllStop, EPllStop }, // not possible + { EPllStop, EPllStop }, // not possible + { EPllStop, EPllStop }, // not possible + { EPllBypass, EPllBypass }, + { EPllFastRelock, EPllAuto }, + { EPllRun, EPllAuto }, + }; + return modeTable[ mode ][ (KPllAutoOff == autoSet) ? 0 : 1 ]; + } + +EXPORT_C void CalcPllFrequencyRange( TPll aPll, TPllConfiguration& aConfig ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::CalcPllFrequencyRange(%x)", aPll ) ); + + struct TFreqSelRange + { + TUint iMin; + TUint iMax; + TPllFrequencyRange iSetting; + }; + + const TFreqSelRange KRanges[] = + { + { 750000, 1000000, EPllRange_075_100 }, + { 1000001, 1250000, EPllRange_100_125 }, + { 1250001, 1500000, EPllRange_125_150 }, + { 1500001, 1750000, EPllRange_150_175 }, + { 1750001, 2100000, EPllRange_175_210 }, + { 7500000, 10000000, EPllRange_750_1000 }, + { 10000001, 12500000, EPllRange_1000_1250 }, + { 12500001, 15000000, EPllRange_1250_1500 }, + { 15000001, 17500000, EPllRange_1500_1750 }, + { 17500001, 21000000, EPllRange_1750_2100 }, + { 0, 0, EPllRange_1750_2100 } + }; + + // We have to work out the internal frequency from the source clock frequency and the + // divider factor N + + const TUint32 divider = aConfig.iDivider; + + TInt found = -1; + + if( divider > 0 ) + { + TUint fInternal = ClockFrequency( EClkSysClk ) / divider; + + // Find an appropriate range + for( TInt i = 0; KRanges[i].iMax > 0; ++i ) + { + if( fInternal < KRanges[i].iMin ) + { + // We've passed all possible ranges, work out whether current or previous is nearest + __DEBUG_ONLY( Panic( EPllInternalFrequencyOutOfRange ) ); + + if( i > 0 ) + { + // How near are we to minimum of current range? + TUint currentDiff = KRanges[i].iMin - fInternal; + + // How near are we to maximum of previous range? + TUint prevDiff = fInternal - KRanges[i - 1].iMax; + + found = (prevDiff < currentDiff) ? i - 1 : i; + } + else + { + // it's below minimum, so use minimum range + found = 0; + } + break; + } + else if( (KRanges[i].iMin <= fInternal) && (KRanges[i].iMax >= fInternal) ) + { + found = i; + break; + } + } + + } + // If we've fallen off end of list, use maximum setting + __ASSERT_DEBUG( found >= 0, Panic( EPllInternalFrequencyOutOfRange ) ); + aConfig.iFreqRange = (found >= 0) ? KRanges[ found ].iSetting : EPllRange_1750_2100; + } + + +EXPORT_C void AutoSetPllLpMode( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) ); + + const TUint32 reg = KPllControlInfo[ aPll ].iConfigRegister; + const TUint shift = KPllControlInfo[ aPll ].iLpShift; + + TUint freq = ClockFrequency( KPllToClock[ aPll ] ); + TUint32 clear = 1 << shift; + TUint32 set = 0; + if( freq <= KPllLpModeMaximumFrequency ) + { + // LP mode can be enabled + set = clear; + clear = 0; + } + _LockedBitClearSet( reg, clear, set ); + } + +EXPORT_C TBool PllIsLocked( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllIsLocked(%x)", aPll ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllIsLockedBadPll ) ); + + TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister; + TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit; + + return ( 0 != (AsspRegister::Read32( reg ) bitand lockMask) ); + } + +EXPORT_C void WaitForPllLock( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WaitForPllLock(%x)", aPll ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EWaitForPllLockBadPll ) ); + + TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister; + TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit; + + while( 0 == (AsspRegister::Read32( reg ) bitand lockMask) ); + } + +EXPORT_C void SetPllBypassDivider( TPll aPll, TBypassDivider aDivider ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllBypassDivider(%x;%x)", aPll, aDivider ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllBypassDividerBadPll ) ); + __ASSERT_DEBUG( (TUint)aDivider <= EBypassDiv4, Panic( ESetPllBypassDividerBadDivider ) ); + + static const TUint8 KLookupTable[] = + { + 1, // EBypassDiv1 + 2, // EBypassDiv2 + 4. // EBypassDiv4 + }; + + TUint32 div = KLookupTable[ aDivider ]; + + switch( aPll ) + { + case EDpll1: + _LockedBitClearSet( KCM_CLKSEL1_PLL_MPU, KBit19 | KBit20 | KBit21, div << 19 ); + break; + + case EDpll2: + _LockedBitClearSet( KCM_CLKSEL1_PLL_IVA2, KBit19 | KBit20 | KBit21, div << 19 ); + break; + + default: + break; + } + } + +EXPORT_C TBypassDivider PllBypassDivider( TPll aPll ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllBypassDivider(%x)", aPll ) ); + __ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllBypassDividerBadPll ) ); + + TUint div = 1; + + switch( aPll ) + { + case EDpll1: + div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_MPU ) >> 19) bitand 0x7; + break; + + case EDpll2: + div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_IVA2 ) >> 19) bitand 0x7; + break; + + default: + break; + } + + TBypassDivider result = EBypassDiv1; + + if( 2 == div ) + { + result = EBypassDiv2; + } + else if( 4 == div ) + { + result = EBypassDiv4; + } + + return result; + } + +EXPORT_C void SetDivider( TClock aClock, TUint aDivide ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetDivider(%x;%x)", aClock, aDivide ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetDividerBadClock ) ); + + const TDividerInfo& inf = KDividerInfo[ aClock ]; + + TUint32 div = aDivide; // most common case, special cases handled below + + switch( inf.iDivType ) + { + case EDivUsimClk: + // Special case, not suppored by this function - use SetUsimClockDivider() + return; + + default: + case EDivNotSupported: + Panic( ESetDividerUnsupportedClock ); + return; + + case EDiv_1_2: + if( (1 != aDivide ) && (2 != aDivide ) ) + { + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + } + break; + + case EDivCore_1_2_4: + if( (1 != aDivide ) && (2 != aDivide ) && (3 != aDivide) ) + { + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + } + break; + + case EDivCore_3_4_6_96M: + { + switch( aDivide ) + { + default: + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + + case 3: + div = 0; + break; + + case 4: + div = 1; + break; + + case 6: + div = 2; + break; + + case 0: + // Special-case, use 96MHz clock + div = 3; + break; + } + break; + } + + case EDivPll_1_To_16: + if( (aDivide < 1) || (aDivide > 16) ) + { + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + } + break; + + case EDivPll_1_To_31: + if( (aDivide < 1) || (aDivide > 16) ) + { + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + } + break; + + + + case EDivClkOut_1_2_4_8_16: + { + switch( aDivide ) + { + default: + __DEBUG_ONLY( Panic( ESetDividerBadDivider ) ); + return; + + case 1: + div = 0; + break; + + case 2: + div = 1; + break; + + case 4: + div = 2; + break; + + case 8: + div = 3; + break; + + case 16: + div = 4; + break; + } + break; + } + } + + // if we get here, we have a valid divider value + + _LockedBitClearSet( inf.iRegister, inf.iMask, div << inf.iShift ); + } + +EXPORT_C TUint Divider( TClock aClock ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::Divider(%x)", aClock ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetDividerBadClock ) ); + + const TDividerInfo& inf = KDividerInfo[ aClock ]; + + TUint32 div = ( AsspRegister::Read32( inf.iRegister ) bitand inf.iMask ) >> inf.iShift; + TUint result = div; // most common case + + switch( inf.iDivType ) + { + case EDivUsimClk: + return UsimDivider(); + + default: + case EDivNotSupported: + Panic( ESetDividerUnsupportedClock ); + return 0xFFFFFFFF; + + // These are all the standard case, where value in register is divide factor + case EDiv_1_2: + case EDivCore_1_2_4: + case EDivPll_1_To_16: + case EDivPll_1_To_31: + break; + + case EDivCore_3_4_6_96M: + { + switch( div ) + { + default: + // hardware value has unknown meaning + result = 0xFFFFFFFF; + + case 0: + result = 3; + break; + + case 1: + result = 4; + break; + + case 2: + result = 6; + break; + + case 3: + result = 0; + break; + } + break; + } + + case EDivClkOut_1_2_4_8_16: + { + switch( div ) + { + default: + // hardware value has unknown meaning + result = 0xFFFFFFFF; + + case 0: + result = 1; + break; + + case 1: + result = 2; + break; + + case 2: + result = 4; + break; + + case 3: + result = 8; + break; + + case 4: + result = 16; + break; + } + break; + } + } + + return result; + } + +EXPORT_C void SetPowerDomainMode( TPowerDomain aDomain, TPowerDomainMode aMode ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPowerDomainMode(%x;%x)", aDomain, aMode ) ); + __ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( ESetDomainModeBadDomain ) ); + __ASSERT_DEBUG( (TUint)aMode <= EPowerOn, Panic( ESetDomainModeBadMode ) ); + + __ASSERT_DEBUG( 0 != (KPowerDomainControl[ aDomain ].iAllowedMask bitand (1 << aMode)), Panic( ESetDomainModeUnsupportedMode ) ); + + TUint shift = KPowerDomainControl[ aDomain ].iShift; + + _LockedBitClearSet( KPowerDomainControl[ aDomain ].iRegister, + KPowerModeMask << shift, + aMode << shift ); + } + +EXPORT_C TPowerDomainMode PowerDomainMode( TPowerDomain aDomain ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PowerDomainMode(%x)", aDomain ) ); + __ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( EGetDomainModeBadDomain ) ); + + TUint32 m = (AsspRegister::Read32( KPowerDomainControl[ aDomain ].iRegister ) >> KPowerDomainControl[ aDomain ].iShift) bitand KPowerModeMask; + return static_cast< TPowerDomainMode >( m ); + } + +EXPORT_C void SetClockState( TClock aClock, TClockState aState ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockState(%x;%x)", aClock, aState ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetStateBadClock ) ); + + const TClockEnableAutoInfo& def = KClockControlTable[ aClock ]; + + TUint32 reg = def.iGate.iRegister; + TUint32 mask = def.iGate.iMask; + TUint32 autoReg = def.iAuto.iRegister; + TUint32 autoMask = def.iAuto.iMask; + + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + + if( EClkOn == aState ) + { + _BitClearSet( reg, mask, def.iGate.iEnablePattern ); + _BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern ); + } + else if( EClkOff == aState ) + { + _BitClearSet( reg, mask, def.iGate.iDisablePattern ); + _BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern ); + } + else if( EClkAuto == aState ) + { + _BitClearSet( autoReg, autoMask, def.iAuto.iEnablePattern ); + _BitClearSet( reg, mask, def.iGate.iEnablePattern ); + } + + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +EXPORT_C TClockState ClockState( TClock aClock ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "+Prcm::ClockState(%x)", aClock ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetStateBadClock ) ); + + const TClockEnableAutoInfo& def = KClockControlTable[ aClock ]; + + TUint32 reg = def.iGate.iRegister; + TUint32 mask = def.iGate.iMask; + TUint32 autoReg = def.iAuto.iRegister; + TUint32 autoMask = def.iAuto.iMask; + + TUint32 enable = AsspRegister::Read32( reg ) bitand mask; + TUint32 autoClock = AsspRegister::Read32( autoReg ) bitand autoMask; + + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockState(%x):e:%x a:%x", aClock, enable, autoClock ) ); + + TClockState state = EClkAuto; + + // OFF = OFF + // ON + AUTO = AUTO + // ON + !AUTO = ON + if( def.iGate.iEnablePattern != enable ) + { + state = EClkOff; + } + else if( def.iAuto.iEnablePattern != autoClock ) + { + state = EClkOn; + } + + __KTRACE_OPT( KPRCM, Kern::Printf( "-Prcm::ClockState(%x):%d", aClock, state ) ); + + return state; + } + +EXPORT_C void SetWakeupMode( TClock aClock, TWakeupMode aMode ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetWakeupMode(%x;%x)", aClock, aMode ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetWakeupBadClock ) ); + + const TRegisterBitDef& def = KClockWakeupTable[ aClock ]; + + TUint32 reg = def.iRegister; + TUint32 mask = def.iMask; + + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + + if( EWakeupEnabled == aMode ) + { + _BitClearSet( reg, mask, def.iEnablePattern ); + } + else + { + _BitClearSet( reg, mask, def.iDisablePattern ); + } + + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +EXPORT_C TWakeupMode WakeupMode( TClock aClock ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WakeupMode(%x)", aClock ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupBadClock ) ); + + const TRegisterBitDef& def = KClockWakeupTable[ aClock ]; + + TUint32 reg = def.iRegister; + TUint32 mask = def.iMask; + + if( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) ) + { + return EWakeupEnabled; + } + else + { + return EWakeupDisabled; + } + } + +EXPORT_C void AddToWakeupGroup( TClock aClock, TWakeupGroup aGroup ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupGroup(%x;%x)", aClock, aGroup ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EAddWakeupGroupBadClock ) ); + __ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EAddWakeupGroupBadGroup ) ); + + const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ]; + + TUint32 reg = def.iRegister; + TUint32 mask = def.iMask; + + _LockedBitClearSet( reg, mask, def.iEnablePattern ); + } + +EXPORT_C void RemoveFromWakeupGroup( TClock aClock, TWakeupGroup aGroup ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupGroup(%x;%x)", aClock, aGroup ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ERemoveWakeupGroupBadClock ) ); + __ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( ERemoveWakeupGroupBadGroup ) ); + + const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ]; + + TUint32 reg = def.iRegister; + TUint32 mask = def.iMask; + + _LockedBitClearSet( reg, mask, def.iDisablePattern ); + } + +EXPORT_C TBool IsInWakeupGroup( TClock aClock, TWakeupGroup aGroup ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupGroup(%x)", aClock ) ); + + __ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupGroupBadClock ) ); + __ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EGetWakeupGroupBadGroup ) ); + + const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ]; + + TUint32 reg = def.iRegister; + TUint32 mask = def.iMask; + + return( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) ); + } + + +EXPORT_C void AddToWakeupDomain( TClock aClock, TWakeupDomain aDomain ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupDomain(%x;%x)", aClock, aDomain ) ); + + __ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( EAddDomainBadClock ) ); + __ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( EAddDomainBadDomain ) ); + + const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ]; + TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000 + + _LockedBitClearSet( inf.iRegister, KClearNone, mask ); + } + +EXPORT_C void RemoveFromWakeupDomain( TClock aClock, TWakeupDomain aDomain ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupDomain(%x;%x)", aClock, aDomain ) ); + + __ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ERemoveDomainBadClock ) ); + __ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ERemoveDomainBadDomain ) ); + + const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ]; + TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000 + + _LockedBitClearSet( inf.iRegister, mask, KSetNone ); + } + +EXPORT_C TBool IsInWakeupDomain( TClock aClock, TWakeupDomain aDomain ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupDomain(%x;%x)", aClock, aDomain ) ); + + __ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ECheckDomainBadClock ) ); + __ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ECheckDomainBadDomain ) ); + + const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ]; + TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000 + + return ( 0 != (AsspRegister::Read32( inf.iRegister ) bitand mask) ); + } + +EXPORT_C void SetGptClockSource( TGpt aGpt, TGptClockSource aSource ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetGptClockSource(%x;%x)", aGpt, aSource ) ); + + __ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) ); + + + TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister; + TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask; + TUint32 setPattern = (EGptClockSysClk == aSource ) ? mask : 0; + + _LockedBitClearSet( reg, mask, setPattern ); + } + +EXPORT_C TGptClockSource GptClockSource( TGpt aGpt ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::GptClockSource(%x)", aGpt ) ); + + __ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) ); + + TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister; + TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask; + + if( 0 == (AsspRegister::Read32( reg ) bitand mask) ) + { + return EGptClock32k; + } + else + { + return EGptClockSysClk; + } + } + +EXPORT_C TUint UsimDivider() + { + const TDividerInfo& info = KDividerInfo[ EClkUsim_F ]; + TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift; + return UsimDivMuxInfo[ divmux ].iDivider; + } + +EXPORT_C TClock UsimClockSource() + { + const TDividerInfo& info = KDividerInfo[ EClkUsim_F ]; + TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift; + return UsimDivMuxInfo[ divmux ].iClock; + } + +EXPORT_C void SetClockMux( TClock aClock, TClock aSource ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockMux(%x;%x)", aClock, aSource ) ); + + switch( aClock ) + { + case EClk96M: + { + TUint set = KBit6; + TUint clear = 0; + + switch( aSource ) + { + case EClkPeriph: + clear = KBit6; + set = 0; + // fall through... + + case EClkSysClk: + _LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set ); + break; + + default: + Panic( ESetClockMuxBadSource ); + } + break; + } + + case EClkSysOut: + { + TUint set; + switch( aSource ) + { + case EClkCore: + set = 0; + break; + + case EClkSysClk: + set = 1; + break; + + case EClkPeriph: + set = 2; + break; + + case EClkTv_F: + set = 3; + break; + + default: + Panic( ESetClockMuxBadSource ); + return; + } + + _LockedBitClearSet( KCM_CLKOUT_CTRL, KBit1 | KBit0, set ); + break; + } + + case EClkTv_F: + { + TUint set = KBit5; + TUint clear = 0; + + switch( aSource ) + { + case EClkPeriph: + clear = KBit5; + set = 0; + // fall through... + + case EClkAltClk: + _LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set ); + break; + + default: + Panic( ESetClockMuxBadSource ); + return; + } + break; + } + + case EClkGpt1_F: + case EClkGpt2_F: + case EClkGpt3_F: + case EClkGpt4_F: + case EClkGpt5_F: + case EClkGpt6_F: + case EClkGpt7_F: + case EClkGpt8_F: + case EClkGpt9_F: + { + TGptClockSource src = EGptClock32k; + + switch( aSource ) + { + case EClkSysClk: + src = EGptClockSysClk; + case EClkSysClk32k: + break; + default: + Panic( ESetClockMuxBadSource ); + return; + } + + SetGptClockSource( KClockSourceInfo[ aClock ].iGpt, src ); + break; + } + + case EClkSgx_F: + switch( aSource ) + { + case EClk96M: + SetDivider( EClkSgx_F, 0 ); + break; + + case EClkCore: + // Unfortunately the combined divider/mux means that switching from + // CORE t 96M loses the old divider values + if( 0 != Divider( EClkSgx_F ) ) + { + // Not currently CORE, switch to default maximum divider + SetDivider( EClkSgx_F, 6 ); + } + break; + + default: + Panic( ESetClockMuxBadSource ); + return; + } + break; + + + case EClk48M: + { + TUint set = KBit3; + TUint clear = 0; + + switch( aSource ) + { + case EClkPeriph: + clear = KBit3; + set = 0; + // fall through... + + case EClkAltClk: + _LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set ); + break; + + default: + Panic( ESetClockMuxBadSource ); + return; + } + break; + } + + default: + Panic( ESetClockMuxBadClock ); + return; + } + } + +EXPORT_C TClock ClockMux( TClock aClock ) + { + __KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockMux(%x)", aClock ) ); + + TClock result; + + switch( aClock ) + { + case EClk96M: + if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit6 ) ) + { + result = EClkPeriph; + } + else + { + result = EClkSysClk; + } + break; + + case EClkSysOut: + switch( AsspRegister::Read32( KCM_CLKOUT_CTRL ) bitand (KBit1 | KBit0) ) + { + default: + case 0: + result = EClkCore; + break; + + case 1: + result = EClkSysClk; + break; + + case 2: + result = EClkPeriph; + break; + + case 3: + result = EClkTv_F; // same as 54MHz clock + break; + } + break; + + case EClkTv_F: + if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit5 ) ) + { + result = EClkPeriph; + } + else + { + result = EClkAltClk; + } + break; + + case EClkGpt1_F: + case EClkGpt2_F: + case EClkGpt3_F: + case EClkGpt4_F: + case EClkGpt5_F: + case EClkGpt6_F: + case EClkGpt7_F: + case EClkGpt8_F: + case EClkGpt9_F: + case EClkGpt10_F: + case EClkGpt11_F: + // Redirect these to GptClockSource() + if( EGptClockSysClk == GptClockSource( KClockSourceInfo[ aClock ].iGpt ) ) + { + result = EClkSysClk; + } + else + { + result = EClkSysClk32k; + } + break; + + case EClkSgx_F: + if( Divider( EClkSgx_F ) == 0 ) + { + result = EClk96M; + } + else + { + result = EClkCore; + } + break; + + case EClkUsim_F: + result = UsimClockSource(); + break; + + case EClk48M: + if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit3 ) ) + { + result = EClk96M; + } + else + { + result = EClkAltClk; + } + break; + + default: + Panic( EGetClockMuxBadClock ); + return EClkAltClk; // dumy to stop compiler warning + } + + return result; + } + +EXPORT_C TUint ClockFrequency( TClock aClock ) + { + // Works out the frequency by traversing backwards through the clock chain + // assumulating a multply and divide factor until SYSCLK or SYSCLK32 is reached + // Reaching a DPLL implicitly means SYSCLK has been reached + + TUint mul = 1; + TUint div = 1; + TClock currentClock = aClock; + __ASSERT_ALWAYS( currentClock < Prcm::KSupportedClockCount, Panic( EClockFrequencyBadClock ) ); + + // Ensure assumption that root clock range is >=EClkSysClk + __ASSERT_COMPILE( EClkSysClk < EClkAltClk ); + __ASSERT_COMPILE( EClkAltClk < EClkSysClk32k ); + __ASSERT_COMPILE( (TUint)EClkSysClk32k == (TUint)KSupportedClockCount - 1 ); + + while( currentClock < EClkSysClk ) + { + // Get previous clock in chain + TClock prevClock = KClockSourceInfo[ currentClock ].iClock; + + switch( KClockSourceInfo[ currentClock ].iType ) + { + case EIgnore: + return 0; // unsupported clock + + case EDpll: + { + TPll pll = KClockSourceInfo[ currentClock ].iPll; + + if( PllMode( pll ) == EPllBypass ) + { + if( EDpll1 == pll ) + { + prevClock = Prcm::EClkMpuPll_Bypass; + } + else if( EDpll2 == pll ) + { + prevClock = Prcm::EClkIva2Pll_Bypass; + } + else + { + // for all other DPLL1 the bypass clock is the input clock SYSCLK + prevClock = EClkSysClk; + } + } + else + { + TPllConfiguration pllCfg; + PllConfig( pll, pllCfg ); + mul *= pllCfg.iMultiplier; + div *= pllCfg.iDivider; + if( EDpll4 == pll ) + { + // Output is multiplied by 2 for DPLL4 + mul *= 2; + } + prevClock = EClkSysClk; + } + break; + } + + case EMux: + prevClock = ClockMux( currentClock ); + break; + + case EDivMux: + // need to find what clock the divider is fed from + prevClock = ClockMux( currentClock ); + // fall through to get divider.. + + case EDivider: + { + TUint selectedDiv = Divider( currentClock ); + // Special case for SGX - ignore a return of 0 + if( 0 != selectedDiv ) + { + div *= selectedDiv; + } + break; + } + + case EDuplicate: + // Nothing to do, we just follow to the next clock + break; + + case E48MMux: + prevClock = ClockMux( currentClock ); + if( prevClock != EClkAltClk ) + { + div *= 2; + } + break; + + case E54MMux: + prevClock = ClockMux( currentClock ); + if( prevClock != EClkAltClk ) + { + div *= Divider( currentClock ); + } + break; + + case E96MMux: + prevClock = ClockMux( currentClock ); + if( prevClock != EClkSysClk ) + { + div *= Divider( currentClock ); + } + break; + + case EDiv4: + div *= 4; + break; + } + + currentClock = prevClock; + } // end do + + // When we reach here we have worked back to the origin clock + + TUint64 fSrc; + const Omap3530Assp* variant = (Omap3530Assp*)Arch::TheAsic(); + + if( EClkSysClk == currentClock ) + { + // input OSC_SYSCLK is always divided by 2 before being fed to SYS_CLK + fSrc = variant->SysClkFrequency() / 2; + } + else if( EClkSysClk32k == currentClock ) + { + fSrc = variant->SysClk32kFrequency(); + } + else + { + fSrc = variant->AltClkFrequency(); + } + + if( div == 0 ) + { + // to account for any registers set at illegal values + return 0; + } + else + { + return (TUint)((fSrc * mul) / div); + } + } + +EXPORT_C void SetSysClkFrequency( TSysClkFrequency aFrequency ) + { + static const TUint8 KConfigValues[] = + { + 0, // ESysClk12MHz + 1, // ESysClk13MHz + 5, // ESysClk16_8MHz + 2, // ESysClk19_2MHz + 3, // ESysClk26MHz + 4 // ESysClk38_4MHz + }; + + _LockedBitClearSet( KPRM_CLKSEL, KBit0 | KBit1 | KBit2, KConfigValues[ aFrequency ] ); + } + +/** Get the currently configured SysClk frequency */ +EXPORT_C TSysClkFrequency SysClkFrequency() + { + + switch( AsspRegister::Read32( KPRM_CLKSEL ) bitand (KBit0 | KBit1 | KBit2) ) + { + case 0: + return ESysClk12MHz; + case 1: + return ESysClk13MHz; + case 2: + return ESysClk19_2MHz; + case 3: + return ESysClk26MHz; + case 4: + return ESysClk38_4MHz; + case 5: + return ESysClk16_8MHz; + default: + __DEBUG_ONLY( InternalPanic( __LINE__ ) ); + return ESysClk13MHz; + } + } + + +EXPORT_C const TDesC& PrmName( TClock aClock ) + { + __ASSERT_DEBUG( (TUint)aClock <= KSupportedClockCount, Panic( EGetNameBadClock ) ); + __ASSERT_DEBUG( KNames[ aClock ] != NULL, Kern::Fault( "PrmName", aClock ) ); + + return *KNames[ aClock ]; + } + +EXPORT_C void Init3() + { + // Enable LP mode if possible on MPU and CORE PLLs. + // Don't enable on PERIPHERAL, IVA2 or USB because LP mode introduces jitter + AutoSetPllLpMode( EDpll1 ); + AutoSetPllLpMode( EDpll3 ); + + TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + TUint32 r; + + // IVA2 +// Not yet mapped! const TUint32 KPDCCMD = Omap3530HwBase::TVirtual<0x01810000>::Value; +// r = AsspRegister::Read32(KPDCCMD); +// AsspRegister::Modify32(KPDCCMD, 0, 1 << 16); +// Set(KCM_FCLKEN_IVA2, 1 << 0, 0); + // CAM + const TUint32 KISP_CTRL = Omap3530HwBase::TVirtual<0x480BC040>::Value; + r = AsspRegister::Read32(KISP_CTRL); + _BitClearSet(KISP_CTRL, 0xf << 10, 0); + _BitClearSet(KCM_FCLKEN_CAM, 1 << 0, 0); + _BitClearSet(KCM_ICLKEN_CAM, 1 << 0, 0); + + // MMC + r = AsspRegister::Read32(KMMCHS1_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMmc1_F, EClkOff ); + SetClockState( EClkMmc1_I, EClkOff ); + r = AsspRegister::Read32(KMMCHS2_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMmc2_F, EClkOff ); + SetClockState( EClkMmc2_I, EClkOff ); +/* There is no MMC3 on the beagle board + r = AsspRegister::Read32(KMMCHS3_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); +*/ + SetClockState( EClkMmc3_F, EClkOff ); + SetClockState( EClkMmc3_I, EClkOff ); + + // McBSP + r = AsspRegister::Read32(KMCBSPLP1_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcBsp1_F, EClkOff ); + SetClockState( EClkMcBsp1_I, EClkOff ); + const TUint32 KMCBSPLP2_SPCR1 = Omap3530HwBase::TVirtual<0x49022014>::Value; + _BitClearSet(KMCBSPLP2_SPCR1, 1 << 0, 0); // RRST := 0 + const TUint32 KMCBSPLP2_SPCR2 = Omap3530HwBase::TVirtual<0x49022010>::Value; + _BitClearSet(KMCBSPLP2_SPCR2, 1 << 7 | 1 << 0, 0); // FRST, XRST := 0 + _BitClearSet(KMCBSPLP2_SYSCONFIG, 0x3 << 8 | 0x3 << 3, 0); // CLOCKACTIVITY := can be switched off, SIDLEMODE := force idle + r = AsspRegister::Read32(KMCBSPLP2_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcBsp2_F, EClkOff ); + SetClockState( EClkMcBsp2_I, EClkOff ); + r = AsspRegister::Read32(KMCBSPLP3_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcBsp3_F, EClkOff ); + SetClockState( EClkMcBsp3_I, EClkOff ); + r = AsspRegister::Read32(KMCBSPLP4_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcBsp4_F, EClkOff ); + SetClockState( EClkMcBsp4_I, EClkOff ); + r = AsspRegister::Read32(KMCBSPLP5_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcBsp5_F, EClkOff ); + SetClockState( EClkMcBsp5_I, EClkOff ); + + // McSPI + r = AsspRegister::Read32(KMCSPI1_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcSpi1_F, EClkOff ); + SetClockState( EClkMcSpi1_I, EClkOff ); + r = AsspRegister::Read32(KMCSPI2_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcSpi2_F, EClkOff ); + SetClockState( EClkMcSpi2_I, EClkOff ); + r = AsspRegister::Read32(KMCSPI3_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcSpi3_F, EClkOff ); + SetClockState( EClkMcSpi3_I, EClkOff ); + r = AsspRegister::Read32(KMCSPI4_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkMcSpi4_F, EClkOff ); + SetClockState( EClkMcSpi4_I, EClkOff ); + + // UART + TInt debugport = Kern::SuperPage().iDebugPort; + if( debugport != 0 ) + { + r = AsspRegister::Read32(KUART1_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + SetClockState( EClkUart1_F, EClkOff ); + SetClockState( EClkUart1_I, EClkOff ); + } + if( debugport != 1 ) + { + r = AsspRegister::Read32(KUART2_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + SetClockState( EClkUart2_F, EClkOff ); + SetClockState( EClkUart2_I, EClkOff ); + } + if( debugport != 2 ) + { + r = AsspRegister::Read32(KUART3_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + SetClockState( EClkUart3_F, EClkOff ); + SetClockState( EClkUart3_I, EClkOff ); + } + + // I2C KI2C1_SYSC + r = AsspRegister::Read32(KI2C1_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkI2c1_F, EClkOff ); + SetClockState( EClkI2c1_I, EClkOff ); + r = AsspRegister::Read32(KI2C2_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkI2c2_F, EClkOff ); + SetClockState( EClkI2c2_I, EClkOff ); + r = AsspRegister::Read32(KI2C3_SYSC); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkI2c3_F, EClkOff ); + SetClockState( EClkI2c3_I, EClkOff ); + + // GPT + r = AsspRegister::Read32(KTI1OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt1_F, EClkOff ); + SetClockState( EClkGpt1_I, EClkOff ); + r = AsspRegister::Read32(KTI2OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt2_F, EClkOff ); + SetClockState( EClkGpt2_I, EClkOff ); + r = AsspRegister::Read32(KTI3OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt3_F, EClkOff ); + SetClockState( EClkGpt3_I, EClkOff ); + r = AsspRegister::Read32(KTI4OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt4_F, EClkOff ); + SetClockState( EClkGpt4_I, EClkOff ); + r = AsspRegister::Read32(KTI5OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt5_F, EClkOff ); + SetClockState( EClkGpt5_I, EClkOff ); + r = AsspRegister::Read32(KTI6OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt6_F, EClkOff ); + SetClockState( EClkGpt6_I, EClkOff ); + r = AsspRegister::Read32(KTI7OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt7_F, EClkOff ); + SetClockState( EClkGpt7_I, EClkOff ); + r = AsspRegister::Read32(KTI8OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt8_F, EClkOff ); + SetClockState( EClkGpt8_I, EClkOff ); + r = AsspRegister::Read32(KTI9OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt9_F, EClkOff ); + SetClockState( EClkGpt9_I, EClkOff ); + r = AsspRegister::Read32(KTI10OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt10_F, EClkOff ); + SetClockState( EClkGpt10_I, EClkOff ); + r = AsspRegister::Read32(KTI11OCP_CFG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkGpt11_F, EClkOff ); + SetClockState( EClkGpt11_I, EClkOff ); + + // WDT + r = AsspRegister::Read32(KWD2_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkWdt2_F, EClkOff ); + SetClockState( EClkWdt2_I, EClkOff ); + r = AsspRegister::Read32(KWD3_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + SetClockState( EClkWdt3_F, EClkOff ); + SetClockState( EClkWdt3_I, EClkOff ); + + // GPIO + /* + r = AsspRegister::Read32(KGPIO1_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + _BitClearSet(KCM_FCLKEN_WKUP, 1 << 3, 0); + _BitClearSet(KCM_ICLKEN_WKUP, 1 << 3, 0); + + //r = AsspRegister::Read32(KGPIO2_SYSCONFIG); + //__NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + //__NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + //_BitClearSet(KCM_FCLKEN_PER, 1 << 13, 0); + //_BitClearSet(KCM_ICLKEN_PER, 1 << 13, 0); + r = AsspRegister::Read32(KGPIO3_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + _BitClearSet(KCM_FCLKEN_PER, 1 << 14, 0); + _BitClearSet(KCM_ICLKEN_PER, 1 << 14, 0); + r = AsspRegister::Read32(KGPIO4_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + _BitClearSet(KCM_FCLKEN_PER, 1 << 15, 0); + _BitClearSet(KCM_ICLKEN_PER, 1 << 15, 0); + r = AsspRegister::Read32(KGPIO5_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + _BitClearSet(KCM_FCLKEN_PER, 1 << 16, 0); + _BitClearSet(KCM_ICLKEN_PER, 1 << 16, 0); + r = AsspRegister::Read32(KGPIO6_SYSCONFIG); + __NK_ASSERT_ALWAYS((r & 1 << 3) == 0); + __NK_ASSERT_ALWAYS((r & 1 << 8) == 0); + _BitClearSet(KCM_FCLKEN_PER, 1 << 17, 0); + _BitClearSet(KCM_ICLKEN_PER, 1 << 17, 0); + */ + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +} // end namespace Prcm + + +NONSHARABLE_CLASS( TPrcmInterruptDispatch ): public MInterruptDispatcher + { + public: + TInt Init(); + virtual TInt Bind(TInt aId, TIsr anIsr, TAny* aPtr) ; + virtual TInt Unbind(TInt aId); + virtual TInt Enable(TInt aId); + virtual TInt Disable(TInt aId); + virtual TInt Clear(TInt aId); + virtual TInt SetPriority(TInt aId, TInt aPriority); + + private: + static void Spurious( TAny* aId ); + static void Dispatch( TAny* aParam ); + }; + +SInterruptHandler Handlers[ Prcm::KInterruptCount ]; +TInt TheRootInterruptEnable = 0; +TSpinLock iIntLock(/*TSpinLock::EOrderGenericIrqLow0*/); +TPrcmInterruptDispatch TheIntDispatcher; + +void TPrcmInterruptDispatch::Spurious( TAny* aId ) + { + Kern::Fault( "PRCM:Spurious", (TInt)aId ); + } + +void TPrcmInterruptDispatch::Dispatch( TAny* /*aParam*/ ) + { + TUint32 status = AsspRegister::Read32( KPRM_IRQSTATUS_MPU ) + bitand AsspRegister::Read32( KPRM_IRQENABLE_MPU ); + + for( TInt i = 0; (status) && (i < Prcm::KInterruptCount); ++i ) + { + if( status bitand 1 ) + { + (*Handlers[i].iIsr)( Handlers[i].iPtr ); + } + status >>= 1; + } + } + +TInt TPrcmInterruptDispatch::Init() + { + // Disable all interrupts + AsspRegister::Write32( KPRM_IRQENABLE_MPU, 0 ); + AsspRegister::Write32( KPRM_IRQSTATUS_MPU, KSetAll ); + + // Bind all to spurious handler + for( TInt i = 0; i < Prcm::KInterruptCount; ++i ) + { + Handlers[i].iIsr = TPrcmInterruptDispatch::Spurious; + Handlers[i].iPtr = (TAny*)(i + (EIrqRangeBasePrcm << KIrqRangeIndexShift)); + } + + TInt r = Interrupt::Bind( EOmap3530_IRQ11_PRCM_MPU_IRQ, TPrcmInterruptDispatch::Dispatch, this ); + if( KErrNone == r ) + { + Register( EIrqRangeBasePrcm ); + } + return r; + } + +TInt TPrcmInterruptDispatch::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TUint id = aId bitand KIrqNumberMask; + TInt r; + + if( id < Prcm::KInterruptCount ) + { + if( Handlers[ id ].iIsr != TPrcmInterruptDispatch::Spurious ) + { + r = KErrInUse; + } + else + { + Handlers[ id ].iIsr = aIsr; + Handlers[ id ].iPtr = aPtr; + r = KErrNone; + } + } + else + { + r = KErrArgument; + } + return r; + } + +TInt TPrcmInterruptDispatch::Unbind(TInt aId) + { + TUint id = aId bitand KIrqNumberMask; + TInt r; + + if( id < Prcm::KInterruptCount ) + { + if( Handlers[ id ].iIsr == TPrcmInterruptDispatch::Spurious ) + { + r = KErrGeneral; + } + else + { + Handlers[ id ].iIsr = TPrcmInterruptDispatch::Spurious; + r = KErrNone; + } + } + else + { + r = KErrArgument; + } + return r; + } + +TInt TPrcmInterruptDispatch::Enable(TInt aId) + { + TUint id = aId bitand KIrqNumberMask; + + if( id < Prcm::KInterruptCount ) + { + TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock); + if( ++TheRootInterruptEnable == 1 ) + { + Interrupt::Enable( EOmap3530_IRQ11_PRCM_MPU_IRQ ); + } + Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, KClearNone, 1 << id ); + __SPIN_UNLOCK_IRQRESTORE(iIntLock, irq); + return KErrNone; + } + else + { + return KErrArgument; + } + } + +TInt TPrcmInterruptDispatch::Disable(TInt aId) + { + TUint id = aId bitand KIrqNumberMask; + + if( id < Prcm::KInterruptCount ) + { + TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock); + if( --TheRootInterruptEnable == 0 ) + { + Interrupt::Disable( EOmap3530_IRQ11_PRCM_MPU_IRQ ); + } + Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, 1 << id, KSetNone ); + __SPIN_UNLOCK_IRQRESTORE(iIntLock, irq); + return KErrNone; + } + else + { + return KErrArgument; + } + } + +TInt TPrcmInterruptDispatch::Clear(TInt aId) + { + TUint id = aId bitand KIrqNumberMask; + TInt r; + + if( id < Prcm::KInterruptCount ) + { + AsspRegister::Write32( KPRM_IRQSTATUS_MPU, 1 << id ); + r = KErrNone; + } + else + { + r = KErrArgument; + } + return r; + } + +TInt TPrcmInterruptDispatch::SetPriority(TInt anId, TInt aPriority) + { + return KErrNotSupported; + } + + + +DECLARE_STANDARD_EXTENSION() + { + return TheIntDispatcher.Init(); + } + + + + + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/prcm.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/prcm.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,38 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/prcm/prcm.mmp +// + +#include +#include "kernel/kern_ext.mmh" + +TARGET AsspTarget(prcm, dll) +TARGETTYPE kext +LINKAS prcm.dll +DEFFILE ./def/~/prcm.def +NOSTRICTDEF + +SOURCEPATH . +SOURCE prcm.cpp + +USERINCLUDE . +SYSTEMINCLUDE +\include\assp\omap3530_assp\ + +LIBRARY AsspTarget(kaomap3530, lib) + +EPOCALLOWDLLDATA + +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/prcm/prcm_regs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/prcm/prcm_regs.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,286 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// \omap3530\omap3530_assp\prcm_regs.h. +// This file is part of the Beagle Base port +// + +#ifndef __PRCM_REGS_H__ +#define __PRCM_REGS_H__ + +#include "omap3530_hardware_base.h" + +namespace +{ +const TUint32 KCM_CLKSEL_CORE = Omap3530HwBase::TVirtual<0x48004A40>::Value; +const TUint32 KCM_CLKSEL_SGX = Omap3530HwBase::TVirtual<0x48004B40>::Value; +const TUint32 KCM_CLKSEL_WKUP = Omap3530HwBase::TVirtual<0x48004C40>::Value; +const TUint32 KCM_CLKSEL_DSS = Omap3530HwBase::TVirtual<0x48004E40>::Value; +const TUint32 KCM_CLKSEL_CAM = Omap3530HwBase::TVirtual<0x48004F40>::Value; +const TUint32 KCM_CLKSEL_PER = Omap3530HwBase::TVirtual<0x48005040>::Value; +const TUint32 KCM_CLKSEL1_EMU = Omap3530HwBase::TVirtual<0x48005140>::Value; +const TUint32 KCM_CLKSEL2_EMU = Omap3530HwBase::TVirtual<0x48005150>::Value; +const TUint32 KCM_CLKSEL3_EMU = Omap3530HwBase::TVirtual<0x48005154>::Value; +const TUint32 KCM_CLKSEL1_PLL = Omap3530HwBase::TVirtual<0x48004D40>::Value; +const TUint32 KCM_CLKSEL2_PLL = Omap3530HwBase::TVirtual<0x48004D44>::Value; +const TUint32 KCM_CLKSEL3_PLL = Omap3530HwBase::TVirtual<0x48004D48>::Value; +const TUint32 KCM_CLKSEL4_PLL = Omap3530HwBase::TVirtual<0x48004D4C>::Value; +const TUint32 KCM_CLKSEL5_PLL = Omap3530HwBase::TVirtual<0x48004D50>::Value; +const TUint32 KCM_CLKEN_PLL = Omap3530HwBase::TVirtual<0x48004D00>::Value; +const TUint32 KCM_FCLKEN_IVA2 = Omap3530HwBase::TVirtual<0x48004000>::Value; +const TUint32 KCM_FCLKEN_SGX = Omap3530HwBase::TVirtual<0x48004B00>::Value; +const TUint32 KCM_FCLKEN_WKUP = Omap3530HwBase::TVirtual<0x48004C00>::Value; +const TUint32 KCM_FCLKEN_DSS = Omap3530HwBase::TVirtual<0x48004E00>::Value; +const TUint32 KCM_FCLKEN_CAM = Omap3530HwBase::TVirtual<0x48004F00>::Value; +const TUint32 KCM_FCLKEN_PER = Omap3530HwBase::TVirtual<0x48005000>::Value; +const TUint32 KCM_FCLKEN_USBHOST = Omap3530HwBase::TVirtual<0x48005400>::Value; +const TUint32 KCM_FCLKEN1_CORE = Omap3530HwBase::TVirtual<0x48004A00>::Value; +const TUint32 KCM_FCLKEN3_CORE = Omap3530HwBase::TVirtual<0x48004A08>::Value; +const TUint32 KCM_ICLKEN1_CORE = Omap3530HwBase::TVirtual<0x48004A10>::Value; +const TUint32 KCM_ICLKEN2_CORE = Omap3530HwBase::TVirtual<0x48004A14>::Value; +const TUint32 KCM_ICLKEN3_CORE = Omap3530HwBase::TVirtual<0x48004A18>::Value; +const TUint32 KCM_ICLKEN_SGX = Omap3530HwBase::TVirtual<0x48004B10>::Value; +const TUint32 KCM_ICLKEN_WKUP = Omap3530HwBase::TVirtual<0x48004C10>::Value; +const TUint32 KCM_ICLKEN_DSS = Omap3530HwBase::TVirtual<0x48004E10>::Value; +const TUint32 KCM_ICLKEN_CAM = Omap3530HwBase::TVirtual<0x48004F10>::Value; +const TUint32 KCM_ICLKEN_PER = Omap3530HwBase::TVirtual<0x48005010>::Value; +const TUint32 KCM_ICLKEN_USBHOST = Omap3530HwBase::TVirtual<0x48005410>::Value; +const TUint32 KCM_AUTOIDLE1_CORE = Omap3530HwBase::TVirtual<0x48004A30>::Value; +const TUint32 KCM_AUTOIDLE2_CORE = Omap3530HwBase::TVirtual<0x48004A34>::Value; +const TUint32 KCM_AUTOIDLE3_CORE = Omap3530HwBase::TVirtual<0x48004A38>::Value; +const TUint32 KCM_AUTOIDLE_WKUP = Omap3530HwBase::TVirtual<0x48004C30>::Value; +const TUint32 KCM_AUTOIDLE_PLL = Omap3530HwBase::TVirtual<0x48004D30>::Value; +const TUint32 KCM_AUTOIDLE2_PLL = Omap3530HwBase::TVirtual<0x48004D34>::Value; +const TUint32 KCM_AUTOIDLE_DSS = Omap3530HwBase::TVirtual<0x48004E30>::Value; +const TUint32 KCM_AUTOIDLE_CAM = Omap3530HwBase::TVirtual<0x48004F30>::Value; +const TUint32 KCM_AUTOIDLE_PER = Omap3530HwBase::TVirtual<0x48005030>::Value; +const TUint32 KCM_AUTOIDLE_USBHOST = Omap3530HwBase::TVirtual<0x48005430>::Value; +const TUint32 KCM_IDLEST1_CORE = Omap3530HwBase::TVirtual<0x48004A20>::Value; +const TUint32 KCM_IDLEST2_CORE = Omap3530HwBase::TVirtual<0x48004A24>::Value; +const TUint32 KCM_IDLEST3_CORE = Omap3530HwBase::TVirtual<0x48004A28>::Value; +const TUint32 KCM_IDLEST_IVA2 = Omap3530HwBase::TVirtual<0x48004024>::Value; +const TUint32 KCM_IDLEST_MPU = Omap3530HwBase::TVirtual<0x48004920>::Value; +const TUint32 KCM_IDLEST_SGX = Omap3530HwBase::TVirtual<0x48004B20>::Value; +const TUint32 KCM_IDLEST_WKUP = Omap3530HwBase::TVirtual<0x48004C20>::Value; +const TUint32 KCM_IDLEST_CKGEN = Omap3530HwBase::TVirtual<0x48004D20>::Value; +const TUint32 KCM_IDLEST2_CKGEN = Omap3530HwBase::TVirtual<0x48004D24>::Value; +const TUint32 KCM_IDLEST_DSS = Omap3530HwBase::TVirtual<0x48004E20>::Value; +const TUint32 KCM_IDLEST_CAM = Omap3530HwBase::TVirtual<0x48004F20>::Value; +const TUint32 KCM_IDLEST_PER = Omap3530HwBase::TVirtual<0x48005020>::Value; +const TUint32 KCM_IDLEST_NEON = Omap3530HwBase::TVirtual<0x48005320>::Value; +const TUint32 KCM_IDLEST_USBHOST = Omap3530HwBase::TVirtual<0x48005420>::Value; +const TUint32 KCM_SLEEPDEP_SGX = Omap3530HwBase::TVirtual<0x48004B44>::Value; +const TUint32 KCM_SLEEPDEP_DSS = Omap3530HwBase::TVirtual<0x48004E44>::Value; +const TUint32 KCM_SLEEPDEP_CAM = Omap3530HwBase::TVirtual<0x48004F44>::Value; +const TUint32 KCM_SLEEPDEP_PER = Omap3530HwBase::TVirtual<0x48005044>::Value; +const TUint32 KCM_SLEEPDEP_USBHOST = Omap3530HwBase::TVirtual<0x48005444>::Value; +const TUint32 KCM_CLKSTCTRL_IVA2 = Omap3530HwBase::TVirtual<0x48004048>::Value; +const TUint32 KCM_CLKSTCTRL_MPU = Omap3530HwBase::TVirtual<0x48004948>::Value; +const TUint32 KCM_CLKSTCTRL_CORE = Omap3530HwBase::TVirtual<0x48004A48>::Value; +const TUint32 KCM_CLKSTCTRL_SGX = Omap3530HwBase::TVirtual<0x48004B48>::Value; +const TUint32 KCM_CLKSTCTRL_DSS = Omap3530HwBase::TVirtual<0x48004E48>::Value; +const TUint32 KCM_CLKSTCTRL_CAM = Omap3530HwBase::TVirtual<0x48004F48>::Value; +const TUint32 KCM_CLKSTCTRL_PER = Omap3530HwBase::TVirtual<0x48005048>::Value; +const TUint32 KCM_CLKSTCTRL_EMU = Omap3530HwBase::TVirtual<0x48005148>::Value; +const TUint32 KCM_CLKSTCTRL_NEON = Omap3530HwBase::TVirtual<0x48005348>::Value; +const TUint32 KCM_CLKSTCTRL_USBHOST = Omap3530HwBase::TVirtual<0x48005448>::Value; +const TUint32 KCM_CLKSTST_IVA2 = Omap3530HwBase::TVirtual<0x4800404C>::Value; +const TUint32 KCM_CLKSTST_MPU = Omap3530HwBase::TVirtual<0x4800494C>::Value; +const TUint32 KCM_CLKSTST_CORE = Omap3530HwBase::TVirtual<0x48004A4C>::Value; +const TUint32 KCM_CLKSTST_SGX = Omap3530HwBase::TVirtual<0x48004B4C>::Value; +const TUint32 KCM_CLKSTST_DSS = Omap3530HwBase::TVirtual<0x48004E4C>::Value; +const TUint32 KCM_CLKSTST_CAM = Omap3530HwBase::TVirtual<0x48004F4C>::Value; +const TUint32 KCM_CLKSTST_PER = Omap3530HwBase::TVirtual<0x4800504C>::Value; +const TUint32 KCM_CLKSTST_EMU = Omap3530HwBase::TVirtual<0x4800514C>::Value; +const TUint32 KCM_CLKSTST_USBHOST = Omap3530HwBase::TVirtual<0x4800544C>::Value; +const TUint32 KCM_CLKSEL1_PLL_IVA2 = Omap3530HwBase::TVirtual<0x48004040>::Value; +const TUint32 KCM_CLKSEL2_PLL_IVA2 = Omap3530HwBase::TVirtual<0x48004044>::Value; +const TUint32 KCM_CLKSEL1_PLL_MPU = Omap3530HwBase::TVirtual<0x48004940>::Value; +const TUint32 KCM_CLKSEL2_PLL_MPU = Omap3530HwBase::TVirtual<0x48004944>::Value; +const TUint32 KCM_CLKEN_PLL_IVA2 = Omap3530HwBase::TVirtual<0x48004004>::Value; +const TUint32 KCM_CLKEN_PLL_MPU = Omap3530HwBase::TVirtual<0x48004904>::Value; +const TUint32 KCM_CLKEN2_PLL = Omap3530HwBase::TVirtual<0x48004D04>::Value; +const TUint32 KCM_AUTOIDLE_PLL_IVA2 = Omap3530HwBase::TVirtual<0x48004034>::Value; +const TUint32 KCM_AUTOIDLE_PLL_MPU = Omap3530HwBase::TVirtual<0x48004934>::Value; +const TUint32 KCM_IDLEST_PLL_IVA2 = Omap3530HwBase::TVirtual<0x48004024>::Value; +const TUint32 KCM_IDLEST_PLL_MPU = Omap3530HwBase::TVirtual<0x48004924>::Value; +const TUint32 KCM_REVISION = Omap3530HwBase::TVirtual<0x48004800>::Value; +const TUint32 KCM_SYSCONFIG = Omap3530HwBase::TVirtual<0x48004810>::Value; +const TUint32 KCM_CLKOUT_CTRL = Omap3530HwBase::TVirtual<0x48004D70>::Value; +const TUint32 KCM_POLCTRL = Omap3530HwBase::TVirtual<0x4800529C>::Value; +const TUint32 KRM_RSTCTRL_IVA2 = Omap3530HwBase::TVirtual<0x48306050>::Value; +const TUint32 KRM_RSTST_IVA2 = Omap3530HwBase::TVirtual<0x48306058>::Value; +const TUint32 KPM_WKDEP_IVA2 = Omap3530HwBase::TVirtual<0x483060C8>::Value; +const TUint32 KPM_PWSTCTRL_IVA2 = Omap3530HwBase::TVirtual<0x483060E0>::Value; +const TUint32 KPM_PWSTST_IVA2 = Omap3530HwBase::TVirtual<0x483060E4>::Value; +const TUint32 KPM_PREPWSTST_IVA2 = Omap3530HwBase::TVirtual<0x483060E8>::Value; +const TUint32 KPRM_IRQSTATUS_IVA2 = Omap3530HwBase::TVirtual<0x483060F8>::Value; +const TUint32 KPRM_IRQENABLE_IVA2 = Omap3530HwBase::TVirtual<0x483060FC>::Value; +const TUint32 KPRM_REVISION = Omap3530HwBase::TVirtual<0x48306804>::Value; +const TUint32 KPRM_SYSCONFIG = Omap3530HwBase::TVirtual<0x48306814>::Value; +const TUint32 KPRM_IRQSTATUS_MPU = Omap3530HwBase::TVirtual<0x48306818>::Value; +const TUint32 KPRM_IRQENABLE_MPU = Omap3530HwBase::TVirtual<0x4830681C>::Value; +const TUint32 KRM_RSTST_MPU = Omap3530HwBase::TVirtual<0x48306958>::Value; +const TUint32 KPM_WKDEP_MPU = Omap3530HwBase::TVirtual<0x483069C8>::Value; +const TUint32 KPM_EVGENCTRL_MPU = Omap3530HwBase::TVirtual<0x483069D4>::Value; +const TUint32 KPM_EVGENONTIM_MPU = Omap3530HwBase::TVirtual<0x483069D8>::Value; +const TUint32 KPM_EVGENOFFTIM_MPU = Omap3530HwBase::TVirtual<0x483069DC>::Value; +const TUint32 KPM_PWSTCTRL_MPU = Omap3530HwBase::TVirtual<0x483069E0>::Value; +const TUint32 KPM_PWSTST_MPU = Omap3530HwBase::TVirtual<0x483069E4>::Value; +const TUint32 KPM_PREPWSTST_MPU = Omap3530HwBase::TVirtual<0x483069E8>::Value; +const TUint32 KRM_RSTST_CORE = Omap3530HwBase::TVirtual<0x48306A58>::Value; +const TUint32 KPM_WKEN1_CORE = Omap3530HwBase::TVirtual<0x48306AA0>::Value; +const TUint32 KPM_MPUGRPSEL1_CORE = Omap3530HwBase::TVirtual<0x48306AA4>::Value; +const TUint32 KPM_IVA2GRPSEL1_CORE = Omap3530HwBase::TVirtual<0x48306AA8>::Value; +const TUint32 KPM_WKST1_CORE = Omap3530HwBase::TVirtual<0x48306AB0>::Value; +const TUint32 KPM_WKST3_CORE = Omap3530HwBase::TVirtual<0x48306AB8>::Value; +const TUint32 KPM_PWSTCTRL_CORE = Omap3530HwBase::TVirtual<0x48306AE0>::Value; +const TUint32 KPM_PWSTST_CORE = Omap3530HwBase::TVirtual<0x48306AE4>::Value; +const TUint32 KPM_PREPWSTST_CORE = Omap3530HwBase::TVirtual<0x48306AE8>::Value; +const TUint32 KPM_WKEN3_CORE = Omap3530HwBase::TVirtual<0x48306AF0>::Value; +const TUint32 KPM_IVA2GRPSEL3_CORE = Omap3530HwBase::TVirtual<0x48306AF4>::Value; +const TUint32 KPM_MPUGRPSEL3_CORE = Omap3530HwBase::TVirtual<0x48306AF8>::Value; +const TUint32 KRM_RSTST_SGX = Omap3530HwBase::TVirtual<0x48306B58>::Value; +const TUint32 KPM_WKDEP_SGX = Omap3530HwBase::TVirtual<0x48306BC8>::Value; +const TUint32 KPM_PWSTCTRL_SGX = Omap3530HwBase::TVirtual<0x48306BE0>::Value; +const TUint32 KPM_PWSTST_SGX = Omap3530HwBase::TVirtual<0x48306BE4>::Value; +const TUint32 KPM_PREPWSTST_SGX = Omap3530HwBase::TVirtual<0x48306BE8>::Value; +const TUint32 KPM_WKEN_WKUP = Omap3530HwBase::TVirtual<0x48306CA0>::Value; +const TUint32 KPM_MPUGRPSEL_WKUP = Omap3530HwBase::TVirtual<0x48306CA4>::Value; +const TUint32 KPM_IVA2GRPSEL_WKUP = Omap3530HwBase::TVirtual<0x48306CA8>::Value; +const TUint32 KPM_WKST_WKUP = Omap3530HwBase::TVirtual<0x48306CB0>::Value; +const TUint32 KPRM_CLKSEL = Omap3530HwBase::TVirtual<0x48306D40>::Value; +const TUint32 KPRM_CLKOUT_CTRL = Omap3530HwBase::TVirtual<0x48306D70>::Value; +const TUint32 KRM_RSTST_DSS = Omap3530HwBase::TVirtual<0x48306E58>::Value; +const TUint32 KPM_WKEN_DSS = Omap3530HwBase::TVirtual<0x48306EA0>::Value; +const TUint32 KPM_WKDEP_DSS = Omap3530HwBase::TVirtual<0x48306EC8>::Value; +const TUint32 KPM_PWSTCTRL_DSS = Omap3530HwBase::TVirtual<0x48306EE0>::Value; +const TUint32 KPM_PWSTST_DSS = Omap3530HwBase::TVirtual<0x48306EE4>::Value; +const TUint32 KPM_PREPWSTST_DSS = Omap3530HwBase::TVirtual<0x48306EE8>::Value; +const TUint32 KRM_RSTST_CAM = Omap3530HwBase::TVirtual<0x48306F58>::Value; +const TUint32 KPM_WKDEP_CAM = Omap3530HwBase::TVirtual<0x48306FC8>::Value; +const TUint32 KPM_PWSTCTRL_CAM = Omap3530HwBase::TVirtual<0x48306FE0>::Value; +const TUint32 KPM_PWSTST_CAM = Omap3530HwBase::TVirtual<0x48306FE4>::Value; +const TUint32 KPM_PREPWSTST_CAM = Omap3530HwBase::TVirtual<0x48306FE8>::Value; +const TUint32 KRM_RSTST_PER = Omap3530HwBase::TVirtual<0x48307058>::Value; +const TUint32 KPM_WKEN_PER = Omap3530HwBase::TVirtual<0x483070A0>::Value; +const TUint32 KPM_MPUGRPSEL_PER = Omap3530HwBase::TVirtual<0x483070A4>::Value; +const TUint32 KPM_IVA2GRPSEL_PER = Omap3530HwBase::TVirtual<0x483070A8>::Value; +const TUint32 KPM_WKST_PER = Omap3530HwBase::TVirtual<0x483070B0>::Value; +const TUint32 KPM_WKDEP_PER = Omap3530HwBase::TVirtual<0x483070C8>::Value; +const TUint32 KPM_PWSTCTRL_PER = Omap3530HwBase::TVirtual<0x483070E0>::Value; +const TUint32 KPM_PWSTST_PER = Omap3530HwBase::TVirtual<0x483070E4>::Value; +const TUint32 KPM_PREPWSTST_PER = Omap3530HwBase::TVirtual<0x483070E8>::Value; +const TUint32 KRM_RSTST_EMU = Omap3530HwBase::TVirtual<0x48307158>::Value; +const TUint32 KPM_PWSTST_EMU = Omap3530HwBase::TVirtual<0x483071E4>::Value; +const TUint32 KPRM_VC_SMPS_SA = Omap3530HwBase::TVirtual<0x48307220>::Value; +const TUint32 KPRM_VC_SMPS_VOL_RA = Omap3530HwBase::TVirtual<0x48307224>::Value; +const TUint32 KPRM_VC_SMPS_CMD_RA = Omap3530HwBase::TVirtual<0x48307228>::Value; +const TUint32 KPRM_VC_CMD_VAL_0 = Omap3530HwBase::TVirtual<0x4830722C>::Value; +const TUint32 KPRM_VC_CMD_VAL_1 = Omap3530HwBase::TVirtual<0x48307230>::Value; +const TUint32 KPRM_VC_CH_CONF = Omap3530HwBase::TVirtual<0x48307234>::Value; +const TUint32 KPRM_VC_I2C_CFG = Omap3530HwBase::TVirtual<0x48307238>::Value; +const TUint32 KPRM_VC_BYPASS_VAL = Omap3530HwBase::TVirtual<0x4830723C>::Value; +const TUint32 KPRM_RSTCTRL = Omap3530HwBase::TVirtual<0x48307250>::Value; +const TUint32 KPRM_RSTTIME = Omap3530HwBase::TVirtual<0x48307254>::Value; +const TUint32 KPRM_RSTST = Omap3530HwBase::TVirtual<0x48307258>::Value; +const TUint32 KPRM_VOLTCTRL = Omap3530HwBase::TVirtual<0x48307260>::Value; +const TUint32 KPRM_SRAM_PCHARGE = Omap3530HwBase::TVirtual<0x48307264>::Value; +const TUint32 KPRM_CLKSRC_CTRL = Omap3530HwBase::TVirtual<0x48307270>::Value; +const TUint32 KPRM_OBS = Omap3530HwBase::TVirtual<0x48307280>::Value; +const TUint32 KPRM_VOLTSETUP1 = Omap3530HwBase::TVirtual<0x48307290>::Value; +const TUint32 KPRM_VOLTOFFSET = Omap3530HwBase::TVirtual<0x48307294>::Value; +const TUint32 KPRM_CLKSETUP = Omap3530HwBase::TVirtual<0x48307298>::Value; +const TUint32 KPRM_POLCTRL = Omap3530HwBase::TVirtual<0x4830729C>::Value; +const TUint32 KPRM_VOLTSETUP2 = Omap3530HwBase::TVirtual<0x483072A0>::Value; +const TUint32 KRM_RSTST_NEON = Omap3530HwBase::TVirtual<0x48307358>::Value; +const TUint32 KPM_WKDEP_NEON = Omap3530HwBase::TVirtual<0x483073C8>::Value; +const TUint32 KPM_PWSTCTRL_NEON = Omap3530HwBase::TVirtual<0x483073E0>::Value; +const TUint32 KPM_PWSTST_NEON = Omap3530HwBase::TVirtual<0x483073E4>::Value; +const TUint32 KPM_PREPWSTST_NEON = Omap3530HwBase::TVirtual<0x483073E8>::Value; +const TUint32 KRM_RSTST_USBHOST = Omap3530HwBase::TVirtual<0x48307458>::Value; +const TUint32 KPM_WKEN_USBHOST = Omap3530HwBase::TVirtual<0x483074A0>::Value; +const TUint32 KPM_MPUGRPSEL_USBHOST = Omap3530HwBase::TVirtual<0x483074A4>::Value; +const TUint32 KPM_IVA2GRPSEL_USBHOST = Omap3530HwBase::TVirtual<0x483074A8>::Value; +const TUint32 KPM_WKST_USBHOST = Omap3530HwBase::TVirtual<0x483074B0>::Value; +const TUint32 KPM_WKDEP_USBHOST = Omap3530HwBase::TVirtual<0x483074C8>::Value; +const TUint32 KPM_PWSTCTRL_USBHOST = Omap3530HwBase::TVirtual<0x483074E0>::Value; +const TUint32 KPM_PWSTST_USBHOST = Omap3530HwBase::TVirtual<0x483074E4>::Value; +const TUint32 KPM_PREPWSTST_USBHOST = Omap3530HwBase::TVirtual<0x483074E8>::Value; + +const TUint32 KMAILBOX_SYSCONFIG = Omap3530HwBase::TVirtual<0x48094010>::Value; +const TUint32 KCONTROL_SYSCONFIG = Omap3530HwBase::TVirtual<0x48002010>::Value; +const TUint32 KMMU1_SYSCONFIG = Omap3530HwBase::TVirtual<0x480BD410>::Value; +const TUint32 KMMU2_SYSCONFIG = Omap3530HwBase::TVirtual<0x5D000010>::Value; +const TUint32 KDMA4_OCP_SYSCONFIG = Omap3530HwBase::TVirtual<0x4805602C>::Value; +const TUint32 KINTCPS_SYSCONFIG = Omap3530HwBase::TVirtual<0x48200010>::Value; +const TUint32 KGPMC_SYSCONFIG = Omap3530HwBase::TVirtual<0x6E000010>::Value; +const TUint32 KSMS_SYSCONFIG = Omap3530HwBase::TVirtual<0x6C000010>::Value; +const TUint32 KSDRC_SYSCONFIG = Omap3530HwBase::TVirtual<0x6D000010>::Value; +const TUint32 KISP_SYSCONFIG = Omap3530HwBase::TVirtual<0x480BC004>::Value; +const TUint32 KCBUFF_SYSCONFIG = Omap3530HwBase::TVirtual<0x480BC110>::Value; +const TUint32 KSYSC_SYSCONFIG = Omap3530HwBase::TVirtual<0x01C20008>::Value; +const TUint32 KWUGEN_SYSCONFIG = Omap3530HwBase::TVirtual<0x01C21008>::Value; +const TUint32 KDSS_SYSCONFIG = Omap3530HwBase::TVirtual<0x48050010>::Value; +const TUint32 KDISPC_SYSCONFIG = Omap3530HwBase::TVirtual<0x48050410>::Value; +const TUint32 KRFBI_SYSCONFIG = Omap3530HwBase::TVirtual<0x48050810>::Value; +const TUint32 KDSI_SYSCONFIG = Omap3530HwBase::TVirtual<0x4804FC10>::Value; +const TUint32 KWD1_SYSCONFIG = Omap3530HwBase::TVirtual<0x4830C010>::Value; +const TUint32 KWD2_SYSCONFIG = Omap3530HwBase::TVirtual<0x48314010>::Value; +const TUint32 KWD3_SYSCONFIG = Omap3530HwBase::TVirtual<0x49030010>::Value; +const TUint32 K32KSYNCNT_SYSCONFIG = Omap3530HwBase::TVirtual<0x48320004>::Value; +const TUint32 KI2C3_SYSC = Omap3530HwBase::TVirtual<0x48060020>::Value; +const TUint32 KI2C1_SYSC = Omap3530HwBase::TVirtual<0x48070020>::Value; +const TUint32 KI2C2_SYSC = Omap3530HwBase::TVirtual<0x48072020>::Value; +const TUint32 KMCSPI1_SYSCONFIG = Omap3530HwBase::TVirtual<0x48098010>::Value; +const TUint32 KMCSPI2_SYSCONFIG = Omap3530HwBase::TVirtual<0x4809A010>::Value; +const TUint32 KMCSPI3_SYSCONFIG = Omap3530HwBase::TVirtual<0x480B8010>::Value; +const TUint32 KMCSPI4_SYSCONFIG = Omap3530HwBase::TVirtual<0x480BA010>::Value; +const TUint32 KHDQ_SYSCONFIG = Omap3530HwBase::TVirtual<0x480B2014>::Value; +const TUint32 KMCBSPLP1_SYSCONFIG = Omap3530HwBase::TVirtual<0x4807408C>::Value; +const TUint32 KMCBSPLP5_SYSCONFIG = Omap3530HwBase::TVirtual<0x4809608C>::Value; +const TUint32 KMCBSPLP2_SYSCONFIG = Omap3530HwBase::TVirtual<0x4902208C>::Value; +const TUint32 KMCBSPLP3_SYSCONFIG = Omap3530HwBase::TVirtual<0x4902408C>::Value; +const TUint32 KMCBSPLP4_SYSCONFIG = Omap3530HwBase::TVirtual<0x4902608C>::Value; +const TUint32 KST2_SYSCONFIG = Omap3530HwBase::TVirtual<0x49028010>::Value; +const TUint32 KST3_SYSCONFIG = Omap3530HwBase::TVirtual<0x4902A010>::Value; +const TUint32 KMMCHS1_SYSCONFIG = Omap3530HwBase::TVirtual<0x4809C010>::Value; +const TUint32 KMMCHS3_SYSCONFIG = Omap3530HwBase::TVirtual<0x480AD010>::Value; +const TUint32 KMMCHS2_SYSCONFIG = Omap3530HwBase::TVirtual<0x480B4010>::Value; +const TUint32 KOTG_SYSCONFIG = Omap3530HwBase::TVirtual<0x480AB404>::Value; +const TUint32 KUSBTLL_SYSCONFIG = Omap3530HwBase::TVirtual<0x48062010>::Value; +const TUint32 KUHH_SYSCONFIG = Omap3530HwBase::TVirtual<0x48064010>::Value; +const TUint32 KGPIO1_SYSCONFIG = Omap3530HwBase::TVirtual<0x48310010>::Value; +const TUint32 KGPIO2_SYSCONFIG = Omap3530HwBase::TVirtual<0x49050010>::Value; +const TUint32 KGPIO3_SYSCONFIG = Omap3530HwBase::TVirtual<0x49052010>::Value; +const TUint32 KGPIO4_SYSCONFIG = Omap3530HwBase::TVirtual<0x49054010>::Value; +const TUint32 KGPIO5_SYSCONFIG = Omap3530HwBase::TVirtual<0x49056010>::Value; +const TUint32 KGPIO6_SYSCONFIG = Omap3530HwBase::TVirtual<0x49058010>::Value; +const TUint32 KUART1_SYSC = Omap3530HwBase::TVirtual<0x4806A050>::Value; +const TUint32 KUART2_SYSC = Omap3530HwBase::TVirtual<0x4806C050>::Value; +const TUint32 KUART3_SYSC = Omap3530HwBase::TVirtual<0x49020050>::Value; +const TUint32 KTI1OCP_CFG = Omap3530HwBase::TVirtual<0x48318010>::Value; +const TUint32 KTI2OCP_CFG = Omap3530HwBase::TVirtual<0x49032010>::Value; +const TUint32 KTI3OCP_CFG = Omap3530HwBase::TVirtual<0x49034010>::Value; +const TUint32 KTI4OCP_CFG = Omap3530HwBase::TVirtual<0x49036010>::Value; +const TUint32 KTI5OCP_CFG = Omap3530HwBase::TVirtual<0x49038010>::Value; +const TUint32 KTI6OCP_CFG = Omap3530HwBase::TVirtual<0x4903A010>::Value; +const TUint32 KTI7OCP_CFG = Omap3530HwBase::TVirtual<0x4903C010>::Value; +const TUint32 KTI8OCP_CFG = Omap3530HwBase::TVirtual<0x4903E010>::Value; +const TUint32 KTI9OCP_CFG = Omap3530HwBase::TVirtual<0x49040010>::Value; +const TUint32 KTI10OCP_CFG = Omap3530HwBase::TVirtual<0x48086010>::Value; +const TUint32 KTI11OCP_CFG = Omap3530HwBase::TVirtual<0x48088010>::Value; +const TUint32 KTI12OCP_CFG = Omap3530HwBase::TVirtual<0x48304010>::Value; +} + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/uart/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/uart/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,25 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/uart/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS + +omap3530_uart.h assp/omap3530_assp/ // + +PRJ_MMPFILES + uart diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/uart/def/eabi/uart.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/uart/def/eabi/uart.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,15 @@ +EXPORTS + _ZN12Omap3530Uart5TUart10DefineModeENS0_9TUartModeE @ 1 NONAME + _ZN12Omap3530Uart5TUart13SetDataFormatENS0_9TDataBitsENS0_9TStopBitsENS0_7TParityE @ 2 NONAME + _ZN12Omap3530Uart5TUart20DisableAllInterruptsEv @ 3 NONAME + _ZN12Omap3530Uart5TUart4InitEv @ 4 NONAME + _ZN12Omap3530Uart5TUart6EnableEv @ 5 NONAME + _ZN12Omap3530Uart5TUart7DisableEv @ 6 NONAME + _ZN12Omap3530Uart5TUart7SetBaudENS0_5TBaudE @ 7 NONAME + _ZN12Omap3530Uart5TUart10EnableFifoENS0_12TEnableStateENS0_12TFifoTriggerES2_ @ 8 NONAME + _ZN12Omap3530Uart5TUart15EnableInterruptENS0_10TInterruptE @ 9 NONAME + _ZN12Omap3530Uart5TUart16DisableInterruptENS0_10TInterruptE @ 10 NONAME + _ZNK12Omap3530Uart5TUart11InterruptIdEv @ 11 NONAME + _ZNK12Omap3530Uart5TUart15PrcmFunctionClkEv @ 12 NONAME + _ZNK12Omap3530Uart5TUart16PrcmInterfaceClkEv @ 13 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/uart/omap3530_uart.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/uart/omap3530_uart.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,760 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/uart/omap3530_uart.h +// This file is part of the Beagle Base port +// + +#ifndef __OMAP3530_UART_H__ +#define __OMAP3530_UART_H__ + +#include +#include +//#include "assp/omap3530_assp/omap3530_prm.h" +#include + +//#include "omap3530_prm.h" + + +namespace Omap3530Uart +{ +using namespace TexasInstruments::Omap3530; + +enum TUartNumber + { + EUartNone = -1, + EUart0 = 0, + EUart1, + EUart2 + }; + +template< const TUartNumber aUartNumber > +struct TUartTraits + { + }; + +template<> +struct TUartTraits< EUart0 > + { + static const TUint32 KBaseAddress = Omap3530HwBase::KL4_Core + 0x0006A000; + static const TInt KInterruptId = EOmap3530_IRQ72_UART1_IRQ; + static const Prcm::TClock KInterfaceClock = Prcm::EClkUart1_I; + static const Prcm::TClock KFunctionClock = Prcm::EClkUart1_F; +// static const Omap3530Prm::TPrmId KPrmInterfaceClock = Omap3530Prm::EPrmClkUart1_I; +// static const Omap3530Prm::TPrmId KPrmFunctionClock = Omap3530Prm::EPrmClkUart1_F; + }; + +template<> +struct TUartTraits< EUart1 > + { + static const TUint32 KBaseAddress = Omap3530HwBase::KL4_Core + 0x0006C000; + static const TInt KInterruptId = EOmap3530_IRQ73_UART2_IRQ; + static const Prcm::TClock KInterfaceClock = Prcm::EClkUart2_I; + static const Prcm::TClock KFunctionClock = Prcm::EClkUart2_F; +// static const Omap3530Prm::TPrmId KPrmInterfaceClock = Omap3530Prm::EPrmClkUart2_I; +// static const Omap3530Prm::TPrmId KPrmFunctionClock = Omap3530Prm::EPrmClkUart2_F; + }; + +template<> +struct TUartTraits< EUart2 > + { + static const TUint32 KBaseAddress = Omap3530HwBase::KL4_Per + 0x00020000; + static const TInt KInterruptId = EOmap3530_IRQ74_UART3_IRQ; + static const Prcm::TClock KInterfaceClock = Prcm::EClkUart3_I; + static const Prcm::TClock KFunctionClock = Prcm::EClkUart3_F; +// static const Omap3530Prm::TPrmId KPrmInterfaceClock = Omap3530Prm::EPrmClkUart3_I; +// static const Omap3530Prm::TPrmId KPrmFunctionClock = Omap3530Prm::EPrmClkUart3_F; + }; + +// Forward declaration +class TUart; + + +/** Representation of general UART register set */ +struct DLL + { + static const TInt KOffset = 0x00; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> CLOCK_LSB; + }; + +struct RHR + { + static const TInt KOffset = 0x00; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct THR + { + static const TInt KOffset = 0x00; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct IER + { + static const TInt KOffset = 0x04; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> CTS_IT; + typedef TSingleBitField<6> RTS_IT; + typedef TSingleBitField<5> XOFF_IT; + typedef TSingleBitField<4> SLEEP_MODE; + typedef TSingleBitField<3> MODEM_STS_IT; + typedef TSingleBitField<2> LINE_STS_IT; + typedef TSingleBitField<1> THR_IT; + typedef TSingleBitField<0> RHR_IT; + }; + +struct IER_IRDA + { + static const TInt KOffset = 0x04; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> EOF_IT; + typedef TSingleBitField<6> LINE_STS_IT; + typedef TSingleBitField<5> TX_STATUS_IT; + typedef TSingleBitField<4> STS_FIFO_TRIG_IT; + typedef TSingleBitField<3> RX_OVERRUN_IT; + typedef TSingleBitField<2> LAST_RX_BYTE_IT; + typedef TSingleBitField<1> THR_IT; + typedef TSingleBitField<0> RHR_IT; + }; + +struct DLH + { + static const TInt KOffset = 0x04; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,6> CLOCK_MSB; + }; + +struct FCR + { + static const TInt KOffset = 0x08; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TSingleBitField<0> FIFO_EN; + typedef TSingleBitField<1> RX_FIFO_CLEAR; + typedef TSingleBitField<2> TX_FIFO_CLEAR; + typedef TSingleBitField<3> DMA_MODE; + struct TX_FIFO_TRIG : public TBitField<4,2> + { + enum TConstants + { + K8Char = 0 << KShift, + K16Char = 1 << KShift, + K32Char = 2 << KShift, + K56Char = 3 << KShift + }; + }; + struct RX_FIFO_TRIG : public TBitField<6,2> + { + static const TUint8 K8Char = 0 << KShift; + static const TUint8 K16Char = 1 << KShift; + static const TUint8 K56Char = 2 << KShift; + static const TUint8 K60Char = 3 << KShift; + }; + }; + +struct IIR + { + static const TInt KOffset = 0x08; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TBitField<6,2> FCR_MIRROR; + struct IT_TYPE : public TBitField<1,5> + { + enum TConstants + { + EModem = 0 << KShift, + ETHR = 1 << KShift, + ERHR = 2 << KShift, + ERxLineStatus = 3 << KShift, + ERxTimeout = 6 << KShift, + EXoff = 8 << KShift, + ECtsRts = 16 << KShift + }; + }; + typedef TSingleBitField<0> IT_PENDING; + }; + +struct EFR + { + static const TInt KOffset = 0x08; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> AUTO_CTS_EN; + typedef TSingleBitField<6> AUTO_RTS_EN; + typedef TSingleBitField<5> SPEC_CHAR; + typedef TSingleBitField<4> ENHANCED_EN; + struct SW_FLOW_CONTROL : public TBitField<0,4> + { + enum TFlowControl + { + ENone = 0, + EXonXoff1 = 8, + EXonXoff2 = 4, + EXonXoffBoth = 8 + 4, + }; + }; + }; + +struct LCR + { + static const TInt KOffset = 0x0c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> DIV_EN; + typedef TSingleBitField<6> BREAK_EN; + typedef TSingleBitField<5> PARITY_TYPE2; + typedef TSingleBitField<4> PARITY_TYPE1; + typedef TSingleBitField<3> PARITY_EN; + struct NB_STOP : public TSingleBitField<2> + { + enum TConstants + { + E1Stop = 0 << KShift, + E1_5Stop = 1 << KShift, + E2Stop = 1 << KShift + }; + }; + struct CHAR_LENGTH : public TBitField<0,2> + { + enum TConstants + { + E5Bits = 0, + E6Bits = 1, + E7Bits = 2, + E8Bits = 3 + }; + }; + + /** Special magic number to enter MODEA */ + static const TUint8 KConfigModeA = 0x80; + + /** Special magic number to enter MODEB */ + static const TUint8 KConfigModeB = 0xBF; + + /** Special magic number to enter operational mode */ + static const TUint8 KConfigModeOperational = 0x00; + }; + +struct MCR + { + static const TInt KOffset = 0x10; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<6> TCR_TLR; + typedef TSingleBitField<5> XON_EN; + typedef TSingleBitField<4> LOOPBACK_EN; + typedef TSingleBitField<3> CD_STS_CH; + typedef TSingleBitField<2> RI_STS_CH; + typedef TSingleBitField<1> RTS; + typedef TSingleBitField<0> DTR; + }; + +struct XON1_ADDR1 + { + static const TInt KOffset = 0x10; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct LSR + { + static const TInt KOffset = 0x14; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TSingleBitField<7> RX_FIFO_STS; + typedef TSingleBitField<6> TX_SR_E; + typedef TSingleBitField<5> TX_FIFO_E; + typedef TSingleBitField<4> RX_BI; + typedef TSingleBitField<3> RX_FE; + typedef TSingleBitField<2> RX_PE; + typedef TSingleBitField<1> RX_OE; + typedef TSingleBitField<0> RX_FIFO_E; + }; + +struct XON2_ADDR2 + { + static const TInt KOffset = 0x14; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct XOFF1 + { + static const TInt KOffset = 0x18; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct TCR + { + static const TInt KOffset = 0x18; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<4,4> RX_FIFO_TRIG_START; + typedef TBitField<0,4> RX_FIFO_TRIG_HALT; + }; + +struct MSR + { + static const TInt KOffset = 0x18; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TSingleBitField<7> NCD_STS; + typedef TSingleBitField<6> NRI_STS; + typedef TSingleBitField<5> NDSR_STS; + typedef TSingleBitField<4> NCTS_STS; + typedef TSingleBitField<3> DCD_STS; + typedef TSingleBitField<2> RI_STS; + typedef TSingleBitField<1> DSR_STS; + typedef TSingleBitField<0> CTS_STS; + }; + +struct SPR + { + static const TInt KOffset = 0x1c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> SPR_WORD; + }; + +struct XOFF2 + { + static const TInt KOffset = 0x1c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct TLR + { + static const TInt KOffset = 0x1c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<4,4> RX_FIFO_TRIG_DMA; + typedef TBitField<0,4> TX_FIFO_TRIG_DMA; + }; + +struct MDR1 + { + static const TInt KOffset = 0x20; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> FRAME_END_MODE; + typedef TSingleBitField<6> SIP_MODE; + typedef TSingleBitField<5> SCT; + typedef TSingleBitField<4> SET_TXIR; + typedef TSingleBitField<3> IR_SLEEP; + struct MODE_SELECT : public TBitField<0,3> + { + enum TMode + { + EUart16x = 0, + ESIR = 1, + EUart16xAutoBaud = 2, + EUart13x = 3, + EMIR = 4, + EFIR = 5, + ECIR = 6, + EDisable = 7 + }; + }; + }; + +struct MDR2 + { + static const TInt KOffset = 0x24; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<6> IRRXINVERT; + struct CIR_PULSE_MODE : public TBitField<4,2> + { + enum TConstants + { + EPw3 = 0 << KShift, + EPw4 = 1 << KShift, + EPw5 = 2 << KShift, + EPw6 = 3 << KShift + }; + }; + typedef TSingleBitField<3> UART_PULSE; + struct STS_FIFO_TRIG : public TBitField<1,2> + { + enum TConstants + { + E1Entry = 0 << KShift, + E4Entry = 1 << KShift, + E7Entry = 2 << KShift, + E8Entry = 3 << KShift + }; + }; + typedef TSingleBitField<0> IRTX_UNDERRUN; + }; + +struct TXFLL + { + static const TInt KOffset = 0x28; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TBitField<0,8> TX_FLL; + }; + +struct SFLSR + { + static const TInt KOffset = 0x28; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TSingleBitField<4> OE_ERROR; + typedef TSingleBitField<3> FTL_ERROR; + typedef TSingleBitField<2> ABORT_DETECT; + typedef TSingleBitField<1> CRC_ERROR; + }; + +struct RESUME + { + static const TInt KOffset = 0x2c; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct TXFLH + { + static const TInt KOffset = 0x2c; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TBitField<0,5> TX_FLH; + }; + +struct RXFLL + { + static const TInt KOffset = 0x30; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TBitField<0,8> RX_FLL; + }; + +struct SFREGL + { + static const TInt KOffset = 0x30; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct SFREGH + { + static const TInt KOffset = 0x34; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TBitField<0,4> Value; + }; + +struct RXFLH + { + static const TInt KOffset = 0x34; + static TDynReg8_W< TUart, KOffset > iMem; + typedef TBitField<0,4> RX_FLH; + }; + +struct BLR + { + typedef TSingleBitField<7> STS_FIFO_RESET; + typedef TSingleBitField<6> XBOF_TYPE; + }; + +struct UASR + { + static const TInt KOffset = 0x38; + static TDynReg8_R< TUart, KOffset > iMem; + struct PARITY_TYPE : public TBitField<6,2> + { + enum TConstants + { + ENone = 0 << KShift, + ESpace = 1 << KShift, + EEven = 2 << KShift, + EOdd = 3 << KShift + }; + }; + struct BIT_BY_CHAR : public TSingleBitField<5> + { + enum TConstants + { + E7Bit = 0 << KShift, + E8Bit = 1 << KShift + }; + }; + struct SPEED : public TBitField<0,5> + { + enum TBaud + { + EUnknown = 0, + E115200 = 1, + E57600 = 2, + E38400 = 3, + E28800 = 4, + E19200 = 5, + E14400 = 6, + E9600 = 7, + E4800 = 8, + E4800_2 = 9, + E1200 = 10 + }; + }; + }; + +struct ACREG + { + static const TInt KOffset = 0x3c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> PULSE_TYPE; + typedef TSingleBitField<6> SID_MOD; + typedef TSingleBitField<5> DIS_IR_RX; + typedef TSingleBitField<4> DIS_TX_UNDERRUN; + typedef TSingleBitField<3> SEND_SIP; + typedef TSingleBitField<2> SCTX_EN; + typedef TSingleBitField<1> ABORT_EN; + typedef TSingleBitField<0> EOT_EN; + }; + +struct SCR + { + static const TInt KOffset = 0x40; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<7> RX_TRIG_GRANU1; + typedef TSingleBitField<6> TX_TRIG_GRANU1; + typedef TSingleBitField<4> RX_CTS_WU_EN; + typedef TSingleBitField<3> TX_EMPTY_CTL_IT; + typedef TBitField<1,2> DMA_MODE2; + typedef TSingleBitField<0> DMA_MODE_CTL; + }; + +struct SSR + { + static const TInt KOffset = 0x44; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TSingleBitField<1> RX_CTS_WU_STS; + typedef TSingleBitField<0> TX_FIFO_FULL; + }; + +struct EBLR + { + static const TInt KOffset = 0x48; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + +struct SYSC + { + static const TInt KOffset = 0x54; + static TDynReg8_RW< TUart, KOffset > iMem; + struct IDLE_MODE : public TBitField<3,2> + { + enum TMode + { + EForceIdle = 0 << KShift, + ENoIdle = 1 << KShift, + ESmartIdle = 2 << KShift + }; + }; + typedef TSingleBitField<2> ENAWAKEUP; + typedef TSingleBitField<1> SOFTRESET; + typedef TSingleBitField<0> AUTOIDLE; + }; + +struct SYSS + { + static const TInt KOffset = 0x58; + static TDynReg8_R< TUart, KOffset > iMem; + typedef TSingleBitField<0> RESETDONE; + }; + +struct WER + { + static const TInt KOffset = 0x5c; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TSingleBitField<6> EVENT_6_RLS_INTERRUPT; + typedef TSingleBitField<5> EVENT_5_RHR_INTERRUPT; + typedef TSingleBitField<4> EVENT_4_RX_ACTIVITY; + typedef TSingleBitField<2> EVENT_2_RI_ACTIVITY; + typedef TSingleBitField<0> EVENT_0_CTS_ACTIVITY; + }; + +struct CFPS + { + static const TInt KOffset = 0x60; + static TDynReg8_RW< TUart, KOffset > iMem; + typedef TBitField<0,8> Value; + }; + + +class TUart + { + public: + enum TBaud + { + E1200, + E2400, + E4800, + E9600, + E14400, + E19200, + E28800, + E38400, + E57600, + E115200, + E230400, + E460800, + E921600, + E1843000, + E3688400, + E4000000, // FIR + + KSupportedBaudCount + }; + + enum TParity + { + ENone, + EOdd, + EEven, + EMark, + ESpace + }; + + enum TDataBits + { + E5Data = ::Omap3530Uart::LCR::CHAR_LENGTH::E5Bits, + E6Data = ::Omap3530Uart::LCR::CHAR_LENGTH::E6Bits, + E7Data = ::Omap3530Uart::LCR::CHAR_LENGTH::E7Bits, + E8Data = ::Omap3530Uart::LCR::CHAR_LENGTH::E8Bits, + }; + + enum TStopBits + { + E1Stop = ::Omap3530Uart::LCR::NB_STOP::E1Stop, + E1_5Stop = ::Omap3530Uart::LCR::NB_STOP::E1_5Stop, + E2Stop = ::Omap3530Uart::LCR::NB_STOP::E2Stop, + }; + + enum TUartMode + { + EUart, + EUartAutoBaud, + ESIR, + EMIR, + EFIR, + ECIR, + + KSupportedUartModes + }; + + enum TFifoTrigger + { + ETrigger8, + ETrigger16, + ETrigger32, + ETrigger56, + ETrigger60, + ETriggerUnchanged + }; + + enum TEnableState + { + EDisabled, + EEnabled + }; + + enum TInterrupt + { + EIntRhr = 0, + EIntThr = 1, + EIntLineStatus = 2, + EIntModemStatus = 3, + EIntXoff = 5, + EIntRts = 6, + EIntCts = 7 + }; + + public: + inline TUart( const TUartNumber aUartNumber ) + : iBase( (aUartNumber == EUart0 ) ? TUartTraits::KBaseAddress + : (aUartNumber == EUart1 ) ? TUartTraits::KBaseAddress + : (aUartNumber == EUart2 ) ? TUartTraits::KBaseAddress + : 0 ), + iUartNumber( aUartNumber ) + {} + + FORCE_INLINE TLinAddr Base() const + { return iBase; } + + IMPORT_C TInt InterruptId() const; + + IMPORT_C Prcm::TClock PrcmInterfaceClk() const; + + IMPORT_C Prcm::TClock PrcmFunctionClk() const; + +// IMPORT_C TInt PrmInterfaceClk() const; + +// IMPORT_C TInt PrmFunctionClk() const; + + /** Reset and initialize the UART + * On return the UART will be in disable mode */ + IMPORT_C void Init(); + + /** Defines which mode the UART will run in when enabled, but does not configure that mode + * You must call this before calling SetBaud to ensure that correct baud rate multiplier is used */ + IMPORT_C void DefineMode( const TUartMode aMode ); + + /** Enabled the UART in the defined mode + * You must call DefineMode() and SetBaud() before calling Enable() + */ + IMPORT_C void Enable(); + + /** Disables the UART */ + IMPORT_C void Disable(); + + /** Set the baud rate + * Do not call this while the UART is enabled + * You must have previously called DefineMode() + */ + IMPORT_C void SetBaud( const TBaud aBaud ); + + /** Set the data length, parity and stop bits */ + IMPORT_C void SetDataFormat( const TDataBits aDataBits, const TStopBits aStopBits, const TParity aParity ); + + /** Setup the FIFO configuration */ + IMPORT_C void EnableFifo( const TEnableState aState, const TFifoTrigger aRxTrigger = ETriggerUnchanged, const TFifoTrigger aTxTrigger = ETriggerUnchanged ); + + /** Enable a particular interrupt source */ + IMPORT_C void EnableInterrupt( const TInterrupt aWhich ); + + /** Disable a particular interrupt source */ + IMPORT_C void DisableInterrupt( const TInterrupt aWhich ); + + /** Disable all interrupts */ + IMPORT_C void DisableAllInterrupts(); + + inline TBool TxFifoFull() + { return SSR::iMem.Read(*this) bitand SSR::TX_FIFO_FULL::KMask; } + + inline TBool TxFifoEmpty() + { return LSR::iMem.Read(*this) bitand LSR::TX_FIFO_E::KMask; } + + inline TBool RxFifoEmpty() + { return !(LSR::iMem.Read(*this) bitand LSR::RX_FIFO_E::KMask); } + + inline void Write( TUint8 aByte ) + { THR::iMem.Write( *this, aByte ); } + + inline TUint8 Read() + { return RHR::iMem.Read( *this ); } + + private: + TUart(); + + public: + const TLinAddr iBase; + const TUartNumber iUartNumber : 8; + TUartMode iMode : 8; + ::Omap3530Uart::MDR1::MODE_SELECT::TMode iTargetMode : 8; + }; + + +} // Omap3530Uart + +#endif // ndef __OMAP3530_UART_H__ + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/uart/uart.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/uart/uart.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,367 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/uart/uart.cpp +// This file is part of the Beagle Base port +// + +#include +#include + + +LOCAL_C void ClientPanic( TInt aLine ) + { + _LIT( KString, "uart.cpp" ); + Kern::PanicCurrentThread( KString, aLine ); + } + + +namespace Omap3530Uart +{ + +struct THwInfo + { + TUint32 iBaseAddress; + TInt iInterruptId; + Prcm::TClock iInterfaceClock : 16; + Prcm::TClock iFunctionClock : 16; +// Omap3530Prm::TPrmId iPrmInterfaceClock : 16; +// Omap3530Prm::TPrmId iPrmFunctionClock : 16; + }; + +static const THwInfo KHwInfo[3] = + { + { // EUart0 + TUartTraits< EUart0 >::KBaseAddress, + TUartTraits< EUart0 >::KInterruptId, + TUartTraits< EUart0 >::KInterfaceClock, + TUartTraits< EUart0 >::KFunctionClock, +// TUartTraits< EUart0 >::KPrmInterfaceClock, +// TUartTraits< EUart0 >::KPrmFunctionClock + }, + { // EUart1 + TUartTraits< EUart1 >::KBaseAddress, + TUartTraits< EUart1 >::KInterruptId, + TUartTraits< EUart1 >::KInterfaceClock, + TUartTraits< EUart1 >::KFunctionClock, +// TUartTraits< EUart1 >::KPrmInterfaceClock, +// TUartTraits< EUart1 >::KPrmFunctionClock + }, + { // EUart2 + TUartTraits< EUart2 >::KBaseAddress, + TUartTraits< EUart2 >::KInterruptId, + TUartTraits< EUart2 >::KInterfaceClock, + TUartTraits< EUart2 >::KFunctionClock, +// TUartTraits< EUart2 >::KPrmInterfaceClock, +// TUartTraits< EUart2 >::KPrmFunctionClock + }, + }; + +// Baud lookup table, indexed by [ TBaud, TUartMode ]. +// Values obtained from 3530 datasheet + +struct TBaudInfo + { + TUint8 iDlh; + TUint8 iDll; + TUint8 iMultiplier; // Multiplier selection for UART16x/13x mode + }; + +static const TBaudInfo KBaudControl[ TUart::KSupportedBaudCount ][ TUart::KSupportedUartModes ] = + { + // EUart EUartAutoBaud ESIR EMIR EFIR ECIR + /*1200*/ { {0x09, 0xC4, 16 }, {0x09, 0xC4, 16 }, {0x09, 0xC4, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*2400*/ { {0x04, 0xE2, 16 }, {0x04, 0xE2, 16 }, {0x04, 0xE2, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*4800*/ { {0x02, 0x71, 16 }, {0x02, 0x71, 16 }, {0x02, 0x71, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*9600*/ { {0x01, 0x38, 16 }, {0x01, 0x38, 16 }, {0x01, 0x38, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*14400*/ { {0x00, 0xD0, 16 }, {0x00, 0xD0, 16 }, {0x00, 0xD0, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*19200*/ { {0x00, 0x9C, 16 }, {0x00, 0x9C, 16 }, {0x00, 0x9C, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*28800*/ { {0x00, 0x68, 16 }, {0x00, 0x68, 16 }, {0x00, 0x68, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*38400*/ { {0x00, 0x4E, 16 }, {0x00, 0x4E, 16 }, {0x00, 0x4E, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*57600*/ { {0x00, 0x34, 16 }, {0x00, 0x34, 16 }, {0x00, 0x34, 16 }, {0x00, 0x02, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*115200*/ { {0x00, 0x1A, 16 }, {0x00, 0x1A, 16 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*230400*/ { {0x00, 0x0D, 16 }, {0x09, 0xC4, 16 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 16 } }, + /*460800*/ { {0x00, 0x08, 13 }, {0x09, 0xC4, 13 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 13 } }, + /*921600*/ { {0x00, 0x04, 13 }, {0x09, 0xC4, 13 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 13 } }, + /*1843000*/ { {0x00, 0x02, 13 }, {0x09, 0xC4, 13 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 13 } }, + /*3688400*/ { {0x00, 0x01, 13 }, {0x09, 0xC4, 13 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 13 } }, + /*4000000*/ { {0x00, 0x01, 13 }, {0x09, 0xC4, 13 }, {0x00, 0x1A, 16 }, {0x00, 0x01, 1 }, {0x00, 0x0, 1 }, {0x09, 0xC4, 13 } } + }; + +/** Default mode to target mode conversion */ +static const MDR1::MODE_SELECT::TMode KDefaultTargetMode[ TUart::KSupportedUartModes ] = + { + MDR1::MODE_SELECT::EUart16x, // EUart + MDR1::MODE_SELECT::EUart16xAutoBaud, // EUartAutoBaud + MDR1::MODE_SELECT::ESIR, // ESIR + MDR1::MODE_SELECT::EMIR, // EMIR + MDR1::MODE_SELECT::EFIR, // EFIR + MDR1::MODE_SELECT::ECIR, // ECIR + }; + +/** Conversion table from parity mode to LCR bit settings */ +static const TUint8 KParitySelectTable[ 5 ] = + { + LCR::PARITY_TYPE2::KOff bitor LCR::PARITY_TYPE1::KOff bitor LCR::PARITY_EN::KOff, // ENone, + LCR::PARITY_TYPE2::KOff bitor LCR::PARITY_TYPE1::KOff bitor LCR::PARITY_EN::KOn, // EOdd, + LCR::PARITY_TYPE2::KOff bitor LCR::PARITY_TYPE1::KOn bitor LCR::PARITY_EN::KOn, // EEven, + LCR::PARITY_TYPE2::KOn bitor LCR::PARITY_TYPE1::KOff bitor LCR::PARITY_EN::KOn, // EMark, + LCR::PARITY_TYPE2::KOn bitor LCR::PARITY_TYPE1::KOn bitor LCR::PARITY_EN::KOn, // ESpace + }; + +static const TUint8 KRxFifoTrigTable[] = + { + FCR::RX_FIFO_TRIG::K8Char, // EFifoTrigger8, + FCR::RX_FIFO_TRIG::K16Char, // EFifoTrigger16, + FCR::RX_FIFO_TRIG::K16Char, // EFifoTrigger32, + FCR::RX_FIFO_TRIG::K56Char, // EFifoTrigger56, + FCR::RX_FIFO_TRIG::K60Char, // EFifoTrigger60 + }; + +static const TUint8 KTxFifoTrigTable[] = + { + FCR::TX_FIFO_TRIG::K8Char, // EFifoTrigger8, + FCR::TX_FIFO_TRIG::K16Char, // EFifoTrigger16, + FCR::TX_FIFO_TRIG::K32Char, // EFifoTrigger32, + FCR::TX_FIFO_TRIG::K56Char, // EFifoTrigger56, + FCR::TX_FIFO_TRIG::K56Char, // EFifoTrigger60 + }; + +// RAII for entering and leaving mode B with enhanced enabled +class TRaiiEnhancedModeB + { + public: + TRaiiEnhancedModeB( TUart& aUart ); + ~TRaiiEnhancedModeB(); + + private: + TRaiiEnhancedModeB(); + + private: + TUart& iUart; + TUint8 iOldLcr; + TUint8 iOldEnhanced; + }; + +TRaiiEnhancedModeB::TRaiiEnhancedModeB( TUart& aUart ) + : iUart( aUart ) + { + iOldLcr = LCR::iMem.Read( aUart ); + LCR::iMem.Write( aUart, LCR::KConfigModeB ); + iOldEnhanced = EFR::iMem.Read( aUart ) bitand EFR::ENHANCED_EN::KMask; + EFR::iMem.Modify( aUart, KClearNone, EFR::ENHANCED_EN::KOn ); + } + +TRaiiEnhancedModeB::~TRaiiEnhancedModeB() + { + LCR::iMem.Write( iUart, LCR::KConfigModeB ); + EFR::iMem.Modify( iUart, EFR::ENHANCED_EN::KMask, iOldEnhanced ); + LCR::iMem.Write( iUart, iOldLcr ); + } + + + +EXPORT_C void TUart::Init() + { + // Perfom a UART soft reset + SYSC::iMem.Write( *this, SYSC::SOFTRESET::KOn ); + while( 0 == (SYSS::iMem.Read( *this ) bitand SYSS::RESETDONE::KMask) ); + LCR::iMem.Write( *this, LCR::KConfigModeB ); + EFR::iMem.Modify( *this, KClearNone, EFR::ENHANCED_EN::KOn ); + LCR::iMem.Write( *this, LCR::KConfigModeA ); + MCR::iMem.Modify( *this, KClearNone, MCR::TCR_TLR::KOn ); + FCR::iMem.Write( *this, FCR::FIFO_EN::KOn + bitor FCR::RX_FIFO_CLEAR::KOn + bitor FCR::TX_FIFO_CLEAR::KOn ); + LCR::iMem.Write( *this, LCR::KConfigModeB ); + EFR::iMem.Modify( *this, EFR::ENHANCED_EN::KOn, KSetNone ); + LCR::iMem.Write( *this, LCR::KConfigModeA ); + MCR::iMem.Modify( *this, MCR::TCR_TLR::KOn, KSetNone ); + LCR::iMem.Write( *this, LCR::KConfigModeOperational ); + } + +EXPORT_C TInt TUart::InterruptId() const + { + return KHwInfo[ iUartNumber ].iInterruptId; + } + +EXPORT_C Prcm::TClock TUart::PrcmInterfaceClk() const + { + return KHwInfo[ iUartNumber ].iInterfaceClock; + } + +EXPORT_C Prcm::TClock TUart::PrcmFunctionClk() const + { + return KHwInfo[ iUartNumber ].iFunctionClock; + } + +/*PORT_C TInt TUart::PrmInterfaceClk() const + { + return KHwInfo[ iUartNumber ].iPrmInterfaceClock; + } + +EXPORT_C TInt TUart::PrmFunctionClk() const + { + return KHwInfo[ iUartNumber ].iPrmFunctionClock; + } +*/ +EXPORT_C void TUart::DefineMode( const TUartMode aMode ) + { + __ASSERT_DEBUG( (TUint)aMode <= KSupportedUartModes, ClientPanic( __LINE__ ) ); + iMode = aMode; + iTargetMode = KDefaultTargetMode[ aMode ]; + } + +EXPORT_C void TUart::Enable() + { + // UART won't be enabled if a read-write cycle is done to MDR1 + // So just write the mode into MDR1 and clear anythis already in register +// MDR1::iMem.Modify( *this, MDR1::MODE_SELECT::KFieldMask, iTargetMode ); + MDR1::iMem.Write( *this, iTargetMode ); + } + +EXPORT_C void TUart::Disable() + { + MDR1::iMem.Modify( *this, MDR1::MODE_SELECT::KFieldMask, MDR1::MODE_SELECT::EDisable ); + } + +EXPORT_C void TUart::SetBaud( const TBaud aBaud ) + { + __ASSERT_DEBUG( (TUint)aBaud < KSupportedBaudCount, ClientPanic( __LINE__ ) ); + + const TUint dlh = KBaudControl[ aBaud ][ iMode ].iDlh; + const TUint dll = KBaudControl[ aBaud ][ iMode ].iDll; + + { + TRaiiEnhancedModeB enhanced_mode_b_in_current_scope( *this ); + + LCR::iMem.Write( *this, LCR::KConfigModeOperational ); + const TUint8 ier = IER::iMem.Read( *this ); + IER::iMem.Write( *this, 0 ); + LCR::iMem.Write( *this, LCR::KConfigModeB ); + + DLL::iMem.Write( *this, dll ); + DLH::iMem.Write( *this, dlh ); + + LCR::iMem.Write( *this, LCR::KConfigModeOperational ); + IER::iMem.Write( *this, ier ); + LCR::iMem.Write( *this, LCR::KConfigModeB ); + } + + // Update target mode if a multipler change is required + if( EUart == iMode ) + { + const TUint m = KBaudControl[ aBaud ][ iMode ].iMultiplier; + if( 13 == m ) + { + iTargetMode = MDR1::MODE_SELECT::EUart13x; + } + else + { + iTargetMode = MDR1::MODE_SELECT::EUart16x; + } + } + } + +EXPORT_C void TUart::SetDataFormat( const TDataBits aDataBits, const TStopBits aStopBits, const TParity aParity ) + { + __ASSERT_DEBUG( (TUint)aDataBits <= E8Data, ClientPanic( __LINE__ ) ); + __ASSERT_DEBUG( (TUint)aStopBits <= E2Stop, ClientPanic( __LINE__ ) ); + __ASSERT_DEBUG( (TUint)aParity <= ESpace, ClientPanic( __LINE__ ) ); + + const TRegValue8 lcrSet = aDataBits bitor aStopBits bitor KParitySelectTable[ aParity ]; + const TRegValue8 KClearMask = LCR::PARITY_TYPE2::KFieldMask + bitor LCR::PARITY_TYPE1::KFieldMask + bitor LCR::PARITY_EN::KFieldMask + bitor LCR::NB_STOP::KFieldMask + bitor LCR::CHAR_LENGTH::KFieldMask; + + LCR::iMem.Modify( *this, KClearMask, lcrSet ); + + } + +EXPORT_C void TUart::EnableFifo( const TEnableState aState, const TFifoTrigger aRxTrigger, const TFifoTrigger aTxTrigger ) + { + TRaiiEnhancedModeB enhanced_mode_b_in_current_scope( *this ); + + const TUint8 dll = DLL::iMem.Read( *this ); + const TUint8 dlh = DLH::iMem.Read( *this ); + + DLL::iMem.Write( *this, 0 ); + DLH::iMem.Write( *this, 0 ); + + const TUint8 rx_trig = ((TUint)aRxTrigger >= ETriggerUnchanged) + ? 0 + : KRxFifoTrigTable[ aRxTrigger ]; + const TUint8 tx_trig = ((TUint)aTxTrigger >= ETriggerUnchanged) + ? 0 + : KTxFifoTrigTable[ aTxTrigger ]; + const TUint8 KClearMask = TUint8(Omap3530Uart::FCR::RX_FIFO_TRIG::KFieldMask bitor Omap3530Uart::FCR::TX_FIFO_TRIG::KFieldMask); + + if( EEnabled == aState ) + { + FCR::iMem.Modify( *this, + KClearMask, + rx_trig bitor tx_trig bitor FCR::FIFO_EN::KOn ); + } + else + { + FCR::iMem.Modify( *this, FCR::FIFO_EN::KOn, KSetNone ); + } + + DLL::iMem.Write( *this, dll ); + DLH::iMem.Write( *this, dlh ); + } + + +LOCAL_C void ModifyIER( TUart& aUart, TUint8 aClearMask, TUint8 aSetMask ) + { + TRaiiEnhancedModeB enhanced_mode_b_in_current_scope( aUart ); + + LCR::iMem.Write( aUart, Omap3530Uart::LCR::KConfigModeOperational ); + IER::iMem.Modify( aUart, aClearMask, aSetMask ); + LCR::iMem.Write( aUart, LCR::KConfigModeB ); + } + +inline void EnableDisableInterrupt( TUart& aUart, TBool aEnable, TUart::TInterrupt aWhich ) + { + ModifyIER( aUart, + (aEnable ? KClearNone : (TUint8)1 << aWhich), + (aEnable ? (TUint8)1 << aWhich : KSetNone) ); + } + +EXPORT_C void TUart::EnableInterrupt( const TInterrupt aWhich ) + { + EnableDisableInterrupt( *this, ETrue, aWhich ); + } + +EXPORT_C void TUart::DisableInterrupt( const TInterrupt aWhich ) + { + EnableDisableInterrupt( *this, EFalse, aWhich ); + } + + +EXPORT_C void TUart::DisableAllInterrupts() + { + ModifyIER( *this, (TUint8)KClearAll, KSetNone ); + } + + +} // namespace Omap3530Uart + + +DECLARE_STANDARD_EXTENSION() + { + return KErrNone; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/uart/uart.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/uart/uart.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,38 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/uart/uart.mmp +// + +#include +#include "kernel/kern_ext.mmh" + +TARGET AsspTarget(uart, dll) +TARGETTYPE kext +LINKAS uart.dll +DEFFILE ./def/~/uart.def +NOSTRICTDEF + +SOURCEPATH . +SOURCE uart.cpp + +USERINCLUDE . +SYSTEMINCLUDE +\include\assp\omap3530_assp\ + +LIBRARY AsspTarget(kaomap3530, lib) + +EPOCALLOWDLLDATA + +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/usbcc/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/usbcc/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,27 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/usbcc/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS + +./omap3530_usbc.h assp/omap3530_assp/ +./def/eabi/usbv.def assp/omap3530_assp/eabi/ + +PRJ_MMPFILES +usbcc +usbv_lib diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/usbcc/def/eabi/usbv.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/usbcc/def/eabi/usbv.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,3 @@ +EXPORTS + _ZN15MOmap3530UsbPhy3NewEv @ 1 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/usbcc/omap3530_usbc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/usbcc/omap3530_usbc.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,318 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/usbcc/omap3530_usbc.h +// Platform-dependent USB client controller layer (USB PSL). +// + + +#ifndef __OMAP3530_USBC_H__ +#define __OMAP3530_USBC_H__ + +#include +#include +#include + +// This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client +// (device) controller. +// For simplicity's sake we assume the following endpoint layout of the controller. +// We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT), +// one Interrupt endpoint (IN), and of course endpoint zero (Ep0). +// +// This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also +// used as the array index for our local TTemplateAsspUsbcc::iEndpoints[]): +// +// 0 - 0 (Ep0 OUT) +// 0 - 1 (Ep0 IN) +// 1 - 3 (Bulk IN, Address 0x11, -> EpAddr2Idx(0x11) = 3) +// 2 - 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) = 4) +// 3 - 7 (Iso IN, Address 0x13, -> EpAddr2Idx(0x13) = 7) +// 4 - 8 (Iso OUT, Address 0x04, -> EpAddr2Idx(0x04) = 8) +// 5 - 11 (Int IN, Address 0x15, -> EpAddr2Idx(0x15) = 11) +// +// For the reason why this is so (or rather for the perhaps not so obvious system behind it), +// see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure +// DeviceEndpoints[] at the top of pa_usbc.cpp. + +// The total number of endpoints in our local endpoint array: +static const TInt KUsbTotalEndpoints = 16; //32; // Disabled due to limited FIFO space + +// The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices): +#define IS_VALID_ENDPOINT(x) ((x) > 0 && (x) < KUsbTotalEndpoints) +#define IS_OUT_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 0 || (x) == 2 || (x) == 4 || (x) == 6 || (x) == 8 || (x) == 10 || (x) == 12 || (x) == 14 || (x) == 16 || (x) == 18 || (x) == 20 || (x) == 22 ||(x) == 24 || (x) == 26 ||(x) == 28) +#define IS_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 1 || (x) == 3 || (x) == 5 || (x) == 7 || (x) == 9 || (x) == 11 || (x) == 13 || (x) == 15 || (x) == 17 || (x) == 19 || (x) == 21 || (x) == 23 ||(x) == 25 || (x) == 27 ||(x) == 29) +#define IS_BULK_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 1 || (x) == 3 || (x) == 5 || (x) == 7 || (x) == 9 || (x) == 11 || (x) == 13 || (x) == 15 || (x) == 17 || (x) == 19 || (x) == 21 || (x) == 23 ||(x) == 25 || (x) == 27) +#define IS_BULK_OUT_ENDPOINT(x) IS_VALID_ENDPOINT(x) &&((x) == 2 || (x) == 4 || (x) == 6 || (x) == 8 || (x) == 10 || (x) == 12 || (x) == 14 || (x) == 16 || (x) == 18 || (x) == 20 || (x) == 22 ||(x) == 24 || (x) == 26 ||(x) == 28) +#define IS_BULK_ENDPOINT(x) (IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x)) +#define IS_ISO_IN_ENDPOINT(x) EFalse +#define IS_ISO_OUT_ENDPOINT(x) EFalse +#define IS_ISO_ENDPOINT(x) (IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x)) +#define IS_INT_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 29) + +// This takes as an index the TTemplateAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11 +// and returns the hardware endpoint number 0..5 (note that not all input indices are valid; +// these will return -1): +/*static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] = +{0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};*/ +static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] = +{0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + +// And here is a function to use the above array: +static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint) + { + if (IS_VALID_ENDPOINT(aRealEndpoint)) return TBeagleAsspEndpoints[aRealEndpoint]; + else return -1; + } + +static inline TInt TemplateEp2ArrayIdx(TInt aRealEndpoint) + { + for(TInt x=0; x +//#include +#include +#include +#include +//#include +#include + + +// Debug support +#ifdef _DEBUG +static const char KUsbPanicCat[] = "USB PSL"; +#endif + +_LIT(KDfcName, "USB_DFC"); + +// Register definitions - move to a seperate header file at some point.. + +const TUint KCM_ICLKEN1_CORE = Omap3530HwBase::TVirtual<0x48004A10>::Value; + const TUint KENHOSTOTGUSB_BIT = KBit4; +const TUint KCM_AUTOIDLE1_CORE = Omap3530HwBase::TVirtual<0x48004A30>::Value; + const TUint KAUTO_HOSTOTGUSB_BIT = KBit4; + + +const TInt KSetupPacketSize = 8; +const TInt KMaxPayload = 0x400; +const TInt KUsbDfcPriority = 45; +const TUint KUSBBase = Omap3530HwBase::TVirtual<0x480AB000>::Value; + +// USB registers - need the slave clock enabled to access most of these +const TUint KFADDR_REG = 0x0; + const TUint KADDRESS_MSK = 0x7F; +const TUint KPOWER_REG = 0x1; + const TUint KSOFTCONNECT_BIT = KBit6; + const TUint KSUSPENDM_BIT = KBit1; + const TUint KRESUME_BIT = KBit2; + const TUint KHSEN_BIT = KBit5; +// const TUint KRESET_BIT = KBit3; +const TUint K_INTRTX_REG =0x2; +const TUint K_INTRRX_REG =0x4; +const TUint K_INTRTXE_REG =0x6; +const TUint K_INTRRXE_REG =0x8; +const TUint K_INTRUSB_REG = 0xA; +const TUint K_INTRUSBE_REG = 0xB; + const TUint K_INT_RESET = KBit2; + const TUint K_INT_RESUME = KBit1; + const TUint K_INT_SUSPEND = KBit0; +//const TUint K_DEVCTRL_REG = 0x60; +const TUint K_FIFO0_REG = 0x20; +const TUint K_FIFO_OFFSET = 0x4; +const TUint K_COUNT0_REG = 0x18; +const TUint K_RXCOUNT_REG = 0x18; +const TUint K_CONFIGDATA_REG = 0x1F; + const TUint K_MPRXE = KBit7; + const TUint K_MPTXE = KBit6; + const TUint K_DYNFIFO = KBit2; + const TUint K_SOFTCONNECT = KBit1; +const TUint K_INDEX_REG = 0xE; +const TUint K_PERI_CSR0_REG = 0x12; + const TUint K_EP0_FLUSHFIFO = KBit8; + const TUint K_EP0_SERV_SETUPEND = KBit7; + const TUint K_EP0_SERV_RXPKTRDY = KBit6; + const TUint K_EP0_SETUPEND = KBit4; + const TUint K_EP0_SENDSTALL = KBit5; + const TUint K_EP0_DATAEND = KBit3; + const TUint K_EP0_SENTSTALL = KBit2; + const TUint K_EP0_TXPKTRDY = KBit1; + const TUint K_EP0_RXPKTRDY = KBit0; +const TUint K_TXMAXP_REG = 0x10; +const TUint K_RXMAXP_REG = 0x14; +const TUint K_PERI_TXCSR_REG = 0x12; + const TUint K_TX_ISO = KBit14; + const TUint K_TX_DMAEN = KBit12; + const TUint K_TX_DMAMODE = KBit10; + const TUint K_TX_CLRDATATOG = KBit6; + const TUint K_TX_SENTSTALL = KBit5; + const TUint K_TX_SENDSTALL = KBit4; + const TUint K_TX_FLUSHFIFO = KBit3; + const TUint K_TX_UNDERRUN = KBit2; +// const TUint K_TX_FIFONOTEMPTY = KBit1; + const TUint K_TX_TXPKTRDY = KBit0; +const TUint K_PERI_RXCSR_REG = 0x16; + const TUint K_RX_ISO = KBit14; + const TUint K_RX_DMAEN = KBit13; + const TUint K_RX_DISNYET = KBit12; + const TUint K_RX_CLRDATATOG = KBit7; + const TUint K_RX_SENTSTALL = KBit6; + const TUint K_RX_SENDSTALL = KBit5; + const TUint K_RX_FLUSHFIFO = KBit4; + const TUint K_RX_OVERRUN = KBit2; + const TUint K_RX_RXPKTRDY = KBit0; +const TUint K_TXFIFOSZ_REG = 0x62; +const TUint K_RXFIFOSZ_REG = 0x63; +const TUint K_TXFIFOADDR_REG = 0x64; +const TUint K_RXFIFOADDR_REG = 0x66; +const TUint K_OTG_SYSCONFIG_REG = 0x404; + const TUint K_ENABLEWAKEUP = KBit2; +//const TUint K_OTG_SYSSTATUS_REG = 0x408; + +// End of Register definitions + +// Define USB_SUPPORTS_PREMATURE_STATUS_IN to enable proper handling of a premature STATUS_IN stage, i.e. a +// situation where the host sends less data than first announced and instead of more data (OUT) will send an +// IN token to start the status stage. What we do in order to implement this here is to prime the TX fifo with +// a ZLP immediately when we find out that we're dealing with a DATA_OUT request. This way, as soon as the +// premature IN token is received, we complete the transaction by sending off the ZLP. If we don't prime the +// TX fifo then there is no way for us to recognise a premature status because the IN token itself doesn't +// raise an interrupt. We would simply wait forever for more data, or rather we would time out and the host +// would move on and send the next Setup packet. +// The reason why we would not want to implement the proper behaviour is this: After having primed the TX fifo +// with a ZLP, it is impossible for a user to reject such a (class/vendor specific) Setup request, basically +// because the successful status stage happens automatically. At the time the user has received and decoded +// the Setup request there's for her no way to stall Ep0 in order to show to the host that this Setup packet +// is invalid or inappropriate or whatever, because she cannot prevent the status stage from happening. +// (All this is strictly true only if the amount of data in the data stage is less than or equal to Ep0's max +// packet size. However this is almost always the case.) +//#define USB_SUPPORTS_PREMATURE_STATUS_IN + + +static const TUsbcEndpointCaps DeviceEndpoints[KUsbTotalEndpoints] = + { + // Hardware # iEndpoints index + {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirOut)}, // 0 - 0 + {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirIn )}, // 0 - 1 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 1 - 2 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 2 - 3 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 3 - 4 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 4 - 5 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 5 - 6 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 6 - 7 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 7 - 8 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 8 - 9 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 9 - 10 + {KEp0MaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 10 - 11 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 11 - 12 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 12 - 13 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 13 - 14 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 14 - 15 + // Disabled due to limited FIFO space + /*{KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 15 - 16 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 16 - 17 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 17 - 18 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 18 - 19 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 19 - 20 + {KEp0MaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 20 - 21 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 21 - 22 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 22 - 23 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 23 - 24 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 24 - 25 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 25 - 26 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 26 - 27 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 27 - 28 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 28 - 29 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 29 - 30 + {KIntMaxPktSzMask, (KUsbEpTypeInterrupt | KUsbEpDirIn )} // 30- 31*/ + }; + + +// --- TEndpoint -------------------------------------------------------------- + +TEndpoint::TEndpoint() +// +// Constructor +// + : iRxBuf(NULL), iReceived(0), iLength(0), iZlpReqd(EFalse), iNoBuffer(EFalse), iDisabled(EFalse), + iPackets(0), iLastError(KErrNone), iRequest(NULL), iRxTimer(RxTimerCallback, this), + iRxTimerSet(EFalse), iRxMoreDataRcvd(EFalse), iPacketIndex(NULL), iPacketSize(NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf("TEndpoint::TEndpoint")); + } + + +void TEndpoint::RxTimerCallback(TAny* aPtr) +// +// (This function is static.) +// + { + TEndpoint* const ep = static_cast(aPtr); + if (!ep) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !ep")); + } + else if (!ep->iRxTimerSet) + { + // Timer 'stop' substitute (instead of stopping it, + // we just let it expire after clearing iRxTimerSet) + __KTRACE_OPT(KUSB, Kern::Printf("!ep->iRxTimerSet - returning")); + } + else if (!ep->iRxBuf) + { + // Request already completed + __KTRACE_OPT(KUSB, Kern::Printf("!ep->iRxBuf - returning")); + } + else if (ep->iRxMoreDataRcvd) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > rx timer cb: not yet completing...")); + ep->iRxMoreDataRcvd = EFalse; + ep->iRxTimer.Again(KRxTimerTimeout); + } + else + { + __KTRACE_OPT(KUSB, Kern::Printf(" > rx timer cb: completing now...")); + *ep->iPacketSize = ep->iReceived; + ep->iController->RxComplete(ep); + } + } + + +// --- DOmap3530Usbcc public --------------------------------------------------- + +DOmap3530Usbcc::DOmap3530Usbcc() +// +// Constructor. +// + : iCableConnected(ETrue), iBusIsPowered(EFalse), + iInitialized(EFalse), iUsbClientConnectorCallback(UsbClientConnectorCallback), + iAssp( static_cast( Arch::TheAsic() ) ), + iEp0Configured(EFalse), iSuspendDfc(SuspendDfcFn, this, 7), + iResumeDfc(ResumeDfcFn, this, 7), iResetDfc(ResetDfcFn, this, 7) + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DOmap3530Usbcc")); + + TInt r = Kern::DfcQCreate(iDfcQueue, KUsbDfcPriority, &KDfcName); + + iSuspendDfc.SetDfcQ(iDfcQueue); + iResetDfc.SetDfcQ(iDfcQueue); + iResumeDfc.SetDfcQ(iDfcQueue); + + iSoftwareConnectable = iAssp->UsbSoftwareConnectable(); + + iCableDetectable = iAssp->UsbClientConnectorDetectable(); + + if (iCableDetectable) + { + // Register our callback for detecting USB cable insertion/removal. + // We ignore the error code: if the registration fails, we just won't get any events. + // (Which of course is bad enough...) + (void) iAssp->RegisterUsbClientConnectorCallback(iUsbClientConnectorCallback, this); + // Call the callback straight away so we get the proper PIL state from the beginning. + (void) UsbClientConnectorCallback(this); + } + + for (TInt i = 0; i < KUsbTotalEndpoints; i++) + { + iEndpoints[i].iController = this; + } + + __KTRACE_OPT(KUSB, Kern::Printf("-DOmap3530Usbcc::DOmap3530Usbcc")); + } + + +TInt DOmap3530Usbcc::Construct() +// +// Construct. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Construct")); + + iPhy = MOmap3530UsbPhy::New(); + if( !iPhy ) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Failed to get pointer to USB PHY")); + return KErrNoMemory; + } + + //TInt r = PowerResourceManager::RegisterClient( iPrmClientId, KDfcName ); + //if( r != KErrNone ) + // { + // __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Failed to connect to PRM")); + // return r; + // } + + + TUsbcDeviceDescriptor* DeviceDesc = TUsbcDeviceDescriptor::New( + 0x00, // aDeviceClass + 0x00, // aDeviceSubClass + 0x00, // aDeviceProtocol + KEp0MaxPktSz, // aMaxPacketSize0 + KUsbVendorId, // aVendorId + KUsbProductId, // aProductId + KUsbDevRelease, // aDeviceRelease + 1); // aNumConfigurations + if (!DeviceDesc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev desc failed.")); + return KErrGeneral; + } + + TUsbcConfigDescriptor* ConfigDesc = TUsbcConfigDescriptor::New( + 1, // aConfigurationValue + ETrue, // aSelfPowered (see 12.4.2 "Bus-Powered Devices") + ETrue, // aRemoteWakeup + 0); // aMaxPower (mA) + if (!ConfigDesc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config desc failed.")); + return KErrGeneral; + } + + TUsbcLangIdDescriptor* StringDescLang = TUsbcLangIdDescriptor::New(KUsbLangId); + if (!StringDescLang) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for lang id $ desc failed.")); + return KErrGeneral; + } + + // ('sizeof(x) - 2' because 'wchar_t KStringXyz' created a wide string that ends in '\0\0'.) + + TUsbcStringDescriptor* StringDescManu = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringManufacturer)), + sizeof(KStringManufacturer) - 2, sizeof(KStringManufacturer) - 2)); + if (!StringDescManu) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for manufacturer $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescProd = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringProduct)), + sizeof(KStringProduct) - 2, sizeof(KStringProduct) - 2)); + if (!StringDescProd) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for product $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescSer = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringSerialNo)), + sizeof(KStringSerialNo) - 2, sizeof(KStringSerialNo) - 2)); + if (!StringDescSer) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for serial no $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescConf = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringConfig)), + sizeof(KStringConfig) - 2, sizeof(KStringConfig) - 2)); + if (!StringDescConf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc failed.")); + return KErrGeneral; + } + + const TBool b = InitialiseBaseClass(DeviceDesc, + ConfigDesc, + StringDescLang, + StringDescManu, + StringDescProd, + StringDescSer, + StringDescConf); + if (!b) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UsbClientController::InitialiseBaseClass failed.")); + return KErrGeneral; + } + + return KErrNone; + } + + +DOmap3530Usbcc::~DOmap3530Usbcc() +// +// Destructor. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::~DOmap3530Usbcc")); + + // Unregister our callback for detecting USB cable insertion/removal + if (iCableDetectable) + { + iAssp->UnregisterUsbClientConnectorCallback(); + } + if (iInitialized) + { + // (The explicit scope operator is used against Lint warning #1506.) + DOmap3530Usbcc::StopUdc(); + } + } + + +TBool DOmap3530Usbcc::DeviceStateChangeCaps() const +// +// Returns capability of hardware to accurately track the device state (Chapter 9 state). +// + { + return EFalse; + } + + +TInt DOmap3530Usbcc::SignalRemoteWakeup() +// +// Forces the UDC into a non-idle state to perform a remote wakeup operation. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SignalRemoteWakeup")); + Kern::Printf("DOmap3530Usbcc::SignalRemoteWakeup"); + // Resume signal + + TInt sysconfig = AsspRegister::Read32(KUSBBase+K_OTG_SYSCONFIG_REG ); + if(sysconfig&K_ENABLEWAKEUP && iRmWakeupStatus_Enabled) + { + AsspRegister::Modify8(KUSBBase+KPOWER_REG, KClearNone , KRESUME_BIT); + Kern::NanoWait(10000000); // Wait 10ms - Use a callback instead! + AsspRegister::Modify8(KUSBBase+KPOWER_REG, KRESUME_BIT, KSetNone); + } + return KErrNone; + } + + +void DOmap3530Usbcc::DumpRegisters() +// +// Dumps the contents of a number of UDC registers to the screen (using Kern::Printf()). +// Rarely used, but might prove helpful when needed. +// + { + Kern::Printf("DOmap3530Usbcc::DumpRegisters:"); + } + + +TDfcQue* DOmap3530Usbcc::DfcQ(TInt /* aUnit */) +// +// Returns a pointer to the kernel DFC queue to be used buy the USB LDD. +// + { + return iDfcQueue; + } + + +// --- DOmap3530Usbcc private virtual ------------------------------------------ + +TInt DOmap3530Usbcc::SetDeviceAddress(TInt aAddress) +// +// Sets the PIL-provided device address manually (if possible - otherwise do nothing). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetDeviceAddress: %d", aAddress)); + + AsspRegister::Write8(KUSBBase+KFADDR_REG, aAddress & KADDRESS_MSK); + + if (aAddress || GetDeviceStatus()==EUsbcDeviceStateAddress) + { + // Address can be zero. + MoveToAddressState(); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo) +// +// Prepares (enables) an endpoint (incl. Ep0) for data transmission or reception. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ConfigureEndpoint(%d)", aRealEndpoint)); + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (n < 0) + return KErrArgument; + + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iDisabled == EFalse) + { + EnableEndpointInterrupt(aRealEndpoint); + if(n!=0) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + if(aRealEndpoint%2==0) + { + + AsspRegister::Write16(KUSBBase+K_PERI_RXCSR_REG, K_RX_CLRDATATOG | K_RX_DISNYET); + } + else + { + AsspRegister::Write16(KUSBBase+K_PERI_TXCSR_REG, K_TX_CLRDATATOG); + } + } + else + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + AsspRegister::Write16(KUSBBase+K_PERI_CSR0_REG, K_EP0_FLUSHFIFO); // FlushFifo; + } + } + ep->iNoBuffer = EFalse; + if (n == 0) + iEp0Configured = ETrue; + + return KErrNone; + } + + +TInt DOmap3530Usbcc::DeConfigureEndpoint(TInt aRealEndpoint) +// +// Disables an endpoint (incl. Ep0). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeConfigureEndpoint(%d)", aRealEndpoint)); + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (n < 0) + return KErrArgument; + + DisableEndpointInterrupt(aRealEndpoint); + if (n == 0) + { + iEp0Configured = EFalse; + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_FLUSHFIFO); + } + else + { + if(aRealEndpoint%2==0) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_FLUSHFIFO); + } + else + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, KClearNone, K_TX_FLUSHFIFO); + } + } + return KErrNone; + } + + +TInt DOmap3530Usbcc::AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) +// +// Puts the requested endpoint resource to use, if possible. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::AllocateEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Allocate endpoint resource here. + + return KErrNone; + } + + +TInt DOmap3530Usbcc::DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) +// +// Stops the use of the indicated endpoint resource, if beneficial. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeAllocateEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Deallocate endpoint resource here. + + return KErrNone; + } + + +TBool DOmap3530Usbcc::QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const +// +// Returns the status of the indicated resource and endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::QueryEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Query endpoint resource here. The return value should reflect the actual state. + return ETrue; + } + + +TInt DOmap3530Usbcc::OpenDmaChannel(TInt aRealEndpoint) +// +// Opens a DMA channel for this endpoint. This function is always called during the creation of an endpoint +// in the PIL. If DMA channels are a scarce resource, it's possible to do nothing here and wait for an +// AllocateEndpointResource call instead. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::OpenDmaChannel(%d)", aRealEndpoint)); + + // TO DO (optional): Open DMA channel here. + + // An error should only be returned in case of an actual DMA problem. + return KErrNone; + } + + +void DOmap3530Usbcc::CloseDmaChannel(TInt aRealEndpoint) +// +// Closes a DMA channel for this endpoint. This function is always called during the destruction of an +// endpoint in the PIL. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::CloseDmaChannel(%d)", aRealEndpoint)); + + // TO DO (optional): Close DMA channel here (only if it was opened via OpenDmaChannel). + } + + +TInt DOmap3530Usbcc::SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) +// +// Sets up a read request for an endpoint on behalf of the LDD. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetupEndpointRead(%d)", aRealEndpoint)); + if (!IS_OUT_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_OUT_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iRxBuf != NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf != NULL", aRealEndpoint)); + return KErrGeneral; + } + ep->iRxBuf = aCallback.iBufferStart; + ep->iReceived = 0; + ep->iLength = aCallback.iLength; + + // For Bulk reads we start out with the assumption of 1 packet (see BulkReceive for why): + ep->iPackets = IS_BULK_OUT_ENDPOINT(aRealEndpoint) ? 1 : 0; + ep->iRequest = &aCallback; + ep->iPacketIndex = aCallback.iPacketIndex; + if (IS_BULK_OUT_ENDPOINT(aRealEndpoint)) + *ep->iPacketIndex = 0; // a one-off optimization + ep->iPacketSize = aCallback.iPacketSize; + + if (ep->iDisabled) + { + ep->iDisabled = EFalse; + EnableEndpointInterrupt(aRealEndpoint); + } + else if (ep->iNoBuffer) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > There had been no Rx buffer available: reading Rx FIFO now")); + ep->iNoBuffer = EFalse; + if (IS_BULK_OUT_ENDPOINT(aRealEndpoint)) + { + BulkReadRxFifo(aRealEndpoint); + } + else if (IS_ISO_OUT_ENDPOINT(aRealEndpoint)) + { + IsoReadRxFifo(aRealEndpoint); + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + } + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) +// +// Sets up a write request for an endpoint on behalf of the LDD. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetupEndpointWrite(%d)", aRealEndpoint)); + + if (!IS_IN_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_IN_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iTxBuf != NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: iEndpoints[%d].iTxBuf != NULL", aRealEndpoint)); + return KErrGeneral; + } + ep->iTxBuf = aCallback.iBufferStart; + ep->iTransmitted = 0; + ep->iLength = aCallback.iLength; + ep->iPackets = 0; + ep->iZlpReqd = aCallback.iZlpReqd; + ep->iRequest = &aCallback; + + if (IS_BULK_IN_ENDPOINT(aRealEndpoint)) + { + if (ep->iDisabled) + { + ep->iDisabled = EFalse; + EnableEndpointInterrupt(aRealEndpoint); + } + BulkTransmit(aRealEndpoint); + } + else if (IS_ISO_IN_ENDPOINT(aRealEndpoint)) + { + IsoTransmit(aRealEndpoint); + } + else if (IS_INT_IN_ENDPOINT(aRealEndpoint)) + { + IntTransmit(aRealEndpoint); + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::CancelEndpointRead(TInt aRealEndpoint) +// +// Cancels a read request for an endpoint on behalf of the LDD. +// No completion to the PIL occurs. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::CancelEndpointRead(%d)", aRealEndpoint)); + + if (!IS_OUT_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_OUT_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iRxBuf == NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf == NULL", aRealEndpoint)); + return KErrNone; + } + + // : Flush the Ep's Rx FIFO here + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_FLUSHFIFO ); + } + else + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_FLUSHFIFO ); + } + + ep->iRxBuf = NULL; + ep->iReceived = 0; + ep->iNoBuffer = EFalse; + + return KErrNone; + } + + +TInt DOmap3530Usbcc::CancelEndpointWrite(TInt aRealEndpoint) +// +// Cancels a write request for an endpoint on behalf of the LDD. +// No completion to the PIL occurs. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::CancelEndpointWrite(%d)", aRealEndpoint)); + + if (!IS_IN_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_IN_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iTxBuf == NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iTxBuf == NULL", aRealEndpoint)); + return KErrNone; + } + + // TO DO (optional): Flush the Ep's Tx FIFO here, if possible. + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_FLUSHFIFO ); + } + else + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, KClearNone, K_TX_FLUSHFIFO ); + } + + ep->iTxBuf = NULL; + ep->iTransmitted = 0; + ep->iNoBuffer = EFalse; + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SetupEndpointZeroRead() +// +// Sets up an Ep0 read request (own function due to Ep0's special status). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetupEndpointZeroRead")); + + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + if (ep->iRxBuf != NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf != NULL", KEp0_Out)); + return KErrGeneral; + } + ep->iRxBuf = iEp0_RxBuf; + ep->iReceived = 0; + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd) +// +// Sets up an Ep0 write request (own function due to Ep0's special status). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetupEndpointZeroWrite")); + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf != NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: iEndpoints[%d].iTxBuf != NULL", KEp0_In)); + return KErrGeneral; + } + ep->iTxBuf = aBuffer; + ep->iTransmitted = 0; + ep->iLength = aLength; + ep->iZlpReqd = aZlpReqd; + ep->iRequest = NULL; + Ep0Transmit(); + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SendEp0ZeroByteStatusPacket() +// +// Sets up an Ep0 write request for zero bytes. +// This is a separate function because no data transfer is involved here. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SendEp0ZeroByteStatusPacket")); + + // This is possibly a bit tricky. When this function is called it just means that the higher layer wants a + // ZLP to be sent. Whether we actually send one manually here depends on a number of factors, as the + // current Ep0 state (i.e. the stage of the Ep0 Control transfer), and, in case the hardware handles some + // ZLPs itself, whether it might already handle this one. + + // Here is an example of what the checking of the conditions might look like: + +#ifndef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST + if ((!iEp0ReceivedNonStdRequest && iEp0State == EP0_IN_DATA_PHASE) || +#else + if ((!iEp0ReceivedNonStdRequest && iEp0State != EP0_IDLE) || +#endif +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + (iEp0ReceivedNonStdRequest && iEp0State != EP0_OUT_DATA_PHASE)) +#else + (iEp0ReceivedNonStdRequest)) +#endif + + { + // TO DO: Arrange for the sending of a ZLP here. + Kern::Printf("ZLP!"); + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY | K_EP0_DATAEND ); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::StallEndpoint(TInt aRealEndpoint) +// +// Stalls an endpoint. +// + { + __KTRACE_OPT(KPANIC, Kern::Printf("DOmap3530Usbcc::StallEndpoint(%d)", aRealEndpoint)); + + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint cannot be stalled")); + return KErrArgument; + } + + // Stall the endpoint here. + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_SENDSTALL); + } + else + if(aRealEndpoint%2==0) + { + // RX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_SENDSTALL); + } + else + { + // TX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, KClearNone, K_TX_SENDSTALL ); + } + return KErrNone; + } + + +TInt DOmap3530Usbcc::ClearStallEndpoint(TInt aRealEndpoint) +// +// Clears the stall condition of an endpoint. +// + { + __KTRACE_OPT(KPANIC, Kern::Printf("DOmap3530Usbcc::ClearStallEndpoint(%d)", aRealEndpoint)); + + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint cannot be unstalled")); + return KErrArgument; + } + + // De-stall the endpoint here. + + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, K_EP0_SENTSTALL, KSetNone ); + } + else + if(aRealEndpoint%2==0) + { + //Clear RX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_SENDSTALL, KSetNone ); + } + else + { + //Clear TX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, K_TX_SENDSTALL, KSetNone ); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::EndpointStallStatus(TInt aRealEndpoint) const +// +// Reports the stall status of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::EndpointStallStatus(%d)", aRealEndpoint)); + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint has no stall status")); + return KErrArgument; + } + + // Query endpoint stall status here. The return value should reflect the actual state. + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_CSR0_REG); + return status & K_EP0_SENTSTALL; + } + else + if(aRealEndpoint%2==0) + { + //Clear RX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_RXCSR_REG); + return status & K_RX_SENDSTALL; + } + else + { + //Clear TX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_TXCSR_REG); + return status & K_TX_SENDSTALL; + + } + } + + +TInt DOmap3530Usbcc::EndpointErrorStatus(TInt aRealEndpoint) const +// +// Reports the error status of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::EndpointErrorStatus(%d)", aRealEndpoint)); + + if (!IS_VALID_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_VALID_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + + // TO DO: Query endpoint error status here. The return value should reflect the actual state. + // With some UDCs there is no way of inquiring the endpoint error status; say 'ETrue' in that case. + + // Bulk EP's don't have an error status + return ETrue; + } + + +TInt DOmap3530Usbcc::ResetDataToggle(TInt aRealEndpoint) +// +// Resets to zero the data toggle bit of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ResetDataToggle(%d)", aRealEndpoint)); + + // Reset the endpoint's data toggle bit here. + // With some UDCs there is no way to individually reset the endpoint's toggle bits; just return KErrNone + // in that case. + + if(aRealEndpoint==KEp0_Out || aRealEndpoint==KEp0_In) + { + // No way of setting data toggle for EP0 + } + else + if(aRealEndpoint%2==0) + { + //Clear RX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_CLRDATATOG); + } + else + { + //Clear TX stall + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aRealEndpoint/2)); + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, KClearNone, K_TX_CLRDATATOG); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SynchFrameNumber() const +// +// For use with isochronous endpoints only. Causes the SOF frame number to be returned. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SynchFrameNumber")); + + // TO DO: Query and return the SOF frame number here. + return 0; + } + +void DOmap3530Usbcc::SetSynchFrameNumber(TInt aFrameNumber) +// +// For use with isochronous endpoints only. Causes the SOF frame number to be stored. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetSynchFrameNumber(%d)", aFrameNumber)); + + // We should actually store this number somewhere. But the PIL always sends '0x00' + // in response to a SYNCH_FRAME request... + // TO DO: Store the frame number. Alternatively (until SYNCH_FRAME request specification changes): Do + // nothing. + } + +TInt DOmap3530Usbcc::StartUdc() +// +// Called to initialize the device controller hardware before any operation can be performed. +// + { + __KTRACE_OPT(KUSB,Kern::Printf("DOmap3530Usbcc::StartUdc")); + + if (iInitialized) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UDC already initialised")); + return KErrNone; + } + + // Disable UDC (might also reset the entire design): + UdcDisable(); + + // Bind & enable the UDC interrupt + if (SetupUdcInterrupt() != KErrNone) + { + return KErrGeneral; + } + // Enable the slave clock + EnableSICLK(); + + // Write meaningful values to some registers: + InitialiseUdcRegisters(); + + // Finally, turn on the UDC: + UdcEnable(); + + // and enable the PHY + iPhy->StartPHY(); + iPhy->SetPHYMode(ENormal); + + // Even if only one USB feature has been enabled, we later need to undo it: + iInitialized = ETrue; + + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc: UDC Enabled")); + + return KErrNone; + } + + +TInt DOmap3530Usbcc::StopUdc() +// +// Basically, makes undone what happened in StartUdc. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::StopUdc")); + + if (!iInitialized) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UDC not initialized")); + return KErrNone; + } + + // Disable UDC: + UdcDisable(); + // Disable & unbind the UDC interrupt: + ReleaseUdcInterrupt(); + iPhy->SetPHYMode(EUART); + + // Finally turn off slave clock + DisableSICLK(); + + // Only when all USB features have been disabled we'll call it a day: + iInitialized = EFalse; + + return KErrNone; + } + + +TInt DOmap3530Usbcc::UdcConnect() +// +// Connects the UDC to the bus under software control. How this is achieved depends on the UDC; the +// functionality might also be part of the Variant component (instead of the ASSP). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UdcConnect")); + + //AsspRegister::Modify8(KUSBBase+KPOWER_REG , KClearNone, KSOFTCONNECT_BIT); + AsspRegister::Write8(KUSBBase+KPOWER_REG , KSOFTCONNECT_BIT | KHSEN_BIT); + iPhy->EnablePHY(); + + // Here: A call into the Variant-provided function. + return iAssp->UsbConnect(); + } + + +TInt DOmap3530Usbcc::UdcDisconnect() +// +// Disconnects the UDC from the bus under software control. How this is achieved depends on the UDC; the +// functionality might also be part of the Variant component (instead of the ASSP). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UdcDisconnect")); + + // Here: A call into the Variant-provided function. + return iAssp->UsbDisconnect(); + } + + +TBool DOmap3530Usbcc::UsbConnectionStatus() const +// +// Returns a value showing the USB cable connection status of the device. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UsbConnectionStatus")); + + return iCableConnected; + } + + +TBool DOmap3530Usbcc::UsbPowerStatus() const +// +// Returns a truth value showing whether VBUS is currently powered or not. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UsbPowerStatus")); + + return iBusIsPowered; + } + + +TBool DOmap3530Usbcc::DeviceSelfPowered() const +// +// Returns a truth value showing whether the device is currently self-powered or not. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeviceSelfPowered")); + + // TO DO: Query and return self powered status here. The return value should reflect the actual state. + // (This can be always 'ETrue' if the UDC does not support bus-powered devices.) + return ETrue; + } + +const TUsbcEndpointCaps* DOmap3530Usbcc::DeviceEndpointCaps() const +// +// Returns a pointer to an array of elements, each of which describes the capabilities of one endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeviceEndpointCaps")); + __KTRACE_OPT(KUSB, Kern::Printf(" > Ep: Sizes Mask, Types Mask")); + __KTRACE_OPT(KUSB, Kern::Printf(" > --------------------------")); + for (TInt i = 0; i < KUsbTotalEndpoints; ++i) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > %02d: 0x%08x, 0x%08x", + i, DeviceEndpoints[i].iSizes, DeviceEndpoints[i].iTypesAndDir)); + } + return DeviceEndpoints; + } + + +TInt DOmap3530Usbcc::DeviceTotalEndpoints() const +// +// Returns the element number of the endpoints array a pointer to which is returned by DeviceEndpointCaps. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeviceTotalEndpoints")); + + return KUsbTotalEndpoints; + } + + +TBool DOmap3530Usbcc::SoftConnectCaps() const +// +// Returns a truth value showing whether or not there is the capability to disconnect and re-connect the D+ +// line under software control. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SoftConnectCaps")); + + return iSoftwareConnectable; + } + + +void DOmap3530Usbcc::Suspend() +// +// Called by the PIL after a Suspend event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Suspend")); + + if (NKern::CurrentContext() == EThread) + { + iSuspendDfc.Enque(); + } + else + { + iSuspendDfc.Add(); + } + // TO DO (optional): Implement here anything the device might require after bus SUSPEND signalling. + // Need to put the transceiver into suspend too. Can't do it here as it requries I2C and we are in an interrupt context. + AsspRegister::Modify8(KUSBBase+KPOWER_REG , KClearNone, KSUSPENDM_BIT); + } + + +void DOmap3530Usbcc::Resume() +// +// Called by the PIL after a Resume event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Resume")); + if (NKern::CurrentContext() == EThread) + { + iResumeDfc.Enque(); + } + else + { + iResumeDfc.Add(); + } + + // TO DO (optional): Implement here anything the device might require after bus RESUME signalling. + // Need to put the transceiver into resume too. Can't do it here as it requries I2C and we are in an interrupt context. + AsspRegister::Modify8(KUSBBase+KPOWER_REG, KClearNone , KRESUME_BIT); + Kern::NanoWait(10000000); // Wait 10ms - Use a callback instead! + AsspRegister::Modify8(KUSBBase+KPOWER_REG, KRESUME_BIT, KSetNone); + } + + +void DOmap3530Usbcc::Reset() +// +// Called by the PIL after a Reset event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Reset")); + + // This does not really belong here, but has to do with the way the PIL sets + // up Ep0 reads and writes. + TEndpoint* ep = &iEndpoints[0]; + ep->iRxBuf = NULL; + ++ep; + ep->iTxBuf = NULL; + // Idle + Ep0NextState(EP0_IDLE); + // TO DO (optional): Implement here anything the device might require after bus RESET signalling. + // Need to put the transceiver into reset too. Can't do it here as it requries I2C and we are in an interrupt context. + if (NKern::CurrentContext() == EThread) + { + iResetDfc.Enque(); + } + else + { + iResetDfc.Add(); + } + + // Write meaningful values to some registers + InitialiseUdcRegisters(); + UdcEnable(); + if (iEp0Configured) + EnableEndpointInterrupt(0); + } + + +// --- DOmap3530Usbcc private -------------------------------------------------- + +void DOmap3530Usbcc::InitialiseUdcRegisters() +// +// Called after every USB Reset etc. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::InitialiseUdcRegisters")); + + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + AsspRegister::Write8(KUSBBase+K_CONFIGDATA_REG, K_SOFTCONNECT | K_DYNFIFO | K_MPTXE | K_MPRXE);// Dynamic FIFO + + // Configure FIFO's + for(TUint n=1; n16!) + { + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)((n+1)/2)); + if(n%2==0) + { + AsspRegister::Write16(KUSBBase+K_TXMAXP_REG, KMaxPayload | 0x1<<11); // Not sure how many packets we want to split into. Use 2 because it is OK for Bulk and INT + AsspRegister::Write8(KUSBBase+K_TXFIFOSZ_REG, 0x7); // No double buffering, FIFO size == 2^(7+3) = 1024 + AsspRegister::Write16(KUSBBase+K_TXFIFOADDR_REG, 128*((TInt)n/2)); // We have 16kb of memory and 16 endpoints. Start each fifo on a 1kb boundary + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, K_TX_DMAMODE | K_TX_ISO | K_TX_DMAEN, K_TX_CLRDATATOG | K_TX_FLUSHFIFO); + } + else + { + AsspRegister::Write16(KUSBBase+K_RXMAXP_REG, KMaxPayload | 0x1<<11); // Not sure how many packets we want to split into. Use 2 because it is OK for Bulk and INT + AsspRegister::Write8(KUSBBase+K_RXFIFOSZ_REG, 0x7); // No double buffering, FIFO size == 2^(7+3) = 1024 + AsspRegister::Write16(KUSBBase+K_RXFIFOADDR_REG, 128*((TInt)(n/2)+8)); // We have 16kb of memory and 16 endpoints. Start each fifo on a 1kb boundary + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_ISO | K_RX_DMAEN, K_RX_CLRDATATOG | K_RX_FLUSHFIFO | K_RX_DISNYET); + } + } + + // Disable interrupt requests for all endpoints + AsspRegister::Modify16(KUSBBase+K_INTRTXE_REG, 0xFFFF, KSetNone); + AsspRegister::Modify16(KUSBBase+K_INTRRXE_REG, 0XFFFE, KSetNone); + + AsspRegister::Modify32(KUSBBase+K_OTG_SYSCONFIG_REG, KClearNone, K_ENABLEWAKEUP); + } + + +void DOmap3530Usbcc::UdcEnable() +// +// Enables the UDC for USB transmission or reception. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UdcEnable")); + EnableSICLK(); + // TO DO: Do whatever is necessary to enable the UDC here. This might include enabling (unmasking) + // the USB Reset interrupt, setting a UDC enable bit, etc. + AsspRegister::Read8(KUSBBase+K_INTRUSB_REG); // Reading this register clears it + AsspRegister::Write8(KUSBBase+K_INTRUSBE_REG, K_INT_SUSPEND | K_INT_RESUME | K_INT_RESET); + DisableSICLK(); + } + + +void DOmap3530Usbcc::UdcDisable() +// +// Disables the UDC. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UdcDisable")); + EnableSICLK(); + // TO DO: Do whatever is necessary to disable the UDC here. This might include disabling (masking) + // the USB Reset interrupt, clearing a UDC enable bit, etc. + AsspRegister::Write8(KUSBBase+K_INTRUSBE_REG, 0x0); + AsspRegister::Read8(KUSBBase+K_INTRUSB_REG); // Reading this register clears it + DisableSICLK(); + } + + +void DOmap3530Usbcc::EnableEndpointInterrupt(TInt aEndpoint) +// +// Enables interrupt requests for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::EnableEndpointInterrupt(%d)", aEndpoint)); + + // Enable (unmask) interrupt requests for this endpoint: + if(aEndpoint==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRTXE_REG , KClearNone, 1<<(int)(aEndpoint/2)); + } + else + { + if(aEndpoint%2==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRRXE_REG , KClearNone, 1<<(int)((aEndpoint)/2)); + } + else + { + AsspRegister::Modify16(KUSBBase+K_INTRTXE_REG, KClearNone, 1<<(int)((aEndpoint)/2)); + } + } + } + + +void DOmap3530Usbcc::DisableEndpointInterrupt(TInt aEndpoint) +// +// Disables interrupt requests for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DisableEndpointInterrupt(%d)", aEndpoint)); + + // Disable (mask) interrupt requests for this endpoint: + if(aEndpoint==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRTXE_REG , 1<<(int)(aEndpoint/2), KSetNone); + } + else + { + if(aEndpoint%2==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRRXE_REG , 1<<(int)((aEndpoint)/2), KSetNone); + } + else + { + AsspRegister::Modify16(KUSBBase+K_INTRTXE_REG, 1<<(int)((aEndpoint)/2), KSetNone); + } + } + } + + +void DOmap3530Usbcc::ClearEndpointInterrupt(TInt aEndpoint) +// +// Clears a pending interrupt request for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ClearEndpointInterrupt(%d)", aEndpoint)); + + // Clear (reset) pending interrupt request for this endpoint: + if(aEndpoint==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRTX_REG , 1<<(int)(aEndpoint/2), KSetNone); + } + else + { + if(aEndpoint%2==0) + { + AsspRegister::Modify16(KUSBBase+K_INTRRX_REG , 1<<(int)((aEndpoint)/2), KSetNone); + } + else + { + AsspRegister::Modify16(KUSBBase+K_INTRTX_REG, 1<<(int)((aEndpoint)/2), KSetNone); + } + } + } + + +void DOmap3530Usbcc::Ep0IntService() +// +// ISR for endpoint zero interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0IntService")); + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + + // Enquire about Ep0 status & the interrupt cause here. Depending on the event and the Ep0 state, + + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0x0); + TUint ep0 = AsspRegister::Read16(KUSBBase+K_PERI_CSR0_REG); + + if(ep0 & K_EP0_SETUPEND) + { + // Setupend is set - A setup transaction ended unexpectedly + Ep0Cancel(); + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_SERV_SETUPEND); + Ep0NextState(EP0_IDLE); + } + if(ep0&K_EP0_SENTSTALL) + { + // Stalled! Complete the stall handshake + ClearStallEndpoint(0); + } + + switch(iEp0State) + { + case EP0_END_XFER: + Ep0EndXfer(); + break; + case EP0_IDLE: + if(ep0&K_EP0_RXPKTRDY) + { + Ep0ReadSetupPkt(); + } + else + { + Ep0StatusIn(); + } + break; + case EP0_OUT_DATA_PHASE: + Ep0Receive(); + break; + case EP0_IN_DATA_PHASE: + Ep0Transmit(); + break; + default: + break; // Do nothing + } + + ClearEndpointInterrupt(0); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + } + + +void DOmap3530Usbcc::Ep0ReadSetupPkt() +// +// Called from the Ep0 ISR when a new Setup packet has been received. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0ReadSetupPkt")); + + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Ep0 Rx buffer available (1)")); + StallEndpoint(KEp0_Out); + return; + } + + // Read Setup packet data from Rx FIFO into 'buf' here. + // (In this function we don't need to use "ep->iReceived" since Setup packets + // are always 8 bytes long.) + for(TInt x=0; xiRxBuf); + + if (state == EEp0StateStatusIn) + { + Ep0NextState(EP0_IDLE); // Ep0 No Data + } + else if (state == EEp0StateDataIn) + { + Ep0NextState(EP0_IN_DATA_PHASE); // Ep0 Control Read + } + else + { + Ep0NextState(EP0_OUT_DATA_PHASE); // Ep0 Control Write + } + + ep->iRxBuf = NULL; + const TInt r = Ep0RequestComplete(KEp0_Out, KSetupPacketSize, KErrNone); + + // Don't finish (proceed) if request completion returned 'KErrNotFound'! + if (!(r == KErrNone || r == KErrGeneral)) + { + DisableEndpointInterrupt(0); + } + +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + if (iEp0State == EP0_OUT_DATA_PHASE) + { + // Allow for a premature STATUS IN + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY | K_EP0_DATAEND); // TXPKTRDY, DATAEND + } +#endif + } + + +void DOmap3530Usbcc::Ep0ReadSetupPktProceed() +// +// Called by the PIL to signal that it has finished processing a received Setup packet and that the PSL can +// now prepare itself for the next Ep0 reception (for instance by re-enabling the Ep0 interrupt). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0ReadSetupPktProceed")); + + EnableEndpointInterrupt(0); + } + + +void DOmap3530Usbcc::Ep0Receive() +// +// Called from the Ep0 ISR when a data packet has been received. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0Receive")); + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Ep0 Rx buffer available (2)")); + StallEndpoint(KEp0_Out); + return; + } + + TInt n = 0; + // Read packet data from Rx FIFO into 'buf' and update 'n' (# of received bytes) here. + TInt FIFOCount = AsspRegister::Read8(KUSBBase+K_COUNT0_REG); + for(; niReceived = n; + ep->iRxBuf = NULL; + const TInt r = Ep0RequestComplete(KEp0_Out, n, KErrNone); + + // Don't finish (proceed) if request was 'KErrNotFound'! + if (!(r == KErrNone || r == KErrGeneral)) + { + DisableEndpointInterrupt(0); + } + +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + // Allow for a premature STATUS IN + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY | K_EP0_DATAEND); // TXPKTRDY, DATAEND +#endif + } + + +void DOmap3530Usbcc::Ep0ReceiveProceed() +// +// Called by the PIL to signal that it has finished processing a received Ep0 data packet and that the PSL can +// now prepare itself for the next Ep0 reception (for instance by re-enabling the Ep0 Ep0ReadSetupPkt). +// + { + Ep0ReadSetupPktProceed(); + } + + +void DOmap3530Usbcc::Ep0Transmit() +// +// Called from either the Ep0 ISR or the PIL when a data packet has been or is to be transmitted. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0Transmit")); + AsspRegister::Write8(KUSBBase+K_INDEX_REG, 0); + if (iEp0State != EP0_IN_DATA_PHASE) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: Invalid Ep0 state when trying to handle EP0 IN (0x%x)", iEp0State)); + // TO DO (optional): Do something about this warning. + } + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + const TUint8* buf = ep->iTxBuf; + if (!buf) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > No Tx buffer available: returning")); + return; + } + const TInt t = ep->iTransmitted; // already transmitted + buf += t; + TInt n = 0; // now transmitted + + // Write packet data (if any) into Tx FIFO from 'buf' and update 'n' (# of tx'ed bytes) here. + for(; niLength-ep->iTransmitted && niTransmitted += n; + if (n == KEp0MaxPktSz) + { + if (ep->iTransmitted == ep->iLength && !(ep->iZlpReqd)) + { + Ep0NextState(EP0_END_XFER); + } + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY); // TXPKTY, + } + else if (n && n != KEp0MaxPktSz) + { + // Send off the data + __ASSERT_DEBUG((ep->iTransmitted == ep->iLength), + Kern::Printf(" > ERROR: Short packet in mid-transfer")); + Ep0NextState(EP0_END_XFER); + // Send off the data here. + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY); // TXPKTRDY, + } + else // if (n == 0) + { + __ASSERT_DEBUG((ep->iTransmitted == ep->iLength), + Kern::Printf(" > ERROR: Nothing transmitted but still not finished")); + if (ep->iZlpReqd) + { + // Send a zero length packet + ep->iZlpReqd = EFalse; + Ep0NextState(EP0_END_XFER); + // Arrange for the sending of a ZLP here. + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_TXPKTRDY | K_EP0_DATAEND); // TXPKTRDY, DATAEND + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: nothing transmitted & no ZLP req'd")); + } + } + } + + +void DOmap3530Usbcc::Ep0EndXfer() +// +// Called at the end of a Ep0 Control transfer. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0EndXfer")); + // Clear Ep0 Rx condition flags here. + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_SERV_RXPKTRDY | K_EP0_DATAEND); // DATAEND + + Ep0NextState(EP0_IDLE); + TEndpoint* const ep = &iEndpoints[KEp0_In]; + ep->iTxBuf = NULL; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, KErrNone); + } + + +void DOmap3530Usbcc::Ep0Cancel() +// +// Called when an ongoing Ep0 Control transfer has to be aborted prematurely (for instance when receiving a +// new Setup packet before the processing of the old one has completed). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0Cancel")); + + Ep0NextState(EP0_IDLE); + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf) + { + ep->iTxBuf = NULL; + const TInt err = (ep->iTransmitted == ep->iLength) ? KErrNone : KErrCancel; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, err); + } + } + + +void DOmap3530Usbcc::Ep0PrematureStatusOut() +// +// Called when an ongoing Ep0 Control transfer encounters a premature Status OUT condition. +// + { + __KTRACE_OPT(KPANIC, Kern::Printf("DOmap3530Usbcc::Ep0PrematureStatusOut")); + + // Clear Ep0 Rx condition flags here. + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_SERV_RXPKTRDY | K_EP0_DATAEND); // DATAEND + Ep0NextState(EP0_IDLE); + + // Flush the Ep0 Tx FIFO here, if possible. + AsspRegister::Modify16(KUSBBase+K_PERI_CSR0_REG, KClearNone, K_EP0_FLUSHFIFO); + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf) + { + ep->iTxBuf = NULL; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, KErrPrematureEnd); + } + } + + +void DOmap3530Usbcc::Ep0StatusIn() +// +// Called when an ongoing Ep0 Control transfer moves to a Status IN stage. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::Ep0StatusIn")); + + Ep0NextState(EP0_IDLE); + } + + +void DOmap3530Usbcc::BulkTransmit(TInt aEndpoint) +// +// Endpoint 1 (BULK IN). +// Called from either the Ep ISR or the PIL when a data packet has been or is to be transmitted. +// + { + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::BulkTransmit(%d)", aEndpoint)); + + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aEndpoint/2)); + + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_TXCSR_REG); + + if(status & K_TX_UNDERRUN) + { + // TX UNDERRUN + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, K_TX_UNDERRUN, KSetNone); + } + if(status & K_TX_SENTSTALL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Stall Handshake")); + // Complete stall handshake + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, K_TX_SENTSTALL, KSetNone); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + if(status & K_TX_SENDSTALL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Stalled")); + // We are stalled + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + + TBool calledFromISR=AsspRegister::Read16(KUSBBase+K_INTRTX_REG) & 1<<(aEndpoint/2)==1; + + const TInt idx = aEndpoint; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + const TUint8* buf = ep->iTxBuf; + + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Tx buffer has been set up")); + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + ClearEndpointInterrupt(aEndpoint); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + const TInt t = ep->iTransmitted; // already transmitted + const TInt len = ep->iLength; // to be sent in total + // (len || ep->iPackets): Don't complete for a zero bytes request straight away. + if (t >= len && (len || ep->iPackets)) + { + if (ep->iZlpReqd) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" > 'Transmit Short Packet' explicitly")); + // Arrange for the sending of a ZLP here. + AsspRegister::Modify16(KUSBBase+K_PERI_TXCSR_REG, KClearNone, K_TX_TXPKTRDY); // FIFO_NOT_EMPTY, TXPKTRDY + ep->iZlpReqd = EFalse; + } + else + { + __KTRACE_OPT(KUSB, Kern::Printf(" > All data sent: %d --> completing", len)); + ep->iTxBuf = NULL; + ep->iRequest->iTxBytes = ep->iTransmitted; + ep->iRequest->iError = KErrNone; + EndpointRequestComplete(ep->iRequest); + ep->iRequest = NULL; + } + } + else + { + buf += t; + TInt left = len - t; // left in total + TInt n = (left >= KBlkMaxPktSz) ? KBlkMaxPktSz : left; // now to be transmitted + __KTRACE_OPT(KUSB, Kern::Printf(" > About to send %d bytes (%d bytes left in total)", n, left)); + + // Write data into Tx FIFO from 'buf' here... + TInt x=0; + TInt FIFOAddr = K_FIFO0_REG+K_FIFO_OFFSET*(TInt)((aEndpoint)/2); + for(; xiTransmitted += x; + ep->iPackets++; // only used for (len == 0) case + left -= n; // (still) left in total + + // If double-buffering is available, it might be possible to stick a second packet + // into the FIFO here. + + // TO DO (optional): Send another packet if possible (& available) here. + + } + if(calledFromISR) + { + ClearEndpointInterrupt(aEndpoint); + } + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + } + + + +void DOmap3530Usbcc::BulkReceive(TInt aEndpoint) +// +// Endpoint 2 (BULK OUT) (This one is called in an ISR.) +// + { + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::BulkReceive(%d)", aEndpoint)); + + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aEndpoint/2)); + + // Start NYETTING packets.. + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_DISNYET, KSetNone); + + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_RXCSR_REG); + + if(status & K_RX_OVERRUN) + { + // RX OVERRUN + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_OVERRUN, KSetNone); + } + if(status & K_RX_SENTSTALL) + { + // Complete stall handshake + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_SENTSTALL, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + + if(status & K_RX_SENDSTALL) + { + // We are stalled + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + + TBool calledFromISR=AsspRegister::Read16(KUSBBase+K_INTRRX_REG) & 1<<(aEndpoint/2)==1; + + const TInt idx = aEndpoint; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > No Rx buffer available: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + ClearEndpointInterrupt(aEndpoint); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_DISNYET); + return; + } + TInt bytes = AsspRegister::Read16(KUSBBase+K_RXCOUNT_REG); + const TInt r = ep->iReceived; // already received + // Check whether a ZLP was received here: + if (bytes==0) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > received zero-length packet")); + } + else// if (status & 2) // some other condition + { + __KTRACE_OPT(KUSB, Kern::Printf(" > Bulk received: %d bytes", bytes)); + if (r + bytes > ep->iLength) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > not enough space in rx buffer: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + StopRxTimer(ep); + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + + if(calledFromISR) + { + ClearEndpointInterrupt(aEndpoint); + } + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + buf += r; // set buffer pointer + + // Read 'bytes' bytes from Rx FIFO into 'buf' here. + TInt FIFOAddr = K_FIFO0_REG+K_FIFO_OFFSET*(TInt)((aEndpoint)/2); + for(TInt n=0; niReceived += bytes; + } + + if (bytes == 0) + { + // ZLPs must be recorded separately + const TInt i = ep->iReceived ? 1 : 0; + ep->iPacketIndex[i] = r; + ep->iPacketSize[i] = 0; + // If there were data packets before: total packets reported 1 -> 2 + ep->iPackets += i; + } + + if ((bytes < KBlkMaxPktSz) || + (ep->iReceived == ep->iLength)) + { + StopRxTimer(ep); + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + // since we have no buffer any longer we disable interrupts: + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + } + else + { + if (!ep->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > setting rx timer")); + ep->iRxTimerSet = ETrue; + ep->iRxTimer.OneShot(KRxTimerTimeout); + } + else + { + ep->iRxMoreDataRcvd = ETrue; + } + } + if(calledFromISR) + { + ClearEndpointInterrupt(aEndpoint); + } + // Clear Ep Rx condition flags here. + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_RXPKTRDY, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + } + + +void DOmap3530Usbcc::BulkReadRxFifo(TInt aEndpoint) +// +// Endpoint 2 (BULK OUT) (This one is called w/o interrupt to be served.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::BulkReadRxFifo(%d)", aEndpoint)); + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + + AsspRegister::Write8(KUSBBase+K_INDEX_REG, (TInt)(aEndpoint/2)); + + // Start NYETTING packets.. + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_DISNYET, KSetNone); + + TInt status = AsspRegister::Read16(KUSBBase+K_PERI_RXCSR_REG); + if(status & K_RX_OVERRUN) + { + // RX OVERRUN + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_OVERRUN, KSetNone); + } + if(status & K_RX_SENTSTALL) + { + // Complete stall handshake + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_SENTSTALL, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + if(status & K_RX_SENTSTALL) + { + // We are stalled + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + + TBool calledFromISR=AsspRegister::Read16(KUSBBase+K_INTRRX_REG) & 1<<(aEndpoint/2)==1; + + const TInt idx = aEndpoint; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Rx buffer has been set up")); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + TInt bytes = AsspRegister::Read16(KUSBBase+K_RXCOUNT_REG); + const TInt r = ep->iReceived; // already received + // Check whether a ZLP was received here: + if (bytes==0) // some condition + { + __KTRACE_OPT(KUSB, Kern::Printf(" > received zero-length packet")); + } + else //if (status & 2) // some other condition + { + __KTRACE_OPT(KUSB, Kern::Printf(" > Bulk received: %d bytes", bytes)); + if (r + bytes > ep->iLength) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > not enough space in rx buffer: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + + // Stop NYETting packets + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, KClearNone, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return; + } + buf += r; // set buffer pointer + + // TO DO: Read 'bytes' bytes from Rx FIFO into 'buf' here. + TInt FIFOAddr = K_FIFO0_REG+K_FIFO_OFFSET*(TInt)((aEndpoint)/2); + for(TInt n=0; niReceived += bytes; + } + if (bytes == 0) + { + // ZLPs must be recorded separately + const TInt i = ep->iReceived ? 1 : 0; + ep->iPacketIndex[i] = r; + ep->iPacketSize[i] = 0; + // If there were data packets before: total packets reported 1 -> 2 + ep->iPackets += i; + } + + if ((bytes < KBlkMaxPktSz) || + (ep->iReceived == ep->iLength)) + { + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + } + else + { + if (!ep->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > setting rx timer")); + ep->iRxTimerSet = ETrue; + ep->iRxTimer.OneShot(KRxTimerTimeout); + } + else + { + ep->iRxMoreDataRcvd = ETrue; + } + } + + if(calledFromISR) + { + ClearEndpointInterrupt(aEndpoint); + } + + // Stop NYETting packets and Clear Ep Rx condition flags here. + AsspRegister::Modify16(KUSBBase+K_PERI_RXCSR_REG, K_RX_RXPKTRDY, K_RX_DISNYET); + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + } + + +void DOmap3530Usbcc::IsoTransmit(TInt aEndpoint) +// +// Endpoint 3 (ISOCHRONOUS IN). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::IsoTransmit(%d)", aEndpoint)); + + // TO DO: Write data to endpoint FIFO. Might be similar to BulkTransmit. + + } + + +void DOmap3530Usbcc::IsoReceive(TInt aEndpoint) +// +// Endpoint 4 (ISOCHRONOUS OUT) (This one is called in an ISR.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::IsoReceive(%d)", aEndpoint)); + + // TO DO: Read data from endpoint FIFO. Might be similar to BulkReceive. + } + + +void DOmap3530Usbcc::IsoReadRxFifo(TInt aEndpoint) +// +// Endpoint 4 (ISOCHRONOUS OUT) (This one is called w/o interrupt to be served.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::IsoReadRxFifo(%d)", aEndpoint)); + + // TO DO: Read data from endpoint FIFO. Might be similar to BulkReadRxFifo. + } + + +void DOmap3530Usbcc::IntTransmit(TInt aEndpoint) +// +// Endpoint 5 (INTERRUPT IN). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::IntTransmit(%d)", aEndpoint)); + + // TO DO: Write data to endpoint FIFO. Might be similar to BulkTransmit. + } + + +void DOmap3530Usbcc::RxComplete(TEndpoint* aEndpoint) +// +// Called at the end of an Rx (OUT) transfer to complete to the PIL. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::RxComplete")); + TUsbcRequestCallback* const req = aEndpoint->iRequest; + + __ASSERT_DEBUG((req != NULL), Kern::Fault(KUsbPanicCat, __LINE__)); + + aEndpoint->iRxBuf = NULL; + aEndpoint->iRxTimerSet = EFalse; + aEndpoint->iRxMoreDataRcvd = EFalse; + req->iRxPackets = aEndpoint->iPackets; + req->iError = aEndpoint->iLastError; + EndpointRequestComplete(req); + aEndpoint->iRequest = NULL; + } + + +void DOmap3530Usbcc::StopRxTimer(TEndpoint* aEndpoint) +// +// Stops (cancels) the Rx timer for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::StopRxTimer")); + + if (aEndpoint->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > stopping rx timer")); + aEndpoint->iRxTimer.Cancel(); + aEndpoint->iRxTimerSet = EFalse; + } + } + + +void DOmap3530Usbcc::EndpointIntService(TInt aEndpoint) +// +// ISR for endpoint interrupts. +// Note: the aEndpoint here is a "hardware endpoint", not a aRealEndpoint. +// + { + switch (aEndpoint) + { + case 0: + Ep0IntService(); + break; + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: + case 29: + BulkTransmit(aEndpoint); + break; + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 26: + case 28: + BulkReceive(aEndpoint); + break; + case 30: + IntTransmit(aEndpoint); + break; + default: + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + break; + } + } + + +TInt DOmap3530Usbcc::ResetIntService() +// +// ISR for a USB Reset event interrupt. +// This function returns a value which can be used on the calling end to decide how to proceed. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ResetIntService")); + + // Clear an interrupt: + // TO DO: Clear reset interrupt flag here. + + // TO DO (optional): Enquire about special conditions and possibly return here. + + DeviceEventNotification(EUsbEventReset); + + return KErrNone; + } + + +void DOmap3530Usbcc::SuspendIntService() +// +// ISR for a USB Suspend event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SuspendIntService")); + + // Clear an interrupt: + // TO DO: Clear suspend interrupt flag here. + + DeviceEventNotification(EUsbEventSuspend); + } + + +void DOmap3530Usbcc::ResumeIntService() +// +// ISR for a USB Resume event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ResumeIntService")); + + // Clear an interrupt: + // TO DO: Clear resume interrupt flag here. + + DeviceEventNotification(EUsbEventResume); + } + + +void DOmap3530Usbcc::SofIntService() +// +// ISR for a USB Start-of-Frame event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SofIntService")); + + // Clear an interrupt: + // TO DO: Clear SOF interrupt flag here. + + // TO DO (optional): Do something about the SOF condition. + } + + +void DOmap3530Usbcc::UdcInterruptService() +// +// Main UDC ISR - determines the cause of the interrupt, clears the condition, dispatches further for service. +// + { + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + TUint status = AsspRegister::Read8(KUSBBase+K_INTRUSB_REG); + + // Reset interrupt + if (status & K_INT_RESET) + { + ResetIntService(); + } + + // Resume interrupt + if (status & K_INT_RESUME) + { + ResumeIntService(); + } + + // Endpoint interrupt + TUint TxEpInt = AsspRegister::Read16(KUSBBase+K_INTRTX_REG); + + TInt ep=0; + for(TInt x=0; TxEpInt!=0 && x<16 ; x++) + { + if(TxEpInt&(1<(aPtr)->UdcInterruptService(); + } + + +TInt DOmap3530Usbcc::UsbClientConnectorCallback(TAny* aPtr) +// +// This function is called in ISR context by the Variant's UsbClientConnectorInterruptService. +// (This function is static.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::UsbClientConnectorCallback")); + + DOmap3530Usbcc* const ptr = static_cast(aPtr); + ptr->iCableConnected = ptr->iAssp->UsbClientConnectorInserted(); +#ifdef _DEBUG + _LIT(KIns, "inserted"); + _LIT(KRem, "removed"); + __KTRACE_OPT(KUSB, Kern::Printf(" > USB cable now %lS", ptr->iCableConnected ? &KIns : &KRem)); +#endif + if (ptr->iCableConnected) + { + ptr->DeviceEventNotification(EUsbEventCableInserted); + } + else + { + ptr->DeviceEventNotification(EUsbEventCableRemoved); + } + + return KErrNone; + } + + +TInt DOmap3530Usbcc::SetupUdcInterrupt() +// +// Registers and enables the UDC interrupt (ASSP first level interrupt). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::SetupUdcInterrupt")); + + TInt error = Interrupt::Bind(EOmap3530_IRQ92_HSUSB_MC_NINT, UdcIsr, this); + if (error != KErrNone) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Binding UDC interrupt failed")); + return error; + } + Interrupt::Enable(EOmap3530_IRQ92_HSUSB_MC_NINT); + return KErrNone; + } + + +void DOmap3530Usbcc::ReleaseUdcInterrupt() +// +// Disables and unbinds the UDC interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::ReleaseUdcInterrupt")); + + Interrupt::Disable(EOmap3530_IRQ92_HSUSB_MC_NINT); + Interrupt::Unbind(EOmap3530_IRQ92_HSUSB_MC_NINT); + } + + +void DOmap3530Usbcc::EnableSICLK() + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::EnableSICLK")); + if(iSICLKEnabled==0) + { + //TInt r = PowerResourceManager::ChangeResourceState( iPrmClientId, Omap3530Prm::EPrmClkHsUsbOtg_I, Prcm::EClkAuto ); + // What are we supposed to do with errors from PRM? + + + AsspRegister::Modify32(KCM_ICLKEN1_CORE, KClearNone, KENHOSTOTGUSB_BIT); + AsspRegister::Modify32(KCM_AUTOIDLE1_CORE, KClearNone, KAUTO_HOSTOTGUSB_BIT); + + + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc: SICLK Enabled")); + } + iSICLKEnabled++; + } + +void DOmap3530Usbcc::DisableSICLK() + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DisableSICLK")); + if(iSICLKEnabled==1) + { + //TInt r = PowerResourceManager::ChangeResourceState( iPrmClientId, Omap3530Prm::EPrmClkHsUsbOtg_I, Prcm::EClkOff ); + // What are we supposed to do with errors from PRM? + + AsspRegister::Modify32(KCM_ICLKEN1_CORE, KENHOSTOTGUSB_BIT, KSetNone); + AsspRegister::Modify32(KCM_AUTOIDLE1_CORE, KAUTO_HOSTOTGUSB_BIT, KSetNone); + + + } + if(iSICLKEnabled>0) + { + iSICLKEnabled--; + } + } + +TBool DOmap3530Usbcc::CurrentlyUsingHighSpeed() + { + return ETrue; + } + +void DOmap3530Usbcc::SuspendDfcFn(TAny *aPtr) + { + + } + +void DOmap3530Usbcc::ResumeDfcFn(TAny *aPtr) + { + + } + +void DOmap3530Usbcc::ResetDfcFn(TAny *aPtr) + { + DOmap3530Usbcc* self = reinterpret_cast(aPtr); + // Put the Transceiver into normal mode + self->iPhy->EnablePHY(); + self->iPhy->SetPHYMode(ENormal); + self->iPhy->DisablePHY(); + } + +TBool DOmap3530Usbcc::DeviceHighSpeedCaps() const + { + __KTRACE_OPT(KUSB, Kern::Printf("DOmap3530Usbcc::DeviceHighSpeedCaps()")); + return ETrue; + } + + +// +// --- DLL Exported Function -------------------------------------------------- +// + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KUSB, Kern::Printf(" > Initializing USB client support (Udcc)...")); + + DOmap3530Usbcc* const usbcc = new DOmap3530Usbcc(); + if (!usbcc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for DOmap3530Usbcc failed")); + return KErrNoMemory; + } +Kern::Printf( "$1" ); + TInt r; + if ((r = usbcc->Construct()) != KErrNone) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Construction of DOmap3530Usbcc failed (%d)", r)); + delete usbcc; + return r; + } +Kern::Printf( "$2" ); + + if (usbcc->RegisterUdc(0) == NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: PIL registration of PSL failed")); + delete usbcc; + return KErrGeneral; + } + + __KTRACE_OPT(KUSB, Kern::Printf(" > Initializing USB client support: Done")); + + return KErrNone; + } + + +// --- EOF -------------------------------------------------------------------- diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/usbcc/usbcc.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/usbcc/usbcc.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,49 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/usbcc/usbcc.mmp +// + +#include +#include "kernel/kern_ext.mmh" + +systeminclude +/include/drivers +systeminclude +/include/assp/omap3530_assp + +target AsspTarget(usbcc,dll) +targettype kext +linkas usbcc.dll +noexportlibrary + +sourcepath ../../../../../../../sf/os/kernelhwsrv/kernel/eka/drivers/usbcc +source chapter9.cpp +source descriptors.cpp +source misc.cpp +source ps_usbc.cpp +source queue.cpp + +sourcepath . +source pa_usbc.cpp + +library dma.lib +//library resman.lib +library AsspTarget(kaomap3530,lib) +library AsspTarget(usbv,lib) + +deffile ../../../../../../../sf/os/kernelhwsrv/kernel/eka/~/usbcc.def + +epocallowdlldata + +capability all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/omap3530_drivers/usbcc/usbv_lib.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/omap3530_drivers/usbcc/usbv_lib.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,27 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_drivers/usbcc/usbv_lib.mmp +// + +#include +#include + +target AsspTarget(usbv,lib) +targettype implib +linkas usbv.dll + +deffile ./def/~/usbv.def +nostrictdef + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/release.src --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/release.src Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,20 @@ +NOTESRC_RELEASER +N/A + +NOTESRC_RELEASE_REASON +N/A + +NOTESRC_GENERAL_COMMENTS +N/A + +NOTESRC_KNOWN_DEVIATIONS +N/A + +NOTESRC_BUGS_FIXED +N/A + +NOTESRC_BUGS_REMAINING +N/A + +NOTESRC_OTHER_CHANGES +N/A \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/monitor/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/monitor/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,21 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/monitor/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +monitor diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/monitor/monitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/monitor/monitor.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,130 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/monitor/monitor.cpp +// +// + +#include +#include +#include +#include + +void CrashDebugger::InitUart() + { + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + Omap3530Uart::TUart uart( portNumber ); + + // Ensure UART clocks are running + Prcm::SetClockState( uart.PrcmInterfaceClk(),Prcm::EClkOn ); + Prcm::SetClockState( uart.PrcmFunctionClk(), Prcm::EClkOn ); + + // We don't know what state the UART is in, so reinitialize it + uart.Init(); + uart.DefineMode( Omap3530Uart::TUart::EUart ); + uart.SetBaud( Omap3530Uart::TUart::E115200 ); + uart.SetDataFormat( Omap3530Uart::TUart::E8Data, Omap3530Uart::TUart::E1Stop, Omap3530Uart::TUart::ENone ); + uart.Enable(); + } + } + +void CrashDebugger::UartOut(TUint aChar) + { + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + Omap3530Uart::TUart uart( portNumber ); + + TUint c=0; + + while ( !uart.RxFifoEmpty() ) + { + if ( CheckPower() ) + { + return; + } + + c = uart.Read(); + + if ( c == 19 ) // XOFF + { + FOREVER + { + while( uart.RxFifoEmpty() ) + { + if ( CheckPower() ) + { + return; + } + } + + c = uart.Read(); + + if ( c == 17 ) // XON + { + break; + } + else if ( c == 3 ) // Ctrl C + { + Leave(KErrCancel); + } + } + } + else if ( c == 3 ) // Ctrl C + { + Leave(KErrCancel); + } + } + + while ( uart.TxFifoFull() ) + { + CheckPower(); + } + + uart.Write( aChar ); + } + } + +TUint8 CrashDebugger::UartIn() + { + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + Omap3530Uart::TUart uart( portNumber ); + + while ( uart.RxFifoEmpty() ) + { + if ( CheckPower() ) + { + return 0x0d; + } + } + return uart.Read(); + } + + return 0; + } + +TBool CrashDebugger::CheckPower() + { + // + // Check if power supply is stable and return ETrue if not + // + return EFalse; // EXAMPLE ONLY + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/monitor/monitor.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/monitor/monitor.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,37 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/monitor/monitor.mmp +// +// + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include "assp/omap3530_assp/assp.mmh" +#include "../../../../../../../sf/os/kernelhwsrv/kernel/eka/kernel/exmondebug.mmp" + +target AsspTarget(exmondebug,dll) + +systeminclude +/include +sourcepath . +source monitor.cpp + +library AsspTarget(uart,lib) +library AsspTarget(prcm,lib) + +noexportlibrary + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,25 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\omap3530_assp\shared\mstick\bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS +omap3_mstick.h assp/omap3530_shared/ +mstick.iby /epoc32/rom/omapshared/ + +PRJ_MMPFILES +mstick diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/def/eabi/distribution.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/def/eabi/distribution.policy Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2 @@ +Category E +OSD: Reference/Test Tools diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/def/eabi/mstick.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/def/eabi/mstick.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,5 @@ +EXPORTS + _ZN5Omap36MsTick17SuppressIdleTicksEi @ 1 NONAME + _ZN5Omap36MsTick22EndIdleTickSuppressionEi @ 2 NONAME + _ZN5Omap36MsTick5StartEv @ 3 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/distribution.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/distribution.policy Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2 @@ +Category E +OSD: Reference/Test Tools diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/mstick.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/mstick.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,189 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/mstick/mstick.cpp +// + +#include +#include +#include +#include +#include + +using namespace TexasInstruments::Omap3530 ; +using namespace TexasInstruments::Omap3530::GPTimer ; + +const TUint32 KMaxIdleTicks = 0xFFFFFF; +const TUint KMinSuppressTickCount = 2; +static const Omap3530HwBase::TRegValue KTickInterruptMask = TISR::T_OVF_IT_FLAG::KOn; + + +namespace Omap3 +{ +namespace MsTick +{ + +void MsTickIsr(TAny* aPtr ) + { + // Clear interrupts + TGpTimer1::iTISR.Write( KTickInterruptMask ); + TGpTimer1::iTOCR.Write( 0 ); + reinterpret_cast< NTimerQ* >( aPtr )->Tick(); + } + + +EXPORT_C TInt Start() + { + __KTRACE_OPT(KBOOT,Kern::Printf("+Omap3:MsTick:Start")); + + // Enable GPT1 and set it to run from the 32kHz sysclk + Prcm::SetGptClockSource( Prcm::EGpt1, Prcm::EGptClock32k ); + Prcm::SetClockState( Prcm::EClkGpt1_F, Prcm::EClkOn ); + Prcm::SetClockState( Prcm::EClkGpt1_I, Prcm::EClkAuto ); + + __NK_ASSERT_DEBUG(TGpTimer1::iTISTAT.Read() == 0x1); + +// Prcm::AddToWakeupGroup( Prcm::EClkGpt1_I, Prcm::EWakeGroupMpu ); + + //Set GPT1 to highest priority + Interrupt::SetPriority(EOmap3530_IRQ37_GPT1_IRQ,KOmap3530MaxIntPriority); + + // Bind to GPTimer 1 interrupt + TInt r = Interrupt::Bind( TGpTimer1::Irq(), MsTickIsr, NTimerQ::TimerAddress() ); + + if( KErrNone == r ) + { + TGpTimer1::Reset(); + while ( !TGpTimer1::ResetComplete()) {} + + const TRegValue startOcp = ( TIOCP_CFG::T_AUTOIDLE::KOff + | TIOCP_CFG::T_SOFTRESET::KOff + | TIOCP_CFG::T_ENAWAKEUP::KOn + | TIOCP_CFG::T_IDLEMODE::KSmartIdle + | TIOCP_CFG::T_EMUFREE::KOff + | TIOCP_CFG::T_CLOCKACTIVITY::KMaintainFuncClock); + TGpTimer1::iTIOCP_CFG.Write(startOcp) ; + TGpTimer1::iTIOCP_CFG.Modify(TIOCP_CFG::T_SOFTRESET::KOn, KClear32); + TGpTimer1::iTIOCP_CFG.Write(startOcp); + + // Enable timer to generate wakeups + TGpTimer1::iTWER.Write(TWER::T_MAT_WUP_ENA::KOff | TWER::T_OVF_WUP_ENA::KOn | TWER::T_TCAR_WUP_ENA::KOff); + + TGpTimer1::ConfigureFor1Ms(); + + TGpTimer1::iTIER.Write(TIER::T_MAT_IT_ENA::KOff | TIER::T_OVF_IT_ENA::KOn | TIER::T_TCAR_IT_ENA::KOff); + TGpTimer1::iTISR.Write(TISR::T_MAT_IT_FLAG::KOn | TISR::T_OVF_IT_FLAG::KOn | TISR::T_TCAR_IT_FLAG::KOff); + + TGpTimer1::iTTGR.Write(1); + + TGpTimer1::iTOWR.Write( 0 ); + + while (TGpTimer1::WriteOutstanding()) {} + + // Start the timer in auto-reload mode + TGpTimer1::iTCLR.Modify(KClear32, (TCLR::T_ST::KOn | TCLR::T_AR::KOn | TCLR::T_IDLEMODE::KOverflow)); + + // Ensure Timer Control Reg write is completed + while(TGpTimer1::WriteOutstanding()); + + Interrupt::Enable(TGpTimer1::Irq()); + } + + __KTRACE_OPT(KBOOT,Kern::Printf("-Omap3:MsTick:Start:%d", r )); + return r; + } + +EXPORT_C TInt SuppressIdleTicks( TInt aMaxSleepTicks ) + { + TUint32 targetSleepTicks = (aMaxSleepTicks >= KMaxIdleTicks) ? KMaxIdleTicks : aMaxSleepTicks; + + if( targetSleepTicks >= KMinSuppressTickCount ) + { + while(TGpTimer1::WriteOutstanding()); + + // Mask out the next number of overflow events + // Don't clear TOCR - we want to include any pending expiries that happened + // while we were setting up into the sleep count + TGpTimer1::iTOWR.Write( targetSleepTicks ); + + // Clear any pending interrupt so we don't wake up immediately + TGpTimer1::iTISR.Write( KTickInterruptMask ); + while(TGpTimer1::WriteOutstanding()); + } + else + { + targetSleepTicks = 0; + } + + return targetSleepTicks; + } + +EXPORT_C TInt EndIdleTickSuppression( TInt aMaxSleepTicks ) + { + TUint actualSleepTicks = 0; + + if( aMaxSleepTicks >= KMinSuppressTickCount ) + { + // Get counter values immediately. TCRR must be read first so we can check for + // overflow while we are executing this code + TUint32 tcrr = TGpTimer1::iTCRR.Read(); + TUint32 tisr = TGpTimer1::iTISR.Read() bitand KTickInterruptMask; + TUint32 tocr = TGpTimer1::iTOCR.Read(); + + TUint32 targetSleepTicks = (aMaxSleepTicks >= KMaxIdleTicks) ? KMaxIdleTicks : aMaxSleepTicks; + + // Initial assumption is number of ticks missed == overflow count + actualSleepTicks = tocr; + + if( tisr ) + { + // If maximum time has expired TOCR will be reset to zero + // we want to handle the pending tick interrupt immediately + // in the normal tick ISR so don't include it in the count of + // ticks slept + actualSleepTicks = targetSleepTicks - 1; + } + + // Set timer back to normal mode + // Dont' clear interrupts - we want any pending timer interrupt handled in the tick ISR + TGpTimer1::iTOWR.Write( 0 ); + TGpTimer1::iTOCR.Write( 0 ); + while(TGpTimer1::WriteOutstanding()); + + // Check whether another tick has expired while we were doing this + if( TGpTimer1::iTCRR.Read() < tcrr ) + { + // it's overflowed since we first checked + if( tisr ) + { + // if there was already a pending interrupt to be handled by the tick ISR + // we need to include this new expiry in the sleep count + ++actualSleepTicks; + } + // else if there wasn't already a pending interrupt, this overflow will have generated + // one which will be handled by the tick ISR + } + } + + return actualSleepTicks; + } + +} // namespace MsTick +} // namespace Omap3 + + +DECLARE_STANDARD_EXTENSION() + { + return KErrNone; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/mstick.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/mstick.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,25 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\shared\mstick\mstick.iby +// + +#ifdef BASE_TEXT_SHELL_BUILD + +extension[VARID]= \Epoc32\Release\ARMV5\##BUILD##\_omap3XXX_mstick.dll \sys\bin\mstick.dll + +#else + +extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3XXX_mstick.dll \sys\bin\mstick.dll + +#endif diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/mstick.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/mstick.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,46 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_assp/shared/mstick/mstick.mmp +// + +#include + +#include + + +TARGET _omap3XXX_mstick.dll +TARGETTYPE kext +LINKAS mstick.dll +ROMTARGET mstick.dll + +SOURCEPATH . +SOURCE mstick.cpp + +USERINCLUDE . +SYSTEMINCLUDE +/include +SYSTEMINCLUDE +/include/kernel +SYSTEMINCLUDE +/include/drivers +SYSTEMINCLUDE +/include/nkern +SYSTEMINCLUDE +/include/assp/omap3530_assp + +NOSTRICTDEF +DEFFILE def/~/mstick.def + +LIBRARY AsspTarget( kaomap3530, lib ) +LIBRARY AsspTarget( prcm, lib ) + +EPOCALLOWDLLDATA +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/mstick/omap3_mstick.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/mstick/omap3_mstick.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,49 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/mstick/omap3_mstick.h +// + +#ifndef OMAP3_MSTICK_H +#define OMAP3_MSTICK_H + +#include + +namespace Omap3 +{ + namespace MsTick + { + /** Start the millisecond timer counting, call from Init3 stage of ASSP */ + IMPORT_C TInt Start(); + + /** Start idle tick supression + * @param aMaxSleepTicks Maximum number of ticks to sleep for + * @return If >0 the number of ticks that will be suppressed (could be < aMaxSleepTicks) + * @return If ==0 supression was not enabled + */ + IMPORT_C TInt SuppressIdleTicks( TInt aMaxSleepTicks ); + + /** End idle supression and restore tick timer to normal operation + * + * @param aMaxSleepTicks Original maximum number of ticks passed to SuppressIdleTicks() + * @return Actual number of ticks since SuppressIdleTickw() was called + */ + IMPORT_C TInt EndIdleTickSuppression( TInt aMaxSleepTicks ); + } // namespace MsTick +} // namespace Omap3 + + + +#endif // define OMAP3_MSTICK_H + + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/serialkeyb/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/serialkeyb/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,21 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/serialkeyb/bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +serialkeyboard diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/serialkeyb/serialkeyboard.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/serialkeyb/serialkeyboard.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,414 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/serialkeyb/serialkeyboard.mmp +// Simple serial keyboard implementation for Beagle baseport +// + +#include +#include +#include +#include +//#include + +const TInt KMagicCrashValue = 15; + + +#define SHIFTED(x) (0x8000|(x)) +#define ISSHIFTED(x) (0x8000&(x)) +#define CTRLED(x) (0x2000|(x)) +#define ISCTRL(x) (0x2000&(x)) +#define FUNCED(x) (0x4000|(x)) +#define ISFUNC(x) (0x4000&(x)) +#define STDKEY(x) (0x1FFF&(x)) + +static const TUint16 KScanCode[] = + { + /*00*/ EStdKeyNull, + /*01*/ EStdKeyHome, // ^A + /*02*/ EStdKeyLeftArrow, // ^B + /*03*/ EStdKeyEscape, // ^C + /*04*/ SHIFTED(EStdKeyDownArrow), // ^D - move window down + /*05*/ EStdKeyEnd, // ^E + /*06*/ EStdKeyRightArrow, // ^F + /*07*/ EStdKeyNull, + /*08*/ EStdKeyBackspace, // ^H - Reserved! + /*09*/ EStdKeyTab, // ^I - Reserved! + /*0a*/ EStdKeyNull, + /*0b*/ EStdKeyIncContrast, // ^K + /*0c*/ EStdKeyDecContrast, // ^L + /*0d*/ EStdKeyEnter, // ^M - Reserved! + /*0e*/ EStdKeyDownArrow, // ^N + /*0f*/ EStdKeyNull, // ^O = instant death + /*10*/ EStdKeyUpArrow, // ^P + /*11*/ CTRLED(EStdKeyLeftArrow), // ^Q - make window narrower + /*12*/ CTRLED(FUNCED('5')), // ^R - rotate windows in text window server + /*13*/ EStdKeyNull, + /*14*/ CTRLED(EStdKeyDownArrow), // ^T - make window taller + /*15*/ SHIFTED(EStdKeyUpArrow), // ^U - move window up + /*16*/ EStdKeyNull, + /*17*/ CTRLED(EStdKeyRightArrow), // ^W - make window wider + /*18*/ SHIFTED(EStdKeyRightArrow), // ^X - move window right + /*19*/ CTRLED(EStdKeyUpArrow), // ^Y - make window shorter + /*1a*/ SHIFTED(EStdKeyLeftArrow), // ^Z - move window left + /*1b*/ EStdKeyEscape, // ^[ - Reserved! + /*1c*/ EStdKeyNull, + /*1d*/ EStdKeyNull, + /*1e*/ EStdKeyNull, + /*1f*/ EStdKeyNull, + /*20*/ EStdKeySpace, + /*21*/ SHIFTED('1'), // ! + /*22*/ SHIFTED('2'), // " + /*23*/ EStdKeyHash, // # + /*24*/ SHIFTED('4'), // $ + /*25*/ SHIFTED('5'), // % + /*26*/ SHIFTED('7'), // & + /*27*/ EStdKeySingleQuote, + /*28*/ SHIFTED('9'), // ( + /*29*/ SHIFTED('0'), // ) + /*2a*/ SHIFTED('8'), // * + /*2b*/ SHIFTED(EStdKeyEquals), // + + /*2c*/ EStdKeyComma, + /*2d*/ EStdKeyMinus, + /*2e*/ EStdKeyFullStop, + /*2f*/ EStdKeyForwardSlash, + /*30*/ '0', + /*31*/ '1', + /*32*/ '2', + /*33*/ '3', + /*34*/ '4', + /*35*/ '5', + /*36*/ '6', + /*37*/ '7', + /*38*/ '8', + /*39*/ '9', + /*3a*/ SHIFTED(EStdKeySemiColon), // : + /*3b*/ EStdKeySemiColon, + /*3c*/ SHIFTED(EStdKeyComma), // < + /*3d*/ EStdKeyEquals, + /*3e*/ SHIFTED(EStdKeyFullStop), // > + /*3f*/ SHIFTED(EStdKeyForwardSlash), // ? + /*40*/ SHIFTED(EStdKeySingleQuote), // @ + /*41*/ SHIFTED('A'), + /*42*/ SHIFTED('B'), + /*43*/ SHIFTED('C'), + /*44*/ SHIFTED('D'), + /*45*/ SHIFTED('E'), + /*46*/ SHIFTED('F'), + /*47*/ SHIFTED('G'), + /*48*/ SHIFTED('H'), + /*49*/ SHIFTED('I'), + /*4a*/ SHIFTED('J'), + /*4b*/ SHIFTED('K'), + /*4c*/ SHIFTED('L'), + /*4d*/ SHIFTED('M'), + /*4e*/ SHIFTED('N'), + /*4f*/ SHIFTED('O'), + /*50*/ SHIFTED('P'), + /*51*/ SHIFTED('Q'), + /*52*/ SHIFTED('R'), + /*53*/ SHIFTED('S'), + /*54*/ SHIFTED('T'), + /*55*/ SHIFTED('U'), + /*56*/ SHIFTED('V'), + /*57*/ SHIFTED('W'), + /*58*/ SHIFTED('X'), + /*59*/ SHIFTED('Y'), + /*5a*/ SHIFTED('Z'), + /*5b*/ EStdKeySquareBracketLeft, + /*5c*/ EStdKeyBackSlash, + /*5d*/ EStdKeySquareBracketRight, + /*5e*/ SHIFTED('6'), // ^ + /*5f*/ SHIFTED(EStdKeyMinus), // _ + /*60*/ EStdKeyBacklightToggle, // Actually ` + /*61*/ 'A', + /*62*/ 'B', + /*63*/ 'C', + /*64*/ 'D', + /*65*/ 'E', + /*66*/ 'F', + /*67*/ 'G', + /*68*/ 'H', + /*69*/ 'I', + /*6a*/ 'J', + /*6b*/ 'K', + /*6c*/ 'L', + /*6d*/ 'M', + /*6e*/ 'N', + /*6f*/ 'O', + /*70*/ 'P', + /*71*/ 'Q', + /*72*/ 'R', + /*73*/ 'S', + /*74*/ 'T', + /*75*/ 'U', + /*76*/ 'V', + /*77*/ 'W', + /*78*/ 'X', + /*79*/ 'Y', + /*7a*/ 'Z', + /*7b*/ SHIFTED(EStdKeySquareBracketLeft), + /*7c*/ SHIFTED(EStdKeyBackSlash), + /*7d*/ SHIFTED(EStdKeySquareBracketRight), + /*7e*/ SHIFTED(EStdKeyHash), + /*7f*/ EKeyDelete + }; + +static const TUint16 KEscapedScanCode[] = + { + EStdKeyUpArrow, + EStdKeyDownArrow, + EStdKeyRightArrow, + EStdKeyLeftArrow + }; + +const TUint8 KEscapeChar = 0x1b; +const TUint8 KEscapeBase = 0x41; +const TUint8 KEscapeCount = sizeof(KEscapedScanCode) / sizeof(KEscapedScanCode[0]); +const TUint16 KEscapeScanCode = EStdKeyEscape; + +NONSHARABLE_CLASS(TSerialKeyboard) : public DBase + { +public: + inline TSerialKeyboard(); + TInt Create(); + +private: + static void UartIsr( TAny* aParam ); + static void AddKeyDfc( TAny* aParam ); + void AddKey( TUint aKey ); + + +private: + enum TState + { + ENormal, + EEscaping1, + EEscaping2 + }; + + TDfc iAddKeyDfc; + Omap3530Uart::TUart iUart; + TUint iPrmClientId; + TState iState : 8; + TUint8 iKey; + }; + +inline TSerialKeyboard::TSerialKeyboard() +: iAddKeyDfc( AddKeyDfc, this, Kern::DfcQue0(), 1 ), + iUart( Omap3530Assp::DebugPortNumber() ), + iState( ENormal ) + { + // Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second) + } + +TInt TSerialKeyboard::Create() + { + TInt r = KErrNone; + + const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() ); + + if( portNumber >= 0 ) + { + // Register with the power resource manager + _LIT( KName, "serkey" ); + /*r = PowerResourceManager::RegisterClient( iPrmClientId, KName ); + if( r != KErrNone ) + { + return r; + }*/ + + __KTRACE_OPT(KBOOT,Kern::Printf("+TSerialKeyboardl::Create:PRM client ID=%x", iPrmClientId )) ; + Kern::Printf("+TSerialKeyboardl::Create:PRM client ID=%x", iPrmClientId ); + + r = Interrupt::Bind( iUart.InterruptId(), UartIsr, this ); + if ( r < 0 ) + { + return r; + } + + // Ask power resource manager to turn on clocks to the UART + // (this could take some time but we're not in any hurry) + /*r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmFunctionClk(), Prcm::EClkOn ); + if( KErrNone != r ) + { + return r; + }*/ + + /*r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmInterfaceClk(), Prcm::EClkOn ); + if( KErrNone != r ) + { + return r; + }*/ + + // We can assume that the debug output code has already initialized the UART, we just need to prepare it for RX + iUart.EnableFifo( Omap3530Uart::TUart::EEnabled, Omap3530Uart::TUart::ETriggerUnchanged, Omap3530Uart::TUart::ETrigger8 ); + iUart.EnableInterrupt( Omap3530Uart::TUart::EIntRhr ); + + Interrupt::Enable( iUart.InterruptId() ); + } + + return r; + } + +void TSerialKeyboard::UartIsr( TAny* aParam ) + { + TSerialKeyboard* self = reinterpret_cast( aParam ); + + const TUint iir = Omap3530Uart::IIR::iMem.Read( self->iUart ); + + if ( 0 == (iir bitand Omap3530Uart::IIR::IT_PENDING::KMask) ) + { + const TUint pending = iir bitand Omap3530Uart::IIR::IT_TYPE::KFieldMask; + + // Although the TI datasheet descrivwed IT_TYPE as being an enumerated priority-decoded interrupt + // it appears to actually be a bitmask of active interrupt sources + if ( (pending bitand Omap3530Uart::IIR::IT_TYPE::ERHR) || (pending bitand Omap3530Uart::IIR::IT_TYPE::ERxLineStatus) ) + { + TUint byte = self->iUart.Read(); + + if( KMagicCrashValue == byte ) + { + Kern::Fault( "SERKEY-FORCED", 0 ); + } + else + { + self->iKey = byte; + self->iAddKeyDfc.Add(); + Interrupt::Disable( self->iUart.InterruptId() ); + } + } + } + } + +void TSerialKeyboard::AddKeyDfc( TAny* aParam ) + { + TSerialKeyboard* self = reinterpret_cast( aParam ); + + switch ( self->iState ) + { + case ENormal: + if ( self->iKey == KEscapeChar ) + { + self->iState = EEscaping1; + } + else + { + self->AddKey( KScanCode[ self->iKey ] ); + } + break; + + case EEscaping1: + if ( self->iKey == KEscapeChar ) + { + self->iState = EEscaping2; + } + else + { + self->AddKey( KEscapeScanCode ); + self->AddKey( KScanCode[ self->iKey ] ); + self->iState = ENormal; + } + break; + + case EEscaping2: + { + TInt index = self->iKey - KEscapeBase; + + if ( (index >= 0) && (index < KEscapeCount) ) + { + self->AddKey( KEscapedScanCode[ index ] ); + } + else + { + self->AddKey( KEscapeScanCode ); + self->AddKey( KScanCode[ self->iKey ] ); + } + self->iState = ENormal; + } + break; + + default: + self->iState = ENormal; + break; + }; + + Interrupt::Enable( self->iUart.InterruptId() ); + } + +void TSerialKeyboard::AddKey( TUint aKey ) + { + const TBool shifted = ISSHIFTED(aKey); + const TBool ctrl = ISCTRL(aKey); + const TBool func = ISFUNC(aKey); + const TUint8 stdKey = STDKEY(aKey); + + TRawEvent e; + + if ( func ) + { + e.Set( TRawEvent::EKeyDown, EStdKeyRightFunc, 0 ); + Kern::AddEvent( e ); + } + + if ( ctrl ) + { + e.Set( TRawEvent::EKeyDown, EStdKeyRightCtrl, 0 ); + Kern::AddEvent( e ); + } + + if ( shifted ) + { + e.Set( TRawEvent::EKeyDown, EStdKeyRightShift, 0 ); + Kern::AddEvent( e ); + } + + e.Set( TRawEvent::EKeyDown, stdKey, 0 ); + Kern::AddEvent( e ); + e.Set( TRawEvent::EKeyUp, stdKey, 0 ); + Kern::AddEvent( e ); + + if ( shifted ) + { + e.Set( TRawEvent::EKeyUp, EStdKeyRightShift, 0 ); + Kern::AddEvent( e ); + } + + if ( ctrl ) + { + e.Set( TRawEvent::EKeyUp, EStdKeyRightCtrl, 0 ); + Kern::AddEvent( e ); + } + + if ( func ) + { + e.Set( TRawEvent::EKeyUp, EStdKeyRightFunc, 0 ); + Kern::AddEvent( e ); + } + } + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting serial keyboard driver")); + + TInt r = KErrNoMemory; + TSerialKeyboard* keyboard = new TSerialKeyboard; + if ( keyboard ) + { + r = keyboard->Create(); + } + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/serialkeyb/serialkeyboard.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/serialkeyb/serialkeyboard.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,48 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/shared/serialkeyb/serialkeyboard.mmp +// omap3530/shared/serialkeyb.serialkeyboard.mmp +// Simple serial keyboard implementation for Beagle baseport +// + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include "beagle/variant.mmh" +#include "kernel/kern_ext.mmh" + +target AsspTarget(serialkeyboard,dll) +targettype kext +romtarget ekeyb.dll + +systeminclude +/include/drivers + +sourcepath . +source serialkeyboard.cpp + +library AsspTarget(uart,lib) +//library resman.lib + +noexportlibrary + +uid 0x100039cf 0x100000db + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/bld.inf Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,26 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530\omap3530_assp\shared\tps65950\bld.inf +// + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS +tps65950.h assp/omap3530_shared/ // +tps65950_registers.h assp/omap3530_shared/ // +tps65950.iby /epoc32/rom/omapshared/ + +PRJ_MMPFILES +tps65950 diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/distribution.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/distribution.policy Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2 @@ +Category E +OSD: Reference/Test Tools diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/eabi/distribution.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/eabi/distribution.policy Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2 @@ +Category E +OSD: Reference/Test Tools diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/eabi/tps65950.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/eabi/tps65950.def Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,11 @@ +EXPORTS + _ZN8TPS6595012ClearSetSyncEthh @ 1 NONAME + _ZN8TPS659508ReadSyncEtRh @ 2 NONAME + _ZN8TPS659509ExecAsyncERNS_4TReqE @ 3 NONAME + _ZN8TPS659509WriteSyncEth @ 4 NONAME + _ZN8TPS6595014DisableProtectEv @ 5 NONAME + _ZN8TPS6595014RestoreProtectEv @ 6 NONAME + _ZN8TPS6595011InitializedEv @ 7 NONAME + _ZN8TPS6595010GetRtcDataERNS_8TRtcTimeE @ 8 NONAME + _ZN8TPS6595010SetRtcDataERKNS_8TRtcTimeE @ 9 NONAME + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,760 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// \omap3530\omap3530_assp\shared\tps65950\tps65950.cpp +// Access driver for TPS65950 +// This file is part of the Beagle Base port +// + +#include +#include +#include +//#include +#include +#include +#include "tps65950.h" + + +GLREF_C TInt InitInterrupts(); + + +const TUint KGroupCount = 5; + +// One handle per group on TPS65950 +static I2c::THandle I2cHandle[ KGroupCount ]; + +// One DCB per group +static I2c::TConfigPb TheDcb[ KGroupCount ]; + +// I2C transfer object +enum TPhase + { + EAddressPb, + EDataPb + }; +static I2c::TTransferPb TheTransferPb[2]; + +// Group index to Group number +static const TUint8 KGroupIndexToGroupNumber[ KGroupCount ] = + { 0x12, 0x48, 0x49, 0x4a, 0x4b }; + +// Queue of requests +static SDblQue TheQueue; + +// Current state +enum TState + { + EIdle, + EPending, + EReading, + EWriting, + EUnprotectPhase0 + }; +static TState CurrentState; +TPS65950::TReq* CurrentPhaseReq; +TPS65950::TReq* PreviousPhaseReq; + +LOCAL_D TUint8 IsInitialized; // auto-cleared to EFalse + +const TUint8 KUnprotectPhase0Data = 0xCE; +const TUint8 KUnprotectPhase1Data = 0xEC; + +static const TUint8 KUnprotectData[4] = + { + TPS65950::Register::PROTECT_KEY bitand TPS65950::Register::KRegisterMask, KUnprotectPhase0Data, + TPS65950::Register::PROTECT_KEY bitand TPS65950::Register::KRegisterMask, KUnprotectPhase1Data, + }; + +static const TUint8 KProtectData[2] = + { + TPS65950::Register::PROTECT_KEY bitand TPS65950::Register::KRegisterMask, 0 + }; + +static TUint8 TempWriteBuf[2]; + +// Spinlock to protect queue when adding or removing items +//static TSpinLock QueueLock(TSpinLock::EOrderGenericIrqLow1+1); +static TSpinLock QueueLock(); + +GLDEF_D TDfcQue* TheDfcQue; + +const TInt KDfcQuePriority = 27; +_LIT( KDriverNameDes, "tps65950" ); + +TInt TheProtectionUsageCount = 0; + + + +LOCAL_C void InternalPanic( TInt aLine ) + { + Kern::Fault( "tps65950", aLine ); + } + +LOCAL_C void PanicClient( TPS65950::TPanic aPanic ) + { + Kern::PanicCurrentThread( KDriverNameDes, aPanic ); + } + +namespace TPS65950 +{ +void CompletionDfcFunction( TAny* aParam ); +void SyncDfcFunction( TAny* aParam ); +void DummyDfcFunction( TAny* aParam ); +static TDfc CompletionDfc( CompletionDfcFunction, NULL, 1 ); +static TDfc DummyDfc( CompletionDfcFunction, NULL, 1 ); + +FORCE_INLINE TReq& ReqFromLink( SDblQueLink* aLink ) + { + return *_LOFF( aLink, TReq, iLink ); + } + +inline TBool AtomicSetPendingWasIdle() + { + // atomic if (CurrentState == idleState) {CurrentState=EPending, returns TRUE} else {idleState=CurrentState, CurrentState unchanged, return FALSE} + TState idleState = EIdle; // required for atomic comparison + //TBool wasIdle = __e32_atomic_cas_ord32( (TUint32*)&CurrentState, (TUint32*)&idleState, EPending ); + //return wasIdle; + + if (CurrentState == idleState) + { + CurrentState = EPending; + return ETrue; + } + else + { + idleState = CurrentState; + return EFalse; + } + + } + + +void StartRead( TReq& aReq ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartRead(@%x) [%x:%x]", + &aReq, + KGroupIndexToGroupNumber[ aReq.iRegister >> Register::KGroupShift ], + aReq.iRegister bitand Register::KRegisterMask ) ); + + //__e32_atomic_store_ord32( &CurrentState, EReading ); + CurrentState = EReading; + + TheTransferPb[ EAddressPb ].iData = (TUint8*)&aReq.iRegister; // low byte is register address + TheTransferPb[ EDataPb ].iType = I2c::TTransferPb::ERead; + TheTransferPb[ EDataPb ].iData = &aReq.iReadValue; + __DEBUG_ONLY( aReq.iReadValue = 0xEE ); + TheTransferPb[ EDataPb ].iLength = 1; + TheTransferPb[ EAddressPb ].iResult = KErrNone; + TheTransferPb[ EDataPb ].iResult = KErrNone; + + TUint groupIndex = aReq.iRegister >> Register::KGroupShift; + I2c::TransferA( I2cHandle[ groupIndex ], TheTransferPb[ EAddressPb ] ); + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartRead(@%x)", &aReq ) ); + } + +void StartWrite( TReq& aReq ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartWrite(@%x) [%x:%x]<-%x", + &aReq, + KGroupIndexToGroupNumber[ aReq.iRegister >> Register::KGroupShift ], + aReq.iRegister bitand Register::KRegisterMask, + aReq.iWriteValue ) ); + + //__e32_atomic_store_ord32( &CurrentState, EWriting ); + CurrentState = EWriting; + + TempWriteBuf[0] = aReq.iRegister bitand Register::KRegisterMask; + TempWriteBuf[1] = aReq.iWriteValue; + TheTransferPb[ EDataPb ].iType = I2c::TTransferPb::EWrite; + TheTransferPb[ EDataPb ].iData = &TempWriteBuf[0]; + TheTransferPb[ EDataPb ].iLength = 2; + TheTransferPb[ EDataPb ].iResult = KErrNone; + + TUint groupIndex = aReq.iRegister >> Register::KGroupShift; + I2c::TransferA( I2cHandle[ groupIndex ], TheTransferPb[ EDataPb ] ); + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartWrite(@%x)", &aReq ) ); + } + +void StartUnprotectPhase0( TReq& aReq ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartUnprotectPhase0(@%x)", &aReq ) ); + + //__e32_atomic_store_ord32( &CurrentState, EUnprotectPhase0 ); + CurrentState = EUnprotectPhase0; + + TheTransferPb[ EDataPb ].iType = I2c::TTransferPb::EWrite; + TheTransferPb[ EDataPb ].iData = &KUnprotectData[0]; + TheTransferPb[ EDataPb ].iLength = 2; + TheTransferPb[ EDataPb ].iResult = KErrNone; + + const TUint groupIndex = Register::PROTECT_KEY >> Register::KGroupShift; + I2c::TransferA( I2cHandle[ groupIndex ], TheTransferPb[ EDataPb ] ); + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartUnprotectPhase0(@%x)", &aReq ) ); + } + +void StartUnprotectPhase1( TReq& aReq ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartUnprotectPhase1(@%x)", &aReq ) ); + + // Set state to writing so that it will complete as a normal write + //__e32_atomic_store_ord32( &CurrentState, EWriting ); + CurrentState = EWriting; + + TheTransferPb[ EDataPb ].iData = &KUnprotectData[2]; + TheTransferPb[ EDataPb ].iResult = KErrNone; + + const TUint groupIndex = Register::PROTECT_KEY >> Register::KGroupShift; + I2c::TransferA( I2cHandle[ groupIndex ], TheTransferPb[ EDataPb ] ); + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartUnprotectPhase1(@%x)", &aReq ) ); + } + +void StartProtect( TReq& aReq ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartProtect(@%x)", &aReq ) ); + + //__e32_atomic_store_ord32( &CurrentState, EWriting ); + CurrentState = EWriting; + + TheTransferPb[ EDataPb ].iType = I2c::TTransferPb::EWrite; + TheTransferPb[ EDataPb ].iData = &KProtectData[0]; + TheTransferPb[ EDataPb ].iLength = 2; + TheTransferPb[ EDataPb ].iResult = KErrNone; + + const TUint groupIndex = Register::PROTECT_KEY >> Register::KGroupShift; + I2c::TransferA( I2cHandle[ groupIndex ], TheTransferPb[ EDataPb ] ); + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartWrite(@%x)", &aReq ) ); + } + + +void StartRequest() + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:StartRequest(%d)", CurrentState ) ); + __ASSERT_DEBUG( EPending == CurrentState, InternalPanic( __LINE__ ) ); + + // We don't need to take lock here because we're currently idle so it's not possible + // for there to be a change in which item is queue head. The link pointers of the + // head item could change if another thread is queueing a new request, but that doesn't + // affect any of the fields we care about here + __ASSERT_DEBUG( !TheQueue.IsEmpty(), InternalPanic( __LINE__ ) ); + + if( !CurrentPhaseReq ) + { + PreviousPhaseReq = NULL; + CurrentPhaseReq = &ReqFromLink( TheQueue.First() ); + } + + FOREVER + { + if( !CurrentPhaseReq ) + { + __ASSERT_DEBUG( PreviousPhaseReq, InternalPanic( __LINE__ ) ); + + // we didn't find any phases to execute, so complete request + // by faking a write completion on the previous phase + CurrentPhaseReq = PreviousPhaseReq; + //__e32_atomic_store_ord32( &CurrentState, EWriting ); + CurrentState = EWriting; + + // Queue DFC instead of calling directly to avoid recursion if multiple items on queue + // complete without any action + CompletionDfc.Enque(); + break; + } + else + { + TReq::TAction action = CurrentPhaseReq->iAction; + + __KTRACE_OPT( KTPS65950, Kern::Printf( "=TPS65950:StartRequest:req@%x:a=%x", CurrentPhaseReq, action ) ); + + if( (TReq::ERead == action) || (TReq::EClearSet == action) ) + { + StartRead( *CurrentPhaseReq ); + break; + } + else if( TReq::EWrite == action ) + { + StartWrite( *CurrentPhaseReq ); + break; + } + else if( TReq::EDisableProtect == action ) + { + if( ++TheProtectionUsageCount == 1 ) + { + // Currently protected, start an unprotect sequence + StartUnprotectPhase0( *CurrentPhaseReq ); + break; + } + else + { + goto move_to_next_phase; + } + } + else if( TReq::ERestoreProtect == action ) + { + if( --TheProtectionUsageCount == 0 ) + { + StartProtect( *CurrentPhaseReq ); + break; + } + else + { + move_to_next_phase: + // already unprotected, skip to next phase + CurrentPhaseReq->iResult = KErrNone; + PreviousPhaseReq = CurrentPhaseReq; + CurrentPhaseReq = CurrentPhaseReq->iNextPhase; + } + } + else + { + InternalPanic( __LINE__ ); + } + } + } + + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:StartRequest(%d)", CurrentState ) ); + } + +void DummyDfcFunction( TAny* /*aParam*/ ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "TPS65950:DummyDFC(%d)", CurrentState ) ); + } + +void CompletionDfcFunction( TAny* /*aParam*/ ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:DFC(%d)", CurrentState ) ); + __ASSERT_DEBUG( EIdle != CurrentState, InternalPanic( __LINE__ ) ); + __ASSERT_DEBUG( CurrentPhaseReq, InternalPanic( __LINE__ ) ); + + TInt result = TheTransferPb[ EDataPb ].iResult; + if( KErrNone != TheTransferPb[ EAddressPb ].iResult ) + { + result = TheTransferPb[ EAddressPb ].iResult; + } + + TReq& req = *CurrentPhaseReq; + TBool completed = ETrue; + + if( KErrNone == result) + { + if( EReading == CurrentState ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "=TPS65950:DFC:Read [%x:%x]=%x", + KGroupIndexToGroupNumber[ req.iRegister >> Register::KGroupShift ], + req.iRegister bitand Register::KRegisterMask, + req.iReadValue ) ); + + if( TReq::EClearSet == req.iAction) + { + // Start write phase of a ClearSet + req.iWriteValue = (req.iReadValue bitand ~req.iClearMask) bitor req.iSetMask; + StartWrite( req ); + completed = EFalse; + } + } + else if( EUnprotectPhase0 == CurrentState ) + { + StartUnprotectPhase1( req ); + completed = EFalse; + } + } + + if( completed || (KErrNone != result) ) + { + // Read or write, protect has completed, or final write stage of a ClearSet or unprotect, or error + PreviousPhaseReq = CurrentPhaseReq; + CurrentPhaseReq = req.iNextPhase; + + if( CurrentPhaseReq ) + { + // start next phase + //__e32_atomic_store_ord32( &CurrentState, EPending ); + CurrentState = EPending; + StartRequest(); + } + else + { + //__e32_atomic_store_ord32( &CurrentState, EIdle ); + CurrentState = EIdle; + // From now a concurrent ExecAsync() can start a new request if it adds an item to the queue + + // remove item from queue and complete + TUint irq = __SPIN_LOCK_IRQSAVE( QueueLock ); + ReqFromLink( TheQueue.First() ).iLink.Deque(); + TBool queueEmpty = TheQueue.IsEmpty(); + __SPIN_UNLOCK_IRQRESTORE( QueueLock, irq ); + + // If queue was empty inside spinlock but an ExecAsync() adds an item before the if statement below, + // the ExecAsync() will start the new request + if( !queueEmpty ) + { + if( AtomicSetPendingWasIdle() ) + { + // ExecAsync didn't start a request + StartRequest(); + } + } + + // Notify client of completion + req.iResult = result; + if( req.iCompletionDfc ) + { + req.iCompletionDfc->Enque(); + } + } + } + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:DFC(%d)", CurrentState ) ); + } + +// Used to complete synchronous operations +void SyncDfcFunction( TAny* aParam ) + { + NKern::FSSignal( reinterpret_cast( aParam ) ); + } + + +EXPORT_C void ExecAsync( TReq& aRequest ) + { + __KTRACE_OPT( KTPS65950, Kern::Printf( "+TPS65950:ExecAsync(@%x)", &aRequest ) ); + + __ASSERT_DEBUG( (TUint)aRequest.iAction <= TReq::ERestoreProtect, PanicClient( EBadAction ) ); + __ASSERT_DEBUG( (TReq::EDisableProtect == aRequest.iAction) + || (TReq::ERestoreProtect == aRequest.iAction) + || (((TUint)aRequest.iRegister >> Register::KGroupShift) < KGroupCount), PanicClient( EBadGroup ) ); + + TUint irq = __SPIN_LOCK_IRQSAVE( QueueLock ); + TheQueue.Add( &aRequest.iLink ); + __SPIN_UNLOCK_IRQRESTORE( QueueLock, irq ); + + if( AtomicSetPendingWasIdle() ) + { + StartRequest(); + } + + __KTRACE_OPT( KTPS65950, Kern::Printf( "-TPS65950:ExecAsync" ) ); + } + +EXPORT_C TInt WriteSync( TUint16 aRegister, TUint8 aValue ) + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req; + req.iRegister = aRegister; + req.iAction = TReq::EWrite; + req.iCompletionDfc = &dfc; + req.iWriteValue = aValue; + req.iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req ); + NKern::FSWait( &sem ); + + return req.iResult; + } + +EXPORT_C TInt ReadSync( TUint16 aRegister, TUint8& aValue ) + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req; + req.iRegister = aRegister; + req.iAction = TReq::ERead; + req.iCompletionDfc = &dfc; + req.iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req ); + NKern::FSWait( &sem ); + + aValue = req.iReadValue; + return req.iResult; + } + +EXPORT_C TInt ClearSetSync( TUint16 aRegister, TUint8 aClearMask, TUint8 aSetMask ) + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req; + req.iRegister = aRegister; + req.iAction = TReq::EClearSet; + req.iCompletionDfc = &dfc; + req.iClearMask = aClearMask; + req.iSetMask = aSetMask; + req.iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req ); + NKern::FSWait( &sem ); + + return req.iResult; + } + +EXPORT_C TInt DisableProtect() + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req; + req.iAction = TReq::EDisableProtect; + req.iCompletionDfc = &dfc; + req.iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req ); + NKern::FSWait( &sem ); + + return req.iResult; + } + +EXPORT_C TInt RestoreProtect() + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req; + req.iAction = TReq::ERestoreProtect; + req.iCompletionDfc = &dfc; + req.iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req ); + NKern::FSWait( &sem ); + + return req.iResult; + } + + +TInt Init() + { + // Create DFC queue + TInt r = Kern::DfcQCreate( TheDfcQue, KDfcQuePriority, &KDriverNameDes ); + if( KErrNone != r ) + { + return r; + } + + TPS65950::CompletionDfc.SetDfcQ( TheDfcQue ); + TPS65950::DummyDfc.SetDfcQ( TheDfcQue ); + + // Open I2c handles + for( TInt i = 0; i < KGroupCount; ++i ) + { + TheDcb[i].iUnit = I2c::E1; // Master / slave + TheDcb[i].iRole = I2c::EMaster; + TheDcb[i].iMode = I2c::E7Bit; + TheDcb[i].iExclusiveClient = NULL; + TheDcb[i].iRate = I2c::E400K; + TheDcb[i].iOwnAddress = 0x01; + TheDcb[i].iDfcQueue = TheDfcQue; + TheDcb[i].iDeviceAddress = KGroupIndexToGroupNumber[i]; + + I2cHandle[i] = I2c::Open( TheDcb[i] ); + if( I2cHandle[i] < 0 ) + { + return I2cHandle[i]; + } + } + + // Setup transfer linked list + TheTransferPb[ EAddressPb ].iType = I2c::TTransferPb::EWrite; // address write + TheTransferPb[ EAddressPb ].iLength = 1; + TheTransferPb[ EAddressPb ].iCompletionDfc = &TPS65950::DummyDfc; + TheTransferPb[ EAddressPb ].iNextPhase = &TheTransferPb[ EDataPb ]; + TheTransferPb[ EDataPb ].iCompletionDfc = &TPS65950::CompletionDfc; + TheTransferPb[ EDataPb ].iNextPhase = NULL; + + return r; + } + +inline TInt BcdToDecimal( TUint8 aBcd ) + { + return ( aBcd bitand 0xF ) + ( (aBcd >> 4) * 10); + } + +inline TUint8 DecimalToBcd( TInt aDecimal ) + { + TUint tens = (aDecimal / 10); + return ( tens << 4 ) + ( aDecimal - tens ); + } + +EXPORT_C TInt GetRtcData( TRtcTime& aTime ) + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req[8]; // 9 stages to the operation + req[0].iRegister = RTC_CTRL_REG::Addr; + req[0].iAction = TReq::EClearSet; + req[0].iSetMask = RTC_CTRL_REG::GET_TIME; + req[0].iClearMask = 0; + req[0].iCompletionDfc = NULL; + req[0].iNextPhase = &req[1]; + + req[1].iRegister = Register::SECONDS_REG; + req[1].iAction = TReq::ERead; + req[1].iCompletionDfc = NULL; + req[1].iNextPhase = &req[2]; + + req[2].iRegister = Register::MINUTES_REG; + req[2].iAction = TReq::ERead; + req[2].iCompletionDfc = NULL; + req[2].iNextPhase = &req[3]; + + req[3].iRegister = Register::HOURS_REG; + req[3].iAction = TReq::ERead; + req[3].iCompletionDfc = NULL; + req[3].iNextPhase = &req[4]; + + req[4].iRegister = Register::DAYS_REG; + req[4].iAction = TReq::ERead; + req[4].iCompletionDfc = NULL; + req[4].iNextPhase = &req[5]; + + req[5].iRegister = Register::MONTHS_REG; + req[5].iAction = TReq::ERead; + req[5].iCompletionDfc = NULL; + req[5].iNextPhase = &req[6]; + + req[6].iRegister = Register::YEARS_REG; + req[6].iAction = TReq::ERead; + req[6].iCompletionDfc = NULL; + req[6].iNextPhase = &req[7]; + + req[7].iRegister = RTC_CTRL_REG::Addr; + req[7].iAction = TReq::EClearSet; + req[7].iSetMask = 0; + req[7].iClearMask = RTC_CTRL_REG::GET_TIME; + req[7].iCompletionDfc = &dfc; + req[7].iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req[0] ); + NKern::FSWait( &sem ); + + aTime.iSecond = BcdToDecimal( req[1].iReadValue ); + aTime.iMinute = BcdToDecimal( req[2].iReadValue ); + aTime.iHour = BcdToDecimal( req[3].iReadValue ); + aTime.iDay = BcdToDecimal( req[4].iReadValue ); + aTime.iMonth = BcdToDecimal( req[5].iReadValue ); + aTime.iYear = BcdToDecimal( req[6].iReadValue ); + + return KErrNone; + } + +#define BCD0(a) ((a)%10) +#define BCD1(a) (((a)/10)<<4) +#define TOBCD(i) (BCD1(i)|BCD0(i)) + +EXPORT_C TInt SetRtcData( const TRtcTime& aTime ) + { + __ASSERT_NO_FAST_MUTEX; + + NFastSemaphore sem; + TDfc dfc( SyncDfcFunction, &sem, TheDfcQue, 2 ); + TReq req[8]; // 9 stages to the operation + req[0].iRegister = RTC_CTRL_REG::Addr; + req[0].iAction = TReq::EClearSet; + req[0].iSetMask = 0; + req[0].iClearMask = RTC_CTRL_REG::STOP_RTC; + req[0].iCompletionDfc = NULL; + req[0].iNextPhase = &req[1]; + + req[1].iRegister = Register::SECONDS_REG; + req[1].iAction = TReq::EWrite; + req[1].iWriteValue = DecimalToBcd( aTime.iSecond ); + req[1].iCompletionDfc = NULL; + req[1].iNextPhase = &req[2]; + + req[2].iRegister = Register::MINUTES_REG; + req[2].iAction = TReq::EWrite; + req[2].iWriteValue = DecimalToBcd( aTime.iMinute ); + req[2].iCompletionDfc = NULL; + req[2].iNextPhase = &req[3]; + + req[3].iRegister = Register::HOURS_REG; + req[3].iAction = TReq::EWrite; + req[3].iWriteValue = DecimalToBcd( aTime.iHour ); + req[3].iCompletionDfc = NULL; + req[3].iNextPhase = &req[4]; + + req[4].iRegister = Register::DAYS_REG; + req[4].iAction = TReq::EWrite; + req[4].iWriteValue = DecimalToBcd( aTime.iDay ); + req[4].iCompletionDfc = NULL; + req[4].iNextPhase = &req[5]; + + req[5].iRegister = Register::MONTHS_REG; + req[5].iAction = TReq::EWrite; + req[5].iWriteValue = DecimalToBcd( aTime.iMonth ); + req[5].iCompletionDfc = NULL; + req[5].iNextPhase = &req[6]; + + req[6].iRegister = Register::YEARS_REG; + req[6].iAction = TReq::EWrite; + req[6].iWriteValue = DecimalToBcd( aTime.iYear ); + req[6].iCompletionDfc = NULL; + req[6].iNextPhase = &req[7]; + + req[7].iRegister = RTC_CTRL_REG::Addr; + req[7].iAction = TReq::EClearSet; + req[7].iSetMask = RTC_CTRL_REG::STOP_RTC; + req[7].iClearMask = 0; + req[7].iCompletionDfc = &dfc; + req[7].iNextPhase = NULL; + + NKern::FSSetOwner( &sem, NULL ); + ExecAsync( req[0] ); + NKern::FSWait( &sem ); + + return KErrNone; + } + +EXPORT_C TBool Initialized() + { + return IsInitialized; + } + +} // namespace TPS65950 + + + + +DECLARE_STANDARD_EXTENSION() + { + TInt r = TPS65950::Init(); + if( KErrNone == r ) + { + r = InitInterrupts(); + } + + IsInitialized = ( KErrNone == r ); + + return r; + } + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,246 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#ifndef TPS65950_H +#define TPS65950_H + +#include +#include +#include +#include + +// Trace - 191 = 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000 0x0000000 0x80000000 0x00000000 0x00000000 +#define KTPS65950 191 + + + +namespace TPS65950 +{ + +/** Structure used for issuing an asynchronous request + * You must set iDfc to point to a TDfc object which will + * be queued on completion + */ +struct TReq + { + enum TAction + { + ERead, + EWrite, + EClearSet, + EDisableProtect, + ERestoreProtect + }; + + + TUint16 iRegister; ///< Register to be accessed + TAction iAction : 8; ///< type of request, read, write or clearset + TUint8 iReadValue; ///< Returned value from a read, original value for a ClearSet, unused for write + union + { + TUint8 iWriteValue; ///< Value to write into register for a write + TUint8 iSetMask; ///< Bits to set in a ClearSet + }; + TUint8 iClearMask; ///< Bits to clear in a ClearSet + TDfc* iCompletionDfc; ///< Pointer to DFC to be called on completion (for multi-phase only the last TReq causes a completion) + TInt iResult; ///< KErrNone on success, else error code + TReq* iNextPhase; ///< set to NULL if this is a single request, for a multi-phase request set this to point to next TReq + SDblQueLink iLink; ///< Used internally to maintain linked list of requests + }; + +struct TRtcTime + { + TUint8 iSecond; + TUint8 iMinute; + TUint8 iHour; + TUint8 iDay; + TUint8 iMonth; + TUint8 iYear; + }; + +/** Test whether this driver has been initialized + * Use this in code which is expected to run early during boot + * to prevent it trying to access this driver before it is ready + * + * @return ETrue if initialized, EFalse if not + */ +IMPORT_C TBool Initialized(); + +/** Execute a request asynchronously + * + * @param aRequest Request object to executed, must stay valid until request completes + */ +IMPORT_C void ExecAsync( TReq& aRequest ); + +/** Execute a write synchronously + * @param aRegister Register to write to - this must be one of the + * register enumerations from tps65950_register.h + * or the value of a register Addr property + * + * @param aValue Value to write to register + * @return KErrNone on success, else standard error code + */ +IMPORT_C TInt WriteSync( TUint16 aRegister, TUint8 aValue ); + +/** Execute a read synchronously + * @param aRegister Register to write to - this must be one of the + * register enumerations from tps65950_register.h + * or the value of a register Addr property + * + * @param aValue Value read will be written to here + * @return KErrNone on success, else standard error code + */ +IMPORT_C TInt ReadSync( TUint16 aRegister, TUint8& aValue ); + +/** Execute a bit clear/set synchronously + * @param aRegister Register to write to - this must be one of the + * register enumerations from tps65950_register.h + * or the value of a register Addr property + * + * @param aClearMask Each '1' clear the corresponding bit in the register + * @param aSetMask Each '1' sets the corresponding bit in the register + * @return KErrNone on success, else standard error code + */ +IMPORT_C TInt ClearSetSync( TUint16 aRegister, TUint8 aClearMask, TUint8 aSetMask ); + +/** Disable protection of voltage control registers + * Call RestoreProtect() to re-enable protection + * + * Note - calls to DisableProtect and RestoreProtect() are + * reference-counted, so you must call RestoreProtect() the same + * number of times you called DisableProtect(). This is to allow + * multiple clients to disable and restore protection so that + * protection will only be re-enabled when the last client has + * restored it. + */ +IMPORT_C TInt DisableProtect(); + +/** Restore protection after a DisableProtect(). + * If other clients have called DisableProtect(), or this client + * has other DisableProtect() calls still not balanced by a + * RestoreProtect() then the protection will remain disabled + */ +IMPORT_C TInt RestoreProtect(); + +/** Read the current RTC time */ +IMPORT_C TInt GetRtcData( TRtcTime& aTime ); + +/** Set the RTC time */ +IMPORT_C TInt SetRtcData( const TRtcTime& aTime ); + +enum TPanic + { + EBadAction, ///< illegal value in TReq::iAction + ENoDfc, ///< iCompletionDFC is NULL + EBadGroup ///< Group component of iRegister is invalid + }; + + +enum TInterruptId + { + KTPS65950IrqFirst= (EIrqRangeBasePsu << KIrqRangeIndexShift), + + ETPS65950_IRQ_PWR_SC_DETECT = KTPS65950IrqFirst, + ETPS65950_IRQ_PWR_MBCHG, + ETPS65950_IRQ_PWR_PWROK_TIMEOUT, + ETPS65950_IRQ_PWR_HOT_DIE, + ETPS65950_IRQ_PWR_RTC_IT, + ETPS65950_IRQ_PWR_USB_PRES, + ETPS65950_IRQ_PWR_CHG_PRES, + ETPS65950_IRQ_PWR_CHG_PWRONS, + + ETPS65950_IRQ_MADC_USB_ISR1, + ETPS65950_IRQ_MADC_SW2_ISR1, + ETPS65950_IRQ_MADC_SW1_ISR1, + ETPS65950_IRQ_MADC_RT_ISR1, + + ETPS65950_IRQ_GPIO_0ISR1, + ETPS65950_IRQ_GPIO_1ISR1, + ETPS65950_IRQ_GPIO_2ISR1, + ETPS65950_IRQ_GPIO_3ISR1, + ETPS65950_IRQ_GPIO_4ISR1, + ETPS65950_IRQ_GPIO_5ISR1, + ETPS65950_IRQ_GPIO_6ISR1, + ETPS65950_IRQ_GPIO_7ISR2, + + ETPS65950_IRQ_GPIO_8ISR2, + ETPS65950_IRQ_GPIO_9ISR2, + ETPS65950_IRQ_GPIO_10ISR2, + ETPS65950_IRQ_GPIO_11ISR2, + ETPS65950_IRQ_GPIO_12ISR2, + ETPS65950_IRQ_GPIO_13ISR2, + ETPS65950_IRQ_GPIO_14ISR2, + ETPS65950_IRQ_GPIO_15ISR2, + + ETPS65950_IRQ_GPIO16ISR3, + ETPS65950_IRQ_GPIO17ISR3, + + ETPS65950_IRQ_BCI_BATSTS_ISR1, + ETPS65950_IRQ_BCI_TBATOR1_ISR1, + ETPS65950_IRQ_BCI_TBATOR2_ISR1, + ETPS65950_IRQ_BCI_ICHGEOC_ISR1, + ETPS65950_IRQ_BCI_ICHGLOW_ISR1ASTO, + ETPS65950_IRQ_BCI_IICHGHIGH_ISR1, + ETPS65950_IRQ_BCI_TMOVF_ISR1, + ETPS65950_IRQ_BCI_WOVF_ISR1, + + ETPS65950_IRQ_BCI_ACCHGOV_ISR1, + ETPS65950_IRQ_BCI_VBUSOV_ISR1, + ETPS65950_IRQ_BCI_VBATOV_ISR1, + ETPS65950_IRQ_BCI_VBATLVL_ISR1, + + ETPS65950_IRQ_KEYP_ITMISR1, + ETPS65950_IRQ_KEYP_ITTOISR1, + ETPS65950_IRQ_KEYP_ITLKISR1, + ETPS65950_IRQ_KEYP_ITKPISR1, + + ETPS65950_IRQ_USB_INTSTS_IDGND, + ETPS65950_IRQ_USB_INTSTS_SESSEND, + ETPS65950_IRQ_USB_INTSTS_SESSVALID, + ETPS65950_IRQ_USB_INTSTS_VBUSVALID, + ETPS65950_IRQ_USB_INTSTS_HOSTDISCONNECT, + ETPS65950_IRQ_USB_CARKIT_CARDP, + ETPS65950_IRQ_USB_CARKIT_CARINTDET, + ETPS65950_IRQ_USB_CARKIT_IDFLOAT, + ETPS65950_IRQ_USB_OTHER_INT_VB_SESS_VLD, + ETPS65950_IRQ_USB_OTHER_INT_DM_HI, + ETPS65950_IRQ_USB_OTHER_INT_DP_HI, + ETPS65950_IRQ_USB_OTHER_INT_MANU, + ETPS65950_IRQ_USB_OTHER_INT_ABNORMAL_STRESS, + ETPS65950_IRQ_USB_ID_INT_ID_RES_FLOAT, + ETPS65950_IRQ_USB_ID_INT_ID_RES_440K, + ETPS65950_IRQ_USB_ID_INT_ID_RES_200K, + ETPS65950_IRQ_USB_ID_INT_ID_RES_102K, + ETPS65950_IRQ_USB_CARKIT_SM_1_PSM_ERROR, + ETPS65950_IRQ_USB_CARKIT_SM_1_PH_ACC, + ETPS65950_IRQ_USB_CARKIT_SM_1_CHARGER, + ETPS65950_IRQ_USB_CARKIT_SM_1_USB_HOST, + ETPS65950_IRQ_USB_CARKIT_SM_1_USB_OTG_B, + ETPS65950_IRQ_USB_CARKIT_SM_1_CARKIT, + ETPS65950_IRQ_USB_CARKIT_SM_1_DISCONNECTED, + ETPS65950_IRQ_USB_CARKIT_SM_2_STOP_PLS_MISS, + ETPS65950_IRQ_USB_CARKIT_SM_2_STEREO_TO_MONO, + ETPS65950_IRQ_USB_CARKIT_SM_2_PHONE_UART, + ETPS65950_IRQ_USB_CARKIT_SM_2_PH_NO_ACK, + + KTPS65950IrqLast, + }; + +const TInt KNumTPSInts = (KTPS65950IrqLast - KTPS65950IrqFirst); + +} // namespace TPS65950 + + +#endif //tps65950 diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950.iby Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,25 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + +#ifdef BASE_TEXT_SHELL_BUILD + +extension[0x09080001]= \Epoc32\Release\ARMV5\##BUILD##\tps65950.dll \sys\bin\tps65950.dll + +#else + +extension[VARID]=\epoc32\release\ARMV5\UDEB\tps65950.dll \sys\bin\tps65950.dll + +#endif \ No newline at end of file diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950.mmp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,46 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/omap3530_assp/shared/tps65950/tps65950.mmp +// + +#include + +#include + + +TARGET tps65950.dll +TARGETTYPE kext + +SOURCEPATH . +SOURCE tps65950.cpp +SOURCE tps65950_int.cpp + +USERINCLUDE . +SYSTEMINCLUDE +/include +SYSTEMINCLUDE +/include/kernel +SYSTEMINCLUDE +/include/drivers +SYSTEMINCLUDE +/include/nkern +SYSTEMINCLUDE +/include/assp/omap3530_assp + +NOSTRICTDEF +DEFFILE ~/tps65950.def + +LIBRARY AsspTarget( kaomap3530, lib ) +LIBRARY AsspTarget( prcm, lib ) +LIBRARY AsspTarget( i2c, lib ) + +EPOCALLOWDLLDATA +CAPABILITY all + +VENDORID 0x70000001 diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950_int.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950_int.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,700 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// \omap3530\omap3530_assp\shared\tps65950\tps65950_int.cpp +// Interrupt dispatcher for TPS65950 +// This file is part of the Beagle Base port +// + +#include +#include +#include +//#include +#include +#include +#include "tps65950.h" +#include + +// Use a dedicated thread for processing interrupts to prevent deadlocking +// the main TSP65960 thread and to avoid needing a big state machine to +// process interrupts in multiple DFCs +TDfcQue* TheInterruptDfcQue; +_LIT( KInterruptDfcQueName, "TPS65950INT" ); +const TInt KInterruptDfcQuePriority = 28; +const TInt KDfcPriority = 2; + +#define FULL_RISING_EDGEMASK 0xAA +#define FULL_FALLING_EDGEMASK 0x55 + + +namespace TPS65950 +{ + +struct TInterruptBank + { + TInt iBit[8]; + }; + +struct TSubInterruptBank + { + TUint8 iLen; + TUint16 iRegs[6]; + }; + +enum TMaskPolarity + { + EClearToEnable, + ESetToEnable + }; + +struct TControl + { + TUint16 iSetReg; + TUint16 iClrReg; + TUint16 iStatReg; + TUint8 iBitMask; + TMaskPolarity iPolarity : 8; + }; + +NONSHARABLE_CLASS( TPS65950Int ) : public MInterruptDispatcher + { + public: + TPS65950Int(); + TInt Init(); + + virtual TInt Bind(TInt aId, TIsr aIsr, TAny* aPtr); + virtual TInt Unbind(TInt aId); + virtual TInt Enable(TInt aId); + virtual TInt Disable(TInt aId); + virtual TInt Clear(TInt aId); + virtual TInt SetPriority(TInt aId, TInt aPriority); + + private: + static void Spurious( TAny* aParam ); + static void Dispatch( TAny* aParam ); + static void Dfc( TAny* aParam ); + + TInt InitialiseTPS65950IntController(); + + private: + TDfc iDfc; + }; + +static SInterruptHandler TheHandlers[ TPS65950::KNumTPSInts ]; + +static const TControl KControl[ TPS65950::KNumTPSInts ] = + { +//iimr iReg group bitoffset /* +/*0*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_SC_DETECT, ESetToEnable}, +/*1*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_MBCHG, ESetToEnable}, +/*2*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_PWROK_TIMEOUT, ESetToEnable}, +/*3*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_HOT_DIE, ESetToEnable}, +/*4*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_RTC_IT, ESetToEnable}, +/*5*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_USB_PRES, ESetToEnable}, +/*6*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_CHG_PRES, ESetToEnable}, +/*7*/{ Register::PWR_IMR1, Register::PWR_IMR1, Register::PWR_ISR1, PWR_IMR1::PWR_CHG_PWRONS, ESetToEnable}, + +/*8*/{ Register::MADC_IMR1, Register::MADC_IMR1, Register::MADC_ISR1, MADC_IMR1::MADC_USB_ISR1, EClearToEnable}, +/*9*/{ Register::MADC_IMR1, Register::MADC_IMR1, Register::MADC_ISR1, MADC_IMR1::MADC_SW2_ISR1, EClearToEnable}, +/*10*/{ Register::MADC_IMR1, Register::MADC_IMR1, Register::MADC_ISR1, MADC_IMR1::MADC_SW1_ISR1, EClearToEnable}, +/*11*/{ Register::MADC_IMR1, Register::MADC_IMR1, Register::MADC_ISR1, MADC_IMR1::MADC_RT_ISR1, EClearToEnable}, + +/*12*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO7ISR1, EClearToEnable}, +/*13*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO6ISR1, EClearToEnable}, +/*14*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO5ISR1, EClearToEnable}, +/*15*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO4ISR1, EClearToEnable}, +/*16*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO3ISR1, EClearToEnable}, +/*17*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO2ISR1, EClearToEnable}, +/*18*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO1ISR1, EClearToEnable}, +/*19*/{ Register::GPIO_IMR1A, Register::GPIO_IMR1A, Register::GPIO_ISR1A, GPIO_IMR1A::GPIO0ISR1, EClearToEnable}, + +/*20*/ { Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO15ISR2, EClearToEnable}, +/*22*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO14ISR2, EClearToEnable}, +/*23*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO13ISR2, EClearToEnable}, +/*24*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO12ISR2, EClearToEnable}, +/*25*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO11ISR2, EClearToEnable}, +/*26*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO10ISR2, EClearToEnable}, +/*27*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO9ISR2, EClearToEnable}, +/*28*/{ Register::GPIO_IMR2A, Register::GPIO_IMR2A, Register::GPIO_ISR2A, GPIO_IMR2A::GPIO8ISR2, EClearToEnable}, + +/*29*/{ Register::GPIO_IMR3A, Register::GPIO_IMR3A, Register::GPIO_ISR3A, GPIO_IMR3A::GPIO17ISR3, EClearToEnable}, +/*30*/{ Register::GPIO_IMR3A, Register::GPIO_IMR3A, Register::GPIO_ISR3A, GPIO_IMR3A::GPIO16ISR3, EClearToEnable}, + +/*31*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_BATSTS_ISR1, EClearToEnable}, +/*32*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_TBATOR1_ISR1, EClearToEnable}, +/*33*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_TBATOR2_ISR1, EClearToEnable}, +/*34*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_ICHGEOC_ISR1, EClearToEnable}, +/*35*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_ICHGLOW_ISR1ASTO, EClearToEnable}, +/*36*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_IICHGHIGH_ISR1, EClearToEnable}, +/*37*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_TMOVF_ISR1, EClearToEnable}, +/*38*/{ Register::BCIIMR1A, Register::BCIIMR1A, Register::BCIISR1A, BCIIMR1A::BCI_WOVF_ISR1, EClearToEnable}, + +/*39*/{ Register::BCIIMR2A, Register::BCIIMR2A, Register::BCIISR2A, BCIIMR2A::BCI_ACCHGOV_ISR1, EClearToEnable}, +/*40*/{ Register::BCIIMR2A, Register::BCIIMR2A, Register::BCIISR2A, BCIIMR2A::BCI_VBUSOV_ISR1, EClearToEnable}, +/*41*/{ Register::BCIIMR2A, Register::BCIIMR2A, Register::BCIISR2A, BCIIMR2A::BCI_VBATOV_ISR1, EClearToEnable}, +/*42*/{ Register::BCIIMR2A, Register::BCIIMR2A, Register::BCIISR2A, BCIIMR2A::BCI_VBATLVL_ISR1, EClearToEnable}, + +/*43*/{ Register::KEYP_IMR1, Register::KEYP_IMR1, Register::KEYP_ISR1, KEYP_IMR1::KEYP_ITMISR1, EClearToEnable}, +/*44*/{ Register::KEYP_IMR1, Register::KEYP_IMR1, Register::KEYP_ISR1, KEYP_IMR1::KEYP_ITTOISR1, EClearToEnable}, +/*45*/{ Register::KEYP_IMR1, Register::KEYP_IMR1, Register::KEYP_ISR1, KEYP_IMR1::KEYP_ITLKISR1, EClearToEnable}, +/*46*/{ Register::KEYP_IMR1, Register::KEYP_IMR1, Register::KEYP_ISR1, KEYP_IMR1::KEYP_ITKPISR1, EClearToEnable}, + +/*46*/{ Register::USB_INT_EN_RISE_SET, Register::USB_INT_EN_RISE_CLR, Register::USB_INT_STS, USB_INT_STS::USB_INTSTS_IDGND, ESetToEnable }, +/*47*/{ Register::USB_INT_EN_RISE_SET, Register::USB_INT_EN_RISE_CLR, Register::USB_INT_STS, USB_INT_STS::USB_INTSTS_SESSEND, ESetToEnable }, +/*48*/{ Register::USB_INT_EN_RISE_SET, Register::USB_INT_EN_RISE_CLR, Register::USB_INT_STS, USB_INT_STS::USB_INTSTS_SESSVALID, ESetToEnable }, +/*49*/{ Register::USB_INT_EN_RISE_SET, Register::USB_INT_EN_RISE_CLR, Register::USB_INT_STS, USB_INT_STS::USB_INTSTS_VBUSVALID, ESetToEnable }, +/*50*/{ Register::USB_INT_EN_RISE_SET, Register::USB_INT_EN_RISE_CLR, Register::USB_INT_STS, USB_INT_STS::USB_INTSTS_HOSTDISCONNECT, ESetToEnable }, + +/*51*/{ Register::CARKIT_INT_EN_SET, Register::CARKIT_INT_EN_CLR, Register::CARKIT_INT_STS, CARKIT_INT_STS::CARKIT_CARDP, ESetToEnable }, +/*52*/{ Register::CARKIT_INT_EN_SET, Register::CARKIT_INT_EN_CLR, Register::CARKIT_INT_STS, CARKIT_INT_STS::CARKIT_CARINTDET, ESetToEnable }, +/*53*/{ Register::CARKIT_INT_EN_SET, Register::CARKIT_INT_EN_CLR, Register::CARKIT_INT_STS, CARKIT_INT_STS::CARKIT_IDFLOAT, ESetToEnable }, + +/*54*/{ Register::OTHER_INT_EN_RISE_SET, Register::OTHER_INT_EN_RISE_CLR, Register::OTHER_INT_STS, OTHER_INT_STS::OTHER_INT_VB_SESS_VLD, ESetToEnable }, +/*55*/{ Register::OTHER_INT_EN_RISE_SET, Register::OTHER_INT_EN_RISE_CLR, Register::OTHER_INT_STS, OTHER_INT_STS::OTHER_INT_DM_HI, ESetToEnable }, +/*56*/{ Register::OTHER_INT_EN_RISE_SET, Register::OTHER_INT_EN_RISE_CLR, Register::OTHER_INT_STS, OTHER_INT_STS::OTHER_INT_DP_HI, ESetToEnable }, +/*57*/{ Register::OTHER_INT_EN_RISE_SET, Register::OTHER_INT_EN_RISE_CLR, Register::OTHER_INT_STS, OTHER_INT_STS::OTHER_INT_MANU, ESetToEnable }, +/*58*/{ Register::OTHER_INT_EN_RISE_SET, Register::OTHER_INT_EN_RISE_CLR, Register::OTHER_INT_STS, OTHER_INT_STS::OTHER_INT_ABNORMAL_STRESS, ESetToEnable }, + +/*59*/{ Register::ID_INT_EN_RISE_SET, Register::ID_INT_EN_RISE_CLR, Register::ID_INT_STS, ID_INT_STS::ID_INTID_RES_FLOAT, ESetToEnable }, +/*60*/{ Register::ID_INT_EN_RISE_SET, Register::ID_INT_EN_RISE_CLR, Register::ID_INT_STS, ID_INT_STS::ID_INTID_RES_440K, ESetToEnable }, +/*61*/{ Register::ID_INT_EN_RISE_SET, Register::ID_INT_EN_RISE_CLR, Register::ID_INT_STS, ID_INT_STS::ID_INTID_RES_200K, ESetToEnable }, +/*62*/{ Register::ID_INT_EN_RISE_SET, Register::ID_INT_EN_RISE_CLR, Register::ID_INT_STS, ID_INT_STS::ID_INTID_RES_102K, ESetToEnable }, + +/*63*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_PSM_ERROR, ESetToEnable }, +/*64*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_PH_ACC, ESetToEnable }, +/*65*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_CHARGER, ESetToEnable }, +/*66*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_USB_HOST, ESetToEnable }, +/*67*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_USB_OTG_B, ESetToEnable }, +/*68*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_CARKIT, ESetToEnable }, +/*69*/ { Register::CARKIT_SM_1_INT_EN_SET, Register::CARKIT_SM_1_INT_EN_CLR, Register::CARKIT_SM_1_INT_STS, CARKIT_SM_1_INT_STS::CARKIT_SM_1_DISCONNECTED, ESetToEnable }, + +/*70*/ { Register::CARKIT_SM_2_INT_EN_SET, Register::CARKIT_SM_2_INT_EN_CLR, Register::CARKIT_SM_2_INT_STS, CARKIT_SM_2_INT_STS::CARKIT_SM_2_STOP_PLS_MISS, ESetToEnable }, +/*71*/ { Register::CARKIT_SM_2_INT_EN_SET, Register::CARKIT_SM_2_INT_EN_CLR, Register::CARKIT_SM_2_INT_STS, CARKIT_SM_2_INT_STS::CARKIT_SM_2_STEREO_TO_MONO, ESetToEnable }, +/*72*/ { Register::CARKIT_SM_2_INT_EN_SET, Register::CARKIT_SM_2_INT_EN_CLR, Register::CARKIT_SM_2_INT_STS, CARKIT_SM_2_INT_STS::CARKIT_SM_2_PHONE_UART, ESetToEnable }, +/*73*/ { Register::CARKIT_SM_2_INT_EN_SET, Register::CARKIT_SM_2_INT_EN_CLR, Register::CARKIT_SM_2_INT_STS, CARKIT_SM_2_INT_STS::CARKIT_SM_2_PH_NO_ACK, ESetToEnable } + }; + + +const static TInterruptBank pwrBank = { + ETPS65950_IRQ_PWR_CHG_PWRONS, + ETPS65950_IRQ_PWR_CHG_PRES, + ETPS65950_IRQ_PWR_USB_PRES, + ETPS65950_IRQ_PWR_RTC_IT, + ETPS65950_IRQ_PWR_HOT_DIE, + ETPS65950_IRQ_PWR_PWROK_TIMEOUT, + ETPS65950_IRQ_PWR_MBCHG, + ETPS65950_IRQ_PWR_SC_DETECT, +}; + +const static TInterruptBank madcBank = { + ETPS65950_IRQ_MADC_RT_ISR1, + ETPS65950_IRQ_MADC_SW1_ISR1, + ETPS65950_IRQ_MADC_SW2_ISR1, + ETPS65950_IRQ_MADC_USB_ISR1, +}; + +const static TInterruptBank gpioBank0 = { + ETPS65950_IRQ_GPIO_0ISR1, + ETPS65950_IRQ_GPIO_1ISR1, + ETPS65950_IRQ_GPIO_2ISR1, + ETPS65950_IRQ_GPIO_3ISR1, + ETPS65950_IRQ_GPIO_4ISR1, + ETPS65950_IRQ_GPIO_5ISR1, + ETPS65950_IRQ_GPIO_6ISR1, + ETPS65950_IRQ_GPIO_7ISR2 +}; + +const static TInterruptBank gpioBank1 = { + ETPS65950_IRQ_GPIO_8ISR2, + ETPS65950_IRQ_GPIO_9ISR2, + ETPS65950_IRQ_GPIO_10ISR2, + ETPS65950_IRQ_GPIO_11ISR2, + ETPS65950_IRQ_GPIO_12ISR2, + ETPS65950_IRQ_GPIO_13ISR2, + ETPS65950_IRQ_GPIO_14ISR2, + ETPS65950_IRQ_GPIO_15ISR2 +}; + +const static TInterruptBank gpioBank2 = { + ETPS65950_IRQ_GPIO16ISR3, + ETPS65950_IRQ_GPIO17ISR3 +}; + +const static TInterruptBank bciBank0 = { + ETPS65950_IRQ_BCI_WOVF_ISR1, + ETPS65950_IRQ_BCI_TMOVF_ISR1, + ETPS65950_IRQ_BCI_IICHGHIGH_ISR1, + ETPS65950_IRQ_BCI_ICHGLOW_ISR1ASTO, + ETPS65950_IRQ_BCI_ICHGEOC_ISR1, + ETPS65950_IRQ_BCI_TBATOR2_ISR1, + ETPS65950_IRQ_BCI_TBATOR1_ISR1, + ETPS65950_IRQ_BCI_BATSTS_ISR1 +}; + +const static TInterruptBank bciBank1 = { + ETPS65950_IRQ_BCI_VBATLVL_ISR1, + ETPS65950_IRQ_BCI_VBATOV_ISR1, + ETPS65950_IRQ_BCI_VBUSOV_ISR1, + ETPS65950_IRQ_BCI_ACCHGOV_ISR1 +}; + +const static TInterruptBank keypBank = { + ETPS65950_IRQ_KEYP_ITKPISR1, + ETPS65950_IRQ_KEYP_ITLKISR1, + ETPS65950_IRQ_KEYP_ITTOISR1, + ETPS65950_IRQ_KEYP_ITMISR1, +}; + +const static TInterruptBank usbINTSTSBank = { + ETPS65950_IRQ_USB_INTSTS_IDGND, + ETPS65950_IRQ_USB_INTSTS_SESSEND, + ETPS65950_IRQ_USB_INTSTS_SESSVALID, + ETPS65950_IRQ_USB_INTSTS_VBUSVALID, + ETPS65950_IRQ_USB_INTSTS_HOSTDISCONNECT +}; + +const static TInterruptBank usbCARKITBank = { + ETPS65950_IRQ_USB_CARKIT_CARDP, + ETPS65950_IRQ_USB_CARKIT_CARINTDET, + ETPS65950_IRQ_USB_CARKIT_IDFLOAT +}; + +const static TInterruptBank usbOTHERBank = { + ETPS65950_IRQ_USB_OTHER_INT_VB_SESS_VLD, + ETPS65950_IRQ_USB_OTHER_INT_DM_HI, + ETPS65950_IRQ_USB_OTHER_INT_DP_HI, + ETPS65950_IRQ_USB_OTHER_INT_MANU, + ETPS65950_IRQ_USB_OTHER_INT_ABNORMAL_STRESS +}; + +const static TInterruptBank usbIDINTBank = { + ETPS65950_IRQ_USB_ID_INT_ID_RES_FLOAT, + ETPS65950_IRQ_USB_ID_INT_ID_RES_440K, + ETPS65950_IRQ_USB_ID_INT_ID_RES_200K, + ETPS65950_IRQ_USB_ID_INT_ID_RES_102K +}; + +const static TInterruptBank usbSM1Bank = { + ETPS65950_IRQ_USB_CARKIT_SM_1_PSM_ERROR, + ETPS65950_IRQ_USB_CARKIT_SM_1_PH_ACC, + ETPS65950_IRQ_USB_CARKIT_SM_1_CHARGER, + ETPS65950_IRQ_USB_CARKIT_SM_1_USB_HOST, + ETPS65950_IRQ_USB_CARKIT_SM_1_USB_OTG_B, + ETPS65950_IRQ_USB_CARKIT_SM_1_CARKIT +}; + +const static TInterruptBank usbSM2Bank = { + ETPS65950_IRQ_USB_CARKIT_SM_2_STOP_PLS_MISS, + ETPS65950_IRQ_USB_CARKIT_SM_2_STEREO_TO_MONO, + ETPS65950_IRQ_USB_CARKIT_SM_2_PHONE_UART, + ETPS65950_IRQ_USB_CARKIT_SM_2_PH_NO_ACK +}; + +const static TInterruptBank* TheMapTable [6][6] = { + //maps against PIH_ISR bits + //reg banks sub modules + {&gpioBank0, &gpioBank1, &gpioBank2, NULL, NULL, NULL}, + {&keypBank, NULL, NULL, NULL, NULL, NULL}, + {&bciBank0, &bciBank1, NULL, NULL, NULL, NULL}, + {&madcBank, NULL, NULL, NULL, NULL, NULL}, + {&usbINTSTSBank, &usbCARKITBank, &usbOTHERBank, &usbIDINTBank, &usbSM1Bank, &usbSM2Bank}, + {&pwrBank, NULL, NULL, NULL, NULL, NULL} +}; + +const static TSubInterruptBank subBank[6] = { + /*gpio*/{3,{Register::GPIO_ISR1A,Register::GPIO_ISR2A,Register::GPIO_ISR3A,NULL,NULL,NULL}}, + /*keyp*/{1,{Register::KEYP_ISR1,NULL,NULL,NULL,NULL,NULL}}, + /*bci*/ {2,{Register::BCIISR1A,Register::BCIISR2A,NULL,NULL,NULL,NULL}}, + /*madc*/{1,{Register::MADC_ISR1,NULL,NULL,NULL,NULL,NULL}}, + /*usb*/ {6,{Register::USB_INT_STS,Register::CARKIT_INT_STS,Register::OTHER_INT_STS,Register::ID_INT_STS, Register::CARKIT_SM_1_INT_STS, Register::CARKIT_SM_2_INT_STS}}, + /*pwr*/ {1,{Register::PWR_ISR1,NULL,NULL,NULL,NULL,NULL}}, +}; + + +TPS65950Int::TPS65950Int() + : iDfc( Dfc, this, KDfcPriority ) + { + for( TInt i = 0; i < TPS65950::KNumTPSInts; ++i ) + { + TheHandlers[ i ].iIsr = Spurious; + TheHandlers[ i ].iPtr = (TAny*)( KTPS65950IrqFirst + i ); + } + } + +TInt TPS65950Int::Init() + { + iDfc.SetDfcQ( TheInterruptDfcQue ); + + TInt r = InitialiseTPS65950IntController(); + + if( KErrNone == r ) + { + TInt r = Interrupt::Bind( EOmap3530_IRQ7_SYS_NIRQ, Dispatch, this ); + if( KErrNone == r ) + { + r = Interrupt::Enable( EOmap3530_IRQ7_SYS_NIRQ ); + } + } + + if( KErrNone == r ) + { + Register( EIrqRangeBasePsu ); + } + return r; + } + + +TInt TPS65950Int::InitialiseTPS65950IntController() + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+TPS65950Int:InitIntController")); + + struct TInitRegList + { + TUint16 iReg; + TUint8 iValue; + }; + + static const TInitRegList KInitList[] = + { + { GPIO_SIH_CTRL::Addr, GPIO_SIH_CTRL::SIH_PENDDIS | GPIO_SIH_CTRL::SIH_COR | GPIO_SIH_CTRL::SIH_EXCLEN }, + // { Register::GPIO_CTRL, 0x00 }, + { Register::GPIO_IMR1A , 0xff }, + { Register::GPIO_IMR2A , 0xff }, + { Register::GPIO_IMR3A , 0xff }, + { Register::GPIO_IMR1B , 0xff }, + { Register::GPIO_IMR2B , 0xff }, + { Register::GPIO_IMR3B , 0xff }, + { Register::GPIO_EDR1, 0x00 }, + { Register::GPIO_EDR2, 0x00 }, + { Register::GPIO_EDR3, 0x00 }, + { Register::GPIO_EDR4, 0x00 }, + { Register::GPIO_EDR5, 0x00 }, + { Register::USB_INT_EN_RISE_CLR, 0x1f }, + { Register::USB_INT_EN_FALL_CLR, 0x1f }, + { Register::CARKIT_INT_EN_CLR, 0x1f }, + { Register::OTHER_INT_EN_RISE_CLR,0xe3 }, + { Register::OTHER_INT_EN_FALL_CLR,0xe3 }, + { Register::ID_INT_EN_RISE_CLR, 0x0f }, + { Register::ID_INT_EN_FALL_CLR, 0x0f }, + { Register::CARKIT_SM_1_INT_EN_CLR,0xff }, + { Register::CARKIT_SM_2_INT_EN_CLR,0xff }, + { KEYP_SIH_CTRL::Addr, KEYP_SIH_CTRL::SIH_PENDDIS | KEYP_SIH_CTRL::SIH_COR | KEYP_SIH_CTRL::SIH_EXCLEN }, + { Register::KEYP_IMR1, 0x0f }, + { Register::KEYP_IMR2, 0x0f }, + { Register::KEYP_EDR, FULL_RISING_EDGEMASK }, + { BCISIHCTRL::Addr, BCISIHCTRL::SIH_PENDDIS | BCISIHCTRL::SIH_COR | BCISIHCTRL::SIH_EXCLEN }, + { Register::BCIIMR1A, 0xff }, + { Register::BCIIMR2A, 0xff }, + { Register::BCIIMR1B, 0xff }, + { Register::BCIIMR2B, 0xff }, + { Register::BCIEDR1, FULL_RISING_EDGEMASK }, + { Register::BCIEDR2, FULL_RISING_EDGEMASK }, + { Register::BCIEDR3, FULL_RISING_EDGEMASK }, + { MADC_SIH_CTRL::Addr, MADC_SIH_CTRL::SIH_PENDDIS | MADC_SIH_CTRL::SIH_COR | MADC_SIH_CTRL::SIH_EXCLEN }, + { Register::MADC_IMR1, 0x0f }, + { Register::MADC_IMR2, 0x0f }, + { Register::MADC_EDR, FULL_RISING_EDGEMASK }, + { PWR_SIH_CTRL::Addr, PWR_SIH_CTRL::SIH_PENDDIS | PWR_SIH_CTRL::SIH_COR | PWR_SIH_CTRL::SIH_EXCLEN }, + { Register::PWR_IMR1, 0xff }, + { Register::PWR_IMR2, 0xff }, + { Register::PWR_EDR1, FULL_FALLING_EDGEMASK }, + { Register::PWR_EDR2, FULL_FALLING_EDGEMASK } + }; + + const TInt KInitListCount = (sizeof( KInitList ) / sizeof( KInitList[0] ) ); + + static const TUint16 KClearList[] = + { + Register::CARKIT_INT_LATCH, + Register::USB_INT_LATCH, + Register::OTHER_INT_LATCH, + Register::ID_INT_LATCH, + Register::CARKIT_SM_1_INT_LATCH, + Register::CARKIT_SM_2_INT_LATCH, + Register::GPIO_ISR1A, + Register::GPIO_ISR2A, + Register::GPIO_ISR3A, + Register::KEYP_ISR1, + Register::BCIISR1A, + Register::BCIISR2A, + Register::MADC_ISR1, + Register::PWR_ISR1 + }; + + const TInt KClearListCount = (sizeof( KClearList ) / sizeof( KClearList[0] ) ); + + + TInt r = KErrNone; + + // Disable all interrupts + for( TInt i = 0; (i < KInitListCount) && (KErrNone == r); ++i ) + { + r = WriteSync( KInitList[i].iReg, KInitList[i].iValue ); + } + + // Clear all interrupts + for( TInt i = 0; (i < KClearListCount) && (KErrNone == r); ++i ) + { + TUint8 dummy; + r = ReadSync( KClearList[i], dummy ); + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-TPS65950Int:InitIntController:%d", r)); + + return r; + } + + +void TPS65950Int::Spurious( TAny* aParam ) + { + Kern::Fault("TPS65950SpurioustInt", (TInt)aParam ); + } + +TInt TPS65950Int::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950:Bind:%x->%x", aId, aIsr )); + + TInt r = KErrNone; + + if( (TUint)aId < KTPS65950IrqLast ) + { + TUint tblOffset = aId - KTPS65950IrqFirst; + + TInt irq=__SPIN_LOCK_IRQSAVE_W(BeagleExtIVTLock); + TheHandlers[tblOffset ].iIsr = aIsr; + TheHandlers[tblOffset].iPtr = aPtr; + __SPIN_UNLOCK_IRQRESTORE_W(BeagleExtIVTLock,irq); + + } + else + { + r = KErrArgument; + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Bind:%x:%d", aId, r )); + return r; + } + +TInt TPS65950Int::Unbind(TInt aId) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950:Unbind:%x", aId )); + + TInt r = KErrNone; + + if( (TUint)aId < KTPS65950IrqLast ) + { + TUint tblOffset = aId - KTPS65950IrqFirst; + TInt irq=__SPIN_LOCK_IRQSAVE_W(BeagleExtIVTLock); + TheHandlers[tblOffset ].iIsr = Spurious; + TheHandlers[tblOffset ].iPtr = NULL; + __SPIN_UNLOCK_IRQRESTORE_W(BeagleExtIVTLock,irq); + } + else + { + r = KErrArgument; + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Unbind:%x:%d", aId, r )); + return r; + } + +TInt TPS65950Int::Enable(TInt aId) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950:Enable:%x", aId )); + + TInt r = KErrNone; + + if( (TUint)aId < KTPS65950IrqLast ) + { + CHECK_PRECONDITIONS(MASK_NOT_ISR | MASK_NOT_IDFC,"tps65950::InterruptEnable Cant enable a slow src in ISR Context"); + + TUint tblOffset = aId - KTPS65950IrqFirst; + + TInt irq=__SPIN_LOCK_IRQSAVE_R(BeagleExtIVTLock); + if( TheHandlers[ tblOffset ].iIsr == Spurious ) + { + r = KErrNotReady; + } + __SPIN_UNLOCK_IRQRESTORE_R(BeagleExtIVTLock,irq); + + if( r != KErrNone ) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("=tps65950:Enable:%d NOT BOUND", aId )); + } + else + { + const TControl& control = KControl[ tblOffset ]; + + TUint8 val; + ReadSync( control.iSetReg, val ); + if( EClearToEnable == control.iPolarity ) + { + ClearSetSync( control.iSetReg, control.iBitMask, KSetNone ); + } + else + { + ClearSetSync( control.iSetReg, KClearNone, control.iBitMask ); + } + ReadSync( control.iSetReg, val ); + } + } + else + { + r = KErrArgument; + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Enable:%x:%d", aId, r )); + return r; + } + +TInt TPS65950Int::Disable(TInt aId) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950:Disable:%x", aId )); + + TInt r = KErrNone; + + if( (TUint)aId < KTPS65950IrqLast ) + { + CHECK_PRECONDITIONS(MASK_NOT_ISR | MASK_NOT_IDFC,"tps65950::InterruptDisable Cant disable a slow src in ISR Context"); + + TUint tblOffset = aId - KTPS65950IrqFirst; + + TInt irq=__SPIN_LOCK_IRQSAVE_R(BeagleExtIVTLock); + if( TheHandlers[ tblOffset ].iIsr == Spurious ) + { + r = KErrNotReady; + } + __SPIN_UNLOCK_IRQRESTORE_R(BeagleExtIVTLock,irq); + + if( r != KErrNone ) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("=tps65950:Disable:%d NOT BOUND", aId )); + } + else + { + const TControl& control = KControl[ tblOffset ]; + + if( EClearToEnable == control.iPolarity ) + { + ClearSetSync( control.iClrReg, KClearNone, control.iBitMask ); + } + else + { + ClearSetSync( control.iSetReg, control.iBitMask, KSetNone ); + } + } + } + else + { + r = KErrArgument; + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Disable:%x:%d", aId, r )); + return r; + } + +TInt TPS65950Int::Clear(TInt aId) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950:Clear:%x", aId )); + + TInt r = KErrNone; + + if( (TUint)aId < KTPS65950IrqLast ) + { + CHECK_PRECONDITIONS(MASK_NOT_ISR,"tps65950::InterruptClear Cant clear a slow src in ISR Context"); + + TUint tblOffset = aId - KTPS65950IrqFirst; + TUint8 value; + //clear on read ! //we may lose some of the other ints if many enabled + ReadSync( KControl[ tblOffset ].iStatReg, value ); + } + else + { + r = KErrArgument; + } + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Clear:%x:%d", aId, r )); + return r; + } + +TInt TPS65950Int::SetPriority(TInt aId, TInt aPriority) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("tps65950:SetPriority:%x", aId )); + return KErrNotSupported; + } + + +void TPS65950Int::Dispatch(TAny * aParam ) + { + Interrupt::Disable(EOmap3530_IRQ7_SYS_NIRQ); + reinterpret_cast(aParam)->iDfc.Add(); + } + +void TPS65950Int::Dfc( TAny* aParam ) + { + __KTRACE_OPT(KTPS65950,Kern::Printf("+tps65950Int:Dfc" )); + + TUint8 highVectors=0; + TUint8 subVector=0; + + ReadSync( PIH_ISR_P1::Addr, highVectors ); + __ASSERT_DEBUG( highVectors != 0,Kern::Fault("tps65950 int signalled but no vector ",highVectors)); + + for(TInt i=0; i<=5;i++,highVectors >>=1) + { + if(highVectors & 0x1) + { + for(TInt8 j=0;jiBit[k] - KTPS65950IrqFirst; + + __KTRACE_OPT(KTPS65950,Kern::Printf("=tps65950:Dfc:BIT_%d HIGH on REG %x VECTOR is %x ISR %x", + k,subBank[i].iRegs[j], tblOffset, TheHandlers[tblOffset].iIsr)); + + (TheHandlers[tblOffset].iIsr)(TheHandlers[tblOffset].iPtr); + } + subVector >>= 1; + } + } + } + } + Interrupt::Enable(EOmap3530_IRQ7_SYS_NIRQ); + + __KTRACE_OPT(KTPS65950,Kern::Printf("-tps65950:Dfc" )); + } + + +} // namespace TPS65950 + + +GLDEF_C TInt InitInterrupts() + { + TInt r = Kern::DfcQCreate( TheInterruptDfcQue, KInterruptDfcQuePriority, &KInterruptDfcQueName ); + if( KErrNone == r ) + { + r = KErrNoMemory; + TPS65950::TPS65950Int* dispatcher = new TPS65950::TPS65950Int; + if( dispatcher ) + { + r = dispatcher->Init(); + } + } + return r; + } + + diff -r 000000000000 -r 6663340f3fc9 omap3530/shared/tps65950/tps65950_registers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/shared/tps65950/tps65950_registers.h Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,1320 @@ +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#ifndef TPS65950_REGISTERS_H +#define TPS65950_REGISTERS_H + +#include + +namespace TPS65950 +{ + +namespace Register + { + const TUint KGroupShift = 8; + const TUint KRegisterMask = 0xFF; + const TUint KGroupMask = 0xFF00; + + enum TGroup + { + EGroup12 = (0 << KGroupShift), + EGroup48 = (1 << KGroupShift), + EGroup49 = (2 << KGroupShift), + EGroup4a = (3 << KGroupShift), + EGroup4b = (4 << KGroupShift) + }; + + enum TGroup12Registers + { + VDD1_SR_CONTROL = EGroup12, + VDD2_SR_CONTROL + }; + + + enum TGroup48Registers + { + VENDOR_ID_LO = EGroup48, + VENDOR_ID_HI, + PRODUCT_ID_LO, + PRODUCT_ID_HI, + FUNC_CTRL, + FUNC_CTRL_SET, + FUNC_CTRL_CLR, + IFC_CTRL, + IFC_CTRL_SET, + IFC_CTRL_CLR, + OTG_CTRL, + OTG_CTRL_SET, + OTG_CTRL_CLR, + USB_INT_EN_RISE, + USB_INT_EN_RISE_SET, + USB_INT_EN_RISE_CLR, + USB_INT_EN_FALL, + USB_INT_EN_FALL_SET, + USB_INT_EN_FALL_CLR, + USB_INT_STS, + USB_INT_LATCH, + DEBUG, + SCRATCH_REG, + SCRATCH_REG_SET, + SCRATCH_REG_CLR, + CARKIT_CTRL, + CARKIT_CTRL_SET, + CARKIT_CTRL_CLR, + CARKIT_INT_DELAY, + CARKIT_INT_EN, + CARKIT_INT_EN_SET, + CARKIT_INT_EN_CLR, + CARKIT_INT_STS, + CARKIT_INT_LATCH, + CARKIT_PLS_CTRL, + CARKIT_PLS_CTRL_SET, + CARKIT_PLS_CTRL_CLR, + TRANS_POS_WIDTH, + TRANS_NEG_WIDTH, + RCV_PLTY_RECOVERY, + MCPC_CTRL = 0x30, + MCPC_CTRL_SET, + MCPC_CTRL_CLR, + MCPC_IO_CTRL, + MCPC_IO_CTRL_SET, + MCPC_IO_CTRL_CLR, + MCPC_CTRL2, + MCPC_CTRL2_SET, + MCPC_CTRL2_CLR, + OTHER_FUNC_CTRL = EGroup48 + 0x80, + OTHER_FUNC_CTRL_SET, + OTHER_FUNC_CTRL_CLR, + OTHER_IFC_CTRL, + OTHER_IFC_CTRL_SET, + OTHER_IFC_CTRL_CLR, + OTHER_INT_EN_RISE, + OTHER_INT_EN_RISE_SET, + OTHER_INT_EN_RISE_CLR, + OTHER_INT_EN_FALL, + OTHER_INT_EN_FALL_SET, + OTHER_INT_EN_FALL_CLR, + OTHER_INT_STS, + OTHER_INT_LATCH, + ID_INT_EN_RISE, + ID_INT_EN_RISE_SET, + ID_INT_EN_RISE_CLR, + ID_INT_EN_FALL, + ID_INT_EN_FALL_SET, + ID_INT_EN_FALL_CLR, + ID_INT_STS, + ID_INT_LATCH, + ID_STATUS, + CARKIT_SM_1_INT_EN, + CARKIT_SM_1_INT_EN_SET, + CARKIT_SM_1_INT_EN_CLR, + CARKIT_SM_1_INT_STS, + CARKIT_SM_1_INT_LATCH, + CARKIT_SM_2_INT_EN, + CARKIT_SM_2_INT_EN_SET, + CARKIT_SM_2_INT_EN_CLR, + CARKIT_SM_2_INT_STS, + CARKIT_SM_2_INT_LATCH, + CARKIT_SM_CTRL, + CARKIT_SM_CTRL_SET, + CARKIT_SM_CTRL_CLR, + CARKIT_SM_CMD, + CARKIT_SM_CMD_SET, + CARKIT_SM_CMD_CLR, + CARKIT_SM_CMD_STS, + CARKIT_SM_STATUS, + CARKIT_SM_NEXT_STATUS, + CARKIT_SM_ERR_STATUS, + CARKIT_SM_CTRL_STATE, + POWER_CTRL, + POWER_CTRL_SET, + POWER_CTRL_CLR, + OTHER_IFC_CTRL2, + OTHER_IFC_CTRL2_SET, + OTHER_IFC_CTRL2_CLR, + REG_CTRL_EN, + REG_CTRL_EN_SET, + REG_CTRL_EN_CLR, + REG_CTRL_ERROR, + OTHER_FUNC_CTRL2, + OTHER_FUNC_CTRL2_SET, + OTHER_FUNC_CTRL2_CLR, + CARKIT_ANA_CTRL, + CARKIT_ANA_CTRL_SET, + CARKIT_ANA_CTRL_CLR, + VBUS_DEBOUNCE = EGroup48 + 0xC0, + ID_DEBOUNCE, + TPH_DP_CON_MIN, + TPH_DP_CON_MAX, + TCR_DP_CON_MIN, + TCR_DP_CON_MAX, + TPH_DP_PD_SHORT, + TPH_CMD_DLY, + TPH_DET_RST, + TPH_AUD_BIAS, + TCR_UART_DET_MIN, + TCR_UART_DET_MAX, + TPH_ID_INT_PW = EGroup48 + 0xCC, + TACC_ID_INT_WAIT, + TACC_ID_INT_PW, + TPH_CMD_WAIT = EGroup48 + 0xD0, + TPH_ACK_WAIT, + TPH_DP_DISC_DET, + VBAT_TIMER, + CARKIT_4W_DEBUG = EGroup48 + 0xE0, + CARKIT_5W_DEBUG, + TEST_CTRL_CLR = EGroup48 + 0xEB, + TEST_CARKIT_SET, + TEST_CARKIT_CLR, + TEST_POWER_SET, + TEST_POWER_CLR, + TEST_ULPI, + TXVR_EN_TEST_SET, + TXVR_EN_TEST_CLR, + VBUS_EN_TEST, + ID_EN_TEST, + PSM_EN_TEST_SET, + PSM_EN_TEST_CLR, + PHY_TRIM_CTRL = EGroup48 + 0xFC, + PHY_PWR_CTRL, + PHY_CLK_CTRL, + PHY_CLK_CTRL_STS // 0x000000ff + }; + + + enum TGroup49Registers + { + CODEC_MODE = EGroup49 + 1, + OPTION , + MICBIAS_CTL = EGroup49 + 0x04, + ANAMICL, + ANAMICR, + AVADC_CTL, + ADCMICSEL, + DIGMIXING, + ATXL1PGA, + ATXR1PGA, + AVTXL2PGA, + AVTXR2PGA, + AUDIO_IF, + VOICE_IF, + ARXR1PGA, + ARXL1PGA, + ARXR2PGA, + ARXL2PGA, + VRXPGA, + VSTPGA, + VRX2ARXPGA, + AVDAC_CTL, + ARX2VTXPGA, + ARXL1_APGA_CTL, + ARXR1_APGA_CTL, + ARXL2_APGA_CTL, + ARXR2_APGA_CTL, + ATX2ARXPGA, + BT_IF, + BTPGA, + BTSTPGA, + EAR_CTL, + HS_SEL, + HS_GAIN_SET, + HS_POPN_SET, + PREDL_CTL, + PREDR_CTL, + PRECKL_CTL, + PRECKR_CTL, + HFL_CTL, + HFR_CTL, + ALC_CTL, + ALC_SET1, + ALC_SET2, + BOOST_CTL, + SOFTVOL_CTL, + DTMF_FREQSEL, + DTMF_TONEXT1H, + DTMF_TONEXT1L, + DTMF_TONEXT2H, + DTMF_TONEXT2L, + DTMF_TONOFF, + DTMF_WANONOFF,// 8 0x0000 0036 + + I2S_RX_SCRAMBLE_H, + I2S_RX_SCRAMBLE_M, + I2S_RX_SCRAMBLE_L, + APLL_CTL, + DTMF_CTL, + DTMF_PGA_CTL2, + DTMF_PGA_CTL1, + MISC_SET_1, + PCMBTMUX, + RX_PATH_SEL, + VDL_APGA_CTL, + VIBRA_CTL, + VIBRA_SET, + ANAMIC_GAIN, + MISC_SET_2,// RW 8 0x0000 0049 + + AUDIO_TEST_CTL = EGroup49 + 0x0000004C, + INT_TEST_CTL, + DAC_ADC_TEST_CTL, + RXTX_TRIM_IB, + CLD_CONTROL, + CLD_MODE_TIMING, + CLD_TRIM_RAMP, + CLD_TESTV_CTL, + APLL_TEST_CTL, + APLL_TEST_DIV, + APLL_TEST_CTL2, + APLL_TEST_CUR, + DIGMIC_BIAS1_CTL, + DIGMIC_BIAS2_CTL, + RX_OFFSET_VOICE, + RX_OFFSET_AL1, + RX_OFFSET_AR1, + RX_OFFSET_AL2, + RX_OFFSET_AR2, + OFFSET1, + OFFSET2, + + + GPIODATAIN1 = EGroup49 + 0x00000098, + GPIODATAIN2, + GPIODATAIN3, + GPIODATADIR1, + GPIODATADIR2, + GPIODATADIR3, + GPIODATAOUT1, + GPIODATAOUT2, + GPIODATAOUT3, + CLEARGPIODATAOUT1, + CLEARGPIODATAOUT2, + CLEARGPIODATAOUT3, + SETGPIODATAOUT1, + SETGPIODATAOUT2, + SETGPIODATAOUT3, + GPIO_DEBEN1, + GPIO_DEBEN3, + GPIO_CTRL , + GPIOPUPDCTR1, + GPIOPUPDCTR2, + GPIOPUPDCTR3, + GPIOPUPDCTR4, + GPIOPUPDCTR5, + GPIO_TEST, + GPIO_ISR1A = EGroup49 + 0xb1, + GPIO_ISR2A, + GPIO_ISR3A, + GPIO_IMR1A, // + GPIO_IMR2A, + GPIO_IMR3A, + GPIO_ISR1B, + GPIO_ISR2B, + GPIO_ISR3B, + GPIO_IMR1B, + GPIO_IMR2B, + GPIO_IMR3B, + GPIO_SIR1, + GPIO_SIR2, + GPIO_SIR3, + GPIO_EDR1, + GPIO_EDR2, + GPIO_EDR3, + GPIO_EDR4, + GPIO_EDR5, + GPIO_SIH_CTRL, + + PIH_ISR_P1 = EGroup49 + 0x00000081, + PIH_ISR_P2, + PIH_SIR , + IDCODE_7_0 = EGroup49 + 0x00000085, + IDCODE_15_8, + IDCODE_23_16, + IDCODE_31_24, + DIEID_7_0, + DIEID_15_8, + DIEID_23_16, + DIEID_31_24, + DIEID_39_32, + DIEID_47_40, + DIEID_55_48, + DIEID_63_56, + GPBR1, + PMBR1, + PMBR2, + GPPUPDCTR1, + GPPUPDCTR2, + GPPUPDCTR3, + UNLOCK_TEST_REG, + }; + + + + /* + Note: Access to the following registers is protected: + · IDCODE_7_0 + · IDCODE_15_8 + · IDCODE_23_16 + · IDCODE_31_24 + · DIEID_7_0 + · DIEID_15_8 + · DIEID_23_16 + · DIEID_31_24 + · DIEID_39_32 + · DIEID_47_40 + · DIEID_55_48 + · DIEID_63_56 + To read these registers, the UNLOCK_TEST_REG register must first be written with 0x49. + Table 2-29. GPPUPDCTR1 + Address Offset 0x0F + Physical Address 0x0000 0094 Instance INT_SCINTBR + */ + + enum TGroup4aRegisters + { + CTRL1 = EGroup4a + 0, + CTRL2, + RTSELECT_LSB, + RTSELECT_MSB, + RTAVERAGE_LSB, + RTAVERAGE_MSB, + SW1SELECT_LSB, + SW1SELECT_MSB, + SW1AVERAGE_LSB, + SW1AVERAGE_MSB, + SW2SELECT_LSB, + SW2SELECT_MSB, + SW2AVERAGE_LSB, + SW2AVERAGE_MSB, + BCI_USBAVERAGE, + ACQUISITION, + USBREF_LSB, + USBREF_MSB, + CTRL_SW1, + CTRL_SW2, + MADC_TEST, + GP_MADC_TEST1, + GP_MADC_TEST2, + RTCH0_LSB, + RTCH0_MSB, + RTCH1_LSB, + RTCH1_MSB, + RTCH2_LSB, + RTCH2_MSB, + RTCH3_LSB, + RTCH3_MSB, + RTCH4_LSB, + RTCH4_MSB, + RTCH5_LSB, + RTCH5_MSB, + RTCH6_LSB, + RTCH6_MSB, + RTCH7_LSB, + RTCH7_MSB, + RTCH8_LSB, + RTCH8_MSB, + RTCH9_LSB, + RTCH9_MSB, + RTCH10_LSB, + RTCH10_MSB, + RTCH11_LSB, + RTCH11_MSB, + RTCH12_LSB, + RTCH12_MSB, + RTCH13_LSB, + RTCH13_MSB, + RTCH14_LSB, + RTCH14_MSB, + RTCH15_LSB, + RTCH15_MSB, + GPCH0_LSB, + GPCH0_MSB, + GPCH1_LSB, + GPCH1_MSB, + GPCH2_LSB, + GPCH2_MSB, + GPCH3_LSB, + GPCH3_MSB, + GPCH4_LSB, + GPCH4_MSB, + GPCH5_LSB, + GPCH5_MSB, + GPCH6_LSB, + GPCH6_MSB, + GPCH7_LSB, + GPCH7_MSB, + GPCH8_LSB, + GPCH8_MSB, + GPCH9_LSB, + GPCH9_MSB, + GPCH10_LSB, + GPCH10_MSB, + GPCH11_LSB, + GPCH11_MSB, + GPCH12_LSB, + GPCH12_MSB, + GPCH13_LSB, + GPCH13_MSB, + GPCH14_LSB, + GPCH14_MSB, + GPCH15_LSB, + GPCH15_MSB, + BCICH0_LSB, + BCICH0_MSB, + BCICH1_LSB, + BCICH1_MSB, + BCICH2_LSB, + BCICH2_MSB, + BCICH3_LSB, + BCICH3_MSB, + BCICH4_LSB, + BCICH4_MSB, + MADC_ISR1, + MADC_IMR1, + MADC_ISR2, + MADC_IMR2, + MADC_SIR, + MADC_EDR, + MADC_SIH_CTRL, + BCIMDEN, + BCIMDKEY, + BCIMSTATEC, + BCIMSTATEP, + BCIVBAT1, + BCIVBAT2, + BCITBAT1, + BCITBAT2, + BCIICHG1, + BCIICHG2, + BCIVAC1, + BCIVAC2, + BCIVBUS1, + BCIVBUS2, + BCIMFSTS2, + BCIMFSTS3, + BCIMFSTS4, + BCIMFKEY, + BCIMFEN1, + BCIMFEN2, + BCIMFEN3, + BCIMFEN4, + BCIMFTH1, + BCIMFTH2, + BCIMFTH3, + BCIMFTH4, + BCIMFTH5, + BCIMFTH6, + BCIMFTH7, + BCIMFTH8, + BCIMFTH9, + BCITIMER1, + BCITIMER2, + BCIWDKEY, + BCIWD, + BCICTL1, + BCICTL2, + BCIVREF1, + BCIVREF2, + BCIIREF1, + BCIIREF2, + BCIPWM2, + BCIPWM1, + BCITRIM1, + BCITRIM2, + BCITRIM3, + BCITRIM4, + BCIVREFCOMB1, + BCIVREFCOMB2, + BCIIREFCOMB1, + BCIIREFCOMB2, + + BCIISR1A = EGroup4a + 0x000000B9, + BCIISR2A, + BCIIMR1A, + BCIIMR2A, + BCIISR1B, + BCIISR2B, + BCIIMR1B, + BCIIMR2B, //0x000000c0 + + BCIEDR1 = EGroup4a + 0x000000c3, + BCIEDR2, + BCIEDR3, + BCISIHCTRL, // c6 + + KEYP_CTRL_REG = EGroup4a + 0x000000D2, + KEY_DEB_REG, + LONG_KEY_REG1, + LK_PTV_REG, + TIME_OUT_REG1, + TIME_OUT_REG2, + KBC_REG, + KBR_REG, + KEYP_SMS, + FULL_CODE_7_0, + FULL_CODE_15_8, + FULL_CODE_23_16, + FULL_CODE_31_24, + FULL_CODE_39_32, + FULL_CODE_47_40, + FULL_CODE_55_48, + FULL_CODE_63_56, + KEYP_ISR1, + KEYP_IMR1, + KEYP_ISR2, + KEYP_IMR2, + KEYP_SIR, + KEYP_EDR, + KEYP_SIH_CTRL, + + LEDEN = EGroup4a + 0x000000EE, + PWMAON, + PWMAOFF, + PWMBON, + PWMBOFF, + + PWM1ON= EGroup4a + 0x000000FB, + PWM1OFF, + PWM0ON = EGroup4a + 0x000000F8, + PWM0OFF, + }; + + enum TGroup4bRegisters + { + SECURED_REG_A = EGroup4b + 0, + SECURED_REG_B, + SECURED_REG_C, + SECURED_REG_D, + SECURED_REG_E, + SECURED_REG_F, + SECURED_REG_G, + SECURED_REG_H, + SECURED_REG_I, + SECURED_REG_J, + SECURED_REG_K, + SECURED_REG_L, + SECURED_REG_M, + SECURED_REG_N, + SECURED_REG_O, + SECURED_REG_P, + SECURED_REG_Q, + SECURED_REG_R, + SECURED_REG_S, + SECURED_REG_U, + BACKUP_REG_A, + BACKUP_REG_B, + BACKUP_REG_C, + BACKUP_REG_D, + BACKUP_REG_E, + BACKUP_REG_F, + BACKUP_REG_G, + BACKUP_REG_H, + PWR_ISR1 = EGroup4b + 0x2e, + PWR_IMR1, + PWR_ISR2, + PWR_IMR2, + PWR_SIR, + PWR_EDR1, + PWR_EDR2, + PWR_SIH_CTRL, + CFG_P1_TRANSITION, + CFG_P2_TRANSITION, + CFG_P3_TRANSITION, + CFG_P123_TRANSITION, + STS_BOOT, + CFG_BOOT, + SHUNDAN, + BOOT_BCI, + CFG_PWRANA1, + CFG_PWRANA2, + BGAP_TRIM, + BACKUP_MISC_STS, + BACKUP_MISC_CFG, + BACKUP_MISC_TST, + PROTECT_KEY, + STS_HW_CONDITIONS, + P1_SW_EVENTS, + P2_SW_EVENTS, + P3_SW_EVENTS, + STS_P123_STATE, + PB_CFG, + PB_WORD_MSB, + PB_WORD_LSB, + RESERVED_A, + RESERVED_B, + RESERVED_C, + RESERVED_D, + RESERVED_E, + SEQ_ADD_W2P, + SEQ_ADD_P2A, + SEQ_ADD_A2W, + SEQ_ADD_A2S, + SEQ_ADD_S2A12, + SEQ_ADD_S2A3, + SEQ_ADD_WARM, + MEMORY_ADDRESS, + MEMORY_DATA, + SC_CONFIG, + SC_DETECT1, + SC_DETECT2, + WATCHDOG_CFG, + IT_CHECK_CFG, + VIBRATOR_CFG, + DCDC_GLOBAL_CFG, + VDD1_TRIM1, + VDD1_TRIM2, + VDD2_TRIM1, + VDD2_TRIM2, + VIO_TRIM1, + VIO_TRIM2, + MISC_CFG, + LS_TST_A, + LS_TST_B, + LS_TST_C, + LS_TST_D, + BB_CFG, + MISC_TST, + TRIM1, + TRIM2, + DCDC_TIMEOUT, + VAUX1_DEV_GRP, + VAUX1_TYPE, + VAUX1_REMAP, + VAUX1_DEDICATED, + VAUX2_DEV_GRP, + VAUX2_TYPE, + VAUX2_REMAP, + VAUX2_DEDICATED, + VAUX3_DEV_GRP, + VAUX3_TYPE, + VAUX3_REMAP, + VAUX3_DEDICATED, + VAUX4_DEV_GRP, + VAUX4_TYPE, + VAUX4_REMAP, + VAUX4_DEDICATED, + VMMC1_DEV_GRP, + VMMC1_TYPE, + VMMC1_REMAP, + VMMC1_DEDICATED, + VMMC2_DEV_GRP, + VMMC2_TYPE, + VMMC2_REMAP, + VMMC2_DEDICATED, + VPLL1_DEV_GRP, + VPLL1_TYPE, + VPLL1_REMAP, + VPLL1_DEDICATED, + VPLL2_DEV_GRP, + VPLL2_TYPE, + VPLL2_REMAP, + VPLL2_DEDICATED, + VSIM_DEV_GRP, + VSIM_TYPE, + VSIM_REMAP, + VSIM_DEDICATED, + VDAC_DEV_GRP, + VDAC_TYPE, + VDAC_REMAP, + VDAC_DEDICATED, + VINTANA1_DEV_GRP, + VINTANA1_TYPE, + VINTANA1_REMAP, + VINTANA1_DEDICATED, + VINTANA2_DEV_GRP, + VINTANA2_TYPE, + VINTANA2_REMAP, + VINTANA2_DEDICATED, + VINTDIG_DEV_GRP, + VINTDIG_TYPE, + VINTDIG_REMAP, + VINTDIG_DEDICATED, + VIO_DEV_GRP, + VIO_TYPE, + VIO_REMAP, + VIO_CFG, + VIO_MISC_CFG, + VIO_TEST1, + VIO_TEST2, + VIO_OSC, + VIO_RESERVED, + VIO_VSEL, + VDD1_DEV_GRP, + VDD1_TYPE, + VDD1_REMAP, + VDD1_CFG, + VDD1_MISC_CFG, + VDD1_TEST1, + VDD1_TEST2, + VDD1_OSC, + VDD1_RESERVED, + VDD1_VSEL, + VDD1_VMODE_CFG, + VDD1_VFLOOR, + VDD1_VROOF, + VDD1_STEP, + VDD2_DEV_GRP, + VDD2_TYPE, + VDD2_REMAP, + VDD2_CFG, + VDD2_MISC_CFG, + VDD2_TEST1, + VDD2_TEST2, + VDD2_OSC, + VDD2_RESERVED, + VDD2_VSEL, + VDD2_VMODE_CFG, + VDD2_VFLOOR, + VDD2_VROOF, + VDD2_STEP, + VUSB1V5_DEV_GRP, + VUSB1V5_TYPE, + VUSB1V5_REMAP, + VUSB1V8_DEV_GRP, + VUSB1V8_TYPE, + VUSB1V8_REMAP, + VUSB3V1_DEV_GRP, + VUSB3V1_TYPE, + VUSB3V1_REMAP, + VUSBCP_DEV_GRP, + VUSBCP_TYPE, + VUSBCP_REMAP, + VUSB_DEDICATED1, + VUSB_DEDICATED2, + REGEN_DEV_GRP, + REGEN_TYPE, + REGEN_REMAP, + NRESPWRON_DEV_GRP, + NRESPWRON_TYPE, + NRESPWRON_REMAP, + CLKEN_DEV_GRP, + CLKEN_TYPE, + CLKEN_REMAP, + SYSEN_DEV_GRP, + SYSEN_TYPE, + SYSEN_REMAP, + HFCLKOUT_DEV_GRP, + HFCLKOUT_TYPE, + HFCLKOUT_REMAP, + E32KCLKOUT_DEV_GRP, + E32KCLKOUT_TYPE, + E32KCLKOUT_REMAP, + TRITON_RESET_DEV_GRP, + TRITON_RESET_TYPE, + TRITON_RESET_REMAP, + MAINREF_DEV_GRP, + MAINREF_TYPE, + MAINREF_REMAP, + SECONDS_REG, + MINUTES_REG, + HOURS_REG, + DAYS_REG, + MONTHS_REG, + YEARS_REG, + WEEKS_REG, + ALARM_SECONDS_REG, + ALARM_MINUTES_REG, + ALARM_HOURS_REG, + ALARM_DAYS_REG, + ALARM_MONTHS_REG, + ALARM_YEARS_REG, + RTC_CTRL_REG, + RTC_STATUS_REG, + RTC_INTERRUPTS_REG, + RTC_COMP_LSB_REG, + RTC_COMP_MSB_REG, //2d + }; + } // namespace Register + + namespace DCDC_GLOBAL_CFG + { + const TUint16 Addr = Register::DCDC_GLOBAL_CFG; + + const TUint8 CARD_DETECT_2_LEVEL = KBit7; + const TUint8 CARD_DETECT_1_LEVEL = KBit6; + const TUint8 REGEN_PU_DISABLE = KBit5; + const TUint8 SYSEN_PU_DISABLE = KBit4; + const TUint8 SMARTREFLEX_ENABLE = KBit3; + const TUint8 CARD_DETECT_CFG = KBit2; + const TUint8 CLK_32K_DEGATE = KBit1; + const TUint8 CLK_HF_DEGATE = KBit0; + }; + + + namespace _VMODE_CFG_ + { + const TUint8 STS_BUSY = KBit5; + const TUint8 STS_ROOF = KBit4; + const TUint8 STS_FLOOR = KBit3; + const TUint8 DCDC_SLP = KBit2; + const TUint8 READ_REG = KBit1; + const TUint8 ENABLE_VMODE = KBit0; + } + + namespace VDD1_VMODE_CFG + { + const TUint16 Addr = Register::VDD1_VMODE_CFG; + using namespace _VMODE_CFG_; + }; + + namespace VDD2_VMODE_CFG + { + const TUint16 Addr = Register::VDD2_VMODE_CFG; + using namespace _VMODE_CFG_; + }; + + namespace _VDDx_VSEL_ + { + namespace Mask + { + const TUint8 VSEL = 0x7F; + } + + namespace Shift + { + const TUint VSEL = 0; + } + } + + namespace VDD1_VSEL + { + const TUint16 Addr = Register::VDD1_VSEL; + using namespace _VDDx_VSEL_; + }; + + namespace VDD2_VSEL + { + const TUint16 Addr = Register::VDD2_VSEL; + using namespace _VDDx_VSEL_; + }; + + namespace _PWR_I_1_ + { + const TUint8 PWR_SC_DETECT = KBit7; + const TUint8 PWR_MBCHG = KBit6; + const TUint8 PWR_PWROK_TIMEOUT = KBit5; + const TUint8 PWR_HOT_DIE = KBit4; + const TUint8 PWR_RTC_IT = KBit3; + const TUint8 PWR_USB_PRES = KBit2; + const TUint8 PWR_CHG_PRES = KBit1; + const TUint8 PWR_CHG_PWRONS = KBit0; + } + + namespace PWR_IMR1 + { + const TUint16 Addr = Register::PWR_IMR1; + using namespace _PWR_I_1_; + } + + namespace PWR_ISR1 + { + const TUint16 Addr = Register::PWR_ISR1; + using namespace _PWR_I_1_; + } + + namespace _MADC_I_1_ + { + const TUint8 MADC_USB_ISR1 = KBit3; + const TUint8 MADC_SW2_ISR1 = KBit2; + const TUint8 MADC_SW1_ISR1 = KBit1; + const TUint8 MADC_RT_ISR1 = KBit0; + } + + namespace MADC_IMR1 + { + const TUint16 Addr = Register::MADC_IMR1; + using namespace _MADC_I_1_; + } + + namespace MADC_ISR1 + { + const TUint16 Addr = Register::MADC_ISR1; + using namespace _MADC_I_1_; + } + + namespace _GPIO_I_1A_ + { + const TUint8 GPIO7ISR1 = KBit7; + const TUint8 GPIO6ISR1 = KBit6; + const TUint8 GPIO5ISR1 = KBit5; + const TUint8 GPIO4ISR1 = KBit4; + const TUint8 GPIO3ISR1 = KBit3; + const TUint8 GPIO2ISR1 = KBit2; + const TUint8 GPIO1ISR1 = KBit1; + const TUint8 GPIO0ISR1 = KBit0; + } + + namespace _GPIO_I_2A_ + { + const TUint8 GPIO15ISR2 = KBit7; + const TUint8 GPIO14ISR2 = KBit6; + const TUint8 GPIO13ISR2 = KBit5; + const TUint8 GPIO12ISR2 = KBit4; + const TUint8 GPIO11ISR2 = KBit3; + const TUint8 GPIO10ISR2 = KBit2; + const TUint8 GPIO9ISR2 = KBit1; + const TUint8 GPIO8ISR2 = KBit0; + } + + namespace _GPIO_I_3A_ + { + const TUint8 GPIO17ISR3 = KBit1; + const TUint8 GPIO16ISR3 = KBit0; + } + + namespace GPIO_IMR1A + { + const TUint16 Addr = Register::GPIO_IMR1A; + using namespace _GPIO_I_1A_; + } + + namespace GPIO_ISR1A + { + const TUint16 Addr = Register::GPIO_ISR1A; + using namespace _GPIO_I_1A_; + } + + namespace GPIO_IMR2A + { + const TUint16 Addr = Register::GPIO_IMR2A; + using namespace _GPIO_I_2A_; + } + + namespace GPIO_ISR2A + { + const TUint16 Addr = Register::GPIO_ISR2A; + using namespace _GPIO_I_2A_; + } + + namespace GPIO_IMR3A + { + const TUint16 Addr = Register::GPIO_IMR3A; + using namespace _GPIO_I_3A_; + } + + namespace GPIO_ISR3A + { + const TUint16 Addr = Register::GPIO_ISR3A; + using namespace _GPIO_I_3A_; + } + + namespace _BCI_I_1_ + { + const TUint8 BCI_BATSTS_ISR1 = KBit7; + const TUint8 BCI_TBATOR1_ISR1 = KBit6; + const TUint8 BCI_TBATOR2_ISR1 = KBit5; + const TUint8 BCI_ICHGEOC_ISR1 = KBit4; + const TUint8 BCI_ICHGLOW_ISR1ASTO = KBit3; + const TUint8 BCI_IICHGHIGH_ISR1 = KBit2; + const TUint8 BCI_TMOVF_ISR1 = KBit1; + const TUint8 BCI_WOVF_ISR1 = KBit0; + } + + namespace _BCI_I_2_ + { + const TUint8 BCI_ACCHGOV_ISR1 = KBit3; + const TUint8 BCI_VBUSOV_ISR1 = KBit2; + const TUint8 BCI_VBATOV_ISR1 = KBit1; + const TUint8 BCI_VBATLVL_ISR1 = KBit0; + } + + namespace BCIIMR1A + { + const TUint16 Addr = Register::BCIIMR1A; + using namespace _BCI_I_1_; + } + + namespace BCIISR1A + { + const TUint16 Addr = Register::BCIISR1A; + using namespace _BCI_I_1_; + } + + namespace BCIIMR2A + { + const TUint16 Addr = Register::BCIIMR2A; + using namespace _BCI_I_2_; + } + + namespace BCIISR2A + { + const TUint16 Addr = Register::BCIISR2A; + using namespace _BCI_I_2_; + } + + namespace _KEYP_I_ + { + const TUint8 KEYP_ITMISR1 = KBit3; + const TUint8 KEYP_ITTOISR1 = KBit2; + const TUint8 KEYP_ITLKISR1 = KBit1; + const TUint8 KEYP_ITKPISR1 = KBit0; + } + + namespace KEYP_IMR1 + { + const TUint16 Addr = Register::KEYP_IMR1; + using namespace _KEYP_I_; + } + + namespace KEYP_ISR1 + { + const TUint16 Addr = Register::KEYP_ISR1; + using namespace _KEYP_I_; + } + + namespace _USB_INT_EN_ + { + const TUint8 USB_INTSTS_IDGND = KBit4; + const TUint8 USB_INTSTS_SESSEND = KBit3; + const TUint8 USB_INTSTS_SESSVALID = KBit2; + const TUint8 USB_INTSTS_VBUSVALID = KBit1; + const TUint8 USB_INTSTS_HOSTDISCONNECT = KBit0; + } + + namespace USB_INT_EN_RISE_SET + { + const TUint16 Addr = Register::USB_INT_EN_RISE_SET; + using namespace _USB_INT_EN_; + } + + namespace USB_INT_EN_RISE_CLR + { + const TUint16 Addr = Register::USB_INT_EN_RISE_CLR; + using namespace _USB_INT_EN_; + } + + namespace USB_INT_STS + { + const TUint16 Addr = Register::USB_INT_STS; + using namespace _USB_INT_EN_; + } + + namespace _OTHER_INT_ + { + const TUint8 OTHER_INT_VB_SESS_VLD = KBit7; + const TUint8 OTHER_INT_DM_HI = KBit6; + const TUint8 OTHER_INT_DP_HI = KBit5; + const TUint8 OTHER_INT_MANU = KBit1; + const TUint8 OTHER_INT_ABNORMAL_STRESS = KBit0; + } + + namespace OTHER_INT_EN_RISE_SET + { + const TUint16 Addr = Register::OTHER_INT_EN_RISE_SET; + using namespace _OTHER_INT_; + } + + namespace OTHER_INT_EN_RISE_CLR + { + const TUint16 Addr = Register::OTHER_INT_EN_RISE_CLR; + using namespace _OTHER_INT_; + } + + namespace OTHER_INT_STS + { + const TUint16 Addr = Register::OTHER_INT_STS; + using namespace _OTHER_INT_; + } + + namespace _CARKIT_INT_ + { + const TUint8 CARKIT_CARDP = KBit2; + const TUint8 CARKIT_CARINTDET = KBit1; + const TUint8 CARKIT_IDFLOAT = KBit0; + } + + namespace CARKIT_INT_EN_SET + { + const TUint16 Addr = Register::CARKIT_INT_EN_SET; + using namespace _CARKIT_INT_; + } + + namespace CARKIT_INT_EN_CLR + { + const TUint16 Addr = Register::CARKIT_INT_EN_CLR; + using namespace _CARKIT_INT_; + } + + namespace CARKIT_INT_STS + { + const TUint16 Addr = Register::CARKIT_INT_STS; + using namespace _CARKIT_INT_; + } + + namespace _ID_INT_ + { + const TUint8 ID_INTID_RES_FLOAT = KBit3; + const TUint8 ID_INTID_RES_440K = KBit2; + const TUint8 ID_INTID_RES_200K = KBit1; + const TUint8 ID_INTID_RES_102K = KBit0; + } + + namespace ID_INT_EN_RISE_SET + { + const TUint16 Addr = Register::ID_INT_EN_RISE_SET; + using namespace _ID_INT_; + } + + namespace ID_INT_EN_RISE_CLR + { + const TUint16 Addr = Register::ID_INT_EN_RISE_CLR; + using namespace _ID_INT_; + } + + namespace ID_INT_STS + { + const TUint16 Addr = Register::ID_INT_STS; + using namespace _ID_INT_; + } + + namespace _CARKIT_SM_1_INT_ + { + const TUint8 CARKIT_SM_1_PSM_ERROR = KBit6; + const TUint8 CARKIT_SM_1_PH_ACC = KBit5; + const TUint8 CARKIT_SM_1_CHARGER = KBit4; + const TUint8 CARKIT_SM_1_USB_HOST = KBit3; + const TUint8 CARKIT_SM_1_USB_OTG_B = KBit2; + const TUint8 CARKIT_SM_1_CARKIT = KBit1; + const TUint8 CARKIT_SM_1_DISCONNECTED = KBit0; + } + + namespace _CARKIT_SM_2_INT_ + { + const TUint8 CARKIT_SM_2_STOP_PLS_MISS = KBit7; + const TUint8 CARKIT_SM_2_STEREO_TO_MONO = KBit3; + const TUint8 CARKIT_SM_2_PHONE_UART = KBit1; + const TUint8 CARKIT_SM_2_PH_NO_ACK = KBit0; + } + + namespace CARKIT_SM_1_INT_EN_SET + { + const TUint16 Addr = Register::CARKIT_SM_1_INT_EN_SET; + using namespace _CARKIT_SM_1_INT_; + } + + namespace CARKIT_SM_1_INT_EN_CLR + { + const TUint16 Addr = Register::CARKIT_SM_1_INT_EN_CLR; + using namespace _CARKIT_SM_1_INT_; + } + + namespace CARKIT_SM_1_INT_STS + { + const TUint16 Addr = Register::CARKIT_SM_1_INT_STS; + using namespace _CARKIT_SM_1_INT_; + } + + namespace CARKIT_SM_2_INT_EN_SET + { + const TUint16 Addr = Register::CARKIT_SM_2_INT_EN_SET; + using namespace _CARKIT_SM_2_INT_; + } + + namespace CARKIT_SM_2_INT_EN_CLR + { + const TUint16 Addr = Register::CARKIT_SM_2_INT_EN_CLR; + using namespace _CARKIT_SM_2_INT_; + } + + namespace CARKIT_SM_2_INT_STS + { + const TUint16 Addr = Register::CARKIT_SM_2_INT_STS; + using namespace _CARKIT_SM_2_INT_; + } + + namespace _PIH_ + { + const TUint8 PIH_PWR_INT = KBit5; + const TUint8 PIH_USB_INT = KBit4; + const TUint8 PIH_MADC_INT = KBit3; + const TUint8 PIH_BCI_INT = KBit2; + const TUint8 PIH_KEYP_INT = KBit1; + const TUint8 PIH_GPIO_INT = KBit0; + } + + namespace PIH_ISR_P1 + { + const TUint Addr = Register::PIH_ISR_P1; + + const TUint8 PIH_ISR7 = KBit7; + const TUint8 PIH_ISR6 = KBit6; + const TUint8 PIH_ISR5 = KBit5; + const TUint8 PIH_ISR4 = KBit4; + const TUint8 PIH_ISR3 = KBit3; + const TUint8 PIH_ISR2 = KBit2; + const TUint8 PIH_ISR1 = KBit1; + const TUint8 PIH_ISR0 = KBit0; + } + + namespace _SIH_CTRL_ + { + const TUint8 SIH_EXCLEN = KBit0; + const TUint8 SIH_PENDDIS = KBit1; + const TUint8 SIH_COR = KBit2; + } + + namespace GPIO_SIH_CTRL + { + const TUint16 Addr = Register::GPIO_SIH_CTRL; + using namespace _SIH_CTRL_; + } + + namespace KEYP_SIH_CTRL + { + const TUint16 Addr = Register::KEYP_SIH_CTRL; + using namespace _SIH_CTRL_; + } + + namespace BCISIHCTRL + { + const TUint16 Addr = Register::BCISIHCTRL; + using namespace _SIH_CTRL_; + } + + namespace MADC_SIH_CTRL + { + const TUint16 Addr = Register::MADC_SIH_CTRL; + using namespace _SIH_CTRL_; + } + + namespace PWR_SIH_CTRL + { + const TUint16 Addr = Register::PWR_SIH_CTRL; + using namespace _SIH_CTRL_; + } + + namespace PROTECT_KEY + { + const TUint16 Addr = Register::PROTECT_KEY; + + const TUint8 KEY_TEST = KBit0; + const TUint8 KEY_CFG = KBit1; + } + + namespace RTC_CTRL_REG + { + const TUint16 Addr = Register::RTC_CTRL_REG; + + const TUint8 STOP_RTC = KBit0; + const TUint8 ROUND_30S = KBit1; + const TUint8 AUTO_COMP = KBit2; + const TUint8 MODE_12_24 = KBit3; + const TUint8 TEST_MODE = KBit4; + const TUint8 SET_32_COUNTER = KBit5; + const TUint8 GET_TIME = KBit6; + } + +} // namespace TPS65950 + +#endif // define TPS65950_REGISTERS_H