source: mainline/uspace/kbd/arch/ia32/src/kbd.c@ 801579fe

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 801579fe was 801579fe, checked in by Jakub Jermar <jakub@…>, 19 years ago

Cleanup and reorganize the kbd service a bit.

  • Property mode set to 100644
File size: 4.4 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 kbdia32 ia32
31 * @brief HelenOS ia32 / amd64 arch dependent parts of uspace keyboard handler.
32 * @ingroup kbd
33 * @{
34 */
35/** @file
36 * @ingroup kbdamd64
37 */
38
39#include <arch/kbd.h>
40#include <ipc/ipc.h>
41#include <unistd.h>
42#include <kbd.h>
43#include <keys.h>
44#include <genarch/kbd.h>
45
46/* Interesting bits for status register */
47#define i8042_OUTPUT_FULL 0x1
48#define i8042_INPUT_FULL 0x2
49#define i8042_MOUSE_DATA 0x20
50
51/* Command constants */
52#define i8042_CMD_KBD 0x60
53#define i8042_CMD_MOUSE 0xd4
54
55/* Keyboard cmd byte */
56#define i8042_KBD_IE 0x1
57#define i8042_MOUSE_IE 0x2
58#define i8042_KBD_DISABLE 0x10
59#define i8042_MOUSE_DISABLE 0x20
60#define i8042_KBD_TRANSLATE 0x40
61
62/* Mouse constants */
63#define MOUSE_OUT_INIT 0xf4
64#define MOUSE_ACK 0xfa
65
66#define KEY_RELEASE 0x80
67
68static volatile int keyflags; /**< Tracking of multiple keypresses. */
69static volatile int lockflags; /**< Tracking of multiple keys lockings. */
70
71irq_cmd_t i8042_cmds[2] = {
72 { CMD_PORT_READ_1, (void *)0x64, 0, 1 },
73 { CMD_PORT_READ_1, (void *)0x60, 0, 2 }
74};
75
76irq_code_t i8042_kbd = {
77 2,
78 i8042_cmds
79};
80
81static void wait_ready(void) {
82 while (i8042_status_read() & i8042_INPUT_FULL)
83 ;
84}
85
86/** Register uspace irq handler
87 * @return
88 */
89int kbd_arch_init(void)
90{
91 int i;
92 int mouseenabled = 0;
93
94 iospace_enable(task_get_id(),(void *)i8042_DATA, 5);
95 /* Disable kbd, enable mouse */
96 i8042_command_write(i8042_CMD_KBD);
97 wait_ready();
98 i8042_command_write(i8042_CMD_KBD);
99 wait_ready();
100 i8042_data_write(i8042_KBD_DISABLE);
101 wait_ready();
102
103 /* Flush all current IO */
104 while (i8042_status_read() & i8042_OUTPUT_FULL)
105 i8042_data_read();
106 /* Initialize mouse */
107 i8042_command_write(i8042_CMD_MOUSE);
108 wait_ready();
109 i8042_data_write(MOUSE_OUT_INIT);
110 wait_ready();
111
112 int mouseanswer = 0;
113 for (i=0;i < 1000; i++) {
114 int status = i8042_status_read();
115 if (status & i8042_OUTPUT_FULL) {
116 int data = i8042_data_read();
117 if (status & i8042_MOUSE_DATA) {
118 mouseanswer = data;
119 break;
120 }
121 }
122 usleep(1000);
123 }
124 if (mouseanswer == MOUSE_ACK) {
125 /* enable mouse */
126 mouseenabled = 1;
127
128 ipc_register_irq(MOUSE_IRQ, &i8042_kbd);
129 }
130 /* Enable kbd */
131 ipc_register_irq(KBD_IRQ, &i8042_kbd);
132 /* Register for irq restart */
133 ipc_register_irq(IPC_IRQ_KBDRESTART, NULL);
134
135 int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
136 if (mouseenabled)
137 newcontrol |= i8042_MOUSE_IE;
138
139 i8042_command_write(i8042_CMD_KBD);
140 wait_ready();
141 i8042_data_write(newcontrol);
142 wait_ready();
143
144 return 0;
145}
146
147/** Process keyboard & mouse events */
148int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
149{
150 int status = IPC_GET_ARG1(*call);
151
152 if (IPC_GET_METHOD(*call) == IPC_IRQ_KBDRESTART) {
153 kbd_arch_init();
154 return 1;
155 }
156
157 if ((status & i8042_MOUSE_DATA))
158 return 0;
159
160 int scan_code = IPC_GET_ARG2(*call);
161
162 if (scan_code & KEY_RELEASE)
163 key_released(keybuffer, scan_code ^ KEY_RELEASE);
164 else
165 key_pressed(keybuffer, scan_code);
166 return 1;
167}
168
169/**
170 * @}
171 */
Note: See TracBrowser for help on using the repository browser.