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 19513ca82dSPatrick Venture typedef struct I2CNodeList I2CNodeList; 200ff596d0Spbrook 21b5ea9327SAnthony Liguori #define TYPE_I2C_SLAVE "i2c-slave" 22c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(I2CSlave, I2CSlaveClass, 2330b5707cSEduardo Habkost I2C_SLAVE) 249e07bdf8SAnthony Liguori 25db1015e9SEduardo Habkost struct I2CSlaveClass { 26b5ea9327SAnthony Liguori DeviceClass parent_class; 2702e2da45SPaul Brook 28d307c28cSCorey Minyard /* Master to slave. Returns non-zero for a NAK, 0 for success. */ 29b5ea9327SAnthony Liguori int (*send)(I2CSlave *s, uint8_t data); 30b5ea9327SAnthony Liguori 31d307c28cSCorey Minyard /* 32d307c28cSCorey Minyard * Slave to master. This cannot fail, the device should always 332ac4c5f4SCorey Minyard * return something here. 34d307c28cSCorey Minyard */ 352ac4c5f4SCorey Minyard uint8_t (*recv)(I2CSlave *s); 36b5ea9327SAnthony Liguori 37d307c28cSCorey Minyard /* 38d307c28cSCorey Minyard * Notify the slave of a bus state change. For start event, 39d307c28cSCorey Minyard * returns non-zero to NAK an operation. For other events the 40d307c28cSCorey Minyard * return code is not used and should be zero. 41d307c28cSCorey Minyard */ 42d307c28cSCorey Minyard int (*event)(I2CSlave *s, enum i2c_event event); 43513ca82dSPatrick Venture 44513ca82dSPatrick Venture /* 45513ca82dSPatrick Venture * Check if this device matches the address provided. Returns bool of 46513ca82dSPatrick Venture * true if it matches (or broadcast), and updates the device list, false 47513ca82dSPatrick Venture * otherwise. 48513ca82dSPatrick Venture * 49513ca82dSPatrick Venture * If broadcast is true, match should add the device and return true. 50513ca82dSPatrick Venture */ 51513ca82dSPatrick Venture bool (*match_and_add)(I2CSlave *candidate, uint8_t address, bool broadcast, 52513ca82dSPatrick Venture I2CNodeList *current_devs); 53db1015e9SEduardo Habkost }; 54fe8de492SPaul Brook 55373b8ac7SCorey Minyard struct I2CSlave { 56fe8de492SPaul Brook DeviceState qdev; 570ff596d0Spbrook 580ff596d0Spbrook /* Remaining fields for internal use by the I2C code. */ 595b7f5327SJuan Quintela uint8_t address; 600ff596d0Spbrook }; 610ff596d0Spbrook 62aa88d7adSCorey Minyard #define TYPE_I2C_BUS "i2c-bus" 638063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(I2CBus, I2C_BUS) 64aa88d7adSCorey Minyard 65aa88d7adSCorey Minyard typedef struct I2CNode I2CNode; 66aa88d7adSCorey Minyard 67aa88d7adSCorey Minyard struct I2CNode { 68aa88d7adSCorey Minyard I2CSlave *elt; 69aa88d7adSCorey Minyard QLIST_ENTRY(I2CNode) next; 70aa88d7adSCorey Minyard }; 71aa88d7adSCorey Minyard 72b98ec689SPatrick Venture typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList; 73b98ec689SPatrick Venture 74aa88d7adSCorey Minyard struct I2CBus { 75aa88d7adSCorey Minyard BusState qbus; 76b98ec689SPatrick Venture I2CNodeList current_devs; 77aa88d7adSCorey Minyard uint8_t saved_address; 78aa88d7adSCorey Minyard bool broadcast; 79aa88d7adSCorey Minyard }; 80aa88d7adSCorey Minyard 81a5c82852SAndreas Färber I2CBus *i2c_init_bus(DeviceState *parent, const char *name); 82a5c82852SAndreas Färber int i2c_bus_busy(I2CBus *bus); 83*e656e387SBALATON Zoltan 84*e656e387SBALATON Zoltan /** 85*e656e387SBALATON Zoltan * i2c_start_transfer: start a transfer on an I2C bus. 86*e656e387SBALATON Zoltan * 87*e656e387SBALATON Zoltan * @bus: #I2CBus to be used 88*e656e387SBALATON Zoltan * @address: address of the slave 89*e656e387SBALATON Zoltan * @is_recv: indicates the transfer direction 90*e656e387SBALATON Zoltan * 91*e656e387SBALATON Zoltan * Returns: 0 on success, -1 on error 92*e656e387SBALATON Zoltan */ 93*e656e387SBALATON Zoltan int i2c_start_transfer(I2CBus *bus, uint8_t address, bool is_recv); 94a5c82852SAndreas Färber void i2c_end_transfer(I2CBus *bus); 95a5c82852SAndreas Färber void i2c_nack(I2CBus *bus); 96a5c82852SAndreas Färber int i2c_send(I2CBus *bus, uint8_t data); 972ac4c5f4SCorey Minyard uint8_t i2c_recv(I2CBus *bus); 983f9b3259SPatrick Venture bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast, 993f9b3259SPatrick Venture I2CNodeList *current_devs); 1000ff596d0Spbrook 10173d5f22eSPhilippe Mathieu-Daudé /** 10273d5f22eSPhilippe Mathieu-Daudé * Create an I2C slave device on the heap. 10373d5f22eSPhilippe Mathieu-Daudé * @name: a device type name 10473d5f22eSPhilippe Mathieu-Daudé * @addr: I2C address of the slave when put on a bus 10573d5f22eSPhilippe Mathieu-Daudé * 10673d5f22eSPhilippe Mathieu-Daudé * This only initializes the device state structure and allows 10773d5f22eSPhilippe Mathieu-Daudé * properties to be set. Type @name must exist. The device still 10873d5f22eSPhilippe Mathieu-Daudé * needs to be realized. See qdev-core.h. 10973d5f22eSPhilippe Mathieu-Daudé */ 110db437ca6SPhilippe Mathieu-Daudé I2CSlave *i2c_slave_new(const char *name, uint8_t addr); 11173d5f22eSPhilippe Mathieu-Daudé 11273d5f22eSPhilippe Mathieu-Daudé /** 11373d5f22eSPhilippe Mathieu-Daudé * Create and realize an I2C slave device on the heap. 11473d5f22eSPhilippe Mathieu-Daudé * @bus: I2C bus to put it on 11573d5f22eSPhilippe Mathieu-Daudé * @name: I2C slave device type name 11673d5f22eSPhilippe Mathieu-Daudé * @addr: I2C address of the slave when put on a bus 11773d5f22eSPhilippe Mathieu-Daudé * 11873d5f22eSPhilippe Mathieu-Daudé * Create the device state structure, initialize it, put it on the 11973d5f22eSPhilippe Mathieu-Daudé * specified @bus, and drop the reference to it (the device is realized). 12073d5f22eSPhilippe Mathieu-Daudé */ 1211373b15bSPhilippe Mathieu-Daudé I2CSlave *i2c_slave_create_simple(I2CBus *bus, const char *name, uint8_t addr); 12273d5f22eSPhilippe Mathieu-Daudé 12373d5f22eSPhilippe Mathieu-Daudé /** 124d4b23573SPhilippe Mathieu-Daudé * Realize and drop a reference an I2C slave device 12573d5f22eSPhilippe Mathieu-Daudé * @dev: I2C slave device to realize 12673d5f22eSPhilippe Mathieu-Daudé * @bus: I2C bus to put it on 12773d5f22eSPhilippe Mathieu-Daudé * @addr: I2C address of the slave on the bus 12873d5f22eSPhilippe Mathieu-Daudé * @errp: pointer to NULL initialized error object 12973d5f22eSPhilippe Mathieu-Daudé * 13073d5f22eSPhilippe Mathieu-Daudé * Returns: %true on success, %false on failure. 13173d5f22eSPhilippe Mathieu-Daudé * 13273d5f22eSPhilippe Mathieu-Daudé * Call 'realize' on @dev, put it on the specified @bus, and drop the 13373d5f22eSPhilippe Mathieu-Daudé * reference to it. 13473d5f22eSPhilippe Mathieu-Daudé * 13573d5f22eSPhilippe Mathieu-Daudé * This function is useful if you have created @dev via qdev_new(), 13673d5f22eSPhilippe Mathieu-Daudé * i2c_slave_new() or i2c_slave_try_new() (which take a reference to 13773d5f22eSPhilippe Mathieu-Daudé * the device it returns to you), so that you can set properties on it 13873d5f22eSPhilippe Mathieu-Daudé * before realizing it. If you don't need to set properties then 13973d5f22eSPhilippe Mathieu-Daudé * i2c_slave_create_simple() is probably better (as it does the create, 14073d5f22eSPhilippe Mathieu-Daudé * init and realize in one step). 14173d5f22eSPhilippe Mathieu-Daudé * 14273d5f22eSPhilippe Mathieu-Daudé * If you are embedding the I2C slave into another QOM device and 14373d5f22eSPhilippe Mathieu-Daudé * initialized it via some variant on object_initialize_child() then 14473d5f22eSPhilippe Mathieu-Daudé * do not use this function, because that family of functions arrange 14573d5f22eSPhilippe Mathieu-Daudé * for the only reference to the child device to be held by the parent 14673d5f22eSPhilippe Mathieu-Daudé * via the child<> property, and so the reference-count-drop done here 14773d5f22eSPhilippe Mathieu-Daudé * would be incorrect. (Instead you would want i2c_slave_realize(), 14873d5f22eSPhilippe Mathieu-Daudé * which doesn't currently exist but would be trivial to create if we 14973d5f22eSPhilippe Mathieu-Daudé * had any code that wanted it.) 15073d5f22eSPhilippe Mathieu-Daudé */ 1512616f572SPhilippe Mathieu-Daudé bool i2c_slave_realize_and_unref(I2CSlave *dev, I2CBus *bus, Error **errp); 152fe8de492SPaul Brook 153c8665a59SPhilippe Mathieu-Daudé /** 154c8665a59SPhilippe Mathieu-Daudé * Set the I2C bus address of a slave device 155c8665a59SPhilippe Mathieu-Daudé * @dev: I2C slave device 156c8665a59SPhilippe Mathieu-Daudé * @address: I2C address of the slave when put on a bus 157c8665a59SPhilippe Mathieu-Daudé */ 158c8665a59SPhilippe Mathieu-Daudé void i2c_slave_set_address(I2CSlave *dev, uint8_t address); 159c8665a59SPhilippe Mathieu-Daudé 160701a8f76SPaolo Bonzini extern const VMStateDescription vmstate_i2c_slave; 161701a8f76SPaolo Bonzini 162701a8f76SPaolo Bonzini #define VMSTATE_I2C_SLAVE(_field, _state) { \ 163701a8f76SPaolo Bonzini .name = (stringify(_field)), \ 1649e07bdf8SAnthony Liguori .size = sizeof(I2CSlave), \ 165701a8f76SPaolo Bonzini .vmsd = &vmstate_i2c_slave, \ 166701a8f76SPaolo Bonzini .flags = VMS_STRUCT, \ 1679e07bdf8SAnthony Liguori .offset = vmstate_offset_value(_state, _field, I2CSlave), \ 168701a8f76SPaolo Bonzini } 169701a8f76SPaolo Bonzini 1700ff596d0Spbrook #endif 171