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

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 int max111x_iid = 0;
        !           125: 
        !           126: static struct max111x_s *max111x_init(qemu_irq cb)
        !           127: {
        !           128:     struct max111x_s *s;
        !           129:     s = (struct max111x_s *)
        !           130:             qemu_mallocz(sizeof(struct max111x_s));
        !           131:     memset(s, 0, sizeof(struct max111x_s));
        !           132: 
        !           133:     s->interrupt = cb;
        !           134: 
        !           135:     /* TODO: add a user interface for setting these */
        !           136:     s->input[0] = 0xf0;
        !           137:     s->input[1] = 0xe0;
        !           138:     s->input[2] = 0xd0;
        !           139:     s->input[3] = 0xc0;
        !           140:     s->input[4] = 0xb0;
        !           141:     s->input[5] = 0xa0;
        !           142:     s->input[6] = 0x90;
        !           143:     s->input[7] = 0x80;
        !           144:     s->com = 0;
        !           145: 
        !           146:     register_savevm("max111x", max111x_iid ++, 0,
        !           147:                     max111x_save, max111x_load, s);
        !           148: 
        !           149:     return s;
        !           150: }
        !           151: 
        !           152: struct max111x_s *max1110_init(qemu_irq cb)
        !           153: {
        !           154:     struct max111x_s *s = max111x_init(cb);
        !           155:     s->inputs = 8;
        !           156:     return s;
        !           157: }
        !           158: 
        !           159: struct max111x_s *max1111_init(qemu_irq cb)
        !           160: {
        !           161:     struct max111x_s *s = max111x_init(cb);
        !           162:     s->inputs = 4;
        !           163:     return s;
        !           164: }
        !           165: 
        !           166: void max111x_set_input(struct max111x_s *s, int line, uint8_t value)
        !           167: {
        !           168:     if (line >= s->inputs) {
        !           169:         printf("%s: There's no input %i\n", __FUNCTION__, line);
        !           170:         return;
        !           171:     }
        !           172: 
        !           173:     s->input[line] = value;
        !           174: }

unix.superglobalmegacorp.com

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