diff -r 2fb8b9db1c86 -r d55eb581a87c baseport/syborg/keyboard/syborg_keyboard.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/keyboard/syborg_keyboard.cpp Tue Aug 04 10:28:23 2009 +0100 @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Minimalistic keyboard driver +* +*/ + +//#define DEBUG + +#include "syborg_keyboard.h" + +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) +{ + DKeyboardPs2Soc* pH=(DKeyboardPs2Soc*)aPtr; + return pH->HalFunction(aFunction,a1,a2); +} + +void rxMsg(TAny* aPtr) +{ + DKeyboardPs2Soc& h=*(DKeyboardPs2Soc*)aPtr; + TMessageBase* pM=h.iMsgQ.iMessage; + if (pM) + h.HandleMsg(pM); +} + +TInt DKeyboardPs2Soc::FifoPop(void) +{ + TInt val = iKeyFifo[iFifoPos]; + iFifoPos++; + iFifoCount--; + + if (iFifoPos == FIFO_SIZE) + iFifoPos = 0; + + return val; +} + +void DKeyboardPs2Soc::FifoPush(TInt val) +{ + TInt slot; + + if (iFifoCount == FIFO_SIZE) + return; + + slot = iFifoPos + iFifoCount; + if (slot >= FIFO_SIZE) + slot -= FIFO_SIZE; + iKeyFifo[slot] = val; + iFifoCount++; +} + +void DKeyboardPs2Soc::Isr(TAny* aPtr) +{ + __DEBUG_PRINT("DKeyboardPs2Soc::Isr"); + DKeyboardPs2Soc& k = *(DKeyboardPs2Soc*)aPtr; + + // Is now auto-clearing + while(ReadReg(KHwBaseKmiKeyboard, KBD_FIFO_COUNT)!=0) + k.FifoPush(ReadReg(KHwBaseKmiKeyboard, KBD_DATA)); + + //WriteReg(KHwBaseKmiKeyboard,KBD_CLEAR_INT, 0); + Interrupt::Clear(EIntKeyboard); + k.iRxDfc.Add(); +} + +DKeyboardPs2Soc::DKeyboardPs2Soc() + : DPowerHandler(KLitKeyboard), + iRxDfc(RxDfc,this,Kern::DfcQue0(),1), + iMsgQ(rxMsg,this,NULL,1) +{ + iKeyboardOn = ETrue; + iFifoPos = 0; + iFifoCount = 0; +} + +TInt DKeyboardPs2Soc::Create() +{ + __DEBUG_PRINT("DKeyboardPs2Soc::Create"); + + TInt r=KErrNone; + iDfcQ=Kern::DfcQue0(); + + iFifoPos = iFifoCount = 0; + + r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this); + if (r!=KErrNone) + return r; + + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + r=Interrupt::Bind(EIntKeyboard,Isr,this); + if (r==KErrNone) { + Add(); + KeyboardOn(); + } + return r; +} + +void DKeyboardPs2Soc::PowerUp() +{ + PowerUpDone(); +} + +void DKeyboardPs2Soc::PowerDown(TPowerState) +{ + PowerDownDone(); +} + +void DKeyboardPs2Soc::KeyboardOn() +{ + __DEBUG_PRINT("DKeyboardPs2Soc::KeyboardOn"); + TInt reg = ReadReg(KHwBaseKmiKeyboard,KBD_ID); + + Interrupt::Enable(EIntKeyboard); + WriteReg(KHwBaseKmiKeyboard,KBD_INT_ENABLE,1); +} + +void DKeyboardPs2Soc::KeyboardOff() +{ + __DEBUG_PRINT("DKeyboardPs2Soc::KeyboardOff"); + Interrupt::Disable(EIntKeyboard); + WriteReg(KHwBaseKmiKeyboard,KBD_INT_ENABLE,0); +} + +void DKeyboardPs2Soc::HandleMsg(TMessageBase* aMsg) +{ + __DEBUG_PRINT("DKeyboardPs2Soc::HandleMsg"); + if (aMsg->iValue) + KeyboardOn(); + else + KeyboardOff(); + aMsg->Complete(KErrNone,ETrue); +} + +void DKeyboardPs2Soc::KeyboardInfo(TKeyboardInfoV01& aInfo) +{ + aInfo.iKeyboardType=KConfigKeyboardType; + aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys; + aInfo.iAppsKeys=KConfigKeyboardAppsKeys; +} + +TInt DKeyboardPs2Soc::HalFunction(TInt aFunction, TAny* a1, TAny* a2) +{ + TInt r=KErrNone; + + __DEBUG_PRINT("DKeyboardPs2Soc::HalFunction"); + switch(aFunction) + { + case EKeyboardHalKeyboardInfo: + { + TPckgBuf kPckg; + KeyboardInfo(kPckg()); + Kern::InfoCopy(*(TDes8*)a1,kPckg); + break; + } + // UIKLAF Silent running/power management + case EKeyboardHalSetKeyboardState: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState"))) + return KErrPermissionDenied; + if ((TBool)a1) + { + TThreadMessage& m=Kern::Message(); + m.iValue = ETrue; + m.SendReceive(&iMsgQ); + } + else + { + TThreadMessage& m=Kern::Message(); + m.iValue = EFalse; + m.SendReceive(&iMsgQ); + } + } + break; + case EKeyboardHalKeyboardState: + kumemput32(a1, &iKeyboardOn, sizeof(TBool)); + break; + default: + r=KErrNotSupported; + break; + } + return r; +} + +void DKeyboardPs2Soc::RxDfc(TAny* aPtr) +{ + TRawEvent e; + DKeyboardPs2Soc& k = *(DKeyboardPs2Soc*)aPtr; + + while(k.iFifoCount>0) { + int keycode = k.FifoPop(); + int dwn = (keycode & 0x80000000) ? 0 : 1; + __DEBUG_PRINT("DKeyboardPs2Soc::RxDfc %d %d", keycode, dwn); + + keycode &= ~(0x80000000); + if (dwn) { + __DEBUG_PRINT("kbd EKeyDown:%d",keycode); + e.Set(TRawEvent::EKeyDown,KConvertCode[keycode],0); + } + else { + __DEBUG_PRINT("kbd EKeyUp:%d",keycode); + e.Set(TRawEvent::EKeyUp,KConvertCode[keycode],0); + } + Kern::AddEvent(e); + } +} + +DECLARE_STANDARD_EXTENSION() +{ + TInt r=KErrNoMemory; + DKeyboardPs2Soc* pK=new DKeyboardPs2Soc; + if (pK) + r=pK->Create(); + __KTRACE_OPT(KEXTENSION,__DEBUG_PRINT("Returns %d",r)); + return r; +}