1:
2:
3:
4:
5:
6:
7:
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:
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:
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:
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:
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: }