qemu/hw/input/adb.c
<<
>>
Prefs
   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, ...) \
  33do { 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
  61static void adb_device_reset(ADBDevice *d)
  62{
  63    qdev_reset_all(DEVICE(d));
  64}
  65
  66int 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 ? */
  91int 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
 115static const TypeInfo adb_bus_type_info = {
 116    .name = TYPE_ADB_BUS,
 117    .parent = TYPE_BUS,
 118    .instance_size = sizeof(ADBBusState),
 119};
 120
 121static 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
 132static 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
 144static 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
 152static 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
 165typedef 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
 179typedef struct ADBKeyboardClass {
 180    /*< private >*/
 181    ADBDeviceClass parent_class;
 182    /*< public >*/
 183
 184    DeviceRealize parent_realize;
 185} ADBKeyboardClass;
 186
 187static 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
 206static 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
 218static 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
 252static 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
 313static 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
 327static 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
 340static 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
 350static void adb_kbd_initfn(Object *obj)
 351{
 352    ADBDevice *d = ADB_DEVICE(obj);
 353
 354    d->devaddr = ADB_DEVID_KEYBOARD;
 355}
 356
 357static 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
 371static 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
 385typedef 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
 399typedef struct ADBMouseClass {
 400    /*< public >*/
 401    ADBDeviceClass parent_class;
 402    /*< private >*/
 403
 404    DeviceRealize parent_realize;
 405} ADBMouseClass;
 406
 407static 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
 419static 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
 457static 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
 517static 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
 528static 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
 544static 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
 554static void adb_mouse_initfn(Object *obj)
 555{
 556    ADBDevice *d = ADB_DEVICE(obj);
 557
 558    d->devaddr = ADB_DEVID_MOUSE;
 559}
 560
 561static 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
 575static 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
 585static 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
 593type_init(adb_register_types)
 594