1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2005, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 #
10 # $Id$
11 # USB Keyboard Driver for PS2 using RPC instead of FIO
12 */
13
14 #include <tamtypes.h>
15 #include <kernel.h>
16 #include <sifrpc.h>
17 #include <string.h>
18 #include "backends/platform/ps2/rpckbd.h"
19
20 static unsigned int curr_readmode = PS2KBD_READMODE_NORMAL;
21 static int kbdRpcSema = -1;
22 static int kbdInitialized = 0;
23
24 static SifRpcClientData_t cd0;
25 static unsigned char rpcBuf[3 * PS2KBD_KEYMAP_SIZE] __attribute__((aligned (16)));
26 static unsigned int rpcKey __attribute__((aligned (16)));
27
PS2KbdInit(void)28 int PS2KbdInit(void)
29 /* Initialise the keyboard library */
30 {
31 int res;
32 ee_sema_t kbdSema;
33
34 while ((res = SifBindRpc(&cd0, PS2KBD_RPC_ID, 0)) < 0)
35 nopdelay();
36
37 memset(rpcBuf, 0, 3 * PS2KBD_KEYMAP_SIZE);
38 rpcKey = 0;
39
40 kbdSema.init_count = 1;
41 kbdSema.max_count = 1;
42
43 kbdRpcSema = CreateSema(&kbdSema);
44 if (kbdRpcSema >= 0) {
45 kbdInitialized = 1;
46 return 0;
47 } else
48 return -1;
49 }
50
rpcCompleteIntr(void * param)51 static void rpcCompleteIntr(void *param) {
52 iSignalSema(kbdRpcSema);
53 }
54
PS2KbdRead(char * key)55 int PS2KbdRead(char *key)
56 /* Reads 1 character from the keyboard */
57 {
58 int res;
59 if ((!kbdInitialized) || (curr_readmode != PS2KBD_READMODE_NORMAL))
60 return -1;
61
62 if (PollSema(kbdRpcSema) >= 0) {
63 // last rpc call completed
64 res = (rpcKey != 0);
65 *key = *(char *)UNCACHED_SEG(&rpcKey);
66 SifCallRpc(&cd0, KBD_RPC_READKEY, SIF_RPC_M_NOWAIT, rpcBuf, 0, &rpcKey, 4, rpcCompleteIntr, NULL);
67 return res;
68 } else // rpc still running
69 return 0;
70 }
71
PS2KbdReadRaw(PS2KbdRawKey * key)72 int PS2KbdReadRaw(PS2KbdRawKey *key)
73 /* Reads 1 raw character from the keyboard */
74 {
75 int res;
76 if ((!kbdInitialized) || (curr_readmode != PS2KBD_READMODE_RAW))
77 return -1;
78
79 if (PollSema(kbdRpcSema) >= 0) {
80 // last rpc call completed
81 res = (rpcKey != 0);
82 *key = *(PS2KbdRawKey *)UNCACHED_SEG(&rpcKey);
83 SifCallRpc(&cd0, KBD_RPC_READRAW, SIF_RPC_M_NOWAIT, rpcBuf, 0, &rpcKey, 4, rpcCompleteIntr, NULL);
84 return res;
85 } else // rpc still running
86 return 0;
87 }
88
PS2KbdSetReadmode(u32 readmode)89 int PS2KbdSetReadmode(u32 readmode)
90 /* Sets the read mode to normal or raw */
91 {
92 if (kbdInitialized) {
93 if (curr_readmode == readmode)
94 return 0;
95 WaitSema(kbdRpcSema);
96 *(unsigned int *)rpcBuf = curr_readmode = readmode;
97 return SifCallRpc(&cd0, KBD_RPC_SETREADMODE, SIF_RPC_M_NOWAIT, rpcBuf, 4, rpcBuf, 0, rpcCompleteIntr, NULL);
98 } else
99 return -1;
100 }
101
PS2KbdSetLeds(u8 leds)102 int PS2KbdSetLeds(u8 leds)
103 /* Sets all connected keyboards leds */
104 {
105 if (kbdInitialized) {
106 WaitSema(kbdRpcSema);
107 *(unsigned char *)rpcBuf = leds;
108 return SifCallRpc(&cd0, KBD_RPC_SETLEDS, SIF_RPC_M_NOWAIT, rpcBuf, 4, rpcBuf, 0, rpcCompleteIntr, NULL);
109 } else
110 return -1;
111 }
112
PS2KbdSetKeymap(PS2KbdKeyMap * keymaps)113 int PS2KbdSetKeymap(PS2KbdKeyMap *keymaps)
114 /* Sets the current keymap */
115 {
116 if (kbdInitialized) {
117 WaitSema(kbdRpcSema);
118 memcpy(rpcBuf + 0 * PS2KBD_KEYMAP_SIZE, keymaps->keymap, PS2KBD_KEYMAP_SIZE);
119 memcpy(rpcBuf + 1 * PS2KBD_KEYMAP_SIZE, keymaps->shiftkeymap, PS2KBD_KEYMAP_SIZE);
120 memcpy(rpcBuf + 2 * PS2KBD_KEYMAP_SIZE, keymaps->keycap, PS2KBD_KEYMAP_SIZE);
121 return SifCallRpc(&cd0, KBD_RPC_SETKEYMAP, SIF_RPC_M_NOWAIT, rpcBuf, 3 * PS2KBD_KEYMAP_SIZE, rpcBuf, 0, rpcCompleteIntr, NULL);
122 } else
123 return -1;
124 }
125
PS2KbdSetCtrlmap(u8 * ctrlmap)126 int PS2KbdSetCtrlmap(u8 *ctrlmap)
127 /* Sets the control key mappings */
128 {
129 if (kbdInitialized) {
130 WaitSema(kbdRpcSema);
131 memcpy(rpcBuf, ctrlmap, PS2KBD_KEYMAP_SIZE);
132 return SifCallRpc(&cd0, KBD_RPC_SETCTRLMAP, SIF_RPC_M_NOWAIT, rpcBuf, PS2KBD_KEYMAP_SIZE, rpcBuf, 0, rpcCompleteIntr, NULL);
133 } else
134 return -1;
135 }
136
PS2KbdSetAltmap(u8 * altmap)137 int PS2KbdSetAltmap(u8 *altmap)
138 /* Sets the alt key mappings */
139 {
140 if (kbdInitialized) {
141 WaitSema(kbdRpcSema);
142 memcpy(rpcBuf, altmap, PS2KBD_KEYMAP_SIZE);
143 return SifCallRpc(&cd0, KBD_RPC_SETALTMAP, SIF_RPC_M_NOWAIT, rpcBuf, PS2KBD_KEYMAP_SIZE, rpcBuf, 0, rpcCompleteIntr, NULL);
144 } else
145 return -1;
146 }
147
PS2KbdSetSpecialmap(u8 * special)148 int PS2KbdSetSpecialmap(u8 *special)
149 /* Sets the special key mappings */
150 {
151 if (kbdInitialized) {
152 WaitSema(kbdRpcSema);
153 memcpy(rpcBuf, special, PS2KBD_KEYMAP_SIZE);
154 return SifCallRpc(&cd0, KBD_RPC_SETSPECIALMAP, SIF_RPC_M_NOWAIT, rpcBuf, PS2KBD_KEYMAP_SIZE, rpcBuf, 0, rpcCompleteIntr, NULL);
155 } else
156 return -1;
157 }
158
PS2KbdFlushBuffer(void)159 int PS2KbdFlushBuffer(void)
160 /* Flushes the keyboard buffer */
161 {
162 if (kbdInitialized) {
163 WaitSema(kbdRpcSema);
164 return SifCallRpc(&cd0, KBD_RPC_FLUSHBUFFER, SIF_RPC_M_NOWAIT, rpcBuf, 0, rpcBuf, 0, rpcCompleteIntr, NULL);
165 } else
166 return -1;
167 }
168
PS2KbdResetKeymap(void)169 int PS2KbdResetKeymap(void)
170 /* Resets the keymap to the default US mapping */
171 {
172 if (kbdInitialized) {
173 WaitSema(kbdRpcSema);
174 return SifCallRpc(&cd0, KBD_RPC_RESETKEYMAP, SIF_RPC_M_NOWAIT, rpcBuf, 0, rpcBuf, 0, rpcCompleteIntr, NULL);
175 } else
176 return -1;
177 }
178