diff options
-rw-r--r-- | src/device/i2c_bus.c | 70 | ||||
-rw-r--r-- | src/include/device/i2c_bus.h | 14 |
2 files changed, 84 insertions, 0 deletions
diff --git a/src/device/i2c_bus.c b/src/device/i2c_bus.c index 8368c247b8..f0d7dd116e 100644 --- a/src/device/i2c_bus.c +++ b/src/device/i2c_bus.c @@ -183,3 +183,73 @@ int i2c_dev_read_at16(struct device *const dev, uint8_t *const buf, const size_t return -1; } } + +int i2c_dev_read_at(struct device *const dev, uint8_t *const buf, const size_t len, + uint8_t off) +{ + struct device *const busdev = i2c_busdev(dev); + if (!busdev) + return -1; + + if (busdev->ops->ops_i2c_bus) { + const struct i2c_msg msg[] = { + { + .flags = 0, + .slave = dev->path.i2c.device, + .buf = &off, + .len = sizeof(off), + }, + { + .flags = I2C_M_RD, + .slave = dev->path.i2c.device, + .buf = buf, + .len = len, + }, + }; + + const int ret = busdev->ops->ops_i2c_bus->transfer(busdev, msg, + ARRAY_SIZE(msg)); + if (ret) + return ret; + else + return len; + } else { + printk(BIOS_ERR, "%s Missing ops_i2c_bus->transfer", dev_path(busdev)); + return -1; + } +} + +int i2c_dev_write_at(struct device *const dev, uint8_t *const buf, const size_t len, + uint8_t off) +{ + struct device *const busdev = i2c_busdev(dev); + if (!busdev) + return -1; + + if (busdev->ops->ops_i2c_bus) { + const struct i2c_msg msg[] = { + { + .flags = 0, + .slave = dev->path.i2c.device, + .buf = &off, + .len = sizeof(off), + }, + { + .flags = I2C_M_NOSTART, + .slave = dev->path.i2c.device, + .buf = buf, + .len = len, + }, + }; + + const int ret = busdev->ops->ops_i2c_bus->transfer(busdev, msg, + ARRAY_SIZE(msg)); + if (ret) + return ret; + else + return len; + } else { + printk(BIOS_ERR, "%s Missing ops_i2c_bus->transfer", dev_path(busdev)); + return -1; + } +} diff --git a/src/include/device/i2c_bus.h b/src/include/device/i2c_bus.h index 1a7e777278..4c9b98d14f 100644 --- a/src/include/device/i2c_bus.h +++ b/src/include/device/i2c_bus.h @@ -90,5 +90,19 @@ int i2c_dev_writeb_at(struct device *, uint8_t off, uint8_t val); * value on error. */ int i2c_dev_read_at16(struct device *, uint8_t *buf, size_t len, uint16_t off); +/* + * Sends the 8-bit register offset `off` and reads `len` bytes into `buf`. + * + * Returns the number of bytes read on success, negative `enum cb_err` + * value on error. + */ +int i2c_dev_read_at(struct device *, uint8_t *buf, size_t len, uint8_t off); +/* + * Sends the 8-bit register offset `off` and writes `len` bytes from `buf`. + * + * Returns the number of bytes written on success, negative `enum cb_err` + * value on error. + */ +int i2c_dev_write_at(struct device *, uint8_t *buf, size_t len, uint8_t off); #endif /* _DEVICE_I2C_BUS_H_ */ |