diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/lcd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/lcd.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,1009 @@ +// 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: +// template\Template_Variant\Specific\lcd.cpp +// Implementation of an LCD driver. +// This file is part of the Template 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 "platform.h" +#include +#include +#include +#include +#include + + +// 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 = 640; // 640 pixels per line +const TUint KConfigLcdHeight = 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; + + +// 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; // = 6.69 inches +const TInt KConfigLcdHeightInTwips = 7370; // = 5.11 inches + +// 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(8, KConfigLcdWidth, KConfigLcdHeight), // iLenghtOfVideoBufferInBytes + KConfigLcdWidth, // iOffsetBetweenLines + ETrue, // iIsPalettized + 8 // iBitsPerPixel + } + }; + + + +_LIT(KLitLcd,"LCD"); + +// +// TO DO: (optional) +// +// Add any private functions and data you require +// +NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler + { +public: + DLcdPowerHandler(); + ~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; + TDynamicDfcQue* 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) + { + } + +DLcdPowerHandler::~DLcdPowerHandler() + { + if (iDfcQ) + iDfcQ->Destroy(); + } + +/** +Second-phase constructor + +Called by factory function at ordinal 0 +*/ +TInt DLcdPowerHandler::Create() + { + const TInt KLCDDfcQPriority=27; // Equal to Kern::DfcQue0() priority + TInt r = Kern::DynamicDfcQCreate(iDfcQ, KLCDDfcQPriority, _L("LCDPowerHandler")); + if (r != KErrNone) + { + return r; + } + + // map the video RAM + TInt vSize = ((TemplateAssp*)Arch::TheAsic())->VideoRamSize(); + ivRamPhys = TTemplate::VideoRamPhys(); // EXAMPLE ONLY: assume TTemplate 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(KPOWER, 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(KPOWER, 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) + { + + // TO DO: (mandatory) + // Power up the display and configure it ready for use + // Examples of things that may need initializing are: + // panel dimensions + // line & frame timings + // bits-per-pixel + // Configuring the DMA engine to map the video buffer in ivRamPhys or iSecurevRamPhys + // contrast, brightness, backlight + // power + // etc. etc. + // + } + +/** +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 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 + + // initialise the video ram to be a splash screen + __KTRACE_OPT(KEXTENSION,Kern::Printf("SplashScreen")); + + TUint x,y; + TUint8 * p = (TUint8*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel); + + //draw >< on screen + TUint rsh = KConfigLcdHeight; + TUint rsw = KConfigLcdWidth; + for (y = 0; y < rsh>>1; y++) + { + TUint8* q = p; + for (x = 0; x < rsw; x++) + *p++ = (x < y || (rsw-x>1; y < rsh; y++) + { + TUint8* q = p; + for (x = 0; x < rsw; x++) + *p++ = ((x < rsh-y) || (rsw-x< on secure screen + for (y = 0; y < rsh>>1; y++) + { + TUint8* q = p; + for (x = 0; x < rsw; x++) + *p++ = (x < y || (rsw-x>1; y < rsh; y++) + { + TUint8* q = p; + for (x = 0; x < rsw; x++) + *p++ = ((x < rsh-y) || (rsw-x= 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) + { + __e32_memory_barrier(); // Ensure changes from other clients are picked up + + 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: + 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: + 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; + } + + __e32_memory_barrier(); // Ensure any changes are propagated to other clients + + 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; + } +