]> Git Repo - qemu.git/blob - hw/input/adb.c
Merge remote-tracking branch 'bonzini/hw-dirs' into staging
[qemu.git] / hw / input / adb.c
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 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
133 static 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
141 static 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 /* Keyboard ADB device */
151
152 #define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
153
154 typedef struct KBDState {
155     /*< private >*/
156     ADBDevice parent_obj;
157     /*< public >*/
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
168 typedef struct ADBKeyboardClass {
169     /*< private >*/
170     ADBDeviceClass parent_class;
171     /*< public >*/
172
173     DeviceRealize parent_realize;
174 } ADBKeyboardClass;
175
176 static 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
195 static 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
207 static 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             /* NOTE: could put a second keycode if needed */
232             obuf[1] = 0xff;
233             olen = 2;
234             ext_keycode = 0;
235             break;
236         }
237     }
238     return olen;
239 }
240
241 static 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         /* flush keyboard fifo */
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             /* LED status */
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                 /* XXX: check this */
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; /* XXX: check this */
288             obuf[1] = 0x07; /* led status */
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
302 static const VMStateDescription vmstate_adb_kbd = {
303     .name = "adb_kbd",
304     .version_id = 1,
305     .minimum_version_id = 1,
306     .minimum_version_id_old = 1,
307     .fields      = (VMStateField[]) {
308         VMSTATE_BUFFER(data, KBDState),
309         VMSTATE_INT32(rptr, KBDState),
310         VMSTATE_INT32(wptr, KBDState),
311         VMSTATE_INT32(count, KBDState),
312         VMSTATE_END_OF_LIST()
313     }
314 };
315
316 static void adb_kbd_reset(DeviceState *dev)
317 {
318     ADBDevice *d = ADB_DEVICE(dev);
319     KBDState *s = ADB_KEYBOARD(dev);
320
321     d->handler = 1;
322     d->devaddr = ADB_DEVID_KEYBOARD;
323     memset(s->data, 0, sizeof(s->data));
324     s->rptr = 0;
325     s->wptr = 0;
326     s->count = 0;
327 }
328
329 static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
330 {
331     ADBDevice *d = ADB_DEVICE(dev);
332     ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
333
334     akc->parent_realize(dev, errp);
335
336     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
337 }
338
339 static void adb_kbd_initfn(Object *obj)
340 {
341     ADBDevice *d = ADB_DEVICE(obj);
342
343     d->devaddr = ADB_DEVID_KEYBOARD;
344 }
345
346 static void adb_kbd_class_init(ObjectClass *oc, void *data)
347 {
348     DeviceClass *dc = DEVICE_CLASS(oc);
349     ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
350     ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
351
352     akc->parent_realize = dc->realize;
353     dc->realize = adb_kbd_realizefn;
354
355     adc->devreq = adb_kbd_request;
356     dc->reset = adb_kbd_reset;
357     dc->vmsd = &vmstate_adb_kbd;
358 }
359
360 static const TypeInfo adb_kbd_type_info = {
361     .name = TYPE_ADB_KEYBOARD,
362     .parent = TYPE_ADB_DEVICE,
363     .instance_size = sizeof(KBDState),
364     .instance_init = adb_kbd_initfn,
365     .class_init = adb_kbd_class_init,
366     .class_size = sizeof(ADBKeyboardClass),
367 };
368
369 /***************************************************************/
370 /* Mouse ADB device */
371
372 #define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
373
374 typedef struct MouseState {
375     /*< public >*/
376     ADBDevice parent_obj;
377     /*< private >*/
378
379     int buttons_state, last_buttons_state;
380     int dx, dy, dz;
381 } MouseState;
382
383 #define ADB_MOUSE_CLASS(class) \
384     OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
385 #define ADB_MOUSE_GET_CLASS(obj) \
386     OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
387
388 typedef struct ADBMouseClass {
389     /*< public >*/
390     ADBDeviceClass parent_class;
391     /*< private >*/
392
393     DeviceRealize parent_realize;
394 } ADBMouseClass;
395
396 static void adb_mouse_event(void *opaque,
397                             int dx1, int dy1, int dz1, int buttons_state)
398 {
399     MouseState *s = opaque;
400
401     s->dx += dx1;
402     s->dy += dy1;
403     s->dz += dz1;
404     s->buttons_state = buttons_state;
405 }
406
407
408 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
409 {
410     MouseState *s = ADB_MOUSE(d);
411     int dx, dy;
412
413     if (s->last_buttons_state == s->buttons_state &&
414         s->dx == 0 && s->dy == 0)
415         return 0;
416
417     dx = s->dx;
418     if (dx < -63)
419         dx = -63;
420     else if (dx > 63)
421         dx = 63;
422
423     dy = s->dy;
424     if (dy < -63)
425         dy = -63;
426     else if (dy > 63)
427         dy = 63;
428
429     s->dx -= dx;
430     s->dy -= dy;
431     s->last_buttons_state = s->buttons_state;
432
433     dx &= 0x7f;
434     dy &= 0x7f;
435
436     if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
437         dy |= 0x80;
438     if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
439         dx |= 0x80;
440
441     obuf[0] = dy;
442     obuf[1] = dx;
443     return 2;
444 }
445
446 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
447                              const uint8_t *buf, int len)
448 {
449     MouseState *s = ADB_MOUSE(d);
450     int cmd, reg, olen;
451
452     if ((buf[0] & 0x0f) == ADB_FLUSH) {
453         /* flush mouse fifo */
454         s->buttons_state = s->last_buttons_state;
455         s->dx = 0;
456         s->dy = 0;
457         s->dz = 0;
458         return 0;
459     }
460
461     cmd = buf[0] & 0xc;
462     reg = buf[0] & 0x3;
463     olen = 0;
464     switch(cmd) {
465     case ADB_WRITEREG:
466         ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
467         switch(reg) {
468         case 2:
469             break;
470         case 3:
471             switch(buf[2]) {
472             case ADB_CMD_SELF_TEST:
473                 break;
474             case ADB_CMD_CHANGE_ID:
475             case ADB_CMD_CHANGE_ID_AND_ACT:
476             case ADB_CMD_CHANGE_ID_AND_ENABLE:
477                 d->devaddr = buf[1] & 0xf;
478                 break;
479             default:
480                 /* XXX: check this */
481                 d->devaddr = buf[1] & 0xf;
482                 break;
483             }
484         }
485         break;
486     case ADB_READREG:
487         switch(reg) {
488         case 0:
489             olen = adb_mouse_poll(d, obuf);
490             break;
491         case 1:
492             break;
493         case 3:
494             obuf[0] = d->handler;
495             obuf[1] = d->devaddr;
496             olen = 2;
497             break;
498         }
499         ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
500                     obuf[0], obuf[1]);
501         break;
502     }
503     return olen;
504 }
505
506 static void adb_mouse_reset(DeviceState *dev)
507 {
508     ADBDevice *d = ADB_DEVICE(dev);
509     MouseState *s = ADB_MOUSE(dev);
510
511     d->handler = 2;
512     d->devaddr = ADB_DEVID_MOUSE;
513     s->last_buttons_state = s->buttons_state = 0;
514     s->dx = s->dy = s->dz = 0;
515 }
516
517 static const VMStateDescription vmstate_adb_mouse = {
518     .name = "adb_mouse",
519     .version_id = 1,
520     .minimum_version_id = 1,
521     .minimum_version_id_old = 1,
522     .fields      = (VMStateField[]) {
523         VMSTATE_INT32(buttons_state, MouseState),
524         VMSTATE_INT32(last_buttons_state, MouseState),
525         VMSTATE_INT32(dx, MouseState),
526         VMSTATE_INT32(dy, MouseState),
527         VMSTATE_INT32(dz, MouseState),
528         VMSTATE_END_OF_LIST()
529     }
530 };
531
532 static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
533 {
534     MouseState *s = ADB_MOUSE(dev);
535     ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
536
537     amc->parent_realize(dev, errp);
538
539     qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
540 }
541
542 static void adb_mouse_initfn(Object *obj)
543 {
544     ADBDevice *d = ADB_DEVICE(obj);
545
546     d->devaddr = ADB_DEVID_MOUSE;
547 }
548
549 static void adb_mouse_class_init(ObjectClass *oc, void *data)
550 {
551     DeviceClass *dc = DEVICE_CLASS(oc);
552     ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
553     ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
554
555     amc->parent_realize = dc->realize;
556     dc->realize = adb_mouse_realizefn;
557
558     adc->devreq = adb_mouse_request;
559     dc->reset = adb_mouse_reset;
560     dc->vmsd = &vmstate_adb_mouse;
561 }
562
563 static const TypeInfo adb_mouse_type_info = {
564     .name = TYPE_ADB_MOUSE,
565     .parent = TYPE_ADB_DEVICE,
566     .instance_size = sizeof(MouseState),
567     .instance_init = adb_mouse_initfn,
568     .class_init = adb_mouse_class_init,
569     .class_size = sizeof(ADBMouseClass),
570 };
571
572
573 static void adb_register_types(void)
574 {
575     type_register_static(&adb_bus_type_info);
576     type_register_static(&adb_device_type_info);
577     type_register_static(&adb_kbd_type_info);
578     type_register_static(&adb_mouse_type_info);
579 }
580
581 type_init(adb_register_types)
This page took 0.054141 seconds and 4 git commands to generate.