1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "hw/hw.h"
25#include "hw/input/adb.h"
26#include "ui/console.h"
27
28
29
30
31#ifdef DEBUG_ADB
32#define ADB_DPRINTF(fmt, ...) \
33do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
34#else
35#define ADB_DPRINTF(fmt, ...)
36#endif
37
38
39#define ADB_BUSRESET 0x00
40#define ADB_FLUSH 0x01
41#define ADB_WRITEREG 0x08
42#define ADB_READREG 0x0c
43
44
45#define ADB_CMD_SELF_TEST 0xff
46#define ADB_CMD_CHANGE_ID 0xfe
47#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
48#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
49
50
51#define ADB_DEVID_DONGLE 1
52#define ADB_DEVID_KEYBOARD 2
53#define ADB_DEVID_MOUSE 3
54#define ADB_DEVID_TABLET 4
55#define ADB_DEVID_MODEM 5
56#define ADB_DEVID_MISC 7
57
58
59#define ADB_RET_NOTPRESENT (-2)
60
61static void adb_device_reset(ADBDevice *d)
62{
63 qdev_reset_all(DEVICE(d));
64}
65
66int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
67{
68 ADBDevice *d;
69 int devaddr, cmd, i;
70
71 cmd = buf[0] & 0xf;
72 if (cmd == ADB_BUSRESET) {
73 for(i = 0; i < s->nb_devices; i++) {
74 d = s->devices[i];
75 adb_device_reset(d);
76 }
77 return 0;
78 }
79 devaddr = buf[0] >> 4;
80 for(i = 0; i < s->nb_devices; i++) {
81 d = s->devices[i];
82 if (d->devaddr == devaddr) {
83 ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
84 return adc->devreq(d, obuf, buf, len);
85 }
86 }
87 return ADB_RET_NOTPRESENT;
88}
89
90
91int adb_poll(ADBBusState *s, uint8_t *obuf)
92{
93 ADBDevice *d;
94 int olen, i;
95 uint8_t buf[1];
96
97 olen = 0;
98 for(i = 0; i < s->nb_devices; i++) {
99 if (s->poll_index >= s->nb_devices)
100 s->poll_index = 0;
101 d = s->devices[s->poll_index];
102 buf[0] = ADB_READREG | (d->devaddr << 4);
103 olen = adb_request(s, obuf + 1, buf, 1);
104
105 if (olen > 0) {
106 obuf[0] = buf[0];
107 olen++;
108 break;
109 }
110 s->poll_index++;
111 }
112 return olen;
113}
114
115static const TypeInfo adb_bus_type_info = {
116 .name = TYPE_ADB_BUS,
117 .parent = TYPE_BUS,
118 .instance_size = sizeof(ADBBusState),
119};
120
121static const VMStateDescription vmstate_adb_device = {
122 .name = "adb_device",
123 .version_id = 0,
124 .minimum_version_id = 0,
125 .fields = (VMStateField[]) {
126 VMSTATE_INT32(devaddr, ADBDevice),
127 VMSTATE_INT32(handler, ADBDevice),
128 VMSTATE_END_OF_LIST()
129 }
130};
131
132static void adb_device_realizefn(DeviceState *dev, Error **errp)
133{
134 ADBDevice *d = ADB_DEVICE(dev);
135 ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
136
137 if (bus->nb_devices >= MAX_ADB_DEVICES) {
138 return;
139 }
140
141 bus->devices[bus->nb_devices++] = d;
142}
143
144static void adb_device_class_init(ObjectClass *oc, void *data)
145{
146 DeviceClass *dc = DEVICE_CLASS(oc);
147
148 dc->realize = adb_device_realizefn;
149 dc->bus_type = TYPE_ADB_BUS;
150}
151
152static const TypeInfo adb_device_type_info = {
153 .name = TYPE_ADB_DEVICE,
154 .parent = TYPE_DEVICE,
155 .instance_size = sizeof(ADBDevice),
156 .abstract = true,
157 .class_init = adb_device_class_init,
158};
159
160
161
162
163#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
164
165typedef struct KBDState {
166
167 ADBDevice parent_obj;
168
169
170 uint8_t data[128];
171 int rptr, wptr, count;
172} KBDState;
173
174#define ADB_KEYBOARD_CLASS(class) \
175 OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
176#define ADB_KEYBOARD_GET_CLASS(obj) \
177 OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
178
179typedef struct ADBKeyboardClass {
180
181 ADBDeviceClass parent_class;
182
183
184 DeviceRealize parent_realize;
185} ADBKeyboardClass;
186
187static const uint8_t pc_to_adb_keycode[256] = {
188 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
189 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
190 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
191 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
192 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
193 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
199 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
200 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
201 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
204};
205
206static void adb_kbd_put_keycode(void *opaque, int keycode)
207{
208 KBDState *s = opaque;
209
210 if (s->count < sizeof(s->data)) {
211 s->data[s->wptr] = keycode;
212 if (++s->wptr == sizeof(s->data))
213 s->wptr = 0;
214 s->count++;
215 }
216}
217
218static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
219{
220 static int ext_keycode;
221 KBDState *s = ADB_KEYBOARD(d);
222 int adb_keycode, keycode;
223 int olen;
224
225 olen = 0;
226 for(;;) {
227 if (s->count == 0)
228 break;
229 keycode = s->data[s->rptr];
230 if (++s->rptr == sizeof(s->data))
231 s->rptr = 0;
232 s->count--;
233
234 if (keycode == 0xe0) {
235 ext_keycode = 1;
236 } else {
237 if (ext_keycode)
238 adb_keycode = pc_to_adb_keycode[keycode | 0x80];
239 else
240 adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
241 obuf[0] = adb_keycode | (keycode & 0x80);
242
243 obuf[1] = 0xff;
244 olen = 2;
245 ext_keycode = 0;
246 break;
247 }
248 }
249 return olen;
250}
251
252static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
253 const uint8_t *buf, int len)
254{
255 KBDState *s = ADB_KEYBOARD(d);
256 int cmd, reg, olen;
257
258 if ((buf[0] & 0x0f) == ADB_FLUSH) {
259
260 s->wptr = s->rptr = s->count = 0;
261 return 0;
262 }
263
264 cmd = buf[0] & 0xc;
265 reg = buf[0] & 0x3;
266 olen = 0;
267 switch(cmd) {
268 case ADB_WRITEREG:
269 switch(reg) {
270 case 2:
271
272 break;
273 case 3:
274 switch(buf[2]) {
275 case ADB_CMD_SELF_TEST:
276 break;
277 case ADB_CMD_CHANGE_ID:
278 case ADB_CMD_CHANGE_ID_AND_ACT:
279 case ADB_CMD_CHANGE_ID_AND_ENABLE:
280 d->devaddr = buf[1] & 0xf;
281 break;
282 default:
283
284 d->devaddr = buf[1] & 0xf;
285 d->handler = buf[2];
286 break;
287 }
288 }
289 break;
290 case ADB_READREG:
291 switch(reg) {
292 case 0:
293 olen = adb_kbd_poll(d, obuf);
294 break;
295 case 1:
296 break;
297 case 2:
298 obuf[0] = 0x00;
299 obuf[1] = 0x07;
300 olen = 2;
301 break;
302 case 3:
303 obuf[0] = d->handler;
304 obuf[1] = d->devaddr;
305 olen = 2;
306 break;
307 }
308 break;
309 }
310 return olen;
311}
312
313static const VMStateDescription vmstate_adb_kbd = {
314 .name = "adb_kbd",
315 .version_id = 2,
316 .minimum_version_id = 2,
317 .fields = (VMStateField[]) {
318 VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
319 VMSTATE_BUFFER(data, KBDState),
320 VMSTATE_INT32(rptr, KBDState),
321 VMSTATE_INT32(wptr, KBDState),
322 VMSTATE_INT32(count, KBDState),
323 VMSTATE_END_OF_LIST()
324 }
325};
326
327static void adb_kbd_reset(DeviceState *dev)
328{
329 ADBDevice *d = ADB_DEVICE(dev);
330 KBDState *s = ADB_KEYBOARD(dev);
331
332 d->handler = 1;
333 d->devaddr = ADB_DEVID_KEYBOARD;
334 memset(s->data, 0, sizeof(s->data));
335 s->rptr = 0;
336 s->wptr = 0;
337 s->count = 0;
338}
339
340static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
341{
342 ADBDevice *d = ADB_DEVICE(dev);
343 ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
344
345 akc->parent_realize(dev, errp);
346
347 qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
348}
349
350static void adb_kbd_initfn(Object *obj)
351{
352 ADBDevice *d = ADB_DEVICE(obj);
353
354 d->devaddr = ADB_DEVID_KEYBOARD;
355}
356
357static void adb_kbd_class_init(ObjectClass *oc, void *data)
358{
359 DeviceClass *dc = DEVICE_CLASS(oc);
360 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
361 ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
362
363 akc->parent_realize = dc->realize;
364 dc->realize = adb_kbd_realizefn;
365
366 adc->devreq = adb_kbd_request;
367 dc->reset = adb_kbd_reset;
368 dc->vmsd = &vmstate_adb_kbd;
369}
370
371static const TypeInfo adb_kbd_type_info = {
372 .name = TYPE_ADB_KEYBOARD,
373 .parent = TYPE_ADB_DEVICE,
374 .instance_size = sizeof(KBDState),
375 .instance_init = adb_kbd_initfn,
376 .class_init = adb_kbd_class_init,
377 .class_size = sizeof(ADBKeyboardClass),
378};
379
380
381
382
383#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
384
385typedef struct MouseState {
386
387 ADBDevice parent_obj;
388
389
390 int buttons_state, last_buttons_state;
391 int dx, dy, dz;
392} MouseState;
393
394#define ADB_MOUSE_CLASS(class) \
395 OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
396#define ADB_MOUSE_GET_CLASS(obj) \
397 OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
398
399typedef struct ADBMouseClass {
400
401 ADBDeviceClass parent_class;
402
403
404 DeviceRealize parent_realize;
405} ADBMouseClass;
406
407static void adb_mouse_event(void *opaque,
408 int dx1, int dy1, int dz1, int buttons_state)
409{
410 MouseState *s = opaque;
411
412 s->dx += dx1;
413 s->dy += dy1;
414 s->dz += dz1;
415 s->buttons_state = buttons_state;
416}
417
418
419static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
420{
421 MouseState *s = ADB_MOUSE(d);
422 int dx, dy;
423
424 if (s->last_buttons_state == s->buttons_state &&
425 s->dx == 0 && s->dy == 0)
426 return 0;
427
428 dx = s->dx;
429 if (dx < -63)
430 dx = -63;
431 else if (dx > 63)
432 dx = 63;
433
434 dy = s->dy;
435 if (dy < -63)
436 dy = -63;
437 else if (dy > 63)
438 dy = 63;
439
440 s->dx -= dx;
441 s->dy -= dy;
442 s->last_buttons_state = s->buttons_state;
443
444 dx &= 0x7f;
445 dy &= 0x7f;
446
447 if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
448 dy |= 0x80;
449 if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
450 dx |= 0x80;
451
452 obuf[0] = dy;
453 obuf[1] = dx;
454 return 2;
455}
456
457static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
458 const uint8_t *buf, int len)
459{
460 MouseState *s = ADB_MOUSE(d);
461 int cmd, reg, olen;
462
463 if ((buf[0] & 0x0f) == ADB_FLUSH) {
464
465 s->buttons_state = s->last_buttons_state;
466 s->dx = 0;
467 s->dy = 0;
468 s->dz = 0;
469 return 0;
470 }
471
472 cmd = buf[0] & 0xc;
473 reg = buf[0] & 0x3;
474 olen = 0;
475 switch(cmd) {
476 case ADB_WRITEREG:
477 ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
478 switch(reg) {
479 case 2:
480 break;
481 case 3:
482 switch(buf[2]) {
483 case ADB_CMD_SELF_TEST:
484 break;
485 case ADB_CMD_CHANGE_ID:
486 case ADB_CMD_CHANGE_ID_AND_ACT:
487 case ADB_CMD_CHANGE_ID_AND_ENABLE:
488 d->devaddr = buf[1] & 0xf;
489 break;
490 default:
491
492 d->devaddr = buf[1] & 0xf;
493 break;
494 }
495 }
496 break;
497 case ADB_READREG:
498 switch(reg) {
499 case 0:
500 olen = adb_mouse_poll(d, obuf);
501 break;
502 case 1:
503 break;
504 case 3:
505 obuf[0] = d->handler;
506 obuf[1] = d->devaddr;
507 olen = 2;
508 break;
509 }
510 ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
511 obuf[0], obuf[1]);
512 break;
513 }
514 return olen;
515}
516
517static void adb_mouse_reset(DeviceState *dev)
518{
519 ADBDevice *d = ADB_DEVICE(dev);
520 MouseState *s = ADB_MOUSE(dev);
521
522 d->handler = 2;
523 d->devaddr = ADB_DEVID_MOUSE;
524 s->last_buttons_state = s->buttons_state = 0;
525 s->dx = s->dy = s->dz = 0;
526}
527
528static const VMStateDescription vmstate_adb_mouse = {
529 .name = "adb_mouse",
530 .version_id = 2,
531 .minimum_version_id = 2,
532 .fields = (VMStateField[]) {
533 VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
534 ADBDevice),
535 VMSTATE_INT32(buttons_state, MouseState),
536 VMSTATE_INT32(last_buttons_state, MouseState),
537 VMSTATE_INT32(dx, MouseState),
538 VMSTATE_INT32(dy, MouseState),
539 VMSTATE_INT32(dz, MouseState),
540 VMSTATE_END_OF_LIST()
541 }
542};
543
544static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
545{
546 MouseState *s = ADB_MOUSE(dev);
547 ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
548
549 amc->parent_realize(dev, errp);
550
551 qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
552}
553
554static void adb_mouse_initfn(Object *obj)
555{
556 ADBDevice *d = ADB_DEVICE(obj);
557
558 d->devaddr = ADB_DEVID_MOUSE;
559}
560
561static void adb_mouse_class_init(ObjectClass *oc, void *data)
562{
563 DeviceClass *dc = DEVICE_CLASS(oc);
564 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
565 ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
566
567 amc->parent_realize = dc->realize;
568 dc->realize = adb_mouse_realizefn;
569
570 adc->devreq = adb_mouse_request;
571 dc->reset = adb_mouse_reset;
572 dc->vmsd = &vmstate_adb_mouse;
573}
574
575static const TypeInfo adb_mouse_type_info = {
576 .name = TYPE_ADB_MOUSE,
577 .parent = TYPE_ADB_DEVICE,
578 .instance_size = sizeof(MouseState),
579 .instance_init = adb_mouse_initfn,
580 .class_init = adb_mouse_class_init,
581 .class_size = sizeof(ADBMouseClass),
582};
583
584
585static void adb_register_types(void)
586{
587 type_register_static(&adb_bus_type_info);
588 type_register_static(&adb_device_type_info);
589 type_register_static(&adb_kbd_type_info);
590 type_register_static(&adb_mouse_type_info);
591}
592
593type_init(adb_register_types)
594