All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC gpio/for-next 0/2]  gpio: add generic gpio input multiplexer
@ 2021-03-25 12:28 Mauri Sandberg
  2021-03-25 12:28 ` [RFC gpio/for-next 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
                   ` (10 more replies)
  0 siblings, 11 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-25 12:28 UTC (permalink / raw)
  To: linux-gpio
  Cc: andy.shevchenko, linus.walleij, bgolaszewski, geert+renesas,
	Mauri Sandberg

Hello,

I obtained the list of people in CC: after discussions with Drew Fustini and I
hope I am not bothering any of you. Here I am sending for review a couple of
patches that add a multiplexer that uses a GPIO pin as its output.

I welcome all ideas how to improve this or, more importantly, pointers if
similar can be achieved with something that is already present in the kernel
code.

Thanks,
Mauri

Mauri Sandberg (2):
  dt-bindings: gpio-mux-input: add documentation
  gpio: gpio-mux-input: add generic gpio input multiplexer

 .../bindings/gpio/gpio-mux-input.yaml         |  55 +++++++
 drivers/gpio/Kconfig                          |  11 ++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-mux-input.c                 | 143 ++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
 create mode 100644 drivers/gpio/gpio-mux-input.c


base-commit: 7ac554888233468a9fd7c4f28721396952dd9959
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [RFC gpio/for-next 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
@ 2021-03-25 12:28 ` Mauri Sandberg
  2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-25 12:28 UTC (permalink / raw)
  To: linux-gpio
  Cc: andy.shevchenko, linus.walleij, bgolaszewski, geert+renesas,
	Mauri Sandberg

Add documentation for a general GPIO multiplexer.

Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
 .../bindings/gpio/gpio-mux-input.yaml         | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
new file mode 100644
index 000000000000..f436000fe138
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO input multiplexer
+
+maintainers:
+  - Mauri Sandberg <sandberg@mailfence.com>
+
+description: |
+  A generic GPIO based input multiplexer
+
+  This driver uses mux-controller to drive the multiplexer.
+
+  For consumer use see gpio.txt.
+
+properties:
+  compatible:
+    enum:
+      - gpio-mux-input
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  pin-gpios:
+    description: |
+      The GPIO pin used the output from the multiplexer
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - pin-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    gpio2: key-mux1 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux output pin
+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;	/* 1y */
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
  2021-03-25 12:28 ` [RFC gpio/for-next 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-03-25 12:28 ` Mauri Sandberg
  2021-03-25 23:08   ` kernel test robot
                     ` (2 more replies)
  2021-03-29 13:57 ` [RFC v2 0/2] gpio: " Mauri Sandberg
                   ` (8 subsequent siblings)
  10 siblings, 3 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-25 12:28 UTC (permalink / raw)
  To: linux-gpio
  Cc: andy.shevchenko, linus.walleij, bgolaszewski, geert+renesas,
	Mauri Sandberg

Suppport for a general GPIO multiplexer. To drive the multiplexer a
mux-controller is needed. The output pin of the multiplexer is a GPIO
pin.

Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
 drivers/gpio/Kconfig          |  11 +++
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpio-mux-input.c | 143 ++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/gpio/gpio-mux-input.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c70f46e80a3b..41062d8f7d93 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1641,4 +1641,15 @@ config GPIO_MOCKUP
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_MUX_INPUT
+	tristate "General GPIO input multiplexer"
+	select MULTIPLEXER
+	select MUX_GPIO
+	depends on OF_GPIO
+	help
+	  Say yes here to enable support for generic GPIO input multiplexer. This
+	  needs a multiplexer controller to drive the select pins.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 35e3b6026665..00f7576ce23f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -105,6 +105,7 @@ obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
 obj-$(CONFIG_GPIO_MSIC)			+= gpio-msic.o
 obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
new file mode 100644
index 000000000000..ec0c7acbab2f
--- /dev/null
+++ b/drivers/gpio/gpio-mux-input.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO input multiplexer driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_mux_input {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*mux_pin;
+};
+
+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_mux_input, gpio_chip);
+}
+
+static int gpio_mux_input_direction_input(struct gpio_chip *gc,
+				       unsigned int offset)
+{
+	return 0;
+}
+
+static int gpio_mux_input_direction_output(struct gpio_chip *gc,
+					unsigned int offset, int val)
+{
+	return -EINVAL;
+}
+
+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_mux_input *mux;
+	int ret;
+
+	mux = gpio_to_mux(gc);
+	ret = mux_control_select(mux->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(mux->mux_pin);
+	mux_control_deselect(mux->mux_control);
+	return ret;
+}
+
+static void gpio_mux_input_set_value(struct gpio_chip *gc,
+				  unsigned int offset, int val)
+{
+	/* not supported */
+}
+
+static int gpio_mux_input_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct gpio_mux_input *mux;
+	struct gpio_chip *gc;
+	struct mux_control *mc;
+	struct gpio_desc *pin;
+	int err;
+
+	mux = kzalloc(sizeof(struct gpio_mux_input), GFP_KERNEL);
+	if (mux == NULL)
+		return -ENOMEM;
+
+	mc = mux_control_get(&pdev->dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get mux-control: %d\n",
+				err);
+		goto err_free_mux;
+	}
+
+	mux->mux_control = mc;
+	pin = gpiod_get(&pdev->dev, "pin",  GPIOD_IN);
+	if (IS_ERR(pin)) {
+		err = (int) PTR_ERR(pin);
+		dev_err(&pdev->dev, "unable to claim pin GPIOs: %d\n", err);
+		goto err_free_mc;
+	}
+
+	mux->mux_pin = pin;
+	mux->parent = &pdev->dev;
+
+	gc = &mux->gpio_chip;
+	gc->direction_input  = gpio_mux_input_direction_input;
+	gc->direction_output = gpio_mux_input_direction_output;
+	gc->get = gpio_mux_input_get_value;
+	gc->set = gpio_mux_input_set_value;
+	gc->can_sleep = 1;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(mux->parent);
+	gc->parent = mux->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&mux->gpio_chip);
+	if (err) {
+		dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
+		goto err_free_pin;
+	}
+
+	platform_set_drvdata(pdev, mux);
+	return 0;
+
+err_free_pin:
+	gpiod_put(pin);
+err_free_mc:
+	mux_control_put(mc);
+err_free_mux:
+	kfree(mux);
+	return err;
+}
+
+static const struct of_device_id gpio_mux_input_id[] = {
+	{
+		.compatible = "gpio-mux-input",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
+
+static struct platform_driver gpio_mux_input_driver = {
+	.driver	= {
+		.name		= "gpio-mux-input",
+		.owner		= THIS_MODULE,
+		.of_match_table = gpio_mux_input_id,
+	},
+	.probe	= gpio_mux_input_probe,
+};
+module_platform_driver(gpio_mux_input_driver);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
@ 2021-03-25 23:08   ` kernel test robot
  2021-03-25 23:08   ` [PATCH] gpio: gpio-mux-input: fix platform_no_drv_owner.cocci warnings kernel test robot
  2021-03-26  6:59   ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Drew Fustini
  2 siblings, 0 replies; 62+ messages in thread
From: kernel test robot @ 2021-03-25 23:08 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 829 bytes --]

Hi Mauri,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on 7ac554888233468a9fd7c4f28721396952dd9959]

url:    https://github.com/0day-ci/linux/commits/Mauri-Sandberg/gpio-add-generic-gpio-input-multiplexer/20210325-203252
base:   7ac554888233468a9fd7c4f28721396952dd9959
config: i386-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


cocci warnings: (new ones prefixed by >>)
>> drivers/gpio/gpio-mux-input.c:138:3-8: No need to set .owner here. The core will do it.

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 64073 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH] gpio: gpio-mux-input: fix platform_no_drv_owner.cocci warnings
  2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-03-25 23:08   ` kernel test robot
@ 2021-03-25 23:08   ` kernel test robot
  2021-03-26  6:59   ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Drew Fustini
  2 siblings, 0 replies; 62+ messages in thread
From: kernel test robot @ 2021-03-25 23:08 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1002 bytes --]

From: kernel test robot <lkp@intel.com>

drivers/gpio/gpio-mux-input.c:138:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Mauri Sandberg <sandberg@mailfence.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: kernel test robot <lkp@intel.com>
---

url:    https://github.com/0day-ci/linux/commits/Mauri-Sandberg/gpio-add-generic-gpio-input-multiplexer/20210325-203252
base:   7ac554888233468a9fd7c4f28721396952dd9959

 gpio-mux-input.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/gpio/gpio-mux-input.c
+++ b/drivers/gpio/gpio-mux-input.c
@@ -135,7 +135,6 @@ MODULE_DEVICE_TABLE(of, gpio_mux_input_i
 static struct platform_driver gpio_mux_input_driver = {
 	.driver	= {
 		.name		= "gpio-mux-input",
-		.owner		= THIS_MODULE,
 		.of_match_table = gpio_mux_input_id,
 	},
 	.probe	= gpio_mux_input_probe,

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-03-25 23:08   ` kernel test robot
  2021-03-25 23:08   ` [PATCH] gpio: gpio-mux-input: fix platform_no_drv_owner.cocci warnings kernel test robot
@ 2021-03-26  6:59   ` Drew Fustini
  2021-03-26 10:32     ` Mauri Sandberg
  2 siblings, 1 reply; 62+ messages in thread
From: Drew Fustini @ 2021-03-26  6:59 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: linux-gpio, andy.shevchenko, linus.walleij, bgolaszewski, geert+renesas

On Thu, Mar 25, 2021 at 02:28:32PM +0200, Mauri Sandberg wrote:
> Suppport for a general GPIO multiplexer. To drive the multiplexer a
> mux-controller is needed. The output pin of the multiplexer is a GPIO
> pin
> 
> Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>

Thanks for posting the RFC so we can take a look at the code and discuss
how it works.

> ---
>  drivers/gpio/Kconfig          |  11 +++
>  drivers/gpio/Makefile         |   1 +
>  drivers/gpio/gpio-mux-input.c | 143 ++++++++++++++++++++++++++++++++++
>  3 files changed, 155 insertions(+)
>  create mode 100644 drivers/gpio/gpio-mux-input.c
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index c70f46e80a3b..41062d8f7d93 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1641,4 +1641,15 @@ config GPIO_MOCKUP
>  
>  endmenu
>  
> +comment "Other GPIO expanders"
> +
> +config GPIO_MUX_INPUT
> +	tristate "General GPIO input multiplexer"
> +	select MULTIPLEXER
> +	select MUX_GPIO
> +	depends on OF_GPIO
> +	help
> +	  Say yes here to enable support for generic GPIO input multiplexer. This
> +	  needs a multiplexer controller to drive the select pins.
> +
>  endif
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 35e3b6026665..00f7576ce23f 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -105,6 +105,7 @@ obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
>  obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
>  obj-$(CONFIG_GPIO_MSIC)			+= gpio-msic.o
>  obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
> +obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
>  obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
>  obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
>  obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o

This does not apply to mainline. I've added it manually to my
drivers/gpio/Makefile but something to fix in v2.

> diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
> new file mode 100644
> index 000000000000..ec0c7acbab2f
> --- /dev/null
> +++ b/drivers/gpio/gpio-mux-input.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *  A generic GPIO input multiplexer driver
> + *
> + *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mux/consumer.h>
> +
> +struct gpio_mux_input {
> +	struct device		*parent;
> +	struct gpio_chip	gpio_chip;
> +	struct mux_control	*mux_control;
> +	struct gpio_desc	*mux_pin;
> +};
> +
> +static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
> +{
> +	return container_of(gc, struct gpio_mux_input, gpio_chip);
> +}
> +
> +static int gpio_mux_input_direction_input(struct gpio_chip *gc,
> +				       unsigned int offset)
> +{
> +	return 0;
> +}
> +
> +static int gpio_mux_input_direction_output(struct gpio_chip *gc,
> +					unsigned int offset, int val)
> +{
> +	return -EINVAL;
> +}
> +
> +static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
> +{
> +	struct gpio_mux_input *mux;
> +	int ret;
> +
> +	mux = gpio_to_mux(gc);
> +	ret = mux_control_select(mux->mux_control, offset);
> +	if (ret)
> +		return ret;
> +
> +	ret = gpiod_get_value(mux->mux_pin);

I'm not too familiar with how mux_control works but does there need to
be locking here?

Or is not possible for mux_pin to change to another offset before if
gpiod_get_value() if gpio_mux_input_get_value() runs concurrently?

> +	mux_control_deselect(mux->mux_control);
> +	return ret;
> +}
> +
> +static void gpio_mux_input_set_value(struct gpio_chip *gc,
> +				  unsigned int offset, int val)
> +{
> +	/* not supported */

I'm not sure but maybe it is better not to define gc->set in the probe?

> +}
> +
> +static int gpio_mux_input_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct gpio_mux_input *mux;
> +	struct gpio_chip *gc;
> +	struct mux_control *mc;
> +	struct gpio_desc *pin;
> +	int err;
> +
> +	mux = kzalloc(sizeof(struct gpio_mux_input), GFP_KERNEL);
> +	if (mux == NULL)
> +		return -ENOMEM;
> +
> +	mc = mux_control_get(&pdev->dev, NULL);
> +	if (IS_ERR(mc)) {
> +		err = (int) PTR_ERR(mc);
> +		if (err != -EPROBE_DEFER)
> +			dev_err(&pdev->dev, "unable to get mux-control: %d\n",
> +				err);
> +		goto err_free_mux;
> +	}
> +
> +	mux->mux_control = mc;
> +	pin = gpiod_get(&pdev->dev, "pin",  GPIOD_IN);
> +	if (IS_ERR(pin)) {
> +		err = (int) PTR_ERR(pin);
> +		dev_err(&pdev->dev, "unable to claim pin GPIOs: %d\n", err);
> +		goto err_free_mc;
> +	}
> +
> +	mux->mux_pin = pin;
> +	mux->parent = &pdev->dev;
> +
> +	gc = &mux->gpio_chip;
> +	gc->direction_input  = gpio_mux_input_direction_input;
> +	gc->direction_output = gpio_mux_input_direction_output;
> +	gc->get = gpio_mux_input_get_value;
> +	gc->set = gpio_mux_input_set_value;
> +	gc->can_sleep = 1;
> +
> +	gc->base = -1;
> +	gc->ngpio = mux_control_states(mc);
> +	gc->label = dev_name(mux->parent);
> +	gc->parent = mux->parent;
> +	gc->owner = THIS_MODULE;
> +	gc->of_node = np;
> +
> +	err = gpiochip_add(&mux->gpio_chip);
> +	if (err) {
> +		dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
> +		goto err_free_pin;
> +	}
> +
> +	platform_set_drvdata(pdev, mux);
> +	return 0;
> +
> +err_free_pin:
> +	gpiod_put(pin);
> +err_free_mc:
> +	mux_control_put(mc);
> +err_free_mux:
> +	kfree(mux);
> +	return err;
> +}
> +
> +static const struct of_device_id gpio_mux_input_id[] = {
> +	{
> +		.compatible = "gpio-mux-input",
> +		.data = NULL,
> +	},
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
> +
> +static struct platform_driver gpio_mux_input_driver = {
> +	.driver	= {
> +		.name		= "gpio-mux-input",
> +		.owner		= THIS_MODULE,
> +		.of_match_table = gpio_mux_input_id,
> +	},
> +	.probe	= gpio_mux_input_probe,
> +};
> +module_platform_driver(gpio_mux_input_driver);

I believe you need to add:

  MODULE_AUTHOR("...");
  MODULE_DESCRIPTION("...");
  MODULE_LICENSE("GPL");

My build failed with:

  ERROR: modpost: missing MODULE_LICENSE() in drivers/gpio/gpio-mux-input.o
  LZMA    arch/arm/boot/compressed/piggy_data
  make[1]: *** [scripts/Makefile.modpost:132: Module.symvers] Error 1
  make[1]: *** Deleting file 'Module.symvers'
  make: *** [Makefile:1442: modules] Error 2
  make: *** Waiting for unfinished jobs....
  AS      arch/arm/boot/compressed/piggy.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

I added those lines and it compiled successfully.


-Drew

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-26  6:59   ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Drew Fustini
@ 2021-03-26 10:32     ` Mauri Sandberg
  2021-03-26 10:49       ` Andy Shevchenko
  0 siblings, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-26 10:32 UTC (permalink / raw)
  To: Drew Fustini
  Cc: linux-gpio, linus.walleij, bgolaszewski, andy.shevchenko, geert+renesas


> ----------------------------------------
> From: Drew Fustini <drew@beagleboard.org>
> Sent: Fri Mar 26 07:59:44 CET 2021
> To: Mauri Sandberg <sandberg@mailfence.com>
> > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> > index 35e3b6026665..00f7576ce23f 100644
> > --- a/drivers/gpio/Makefile
> > +++ b/drivers/gpio/Makefile
> > @@ -105,6 +105,7 @@ obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
> >  obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
> >  obj-$(CONFIG_GPIO_MSIC)			+= gpio-msic.o
> >  obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
> > +obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
> >  obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
> >  obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
> >  obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
> 
> This does not apply to mainline. I've added it manually to my
> drivers/gpio/Makefile but something to fix in v2.

I was developing against gpio tree's [1] 'for-next' branch but should I go against mainline?

> > diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
> > +static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
> > +{
> > +	struct gpio_mux_input *mux;
> > +	int ret;
> > +
> > +	mux = gpio_to_mux(gc);
> > +	ret = mux_control_select(mux->mux_control, offset);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = gpiod_get_value(mux->mux_pin);
> 
> I'm not too familiar with how mux_control works but does there need to
> be locking here?
> 
> Or is not possible for mux_pin to change to another offset before if
> gpiod_get_value() if gpio_mux_input_get_value() runs concurrently?

According to mux documentation [2] successfully selecting a state locks the mux
until it is deselected. So I reckon no extra locking is needed.

> > +
> > +static void gpio_mux_input_set_value(struct gpio_chip *gc,
> > +				  unsigned int offset, int val)
> > +{
> > +	/* not supported */
> 
> I'm not sure but maybe it is better not to define gc->set in the probe?

I will give it a go.
 
> I believe you need to add:
> 
>   MODULE_AUTHOR("...");
>   MODULE_DESCRIPTION("...");
>   MODULE_LICENSE("GPL");
> 
> My build failed with:
> 
>   ERROR: modpost: missing MODULE_LICENSE() in drivers/gpio/gpio-mux-input.o

I will add them, thanks.

 How do you do your build? Mine does not complain pretty much about anything. Also a bot gave me a warning and
I would like to run those tests manually before submitting anything for review.

Cheers,
Mauri

[1] https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mux/core.c#n322

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-26 10:32     ` Mauri Sandberg
@ 2021-03-26 10:49       ` Andy Shevchenko
  0 siblings, 0 replies; 62+ messages in thread
From: Andy Shevchenko @ 2021-03-26 10:49 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Drew Fustini, open list:GPIO SUBSYSTEM, Linus Walleij,
	Bartosz Golaszewski, Geert Uytterhoeven

On Fri, Mar 26, 2021 at 12:32 PM Mauri Sandberg <sandberg@mailfence.com> wrote:
> > From: Drew Fustini <drew@beagleboard.org>
> > Sent: Fri Mar 26 07:59:44 CET 2021

...

> > This does not apply to mainline. I've added it manually to my
> > drivers/gpio/Makefile but something to fix in v2.
>
> I was developing against gpio tree's [1] 'for-next' branch but should I go against mainline?

It's a Bart's tree nowadays [3], gpio/for-next branch.

> > > +   ret = gpiod_get_value(mux->mux_pin);
> >
> > I'm not too familiar with how mux_control works but does there need to
> > be locking here?
> >
> > Or is not possible for mux_pin to change to another offset before if
> > gpiod_get_value() if gpio_mux_input_get_value() runs concurrently?
>
> According to mux documentation [2] successfully selecting a state locks the mux
> until it is deselected. So I reckon no extra locking is needed.

...

> [1] https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mux/core.c#n322

[3]: https://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git/

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [RFC v2 0/2] gpio: add generic gpio input multiplexer
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
  2021-03-25 12:28 ` [RFC gpio/for-next 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
@ 2021-03-29 13:57 ` Mauri Sandberg
  2021-03-29 13:57   ` [RFC v2 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-03-29 13:57   ` [RFC v2 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-29 13:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew

v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip:
     gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - added a little bit more text in the binding documenation
 - Updated description in Kconfig

rangediff v1...v2
1:  addd7422268e ! 1:  37eef51e67be dt-bindings: gpio-mux-input: add documentation
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
     +$schema: http://devicetree.org/meta-schemas/core.yaml#
     +
    -+title: GPIO input multiplexer
    ++title: Generic GPIO input multiplexer
     +
     +maintainers:
     +  - Mauri Sandberg <sandberg@mailfence.com>
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +description: |
     +  A generic GPIO based input multiplexer
     +
    -+  This driver uses mux-controller to drive the multiplexer.
    ++  This driver uses a mux-controller to drive the multiplexer and has a single
    ++  output pin for reading the inputs to the mux.
     +
    -+  For consumer use see gpio.txt.
    ++  For GPIO consumer documentation see gpio.txt.
     +
     +properties:
     +  compatible:
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +
     +  pin-gpios:
     +    description: |
    -+      The GPIO pin used the output from the multiplexer
    ++      The GPIO pin used as the output from the multiplexer
     +
     +required:
     +  - compatible
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +        #gpio-cells = <2>;
     +
     +        // GPIOs used by this node, mux output pin
    -+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;	/* 1y */
    ++        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
     +    };
     +
     +...
2:  067ac01b2ce6 ! 2:  01e497d16a25 gpio: gpio-mux-input: add generic gpio input multiplexer
    @@ Metadata
      ## Commit message ##
         gpio: gpio-mux-input: add generic gpio input multiplexer
     
    -    Suppport for a general GPIO multiplexer. To drive the multiplexer a
    +    Adds support for a generic GPIO multiplexer. To drive the multiplexer a
         mux-controller is needed. The output pin of the multiplexer is a GPIO
         pin.
     
    +    Reported-by: kernel test robot <lkp@intel.com>
         Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
     
      ## drivers/gpio/Kconfig ##
    @@ drivers/gpio/Kconfig: config GPIO_SIM
     +
     +config GPIO_MUX_INPUT
     +	tristate "General GPIO input multiplexer"
    ++	depends on OF_GPIO
     +	select MULTIPLEXER
     +	select MUX_GPIO
    -+	depends on OF_GPIO
     +	help
    -+	  Say yes here to enable support for generic GPIO input multiplexer. This
    -+	  needs a multiplexer controller to drive the select pins.
    ++	  Say yes here to enable support for generic GPIO input multiplexer.
    ++
    ++  	  This driver uses a mux-controller to drive the multiplexer and has a
    ++  	  single output pin for reading the inputs to the mux.
     +
      endif
     
    @@ drivers/gpio/gpio-mux-input.c (new)
     +	return container_of(gc, struct gpio_mux_input, gpio_chip);
     +}
     +
    -+static int gpio_mux_input_direction_input(struct gpio_chip *gc,
    -+				       unsigned int offset)
    -+{
    -+	return 0;
    -+}
    -+
    -+static int gpio_mux_input_direction_output(struct gpio_chip *gc,
    -+					unsigned int offset, int val)
    ++static int gpio_mux_input_get_direction(struct gpio_chip *gc,
    ++					unsigned int offset)
     +{
    -+	return -EINVAL;
    ++	return GPIO_LINE_DIRECTION_IN;
     +}
     +
     +static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
    @@ drivers/gpio/gpio-mux-input.c (new)
     +	return ret;
     +}
     +
    -+static void gpio_mux_input_set_value(struct gpio_chip *gc,
    -+				  unsigned int offset, int val)
    -+{
    -+	/* not supported */
    -+}
    -+
     +static int gpio_mux_input_probe(struct platform_device *pdev)
     +{
     +	struct device_node *np = pdev->dev.of_node;
    @@ drivers/gpio/gpio-mux-input.c (new)
     +	pin = gpiod_get(&pdev->dev, "pin",  GPIOD_IN);
     +	if (IS_ERR(pin)) {
     +		err = (int) PTR_ERR(pin);
    -+		dev_err(&pdev->dev, "unable to claim pin GPIOs: %d\n", err);
    ++		dev_err(&pdev->dev, "unable to claim pin GPIO: %d\n", err);
     +		goto err_free_mc;
     +	}
     +
    @@ drivers/gpio/gpio-mux-input.c (new)
     +	mux->parent = &pdev->dev;
     +
     +	gc = &mux->gpio_chip;
    -+	gc->direction_input  = gpio_mux_input_direction_input;
    -+	gc->direction_output = gpio_mux_input_direction_output;
     +	gc->get = gpio_mux_input_get_value;
    -+	gc->set = gpio_mux_input_set_value;
    -+	gc->can_sleep = 1;
    ++	gc->get_direction = gpio_mux_input_get_direction;
     +
     +	gc->base = -1;
     +	gc->ngpio = mux_control_states(mc);
    @@ drivers/gpio/gpio-mux-input.c (new)
     +	}
     +
     +	platform_set_drvdata(pdev, mux);
    ++
    ++	dev_info(&pdev->dev, "registered %u input GPIOs\n", gc->ngpio);
    ++
     +	return 0;
     +
     +err_free_pin:
    @@ drivers/gpio/gpio-mux-input.c (new)
     +static struct platform_driver gpio_mux_input_driver = {
     +	.driver	= {
     +		.name		= "gpio-mux-input",
    -+		.owner		= THIS_MODULE,
     +		.of_match_table = gpio_mux_input_id,
     +	},
     +	.probe	= gpio_mux_input_probe,
     +};
     +module_platform_driver(gpio_mux_input_driver);
    ++
    ++MODULE_AUTHOR("Mauri Sandberg <sandberg@mailfence.com>");
    ++MODULE_DESCRIPTION("Generic GPIO input multiplexer");
    ++MODULE_LICENSE("GPL");


Mauri Sandberg (2):
  dt-bindings: gpio-mux-input: add documentation
  gpio: gpio-mux-input: add generic gpio input multiplexer

 .../bindings/gpio/gpio-mux-input.yaml         |  56 ++++++++
 drivers/gpio/Kconfig                          |  13 ++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-mux-input.c                 | 134 ++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
 create mode 100644 drivers/gpio/gpio-mux-input.c


base-commit: 9d940ab7264574be59ce3a953dc33de9250429eb
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [RFC v2 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-03-29 13:57 ` [RFC v2 0/2] gpio: " Mauri Sandberg
@ 2021-03-29 13:57   ` Mauri Sandberg
  2021-03-29 13:57   ` [RFC v2 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-29 13:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew

Add documentation for a general GPIO multiplexer.

Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
 .../bindings/gpio/gpio-mux-input.yaml         | 56 +++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
new file mode 100644
index 000000000000..5cb5d6f9e30a
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO input multiplexer
+
+maintainers:
+  - Mauri Sandberg <sandberg@mailfence.com>
+
+description: |
+  A generic GPIO based input multiplexer
+
+  This driver uses a mux-controller to drive the multiplexer and has a single
+  output pin for reading the inputs to the mux.
+
+  For GPIO consumer documentation see gpio.txt.
+
+properties:
+  compatible:
+    enum:
+      - gpio-mux-input
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  pin-gpios:
+    description: |
+      The GPIO pin used as the output from the multiplexer
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - pin-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    gpio2: key-mux1 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux output pin
+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [RFC v2 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-03-29 13:57 ` [RFC v2 0/2] gpio: " Mauri Sandberg
  2021-03-29 13:57   ` [RFC v2 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-03-29 13:57   ` Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-03-29 13:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew, kernel test robot

Adds support for a generic GPIO multiplexer. To drive the multiplexer a
mux-controller is needed. The output pin of the multiplexer is a GPIO
pin.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
 drivers/gpio/Kconfig          |  13 ++++
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpio-mux-input.c | 134 ++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+)
 create mode 100644 drivers/gpio/gpio-mux-input.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b6b6150d0d04..7bf8021e0239 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1643,4 +1643,17 @@ config GPIO_SIM
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_MUX_INPUT
+	tristate "General GPIO input multiplexer"
+	depends on OF_GPIO
+	select MULTIPLEXER
+	select MUX_GPIO
+	help
+	  Say yes here to enable support for generic GPIO input multiplexer.
+
+  	  This driver uses a mux-controller to drive the multiplexer and has a
+  	  single output pin for reading the inputs to the mux.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d717aa85f8e1..e843e1bcfc20 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -103,6 +103,7 @@ obj-$(CONFIG_GPIO_MPC5200)		+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
 obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
new file mode 100644
index 000000000000..2de198a84bb9
--- /dev/null
+++ b/drivers/gpio/gpio-mux-input.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO input multiplexer driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_mux_input {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*mux_pin;
+};
+
+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_mux_input, gpio_chip);
+}
+
+static int gpio_mux_input_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_mux_input *mux;
+	int ret;
+
+	mux = gpio_to_mux(gc);
+	ret = mux_control_select(mux->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(mux->mux_pin);
+	mux_control_deselect(mux->mux_control);
+	return ret;
+}
+
+static int gpio_mux_input_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct gpio_mux_input *mux;
+	struct gpio_chip *gc;
+	struct mux_control *mc;
+	struct gpio_desc *pin;
+	int err;
+
+	mux = kzalloc(sizeof(struct gpio_mux_input), GFP_KERNEL);
+	if (mux == NULL)
+		return -ENOMEM;
+
+	mc = mux_control_get(&pdev->dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get mux-control: %d\n",
+				err);
+		goto err_free_mux;
+	}
+
+	mux->mux_control = mc;
+	pin = gpiod_get(&pdev->dev, "pin",  GPIOD_IN);
+	if (IS_ERR(pin)) {
+		err = (int) PTR_ERR(pin);
+		dev_err(&pdev->dev, "unable to claim pin GPIO: %d\n", err);
+		goto err_free_mc;
+	}
+
+	mux->mux_pin = pin;
+	mux->parent = &pdev->dev;
+
+	gc = &mux->gpio_chip;
+	gc->get = gpio_mux_input_get_value;
+	gc->get_direction = gpio_mux_input_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(mux->parent);
+	gc->parent = mux->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&mux->gpio_chip);
+	if (err) {
+		dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
+		goto err_free_pin;
+	}
+
+	platform_set_drvdata(pdev, mux);
+
+	dev_info(&pdev->dev, "registered %u input GPIOs\n", gc->ngpio);
+
+	return 0;
+
+err_free_pin:
+	gpiod_put(pin);
+err_free_mc:
+	mux_control_put(mc);
+err_free_mux:
+	kfree(mux);
+	return err;
+}
+
+static const struct of_device_id gpio_mux_input_id[] = {
+	{
+		.compatible = "gpio-mux-input",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
+
+static struct platform_driver gpio_mux_input_driver = {
+	.driver	= {
+		.name		= "gpio-mux-input",
+		.of_match_table = gpio_mux_input_id,
+	},
+	.probe	= gpio_mux_input_probe,
+};
+module_platform_driver(gpio_mux_input_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <sandberg@mailfence.com>");
+MODULE_DESCRIPTION("Generic GPIO input multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 0/2] gpio: add generic gpio input multiplexer
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (2 preceding siblings ...)
  2021-03-29 13:57 ` [RFC v2 0/2] gpio: " Mauri Sandberg
@ 2021-05-17 16:58 ` Mauri Sandberg
  2021-05-17 16:58   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
                     ` (3 more replies)
  2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
                   ` (6 subsequent siblings)
  10 siblings, 4 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-17 16:58 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew

Hello all!

This patch set is closely related to another thread at [4], which I abandoned
against better judgement and created this one.

Here I am sending revised versions of the patches. It builds on v2 and adopts 
managed device resources as suggested by Andy on the thread mentioned
above [5].

I have tested the functionality on a NXP 74HC153 dual 4-way muxer. Drew, did
you find the time to have a go with this [6] and if so, did it work as expected?

Thanks,
Mauri

[4] https://www.spinics.net/lists/linux-gpio/msg58573.html
[5] https://www.spinics.net/lists/linux-gpio/msg60160.html
[6] https://www.spinics.net/lists/linux-gpio/msg60159.html


Mauri Sandberg (2):
  dt-bindings: gpio-mux-input: add documentation
  gpio: gpio-mux-input: add generic gpio input multiplexer

 .../bindings/gpio/gpio-mux-input.yaml         |  75 +++++++++++
 drivers/gpio/Kconfig                          |  16 +++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-mux-input.c                 | 124 ++++++++++++++++++
 4 files changed, 216 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
 create mode 100644 drivers/gpio/gpio-mux-input.c


base-commit: 6453b9532b5f77d19837b159c4d074f0af9f141b
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
@ 2021-05-17 16:58   ` Mauri Sandberg
  2021-05-17 16:58   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-17 16:58 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew

Add documentation for a general GPIO multiplexer.

Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
new file mode 100644
index 000000000000..a7ff5d1fd6f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO input multiplexer
+
+maintainers:
+  - Mauri Sandberg <sandberg@mailfence.com>
+
+description: |
+  A generic GPIO based input multiplexer
+
+  This driver uses a mux-controller to drive the multiplexer and has a single
+  output pin for reading the inputs to the mux.
+
+  For GPIO consumer documentation see gpio.txt.
+
+properties:
+  compatible:
+    enum:
+      - gpio-mux-input
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  pin-gpios:
+    description: |
+      The GPIO pin used as the output from the multiplexer
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - pin-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
  2021-05-17 16:58   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-05-17 16:58   ` Mauri Sandberg
  2021-05-17 22:13   ` [PATCH v3 0/2] gpio: " Drew Fustini
  2021-05-24 21:25   ` Drew Fustini
  3 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-17 16:58 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, drew, kernel test robot

Adds support for a generic GPIO multiplexer. To drive the multiplexer a
mux-controller is needed. The output pin of the multiplexer is a GPIO
pin.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig          |  16 +++++
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpio-mux-input.c | 124 ++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 drivers/gpio/gpio-mux-input.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1dd0ec6727fd..b7dd4ba59e6e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1657,4 +1657,20 @@ config GPIO_MOCKUP
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_MUX_INPUT
+	tristate "General GPIO input multiplexer"
+	depends on OF_GPIO
+	select MULTIPLEXER
+	select MUX_GPIO
+	help
+	  Say yes here to enable support for generic GPIO input multiplexer.
+
+  	  This driver uses a mux-controller to drive the multiplexer and has a
+  	  single output pin for reading the inputs to the mux. The driver can be
+  	  used in situations when GPIO pins are used to select what multiplexer
+  	  pin should be used for reading input and the output pin of the
+  	  multiplexer is connected to a GPIO input pin.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d7c81e1611a4..ff2b530d8ef4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_GPIO_MPC5200)		+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
 obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
new file mode 100644
index 000000000000..3c41e6f47012
--- /dev/null
+++ b/drivers/gpio/gpio-mux-input.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO input multiplexer driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_mux_input {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*mux_pin;
+};
+
+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_mux_input, gpio_chip);
+}
+
+static int gpio_mux_input_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_mux_input *mux;
+	int ret;
+
+	mux = gpio_to_mux(gc);
+	ret = mux_control_select(mux->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(mux->mux_pin);
+	mux_control_deselect(mux->mux_control);
+	return ret;
+}
+
+static int gpio_mux_input_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct gpio_mux_input *mux;
+	struct mux_control *mc;
+	struct gpio_desc *pin;
+	struct gpio_chip *gc;
+	int err;
+
+	mux = devm_kzalloc(dev, sizeof(struct gpio_mux_input), GFP_KERNEL);
+	if (mux == NULL)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "unable to get mux-control: %d\n", err);
+		return err;
+	}
+
+	mux->mux_control = mc;
+	pin = devm_gpiod_get(dev, "pin",  GPIOD_IN);
+	if (IS_ERR(pin)) {
+		err = (int) PTR_ERR(pin);
+		dev_err(dev, "unable to claim output pin: %d\n", err);
+		return err;
+	}
+
+	mux->mux_pin = pin;
+	mux->parent = dev;
+
+	gc = &mux->gpio_chip;
+	gc->get = gpio_mux_input_get_value;
+	gc->get_direction = gpio_mux_input_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(mux->parent);
+	gc->parent = mux->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&mux->gpio_chip);
+	if (err) {
+		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, mux);
+	dev_info(dev, "registered %u input GPIOs\n", gc->ngpio);
+	return 0;
+}
+
+static const struct of_device_id gpio_mux_input_id[] = {
+	{
+		.compatible = "gpio-mux-input",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
+
+static struct platform_driver gpio_mux_input_driver = {
+	.driver	= {
+		.name		= "gpio-mux-input",
+		.of_match_table = gpio_mux_input_id,
+	},
+	.probe	= gpio_mux_input_probe,
+};
+module_platform_driver(gpio_mux_input_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <sandberg@mailfence.com>");
+MODULE_DESCRIPTION("Generic GPIO input multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 0/2] gpio: add generic gpio input multiplexer
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
  2021-05-17 16:58   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-05-17 16:58   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
@ 2021-05-17 22:13   ` Drew Fustini
  2021-05-28  0:23     ` Linus Walleij
  2021-05-24 21:25   ` Drew Fustini
  3 siblings, 1 reply; 62+ messages in thread
From: Drew Fustini @ 2021-05-17 22:13 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij, linux-gpio

On Mon, May 17, 2021 at 07:58:45PM +0300, Mauri Sandberg wrote:
> Hello all!
> 
> This patch set is closely related to another thread at [4], which I abandoned
> against better judgement and created this one.
> 
> Here I am sending revised versions of the patches. It builds on v2 and adopts 
> managed device resources as suggested by Andy on the thread mentioned
> above [5].
> 
> I have tested the functionality on a NXP 74HC153 dual 4-way muxer. Drew, did
> you find the time to have a go with this [6] and if so, did it work as expected?

I ordered the parts but did not get around to trying it.  I will try it
out tomorrow with this patch series.

Thanks,
Drew


^ permalink raw reply	[flat|nested] 62+ messages in thread

* RESEND PATCH v3
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (3 preceding siblings ...)
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
@ 2021-05-24 16:29 ` Mauri Sandberg
  2021-05-24 16:29   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
                     ` (2 more replies)
  2021-05-30 16:13 ` [PATCH v4 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (5 subsequent siblings)
  10 siblings, 3 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-24 16:29 UTC (permalink / raw)
  To: linux-gpio; +Cc: bgolaszewski

For some reason Bart did not get the patches with the previous email. So
resending.

-- Mauri



^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
@ 2021-05-24 16:29   ` Mauri Sandberg
  2021-05-24 16:29   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-05-24 21:29   ` RESEND PATCH v3 Drew Fustini
  2 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-24 16:29 UTC (permalink / raw)
  To: linux-gpio; +Cc: bgolaszewski, Mauri Sandberg

Add documentation for a general GPIO multiplexer.

Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
new file mode 100644
index 000000000000..a7ff5d1fd6f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO input multiplexer
+
+maintainers:
+  - Mauri Sandberg <sandberg@mailfence.com>
+
+description: |
+  A generic GPIO based input multiplexer
+
+  This driver uses a mux-controller to drive the multiplexer and has a single
+  output pin for reading the inputs to the mux.
+
+  For GPIO consumer documentation see gpio.txt.
+
+properties:
+  compatible:
+    enum:
+      - gpio-mux-input
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  pin-gpios:
+    description: |
+      The GPIO pin used as the output from the multiplexer
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - pin-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
  2021-05-24 16:29   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-05-24 16:29   ` Mauri Sandberg
  2021-05-24 21:29   ` RESEND PATCH v3 Drew Fustini
  2 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-24 16:29 UTC (permalink / raw)
  To: linux-gpio; +Cc: bgolaszewski, Mauri Sandberg, kernel test robot

Adds support for a generic GPIO multiplexer. To drive the multiplexer a
mux-controller is needed. The output pin of the multiplexer is a GPIO
pin.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
---
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig          |  16 +++++
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpio-mux-input.c | 124 ++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 drivers/gpio/gpio-mux-input.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1dd0ec6727fd..b7dd4ba59e6e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1657,4 +1657,20 @@ config GPIO_MOCKUP
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_MUX_INPUT
+	tristate "General GPIO input multiplexer"
+	depends on OF_GPIO
+	select MULTIPLEXER
+	select MUX_GPIO
+	help
+	  Say yes here to enable support for generic GPIO input multiplexer.
+
+  	  This driver uses a mux-controller to drive the multiplexer and has a
+  	  single output pin for reading the inputs to the mux. The driver can be
+  	  used in situations when GPIO pins are used to select what multiplexer
+  	  pin should be used for reading input and the output pin of the
+  	  multiplexer is connected to a GPIO input pin.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d7c81e1611a4..ff2b530d8ef4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_GPIO_MPC5200)		+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
 obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
new file mode 100644
index 000000000000..3c41e6f47012
--- /dev/null
+++ b/drivers/gpio/gpio-mux-input.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO input multiplexer driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_mux_input {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*mux_pin;
+};
+
+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_mux_input, gpio_chip);
+}
+
+static int gpio_mux_input_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_mux_input *mux;
+	int ret;
+
+	mux = gpio_to_mux(gc);
+	ret = mux_control_select(mux->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(mux->mux_pin);
+	mux_control_deselect(mux->mux_control);
+	return ret;
+}
+
+static int gpio_mux_input_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct gpio_mux_input *mux;
+	struct mux_control *mc;
+	struct gpio_desc *pin;
+	struct gpio_chip *gc;
+	int err;
+
+	mux = devm_kzalloc(dev, sizeof(struct gpio_mux_input), GFP_KERNEL);
+	if (mux == NULL)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "unable to get mux-control: %d\n", err);
+		return err;
+	}
+
+	mux->mux_control = mc;
+	pin = devm_gpiod_get(dev, "pin",  GPIOD_IN);
+	if (IS_ERR(pin)) {
+		err = (int) PTR_ERR(pin);
+		dev_err(dev, "unable to claim output pin: %d\n", err);
+		return err;
+	}
+
+	mux->mux_pin = pin;
+	mux->parent = dev;
+
+	gc = &mux->gpio_chip;
+	gc->get = gpio_mux_input_get_value;
+	gc->get_direction = gpio_mux_input_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(mux->parent);
+	gc->parent = mux->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&mux->gpio_chip);
+	if (err) {
+		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, mux);
+	dev_info(dev, "registered %u input GPIOs\n", gc->ngpio);
+	return 0;
+}
+
+static const struct of_device_id gpio_mux_input_id[] = {
+	{
+		.compatible = "gpio-mux-input",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
+
+static struct platform_driver gpio_mux_input_driver = {
+	.driver	= {
+		.name		= "gpio-mux-input",
+		.of_match_table = gpio_mux_input_id,
+	},
+	.probe	= gpio_mux_input_probe,
+};
+module_platform_driver(gpio_mux_input_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <sandberg@mailfence.com>");
+MODULE_DESCRIPTION("Generic GPIO input multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 0/2] gpio: add generic gpio input multiplexer
  2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
                     ` (2 preceding siblings ...)
  2021-05-17 22:13   ` [PATCH v3 0/2] gpio: " Drew Fustini
@ 2021-05-24 21:25   ` Drew Fustini
  3 siblings, 0 replies; 62+ messages in thread
From: Drew Fustini @ 2021-05-24 21:25 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij, linux-gpio

On Mon, May 17, 2021 at 07:58:45PM +0300, Mauri Sandberg wrote:
> Hello all!
> 
> This patch set is closely related to another thread at [4], which I abandoned
> against better judgement and created this one.
> 
> Here I am sending revised versions of the patches. It builds on v2 and adopts 
> managed device resources as suggested by Andy on the thread mentioned
> above [5].
> 
> I have tested the functionality on a NXP 74HC153 dual 4-way muxer. Drew, did
> you find the time to have a go with this [6] and if so, did it work as expected?
> 
> Thanks,
> Mauri
> 
> [4] https://www.spinics.net/lists/linux-gpio/msg58573.html
> [5] https://www.spinics.net/lists/linux-gpio/msg60160.html
> [6] https://www.spinics.net/lists/linux-gpio/msg60159.html
> 
> 
> Mauri Sandberg (2):
>   dt-bindings: gpio-mux-input: add documentation
>   gpio: gpio-mux-input: add generic gpio input multiplexer
> 
>  .../bindings/gpio/gpio-mux-input.yaml         |  75 +++++++++++
>  drivers/gpio/Kconfig                          |  16 +++
>  drivers/gpio/Makefile                         |   1 +
>  drivers/gpio/gpio-mux-input.c                 | 124 ++++++++++++++++++
>  4 files changed, 216 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
>  create mode 100644 drivers/gpio/gpio-mux-input.c
> 
> 
> base-commit: 6453b9532b5f77d19837b159c4d074f0af9f141b
> -- 
> 2.25.1

Tested-by: Drew Fustini <drew@beagleboard.org>
Reviewed-by: Drew Fustini <drew@beagleboard.org>

I have wired up the TI CD74HC153E to a BeagleBone Black:

  S0: P8_7
  S1: P8_8

  1Y: P8_10
  2Y: P8_9

I added this to arch/arm/boot/dts/am335x-boneblack.dts

  mux: mux-controller {
          compatible = "gpio-mux";
          #mux-control-cells = <0>;

          mux-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>, /* S0: P8_7 */
                      <&gpio2 3 GPIO_ACTIVE_HIGH>  /* S1: P8_8 */;
  };

  gpio8: key-mux1 {
          compatible = "gpio-mux-input";
          mux-controls = <&mux>;

          gpio-controller;
          #gpio-cells = <2>;

          // GPIOs used by this node, mux pin
          pin-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* 2Y: P8_9 */
  };

  gpio9: key-mux2 {
          compatible = "gpio-mux-input";
          mux-controls = <&mux>;

          gpio-controller;
          #gpio-cells = <2>;

          // GPIOs used by this node, mux pin
          pin-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; /* 1Y: P8_10 */
  };


The two new gpiochips appear:

  root@beaglebone:~# gpiodetect
  gpiochip0 [gpio-0-31] (32 lines)
  gpiochip1 [gpio-32-63] (32 lines)
  gpiochip2 [gpio-64-95] (32 lines)
  gpiochip3 [gpio-96-127] (32 lines)
  gpiochip4 [key-mux1] (4 lines)
  gpiochip5 [key-mux2] (4 lines)
  
The mux pins and input pins are connected to lines on gpiochip1:

  debian@beaglebone:~$ gpioinfo 1
  gpiochip1 - 32 lines:
	  line   0:     "P9_15B"       unused   input  active-high
	  line   1:      "P8_18"       unused   input  active-high
	  line   2:       "P8_7"        "mux"  output  active-high [used]
	  line   3:       "P8_8"        "mux"  output  active-high [used]
	  line   4:      "P8_10"        "pin"   input  active-high [used]
	  line   5:       "P8_9"        "pin"   input  active-high [used]
  <snip>
  

Test with all inputs connected to 3.3V (1I0:1I3 and 2I0:2I3)

  debian@beaglebone:~$ gpioget 4 0
  1
  debian@beaglebone:~$ gpioget 4 1
  1
  debian@beaglebone:~$ gpioget 4 2
  1
  debian@beaglebone:~$ gpioget 4 3
  1
  debian@beaglebone:~$ gpioget 5 0
  1
  debian@beaglebone:~$ gpioget 5 1
  1
  debian@beaglebone:~$ gpioget 5 2
  1
  debian@beaglebone:~$ gpioget 5 3
  1

Connect 1I0 to GND

  debian@beaglebone:~$ gpioget 4 0
  0

Connect 1I0 to 3V3

  debian@beaglebone:~$ gpioget 4 0
  1

I tried this with all the rest and got the same succesfull results.

thanks,
drew

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: RESEND PATCH v3
  2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
  2021-05-24 16:29   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-05-24 16:29   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
@ 2021-05-24 21:29   ` Drew Fustini
  2 siblings, 0 replies; 62+ messages in thread
From: Drew Fustini @ 2021-05-24 21:29 UTC (permalink / raw)
  To: Mauri Sandberg; +Cc: linux-gpio, bgolaszewski

On Mon, May 24, 2021 at 07:29:04PM +0300, Mauri Sandberg wrote:
> For some reason Bart did not get the patches with the previous email. So
> resending.
> 
> -- Mauri
> 
> 

Tested-by: Drew Fustini <drew@beagleboard.org>
Reviewed-by: Drew Fustini <drew@beagleboard.org>

I just replied to the original v3 cover letter with my test results [1].

-Drew

[1] https://lore.kernel.org/linux-gpio/20210524212538.GA3756746@x1/

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 0/2] gpio: add generic gpio input multiplexer
  2021-05-17 22:13   ` [PATCH v3 0/2] gpio: " Drew Fustini
@ 2021-05-28  0:23     ` Linus Walleij
  2021-05-28  0:27       ` Drew Fustini
  0 siblings, 1 reply; 62+ messages in thread
From: Linus Walleij @ 2021-05-28  0:23 UTC (permalink / raw)
  To: Drew Fustini
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM

I can't see the mails in this RFC series but it looks interesting and quite
useful.

Looking forward to the next posting.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 0/2] gpio: add generic gpio input multiplexer
  2021-05-28  0:23     ` Linus Walleij
@ 2021-05-28  0:27       ` Drew Fustini
  0 siblings, 0 replies; 62+ messages in thread
From: Drew Fustini @ 2021-05-28  0:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM

On Thu, May 27, 2021 at 5:23 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> I can't see the mails in this RFC series but it looks interesting and quite
> useful.
>
> Looking forward to the next posting.
>
> Yours,
> Linus Walleij

That is too bad.  Hopefully Mauri can repost.  Here it is on lore:
https://lore.kernel.org/linux-gpio/20210325122832.119147-1-sandberg@mailfence.com/

I tested it successfully on a BeagleBone Black with a TI CD74HC153E:
https://lore.kernel.org/linux-gpio/20210524212538.GA3756746@x1/

thanks,
drew

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v4 0/2] gpio: add generic gpio input multiplexer
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (4 preceding siblings ...)
  2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
@ 2021-05-30 16:13 ` Mauri Sandberg
  2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-05-30 16:13   ` [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-06-21 17:20 ` [PATCH v5 0/2] gpio: add generic gpio cascade Mauri Sandberg
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-30 16:13 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Hello all!

I changed my email setup because there were serious issues with it
previously and patches were not delivered to people. Hopefully it's working
now. Because of that I am sending updated patches in v4, which consist of
the same functionality as in v3 added with cosmetic changes to Kconfig and
updated author email address.

Drew gave acked and tested-by tags in [1] so I took the liberty to include
them in the patches.

For convenience I am including also rangediff between v3 and v4 below.

Thanks,
Mauri

[1] https://www.spinics.net/lists/linux-gpio/msg61277.html

1:  1ca26bb53ab6 ! 1:  496558967cd8 dt-bindings: gpio-mux-input: add documentation
    @@
      ## Metadata ##
    -Author: Mauri Sandberg <sandberg@mailfence.com>
    +Author: Mauri Sandberg <maukka@ext.kapsi.fi>
     
      ## Commit message ##
         dt-bindings: gpio-mux-input: add documentation
     
         Add documentation for a general GPIO multiplexer.
     
    -    Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
    +    Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    +    Tested-by: Drew Fustini <drew@beagleboard.org>
    +    Reviewed-by: Drew Fustini <drew@beagleboard.org>
         ---
    +    v3 -> v4:
    +     - Changed author email
    +     - Included Tested-by and Reviewed-by from Drew
         v2 -> v3: added a complete example on dual 4-way multiplexer
         v1 -> v2: added a little bit more text in the binding documenation
     
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +title: Generic GPIO input multiplexer
     +
     +maintainers:
    -+  - Mauri Sandberg <sandberg@mailfence.com>
    ++  - Mauri Sandberg <maukka@ext.kapsi.fi>
     +
     +description: |
     +  A generic GPIO based input multiplexer
2:  dcd76ada9d34 ! 2:  782e009ba54b gpio: gpio-mux-input: add generic gpio input multiplexer
    @@
      ## Metadata ##
    -Author: Mauri Sandberg <sandberg@mailfence.com>
    +Author: Mauri Sandberg <maukka@ext.kapsi.fi>
     
      ## Commit message ##
         gpio: gpio-mux-input: add generic gpio input multiplexer
    @@ Commit message
         pin.
     
         Reported-by: kernel test robot <lkp@intel.com>
    -    Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
    +    Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    +    Tested-by: Drew Fustini <drew@beagleboard.org>
    +    Reviewed-by: Drew Fustini <drew@beagleboard.org>
         ---
    +    v3 -> v4:
    +     - Changed author email
    +     - Included Tested-by and Reviewed-by from Drew
         v2 -> v3:
          - use managed device resources
          - update Kconfig description
    @@ drivers/gpio/Kconfig: config GPIO_MOCKUP
     +	help
     +	  Say yes here to enable support for generic GPIO input multiplexer.
     +
    -+  	  This driver uses a mux-controller to drive the multiplexer and has a
    -+  	  single output pin for reading the inputs to the mux. The driver can be
    -+  	  used in situations when GPIO pins are used to select what multiplexer
    -+  	  pin should be used for reading input and the output pin of the
    -+  	  multiplexer is connected to a GPIO input pin.
    ++	  This driver uses a mux-controller to drive the multiplexer and has a
    ++	  single output pin for reading the inputs to the mux. The driver can
    ++	  be used in situations when GPIO pins are used to select what
    ++	  multiplexer pin should be used for reading input and the output pin
    ++	  of the multiplexer is connected to a GPIO input pin.
     +
      endif
     
    @@ drivers/gpio/gpio-mux-input.c (new)
     +/*
     + *  A generic GPIO input multiplexer driver
     + *
    -+ *  Copyright (C) 2021 Mauri Sandberg <sandberg@mailfence.com>
    ++ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
     + *
     + */
     +
    @@ drivers/gpio/gpio-mux-input.c (new)
     +};
     +module_platform_driver(gpio_mux_input_driver);
     +
    -+MODULE_AUTHOR("Mauri Sandberg <sandberg@mailfence.com>");
    ++MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
     +MODULE_DESCRIPTION("Generic GPIO input multiplexer");
     +MODULE_LICENSE("GPL");

Mauri Sandberg (2):
  dt-bindings: gpio-mux-input: add documentation
  gpio: gpio-mux-input: add generic gpio input multiplexer

 .../bindings/gpio/gpio-mux-input.yaml         |  75 +++++++++++
 drivers/gpio/Kconfig                          |  16 +++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-mux-input.c                 | 124 ++++++++++++++++++
 4 files changed, 216 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
 create mode 100644 drivers/gpio/gpio-mux-input.c


base-commit: c354c29524eeabba63da51f30a09b85ec9dc853a
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-30 16:13 ` [PATCH v4 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
@ 2021-05-30 16:13   ` Mauri Sandberg
  2021-06-01 10:10     ` Linus Walleij
                       ` (2 more replies)
  2021-05-30 16:13   ` [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  1 sibling, 3 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-30 16:13 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Add documentation for a general GPIO multiplexer.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Tested-by: Drew Fustini <drew@beagleboard.org>
Reviewed-by: Drew Fustini <drew@beagleboard.org>
---
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
new file mode 100644
index 000000000000..1ca4c3c8d64b
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO input multiplexer
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO based input multiplexer
+
+  This driver uses a mux-controller to drive the multiplexer and has a single
+  output pin for reading the inputs to the mux.
+
+  For GPIO consumer documentation see gpio.txt.
+
+properties:
+  compatible:
+    enum:
+      - gpio-mux-input
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  pin-gpios:
+    description: |
+      The GPIO pin used as the output from the multiplexer
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - pin-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-mux-input";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, mux pin
+        pin-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 16:13 ` [PATCH v4 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
  2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-05-30 16:13   ` Mauri Sandberg
  2021-05-30 18:09     ` Andy Shevchenko
  2021-06-01 10:38     ` Linus Walleij
  1 sibling, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-30 16:13 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg, kernel test robot

Adds support for a generic GPIO multiplexer. To drive the multiplexer a
mux-controller is needed. The output pin of the multiplexer is a GPIO
pin.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Tested-by: Drew Fustini <drew@beagleboard.org>
Reviewed-by: Drew Fustini <drew@beagleboard.org>
---
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig          |  16 +++++
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpio-mux-input.c | 124 ++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 drivers/gpio/gpio-mux-input.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1dd0ec6727fd..8a41a283ba42 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1657,4 +1657,20 @@ config GPIO_MOCKUP
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_MUX_INPUT
+	tristate "General GPIO input multiplexer"
+	depends on OF_GPIO
+	select MULTIPLEXER
+	select MUX_GPIO
+	help
+	  Say yes here to enable support for generic GPIO input multiplexer.
+
+	  This driver uses a mux-controller to drive the multiplexer and has a
+	  single output pin for reading the inputs to the mux. The driver can
+	  be used in situations when GPIO pins are used to select what
+	  multiplexer pin should be used for reading input and the output pin
+	  of the multiplexer is connected to a GPIO input pin.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d7c81e1611a4..ff2b530d8ef4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_GPIO_MPC5200)		+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
 obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mux-input.c b/drivers/gpio/gpio-mux-input.c
new file mode 100644
index 000000000000..e0739640541e
--- /dev/null
+++ b/drivers/gpio/gpio-mux-input.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO input multiplexer driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_mux_input {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*mux_pin;
+};
+
+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_mux_input, gpio_chip);
+}
+
+static int gpio_mux_input_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_mux_input *mux;
+	int ret;
+
+	mux = gpio_to_mux(gc);
+	ret = mux_control_select(mux->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(mux->mux_pin);
+	mux_control_deselect(mux->mux_control);
+	return ret;
+}
+
+static int gpio_mux_input_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct gpio_mux_input *mux;
+	struct mux_control *mc;
+	struct gpio_desc *pin;
+	struct gpio_chip *gc;
+	int err;
+
+	mux = devm_kzalloc(dev, sizeof(struct gpio_mux_input), GFP_KERNEL);
+	if (mux == NULL)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "unable to get mux-control: %d\n", err);
+		return err;
+	}
+
+	mux->mux_control = mc;
+	pin = devm_gpiod_get(dev, "pin",  GPIOD_IN);
+	if (IS_ERR(pin)) {
+		err = (int) PTR_ERR(pin);
+		dev_err(dev, "unable to claim output pin: %d\n", err);
+		return err;
+	}
+
+	mux->mux_pin = pin;
+	mux->parent = dev;
+
+	gc = &mux->gpio_chip;
+	gc->get = gpio_mux_input_get_value;
+	gc->get_direction = gpio_mux_input_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(mux->parent);
+	gc->parent = mux->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&mux->gpio_chip);
+	if (err) {
+		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, mux);
+	dev_info(dev, "registered %u input GPIOs\n", gc->ngpio);
+	return 0;
+}
+
+static const struct of_device_id gpio_mux_input_id[] = {
+	{
+		.compatible = "gpio-mux-input",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
+
+static struct platform_driver gpio_mux_input_driver = {
+	.driver	= {
+		.name		= "gpio-mux-input",
+		.of_match_table = gpio_mux_input_id,
+	},
+	.probe	= gpio_mux_input_probe,
+};
+module_platform_driver(gpio_mux_input_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO input multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 16:13   ` [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
@ 2021-05-30 18:09     ` Andy Shevchenko
  2021-05-30 19:02       ` Mauri Sandberg
  2021-06-01 10:38     ` Linus Walleij
  1 sibling, 1 reply; 62+ messages in thread
From: Andy Shevchenko @ 2021-05-30 18:09 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: sandberg, bgolaszewski, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, kernel test robot

On Sun, May 30, 2021 at 7:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>
> Adds support for a generic GPIO multiplexer. To drive the multiplexer a
> mux-controller is needed. The output pin of the multiplexer is a GPIO
> pin.
>
> Reported-by: kernel test robot <lkp@intel.com>

Is it a fix? Shall we add the Fixes tag?

> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Tested-by: Drew Fustini <drew@beagleboard.org>
> Reviewed-by: Drew Fustini <drew@beagleboard.org>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 18:09     ` Andy Shevchenko
@ 2021-05-30 19:02       ` Mauri Sandberg
  2021-05-30 19:38         ` Andy Shevchenko
  0 siblings, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-30 19:02 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: sandberg, bgolaszewski, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, kernel test robot


On 30.5.2021 21.09, Andy Shevchenko wrote:
> On Sun, May 30, 2021 at 7:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>> Adds support for a generic GPIO multiplexer. To drive the multiplexer a
>> mux-controller is needed. The output pin of the multiplexer is a GPIO
>> pin.
>>
>> Reported-by: kernel test robot <lkp@intel.com>
> Is it a fix? Shall we add the Fixes tag?

In the v1 a build bot complained about .owner along these lines:

--- snip ----
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


cocci warnings: (new ones prefixed by >>)
 >> drivers/gpio/gpio-mux-input.c:138:3-8: No need to set .owner here. 
The core will do it.

Please review and possibly fold the followup patch.
--- snip ---

I removed the .owner attribute in v2 as requested but wasn't really sure 
whether it was "appropriate"
to add the tag so I put it there anyhow. Technically, this does not fix 
any previous commit.

>> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
>> Tested-by: Drew Fustini <drew@beagleboard.org>
>> Reviewed-by: Drew Fustini <drew@beagleboard.org>
>

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 19:02       ` Mauri Sandberg
@ 2021-05-30 19:38         ` Andy Shevchenko
  2021-05-31 10:19           ` Mauri Sandberg
  0 siblings, 1 reply; 62+ messages in thread
From: Andy Shevchenko @ 2021-05-30 19:38 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: sandberg, bgolaszewski, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, kernel test robot

On Sun, May 30, 2021 at 10:02 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
> On 30.5.2021 21.09, Andy Shevchenko wrote:
> > On Sun, May 30, 2021 at 7:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> >> Reported-by: kernel test robot <lkp@intel.com>
> > Is it a fix? Shall we add the Fixes tag?
>
> In the v1 a build bot complained about .owner along these lines:
>
> --- snip ----
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
>
> cocci warnings: (new ones prefixed by >>)
>  >> drivers/gpio/gpio-mux-input.c:138:3-8: No need to set .owner here.
> The core will do it.
>
> Please review and possibly fold the followup patch.
> --- snip ---
>
> I removed the .owner attribute in v2 as requested but wasn't really sure
> whether it was "appropriate"
> to add the tag so I put it there anyhow. Technically, this does not fix
> any previous commit.

For this kind of thing you may attribute the reporter(s) by mentioning
them in the comment lines / cover letter.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 19:38         ` Andy Shevchenko
@ 2021-05-31 10:19           ` Mauri Sandberg
  0 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-05-31 10:19 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: sandberg, bgolaszewski, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, kernel test robot


On 30.5.2021 22.38, Andy Shevchenko wrote:
> On Sun, May 30, 2021 at 10:02 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>> On 30.5.2021 21.09, Andy Shevchenko wrote:
>>> On Sun, May 30, 2021 at 7:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>>>> Reported-by: kernel test robot <lkp@intel.com>
>>> Is it a fix? Shall we add the Fixes tag?
>> In the v1 a build bot complained about .owner along these lines:
>>
>> --- snip ----
>> If you fix the issue, kindly add following tag as appropriate
>> Reported-by: kernel test robot <lkp@intel.com>
>>
>>
>> cocci warnings: (new ones prefixed by >>)
>>   >> drivers/gpio/gpio-mux-input.c:138:3-8: No need to set .owner here.
>> The core will do it.
>>
>> Please review and possibly fold the followup patch.
>> --- snip ---
>>
>> I removed the .owner attribute in v2 as requested but wasn't really sure
>> whether it was "appropriate"
>> to add the tag so I put it there anyhow. Technically, this does not fix
>> any previous commit.
> For this kind of thing you may attribute the reporter(s) by mentioning
> them in the comment lines / cover letter.
It's there in the patch version notes so the 'Reported-by' was 
unnecessary. Should it be removed?
That is, is there a tool sitting somwhere that tries to match reports 
and their fixes?


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
@ 2021-06-01 10:10     ` Linus Walleij
  2021-06-01 10:44     ` Linus Walleij
  2021-06-01 13:32     ` Rob Herring
  2 siblings, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2021-06-01 10:10 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

On Sun, May 30, 2021 at 6:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Add documentation for a general GPIO multiplexer.
>
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Tested-by: Drew Fustini <drew@beagleboard.org>
> Reviewed-by: Drew Fustini <drew@beagleboard.org>

Overall very interesting!

> +  pin-gpios:
> +    description: |
> +      The GPIO pin used as the output from the multiplexer

This is not a good name. "pin" what pin? Choose a descriptive
name, like:

parent-gpios
multiplexed-gpios
cascaded-gpios
fanout-gpios

(My order of preference.)

Otherwise these bindings look good.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer
  2021-05-30 16:13   ` [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
  2021-05-30 18:09     ` Andy Shevchenko
@ 2021-06-01 10:38     ` Linus Walleij
  1 sibling, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2021-06-01 10:38 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini, kernel test robot

On Sun, May 30, 2021 at 6:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Adds support for a generic GPIO multiplexer. To drive the multiplexer a
> mux-controller is needed. The output pin of the multiplexer is a GPIO
> pin.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Tested-by: Drew Fustini <drew@beagleboard.org>
> Reviewed-by: Drew Fustini <drew@beagleboard.org>

The commit message and part of the driver becomes hard to
read and understand because the word pin is overused.
Switch to talk about "gpio lines" rather than pins.

Draw a simple ASCII image like this:

               /|---- Cascaded GPIO line 0
              |M|---- Cascaded GPIO line 1
GPIO line ----+U| .
              |X| .
           \|---- Cascaded GPIO line n

Maybe also as illustration in the driver and in the bindings.
Make things easy to understand.

Explain exactly why only input lines can be multiplexed.

I'm not sure it should be restricted to just input
in theory, but since that is all we can test, restrict it to
input in practice.

> +config GPIO_MUX_INPUT
> +       tristate "General GPIO input multiplexer"

Rename it just GPIO_MUX
  "General GPIO multiplexer"

Then clarify in the help description that it currently can only
handle input lines.

> +       depends on OF_GPIO
> +       select MULTIPLEXER
> +       select MUX_GPIO
> +       help
> +         Say yes here to enable support for generic GPIO input multiplexer.
> +
> +         This driver uses a mux-controller to drive the multiplexer and has a
> +         single output pin for reading the inputs to the mux. The driver can
> +         be used in situations when GPIO pins are used to select what
> +         multiplexer pin should be used for reading input and the output pin
> +         of the multiplexer is connected to a GPIO input pin.

Input output etc, this gets very hard to understand.

Switch terminology from "pin" to "GPIO lines", (or "GPIO rails").

Use the word "routing" as the GPIO line is routed through the
multiplexer. Maybe spell out multiplexer for clarity.

Explain why, for electrical reasons, output lines are harder
to multiplex like this, as the output will not maintain
state. Notice that "using open drain constructions, output
multiplexing may be possible, but it is currently not implemented."

> +static int gpio_mux_input_get_direction(struct gpio_chip *gc,
> +                                       unsigned int offset)
> +{
> +       return GPIO_LINE_DIRECTION_IN;
> +}

Explain why this is a restriction with a comment in the code.
Add comment that in the future we might be able to handle
also output.

> +static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)

This looks very nice!

We might have to extend this driver at some point.

Intuitively I'd say it takes some time and then someone
comes along and say "actually we have done this
for output as well, using some open drain and stuff"
but this is a good starting point anyway we need no
big upfront designs.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-06-01 10:10     ` Linus Walleij
@ 2021-06-01 10:44     ` Linus Walleij
  2021-06-02  9:31       ` Mauri Sandberg
  2021-06-01 13:32     ` Rob Herring
  2 siblings, 1 reply; 62+ messages in thread
From: Linus Walleij @ 2021-06-01 10:44 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

On Sun, May 30, 2021 at 6:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Add documentation for a general GPIO multiplexer.
>
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Tested-by: Drew Fustini <drew@beagleboard.org>
> Reviewed-by: Drew Fustini <drew@beagleboard.org>

After some thinking I realized these bindings should not
be restricted to just input. There exist electronic constructions
such as open drain that would make it possible to mux also
outputs.

>  .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++

Rename it just gpio-mux.yaml

> +$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#

Also here

> +title: Generic GPIO input multiplexer

Generic GPIO multiplexer

> +description: |
> +  A generic GPIO based input multiplexer

Not just input

> +  This driver uses a mux-controller to drive the multiplexer and has a single
> +  output pin for reading the inputs to the mux.

Make this clearer and do not mention "driver".
Here is a suggestion:

This hardware construction multiplexes (cascades) several GPIO
lines from one-to-many using a software controlled multiplexer.
The most common use case is probably reading several inputs
by switching the multiplexer over several input lines, which in
practice works well since input lines has high impedance.

Constructions with multiplexed outputs are also possible using
open drain electronics.

> +  For GPIO consumer documentation see gpio.txt.

No need to mention this I think, not your problem :D

> +  pin-gpios:

I still want this renamed like in my previous mail.

Hope all is clear!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
  2021-06-01 10:10     ` Linus Walleij
  2021-06-01 10:44     ` Linus Walleij
@ 2021-06-01 13:32     ` Rob Herring
  2021-06-02 11:36       ` Mauri Sandberg
  2 siblings, 1 reply; 62+ messages in thread
From: Rob Herring @ 2021-06-01 13:32 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: linus.walleij, andy.shevchenko, sandberg, linux-gpio,
	geert+renesas, bgolaszewski, linux-kernel, drew, robh+dt,
	devicetree

On Sun, 30 May 2021 19:13:32 +0300, Mauri Sandberg wrote:
> Add documentation for a general GPIO multiplexer.
> 
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Tested-by: Drew Fustini <drew@beagleboard.org>
> Reviewed-by: Drew Fustini <drew@beagleboard.org>
> ---
> v3 -> v4:
>  - Changed author email
>  - Included Tested-by and Reviewed-by from Drew
> v2 -> v3: added a complete example on dual 4-way multiplexer
> v1 -> v2: added a little bit more text in the binding documenation
> ---
>  .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
>  1 file changed, 75 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml:0:0: /example-0/mux-controller: failed to match any schema with compatible: ['gpio-mux']
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml: key-mux1: 'mux-controls' does not match any of the regexes: 'pinctrl-[0-9]+'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml: key-mux2: 'mux-controls' does not match any of the regexes: 'pinctrl-[0-9]+'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml

See https://patchwork.ozlabs.org/patch/1485492

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-06-01 10:44     ` Linus Walleij
@ 2021-06-02  9:31       ` Mauri Sandberg
  2021-06-02 10:35         ` Linus Walleij
  0 siblings, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-02  9:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini


On 1.6.2021 13.44, Linus Walleij wrote:
> On Sun, May 30, 2021 at 6:16 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>
>> Add documentation for a general GPIO multiplexer.
>>
>> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
>> Tested-by: Drew Fustini <drew@beagleboard.org>
>> Reviewed-by: Drew Fustini <drew@beagleboard.org>
> After some thinking I realized these bindings should not
> be restricted to just input. There exist electronic constructions
> such as open drain that would make it possible to mux also
> outputs.
>
>>   .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
> Rename it just gpio-mux.yaml
>
>> +$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
> Also here
>
>> +title: Generic GPIO input multiplexer
> Generic GPIO multiplexer
>
>> +description: |
>> +  A generic GPIO based input multiplexer
> Not just input
>
>> +  This driver uses a mux-controller to drive the multiplexer and has a single
>> +  output pin for reading the inputs to the mux.
> Make this clearer and do not mention "driver".
> Here is a suggestion:
>
> This hardware construction multiplexes (cascades) several GPIO
> lines from one-to-many using a software controlled multiplexer.
> The most common use case is probably reading several inputs
> by switching the multiplexer over several input lines, which in
> practice works well since input lines has high impedance.
>
> Constructions with multiplexed outputs are also possible using
> open drain electronics.
>
>> +  For GPIO consumer documentation see gpio.txt.
> No need to mention this I think, not your problem :D
>
>> +  pin-gpios:
> I still want this renamed like in my previous mail.
>
> Hope all is clear!
>
> Yours,
> Linus Walleij

Hi and thanks the  comments.

Generally I agree with everything you noted above and elsewhere and will 
make changes
accordingly. But there is a small detail that needs to be sorted out. 
The name 'gpio-mux'
has already been taken by 'mux-gpio' driver [2] [3].

Should we look for another name for this driver and it's bindings or 
refactor the mux-gpio's bindings
first? I would be inclined to do the latter as the config symbol for 
mux-gpio is the same way around,
MUX_GPIO.

The bindings for mux-gpio need to be converted to .yaml anyhow and maybe 
the issues with the schema
that Rob pointed out elsewhere would go away too. Otherwise I cannot 
really say what's wrong as the
errors look unrelated to me.

-- Mauri

[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mux/gpio-mux.txt
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mux/gpio.c






^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-06-02  9:31       ` Mauri Sandberg
@ 2021-06-02 10:35         ` Linus Walleij
  2021-06-02 11:21           ` Mauri Sandberg
  0 siblings, 1 reply; 62+ messages in thread
From: Linus Walleij @ 2021-06-02 10:35 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

Hi Mauri,

On Wed, Jun 2, 2021 at 11:31 AM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> But there is a small detail that needs to be sorted out.
> The name 'gpio-mux'
> has already been taken by 'mux-gpio' driver [2] [3].

What about "gpio-multiplexer"?

It is not good that the thing using GPIOs to do multiplexing
has take a name that seem to infer that GPIOs are being
multiplexed. Now we can't do much about that we just have
to live with it. How typical of formal languages to screw
with the semantics of natural languages and create confusion...

> Should we look for another name for this driver and it's bindings or
> refactor the mux-gpio's bindings
> first?

Bindings are etched in stone and cannot be changed.
Unless we change them anyways.
But generally we can't.

> The bindings for mux-gpio need to be converted to .yaml anyhow

Yeah just do it if you have the time, all conversions are appreciated.
(Separate patch and work item though, don't know if you need to
mix that with this work?)

> and maybe
> the issues with the schema
> that Rob pointed out elsewhere would go away too. Otherwise I cannot
> really say what's wrong as the
> errors look unrelated to me.

I don't know about these, tell Rob if you have issues and I might
be able to pitch in, I write a fair amount of schema too.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-06-02 10:35         ` Linus Walleij
@ 2021-06-02 11:21           ` Mauri Sandberg
  2021-06-04  7:51             ` Linus Walleij
  0 siblings, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-02 11:21 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

Hi Linus,

On 2.6.2021 13.35, Linus Walleij wrote:
> On Wed, Jun 2, 2021 at 11:31 AM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
> 
>> But there is a small detail that needs to be sorted out.
>> The name 'gpio-mux'
>> has already been taken by 'mux-gpio' driver [2] [3].
> 
> What about "gpio-multiplexer"?
> 
> It is not good that the thing using GPIOs to do multiplexing
> has take a name that seem to infer that GPIOs are being
> multiplexed. Now we can't do much about that we just have
> to live with it. How typical of formal languages to screw
> with the semantics of natural languages and create confusion...
> 

I am afraid having 'gpio-mux' and 'gpio-multiplexer' would create too 
many what-were-they-thinking moments for any unfortunate reader so I 
would rather choose something else. Can we just call it 'gpio-cascade' 
without referral to the underlying mux? Maybe at somepoint in future 
something else could be used in its place too.

-- Mauri


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-06-01 13:32     ` Rob Herring
@ 2021-06-02 11:36       ` Mauri Sandberg
  0 siblings, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-02 11:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: linus.walleij, andy.shevchenko, sandberg, linux-gpio,
	geert+renesas, bgolaszewski, linux-kernel, drew, robh+dt,
	devicetree

Hi Rob,

On 1.6.2021 16.32, Rob Herring wrote:
> On Sun, 30 May 2021 19:13:32 +0300, Mauri Sandberg wrote:
>> Add documentation for a general GPIO multiplexer.
>>
>> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
>> Tested-by: Drew Fustini <drew@beagleboard.org>
>> Reviewed-by: Drew Fustini <drew@beagleboard.org>
>> ---
>> v3 -> v4:
>>   - Changed author email
>>   - Included Tested-by and Reviewed-by from Drew
>> v2 -> v3: added a complete example on dual 4-way multiplexer
>> v1 -> v2: added a little bit more text in the binding documenation
>> ---
>>   .../bindings/gpio/gpio-mux-input.yaml         | 75 +++++++++++++++++++
>>   1 file changed, 75 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
>>
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml:0:0: /example-0/mux-controller: failed to match any schema with compatible: ['gpio-mux']
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml: key-mux1: 'mux-controls' does not match any of the regexes: 'pinctrl-[0-9]+'
> 	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.example.dt.yaml: key-mux2: 'mux-controls' does not match any of the regexes: 'pinctrl-[0-9]+'
> 	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml
> 

These look like they could be caused by gpio-mux bindings [2], which 
this depends on, not being formulated in yaml. Should it be addressed 
before carrying on?

Thanks,
Mauri

[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mux/gpio-mux.txt


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation
  2021-06-02 11:21           ` Mauri Sandberg
@ 2021-06-04  7:51             ` Linus Walleij
  0 siblings, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2021-06-04  7:51 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

On Wed, Jun 2, 2021 at 1:21 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Can we just call it 'gpio-cascade'
> without referral to the underlying mux? Maybe at somepoint in future
> something else could be used in its place too.

That has a nice ring to it, go with that!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v5 0/2] gpio: add generic gpio cascade
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (5 preceding siblings ...)
  2021-05-30 16:13 ` [PATCH v4 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
@ 2021-06-21 17:20 ` Mauri Sandberg
  2021-06-21 17:20   ` [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
  2021-06-21 17:20   ` [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  2021-10-19 12:57 ` [PATCH v6 0/2] " Mauri Sandberg
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-21 17:20 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Hello all,

Thank you for your review comments so far. Here comes new attempt at the gpio
multiplexer driver. There are quite a lot of changes if you look at the diff
based on the v4. Functionality is still the same, though. Only renaming,
refactoring and some more documentation.

What was done
 - rename 'gpio-mux-input' -> 'gpio-cascade' in sources
 - bindings were changed to reflect the renaming
 - refactoring here and there, renaming variables
 - documentation was made simpler and more verbose

Drew: I chose to drop the Reviewed-by and Tested-by tags because, even though
mostly renaming, bindings were changed too and that affects functionality. If
you have the time, could you please have another look?

Linus: I hope the changes to the documentation were what you had in mind.

Rob: I fixed a couple of errors that you bot detected but one is due to missing
schema file (gpio-mux) and adding that is not in the scope of this work.

Andy: I dropped the Reported-by tag the bot had instructed me to add.

Thanks,
Mauri

diff between v4 and v5

1:  496558967cd8 ! 1:  83defaf33475 dt-bindings: gpio-mux-input: add documentation
    @@ Metadata
     Author: Mauri Sandberg <maukka@ext.kapsi.fi>
     
      ## Commit message ##
    -    dt-bindings: gpio-mux-input: add documentation
    +    dt-bindings: gpio-cascade: add documentation
     
    -    Add documentation for a general GPIO multiplexer.
    +    Add documentation for a general GPIO cascade. It allows building
    +    one-to-many cascades of GPIO lines using multiplexer to choose
    +    the cascaded line.
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    -    Tested-by: Drew Fustini <drew@beagleboard.org>
    -    Reviewed-by: Drew Fustini <drew@beagleboard.org>
         ---
    +    v4 -> v5:
    +     - renamed gpio-mux-input -> gpio-cascade
    +     - changed vague term 'pin' to 'upstream line'
    +     - added more verbose description for the module
    +     - added missing 'mux-controls' entry
    +     - dropped Tested-by and Reviewed-by due to changes in bindings
         v3 -> v4:
          - Changed author email
          - Included Tested-by and Reviewed-by from Drew
         v2 -> v3: added a complete example on dual 4-way multiplexer
         v1 -> v2: added a little bit more text in the binding documenation
     
    - ## Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new) ##
    + ## Documentation/devicetree/bindings/gpio/gpio-cascade.yaml (new) ##
     @@
     +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
     +%YAML 1.2
     +---
    -+$id: http://devicetree.org/schemas/gpio/gpio-mux-input.yaml#
    ++$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
     +$schema: http://devicetree.org/meta-schemas/core.yaml#
     +
    -+title: Generic GPIO input multiplexer
    ++title: Generic GPIO cascade
     +
     +maintainers:
     +  - Mauri Sandberg <maukka@ext.kapsi.fi>
     +
     +description: |
    -+  A generic GPIO based input multiplexer
    ++  A generic GPIO cascade
     +
    -+  This driver uses a mux-controller to drive the multiplexer and has a single
    -+  output pin for reading the inputs to the mux.
    ++  This hardware construction cascades (multiplexes) several GPIO lines from
    ++  one-to-many using a software controlled multiplexer. The most common use
    ++  case is probably reading several inputs by switching the multiplexer over
    ++  several input lines, which in practice works well since input lines has
    ++  high impedance.
     +
    -+  For GPIO consumer documentation see gpio.txt.
    ++  Constructions with multiplexed outputs are also possible using open drain
    ++  electronics.
    ++
    ++  The number of cascaded GPIO lines is limited by the technology used to
    ++  switch over the cascaded lines. There are readily available dual/triple
    ++  4-to-1 multiplexers, for example, and others.
    ++
    ++  Illustration (pins used to drive the multiplexer are omitted for clarity)
    ++
    ++                 /|---- Cascaded GPIO line 0
    ++  Upstream      | |---- Cascaded GPIO line 1
    ++  GPIO line ----+ | .
    ++                | | .
    ++                 \|---- Cascaded GPIO line n
     +
     +properties:
     +  compatible:
     +    enum:
    -+      - gpio-mux-input
    ++      - gpio-cascade
     +
     +  gpio-controller: true
     +
     +  '#gpio-cells':
     +    const: 2
     +
    -+  pin-gpios:
    ++  mux-controls:
    ++    minItems: 1
    ++    maxItems: 1
     +    description: |
    -+      The GPIO pin used as the output from the multiplexer
    ++      The mux controller that will be driving the GPIO cascade.
    ++
    ++  upstream-gpios:
    ++    description: |
    ++      The GPIO line used as the upstream line will convey the status to/from
    ++      cascaded GPIO lines. In an input mode, by using this line, it is
    ++      possible to read the status from selected cascaded GPIO line.
    ++
    ++      In an output mode the status of the upstream GPIO will be conveyed to
    ++      the selected cascaded GPIO line.
     +
     +required:
     +  - compatible
     +  - gpio-controller
     +  - "#gpio-cells"
    -+  - pin-gpios
    ++  - mux-controls
    ++  - upstream-gpios
     +
     +additionalProperties: false
     +
    @@ Documentation/devicetree/bindings/gpio/gpio-mux-input.yaml (new)
     +    };
     +
     +    gpio2: key-mux1 {
    -+        compatible = "gpio-mux-input";
    ++        compatible = "gpio-cascade";
     +        mux-controls = <&mux>;
     +
     +        gpio-controller;
     +        #gpio-cells = <2>;
     +
    -+        // GPIOs used by this node, mux pin
    -+        pin-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
    ++        // GPIOs used by this node, upstream pin
    ++        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
     +    };
     +
     +    gpio3: key-mux2 {
    -+        compatible = "gpio-mux-input";
    ++        compatible = "gpio-cascade";
     +        mux-controls = <&mux>;
     +
     +        gpio-controller;
     +        #gpio-cells = <2>;
     +
    -+        // GPIOs used by this node, mux pin
    -+        pin-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
    ++        // GPIOs used by this node, upstream pin
    ++        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
     +    };
     +
     +...
2:  782e009ba54b ! 2:  d1063611d6ac gpio: gpio-mux-input: add generic gpio input multiplexer
    @@ Metadata
     Author: Mauri Sandberg <maukka@ext.kapsi.fi>
     
      ## Commit message ##
    -    gpio: gpio-mux-input: add generic gpio input multiplexer
    +    gpio: gpio-cascade: add generic GPIO cascade
     
    -    Adds support for a generic GPIO multiplexer. To drive the multiplexer a
    -    mux-controller is needed. The output pin of the multiplexer is a GPIO
    -    pin.
    +    Adds support for a building cascades of GPIO lines. That is, it allows
    +    setups when there is one upstream line and multiple cascaded lines, out
    +    of which one can be chosen at a time. The status of the upstream line
    +    can be conveyd to the selected cascaded line or, vice versa, the status
    +    of the cascaded line can be conveyed to the upstream line.
    +
    +    A gpio-mux is being used to select, which cascaded GPIO line is being
    +    used at any given time.
    +
    +    At the moment only input direction is supported. In future it should be
    +    possible to add support for output direction, too.
     
    -    Reported-by: kernel test robot <lkp@intel.com>
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    -    Tested-by: Drew Fustini <drew@beagleboard.org>
    -    Reviewed-by: Drew Fustini <drew@beagleboard.org>
         ---
    +    v4 -> v5:
    +     - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
    +       here and there and changed to use new bindings and compatible string
    +       - ambigious and vague 'pin' was rename to 'upstream_line'
    +     - dropped Tested-by and Reviewed-by due to changes in bindings
    +     - dropped Reported-by suggested by an automatic bot as it was not really
    +       appropriate to begin with
    +     - functionally it's the same as v4
         v3 -> v4:
          - Changed author email
          - Included Tested-by and Reviewed-by from Drew
    @@ drivers/gpio/Kconfig: config GPIO_MOCKUP
      
     +comment "Other GPIO expanders"
     +
    -+config GPIO_MUX_INPUT
    -+	tristate "General GPIO input multiplexer"
    ++config GPIO_CASCADE
    ++	tristate "General GPIO cascade"
     +	depends on OF_GPIO
     +	select MULTIPLEXER
     +	select MUX_GPIO
     +	help
    -+	  Say yes here to enable support for generic GPIO input multiplexer.
    ++	  Say yes here to enable support for generic GPIO cascade.
     +
    -+	  This driver uses a mux-controller to drive the multiplexer and has a
    -+	  single output pin for reading the inputs to the mux. The driver can
    -+	  be used in situations when GPIO pins are used to select what
    -+	  multiplexer pin should be used for reading input and the output pin
    -+	  of the multiplexer is connected to a GPIO input pin.
    ++	  This allows building one-to-many cascades of GPIO lines using
    ++	  different types of multiplexers readily available. At the
    ++	  moment only input lines are supported.
     +
      endif
     
      ## drivers/gpio/Makefile ##
    -@@ drivers/gpio/Makefile: obj-$(CONFIG_GPIO_MPC5200)		+= gpio-mpc5200.o
    - obj-$(CONFIG_GPIO_MPC8XXX)		+= gpio-mpc8xxx.o
    - obj-$(CONFIG_GPIO_MSC313)		+= gpio-msc313.o
    - obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
    -+obj-$(CONFIG_GPIO_MUX_INPUT)		+= gpio-mux-input.o
    - obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
    - obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
    - obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
    +@@ drivers/gpio/Makefile: obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
    + obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
    + obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
    + obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
    ++obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
    + obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
    + obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
    + obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
     
    - ## drivers/gpio/gpio-mux-input.c (new) ##
    + ## drivers/gpio/gpio-cascade.c (new) ##
     @@
     +// SPDX-License-Identifier: GPL-2.0-only
     +/*
    -+ *  A generic GPIO input multiplexer driver
    ++ *  A generic GPIO cascade driver
     + *
     + *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
     + *
    ++ * This allows building cascades of GPIO lines in a manner illustrated
    ++ * below:
    ++ *
    ++ *                 /|---- Cascaded GPIO line 0
    ++ *  Upstream      | |---- Cascaded GPIO line 1
    ++ *  GPIO line ----+ | .
    ++ *                | | .
    ++ *                 \|---- Cascaded GPIO line n
    ++ *
    ++ * A gpio-mux is being used to select, which cascaded line is being
    ++ * addressed at any given time.
    ++ *
    ++ * At the moment only input mode is supported due to lack of means for
    ++ * testing output functionality. At least theoretically output should be
    ++ * possible with an open drain constructions.
     + */
     +
     +#include <linux/module.h>
    @@ drivers/gpio/gpio-mux-input.c (new)
     +#include <linux/platform_device.h>
     +#include <linux/mux/consumer.h>
     +
    -+struct gpio_mux_input {
    ++struct gpio_cascade {
     +	struct device		*parent;
     +	struct gpio_chip	gpio_chip;
     +	struct mux_control	*mux_control;
    -+	struct gpio_desc	*mux_pin;
    ++	struct gpio_desc	*upstream_line;
     +};
     +
    -+static struct gpio_mux_input *gpio_to_mux(struct gpio_chip *gc)
    ++static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
     +{
    -+	return container_of(gc, struct gpio_mux_input, gpio_chip);
    ++	return container_of(gc, struct gpio_cascade, gpio_chip);
     +}
     +
    -+static int gpio_mux_input_get_direction(struct gpio_chip *gc,
    ++static int gpio_cascade_get_direction(struct gpio_chip *gc,
     +					unsigned int offset)
     +{
     +	return GPIO_LINE_DIRECTION_IN;
     +}
     +
    -+static int gpio_mux_input_get_value(struct gpio_chip *gc, unsigned int offset)
    ++static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
     +{
    -+	struct gpio_mux_input *mux;
    ++	struct gpio_cascade *cas;
     +	int ret;
     +
    -+	mux = gpio_to_mux(gc);
    -+	ret = mux_control_select(mux->mux_control, offset);
    ++	cas = chip_to_cascade(gc);
    ++	ret = mux_control_select(cas->mux_control, offset);
     +	if (ret)
     +		return ret;
     +
    -+	ret = gpiod_get_value(mux->mux_pin);
    -+	mux_control_deselect(mux->mux_control);
    ++	ret = gpiod_get_value(cas->upstream_line);
    ++	mux_control_deselect(cas->mux_control);
     +	return ret;
     +}
     +
    -+static int gpio_mux_input_probe(struct platform_device *pdev)
    ++static int gpio_cascade_probe(struct platform_device *pdev)
     +{
     +	struct device_node *np = pdev->dev.of_node;
     +	struct device *dev = &pdev->dev;
    -+	struct gpio_mux_input *mux;
    ++	struct gpio_cascade *cas;
     +	struct mux_control *mc;
    -+	struct gpio_desc *pin;
    ++	struct gpio_desc *upstream;
     +	struct gpio_chip *gc;
     +	int err;
     +
    -+	mux = devm_kzalloc(dev, sizeof(struct gpio_mux_input), GFP_KERNEL);
    -+	if (mux == NULL)
    ++	cas = devm_kzalloc(dev, sizeof(struct gpio_cascade), GFP_KERNEL);
    ++	if (cas == NULL)
     +		return -ENOMEM;
     +
     +	mc = devm_mux_control_get(dev, NULL);
    @@ drivers/gpio/gpio-mux-input.c (new)
     +		return err;
     +	}
     +
    -+	mux->mux_control = mc;
    -+	pin = devm_gpiod_get(dev, "pin",  GPIOD_IN);
    -+	if (IS_ERR(pin)) {
    -+		err = (int) PTR_ERR(pin);
    -+		dev_err(dev, "unable to claim output pin: %d\n", err);
    ++	cas->mux_control = mc;
    ++	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
    ++	if (IS_ERR(upstream)) {
    ++		err = (int) PTR_ERR(upstream);
    ++		dev_err(dev, "unable to claim upstream GPIO line: %d\n", err);
     +		return err;
     +	}
     +
    -+	mux->mux_pin = pin;
    -+	mux->parent = dev;
    ++	cas->upstream_line = upstream;
    ++	cas->parent = dev;
     +
    -+	gc = &mux->gpio_chip;
    -+	gc->get = gpio_mux_input_get_value;
    -+	gc->get_direction = gpio_mux_input_get_direction;
    ++	gc = &cas->gpio_chip;
    ++	gc->get = gpio_cascade_get_value;
    ++	gc->get_direction = gpio_cascade_get_direction;
     +
     +	gc->base = -1;
     +	gc->ngpio = mux_control_states(mc);
    -+	gc->label = dev_name(mux->parent);
    -+	gc->parent = mux->parent;
    ++	gc->label = dev_name(cas->parent);
    ++	gc->parent = cas->parent;
     +	gc->owner = THIS_MODULE;
     +	gc->of_node = np;
     +
    -+	err = gpiochip_add(&mux->gpio_chip);
    ++	err = gpiochip_add(&cas->gpio_chip);
     +	if (err) {
     +		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
     +		return err;
     +	}
     +
    -+	platform_set_drvdata(pdev, mux);
    -+	dev_info(dev, "registered %u input GPIOs\n", gc->ngpio);
    ++	platform_set_drvdata(pdev, cas);
    ++	dev_info(dev, "registered %u cascaded GPIO lines\n", gc->ngpio);
     +	return 0;
     +}
     +
    -+static const struct of_device_id gpio_mux_input_id[] = {
    ++static const struct of_device_id gpio_cascade_id[] = {
     +	{
    -+		.compatible = "gpio-mux-input",
    ++		.compatible = "gpio-cascade",
     +		.data = NULL,
     +	},
     +	{ /* sentinel */ }
     +};
    -+MODULE_DEVICE_TABLE(of, gpio_mux_input_id);
    ++MODULE_DEVICE_TABLE(of, gpio_cascade_id);
     +
    -+static struct platform_driver gpio_mux_input_driver = {
    ++static struct platform_driver gpio_cascade_driver = {
     +	.driver	= {
    -+		.name		= "gpio-mux-input",
    -+		.of_match_table = gpio_mux_input_id,
    ++		.name		= "gpio-cascade",
    ++		.of_match_table = gpio_cascade_id,
     +	},
    -+	.probe	= gpio_mux_input_probe,
    ++	.probe	= gpio_cascade_probe,
     +};
    -+module_platform_driver(gpio_mux_input_driver);
    ++module_platform_driver(gpio_cascade_driver);
     +
     +MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
    -+MODULE_DESCRIPTION("Generic GPIO input multiplexer");
    ++MODULE_DESCRIPTION("Generic GPIO cascade");
     +MODULE_LICENSE("GPL");

Mauri Sandberg (2):
  dt-bindings: gpio-cascade: add documentation
  gpio: gpio-cascade: add generic GPIO cascade

 .../bindings/gpio/gpio-cascade.yaml           | 103 +++++++++++++
 drivers/gpio/Kconfig                          |  14 ++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cascade.c                   | 139 ++++++++++++++++++
 4 files changed, 257 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
 create mode 100644 drivers/gpio/gpio-cascade.c


base-commit: 6d49b3a0f351925b5ea5047166c112b7590b918a
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation
  2021-06-21 17:20 ` [PATCH v5 0/2] gpio: add generic gpio cascade Mauri Sandberg
@ 2021-06-21 17:20   ` Mauri Sandberg
  2021-06-24 18:30     ` Rob Herring
  2021-06-21 17:20   ` [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  1 sibling, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-21 17:20 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Add documentation for a general GPIO cascade. It allows building
one-to-many cascades of GPIO lines using multiplexer to choose
the cascaded line.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
---
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade
 - changed vague term 'pin' to 'upstream line'
 - added more verbose description for the module
 - added missing 'mux-controls' entry
 - dropped Tested-by and Reviewed-by due to changes in bindings
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
new file mode 100644
index 000000000000..46248f8e2ba5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO cascade
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO cascade
+
+  This hardware construction cascades (multiplexes) several GPIO lines from
+  one-to-many using a software controlled multiplexer. The most common use
+  case is probably reading several inputs by switching the multiplexer over
+  several input lines, which in practice works well since input lines has
+  high impedance.
+
+  Constructions with multiplexed outputs are also possible using open drain
+  electronics.
+
+  The number of cascaded GPIO lines is limited by the technology used to
+  switch over the cascaded lines. There are readily available dual/triple
+  4-to-1 multiplexers, for example, and others.
+
+  Illustration (pins used to drive the multiplexer are omitted for clarity)
+
+                 /|---- Cascaded GPIO line 0
+  Upstream      | |---- Cascaded GPIO line 1
+  GPIO line ----+ | .
+                | | .
+                 \|---- Cascaded GPIO line n
+
+properties:
+  compatible:
+    enum:
+      - gpio-cascade
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  mux-controls:
+    minItems: 1
+    maxItems: 1
+    description: |
+      The mux controller that will be driving the GPIO cascade.
+
+  upstream-gpios:
+    description: |
+      The GPIO line used as the upstream line will convey the status to/from
+      cascaded GPIO lines. In an input mode, by using this line, it is
+      possible to read the status from selected cascaded GPIO line.
+
+      In an output mode the status of the upstream GPIO will be conveyed to
+      the selected cascaded GPIO line.
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - mux-controls
+  - upstream-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-06-21 17:20 ` [PATCH v5 0/2] gpio: add generic gpio cascade Mauri Sandberg
  2021-06-21 17:20   ` [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-06-21 17:20   ` Mauri Sandberg
  2021-06-21 17:43     ` Andy Shevchenko
  1 sibling, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-06-21 17:20 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Adds support for a building cascades of GPIO lines. That is, it allows
setups when there is one upstream line and multiple cascaded lines, out
of which one can be chosen at a time. The status of the upstream line
can be conveyd to the selected cascaded line or, vice versa, the status
of the cascaded line can be conveyed to the upstream line.

A gpio-mux is being used to select, which cascaded GPIO line is being
used at any given time.

At the moment only input direction is supported. In future it should be
possible to add support for output direction, too.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
---
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
   here and there and changed to use new bindings and compatible string
   - ambigious and vague 'pin' was rename to 'upstream_line'
 - dropped Tested-by and Reviewed-by due to changes in bindings
 - dropped Reported-by suggested by an automatic bot as it was not really
   appropriate to begin with
 - functionally it's the same as v4
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig        |  14 ++++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cascade.c | 139 ++++++++++++++++++++++++++++++++++++
 3 files changed, 154 insertions(+)
 create mode 100644 drivers/gpio/gpio-cascade.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ae2721967191..d8bdb6d87b1f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1669,4 +1669,18 @@ config GPIO_MOCKUP
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_CASCADE
+	tristate "General GPIO cascade"
+	depends on OF_GPIO
+	select MULTIPLEXER
+	select MUX_GPIO
+	help
+	  Say yes here to enable support for generic GPIO cascade.
+
+	  This allows building one-to-many cascades of GPIO lines using
+	  different types of multiplexers readily available. At the
+	  moment only input lines are supported.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 32a32659866a..94a9d6e43bc2 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
+obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
new file mode 100644
index 000000000000..91053ac489c2
--- /dev/null
+++ b/drivers/gpio/gpio-cascade.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO cascade driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ * This allows building cascades of GPIO lines in a manner illustrated
+ * below:
+ *
+ *                 /|---- Cascaded GPIO line 0
+ *  Upstream      | |---- Cascaded GPIO line 1
+ *  GPIO line ----+ | .
+ *                | | .
+ *                 \|---- Cascaded GPIO line n
+ *
+ * A gpio-mux is being used to select, which cascaded line is being
+ * addressed at any given time.
+ *
+ * At the moment only input mode is supported due to lack of means for
+ * testing output functionality. At least theoretically output should be
+ * possible with an open drain constructions.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_cascade {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*upstream_line;
+};
+
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_cascade, gpio_chip);
+}
+
+static int gpio_cascade_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_cascade *cas;
+	int ret;
+
+	cas = chip_to_cascade(gc);
+	ret = mux_control_select(cas->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(cas->upstream_line);
+	mux_control_deselect(cas->mux_control);
+	return ret;
+}
+
+static int gpio_cascade_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct gpio_cascade *cas;
+	struct mux_control *mc;
+	struct gpio_desc *upstream;
+	struct gpio_chip *gc;
+	int err;
+
+	cas = devm_kzalloc(dev, sizeof(struct gpio_cascade), GFP_KERNEL);
+	if (cas == NULL)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc)) {
+		err = (int) PTR_ERR(mc);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "unable to get mux-control: %d\n", err);
+		return err;
+	}
+
+	cas->mux_control = mc;
+	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
+	if (IS_ERR(upstream)) {
+		err = (int) PTR_ERR(upstream);
+		dev_err(dev, "unable to claim upstream GPIO line: %d\n", err);
+		return err;
+	}
+
+	cas->upstream_line = upstream;
+	cas->parent = dev;
+
+	gc = &cas->gpio_chip;
+	gc->get = gpio_cascade_get_value;
+	gc->get_direction = gpio_cascade_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(cas->parent);
+	gc->parent = cas->parent;
+	gc->owner = THIS_MODULE;
+	gc->of_node = np;
+
+	err = gpiochip_add(&cas->gpio_chip);
+	if (err) {
+		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, cas);
+	dev_info(dev, "registered %u cascaded GPIO lines\n", gc->ngpio);
+	return 0;
+}
+
+static const struct of_device_id gpio_cascade_id[] = {
+	{
+		.compatible = "gpio-cascade",
+		.data = NULL,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
+
+static struct platform_driver gpio_cascade_driver = {
+	.driver	= {
+		.name		= "gpio-cascade",
+		.of_match_table = gpio_cascade_id,
+	},
+	.probe	= gpio_cascade_probe,
+};
+module_platform_driver(gpio_cascade_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO cascade");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-06-21 17:20   ` [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
@ 2021-06-21 17:43     ` Andy Shevchenko
  2021-06-21 18:31       ` Enrico Weigelt, metux IT consult
  2021-10-15 12:56       ` Mauri Sandberg
  0 siblings, 2 replies; 62+ messages in thread
From: Andy Shevchenko @ 2021-06-21 17:43 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini

On Mon, Jun 21, 2021 at 8:25 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>
> Adds support for a building cascades of GPIO lines. That is, it allows

for building

> setups when there is one upstream line and multiple cascaded lines, out
> of which one can be chosen at a time. The status of the upstream line
> can be conveyd to the selected cascaded line or, vice versa, the status

conveyed

> of the cascaded line can be conveyed to the upstream line.
>
> A gpio-mux is being used to select, which cascaded GPIO line is being
> used at any given time.
>
> At the moment only input direction is supported. In future it should be
> possible to add support for output direction, too.

Since in parallel there is a discussion about the virtio-gpio
interface, how will this work with it?

> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *  A generic GPIO cascade driver
> + *
> + *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
> + *
> + * This allows building cascades of GPIO lines in a manner illustrated
> + * below:
> + *
> + *                 /|---- Cascaded GPIO line 0
> + *  Upstream      | |---- Cascaded GPIO line 1
> + *  GPIO line ----+ | .
> + *                | | .
> + *                 \|---- Cascaded GPIO line n
> + *
> + * A gpio-mux is being used to select, which cascaded line is being
> + * addressed at any given time.
> + *
> + * At the moment only input mode is supported due to lack of means for
> + * testing output functionality. At least theoretically output should be
> + * possible with an open drain constructions.
> + */

...

> +static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
> +{
> +       struct gpio_cascade *cas;
> +       int ret;

> +       cas = chip_to_cascade(gc);

Doing this in the definition block above will save a LOC.

> +       ret = mux_control_select(cas->mux_control, offset);
> +       if (ret)
> +               return ret;
> +
> +       ret = gpiod_get_value(cas->upstream_line);
> +       mux_control_deselect(cas->mux_control);
> +       return ret;
> +}

...

> +       struct device_node *np = pdev->dev.of_node;

Nope, see below.

...

> +       cas = devm_kzalloc(dev, sizeof(struct gpio_cascade), GFP_KERNEL);

sizeof(*cas)

> +       if (cas == NULL)

if (!cas)

> +               return -ENOMEM;

...

> +       mc = devm_mux_control_get(dev, NULL);
> +       if (IS_ERR(mc)) {
> +               err = (int) PTR_ERR(mc);
> +               if (err != -EPROBE_DEFER)
> +                       dev_err(dev, "unable to get mux-control: %d\n", err);
> +               return err;

Oh là là! No, the explicit castings are bad. besides the fact that all
above can be replaced by

  return dev_err_probe(...);

> +       }
> +
> +       cas->mux_control = mc;
> +       upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
> +       if (IS_ERR(upstream)) {

> +               err = (int) PTR_ERR(upstream);
> +               dev_err(dev, "unable to claim upstream GPIO line: %d\n", err);

No castings. Use proper printf() specifiers.

> +               return err;
> +       }

...

> +       gc->of_node = np;

This should be guarded by CONFIG_OF_GPIO.
And no need to use the np temporary variable for one use like this.

...

> +       err = gpiochip_add(&cas->gpio_chip);

Why not the devm variant?

> +       if (err) {
> +               dev_err(dev, "unable to add gpio chip, err=%d\n", err);
> +               return err;
> +       }

...

> +       dev_info(dev, "registered %u cascaded GPIO lines\n", gc->ngpio);

No, we don't pollute logs when everything is fine.

...

> +static const struct of_device_id gpio_cascade_id[] = {
> +       {
> +               .compatible = "gpio-cascade",

> +               .data = NULL,

Redundant.

> +       },

All above may consume only a single LOC.

> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, gpio_cascade_id);

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-06-21 17:43     ` Andy Shevchenko
@ 2021-06-21 18:31       ` Enrico Weigelt, metux IT consult
  2021-10-15 12:56       ` Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Enrico Weigelt, metux IT consult @ 2021-06-21 18:31 UTC (permalink / raw)
  To: Andy Shevchenko, Mauri Sandberg
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini

On 21.06.21 19:43, Andy Shevchenko wrote:

> Since in parallel there is a discussion about the virtio-gpio
> interface, how will this work with it?

Haven't really understood what this is actually doing. A multiplexer
where only external line is connected to some actual gpio at a time ?
Or does it merge multiple inputs into one (eg. logical OR) ?

Is that about real hardware mux chips or just a software only ?

What is the actual use case ?

For now, I don't see any relation to virtio-gpio. Correct me if I'm
wrong.


--mtx

-- 
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info@metux.net -- +49-151-27565287

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation
  2021-06-21 17:20   ` [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-06-24 18:30     ` Rob Herring
  0 siblings, 0 replies; 62+ messages in thread
From: Rob Herring @ 2021-06-24 18:30 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: sandberg, linux-kernel, linux-gpio, andy.shevchenko, robh+dt,
	linus.walleij, bgolaszewski, drew, devicetree, geert+renesas

On Mon, 21 Jun 2021 20:20:52 +0300, Mauri Sandberg wrote:
> Add documentation for a general GPIO cascade. It allows building
> one-to-many cascades of GPIO lines using multiplexer to choose
> the cascaded line.
> 
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> ---
> v4 -> v5:
>  - renamed gpio-mux-input -> gpio-cascade
>  - changed vague term 'pin' to 'upstream line'
>  - added more verbose description for the module
>  - added missing 'mux-controls' entry
>  - dropped Tested-by and Reviewed-by due to changes in bindings
> v3 -> v4:
>  - Changed author email
>  - Included Tested-by and Reviewed-by from Drew
> v2 -> v3: added a complete example on dual 4-way multiplexer
> v1 -> v2: added a little bit more text in the binding documenation
> ---
>  .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-06-21 17:43     ` Andy Shevchenko
  2021-06-21 18:31       ` Enrico Weigelt, metux IT consult
@ 2021-10-15 12:56       ` Mauri Sandberg
  2021-10-15 17:20         ` Andy Shevchenko
  1 sibling, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-15 12:56 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini


On 21.6.2021 20.43, Andy Shevchenko wrote:

>> +       gc->of_node = np;
> 
> This should be guarded by CONFIG_OF_GPIO.
In the Kconfig I have a dependency to OF_GPIO. Is the guarding still 
necessary? Or should the guard be added and dependency removed? Or have 
them both?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-15 12:56       ` Mauri Sandberg
@ 2021-10-15 17:20         ` Andy Shevchenko
  0 siblings, 0 replies; 62+ messages in thread
From: Andy Shevchenko @ 2021-10-15 17:20 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini

On Fri, Oct 15, 2021 at 3:56 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
> On 21.6.2021 20.43, Andy Shevchenko wrote:
>
> >> +       gc->of_node = np;
> >
> > This should be guarded by CONFIG_OF_GPIO.

The above is actually done by the GPIO library nowadays.

> In the Kconfig I have a dependency to OF_GPIO. Is the guarding still
> necessary? Or should the guard be added and dependency removed? Or have
> them both?

For this kind ("generic") driver the OF_GPIO dependency is simply
wrong. You shouldn't have it.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v6 0/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (6 preceding siblings ...)
  2021-06-21 17:20 ` [PATCH v5 0/2] gpio: add generic gpio cascade Mauri Sandberg
@ 2021-10-19 12:57 ` Mauri Sandberg
  2021-10-19 12:57   ` [PATCH v6 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
  2021-10-19 12:57   ` [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  2021-10-19 20:08 ` [PATCH v7 0/2] " Mauri Sandberg
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 12:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Hello all,

It's been a while and here comes the sixth version of the patches.

What was done:
 - adjust module dependecies and what it selects in Kconfig
 - use managed device resource call when adding gpio chip
 - remove redundant code
 - cosmetic changes

Thanks,
Mauri

rangediff v5 -> v6:
1:  a1bb23f56378 ! 1:  87348f391671 dt-bindings: gpio-cascade: add documentation
    @@ Commit message
         the cascaded line.
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    +    Reviewed-by: Rob Herring <robh@kernel.org>
         ---
    +    v5 -> v6:
    +     - added Reviewed-by tag by Rob
         v4 -> v5:
          - renamed gpio-mux-input -> gpio-cascade
          - changed vague term 'pin' to 'upstream line'
2:  e0be9df088a9 ! 2:  a8e608181bc7 gpio: gpio-cascade: add generic GPIO cascade
    @@ Metadata
      ## Commit message ##
         gpio: gpio-cascade: add generic GPIO cascade
     
    -    Adds support for a building cascades of GPIO lines. That is, it allows
    +    Adds support for building cascades of GPIO lines. That is, it allows
         setups when there is one upstream line and multiple cascaded lines, out
         of which one can be chosen at a time. The status of the upstream line
    -    can be conveyd to the selected cascaded line or, vice versa, the status
    +    can be conveyed to the selected cascaded line or, vice versa, the status
         of the cascaded line can be conveyed to the upstream line.
     
    -    A gpio-mux is being used to select, which cascaded GPIO line is being
    +    A multiplexer is being used to select, which cascaded GPIO line is being
         used at any given time.
     
         At the moment only input direction is supported. In future it should be
    @@ Commit message
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
         ---
    +    v5 -> v6:
    +     - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
    +     - refactor code preferring one-liners
    +     - clean up prints, removing them from success-path.
    +     - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
    +     - use devm_gpiochip_add_data instead of gpiochip_add
         v4 -> v5:
          - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
            here and there and changed to use new bindings and compatible string
    @@ drivers/gpio/Kconfig: config GPIO_VIRTIO
     +
     +config GPIO_CASCADE
     +	tristate "General GPIO cascade"
    -+	depends on OF_GPIO
     +	select MULTIPLEXER
    -+	select MUX_GPIO
     +	help
     +	  Say yes here to enable support for generic GPIO cascade.
     +
    @@ drivers/gpio/gpio-cascade.c (new)
     +
     +static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
     +{
    -+	struct gpio_cascade *cas;
    ++	struct gpio_cascade *cas = chip_to_cascade(gc);
     +	int ret;
     +
    -+	cas = chip_to_cascade(gc);
     +	ret = mux_control_select(cas->mux_control, offset);
     +	if (ret)
     +		return ret;
    @@ drivers/gpio/gpio-cascade.c (new)
     +
     +static int gpio_cascade_probe(struct platform_device *pdev)
     +{
    -+	struct device_node *np = pdev->dev.of_node;
     +	struct device *dev = &pdev->dev;
     +	struct gpio_cascade *cas;
     +	struct mux_control *mc;
    @@ drivers/gpio/gpio-cascade.c (new)
     +	struct gpio_chip *gc;
     +	int err;
     +
    -+	cas = devm_kzalloc(dev, sizeof(struct gpio_cascade), GFP_KERNEL);
    -+	if (cas == NULL)
    ++	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
    ++	if (!cas)
     +		return -ENOMEM;
     +
     +	mc = devm_mux_control_get(dev, NULL);
    -+	if (IS_ERR(mc)) {
    -+		err = (int) PTR_ERR(mc);
    -+		if (err != -EPROBE_DEFER)
    -+			dev_err(dev, "unable to get mux-control: %d\n", err);
    -+		return err;
    -+	}
    ++	if (IS_ERR(mc))
    ++		return dev_err_probe(dev,
    ++				     PTR_ERR(mc),
    ++				     "unable to get mux-control\n");
     +
     +	cas->mux_control = mc;
     +	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
     +	if (IS_ERR(upstream)) {
    -+		err = (int) PTR_ERR(upstream);
    -+		dev_err(dev, "unable to claim upstream GPIO line: %d\n", err);
    -+		return err;
    ++		dev_err(dev, "unable to claim upstream GPIO line\n");
    ++		return -ENODEV;
     +	}
     +
     +	cas->upstream_line = upstream;
    @@ drivers/gpio/gpio-cascade.c (new)
     +	gc->label = dev_name(cas->parent);
     +	gc->parent = cas->parent;
     +	gc->owner = THIS_MODULE;
    -+	gc->of_node = np;
     +
    -+	err = gpiochip_add(&cas->gpio_chip);
    ++	err = devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
     +	if (err) {
    -+		dev_err(dev, "unable to add gpio chip, err=%d\n", err);
    ++		dev_err(dev, "unable to add gpio chip\n");
     +		return err;
     +	}
     +
     +	platform_set_drvdata(pdev, cas);
    -+	dev_info(dev, "registered %u cascaded GPIO lines\n", gc->ngpio);
     +	return 0;
     +}
     +
     +static const struct of_device_id gpio_cascade_id[] = {
    -+	{
    -+		.compatible = "gpio-cascade",
    -+		.data = NULL,
    -+	},
    ++	{ .compatible = "gpio-cascade" },
     +	{ /* sentinel */ }
     +};
     +MODULE_DEVICE_TABLE(of, gpio_cascade_id);

Mauri Sandberg (2):
  dt-bindings: gpio-cascade: add documentation
  gpio: gpio-cascade: add generic GPIO cascade

 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++
 drivers/gpio/Kconfig                          |  12 ++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cascade.c                   | 129 ++++++++++++++++++
 4 files changed, 245 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
 create mode 100644 drivers/gpio/gpio-cascade.c


base-commit: f4a20dfac88c06c9b529a41ff4cf9acba8f3fdff
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v6 1/2] dt-bindings: gpio-cascade: add documentation
  2021-10-19 12:57 ` [PATCH v6 0/2] " Mauri Sandberg
@ 2021-10-19 12:57   ` Mauri Sandberg
  2021-10-19 12:57   ` [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 12:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg, Rob Herring

Add documentation for a general GPIO cascade. It allows building
one-to-many cascades of GPIO lines using multiplexer to choose
the cascaded line.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Rob Herring <robh@kernel.org>
---
v5 -> v6:
 - added Reviewed-by tag by Rob
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade
 - changed vague term 'pin' to 'upstream line'
 - added more verbose description for the module
 - added missing 'mux-controls' entry
 - dropped Tested-by and Reviewed-by due to changes in bindings
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
new file mode 100644
index 000000000000..46248f8e2ba5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO cascade
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO cascade
+
+  This hardware construction cascades (multiplexes) several GPIO lines from
+  one-to-many using a software controlled multiplexer. The most common use
+  case is probably reading several inputs by switching the multiplexer over
+  several input lines, which in practice works well since input lines has
+  high impedance.
+
+  Constructions with multiplexed outputs are also possible using open drain
+  electronics.
+
+  The number of cascaded GPIO lines is limited by the technology used to
+  switch over the cascaded lines. There are readily available dual/triple
+  4-to-1 multiplexers, for example, and others.
+
+  Illustration (pins used to drive the multiplexer are omitted for clarity)
+
+                 /|---- Cascaded GPIO line 0
+  Upstream      | |---- Cascaded GPIO line 1
+  GPIO line ----+ | .
+                | | .
+                 \|---- Cascaded GPIO line n
+
+properties:
+  compatible:
+    enum:
+      - gpio-cascade
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  mux-controls:
+    minItems: 1
+    maxItems: 1
+    description: |
+      The mux controller that will be driving the GPIO cascade.
+
+  upstream-gpios:
+    description: |
+      The GPIO line used as the upstream line will convey the status to/from
+      cascaded GPIO lines. In an input mode, by using this line, it is
+      possible to read the status from selected cascaded GPIO line.
+
+      In an output mode the status of the upstream GPIO will be conveyed to
+      the selected cascaded GPIO line.
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - mux-controls
+  - upstream-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-19 12:57 ` [PATCH v6 0/2] " Mauri Sandberg
  2021-10-19 12:57   ` [PATCH v6 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-10-19 12:57   ` Mauri Sandberg
  2021-10-19 13:12     ` Andy Shevchenko
  1 sibling, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 12:57 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Adds support for building cascades of GPIO lines. That is, it allows
setups when there is one upstream line and multiple cascaded lines, out
of which one can be chosen at a time. The status of the upstream line
can be conveyed to the selected cascaded line or, vice versa, the status
of the cascaded line can be conveyed to the upstream line.

A multiplexer is being used to select, which cascaded GPIO line is being
used at any given time.

At the moment only input direction is supported. In future it should be
possible to add support for output direction, too.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
---
v5 -> v6:
 - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
 - refactor code preferring one-liners
 - clean up prints, removing them from success-path.
 - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
 - use devm_gpiochip_add_data instead of gpiochip_add
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
   here and there and changed to use new bindings and compatible string
   - ambigious and vague 'pin' was rename to 'upstream_line'
 - dropped Tested-by and Reviewed-by due to changes in bindings
 - dropped Reported-by suggested by an automatic bot as it was not really
   appropriate to begin with
 - functionally it's the same as v4
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig        |  12 ++++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cascade.c | 129 ++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100644 drivers/gpio/gpio-cascade.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 37a6f77c86fe..25096fb150f6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1694,4 +1694,16 @@ config GPIO_VIRTIO
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_CASCADE
+	tristate "General GPIO cascade"
+	select MULTIPLEXER
+	help
+	  Say yes here to enable support for generic GPIO cascade.
+
+	  This allows building one-to-many cascades of GPIO lines using
+	  different types of multiplexers readily available. At the
+	  moment only input lines are supported.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 71ee9fc2ff83..e8945456e7ea 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
+obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
new file mode 100644
index 000000000000..151ece25c64e
--- /dev/null
+++ b/drivers/gpio/gpio-cascade.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO cascade driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ * This allows building cascades of GPIO lines in a manner illustrated
+ * below:
+ *
+ *                 /|---- Cascaded GPIO line 0
+ *  Upstream      | |---- Cascaded GPIO line 1
+ *  GPIO line ----+ | .
+ *                | | .
+ *                 \|---- Cascaded GPIO line n
+ *
+ * A gpio-mux is being used to select, which cascaded line is being
+ * addressed at any given time.
+ *
+ * At the moment only input mode is supported due to lack of means for
+ * testing output functionality. At least theoretically output should be
+ * possible with an open drain constructions.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+struct gpio_cascade {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*upstream_line;
+};
+
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_cascade, gpio_chip);
+}
+
+static int gpio_cascade_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_cascade *cas = chip_to_cascade(gc);
+	int ret;
+
+	ret = mux_control_select(cas->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(cas->upstream_line);
+	mux_control_deselect(cas->mux_control);
+	return ret;
+}
+
+static int gpio_cascade_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_cascade *cas;
+	struct mux_control *mc;
+	struct gpio_desc *upstream;
+	struct gpio_chip *gc;
+	int err;
+
+	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
+	if (!cas)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc))
+		return dev_err_probe(dev,
+				     PTR_ERR(mc),
+				     "unable to get mux-control\n");
+
+	cas->mux_control = mc;
+	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
+	if (IS_ERR(upstream)) {
+		dev_err(dev, "unable to claim upstream GPIO line\n");
+		return -ENODEV;
+	}
+
+	cas->upstream_line = upstream;
+	cas->parent = dev;
+
+	gc = &cas->gpio_chip;
+	gc->get = gpio_cascade_get_value;
+	gc->get_direction = gpio_cascade_get_direction;
+
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(cas->parent);
+	gc->parent = cas->parent;
+	gc->owner = THIS_MODULE;
+
+	err = devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
+	if (err) {
+		dev_err(dev, "unable to add gpio chip\n");
+		return err;
+	}
+
+	platform_set_drvdata(pdev, cas);
+	return 0;
+}
+
+static const struct of_device_id gpio_cascade_id[] = {
+	{ .compatible = "gpio-cascade" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
+
+static struct platform_driver gpio_cascade_driver = {
+	.driver	= {
+		.name		= "gpio-cascade",
+		.of_match_table = gpio_cascade_id,
+	},
+	.probe	= gpio_cascade_probe,
+};
+module_platform_driver(gpio_cascade_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO cascade");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-19 12:57   ` [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
@ 2021-10-19 13:12     ` Andy Shevchenko
  0 siblings, 0 replies; 62+ messages in thread
From: Andy Shevchenko @ 2021-10-19 13:12 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini

On Tue, Oct 19, 2021 at 4:00 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>
> Adds support for building cascades of GPIO lines. That is, it allows
> setups when there is one upstream line and multiple cascaded lines, out
> of which one can be chosen at a time. The status of the upstream line
> can be conveyed to the selected cascaded line or, vice versa, the status
> of the cascaded line can be conveyed to the upstream line.
>
> A multiplexer is being used to select, which cascaded GPIO line is being
> used at any given time.
>
> At the moment only input direction is supported. In future it should be
> possible to add support for output direction, too.

Thanks for an update! My comments below.

...

> +config GPIO_CASCADE
> +       tristate "General GPIO cascade"
> +       select MULTIPLEXER
> +       help
> +         Say yes here to enable support for generic GPIO cascade.
> +
> +         This allows building one-to-many cascades of GPIO lines using
> +         different types of multiplexers readily available. At the
> +         moment only input lines are supported.

Care to mention what will be the module name in the case of being
built as a module?
(Hint: there are plenty of existing examples in the kernel)

...

> +#include <linux/module.h>

> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>

I would move this group...

> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mux/consumer.h>
> +

...to be somewhere here to explicitly show that this is the GPIO
subsystem related driver.

...

> +       mc = devm_mux_control_get(dev, NULL);
> +       if (IS_ERR(mc))

> +               return dev_err_probe(dev,
> +                                    PTR_ERR(mc),
> +                                    "unable to get mux-control\n");

Why not one line?

...

> +       upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
> +       if (IS_ERR(upstream)) {
> +               dev_err(dev, "unable to claim upstream GPIO line\n");
> +               return -ENODEV;

Why shadowing error code? What happens if it's deferred?
Hint: use dev_err_probe() here as well.

> +       }

...

> +       err = devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
> +       if (err) {
> +               dev_err(dev, "unable to add gpio chip\n");
> +               return err;
> +       }
> +
> +       platform_set_drvdata(pdev, cas);
> +       return 0;

I would rather do

       platform_set_drvdata(pdev, cas);

       return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 0/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (7 preceding siblings ...)
  2021-10-19 12:57 ` [PATCH v6 0/2] " Mauri Sandberg
@ 2021-10-19 20:08 ` Mauri Sandberg
  2021-10-19 20:08   ` [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
  2021-10-19 20:08   ` [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  2021-10-26 19:15 ` [PATCH v8 0/2] " Mauri Sandberg
  2022-02-05 21:59 ` [RESEND v8 0/2] " Mauri Sandberg
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 20:08 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Thanks for you prompt feedback Andy. Here are the highlights on this round:
 - no changes in the bindings file.
 - added better help text in Kconfig
 - refactored the return code handling for claiming upstream gpio line
 - refactored the return and exit at the end of the function
 
Thanks,
Mauri

rangediff v6 -> v7:
1:  1283751fadd4 = 1:  434637e7188e dt-bindings: gpio-cascade: add documentation
2:  46541776733a ! 2:  a72e186f8e3b gpio: gpio-cascade: add generic GPIO cascade
    @@ Commit message
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
         ---
    +    v6 -> v7:
    +     - In Kconfig add info about module name
    +     - adhere to new convention that allows lines longer than 80 chars
    +     - use dev_probe_err with upstream gpio line too
    +     - refactor for cleaner exit of probe function.
         v5 -> v6:
          - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
          - refactor code preferring one-liners
    @@ drivers/gpio/Kconfig: config GPIO_VIRTIO
     +	  This allows building one-to-many cascades of GPIO lines using
     +	  different types of multiplexers readily available. At the
     +	  moment only input lines are supported.
    ++
    ++	  To build the driver as a module choose 'm' and the resulting module
    ++	  will be called 'gpio-cascade'.
     +
      endif
     
    @@ drivers/gpio/gpio-cascade.c (new)
     + */
     +
     +#include <linux/module.h>
    -+#include <linux/gpio/consumer.h>
    -+#include <linux/gpio/driver.h>
     +#include <linux/slab.h>
     +#include <linux/platform_device.h>
     +#include <linux/mux/consumer.h>
     +
    ++#include <linux/gpio/consumer.h>
    ++#include <linux/gpio/driver.h>
    ++
     +struct gpio_cascade {
     +	struct device		*parent;
     +	struct gpio_chip	gpio_chip;
    @@ drivers/gpio/gpio-cascade.c (new)
     +	struct mux_control *mc;
     +	struct gpio_desc *upstream;
     +	struct gpio_chip *gc;
    -+	int err;
     +
     +	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
     +	if (!cas)
    @@ drivers/gpio/gpio-cascade.c (new)
     +
     +	mc = devm_mux_control_get(dev, NULL);
     +	if (IS_ERR(mc))
    -+		return dev_err_probe(dev,
    -+				     PTR_ERR(mc),
    -+				     "unable to get mux-control\n");
    ++		return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
     +
     +	cas->mux_control = mc;
     +	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
    -+	if (IS_ERR(upstream)) {
    -+		dev_err(dev, "unable to claim upstream GPIO line\n");
    -+		return -ENODEV;
    -+	}
    ++	if (IS_ERR(upstream))
    ++		return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
     +
     +	cas->upstream_line = upstream;
     +	cas->parent = dev;
    @@ drivers/gpio/gpio-cascade.c (new)
     +	gc = &cas->gpio_chip;
     +	gc->get = gpio_cascade_get_value;
     +	gc->get_direction = gpio_cascade_get_direction;
    -+
     +	gc->base = -1;
     +	gc->ngpio = mux_control_states(mc);
     +	gc->label = dev_name(cas->parent);
     +	gc->parent = cas->parent;
     +	gc->owner = THIS_MODULE;
     +
    -+	err = devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
    -+	if (err) {
    -+		dev_err(dev, "unable to add gpio chip\n");
    -+		return err;
    -+	}
    -+
     +	platform_set_drvdata(pdev, cas);
    -+	return 0;
    ++	return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
     +}
     +
     +static const struct of_device_id gpio_cascade_id[] = {

Mauri Sandberg (2):
  dt-bindings: gpio-cascade: add documentation
  gpio: gpio-cascade: add generic GPIO cascade

 .../bindings/gpio/gpio-cascade.yaml           | 103 +++++++++++++++
 drivers/gpio/Kconfig                          |  15 +++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cascade.c                   | 118 ++++++++++++++++++
 4 files changed, 237 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
 create mode 100644 drivers/gpio/gpio-cascade.c


base-commit: f4a20dfac88c06c9b529a41ff4cf9acba8f3fdff
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation
  2021-10-19 20:08 ` [PATCH v7 0/2] " Mauri Sandberg
@ 2021-10-19 20:08   ` Mauri Sandberg
  2021-10-24 22:18     ` Linus Walleij
  2021-10-19 20:08   ` [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  1 sibling, 1 reply; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 20:08 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg, Rob Herring

Add documentation for a general GPIO cascade. It allows building
one-to-many cascades of GPIO lines using multiplexer to choose
the cascaded line.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Rob Herring <robh@kernel.org>
---
v5 -> v6:
 - added Reviewed-by tag by Rob
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade
 - changed vague term 'pin' to 'upstream line'
 - added more verbose description for the module
 - added missing 'mux-controls' entry
 - dropped Tested-by and Reviewed-by due to changes in bindings
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
new file mode 100644
index 000000000000..46248f8e2ba5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO cascade
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO cascade
+
+  This hardware construction cascades (multiplexes) several GPIO lines from
+  one-to-many using a software controlled multiplexer. The most common use
+  case is probably reading several inputs by switching the multiplexer over
+  several input lines, which in practice works well since input lines has
+  high impedance.
+
+  Constructions with multiplexed outputs are also possible using open drain
+  electronics.
+
+  The number of cascaded GPIO lines is limited by the technology used to
+  switch over the cascaded lines. There are readily available dual/triple
+  4-to-1 multiplexers, for example, and others.
+
+  Illustration (pins used to drive the multiplexer are omitted for clarity)
+
+                 /|---- Cascaded GPIO line 0
+  Upstream      | |---- Cascaded GPIO line 1
+  GPIO line ----+ | .
+                | | .
+                 \|---- Cascaded GPIO line n
+
+properties:
+  compatible:
+    enum:
+      - gpio-cascade
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  mux-controls:
+    minItems: 1
+    maxItems: 1
+    description: |
+      The mux controller that will be driving the GPIO cascade.
+
+  upstream-gpios:
+    description: |
+      The GPIO line used as the upstream line will convey the status to/from
+      cascaded GPIO lines. In an input mode, by using this line, it is
+      possible to read the status from selected cascaded GPIO line.
+
+      In an output mode the status of the upstream GPIO will be conveyed to
+      the selected cascaded GPIO line.
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - mux-controls
+  - upstream-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-19 20:08 ` [PATCH v7 0/2] " Mauri Sandberg
  2021-10-19 20:08   ` [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-10-19 20:08   ` Mauri Sandberg
  2021-10-24 22:17     ` Linus Walleij
  2021-10-25  9:29     ` Andy Shevchenko
  1 sibling, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-19 20:08 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Adds support for building cascades of GPIO lines. That is, it allows
setups when there is one upstream line and multiple cascaded lines, out
of which one can be chosen at a time. The status of the upstream line
can be conveyed to the selected cascaded line or, vice versa, the status
of the cascaded line can be conveyed to the upstream line.

A multiplexer is being used to select, which cascaded GPIO line is being
used at any given time.

At the moment only input direction is supported. In future it should be
possible to add support for output direction, too.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
---
v6 -> v7:
 - In Kconfig add info about module name
 - adhere to new convention that allows lines longer than 80 chars
 - use dev_probe_err with upstream gpio line too
 - refactor for cleaner exit of probe function.
v5 -> v6:
 - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
 - refactor code preferring one-liners
 - clean up prints, removing them from success-path.
 - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
 - use devm_gpiochip_add_data instead of gpiochip_add
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
   here and there and changed to use new bindings and compatible string
   - ambigious and vague 'pin' was rename to 'upstream_line'
 - dropped Tested-by and Reviewed-by due to changes in bindings
 - dropped Reported-by suggested by an automatic bot as it was not really
   appropriate to begin with
 - functionally it's the same as v4
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig        |  15 +++++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cascade.c | 118 ++++++++++++++++++++++++++++++++++++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/gpio/gpio-cascade.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 37a6f77c86fe..e69457144459 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1694,4 +1694,19 @@ config GPIO_VIRTIO
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_CASCADE
+	tristate "General GPIO cascade"
+	select MULTIPLEXER
+	help
+	  Say yes here to enable support for generic GPIO cascade.
+
+	  This allows building one-to-many cascades of GPIO lines using
+	  different types of multiplexers readily available. At the
+	  moment only input lines are supported.
+
+	  To build the driver as a module choose 'm' and the resulting module
+	  will be called 'gpio-cascade'.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 71ee9fc2ff83..e8945456e7ea 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
+obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
new file mode 100644
index 000000000000..82001299265e
--- /dev/null
+++ b/drivers/gpio/gpio-cascade.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO cascade driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ * This allows building cascades of GPIO lines in a manner illustrated
+ * below:
+ *
+ *                 /|---- Cascaded GPIO line 0
+ *  Upstream      | |---- Cascaded GPIO line 1
+ *  GPIO line ----+ | .
+ *                | | .
+ *                 \|---- Cascaded GPIO line n
+ *
+ * A gpio-mux is being used to select, which cascaded line is being
+ * addressed at any given time.
+ *
+ * At the moment only input mode is supported due to lack of means for
+ * testing output functionality. At least theoretically output should be
+ * possible with an open drain constructions.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+
+struct gpio_cascade {
+	struct device		*parent;
+	struct gpio_chip	gpio_chip;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*upstream_line;
+};
+
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_cascade, gpio_chip);
+}
+
+static int gpio_cascade_get_direction(struct gpio_chip *gc,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_cascade *cas = chip_to_cascade(gc);
+	int ret;
+
+	ret = mux_control_select(cas->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(cas->upstream_line);
+	mux_control_deselect(cas->mux_control);
+	return ret;
+}
+
+static int gpio_cascade_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_cascade *cas;
+	struct mux_control *mc;
+	struct gpio_desc *upstream;
+	struct gpio_chip *gc;
+
+	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
+	if (!cas)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc))
+		return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
+
+	cas->mux_control = mc;
+	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
+	if (IS_ERR(upstream))
+		return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
+
+	cas->upstream_line = upstream;
+	cas->parent = dev;
+
+	gc = &cas->gpio_chip;
+	gc->get = gpio_cascade_get_value;
+	gc->get_direction = gpio_cascade_get_direction;
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(cas->parent);
+	gc->parent = cas->parent;
+	gc->owner = THIS_MODULE;
+
+	platform_set_drvdata(pdev, cas);
+	return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
+}
+
+static const struct of_device_id gpio_cascade_id[] = {
+	{ .compatible = "gpio-cascade" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
+
+static struct platform_driver gpio_cascade_driver = {
+	.driver	= {
+		.name		= "gpio-cascade",
+		.of_match_table = gpio_cascade_id,
+	},
+	.probe	= gpio_cascade_probe,
+};
+module_platform_driver(gpio_cascade_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO cascade");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-19 20:08   ` [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
@ 2021-10-24 22:17     ` Linus Walleij
  2021-10-25  9:29     ` Andy Shevchenko
  1 sibling, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2021-10-24 22:17 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini

On Tue, Oct 19, 2021 at 10:10 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Adds support for building cascades of GPIO lines. That is, it allows
> setups when there is one upstream line and multiple cascaded lines, out
> of which one can be chosen at a time. The status of the upstream line
> can be conveyed to the selected cascaded line or, vice versa, the status
> of the cascaded line can be conveyed to the upstream line.
>
> A multiplexer is being used to select, which cascaded GPIO line is being
> used at any given time.
>
> At the moment only input direction is supported. In future it should be
> possible to add support for output direction, too.
>
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> ---
> v6 -> v7:

This v7 looks like clean and nice merge material to me,
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation
  2021-10-19 20:08   ` [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-10-24 22:18     ` Linus Walleij
  0 siblings, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2021-10-24 22:18 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Andy Shevchenko, Bartosz Golaszewski,
	Geert Uytterhoeven, open list:GPIO SUBSYSTEM, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Drew Fustini, Rob Herring

On Tue, Oct 19, 2021 at 10:10 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:

> Add documentation for a general GPIO cascade. It allows building
> one-to-many cascades of GPIO lines using multiplexer to choose
> the cascaded line.
>
> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> Reviewed-by: Rob Herring <robh@kernel.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-19 20:08   ` [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  2021-10-24 22:17     ` Linus Walleij
@ 2021-10-25  9:29     ` Andy Shevchenko
  1 sibling, 0 replies; 62+ messages in thread
From: Andy Shevchenko @ 2021-10-25  9:29 UTC (permalink / raw)
  To: Mauri Sandberg
  Cc: Mauri Sandberg, Bartosz Golaszewski, Geert Uytterhoeven,
	Linus Walleij, open list:GPIO SUBSYSTEM, Rob Herring, devicetree,
	Linux Kernel Mailing List, Drew Fustini

On Tue, Oct 19, 2021 at 11:10 PM Mauri Sandberg <maukka@ext.kapsi.fi> wrote:
>
> Adds support for building cascades of GPIO lines. That is, it allows
> setups when there is one upstream line and multiple cascaded lines, out
> of which one can be chosen at a time. The status of the upstream line
> can be conveyed to the selected cascaded line or, vice versa, the status
> of the cascaded line can be conveyed to the upstream line.
>
> A multiplexer is being used to select, which cascaded GPIO line is being
> used at any given time.
>
> At the moment only input direction is supported. In future it should be
> possible to add support for output direction, too.

A nit-pick below and you may have my
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
> ---
> v6 -> v7:
>  - In Kconfig add info about module name
>  - adhere to new convention that allows lines longer than 80 chars
>  - use dev_probe_err with upstream gpio line too
>  - refactor for cleaner exit of probe function.
> v5 -> v6:
>  - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
>  - refactor code preferring one-liners
>  - clean up prints, removing them from success-path.
>  - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
>  - use devm_gpiochip_add_data instead of gpiochip_add
> v4 -> v5:
>  - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
>    here and there and changed to use new bindings and compatible string
>    - ambigious and vague 'pin' was rename to 'upstream_line'
>  - dropped Tested-by and Reviewed-by due to changes in bindings
>  - dropped Reported-by suggested by an automatic bot as it was not really
>    appropriate to begin with
>  - functionally it's the same as v4
> v3 -> v4:
>  - Changed author email
>  - Included Tested-by and Reviewed-by from Drew
> v2 -> v3:
>  - use managed device resources
>  - update Kconfig description
> v1 -> v2:
>  - removed .owner from platform_driver as per test bot's instruction
>  - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
>  - added gpio_mux_input_get_direction as it's recommended for all chips
>  - removed because this is input only chip: gpio_mux_input_set_value
>  - removed because they are not needed for input/output only chips:
>      gpio_mux_input_direction_input
>      gpio_mux_input_direction_output
>  - fixed typo in an error message
>  - added info message about successful registration
>  - removed can_sleep flag as this does not sleep while getting GPIO value
>    like I2C or SPI do
>  - Updated description in Kconfig
> ---
>  drivers/gpio/Kconfig        |  15 +++++
>  drivers/gpio/Makefile       |   1 +
>  drivers/gpio/gpio-cascade.c | 118 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 134 insertions(+)
>  create mode 100644 drivers/gpio/gpio-cascade.c
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 37a6f77c86fe..e69457144459 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1694,4 +1694,19 @@ config GPIO_VIRTIO
>
>  endmenu
>
> +comment "Other GPIO expanders"
> +
> +config GPIO_CASCADE
> +       tristate "General GPIO cascade"
> +       select MULTIPLEXER
> +       help
> +         Say yes here to enable support for generic GPIO cascade.
> +
> +         This allows building one-to-many cascades of GPIO lines using
> +         different types of multiplexers readily available. At the
> +         moment only input lines are supported.
> +
> +         To build the driver as a module choose 'm' and the resulting module
> +         will be called 'gpio-cascade'.
> +
>  endif
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 71ee9fc2ff83..e8945456e7ea 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)          += gpio-bd9571mwv.o
>  obj-$(CONFIG_GPIO_BRCMSTB)             += gpio-brcmstb.o
>  obj-$(CONFIG_GPIO_BT8XX)               += gpio-bt8xx.o
>  obj-$(CONFIG_GPIO_CADENCE)             += gpio-cadence.o
> +obj-$(CONFIG_GPIO_CASCADE)             += gpio-cascade.o
>  obj-$(CONFIG_GPIO_CLPS711X)            += gpio-clps711x.o
>  obj-$(CONFIG_GPIO_SNPS_CREG)           += gpio-creg-snps.o
>  obj-$(CONFIG_GPIO_CRYSTAL_COVE)                += gpio-crystalcove.o
> diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
> new file mode 100644
> index 000000000000..82001299265e
> --- /dev/null
> +++ b/drivers/gpio/gpio-cascade.c
> @@ -0,0 +1,118 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *  A generic GPIO cascade driver
> + *
> + *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
> + *
> + * This allows building cascades of GPIO lines in a manner illustrated
> + * below:
> + *
> + *                 /|---- Cascaded GPIO line 0
> + *  Upstream      | |---- Cascaded GPIO line 1
> + *  GPIO line ----+ | .
> + *                | | .
> + *                 \|---- Cascaded GPIO line n
> + *
> + * A gpio-mux is being used to select, which cascaded line is being
> + * addressed at any given time.
> + *
> + * At the moment only input mode is supported due to lack of means for
> + * testing output functionality. At least theoretically output should be
> + * possible with an open drain constructions.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mux/consumer.h>
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>
> +
> +struct gpio_cascade {

> +       struct device           *parent;
> +       struct gpio_chip        gpio_chip;

Make the gpio_chip first and any container_of become a no-op at compile time!

> +       struct mux_control      *mux_control;
> +       struct gpio_desc        *upstream_line;
> +};
> +
> +static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
> +{
> +       return container_of(gc, struct gpio_cascade, gpio_chip);
> +}
> +
> +static int gpio_cascade_get_direction(struct gpio_chip *gc,
> +                                       unsigned int offset)
> +{
> +       return GPIO_LINE_DIRECTION_IN;
> +}
> +
> +static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
> +{
> +       struct gpio_cascade *cas = chip_to_cascade(gc);
> +       int ret;
> +
> +       ret = mux_control_select(cas->mux_control, offset);
> +       if (ret)
> +               return ret;
> +
> +       ret = gpiod_get_value(cas->upstream_line);
> +       mux_control_deselect(cas->mux_control);
> +       return ret;
> +}
> +
> +static int gpio_cascade_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct gpio_cascade *cas;
> +       struct mux_control *mc;
> +       struct gpio_desc *upstream;
> +       struct gpio_chip *gc;
> +
> +       cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
> +       if (!cas)
> +               return -ENOMEM;
> +
> +       mc = devm_mux_control_get(dev, NULL);
> +       if (IS_ERR(mc))
> +               return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
> +
> +       cas->mux_control = mc;
> +       upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
> +       if (IS_ERR(upstream))
> +               return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
> +
> +       cas->upstream_line = upstream;
> +       cas->parent = dev;
> +
> +       gc = &cas->gpio_chip;
> +       gc->get = gpio_cascade_get_value;
> +       gc->get_direction = gpio_cascade_get_direction;
> +       gc->base = -1;
> +       gc->ngpio = mux_control_states(mc);
> +       gc->label = dev_name(cas->parent);
> +       gc->parent = cas->parent;
> +       gc->owner = THIS_MODULE;
> +
> +       platform_set_drvdata(pdev, cas);
> +       return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
> +}
> +
> +static const struct of_device_id gpio_cascade_id[] = {
> +       { .compatible = "gpio-cascade" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, gpio_cascade_id);
> +
> +static struct platform_driver gpio_cascade_driver = {
> +       .driver = {
> +               .name           = "gpio-cascade",
> +               .of_match_table = gpio_cascade_id,
> +       },
> +       .probe  = gpio_cascade_probe,
> +};
> +module_platform_driver(gpio_cascade_driver);
> +
> +MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
> +MODULE_DESCRIPTION("Generic GPIO cascade");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 0/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (8 preceding siblings ...)
  2021-10-19 20:08 ` [PATCH v7 0/2] " Mauri Sandberg
@ 2021-10-26 19:15 ` Mauri Sandberg
  2021-10-26 19:15   ` [PATCH v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
  2021-10-26 19:15   ` [PATCH v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  2022-02-05 21:59 ` [RESEND v8 0/2] " Mauri Sandberg
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-26 19:15 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Hello everyone!

I am sending what I am hoping to be the final version of the patch set and
having kernel support for my router is one step closer.
I want to thank Drew, Linus, Andy and others for their patient review and
testing work over the different iterations.

The changes in this one compared to v7 are cosmetic consisting of
 - rearrange members of struct gpio_chip
 - fix typoes and one instance of split lines in function declaration
 - added Reviewed-by tags in appropriate commit messages

Thanks,
Mauri

rangediff v7 -> v8:

1:  0fa5e65443fb ! 1:  33008c379a28 dt-bindings: gpio-cascade: add documentation
    @@ Commit message
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
         Reviewed-by: Rob Herring <robh@kernel.org>
    +    Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
         ---
    +    v7 -> v8:
    +     - added Reviewed-by tag by Linus
    +    v6 -> v7:
    +     - no changes
         v5 -> v6:
          - added Reviewed-by tag by Rob
         v4 -> v5:
2:  c2237aca3364 ! 2:  fc23ea48ba52 gpio: gpio-cascade: add generic GPIO cascade
    @@ Commit message
         possible to add support for output direction, too.
     
         Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
    +    Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
    +    Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
         ---
    +    v7 -> v8:
    +     - rearrange members in struct gpio_cascade
    +     - cosmetic changes in file header and in one function declaration
    +     - added Reviewed-by tags by Linus and Andy
         v6 -> v7:
          - In Kconfig add info about module name
          - adhere to new convention that allows lines longer than 80 chars
    @@ drivers/gpio/gpio-cascade.c (new)
     + *                | | .
     + *                 \|---- Cascaded GPIO line n
     + *
    -+ * A gpio-mux is being used to select, which cascaded line is being
    ++ * A multiplexer is being used to select, which cascaded line is being
     + * addressed at any given time.
     + *
     + * At the moment only input mode is supported due to lack of means for
     + * testing output functionality. At least theoretically output should be
    -+ * possible with an open drain constructions.
    ++ * possible with open drain constructions.
     + */
     +
     +#include <linux/module.h>
    @@ drivers/gpio/gpio-cascade.c (new)
     +#include <linux/gpio/driver.h>
     +
     +struct gpio_cascade {
    -+	struct device		*parent;
     +	struct gpio_chip	gpio_chip;
    ++	struct device		*parent;
     +	struct mux_control	*mux_control;
     +	struct gpio_desc	*upstream_line;
     +};
    @@ drivers/gpio/gpio-cascade.c (new)
     +	return container_of(gc, struct gpio_cascade, gpio_chip);
     +}
     +
    -+static int gpio_cascade_get_direction(struct gpio_chip *gc,
    -+					unsigned int offset)
    ++static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
     +{
     +	return GPIO_LINE_DIRECTION_IN;
     +}

Mauri Sandberg (2):
  dt-bindings: gpio-cascade: add documentation
  gpio: gpio-cascade: add generic GPIO cascade

 .../bindings/gpio/gpio-cascade.yaml           | 103 +++++++++++++++
 drivers/gpio/Kconfig                          |  15 +++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cascade.c                   | 117 ++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
 create mode 100644 drivers/gpio/gpio-cascade.c


base-commit: f4a20dfac88c06c9b529a41ff4cf9acba8f3fdff
-- 
2.25.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v8 1/2] dt-bindings: gpio-cascade: add documentation
  2021-10-26 19:15 ` [PATCH v8 0/2] " Mauri Sandberg
@ 2021-10-26 19:15   ` Mauri Sandberg
  2021-10-26 19:15   ` [PATCH v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-26 19:15 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg, Rob Herring

Add documentation for a general GPIO cascade. It allows building
one-to-many cascades of GPIO lines using multiplexer to choose
the cascaded line.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
v7 -> v8:
 - added Reviewed-by tag by Linus
v6 -> v7:
 - no changes
v5 -> v6:
 - added Reviewed-by tag by Rob
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade
 - changed vague term 'pin' to 'upstream line'
 - added more verbose description for the module
 - added missing 'mux-controls' entry
 - dropped Tested-by and Reviewed-by due to changes in bindings
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
new file mode 100644
index 000000000000..46248f8e2ba5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO cascade
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO cascade
+
+  This hardware construction cascades (multiplexes) several GPIO lines from
+  one-to-many using a software controlled multiplexer. The most common use
+  case is probably reading several inputs by switching the multiplexer over
+  several input lines, which in practice works well since input lines has
+  high impedance.
+
+  Constructions with multiplexed outputs are also possible using open drain
+  electronics.
+
+  The number of cascaded GPIO lines is limited by the technology used to
+  switch over the cascaded lines. There are readily available dual/triple
+  4-to-1 multiplexers, for example, and others.
+
+  Illustration (pins used to drive the multiplexer are omitted for clarity)
+
+                 /|---- Cascaded GPIO line 0
+  Upstream      | |---- Cascaded GPIO line 1
+  GPIO line ----+ | .
+                | | .
+                 \|---- Cascaded GPIO line n
+
+properties:
+  compatible:
+    enum:
+      - gpio-cascade
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  mux-controls:
+    minItems: 1
+    maxItems: 1
+    description: |
+      The mux controller that will be driving the GPIO cascade.
+
+  upstream-gpios:
+    description: |
+      The GPIO line used as the upstream line will convey the status to/from
+      cascaded GPIO lines. In an input mode, by using this line, it is
+      possible to read the status from selected cascaded GPIO line.
+
+      In an output mode the status of the upstream GPIO will be conveyed to
+      the selected cascaded GPIO line.
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - mux-controls
+  - upstream-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v8 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-10-26 19:15 ` [PATCH v8 0/2] " Mauri Sandberg
  2021-10-26 19:15   ` [PATCH v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2021-10-26 19:15   ` Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2021-10-26 19:15 UTC (permalink / raw)
  To: sandberg
  Cc: andy.shevchenko, bgolaszewski, geert+renesas, linus.walleij,
	linux-gpio, robh+dt, devicetree, linux-kernel, drew,
	Mauri Sandberg

Adds support for building cascades of GPIO lines. That is, it allows
setups when there is one upstream line and multiple cascaded lines, out
of which one can be chosen at a time. The status of the upstream line
can be conveyed to the selected cascaded line or, vice versa, the status
of the cascaded line can be conveyed to the upstream line.

A multiplexer is being used to select, which cascaded GPIO line is being
used at any given time.

At the moment only input direction is supported. In future it should be
possible to add support for output direction, too.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
v7 -> v8:
 - rearrange members in struct gpio_cascade
 - cosmetic changes in file header and in one function declaration
 - added Reviewed-by tags by Linus and Andy
v6 -> v7:
 - In Kconfig add info about module name
 - adhere to new convention that allows lines longer than 80 chars
 - use dev_probe_err with upstream gpio line too
 - refactor for cleaner exit of probe function.
v5 -> v6:
 - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
 - refactor code preferring one-liners
 - clean up prints, removing them from success-path.
 - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
 - use devm_gpiochip_add_data instead of gpiochip_add
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
   here and there and changed to use new bindings and compatible string
   - ambigious and vague 'pin' was rename to 'upstream_line'
 - dropped Tested-by and Reviewed-by due to changes in bindings
 - dropped Reported-by suggested by an automatic bot as it was not really
   appropriate to begin with
 - functionally it's the same as v4
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig        |  15 +++++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 drivers/gpio/gpio-cascade.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 37a6f77c86fe..e69457144459 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1694,4 +1694,19 @@ config GPIO_VIRTIO
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_CASCADE
+	tristate "General GPIO cascade"
+	select MULTIPLEXER
+	help
+	  Say yes here to enable support for generic GPIO cascade.
+
+	  This allows building one-to-many cascades of GPIO lines using
+	  different types of multiplexers readily available. At the
+	  moment only input lines are supported.
+
+	  To build the driver as a module choose 'm' and the resulting module
+	  will be called 'gpio-cascade'.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 71ee9fc2ff83..e8945456e7ea 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
+obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
new file mode 100644
index 000000000000..5cbda882d79a
--- /dev/null
+++ b/drivers/gpio/gpio-cascade.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO cascade driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ * This allows building cascades of GPIO lines in a manner illustrated
+ * below:
+ *
+ *                 /|---- Cascaded GPIO line 0
+ *  Upstream      | |---- Cascaded GPIO line 1
+ *  GPIO line ----+ | .
+ *                | | .
+ *                 \|---- Cascaded GPIO line n
+ *
+ * A multiplexer is being used to select, which cascaded line is being
+ * addressed at any given time.
+ *
+ * At the moment only input mode is supported due to lack of means for
+ * testing output functionality. At least theoretically output should be
+ * possible with open drain constructions.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+
+struct gpio_cascade {
+	struct gpio_chip	gpio_chip;
+	struct device		*parent;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*upstream_line;
+};
+
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_cascade, gpio_chip);
+}
+
+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_cascade *cas = chip_to_cascade(gc);
+	int ret;
+
+	ret = mux_control_select(cas->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(cas->upstream_line);
+	mux_control_deselect(cas->mux_control);
+	return ret;
+}
+
+static int gpio_cascade_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_cascade *cas;
+	struct mux_control *mc;
+	struct gpio_desc *upstream;
+	struct gpio_chip *gc;
+
+	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
+	if (!cas)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc))
+		return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
+
+	cas->mux_control = mc;
+	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
+	if (IS_ERR(upstream))
+		return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
+
+	cas->upstream_line = upstream;
+	cas->parent = dev;
+
+	gc = &cas->gpio_chip;
+	gc->get = gpio_cascade_get_value;
+	gc->get_direction = gpio_cascade_get_direction;
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(cas->parent);
+	gc->parent = cas->parent;
+	gc->owner = THIS_MODULE;
+
+	platform_set_drvdata(pdev, cas);
+	return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
+}
+
+static const struct of_device_id gpio_cascade_id[] = {
+	{ .compatible = "gpio-cascade" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
+
+static struct platform_driver gpio_cascade_driver = {
+	.driver	= {
+		.name		= "gpio-cascade",
+		.of_match_table = gpio_cascade_id,
+	},
+	.probe	= gpio_cascade_probe,
+};
+module_platform_driver(gpio_cascade_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO cascade");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [RESEND v8 0/2] gpio: gpio-cascade: add generic GPIO cascade
  2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
                   ` (9 preceding siblings ...)
  2021-10-26 19:15 ` [PATCH v8 0/2] " Mauri Sandberg
@ 2022-02-05 21:59 ` Mauri Sandberg
  2022-02-05 21:59   ` [RESEND v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
  2022-02-05 21:59   ` [RESEND v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  10 siblings, 2 replies; 62+ messages in thread
From: Mauri Sandberg @ 2022-02-05 21:59 UTC (permalink / raw)
  To: bgolaszewski, brgl
  Cc: andy.shevchenko, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, Mauri Sandberg

Hello all,

Hopefully I am reaching Bartosz with this too now. I may have used an
outdated e-mail address earlier. Please kindly take these two pathces
in consideration.

Thanks,
Mauri

Mauri Sandberg (2):
  dt-bindings: gpio-cascade: add documentation
  gpio: gpio-cascade: add generic GPIO cascade

 .../bindings/gpio/gpio-cascade.yaml           | 103 +++++++++++++++
 drivers/gpio/Kconfig                          |  15 +++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cascade.c                   | 117 ++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
 create mode 100644 drivers/gpio/gpio-cascade.c


base-commit: 0868ad385affa28cf15aebca3c38c5c51f79b286
--
2.25.1

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [RESEND v8 1/2] dt-bindings: gpio-cascade: add documentation
  2022-02-05 21:59 ` [RESEND v8 0/2] " Mauri Sandberg
@ 2022-02-05 21:59   ` Mauri Sandberg
  2022-02-05 21:59   ` [RESEND v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2022-02-05 21:59 UTC (permalink / raw)
  To: bgolaszewski, brgl
  Cc: andy.shevchenko, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, Mauri Sandberg,
	Rob Herring

Add documentation for a general GPIO cascade. It allows building
one-to-many cascades of GPIO lines using multiplexer to choose
the cascaded line.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
v7 -> v8:
 - added Reviewed-by tag by Linus
v6 -> v7:
 - no changes
v5 -> v6:
 - added Reviewed-by tag by Rob
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade
 - changed vague term 'pin' to 'upstream line'
 - added more verbose description for the module
 - added missing 'mux-controls' entry
 - dropped Tested-by and Reviewed-by due to changes in bindings
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3: added a complete example on dual 4-way multiplexer
v1 -> v2: added a little bit more text in the binding documenation
---
 .../bindings/gpio/gpio-cascade.yaml           | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-cascade.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
new file mode 100644
index 000000000000..46248f8e2ba5
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-cascade.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-cascade.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic GPIO cascade
+
+maintainers:
+  - Mauri Sandberg <maukka@ext.kapsi.fi>
+
+description: |
+  A generic GPIO cascade
+
+  This hardware construction cascades (multiplexes) several GPIO lines from
+  one-to-many using a software controlled multiplexer. The most common use
+  case is probably reading several inputs by switching the multiplexer over
+  several input lines, which in practice works well since input lines has
+  high impedance.
+
+  Constructions with multiplexed outputs are also possible using open drain
+  electronics.
+
+  The number of cascaded GPIO lines is limited by the technology used to
+  switch over the cascaded lines. There are readily available dual/triple
+  4-to-1 multiplexers, for example, and others.
+
+  Illustration (pins used to drive the multiplexer are omitted for clarity)
+
+                 /|---- Cascaded GPIO line 0
+  Upstream      | |---- Cascaded GPIO line 1
+  GPIO line ----+ | .
+                | | .
+                 \|---- Cascaded GPIO line n
+
+properties:
+  compatible:
+    enum:
+      - gpio-cascade
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  mux-controls:
+    minItems: 1
+    maxItems: 1
+    description: |
+      The mux controller that will be driving the GPIO cascade.
+
+  upstream-gpios:
+    description: |
+      The GPIO line used as the upstream line will convey the status to/from
+      cascaded GPIO lines. In an input mode, by using this line, it is
+      possible to read the status from selected cascaded GPIO line.
+
+      In an output mode the status of the upstream GPIO will be conveyed to
+      the selected cascaded GPIO line.
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+  - mux-controls
+  - upstream-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
+
+        mux-gpios = <&gpio 9 GPIO_ACTIVE_HIGH>,
+                    <&gpio 11 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio2: key-mux1 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+    };
+
+    gpio3: key-mux2 {
+        compatible = "gpio-cascade";
+        mux-controls = <&mux>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        // GPIOs used by this node, upstream pin
+        upstream-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [RESEND v8 2/2] gpio: gpio-cascade: add generic GPIO cascade
  2022-02-05 21:59 ` [RESEND v8 0/2] " Mauri Sandberg
  2022-02-05 21:59   ` [RESEND v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
@ 2022-02-05 21:59   ` Mauri Sandberg
  1 sibling, 0 replies; 62+ messages in thread
From: Mauri Sandberg @ 2022-02-05 21:59 UTC (permalink / raw)
  To: bgolaszewski, brgl
  Cc: andy.shevchenko, geert+renesas, linus.walleij, linux-gpio,
	robh+dt, devicetree, linux-kernel, drew, Mauri Sandberg

Adds support for building cascades of GPIO lines. That is, it allows
setups when there is one upstream line and multiple cascaded lines, out
of which one can be chosen at a time. The status of the upstream line
can be conveyed to the selected cascaded line or, vice versa, the status
of the cascaded line can be conveyed to the upstream line.

A multiplexer is being used to select, which cascaded GPIO line is being
used at any given time.

At the moment only input direction is supported. In future it should be
possible to add support for output direction, too.

Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
v7 -> v8:
 - rearrange members in struct gpio_cascade
 - cosmetic changes in file header and in one function declaration
 - added Reviewed-by tags by Linus and Andy
v6 -> v7:
 - In Kconfig add info about module name
 - adhere to new convention that allows lines longer than 80 chars
 - use dev_probe_err with upstream gpio line too
 - refactor for cleaner exit of probe function.
v5 -> v6:
 - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
 - refactor code preferring one-liners
 - clean up prints, removing them from success-path.
 - don't explicitly set gpio_chip.of_node as it's done in the GPIO library
 - use devm_gpiochip_add_data instead of gpiochip_add
v4 -> v5:
 - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
   here and there and changed to use new bindings and compatible string
   - ambigious and vague 'pin' was rename to 'upstream_line'
 - dropped Tested-by and Reviewed-by due to changes in bindings
 - dropped Reported-by suggested by an automatic bot as it was not really
   appropriate to begin with
 - functionally it's the same as v4
v3 -> v4:
 - Changed author email
 - Included Tested-by and Reviewed-by from Drew
v2 -> v3:
 - use managed device resources
 - update Kconfig description
v1 -> v2:
 - removed .owner from platform_driver as per test bot's instruction
 - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
 - added gpio_mux_input_get_direction as it's recommended for all chips
 - removed because this is input only chip: gpio_mux_input_set_value
 - removed because they are not needed for input/output only chips:
     gpio_mux_input_direction_input
     gpio_mux_input_direction_output
 - fixed typo in an error message
 - added info message about successful registration
 - removed can_sleep flag as this does not sleep while getting GPIO value
   like I2C or SPI do
 - Updated description in Kconfig
---
 drivers/gpio/Kconfig        |  15 +++++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 drivers/gpio/gpio-cascade.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2031a727be30..b9201d29a2d2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1701,4 +1701,19 @@ config GPIO_SIM
 
 endmenu
 
+comment "Other GPIO expanders"
+
+config GPIO_CASCADE
+	tristate "General GPIO cascade"
+	select MULTIPLEXER
+	help
+	  Say yes here to enable support for generic GPIO cascade.
+
+	  This allows building one-to-many cascades of GPIO lines using
+	  different types of multiplexers readily available. At the
+	  moment only input lines are supported.
+
+	  To build the driver as a module choose 'm' and the resulting module
+	  will be called 'gpio-cascade'.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1a14e248bdbd..6cb0e5c42fc5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
+obj-$(CONFIG_GPIO_CASCADE)		+= gpio-cascade.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c
new file mode 100644
index 000000000000..5cbda882d79a
--- /dev/null
+++ b/drivers/gpio/gpio-cascade.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  A generic GPIO cascade driver
+ *
+ *  Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
+ *
+ * This allows building cascades of GPIO lines in a manner illustrated
+ * below:
+ *
+ *                 /|---- Cascaded GPIO line 0
+ *  Upstream      | |---- Cascaded GPIO line 1
+ *  GPIO line ----+ | .
+ *                | | .
+ *                 \|---- Cascaded GPIO line n
+ *
+ * A multiplexer is being used to select, which cascaded line is being
+ * addressed at any given time.
+ *
+ * At the moment only input mode is supported due to lack of means for
+ * testing output functionality. At least theoretically output should be
+ * possible with open drain constructions.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mux/consumer.h>
+
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+
+struct gpio_cascade {
+	struct gpio_chip	gpio_chip;
+	struct device		*parent;
+	struct mux_control	*mux_control;
+	struct gpio_desc	*upstream_line;
+};
+
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
+{
+	return container_of(gc, struct gpio_cascade, gpio_chip);
+}
+
+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_cascade *cas = chip_to_cascade(gc);
+	int ret;
+
+	ret = mux_control_select(cas->mux_control, offset);
+	if (ret)
+		return ret;
+
+	ret = gpiod_get_value(cas->upstream_line);
+	mux_control_deselect(cas->mux_control);
+	return ret;
+}
+
+static int gpio_cascade_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_cascade *cas;
+	struct mux_control *mc;
+	struct gpio_desc *upstream;
+	struct gpio_chip *gc;
+
+	cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
+	if (!cas)
+		return -ENOMEM;
+
+	mc = devm_mux_control_get(dev, NULL);
+	if (IS_ERR(mc))
+		return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
+
+	cas->mux_control = mc;
+	upstream = devm_gpiod_get(dev, "upstream",  GPIOD_IN);
+	if (IS_ERR(upstream))
+		return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
+
+	cas->upstream_line = upstream;
+	cas->parent = dev;
+
+	gc = &cas->gpio_chip;
+	gc->get = gpio_cascade_get_value;
+	gc->get_direction = gpio_cascade_get_direction;
+	gc->base = -1;
+	gc->ngpio = mux_control_states(mc);
+	gc->label = dev_name(cas->parent);
+	gc->parent = cas->parent;
+	gc->owner = THIS_MODULE;
+
+	platform_set_drvdata(pdev, cas);
+	return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
+}
+
+static const struct of_device_id gpio_cascade_id[] = {
+	{ .compatible = "gpio-cascade" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
+
+static struct platform_driver gpio_cascade_driver = {
+	.driver	= {
+		.name		= "gpio-cascade",
+		.of_match_table = gpio_cascade_id,
+	},
+	.probe	= gpio_cascade_probe,
+};
+module_platform_driver(gpio_cascade_driver);
+
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
+MODULE_DESCRIPTION("Generic GPIO cascade");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2022-02-05 21:59 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-25 12:28 [RFC gpio/for-next 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
2021-03-25 12:28 ` [RFC gpio/for-next 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
2021-03-25 12:28 ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
2021-03-25 23:08   ` kernel test robot
2021-03-25 23:08   ` [PATCH] gpio: gpio-mux-input: fix platform_no_drv_owner.cocci warnings kernel test robot
2021-03-26  6:59   ` [RFC gpio/for-next 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Drew Fustini
2021-03-26 10:32     ` Mauri Sandberg
2021-03-26 10:49       ` Andy Shevchenko
2021-03-29 13:57 ` [RFC v2 0/2] gpio: " Mauri Sandberg
2021-03-29 13:57   ` [RFC v2 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
2021-03-29 13:57   ` [RFC v2 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
2021-05-17 16:58 ` [PATCH v3 0/2] gpio: " Mauri Sandberg
2021-05-17 16:58   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
2021-05-17 16:58   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
2021-05-17 22:13   ` [PATCH v3 0/2] gpio: " Drew Fustini
2021-05-28  0:23     ` Linus Walleij
2021-05-28  0:27       ` Drew Fustini
2021-05-24 21:25   ` Drew Fustini
2021-05-24 16:29 ` RESEND PATCH v3 Mauri Sandberg
2021-05-24 16:29   ` [PATCH v3 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
2021-05-24 16:29   ` [PATCH v3 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
2021-05-24 21:29   ` RESEND PATCH v3 Drew Fustini
2021-05-30 16:13 ` [PATCH v4 0/2] gpio: add generic gpio input multiplexer Mauri Sandberg
2021-05-30 16:13   ` [PATCH v4 1/2] dt-bindings: gpio-mux-input: add documentation Mauri Sandberg
2021-06-01 10:10     ` Linus Walleij
2021-06-01 10:44     ` Linus Walleij
2021-06-02  9:31       ` Mauri Sandberg
2021-06-02 10:35         ` Linus Walleij
2021-06-02 11:21           ` Mauri Sandberg
2021-06-04  7:51             ` Linus Walleij
2021-06-01 13:32     ` Rob Herring
2021-06-02 11:36       ` Mauri Sandberg
2021-05-30 16:13   ` [PATCH v4 2/2] gpio: gpio-mux-input: add generic gpio input multiplexer Mauri Sandberg
2021-05-30 18:09     ` Andy Shevchenko
2021-05-30 19:02       ` Mauri Sandberg
2021-05-30 19:38         ` Andy Shevchenko
2021-05-31 10:19           ` Mauri Sandberg
2021-06-01 10:38     ` Linus Walleij
2021-06-21 17:20 ` [PATCH v5 0/2] gpio: add generic gpio cascade Mauri Sandberg
2021-06-21 17:20   ` [PATCH v5 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
2021-06-24 18:30     ` Rob Herring
2021-06-21 17:20   ` [PATCH v5 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
2021-06-21 17:43     ` Andy Shevchenko
2021-06-21 18:31       ` Enrico Weigelt, metux IT consult
2021-10-15 12:56       ` Mauri Sandberg
2021-10-15 17:20         ` Andy Shevchenko
2021-10-19 12:57 ` [PATCH v6 0/2] " Mauri Sandberg
2021-10-19 12:57   ` [PATCH v6 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
2021-10-19 12:57   ` [PATCH v6 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
2021-10-19 13:12     ` Andy Shevchenko
2021-10-19 20:08 ` [PATCH v7 0/2] " Mauri Sandberg
2021-10-19 20:08   ` [PATCH v7 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
2021-10-24 22:18     ` Linus Walleij
2021-10-19 20:08   ` [PATCH v7 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
2021-10-24 22:17     ` Linus Walleij
2021-10-25  9:29     ` Andy Shevchenko
2021-10-26 19:15 ` [PATCH v8 0/2] " Mauri Sandberg
2021-10-26 19:15   ` [PATCH v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
2021-10-26 19:15   ` [PATCH v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg
2022-02-05 21:59 ` [RESEND v8 0/2] " Mauri Sandberg
2022-02-05 21:59   ` [RESEND v8 1/2] dt-bindings: gpio-cascade: add documentation Mauri Sandberg
2022-02-05 21:59   ` [RESEND v8 2/2] gpio: gpio-cascade: add generic GPIO cascade Mauri Sandberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.