xref: /openbmc/qemu/hw/input/adb.c (revision 27215a22)
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 
366     adc->devreq = adb_kbd_request;
367     dc->reset = adb_kbd_reset;
368     dc->vmsd = &vmstate_adb_kbd;
369 }
370 
371 static 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 /* Mouse ADB device */
382 
383 #define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
384 
385 typedef struct MouseState {
386     /*< public >*/
387     ADBDevice parent_obj;
388     /*< private >*/
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 
399 typedef struct ADBMouseClass {
400     /*< public >*/
401     ADBDeviceClass parent_class;
402     /*< private >*/
403 
404     DeviceRealize parent_realize;
405 } ADBMouseClass;
406 
407 static 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 
419 static 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 
457 static 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         /* flush mouse fifo */
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                 /* XXX: check this */
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 
517 static 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 
528 static 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 
544 static 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 
554 static void adb_mouse_initfn(Object *obj)
555 {
556     ADBDevice *d = ADB_DEVICE(obj);
557 
558     d->devaddr = ADB_DEVID_MOUSE;
559 }
560 
561 static 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 
575 static 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 
585 static 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 
593 type_init(adb_register_types)
594