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