summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/comm-host.c29
-rw-r--r--util/comm-host.h3
-rw-r--r--util/comm-i2c.c47
-rw-r--r--util/ectool.c28
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;
}