mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 12:26:32 +00:00
134 lines
3.2 KiB
C
134 lines
3.2 KiB
C
/*
|
|
* PROJECT: ReactOS Boot Loader
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: boot/armllb/hw/versatile/hwkmi.c
|
|
* PURPOSE: LLB KMI Support for Versatile
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
//
|
|
// Control Register Bits
|
|
//
|
|
#define KMICR_TYPE (1 << 5)
|
|
#define KMICR_RXINTREN (1 << 4)
|
|
#define KMICR_TXINTREN (1 << 3)
|
|
#define KMICR_EN (1 << 2)
|
|
#define KMICR_FD (1 << 1)
|
|
#define KMICR_FC (1 << 0)
|
|
|
|
//
|
|
// Status Register Bits
|
|
//
|
|
#define KMISTAT_TXEMPTY (1 << 6)
|
|
#define KMISTAT_TXBUSY (1 << 5)
|
|
#define KMISTAT_RXFULL (1 << 4)
|
|
#define KMISTAT_RXBUSY (1 << 3)
|
|
#define KMISTAT_RXPARITY (1 << 2)
|
|
#define KMISTAT_IC (1 << 1)
|
|
#define KMISTAT_ID (1 << 0)
|
|
|
|
//
|
|
// KMI Registers
|
|
//
|
|
#define PL050_KMICR (LlbHwVersaKmiBase + 0x00)
|
|
#define PL050_KMISTAT (LlbHwVersaKmiBase + 0x04)
|
|
#define PL050_KMIDATA (LlbHwVersaKmiBase + 0x08)
|
|
#define PL050_KMICLKDIV (LlbHwVersaKmiBase + 0x0c)
|
|
static const ULONG LlbHwVersaKmiBase = 0x10006000;
|
|
|
|
//
|
|
// PS/2 Commands/Requests
|
|
//
|
|
#define PS2_O_RESET 0xff
|
|
#define PS2_O_RESEND 0xfe
|
|
#define PS2_O_DISABLE 0xf5
|
|
#define PS2_O_ENABLE 0xf4
|
|
#define PS2_O_ECHO 0xee
|
|
#define PS2_O_SET_DEFAULT 0xf6
|
|
#define PS2_O_SET_RATE_DELAY 0xf3
|
|
#define PS2_O_SET_SCANSET 0xf0
|
|
#define PS2_O_INDICATORS 0xed
|
|
#define PS2_I_RESEND 0xfe
|
|
#define PS2_I_DIAGFAIL 0xfd
|
|
#define PS2_I_ACK 0xfa
|
|
#define PS2_I_BREAK 0xf0
|
|
#define PS2_I_ECHO 0xee
|
|
#define PS2_I_BAT_OK 0xaa
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
VOID
|
|
NTAPI
|
|
LlbHwVersaKmiSendAndWait(IN ULONG Value)
|
|
{
|
|
volatile int i = 1000;
|
|
|
|
/* Send the value */
|
|
LlbHwKbdSend(Value);
|
|
|
|
/* Wait a bit */
|
|
while (--i);
|
|
|
|
/* Now make sure we received an ACK */
|
|
if (LlbHwKbdRead() != PS2_I_ACK) DbgPrint("PS/2 FAILURE!\n");
|
|
}
|
|
|
|
VOID
|
|
NTAPI
|
|
LlbHwVersaKmiInitialize(VOID)
|
|
{
|
|
UCHAR Divisor;
|
|
|
|
/* Setup divisor and enable KMI */
|
|
Divisor = (LlbHwGetPClk() / 8000000) - 1;
|
|
WRITE_REGISTER_UCHAR(PL050_KMICLKDIV, Divisor);
|
|
WRITE_REGISTER_UCHAR(PL050_KMICR, KMICR_EN);
|
|
|
|
/* Reset PS/2 controller */
|
|
LlbHwVersaKmiSendAndWait(PS2_O_RESET);
|
|
if (LlbHwKbdRead() != PS2_I_BAT_OK) DbgPrint("PS/2 RESET FAILURE!\n");
|
|
|
|
/* Send PS/2 Initialization Stream */
|
|
LlbHwVersaKmiSendAndWait(PS2_O_DISABLE);
|
|
LlbHwVersaKmiSendAndWait(PS2_O_SET_DEFAULT);
|
|
LlbHwVersaKmiSendAndWait(PS2_O_SET_SCANSET);
|
|
LlbHwVersaKmiSendAndWait(1);
|
|
LlbHwVersaKmiSendAndWait(PS2_O_ENABLE);
|
|
}
|
|
|
|
VOID
|
|
NTAPI
|
|
LlbHwKbdSend(IN ULONG Value)
|
|
{
|
|
ULONG Status;
|
|
|
|
/* Wait for ready signal */
|
|
do
|
|
{
|
|
/* Read TX buffer state */
|
|
Status = READ_REGISTER_UCHAR(PL050_KMISTAT);
|
|
} while (!(Status & KMISTAT_TXEMPTY));
|
|
|
|
/* Send value */
|
|
WRITE_REGISTER_UCHAR(PL050_KMIDATA, Value);
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
LlbHwKbdReady(VOID)
|
|
{
|
|
return READ_REGISTER_UCHAR(PL050_KMISTAT) & KMISTAT_RXFULL;
|
|
}
|
|
|
|
INT
|
|
NTAPI
|
|
LlbHwKbdRead(VOID)
|
|
{
|
|
/* Read current data on keyboard */
|
|
return READ_REGISTER_UCHAR(PL050_KMIDATA);
|
|
}
|
|
|
|
/* EOF */
|