--- /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 <videodriver.h>
+#include <platform.h>
+#include <nkern.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <kpower.h>
+#include <assp/omap3530_assp/omap3530_assp_priv.h>
+#include <assp/omap3530_assp/omap3530_hardware_base.h>
+#include <assp/omap3530_assp/omap3530_prcm.h>
+
+#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<Reg>::Value )
+#define SET_REGISTER(Reg,Val) *( (TUint *) Omap3530HwBase::TVirtual<Reg>::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<KConfigLcdHeight; ++y)
+ {
+ for(TInt x = 0; x<KConfigLcdHeight; ++x)
+ {
+ TUint8 r = 0x00;
+ TUint8 g = 0x00;
+ TUint8 b = 0x00;
+ TUint16 rgb = ((r&0xf8) << 8) | ((g&0xfc) << 3) | ((b&0xf8) >> 3);
+
+ TUint16* px = reinterpret_cast<TUint16*>(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<<iVideoInfo.iBitsPerPixel : 0;
+
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
+
+ return num;
+ }
+
+
+/**
+Retrieve the palette entry at a particular offset
+
+@param aEntry the palette index
+@param aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
+@return KErrNone if successful
+ KErrNotSupported if the current vide mode does not support a palette
+ KErrArgument if aEntry is out of range
+*/
+TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
+ {
+ NKern::FMWait(&iLock);
+ if (!iVideoInfo.iIsPalettized)
+ {
+ NKern::FMSignal(&iLock);
+ return KErrNotSupported;
+ }
+
+ if ((aEntry < 0) || (aEntry >= 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<TScreenInfoV01> 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()<ELow)
+ r=KErrBadPower;
+ else
+ SetBacklightState(TBool(a1));
+ break;
+
+ case EDisplayHalBacklightOn:
+ kumemput32(a1,&iBacklightOn,sizeof(TInt));
+ break;
+
+ case EDisplayHalModeCount:
+ {
+ TInt ndm = KConfigLcdNumberOfDisplayModes;
+ kumemput32(a1, &ndm, sizeof(ndm));
+ break;
+ }
+
+ case EDisplayHalSetMode:
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+ return KErrPermissionDenied;
+ r = SetDisplayMode((TInt)a1);
+ break;
+
+ case EDisplayHalMode:
+ kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
+ break;
+
+ case EDisplayHalSetPaletteEntry:
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+ return KErrPermissionDenied;
+ r = SetPaletteEntry((TInt)a1, (TInt)a2);
+ break;
+
+ case EDisplayHalPaletteEntry:
+ {
+ TInt entry;
+ kumemget32(&entry, a1, sizeof(TInt));
+ TInt x;
+ r = GetPaletteEntry(entry, &x);
+ if (r == KErrNone)
+ kumemput32(a2, &x, sizeof(x));
+ break;
+ }
+
+ case EDisplayHalSetState:
+ {
+ if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+ return KErrPermissionDenied;
+ if ((TBool)a1)
+ {
+ WsSwitchOnScreen();
+ }
+ else
+ {
+ WsSwitchOffScreen();
+ }
+ break;
+ }
+
+ case EDisplayHalState:
+ kumemput32(a1, &iDisplayOn, sizeof(TBool));
+ break;
+
+ case EDisplayHalColors:
+ {
+ TInt mdc = KConfigLcdMaxDisplayColors;
+ kumemput32(a1, &mdc, sizeof(mdc));
+ break;
+ }
+
+ case EDisplayHalCurrentModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> vPckg;
+ r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
+ if (KErrNone == r)
+ Kern::InfoCopy(*(TDes8*)a1,vPckg);
+ }
+ break;
+
+ case EDisplayHalSpecifiedModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> 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;
+ }
+