Linux Kernels

gpio: tc3589x: implement open drain/source callback

This change “gpio: tc3589x: implement open drain/source callback” (commit 8b866b0) in Linux kernel is authored by Linus Walleij <linus.walleij [at] linaro.org> on Tue Apr 5 15:11:11 2016 +0200.

Description of "gpio: tc3589x: implement open drain/source callback"

The change “gpio: tc3589x: implement open drain/source callback” introduces changes as follows.

gpio: tc3589x: implement open drain/source callback

This makes use of the new .set_single_ended() callback to
set the GPIO line as open drain/open source using hardware.
The TC3589x can do this by either disabling the N-MOS
transistor (open drain) or the P-MOS transistor (open source)
of the output driver stage, in the first case making the signal
drive actively low and high impedance as "high" and in the second
case actively high and high impedance, which is as close to native
open drain support as we come.

Cc: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Linux kernel releases containing commit 8b866b0

The Linux kernel releases containing this commit are as follows.

Linux kernel code changes from "gpio: tc3589x: implement open drain/source callback"

There are 41 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/gpio/gpio-tc3589x.c | 41 +++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c
index 2845653f394a..15552fdadcba 100644
--- a/drivers/gpio/gpio-tc3589x.c
+++ b/drivers/gpio/gpio-tc3589x.c
@@ -85,6 +85,46 @@ static int tc3589x_gpio_direction_input(struct gpio_chip *chip,
 	return tc3589x_set_bits(tc3589x, reg, BIT(pos), 0);
 }
 
+static int tc3589x_gpio_single_ended(struct gpio_chip *chip,
+				     unsigned offset,
+				     enum single_ended_mode mode)
+{
+	struct tc3589x_gpio *tc3589x_gpio = gpiochip_get_data(chip);
+	struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+	/*
+	 * These registers are alterated at each second address
+	 * ODM bit 0 = drive to GND or Hi-Z (open drain)
+	 * ODM bit 1 = drive to VDD or Hi-Z (open source)
+	 */
+	u8 odmreg = TC3589x_GPIOODM0 + (offset / 8) * 2;
+	u8 odereg = TC3589x_GPIOODE0 + (offset / 8) * 2;
+	unsigned pos = offset % 8;
+	int ret;
+
+	switch(mode) {
+	case LINE_MODE_OPEN_DRAIN:
+		/* Set open drain mode */
+		ret = tc3589x_set_bits(tc3589x, odmreg, BIT(pos), 0);
+		if (ret)
+			return ret;
+		/* Enable open drain/source mode */
+		return tc3589x_set_bits(tc3589x, odereg, BIT(pos), BIT(pos));
+	case LINE_MODE_OPEN_SOURCE:
+		/* Set open source mode */
+		ret = tc3589x_set_bits(tc3589x, odmreg, BIT(pos), BIT(pos));
+		if (ret)
+			return ret;
+		/* Enable open drain/source mode */
+		return tc3589x_set_bits(tc3589x, odereg, BIT(pos), BIT(pos));
+	case LINE_MODE_PUSH_PULL:
+		/* Disable open drain/source mode */
+		return tc3589x_set_bits(tc3589x, odereg, BIT(pos), 0);
+	default:
+		break;
+	}
+	return -ENOTSUPP;
+}
+
 static struct gpio_chip template_chip = {
 	.label			= "tc3589x",
 	.owner			= THIS_MODULE,
@@ -92,6 +132,7 @@ static struct gpio_chip template_chip = {
 	.get			= tc3589x_gpio_get,
 	.direction_output	= tc3589x_gpio_direction_output,
 	.set			= tc3589x_gpio_set,
+	.set_single_ended	= tc3589x_gpio_single_ended,
 	.can_sleep		= true,
 };
 

The commit for this change in Linux stable tree is 8b866b0 (patch).

Last modified: 2020/01/11 09:54