diff options
-rw-r--r-- | util/comm-host.c | 29 | ||||
-rw-r--r-- | util/comm-host.h | 3 | ||||
-rw-r--r-- | util/comm-i2c.c | 47 | ||||
-rw-r--r-- | util/ectool.c | 28 |
4 files changed, 73 insertions, 34 deletions
diff --git a/util/comm-host.c b/util/comm-host.c index 947b240bfa..dd42df1aa8 100644 --- a/util/comm-host.c +++ b/util/comm-host.c @@ -4,6 +4,7 @@ */ #include <errno.h> +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -31,7 +32,7 @@ static int command_offset; int comm_init_dev(const char *device_name) __attribute__((weak)); int comm_init_lpc(void) __attribute__((weak)); -int comm_init_i2c(void) __attribute__((weak)); +int comm_init_i2c(int i2c_bus) __attribute__((weak)); int comm_init_servo_spi(const char *device_name) __attribute__((weak)); static int fake_readmem(int offset, int bytes, void *dest) @@ -82,8 +83,10 @@ int ec_command(int command, int version, indata, insize); } -int comm_init_alt(int interfaces, const char *device_name) +int comm_init_alt(int interfaces, const char *device_name, int i2c_bus) { + bool dev_is_cros_ec; + /* Default memmap access */ ec_readmem = fake_readmem; @@ -93,17 +96,17 @@ int comm_init_alt(int interfaces, const char *device_name) /* Do not fallback to other communication methods if target is not a * cros_ec device */ - if (!strcmp(CROS_EC_DEV_NAME, device_name)) { - /* Fallback to direct LPC on x86 */ - if ((interfaces & COMM_LPC) && - comm_init_lpc && !comm_init_lpc()) - return 0; - - /* Fallback to direct i2c on ARM */ - if ((interfaces & COMM_I2C) && - comm_init_i2c && !comm_init_i2c()) - return 0; - } + dev_is_cros_ec = !strcmp(CROS_EC_DEV_NAME, device_name); + + /* Fallback to direct LPC on x86 */ + if (dev_is_cros_ec && (interfaces & COMM_LPC) && + comm_init_lpc && !comm_init_lpc()) + return 0; + + /* Fallback to direct I2C */ + if ((dev_is_cros_ec || i2c_bus != -1) && (interfaces & COMM_I2C) && + comm_init_i2c && !comm_init_i2c(i2c_bus)) + return 0; /* Give up */ fprintf(stderr, "Unable to establish host communication\n"); diff --git a/util/comm-host.h b/util/comm-host.h index 603f95e107..309c97eeb5 100644 --- a/util/comm-host.h +++ b/util/comm-host.h @@ -39,9 +39,10 @@ enum comm_interface { * * @param interfaces Interfaces to try; use COMM_ALL to try all of them. * @param device_name For DEV option, the device file to use. + * @param i2c_bus For I2C option, the bus number to use (or -1 to autodetect). * @return 0 in case of success, or error code. */ -int comm_init_alt(int interfaces, const char *device_name); +int comm_init_alt(int interfaces, const char *device_name, int i2c_bus); /** * Initialize dev interface diff --git a/util/comm-i2c.c b/util/comm-i2c.c index d01ce3d023..d88454ee3b 100644 --- a/util/comm-i2c.c +++ b/util/comm-i2c.c @@ -196,33 +196,44 @@ done: return ret; } -int comm_init_i2c(void) +int comm_init_i2c(int i2c_bus) { char *file_path; char buffer[64]; int i; - /* find the device number based on the adapter name */ - for (i = 0; i < I2C_MAX_ADAPTER; i++) { - FILE *f; - if (asprintf(&file_path, I2C_ADAPTER_NODE, - i, i, EC_I2C_ADDR) < 0) + if (i2c_bus != -1) { + i = i2c_bus; + + if (i >= I2C_MAX_ADAPTER) { + fprintf(stderr, "Invalid I2C bus number %d. (The highest possible bus number is %d.)\n", + i, I2C_MAX_ADAPTER); return -1; - f = fopen(file_path, "r"); - if (f) { - if (fgets(buffer, sizeof(buffer), f) && - !strncmp(buffer, I2C_ADAPTER_NAME, 6)) { - free(file_path); + } + } else { + /* find the device number based on the adapter name */ + for (i = 0; i < I2C_MAX_ADAPTER; i++) { + FILE *f; + + if (asprintf(&file_path, I2C_ADAPTER_NODE, + i, i, EC_I2C_ADDR) < 0) + return -1; + f = fopen(file_path, "r"); + if (f) { + if (fgets(buffer, sizeof(buffer), f) && + !strncmp(buffer, I2C_ADAPTER_NAME, 6)) { + free(file_path); + fclose(f); + break; + } fclose(f); - break; } - fclose(f); + free(file_path); + } + if (i == I2C_MAX_ADAPTER) { + fprintf(stderr, "Cannot find I2C adapter\n"); + return -1; } - free(file_path); - } - if (i == I2C_MAX_ADAPTER) { - fprintf(stderr, "Cannot find I2C adapter\n"); - return -1; } if (asprintf(&file_path, I2C_NODE, i) < 0) diff --git a/util/ectool.c b/util/ectool.c index d73dd770ee..a78c8ba5f6 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -48,6 +48,7 @@ enum { OPT_INTERFACE, OPT_NAME, OPT_ASCII, + OPT_I2C_BUS, }; static struct option long_opts[] = { @@ -55,6 +56,7 @@ static struct option long_opts[] = { {"interface", 1, 0, OPT_INTERFACE}, {"name", 1, 0, OPT_NAME}, {"ascii", 0, 0, OPT_ASCII}, + {"i2c_bus", 1, 0, OPT_I2C_BUS}, {NULL, 0, 0, 0} }; @@ -352,9 +354,13 @@ int parse_bool(const char *s, int *dest) void print_help(const char *prog, int print_cmds) { - printf("Usage: %s [--dev=n] [--interface=dev|i2c|lpc] ", prog); + printf("Usage: %s [--dev=n] [--interface=dev|i2c|lpc] [--i2c_bus=n]", + prog); printf("[--name=cros_ec|cros_fp|cros_pd|cros_scp|cros_ish] [--ascii] "); printf("<command> [params]\n\n"); + printf(" --i2c_bus=n Specifies the number of an I2C bus to use. For\n" + " example, to use /dev/i2c-7, pass --i2c_bus=7.\n" + " Implies --interface=i2c.\n\n"); if (print_cmds) puts(help_str); else @@ -9156,6 +9162,7 @@ int main(int argc, char *argv[]) const struct command *cmd; int dev = 0; int interfaces = COMM_ALL; + int i2c_bus = -1; char device_name[41] = CROS_EC_DEV_NAME; int rv = 1; int parse_error = 0; @@ -9197,12 +9204,29 @@ int main(int argc, char *argv[]) strncpy(device_name, optarg, 40); device_name[40] = '\0'; break; + case OPT_I2C_BUS: + i2c_bus = strtoul(optarg, &e, 0); + if (*optarg == '\0' || (e && *e != '\0') + || i2c_bus < 0) { + fprintf(stderr, "Invalid --i2c_bus\n"); + parse_error = 1; + } + break; case OPT_ASCII: ascii_mode = 1; break; } } + if (i2c_bus != -1) { + if (!(interfaces & COMM_I2C)) { + fprintf(stderr, "--i2c_bus is specified, but --interface is set to something other than I2C\n"); + parse_error = 1; + } else { + interfaces = COMM_I2C; + } + } + /* Must specify a command */ if (!parse_error && optind == argc) parse_error = 1; @@ -9236,7 +9260,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Could not acquire GEC lock.\n"); exit(1); } - if (comm_init_alt(interfaces, device_name)) { + if (comm_init_alt(interfaces, device_name, i2c_bus)) { fprintf(stderr, "Couldn't find EC\n"); goto out; } |