xref: /qemu/include/hw/i2c/i2c.h (revision 8110fa1d94f2997badc2af39231a1d279c5bb1ee)
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,
150ff596d0Spbrook     I2C_FINISH,
16aa1f17c1Sths     I2C_NACK /* Masker NACKed a receive byte.  */
170ff596d0Spbrook };
180ff596d0Spbrook 
199e07bdf8SAnthony Liguori typedef struct I2CSlave I2CSlave;
200ff596d0Spbrook 
21b5ea9327SAnthony Liguori #define TYPE_I2C_SLAVE "i2c-slave"
22db1015e9SEduardo Habkost typedef struct I2CSlaveClass I2CSlaveClass;
23*8110fa1dSEduardo Habkost DECLARE_OBJ_CHECKERS(I2CSlave, I2CSlaveClass,
24*8110fa1dSEduardo Habkost                      I2C_SLAVE, TYPE_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 
32d307c28cSCorey Minyard     /*
33d307c28cSCorey Minyard      * Slave to master.  This cannot fail, the device should always
342ac4c5f4SCorey Minyard      * return something here.
35d307c28cSCorey Minyard      */
362ac4c5f4SCorey Minyard     uint8_t (*recv)(I2CSlave *s);
37b5ea9327SAnthony Liguori 
38d307c28cSCorey Minyard     /*
39d307c28cSCorey Minyard      * Notify the slave of a bus state change.  For start event,
40d307c28cSCorey Minyard      * returns non-zero to NAK an operation.  For other events the
41d307c28cSCorey Minyard      * return code is not used and should be zero.
42d307c28cSCorey Minyard      */
43d307c28cSCorey Minyard     int (*event)(I2CSlave *s, enum i2c_event event);
44db1015e9SEduardo Habkost };
45fe8de492SPaul Brook 
46373b8ac7SCorey Minyard struct I2CSlave {
47fe8de492SPaul Brook     DeviceState qdev;
480ff596d0Spbrook 
490ff596d0Spbrook     /* Remaining fields for internal use by the I2C code.  */
505b7f5327SJuan Quintela     uint8_t address;
510ff596d0Spbrook };
520ff596d0Spbrook 
53aa88d7adSCorey Minyard #define TYPE_I2C_BUS "i2c-bus"
54*8110fa1dSEduardo Habkost DECLARE_INSTANCE_CHECKER(I2CBus, I2C_BUS,
55*8110fa1dSEduardo Habkost                          TYPE_I2C_BUS)
56aa88d7adSCorey Minyard 
57aa88d7adSCorey Minyard typedef struct I2CNode I2CNode;
58aa88d7adSCorey Minyard 
59aa88d7adSCorey Minyard struct I2CNode {
60aa88d7adSCorey Minyard     I2CSlave *elt;
61aa88d7adSCorey Minyard     QLIST_ENTRY(I2CNode) next;
62aa88d7adSCorey Minyard };
63aa88d7adSCorey Minyard 
64aa88d7adSCorey Minyard struct I2CBus {
65aa88d7adSCorey Minyard     BusState qbus;
66aa88d7adSCorey Minyard     QLIST_HEAD(, I2CNode) current_devs;
67aa88d7adSCorey Minyard     uint8_t saved_address;
68aa88d7adSCorey Minyard     bool broadcast;
69aa88d7adSCorey Minyard };
70aa88d7adSCorey Minyard 
71a5c82852SAndreas Färber I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
729e07bdf8SAnthony Liguori void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
73a5c82852SAndreas Färber int i2c_bus_busy(I2CBus *bus);
74a5c82852SAndreas Färber int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
75a5c82852SAndreas Färber void i2c_end_transfer(I2CBus *bus);
76a5c82852SAndreas Färber void i2c_nack(I2CBus *bus);
77056fca7bSPeter Crosthwaite int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send);
78a5c82852SAndreas Färber int i2c_send(I2CBus *bus, uint8_t data);
792ac4c5f4SCorey Minyard uint8_t i2c_recv(I2CBus *bus);
800ff596d0Spbrook 
8173d5f22eSPhilippe Mathieu-Daudé /**
8273d5f22eSPhilippe Mathieu-Daudé  * Create an I2C slave device on the heap.
8373d5f22eSPhilippe Mathieu-Daudé  * @name: a device type name
8473d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave when put on a bus
8573d5f22eSPhilippe Mathieu-Daudé  *
8673d5f22eSPhilippe Mathieu-Daudé  * This only initializes the device state structure and allows
8773d5f22eSPhilippe Mathieu-Daudé  * properties to be set. Type @name must exist. The device still
8873d5f22eSPhilippe Mathieu-Daudé  * needs to be realized. See qdev-core.h.
8973d5f22eSPhilippe Mathieu-Daudé  */
90db437ca6SPhilippe Mathieu-Daudé I2CSlave *i2c_slave_new(const char *name, uint8_t addr);
9173d5f22eSPhilippe Mathieu-Daudé 
9273d5f22eSPhilippe Mathieu-Daudé /**
9373d5f22eSPhilippe Mathieu-Daudé  * Create and realize an I2C slave device on the heap.
9473d5f22eSPhilippe Mathieu-Daudé  * @bus: I2C bus to put it on
9573d5f22eSPhilippe Mathieu-Daudé  * @name: I2C slave device type name
9673d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave when put on a bus
9773d5f22eSPhilippe Mathieu-Daudé  *
9873d5f22eSPhilippe Mathieu-Daudé  * Create the device state structure, initialize it, put it on the
9973d5f22eSPhilippe Mathieu-Daudé  * specified @bus, and drop the reference to it (the device is realized).
10073d5f22eSPhilippe Mathieu-Daudé  */
1011373b15bSPhilippe Mathieu-Daudé I2CSlave *i2c_slave_create_simple(I2CBus *bus, const char *name, uint8_t addr);
10273d5f22eSPhilippe Mathieu-Daudé 
10373d5f22eSPhilippe Mathieu-Daudé /**
104d4b23573SPhilippe Mathieu-Daudé  * Realize and drop a reference an I2C slave device
10573d5f22eSPhilippe Mathieu-Daudé  * @dev: I2C slave device to realize
10673d5f22eSPhilippe Mathieu-Daudé  * @bus: I2C bus to put it on
10773d5f22eSPhilippe Mathieu-Daudé  * @addr: I2C address of the slave on the bus
10873d5f22eSPhilippe Mathieu-Daudé  * @errp: pointer to NULL initialized error object
10973d5f22eSPhilippe Mathieu-Daudé  *
11073d5f22eSPhilippe Mathieu-Daudé  * Returns: %true on success, %false on failure.
11173d5f22eSPhilippe Mathieu-Daudé  *
11273d5f22eSPhilippe Mathieu-Daudé  * Call 'realize' on @dev, put it on the specified @bus, and drop the
11373d5f22eSPhilippe Mathieu-Daudé  * reference to it.
11473d5f22eSPhilippe Mathieu-Daudé  *
11573d5f22eSPhilippe Mathieu-Daudé  * This function is useful if you have created @dev via qdev_new(),
11673d5f22eSPhilippe Mathieu-Daudé  * i2c_slave_new() or i2c_slave_try_new() (which take a reference to
11773d5f22eSPhilippe Mathieu-Daudé  * the device it returns to you), so that you can set properties on it
11873d5f22eSPhilippe Mathieu-Daudé  * before realizing it. If you don't need to set properties then
11973d5f22eSPhilippe Mathieu-Daudé  * i2c_slave_create_simple() is probably better (as it does the create,
12073d5f22eSPhilippe Mathieu-Daudé  * init and realize in one step).
12173d5f22eSPhilippe Mathieu-Daudé  *
12273d5f22eSPhilippe Mathieu-Daudé  * If you are embedding the I2C slave into another QOM device and
12373d5f22eSPhilippe Mathieu-Daudé  * initialized it via some variant on object_initialize_child() then
12473d5f22eSPhilippe Mathieu-Daudé  * do not use this function, because that family of functions arrange
12573d5f22eSPhilippe Mathieu-Daudé  * for the only reference to the child device to be held by the parent
12673d5f22eSPhilippe Mathieu-Daudé  * via the child<> property, and so the reference-count-drop done here
12773d5f22eSPhilippe Mathieu-Daudé  * would be incorrect.  (Instead you would want i2c_slave_realize(),
12873d5f22eSPhilippe Mathieu-Daudé  * which doesn't currently exist but would be trivial to create if we
12973d5f22eSPhilippe Mathieu-Daudé  * had any code that wanted it.)
13073d5f22eSPhilippe Mathieu-Daudé  */
1312616f572SPhilippe Mathieu-Daudé bool i2c_slave_realize_and_unref(I2CSlave *dev, I2CBus *bus, Error **errp);
132fe8de492SPaul Brook 
1331d4e547bSbalrog /* lm832x.c */
134c4f05c8cSPeter Maydell void lm832x_key_event(DeviceState *dev, int key, int state);
1351d4e547bSbalrog 
136701a8f76SPaolo Bonzini extern const VMStateDescription vmstate_i2c_slave;
137701a8f76SPaolo Bonzini 
138701a8f76SPaolo Bonzini #define VMSTATE_I2C_SLAVE(_field, _state) {                          \
139701a8f76SPaolo Bonzini     .name       = (stringify(_field)),                               \
1409e07bdf8SAnthony Liguori     .size       = sizeof(I2CSlave),                                  \
141701a8f76SPaolo Bonzini     .vmsd       = &vmstate_i2c_slave,                                \
142701a8f76SPaolo Bonzini     .flags      = VMS_STRUCT,                                        \
1439e07bdf8SAnthony Liguori     .offset     = vmstate_offset_value(_state, _field, I2CSlave),    \
144701a8f76SPaolo Bonzini }
145701a8f76SPaolo Bonzini 
1460ff596d0Spbrook #endif
147