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 "qemu/osdep.h"
25#include "hw/hw.h"
26#include "hw/input/adb.h"
27#include "ui/console.h"
28
29
30
31
32#ifdef DEBUG_ADB
33#define ADB_DPRINTF(fmt, ...) \
34do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
35#else
36#define ADB_DPRINTF(fmt, ...)
37#endif
38
39
40#define ADB_BUSRESET 0x00
41#define ADB_FLUSH 0x01
42#define ADB_WRITEREG 0x08
43#define ADB_READREG 0x0c
44
45
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
50
51
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
58
59
60#define ADB_RET_NOTPRESENT (-2)
61
62static void adb_device_reset(ADBDevice *d)
63{
64 qdev_reset_all(DEVICE(d));
65}
66
67int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
68{
69 ADBDevice *d;
70 int devaddr, cmd, i;
71
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);
77 }
78 return 0;
79 }
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);
86 }
87 }
88 return ADB_RET_NOTPRESENT;
89}
90
91
92int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
93{
94 ADBDevice *d;
95 int olen, i;
96 uint8_t buf[1];
97
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
107 if (olen > 0) {
108 obuf[0] = buf[0];
109 olen++;
110 break;
111 }
112 }
113 s->poll_index++;
114 }
115 return olen;
116}
117
118static const TypeInfo adb_bus_type_info = {
119 .name = TYPE_ADB_BUS,
120 .parent = TYPE_BUS,
121 .instance_size = sizeof(ADBBusState),
122};
123
124static 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()
132 }
133};
134
135static void adb_device_realizefn(DeviceState *dev, Error **errp)
136{
137 ADBDevice *d = ADB_DEVICE(dev);
138 ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
139
140 if (bus->nb_devices >= MAX_ADB_DEVICES) {
141 return;
142 }
143
144 bus->devices[bus->nb_devices++] = d;
145}
146
147static void adb_device_class_init(ObjectClass *oc, void *data)
148{
149 DeviceClass *dc = DEVICE_CLASS(oc);
150
151 dc->realize = adb_device_realizefn;
152 dc->bus_type = TYPE_ADB_BUS;
153}
154
155static 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,
161};
162
163
164
165
166#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
167
168typedef struct KBDState {
169
170 ADBDevice parent_obj;
171
172
173 uint8_t data[128];
174 int rptr, wptr, count;
175} KBDState;
176
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)
181
182typedef struct ADBKeyboardClass {
183
184 ADBDeviceClass parent_class;
185
186
187 DeviceRealize parent_realize;
188} ADBKeyboardClass;
189
190static 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,
207};
208
209static void adb_kbd_put_keycode(void *opaque, int keycode)
210{
211 KBDState *s = opaque;
212
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++;
218 }
219}
220
221static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
222{
223 static int ext_keycode;
224 KBDState *s = ADB_KEYBOARD(d);
225 int adb_keycode, keycode;
226 int olen;
227
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--;
236
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
246 obuf[1] = 0xff;
247 olen = 2;
248 ext_keycode = 0;
249 break;
250 }
251 }
252 return olen;
253}
254
255static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
256 const uint8_t *buf, int len)
257{
258 KBDState *s = ADB_KEYBOARD(d);
259 int cmd, reg, olen;
260
261 if ((buf[0] & 0x0f) == ADB_FLUSH) {
262
263 s->wptr = s->rptr = s->count = 0;
264 return 0;
265 }
266
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
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
287 d->devaddr = buf[1] & 0xf;
288 d->handler = buf[2];
289 break;
290 }
291 }
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;
302 obuf[1] = 0x07;
303 olen = 2;
304 break;
305 case 3:
306 obuf[0] = d->handler;
307 obuf[1] = d->devaddr;
308 olen = 2;
309 break;
310 }
311 break;
312 }
313 return olen;
314}
315
316static 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()
327 }
328};
329
330static void adb_kbd_reset(DeviceState *dev)
331{
332 ADBDevice *d = ADB_DEVICE(dev);
333 KBDState *s = ADB_KEYBOARD(dev);
334
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;
341}
342
343static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
344{
345 ADBDevice *d = ADB_DEVICE(dev);
346 ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
347
348 akc->parent_realize(dev, errp);
349
350 qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
351}
352
353static void adb_kbd_initfn(Object *obj)
354{
355 ADBDevice *d = ADB_DEVICE(obj);
356
357 d->devaddr = ADB_DEVID_KEYBOARD;
358}
359
360static void adb_kbd_class_init(ObjectClass *oc, void *data)
361{
362 DeviceClass *dc = DEVICE_CLASS(oc);
363 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
364 ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
365
366 akc->parent_realize = dc->realize;
367 dc->realize = adb_kbd_realizefn;
368 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
369
370 adc->devreq = adb_kbd_request;
371 dc->reset = adb_kbd_reset;
372 dc->vmsd = &vmstate_adb_kbd;
373}
374
375static 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),
382};
383
384
385
386
387#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
388
389typedef struct MouseState {
390
391 ADBDevice parent_obj;
392
393
394 int buttons_state, last_buttons_state;
395 int dx, dy, dz;
396} MouseState;
397
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)
402
403typedef struct ADBMouseClass {
404
405 ADBDeviceClass parent_class;
406
407
408 DeviceRealize parent_realize;
409} ADBMouseClass;
410
411static void adb_mouse_event(void *opaque,
412 int dx1, int dy1, int dz1, int buttons_state)
413{
414 MouseState *s = opaque;
415
416 s->dx += dx1;
417 s->dy += dy1;
418 s->dz += dz1;
419 s->buttons_state = buttons_state;
420}
421
422
423static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
424{
425 MouseState *s = ADB_MOUSE(d);
426 int dx, dy;
427
428 if (s->last_buttons_state == s->buttons_state &&
429 s->dx == 0 && s->dy == 0)
430 return 0;
431
432 dx = s->dx;
433 if (dx < -63)
434 dx = -63;
435 else if (dx > 63)
436 dx = 63;
437
438 dy = s->dy;
439 if (dy < -63)
440 dy = -63;
441 else if (dy > 63)
442 dy = 63;
443
444 s->dx -= dx;
445 s->dy -= dy;
446 s->last_buttons_state = s->buttons_state;
447
448 dx &= 0x7f;
449 dy &= 0x7f;
450
451 if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
452 dy |= 0x80;
453 if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
454 dx |= 0x80;
455
456 obuf[0] = dy;
457 obuf[1] = dx;
458 return 2;
459}
460
461static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
462 const uint8_t *buf, int len)
463{
464 MouseState *s = ADB_MOUSE(d);
465 int cmd, reg, olen;
466
467 if ((buf[0] & 0x0f) == ADB_FLUSH) {
468
469 s->buttons_state = s->last_buttons_state;
470 s->dx = 0;
471 s->dy = 0;
472 s->dz = 0;
473 return 0;
474 }
475
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
496 d->devaddr = buf[1] & 0xf;
497 break;
498 }
499 }
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;
513 }
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;
517 }
518 return olen;
519}
520
521static void adb_mouse_reset(DeviceState *dev)
522{
523 ADBDevice *d = ADB_DEVICE(dev);
524 MouseState *s = ADB_MOUSE(dev);
525
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;
530}
531
532static 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()
545 }
546};
547
548static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
549{
550 MouseState *s = ADB_MOUSE(dev);
551 ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
552
553 amc->parent_realize(dev, errp);
554
555 qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
556}
557
558static void adb_mouse_initfn(Object *obj)
559{
560 ADBDevice *d = ADB_DEVICE(obj);
561
562 d->devaddr = ADB_DEVID_MOUSE;
563}
564
565static void adb_mouse_class_init(ObjectClass *oc, void *data)
566{
567 DeviceClass *dc = DEVICE_CLASS(oc);
568 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
569 ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
570
571 amc->parent_realize = dc->realize;
572 dc->realize = adb_mouse_realizefn;
573 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
574
575 adc->devreq = adb_mouse_request;
576 dc->reset = adb_mouse_reset;
577 dc->vmsd = &vmstate_adb_mouse;
578}
579
580static 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),
587};
588
589
590static void adb_register_types(void)
591{
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);
596}
597
598type_init(adb_register_types)
599