Add qemu 2.4.0
[kvmfornfv.git] / qemu / hw / i2c / smbus.c
1 /*
2  * QEMU SMBus device emulation.
3  *
4  * Copyright (c) 2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the LGPL.
8  */
9
10 /* TODO: Implement PEC.  */
11
12 #include "hw/hw.h"
13 #include "hw/i2c/i2c.h"
14 #include "hw/i2c/smbus.h"
15
16 //#define DEBUG_SMBUS 1
17
18 #ifdef DEBUG_SMBUS
19 #define DPRINTF(fmt, ...) \
20 do { printf("smbus(%02x): " fmt , dev->i2c.address, ## __VA_ARGS__); } while (0)
21 #define BADF(fmt, ...) \
22 do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
23 #else
24 #define DPRINTF(fmt, ...) do {} while(0)
25 #define BADF(fmt, ...) \
26 do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__);} while (0)
27 #endif
28
29 enum {
30     SMBUS_IDLE,
31     SMBUS_WRITE_DATA,
32     SMBUS_RECV_BYTE,
33     SMBUS_READ_DATA,
34     SMBUS_DONE,
35     SMBUS_CONFUSED = -1
36 };
37
38 static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
39 {
40     SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
41
42     DPRINTF("Quick Command %d\n", recv);
43     if (sc->quick_cmd) {
44         sc->quick_cmd(dev, recv);
45     }
46 }
47
48 static void smbus_do_write(SMBusDevice *dev)
49 {
50     SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
51
52     if (dev->data_len == 0) {
53         smbus_do_quick_cmd(dev, 0);
54     } else if (dev->data_len == 1) {
55         DPRINTF("Send Byte\n");
56         if (sc->send_byte) {
57             sc->send_byte(dev, dev->data_buf[0]);
58         }
59     } else {
60         dev->command = dev->data_buf[0];
61         DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
62         if (sc->write_data) {
63             sc->write_data(dev, dev->command, dev->data_buf + 1,
64                            dev->data_len - 1);
65         }
66     }
67 }
68
69 static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
70 {
71     SMBusDevice *dev = SMBUS_DEVICE(s);
72
73     switch (event) {
74     case I2C_START_SEND:
75         switch (dev->mode) {
76         case SMBUS_IDLE:
77             DPRINTF("Incoming data\n");
78             dev->mode = SMBUS_WRITE_DATA;
79             break;
80         default:
81             BADF("Unexpected send start condition in state %d\n", dev->mode);
82             dev->mode = SMBUS_CONFUSED;
83             break;
84         }
85         break;
86
87     case I2C_START_RECV:
88         switch (dev->mode) {
89         case SMBUS_IDLE:
90             DPRINTF("Read mode\n");
91             dev->mode = SMBUS_RECV_BYTE;
92             break;
93         case SMBUS_WRITE_DATA:
94             if (dev->data_len == 0) {
95                 BADF("Read after write with no data\n");
96                 dev->mode = SMBUS_CONFUSED;
97             } else {
98                 if (dev->data_len > 1) {
99                     smbus_do_write(dev);
100                 } else {
101                     dev->command = dev->data_buf[0];
102                     DPRINTF("%02x: Command %d\n", dev->i2c.address,
103                             dev->command);
104                 }
105                 DPRINTF("Read mode\n");
106                 dev->data_len = 0;
107                 dev->mode = SMBUS_READ_DATA;
108             }
109             break;
110         default:
111             BADF("Unexpected recv start condition in state %d\n", dev->mode);
112             dev->mode = SMBUS_CONFUSED;
113             break;
114         }
115         break;
116
117     case I2C_FINISH:
118         switch (dev->mode) {
119         case SMBUS_WRITE_DATA:
120             smbus_do_write(dev);
121             break;
122         case SMBUS_RECV_BYTE:
123             smbus_do_quick_cmd(dev, 1);
124             break;
125         case SMBUS_READ_DATA:
126             BADF("Unexpected stop during receive\n");
127             break;
128         default:
129             /* Nothing to do.  */
130             break;
131         }
132         dev->mode = SMBUS_IDLE;
133         dev->data_len = 0;
134         break;
135
136     case I2C_NACK:
137         switch (dev->mode) {
138         case SMBUS_DONE:
139             /* Nothing to do.  */
140             break;
141         case SMBUS_READ_DATA:
142             dev->mode = SMBUS_DONE;
143             break;
144         default:
145             BADF("Unexpected NACK in state %d\n", dev->mode);
146             dev->mode = SMBUS_CONFUSED;
147             break;
148         }
149     }
150 }
151
152 static int smbus_i2c_recv(I2CSlave *s)
153 {
154     SMBusDevice *dev = SMBUS_DEVICE(s);
155     SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
156     int ret;
157
158     switch (dev->mode) {
159     case SMBUS_RECV_BYTE:
160         if (sc->receive_byte) {
161             ret = sc->receive_byte(dev);
162         } else {
163             ret = 0;
164         }
165         DPRINTF("Receive Byte %02x\n", ret);
166         dev->mode = SMBUS_DONE;
167         break;
168     case SMBUS_READ_DATA:
169         if (sc->read_data) {
170             ret = sc->read_data(dev, dev->command, dev->data_len);
171             dev->data_len++;
172         } else {
173             ret = 0;
174         }
175         DPRINTF("Read data %02x\n", ret);
176         break;
177     default:
178         BADF("Unexpected read in state %d\n", dev->mode);
179         dev->mode = SMBUS_CONFUSED;
180         ret = 0;
181         break;
182     }
183     return ret;
184 }
185
186 static int smbus_i2c_send(I2CSlave *s, uint8_t data)
187 {
188     SMBusDevice *dev = SMBUS_DEVICE(s);
189
190     switch (dev->mode) {
191     case SMBUS_WRITE_DATA:
192         DPRINTF("Write data %02x\n", data);
193         dev->data_buf[dev->data_len++] = data;
194         break;
195     default:
196         BADF("Unexpected write in state %d\n", dev->mode);
197         break;
198     }
199     return 0;
200 }
201
202 static int smbus_device_init(I2CSlave *i2c)
203 {
204     SMBusDevice *dev = SMBUS_DEVICE(i2c);
205     SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
206
207     return sc->init(dev);
208 }
209
210 /* Master device commands.  */
211 int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
212 {
213     if (i2c_start_transfer(bus, addr, read)) {
214         return -1;
215     }
216     i2c_end_transfer(bus);
217     return 0;
218 }
219
220 int smbus_receive_byte(I2CBus *bus, uint8_t addr)
221 {
222     uint8_t data;
223
224     if (i2c_start_transfer(bus, addr, 1)) {
225         return -1;
226     }
227     data = i2c_recv(bus);
228     i2c_nack(bus);
229     i2c_end_transfer(bus);
230     return data;
231 }
232
233 int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
234 {
235     if (i2c_start_transfer(bus, addr, 0)) {
236         return -1;
237     }
238     i2c_send(bus, data);
239     i2c_end_transfer(bus);
240     return 0;
241 }
242
243 int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
244 {
245     uint8_t data;
246     if (i2c_start_transfer(bus, addr, 0)) {
247         return -1;
248     }
249     i2c_send(bus, command);
250     i2c_start_transfer(bus, addr, 1);
251     data = i2c_recv(bus);
252     i2c_nack(bus);
253     i2c_end_transfer(bus);
254     return data;
255 }
256
257 int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
258 {
259     if (i2c_start_transfer(bus, addr, 0)) {
260         return -1;
261     }
262     i2c_send(bus, command);
263     i2c_send(bus, data);
264     i2c_end_transfer(bus);
265     return 0;
266 }
267
268 int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
269 {
270     uint16_t data;
271     if (i2c_start_transfer(bus, addr, 0)) {
272         return -1;
273     }
274     i2c_send(bus, command);
275     i2c_start_transfer(bus, addr, 1);
276     data = i2c_recv(bus);
277     data |= i2c_recv(bus) << 8;
278     i2c_nack(bus);
279     i2c_end_transfer(bus);
280     return data;
281 }
282
283 int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
284 {
285     if (i2c_start_transfer(bus, addr, 0)) {
286         return -1;
287     }
288     i2c_send(bus, command);
289     i2c_send(bus, data & 0xff);
290     i2c_send(bus, data >> 8);
291     i2c_end_transfer(bus);
292     return 0;
293 }
294
295 int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
296 {
297     int len;
298     int i;
299
300     if (i2c_start_transfer(bus, addr, 0)) {
301         return -1;
302     }
303     i2c_send(bus, command);
304     i2c_start_transfer(bus, addr, 1);
305     len = i2c_recv(bus);
306     if (len > 32) {
307         len = 0;
308     }
309     for (i = 0; i < len; i++) {
310         data[i] = i2c_recv(bus);
311     }
312     i2c_nack(bus);
313     i2c_end_transfer(bus);
314     return len;
315 }
316
317 int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
318                       int len)
319 {
320     int i;
321
322     if (len > 32)
323         len = 32;
324
325     if (i2c_start_transfer(bus, addr, 0)) {
326         return -1;
327     }
328     i2c_send(bus, command);
329     i2c_send(bus, len);
330     for (i = 0; i < len; i++) {
331         i2c_send(bus, data[i]);
332     }
333     i2c_end_transfer(bus);
334     return 0;
335 }
336
337 static void smbus_device_class_init(ObjectClass *klass, void *data)
338 {
339     I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
340
341     sc->init = smbus_device_init;
342     sc->event = smbus_i2c_event;
343     sc->recv = smbus_i2c_recv;
344     sc->send = smbus_i2c_send;
345 }
346
347 static const TypeInfo smbus_device_type_info = {
348     .name = TYPE_SMBUS_DEVICE,
349     .parent = TYPE_I2C_SLAVE,
350     .instance_size = sizeof(SMBusDevice),
351     .abstract = true,
352     .class_size = sizeof(SMBusDeviceClass),
353     .class_init = smbus_device_class_init,
354 };
355
356 static void smbus_device_register_types(void)
357 {
358     type_register_static(&smbus_device_type_info);
359 }
360
361 type_init(smbus_device_register_types)