usb-bot: hotplug support
[qemu/kevin.git] / hw / input / adb.c
blobf0ad0d44712e77201d6537a595cb3cb7ef403de2
1 /*
2 * QEMU ADB support
4 * Copyright (c) 2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include "qemu/osdep.h"
25 #include "hw/hw.h"
26 #include "hw/input/adb.h"
27 #include "ui/console.h"
29 /* debug ADB */
30 //#define DEBUG_ADB
32 #ifdef DEBUG_ADB
33 #define ADB_DPRINTF(fmt, ...) \
34 do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
35 #else
36 #define ADB_DPRINTF(fmt, ...)
37 #endif
39 /* ADB commands */
40 #define ADB_BUSRESET 0x00
41 #define ADB_FLUSH 0x01
42 #define ADB_WRITEREG 0x08
43 #define ADB_READREG 0x0c
45 /* ADB device commands */
46 #define ADB_CMD_SELF_TEST 0xff
47 #define ADB_CMD_CHANGE_ID 0xfe
48 #define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
49 #define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
51 /* ADB default device IDs (upper 4 bits of ADB command byte) */
52 #define ADB_DEVID_DONGLE 1
53 #define ADB_DEVID_KEYBOARD 2
54 #define ADB_DEVID_MOUSE 3
55 #define ADB_DEVID_TABLET 4
56 #define ADB_DEVID_MODEM 5
57 #define ADB_DEVID_MISC 7
59 /* error codes */
60 #define ADB_RET_NOTPRESENT (-2)
62 static void adb_device_reset(ADBDevice *d)
64 qdev_reset_all(DEVICE(d));
67 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
69 ADBDevice *d;
70 int devaddr, cmd, i;
72 cmd = buf[0] & 0xf;
73 if (cmd == ADB_BUSRESET) {
74 for(i = 0; i < s->nb_devices; i++) {
75 d = s->devices[i];
76 adb_device_reset(d);
78 return 0;
80 devaddr = buf[0] >> 4;
81 for(i = 0; i < s->nb_devices; i++) {
82 d = s->devices[i];
83 if (d->devaddr == devaddr) {
84 ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
85 return adc->devreq(d, obuf, buf, len);
88 return ADB_RET_NOTPRESENT;
91 /* XXX: move that to cuda ? */
92 int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
94 ADBDevice *d;
95 int olen, i;
96 uint8_t buf[1];
98 olen = 0;
99 for(i = 0; i < s->nb_devices; i++) {
100 if (s->poll_index >= s->nb_devices)
101 s->poll_index = 0;
102 d = s->devices[s->poll_index];
103 if ((1 << d->devaddr) & poll_mask) {
104 buf[0] = ADB_READREG | (d->devaddr << 4);
105 olen = adb_request(s, obuf + 1, buf, 1);
106 /* if there is data, we poll again the same device */
107 if (olen > 0) {
108 obuf[0] = buf[0];
109 olen++;
110 break;
113 s->poll_index++;
115 return olen;
118 static const TypeInfo adb_bus_type_info = {
119 .name = TYPE_ADB_BUS,
120 .parent = TYPE_BUS,
121 .instance_size = sizeof(ADBBusState),
124 static const VMStateDescription vmstate_adb_device = {
125 .name = "adb_device",
126 .version_id = 0,
127 .minimum_version_id = 0,
128 .fields = (VMStateField[]) {
129 VMSTATE_INT32(devaddr, ADBDevice),
130 VMSTATE_INT32(handler, ADBDevice),
131 VMSTATE_END_OF_LIST()
135 static void adb_device_realizefn(DeviceState *dev, Error **errp)
137 ADBDevice *d = ADB_DEVICE(dev);
138 ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
140 if (bus->nb_devices >= MAX_ADB_DEVICES) {
141 return;
144 bus->devices[bus->nb_devices++] = d;
147 static void adb_device_class_init(ObjectClass *oc, void *data)
149 DeviceClass *dc = DEVICE_CLASS(oc);
151 dc->realize = adb_device_realizefn;
152 dc->bus_type = TYPE_ADB_BUS;
155 static const TypeInfo adb_device_type_info = {
156 .name = TYPE_ADB_DEVICE,
157 .parent = TYPE_DEVICE,
158 .instance_size = sizeof(ADBDevice),
159 .abstract = true,
160 .class_init = adb_device_class_init,
163 /***************************************************************/
164 /* Keyboard ADB device */
166 #define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
168 typedef struct KBDState {
169 /*< private >*/
170 ADBDevice parent_obj;
171 /*< public >*/
173 uint8_t data[128];
174 int rptr, wptr, count;
175 } KBDState;
177 #define ADB_KEYBOARD_CLASS(class) \
178 OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
179 #define ADB_KEYBOARD_GET_CLASS(obj) \
180 OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
182 typedef struct ADBKeyboardClass {
183 /*< private >*/
184 ADBDeviceClass parent_class;
185 /*< public >*/
187 DeviceRealize parent_realize;
188 } ADBKeyboardClass;
190 static const uint8_t pc_to_adb_keycode[256] = {
191 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
192 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
193 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
194 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
195 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
196 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
204 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
206 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
209 static void adb_kbd_put_keycode(void *opaque, int keycode)
211 KBDState *s = opaque;
213 if (s->count < sizeof(s->data)) {
214 s->data[s->wptr] = keycode;
215 if (++s->wptr == sizeof(s->data))
216 s->wptr = 0;
217 s->count++;
221 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
223 static int ext_keycode;
224 KBDState *s = ADB_KEYBOARD(d);
225 int adb_keycode, keycode;
226 int olen;
228 olen = 0;
229 for(;;) {
230 if (s->count == 0)
231 break;
232 keycode = s->data[s->rptr];
233 if (++s->rptr == sizeof(s->data))
234 s->rptr = 0;
235 s->count--;
237 if (keycode == 0xe0) {
238 ext_keycode = 1;
239 } else {
240 if (ext_keycode)
241 adb_keycode = pc_to_adb_keycode[keycode | 0x80];
242 else
243 adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
244 obuf[0] = adb_keycode | (keycode & 0x80);
245 /* NOTE: could put a second keycode if needed */
246 obuf[1] = 0xff;
247 olen = 2;
248 ext_keycode = 0;
249 break;
252 return olen;
255 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
256 const uint8_t *buf, int len)
258 KBDState *s = ADB_KEYBOARD(d);
259 int cmd, reg, olen;
261 if ((buf[0] & 0x0f) == ADB_FLUSH) {
262 /* flush keyboard fifo */
263 s->wptr = s->rptr = s->count = 0;
264 return 0;
267 cmd = buf[0] & 0xc;
268 reg = buf[0] & 0x3;
269 olen = 0;
270 switch(cmd) {
271 case ADB_WRITEREG:
272 switch(reg) {
273 case 2:
274 /* LED status */
275 break;
276 case 3:
277 switch(buf[2]) {
278 case ADB_CMD_SELF_TEST:
279 break;
280 case ADB_CMD_CHANGE_ID:
281 case ADB_CMD_CHANGE_ID_AND_ACT:
282 case ADB_CMD_CHANGE_ID_AND_ENABLE:
283 d->devaddr = buf[1] & 0xf;
284 break;
285 default:
286 /* XXX: check this */
287 d->devaddr = buf[1] & 0xf;
288 d->handler = buf[2];
289 break;
292 break;
293 case ADB_READREG:
294 switch(reg) {
295 case 0:
296 olen = adb_kbd_poll(d, obuf);
297 break;
298 case 1:
299 break;
300 case 2:
301 obuf[0] = 0x00; /* XXX: check this */
302 obuf[1] = 0x07; /* led status */
303 olen = 2;
304 break;
305 case 3:
306 obuf[0] = d->handler;
307 obuf[1] = d->devaddr;
308 olen = 2;
309 break;
311 break;
313 return olen;
316 static const VMStateDescription vmstate_adb_kbd = {
317 .name = "adb_kbd",
318 .version_id = 2,
319 .minimum_version_id = 2,
320 .fields = (VMStateField[]) {
321 VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
322 VMSTATE_BUFFER(data, KBDState),
323 VMSTATE_INT32(rptr, KBDState),
324 VMSTATE_INT32(wptr, KBDState),
325 VMSTATE_INT32(count, KBDState),
326 VMSTATE_END_OF_LIST()
330 static void adb_kbd_reset(DeviceState *dev)
332 ADBDevice *d = ADB_DEVICE(dev);
333 KBDState *s = ADB_KEYBOARD(dev);
335 d->handler = 1;
336 d->devaddr = ADB_DEVID_KEYBOARD;
337 memset(s->data, 0, sizeof(s->data));
338 s->rptr = 0;
339 s->wptr = 0;
340 s->count = 0;
343 static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
345 ADBDevice *d = ADB_DEVICE(dev);
346 ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
348 akc->parent_realize(dev, errp);
350 qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
353 static void adb_kbd_initfn(Object *obj)
355 ADBDevice *d = ADB_DEVICE(obj);
357 d->devaddr = ADB_DEVID_KEYBOARD;
360 static void adb_kbd_class_init(ObjectClass *oc, void *data)
362 DeviceClass *dc = DEVICE_CLASS(oc);
363 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
364 ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
366 akc->parent_realize = dc->realize;
367 dc->realize = adb_kbd_realizefn;
368 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
370 adc->devreq = adb_kbd_request;
371 dc->reset = adb_kbd_reset;
372 dc->vmsd = &vmstate_adb_kbd;
375 static const TypeInfo adb_kbd_type_info = {
376 .name = TYPE_ADB_KEYBOARD,
377 .parent = TYPE_ADB_DEVICE,
378 .instance_size = sizeof(KBDState),
379 .instance_init = adb_kbd_initfn,
380 .class_init = adb_kbd_class_init,
381 .class_size = sizeof(ADBKeyboardClass),
384 /***************************************************************/
385 /* Mouse ADB device */
387 #define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
389 typedef struct MouseState {
390 /*< public >*/
391 ADBDevice parent_obj;
392 /*< private >*/
394 int buttons_state, last_buttons_state;
395 int dx, dy, dz;
396 } MouseState;
398 #define ADB_MOUSE_CLASS(class) \
399 OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
400 #define ADB_MOUSE_GET_CLASS(obj) \
401 OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
403 typedef struct ADBMouseClass {
404 /*< public >*/
405 ADBDeviceClass parent_class;
406 /*< private >*/
408 DeviceRealize parent_realize;
409 } ADBMouseClass;
411 static void adb_mouse_event(void *opaque,
412 int dx1, int dy1, int dz1, int buttons_state)
414 MouseState *s = opaque;
416 s->dx += dx1;
417 s->dy += dy1;
418 s->dz += dz1;
419 s->buttons_state = buttons_state;
423 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
425 MouseState *s = ADB_MOUSE(d);
426 int dx, dy;
428 if (s->last_buttons_state == s->buttons_state &&
429 s->dx == 0 && s->dy == 0)
430 return 0;
432 dx = s->dx;
433 if (dx < -63)
434 dx = -63;
435 else if (dx > 63)
436 dx = 63;
438 dy = s->dy;
439 if (dy < -63)
440 dy = -63;
441 else if (dy > 63)
442 dy = 63;
444 s->dx -= dx;
445 s->dy -= dy;
446 s->last_buttons_state = s->buttons_state;
448 dx &= 0x7f;
449 dy &= 0x7f;
451 if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
452 dy |= 0x80;
453 if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
454 dx |= 0x80;
456 obuf[0] = dy;
457 obuf[1] = dx;
458 return 2;
461 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
462 const uint8_t *buf, int len)
464 MouseState *s = ADB_MOUSE(d);
465 int cmd, reg, olen;
467 if ((buf[0] & 0x0f) == ADB_FLUSH) {
468 /* flush mouse fifo */
469 s->buttons_state = s->last_buttons_state;
470 s->dx = 0;
471 s->dy = 0;
472 s->dz = 0;
473 return 0;
476 cmd = buf[0] & 0xc;
477 reg = buf[0] & 0x3;
478 olen = 0;
479 switch(cmd) {
480 case ADB_WRITEREG:
481 ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
482 switch(reg) {
483 case 2:
484 break;
485 case 3:
486 switch(buf[2]) {
487 case ADB_CMD_SELF_TEST:
488 break;
489 case ADB_CMD_CHANGE_ID:
490 case ADB_CMD_CHANGE_ID_AND_ACT:
491 case ADB_CMD_CHANGE_ID_AND_ENABLE:
492 d->devaddr = buf[1] & 0xf;
493 break;
494 default:
495 /* XXX: check this */
496 d->devaddr = buf[1] & 0xf;
497 break;
500 break;
501 case ADB_READREG:
502 switch(reg) {
503 case 0:
504 olen = adb_mouse_poll(d, obuf);
505 break;
506 case 1:
507 break;
508 case 3:
509 obuf[0] = d->handler;
510 obuf[1] = d->devaddr;
511 olen = 2;
512 break;
514 ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
515 obuf[0], obuf[1]);
516 break;
518 return olen;
521 static void adb_mouse_reset(DeviceState *dev)
523 ADBDevice *d = ADB_DEVICE(dev);
524 MouseState *s = ADB_MOUSE(dev);
526 d->handler = 2;
527 d->devaddr = ADB_DEVID_MOUSE;
528 s->last_buttons_state = s->buttons_state = 0;
529 s->dx = s->dy = s->dz = 0;
532 static const VMStateDescription vmstate_adb_mouse = {
533 .name = "adb_mouse",
534 .version_id = 2,
535 .minimum_version_id = 2,
536 .fields = (VMStateField[]) {
537 VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
538 ADBDevice),
539 VMSTATE_INT32(buttons_state, MouseState),
540 VMSTATE_INT32(last_buttons_state, MouseState),
541 VMSTATE_INT32(dx, MouseState),
542 VMSTATE_INT32(dy, MouseState),
543 VMSTATE_INT32(dz, MouseState),
544 VMSTATE_END_OF_LIST()
548 static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
550 MouseState *s = ADB_MOUSE(dev);
551 ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
553 amc->parent_realize(dev, errp);
555 qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
558 static void adb_mouse_initfn(Object *obj)
560 ADBDevice *d = ADB_DEVICE(obj);
562 d->devaddr = ADB_DEVID_MOUSE;
565 static void adb_mouse_class_init(ObjectClass *oc, void *data)
567 DeviceClass *dc = DEVICE_CLASS(oc);
568 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
569 ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
571 amc->parent_realize = dc->realize;
572 dc->realize = adb_mouse_realizefn;
573 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
575 adc->devreq = adb_mouse_request;
576 dc->reset = adb_mouse_reset;
577 dc->vmsd = &vmstate_adb_mouse;
580 static const TypeInfo adb_mouse_type_info = {
581 .name = TYPE_ADB_MOUSE,
582 .parent = TYPE_ADB_DEVICE,
583 .instance_size = sizeof(MouseState),
584 .instance_init = adb_mouse_initfn,
585 .class_init = adb_mouse_class_init,
586 .class_size = sizeof(ADBMouseClass),
590 static void adb_register_types(void)
592 type_register_static(&adb_bus_type_info);
593 type_register_static(&adb_device_type_info);
594 type_register_static(&adb_kbd_type_info);
595 type_register_static(&adb_mouse_type_info);
598 type_init(adb_register_types)