@@ -5,6 +5,7 @@
* Copyright (C) 2007 David Brownell
*/
+#include <linux/delay.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -272,12 +273,11 @@ static const struct irq_chip pcf857x_irq_chip = {
static int pcf857x_probe(struct i2c_client *client)
{
+ struct gpio_desc *rstn_gpio;
struct pcf857x *gpio;
- unsigned int n_latch = 0;
+ unsigned int n_latch;
int status;
- device_property_read_u32(&client->dev, "lines-initial-states", &n_latch);
-
/* Allocate, initialize, and register this gpio_chip. */
gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
@@ -297,6 +297,29 @@ static int pcf857x_probe(struct i2c_client *client)
gpio->chip.direction_output = pcf857x_output;
gpio->chip.ngpio = (uintptr_t)i2c_get_match_data(client);
+ rstn_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(rstn_gpio)) {
+ return dev_err_probe(&client->dev, PTR_ERR(rstn_gpio),
+ "failed to get reset GPIO\n");
+ }
+
+ if (rstn_gpio) {
+ /* Reset already held with devm_gpiod_get_optional with GPIOD_OUT_HIGH */
+ usleep_range(4, 8); /* tw(rst) > 4us */
+ gpiod_set_value(rstn_gpio, 0);
+ usleep_range(100, 200); /* trst > 100uS */
+
+ /*
+ * Reset "will initialize to their default states of all I/Os to
+ * inputs with weak current source to VDD", which is the same as
+ * writing 1 for all I/Os which is 0 in n_latch.
+ */
+ n_latch = 0;
+ } else {
+ device_property_read_u32(&client->dev, "lines-initial-states",
+ &n_latch);
+ }
+
/* NOTE: the OnSemi jlc1562b is also largely compatible with
* these parts, notably for output. It has a low-resolution
* DAC instead of pin change IRQs; and its inputs can be the