|
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 |