diff options
author | Werner Zeh <werner.zeh@siemens.com> | 2022-08-26 13:17:52 +0200 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2022-09-04 14:55:59 +0000 |
commit | 63f72f0cd0d01ef6138bfba80b7cd19d57c6602c (patch) | |
tree | 87da2616c21e262eed5133fd4fa3d0b024846528 /src/device | |
parent | 74a00b9cec6ce4f1a92d6ade4baa305dbe9e5ffb (diff) |
device/i2c_bus: Add routines to read and write multiple bytes
Some devices require that several bytes are written with a single I2C
write command. Extend the i2c_bus interface functions and add both, read
and write for more than one byte at a defined byte offset.
Change-Id: I0eec2e1d4185170f02b4ab35aa6546dc69569303
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/67098
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Mario Scheithauer <mario.scheithauer@siemens.com>
Diffstat (limited to 'src/device')
-rw-r--r-- | src/device/i2c_bus.c | 70 |
1 files changed, 70 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; + } +} |