Annotation of qemu/hw/max111x.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Maxim MAX1110/1111 ADC 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 GPLv2.
                      8:  */
                      9: 
                     10: #include "hw.h"
                     11: #include "i2c.h"
                     12: 
                     13: struct max111x_s {
                     14:     qemu_irq interrupt;
                     15:     uint8_t tb1, rb2, rb3;
                     16:     int cycle;
                     17: 
                     18:     int input[8];
                     19:     int inputs, com;
                     20: };
                     21: 
                     22: /* Control-byte bitfields */
                     23: #define CB_PD0         (1 << 0)
                     24: #define CB_PD1         (1 << 1)
                     25: #define CB_SGL         (1 << 2)
                     26: #define CB_UNI         (1 << 3)
                     27: #define CB_SEL0                (1 << 4)
                     28: #define CB_SEL1                (1 << 5)
                     29: #define CB_SEL2                (1 << 6)
                     30: #define CB_START       (1 << 7)
                     31: 
                     32: #define CHANNEL_NUM(v, b0, b1, b2)     \
                     33:                        ((((v) >> (2 + (b0))) & 4) |    \
                     34:                         (((v) >> (3 + (b1))) & 2) |    \
                     35:                         (((v) >> (4 + (b2))) & 1))
                     36: 
                     37: uint32_t max111x_read(void *opaque)
                     38: {
                     39:     struct max111x_s *s = (struct max111x_s *) opaque;
                     40: 
                     41:     if (!s->tb1)
                     42:         return 0;
                     43: 
                     44:     switch (s->cycle ++) {
                     45:     case 1:
                     46:         return s->rb2;
                     47:     case 2:
                     48:         return s->rb3;
                     49:     }
                     50: 
                     51:     return 0;
                     52: }
                     53: 
                     54: /* Interpret a control-byte */
                     55: void max111x_write(void *opaque, uint32_t value)
                     56: {
                     57:     struct max111x_s *s = (struct max111x_s *) opaque;
                     58:     int measure, chan;
                     59: 
                     60:     /* Ignore the value if START bit is zero */
                     61:     if (!(value & CB_START))
                     62:         return;
                     63: 
                     64:     s->cycle = 0;
                     65: 
                     66:     if (!(value & CB_PD1)) {
                     67:         s->tb1 = 0;
                     68:         return;
                     69:     }
                     70: 
                     71:     s->tb1 = value;
                     72: 
                     73:     if (s->inputs == 8)
                     74:         chan = CHANNEL_NUM(value, 1, 0, 2);
                     75:     else
                     76:         chan = CHANNEL_NUM(value & ~CB_SEL0, 0, 1, 2);
                     77: 
                     78:     if (value & CB_SGL)
                     79:         measure = s->input[chan] - s->com;
                     80:     else
                     81:         measure = s->input[chan] - s->input[chan ^ 1];
                     82: 
                     83:     if (!(value & CB_UNI))
                     84:         measure ^= 0x80;
                     85: 
                     86:     s->rb2 = (measure >> 2) & 0x3f;
                     87:     s->rb3 = (measure << 6) & 0xc0;
                     88: 
                     89:     if (s->interrupt)
                     90:         qemu_irq_raise(s->interrupt);
                     91: }
                     92: 
                     93: static void max111x_save(QEMUFile *f, void *opaque)
                     94: {
                     95:     struct max111x_s *s = (struct max111x_s *) opaque;
                     96:     int i;
                     97: 
                     98:     qemu_put_8s(f, &s->tb1);
                     99:     qemu_put_8s(f, &s->rb2);
                    100:     qemu_put_8s(f, &s->rb3);
                    101:     qemu_put_be32(f, s->inputs);
                    102:     qemu_put_be32(f, s->com);
                    103:     for (i = 0; i < s->inputs; i ++)
                    104:         qemu_put_byte(f, s->input[i]);
                    105: }
                    106: 
                    107: static int max111x_load(QEMUFile *f, void *opaque, int version_id)
                    108: {
                    109:     struct max111x_s *s = (struct max111x_s *) opaque;
                    110:     int i;
                    111: 
                    112:     qemu_get_8s(f, &s->tb1);
                    113:     qemu_get_8s(f, &s->rb2);
                    114:     qemu_get_8s(f, &s->rb3);
                    115:     if (s->inputs != qemu_get_be32(f))
                    116:         return -EINVAL;
                    117:     s->com = qemu_get_be32(f);
                    118:     for (i = 0; i < s->inputs; i ++)
                    119:         s->input[i] = qemu_get_byte(f);
                    120: 
                    121:     return 0;
                    122: }
                    123: 
                    124: static struct max111x_s *max111x_init(qemu_irq cb)
                    125: {
                    126:     struct max111x_s *s;
                    127:     s = (struct max111x_s *)
                    128:             qemu_mallocz(sizeof(struct max111x_s));
                    129:     memset(s, 0, sizeof(struct max111x_s));
                    130: 
                    131:     s->interrupt = cb;
                    132: 
                    133:     /* TODO: add a user interface for setting these */
                    134:     s->input[0] = 0xf0;
                    135:     s->input[1] = 0xe0;
                    136:     s->input[2] = 0xd0;
                    137:     s->input[3] = 0xc0;
                    138:     s->input[4] = 0xb0;
                    139:     s->input[5] = 0xa0;
                    140:     s->input[6] = 0x90;
                    141:     s->input[7] = 0x80;
                    142:     s->com = 0;
                    143: 
1.1.1.2 ! root      144:     register_savevm("max111x", -1, 0, max111x_save, max111x_load, s);
1.1       root      145: 
                    146:     return s;
                    147: }
                    148: 
                    149: struct max111x_s *max1110_init(qemu_irq cb)
                    150: {
                    151:     struct max111x_s *s = max111x_init(cb);
                    152:     s->inputs = 8;
                    153:     return s;
                    154: }
                    155: 
                    156: struct max111x_s *max1111_init(qemu_irq cb)
                    157: {
                    158:     struct max111x_s *s = max111x_init(cb);
                    159:     s->inputs = 4;
                    160:     return s;
                    161: }
                    162: 
                    163: void max111x_set_input(struct max111x_s *s, int line, uint8_t value)
                    164: {
                    165:     if (line >= s->inputs) {
                    166:         printf("%s: There's no input %i\n", __FUNCTION__, line);
                    167:         return;
                    168:     }
                    169: 
                    170:     s->input[line] = value;
                    171: }

unix.superglobalmegacorp.com

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