xref: /qemu/include/hw/i2c/i2c.h (revision cad8db986560668afbaed972e162e3e7a2d3a34c)
10ff596d0Spbrook #ifndef QEMU_I2C_H
20ff596d0Spbrook #define QEMU_I2C_H
30ff596d0Spbrook 
4a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
5db1015e9SEduardo Habkost #include "qom/object.h"
6fe8de492SPaul Brook 
70ff596d0Spbrook /* The QEMU I2C implementation only supports simple transfers that complete
80ff596d0Spbrook    immediately.  It does not support slave devices that need to be able to
90ff596d0Spbrook    defer their response (eg. CPU slave interfaces where the data is supplied
100ff596d0Spbrook    by the device driver in response to an interrupt).  */
110ff596d0Spbrook 
120ff596d0Spbrook enum i2c_event {
130ff596d0Spbrook     I2C_START_RECV,
140ff596d0Spbrook     I2C_START_SEND,
15a78e9839SKlaus Jensen     I2C_START_SEND_ASYNC,
160ff596d0Spbrook     I2C_FINISH,
17aa1f17c1Sths     I2C_NACK /* Masker NACKed a receive byte.  */
180ff596d0Spbrook };
190ff596d0Spbrook 
20513ca82dSPatrick Venture typedef struct I2CNodeList I2CNodeList;
210ff596d0Spbrook 
22b5ea9327SAnthony Liguori #define TYPE_I2C_SLAVE "i2c-slave"
23c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(I2CSlave, I2CSlaveClass,
2430b5707cSEduardo Habkost                     I2C_SLAVE)
259e07bdf8SAnthony Liguori 
26db1015e9SEduardo Habkost struct I2CSlaveClass {
27b5ea9327SAnthony Liguori     DeviceClass parent_class;
2802e2da45SPaul Brook 
29d307c28cSCorey Minyard     /* Master to slave. Returns non-zero for a NAK, 0 for success. */
30b5ea9327SAnthony Liguori     int (*send)(I2CSlave *s, uint8_t data);
31b5ea9327SAnthony Liguori 
32a78e9839SKlaus Jensen     /* Master to slave (asynchronous). Receiving slave must call i2c_ack(). */
33a78e9839SKlaus Jensen     void (*send_async)(I2CSlave *s, uint8_t data);
34a78e9839SKlaus Jensen 
35d307c28cSCorey Minyard     /*
36d307c28cSCorey Minyard      * Slave to master.  This cannot fail, the device should always
372ac4c5f4SCorey Minyard      * return something here.
38d307c28cSCorey Minyard      */
392ac4c5f4SCorey Minyard     uint8_t (*recv)(I2CSlave *s);
40b5ea9327SAnthony Liguori 
41d307c28cSCorey Minyard     /*
42d307c28cSCorey Minyard      * Notify the slave of a bus state change.  For start event,
43d307c28cSCorey Minyard      * returns non-zero to NAK an operation.  For other events the
44d307c28cSCorey Minyard      * return code is not used and should be zero.
45d307c28cSCorey Minyard      */
46d307c28cSCorey Minyard     int (*event)(I2CSlave *s, enum i2c_event event);
47513ca82dSPatrick Venture 
48513ca82dSPatrick Venture     /*
49513ca82dSPatrick Venture      * Check if this device matches the address provided.  Returns bool of
50513ca82dSPatrick Venture      * true if it matches (or broadcast), and updates the device list, false
51513ca82dSPatrick Venture      * otherwise.
52513ca82dSPatrick Venture      *
53513ca82dSPatrick Venture      * If broadcast is true, match should add the device and return true.
54513ca82dSPatrick Venture      */
55513ca82dSPatrick Venture     bool (*match_and_add)(I2CSlave *candidate, uint8_t address, bool broadcast,
56513ca82dSPatrick Venture                           I2CNodeList *current_devs);
57db1015e9SEduardo Habkost };
58fe8de492SPaul Brook 
59373b8ac7SCorey Minyard struct I2CSlave {
60fe8de492SPaul Brook     DeviceState qdev;
610ff596d0Spbrook 
620ff596d0Spbrook     /* Remaining fields for internal use by the I2C code.  */
635b7f5327SJuan Quintela     uint8_t address;
640ff596d0Spbrook };
650ff596d0Spbrook 
66aa88d7adSCorey Minyard #define TYPE_I2C_BUS "i2c-bus"
678063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(I2CBus, I2C_BUS)
68aa88d7adSCorey Minyard 
69aa88d7adSCorey Minyard typedef struct I2CNode I2CNode;
70aa88d7adSCorey Minyard 
71aa88d7adSCorey Minyard struct I2CNode {
72aa88d7adSCorey Minyard     I2CSlave *elt;
73aa88d7adSCorey Minyard     QLIST_ENTRY(I2CNode) next;
74aa88d7adSCorey Minyard };
75aa88d7adSCorey Minyard 
7637fa5ca4SKlaus Jensen typedef struct I2CPendingMaster I2CPendingMaster;
7737fa5ca4SKlaus Jensen 
7837fa5ca4SKlaus Jensen struct I2CPendingMaster {
7937fa5ca4SKlaus Jensen     QEMUBH *bh;
8037fa5ca4SKlaus Jensen     QSIMPLEQ_ENTRY(I2CPendingMaster) entry;
8137fa5ca4SKlaus Jensen };
8237fa5ca4SKlaus Jensen 
83b98ec689SPatrick Venture typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
8437fa5ca4SKlaus Jensen typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters;
85b98ec689SPatrick Venture 
86aa88d7adSCorey Minyard struct I2CBus {
87aa88d7adSCorey Minyard     BusState qbus;
88b98ec689SPatrick Venture     I2CNodeList current_devs;
8937fa5ca4SKlaus Jensen     I2CPendingMasters pending_masters;
90aa88d7adSCorey Minyard     uint8_t saved_address;
91aa88d7adSCorey Minyard     bool broadcast;
9237fa5ca4SKlaus Jensen 
9337fa5ca4SKlaus Jensen     /* Set from slave currently mastering the bus. */
9437fa5ca4SKlaus Jensen     QEMUBH *bh;
95aa88d7adSCorey Minyard };
96aa88d7adSCorey Minyard 
97a5c82852SAndreas Färber I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
98a5c82852SAndreas Färber int i2c_bus_busy(I2CBus *bus);
99e656e387SBALATON Zoltan 
100e656e387SBALATON Zoltan /**
101e656e387SBALATON Zoltan  * i2c_start_transfer: start a transfer on an I2C bus.
102e656e387SBALATON Zoltan  *
103e656e387SBALATON Zoltan  * @bus: #I2CBus to be used
104e656e387SBALATON Zoltan  * @address: address of the slave
105e656e387SBALATON Zoltan  * @is_recv: indicates the transfer direction
106e656e387SBALATON Zoltan  *
10790603c5bSPhilippe Mathieu-Daudé  * When @is_recv is a known boolean constant, use the
10890603c5bSPhilippe Mathieu-Daudé  * i2c_start_recv() or i2c_start_send() helper instead.
10990603c5bSPhilippe Mathieu-Daudé  *
110e656e387SBALATON Zoltan  * Returns: 0 on success, -1 on error
111e656e387SBALATON Zoltan  */
112e656e387SBALATON Zoltan int i2c_start_transfer(I2CBus *bus, uint8_t address, bool is_recv);
11390603c5bSPhilippe Mathieu-Daudé 
11490603c5bSPhilippe Mathieu-Daudé /**
11590603c5bSPhilippe Mathieu-Daudé  * i2c_start_recv: start a 'receive' transfer on an I2C bus.
11690603c5bSPhilippe Mathieu-Daudé  *
11790603c5bSPhilippe Mathieu-Daudé  * @bus: #I2CBus to be used
11890603c5bSPhilippe Mathieu-Daudé  * @address: address of the slave
11990603c5bSPhilippe Mathieu-Daudé  *
12090603c5bSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error
12190603c5bSPhilippe Mathieu-Daudé  */
12290603c5bSPhilippe Mathieu-Daudé int i2c_start_recv(I2CBus *bus, uint8_t address);
12390603c5bSPhilippe Mathieu-Daudé 
12490603c5bSPhilippe Mathieu-Daudé /**
12590603c5bSPhilippe Mathieu-Daudé  * i2c_start_send: start a 'send' transfer on an I2C bus.
12690603c5bSPhilippe Mathieu-Daudé  *
12790603c5bSPhilippe Mathieu-Daudé  * @bus: #I2CBus to be used
12890603c5bSPhilippe Mathieu-Daudé  * @address: address of the slave
12990603c5bSPhilippe Mathieu-Daudé  *
13090603c5bSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error
13190603c5bSPhilippe Mathieu-Daudé  */
13290603c5bSPhilippe Mathieu-Daudé int i2c_start_send(I2CBus *bus, uint8_t address);
13390603c5bSPhilippe Mathieu-Daudé 
134a78e9839SKlaus Jensen /**
135a78e9839SKlaus Jensen  * i2c_start_send_async: start an asynchronous 'send' transfer on an I2C bus.
136a78e9839SKlaus Jensen  *
137a78e9839SKlaus Jensen  * @bus: #I2CBus to be used
138a78e9839SKlaus Jensen  * @address: address of the slave
139a78e9839SKlaus Jensen  *
140a78e9839SKlaus Jensen  * Return: 0 on success, -1 on error
141a78e9839SKlaus Jensen  */
142a78e9839SKlaus Jensen int i2c_start_send_async(I2CBus *bus, uint8_t address);
143a78e9839SKlaus Jensen 
144*791cb95fSKlaus Jensen void i2c_schedule_pending_master(I2CBus *bus);
145*791cb95fSKlaus Jensen 
146a5c82852SAndreas Färber void i2c_end_transfer(I2CBus *bus);
147a5c82852SAndreas Färber void i2c_nack(I2CBus *bus);
148a78e9839SKlaus Jensen void i2c_ack(I2CBus *bus);
14937fa5ca4SKlaus Jensen void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
15037fa5ca4SKlaus Jensen void i2c_bus_release(I2CBus *bus);
151a5c82852SAndreas Färber int i2c_send(I2CBus *bus, uint8_t data);
152a78e9839SKlaus Jensen int i2c_send_async(I2CBus *bus, uint8_t data);
1532ac4c5f4SCorey Minyard uint8_t i2c_recv(I2CBus *bus);
1543f9b3259SPatrick Venture bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
1553f9b3259SPatrick Venture                   I2CNodeList *current_devs);
1560ff596d0Spbrook 
15773d5f22eSPhilippe Mathieu-Daudé /**
15873d5f22eSPhilippe Mathieu-Daudé  * Create an I2C slave device on the heap.
15973d5f22eSPhilippe Mathieu-Daudé  * @name: a device type name
16073d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave when put on a bus
16173d5f22eSPhilippe Mathieu-Daudé  *
16273d5f22eSPhilippe Mathieu-Daudé  * This only initializes the device state structure and allows
16373d5f22eSPhilippe Mathieu-Daudé  * properties to be set. Type @name must exist. The device still
16473d5f22eSPhilippe Mathieu-Daudé  * needs to be realized. See qdev-core.h.
16573d5f22eSPhilippe Mathieu-Daudé  */
166db437ca6SPhilippe Mathieu-Daudé I2CSlave *i2c_slave_new(const char *name, uint8_t addr);
16773d5f22eSPhilippe Mathieu-Daudé 
16873d5f22eSPhilippe Mathieu-Daudé /**
16973d5f22eSPhilippe Mathieu-Daudé  * Create and realize an I2C slave device on the heap.
17073d5f22eSPhilippe Mathieu-Daudé  * @bus: I2C bus to put it on
17173d5f22eSPhilippe Mathieu-Daudé  * @name: I2C slave device type name
17273d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave when put on a bus
17373d5f22eSPhilippe Mathieu-Daudé  *
17473d5f22eSPhilippe Mathieu-Daudé  * Create the device state structure, initialize it, put it on the
17573d5f22eSPhilippe Mathieu-Daudé  * specified @bus, and drop the reference to it (the device is realized).
17673d5f22eSPhilippe Mathieu-Daudé  */
1771373b15bSPhilippe Mathieu-Daudé I2CSlave *i2c_slave_create_simple(I2CBus *bus, const char *name, uint8_t addr);
17873d5f22eSPhilippe Mathieu-Daudé 
17973d5f22eSPhilippe Mathieu-Daudé /**
180d4b23573SPhilippe Mathieu-Daudé  * Realize and drop a reference an I2C slave device
18173d5f22eSPhilippe Mathieu-Daudé  * @dev: I2C slave device to realize
18273d5f22eSPhilippe Mathieu-Daudé  * @bus: I2C bus to put it on
18373d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave on the bus
18473d5f22eSPhilippe Mathieu-Daudé  * @errp: pointer to NULL initialized error object
18573d5f22eSPhilippe Mathieu-Daudé  *
18673d5f22eSPhilippe Mathieu-Daudé  * Returns: %true on success, %false on failure.
18773d5f22eSPhilippe Mathieu-Daudé  *
18873d5f22eSPhilippe Mathieu-Daudé  * Call 'realize' on @dev, put it on the specified @bus, and drop the
18973d5f22eSPhilippe Mathieu-Daudé  * reference to it.
19073d5f22eSPhilippe Mathieu-Daudé  *
19173d5f22eSPhilippe Mathieu-Daudé  * This function is useful if you have created @dev via qdev_new(),
19273d5f22eSPhilippe Mathieu-Daudé  * i2c_slave_new() or i2c_slave_try_new() (which take a reference to
19373d5f22eSPhilippe Mathieu-Daudé  * the device it returns to you), so that you can set properties on it
19473d5f22eSPhilippe Mathieu-Daudé  * before realizing it. If you don't need to set properties then
19573d5f22eSPhilippe Mathieu-Daudé  * i2c_slave_create_simple() is probably better (as it does the create,
19673d5f22eSPhilippe Mathieu-Daudé  * init and realize in one step).
19773d5f22eSPhilippe Mathieu-Daudé  *
19873d5f22eSPhilippe Mathieu-Daudé  * If you are embedding the I2C slave into another QOM device and
19973d5f22eSPhilippe Mathieu-Daudé  * initialized it via some variant on object_initialize_child() then
20073d5f22eSPhilippe Mathieu-Daudé  * do not use this function, because that family of functions arrange
20173d5f22eSPhilippe Mathieu-Daudé  * for the only reference to the child device to be held by the parent
20273d5f22eSPhilippe Mathieu-Daudé  * via the child<> property, and so the reference-count-drop done here
20373d5f22eSPhilippe Mathieu-Daudé  * would be incorrect.  (Instead you would want i2c_slave_realize(),
20473d5f22eSPhilippe Mathieu-Daudé  * which doesn't currently exist but would be trivial to create if we
20573d5f22eSPhilippe Mathieu-Daudé  * had any code that wanted it.)
20673d5f22eSPhilippe Mathieu-Daudé  */
2072616f572SPhilippe Mathieu-Daudé bool i2c_slave_realize_and_unref(I2CSlave *dev, I2CBus *bus, Error **errp);
208fe8de492SPaul Brook 
209c8665a59SPhilippe Mathieu-Daudé /**
210c8665a59SPhilippe Mathieu-Daudé  * Set the I2C bus address of a slave device
211c8665a59SPhilippe Mathieu-Daudé  * @dev: I2C slave device
212c8665a59SPhilippe Mathieu-Daudé  * @address: I2C address of the slave when put on a bus
213c8665a59SPhilippe Mathieu-Daudé  */
214c8665a59SPhilippe Mathieu-Daudé void i2c_slave_set_address(I2CSlave *dev, uint8_t address);
215c8665a59SPhilippe Mathieu-Daudé 
216701a8f76SPaolo Bonzini extern const VMStateDescription vmstate_i2c_slave;
217701a8f76SPaolo Bonzini 
218701a8f76SPaolo Bonzini #define VMSTATE_I2C_SLAVE(_field, _state) {                          \
219701a8f76SPaolo Bonzini     .name       = (stringify(_field)),                               \
2209e07bdf8SAnthony Liguori     .size       = sizeof(I2CSlave),                                  \
221701a8f76SPaolo Bonzini     .vmsd       = &vmstate_i2c_slave,                                \
222701a8f76SPaolo Bonzini     .flags      = VMS_STRUCT,                                        \
2239e07bdf8SAnthony Liguori     .offset     = vmstate_offset_value(_state, _field, I2CSlave),    \
224701a8f76SPaolo Bonzini }
225701a8f76SPaolo Bonzini 
2260ff596d0Spbrook #endif
227