aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-03-16 12:52:02 -0400
committerTom Rini <trini@konsulko.com>2022-03-16 12:52:02 -0400
commit297e6eb8dcf9d90aaf9b0d146cdd502403003d04 (patch)
treea08774cdaa4a72af892d4c7a57b3e1307734ad89 /drivers/gpio
parentc24b4e4fb8810b496e5f303ffd2641293f4c4b50 (diff)
parent0ac03fbab51c72fa978569a831c001c4ddad8e2a (diff)
downloadu-boot-297e6eb8dcf9d90aaf9b0d146cdd502403003d04.zip
u-boot-297e6eb8dcf9d90aaf9b0d146cdd502403003d04.tar.gz
u-boot-297e6eb8dcf9d90aaf9b0d146cdd502403003d04.tar.bz2
Merge tag 'xilinx-for-v2022.07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into nextWIP/16Mar2022-next
Xilinx changes for v2022.07-rc1 microblaze: - Add support for reserved memory xilinx: - Update FRU code with MAC reading zynqmp: - Remove double AMS setting - DT updates (mostly for SOMs) - Add support for zcu106 rev 1.0 zynq: - Update nand binding nand: - Aligned zynq_nand to upstream DT binding net: - Add support for ethernet-phy-id mmc: - Workaround CD in zynq_sdhci driver also for ZynqMP - Add support for dynamic/run-time SD config for SOMs gpio: - Add driver for slg7xl45106 firmware: - Add support for dynamic SD config power-domain: - Update zynqmp driver with the latest firmware video: - Add skeleton driver for DP and DPDMA i2c: - Fix i2c to work with QEMU pinctrl: - Add driver for zynqmp pinctrl driver
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio_slg7xl45106.c115
3 files changed, 124 insertions, 0 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 12972cd..c3f1109 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -558,4 +558,12 @@ config SL28CPLD_GPIO
help
Support GPIO access on Kontron sl28cpld board management controllers.
+config SLG7XL45106_I2C_GPO
+ bool "slg7xl45106 i2c gpo expander"
+ depends on DM_GPIO
+ help
+ Support for slg7xl45106 i2c gpo expander. It is an i2c based
+ 8-bit gpo expander, all gpo lines are controlled by writing
+ value into data register.
+
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 44f0153..b39dde1 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -73,3 +73,4 @@ obj-$(CONFIG_NOMADIK_GPIO) += nmk_gpio.o
obj-$(CONFIG_MAX7320_GPIO) += max7320_gpio.o
obj-$(CONFIG_SL28CPLD_GPIO) += sl28cpld-gpio.o
obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o
+obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o
diff --git a/drivers/gpio/gpio_slg7xl45106.c b/drivers/gpio/gpio_slg7xl45106.c
new file mode 100644
index 0000000..2cbf748
--- /dev/null
+++ b/drivers/gpio/gpio_slg7xl45106.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * slg7xl45106_i2c_gpo driver
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+
+#define SLG7XL45106_REG 0xdb
+
+static int slg7xl45106_i2c_gpo_direction_input(struct udevice *dev,
+ unsigned int offset)
+{
+ return 0;
+}
+
+static int slg7xl45106_i2c_gpo_xlate(struct udevice *dev,
+ struct gpio_desc *desc,
+ struct ofnode_phandle_args *args)
+{
+ desc->offset = (unsigned int)args->args[0];
+
+ return 0;
+}
+
+static int slg7xl45106_i2c_gpo_set_value(struct udevice *dev,
+ unsigned int offset, int value)
+{
+ int ret;
+ u8 val;
+
+ ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1);
+ if (ret)
+ return ret;
+
+ if (value)
+ val |= BIT(offset);
+ else
+ val &= ~BIT(offset);
+
+ return dm_i2c_write(dev, SLG7XL45106_REG, &val, 1);
+}
+
+static int slg7xl45106_i2c_gpo_direction_output(struct udevice *dev,
+ unsigned int offset, int value)
+{
+ return slg7xl45106_i2c_gpo_set_value(dev, offset, value);
+}
+
+static int slg7xl45106_i2c_gpo_get_value(struct udevice *dev,
+ unsigned int offset)
+{
+ int ret;
+ u8 val;
+
+ ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1);
+ if (ret)
+ return ret;
+
+ return !!(val & BIT(offset));
+}
+
+static int slg7xl45106_i2c_gpo_get_function(struct udevice *dev,
+ unsigned int offset)
+{
+ return GPIOF_OUTPUT;
+}
+
+static const struct dm_gpio_ops slg7xl45106_i2c_gpo_ops = {
+ .direction_input = slg7xl45106_i2c_gpo_direction_input,
+ .direction_output = slg7xl45106_i2c_gpo_direction_output,
+ .get_value = slg7xl45106_i2c_gpo_get_value,
+ .set_value = slg7xl45106_i2c_gpo_set_value,
+ .get_function = slg7xl45106_i2c_gpo_get_function,
+ .xlate = slg7xl45106_i2c_gpo_xlate,
+};
+
+static int slg7xl45106_i2c_gpo_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ const void *label_ptr;
+
+ label_ptr = dev_read_prop(dev, "label", NULL);
+ if (label_ptr) {
+ uc_priv->bank_name = strdup(label_ptr);
+ if (!uc_priv->bank_name)
+ return -ENOMEM;
+ } else {
+ uc_priv->bank_name = dev->name;
+ }
+
+ uc_priv->gpio_count = 8;
+
+ return 0;
+}
+
+static const struct udevice_id slg7xl45106_i2c_gpo_ids[] = {
+ { .compatible = "dlg,slg7xl45106",},
+ { }
+};
+
+U_BOOT_DRIVER(slg7xl45106_i2c_gpo) = {
+ .name = "slg7xl45106_i2c_gpo",
+ .id = UCLASS_GPIO,
+ .ops = &slg7xl45106_i2c_gpo_ops,
+ .of_match = slg7xl45106_i2c_gpo_ids,
+ .probe = slg7xl45106_i2c_gpo_probe,
+};