Statistics
| Branch: | Revision:

root / hw / input / adb.c @ a8aec295

History | View | Annotate | Download (15 kB)

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)