[PATCH 2/4] ath79: add GPIO-latch driver for Mikrotik RB91xG

Denis Kalashnikov denis281089 at gmail.com
Thu May 6 17:25:12 BST 2021


This driver exports GPIO lines on the latch that are not
used for NAND control lines (but used for data lines).
It doesn't request byself SoC gpio lines and set them
through API provided by rb91x-ngl. Exported lines are used
for power LED, user LED and nCS of the Shift Register.

Signed-off-by: Denis Kalashnikov <denis281089 at gmail.com>
---
 .../files/drivers/gpio/gpio-latch-rb91x.c     | 127 ++++++++++++++++++
 target/linux/ath79/mikrotik/config-default    |   1 +
 .../patches-5.4/939-mikrotik-rb91x.patch      |  23 ++++
 3 files changed, 151 insertions(+)
 create mode 100644 target/linux/ath79/files/drivers/gpio/gpio-latch-rb91x.c

diff --git a/target/linux/ath79/files/drivers/gpio/gpio-latch-rb91x.c b/target/linux/ath79/files/drivers/gpio/gpio-latch-rb91x.c
new file mode 100644
index 0000000000..f1ed8ebc96
--- /dev/null
+++ b/target/linux/ath79/files/drivers/gpio/gpio-latch-rb91x.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver of GPIO controller on a 8-bit NAND latch (LVC573) on MikroTik RB91x.
+ *
+ * Copyright (C) 2021 Denis Kalashnikov <denis281089 at gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <mfd/rb91x-ngl.h>
+
+#define DRIVER_NAME  "rb91x-gpio-latch"
+
+static int get(struct gpio_chip *gc, unsigned offset)
+{
+	return -ENOSYS;
+}
+
+static void set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct rb91x_ngl *ngl = gpiochip_get_data(gc);
+
+	ngl->latch_gpio_set_value(ngl, offset, value);
+}
+
+static int direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	return -ENOSYS;
+}
+
+static int direction_output(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct rb91x_ngl *ngl = gpiochip_get_data(gc);
+
+	ngl->latch_gpio_set_value(ngl, offset, value);
+
+	return 0;
+}
+
+static int probe(struct platform_device *pdev)
+{
+	struct gpio_chip *gc;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct device *dev = &pdev->dev, *parent = pdev->dev.parent;
+	struct rb91x_ngl *ngl;
+	int ret;
+	u32 val;
+
+	pr_info(DRIVER_NAME " driver probe\n");
+
+	if (!parent)
+		return -ENODEV;
+
+	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+	if (!gc)
+		return -ENOMEM;
+
+	/*
+	ret = of_property_read_u32(of_node, "base", &val);
+	if (ret < 0) {
+		dev_err(dev, "Could not read required 'base' property\n");
+		return -EINVAL;
+	}
+	pr_info(DRIVER_NAME ": base = %d\n", val);
+	gc->base = val;
+	*/
+	gc->base = -1; /* Request dynamic allocation */
+
+	ngl = dev_get_drvdata(parent);
+	if (!ngl) {
+		pr_err(DRIVER_NAME " ngl is null\n");
+		return -EINVAL;
+	}
+
+	gc->label = DRIVER_NAME;
+	gc->parent = dev;
+	gc->can_sleep = true;
+	gc->ngpio = ngl->latch_gpios_count(ngl);
+	gc->get = get;
+	gc->set = set;
+	gc->direction_input = direction_input,
+	gc->direction_output = direction_output;
+	gc->of_node = of_node;
+
+	platform_set_drvdata(pdev, gc);
+
+	ret = gpiochip_add_data(gc, ngl);
+	if (ret) {
+		pr_err(DRIVER_NAME ": failed to add gpio chip: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int remove(struct platform_device *pdev)
+{
+	gpiochip_remove(platform_get_drvdata(pdev));
+	return 0;
+}
+
+static const struct of_device_id match[] = {
+	{ .compatible = "mikrotik," DRIVER_NAME },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, match);
+
+static struct platform_driver rb91x_gpio_latch_driver = {
+	.probe = probe,
+	.remove = remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = match,
+	},
+};
+
+module_platform_driver(rb91x_gpio_latch_driver);
+
+MODULE_DESCRIPTION("Driver for GPIO on MikroTik RB91x NAND latch");
+MODULE_AUTHOR("Denis Kalashnikov <denis281089 at gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ath79/mikrotik/config-default b/target/linux/ath79/mikrotik/config-default
index 67c980a491..92b7824eba 100644
--- a/target/linux/ath79/mikrotik/config-default
+++ b/target/linux/ath79/mikrotik/config-default
@@ -1,6 +1,7 @@
 CONFIG_CRC16=y
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_GPIO_LATCH=y
+CONFIG_GPIO_LATCH_RB91X=y
 CONFIG_GPIO_RB4XX=y
 CONFIG_GPIO_WATCHDOG=y
 CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
diff --git a/target/linux/ath79/patches-5.4/939-mikrotik-rb91x.patch b/target/linux/ath79/patches-5.4/939-mikrotik-rb91x.patch
index a85db0892c..f2135d486b 100644
--- a/target/linux/ath79/patches-5.4/939-mikrotik-rb91x.patch
+++ b/target/linux/ath79/patches-5.4/939-mikrotik-rb91x.patch
@@ -19,3 +19,26 @@
  obj-$(CONFIG_MFD_RB4XX_CPLD)	+= rb4xx-cpld.o
 +
 +obj-$(CONFIG_MFD_RB91X_NGL)	+= rb91x-ngl.o
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -130,6 +130,10 @@ config GPIO_ATH79
+ 	  Select this option to enable GPIO driver for
+ 	  Atheros AR71XX/AR724X/AR913X SoC devices.
+ 
++config GPIO_LATCH_RB91X
++	tristate "Mikrotik RB91X GPIO latch driver"
++	depends on MFD_RB91X_NGL
++
+ config GPIO_RASPBERRYPI_EXP
+ 	tristate "Raspberry Pi 3 GPIO Expander"
+ 	default RASPBERRYPI_FIRMWARE
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_IT87)			+= gpio-it87.o
+ obj-$(CONFIG_GPIO_IXP4XX)		+= gpio-ixp4xx.o
+ obj-$(CONFIG_GPIO_JANZ_TTL)		+= gpio-janz-ttl.o
+ obj-$(CONFIG_GPIO_KEMPLD)		+= gpio-kempld.o
++obj-$(CONFIG_GPIO_LATCH_RB91X)		+= gpio-latch-rb91x.o
+ obj-$(CONFIG_GPIO_LOONGSON1)		+= gpio-loongson1.o
+ obj-$(CONFIG_GPIO_LOONGSON)		+= gpio-loongson.o
+ obj-$(CONFIG_GPIO_LP3943)		+= gpio-lp3943.o
-- 
2.26.3




More information about the openwrt-devel mailing list