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