(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/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.h"
   25: #include "ppc_mac.h"
   26: #include "console.h"
   27: 
   28: /* ADB commands */
   29: #define ADB_BUSRESET            0x00
   30: #define ADB_FLUSH               0x01
   31: #define ADB_WRITEREG            0x08
   32: #define ADB_READREG             0x0c
   33: 
   34: /* ADB device commands */
   35: #define ADB_CMD_SELF_TEST               0xff
   36: #define ADB_CMD_CHANGE_ID               0xfe
   37: #define ADB_CMD_CHANGE_ID_AND_ACT       0xfd
   38: #define ADB_CMD_CHANGE_ID_AND_ENABLE    0x00
   39: 
   40: /* ADB default device IDs (upper 4 bits of ADB command byte) */
   41: #define ADB_DONGLE      1
   42: #define ADB_KEYBOARD    2
   43: #define ADB_MOUSE       3
   44: #define ADB_TABLET      4
   45: #define ADB_MODEM       5
   46: #define ADB_MISC        7
   47: 
   48: /* error codes */
   49: #define ADB_RET_NOTPRESENT (-2)
   50: 
   51: int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
   52: {
   53:     ADBDevice *d;
   54:     int devaddr, cmd, i;
   55: 
   56:     cmd = buf[0] & 0xf;
   57:     if (cmd == ADB_BUSRESET) {
   58:         for(i = 0; i < s->nb_devices; i++) {
   59:             d = &s->devices[i];
   60:             if (d->devreset) {
   61:                 d->devreset(d);
   62:             }
   63:         }
   64:         return 0;
   65:     }
   66:     devaddr = buf[0] >> 4;
   67:     for(i = 0; i < s->nb_devices; i++) {
   68:         d = &s->devices[i];
   69:         if (d->devaddr == devaddr) {
   70:             return d->devreq(d, obuf, buf, len);
   71:         }
   72:     }
   73:     return ADB_RET_NOTPRESENT;
   74: }
   75: 
   76: /* XXX: move that to cuda ? */
   77: int adb_poll(ADBBusState *s, uint8_t *obuf)
   78: {
   79:     ADBDevice *d;
   80:     int olen, i;
   81:     uint8_t buf[1];
   82: 
   83:     olen = 0;
   84:     for(i = 0; i < s->nb_devices; i++) {
   85:         if (s->poll_index >= s->nb_devices)
   86:             s->poll_index = 0;
   87:         d = &s->devices[s->poll_index];
   88:         buf[0] = ADB_READREG | (d->devaddr << 4);
   89:         olen = adb_request(s, obuf + 1, buf, 1);
   90:         /* if there is data, we poll again the same device */
   91:         if (olen > 0) {
   92:             obuf[0] = buf[0];
   93:             olen++;
   94:             break;
   95:         }
   96:         s->poll_index++;
   97:     }
   98:     return olen;
   99: }
  100: 
  101: ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
  102:                                ADBDeviceRequest *devreq,
  103:                                ADBDeviceReset *devreset,
  104:                                void *opaque)
  105: {
  106:     ADBDevice *d;
  107:     if (s->nb_devices >= MAX_ADB_DEVICES)
  108:         return NULL;
  109:     d = &s->devices[s->nb_devices++];
  110:     d->bus = s;
  111:     d->devaddr = devaddr;
  112:     d->devreq = devreq;
  113:     d->devreset = devreset;
  114:     d->opaque = opaque;
  115:     return d;
  116: }
  117: 
  118: /***************************************************************/
  119: /* Keyboard ADB device */
  120: 
  121: typedef struct KBDState {
  122:     uint8_t data[128];
  123:     int rptr, wptr, count;
  124: } KBDState;
  125: 
  126: static const uint8_t pc_to_adb_keycode[256] = {
  127:   0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
  128:  12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
  129:   2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
  130:  11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
  131:  97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
  132:  84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
  133:   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  134:   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  135:   0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
  136:   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
  137:   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
  138:   0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
  139:   0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
  140:  61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
  141:   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  142:   0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  143: };
  144: 
  145: static void adb_kbd_put_keycode(void *opaque, int keycode)
  146: {
  147:     ADBDevice *d = opaque;
  148:     KBDState *s = d->opaque;
  149: 
  150:     if (s->count < sizeof(s->data)) {
  151:         s->data[s->wptr] = keycode;
  152:         if (++s->wptr == sizeof(s->data))
  153:             s->wptr = 0;
  154:         s->count++;
  155:     }
  156: }
  157: 
  158: static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
  159: {
  160:     static int ext_keycode;
  161:     KBDState *s = d->opaque;
  162:     int adb_keycode, keycode;
  163:     int olen;
  164: 
  165:     olen = 0;
  166:     for(;;) {
  167:         if (s->count == 0)
  168:             break;
  169:         keycode = s->data[s->rptr];
  170:         if (++s->rptr == sizeof(s->data))
  171:             s->rptr = 0;
  172:         s->count--;
  173: 
  174:         if (keycode == 0xe0) {
  175:             ext_keycode = 1;
  176:         } else {
  177:             if (ext_keycode)
  178:                 adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
  179:             else
  180:                 adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
  181:             obuf[0] = adb_keycode | (keycode & 0x80);
  182:             /* NOTE: could put a second keycode if needed */
  183:             obuf[1] = 0xff;
  184:             olen = 2;
  185:             ext_keycode = 0;
  186:             break;
  187:         }
  188:     }
  189:     return olen;
  190: }
  191: 
  192: static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
  193:                            const uint8_t *buf, int len)
  194: {
  195:     KBDState *s = d->opaque;
  196:     int cmd, reg, olen;
  197: 
  198:     if ((buf[0] & 0x0f) == ADB_FLUSH) {
  199:         /* flush keyboard fifo */
  200:         s->wptr = s->rptr = s->count = 0;
  201:         return 0;
  202:     }
  203: 
  204:     cmd = buf[0] & 0xc;
  205:     reg = buf[0] & 0x3;
  206:     olen = 0;
  207:     switch(cmd) {
  208:     case ADB_WRITEREG:
  209:         switch(reg) {
  210:         case 2:
  211:             /* LED status */
  212:             break;
  213:         case 3:
  214:             switch(buf[2]) {
  215:             case ADB_CMD_SELF_TEST:
  216:                 break;
  217:             case ADB_CMD_CHANGE_ID:
  218:             case ADB_CMD_CHANGE_ID_AND_ACT:
  219:             case ADB_CMD_CHANGE_ID_AND_ENABLE:
  220:                 d->devaddr = buf[1] & 0xf;
  221:                 break;
  222:             default:
  223:                 /* XXX: check this */
  224:                 d->devaddr = buf[1] & 0xf;
  225:                 d->handler = buf[2];
  226:                 break;
  227:             }
  228:         }
  229:         break;
  230:     case ADB_READREG:
  231:         switch(reg) {
  232:         case 0:
  233:             olen = adb_kbd_poll(d, obuf);
  234:             break;
  235:         case 1:
  236:             break;
  237:         case 2:
  238:             obuf[0] = 0x00; /* XXX: check this */
  239:             obuf[1] = 0x07; /* led status */
  240:             olen = 2;
  241:             break;
  242:         case 3:
  243:             obuf[0] = d->handler;
  244:             obuf[1] = d->devaddr;
  245:             olen = 2;
  246:             break;
  247:         }
  248:         break;
  249:     }
  250:     return olen;
  251: }
  252: 
  253: static int adb_kbd_reset(ADBDevice *d)
  254: {
  255:     KBDState *s = d->opaque;
  256: 
  257:     d->handler = 1;
  258:     d->devaddr = ADB_KEYBOARD;
  259:     memset(s, 0, sizeof(KBDState));
  260: 
  261:     return 0;
  262: }
  263: 
  264: void adb_kbd_init(ADBBusState *bus)
  265: {
  266:     ADBDevice *d;
  267:     KBDState *s;
  268:     s = qemu_mallocz(sizeof(KBDState));
  269:     d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
  270:                             adb_kbd_reset, s);
  271:     adb_kbd_reset(d);
  272:     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
  273: }
  274: 
  275: /***************************************************************/
  276: /* Mouse ADB device */
  277: 
  278: typedef struct MouseState {
  279:     int buttons_state, last_buttons_state;
  280:     int dx, dy, dz;
  281: } MouseState;
  282: 
  283: static void adb_mouse_event(void *opaque,
  284:                             int dx1, int dy1, int dz1, int buttons_state)
  285: {
  286:     ADBDevice *d = opaque;
  287:     MouseState *s = d->opaque;
  288: 
  289:     s->dx += dx1;
  290:     s->dy += dy1;
  291:     s->dz += dz1;
  292:     s->buttons_state = buttons_state;
  293: }
  294: 
  295: 
  296: static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
  297: {
  298:     MouseState *s = d->opaque;
  299:     int dx, dy;
  300: 
  301:     if (s->last_buttons_state == s->buttons_state &&
  302:         s->dx == 0 && s->dy == 0)
  303:         return 0;
  304: 
  305:     dx = s->dx;
  306:     if (dx < -63)
  307:         dx = -63;
  308:     else if (dx > 63)
  309:         dx = 63;
  310: 
  311:     dy = s->dy;
  312:     if (dy < -63)
  313:         dy = -63;
  314:     else if (dy > 63)
  315:         dy = 63;
  316: 
  317:     s->dx -= dx;
  318:     s->dy -= dy;
  319:     s->last_buttons_state = s->buttons_state;
  320: 
  321:     dx &= 0x7f;
  322:     dy &= 0x7f;
  323: 
  324:     if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
  325:         dy |= 0x80;
  326:     if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
  327:         dx |= 0x80;
  328: 
  329:     obuf[0] = dy;
  330:     obuf[1] = dx;
  331:     return 2;
  332: }
  333: 
  334: static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
  335:                              const uint8_t *buf, int len)
  336: {
  337:     MouseState *s = d->opaque;
  338:     int cmd, reg, olen;
  339: 
  340:     if ((buf[0] & 0x0f) == ADB_FLUSH) {
  341:         /* flush mouse fifo */
  342:         s->buttons_state = s->last_buttons_state;
  343:         s->dx = 0;
  344:         s->dy = 0;
  345:         s->dz = 0;
  346:         return 0;
  347:     }
  348: 
  349:     cmd = buf[0] & 0xc;
  350:     reg = buf[0] & 0x3;
  351:     olen = 0;
  352:     switch(cmd) {
  353:     case ADB_WRITEREG:
  354:         switch(reg) {
  355:         case 2:
  356:             break;
  357:         case 3:
  358:             switch(buf[2]) {
  359:             case ADB_CMD_SELF_TEST:
  360:                 break;
  361:             case ADB_CMD_CHANGE_ID:
  362:             case ADB_CMD_CHANGE_ID_AND_ACT:
  363:             case ADB_CMD_CHANGE_ID_AND_ENABLE:
  364:                 d->devaddr = buf[1] & 0xf;
  365:                 break;
  366:             default:
  367:                 /* XXX: check this */
  368:                 d->devaddr = buf[1] & 0xf;
  369:                 break;
  370:             }
  371:         }
  372:         break;
  373:     case ADB_READREG:
  374:         switch(reg) {
  375:         case 0:
  376:             olen = adb_mouse_poll(d, obuf);
  377:             break;
  378:         case 1:
  379:             break;
  380:         case 3:
  381:             obuf[0] = d->handler;
  382:             obuf[1] = d->devaddr;
  383:             olen = 2;
  384:             break;
  385:         }
  386:         break;
  387:     }
  388:     return olen;
  389: }
  390: 
  391: static int adb_mouse_reset(ADBDevice *d)
  392: {
  393:     MouseState *s = d->opaque;
  394: 
  395:     d->handler = 2;
  396:     d->devaddr = ADB_MOUSE;
  397:     memset(s, 0, sizeof(MouseState));
  398: 
  399:     return 0;
  400: }
  401: 
  402: void adb_mouse_init(ADBBusState *bus)
  403: {
  404:     ADBDevice *d;
  405:     MouseState *s;
  406: 
  407:     s = qemu_mallocz(sizeof(MouseState));
  408:     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
  409:                             adb_mouse_reset, s);
  410:     adb_mouse_reset(d);
  411:     qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
  412: }
Syntax (Markdown)