bsptemplate/asspandvariant/template_variant/specific/lcd.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // template\Template_Variant\Specific\lcd.cpp
       
    15 // Implementation of an LCD driver. 
       
    16 // This file is part of the Template Base port
       
    17 // N.B. This sample code assumes that the display supports setting the backlight on or off, 
       
    18 // as well as adjusting the contrast and the brightness.
       
    19 // 
       
    20 //
       
    21 
       
    22 
       
    23 
       
    24 #include <videodriver.h>
       
    25 #include "platform.h"
       
    26 #include <nkern.h>
       
    27 #include <kernel/kernel.h>
       
    28 #include <kernel/kern_priv.h>
       
    29 #include <kernel/kpower.h>
       
    30 #include <template_assp_priv.h>
       
    31 
       
    32 
       
    33 // TO DO: (mandatory)
       
    34 // If the display supports Contrast and/or Brightness control then supply the following defines:
       
    35 // This is only example code... you may need to modify it for your hardware
       
    36 const TInt KConfigInitialDisplayContrast	= 128;
       
    37 const TInt KConfigLcdMinDisplayContrast		= 1;
       
    38 const TInt KConfigLcdMaxDisplayContrast		= 255;
       
    39 const TInt KConfigInitialDisplayBrightness	= 128;
       
    40 const TInt KConfigLcdMinDisplayBrightness	= 1;
       
    41 const TInt KConfigLcdMaxDisplayBrightness	= 255;
       
    42 
       
    43 // TO DO: (mandatory)
       
    44 // define a macro to calculate the screen buffer size
       
    45 // This is only example code... you may need to modify it for your hardware
       
    46 // aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and 
       
    47 // aLpp number of lines per panel
       
    48 #define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp)	(aBpp*aPpl*aLpp)/8	
       
    49 																
       
    50 
       
    51 // TO DO: (mandatory)
       
    52 // define the physical screen dimensions
       
    53 // This is only example code... you need to modify it for your hardware
       
    54 const TUint	KConfigLcdWidth					= 640;		// 640 pixels per line
       
    55 const TUint	KConfigLcdHeight				= 480;		// 480 lines per panel
       
    56 
       
    57 // TO DO: (mandatory)
       
    58 // define the characteristics of the LCD display
       
    59 // This is only example code... you need to modify it for your hardware
       
    60 const TBool	KConfigLcdIsMono				= EFalse;
       
    61 const TBool	KConfigLcdPixelOrderLandscape	= ETrue;
       
    62 const TBool	KConfigLcdPixelOrderRGB			= ETrue;
       
    63 const TInt	KConfigLcdMaxDisplayColors		= 65536;
       
    64 
       
    65 
       
    66 // TO DO: (mandatory)
       
    67 // define the display dimensions in TWIPs
       
    68 // A TWIP is a 20th of a point.  A point is a 72nd of an inch
       
    69 // Therefore a TWIP is a 1440th of an inch
       
    70 // This is only example code... you need to modify it for your hardware
       
    71 const TInt	KConfigLcdWidthInTwips			= 9638;		// = 6.69 inches
       
    72 const TInt	KConfigLcdHeightInTwips			= 7370;		// = 5.11 inches
       
    73 
       
    74 // TO DO: (mandatory)
       
    75 // define the available display modes
       
    76 // This is only example code... you need to modify it for your hardware
       
    77 const TInt  KConfigLcdNumberOfDisplayModes	= 1;
       
    78 const TInt  KConfigLcdInitialDisplayMode	= 0;
       
    79 struct SLcdConfig
       
    80 	{
       
    81 	TInt iMode;
       
    82 	TInt iOffsetToFirstVideoBuffer;
       
    83 	TInt iLenghtOfVideoBufferInBytes;
       
    84 	TInt iOffsetBetweenLines;
       
    85 	TBool iIsPalettized;
       
    86 	TInt iBitsPerPixel;
       
    87 	};
       
    88 static const SLcdConfig Lcd_Mode_Config[KConfigLcdNumberOfDisplayModes]=
       
    89 	{
       
    90 		{
       
    91 		0,								// iMode
       
    92 		0,								// iOffsetToFirstVideoBuffer
       
    93 		FRAME_BUFFER_SIZE(8, KConfigLcdWidth, KConfigLcdHeight),	// iLenghtOfVideoBufferInBytes
       
    94 		KConfigLcdWidth,				// iOffsetBetweenLines
       
    95 		ETrue,							// iIsPalettized
       
    96 		8								// iBitsPerPixel
       
    97 		}
       
    98 	};	
       
    99 
       
   100 
       
   101 
       
   102 _LIT(KLitLcd,"LCD");
       
   103 
       
   104 //
       
   105 // TO DO: (optional)
       
   106 //
       
   107 // Add any private functions and data you require
       
   108 //
       
   109 NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler
       
   110 	{
       
   111 public: 
       
   112 	DLcdPowerHandler();
       
   113 	~DLcdPowerHandler();
       
   114 	
       
   115 	// from DPowerHandler
       
   116 	void PowerDown(TPowerState);
       
   117 	void PowerUp();
       
   118 
       
   119 	void PowerUpDfc();
       
   120 	void PowerDownDfc();
       
   121 
       
   122 	TInt Create();
       
   123 	void DisplayOn();
       
   124 	void DisplayOff();
       
   125 	TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
       
   126 
       
   127 	void PowerUpLcd(TBool aSecure);
       
   128 	void PowerDownLcd();
       
   129 
       
   130 	void ScreenInfo(TScreenInfoV01& aInfo);
       
   131 	void WsSwitchOnScreen();
       
   132 	void WsSwitchOffScreen();
       
   133 	void HandleMsg();
       
   134 	void SwitchDisplay(TBool aSecure);
       
   135 
       
   136 	void SetBacklightState(TBool aState);
       
   137 	void BacklightOn();
       
   138 	void BacklightOff();
       
   139 	TInt SetContrast(TInt aContrast);
       
   140 	TInt SetBrightness(TInt aBrightness);
       
   141 
       
   142 private:
       
   143 	TInt SetPaletteEntry(TInt aEntry, TInt aColor);
       
   144 	TInt GetPaletteEntry(TInt aEntry, TInt* aColor);
       
   145 	TInt NumberOfPaletteEntries();
       
   146 	TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
       
   147 	TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
       
   148 	TInt SetDisplayMode(TInt aMode);
       
   149 	void SplashScreen();
       
   150 	TInt GetDisplayColors(TInt* aColors);
       
   151 
       
   152 private:
       
   153 	TBool iIsPalettized;
       
   154 	TBool iDisplayOn;				// to prevent a race condition with WServer trying to power up/down at the same time
       
   155 	DPlatChunkHw* iChunk;
       
   156 	DPlatChunkHw* iSecureChunk;
       
   157 	TBool iWsSwitchOnScreen;
       
   158  	TBool iSecureDisplay;
       
   159 	TDynamicDfcQue* iDfcQ;
       
   160 	TMessageQue iMsgQ;
       
   161 	TDfc iPowerUpDfc;
       
   162 	TDfc iPowerDownDfc;	
       
   163 	TVideoInfoV01 iVideoInfo;
       
   164 	TVideoInfoV01 iSecureVideoInfo;
       
   165 	NFastMutex iLock;				// protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo
       
   166 	TPhysAddr ivRamPhys;
       
   167 	TPhysAddr iSecurevRamPhys;
       
   168 
       
   169 	TBool iBacklightOn;
       
   170 	TInt iContrast;
       
   171 	TInt iBrightness;
       
   172 	};
       
   173 
       
   174 
       
   175 /**
       
   176 HAL handler function
       
   177 
       
   178 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   179 @param	aFunction the function number
       
   180 @param	a1 an arbitrary parameter
       
   181 @param	a2 an arbitrary parameter
       
   182 */
       
   183 LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
   184 	{
       
   185 	DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
       
   186 	return pH->HalFunction(aFunction,a1,a2);
       
   187 	}
       
   188 
       
   189 /**
       
   190 DFC for receiving messages from the power handler
       
   191 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   192 */
       
   193 void rxMsg(TAny* aPtr)
       
   194 	{
       
   195 	DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
       
   196 	h.HandleMsg();
       
   197 	}
       
   198 
       
   199 /**
       
   200 DFC for powering up the device
       
   201 
       
   202 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   203 */
       
   204 void power_up_dfc(TAny* aPtr)
       
   205 	{
       
   206 	((DLcdPowerHandler*)aPtr)->PowerUpDfc();
       
   207 	}
       
   208 
       
   209 /**
       
   210 DFC for powering down the device
       
   211 
       
   212 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   213 */
       
   214 void power_down_dfc(TAny* aPtr)
       
   215 	{
       
   216 	((DLcdPowerHandler*)aPtr)->PowerDownDfc();
       
   217 	}
       
   218 
       
   219 
       
   220 /**
       
   221 Default constructor
       
   222 */
       
   223 DLcdPowerHandler::DLcdPowerHandler() :
       
   224 		DPowerHandler(KLitLcd),
       
   225 		iMsgQ(rxMsg,this,NULL,1),
       
   226 		iPowerUpDfc(&power_up_dfc,this,6),
       
   227 		iPowerDownDfc(&power_down_dfc,this,7),
       
   228 		iBacklightOn(EFalse),
       
   229 		iContrast(KConfigInitialDisplayContrast),
       
   230 		iBrightness(KConfigInitialDisplayBrightness)
       
   231 	{
       
   232 	}
       
   233 
       
   234 DLcdPowerHandler::~DLcdPowerHandler()
       
   235 	{
       
   236 	if (iDfcQ)
       
   237 		iDfcQ->Destroy();
       
   238 	}
       
   239 
       
   240 /**
       
   241 Second-phase constructor 
       
   242 
       
   243 Called by factory function at ordinal 0
       
   244 */
       
   245 TInt DLcdPowerHandler::Create()
       
   246 	{
       
   247 	const TInt KLCDDfcQPriority=27; // Equal to Kern::DfcQue0() priority
       
   248 	TInt r = Kern::DynamicDfcQCreate(iDfcQ, KLCDDfcQPriority, _L("LCDPowerHandler"));
       
   249 	if (r != KErrNone)
       
   250 		{
       
   251 		return r;
       
   252 		}
       
   253 
       
   254 	// map the video RAM
       
   255 	TInt vSize = ((TemplateAssp*)Arch::TheAsic())->VideoRamSize();
       
   256 	ivRamPhys = TTemplate::VideoRamPhys();				// EXAMPLE ONLY: assume TTemplate interface class
       
   257 	r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   258 	if (r != KErrNone)
       
   259 		return r;
       
   260 	
       
   261 	//create "secure" screen immediately after normal one
       
   262 	iSecurevRamPhys =  ivRamPhys + vSize;
       
   263 	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   264 	if (r2 != KErrNone)
       
   265 		return r2;
       
   266 
       
   267 	TUint* pV=(TUint*)iChunk->LinearAddress();
       
   268 
       
   269 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV));
       
   270 
       
   271 	// TO DO: (mandatory)
       
   272 	// initialise the palette for the initial display mode
       
   273 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
   274 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
   275 	//
       
   276 
       
   277 	TUint* pV2=(TUint*)iSecureChunk->LinearAddress();
       
   278 
       
   279 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2));
       
   280 
       
   281 	// TO DO: (mandatory)
       
   282 	// initialise the secure screen's palette for the initial display mode
       
   283 	//
       
   284 	
       
   285 	// setup the video info structure, this'll be used to remember the video settings
       
   286 	iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode;
       
   287 	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer;
       
   288 	iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized;
       
   289 	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines;
       
   290 	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel;
       
   291 
       
   292 	iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
       
   293 	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
       
   294 	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
       
   295 	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
       
   296 	iVideoInfo.iIsMono = KConfigLcdIsMono;
       
   297 	iVideoInfo.iVideoAddress=(TInt)pV;
       
   298 	iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape;
       
   299 	iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB;
       
   300 
       
   301 	iSecureVideoInfo = iVideoInfo;
       
   302 	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
       
   303 
       
   304 	iDisplayOn = EFalse;
       
   305 	iSecureDisplay = EFalse;
       
   306 
       
   307 	// install the HAL function
       
   308 	r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
       
   309 	if (r!=KErrNone)
       
   310 		return r;
       
   311 
       
   312 	iPowerUpDfc.SetDfcQ(iDfcQ);
       
   313 	iPowerDownDfc.SetDfcQ(iDfcQ);
       
   314 	iMsgQ.SetDfcQ(iDfcQ);
       
   315 	iMsgQ.Receive();
       
   316 
       
   317 	// install the power handler
       
   318 	// power up the screen
       
   319 	Add();
       
   320 	DisplayOn();
       
   321 
       
   322 	SplashScreen();
       
   323 	
       
   324 	return KErrNone;
       
   325 	}
       
   326 
       
   327 /**
       
   328 Turn the display on
       
   329 May be called as a result of a power transition or from the HAL
       
   330 If called from HAL, then the display may be already be on (iDisplayOn == ETrue)
       
   331 */
       
   332 void DLcdPowerHandler::DisplayOn()
       
   333 	{
       
   334 	__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOn %d", iDisplayOn));
       
   335 	if (!iDisplayOn)				// may have been powered up already
       
   336 		{
       
   337 		iDisplayOn = ETrue;
       
   338 		PowerUpLcd(iSecureDisplay);
       
   339 		SetContrast(iContrast);
       
   340 		SetBrightness(iBrightness);
       
   341 		}
       
   342 	}
       
   343 
       
   344 /**
       
   345 Turn the display off
       
   346 May be called as a result of a power transition or from the HAL
       
   347 If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse)
       
   348 if the platform is in silent running mode
       
   349 */
       
   350 void DLcdPowerHandler::DisplayOff()
       
   351 	{
       
   352 	__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOff %d", iDisplayOn));
       
   353 	if (iDisplayOn)
       
   354 		{
       
   355 		iDisplayOn = EFalse;
       
   356 		PowerDownLcd();
       
   357 		}
       
   358 	}
       
   359 
       
   360 /**
       
   361 Switch between secure and non-secure displays
       
   362 
       
   363 @param aSecure ETrue if switching to secure display
       
   364 */
       
   365 void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
       
   366  	{
       
   367  	if (aSecure)
       
   368  		{
       
   369  		if (!iSecureDisplay)
       
   370  			{
       
   371  			//switch to secure display
       
   372  			DisplayOff();
       
   373  			iSecureDisplay = ETrue;
       
   374  			DisplayOn();
       
   375  			}
       
   376  		}
       
   377  	else
       
   378  		{
       
   379  		if (iSecureDisplay)
       
   380  			{
       
   381  			//switch from secure display
       
   382  			DisplayOff();
       
   383  			iSecureDisplay = EFalse;
       
   384  			DisplayOn();
       
   385  			}
       
   386  		}
       
   387  	}
       
   388 
       
   389 /**
       
   390 DFC to power up the display
       
   391 */
       
   392 void DLcdPowerHandler::PowerUpDfc()
       
   393 	{
       
   394 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc"));
       
   395 	DisplayOn();
       
   396 
       
   397 	PowerUpDone();				// must be called from a different thread than PowerUp()
       
   398 	}
       
   399 
       
   400 /**
       
   401 DFC to power down the display
       
   402 */
       
   403 void DLcdPowerHandler::PowerDownDfc()
       
   404 	{
       
   405 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc"));
       
   406 	DisplayOff();
       
   407 	PowerDownDone();			// must be called from a different thread than PowerUp()
       
   408 	}
       
   409 
       
   410 /**
       
   411 Schedule the power-down DFC
       
   412 */
       
   413 void DLcdPowerHandler::PowerDown(TPowerState)
       
   414 	{
       
   415 	iPowerDownDfc.Enque();		// schedules DFC to execute on this driver's thread
       
   416 	}
       
   417 
       
   418 /**
       
   419 Schedule the power-up DFC
       
   420 */
       
   421 void DLcdPowerHandler::PowerUp()
       
   422 	{
       
   423 	iPowerUpDfc.Enque();		// schedules DFC to execute on this driver's thread
       
   424 	}
       
   425 
       
   426 /**
       
   427 Power up the display
       
   428 
       
   429 @param aSecure ETrue if powering up the secure display
       
   430 */
       
   431 void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
       
   432     {
       
   433 
       
   434 	// TO DO: (mandatory)
       
   435 	// Power up the display and configure it ready for use
       
   436 	// Examples of things that may need initializing are:
       
   437 	// panel dimensions
       
   438 	// line & frame timings
       
   439 	// bits-per-pixel
       
   440 	// Configuring the DMA engine to map the video buffer in ivRamPhys or iSecurevRamPhys
       
   441 	// contrast, brightness, backlight
       
   442 	// power
       
   443 	// etc. etc.
       
   444 	//
       
   445     }
       
   446 
       
   447 /**
       
   448 Power down the display and the backlight
       
   449 */
       
   450 void DLcdPowerHandler::PowerDownLcd()
       
   451     {
       
   452 	SetBacklightState(EFalse);
       
   453 
       
   454 	// TO DO: (mandatory)
       
   455 	// Power down the display & disable LCD DMA.
       
   456 	// May need to wait until the current frame has been output
       
   457 	//
       
   458     }
       
   459 
       
   460 /**
       
   461 Set the Lcd contrast
       
   462 
       
   463 @param aValue the contrast setting
       
   464 */
       
   465 TInt DLcdPowerHandler::SetContrast(TInt aValue)
       
   466 	{
       
   467 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue));
       
   468 
       
   469 	if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast)
       
   470 		{
       
   471 		iContrast=aValue;
       
   472 		
       
   473 		// TO DO: (mandatory)
       
   474 		// set the contrast
       
   475 		//
       
   476 		return KErrNone;
       
   477 		}
       
   478 
       
   479 	return KErrArgument;
       
   480 	}
       
   481 
       
   482 /**
       
   483 Set the Lcd brightness
       
   484 
       
   485 @param aValue the brightness setting
       
   486 */
       
   487 TInt DLcdPowerHandler::SetBrightness(TInt aValue)
       
   488 	{
       
   489 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
       
   490 
       
   491 	if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness)
       
   492 		{
       
   493 		iBrightness=aValue;
       
   494 
       
   495 		// TO DO: (mandatory)
       
   496 		// set the brightness
       
   497 		//
       
   498 		return KErrNone;
       
   499 		}
       
   500 	return KErrArgument;
       
   501 	}
       
   502 
       
   503 /**
       
   504 Turn the backlight on
       
   505 */
       
   506 void DLcdPowerHandler::BacklightOn()
       
   507     {
       
   508 	// TO DO: (mandatory)
       
   509 	// turn the backlight on
       
   510 	//
       
   511     }
       
   512 
       
   513 /**
       
   514 Turn the backlight off
       
   515 */
       
   516 void DLcdPowerHandler::BacklightOff()
       
   517     {
       
   518 	// TO DO: (mandatory)
       
   519 	// turn the backlight off
       
   520 	//
       
   521     }
       
   522 
       
   523 /**
       
   524 Set the state of the backlight
       
   525 
       
   526 @param aState ETrue if setting the backlight on
       
   527 */
       
   528 void DLcdPowerHandler::SetBacklightState(TBool aState)
       
   529 	{
       
   530 	iBacklightOn=aState;
       
   531 	if (iBacklightOn)
       
   532 		BacklightOn();
       
   533 	else
       
   534 		BacklightOff();
       
   535 	}
       
   536 
       
   537 void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
       
   538 	{
       
   539 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo"));
       
   540 	anInfo.iWindowHandleValid=EFalse;
       
   541 	anInfo.iWindowHandle=NULL;
       
   542 	anInfo.iScreenAddressValid=ETrue;
       
   543 	anInfo.iScreenAddress=(TAny *)(iChunk->LinearAddress());
       
   544 	anInfo.iScreenSize.iWidth=KConfigLcdWidth;
       
   545 	anInfo.iScreenSize.iHeight=KConfigLcdHeight;
       
   546 	}
       
   547 
       
   548 /**
       
   549 Handle a message from the power handler
       
   550 */
       
   551 void DLcdPowerHandler::HandleMsg(void)
       
   552 	{
       
   553 	
       
   554 	TMessageBase* msg = iMsgQ.iMessage;
       
   555 	if (msg == NULL)
       
   556 		return;
       
   557 
       
   558 	if (msg->iValue)
       
   559 		DisplayOn();
       
   560 	else
       
   561 		DisplayOff();
       
   562 	msg->Complete(KErrNone,ETrue);
       
   563 	}
       
   564 
       
   565 /**
       
   566 Send a message to the power-handler message queue to turn the display on
       
   567 */
       
   568 void DLcdPowerHandler::WsSwitchOnScreen()
       
   569 	{
       
   570 	TThreadMessage& m=Kern::Message();
       
   571 	m.iValue = ETrue;
       
   572 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
       
   573 	}
       
   574 
       
   575 /**
       
   576 Send a message to the power-handler message queue to turn the display off
       
   577 */
       
   578 void DLcdPowerHandler::WsSwitchOffScreen()
       
   579 	{
       
   580 	TThreadMessage& m=Kern::Message();
       
   581 	m.iValue = EFalse;
       
   582 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
       
   583 	}
       
   584 
       
   585 /**
       
   586 Return information about the current display mode
       
   587 
       
   588 @param	aInfo a structure supplied by the caller to be filled by this function.
       
   589 @param	aSecure ETrue if requesting information about the secure display
       
   590 @return	KErrNone if successful
       
   591 */
       
   592 TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
       
   593 	{
       
   594 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
       
   595 	NKern::FMWait(&iLock);
       
   596 	if (aSecure)
       
   597  		aInfo = iSecureVideoInfo;
       
   598  	else
       
   599  		aInfo = iVideoInfo;
       
   600 	NKern::FMSignal(&iLock);
       
   601 	return KErrNone;
       
   602 	}
       
   603 
       
   604 /**
       
   605 Return information about the specified display mode
       
   606 
       
   607 @param	aMode the display mode to query
       
   608 @param	aInfo a structure supplied by the caller to be filled by this function.
       
   609 @return	KErrNone if successful
       
   610 */
       
   611 TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
       
   612 	{
       
   613 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetSpecifiedDisplayModeInfo mode is %d",aMode));
       
   614 
       
   615 	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   616 		return KErrArgument;
       
   617 
       
   618 	NKern::FMWait(&iLock);
       
   619 	aInfo = iVideoInfo;
       
   620 	NKern::FMSignal(&iLock);
       
   621 
       
   622 	if (aMode != aInfo.iDisplayMode)
       
   623 		{
       
   624 		aInfo.iOffsetToFirstPixel=Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   625 		aInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   626 		aInfo.iOffsetBetweenLines=Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   627 		aInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   628 		}
       
   629 	return KErrNone;
       
   630 	}
       
   631 
       
   632 /**
       
   633 Set the display mode
       
   634 
       
   635 @param	aMode the display mode to set
       
   636 */
       
   637 TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
       
   638 	{
       
   639 
       
   640 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode = %d", aMode));
       
   641 
       
   642 	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   643 		return KErrArgument;
       
   644 
       
   645 	NKern::FMWait(&iLock);
       
   646 
       
   647 	// store the current mode
       
   648 	iVideoInfo.iDisplayMode = aMode;
       
   649 	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   650 	iVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   651 	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   652 	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   653 
       
   654 	// store the current mode for secure screen
       
   655 	iSecureVideoInfo.iDisplayMode = aMode;
       
   656 	iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   657 	iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   658 	iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   659 	iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   660 	
       
   661 	// TO DO: (mandatory)
       
   662 	// set bits per pixel on hardware
       
   663 	// May need to reconfigure DMA if video buffer size and location have changed
       
   664 	//
       
   665 	NKern::FMSignal(&iLock);
       
   666 
       
   667 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode mode = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d",
       
   668 		aMode, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines));
       
   669 
       
   670 	return KErrNone;
       
   671 	}
       
   672 
       
   673 /**
       
   674 Fill the video memory with an initial pattern or image
       
   675 This will be displayed on boot-up
       
   676 */
       
   677 void DLcdPowerHandler::SplashScreen()
       
   678 	{
       
   679 	// TO DO: (optional)
       
   680 	// replace the example code below to display a different spash screen
       
   681 
       
   682 	// initialise the video ram to be a splash screen
       
   683 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SplashScreen"));
       
   684 
       
   685 	TUint x,y;
       
   686 	TUint8 * p = (TUint8*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel);
       
   687 
       
   688 	//draw >< on screen
       
   689 	TUint rsh = KConfigLcdHeight;
       
   690 	TUint rsw = KConfigLcdWidth;
       
   691 	for (y = 0; y < rsh>>1; y++)
       
   692 		{
       
   693 		TUint8* q = p;
       
   694 		for (x = 0; x < rsw; x++)
       
   695 			*p++ = (x < y || (rsw-x<y)) ? 1 : 2;
       
   696 		p = q + iVideoInfo.iOffsetBetweenLines;
       
   697 		}
       
   698 	for (y = rsh>>1; y < rsh; y++)
       
   699 		{
       
   700 		TUint8* q = p;
       
   701 		for (x = 0; x < rsw; x++)
       
   702 			*p++ = ((x < rsh-y) || (rsw-x<rsh-y)) ? 1 : 2;
       
   703 		p = q + iVideoInfo.iOffsetBetweenLines;
       
   704 		}
       
   705 
       
   706 	p = (TUint8*)(iSecureVideoInfo.iVideoAddress + iSecureVideoInfo.iOffsetToFirstPixel);
       
   707 
       
   708 	//draw >< on secure screen
       
   709 	for (y = 0; y < rsh>>1; y++)
       
   710 		{
       
   711 		TUint8* q = p;
       
   712 		for (x = 0; x < rsw; x++)
       
   713 			*p++ = (x < y || (rsw-x<y)) ? 1 : 2;
       
   714 		p = q + iSecureVideoInfo.iOffsetBetweenLines;
       
   715 		}
       
   716 	for (y = rsh>>1; y < rsh; y++)
       
   717 		{
       
   718 		TUint8* q = p;
       
   719 		for (x = 0; x < rsw; x++)
       
   720 			*p++ = ((x < rsh-y) || (rsw-x<rsh-y)) ? 1 : 2;
       
   721 		p = q + iSecureVideoInfo.iOffsetBetweenLines;
       
   722 		}
       
   723 	}
       
   724 
       
   725 
       
   726 /**
       
   727 Get the size of the pallete
       
   728 
       
   729 @return	the number of pallete entries
       
   730 */
       
   731 TInt DLcdPowerHandler::NumberOfPaletteEntries()		//only call when holding mutex
       
   732 	{
       
   733 	// TO DO: (mandatory)
       
   734 	// Calculate the number of Palette entries - this is normally 
       
   735 	// calculated from the bits per-pixel.
       
   736 	// This is only example code... you may need to modify it for your hardware
       
   737 	//
       
   738 	TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
       
   739 
       
   740 	__KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
       
   741 
       
   742 	return num;
       
   743 	}
       
   744 
       
   745 
       
   746 /** 
       
   747 Retrieve the palette entry at a particular offset
       
   748 
       
   749 @param	aEntry the palette index
       
   750 @param	aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
       
   751 @return	KErrNone if successful
       
   752 		KErrNotSupported if the current vide mode does not support a palette
       
   753 		KErrArgument if aEntry is out of range
       
   754 */
       
   755 TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
       
   756 	{
       
   757 	NKern::FMWait(&iLock);
       
   758 	if (!iVideoInfo.iIsPalettized)
       
   759 		{
       
   760 		NKern::FMSignal(&iLock);
       
   761 		return KErrNotSupported;
       
   762 		}
       
   763 
       
   764 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))
       
   765 		{
       
   766 		NKern::FMSignal(&iLock);
       
   767 		return KErrArgument;
       
   768 		}
       
   769 
       
   770 	// TO DO: (mandatory)
       
   771 	// read the RGB value of the palette entry into aColor
       
   772 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
   773 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
   774 	//
       
   775 	NKern::FMSignal(&iLock);
       
   776 
       
   777 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor));
       
   778 
       
   779 	return KErrNone;
       
   780 	}
       
   781 
       
   782 /** 
       
   783 Set the palette entry at a particular offset
       
   784 
       
   785 @param	aEntry the palette index
       
   786 @param	aColor the RGB color to store
       
   787 @return	KErrNone if successful
       
   788 		KErrNotSupported if the current vide mode does not support a palette
       
   789 		KErrArgument if aEntry is out of range
       
   790 */
       
   791 TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor)
       
   792 	{
       
   793 
       
   794 	NKern::FMWait(&iLock);
       
   795 	if (!iVideoInfo.iIsPalettized)
       
   796 		{
       
   797 		NKern::FMSignal(&iLock);
       
   798 		return KErrNotSupported;
       
   799 		}
       
   800 
       
   801 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))	//check entry in range
       
   802 		{
       
   803 		NKern::FMSignal(&iLock);
       
   804 		return KErrArgument;
       
   805 		}
       
   806 
       
   807 	// TO DO: (mandatory)
       
   808 	// update the palette entry for the secure and non-secure screen
       
   809 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
   810 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
   811 	//
       
   812 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor ));
       
   813 
       
   814 	return KErrNone;
       
   815 	}
       
   816 
       
   817 /**
       
   818 a HAL entry handling function for HAL group attribute EHalGroupDisplay
       
   819 
       
   820 @param	a1 an arbitrary argument
       
   821 @param	a2 an arbitrary argument
       
   822 @return	KErrNone if successful
       
   823 */
       
   824 TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
   825 	{
       
   826 	__e32_memory_barrier(); // Ensure changes from other clients are picked up
       
   827 
       
   828 	TInt r=KErrNone;
       
   829 	switch(aFunction)
       
   830 		{
       
   831 		case EDisplayHalScreenInfo:
       
   832 			{
       
   833 			TPckgBuf<TScreenInfoV01> vPckg;
       
   834 			ScreenInfo(vPckg());
       
   835 			Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
   836 			break;
       
   837 			}
       
   838 
       
   839 		case EDisplayHalWsRegisterSwitchOnScreenHandling:
       
   840 			iWsSwitchOnScreen=(TBool)a1;
       
   841 			break;
       
   842 		
       
   843 		case EDisplayHalWsSwitchOnScreen:
       
   844 			WsSwitchOnScreen();
       
   845 			break;
       
   846 
       
   847 		case EDisplayHalMaxDisplayContrast:
       
   848 			{
       
   849 			TInt mc=KConfigLcdMaxDisplayContrast;
       
   850 			kumemput32(a1,&mc,sizeof(mc));
       
   851 			break;
       
   852 			}
       
   853 		case EDisplayHalSetDisplayContrast:
       
   854 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
       
   855 				return KErrPermissionDenied;
       
   856 			r=SetContrast(TInt(a1));
       
   857 			break;
       
   858 		
       
   859 		case EDisplayHalDisplayContrast:
       
   860 			kumemput32(a1,&iContrast,sizeof(iContrast));
       
   861 			break;
       
   862 
       
   863 		case EDisplayHalMaxDisplayBrightness:
       
   864 			{
       
   865 			TInt mc=KConfigLcdMaxDisplayBrightness;
       
   866 			kumemput32(a1,&mc,sizeof(mc));
       
   867 			break;
       
   868 			}
       
   869 		
       
   870 		case EDisplayHalSetDisplayBrightness:
       
   871 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
       
   872 				return KErrPermissionDenied;
       
   873 			r=SetBrightness(TInt(a1));
       
   874 			break;
       
   875 		
       
   876 		case EDisplayHalDisplayBrightness:
       
   877 			kumemput32(a1,&iBrightness,sizeof(iBrightness));
       
   878 			break;
       
   879 		
       
   880 		case EDisplayHalSetBacklightOn:
       
   881 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
       
   882 				return KErrPermissionDenied;
       
   883 			if (Kern::MachinePowerStatus()<ELow)
       
   884 				r=KErrBadPower;
       
   885 			else
       
   886 				SetBacklightState(TBool(a1));
       
   887 			break;
       
   888 		
       
   889 		case EDisplayHalBacklightOn:
       
   890 			kumemput32(a1,&iBacklightOn,sizeof(TInt));
       
   891 			break;
       
   892 
       
   893 		case EDisplayHalModeCount:
       
   894 			{
       
   895 			TInt ndm = KConfigLcdNumberOfDisplayModes;
       
   896 			kumemput32(a1, &ndm, sizeof(ndm));
       
   897 			break;
       
   898 			}
       
   899 		
       
   900 		case EDisplayHalSetMode:
       
   901 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
       
   902 				return KErrPermissionDenied;
       
   903 			r = SetDisplayMode((TInt)a1);
       
   904 			break;
       
   905 		
       
   906 		case EDisplayHalMode:
       
   907 			kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
       
   908 			break;
       
   909 
       
   910 		case EDisplayHalSetPaletteEntry:
       
   911 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
       
   912 				return KErrPermissionDenied;
       
   913 			r = SetPaletteEntry((TInt)a1, (TInt)a2);
       
   914 			break;
       
   915 		
       
   916 		case EDisplayHalPaletteEntry:
       
   917 			{
       
   918 			TInt entry;
       
   919 			kumemget32(&entry, a1, sizeof(TInt));
       
   920 			TInt x;
       
   921 			r = GetPaletteEntry(entry, &x);
       
   922 			if (r == KErrNone)
       
   923 				kumemput32(a2, &x, sizeof(x));
       
   924 			break;
       
   925 			}
       
   926 		
       
   927 		case EDisplayHalSetState:
       
   928 			{
       
   929 			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
       
   930 				return KErrPermissionDenied;
       
   931 			if ((TBool)a1)
       
   932 				{
       
   933 				WsSwitchOnScreen();
       
   934 				}
       
   935 			else
       
   936 				{
       
   937 				WsSwitchOffScreen();
       
   938 				}
       
   939 			break;
       
   940 			}
       
   941 
       
   942 		case EDisplayHalState:
       
   943 			kumemput32(a1, &iDisplayOn, sizeof(TBool));
       
   944 			break;
       
   945 
       
   946 		case EDisplayHalColors:
       
   947 			{
       
   948 			TInt mdc = KConfigLcdMaxDisplayColors;
       
   949 			kumemput32(a1, &mdc, sizeof(mdc));
       
   950 			break;
       
   951 			}
       
   952 
       
   953 		case EDisplayHalCurrentModeInfo:
       
   954 			{
       
   955 			TPckgBuf<TVideoInfoV01> vPckg;
       
   956 			r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
       
   957 			if (KErrNone == r)
       
   958 				Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
   959 			}
       
   960 			break;
       
   961 
       
   962 		case EDisplayHalSpecifiedModeInfo:
       
   963 			{
       
   964 			TPckgBuf<TVideoInfoV01> vPckg;
       
   965 			TInt mode;
       
   966 			kumemget32(&mode, a1, sizeof(mode));
       
   967 			r = GetSpecifiedDisplayModeInfo(mode, vPckg());
       
   968 			if (KErrNone == r)
       
   969 				Kern::InfoCopy(*(TDes8*)a2,vPckg);
       
   970 			}
       
   971 			break;
       
   972 			
       
   973 		case EDisplayHalSecure:
       
   974 			kumemput32(a1, &iSecureDisplay, sizeof(TBool));
       
   975 			break;
       
   976 
       
   977 		case EDisplayHalSetSecure:
       
   978 			{
       
   979 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
       
   980 				return KErrPermissionDenied;
       
   981 			SwitchDisplay((TBool)a1);
       
   982 			}
       
   983 			break;
       
   984 
       
   985 		default:
       
   986 			r=KErrNotSupported;
       
   987 			break;
       
   988 		}
       
   989 
       
   990 	__e32_memory_barrier(); // Ensure any changes are propagated to other clients
       
   991 
       
   992 	return r;
       
   993 	}
       
   994 
       
   995 
       
   996 DECLARE_STANDARD_EXTENSION()
       
   997 	{
       
   998 	__KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
       
   999 
       
  1000 	// create LCD power handler
       
  1001 	TInt r=KErrNoMemory;
       
  1002 	DLcdPowerHandler* pH=new DLcdPowerHandler;
       
  1003 	if (pH)
       
  1004 		r=pH->Create();
       
  1005 
       
  1006 	__KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
       
  1007 	return r;
       
  1008 	}
       
  1009