mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
gpio: pcf857x: Implement get_multiple/set_multiple methods
This change allows the GPIO core to read/change multiple pins in a single driver call and subsequent I2C transfer. It helps a lot with PCF857x devices, since their I2C protocol always reads/changes all existing pins anyway. Therefore, when the GPIO client code does a bulk operation on multiple pins, the driver makes a single I2C transfer. Signed-off-by: Radu Rendec <radu.rendec@gmail.com> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
parent
17a5f49b49
commit
64d2f4594e
1 changed files with 29 additions and 0 deletions
|
@ -141,6 +141,21 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned int offset)
|
|||
return (value < 0) ? value : !!(value & (1 << offset));
|
||||
}
|
||||
|
||||
static int pcf857x_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct pcf857x *gpio = gpiochip_get_data(chip);
|
||||
int value = gpio->read(gpio->client);
|
||||
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
*bits &= ~*mask;
|
||||
*bits |= value & *mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf857x_output(struct gpio_chip *chip, unsigned int offset, int value)
|
||||
{
|
||||
struct pcf857x *gpio = gpiochip_get_data(chip);
|
||||
|
@ -163,6 +178,18 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned int offset, int value)
|
|||
pcf857x_output(chip, offset, value);
|
||||
}
|
||||
|
||||
static void pcf857x_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct pcf857x *gpio = gpiochip_get_data(chip);
|
||||
|
||||
mutex_lock(&gpio->lock);
|
||||
gpio->out &= ~*mask;
|
||||
gpio->out |= *bits & *mask;
|
||||
gpio->write(gpio->client, gpio->out);
|
||||
mutex_unlock(&gpio->lock);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static irqreturn_t pcf857x_irq(int irq, void *data)
|
||||
|
@ -275,7 +302,9 @@ static int pcf857x_probe(struct i2c_client *client)
|
|||
gpio->chip.parent = &client->dev;
|
||||
gpio->chip.owner = THIS_MODULE;
|
||||
gpio->chip.get = pcf857x_get;
|
||||
gpio->chip.get_multiple = pcf857x_get_multiple;
|
||||
gpio->chip.set = pcf857x_set;
|
||||
gpio->chip.set_multiple = pcf857x_set_multiple;
|
||||
gpio->chip.direction_input = pcf857x_input;
|
||||
gpio->chip.direction_output = pcf857x_output;
|
||||
gpio->chip.ngpio = id->driver_data;
|
||||
|
|
Loading…
Reference in a new issue