From 2457b509cc1a962231a543dff54d1ecd04ee952d Mon Sep 17 00:00:00 2001 From: Mohammed Habibulla Date: Wed, 23 Apr 2014 15:47:26 -0700 Subject: Added v1 version of ectool gpioget supporting more functions ectool gpioget - returns all GPIOs (with flag info) ectool gpioget - get value of ectool gpioget count - returns number of GPIOs ectool gpioget all - returns all GPIOs (with flag info) BUG=chromium:344969 TEST="ectool gpioget [ ]" returns correct information on squawks BRANCH=none Change-Id: Ib6f0d8135a76501f08b084bfd7eb1f2689d5d6e0 Signed-off-by: Mohammed Habibulla Reviewed-on: https://chromium-review.googlesource.com/196680 Reviewed-by: Randall Spangler --- common/gpio.c | 55 ++++++++++++++++++++++++----- include/ec_commands.h | 33 +++++++++++++++++ util/ectool.c | 98 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 166 insertions(+), 20 deletions(-) diff --git a/common/gpio.c b/common/gpio.c index 13775ea449..84a4fc1f47 100644 --- a/common/gpio.c +++ b/common/gpio.c @@ -177,19 +177,56 @@ DECLARE_CONSOLE_COMMAND(gpioset, command_gpio_set, static int gpio_command_get(struct host_cmd_handler_args *args) { - const struct ec_params_gpio_get *p = args->params; - struct ec_response_gpio_get *r = args->response; - int i; + const struct gpio_info *g = gpio_list; + const struct ec_params_gpio_get_v1 *p_v1 = args->params; + struct ec_response_gpio_get_v1 *r_v1 = args->response; + int i, len; + + if (args->version == 0) { + const struct ec_params_gpio_get *p = args->params; + struct ec_response_gpio_get *r = args->response; + i = find_signal_by_name(p->name); + if (i == GPIO_COUNT) + return EC_RES_ERROR; - i = find_signal_by_name(p->name); - if (i == GPIO_COUNT) - return EC_RES_ERROR; + r->val = gpio_get_level(i); + args->response_size = sizeof(struct ec_response_gpio_get); + return EC_RES_SUCCESS; + } + + switch (p_v1->subcmd) { + case EC_GPIO_GET_BY_NAME: + i = find_signal_by_name(p_v1->get_value_by_name.name); + if (i == GPIO_COUNT) + return EC_RES_ERROR; + + r_v1->get_value_by_name.val = gpio_get_level(i); + args->response_size = sizeof(r_v1->get_value_by_name); + break; + case EC_GPIO_GET_COUNT: + r_v1->get_count.val = GPIO_COUNT; + args->response_size = sizeof(r_v1->get_count); + break; + case EC_GPIO_GET_INFO: + if (p_v1->get_info.index >= GPIO_COUNT) + return EC_RES_ERROR; + + i = p_v1->get_info.index; + len = strlen(g[i].name); + memcpy(r_v1->get_info.name, g[i].name, len+1); + r_v1->get_info.val = gpio_get_level(i); + r_v1->get_info.flags = g[i].flags; + args->response_size = sizeof(r_v1->get_info); + break; + default: + return EC_RES_INVALID_PARAM; + } - r->val = gpio_get_level(i); - args->response_size = sizeof(struct ec_response_gpio_get); return EC_RES_SUCCESS; + } -DECLARE_HOST_COMMAND(EC_CMD_GPIO_GET, gpio_command_get, EC_VER_MASK(0)); +DECLARE_HOST_COMMAND(EC_CMD_GPIO_GET, gpio_command_get, + EC_VER_MASK(0) | EC_VER_MASK(1)); static int gpio_command_set(struct host_cmd_handler_args *args) { diff --git a/include/ec_commands.h b/include/ec_commands.h index 1aa902eb32..9b68e1f3bd 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1767,6 +1767,7 @@ struct ec_params_gpio_set { /* Get GPIO value */ #define EC_CMD_GPIO_GET 0x93 +/* Version 0 of input params and response */ struct ec_params_gpio_get { char name[32]; } __packed; @@ -1774,6 +1775,38 @@ struct ec_response_gpio_get { uint8_t val; } __packed; +/* Version 1 of input params and response */ +struct ec_params_gpio_get_v1 { + uint8_t subcmd; + union { + struct { + char name[32]; + } get_value_by_name; + struct { + uint8_t index; + } get_info; + }; +} __packed; + +struct ec_response_gpio_get_v1 { + union { + struct { + uint8_t val; + } get_value_by_name, get_count; + struct { + uint8_t val; + char name[32]; + uint32_t flags; + } get_info; + }; +} __packed; + +enum gpio_get_subcmd { + EC_GPIO_GET_BY_NAME = 0, + EC_GPIO_GET_COUNT = 1, + EC_GPIO_GET_INFO = 2, +}; + /*****************************************************************************/ /* I2C commands. Only available when flash write protect is unlocked. */ diff --git a/util/ectool.c b/util/ectool.c index 1a1e5d5a43..b9da55fada 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -3157,26 +3157,102 @@ static int cmd_charge_state(int argc, char **argv) int cmd_gpio_get(int argc, char *argv[]) { - struct ec_params_gpio_get p; - struct ec_response_gpio_get r; - int rv; + struct ec_params_gpio_get_v1 p_v1; + struct ec_response_gpio_get_v1 r_v1; + int i, rv, subcmd, num_gpios; + int cmdver = 1; - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return -1; + if (!ec_cmd_version_supported(EC_CMD_GPIO_GET, cmdver)) { + struct ec_params_gpio_get p; + struct ec_response_gpio_get r; + + /* Fall back to version 0 command */ + cmdver = 0; + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + + if (strlen(argv[1]) + 1 > sizeof(p.name)) { + fprintf(stderr, "GPIO name too long.\n"); + return -1; + } + strcpy(p.name, argv[1]); + + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p, + sizeof(p), &r, sizeof(r)); + if (rv < 0) + return rv; + + printf("GPIO %s = %d\n", p.name, r.val); + return 0; } - if (strlen(argv[1]) + 1 > sizeof(p.name)) { - fprintf(stderr, "GPIO name too long.\n"); + if (argc > 2 || (argc == 2 && !strcmp(argv[1], "help"))) { + printf("Usage: %s [ ]\n", argv[0]); + printf("'gpioget ' - Get value by name\n"); + printf("'gpioget count' - Get count of GPIOS\n"); + printf("'gpioget all' - Get info for all GPIOs\n"); return -1; } - strcpy(p.name, argv[1]); - rv = ec_command(EC_CMD_GPIO_GET, 0, &p, sizeof(p), &r, sizeof(r)); + /* Keeping it consistent with console command behavior */ + if (argc == 1) + subcmd = EC_GPIO_GET_INFO; + else if (!strcmp(argv[1], "count")) + subcmd = EC_GPIO_GET_COUNT; + else if (!strcmp(argv[1], "all")) + subcmd = EC_GPIO_GET_INFO; + else + subcmd = EC_GPIO_GET_BY_NAME; + + if (subcmd == EC_GPIO_GET_BY_NAME) { + p_v1.subcmd = EC_GPIO_GET_BY_NAME; + if (strlen(argv[1]) + 1 > sizeof(p_v1.get_value_by_name.name)) { + fprintf(stderr, "GPIO name too long.\n"); + return -1; + } + strcpy(p_v1.get_value_by_name.name, argv[1]); + + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, + sizeof(p_v1), &r_v1, sizeof(r_v1)); + + if (rv < 0) + return rv; + + printf("GPIO %s = %d\n", p_v1.get_value_by_name.name, + r_v1.get_value_by_name.val); + return 0; + } + + /* Need GPIO count for EC_GPIO_GET_COUNT or EC_GPIO_GET_INFO */ + p_v1.subcmd = EC_GPIO_GET_COUNT; + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, + sizeof(p_v1), &r_v1, sizeof(r_v1)); if (rv < 0) return rv; - printf("GPIO %s = %d\n", p.name, r.val); + if (subcmd == EC_GPIO_GET_COUNT) { + printf("GPIO COUNT = %d\n", r_v1.get_count.val); + return 0; + } + + /* subcmd EC_GPIO_GET_INFO */ + num_gpios = r_v1.get_count.val; + p_v1.subcmd = EC_GPIO_GET_INFO; + + for (i = 0; i < num_gpios; i++) { + p_v1.get_info.index = i; + + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, + sizeof(p_v1), &r_v1, sizeof(r_v1)); + if (rv < 0) + return rv; + + printf("%2d %-32s 0x%04X\n", r_v1.get_info.val, + r_v1.get_info.name, r_v1.get_info.flags); + } + return 0; } -- cgit v1.2.1