From 49b4c54bc969aae9a79e598266feec3d74275635 Mon Sep 17 00:00:00 2001 From: Tomas Novotny Date: Wed, 25 Nov 2020 18:42:16 +0100 Subject: [PATCH] gpio: tca642x: fix input subcommand for gpio banks > 0 The value of input pin for bank > 0 is always 0 for input subcommand. The reason is that gpio_bank variable is computed only for invert and output subcommands (it depends on number of arguments). The default value of zero causes to shift the mask away for banks > 0. Please note that info subcommand works as expected, because the input pin values are accessed differently. Fixes: 61c1775f16ed ("gpio: tca642x: Add the tca642x gpio expander driver") Cc: Dan Murphy Signed-off-by: Tomas Novotny --- drivers/gpio/tca642x.c | 49 ++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/tca642x.c b/drivers/gpio/tca642x.c index 463cfe879a..7007c7a002 100644 --- a/drivers/gpio/tca642x.c +++ b/drivers/gpio/tca642x.c @@ -213,6 +213,24 @@ static int tca642x_info(uchar chip) return 0; } +static int tca642x_get_bank(int pin) +{ + int gpio_bank; + + if (pin <= 7) { + gpio_bank = 0; + } else if ((pin >= 10) && (pin <= 17)) { + gpio_bank = 1; + } else if ((pin >= 20) && (pin <= 27)) { + gpio_bank = 2; + } else { + printf("Requested pin is not available\n"); + gpio_bank = -1; + } + + return gpio_bank; +} + static struct cmd_tbl cmd_tca642x[] = { U_BOOT_CMD_MKENT(device, 3, 0, (void *)TCA642X_CMD_DEVICE, "", ""), U_BOOT_CMD_MKENT(output, 4, 0, (void *)TCA642X_CMD_OUTPUT, "", ""), @@ -226,7 +244,7 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc, { static uchar chip = CONFIG_SYS_I2C_TCA642X_ADDR; int ret = CMD_RET_USAGE, val; - uint8_t gpio_bank = 0; + int gpio_bank = 0; uint8_t bank_shift; ulong ul_arg2 = 0; ulong ul_arg3 = 0; @@ -247,20 +265,8 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc, ul_arg2 = simple_strtoul(argv[2], NULL, 10); /* arg3 used as pin or invert value */ - if (argc > 3) { + if (argc > 3) ul_arg3 = simple_strtoul(argv[3], NULL, 10) & 0x1; - if (ul_arg2 <= 7) { - gpio_bank = 0; - } else if ((ul_arg2 >= 10) && (ul_arg2 <= 17)) { - gpio_bank = 1; - } else if ((ul_arg2 >= 20) && (ul_arg2 <= 27)) { - gpio_bank = 2; - } else { - printf("Requested pin is not available\n"); - ret = CMD_RET_FAILURE; - goto error; - } - } switch ((int)c->cmd) { case TCA642X_CMD_INFO: @@ -277,6 +283,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc, break; case TCA642X_CMD_INPUT: + gpio_bank = tca642x_get_bank(ul_arg2); + if (gpio_bank < 0) { + ret = CMD_RET_FAILURE; + goto error; + } bank_shift = ul_arg2 - (gpio_bank * 10); ret = tca642x_set_dir(chip, gpio_bank, (1 << bank_shift), TCA642X_DIR_IN << bank_shift); @@ -291,6 +302,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc, break; case TCA642X_CMD_OUTPUT: + gpio_bank = tca642x_get_bank(ul_arg2); + if (gpio_bank < 0) { + ret = CMD_RET_FAILURE; + goto error; + } bank_shift = ul_arg2 - (gpio_bank * 10); ret = tca642x_set_dir(chip, gpio_bank, (1 << bank_shift), (TCA642X_DIR_OUT << bank_shift)); @@ -303,6 +319,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc, break; case TCA642X_CMD_INVERT: + gpio_bank = tca642x_get_bank(ul_arg2); + if (gpio_bank < 0) { + ret = CMD_RET_FAILURE; + goto error; + } bank_shift = ul_arg2 - (gpio_bank * 10); ret = tca642x_set_pol(chip, gpio_bank, (1 << bank_shift), (ul_arg3 << bank_shift));