[PATCH v2] gpio: ftgpio010: Add support for Faraday Technology FTGPIO010

Add Faraday Technology's FTGPIO010 controller driver.
Signed-off-by: Sergei Antonov saproj@gmail.com --- v1 -> v2: Replace setbits_le32() with a simpler function out_le32(). Replace readl() with in_le32() to respect endianness.
drivers/gpio/Kconfig | 6 +++ drivers/gpio/Makefile | 1 + drivers/gpio/ftgpio010.c | 100 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 drivers/gpio/ftgpio010.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c949f9d2f7cc..2a60478b476a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -605,4 +605,10 @@ config TURRIS_OMNIA_MCU help Support for GPIOs on MCU connected to Turris Omnia via i2c.
+config FTGPIO010 + bool "Faraday Technology FTGPIO010 driver" + depends on DM_GPIO + help + Support for GPIOs on Faraday Technology's FTGPIO010 controller. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9d718a554e59..eee7908871d8 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -75,3 +75,4 @@ obj-$(CONFIG_SL28CPLD_GPIO) += sl28cpld-gpio.o obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU) += turris_omnia_mcu.o +obj-$(CONFIG_FTGPIO010) += ftgpio010.o diff --git a/drivers/gpio/ftgpio010.c b/drivers/gpio/ftgpio010.c new file mode 100644 index 000000000000..fa6b180963d3 --- /dev/null +++ b/drivers/gpio/ftgpio010.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Faraday Technology's FTGPIO010 controller. + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <asm/gpio.h> + +struct ftgpio010_regs { + u32 out; + u32 in; + u32 direction; + u32 reserved; + u32 set; + u32 clear; +}; + +struct ftgpio010_plat { + struct ftgpio010_regs __iomem *regs; +}; + +static int ftgpio010_direction_input(struct udevice *dev, unsigned int pin) +{ + struct ftgpio010_plat *plat = dev_get_plat(dev); + struct ftgpio010_regs *const regs = plat->regs; + + clrbits_le32(®s->direction, 1 << pin); + return 0; +} + +static int ftgpio010_direction_output(struct udevice *dev, unsigned int pin, + int val) +{ + struct ftgpio010_plat *plat = dev_get_plat(dev); + struct ftgpio010_regs *const regs = plat->regs; + + /* change the data first, then the direction. to avoid glitch */ + out_le32(val ? ®s->set : ®s->clear, 1 << pin); + setbits_le32(®s->direction, 1 << pin); + + return 0; +} + +static int ftgpio010_get_value(struct udevice *dev, unsigned int pin) +{ + struct ftgpio010_plat *plat = dev_get_plat(dev); + struct ftgpio010_regs *const regs = plat->regs; + + return in_le32(®s->in) >> pin & 1; +} + +static int ftgpio010_set_value(struct udevice *dev, unsigned int pin, int val) +{ + struct ftgpio010_plat *plat = dev_get_plat(dev); + struct ftgpio010_regs *const regs = plat->regs; + + out_le32(val ? ®s->set : ®s->clear, 1 << pin); + return 0; +} + +static int ftgpio010_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->gpio_count = ofnode_read_u32_default(dev_ofnode(dev), + "nr-gpios", 32); + return 0; +} + +static int ftgpio010_of_to_plat(struct udevice *dev) +{ + struct ftgpio010_plat *plat = dev_get_plat(dev); + + plat->regs = dev_read_addr_ptr(dev); + return 0; +} + +static const struct dm_gpio_ops ftgpio010_ops = { + .direction_input = ftgpio010_direction_input, + .direction_output = ftgpio010_direction_output, + .get_value = ftgpio010_get_value, + .set_value = ftgpio010_set_value, +}; + +static const struct udevice_id ftgpio010_ids[] = { + { .compatible = "faraday,ftgpio010" }, + { } +}; + +U_BOOT_DRIVER(ftgpio010) = { + .name = "ftgpio010", + .id = UCLASS_GPIO, + .of_match = ftgpio010_ids, + .ops = &ftgpio010_ops, + .of_to_plat = ftgpio010_of_to_plat, + .plat_auto = sizeof(struct ftgpio010_plat), + .probe = ftgpio010_probe, +};

On Sunday 04 September 2022 13:22:00 Sergei Antonov wrote:
Add Faraday Technology's FTGPIO010 controller driver.
Signed-off-by: Sergei Antonov saproj@gmail.com
v1 -> v2: Replace setbits_le32() with a simpler function out_le32(). Replace readl() with in_le32() to respect endianness.
drivers/gpio/Kconfig | 6 +++ drivers/gpio/Makefile | 1 + drivers/gpio/ftgpio010.c | 100 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 drivers/gpio/ftgpio010.c
Hello! I'm really not maintainer of ftgpio010.c driver, nor of gpio. So please do not send me emails about ftgpio010.c if you do not have really good reason. I'm getting tons of unrelated emails, so please do not spam me otherwise I would not be able to filter out those emails which are important and which I should review as maintainer.
participants (2)
-
Pali Rohár
-
Sergei Antonov