xref: /openbmc/qemu/hw/input/adb.c (revision 61b9251a)
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 "hw/hw.h"
25 #include "hw/input/adb.h"
26 #include "ui/console.h"
27 
28 /* debug ADB */
29 //#define DEBUG_ADB
30 
31 #ifdef DEBUG_ADB
32 #define ADB_DPRINTF(fmt, ...) \
33 do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
34 #else
35 #define ADB_DPRINTF(fmt, ...)
36 #endif
37 
38 /* ADB commands */
39 #define ADB_BUSRESET		0x00
40 #define ADB_FLUSH               0x01
41 #define ADB_WRITEREG		0x08
42 #define ADB_READREG		0x0c
43 
44 /* ADB device commands */
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 /* ADB default device IDs (upper 4 bits of ADB command byte) */
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 /* error codes */
59 #define ADB_RET_NOTPRESENT (-2)
60 
61 static void adb_device_reset(ADBDevice *d)
62 {
63     qdev_reset_all(DEVICE(d));
64 }
65 
66 int 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 /* XXX: move that to cuda ? */
91 int 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         /* if there is data, we poll again the same device */
105         if (olen > 0) {
106             obuf[0] = buf[0];
107             olen++;
108             break;
109         }
110         s->poll_index++;
111     }
112     return olen;
113 }
114 
115 static const TypeInfo adb_bus_type_info = {
116     .name = TYPE_ADB_BUS,
117     .parent = TYPE_BUS,
118     .instance_size = sizeof(ADBBusState),
119 };
120 
121 static 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 
132 static 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 
144 static 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 
152 static 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 /* Keyboard ADB device */
162 
163 #define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
164 
165 typedef struct KBDState {
166     /*< private >*/
167     ADBDevice parent_obj;
168     /*< public >*/
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 
179 typedef struct ADBKeyboardClass {
180     /*< private >*/
181     ADBDeviceClass parent_class;
182     /*< public >*/
183 
184     DeviceRealize parent_realize;
185 } ADBKeyboardClass;
186 
187 static 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 
206 static 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 
218 static 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             /* NOTE: could put a second keycode if needed */
243             obuf[1] = 0xff;
244             olen = 2;
245             ext_keycode = 0;
246             break;
247         }
248     }
249     return olen;
250 }
251 
252 static 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         /* flush keyboard fifo */
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             /* LED status */
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                 /* XXX: check this */
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; /* XXX: check this */
299             obuf[1] = 0x07; /* led status */
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 
313 static 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 
327 static 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 
340 static 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 
350 static void adb_kbd_initfn(Object *obj)
351 {
352     ADBDevice *d = ADB_DEVICE(obj);
353 
354     d->devaddr = ADB_DEVID_KEYBOARD;
355 }
356 
357 static 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     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
366 
367     adc->devreq = adb_kbd_request;
368     dc->reset = adb_kbd_reset;
369     dc->vmsd = &vmstate_adb_kbd;
370 }
371 
372 static const TypeInfo adb_kbd_type_info = {
373     .name = TYPE_ADB_KEYBOARD,
374     .parent = TYPE_ADB_DEVICE,
375     .instance_size = sizeof(KBDState),
376     .instance_init = adb_kbd_initfn,
377     .class_init = adb_kbd_class_init,
378     .class_size = sizeof(ADBKeyboardClass),
379 };
380 
381 /***************************************************************/
382 /* Mouse ADB device */
383 
384 #define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
385 
386 typedef struct MouseState {
387     /*< public >*/
388     ADBDevice parent_obj;
389     /*< private >*/
390 
391     int buttons_state, last_buttons_state;
392     int dx, dy, dz;
393 } MouseState;
394 
395 #define ADB_MOUSE_CLASS(class) \
396     OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
397 #define ADB_MOUSE_GET_CLASS(obj) \
398     OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
399 
400 typedef struct ADBMouseClass {
401     /*< public >*/
402     ADBDeviceClass parent_class;
403     /*< private >*/
404 
405     DeviceRealize parent_realize;
406 } ADBMouseClass;
407 
408 static void adb_mouse_event(void *opaque,
409                             int dx1, int dy1, int dz1, int buttons_state)
410 {
411     MouseState *s = opaque;
412 
413     s->dx += dx1;
414     s->dy += dy1;
415     s->dz += dz1;
416     s->buttons_state = buttons_state;
417 }
418 
419 
420 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
421 {
422     MouseState *s = ADB_MOUSE(d);
423     int dx, dy;
424 
425     if (s->last_buttons_state == s->buttons_state &&
426         s->dx == 0 && s->dy == 0)
427         return 0;
428 
429     dx = s->dx;
430     if (dx < -63)
431         dx = -63;
432     else if (dx > 63)
433         dx = 63;
434 
435     dy = s->dy;
436     if (dy < -63)
437         dy = -63;
438     else if (dy > 63)
439         dy = 63;
440 
441     s->dx -= dx;
442     s->dy -= dy;
443     s->last_buttons_state = s->buttons_state;
444 
445     dx &= 0x7f;
446     dy &= 0x7f;
447 
448     if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
449         dy |= 0x80;
450     if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
451         dx |= 0x80;
452 
453     obuf[0] = dy;
454     obuf[1] = dx;
455     return 2;
456 }
457 
458 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
459                              const uint8_t *buf, int len)
460 {
461     MouseState *s = ADB_MOUSE(d);
462     int cmd, reg, olen;
463 
464     if ((buf[0] & 0x0f) == ADB_FLUSH) {
465         /* flush mouse fifo */
466         s->buttons_state = s->last_buttons_state;
467         s->dx = 0;
468         s->dy = 0;
469         s->dz = 0;
470         return 0;
471     }
472 
473     cmd = buf[0] & 0xc;
474     reg = buf[0] & 0x3;
475     olen = 0;
476     switch(cmd) {
477     case ADB_WRITEREG:
478         ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
479         switch(reg) {
480         case 2:
481             break;
482         case 3:
483             switch(buf[2]) {
484             case ADB_CMD_SELF_TEST:
485                 break;
486             case ADB_CMD_CHANGE_ID:
487             case ADB_CMD_CHANGE_ID_AND_ACT:
488             case ADB_CMD_CHANGE_ID_AND_ENABLE:
489                 d->devaddr = buf[1] & 0xf;
490                 break;
491             default:
492                 /* XXX: check this */
493                 d->devaddr = buf[1] & 0xf;
494                 break;
495             }
496         }
497         break;
498     case ADB_READREG:
499         switch(reg) {
500         case 0:
501             olen = adb_mouse_poll(d, obuf);
502             break;
503         case 1:
504             break;
505         case 3:
506             obuf[0] = d->handler;
507             obuf[1] = d->devaddr;
508             olen = 2;
509             break;
510         }
511         ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
512                     obuf[0], obuf[1]);
513         break;
514     }
515     return olen;
516 }
517 
518 static void adb_mouse_reset(DeviceState *dev)
519 {
520     ADBDevice *d = ADB_DEVICE(dev);
521     MouseState *s = ADB_MOUSE(dev);
522 
523     d->handler = 2;
524     d->devaddr = ADB_DEVID_MOUSE;
525     s->last_buttons_state = s->buttons_state = 0;
526     s->dx = s->dy = s->dz = 0;
527 }
528 
529 static const VMStateDescription vmstate_adb_mouse = {
530     .name = "adb_mouse",
531     .version_id = 2,
532     .minimum_version_id = 2,
533     .fields = (VMStateField[]) {
534         VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
535                        ADBDevice),
536         VMSTATE_INT32(buttons_state, MouseState),
537         VMSTATE_INT32(last_buttons_state, MouseState),
538         VMSTATE_INT32(dx, MouseState),
539         VMSTATE_INT32(dy, MouseState),
540         VMSTATE_INT32(dz, MouseState),
541         VMSTATE_END_OF_LIST()
542     }
543 };
544 
545 static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
546 {
547     MouseState *s = ADB_MOUSE(dev);
548     ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
549 
550     amc->parent_realize(dev, errp);
551 
552     qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
553 }
554 
555 static void adb_mouse_initfn(Object *obj)
556 {
557     ADBDevice *d = ADB_DEVICE(obj);
558 
559     d->devaddr = ADB_DEVID_MOUSE;
560 }
561 
562 static void adb_mouse_class_init(ObjectClass *oc, void *data)
563 {
564     DeviceClass *dc = DEVICE_CLASS(oc);
565     ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
566     ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
567 
568     amc->parent_realize = dc->realize;
569     dc->realize = adb_mouse_realizefn;
570     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
571 
572     adc->devreq = adb_mouse_request;
573     dc->reset = adb_mouse_reset;
574     dc->vmsd = &vmstate_adb_mouse;
575 }
576 
577 static const TypeInfo adb_mouse_type_info = {
578     .name = TYPE_ADB_MOUSE,
579     .parent = TYPE_ADB_DEVICE,
580     .instance_size = sizeof(MouseState),
581     .instance_init = adb_mouse_initfn,
582     .class_init = adb_mouse_class_init,
583     .class_size = sizeof(ADBMouseClass),
584 };
585 
586 
587 static void adb_register_types(void)
588 {
589     type_register_static(&adb_bus_type_info);
590     type_register_static(&adb_device_type_info);
591     type_register_static(&adb_kbd_type_info);
592     type_register_static(&adb_mouse_type_info);
593 }
594 
595 type_init(adb_register_types)
596