Annotation of qemu/hw/ads7846.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * TI ADS7846 / TSC2046 chip emulation.
                      3:  *
                      4:  * Copyright (c) 2006 Openedhand Ltd.
                      5:  * Written by Andrzej Zaborowski <[email protected]>
                      6:  *
                      7:  * This code is licensed under the GNU GPL v2.
                      8:  */
                      9: 
1.1.1.3 ! root       10: #include "ssi.h"
1.1       root       11: #include "console.h"
                     12: 
1.1.1.3 ! root       13: typedef struct {
        !            14:     SSISlave ssidev;
1.1       root       15:     qemu_irq interrupt;
                     16: 
                     17:     int input[8];
                     18:     int pressure;
                     19:     int noise;
                     20: 
                     21:     int cycle;
                     22:     int output;
1.1.1.3 ! root       23: } ADS7846State;
1.1       root       24: 
                     25: /* Control-byte bitfields */
                     26: #define CB_PD0         (1 << 0)
                     27: #define CB_PD1         (1 << 1)
                     28: #define CB_SER         (1 << 2)
                     29: #define CB_MODE                (1 << 3)
                     30: #define CB_A0          (1 << 4)
                     31: #define CB_A1          (1 << 5)
                     32: #define CB_A2          (1 << 6)
                     33: #define CB_START       (1 << 7)
                     34: 
                     35: #define X_AXIS_DMAX    3470
                     36: #define X_AXIS_MIN     290
                     37: #define Y_AXIS_DMAX    3450
                     38: #define Y_AXIS_MIN     200
                     39: 
                     40: #define ADS_VBAT       2000
                     41: #define ADS_VAUX       2000
                     42: #define ADS_TEMP0      2000
                     43: #define ADS_TEMP1      3000
                     44: #define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
                     45: #define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
                     46: #define ADS_Z1POS(x, y)        600
                     47: #define ADS_Z2POS(x, y)        (600 + 6000 / ADS_XPOS(x, y))
                     48: 
1.1.1.3 ! root       49: static void ads7846_int_update(ADS7846State *s)
1.1       root       50: {
                     51:     if (s->interrupt)
                     52:         qemu_set_irq(s->interrupt, s->pressure == 0);
                     53: }
                     54: 
1.1.1.3 ! root       55: static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
1.1       root       56: {
1.1.1.3 ! root       57:     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
1.1       root       58: 
                     59:     switch (s->cycle ++) {
                     60:     case 0:
                     61:         if (!(value & CB_START)) {
                     62:             s->cycle = 0;
                     63:             break;
                     64:         }
                     65: 
                     66:         s->output = s->input[(value >> 4) & 7];
                     67: 
                     68:         /* Imitate the ADC noise, some drivers expect this.  */
                     69:         s->noise = (s->noise + 3) & 7;
                     70:         switch ((value >> 4) & 7) {
                     71:         case 1: s->output += s->noise ^ 2; break;
                     72:         case 3: s->output += s->noise ^ 0; break;
                     73:         case 4: s->output += s->noise ^ 7; break;
                     74:         case 5: s->output += s->noise ^ 5; break;
                     75:         }
                     76: 
                     77:         if (value & CB_MODE)
                     78:             s->output >>= 4;   /* 8 bits instead of 12 */
                     79: 
                     80:         break;
                     81:     case 1:
                     82:         s->cycle = 0;
                     83:         break;
                     84:     }
1.1.1.3 ! root       85:     return s->output;
1.1       root       86: }
                     87: 
                     88: static void ads7846_ts_event(void *opaque,
                     89:                 int x, int y, int z, int buttons_state)
                     90: {
1.1.1.3 ! root       91:     ADS7846State *s = opaque;
1.1       root       92: 
                     93:     if (buttons_state) {
                     94:         x = 0x7fff - x;
                     95:         s->input[1] = ADS_XPOS(x, y);
                     96:         s->input[3] = ADS_Z1POS(x, y);
                     97:         s->input[4] = ADS_Z2POS(x, y);
                     98:         s->input[5] = ADS_YPOS(x, y);
                     99:     }
                    100: 
                    101:     if (s->pressure == !buttons_state) {
                    102:         s->pressure = !!buttons_state;
                    103: 
                    104:         ads7846_int_update(s);
                    105:     }
                    106: }
                    107: 
                    108: static void ads7846_save(QEMUFile *f, void *opaque)
                    109: {
1.1.1.3 ! root      110:     ADS7846State *s = (ADS7846State *) opaque;
1.1       root      111:     int i;
                    112: 
                    113:     for (i = 0; i < 8; i ++)
                    114:         qemu_put_be32(f, s->input[i]);
                    115:     qemu_put_be32(f, s->noise);
                    116:     qemu_put_be32(f, s->cycle);
                    117:     qemu_put_be32(f, s->output);
                    118: }
                    119: 
                    120: static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
                    121: {
1.1.1.3 ! root      122:     ADS7846State *s = (ADS7846State *) opaque;
1.1       root      123:     int i;
                    124: 
                    125:     for (i = 0; i < 8; i ++)
                    126:         s->input[i] = qemu_get_be32(f);
                    127:     s->noise = qemu_get_be32(f);
                    128:     s->cycle = qemu_get_be32(f);
                    129:     s->output = qemu_get_be32(f);
                    130: 
                    131:     s->pressure = 0;
                    132:     ads7846_int_update(s);
                    133: 
                    134:     return 0;
                    135: }
                    136: 
1.1.1.3 ! root      137: static void ads7846_init(SSISlave *dev)
1.1       root      138: {
1.1.1.3 ! root      139:     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
1.1       root      140: 
1.1.1.3 ! root      141:     qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
1.1       root      142: 
                    143:     s->input[0] = ADS_TEMP0;   /* TEMP0 */
                    144:     s->input[2] = ADS_VBAT;    /* VBAT */
                    145:     s->input[6] = ADS_VAUX;    /* VAUX */
                    146:     s->input[7] = ADS_TEMP1;   /* TEMP1 */
                    147: 
                    148:     /* We want absolute coordinates */
                    149:     qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
                    150:                     "QEMU ADS7846-driven Touchscreen");
                    151: 
                    152:     ads7846_int_update(s);
                    153: 
1.1.1.2   root      154:     register_savevm("ads7846", -1, 0, ads7846_save, ads7846_load, s);
1.1.1.3 ! root      155: }
        !           156: 
        !           157: static SSISlaveInfo ads7846_info = {
        !           158:     .qdev.name ="ads7846",
        !           159:     .qdev.size = sizeof(ADS7846State),
        !           160:     .init = ads7846_init,
        !           161:     .transfer = ads7846_transfer
        !           162: };
1.1       root      163: 
1.1.1.3 ! root      164: static void ads7846_register_devices(void)
        !           165: {
        !           166:     ssi_register_slave(&ads7846_info);
1.1       root      167: }
1.1.1.3 ! root      168: 
        !           169: device_init(ads7846_register_devices)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.