summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/74x164_gpio.c193
-rw-r--r--drivers/gpio/Kconfig30
-rw-r--r--drivers/gpio/Makefile3
-rw-r--r--drivers/gpio/gpio-uclass.c30
-rw-r--r--drivers/gpio/intel_broadwell_gpio.c10
-rw-r--r--drivers/gpio/omap_gpio.c11
-rw-r--r--drivers/gpio/pca953x_gpio.c351
-rw-r--r--drivers/gpio/pic32_gpio.c10
-rw-r--r--drivers/gpio/rk_gpio.c11
-rw-r--r--drivers/gpio/s5p_gpio.c11
10 files changed, 600 insertions, 60 deletions
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
new file mode 100644
index 0000000000..9ac10a745d
--- /dev/null
+++ b/drivers/gpio/74x164_gpio.c
@@ -0,0 +1,193 @@
+/*
+ * Take drivers/gpio/gpio-74x164.c as reference.
+ *
+ * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct gen_74x164_chip - Data for 74Hx164
+ *
+ * @oe: OE pin
+ * @nregs: number of registers
+ * @buffer: buffer for chained chips
+ */
+#define GEN_74X164_NUMBER_GPIOS 8
+
+struct gen_74x164_priv {
+ struct gpio_desc oe;
+ u32 nregs;
+ /*
+ * Since the nregs are chained, every byte sent will make
+ * the previous byte shift to the next register in the
+ * chain. Thus, the first byte sent will end up in the last
+ * register at the end of the transfer. So, to have a logical
+ * numbering, store the bytes in reverse order.
+ */
+ u8 *buffer;
+};
+
+static int gen_74x164_write_conf(struct udevice *dev)
+{
+ struct gen_74x164_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_spi_claim_bus(dev);
+ if (ret)
+ return ret;
+
+ ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL,
+ SPI_XFER_BEGIN | SPI_XFER_END);
+
+ dm_spi_release_bus(dev);
+
+ return ret;
+}
+
+static int gen_74x164_get_value(struct udevice *dev, unsigned offset)
+{
+ struct gen_74x164_priv *priv = dev_get_priv(dev);
+ uint bank = priv->nregs - 1 - offset / 8;
+ uint pin = offset % 8;
+
+ return (priv->buffer[bank] >> pin) & 0x1;
+}
+
+static int gen_74x164_set_value(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct gen_74x164_priv *priv = dev_get_priv(dev);
+ uint bank = priv->nregs - 1 - offset / 8;
+ uint pin = offset % 8;
+ int ret;
+
+ if (value)
+ priv->buffer[bank] |= 1 << pin;
+ else
+ priv->buffer[bank] &= ~(1 << pin);
+
+ ret = gen_74x164_write_conf(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int gen_74x164_direction_input(struct udevice *dev, unsigned offset)
+{
+ return -ENOSYS;
+}
+
+static int gen_74x164_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ return gen_74x164_set_value(dev, offset, value);
+}
+
+static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
+{
+ return GPIOF_OUTPUT;
+}
+
+static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+{
+ desc->offset = args->args[0];
+ desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops gen_74x164_ops = {
+ .direction_input = gen_74x164_direction_input,
+ .direction_output = gen_74x164_direction_output,
+ .get_value = gen_74x164_get_value,
+ .set_value = gen_74x164_set_value,
+ .get_function = gen_74x164_get_function,
+ .xlate = gen_74x164_xlate,
+};
+
+static int gen_74x164_probe(struct udevice *dev)
+{
+ struct gen_74x164_priv *priv = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ char *str, name[32];
+ int ret;
+ const void *fdt = gd->fdt_blob;
+ int node = dev->of_offset;
+
+ snprintf(name, sizeof(name), "%s_", dev->name);
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+
+ /*
+ * See Linux kernel:
+ * Documentation/devicetree/bindings/gpio/gpio-74x164.txt
+ */
+ priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1);
+ priv->buffer = calloc(priv->nregs, sizeof(u8));
+ if (!priv->buffer) {
+ ret = -ENOMEM;
+ goto free_str;
+ }
+
+ ret = fdtdec_get_byte_array(fdt, node, "registers-default",
+ priv->buffer, priv->nregs);
+ if (ret)
+ dev_dbg(dev, "No registers-default property\n");
+
+ ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret) {
+ dev_err(dev, "No oe-pins property\n");
+ goto free_buf;
+ }
+
+ uc_priv->bank_name = str;
+ uc_priv->gpio_count = priv->nregs * 8;
+
+ ret = gen_74x164_write_conf(dev);
+ if (ret)
+ goto free_buf;
+
+ dev_dbg(dev, "%s is ready\n", dev->name);
+
+ return 0;
+
+free_buf:
+ free(priv->buffer);
+free_str:
+ free(str);
+ return ret;
+}
+
+static const struct udevice_id gen_74x164_ids[] = {
+ { .compatible = "fairchild,74hc595" },
+ { }
+};
+
+U_BOOT_DRIVER(74x164) = {
+ .name = "74x164",
+ .id = UCLASS_GPIO,
+ .ops = &gen_74x164_ops,
+ .probe = gen_74x164_probe,
+ .priv_auto_alloc_size = sizeof(struct gen_74x164_priv),
+ .of_match = gen_74x164_ids,
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2b4624d7f8..93a7e8c6c2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -143,4 +143,34 @@ config ZYNQ_GPIO
help
Supports GPIO access on Zynq SoC.
+config DM_74X164
+ bool "74x164 serial-in/parallel-out 8-bits shift register"
+ depends on DM_GPIO
+ help
+ Driver for 74x164 compatible serial-in/parallel-out 8-outputs
+ shift registers, such as 74lv165, 74hc595.
+ This driver can be used to provide access to more gpio outputs.
+
+config DM_PCA953X
+ bool "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports"
+ depends on DM_GPIO
+ help
+ Say yes here to provide access to several register-oriented
+ SMBus I/O expanders, made mostly by NXP or TI. Compatible
+ models include:
+
+ 4 bits: pca9536, pca9537
+
+ 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554,
+ pca9556, pca9557, pca9574, tca6408, xra1202
+
+ 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575,
+ tca6416
+
+ 24 bits: tca6424
+
+ 40 bits: pca9505, pca9698
+
+ Now, max 24 bits chips and PCA953X compatible chips are
+ supported
endmenu
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 4f071c4517..ddec1ef8de 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -11,6 +11,9 @@ obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
endif
obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
+obj-$(CONFIG_DM_PCA953X) += pca953x_gpio.o
+obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
+
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index b58d4e64e8..732b6c2afa 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
+#include <dt-bindings/gpio/gpio.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
@@ -113,19 +114,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
return 0;
}
+int gpio_xlate_offs_flags(struct udevice *dev,
+ struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+{
+ if (args->args_count < 1)
+ return -EINVAL;
+
+ desc->offset = args->args[0];
+
+ if (args->args_count < 2)
+ return 0;
+
+ if (args->args[1] & GPIO_ACTIVE_LOW)
+ desc->flags = GPIOD_ACTIVE_LOW;
+
+ return 0;
+}
+
static int gpio_find_and_xlate(struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
- /* Use the first argument as the offset by default */
- if (args->args_count > 0)
- desc->offset = args->args[0];
+ if (ops->xlate)
+ return ops->xlate(desc->dev, desc, args);
else
- desc->offset = -1;
- desc->flags = 0;
-
- return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+ return gpio_xlate_offs_flags(desc->dev, desc, args);
}
int dm_gpio_request(struct gpio_desc *desc, const char *label)
@@ -605,6 +620,7 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
desc->dev = NULL;
desc->offset = 0;
+ desc->flags = 0;
ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
"#gpio-cells", 0, index, &args);
if (ret) {
diff --git a/drivers/gpio/intel_broadwell_gpio.c b/drivers/gpio/intel_broadwell_gpio.c
index 8cf76f96c2..81ce446e1a 100644
--- a/drivers/gpio/intel_broadwell_gpio.c
+++ b/drivers/gpio/intel_broadwell_gpio.c
@@ -162,15 +162,6 @@ static int broadwell_gpio_ofdata_to_platdata(struct udevice *dev)
return 0;
}
-static int broadwell_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
-{
- desc->offset = args->args[0];
- desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
- return 0;
-}
-
static const struct dm_gpio_ops gpio_broadwell_ops = {
.request = broadwell_gpio_request,
.direction_input = broadwell_gpio_direction_input,
@@ -178,7 +169,6 @@ static const struct dm_gpio_ops gpio_broadwell_ops = {
.get_value = broadwell_gpio_get_value,
.set_value = broadwell_gpio_set_value,
.get_function = broadwell_gpio_get_function,
- .xlate = broadwell_gpio_xlate,
};
static const struct udevice_id intel_broadwell_gpio_ids[] = {
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 93d18e44a5..cd960dc013 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -25,7 +25,6 @@
#include <asm/io.h>
#include <asm/errno.h>
#include <malloc.h>
-#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -277,22 +276,12 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
-static int omap_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
-{
- desc->offset = args->args[0];
- desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
- return 0;
-}
-
static const struct dm_gpio_ops gpio_omap_ops = {
.direction_input = omap_gpio_direction_input,
.direction_output = omap_gpio_direction_output,
.get_value = omap_gpio_get_value,
.set_value = omap_gpio_set_value,
.get_function = omap_gpio_get_function,
- .xlate = omap_gpio_xlate,
};
static int omap_gpio_probe(struct udevice *dev)
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
new file mode 100644
index 0000000000..987d10e967
--- /dev/null
+++ b/drivers/gpio/pca953x_gpio.c
@@ -0,0 +1,351 @@
+/*
+ * Take linux kernel driver drivers/gpio/gpio-pca953x.c for reference.
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+/*
+ * Note:
+ * The driver's compatible table is borrowed from Linux Kernel,
+ * but now max supported gpio pins is 24 and only PCA953X_TYPE
+ * is supported. PCA957X_TYPE is not supported now.
+ * Also the Polarity Inversion feature is not supported now.
+ *
+ * TODO:
+ * 1. Support PCA957X_TYPE
+ * 2. Support max 40 gpio pins
+ * 3. Support Plolarity Inversion
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define PCA953X_INPUT 0
+#define PCA953X_OUTPUT 1
+#define PCA953X_INVERT 2
+#define PCA953X_DIRECTION 3
+
+#define PCA_GPIO_MASK 0x00FF
+#define PCA_INT 0x0100
+#define PCA953X_TYPE 0x1000
+#define PCA957X_TYPE 0x2000
+#define PCA_TYPE_MASK 0xF000
+#define PCA_CHIP_TYPE(x) ((x) & PCA_TYPE_MASK)
+
+enum {
+ PCA953X_DIRECTION_IN,
+ PCA953X_DIRECTION_OUT,
+};
+
+#define MAX_BANK 3
+#define BANK_SZ 8
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct pca953x_info - Data for pca953x
+ *
+ * @dev: udevice structure for the device
+ * @addr: i2c slave address
+ * @invert: Polarity inversion or not
+ * @gpio_count: the number of gpio pins that the device supports
+ * @chip_type: indicate the chip type,PCA953X or PCA957X
+ * @bank_count: the number of banks that the device supports
+ * @reg_output: array to hold the value of output registers
+ * @reg_direction: array to hold the value of direction registers
+ */
+struct pca953x_info {
+ struct udevice *dev;
+ int addr;
+ int invert;
+ int gpio_count;
+ int chip_type;
+ int bank_count;
+ u8 reg_output[MAX_BANK];
+ u8 reg_direction[MAX_BANK];
+};
+
+static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
+ int offset)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+ int off = offset / BANK_SZ;
+ int ret = 0;
+
+ ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
+ if (ret) {
+ dev_err(dev, "%s error\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
+ int offset)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+ int off = offset / BANK_SZ;
+ int ret;
+ u8 byte;
+
+ ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
+ if (ret) {
+ dev_err(dev, "%s error\n", __func__);
+ return ret;
+ }
+
+ *val = byte;
+
+ return 0;
+}
+
+static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ int ret = 0;
+
+ if (info->gpio_count <= 8) {
+ ret = dm_i2c_read(dev, reg, val, 1);
+ } else if (info->gpio_count <= 16) {
+ ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
+ } else {
+ dev_err(dev, "Unsupported now\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int pca953x_is_output(struct udevice *dev, int offset)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+
+ int bank = offset / BANK_SZ;
+ int off = offset % BANK_SZ;
+
+ /*0: output; 1: input */
+ return !(info->reg_direction[bank] & (1 << off));
+}
+
+static int pca953x_get_value(struct udevice *dev, unsigned offset)
+{
+ int ret;
+ u8 val = 0;
+
+ ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
+ if (ret)
+ return ret;
+
+ return (val >> offset) & 0x1;
+}
+
+static int pca953x_set_value(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ int bank = offset / BANK_SZ;
+ int off = offset % BANK_SZ;
+ u8 val;
+ int ret;
+
+ if (value)
+ val = info->reg_output[bank] | (1 << off);
+ else
+ val = info->reg_output[bank] & ~(1 << off);
+
+ ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
+ if (ret)
+ return ret;
+
+ info->reg_output[bank] = val;
+
+ return 0;
+}
+
+static int pca953x_set_direction(struct udevice *dev, unsigned offset, int dir)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ int bank = offset / BANK_SZ;
+ int off = offset % BANK_SZ;
+ u8 val;
+ int ret;
+
+ if (dir == PCA953X_DIRECTION_IN)
+ val = info->reg_direction[bank] | (1 << off);
+ else
+ val = info->reg_direction[bank] & ~(1 << off);
+
+ ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
+ if (ret)
+ return ret;
+
+ info->reg_direction[bank] = val;
+
+ return 0;
+}
+
+static int pca953x_direction_input(struct udevice *dev, unsigned offset)
+{
+ return pca953x_set_direction(dev, offset, PCA953X_DIRECTION_IN);
+}
+
+static int pca953x_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ /* Configure output value. */
+ pca953x_set_value(dev, offset, value);
+
+ /* Configure direction as output. */
+ pca953x_set_direction(dev, offset, PCA953X_DIRECTION_OUT);
+
+ return 0;
+}
+
+static int pca953x_get_function(struct udevice *dev, unsigned offset)
+{
+ if (pca953x_is_output(dev, offset))
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+}
+
+static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+{
+ desc->offset = args->args[0];
+ desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops pca953x_ops = {
+ .direction_input = pca953x_direction_input,
+ .direction_output = pca953x_direction_output,
+ .get_value = pca953x_get_value,
+ .set_value = pca953x_set_value,
+ .get_function = pca953x_get_function,
+ .xlate = pca953x_xlate,
+};
+
+static int pca953x_probe(struct udevice *dev)
+{
+ struct pca953x_info *info = dev_get_platdata(dev);
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+ char name[32], *str;
+ int addr;
+ ulong driver_data;
+ int ret;
+
+ if (!info) {
+ dev_err(dev, "platdata not ready\n");
+ return -ENOMEM;
+ }
+
+ if (!chip) {
+ dev_err(dev, "i2c not ready\n");
+ return -ENODEV;
+ }
+
+ addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+ if (addr == 0)
+ return -ENODEV;
+
+ info->addr = addr;
+
+ driver_data = dev_get_driver_data(dev);
+
+ info->gpio_count = driver_data & PCA_GPIO_MASK;
+ if (info->gpio_count > MAX_BANK * BANK_SZ) {
+ dev_err(dev, "Max support %d pins now\n", MAX_BANK * BANK_SZ);
+ return -EINVAL;
+ }
+
+ info->chip_type = PCA_CHIP_TYPE(driver_data);
+ if (info->chip_type != PCA953X_TYPE) {
+ dev_err(dev, "Only support PCA953X chip type now.\n");
+ return -EINVAL;
+ }
+
+ info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
+
+ ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
+ if (ret) {
+ dev_err(dev, "Error reading output register\n");
+ return ret;
+ }
+
+ ret = pca953x_read_regs(dev, PCA953X_DIRECTION, info->reg_direction);
+ if (ret) {
+ dev_err(dev, "Error reading direction register\n");
+ return ret;
+ }
+
+ snprintf(name, sizeof(name), "gpio@%x_", info->addr);
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ uc_priv->bank_name = str;
+ uc_priv->gpio_count = info->gpio_count;
+
+ dev_dbg(dev, "%s is ready\n", str);
+
+ return 0;
+}
+
+#define OF_953X(__nrgpio, __int) (ulong)(__nrgpio | PCA953X_TYPE | __int)
+#define OF_957X(__nrgpio, __int) (ulong)(__nrgpio | PCA957X_TYPE | __int)
+
+static const struct udevice_id pca953x_ids[] = {
+ { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
+ { .compatible = "nxp,pca9534", .data = OF_953X(8, PCA_INT), },
+ { .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "nxp,pca9536", .data = OF_953X(4, 0), },
+ { .compatible = "nxp,pca9537", .data = OF_953X(4, PCA_INT), },
+ { .compatible = "nxp,pca9538", .data = OF_953X(8, PCA_INT), },
+ { .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "nxp,pca9554", .data = OF_953X(8, PCA_INT), },
+ { .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "nxp,pca9556", .data = OF_953X(8, 0), },
+ { .compatible = "nxp,pca9557", .data = OF_953X(8, 0), },
+ { .compatible = "nxp,pca9574", .data = OF_957X(8, PCA_INT), },
+ { .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
+ { .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
+
+ { .compatible = "maxim,max7310", .data = OF_953X(8, 0), },
+ { .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "maxim,max7315", .data = OF_953X(8, PCA_INT), },
+
+ { .compatible = "ti,pca6107", .data = OF_953X(8, PCA_INT), },
+ { .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
+ { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
+ { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
+
+ { .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
+
+ { .compatible = "exar,xra1202", .data = OF_953X(8, 0), },
+ { }
+};
+
+U_BOOT_DRIVER(pca953x) = {
+ .name = "pca953x",
+ .id = UCLASS_GPIO,
+ .ops = &pca953x_ops,
+ .probe = pca953x_probe,
+ .platdata_auto_alloc_size = sizeof(struct pca953x_info),
+ .of_match = pca953x_ids,
+};
diff --git a/drivers/gpio/pic32_gpio.c b/drivers/gpio/pic32_gpio.c
index 499b4fa5ad..7a037f3a77 100644
--- a/drivers/gpio/pic32_gpio.c
+++ b/drivers/gpio/pic32_gpio.c
@@ -12,7 +12,6 @@
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/compat.h>
-#include <dt-bindings/gpio/gpio.h>
#include <mach/pic32.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,14 +98,6 @@ static int pic32_gpio_direction_output(struct udevice *dev,
return 0;
}
-static int pic32_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
-{
- desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
- return 0;
-}
-
static int pic32_gpio_get_function(struct udevice *dev, unsigned offset)
{
int ret = GPIOF_UNUSED;
@@ -131,7 +122,6 @@ static const struct dm_gpio_ops gpio_pic32_ops = {
.get_value = pic32_gpio_get_value,
.set_value = pic32_gpio_set_value,
.get_function = pic32_gpio_get_function,
- .xlate = pic32_gpio_xlate,
};
static int pic32_gpio_probe(struct udevice *dev)
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 40e87bd199..fefe3ca203 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -16,7 +16,6 @@
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <dm/pinctrl.h>
-#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/rk3288-cru.h>
enum {
@@ -98,15 +97,6 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
#endif
}
-static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
-{
- desc->offset = args->args[0];
- desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
- return 0;
-}
-
static int rockchip_gpio_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
@@ -135,7 +125,6 @@ static const struct dm_gpio_ops gpio_rockchip_ops = {
.get_value = rockchip_gpio_get_value,
.set_value = rockchip_gpio_set_value,
.get_function = rockchip_gpio_get_function,
- .xlate = rockchip_gpio_xlate,
};
static const struct udevice_id rockchip_gpio_ids[] = {
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 0f22b238ba..377fed467f 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -13,7 +13,6 @@
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm/device-internal.h>
-#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -276,22 +275,12 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_FUNC;
}
-static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
-{
- desc->offset = args->args[0];
- desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
- return 0;
-}
-
static const struct dm_gpio_ops gpio_exynos_ops = {
.direction_input = exynos_gpio_direction_input,
.direction_output = exynos_gpio_direction_output,
.get_value = exynos_gpio_get_value,
.set_value = exynos_gpio_set_value,
.get_function = exynos_gpio_get_function,
- .xlate = exynos_gpio_xlate,
};
static int gpio_exynos_probe(struct udevice *dev)
OpenPOWER on IntegriCloud