00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <ipc/irc.h>
00038 #include <async.h>
00039 #include <sysinfo.h>
00040 #include <kbd.h>
00041 #include <kbd_port.h>
00042 #include <sun.h>
00043 #include <sys/types.h>
00044 #include <ddi.h>
00045 #include <errno.h>
00046
00047 #define CHAN_A_STATUS 4
00048 #define CHAN_A_DATA 6
00049
00050 #define RR0_RCA 1
00051
00052 static irq_cmd_t z8530_cmds[] = {
00053 {
00054 .cmd = CMD_PIO_READ_8,
00055 .addr = (void *) 0,
00056 .dstarg = 1
00057 },
00058 {
00059 .cmd = CMD_BTEST,
00060 .value = RR0_RCA,
00061 .srcarg = 1,
00062 .dstarg = 3
00063 },
00064 {
00065 .cmd = CMD_PREDICATE,
00066 .value = 2,
00067 .srcarg = 3
00068 },
00069 {
00070 .cmd = CMD_PIO_READ_8,
00071 .addr = (void *) 0,
00072 .dstarg = 2
00073 },
00074 {
00075 .cmd = CMD_ACCEPT
00076 }
00077 };
00078
00079 irq_code_t z8530_kbd = {
00080 sizeof(z8530_cmds) / sizeof(irq_cmd_t),
00081 z8530_cmds
00082 };
00083
00084 static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
00085
00086 int z8530_port_init(void)
00087 {
00088 sysarg_t kaddr;
00089 if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
00090 return -1;
00091
00092 sysarg_t inr;
00093 if (sysinfo_get_value("kbd.inr", &inr) != EOK)
00094 return -1;
00095
00096 z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
00097 z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
00098
00099 async_set_interrupt_received(z8530_irq_handler);
00100 register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
00101
00102 return 0;
00103 }
00104
00105 static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
00106 {
00107 int scan_code = IPC_GET_ARG2(*call);
00108 kbd_push_scancode(scan_code);
00109
00110 if (irc_service)
00111 async_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
00112 IPC_GET_IMETHOD(*call));
00113 }
00114