PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
ps2kbd.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, 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
16#include "types.h"
17#include "ioman.h"
18#include "loadcore.h"
19#include "stdio.h"
20#include "sifcmd.h"
21#include "sifrpc.h"
22#include "sysclib.h"
23#include <errno.h>
24#include "sysmem.h"
25#include "usbd.h"
26#include "usbd_macro.h"
27#include "thbase.h"
28#include "thevent.h"
29#include "thsemap.h"
30
31#include "ps2kbd.h"
32#include "us_keymap.h"
33
34#define MODNAME "PS2 USB keyboard driver"
35
36IRX_ID(MODNAME, 1, 1);
37
38#define PS2KBD_VERSION 0x100
39
40#define USB_SUBCLASS_BOOT 1
41#define USB_HIDPROTO_KEYBOARD 1
42
43#define PS2KBD_MAXDEV 2
44#define PS2KBD_MAXKEYS 6
45
46#define PS2KBD_DEFLINELEN 4096
47#define PS2KBD_DEFREPEATRATE 100
49#define PS2KBD_REPEATWAIT 1000
51#define USB_KEYB_NUMLOCK 0x53
52#define USB_KEYB_CAPSLOCK 0x39
53#define USB_KEYB_SCRLOCK 0x47
54
55#define USB_KEYB_NUMPAD_START 0x54
56#define USB_KEYB_NUMPAD_END 0x63
57
58#define SEMA_ZERO -419
59#define SEMA_DELETED -425
60
61int ps2kbd_init();
62void ps2kbd_config_set(int resultCode, int bytes, void *arg);
63void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg);
64void ps2kbd_data_recv(int resultCode, int bytes, void *arg);
65int ps2kbd_probe(int devId);
66int ps2kbd_connect(int devId);
67int ps2kbd_disconnect(int devId);
68void usb_getstring(int endp, int index, char *desc);
69
70typedef struct _kbd_data_recv
71
72{
73 u8 mod_keys;
74 u8 reserved;
75 u8 keycodes[PS2KBD_MAXKEYS];
77
78typedef struct _keyb_dev
79
80{
81 int configEndp;
82 int dataEndp;
83 int packetSize;
84 int devId;
87 char repeatkeys[2];
88 u32 eventmask;
91 kbd_data_recv oldData;
94} kbd_dev;
95
96/* Global Variables */
97
98int kbd_readmode;
99int kbd_blocking;
100u32 kbd_repeatrate;
102kbd_dev *devices[PS2KBD_MAXDEV];
103int dev_count;
104sceUsbdLddOps kbd_driver = { NULL, NULL, "PS2Kbd", ps2kbd_probe, ps2kbd_connect, ps2kbd_disconnect, 0, 0, 0, 0, 0, NULL };
105u8 *lineBuffer;
106u32 lineStartP, lineEndP;
107int lineSema;
108int bufferSema;
109u32 lineSize;
111u8 keymap[PS2KBD_KEYMAP_SIZE];
113u8 shiftkeymap[PS2KBD_KEYMAP_SIZE];
115u8 keycap[PS2KBD_KEYMAP_SIZE];
116u8 special_keys[PS2KBD_KEYMAP_SIZE];
117u8 control_map[PS2KBD_KEYMAP_SIZE];
118u8 alt_map[PS2KBD_KEYMAP_SIZE];
119//static struct fileio_driver kbd_fdriver;
120u8 keyModValue[8] = { 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 };
121int repeat_tid;
122int eventid; /* Id of the repeat event */
123
124int _start (int argc, char *argv[])
125{
126 (void)argc;
127 (void)argv;
128
129 ps2kbd_init();
130
131 printf("PS2KBD - USB Keyboard Library\n");
132
133 return MODULE_RESIDENT_END;
134}
135
136int ps2kbd_probe(int devId)
137
138{
143 //UsbStringDescriptor *str;
144
145 if(dev_count >= PS2KBD_MAXDEV)
146 {
147 printf("ERROR: Maximum keyboard devices reached\n");
148 return 0;
149 }
150
151 //printf("PS2Kbd_probe devId %d\n", devId);
152
153 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */
154 if(!dev)
155 {
156 printf("ERROR: Couldn't get device descriptor\n");
157 return 0;
158 }
159
160 //printf("Device class %d, Size %d, Man %d, Product %d Cpnfigurations %d\n", dev->bDeviceClass, dev->bMaxPacketSize0, dev->iManufacturer, dev->iProduct, dev->bNumConfigurations);
161 /* Check that the device class is specified in the interfaces and it has at least one configuration */
162 if((dev->bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->bNumConfigurations < 1))
163 {
164 //printf("This is not the droid you're looking for\n");
165 return 0;
166 }
167
168 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
169 if(!conf)
170 {
171 printf("ERROR: Couldn't get configuration descriptor\n");
172 return 0;
173 }
174 //printf("Config Length %d Total %d Interfaces %d\n", conf->bLength, conf->wTotalLength, conf->bNumInterfaces);
175
176 if((conf->bNumInterfaces < 1) || (conf->wTotalLength < (sizeof(UsbConfigDescriptor) + sizeof(UsbInterfaceDescriptor))))
177 {
178 printf("ERROR: No interfaces available\n");
179 return 0;
180 }
181
182 intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */
183/* printf("Interface Length %d Endpoints %d Class %d Sub %d Proto %d\n", intf->bLength, */
184/* intf->bNumEndpoints, intf->bInterfaceClass, intf->bInterfaceSubClass, */
185/* intf->bInterfaceProtocol); */
186
187 if((intf->bInterfaceClass != USB_CLASS_HID) || (intf->bInterfaceSubClass != USB_SUBCLASS_BOOT) ||
188 (intf->bInterfaceProtocol != USB_HIDPROTO_KEYBOARD) || (intf->bNumEndpoints < 1))
189
190 {
191 //printf("We came, we saw, we told it to fuck off\n");
192 return 0;
193 }
194
195 endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength);
196 endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */
197
198 //printf("Endpoint 1 Addr %d, Attr %d, MaxPacket %d\n", endp->bEndpointAddress, endp->bmAttributes, endp->wMaxPacketSizeLB);
199
200 if(((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) ||
201 ((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN))
202 {
203 printf("ERROR: Endpoint not interrupt type and/or an input\n");
204 return 0;
205 }
206
207 printf("PS2KBD: Found a keyboard device\n");
208
209 return 1;
210}
211
212int ps2kbd_connect(int devId)
213
214{
215 /* Assume we can only get here if we have already checked the device is kosher */
216
221 kbd_dev *currDev;
222 int devLoop;
223
224 //printf("PS2Kbd_connect devId %d\n", devId);
225
226 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */
227 if(!dev)
228 {
229 printf("ERROR: Couldn't get device descriptor\n");
230 return 1;
231 }
232
233 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
234 if(!conf)
235 {
236 printf("ERROR: Couldn't get configuration descriptor\n");
237 return 1;
238 }
239
240 intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */
241 endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength);
242 endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */
243
244 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
245 {
246 if(devices[devLoop] == NULL)
247 {
248 break;
249 }
250 }
251
252 if(devLoop == PS2KBD_MAXDEV)
253 {
254 /* How the f*** did we end up here ??? */
255 printf("ERROR: Device Weirdness!!\n");
256 return 1;
257 }
258
259 currDev = (kbd_dev *) AllocSysMemory(0, sizeof(kbd_dev), NULL);
260 if(!currDev)
261 {
262 printf("ERROR: Couldn't allocate a device point for the kbd\n");
263 return 1;
264 }
265
266 devices[devLoop] = currDev;
267 memset(currDev, 0, sizeof(kbd_dev));
268 currDev->configEndp = sceUsbdOpenPipe(devId, NULL);
269 currDev->dataEndp = sceUsbdOpenPipe(devId, endp);
270 currDev->packetSize = endp->wMaxPacketSizeLB | ((int) endp->wMaxPacketSizeHB << 8);
271 currDev->eventmask = (1 << devLoop);
272 if((unsigned int)(currDev->packetSize) > sizeof(kbd_data_recv))
273 {
274 currDev->packetSize = sizeof(kbd_data_recv);
275 }
276
277 if(dev->iManufacturer != 0)
278 {
279 usb_getstring(currDev->configEndp, dev->iManufacturer, "Keyboard Manufacturer");
280 }
281
282 if(dev->iProduct != 0)
283 {
284 usb_getstring(currDev->configEndp, dev->iProduct, "Keyboard Product");
285 }
286
287 currDev->devId = devId;
288 currDev->interfaceNo = intf->bInterfaceNumber;
289 currDev->ledStatus = 0;
290
291 sceUsbdSetPrivateData(devId, currDev); /* Set the index for the device data */
292
293 //printf("Configuration value %d\n", conf->bConfigurationValue);
294 sceUsbdSetConfiguration(currDev->configEndp, conf->bConfigurationValue, ps2kbd_config_set, currDev);
295
296 dev_count++; /* Increment device count */
297 printf("PS2KBD: Connected device\n");
298
299 return 0;
300}
301
302int ps2kbd_disconnect(int devId)
303
304{
305 int devLoop;
306 //printf("PS2Kbd_disconnect devId %d\n", devId);
307
308 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
309 {
310 if((devices[devLoop]) && (devices[devLoop]->devId == devId))
311 {
312 dev_count--;
313 FreeSysMemory(devices[devLoop]);
314 devices[devLoop] = NULL;
315 printf("PS2KBD: Disconnected device\n");
316 break;
317 }
318 }
319
320 return 0;
321}
322
323typedef struct _string_descriptor
324
325{
326 u8 buf[200];
327 char *desc;
329
330void ps2kbd_getstring_set(int resultCode, int bytes, void *arg)
331
332{
334 string_descriptor *strBuf = (string_descriptor *) arg;
335
336/* printf("=========getstring=========\n"); */
337
338/* printf("PS2KEYBOARD: GET_DESCRIPTOR res %d, bytes %d, arg %p\n", resultCode, bytes, arg); */
339
340 if(resultCode == USB_RC_OK)
341 {
342 char string[50];
343 int strLoop;
344
345 memset(string, 0, 50);
346 for(strLoop = 0; strLoop < ((bytes - 2) / 2); strLoop++)
347 {
348 string[strLoop] = str->wData[strLoop] & 0xFF;
349 }
350 printf("PS2KBD %s: %s\n", strBuf->desc, string);
351 }
352
353 FreeSysMemory(arg);
354}
355
356void usb_getstring(int endp, int index, char *desc)
357
358{
359 u8 *data;
361
362 data = (u8 *) AllocSysMemory(0, sizeof(string_descriptor), NULL);
363 str = (string_descriptor *) data;
364
365 if(data != NULL)
366 {
367 int ret;
368
369 str->desc = desc;
370 ret = sceUsbdControlTransfer(endp, 0x80, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | index,
371 0x0409, sizeof(string_descriptor) - 4, data, ps2kbd_getstring_set, data);
372 if(ret != USB_RC_OK)
373 {
374 printf("PS2KBD: Error sending string descriptor request\n");
375 FreeSysMemory(data);
376 }
377 }
378}
379
380void ps2kbd_config_set(int resultCode, int bytes, void *arg)
381 /* Called when we have finished choosing our configuration */
382
383{
384 kbd_dev *dev;
385
386 if(resultCode != USB_RC_OK)
387 {
388 printf("PS2KEYBOARD: Configuration set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
389 return;
390 }
391
392 //printf("PS2KEYBOARD: Configuration set res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
393 /* Do a interrupt data transfer */
394
395 dev = (kbd_dev *) arg;
396 if(dev != NULL)
397 {
398 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_IDLE, 0, dev->interfaceNo, 0, NULL, ps2kbd_idlemode_set, arg);
399 }
400}
401
402void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg)
403
404{
405 kbd_dev *dev;
406
407
408
409 if(resultCode != USB_RC_OK)
410 {
411 printf("PS2KBD: Idlemode set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
412 return;
413 }
414
415 dev = (kbd_dev *) arg;
416 if(dev != NULL)
417 {
418 sceUsbdInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg);
419 }
420}
421
422void ps2kbd_led_set(int resultCode, int bytes, void *arg)
423
424{
425 (void)resultCode;
426 (void)bytes;
427 (void)arg;
428
429 //printf("LED Set\n");
430}
431
432void ps2kbd_build_uniquekeys(u8 *res, const u8 *new, const u8 *old)
433
434 /* Builds a list of unique keys */
435
436{
437 int loopNew, loopOld;
438 int loopRes = 0;
439 int foundKey;
440
441 for(loopNew = 0; loopNew < PS2KBD_MAXKEYS; loopNew++)
442 {
443 if(new[loopNew] != 0)
444 {
445 foundKey = 0;
446 for(loopOld = 0; loopOld < PS2KBD_MAXKEYS; loopOld++)
447 {
448 if(new[loopNew] == old[loopOld])
449 {
450 foundKey = 1;
451 break;
452 }
453 }
454 if(!foundKey)
455 {
456 res[loopRes++] = new[loopNew];
457 }
458 }
459 }
460}
461
462u32 ps2kbd_repeathandler(void *arg)
463
464{
465 kbd_dev *dev = arg;
467 //printf("Repeat handler\n");
468
469 iSetEventFlag(eventid, dev->eventmask);
470
471 USec2SysClock(kbd_repeatrate * 1000, &t);
472 iSetAlarm(&t, (void *)ps2kbd_repeathandler, arg);
473
474 return t.hi;
475}
476
477void ps2kbd_getkeys(u8 keyMods, u8 ledStatus, const u8 *keys, kbd_dev *dev)
478
479{
480 int loopKey;
481 int tempPos = 0;
482 int byteCount = 0;
483 u8 currChars[2];
484
485 if(lineStartP < lineEndP)
486 {
487 tempPos = lineStartP + lineSize;
488 }
489 else
490 {
491 tempPos = lineStartP;
492 }
493
494 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
495 {
496 u8 currKey = keys[loopKey];
497
498 currChars[0] = 0;
499 currChars[1] = 0;
500
501 if(lineEndP == (u32)(tempPos - 1))
502 {
503 break;
504 }
505
506 if(currKey) /* If this is a valid key */
507 {
508 if((currKey >= USB_KEYB_NUMPAD_START) && (currKey <= USB_KEYB_NUMPAD_END))
509 /* Handle numpad specially */
510 {
511 if(ledStatus & PS2KBD_LED_NUMLOCK)
512 {
513 if(keymap[currKey])
514 {
515 currChars[0] = keymap[currKey];
516 }
517 }
518 else
519 {
520 if(special_keys[currKey])
521 {
522 currChars[0] = PS2KBD_ESCAPE_KEY;
523 currChars[1] = special_keys[currKey];
524 }
525 else if(keymap[currKey] != '5') /* Make sure this isnt a 5 key :) */
526 {
527 currChars[0] = keymap[currKey];
528 }
529 }
530 }
531 else if(special_keys[currKey]) /* This is a special key */
532 {
533 currChars[0] = PS2KBD_ESCAPE_KEY;
534 currChars[1] = special_keys[currKey];
535 }
536 else if(keyMods & PS2KBD_CTRL) /* CTRL */
537 {
538 if(control_map[currKey])
539 {
540 currChars[0] = control_map[currKey];
541 }
542 }
543 else if(keyMods & PS2KBD_ALT) /* ALT */
544 {
545 if(alt_map[currKey])
546 {
547 currChars[0] = alt_map[currKey];
548 }
549 }
550 else if(keyMods & PS2KBD_SHIFT) /* SHIFT */
551 {
552 if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey]))
553 {
554 currChars[0] = keymap[currKey];
555 }
556 else
557 {
558 currChars[0] = shiftkeymap[currKey];
559 }
560 }
561 else /* Normal key */
562 {
563 if(keymap[keys[loopKey]])
564 {
565 if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey]))
566 {
567 currChars[0] = shiftkeymap[currKey];
568 }
569 else
570 {
571 currChars[0] = keymap[currKey];
572 }
573 }
574 }
575 }
576
577 if((currChars[0] == PS2KBD_ESCAPE_KEY) && (currChars[1] != 0))
578 {
579 if(lineEndP != (u32)(tempPos - 2))
580 {
581 lineBuffer[lineEndP++] = currChars[0];
582 lineEndP %= lineSize;
583 lineBuffer[lineEndP++] = currChars[1];
584 lineEndP %= lineSize;
585 byteCount += 2;
586 }
587 dev->repeatkeys[0] = currChars[0];
588 dev->repeatkeys[1] = currChars[1];
589 }
590 else if(currChars[0] != 0)
591 {
592 lineBuffer[lineEndP++] = currChars[0];
593 lineEndP %= lineSize;
594 byteCount++;
595 dev->repeatkeys[0] = currChars[0];
596 dev->repeatkeys[1] = 0;
597 }
598 }
599
600 if(byteCount > 0)
601 {
603 /* Set alarm to do repeat rate */
604 //printf("repeatkeys %d %d\n", kbd_repeatkeys[0], kbd_repeatkeys[1]);
605 USec2SysClock(PS2KBD_REPEATWAIT * 1000, &t);
606 SetAlarm(&t, (void *)ps2kbd_repeathandler, dev);
607 }
608
609 for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema to indicate data */
610 {
611 SignalSema(bufferSema);
612 }
613
614/* lineBuffer[PS2KBD_DEFLINELEN - 1] = 0; */
615/* printf(lineBuffer); */
616 //printf("lineStart %d, lineEnd %d\n", lineStartP, lineEndP);
617}
618
619
620void ps2kbd_getkeys_raw(u8 newKeyMods, u8 oldKeyMods, const u8 *new, const u8 *old)
621
622{
623 int loopKey;
624 u8 currKey;
625 u8 keyMods = newKeyMods ^ oldKeyMods;
626 u8 keyModsMap = newKeyMods & keyMods;
627 int tempPos = 0;
628 int byteCount = 0;
629
630 if(lineStartP < lineEndP)
631 {
632 tempPos = lineStartP + lineSize;
633 }
634 else
635 {
636 tempPos = lineStartP;
637 }
638
639 for(loopKey = 0; loopKey < 8; loopKey++)
640 {
641 int currMod = (1 << loopKey);
642 if(keyMods & currMod)
643 {
644 if(lineEndP == (u32)(tempPos - 2))
645 {
646 return;
647 }
648
649 currKey = keyModValue[loopKey];
650
651 if(keyModsMap & currMod) /* If key pressed */
652 {
653 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN;
654 //printf("Key down\n");
655 }
656 else
657 {
658 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP;
659 //printf("Key up\n");
660 }
661
662 lineEndP %= lineSize;
663 lineBuffer[lineEndP++] = currKey;
664 lineEndP %= lineSize;
665 byteCount += 2;
666 //printf("Key %d\n", currKey);
667 }
668 }
669
670 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
671 {
672 if(lineEndP == (u32)(tempPos - 2))
673 {
674 return;
675 }
676
677 if(new[loopKey] != 0)
678 {
679 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN;
680 lineEndP %= lineSize;
681 lineBuffer[lineEndP++] = new[loopKey];
682 lineEndP %= lineSize;
683 byteCount += 2;
684 //printf("Key down\nKey %d\n", new[loopKey]);
685 }
686
687 }
688
689 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
690 {
691 if(lineEndP == (u32)(tempPos - 2))
692 {
693 return;
694 }
695
696 if(old[loopKey] != 0)
697 {
698 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP;
699 lineEndP %= lineSize;
700 lineBuffer[lineEndP++] = old[loopKey];
701 lineEndP %= lineSize;
702 byteCount += 2;
703 //printf("Key up\nKey %d\n", old[loopKey]);
704 }
705
706 }
707
708 for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema for the number of bytes read */
709 {
710 SignalSema(bufferSema);
711 }
712}
713
714void ps2kbd_data_recv(int resultCode, int bytes, void *arg)
715
716{
717 kbd_dev *dev;
718 int phantom;
719 int loop;
720
721 if(resultCode != USB_RC_OK)
722 {
723 printf("PS2KEYBOARD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
724 return;
725 }
726
727 //printf("PS2KBD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
728
729 dev = (kbd_dev *) arg;
730 if(dev == NULL)
731 {
732 printf("PS2KBD: dev == NULL\n");
733 return;
734 }
735
736/* printf("PS2KBD Modifiers %02X, Keys ", dev->data.mod_keys); */
737/* for(loop = 0; loop < PS2KBD_MAXKEYS; loop++) */
738/* { */
739/* printf("%02X ", dev->data.keycodes[loop]); */
740/* } */
741/* printf("\n"); */
742
743 CancelAlarm((void *)ps2kbd_repeathandler, dev); /* Make sure repeat alarm is cancelled */
744
745 /* Check for phantom states */
746 phantom = 1;
747 for(loop = 0; loop < PS2KBD_MAXKEYS; loop++)
748 {
749 if(dev->data.keycodes[loop] != 1)
750 {
751 phantom = 0;
752 break;
753 }
754 }
755
756 if(!phantom) /* If not in a phantom state */
757 {
758 u8 uniqueKeys[PS2KBD_MAXKEYS];
759 u8 missingKeys[PS2KBD_MAXKEYS];
760
761 memset(uniqueKeys, 0, PS2KBD_MAXKEYS);
762 memset(missingKeys, 0, PS2KBD_MAXKEYS);
763 ps2kbd_build_uniquekeys(uniqueKeys, dev->data.keycodes, dev->oldData.keycodes);
764 ps2kbd_build_uniquekeys(missingKeys, dev->oldData.keycodes, dev->data.keycodes);
765 /* Build new and missing key lists */
766
767/* printf("Unique keys : "); */
768/* for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */
769/* { */
770/* printf("%02X ", uniqueKeys[loopKey]); */
771/* } */
772/* printf("\n"); */
773
774/* printf("Missing keys : "); */
775/* for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */
776/* { */
777/* printf("%02X ", missingKeys[loopKey]); */
778/* } */
779/* printf("\n"); */
780
781 if(kbd_readmode == PS2KBD_READMODE_NORMAL)
782 {
783 int loopKey;
784 u8 ledStatus;
785
786 ledStatus = dev->ledStatus;
787 //printf("ledStatus %02X\n", ledStatus);
788
789 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) /* Process key codes */
790 {
791 switch(uniqueKeys[loopKey])
792 {
793 case USB_KEYB_NUMLOCK :
794 ledStatus ^= PS2KBD_LED_NUMLOCK;
795 uniqueKeys[loopKey] = 0;
796 break;
797 case USB_KEYB_CAPSLOCK :
798 ledStatus ^= PS2KBD_LED_CAPSLOCK;
799 uniqueKeys[loopKey] = 0;
800 break;
801 case USB_KEYB_SCRLOCK :
802 ledStatus ^= PS2KBD_LED_SCRLOCK;
803 uniqueKeys[loopKey] = 0;
804 break;
805 }
806 }
807
808 if(ledStatus != dev->ledStatus)
809 {
810 dev->ledStatus = ledStatus & PS2KBD_LED_MASK;
811 //printf("LEDS %02X\n", dev->ledStatus);
812 /* Call Set LEDS */
813 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200,
814 dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, arg);
815 }
816
817 WaitSema(lineSema); /* Make sure no other thread is going to manipulate the buffer */
818 ps2kbd_getkeys(dev->data.mod_keys, dev->ledStatus, uniqueKeys, dev); /* read in remaining keys */
819 SignalSema(lineSema);
820 }
821 else /* RAW Mode */
822 {
823 WaitSema(lineSema);
824 ps2kbd_getkeys_raw(dev->data.mod_keys, dev->oldData.mod_keys, uniqueKeys, missingKeys);
825 SignalSema(lineSema);
826 }
827
828 memcpy(&dev->oldData, &dev->data, sizeof(kbd_data_recv));
829 }
830
831 sceUsbdInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg);
832}
833
834void flushbuffer()
835
836{
837 iop_sema_t s;
838
839 lineStartP = 0;
840 lineEndP = 0;
841 memset(lineBuffer, 0, lineSize);
842
843 DeleteSema(bufferSema);
844 s.initial = 0;
845 s.max = lineSize;
846 s.option = 0;
847 s.attr = 0;
848 bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */
849
850 if(bufferSema <= 0)
851 {
852 printf("PS2KBD: Error creating buffer sema\n");
853 }
854}
855
856void ps2kbd_ioctl_setreadmode(u32 readmode)
857
858{
859
860 if(readmode == (u32)kbd_readmode) return;
861
862 if((readmode == PS2KBD_READMODE_NORMAL) || (readmode == PS2KBD_READMODE_RAW))
863 {
864 int devLoop;
865
866 /* Reset line buffer */
867 //printf("ioctl_setreadmode %d\n", readmode);
868 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
869 {
870 CancelAlarm((void *)ps2kbd_repeathandler, devices[devLoop]);
871 }
872
873 WaitSema(lineSema);
874 kbd_readmode = readmode;
875 flushbuffer();
876 SignalSema(lineSema);
877 }
878}
879
880void ps2kbd_ioctl_setkeymap(kbd_keymap *keymaps)
881
882{
883 //printf("ioctl_setkeymap %p\n", keymaps);
884 WaitSema(lineSema); /* Lock the input so you dont end up with weird results */
885 memcpy(keymap, keymaps->keymap, PS2KBD_KEYMAP_SIZE);
886 memcpy(shiftkeymap, keymaps->shiftkeymap, PS2KBD_KEYMAP_SIZE);
887 memcpy(keycap, keymaps->keycap, PS2KBD_KEYMAP_SIZE);
888 SignalSema(lineSema);
889}
890
891void ps2kbd_ioctl_setctrlmap(u8 *ctrlmap)
892
893{
894 //printf("ioctl_setctrlmap %p\n", ctrlmap);
895 WaitSema(lineSema);
896 memcpy(control_map, ctrlmap, PS2KBD_KEYMAP_SIZE);
897 SignalSema(lineSema);
898}
899
900void ps2kbd_ioctl_setaltmap(u8 *altmap)
901
902{
903 //printf("ioctl_setaltmap %p\n", altmap);
904 WaitSema(lineSema);
905 memcpy(alt_map, altmap, PS2KBD_KEYMAP_SIZE);
906 SignalSema(lineSema);
907}
908
909void ps2kbd_ioctl_setspecialmap(u8 *special)
910
911{
912 //printf("ioctl_setspecialmap %p\n", special);
913 WaitSema(lineSema);
914 memcpy(special_keys, special, PS2KBD_KEYMAP_SIZE);
915 SignalSema(lineSema);
916}
917
918void ps2kbd_ioctl_resetkeymap()
919 /* Reset keymap to default US variety */
920
921{
922 //printf("ioctl_resetkeymap()\n");
923 WaitSema(lineSema);
924 memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE);
925 memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE);
926 memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE);
927 memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE);
928 memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE);
929 memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE);
930 SignalSema(lineSema);
931}
932
933void ps2kbd_ioctl_flushbuffer()
934 /* Flush the internal buffer */
935
936{
937 //printf("ioctl_flushbuffer()\n");
938 WaitSema(lineSema);
939 flushbuffer();
940 SignalSema(lineSema);
941}
942
943void ps2kbd_ioctl_setleds(u8 ledStatus)
944
945{
946 int devLoop;
947 kbd_dev *dev;
948
949 //printf("ioctl_setleds %d\n", ledStatus);
950 ledStatus &= PS2KBD_LED_MASK;
951 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
952 {
953 dev = devices[devLoop];
954 if(dev)
955 {
956 if(ledStatus != dev->ledStatus)
957 {
958 dev->ledStatus = ledStatus & PS2KBD_LED_MASK;
959 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200,
960 dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, dev);
961 }
962 }
963 }
964}
965
966void ps2kbd_ioctl_setblockmode(u32 blockmode)
967
968{
969 if((blockmode == PS2KBD_BLOCKING) || (blockmode == PS2KBD_NONBLOCKING))
970 {
971 kbd_blocking = blockmode;
972 //printf("ioctl_setblockmode %d\n", blockmode);
973 }
974}
975
976void ps2kbd_ioctl_setrepeatrate(u32 rate)
977
978{
979 kbd_repeatrate = rate;
980}
981
982int fio_dummy()
983{
984 //printf("fio_dummy()\n");
985 return -EIO;
986}
987
988int fio_init(iop_device_t *driver)
989{
990 (void)driver;
991
992 //printf("fio_init()\n");
993 return 0;
994}
995
996int fio_format(iop_file_t *f)
997{
998 (void)f;
999
1000 //printf("fio_format()\n");
1001 return 0;
1002}
1003
1004int fio_open(iop_file_t *f, const char *name, int mode)
1005{
1006 (void)f;
1007 (void)mode;
1008
1009 //printf("fio_open() %s %d\n", name, mode);
1010 if(strcmp(name, PS2KBD_KBDFILE)) /* If not the keyboard file */
1011 {
1012 return -EPERM;
1013 }
1014
1015 return 0;
1016}
1017
1018int fio_read(iop_file_t *f, void *buf, int size)
1019
1020{
1021 int count = 0;
1022 char *data = (char *) buf;
1023 int ret;
1024
1025 (void)f;
1026
1027 //printf("fio_read() %p %d\n", buf, size);
1028
1029 if(kbd_readmode == PS2KBD_READMODE_RAW)
1030 {
1031 size &= ~1; /* Ensure size of a multiple of 2 */
1032 }
1033
1034 ret = PollSema(bufferSema);
1035 if(ret < 0)
1036 {
1037 if((ret == SEMA_ZERO) && (kbd_blocking == PS2KBD_BLOCKING))
1038 {
1039 //printf("Blocking\n");
1040 ret = WaitSema(bufferSema);
1041 if(ret < 0) /* Means either an error or the sema was deleted from under us */
1042 {
1043 return 0;
1044 }
1045 }
1046 else
1047 {
1048 return 0;
1049 }
1050 }
1051
1052 SignalSema(bufferSema);
1053 ret = WaitSema(lineSema);
1054 if(ret < 0) return 0;
1055
1056 while((count < size) && (lineStartP != lineEndP))
1057 {
1058 data[count] = lineBuffer[lineStartP++];
1059 lineStartP %= lineSize;
1060 count++;
1061 PollSema(bufferSema); /* Take off one count from the sema */
1062 }
1063
1064 SignalSema(lineSema);
1065/* //printf("read %d bytes\n", count); */
1066/* { */
1067/* struct t_sema_status s; */
1068
1069/* ReferSemaStatus(bufferSema, &s); */
1070/* //printf("Sema count %d\n", s.curr_count); */
1071/* } */
1072
1073 return count;
1074}
1075
1076int fio_ioctl(iop_file_t *f, int cmd, void *param)
1077
1078{
1079 (void)f;
1080
1081 //printf("fio_ioctl() %ld %d\n", cmd, *((u32 *) param));
1082 switch(cmd)
1083 {
1084 case PS2KBD_IOCTL_SETREADMODE: ps2kbd_ioctl_setreadmode(*((u32 *) param));
1085 break;
1086 case PS2KBD_IOCTL_SETKEYMAP: ps2kbd_ioctl_setkeymap((kbd_keymap *) param);
1087 break;
1088 case PS2KBD_IOCTL_SETALTMAP: ps2kbd_ioctl_setaltmap((u8 *) param);
1089 break;
1090 case PS2KBD_IOCTL_SETCTRLMAP: ps2kbd_ioctl_setctrlmap((u8 *) param);
1091 break;
1092 case PS2KBD_IOCTL_SETSPECIALMAP: ps2kbd_ioctl_setspecialmap((u8 *) param);
1093 break;
1094 case PS2KBD_IOCTL_FLUSHBUFFER: ps2kbd_ioctl_flushbuffer();
1095 break;
1096 case PS2KBD_IOCTL_SETLEDS: ps2kbd_ioctl_setleds(*(u8*) param);
1097 break;
1098 case PS2KBD_IOCTL_SETBLOCKMODE: ps2kbd_ioctl_setblockmode(*(u32 *) param);
1099 break;
1100 case PS2KBD_IOCTL_RESETKEYMAP: ps2kbd_ioctl_resetkeymap();
1101 break;
1102 case PS2KBD_IOCTL_SETREPEATRATE: ps2kbd_ioctl_setrepeatrate(*(u32 *) param);
1103 break;
1104 default : return -EPERM;
1105 }
1106
1107 return 0;
1108}
1109
1110int fio_close(iop_file_t *f)
1111
1112{
1113 (void)f;
1114
1115 //printf("fio_close()\n");
1116 return 0;
1117}
1118
1119static iop_device_ops_t fio_ops =
1120
1121 {
1122 &fio_init,
1123 (void *)&fio_dummy,
1124 &fio_format,
1125 &fio_open,
1126 &fio_close,
1127 &fio_read,
1128 (void *)&fio_dummy,
1129 (void *)&fio_dummy,
1130 &fio_ioctl,
1131 (void *)&fio_dummy,
1132 (void *)&fio_dummy,
1133 (void *)&fio_dummy,
1134 (void *)&fio_dummy,
1135 (void *)&fio_dummy,
1136 (void *)&fio_dummy,
1137 (void *)&fio_dummy,
1138 (void *)&fio_dummy,
1139 };
1140
1141static iop_device_t kbd_filedrv = {
1142 PS2KBD_FSNAME,
1143 IOP_DT_CHAR,
1144 0,
1145 "USB Keyboard FIO driver",
1146 &fio_ops,
1147};
1148
1149
1150int init_fio()
1151
1152{
1153 return AddDrv(&kbd_filedrv);
1154}
1155
1156void repeat_thread(void *arg)
1157
1158{
1159 u32 eventmask;
1160 int devLoop;
1161
1162 (void)arg;
1163
1164 for(;;)
1165 {
1166 WaitEventFlag(eventid, 0xFFFFFFFF, 0x01 | 0x10, &eventmask);
1167 //printf("Recieved event %08X\n", eventmask);
1168 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
1169 {
1170 if((eventmask & (1 << devLoop)) && (devices[devLoop]))
1171 {
1172 int tempPos = 0;
1173
1174 WaitSema(lineSema);
1175 if(lineStartP < lineEndP)
1176 {
1177 tempPos = lineStartP + lineSize;
1178 }
1179 else
1180 {
1181 tempPos = lineStartP;
1182 }
1183
1184 if((devices[devLoop]->repeatkeys[0]) && (devices[devLoop]->repeatkeys[1]))
1185 {
1186 if(lineEndP != (u32)(tempPos - 2))
1187 {
1188 lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0];
1189 lineEndP %= lineSize;
1190 lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[1];
1191 lineEndP %= lineSize;
1192 SignalSema(bufferSema);
1193 SignalSema(bufferSema);
1194 }
1195 }
1196 else if(devices[devLoop]->repeatkeys[0])
1197 {
1198 if(lineEndP != (u32)(tempPos - 1))
1199 {
1200 lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0];
1201 lineEndP %= lineSize;
1202 SignalSema(bufferSema);
1203 }
1204 }
1205
1206 SignalSema(lineSema);
1207 }
1208 }
1209 }
1210}
1211
1212int init_repeatthread()
1213 /* Creates a thread to handle key repeats */
1214
1215{
1216 iop_thread_t param;
1218
1219 event.attr = 0;
1220 event.option = 0;
1221 event.bits = 0;
1222 eventid = CreateEventFlag(&event);
1223
1224 param.attr = TH_C;
1225 param.thread = repeat_thread;
1226 param.priority = 40;
1227 param.stacksize = 0x800;
1228 param.option = 0;
1229
1230 repeat_tid = CreateThread(&param);
1231 if (repeat_tid > 0) {
1232 StartThread(repeat_tid, 0);
1233 return 0;
1234 }
1235 else
1236 {
1237 return 1;
1238 }
1239}
1240
1241int ps2kbd_init()
1242
1243{
1244 int ret;
1245 iop_sema_t s;
1246
1247 s.initial = 1;
1248 s.max = 1;
1249 s.option = 0;
1250 s.attr = 0;
1251 lineSema = CreateSema(&s);
1252 if(lineSema <= 0)
1253 {
1254 printf("PS2KBD: Error creating sema\n");
1255 return 1;
1256 }
1257
1258 s.initial = 0;
1259 s.max = PS2KBD_DEFLINELEN;
1260 s.option = 0;
1261 s.attr = 0;
1262 bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */
1263 if(bufferSema <= 0)
1264 {
1265 printf("PS2KBD: Error creating buffer sema\n");
1266 return 1;
1267 }
1268
1269 lineBuffer = (u8 *) AllocSysMemory(0, PS2KBD_DEFLINELEN, NULL);
1270 if(lineBuffer == NULL)
1271 {
1272 printf("PS2KBD: Error allocating line buffer\n");
1273 return 1;
1274 }
1275 lineStartP = 0;
1276 lineEndP = 0;
1277 lineSize = PS2KBD_DEFLINELEN;
1278 memset(lineBuffer, 0, PS2KBD_DEFLINELEN);
1279
1280 memset(devices, 0, sizeof(kbd_dev *) * PS2KBD_MAXDEV);
1281 dev_count = 0;
1282 kbd_blocking = PS2KBD_NONBLOCKING;
1283 kbd_readmode = PS2KBD_READMODE_NORMAL;
1284 kbd_repeatrate = PS2KBD_DEFREPEATRATE;
1285 memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE);
1286 memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE);
1287 memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE);
1288 memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE);
1289 memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE);
1290 memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE);
1291
1292 ret = init_fio();
1293 if(ret < 0)
1294 {
1295 printf("PS2KBD: Error adding ioman driver\n");
1296 return 1;
1297 }
1298 //printf("ps2kbd AddDrv [%d]\n", ret);
1299 init_repeatthread();
1300
1301 ret = sceUsbdRegisterLdd(&kbd_driver);
1302 if(ret != USB_RC_OK)
1303 {
1304 printf("PS2KBD: Error registering USB devices\n");
1305 return 1;
1306 }
1307
1308 //printf("sceUsbdRegisterLdd %d\n", ret);
1309
1310 return 0;
1311}
#define PS2KBD_IOCTL_SETREPEATRATE
Definition ps2kbd.h:87
#define PS2KBD_IOCTL_SETALTMAP
Definition ps2kbd.h:93
#define PS2KBD_IOCTL_SETLEDS
Definition ps2kbd.h:85
#define PS2KBD_IOCTL_SETKEYMAP
Definition ps2kbd.h:89
#define PS2KBD_IOCTL_SETREADMODE
Definition ps2kbd.h:83
#define PS2KBD_IOCTL_SETSPECIALMAP
Definition ps2kbd.h:95
#define PS2KBD_IOCTL_SETBLOCKMODE
Definition ps2kbd.h:97
#define PS2KBD_IOCTL_SETCTRLMAP
Definition ps2kbd.h:91
#define PS2KBD_IOCTL_FLUSHBUFFER
Definition ps2kbd.h:99
#define PS2KBD_IOCTL_RESETKEYMAP
Definition ps2kbd.h:101
#define EIO
Definition errno.h:29
#define EPERM
Definition errno.h:21
#define PS2KBD_REPEATWAIT
Definition ps2kbd.c:49
u8 keymap[PS2KBD_KEYMAP_SIZE]
Definition ps2kbd.c:111
u8 keycap[PS2KBD_KEYMAP_SIZE]
Definition ps2kbd.c:115
kbd_data_recv data
Definition ps2kbd.c:93
u8 ledStatus
Definition ps2kbd.c:90
u8 shiftkeymap[PS2KBD_KEYMAP_SIZE]
Definition ps2kbd.c:113
#define USB_KEYB_NUMLOCK
Definition ps2kbd.c:51
int interfaceNo
Definition ps2kbd.c:86
kbd_dev * devices[PS2KBD_MAXDEV]
Definition ps2kbd.c:102
#define USB_RC_OK
Definition usbd.h:238
u32 count
start sector of fragmented bd/file