2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/armllb/hw/versatile/hwkmi.c
5 * PURPOSE: LLB KMI Support for Versatile
6 * PROGRAMMERS: ReactOS Portable Systems Group
12 // Control Register Bits
14 #define KMICR_TYPE (1 << 5)
15 #define KMICR_RXINTREN (1 << 4)
16 #define KMICR_TXINTREN (1 << 3)
17 #define KMICR_EN (1 << 2)
18 #define KMICR_FD (1 << 1)
19 #define KMICR_FC (1 << 0)
22 // Status Register Bits
24 #define KMISTAT_TXEMPTY (1 << 6)
25 #define KMISTAT_TXBUSY (1 << 5)
26 #define KMISTAT_RXFULL (1 << 4)
27 #define KMISTAT_RXBUSY (1 << 3)
28 #define KMISTAT_RXPARITY (1 << 2)
29 #define KMISTAT_IC (1 << 1)
30 #define KMISTAT_ID (1 << 0)
35 #define PL050_KMICR (LlbHwVersaKmiBase + 0x00)
36 #define PL050_KMISTAT (LlbHwVersaKmiBase + 0x04)
37 #define PL050_KMIDATA (LlbHwVersaKmiBase + 0x08)
38 #define PL050_KMICLKDIV (LlbHwVersaKmiBase + 0x0c)
39 static const ULONG LlbHwVersaKmiBase
= 0x10006000;
42 // PS/2 Commands/Requests
44 #define PS2_O_RESET 0xff
45 #define PS2_O_RESEND 0xfe
46 #define PS2_O_DISABLE 0xf5
47 #define PS2_O_ENABLE 0xf4
48 #define PS2_O_ECHO 0xee
49 #define PS2_O_SET_DEFAULT 0xf6
50 #define PS2_O_SET_RATE_DELAY 0xf3
51 #define PS2_O_SET_SCANSET 0xf0
52 #define PS2_O_INDICATORS 0xed
53 #define PS2_I_RESEND 0xfe
54 #define PS2_I_DIAGFAIL 0xfd
55 #define PS2_I_ACK 0xfa
56 #define PS2_I_BREAK 0xf0
57 #define PS2_I_ECHO 0xee
58 #define PS2_I_BAT_OK 0xaa
60 /* FUNCTIONS ******************************************************************/
64 LlbHwVersaKmiSendAndWait(IN ULONG Value
)
66 volatile int i
= 1000;
74 /* Now make sure we received an ACK */
75 if (LlbHwKbdRead() != PS2_I_ACK
) DbgPrint("PS/2 FAILURE!\n");
80 LlbHwVersaKmiInitialize(VOID
)
84 /* Setup divisor and enable KMI */
85 Divisor
= (LlbHwGetPClk() / 8000000) - 1;
86 WRITE_REGISTER_UCHAR(PL050_KMICLKDIV
, Divisor
);
87 WRITE_REGISTER_UCHAR(PL050_KMICR
, KMICR_EN
);
89 /* Reset PS/2 controller */
90 LlbHwVersaKmiSendAndWait(PS2_O_RESET
);
91 if (LlbHwKbdRead() != PS2_I_BAT_OK
) DbgPrint("PS/2 RESET FAILURE!\n");
93 /* Send PS/2 Initialization Stream */
94 LlbHwVersaKmiSendAndWait(PS2_O_DISABLE
);
95 LlbHwVersaKmiSendAndWait(PS2_O_SET_DEFAULT
);
96 LlbHwVersaKmiSendAndWait(PS2_O_SET_SCANSET
);
97 LlbHwVersaKmiSendAndWait(1);
98 LlbHwVersaKmiSendAndWait(PS2_O_ENABLE
);
103 LlbHwKbdSend(IN ULONG Value
)
107 /* Wait for ready signal */
110 /* Read TX buffer state */
111 Status
= READ_REGISTER_UCHAR(PL050_KMISTAT
);
112 } while (!(Status
& KMISTAT_TXEMPTY
));
115 WRITE_REGISTER_UCHAR(PL050_KMIDATA
, Value
);
122 return READ_REGISTER_UCHAR(PL050_KMISTAT
) & KMISTAT_RXFULL
;
129 /* Read current data on keyboard */
130 return READ_REGISTER_UCHAR(PL050_KMIDATA
);