]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpio/gpio-pca953x.c
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
[mirror_ubuntu-bionic-kernel.git] / drivers / gpio / gpio-pca953x.c
index d44232aadb6c2224301f45aa665af998e4aa9a4b..4c9e21300a262170499a4e009af3638b79536579 100644 (file)
  *  the Free Software Foundation; version 2 of the License.
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
-#include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
 #include <linux/platform_data/pca953x.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+
 #include <asm/unaligned.h>
-#include <linux/of_platform.h>
-#include <linux/acpi.h>
-#include <linux/regulator/consumer.h>
 
 #define PCA953X_INPUT          0
 #define PCA953X_OUTPUT         1
@@ -81,6 +82,7 @@ static const struct i2c_device_id pca953x_id[] = {
        { "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
        { "tca6424", 24 | PCA953X_TYPE | PCA_INT, },
        { "tca9539", 16 | PCA953X_TYPE | PCA_INT, },
+       { "tca9554", 8  | PCA953X_TYPE | PCA_INT, },
        { "xra1202", 8  | PCA953X_TYPE },
        { }
 };
@@ -363,6 +365,21 @@ exit:
        mutex_unlock(&chip->i2c_lock);
 }
 
+static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
+{
+       struct pca953x_chip *chip = gpiochip_get_data(gc);
+       u32 reg_val;
+       int ret;
+
+       mutex_lock(&chip->i2c_lock);
+       ret = pca953x_read_single(chip, chip->regs->direction, &reg_val, off);
+       mutex_unlock(&chip->i2c_lock);
+       if (ret < 0)
+               return ret;
+
+       return !!(reg_val & (1u << (off % BANK_SZ)));
+}
+
 static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
                                      unsigned long *mask, unsigned long *bits)
 {
@@ -408,6 +425,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
        gc->direction_output = pca953x_gpio_direction_output;
        gc->get = pca953x_gpio_get_value;
        gc->set = pca953x_gpio_set_value;
+       gc->get_direction = pca953x_gpio_get_direction;
        gc->set_multiple = pca953x_gpio_set_multiple;
        gc->can_sleep = true;
 
@@ -760,7 +778,13 @@ static int pca953x_probe(struct i2c_client *client,
                chip->gpio_start = -1;
                irq_base = 0;
 
-               /* See if we need to de-assert a reset pin */
+               /*
+                * See if we need to de-assert a reset pin.
+                *
+                * There is no known ACPI-enabled platforms that are
+                * using "reset" GPIO. Otherwise any of those platform
+                * must use _DSD method with corresponding property.
+                */
                reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
                                                     GPIOD_OUT_LOW);
                if (IS_ERR(reset_gpio))