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

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.
1.1.1.7 ! root        8:  *
        !             9:  * Contributions after 2012-01-13 are licensed under the terms of the
        !            10:  * GNU GPL, version 2 or (at your option) any later version.
1.1       root       11:  */
                     12: 
1.1.1.3   root       13: #include "ssi.h"
1.1       root       14: #include "console.h"
                     15: 
1.1.1.3   root       16: typedef struct {
                     17:     SSISlave ssidev;
1.1       root       18:     qemu_irq interrupt;
                     19: 
                     20:     int input[8];
                     21:     int pressure;
                     22:     int noise;
                     23: 
                     24:     int cycle;
                     25:     int output;
1.1.1.3   root       26: } ADS7846State;
1.1       root       27: 
                     28: /* Control-byte bitfields */
                     29: #define CB_PD0         (1 << 0)
                     30: #define CB_PD1         (1 << 1)
                     31: #define CB_SER         (1 << 2)
                     32: #define CB_MODE                (1 << 3)
                     33: #define CB_A0          (1 << 4)
                     34: #define CB_A1          (1 << 5)
                     35: #define CB_A2          (1 << 6)
                     36: #define CB_START       (1 << 7)
                     37: 
                     38: #define X_AXIS_DMAX    3470
                     39: #define X_AXIS_MIN     290
                     40: #define Y_AXIS_DMAX    3450
                     41: #define Y_AXIS_MIN     200
                     42: 
                     43: #define ADS_VBAT       2000
                     44: #define ADS_VAUX       2000
                     45: #define ADS_TEMP0      2000
                     46: #define ADS_TEMP1      3000
                     47: #define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
                     48: #define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
                     49: #define ADS_Z1POS(x, y)        600
                     50: #define ADS_Z2POS(x, y)        (600 + 6000 / ADS_XPOS(x, y))
                     51: 
1.1.1.3   root       52: static void ads7846_int_update(ADS7846State *s)
1.1       root       53: {
                     54:     if (s->interrupt)
                     55:         qemu_set_irq(s->interrupt, s->pressure == 0);
                     56: }
                     57: 
1.1.1.3   root       58: static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
1.1       root       59: {
1.1.1.3   root       60:     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
1.1       root       61: 
                     62:     switch (s->cycle ++) {
                     63:     case 0:
                     64:         if (!(value & CB_START)) {
                     65:             s->cycle = 0;
                     66:             break;
                     67:         }
                     68: 
                     69:         s->output = s->input[(value >> 4) & 7];
                     70: 
                     71:         /* Imitate the ADC noise, some drivers expect this.  */
                     72:         s->noise = (s->noise + 3) & 7;
                     73:         switch ((value >> 4) & 7) {
                     74:         case 1: s->output += s->noise ^ 2; break;
                     75:         case 3: s->output += s->noise ^ 0; break;
                     76:         case 4: s->output += s->noise ^ 7; break;
                     77:         case 5: s->output += s->noise ^ 5; break;
                     78:         }
                     79: 
                     80:         if (value & CB_MODE)
                     81:             s->output >>= 4;   /* 8 bits instead of 12 */
                     82: 
                     83:         break;
                     84:     case 1:
                     85:         s->cycle = 0;
                     86:         break;
                     87:     }
1.1.1.3   root       88:     return s->output;
1.1       root       89: }
                     90: 
                     91: static void ads7846_ts_event(void *opaque,
                     92:                 int x, int y, int z, int buttons_state)
                     93: {
1.1.1.3   root       94:     ADS7846State *s = opaque;
1.1       root       95: 
                     96:     if (buttons_state) {
                     97:         x = 0x7fff - x;
                     98:         s->input[1] = ADS_XPOS(x, y);
                     99:         s->input[3] = ADS_Z1POS(x, y);
                    100:         s->input[4] = ADS_Z2POS(x, y);
                    101:         s->input[5] = ADS_YPOS(x, y);
                    102:     }
                    103: 
                    104:     if (s->pressure == !buttons_state) {
                    105:         s->pressure = !!buttons_state;
                    106: 
                    107:         ads7846_int_update(s);
                    108:     }
                    109: }
                    110: 
1.1.1.6   root      111: static int ads7856_post_load(void *opaque, int version_id)
1.1       root      112: {
1.1.1.6   root      113:     ADS7846State *s = opaque;
1.1       root      114: 
                    115:     s->pressure = 0;
                    116:     ads7846_int_update(s);
                    117:     return 0;
                    118: }
                    119: 
1.1.1.6   root      120: static const VMStateDescription vmstate_ads7846 = {
                    121:     .name = "ads7846",
                    122:     .version_id = 0,
                    123:     .minimum_version_id = 0,
                    124:     .minimum_version_id_old = 0,
                    125:     .post_load = ads7856_post_load,
                    126:     .fields      = (VMStateField[]) {
                    127:         VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
                    128:         VMSTATE_INT32(noise, ADS7846State),
                    129:         VMSTATE_INT32(cycle, ADS7846State),
                    130:         VMSTATE_INT32(output, ADS7846State),
                    131:         VMSTATE_END_OF_LIST()
                    132:     }
                    133: };
                    134: 
1.1.1.4   root      135: static int ads7846_init(SSISlave *dev)
1.1       root      136: {
1.1.1.3   root      137:     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
1.1       root      138: 
1.1.1.3   root      139:     qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
1.1       root      140: 
                    141:     s->input[0] = ADS_TEMP0;   /* TEMP0 */
                    142:     s->input[2] = ADS_VBAT;    /* VBAT */
                    143:     s->input[6] = ADS_VAUX;    /* VAUX */
                    144:     s->input[7] = ADS_TEMP1;   /* TEMP1 */
                    145: 
                    146:     /* We want absolute coordinates */
                    147:     qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
                    148:                     "QEMU ADS7846-driven Touchscreen");
                    149: 
                    150:     ads7846_int_update(s);
                    151: 
1.1.1.6   root      152:     vmstate_register(NULL, -1, &vmstate_ads7846, s);
1.1.1.4   root      153:     return 0;
1.1.1.3   root      154: }
                    155: 
1.1.1.7 ! root      156: static void ads7846_class_init(ObjectClass *klass, void *data)
        !           157: {
        !           158:     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
        !           159: 
        !           160:     k->init = ads7846_init;
        !           161:     k->transfer = ads7846_transfer;
        !           162: }
        !           163: 
        !           164: static TypeInfo ads7846_info = {
        !           165:     .name          = "ads7846",
        !           166:     .parent        = TYPE_SSI_SLAVE,
        !           167:     .instance_size = sizeof(ADS7846State),
        !           168:     .class_init    = ads7846_class_init,
1.1.1.3   root      169: };
1.1       root      170: 
1.1.1.7 ! root      171: static void ads7846_register_types(void)
1.1.1.3   root      172: {
1.1.1.7 ! root      173:     type_register_static(&ads7846_info);
1.1       root      174: }
1.1.1.3   root      175: 
1.1.1.7 ! root      176: type_init(ads7846_register_types)

unix.superglobalmegacorp.com

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