Peter Marheine has uploaded this change for review.

View Change

lspcon_i2c_spi: support a devpath option

Some callers may find it easier to provide the path to an I2C device
at which to communicate with the device, rather than specify the bus
number- doing so might involve trying to parse a path to extract the
number only for flashrom to do the reverse, which is error-prone and
unnecessary.

This change adds support for a `devpath` option that is preferred,
continuing to allow `bus` and requiring one of them be specified.

TEST=Verified --flash-size outputs correct values with both
devpath=/dev/i2c-7 and bus=7, as well as noting that one is
required if neither is specified.

Signed-off-by: Peter Marheine <pmarheine@chromium.org>
Change-Id: Id2adf8a307b9205ce5e5804a6c3e22f19d0c34c9
---
M i2c_helper.h
M i2c_helper_linux.c
M lspcon_i2c_spi.c
3 files changed, 46 insertions(+), 23 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/67/51967/1
diff --git a/i2c_helper.h b/i2c_helper.h
index 599e08b..cab2ce6 100644
--- a/i2c_helper.h
+++ b/i2c_helper.h
@@ -72,6 +72,14 @@
int i2c_open(int bus, uint16_t addr, int force);

/**
+ * i2c_open_path: open an I2C device by device path
+ *
+ * This function behaves the same as i2c_open, but takes a filesystem
+ * path (assumed to be an I2C device file) instead of a bus number.
+ */
+int i2c_open_path(const char *path, uint16_t addr, int force);
+
+/**
* i2c_close - closes the file descriptor returned by i2c_open
*
* @fd: file descriptor to be closed.
diff --git a/i2c_helper_linux.c b/i2c_helper_linux.c
index 5c191f9..10c4547 100644
--- a/i2c_helper_linux.c
+++ b/i2c_helper_linux.c
@@ -36,14 +36,35 @@
return fd == -1 ? 0 : close(fd);
}

+int i2c_open_path(const char *path, uint16_t addr, int force)
+{
+ int ret = -1;
+ int fd = open(path, O_RDWR);
+ if (fd < 0) {
+ msg_perr("Unable to open I2C device %s: %s.\n", path, strerror(errno));
+ ret = fd;
+ goto err;
+ }
+
+ int request = force ? I2C_SLAVE_FORCE : I2C_SLAVE;
+ ret = ioctl(fd, request, addr);
+ if (ret < 0) {
+ msg_perr("Unable to set I2C slave address to 0x%02x: %s.\n", addr, strerror(errno));
+ i2c_close(fd);
+ goto err;
+ }
+
+err:
+ return ret ? ret : fd;
+}
+
+
int i2c_open(int bus, uint16_t addr, int force)
{
int ret = -1;
- int fd = -1;

/* Maximum i2c bus number is 255(3 char), +1 for null terminated string. */
int path_len = strlen(I2C_DEV_PREFIX) + 4;
- int request = force ? I2C_SLAVE_FORCE : I2C_SLAVE;

if (bus < 0 || bus > I2C_MAX_BUS) {
msg_perr("Invalid I2C bus %d.\n", bus);
@@ -63,25 +84,12 @@
goto linux_i2c_open_err;
}

- fd = open(dev, O_RDWR);
- if (fd < 0) {
- msg_perr("Unable to open I2C device %s: %s.\n", dev, strerror(errno));
- ret = fd;
- goto linux_i2c_open_err;
- }
-
- ret = ioctl(fd, request, addr);
- if (ret < 0) {
- msg_perr("Unable to set I2C slave address to 0x%02x: %s.\n", addr, strerror(errno));
- i2c_close(fd);
- goto linux_i2c_open_err;
- }
-
+ ret = i2c_open_path(dev, addr, force);
linux_i2c_open_err:
if (dev)
free(dev);

- return ret ? ret : fd;
+ return ret;
}

int i2c_read(int fd, uint16_t addr, i2c_buffer_t *buf)
diff --git a/lspcon_i2c_spi.c b/lspcon_i2c_spi.c
index 7b9f1c0..a748f85 100644
--- a/lspcon_i2c_spi.c
+++ b/lspcon_i2c_spi.c
@@ -434,7 +434,7 @@
}

/* TODO: remove this out of the specific SPI master implementation. */
-static int get_bus(void)
+static int get_bus_number(void)
{
char *bus_str = extract_programmer_param("bus");
int ret = SPI_GENERIC_ERROR;
@@ -474,16 +474,23 @@

int lspcon_i2c_spi_init(void)
{
- int lspcon_i2c_spi_bus = get_bus();
- if (lspcon_i2c_spi_bus < 0)
+ int fd = -1;
+ char *device_path;
+ int bus_number;
+ if ((device_path = extract_programmer_param("devpath")) != NULL) {
+ fd = i2c_open_path(device_path, REGISTER_ADDRESS, 0);
+ free(device_path);
+ } else if ((bus_number = get_bus_number()) >= 0) {
+ fd = i2c_open(bus_number, REGISTER_ADDRESS, 0);
+ } else {
+ msg_perr("%s: one of devpath or bus must be specified\n", __func__);
return SPI_GENERIC_ERROR;
+ }

- int ret = 0;
- int fd = i2c_open(lspcon_i2c_spi_bus, REGISTER_ADDRESS, 0);
if (fd < 0)
return fd;

- ret |= lspcon_i2c_spi_reset_mpu_stop(fd);
+ int ret = lspcon_i2c_spi_reset_mpu_stop(fd);
if (ret) {
msg_perr("%s: call to reset_mpu_stop failed.\n", __func__);
return ret;

To view, visit change 51967. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: Id2adf8a307b9205ce5e5804a6c3e22f19d0c34c9
Gerrit-Change-Number: 51967
Gerrit-PatchSet: 1
Gerrit-Owner: Peter Marheine <pmarheine@chromium.org>
Gerrit-MessageType: newchange