|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * ne1_tb\specific\keyboard.cpp |
|
16 * Access to NE1_TBVariant polled keyboard |
|
17 * The code here implements a simple polled keyboard driver. |
|
18 * This is an alternative to the interrupt-driven driver in keyboard_interrupt.cpp. |
|
19 * This example assumes that we have a non-intelligent keyboard |
|
20 * consisting of a number of i/o lines arranged in a grid. |
|
21 * You can use this code as a starting point and modify it to suit |
|
22 * your hardware. |
|
23 * |
|
24 */ |
|
25 |
|
26 |
|
27 |
|
28 #include <naviengine.h> |
|
29 #include "platform.h" |
|
30 #include <kernel/kpower.h> |
|
31 #include <e32keys.h> |
|
32 |
|
33 |
|
34 |
|
35 // The TKeyboardState class is used to encapsulate the state of |
|
36 // the keyboard. i.e which keys are currently being pressed. |
|
37 // To determine which keys are being pressed, typically a voltage |
|
38 // is applied to each row in turn (or column, depending on the hardware) |
|
39 // and the output is read resulting in a bitmask for each row. |
|
40 // |
|
41 // For example, the keys could be arranged as follows (where a '1' indicates |
|
42 // that a key is currently being pressed : |
|
43 // EXAMPLE ONLY |
|
44 // |
|
45 // Translated |
|
46 // Column# 0 1 2 3 4 5 6 7 8 9 A B C D E F KeyCode |
|
47 // Row# |
|
48 // 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 to 6F |
|
49 // 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 to 5F |
|
50 // 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 to 4F |
|
51 // 3 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 30 to 3F |
|
52 // Input-> 2 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 20 to 2F |
|
53 // 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 to 1F |
|
54 // 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 to 0F |
|
55 // |
|
56 // output-> 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 |
|
57 // |
|
58 // TO DO: (mandadory) |
|
59 // Modify TKeyboardState (or provide an alternative) to model the |
|
60 // real keyboard state |
|
61 // |
|
62 // EXAMPLE ONLY |
|
63 class TKeyboardState |
|
64 { |
|
65 public: |
|
66 |
|
67 enum TDimensions |
|
68 { |
|
69 KRows = 7, |
|
70 KColumns = 16 |
|
71 }; |
|
72 |
|
73 public: |
|
74 TKeyboardState(); |
|
75 void Clear(); |
|
76 TBool IsKeyReady(); |
|
77 TUint32 GetKeyCode(); |
|
78 TKeyboardState operator&(const TKeyboardState& aState); |
|
79 TKeyboardState operator|(const TKeyboardState& aState); |
|
80 TKeyboardState operator~(); |
|
81 |
|
82 public: |
|
83 TUint32 iKeyBitMask[KRows]; |
|
84 }; |
|
85 |
|
86 /** |
|
87 Constructor |
|
88 */ |
|
89 TKeyboardState::TKeyboardState() |
|
90 { |
|
91 Clear(); |
|
92 } |
|
93 |
|
94 /** |
|
95 Clears the array of bitmasks |
|
96 */ |
|
97 void TKeyboardState::Clear() |
|
98 { |
|
99 for (TInt row=0; row<KRows; row++) |
|
100 iKeyBitMask[row] = 0; |
|
101 } |
|
102 |
|
103 /** |
|
104 Determines whether any keys are being pressed by examining the |
|
105 array of bitmasks to determine whether any bits are set |
|
106 |
|
107 @return ETrue if one or more keys are being pressed |
|
108 */ |
|
109 TBool TKeyboardState::IsKeyReady() |
|
110 { |
|
111 for (TInt row=0; row<KRows; row++) |
|
112 { |
|
113 if (iKeyBitMask[row] != 0) |
|
114 return ETrue; |
|
115 } |
|
116 |
|
117 return EFalse; |
|
118 } |
|
119 |
|
120 /** |
|
121 Scans the array of bitmasks and returns a keycode representing |
|
122 the first bit that it finds that is on. |
|
123 E.g. : |
|
124 if the first bit on the first row is set, then 1 is returned, |
|
125 if the third bit on the first row is set, then 3 is returned. etc. |
|
126 |
|
127 Once a bit is found it is cleared to avoid reading it again. |
|
128 |
|
129 NB Before calling this function, IsKeyReady() should be called |
|
130 to determine whether a key code is available. |
|
131 |
|
132 @return a 32-bit keycode representing a key that is currently pressed |
|
133 */ |
|
134 |
|
135 TUint32 TKeyboardState::GetKeyCode() |
|
136 { |
|
137 TInt keyNum = 0; |
|
138 for (TInt row=0; row<KRows; row++) |
|
139 { |
|
140 TUint32 bitMask = 1; |
|
141 for (TInt col=0; col<KColumns; col++) |
|
142 { |
|
143 if (iKeyBitMask[row] & bitMask) |
|
144 { |
|
145 iKeyBitMask[row] &= ~bitMask; |
|
146 return keyNum; |
|
147 } |
|
148 bitMask<<= 1; |
|
149 keyNum++; |
|
150 } |
|
151 } |
|
152 return 0; |
|
153 } |
|
154 |
|
155 /** |
|
156 Perform a bitwise AND between two TKeyboardState objects |
|
157 by AND-ing together all the 32-bit integers |
|
158 |
|
159 @return a new instance of a TKeyboardState object containing the result |
|
160 */ |
|
161 TKeyboardState TKeyboardState::operator&(const TKeyboardState& aState) |
|
162 { |
|
163 TKeyboardState state = *this; |
|
164 |
|
165 for (TInt row=0; row<KRows; row++) |
|
166 state.iKeyBitMask[row]&= aState.iKeyBitMask[row];; |
|
167 |
|
168 return state; |
|
169 } |
|
170 |
|
171 /** |
|
172 Perform a bitwise OR between two TKeyboardState objects |
|
173 by OR-ing together all the 32-bit integers |
|
174 |
|
175 @return a new instance of a TKeyboardState object containing the result |
|
176 */ |
|
177 TKeyboardState TKeyboardState::operator|(const TKeyboardState& aState) |
|
178 { |
|
179 TKeyboardState state = *this; |
|
180 |
|
181 for (TInt row=0; row<KRows; row++) |
|
182 state.iKeyBitMask[row]|= aState.iKeyBitMask[row];; |
|
183 |
|
184 return state; |
|
185 } |
|
186 |
|
187 /** |
|
188 Perform a bitwise NOT (one's complement) of a KeyboardState object |
|
189 by NOT-ing all the 32-bit integers |
|
190 |
|
191 @return a new instance of a TKeyboardState object containing the result |
|
192 */ |
|
193 TKeyboardState TKeyboardState::operator~() |
|
194 { |
|
195 TKeyboardState state = *this; |
|
196 |
|
197 for (TInt row=0; row<KRows; row++) |
|
198 state.iKeyBitMask[row] = ~state.iKeyBitMask[row]; |
|
199 |
|
200 return state; |
|
201 } |
|
202 |
|
203 // |
|
204 // |
|
205 // TO DO: (optional) |
|
206 // |
|
207 // Modify this conversion table to suit your keyboard layout |
|
208 // EXAMPLE ONLY |
|
209 // |
|
210 |
|
211 const TUint8 convertCode[] = |
|
212 { |
|
213 //Row 0 (bottom row) |
|
214 EStdKeyLeftAlt , EStdKeyHash , EStdKeyNull , EStdKeyLeftCtrl , |
|
215 EStdKeyLeftFunc , EStdKeyEscape , '1' , '2' , |
|
216 '9' , '0' , EStdKeyMinus , EStdKeyEquals , |
|
217 EStdKeyNull , EStdKeyBackspace , EStdKeyNull , EStdKeyNull , |
|
218 //Row 1 |
|
219 EStdKeyNull , EStdKeyBackSlash , EStdKeyLeftShift , EStdKeyNull , |
|
220 EStdKeyNull , EStdKeyDelete , EStdKeyNull , 'T' , |
|
221 'Y' , 'U' , 'I' , EStdKeyEnter , |
|
222 EStdKeyRightShift , EStdKeyDownArrow , EStdKeyNull , EStdKeyNull , |
|
223 //Row 2 |
|
224 EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull , |
|
225 EStdKeyNull , 'Q' , 'W' , 'E' , |
|
226 'R' , 'O' , 'P' , EStdKeySquareBracketLeft , |
|
227 EStdKeyNull , EStdKeySquareBracketRight,EStdKeyNull , EStdKeyNull , |
|
228 //Row 3 |
|
229 EStdKeyNull , 'Z' , EStdKeyNull , EStdKeyNull , |
|
230 EStdKeyNull , EStdKeyCapsLock , EStdKeyNull , EStdKeyNull , |
|
231 'K' , 'L' , EStdKeySemiColon , EStdKeySingleQuote , |
|
232 EStdKeyNull , EStdKeyUpArrow , EStdKeyNull , EStdKeyNull , |
|
233 //Row 4 |
|
234 EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull, |
|
235 EStdKeyNull , 'Q' , 'W' , 'E' , |
|
236 'R' , 'O' , 'P' , EStdKeySquareBracketLeft , |
|
237 EStdKeyNull , EStdKeySquareBracketRight, EStdKeyNull , EStdKeyNull , |
|
238 //Row 5 |
|
239 EStdKeyNull , 'X' , EStdKeyNull , EStdKeyNull , |
|
240 EStdKeyNull , 'C' , 'V' , 'B' , |
|
241 'N' , 'M' , EStdKeyComma , EStdKeyFullStop , |
|
242 EStdKeyNull , EStdKeySpace , EStdKeyNull , EStdKeyNull , |
|
243 //Row 6 |
|
244 EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , |
|
245 EStdKeyNull , '3' , '4' , '5' , |
|
246 '6' , '7' , '8' , EStdKeyMenu , |
|
247 EStdKeyNull , EStdKeyRightArrow , EStdKeyNull , EStdKeyNull |
|
248 }; |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 // EXAMPLE ONLY |
|
254 const TKeyboard KConfigKeyboardType = EKeyboard_Full; |
|
255 const TInt KConfigKeyboardDeviceKeys = 0; |
|
256 const TInt KConfigKeyboardAppsKeys = 0; |
|
257 |
|
258 |
|
259 // |
|
260 // TO DO: (optional) |
|
261 // |
|
262 // Set the keyboard scan rate in milliseconds |
|
263 // |
|
264 |
|
265 // EXAMPLE ONLY |
|
266 const TInt KScanRate = 50; // poll every 1/20 of a second (i.e. every 50 milliseconds) |
|
267 |
|
268 |
|
269 _LIT(KLitKeyboard,"Keyboard"); |
|
270 |
|
271 |
|
272 // |
|
273 // TO DO: (optional) |
|
274 // |
|
275 // Add any private functions and data you require |
|
276 // |
|
277 NONSHARABLE_CLASS(DKeyboardNE1_TB) : public DPowerHandler |
|
278 { |
|
279 public: |
|
280 DKeyboardNE1_TB(); |
|
281 TInt Create(); |
|
282 |
|
283 // from DPowerHandler |
|
284 void PowerUp(); |
|
285 void PowerDown(TPowerState); |
|
286 |
|
287 private: |
|
288 static void HandleMessage(TAny* aPtr); |
|
289 void HandleMsg(TMessageBase* aMsg); |
|
290 |
|
291 static TInt HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2); |
|
292 TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); |
|
293 |
|
294 static void PowerUpDfcFn(TAny* aPtr); |
|
295 void PowerUpDfc(); |
|
296 |
|
297 static void PowerDownDfcFn(TAny* aPtr); |
|
298 void PowerDownDfc(); |
|
299 |
|
300 static void TimerCallback(TAny* aDriver); |
|
301 static void TimerDfcFn(TAny* aDriver); |
|
302 void Poll(); |
|
303 |
|
304 void KeyboardInfo(TKeyboardInfoV01& aInfo); |
|
305 |
|
306 void KeyboardOn(); |
|
307 void KeyboardOff(); |
|
308 void KeyboardPowerUp(); |
|
309 |
|
310 private: |
|
311 TDfcQue* iDfcQ; |
|
312 TMessageQue iMsgQ; |
|
313 TDfc iPowerUpDfc; |
|
314 TDfc iPowerDownDfc; |
|
315 TBool iKeyboardOn; |
|
316 NTimer iTimer; |
|
317 TInt iTimerTicks; |
|
318 TDfc iTimerDfc; |
|
319 |
|
320 // a bitmask indicating which keys were pressed down on the last timer tick |
|
321 TKeyboardState iKeyStateLast; |
|
322 |
|
323 // a bitmask indicating the set of keys for which we have sent an EKeyDown event |
|
324 TKeyboardState iKeysDown; |
|
325 }; |
|
326 |
|
327 /** |
|
328 constructor |
|
329 */ |
|
330 DKeyboardNE1_TB::DKeyboardNE1_TB() |
|
331 : DPowerHandler(KLitKeyboard), |
|
332 iMsgQ(HandleMessage, this, NULL, 1), |
|
333 iPowerUpDfc(PowerUpDfcFn, this, 6), |
|
334 iPowerDownDfc(PowerDownDfcFn, this, 7), |
|
335 iTimer(&DKeyboardNE1_TB::TimerCallback, (TAny*) this), |
|
336 iTimerDfc(TimerDfcFn, this, 1) |
|
337 { |
|
338 // Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second) |
|
339 iTimerTicks = NKern::TimerTicks(KScanRate); |
|
340 } |
|
341 |
|
342 /** |
|
343 Second-phase constructor |
|
344 Assigns queues for all the DFCs and starts the keyboard-polling timer |
|
345 |
|
346 Called by factory function at ordinal 0 |
|
347 */ |
|
348 TInt DKeyboardNE1_TB::Create() |
|
349 { |
|
350 iDfcQ=Kern::DfcQue0(); |
|
351 |
|
352 iKeyboardOn = EFalse; |
|
353 |
|
354 // install the HAL function |
|
355 TInt r = Kern::AddHalEntry(EHalGroupKeyboard, DKeyboardNE1_TB::HalFunction, this); |
|
356 if (r != KErrNone) |
|
357 return r; |
|
358 |
|
359 iTimerDfc.SetDfcQ(iDfcQ); |
|
360 |
|
361 iPowerUpDfc.SetDfcQ(iDfcQ); |
|
362 iPowerDownDfc.SetDfcQ(iDfcQ); |
|
363 iMsgQ.SetDfcQ(iDfcQ); |
|
364 iMsgQ.Receive(); |
|
365 |
|
366 // install the power handler |
|
367 Add(); |
|
368 |
|
369 // Power up the device and start the timer |
|
370 KeyboardPowerUp(); |
|
371 |
|
372 return r; |
|
373 } |
|
374 |
|
375 /** |
|
376 Calback for the keyboard-polling timer |
|
377 Called in the context of an ISR |
|
378 |
|
379 @param aPtr A pointer to an instance of DKeyboardNE1_TB |
|
380 */ |
|
381 void DKeyboardNE1_TB::TimerCallback(TAny *aPtr) |
|
382 { |
|
383 // schedule a DFC |
|
384 DKeyboardNE1_TB& k=*(DKeyboardNE1_TB*)aPtr; |
|
385 k.iTimerDfc.Add(); |
|
386 } |
|
387 |
|
388 |
|
389 /** |
|
390 DFC scheduled by the keyboard-polling timer when it expires |
|
391 |
|
392 @param aPtr A pointer to an instance of DKeyboardNE1_TB |
|
393 */ |
|
394 void DKeyboardNE1_TB::TimerDfcFn(TAny* aPtr) |
|
395 { |
|
396 ((DKeyboardNE1_TB*)aPtr)->Poll(); |
|
397 } |
|
398 |
|
399 |
|
400 /** |
|
401 Reads scan codes from the keyboard until there are none left |
|
402 Called from the keyboard-polling timer's DFC |
|
403 */ |
|
404 void DKeyboardNE1_TB::Poll() |
|
405 { |
|
406 __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardNE1_TB::EventDfc")); |
|
407 |
|
408 |
|
409 TKeyboardState keyState; |
|
410 |
|
411 // |
|
412 // TO DO: (mandatory) |
|
413 // Read new key state into the array of bitmasks in keyState |
|
414 // This typically involves applying a voltage to each row from 0 to KRows-1, |
|
415 // reading the output state of the i/o lines at every step |
|
416 // - this represents the keys that are pressed on each row - |
|
417 // and storing the output of each row as a bitmask into keyState.iKeyBitMask[n], |
|
418 // where n = the row being accessed |
|
419 // |
|
420 |
|
421 // To enable a simple de-bouncing algorithm, |
|
422 // work out which keys have been pressed down for at least two timer |
|
423 // ticks by AND-ing together the last bitmask with the current bitmask |
|
424 TKeyboardState keysStillDown = keyState & iKeyStateLast; |
|
425 |
|
426 |
|
427 // Similarly, work out which keys have been "un-pressed" for at least two timer |
|
428 // ticks by AND-ing together the one's complement of the last bitmask with the |
|
429 // one's complement of the current bitmask and |
|
430 // then AND-ing this with the set of keys for which we have sent an EKeyDown |
|
431 // event to give the set of keys for which we need to send an EKeyUp event |
|
432 TKeyboardState keysStillUp = (~keyState & ~iKeyStateLast) & iKeysDown; |
|
433 |
|
434 // save the current state for next time |
|
435 iKeyStateLast = keyState; |
|
436 |
|
437 // update the set of keys for which we have sent an EKeyDown event |
|
438 iKeysDown = iKeysDown | keysStillDown; |
|
439 iKeysDown = iKeysDown & ~keysStillUp; |
|
440 |
|
441 // process all the key-down events |
|
442 while (keysStillDown.IsKeyReady()) // while there are keys we haven't processed |
|
443 { |
|
444 TRawEvent e; |
|
445 TUint keyCode = keysStillDown.GetKeyCode(); // Read keycodes from bitmask |
|
446 |
|
447 __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyDown: #%02x\n",keyCode)); |
|
448 |
|
449 // |
|
450 // TO DO: (mandatory) |
|
451 // |
|
452 // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) |
|
453 // as per below EXAMPLE ONLY: |
|
454 // |
|
455 __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); |
|
456 TUint8 stdKey = convertCode[keyCode]; |
|
457 |
|
458 e.Set(TRawEvent::EKeyDown, stdKey, 0); |
|
459 Kern::AddEvent(e); |
|
460 } |
|
461 |
|
462 // process all the key-up events |
|
463 while (keysStillUp.IsKeyReady()) // while there are keys we haven't processed |
|
464 { |
|
465 TRawEvent e; |
|
466 TUint keyCode = keysStillUp.GetKeyCode(); // Read keycodes from bitmask |
|
467 |
|
468 __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyUp: #%02x\n",keyCode)); |
|
469 |
|
470 // |
|
471 // TO DO: (mandatory) |
|
472 // |
|
473 // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) |
|
474 // as per below EXAMPLE ONLY: |
|
475 // |
|
476 __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); |
|
477 TUint8 stdKey = convertCode[keyCode]; |
|
478 |
|
479 e.Set(TRawEvent::EKeyUp, stdKey, 0); |
|
480 Kern::AddEvent(e); |
|
481 } |
|
482 |
|
483 // start the timer again |
|
484 iTimer.OneShot(iTimerTicks); |
|
485 } |
|
486 |
|
487 |
|
488 |
|
489 /** |
|
490 Notifies the peripheral of system power up. |
|
491 Called by the power manager during a transition from standby. |
|
492 Schedules a DFC to handle the power up. |
|
493 */ |
|
494 void DKeyboardNE1_TB::PowerUp() |
|
495 { |
|
496 iPowerUpDfc.Enque(); |
|
497 } |
|
498 |
|
499 |
|
500 /** |
|
501 static DFC to handle powering up the keyboard |
|
502 |
|
503 @param aPtr A pointer to an instance of DKeyboardNE1_TB |
|
504 */ |
|
505 void DKeyboardNE1_TB::PowerUpDfcFn(TAny* aPtr) |
|
506 { |
|
507 ((DKeyboardNE1_TB*)aPtr)->PowerUpDfc(); |
|
508 } |
|
509 |
|
510 |
|
511 /** |
|
512 DFC to handle powering up the keyboard |
|
513 */ |
|
514 void DKeyboardNE1_TB::PowerUpDfc() |
|
515 { |
|
516 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerUpDfc()")); |
|
517 KeyboardOn(); |
|
518 |
|
519 // Indicate to power handle that powered up is complete |
|
520 PowerUpDone(); |
|
521 } |
|
522 |
|
523 /** |
|
524 Powers up the keyboard |
|
525 May be called as a result of a power transition or from the HAL |
|
526 */ |
|
527 void DKeyboardNE1_TB::KeyboardOn() |
|
528 { |
|
529 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOn() iKeyboardOn=%d", iKeyboardOn)); |
|
530 |
|
531 if (!iKeyboardOn) // make sure we don't initialize more than once |
|
532 KeyboardPowerUp(); |
|
533 } |
|
534 |
|
535 /** |
|
536 Powers up the keyboard |
|
537 Assumes that the keyboard is currently powered off |
|
538 */ |
|
539 void DKeyboardNE1_TB::KeyboardPowerUp() |
|
540 { |
|
541 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardPowerUp()")); |
|
542 |
|
543 iKeyboardOn = ETrue; |
|
544 |
|
545 iKeyStateLast.Clear(); |
|
546 iKeysDown.Clear(); |
|
547 |
|
548 // Send key up events for EStdKeyOff (Fn+Esc) event |
|
549 TRawEvent e; |
|
550 e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0); |
|
551 Kern::AddEvent(e); |
|
552 e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); |
|
553 Kern::AddEvent(e); |
|
554 |
|
555 // Start the periodic tick for the selected rate. |
|
556 // This will call TimerCallback() in the context of an ISR |
|
557 iTimer.OneShot(iTimerTicks); |
|
558 } |
|
559 |
|
560 |
|
561 /** |
|
562 Requests keyboard to power down. |
|
563 Called by the power manager during a transition to standby or power off |
|
564 Schedules a DFC to handle the power up. |
|
565 |
|
566 @param aPowerState the current power state |
|
567 */ |
|
568 void DKeyboardNE1_TB::PowerDown(TPowerState) |
|
569 { |
|
570 iPowerDownDfc.Enque(); |
|
571 } |
|
572 |
|
573 /** |
|
574 static DFC to handle powering down the keyboard |
|
575 |
|
576 @param aPtr A pointer to an instance of DKeyboardNE1_TB |
|
577 */ |
|
578 void DKeyboardNE1_TB::PowerDownDfcFn(TAny* aPtr) |
|
579 { |
|
580 ((DKeyboardNE1_TB*)aPtr)->PowerDownDfc(); |
|
581 } |
|
582 |
|
583 /** |
|
584 DFC to handle powering down the keyboard |
|
585 */ |
|
586 void DKeyboardNE1_TB::PowerDownDfc() |
|
587 { |
|
588 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerDownDfc()")); |
|
589 KeyboardOff(); |
|
590 PowerDownDone(); |
|
591 } |
|
592 |
|
593 /** |
|
594 Powers down the keyboard |
|
595 May be called as a result of a power transition or from the HAL |
|
596 */ |
|
597 void DKeyboardNE1_TB::KeyboardOff() |
|
598 { |
|
599 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOff() iKeyboardOn=%d", iKeyboardOn)); |
|
600 |
|
601 // cancel the keyboard-polling timer |
|
602 iTimerDfc.Cancel(); |
|
603 iTimer.Cancel(); |
|
604 |
|
605 iKeyboardOn = EFalse; |
|
606 } |
|
607 |
|
608 |
|
609 /** |
|
610 static message handler for processing power up/down messages |
|
611 posted internally from HalFunction() |
|
612 |
|
613 @param aPtr A pointer to an instance of DKeyboardNE1_TB |
|
614 */ |
|
615 void DKeyboardNE1_TB::HandleMessage(TAny* aPtr) |
|
616 { |
|
617 DKeyboardNE1_TB& h=*(DKeyboardNE1_TB*)aPtr; |
|
618 TMessageBase* pM=h.iMsgQ.iMessage; |
|
619 if (pM) |
|
620 h.HandleMsg(pM); |
|
621 } |
|
622 |
|
623 /** |
|
624 Message handler for processing power up/down messages |
|
625 posted internally from HalFunction() |
|
626 |
|
627 param aMsg A message indicating whether to power the keyboard on or off |
|
628 */ |
|
629 void DKeyboardNE1_TB::HandleMsg(TMessageBase* aMsg) |
|
630 { |
|
631 if (aMsg->iValue) |
|
632 KeyboardOn(); |
|
633 else |
|
634 KeyboardOff(); |
|
635 aMsg->Complete(KErrNone,ETrue); |
|
636 } |
|
637 |
|
638 |
|
639 /** |
|
640 Retrieves information about the keyboard |
|
641 Called from HalFunction() |
|
642 |
|
643 @param aInfo a caller-supplied class which on return contains information about the keyboard |
|
644 */ |
|
645 void DKeyboardNE1_TB::KeyboardInfo(TKeyboardInfoV01& aInfo) |
|
646 { |
|
647 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::KeyboardInfo")); |
|
648 aInfo.iKeyboardType=KConfigKeyboardType; |
|
649 aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys; |
|
650 aInfo.iAppsKeys=KConfigKeyboardAppsKeys; |
|
651 } |
|
652 |
|
653 |
|
654 /** |
|
655 HAL handler function |
|
656 |
|
657 @param aPtr a pointer to an instance of DLcdPowerHandler |
|
658 @param aFunction the function number |
|
659 @param a1 an arbitrary parameter |
|
660 @param a2 an arbitrary parameter |
|
661 */ |
|
662 TInt DKeyboardNE1_TB::HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) |
|
663 { |
|
664 DKeyboardNE1_TB* pH=(DKeyboardNE1_TB*)aPtr; |
|
665 return pH->HalFunction(aFunction,a1,a2); |
|
666 } |
|
667 |
|
668 |
|
669 /** |
|
670 a HAL entry handling function for HAL group attribute EHalGroupKeyboard |
|
671 |
|
672 @param a1 an arbitrary argument |
|
673 @param a2 an arbitrary argument |
|
674 @return KErrNone if successful |
|
675 */ |
|
676 TInt DKeyboardNE1_TB::HalFunction(TInt aFunction, TAny* a1, TAny* a2) |
|
677 { |
|
678 TInt r=KErrNone; |
|
679 |
|
680 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::HalFunction %d", aFunction)); |
|
681 |
|
682 switch(aFunction) |
|
683 { |
|
684 case EKeyboardHalKeyboardInfo: |
|
685 { |
|
686 TPckgBuf<TKeyboardInfoV01> kPckg; |
|
687 KeyboardInfo(kPckg()); |
|
688 Kern::InfoCopy(*(TDes8*)a1,kPckg); |
|
689 break; |
|
690 } |
|
691 |
|
692 case EKeyboardHalSetKeyboardState: |
|
693 { |
|
694 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState"))) |
|
695 return KErrPermissionDenied; |
|
696 if ((TBool)a1) |
|
697 { |
|
698 TThreadMessage& m=Kern::Message(); |
|
699 m.iValue = ETrue; |
|
700 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up |
|
701 } |
|
702 else |
|
703 { |
|
704 TThreadMessage& m=Kern::Message(); |
|
705 m.iValue = EFalse; |
|
706 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down |
|
707 } |
|
708 } |
|
709 break; |
|
710 |
|
711 case EKeyboardHalKeyboardState: |
|
712 kumemput32(a1, &iKeyboardOn, sizeof(TBool)); |
|
713 break; |
|
714 |
|
715 default: |
|
716 r=KErrNotSupported; |
|
717 break; |
|
718 } |
|
719 return r; |
|
720 } |
|
721 |
|
722 |
|
723 |
|
724 DECLARE_STANDARD_EXTENSION() |
|
725 { |
|
726 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); |
|
727 |
|
728 // create keyboard driver |
|
729 TInt r=KErrNoMemory; |
|
730 DKeyboardNE1_TB* pK=new DKeyboardNE1_TB; |
|
731 if (pK) |
|
732 r=pK->Create(); |
|
733 |
|
734 __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); |
|
735 return r; |
|
736 } |