1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,733 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// template\template_variant\specific\keyboard.cpp
1.18 +// Access to Template polled keyboard
1.19 +// The code here implements a simple polled keyboard driver.
1.20 +// This is an alternative to the interrupt-driven driver in keyboard_interrupt.cpp.
1.21 +// This example assumes that we have a non-intelligent keyboard
1.22 +// consisting of a number of i/o lines arranged in a grid.
1.23 +// You can use this code as a starting point and modify it to suit
1.24 +// your hardware.
1.25 +//
1.26 +//
1.27 +
1.28 +#include <template_assp.h>
1.29 +#include "platform.h"
1.30 +#include <kernel/kpower.h>
1.31 +#include <e32keys.h>
1.32 +
1.33 +
1.34 +
1.35 +// The TKeyboardState class is used to encapsulate the state of
1.36 +// the keyboard. i.e which keys are currently being pressed.
1.37 +// To determine which keys are being pressed, typically a voltage
1.38 +// is applied to each row in turn (or column, depending on the hardware)
1.39 +// and the output is read resulting in a bitmask for each row.
1.40 +//
1.41 +// For example, the keys could be arranged as follows (where a '1' indicates
1.42 +// that a key is currently being pressed :
1.43 +// EXAMPLE ONLY
1.44 +//
1.45 +// Translated
1.46 +// Column# 0 1 2 3 4 5 6 7 8 9 A B C D E F KeyCode
1.47 +// Row#
1.48 +// 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 to 6F
1.49 +// 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 to 5F
1.50 +// 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 to 4F
1.51 +// 3 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 30 to 3F
1.52 +// Input-> 2 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 20 to 2F
1.53 +// 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 to 1F
1.54 +// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 to 0F
1.55 +//
1.56 +// output-> 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
1.57 +//
1.58 +// TO DO: (mandadory)
1.59 +// Modify TKeyboardState (or provide an alternative) to model the
1.60 +// real keyboard state
1.61 +//
1.62 +// EXAMPLE ONLY
1.63 +class TKeyboardState
1.64 + {
1.65 +public:
1.66 +
1.67 + enum TDimensions
1.68 + {
1.69 + KRows = 7,
1.70 + KColumns = 16
1.71 + };
1.72 +
1.73 +public:
1.74 + TKeyboardState();
1.75 + void Clear();
1.76 + TBool IsKeyReady();
1.77 + TUint32 GetKeyCode();
1.78 + TKeyboardState operator&(const TKeyboardState& aState);
1.79 + TKeyboardState operator|(const TKeyboardState& aState);
1.80 + TKeyboardState operator~();
1.81 +
1.82 +public:
1.83 + TUint32 iKeyBitMask[KRows];
1.84 + };
1.85 +
1.86 +/**
1.87 +Constructor
1.88 +*/
1.89 +TKeyboardState::TKeyboardState()
1.90 + {
1.91 + Clear();
1.92 + }
1.93 +
1.94 +/**
1.95 +Clears the array of bitmasks
1.96 +*/
1.97 +void TKeyboardState::Clear()
1.98 + {
1.99 + for (TInt row=0; row<KRows; row++)
1.100 + iKeyBitMask[row] = 0;
1.101 + }
1.102 +
1.103 +/**
1.104 +Determines whether any keys are being pressed by examining the
1.105 +array of bitmasks to determine whether any bits are set
1.106 +
1.107 +@return ETrue if one or more keys are being pressed
1.108 +*/
1.109 +TBool TKeyboardState::IsKeyReady()
1.110 + {
1.111 + for (TInt row=0; row<KRows; row++)
1.112 + {
1.113 + if (iKeyBitMask[row] != 0)
1.114 + return ETrue;
1.115 + }
1.116 +
1.117 + return EFalse;
1.118 + }
1.119 +
1.120 +/**
1.121 +Scans the array of bitmasks and returns a keycode representing
1.122 +the first bit that it finds that is on.
1.123 +E.g. :
1.124 +if the first bit on the first row is set, then 1 is returned,
1.125 +if the third bit on the first row is set, then 3 is returned. etc.
1.126 +
1.127 +Once a bit is found it is cleared to avoid reading it again.
1.128 +
1.129 +NB Before calling this function, IsKeyReady() should be called
1.130 +to determine whether a key code is available.
1.131 +
1.132 +@return a 32-bit keycode representing a key that is currently pressed
1.133 +*/
1.134 +
1.135 +TUint32 TKeyboardState::GetKeyCode()
1.136 + {
1.137 + TInt keyNum = 0;
1.138 + for (TInt row=0; row<KRows; row++)
1.139 + {
1.140 + TUint32 bitMask = 1;
1.141 + for (TInt col=0; col<KColumns; col++)
1.142 + {
1.143 + if (iKeyBitMask[row] & bitMask)
1.144 + {
1.145 + iKeyBitMask[row] &= ~bitMask;
1.146 + return keyNum;
1.147 + }
1.148 + bitMask<<= 1;
1.149 + keyNum++;
1.150 + }
1.151 + }
1.152 + return 0;
1.153 + }
1.154 +
1.155 +/**
1.156 +Perform a bitwise AND between two TKeyboardState objects
1.157 +by AND-ing together all the 32-bit integers
1.158 +
1.159 +@return a new instance of a TKeyboardState object containing the result
1.160 +*/
1.161 +TKeyboardState TKeyboardState::operator&(const TKeyboardState& aState)
1.162 + {
1.163 + TKeyboardState state = *this;
1.164 +
1.165 + for (TInt row=0; row<KRows; row++)
1.166 + state.iKeyBitMask[row]&= aState.iKeyBitMask[row];;
1.167 +
1.168 + return state;
1.169 + }
1.170 +
1.171 +/**
1.172 +Perform a bitwise OR between two TKeyboardState objects
1.173 +by OR-ing together all the 32-bit integers
1.174 +
1.175 +@return a new instance of a TKeyboardState object containing the result
1.176 +*/
1.177 +TKeyboardState TKeyboardState::operator|(const TKeyboardState& aState)
1.178 + {
1.179 + TKeyboardState state = *this;
1.180 +
1.181 + for (TInt row=0; row<KRows; row++)
1.182 + state.iKeyBitMask[row]|= aState.iKeyBitMask[row];;
1.183 +
1.184 + return state;
1.185 + }
1.186 +
1.187 +/**
1.188 +Perform a bitwise NOT (one's complement) of a KeyboardState object
1.189 +by NOT-ing all the 32-bit integers
1.190 +
1.191 +@return a new instance of a TKeyboardState object containing the result
1.192 +*/
1.193 +TKeyboardState TKeyboardState::operator~()
1.194 + {
1.195 + TKeyboardState state = *this;
1.196 +
1.197 + for (TInt row=0; row<KRows; row++)
1.198 + state.iKeyBitMask[row] = ~state.iKeyBitMask[row];
1.199 +
1.200 + return state;
1.201 + }
1.202 +
1.203 +//
1.204 +//
1.205 +// TO DO: (optional)
1.206 +//
1.207 +// Modify this conversion table to suit your keyboard layout
1.208 +// EXAMPLE ONLY
1.209 +//
1.210 +
1.211 +const TUint8 convertCode[] =
1.212 + {
1.213 +//Row 0 (bottom row)
1.214 + EStdKeyLeftAlt , EStdKeyHash , EStdKeyNull , EStdKeyLeftCtrl ,
1.215 + EStdKeyLeftFunc , EStdKeyEscape , '1' , '2' ,
1.216 + '9' , '0' , EStdKeyMinus , EStdKeyEquals ,
1.217 + EStdKeyNull , EStdKeyBackspace , EStdKeyNull , EStdKeyNull ,
1.218 +//Row 1
1.219 + EStdKeyNull , EStdKeyBackSlash , EStdKeyLeftShift , EStdKeyNull ,
1.220 + EStdKeyNull , EStdKeyDelete , EStdKeyNull , 'T' ,
1.221 + 'Y' , 'U' , 'I' , EStdKeyEnter ,
1.222 + EStdKeyRightShift , EStdKeyDownArrow , EStdKeyNull , EStdKeyNull ,
1.223 +//Row 2
1.224 + EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull ,
1.225 + EStdKeyNull , 'Q' , 'W' , 'E' ,
1.226 + 'R' , 'O' , 'P' , EStdKeySquareBracketLeft ,
1.227 + EStdKeyNull , EStdKeySquareBracketRight,EStdKeyNull , EStdKeyNull ,
1.228 +//Row 3
1.229 + EStdKeyNull , 'Z' , EStdKeyNull , EStdKeyNull ,
1.230 + EStdKeyNull , EStdKeyCapsLock , EStdKeyNull , EStdKeyNull ,
1.231 + 'K' , 'L' , EStdKeySemiColon , EStdKeySingleQuote ,
1.232 + EStdKeyNull , EStdKeyUpArrow , EStdKeyNull , EStdKeyNull ,
1.233 +//Row 4
1.234 + EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull,
1.235 + EStdKeyNull , 'Q' , 'W' , 'E' ,
1.236 + 'R' , 'O' , 'P' , EStdKeySquareBracketLeft ,
1.237 + EStdKeyNull , EStdKeySquareBracketRight, EStdKeyNull , EStdKeyNull ,
1.238 +//Row 5
1.239 + EStdKeyNull , 'X' , EStdKeyNull , EStdKeyNull ,
1.240 + EStdKeyNull , 'C' , 'V' , 'B' ,
1.241 + 'N' , 'M' , EStdKeyComma , EStdKeyFullStop ,
1.242 + EStdKeyNull , EStdKeySpace , EStdKeyNull , EStdKeyNull ,
1.243 +//Row 6
1.244 + EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,
1.245 + EStdKeyNull , '3' , '4' , '5' ,
1.246 + '6' , '7' , '8' , EStdKeyMenu ,
1.247 + EStdKeyNull , EStdKeyRightArrow , EStdKeyNull , EStdKeyNull
1.248 + };
1.249 +
1.250 +
1.251 +
1.252 +
1.253 +// EXAMPLE ONLY
1.254 +const TKeyboard KConfigKeyboardType = EKeyboard_Full;
1.255 +const TInt KConfigKeyboardDeviceKeys = 0;
1.256 +const TInt KConfigKeyboardAppsKeys = 0;
1.257 +
1.258 +
1.259 +//
1.260 +// TO DO: (optional)
1.261 +//
1.262 +// Set the keyboard scan rate in milliseconds
1.263 +//
1.264 +
1.265 +// EXAMPLE ONLY
1.266 +const TInt KScanRate = 50; // poll every 1/20 of a second (i.e. every 50 milliseconds)
1.267 +
1.268 +
1.269 +_LIT(KLitKeyboard,"Keyboard");
1.270 +
1.271 +
1.272 +//
1.273 +// TO DO: (optional)
1.274 +//
1.275 +// Add any private functions and data you require
1.276 +//
1.277 +NONSHARABLE_CLASS(DKeyboardTemplate) : public DPowerHandler
1.278 + {
1.279 +public:
1.280 + DKeyboardTemplate();
1.281 + TInt Create();
1.282 +
1.283 + // from DPowerHandler
1.284 + void PowerUp();
1.285 + void PowerDown(TPowerState);
1.286 +
1.287 +private:
1.288 + static void HandleMessage(TAny* aPtr);
1.289 + void HandleMsg(TMessageBase* aMsg);
1.290 +
1.291 + static TInt HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2);
1.292 + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
1.293 +
1.294 + static void PowerUpDfcFn(TAny* aPtr);
1.295 + void PowerUpDfc();
1.296 +
1.297 + static void PowerDownDfcFn(TAny* aPtr);
1.298 + void PowerDownDfc();
1.299 +
1.300 + static void TimerCallback(TAny* aDriver);
1.301 + static void TimerDfcFn(TAny* aDriver);
1.302 + void Poll();
1.303 +
1.304 + void KeyboardInfo(TKeyboardInfoV01& aInfo);
1.305 +
1.306 + void KeyboardOn();
1.307 + void KeyboardOff();
1.308 + void KeyboardPowerUp();
1.309 +
1.310 +private:
1.311 + TDfcQue* iDfcQ;
1.312 + TMessageQue iMsgQ;
1.313 + TDfc iPowerUpDfc;
1.314 + TDfc iPowerDownDfc;
1.315 + TBool iKeyboardOn;
1.316 + NTimer iTimer;
1.317 + TInt iTimerTicks;
1.318 + TDfc iTimerDfc;
1.319 +
1.320 + // a bitmask indicating which keys were pressed down on the last timer tick
1.321 + TKeyboardState iKeyStateLast;
1.322 +
1.323 + // a bitmask indicating the set of keys for which we have sent an EKeyDown event
1.324 + TKeyboardState iKeysDown;
1.325 + };
1.326 +
1.327 +/**
1.328 +constructor
1.329 +*/
1.330 +DKeyboardTemplate::DKeyboardTemplate()
1.331 + : DPowerHandler(KLitKeyboard),
1.332 + iMsgQ(HandleMessage, this, NULL, 1),
1.333 + iPowerUpDfc(PowerUpDfcFn, this, 6),
1.334 + iPowerDownDfc(PowerDownDfcFn, this, 7),
1.335 + iTimer(&DKeyboardTemplate::TimerCallback, (TAny*) this),
1.336 + iTimerDfc(TimerDfcFn, this, 1)
1.337 + {
1.338 + // Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second)
1.339 + iTimerTicks = NKern::TimerTicks(KScanRate);
1.340 + }
1.341 +
1.342 +/**
1.343 +Second-phase constructor
1.344 +Assigns queues for all the DFCs and starts the keyboard-polling timer
1.345 +
1.346 +Called by factory function at ordinal 0
1.347 +*/
1.348 +TInt DKeyboardTemplate::Create()
1.349 + {
1.350 + iDfcQ=Kern::DfcQue0();
1.351 +
1.352 + iKeyboardOn = EFalse;
1.353 +
1.354 + // install the HAL function
1.355 + TInt r = Kern::AddHalEntry(EHalGroupKeyboard, DKeyboardTemplate::HalFunction, this);
1.356 + if (r != KErrNone)
1.357 + return r;
1.358 +
1.359 + iTimerDfc.SetDfcQ(iDfcQ);
1.360 +
1.361 + iPowerUpDfc.SetDfcQ(iDfcQ);
1.362 + iPowerDownDfc.SetDfcQ(iDfcQ);
1.363 + iMsgQ.SetDfcQ(iDfcQ);
1.364 + iMsgQ.Receive();
1.365 +
1.366 + // install the power handler
1.367 + Add();
1.368 +
1.369 + // Power up the device and start the timer
1.370 + KeyboardPowerUp();
1.371 +
1.372 + return r;
1.373 + }
1.374 +
1.375 +/**
1.376 +Calback for the keyboard-polling timer
1.377 +Called in the context of an ISR
1.378 +
1.379 +@param aPtr A pointer to an instance of DKeyboardTemplate
1.380 +*/
1.381 +void DKeyboardTemplate::TimerCallback(TAny *aPtr)
1.382 + {
1.383 + // schedule a DFC
1.384 + DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr;
1.385 + k.iTimerDfc.Add();
1.386 + }
1.387 +
1.388 +
1.389 +/**
1.390 +DFC scheduled by the keyboard-polling timer when it expires
1.391 +
1.392 +@param aPtr A pointer to an instance of DKeyboardTemplate
1.393 +*/
1.394 +void DKeyboardTemplate::TimerDfcFn(TAny* aPtr)
1.395 + {
1.396 + ((DKeyboardTemplate*)aPtr)->Poll();
1.397 + }
1.398 +
1.399 +
1.400 +/**
1.401 +Reads scan codes from the keyboard until there are none left
1.402 +Called from the keyboard-polling timer's DFC
1.403 +*/
1.404 +void DKeyboardTemplate::Poll()
1.405 + {
1.406 + __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc"));
1.407 +
1.408 +
1.409 + TKeyboardState keyState;
1.410 +
1.411 + //
1.412 + // TO DO: (mandatory)
1.413 + // Read new key state into the array of bitmasks in keyState
1.414 + // This typically involves applying a voltage to each row from 0 to KRows-1,
1.415 + // reading the output state of the i/o lines at every step
1.416 + // - this represents the keys that are pressed on each row -
1.417 + // and storing the output of each row as a bitmask into keyState.iKeyBitMask[n],
1.418 + // where n = the row being accessed
1.419 + //
1.420 +
1.421 + // To enable a simple de-bouncing algorithm,
1.422 + // work out which keys have been pressed down for at least two timer
1.423 + // ticks by AND-ing together the last bitmask with the current bitmask
1.424 + TKeyboardState keysStillDown = keyState & iKeyStateLast;
1.425 +
1.426 +
1.427 + // Similarly, work out which keys have been "un-pressed" for at least two timer
1.428 + // ticks by AND-ing together the one's complement of the last bitmask with the
1.429 + // one's complement of the current bitmask and
1.430 + // then AND-ing this with the set of keys for which we have sent an EKeyDown
1.431 + // event to give the set of keys for which we need to send an EKeyUp event
1.432 + TKeyboardState keysStillUp = (~keyState & ~iKeyStateLast) & iKeysDown;
1.433 +
1.434 + // save the current state for next time
1.435 + iKeyStateLast = keyState;
1.436 +
1.437 + // update the set of keys for which we have sent an EKeyDown event
1.438 + iKeysDown = iKeysDown | keysStillDown;
1.439 + iKeysDown = iKeysDown & ~keysStillUp;
1.440 +
1.441 + // process all the key-down events
1.442 + while (keysStillDown.IsKeyReady()) // while there are keys we haven't processed
1.443 + {
1.444 + TRawEvent e;
1.445 + TUint keyCode = keysStillDown.GetKeyCode(); // Read keycodes from bitmask
1.446 +
1.447 + __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyDown: #%02x\n",keyCode));
1.448 +
1.449 + //
1.450 + // TO DO: (mandatory)
1.451 + //
1.452 + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released)
1.453 + // as per below EXAMPLE ONLY:
1.454 + //
1.455 + __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__));
1.456 + TUint8 stdKey = convertCode[keyCode];
1.457 +
1.458 + e.Set(TRawEvent::EKeyDown, stdKey, 0);
1.459 + Kern::AddEvent(e);
1.460 + }
1.461 +
1.462 + // process all the key-up events
1.463 + while (keysStillUp.IsKeyReady()) // while there are keys we haven't processed
1.464 + {
1.465 + TRawEvent e;
1.466 + TUint keyCode = keysStillUp.GetKeyCode(); // Read keycodes from bitmask
1.467 +
1.468 + __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyUp: #%02x\n",keyCode));
1.469 +
1.470 + //
1.471 + // TO DO: (mandatory)
1.472 + //
1.473 + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released)
1.474 + // as per below EXAMPLE ONLY:
1.475 + //
1.476 + __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__));
1.477 + TUint8 stdKey = convertCode[keyCode];
1.478 +
1.479 + e.Set(TRawEvent::EKeyUp, stdKey, 0);
1.480 + Kern::AddEvent(e);
1.481 + }
1.482 +
1.483 + // start the timer again
1.484 + iTimer.OneShot(iTimerTicks);
1.485 + }
1.486 +
1.487 +
1.488 +
1.489 +/**
1.490 +Notifies the peripheral of system power up.
1.491 +Called by the power manager during a transition from standby.
1.492 +Schedules a DFC to handle the power up.
1.493 +*/
1.494 +void DKeyboardTemplate::PowerUp()
1.495 + {
1.496 + iPowerUpDfc.Enque();
1.497 + }
1.498 +
1.499 +
1.500 +/**
1.501 +static DFC to handle powering up the keyboard
1.502 +
1.503 +@param aPtr A pointer to an instance of DKeyboardTemplate
1.504 +*/
1.505 +void DKeyboardTemplate::PowerUpDfcFn(TAny* aPtr)
1.506 + {
1.507 + ((DKeyboardTemplate*)aPtr)->PowerUpDfc();
1.508 + }
1.509 +
1.510 +
1.511 +/**
1.512 +DFC to handle powering up the keyboard
1.513 +*/
1.514 +void DKeyboardTemplate::PowerUpDfc()
1.515 + {
1.516 + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerUpDfc()"));
1.517 + KeyboardOn();
1.518 +
1.519 + // Indicate to power handle that powered up is complete
1.520 + PowerUpDone();
1.521 + }
1.522 +
1.523 +/**
1.524 +Powers up the keyboard
1.525 +May be called as a result of a power transition or from the HAL
1.526 +*/
1.527 +void DKeyboardTemplate::KeyboardOn()
1.528 + {
1.529 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOn() iKeyboardOn=%d", iKeyboardOn));
1.530 +
1.531 + if (!iKeyboardOn) // make sure we don't initialize more than once
1.532 + KeyboardPowerUp();
1.533 + }
1.534 +
1.535 +/**
1.536 +Powers up the keyboard
1.537 +Assumes that the keyboard is currently powered off
1.538 +*/
1.539 +void DKeyboardTemplate::KeyboardPowerUp()
1.540 + {
1.541 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardPowerUp()"));
1.542 +
1.543 + iKeyboardOn = ETrue;
1.544 +
1.545 + iKeyStateLast.Clear();
1.546 + iKeysDown.Clear();
1.547 +
1.548 + // Send key up events for EStdKeyOff (Fn+Esc) event
1.549 + TRawEvent e;
1.550 + e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0);
1.551 + Kern::AddEvent(e);
1.552 + e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
1.553 + Kern::AddEvent(e);
1.554 +
1.555 + // Start the periodic tick for the selected rate.
1.556 + // This will call TimerCallback() in the context of an ISR
1.557 + iTimer.OneShot(iTimerTicks);
1.558 + }
1.559 +
1.560 +
1.561 +/**
1.562 +Requests keyboard to power down.
1.563 +Called by the power manager during a transition to standby or power off
1.564 +Schedules a DFC to handle the power up.
1.565 +
1.566 +@param aPowerState the current power state
1.567 +*/
1.568 +void DKeyboardTemplate::PowerDown(TPowerState)
1.569 + {
1.570 + iPowerDownDfc.Enque();
1.571 + }
1.572 +
1.573 +/**
1.574 +static DFC to handle powering down the keyboard
1.575 +
1.576 +@param aPtr A pointer to an instance of DKeyboardTemplate
1.577 +*/
1.578 +void DKeyboardTemplate::PowerDownDfcFn(TAny* aPtr)
1.579 + {
1.580 + ((DKeyboardTemplate*)aPtr)->PowerDownDfc();
1.581 + }
1.582 +
1.583 +/**
1.584 +DFC to handle powering down the keyboard
1.585 +*/
1.586 +void DKeyboardTemplate::PowerDownDfc()
1.587 + {
1.588 + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerDownDfc()"));
1.589 + KeyboardOff();
1.590 + PowerDownDone();
1.591 + }
1.592 +
1.593 +/**
1.594 +Powers down the keyboard
1.595 +May be called as a result of a power transition or from the HAL
1.596 +*/
1.597 +void DKeyboardTemplate::KeyboardOff()
1.598 + {
1.599 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOff() iKeyboardOn=%d", iKeyboardOn));
1.600 +
1.601 + // cancel the keyboard-polling timer
1.602 + iTimerDfc.Cancel();
1.603 + iTimer.Cancel();
1.604 +
1.605 + iKeyboardOn = EFalse;
1.606 + }
1.607 +
1.608 +
1.609 +/**
1.610 +static message handler for processing power up/down messages
1.611 +posted internally from HalFunction()
1.612 +
1.613 +@param aPtr A pointer to an instance of DKeyboardTemplate
1.614 +*/
1.615 +void DKeyboardTemplate::HandleMessage(TAny* aPtr)
1.616 + {
1.617 + DKeyboardTemplate& h=*(DKeyboardTemplate*)aPtr;
1.618 + TMessageBase* pM=h.iMsgQ.iMessage;
1.619 + if (pM)
1.620 + h.HandleMsg(pM);
1.621 + }
1.622 +
1.623 +/**
1.624 +Message handler for processing power up/down messages
1.625 +posted internally from HalFunction()
1.626 +
1.627 +param aMsg A message indicating whether to power the keyboard on or off
1.628 +*/
1.629 +void DKeyboardTemplate::HandleMsg(TMessageBase* aMsg)
1.630 + {
1.631 + if (aMsg->iValue)
1.632 + KeyboardOn();
1.633 + else
1.634 + KeyboardOff();
1.635 + aMsg->Complete(KErrNone,ETrue);
1.636 + }
1.637 +
1.638 +
1.639 +/**
1.640 +Retrieves information about the keyboard
1.641 +Called from HalFunction()
1.642 +
1.643 +@param aInfo a caller-supplied class which on return contains information about the keyboard
1.644 +*/
1.645 +void DKeyboardTemplate::KeyboardInfo(TKeyboardInfoV01& aInfo)
1.646 + {
1.647 + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::KeyboardInfo"));
1.648 + aInfo.iKeyboardType=KConfigKeyboardType;
1.649 + aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys;
1.650 + aInfo.iAppsKeys=KConfigKeyboardAppsKeys;
1.651 + }
1.652 +
1.653 +
1.654 +/**
1.655 +HAL handler function
1.656 +
1.657 +@param aPtr a pointer to an instance of DLcdPowerHandler
1.658 +@param aFunction the function number
1.659 +@param a1 an arbitrary parameter
1.660 +@param a2 an arbitrary parameter
1.661 +*/
1.662 +TInt DKeyboardTemplate::HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
1.663 + {
1.664 + DKeyboardTemplate* pH=(DKeyboardTemplate*)aPtr;
1.665 + return pH->HalFunction(aFunction,a1,a2);
1.666 + }
1.667 +
1.668 +
1.669 +/**
1.670 +a HAL entry handling function for HAL group attribute EHalGroupKeyboard
1.671 +
1.672 +@param a1 an arbitrary argument
1.673 +@param a2 an arbitrary argument
1.674 +@return KErrNone if successful
1.675 +*/
1.676 +TInt DKeyboardTemplate::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
1.677 + {
1.678 + TInt r=KErrNone;
1.679 +
1.680 + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::HalFunction %d", aFunction));
1.681 +
1.682 + switch(aFunction)
1.683 + {
1.684 + case EKeyboardHalKeyboardInfo:
1.685 + {
1.686 + TPckgBuf<TKeyboardInfoV01> kPckg;
1.687 + KeyboardInfo(kPckg());
1.688 + Kern::InfoCopy(*(TDes8*)a1,kPckg);
1.689 + break;
1.690 + }
1.691 +
1.692 + case EKeyboardHalSetKeyboardState:
1.693 + {
1.694 + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
1.695 + return KErrPermissionDenied;
1.696 + if ((TBool)a1)
1.697 + {
1.698 + TThreadMessage& m=Kern::Message();
1.699 + m.iValue = ETrue;
1.700 + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up
1.701 + }
1.702 + else
1.703 + {
1.704 + TThreadMessage& m=Kern::Message();
1.705 + m.iValue = EFalse;
1.706 + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down
1.707 + }
1.708 + }
1.709 + break;
1.710 +
1.711 + case EKeyboardHalKeyboardState:
1.712 + kumemput32(a1, &iKeyboardOn, sizeof(TBool));
1.713 + break;
1.714 +
1.715 + default:
1.716 + r=KErrNotSupported;
1.717 + break;
1.718 + }
1.719 + return r;
1.720 + }
1.721 +
1.722 +
1.723 +
1.724 +DECLARE_STANDARD_EXTENSION()
1.725 + {
1.726 + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
1.727 +
1.728 + // create keyboard driver
1.729 + TInt r=KErrNoMemory;
1.730 + DKeyboardTemplate* pK=new DKeyboardTemplate;
1.731 + if (pK)
1.732 + r=pK->Create();
1.733 +
1.734 + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
1.735 + return r;
1.736 + }