qdev: move name+size into DeviceInfo (v2)
[qemu] / hw / smbus.c
1 /*
2  * QEMU SMBus device emulation.
3  *
4  * Copyright (c) 2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licenced under the LGPL.
8  */
9
10 /* TODO: Implement PEC.  */
11
12 #include "hw.h"
13 #include "i2c.h"
14 #include "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     SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
41
42     DPRINTF("Quick Command %d\n", recv);
43     if (t->quick_cmd)
44         t->quick_cmd(dev, recv);
45 }
46
47 static void smbus_do_write(SMBusDevice *dev)
48 {
49     SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
50
51     if (dev->data_len == 0) {
52         smbus_do_quick_cmd(dev, 0);
53     } else if (dev->data_len == 1) {
54         DPRINTF("Send Byte\n");
55         if (t->send_byte) {
56             t->send_byte(dev, dev->data_buf[0]);
57         }
58     } else {
59         dev->command = dev->data_buf[0];
60         DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
61         if (t->write_data) {
62             t->write_data(dev, dev->command, dev->data_buf + 1,
63                           dev->data_len - 1);
64         }
65     }
66 }
67
68 static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
69 {
70     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
71
72     switch (event) {
73     case I2C_START_SEND:
74         switch (dev->mode) {
75         case SMBUS_IDLE:
76             DPRINTF("Incoming data\n");
77             dev->mode = SMBUS_WRITE_DATA;
78             break;
79         default:
80             BADF("Unexpected send start condition in state %d\n", dev->mode);
81             dev->mode = SMBUS_CONFUSED;
82             break;
83         }
84         break;
85
86     case I2C_START_RECV:
87         switch (dev->mode) {
88         case SMBUS_IDLE:
89             DPRINTF("Read mode\n");
90             dev->mode = SMBUS_RECV_BYTE;
91             break;
92         case SMBUS_WRITE_DATA:
93             if (dev->data_len == 0) {
94                 BADF("Read after write with no data\n");
95                 dev->mode = SMBUS_CONFUSED;
96             } else {
97                 if (dev->data_len > 1) {
98                     smbus_do_write(dev);
99                 } else {
100                     dev->command = dev->data_buf[0];
101                     DPRINTF("%02x: Command %d\n", dev->i2c.address,
102                             dev->command);
103                 }
104                 DPRINTF("Read mode\n");
105                 dev->data_len = 0;
106                 dev->mode = SMBUS_READ_DATA;
107             }
108             break;
109         default:
110             BADF("Unexpected recv start condition in state %d\n", dev->mode);
111             dev->mode = SMBUS_CONFUSED;
112             break;
113         }
114         break;
115
116     case I2C_FINISH:
117         switch (dev->mode) {
118         case SMBUS_WRITE_DATA:
119             smbus_do_write(dev);
120             break;
121         case SMBUS_RECV_BYTE:
122             smbus_do_quick_cmd(dev, 1);
123             break;
124         case SMBUS_READ_DATA:
125             BADF("Unexpected stop during receive\n");
126             break;
127         default:
128             /* Nothing to do.  */
129             break;
130         }
131         dev->mode = SMBUS_IDLE;
132         dev->data_len = 0;
133         break;
134
135     case I2C_NACK:
136         switch (dev->mode) {
137         case SMBUS_DONE:
138             /* Nothing to do.  */
139             break;
140         case SMBUS_READ_DATA:
141             dev->mode = SMBUS_DONE;
142             break;
143         default:
144             BADF("Unexpected NACK in state %d\n", dev->mode);
145             dev->mode = SMBUS_CONFUSED;
146             break;
147         }
148     }
149 }
150
151 static int smbus_i2c_recv(i2c_slave *s)
152 {
153     SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
154     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
155     int ret;
156
157     switch (dev->mode) {
158     case SMBUS_RECV_BYTE:
159         if (t->receive_byte) {
160             ret = t->receive_byte(dev);
161         } else {
162             ret = 0;
163         }
164         DPRINTF("Receive Byte %02x\n", ret);
165         dev->mode = SMBUS_DONE;
166         break;
167     case SMBUS_READ_DATA:
168         if (t->read_data) {
169             ret = t->read_data(dev, dev->command, dev->data_len);
170             dev->data_len++;
171         } else {
172             ret = 0;
173         }
174         DPRINTF("Read data %02x\n", ret);
175         break;
176     default:
177         BADF("Unexpected read in state %d\n", dev->mode);
178         dev->mode = SMBUS_CONFUSED;
179         ret = 0;
180         break;
181     }
182     return ret;
183 }
184
185 static int smbus_i2c_send(i2c_slave *s, uint8_t data)
186 {
187     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
188
189     switch (dev->mode) {
190     case SMBUS_WRITE_DATA:
191         DPRINTF("Write data %02x\n", data);
192         dev->data_buf[dev->data_len++] = data;
193         break;
194     default:
195         BADF("Unexpected write in state %d\n", dev->mode);
196         break;
197     }
198     return 0;
199 }
200
201 static void smbus_device_init(i2c_slave *i2c)
202 {
203     SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
204     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
205
206     t->init(dev);
207 }
208
209 void smbus_register_device(SMBusDeviceInfo *info)
210 {
211     assert(info->i2c.qdev.size >= sizeof(SMBusDevice));
212     info->i2c.init = smbus_device_init;
213     info->i2c.event = smbus_i2c_event;
214     info->i2c.recv = smbus_i2c_recv;
215     info->i2c.send = smbus_i2c_send;
216     i2c_register_slave(&info->i2c);
217 }
218
219 /* Master device commands.  */
220 void smbus_quick_command(i2c_bus *bus, int addr, int read)
221 {
222     i2c_start_transfer(bus, addr, read);
223     i2c_end_transfer(bus);
224 }
225
226 uint8_t smbus_receive_byte(i2c_bus *bus, int addr)
227 {
228     uint8_t data;
229
230     i2c_start_transfer(bus, addr, 1);
231     data = i2c_recv(bus);
232     i2c_nack(bus);
233     i2c_end_transfer(bus);
234     return data;
235 }
236
237 void smbus_send_byte(i2c_bus *bus, int addr, uint8_t data)
238 {
239     i2c_start_transfer(bus, addr, 0);
240     i2c_send(bus, data);
241     i2c_end_transfer(bus);
242 }
243
244 uint8_t smbus_read_byte(i2c_bus *bus, int addr, uint8_t command)
245 {
246     uint8_t data;
247     i2c_start_transfer(bus, addr, 0);
248     i2c_send(bus, command);
249     i2c_start_transfer(bus, addr, 1);
250     data = i2c_recv(bus);
251     i2c_nack(bus);
252     i2c_end_transfer(bus);
253     return data;
254 }
255
256 void smbus_write_byte(i2c_bus *bus, int addr, uint8_t command, uint8_t data)
257 {
258     i2c_start_transfer(bus, addr, 0);
259     i2c_send(bus, command);
260     i2c_send(bus, data);
261     i2c_end_transfer(bus);
262 }
263
264 uint16_t smbus_read_word(i2c_bus *bus, int addr, uint8_t command)
265 {
266     uint16_t data;
267     i2c_start_transfer(bus, addr, 0);
268     i2c_send(bus, command);
269     i2c_start_transfer(bus, addr, 1);
270     data = i2c_recv(bus);
271     data |= i2c_recv(bus) << 8;
272     i2c_nack(bus);
273     i2c_end_transfer(bus);
274     return data;
275 }
276
277 void smbus_write_word(i2c_bus *bus, int addr, uint8_t command, uint16_t data)
278 {
279     i2c_start_transfer(bus, addr, 0);
280     i2c_send(bus, command);
281     i2c_send(bus, data & 0xff);
282     i2c_send(bus, data >> 8);
283     i2c_end_transfer(bus);
284 }
285
286 int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data)
287 {
288     int len;
289     int i;
290
291     i2c_start_transfer(bus, addr, 0);
292     i2c_send(bus, command);
293     i2c_start_transfer(bus, addr, 1);
294     len = i2c_recv(bus);
295     if (len > 32)
296         len = 0;
297     for (i = 0; i < len; i++)
298         data[i] = i2c_recv(bus);
299     i2c_nack(bus);
300     i2c_end_transfer(bus);
301     return len;
302 }
303
304 void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
305                        int len)
306 {
307     int i;
308
309     if (len > 32)
310         len = 32;
311
312     i2c_start_transfer(bus, addr, 0);
313     i2c_send(bus, command);
314     i2c_send(bus, len);
315     for (i = 0; i < len; i++)
316         i2c_send(bus, data[i]);
317     i2c_end_transfer(bus);
318 }