i2c.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * QEMU I2C bus interface.
  3. *
  4. * Copyright (c) 2007 CodeSourcery.
  5. * Written by Paul Brook
  6. *
  7. * This code is licensed under the LGPL.
  8. */
  9. #include "i2c.h"
  10. struct i2c_bus
  11. {
  12. BusState qbus;
  13. I2CSlave *current_dev;
  14. I2CSlave *dev;
  15. uint8_t saved_address;
  16. };
  17. static Property i2c_props[] = {
  18. DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
  19. DEFINE_PROP_END_OF_LIST(),
  20. };
  21. #define TYPE_I2C_BUS "i2c-bus"
  22. #define I2C_BUS(obj) OBJECT_CHECK(i2c_bus, (obj), TYPE_I2C_BUS)
  23. static const TypeInfo i2c_bus_info = {
  24. .name = TYPE_I2C_BUS,
  25. .parent = TYPE_BUS,
  26. .instance_size = sizeof(i2c_bus),
  27. };
  28. static void i2c_bus_pre_save(void *opaque)
  29. {
  30. i2c_bus *bus = opaque;
  31. bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
  32. }
  33. static int i2c_bus_post_load(void *opaque, int version_id)
  34. {
  35. i2c_bus *bus = opaque;
  36. /* The bus is loaded before attached devices, so load and save the
  37. current device id. Devices will check themselves as loaded. */
  38. bus->current_dev = NULL;
  39. return 0;
  40. }
  41. static const VMStateDescription vmstate_i2c_bus = {
  42. .name = "i2c_bus",
  43. .version_id = 1,
  44. .minimum_version_id = 1,
  45. .minimum_version_id_old = 1,
  46. .pre_save = i2c_bus_pre_save,
  47. .post_load = i2c_bus_post_load,
  48. .fields = (VMStateField []) {
  49. VMSTATE_UINT8(saved_address, i2c_bus),
  50. VMSTATE_END_OF_LIST()
  51. }
  52. };
  53. /* Create a new I2C bus. */
  54. i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
  55. {
  56. i2c_bus *bus;
  57. bus = FROM_QBUS(i2c_bus, qbus_create(TYPE_I2C_BUS, parent, name));
  58. vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
  59. return bus;
  60. }
  61. void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
  62. {
  63. dev->address = address;
  64. }
  65. /* Return nonzero if bus is busy. */
  66. int i2c_bus_busy(i2c_bus *bus)
  67. {
  68. return bus->current_dev != NULL;
  69. }
  70. /* Returns non-zero if the address is not valid. */
  71. /* TODO: Make this handle multiple masters. */
  72. int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
  73. {
  74. BusChild *kid;
  75. I2CSlave *slave = NULL;
  76. I2CSlaveClass *sc;
  77. QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
  78. DeviceState *qdev = kid->child;
  79. I2CSlave *candidate = I2C_SLAVE(qdev);
  80. if (candidate->address == address) {
  81. slave = candidate;
  82. break;
  83. }
  84. }
  85. if (!slave) {
  86. return 1;
  87. }
  88. sc = I2C_SLAVE_GET_CLASS(slave);
  89. /* If the bus is already busy, assume this is a repeated
  90. start condition. */
  91. bus->current_dev = slave;
  92. if (sc->event) {
  93. sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
  94. }
  95. return 0;
  96. }
  97. void i2c_end_transfer(i2c_bus *bus)
  98. {
  99. I2CSlave *dev = bus->current_dev;
  100. I2CSlaveClass *sc;
  101. if (!dev) {
  102. return;
  103. }
  104. sc = I2C_SLAVE_GET_CLASS(dev);
  105. if (sc->event) {
  106. sc->event(dev, I2C_FINISH);
  107. }
  108. bus->current_dev = NULL;
  109. }
  110. int i2c_send(i2c_bus *bus, uint8_t data)
  111. {
  112. I2CSlave *dev = bus->current_dev;
  113. I2CSlaveClass *sc;
  114. if (!dev) {
  115. return -1;
  116. }
  117. sc = I2C_SLAVE_GET_CLASS(dev);
  118. if (sc->send) {
  119. return sc->send(dev, data);
  120. }
  121. return -1;
  122. }
  123. int i2c_recv(i2c_bus *bus)
  124. {
  125. I2CSlave *dev = bus->current_dev;
  126. I2CSlaveClass *sc;
  127. if (!dev) {
  128. return -1;
  129. }
  130. sc = I2C_SLAVE_GET_CLASS(dev);
  131. if (sc->recv) {
  132. return sc->recv(dev);
  133. }
  134. return -1;
  135. }
  136. void i2c_nack(i2c_bus *bus)
  137. {
  138. I2CSlave *dev = bus->current_dev;
  139. I2CSlaveClass *sc;
  140. if (!dev) {
  141. return;
  142. }
  143. sc = I2C_SLAVE_GET_CLASS(dev);
  144. if (sc->event) {
  145. sc->event(dev, I2C_NACK);
  146. }
  147. }
  148. static int i2c_slave_post_load(void *opaque, int version_id)
  149. {
  150. I2CSlave *dev = opaque;
  151. i2c_bus *bus;
  152. bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
  153. if (bus->saved_address == dev->address) {
  154. bus->current_dev = dev;
  155. }
  156. return 0;
  157. }
  158. const VMStateDescription vmstate_i2c_slave = {
  159. .name = "I2CSlave",
  160. .version_id = 1,
  161. .minimum_version_id = 1,
  162. .minimum_version_id_old = 1,
  163. .post_load = i2c_slave_post_load,
  164. .fields = (VMStateField []) {
  165. VMSTATE_UINT8(address, I2CSlave),
  166. VMSTATE_END_OF_LIST()
  167. }
  168. };
  169. static int i2c_slave_qdev_init(DeviceState *dev)
  170. {
  171. I2CSlave *s = I2C_SLAVE(dev);
  172. I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
  173. return sc->init(s);
  174. }
  175. DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
  176. {
  177. DeviceState *dev;
  178. dev = qdev_create(&bus->qbus, name);
  179. qdev_prop_set_uint8(dev, "address", addr);
  180. qdev_init_nofail(dev);
  181. return dev;
  182. }
  183. static void i2c_slave_class_init(ObjectClass *klass, void *data)
  184. {
  185. DeviceClass *k = DEVICE_CLASS(klass);
  186. k->init = i2c_slave_qdev_init;
  187. k->bus_type = TYPE_I2C_BUS;
  188. k->props = i2c_props;
  189. }
  190. static const TypeInfo i2c_slave_type_info = {
  191. .name = TYPE_I2C_SLAVE,
  192. .parent = TYPE_DEVICE,
  193. .instance_size = sizeof(I2CSlave),
  194. .abstract = true,
  195. .class_size = sizeof(I2CSlaveClass),
  196. .class_init = i2c_slave_class_init,
  197. };
  198. static void i2c_slave_register_types(void)
  199. {
  200. type_register_static(&i2c_bus_info);
  201. type_register_static(&i2c_slave_type_info);
  202. }
  203. type_init(i2c_slave_register_types)