source: mainline/uspace/srv/kbd/port/i8042.c@ 3636964

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3636964 was 84afc7b, checked in by Martin Decky <martin@…>, 16 years ago

as kernel little brother drivers are not needed anymore, the device numbers do not have to be correlated between kernel and uspace in any way
introduce new syscall sys_device_assign_devno() for generating system-wide unique device numbers for uspace

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Jakub Jermar
3 * Copyright (c) 2006 Josef Cejka
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup kbd_port
31 * @ingroup kbd
32 * @{
33 */
34/** @file
35 * @brief i8042 port driver.
36 */
37
38#include <ddi.h>
39#include <libarch/ddi.h>
40#include <ipc/ipc.h>
41#include <async.h>
42#include <unistd.h>
43#include <sysinfo.h>
44#include <kbd_port.h>
45#include <kbd.h>
46#include <ddi.h>
47#include "i8042.h"
48
49/* Interesting bits for status register */
50#define i8042_OUTPUT_FULL 0x1
51#define i8042_INPUT_FULL 0x2
52#define i8042_MOUSE_DATA 0x20
53
54/* Command constants */
55#define i8042_CMD_KBD 0x60
56#define i8042_CMD_MOUSE 0xd4
57
58/* Keyboard cmd byte */
59#define i8042_KBD_IE 0x1
60#define i8042_MOUSE_IE 0x2
61#define i8042_KBD_DISABLE 0x10
62#define i8042_MOUSE_DISABLE 0x20
63#define i8042_KBD_TRANSLATE 0x40
64
65/* Mouse constants */
66#define MOUSE_OUT_INIT 0xf4
67#define MOUSE_ACK 0xfa
68
69static irq_cmd_t i8042_cmds[] = {
70 {
71 .cmd = CMD_PIO_READ_8,
72 .addr = NULL, /* will be patched in run-time */
73 .dstarg = 1
74 },
75 {
76 .cmd = CMD_BTEST,
77 .value = i8042_OUTPUT_FULL,
78 .srcarg = 1,
79 .dstarg = 3
80 },
81 {
82 .cmd = CMD_PREDICATE,
83 .value = 2,
84 .srcarg = 3
85 },
86 {
87 .cmd = CMD_PIO_READ_8,
88 .addr = NULL, /* will be patched in run-time */
89 .dstarg = 2
90 },
91 {
92 .cmd = CMD_ACCEPT
93 }
94};
95
96static irq_code_t i8042_kbd = {
97 sizeof(i8042_cmds) / sizeof(irq_cmd_t),
98 i8042_cmds
99};
100
101static uintptr_t i8042_physical;
102static uintptr_t i8042_kernel;
103static i8042_t * i8042;
104
105static void wait_ready(void) {
106 while (pio_read_8(&i8042->status) & i8042_INPUT_FULL)
107 ;
108}
109
110static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
111
112int kbd_port_init(void)
113{
114 int mouseenabled = 0;
115 void *vaddr;
116
117 i8042_physical = sysinfo_value("kbd.address.physical");
118 i8042_kernel = sysinfo_value("kbd.address.kernel");
119 if (pio_enable((void *) i8042_physical, sizeof(i8042_t), &vaddr) != 0)
120 return -1;
121 i8042 = vaddr;
122
123 async_set_interrupt_received(i8042_irq_handler);
124
125 /* Disable kbd, enable mouse */
126 pio_write_8(&i8042->status, i8042_CMD_KBD);
127 wait_ready();
128 pio_write_8(&i8042->status, i8042_CMD_KBD);
129 wait_ready();
130 pio_write_8(&i8042->data, i8042_KBD_DISABLE);
131 wait_ready();
132
133 /* Flush all current IO */
134 while (pio_read_8(&i8042->status) & i8042_OUTPUT_FULL)
135 (void) pio_read_8(&i8042->data);
136
137 /* Enable kbd */
138 i8042_kbd.cmds[0].addr = &((i8042_t *) i8042_kernel)->status;
139 i8042_kbd.cmds[3].addr = &((i8042_t *) i8042_kernel)->data;
140 ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &i8042_kbd);
141
142 int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
143 if (mouseenabled)
144 newcontrol |= i8042_MOUSE_IE;
145
146 pio_write_8(&i8042->status, i8042_CMD_KBD);
147 wait_ready();
148 pio_write_8(&i8042->data, newcontrol);
149 wait_ready();
150
151 return 0;
152}
153
154static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
155{
156 int status = IPC_GET_ARG1(*call);
157
158 if ((status & i8042_MOUSE_DATA))
159 return;
160
161 int scan_code = IPC_GET_ARG2(*call);
162
163 kbd_push_scancode(scan_code);
164 return;
165}
166
167/**
168 * @}
169 */
Note: See TracBrowser for help on using the repository browser.