From d46ab6823963de2165f5a2af7600ce830e990e53 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Mar 2016 16:19:18 +0100 Subject: [PATCH] gpio: 74x164: Implement gpiochip.set_multiple() This allows to set multiple outputs using a single SPI transfer. Signed-off-by: Geert Uytterhoeven Reviewed-by: Phil Reid Signed-off-by: Linus Walleij --- drivers/gpio/gpio-74x164.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index c81224ff2dca..62291a81c97f 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -75,6 +75,29 @@ static void gen_74x164_set_value(struct gpio_chip *gc, mutex_unlock(&chip->lock); } +static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + struct gen_74x164_chip *chip = gpiochip_get_data(gc); + unsigned int i, idx, shift; + u8 bank, bankmask; + + mutex_lock(&chip->lock); + for (i = 0, bank = chip->registers - 1; i < chip->registers; + i++, bank--) { + idx = i / sizeof(*mask); + shift = i % sizeof(*mask) * BITS_PER_BYTE; + bankmask = mask[idx] >> shift; + if (!bankmask) + continue; + + chip->buffer[bank] &= ~bankmask; + chip->buffer[bank] |= bankmask & (bits[idx] >> shift); + } + __gen_74x164_write_config(chip); + mutex_unlock(&chip->lock); +} + static int gen_74x164_direction_output(struct gpio_chip *gc, unsigned offset, int val) { @@ -114,6 +137,7 @@ static int gen_74x164_probe(struct spi_device *spi) chip->gpio_chip.direction_output = gen_74x164_direction_output; chip->gpio_chip.get = gen_74x164_get_value; chip->gpio_chip.set = gen_74x164_set_value; + chip->gpio_chip.set_multiple = gen_74x164_set_multiple; chip->gpio_chip.base = -1; chip->registers = nregs;