Skip to content

Commit 64d2f45

Browse files
rrendecBartosz Golaszewski
authored andcommitted
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 <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 17a5f49 commit 64d2f45

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

drivers/gpio/gpio-pcf857x.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned int offset)
141141
return (value < 0) ? value : !!(value & (1 << offset));
142142
}
143143

144+
static int pcf857x_get_multiple(struct gpio_chip *chip, unsigned long *mask,
145+
unsigned long *bits)
146+
{
147+
struct pcf857x *gpio = gpiochip_get_data(chip);
148+
int value = gpio->read(gpio->client);
149+
150+
if (value < 0)
151+
return value;
152+
153+
*bits &= ~*mask;
154+
*bits |= value & *mask;
155+
156+
return 0;
157+
}
158+
144159
static int pcf857x_output(struct gpio_chip *chip, unsigned int offset, int value)
145160
{
146161
struct pcf857x *gpio = gpiochip_get_data(chip);
@@ -163,6 +178,18 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned int offset, int value)
163178
pcf857x_output(chip, offset, value);
164179
}
165180

181+
static void pcf857x_set_multiple(struct gpio_chip *chip, unsigned long *mask,
182+
unsigned long *bits)
183+
{
184+
struct pcf857x *gpio = gpiochip_get_data(chip);
185+
186+
mutex_lock(&gpio->lock);
187+
gpio->out &= ~*mask;
188+
gpio->out |= *bits & *mask;
189+
gpio->write(gpio->client, gpio->out);
190+
mutex_unlock(&gpio->lock);
191+
}
192+
166193
/*-------------------------------------------------------------------------*/
167194

168195
static irqreturn_t pcf857x_irq(int irq, void *data)
@@ -275,7 +302,9 @@ static int pcf857x_probe(struct i2c_client *client)
275302
gpio->chip.parent = &client->dev;
276303
gpio->chip.owner = THIS_MODULE;
277304
gpio->chip.get = pcf857x_get;
305+
gpio->chip.get_multiple = pcf857x_get_multiple;
278306
gpio->chip.set = pcf857x_set;
307+
gpio->chip.set_multiple = pcf857x_set_multiple;
279308
gpio->chip.direction_input = pcf857x_input;
280309
gpio->chip.direction_output = pcf857x_output;
281310
gpio->chip.ngpio = id->driver_data;

0 commit comments

Comments
 (0)