Linux-GPIO Archive on lore.kernel.org
 help / color / Atom feed
From: Harish Jenny K N <harish_kandiga@mentor.com>
To: Linus Walleij <linus.walleij@linaro.org>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: <linux-gpio@vger.kernel.org>,
	Harish Jenny K N <harish_kandiga@mentor.com>,
	Balasubramani Vivekanandan 
	<balasubramani_vivekanandan@mentor.com>
Subject: [PATCH V4 1/2] gpio: inverter: Add Inverter controller for gpio configuration
Date: Fri, 28 Jun 2019 10:50:35 +0530
Message-ID: <1561699236-18620-2-git-send-email-harish_kandiga@mentor.com> (raw)
In-Reply-To: <1561699236-18620-1-git-send-email-harish_kandiga@mentor.com>

Provides a new inverter gpio controller to configure the polarity
of the gpio pins. This driver enables the consumers to directly
use the gpio pin without worrying about the hardware level
polarity configuration. Polarity configuration will be done by
the inverter gpio controller based on device tree information.

Signed-off-by: Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com>
Signed-off-by: Harish Jenny K N <harish_kandiga@mentor.com>
---
 drivers/gpio/Kconfig         |   9 +++
 drivers/gpio/Makefile        |   1 +
 drivers/gpio/gpio-inverter.c | 128 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 drivers/gpio/gpio-inverter.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index acd40eb..8978047 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -77,6 +77,15 @@ config GPIO_GENERIC
 	depends on HAS_IOMEM # Only for IOMEM drivers
 	tristate

+config GPIO_INVERTER
+	tristate "Inverter GPIO controller for handling hardware inverters"
+	depends on OF_GPIO
+	help
+	 Enabling this configuration provides an inverter gpio controller to
+	 configure the polarity of the gpio pins.
+	 This enables the consumers to directly use the gpio pin without
+	 worrying about the hardware level polarity configuration.
+
 # put drivers in the right section, in alphabetical order

 # This symbol is selected by both I2C and SPI expanders
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6700eee..b951b73 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_GPIO_HLWD)		+= gpio-hlwd.o
 obj-$(CONFIG_HTC_EGPIO)		+= gpio-htc-egpio.o
 obj-$(CONFIG_GPIO_ICH)		+= gpio-ich.o
 obj-$(CONFIG_GPIO_IOP)		+= gpio-iop.o
+obj-$(CONFIG_GPIO_INVERTER)	+= gpio-inverter.o
 obj-$(CONFIG_GPIO_IXP4XX)	+= gpio-ixp4xx.o
 obj-$(CONFIG_GPIO_IT87)		+= gpio-it87.o
 obj-$(CONFIG_GPIO_JANZ_TTL)	+= gpio-janz-ttl.o
diff --git a/drivers/gpio/gpio-inverter.c b/drivers/gpio/gpio-inverter.c
new file mode 100644
index 0000000..4883b33
--- /dev/null
+++ b/drivers/gpio/gpio-inverter.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Inverter GPIO controller for configuring the gpio polarity
+ *
+ * Copyright (c) 2019 Mentor Graphics Inc.
+ * Developed using gpiolib and gpio documentation as reference
+ *
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+struct gpio_inverter {
+	struct gpio_chip gpiochip;
+	int count;
+	struct gpio_desc *gpios[];
+};
+
+static int gpio_inverter_direction_input(struct gpio_chip *chip,
+					 unsigned int offset)
+{
+	struct gpio_inverter *inv = gpiochip_get_data(chip);
+
+	return gpiod_direction_input(inv->gpios[offset]);
+}
+
+static int gpio_inverter_direction_output(struct gpio_chip *chip,
+					  unsigned int offset, int value)
+{
+	struct gpio_inverter *inv = gpiochip_get_data(chip);
+
+	return gpiod_direction_output(inv->gpios[offset], value);
+}
+
+static int gpio_inverter_get(struct gpio_chip *chip,
+			     unsigned int offset)
+{
+	struct gpio_inverter *inv = gpiochip_get_data(chip);
+
+	return !gpiod_get_value(inv->gpios[offset]);
+}
+
+static void gpio_inverter_set(struct gpio_chip *chip,
+			      unsigned int offset, int value)
+{
+	struct gpio_inverter *inv = gpiochip_get_data(chip);
+
+	return gpiod_set_value(inv->gpios[offset], !value);
+}
+
+static int gpio_inverter_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_inverter *inv;
+	struct gpio_chip *gpio_chip;
+	struct gpio_desc *gpio;
+	int index = 0;
+	int count;
+	int ret;
+
+	count = gpiod_count(dev, "inverted");
+	if (count <= 0)
+		return count ? count : -ENOENT;
+
+	inv = devm_kzalloc(dev, struct_size(inv, gpios, count), GFP_KERNEL);
+	if (!inv)
+		return -ENOMEM;
+
+	inv->count = count;
+	gpio_chip = &inv->gpiochip;
+
+	platform_set_drvdata(pdev, inv);
+
+	while (index < count) {
+		gpio = devm_gpiod_get_index(dev, "inverted", index, GPIOD_ASIS);
+
+		if (gpio == ERR_PTR(-ENOENT))
+			return -EPROBE_DEFER;
+
+		if (IS_ERR(gpio))
+			return PTR_ERR(gpio);
+
+		inv->gpios[index++] = gpio;
+
+		if (!gpio_chip->can_sleep && gpiod_cansleep(gpio))
+			gpio_chip->can_sleep = true;
+	}
+
+	gpio_chip->direction_input = gpio_inverter_direction_input;
+	gpio_chip->direction_output = gpio_inverter_direction_output;
+	gpio_chip->get = gpio_inverter_get;
+	gpio_chip->set = gpio_inverter_set;
+	gpio_chip->label = dev_name(dev);
+	gpio_chip->parent = dev;
+	gpio_chip->owner = THIS_MODULE;
+	gpio_chip->base = -1;
+	gpio_chip->ngpio = count;
+
+	ret = devm_gpiochip_add_data(dev, gpio_chip, inv);
+	if (ret) {
+		dev_err(dev, "failed to add gpio controller\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id gpio_inverter_match[] = {
+	{ .compatible =	"gpio-inverter", }, { },
+};
+
+static struct platform_driver gpio_inverter_driver = {
+	.probe = gpio_inverter_probe,
+	.driver = {
+		.name = "gpio-inverter",
+		.of_match_table = of_match_ptr(gpio_inverter_match),
+	}
+};
+
+module_platform_driver(gpio_inverter_driver);
+
+MODULE_AUTHOR("Harish Jenny K N <harish_kandiga@mentor.com>");
+MODULE_AUTHOR("Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com>");
+MODULE_DESCRIPTION("Inverter GPIO controller for configuring the gpio polarity");
+MODULE_LICENSE("GPL v2");
--
2.7.4


  reply index

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-28  5:20 [PATCH V4 0/2] " Harish Jenny K N
2019-06-28  5:20 ` Harish Jenny K N [this message]
2019-06-28  8:55   ` [PATCH V4 1/2] gpio: inverter: " Linus Walleij
2019-06-28  9:15     ` Harish Jenny K N
2019-06-28  9:22       ` Linus Walleij
2019-06-28  5:20 ` [PATCH V4 2/2] gpio: inverter: document the inverter bindings Harish Jenny K N

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1561699236-18620-2-git-send-email-harish_kandiga@mentor.com \
    --to=harish_kandiga@mentor.com \
    --cc=balasubramani_vivekanandan@mentor.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-GPIO Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-gpio/0 linux-gpio/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-gpio linux-gpio/ https://lore.kernel.org/linux-gpio \
		linux-gpio@vger.kernel.org
	public-inbox-index linux-gpio

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-gpio


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git