cuda fixes
[qemu] / hw / adb.c
1 /*
2  * QEMU ADB support
3  * 
4  * Copyright (c) 2004 Fabrice Bellard
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25
26 /* ADB commands */
27 #define ADB_BUSRESET            0x00
28 #define ADB_FLUSH               0x01
29 #define ADB_WRITEREG            0x08
30 #define ADB_READREG             0x0c
31
32 /* ADB device commands */
33 #define ADB_CMD_SELF_TEST               0xff
34 #define ADB_CMD_CHANGE_ID               0xfe
35 #define ADB_CMD_CHANGE_ID_AND_ACT       0xfd
36 #define ADB_CMD_CHANGE_ID_AND_ENABLE    0x00
37
38 /* ADB default device IDs (upper 4 bits of ADB command byte) */
39 #define ADB_DONGLE      1
40 #define ADB_KEYBOARD    2
41 #define ADB_MOUSE       3
42 #define ADB_TABLET      4
43 #define ADB_MODEM       5
44 #define ADB_MISC        7
45
46 #define ADB_RET_OK                      0
47 #define ADB_RET_INUSE                   1
48 #define ADB_RET_NOTPRESENT              2
49 #define ADB_RET_TIMEOUT                 3
50 #define ADB_RET_UNEXPECTED_RESULT       4
51 #define ADB_RET_REQUEST_ERROR           5
52 #define ADB_RET_BUS_ERROR               6
53
54
55 static void adb_send_packet1(ADBBusState *s, uint8_t reply)
56 {
57     adb_send_packet(s, &reply, 1);
58 }
59
60 void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len)
61 {
62     ADBDevice *d;
63     int devaddr, cmd, i;
64     uint8_t obuf[4];
65
66     cmd = buf[0] & 0xf;
67     devaddr = buf[0] >> 4;
68     if (buf[1] == ADB_BUSRESET) {
69         obuf[0] = 0x00;
70         obuf[1] = 0x00;
71         adb_send_packet(s, obuf, 2);
72         return;
73     }
74     if (cmd == ADB_FLUSH) {
75         obuf[0] = 0x00;
76         obuf[1] = 0x00;
77         adb_send_packet(s, obuf, 2);
78         return;
79     }
80
81     for(i = 0; i < s->nb_devices; i++) {
82         d = &s->devices[i];
83         if (d->devaddr == devaddr) {
84             d->receive_packet(d, buf, len);
85             return;
86         }
87     }
88     adb_send_packet1(s, ADB_RET_NOTPRESENT);
89 }
90
91 ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
92                                ADBDeviceReceivePacket *receive_packet, 
93                                void *opaque)
94 {
95     ADBDevice *d;
96     if (s->nb_devices >= MAX_ADB_DEVICES)
97         return NULL;
98     d = &s->devices[s->nb_devices++];
99     d->bus = s;
100     d->devaddr = devaddr;
101     d->receive_packet = receive_packet;
102     d->opaque = opaque;
103     return d;
104 }
105
106 /***************************************************************/
107 /* Keyboard ADB device */
108
109 static const uint8_t pc_to_adb_keycode[256] = {
110   0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
111  12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
112   2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
113  11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
114  97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
115  84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,  0,  0,  0,  0,  0,
116  76,125, 75,105,124,110,115, 62,116, 59, 60,119, 61,121,114,117,
117   0,  0,  0,  0,127, 81,  0,113,  0,  0,  0,  0, 95, 55,  0,  0,
118   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
119   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
120   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
121   0,  0,  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,
122   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
123   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
124   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
125   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
126 };
127
128 static void adb_kbd_put_keycode(void *opaque, int keycode)
129 {
130     static int ext_keycode;
131     ADBDevice *d = opaque;
132     uint8_t buf[4];
133     int adb_keycode;
134     
135     if (keycode == 0xe0) {
136         ext_keycode = 1;
137     } else {
138         
139         if (ext_keycode)
140             adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
141         else
142             adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
143             
144         buf[0] = 0x40;
145         buf[1] = (d->devaddr << 4) | 0x0c;
146         buf[2] = adb_keycode | (keycode & 0x80);
147         buf[3] = 0xff;
148         adb_send_packet(d->bus, buf, 4);
149         ext_keycode = 0;
150     }
151 }
152
153 static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
154 {
155     int cmd, reg;
156     uint8_t obuf[4];
157
158     cmd = buf[0] & 0xc;
159     reg = buf[0] & 0x3;
160     switch(cmd) {
161     case ADB_WRITEREG:
162         switch(reg) {
163         case 2:
164             /* LED status */
165             adb_send_packet1(d->bus, ADB_RET_OK);
166             break;
167         case 3:
168             switch(buf[2]) {
169             case ADB_CMD_SELF_TEST:
170                 adb_send_packet1(d->bus, ADB_RET_OK);
171                 break;
172             case ADB_CMD_CHANGE_ID:
173             case ADB_CMD_CHANGE_ID_AND_ACT:
174             case ADB_CMD_CHANGE_ID_AND_ENABLE:
175                 d->devaddr = buf[1] & 0xf;
176                 adb_send_packet1(d->bus, ADB_RET_OK);
177                 break;
178             default:
179                 /* XXX: check this */
180                 d->devaddr = buf[1] & 0xf;
181                 d->handler = buf[2];
182                 adb_send_packet1(d->bus, ADB_RET_OK);
183                 break;
184             }
185         }
186         break;
187     case ADB_READREG:
188         switch(reg) {
189         case 1:
190             adb_send_packet1(d->bus, ADB_RET_OK);
191             break;
192         case 2:
193             obuf[0] = ADB_RET_OK;
194             obuf[1] = 0x00; /* XXX: check this */
195             obuf[2] = 0x07; /* led status */
196             adb_send_packet(d->bus, obuf, 3);
197             break;
198         case 3:
199             obuf[0] = ADB_RET_OK;
200             obuf[1] = d->handler;
201             obuf[2] = d->devaddr;
202             adb_send_packet(d->bus, obuf, 3);
203             break;
204         }
205         break;
206     }
207 }
208
209 void adb_kbd_init(ADBBusState *bus)
210 {
211     ADBDevice *d;
212
213     d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL);
214     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
215 }
216
217 /***************************************************************/
218 /* Mouse ADB device */
219
220 static void adb_mouse_event(void *opaque,
221                             int dx1, int dy1, int dz1, int buttons_state)
222 {
223     ADBDevice *d = opaque;
224     uint8_t buf[4];
225     int dx, dy;
226
227     dx = dx1;
228     if (dx < -63)
229         dx = -63;
230     else if (dx > 63)
231         dx = 63;
232
233     dy = dy1;
234     if (dy < -63)
235         dy = -63;
236     else if (dy > 63)
237         dy = 63;
238
239     dx &= 0x7f;
240     dy &= 0x7f;
241
242     if (buttons_state & MOUSE_EVENT_LBUTTON)
243         dy |= 0x80;
244     if (buttons_state & MOUSE_EVENT_RBUTTON)
245         dx |= 0x80;
246
247     buf[0] = 0x40;
248     buf[1] = (d->devaddr << 4) | 0x0c;
249     buf[2] = dy;
250     buf[3] = dx;
251     adb_send_packet(d->bus, buf, 4);
252 }
253
254 static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
255 {
256     int cmd, reg;
257     uint8_t obuf[4];
258
259     cmd = buf[0] & 0xc;
260     reg = buf[0] & 0x3;
261     switch(cmd) {
262     case ADB_WRITEREG:
263         switch(reg) {
264         case 2:
265             adb_send_packet1(d->bus, ADB_RET_OK);
266             break;
267         case 3:
268             switch(buf[2]) {
269             case ADB_CMD_SELF_TEST:
270                 adb_send_packet1(d->bus, ADB_RET_OK);
271                 break;
272             case ADB_CMD_CHANGE_ID:
273             case ADB_CMD_CHANGE_ID_AND_ACT:
274             case ADB_CMD_CHANGE_ID_AND_ENABLE:
275                 d->devaddr = buf[1] & 0xf;
276                 adb_send_packet1(d->bus, ADB_RET_OK);
277                 break;
278             default:
279                 /* XXX: check this */
280                 d->devaddr = buf[1] & 0xf;
281                 adb_send_packet1(d->bus, ADB_RET_OK);
282                 break;
283             }
284         }
285         break;
286     case ADB_READREG:
287         switch(reg) {
288         case 1:
289             adb_send_packet1(d->bus, ADB_RET_OK);
290             break;
291         case 3:
292             obuf[0] = ADB_RET_OK;
293             obuf[1] = d->handler;
294             obuf[2] = d->devaddr;
295             adb_send_packet(d->bus, obuf, 3);
296             break;
297         }
298         break;
299     }
300 }
301
302 void adb_mouse_init(ADBBusState *bus)
303 {
304     ADBDevice *d;
305
306     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL);
307     qemu_add_mouse_event_handler(adb_mouse_event, d);
308 }