34#define MODNAME "PS2 USB keyboard driver"
38#define PS2KBD_VERSION 0x100
40#define USB_SUBCLASS_BOOT 1
41#define USB_HIDPROTO_KEYBOARD 1
43#define PS2KBD_MAXDEV 2
44#define PS2KBD_MAXKEYS 6
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
55#define USB_KEYB_NUMPAD_START 0x54
56#define USB_KEYB_NUMPAD_END 0x63
59#define SEMA_DELETED -425
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);
75 u8 keycodes[PS2KBD_MAXKEYS];
104sceUsbdLddOps kbd_driver = { NULL, NULL,
"PS2Kbd", ps2kbd_probe, ps2kbd_connect, ps2kbd_disconnect, 0, 0, 0, 0, 0, NULL };
106u32 lineStartP, lineEndP;
116u8 special_keys[PS2KBD_KEYMAP_SIZE];
117u8 control_map[PS2KBD_KEYMAP_SIZE];
118u8 alt_map[PS2KBD_KEYMAP_SIZE];
120u8 keyModValue[8] = { 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 };
124int _start (
int argc,
char *argv[])
131 printf(
"PS2KBD - USB Keyboard Library\n");
133 return MODULE_RESIDENT_END;
136int ps2kbd_probe(
int devId)
145 if(dev_count >= PS2KBD_MAXDEV)
147 printf(
"ERROR: Maximum keyboard devices reached\n");
153 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE);
156 printf(
"ERROR: Couldn't get device descriptor\n");
162 if((dev->bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->bNumConfigurations < 1))
168 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
171 printf(
"ERROR: Couldn't get configuration descriptor\n");
178 printf(
"ERROR: No interfaces available\n");
187 if((intf->bInterfaceClass != USB_CLASS_HID) || (intf->bInterfaceSubClass != USB_SUBCLASS_BOOT) ||
188 (intf->bInterfaceProtocol != USB_HIDPROTO_KEYBOARD) || (intf->bNumEndpoints < 1))
200 if(((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) ||
201 ((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN))
203 printf(
"ERROR: Endpoint not interrupt type and/or an input\n");
207 printf(
"PS2KBD: Found a keyboard device\n");
212int ps2kbd_connect(
int devId)
226 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE);
229 printf(
"ERROR: Couldn't get device descriptor\n");
233 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
236 printf(
"ERROR: Couldn't get configuration descriptor\n");
244 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
252 if(devLoop == PS2KBD_MAXDEV)
255 printf(
"ERROR: Device Weirdness!!\n");
262 printf(
"ERROR: Couldn't allocate a device point for the kbd\n");
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))
277 if(dev->iManufacturer != 0)
279 usb_getstring(currDev->configEndp, dev->iManufacturer,
"Keyboard Manufacturer");
282 if(dev->iProduct != 0)
284 usb_getstring(currDev->configEndp, dev->iProduct,
"Keyboard Product");
287 currDev->devId = devId;
291 sceUsbdSetPrivateData(devId, currDev);
294 sceUsbdSetConfiguration(currDev->configEndp, conf->bConfigurationValue, ps2kbd_config_set, currDev);
297 printf(
"PS2KBD: Connected device\n");
302int ps2kbd_disconnect(
int devId)
308 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
313 FreeSysMemory(
devices[devLoop]);
315 printf(
"PS2KBD: Disconnected device\n");
330void ps2kbd_getstring_set(
int resultCode,
int bytes,
void *arg)
345 memset(
string, 0, 50);
346 for(strLoop = 0; strLoop < ((bytes - 2) / 2); strLoop++)
348 string[strLoop] = str->wData[strLoop] & 0xFF;
350 printf(
"PS2KBD %s: %s\n", strBuf->desc,
string);
356void usb_getstring(
int endp,
int index,
char *desc)
370 ret = sceUsbdControlTransfer(endp, 0x80, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | index,
374 printf(
"PS2KBD: Error sending string descriptor request\n");
380void ps2kbd_config_set(
int resultCode,
int bytes,
void *arg)
388 printf(
"PS2KEYBOARD: Configuration set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
398 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_IDLE, 0, dev->
interfaceNo, 0, NULL, ps2kbd_idlemode_set, arg);
402void ps2kbd_idlemode_set(
int resultCode,
int bytes,
void *arg)
411 printf(
"PS2KBD: Idlemode set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
418 sceUsbdInterruptTransfer(dev->dataEndp, &dev->
data, dev->packetSize, ps2kbd_data_recv, arg);
422void ps2kbd_led_set(
int resultCode,
int bytes,
void *arg)
432void ps2kbd_build_uniquekeys(u8 *res,
const u8 *
new,
const u8 *old)
437 int loopNew, loopOld;
441 for(loopNew = 0; loopNew < PS2KBD_MAXKEYS; loopNew++)
443 if(
new[loopNew] != 0)
446 for(loopOld = 0; loopOld < PS2KBD_MAXKEYS; loopOld++)
448 if(
new[loopNew] == old[loopOld])
456 res[loopRes++] =
new[loopNew];
462u32 ps2kbd_repeathandler(
void *arg)
469 iSetEventFlag(eventid, dev->eventmask);
471 USec2SysClock(kbd_repeatrate * 1000, &t);
472 iSetAlarm(&t, (
void *)ps2kbd_repeathandler, arg);
477void ps2kbd_getkeys(u8 keyMods, u8 ledStatus,
const u8 *keys,
kbd_dev *dev)
485 if(lineStartP < lineEndP)
487 tempPos = lineStartP + lineSize;
491 tempPos = lineStartP;
494 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
496 u8 currKey = keys[loopKey];
501 if(lineEndP == (u32)(tempPos - 1))
508 if((currKey >= USB_KEYB_NUMPAD_START) && (currKey <= USB_KEYB_NUMPAD_END))
511 if(ledStatus & PS2KBD_LED_NUMLOCK)
515 currChars[0] =
keymap[currKey];
520 if(special_keys[currKey])
522 currChars[0] = PS2KBD_ESCAPE_KEY;
523 currChars[1] = special_keys[currKey];
525 else if(
keymap[currKey] !=
'5')
527 currChars[0] =
keymap[currKey];
531 else if(special_keys[currKey])
533 currChars[0] = PS2KBD_ESCAPE_KEY;
534 currChars[1] = special_keys[currKey];
536 else if(keyMods & PS2KBD_CTRL)
538 if(control_map[currKey])
540 currChars[0] = control_map[currKey];
543 else if(keyMods & PS2KBD_ALT)
547 currChars[0] = alt_map[currKey];
550 else if(keyMods & PS2KBD_SHIFT)
552 if((ledStatus & PS2KBD_LED_CAPSLOCK) && (
keycap[currKey]))
554 currChars[0] =
keymap[currKey];
565 if((ledStatus & PS2KBD_LED_CAPSLOCK) && (
keycap[currKey]))
571 currChars[0] =
keymap[currKey];
577 if((currChars[0] == PS2KBD_ESCAPE_KEY) && (currChars[1] != 0))
579 if(lineEndP != (u32)(tempPos - 2))
581 lineBuffer[lineEndP++] = currChars[0];
582 lineEndP %= lineSize;
583 lineBuffer[lineEndP++] = currChars[1];
584 lineEndP %= lineSize;
587 dev->repeatkeys[0] = currChars[0];
588 dev->repeatkeys[1] = currChars[1];
590 else if(currChars[0] != 0)
592 lineBuffer[lineEndP++] = currChars[0];
593 lineEndP %= lineSize;
595 dev->repeatkeys[0] = currChars[0];
596 dev->repeatkeys[1] = 0;
606 SetAlarm(&t, (
void *)ps2kbd_repeathandler, dev);
609 for(loopKey = 0; loopKey < byteCount; loopKey++)
611 SignalSema(bufferSema);
620void ps2kbd_getkeys_raw(u8 newKeyMods, u8 oldKeyMods,
const u8 *
new,
const u8 *old)
625 u8 keyMods = newKeyMods ^ oldKeyMods;
626 u8 keyModsMap = newKeyMods & keyMods;
630 if(lineStartP < lineEndP)
632 tempPos = lineStartP + lineSize;
636 tempPos = lineStartP;
639 for(loopKey = 0; loopKey < 8; loopKey++)
641 int currMod = (1 << loopKey);
642 if(keyMods & currMod)
644 if(lineEndP == (u32)(tempPos - 2))
649 currKey = keyModValue[loopKey];
651 if(keyModsMap & currMod)
653 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN;
658 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP;
662 lineEndP %= lineSize;
663 lineBuffer[lineEndP++] = currKey;
664 lineEndP %= lineSize;
670 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
672 if(lineEndP == (u32)(tempPos - 2))
677 if(
new[loopKey] != 0)
679 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN;
680 lineEndP %= lineSize;
681 lineBuffer[lineEndP++] =
new[loopKey];
682 lineEndP %= lineSize;
689 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
691 if(lineEndP == (u32)(tempPos - 2))
696 if(old[loopKey] != 0)
698 lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP;
699 lineEndP %= lineSize;
700 lineBuffer[lineEndP++] = old[loopKey];
701 lineEndP %= lineSize;
708 for(loopKey = 0; loopKey < byteCount; loopKey++)
710 SignalSema(bufferSema);
714void ps2kbd_data_recv(
int resultCode,
int bytes,
void *arg)
723 printf(
"PS2KEYBOARD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
732 printf(
"PS2KBD: dev == NULL\n");
743 CancelAlarm((
void *)ps2kbd_repeathandler, dev);
747 for(loop = 0; loop < PS2KBD_MAXKEYS; loop++)
749 if(dev->
data.keycodes[loop] != 1)
758 u8 uniqueKeys[PS2KBD_MAXKEYS];
759 u8 missingKeys[PS2KBD_MAXKEYS];
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);
781 if(kbd_readmode == PS2KBD_READMODE_NORMAL)
789 for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++)
791 switch(uniqueKeys[loopKey])
794 ledStatus ^= PS2KBD_LED_NUMLOCK;
795 uniqueKeys[loopKey] = 0;
797 case USB_KEYB_CAPSLOCK :
798 ledStatus ^= PS2KBD_LED_CAPSLOCK;
799 uniqueKeys[loopKey] = 0;
801 case USB_KEYB_SCRLOCK :
802 ledStatus ^= PS2KBD_LED_SCRLOCK;
803 uniqueKeys[loopKey] = 0;
810 dev->
ledStatus = ledStatus & PS2KBD_LED_MASK;
813 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200,
818 ps2kbd_getkeys(dev->
data.mod_keys, dev->
ledStatus, uniqueKeys, dev);
819 SignalSema(lineSema);
824 ps2kbd_getkeys_raw(dev->
data.mod_keys, dev->oldData.mod_keys, uniqueKeys, missingKeys);
825 SignalSema(lineSema);
831 sceUsbdInterruptTransfer(dev->dataEndp, &dev->
data, dev->packetSize, ps2kbd_data_recv, arg);
841 memset(lineBuffer, 0, lineSize);
843 DeleteSema(bufferSema);
848 bufferSema = CreateSema(&s);
852 printf(
"PS2KBD: Error creating buffer sema\n");
856void ps2kbd_ioctl_setreadmode(u32 readmode)
860 if(readmode == (u32)kbd_readmode)
return;
862 if((readmode == PS2KBD_READMODE_NORMAL) || (readmode == PS2KBD_READMODE_RAW))
868 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
870 CancelAlarm((
void *)ps2kbd_repeathandler,
devices[devLoop]);
874 kbd_readmode = readmode;
876 SignalSema(lineSema);
880void ps2kbd_ioctl_setkeymap(
kbd_keymap *keymaps)
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);
891void ps2kbd_ioctl_setctrlmap(u8 *ctrlmap)
896 memcpy(control_map, ctrlmap, PS2KBD_KEYMAP_SIZE);
897 SignalSema(lineSema);
900void ps2kbd_ioctl_setaltmap(u8 *altmap)
905 memcpy(alt_map, altmap, PS2KBD_KEYMAP_SIZE);
906 SignalSema(lineSema);
909void ps2kbd_ioctl_setspecialmap(u8 *special)
914 memcpy(special_keys, special, PS2KBD_KEYMAP_SIZE);
915 SignalSema(lineSema);
918void ps2kbd_ioctl_resetkeymap()
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);
933void ps2kbd_ioctl_flushbuffer()
940 SignalSema(lineSema);
943void ps2kbd_ioctl_setleds(u8 ledStatus)
950 ledStatus &= PS2KBD_LED_MASK;
951 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
958 dev->
ledStatus = ledStatus & PS2KBD_LED_MASK;
959 sceUsbdControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200,
966void ps2kbd_ioctl_setblockmode(u32 blockmode)
969 if((blockmode == PS2KBD_BLOCKING) || (blockmode == PS2KBD_NONBLOCKING))
971 kbd_blocking = blockmode;
976void ps2kbd_ioctl_setrepeatrate(u32 rate)
979 kbd_repeatrate = rate;
1004int fio_open(
iop_file_t *f,
const char *name,
int mode)
1010 if(strcmp(name, PS2KBD_KBDFILE))
1018int fio_read(
iop_file_t *f,
void *buf,
int size)
1022 char *data = (
char *) buf;
1029 if(kbd_readmode == PS2KBD_READMODE_RAW)
1034 ret = PollSema(bufferSema);
1037 if((ret == SEMA_ZERO) && (kbd_blocking == PS2KBD_BLOCKING))
1040 ret = WaitSema(bufferSema);
1052 SignalSema(bufferSema);
1053 ret = WaitSema(lineSema);
1054 if(ret < 0)
return 0;
1056 while((
count < size) && (lineStartP != lineEndP))
1058 data[
count] = lineBuffer[lineStartP++];
1059 lineStartP %= lineSize;
1061 PollSema(bufferSema);
1064 SignalSema(lineSema);
1076int fio_ioctl(
iop_file_t *f,
int cmd,
void *param)
1104 default :
return -
EPERM;
1145 "USB Keyboard FIO driver",
1153 return AddDrv(&kbd_filedrv);
1156void repeat_thread(
void *arg)
1166 WaitEventFlag(eventid, 0xFFFFFFFF, 0x01 | 0x10, &eventmask);
1168 for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++)
1170 if((eventmask & (1 << devLoop)) && (
devices[devLoop]))
1175 if(lineStartP < lineEndP)
1177 tempPos = lineStartP + lineSize;
1181 tempPos = lineStartP;
1184 if((
devices[devLoop]->repeatkeys[0]) && (
devices[devLoop]->repeatkeys[1]))
1186 if(lineEndP != (u32)(tempPos - 2))
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);
1196 else if(
devices[devLoop]->repeatkeys[0])
1198 if(lineEndP != (u32)(tempPos - 1))
1200 lineBuffer[lineEndP++] =
devices[devLoop]->repeatkeys[0];
1201 lineEndP %= lineSize;
1202 SignalSema(bufferSema);
1206 SignalSema(lineSema);
1212int init_repeatthread()
1222 eventid = CreateEventFlag(&
event);
1225 param.thread = repeat_thread;
1226 param.priority = 40;
1227 param.stacksize = 0x800;
1230 repeat_tid = CreateThread(¶m);
1231 if (repeat_tid > 0) {
1232 StartThread(repeat_tid, 0);
1251 lineSema = CreateSema(&s);
1254 printf(
"PS2KBD: Error creating sema\n");
1259 s.max = PS2KBD_DEFLINELEN;
1262 bufferSema = CreateSema(&s);
1265 printf(
"PS2KBD: Error creating buffer sema\n");
1269 lineBuffer = (u8 *) AllocSysMemory(0, PS2KBD_DEFLINELEN, NULL);
1270 if(lineBuffer == NULL)
1272 printf(
"PS2KBD: Error allocating line buffer\n");
1277 lineSize = PS2KBD_DEFLINELEN;
1278 memset(lineBuffer, 0, PS2KBD_DEFLINELEN);
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);
1295 printf(
"PS2KBD: Error adding ioman driver\n");
1299 init_repeatthread();
1301 ret = sceUsbdRegisterLdd(&kbd_driver);
1304 printf(
"PS2KBD: Error registering USB devices\n");
#define PS2KBD_IOCTL_SETREPEATRATE
#define PS2KBD_IOCTL_SETALTMAP
#define PS2KBD_IOCTL_SETLEDS
#define PS2KBD_IOCTL_SETKEYMAP
#define PS2KBD_IOCTL_SETREADMODE
#define PS2KBD_IOCTL_SETSPECIALMAP
#define PS2KBD_IOCTL_SETBLOCKMODE
#define PS2KBD_IOCTL_SETCTRLMAP
#define PS2KBD_IOCTL_FLUSHBUFFER
#define PS2KBD_IOCTL_RESETKEYMAP
#define PS2KBD_REPEATWAIT
u8 keymap[PS2KBD_KEYMAP_SIZE]
u8 keycap[PS2KBD_KEYMAP_SIZE]
u8 shiftkeymap[PS2KBD_KEYMAP_SIZE]
kbd_dev * devices[PS2KBD_MAXDEV]
u32 count
start sector of fragmented bd/file