gpio: pcf857x: Implement get_multiple/set_multiple methods
v2 cover gpio: pcf857x: Implement get_multiple/set_multiple methods
The first two patches are just cosmetic changes. The actual changes are in the third patch. They are all bundled together in a patch series just because the third patch doesn't apply cleanly without the other two.
Change description from the third patch:
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.
Radu Rendec (3):
gpio: pcf857x: Replace 'unsigned' with 'unsigned int'
gpio: pcf857x: Fix indentation of variable declarations
gpio: pcf857x: Implement get_multiple/set_multiple methods
drivers/gpio/gpio-pcf857x.c | 79 +++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 25 deletions(-)
Signature · 1 line
2.39.0
PATCH v2 1/3 gpio: pcf857x: Replace 'unsigned' with 'unsigned int'
Cosmetic change only to improve the coding style. No functional change, since 'unsigned' and 'unsigned int' are identical as far as the compiler is concerned.
--- drivers/gpio/gpio-pcf857x.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/gpio/gpio-pcf857x.c +11 -11
@@ -73,11 +73,11 @@ struct pcf857x {struct gpio_chip chip;struct i2c_client *client;struct mutex lock;/* protect 'out' */ -unsigned out;/* software latch */ -unsigned status;/* current status */ -unsigned irq_enabled;/* enabled irqs */ +unsigned int out;/* software latch */ +unsigned int status;/* current status */ +unsigned int irq_enabled;/* enabled irqs */ -int (*write)(struct i2c_client *client,unsigned data); +int (*write)(struct i2c_client *client,unsigned int data);int (*read)(struct i2c_client *client); };
@@ -85,7 +85,7 @@ struct pcf857x {/* Talk to 8-bit I/O expander */ -static int i2c_write_le8 (struct i2c_client *client,unsigned data) +static int i2c_write_le8 (struct i2c_client *client,unsigned int data) {return i2c_smbus_write_byte (client, data); }
@@ -97,7 +97,7 @@ static int i2c_read_le8(struct i2c_client *client)/* Talk to 16-bit I/O expander */ -static int i2c_write_le16 (struct i2c_client *client,unsigned word) +static int i2c_write_le16 (struct i2c_client *client,unsigned int word) {u8 buf[2 ] = { word &0xff , word >>8 , };int status;
@@ -119,7 +119,7 @@ static int i2c_read_le16(struct i2c_client *client)/*-------------------------------------------------------------------------*/ -static int pcf857x_input (struct gpio_chip *chip,unsigned offset) +static int pcf857x_input (struct gpio_chip *chip,unsigned int offset) {struct pcf857x *gpio =gpiochip_get_data (chip);int status;
@@ -132,7 +132,7 @@ static int pcf857x_input(struct gpio_chip *chip, unsigned offset)return status; } -static int pcf857x_get (struct gpio_chip *chip,unsigned offset) +static int pcf857x_get (struct gpio_chip *chip,unsigned int offset) {struct pcf857x *gpio =gpiochip_get_data (chip);int value;
@@ -141,10 +141,10 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned offset)return (value <0 ) ? value : !!(value & (1 << offset)); } -static int pcf857x_output (struct gpio_chip *chip,unsigned offset,int value) +static int pcf857x_output (struct gpio_chip *chip,unsigned int offset,int value) {struct pcf857x *gpio =gpiochip_get_data (chip); -unsigned bit =1 << offset; +unsigned int bit =1 << offset;int status;mutex_lock (&gpio->lock);
@@ -158,7 +158,7 @@ static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value)return status; } -static void pcf857x_set (struct gpio_chip *chip,unsigned offset,int value) +static void pcf857x_set (struct gpio_chip *chip,unsigned int offset,int value) {pcf857x_output (chip, offset, value); }
Signature · 1 line
2.39.0
PATCH v2 2/3 gpio: pcf857x: Fix indentation of variable declarations
In reply to Radu RendecNo functional changes. This is a whitespace change only.
--- drivers/gpio/gpio-pcf857x.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/gpio/gpio-pcf857x.c +15 -15
@@ -121,8 +121,8 @@ static int i2c_read_le16(struct i2c_client *client)static int pcf857x_input (struct gpio_chip *chip,unsigned int offset) { -struct pcf857x *gpio =gpiochip_get_data (chip); -int status; +struct pcf857x *gpio =gpiochip_get_data (chip); +int status;mutex_lock (&gpio->lock); gpio->out |= (1 << offset);
@@ -134,8 +134,8 @@ static int pcf857x_input(struct gpio_chip *chip, unsigned int offset)static int pcf857x_get (struct gpio_chip *chip,unsigned int offset) { -struct pcf857x *gpio =gpiochip_get_data (chip); -int value; +struct pcf857x *gpio =gpiochip_get_data (chip); +int value; value = gpio->read (gpio->client);return (value <0 ) ? value : !!(value & (1 << offset));
@@ -143,9 +143,9 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned int offset)static int pcf857x_output (struct gpio_chip *chip,unsigned int offset,int value) { -struct pcf857x *gpio =gpiochip_get_data (chip); -unsigned int bit =1 << offset; -int status; +struct pcf857x *gpio =gpiochip_get_data (chip); +unsigned int bit =1 << offset; +int status;mutex_lock (&gpio->lock);if (value)
@@ -167,7 +167,7 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned int offset, int value)static irqreturn_t pcf857x_irq (int irq,void *data) { -struct pcf857x *gpio = data; +struct pcf857x *gpio = data;unsigned long change, i, status; status = gpio->read (gpio->client);
@@ -250,11 +250,11 @@ static const struct irq_chip pcf857x_irq_chip = {static int pcf857x_probe (struct i2c_client *client) {const struct i2c_device_id *id =i2c_client_get_device_id (client); -struct pcf857x_platform_data *pdata =dev_get_platdata (&client->dev); -struct device_node *np = client->dev.of_node; -struct pcf857x *gpio; -unsigned int n_latch =0 ; -int status; +struct pcf857x_platform_data *pdata =dev_get_platdata (&client->dev); +struct device_node *np = client->dev.of_node; +struct pcf857x *gpio; +unsigned int n_latch =0 ; +int status;if (IS_ENABLED (CONFIG_OF ) && np)of_property_read_u32 (np,"lines-initial-states" , &n_latch);
@@ -401,8 +401,8 @@ static int pcf857x_probe(struct i2c_client *client)static void pcf857x_remove (struct i2c_client *client) { -struct pcf857x_platform_data *pdata =dev_get_platdata (&client->dev); -struct pcf857x *gpio =i2c_get_clientdata (client); +struct pcf857x_platform_data *pdata =dev_get_platdata (&client->dev); +struct pcf857x *gpio =i2c_get_clientdata (client);if (pdata && pdata->teardown) pdata->teardown(client, gpio->chip.base, gpio->chip.ngpio,
Signature · 1 line
2.39.0
PATCH v2 3/3 gpio: pcf857x: Implement get_multiple/set_multiple methods
In reply to Radu RendecThis 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.
--- drivers/gpio/gpio-pcf857x.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/gpio/gpio-pcf857x.c +29 -0
@@ -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;
Signature · 1 line
2.39.0
Bartosz Golaszewski
AppliedQuoted 18 lines · Radu Rendec
The first two patches are just cosmetic changes. The actual changes are in the third patch. They are all bundled together in a patch series just because the third patch doesn't apply cleanly without the other two.
Change description from the third patch:
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.
Radu Rendec (3):
gpio: pcf857x: Replace 'unsigned' with 'unsigned int'
gpio: pcf857x: Fix indentation of variable declarations
gpio: pcf857x: Implement get_multiple/set_multiple methods
Quoted 6 lines
drivers/gpio/gpio-pcf857x.c | 79 +++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 25 deletions(-)--
2.39.0
Applied, thanks!
Bart