baseport/syborg/keyboard/syborg_keyboard.cpp
changeset 2 d55eb581a87c
parent 0 ffa851df0825
equal deleted inserted replaced
1:2fb8b9db1c86 2:d55eb581a87c
       
     1 /*
       
     2 * Copyright (c) 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 the License "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: Minimalistic keyboard driver
       
    15 *
       
    16 */
       
    17 
       
    18 //#define DEBUG
       
    19 
       
    20 #include "syborg_keyboard.h"
       
    21 
       
    22 LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
    23 {
       
    24   DKeyboardPs2Soc* pH=(DKeyboardPs2Soc*)aPtr;
       
    25   return pH->HalFunction(aFunction,a1,a2);
       
    26 }
       
    27 
       
    28 void rxMsg(TAny* aPtr)
       
    29 {
       
    30   DKeyboardPs2Soc& h=*(DKeyboardPs2Soc*)aPtr;
       
    31   TMessageBase* pM=h.iMsgQ.iMessage;
       
    32   if (pM)
       
    33 	h.HandleMsg(pM);
       
    34 }
       
    35 
       
    36 TInt DKeyboardPs2Soc::FifoPop(void)
       
    37 {
       
    38   TInt val = iKeyFifo[iFifoPos];
       
    39   iFifoPos++;
       
    40   iFifoCount--;
       
    41   
       
    42   if (iFifoPos == FIFO_SIZE)
       
    43 	iFifoPos = 0;
       
    44 
       
    45   return val;
       
    46 }
       
    47 
       
    48 void DKeyboardPs2Soc::FifoPush(TInt val)
       
    49 {
       
    50   TInt slot;
       
    51 
       
    52   if (iFifoCount == FIFO_SIZE)
       
    53 	return;
       
    54   
       
    55   slot = iFifoPos + iFifoCount;
       
    56   if (slot >= FIFO_SIZE)
       
    57 	slot -= FIFO_SIZE;
       
    58   iKeyFifo[slot] = val;
       
    59   iFifoCount++;
       
    60 }
       
    61 
       
    62 void DKeyboardPs2Soc::Isr(TAny* aPtr)
       
    63 {
       
    64   __DEBUG_PRINT("DKeyboardPs2Soc::Isr");
       
    65   DKeyboardPs2Soc& k = *(DKeyboardPs2Soc*)aPtr;
       
    66 
       
    67   // Is now auto-clearing
       
    68   while(ReadReg(KHwBaseKmiKeyboard, KBD_FIFO_COUNT)!=0)
       
    69 	k.FifoPush(ReadReg(KHwBaseKmiKeyboard, KBD_DATA));
       
    70   
       
    71   //WriteReg(KHwBaseKmiKeyboard,KBD_CLEAR_INT, 0);
       
    72   Interrupt::Clear(EIntKeyboard); 
       
    73   k.iRxDfc.Add();
       
    74 }
       
    75 
       
    76 DKeyboardPs2Soc::DKeyboardPs2Soc()
       
    77   :	DPowerHandler(KLitKeyboard),
       
    78 	iRxDfc(RxDfc,this,Kern::DfcQue0(),1),
       
    79 	iMsgQ(rxMsg,this,NULL,1)
       
    80 {
       
    81   iKeyboardOn = ETrue;
       
    82   iFifoPos = 0;
       
    83   iFifoCount = 0;
       
    84 }
       
    85 
       
    86 TInt DKeyboardPs2Soc::Create()
       
    87 {
       
    88   __DEBUG_PRINT("DKeyboardPs2Soc::Create");
       
    89 
       
    90   TInt r=KErrNone;
       
    91   iDfcQ=Kern::DfcQue0();
       
    92 
       
    93   iFifoPos = iFifoCount = 0;
       
    94 
       
    95   r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this);
       
    96   if (r!=KErrNone)
       
    97 	return r;
       
    98 
       
    99   iMsgQ.SetDfcQ(iDfcQ);
       
   100   iMsgQ.Receive();
       
   101 
       
   102   r=Interrupt::Bind(EIntKeyboard,Isr,this);
       
   103   if (r==KErrNone) {
       
   104 	Add();
       
   105 	KeyboardOn();
       
   106   }
       
   107   return r;
       
   108 }
       
   109 
       
   110 void DKeyboardPs2Soc::PowerUp()
       
   111 {
       
   112   PowerUpDone();
       
   113 }
       
   114 
       
   115 void DKeyboardPs2Soc::PowerDown(TPowerState)
       
   116 {
       
   117   PowerDownDone();
       
   118 }
       
   119 
       
   120 void DKeyboardPs2Soc::KeyboardOn()
       
   121 {
       
   122   __DEBUG_PRINT("DKeyboardPs2Soc::KeyboardOn");
       
   123   TInt reg = ReadReg(KHwBaseKmiKeyboard,KBD_ID);
       
   124   
       
   125   Interrupt::Enable(EIntKeyboard);
       
   126   WriteReg(KHwBaseKmiKeyboard,KBD_INT_ENABLE,1);
       
   127 }
       
   128 
       
   129 void DKeyboardPs2Soc::KeyboardOff()
       
   130 {
       
   131   __DEBUG_PRINT("DKeyboardPs2Soc::KeyboardOff");
       
   132   Interrupt::Disable(EIntKeyboard);
       
   133   WriteReg(KHwBaseKmiKeyboard,KBD_INT_ENABLE,0);
       
   134 }
       
   135 
       
   136 void DKeyboardPs2Soc::HandleMsg(TMessageBase* aMsg)
       
   137 {
       
   138   __DEBUG_PRINT("DKeyboardPs2Soc::HandleMsg");
       
   139   if (aMsg->iValue)
       
   140 	KeyboardOn();
       
   141   else
       
   142 	KeyboardOff();
       
   143   aMsg->Complete(KErrNone,ETrue);
       
   144 }
       
   145 
       
   146 void DKeyboardPs2Soc::KeyboardInfo(TKeyboardInfoV01& aInfo)
       
   147 {
       
   148   aInfo.iKeyboardType=KConfigKeyboardType;
       
   149   aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys;
       
   150   aInfo.iAppsKeys=KConfigKeyboardAppsKeys;
       
   151 }
       
   152 
       
   153 TInt DKeyboardPs2Soc::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
   154 {
       
   155   TInt r=KErrNone;
       
   156 
       
   157   __DEBUG_PRINT("DKeyboardPs2Soc::HalFunction");
       
   158   switch(aFunction)
       
   159 	{
       
   160 	case EKeyboardHalKeyboardInfo:
       
   161 	  {
       
   162 		TPckgBuf<TKeyboardInfoV01> kPckg;
       
   163 		KeyboardInfo(kPckg());
       
   164 		Kern::InfoCopy(*(TDes8*)a1,kPckg);
       
   165 		break;
       
   166 	  }
       
   167 	  // UIKLAF Silent running/power management
       
   168 	case EKeyboardHalSetKeyboardState:
       
   169 	  {
       
   170 		if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
       
   171 		  return KErrPermissionDenied;
       
   172 		if ((TBool)a1)
       
   173 		  {
       
   174 			TThreadMessage& m=Kern::Message();
       
   175 			m.iValue = ETrue;
       
   176 			m.SendReceive(&iMsgQ);
       
   177 		  }
       
   178 		else
       
   179 		  {
       
   180 			TThreadMessage& m=Kern::Message();
       
   181 			m.iValue = EFalse;
       
   182 			m.SendReceive(&iMsgQ);
       
   183 		  }
       
   184 	  }
       
   185 	  break;
       
   186 	case EKeyboardHalKeyboardState:
       
   187 	  kumemput32(a1, &iKeyboardOn, sizeof(TBool));
       
   188 	  break;
       
   189 	default:
       
   190 	  r=KErrNotSupported;
       
   191 	  break;
       
   192 	}
       
   193   return r;
       
   194 }
       
   195 
       
   196 void DKeyboardPs2Soc::RxDfc(TAny* aPtr)
       
   197 {
       
   198   TRawEvent e;
       
   199   DKeyboardPs2Soc& k = *(DKeyboardPs2Soc*)aPtr;
       
   200 
       
   201   while(k.iFifoCount>0) {
       
   202 	int keycode = k.FifoPop();
       
   203 	int dwn = (keycode & 0x80000000) ? 0 : 1;
       
   204 	__DEBUG_PRINT("DKeyboardPs2Soc::RxDfc %d %d", keycode, dwn);
       
   205   
       
   206 	keycode &= ~(0x80000000);	
       
   207 	if (dwn) {
       
   208 	  __DEBUG_PRINT("kbd EKeyDown:%d",keycode);
       
   209 	  e.Set(TRawEvent::EKeyDown,KConvertCode[keycode],0);
       
   210 	}
       
   211 	else {
       
   212 	  __DEBUG_PRINT("kbd EKeyUp:%d",keycode);
       
   213 	  e.Set(TRawEvent::EKeyUp,KConvertCode[keycode],0);
       
   214 	}
       
   215 	Kern::AddEvent(e);
       
   216   }
       
   217 }
       
   218 
       
   219 DECLARE_STANDARD_EXTENSION()
       
   220 {
       
   221   TInt r=KErrNoMemory;
       
   222   DKeyboardPs2Soc* pK=new DKeyboardPs2Soc;
       
   223   if (pK)
       
   224 	r=pK->Create();
       
   225   __KTRACE_OPT(KEXTENSION,__DEBUG_PRINT("Returns %d",r));
       
   226   return r;
       
   227 }