Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e397824b authored by Jan Kundrát's avatar Jan Kundrát Committed by Greg Kroah-Hartman
Browse files

gpio: serial: max310x: Support open-drain configuration for GPIOs

The push-pull vs. open-drain are the only supported output modes. The
inputs are always unconditionally equipped with weak pull-downs. That's
the only mode, so there's probably no point in exporting that. I wonder
if it's worthwhile to provide a custom dbg_show method to indicate the
current status of the outputs, though.

This patch and [1] for i2c-gpio together make it possible to bit-bang an
I2C bus over GPIOs of an UART which is connected via SPI :). Yes, this
is crazy, but it's fast enough (while on a 26Mhz SPI HW bus with a
dual-core 1.6GHz CPU) to drive an I2C bus at 200kHz, according to my
scope.

[1] https://patchwork.ozlabs.org/patch/852591/



Signed-off-by: default avatarJan Kundrát <jan.kundrat@cesnet.cz>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d09995d
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -1159,6 +1159,27 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip,


	return 0;
	return 0;
}
}

static int max310x_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
				   unsigned long config)
{
	struct max310x_port *s = gpiochip_get_data(chip);
	struct uart_port *port = &s->p[offset / 4].port;

	switch (pinconf_to_config_param(config)) {
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		max310x_port_update(port, MAX310X_GPIOCFG_REG,
				1 << ((offset % 4) + 4),
				1 << ((offset % 4) + 4));
		return 0;
	case PIN_CONFIG_DRIVE_PUSH_PULL:
		max310x_port_update(port, MAX310X_GPIOCFG_REG,
				1 << ((offset % 4) + 4), 0);
		return 0;
	default:
		return -ENOTSUPP;
	}
}
#endif
#endif


static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
@@ -1302,6 +1323,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
	s->gpio.get		= max310x_gpio_get;
	s->gpio.get		= max310x_gpio_get;
	s->gpio.direction_output= max310x_gpio_direction_output;
	s->gpio.direction_output= max310x_gpio_direction_output;
	s->gpio.set		= max310x_gpio_set;
	s->gpio.set		= max310x_gpio_set;
	s->gpio.set_config	= max310x_gpio_set_config;
	s->gpio.base		= -1;
	s->gpio.base		= -1;
	s->gpio.ngpio		= devtype->nr * 4;
	s->gpio.ngpio		= devtype->nr * 4;
	s->gpio.can_sleep	= 1;
	s->gpio.can_sleep	= 1;