diff mbox series

[v1] drivers/gpio: add support for MAX7320 i2c i/o expander

Message ID 1633088277-24976-1-git-send-email-hannes.schmelzer@br-automation.com
State Accepted
Delegated to: Tom Rini
Headers show
Series [v1] drivers/gpio: add support for MAX7320 i2c i/o expander | expand

Commit Message

Hannes Schmelzer Oct. 1, 2021, 11:37 a.m. UTC
This commit adds support for the MAX7320 (and clones) gpio expander.

Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>

---

 doc/device-tree-bindings/gpio/gpio-max7320.txt |  36 ++++++++
 drivers/gpio/Kconfig                           |   8 ++
 drivers/gpio/Makefile                          |   1 +
 drivers/gpio/max7320_gpio.c                    | 113 +++++++++++++++++++++++++
 4 files changed, 158 insertions(+)
 create mode 100644 doc/device-tree-bindings/gpio/gpio-max7320.txt
 create mode 100644 drivers/gpio/max7320_gpio.c

Comments

Tom Rini Oct. 1, 2021, 1:52 p.m. UTC | #1
On Fri, Oct 01, 2021 at 01:37:57PM +0200, Hannes Schmelzer wrote:

> This commit adds support for the MAX7320 (and clones) gpio expander.
> 
> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
> ---
> 
>  doc/device-tree-bindings/gpio/gpio-max7320.txt |  36 ++++++++
>  drivers/gpio/Kconfig                           |   8 ++
>  drivers/gpio/Makefile                          |   1 +
>  drivers/gpio/max7320_gpio.c                    | 113 +++++++++++++++++++++++++
>  4 files changed, 158 insertions(+)
>  create mode 100644 doc/device-tree-bindings/gpio/gpio-max7320.txt
>  create mode 100644 drivers/gpio/max7320_gpio.c
> 
> diff --git a/doc/device-tree-bindings/gpio/gpio-max7320.txt b/doc/device-tree-bindings/gpio/gpio-max7320.txt
> new file mode 100644
> index 0000000..87b703b
> --- /dev/null
> +++ b/doc/device-tree-bindings/gpio/gpio-max7320.txt
> @@ -0,0 +1,36 @@
> +* MAX7320 I/O expanders
> +
> +The original maxim 7320 i/o expander offers 8 bit push/pull outputs.
> +There exists some clones which offers 16 bit.
> +
> +Required Properties:
> +
> +  - compatible: should be one of the following.
> +    - "maxim,max7320"
> +
> +  - reg: I2C slave address.
> +
> +  - gpio-controller: Marks the device node as a gpio controller.
> +  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
> +    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
> +    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
> +
> +Optional Properties:
> +
> +   - ngpios: tell the driver how many gpios the device offers.
> +     if the property is omitted, 8bit (original maxim) is assumed.
> +
> +Please refer to gpio.txt in this directory for details of the common GPIO
> +bindings used by client devices.
> +
> +Example: MAX7320 I/O expander node
> +
> +	ledgpio: max7320@5d {
> +		status = "okay";
> +		compatible = "maxim,max7320";
> +		reg = <0x5d>;
> +		#gpio-cells = <2>;
> +		gpio-controller;
> +		ngpios = <16>;
> +	};
> +

Where does this binding come from?  Thanks!
Hannes Schmelzer Oct. 1, 2021, 7:15 p.m. UTC | #2
Am 01.10.2021 um 15:52 schrieb Tom Rini:
> On Fri, Oct 01, 2021 at 01:37:57PM +0200, Hannes Schmelzer wrote:
>
>> This commit adds support for the MAX7320 (and clones) gpio expander.
>>
>> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
>> ---
>>
>>   doc/device-tree-bindings/gpio/gpio-max7320.txt |  36 ++++++++
>>   drivers/gpio/Kconfig                           |   8 ++
>>   drivers/gpio/Makefile                          |   1 +
>>   drivers/gpio/max7320_gpio.c                    | 113 +++++++++++++++++++++++++
>>   4 files changed, 158 insertions(+)
>>   create mode 100644 doc/device-tree-bindings/gpio/gpio-max7320.txt
>>   create mode 100644 drivers/gpio/max7320_gpio.c
>>
>> diff --git a/doc/device-tree-bindings/gpio/gpio-max7320.txt b/doc/device-tree-bindings/gpio/gpio-max7320.txt
>> new file mode 100644
>> index 0000000..87b703b
>> --- /dev/null
>> +++ b/doc/device-tree-bindings/gpio/gpio-max7320.txt
>> @@ -0,0 +1,36 @@
>> +* MAX7320 I/O expanders
>> +
>> +The original maxim 7320 i/o expander offers 8 bit push/pull outputs.
>> +There exists some clones which offers 16 bit.
>> +
>> +Required Properties:
>> +
>> +  - compatible: should be one of the following.
>> +    - "maxim,max7320"
>> +
>> +  - reg: I2C slave address.
>> +
>> +  - gpio-controller: Marks the device node as a gpio controller.
>> +  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
>> +    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
>> +    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
>> +
>> +Optional Properties:
>> +
>> +   - ngpios: tell the driver how many gpios the device offers.
>> +     if the property is omitted, 8bit (original maxim) is assumed.
>> +
>> +Please refer to gpio.txt in this directory for details of the common GPIO
>> +bindings used by client devices.
>> +
>> +Example: MAX7320 I/O expander node
>> +
>> +	ledgpio: max7320@5d {
>> +		status = "okay";
>> +		compatible = "maxim,max7320";
>> +		reg = <0x5d>;
>> +		#gpio-cells = <2>;
>> +		gpio-controller;
>> +		ngpios = <16>;
>> +	};
>> +
> Where does this binding come from?  Thanks!
>
Hi Tom,

i took it from 'doc/device-tree-bindings/gpio/gpio-pcf857x.txt'  and 
adapted it for my needs.

cheers,
Hannes
Tom Rini Oct. 20, 2021, 12:46 a.m. UTC | #3
On Fri, Oct 01, 2021 at 01:37:57PM +0200, Hannes Schmelzer wrote:

> This commit adds support for the MAX7320 (and clones) gpio expander.
> 
> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/doc/device-tree-bindings/gpio/gpio-max7320.txt b/doc/device-tree-bindings/gpio/gpio-max7320.txt
new file mode 100644
index 0000000..87b703b
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/gpio-max7320.txt
@@ -0,0 +1,36 @@ 
+* MAX7320 I/O expanders
+
+The original maxim 7320 i/o expander offers 8 bit push/pull outputs.
+There exists some clones which offers 16 bit.
+
+Required Properties:
+
+  - compatible: should be one of the following.
+    - "maxim,max7320"
+
+  - reg: I2C slave address.
+
+  - gpio-controller: Marks the device node as a gpio controller.
+  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
+    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
+    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+
+Optional Properties:
+
+   - ngpios: tell the driver how many gpios the device offers.
+     if the property is omitted, 8bit (original maxim) is assumed.
+
+Please refer to gpio.txt in this directory for details of the common GPIO
+bindings used by client devices.
+
+Example: MAX7320 I/O expander node
+
+	ledgpio: max7320@5d {
+		status = "okay";
+		compatible = "maxim,max7320";
+		reg = <0x5d>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		ngpios = <16>;
+	};
+
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e37ac9f..3aafbe3 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -513,4 +513,12 @@  config NOMADIK_GPIO
 	  into a number of banks each with 32 GPIOs. The GPIOs for a device are
 	  defined in the device tree with one node for each bank.
 
+config MAX7320_GPIO
+	bool "MAX7320 I2C GPIO Expander driver"
+	depends on DM_GPIO && DM_I2C
+	help
+	 Support for MAX7320 I2C 8/16-bit GPIO expander.
+	 original maxim device has 8 push/pull outputs,
+	 some clones offers 16bit.
+
 endmenu
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 58f4704..f59ea4a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -69,3 +69,4 @@  obj-$(CONFIG_MSCC_SGPIO)	+= mscc_sgpio.o
 obj-$(CONFIG_NX_GPIO)		+= nx_gpio.o
 obj-$(CONFIG_SIFIVE_GPIO)	+= sifive-gpio.o
 obj-$(CONFIG_NOMADIK_GPIO)	+= nmk_gpio.o
+obj-$(CONFIG_MAX7320_GPIO)	+= max7320_gpio.o
diff --git a/drivers/gpio/max7320_gpio.c b/drivers/gpio/max7320_gpio.c
new file mode 100644
index 0000000..647aed9
--- /dev/null
+++ b/drivers/gpio/max7320_gpio.c
@@ -0,0 +1,113 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * max7320 I2C GPIO EXPANDER DRIVER
+ *
+ * Copyright (C) 2021 Hannes Schmelzer <oe5hpm@oevsv.at>
+ * B&R Industrial Automation GmbH - http://www.br-automation.com
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm-generic/gpio.h>
+#include <linux/bitops.h>
+
+struct max7320_chip {
+	u32 outreg;
+};
+
+static int max7320_direction_output(struct udevice *dev,
+				    unsigned int offset, int value)
+{
+	struct max7320_chip *plat = dev_get_plat(dev);
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
+
+	int ret;
+
+	if (value)
+		plat->outreg |= BIT(offset);
+	else
+		plat->outreg &= ~BIT(offset);
+
+	ret = dm_i2c_write(dev,
+			   plat->outreg & 0xff,
+			   (uint8_t *)&plat->outreg + 1,
+			   uc_priv->gpio_count > 8 ? 1 : 0);
+	if (ret)
+		printf("%s i2c write failed to addr %x\n", __func__,
+		       chip->chip_addr);
+
+	return ret;
+}
+
+static int max7320_get_value(struct udevice *dev, unsigned int offset)
+{
+	struct max7320_chip *plat = dev_get_plat(dev);
+
+	return (plat->outreg >> offset) & 0x1;
+}
+
+static int max7320_set_value(struct udevice *dev, unsigned int offset,
+			     int value)
+{
+	return max7320_direction_output(dev, offset, value);
+}
+
+static int max7320_get_function(struct udevice *dev, unsigned int offset)
+{
+	return GPIOF_OUTPUT;
+}
+
+static int max7320_ofdata_plat(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", 8);
+	if (uc_priv->gpio_count > 16) {
+		printf("%s: max7320 doesn't support more than 16 gpios!",
+		       __func__);
+		return -EINVAL;
+	}
+
+	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
+					 "gpio-bank-name", NULL);
+	if (!uc_priv->bank_name)
+		uc_priv->bank_name = fdt_get_name(gd->fdt_blob,
+						  dev_of_offset(dev), NULL);
+
+	return 0;
+}
+
+static int max7320_gpio_probe(struct udevice  *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	debug("%s GPIO controller with %d gpios probed\n",
+	      uc_priv->bank_name, uc_priv->gpio_count);
+
+	return 0;
+}
+
+static const struct dm_gpio_ops max7320_gpio_ops = {
+	.direction_output	= max7320_direction_output,
+	.set_value		= max7320_set_value,
+	.get_value		= max7320_get_value,
+	.get_function		= max7320_get_function,
+};
+
+static const struct udevice_id max7320_gpio_ids[] = {
+	{ .compatible = "maxim,max7320" },
+	{ }
+};
+
+U_BOOT_DRIVER(gpio_max7320) = {
+	.name		= "gpio_max7320",
+	.id		= UCLASS_GPIO,
+	.ops		= &max7320_gpio_ops,
+	.of_match	= max7320_gpio_ids,
+	.of_to_plat	= max7320_ofdata_plat,
+	.probe		= max7320_gpio_probe,
+	.plat_auto	= sizeof(struct max7320_chip),
+};