[v3,4/7] dt-bindings: gpio: Add gpio-repeater bindings
diff mbox series

Message ID 20191127084253.16356-5-geert+renesas@glider.be
State New
Headers show
Series
  • gpio: Add GPIO Aggregator/Repeater
Related show

Commit Message

Geert Uytterhoeven Nov. 27, 2019, 8:42 a.m. UTC
Add Device Tree bindings for a GPIO repeater, with optional translation
of physical signal properties.  This is useful for describing explicitly
the presence of e.g. an inverter on a GPIO line, and was inspired by the
non-YAML gpio-inverter bindings by Harish Jenny K N
<harish_kandiga@mentor.com>[1].

Note that this is different from a GPIO Nexus Node[2], which cannot do
physical signal property translation.

While an inverter can be described implicitly by exchanging the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
th provider and consumer sides:
  1. The GPIO provider (controller) looks at the flags to know the
     polarity, so it can translate between logical (active/not active)
     and physical (high/low) signal levels.
  2. While the signal polarity is usually fixed on the GPIO consumer
     side (e.g. an LED is tied to either the supply voltage or GND),
     it may be configurable on some devices, and both sides need to
     agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
     match the actual polarity.
     There exists a similar issue with interrupt flags, where both the
     interrupt controller and the device generating the interrupt need
     to agree, which breaks in the presence of a physical inverter not
     described in DT (see e.g. [3]).

[1] "[PATCH V4 2/2] gpio: inverter: document the inverter bindings"
    https://lore.kernel.org/linux-gpio/1561699236-18620-3-git-send-email-harish_kandiga@mentor.com/

[2] Devicetree Specification v0.3-rc2, Section 2.5
    https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3-rc2

[3] "[PATCH] wlcore/wl18xx: Add invert-irq OF property for physically
    inverted IRQ"
    https://lore.kernel.org/linux-renesas-soc/20190607172958.20745-1-erosca@de.adit-jv.com/

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 .../bindings/gpio/gpio-repeater.yaml          | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-repeater.yaml

Comments

Ulrich Hecht Nov. 28, 2019, 3:39 a.m. UTC | #1
> On November 27, 2019 at 9:42 AM Geert Uytterhoeven <geert+renesas@glider.be> wrote:
> 
> 
> Add Device Tree bindings for a GPIO repeater, with optional translation
> of physical signal properties.  This is useful for describing explicitly
> the presence of e.g. an inverter on a GPIO line, and was inspired by the
> non-YAML gpio-inverter bindings by Harish Jenny K N
> <harish_kandiga@mentor.com>[1].
> 
> Note that this is different from a GPIO Nexus Node[2], which cannot do
> physical signal property translation.
> 
> While an inverter can be described implicitly by exchanging the
> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> th provider and consumer sides:
>   1. The GPIO provider (controller) looks at the flags to know the
>      polarity, so it can translate between logical (active/not active)
>      and physical (high/low) signal levels.
>   2. While the signal polarity is usually fixed on the GPIO consumer
>      side (e.g. an LED is tied to either the supply voltage or GND),
>      it may be configurable on some devices, and both sides need to
>      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>      match the actual polarity.
>      There exists a similar issue with interrupt flags, where both the
>      interrupt controller and the device generating the interrupt need
>      to agree, which breaks in the presence of a physical inverter not
>      described in DT (see e.g. [3]).
> 
> [1] "[PATCH V4 2/2] gpio: inverter: document the inverter bindings"
>     https://lore.kernel.org/linux-gpio/1561699236-18620-3-git-send-email-harish_kandiga@mentor.com/
> 
> [2] Devicetree Specification v0.3-rc2, Section 2.5
>     https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3-rc2
> 
> [3] "[PATCH] wlcore/wl18xx: Add invert-irq OF property for physically
>     inverted IRQ"
>     https://lore.kernel.org/linux-renesas-soc/20190607172958.20745-1-erosca@de.adit-jv.com/
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v3:
>   - New.
> ---
>  .../bindings/gpio/gpio-repeater.yaml          | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> new file mode 100644
> index 0000000000000000..efdee0c3be43f731
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/gpio-repeater.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GPIO Repeater
> +
> +maintainers:
> +  - Harish Jenny K N <harish_kandiga@mentor.com>
> +  - Geert Uytterhoeven <geert+renesas@glider.be>
> +
> +description:
> +  This represents a repeater for one or more GPIOs, possibly including physical
> +  signal property translation (e.g. polarity inversion).
> +
> +properties:
> +  compatible:
> +    const: gpio-repeater
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-controller: true
> +
> +  gpios:
> +    description:
> +      Phandle and specifier, one for each repeated GPIO.
> +
> +  gpio-line-names:
> +    description:
> +      Strings defining the names of the GPIO lines going out of the GPIO
> +      controller.
> +
> +required:
> +  - compatible
> +  - "#gpio-cells"
> +  - gpio-controller
> +  - gpios
> +
> +additionalProperties: false
> +
> +examples:
> +  # Device node describing a polarity inverter for a single GPIO
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    inverter: gpio-repeater {
> +        compatible = "gpio-repeater";
> +        #gpio-cells = <2>;
> +        gpio-controller;
> +        gpios = <&gpio 95 GPIO_ACTIVE_LOW>;
> +    };
> -- 
> 2.17.1
>

Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>

CU
Uli
Harish Jenny K N Dec. 3, 2019, 5:51 a.m. UTC | #2
On 27/11/19 2:12 PM, Geert Uytterhoeven wrote:
> Add Device Tree bindings for a GPIO repeater, with optional translation
> of physical signal properties.  This is useful for describing explicitly
> the presence of e.g. an inverter on a GPIO line, and was inspired by the
> non-YAML gpio-inverter bindings by Harish Jenny K N
> <harish_kandiga@mentor.com>[1].
>
> Note that this is different from a GPIO Nexus Node[2], which cannot do
> physical signal property translation.
>
> While an inverter can be described implicitly by exchanging the
> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> th provider and consumer sides:
>   1. The GPIO provider (controller) looks at the flags to know the
>      polarity, so it can translate between logical (active/not active)
>      and physical (high/low) signal levels.
>   2. While the signal polarity is usually fixed on the GPIO consumer
>      side (e.g. an LED is tied to either the supply voltage or GND),
>      it may be configurable on some devices, and both sides need to
>      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>      match the actual polarity.
>      There exists a similar issue with interrupt flags, where both the
>      interrupt controller and the device generating the interrupt need
>      to agree, which breaks in the presence of a physical inverter not
>      described in DT (see e.g. [3]).
>
> [1] "[PATCH V4 2/2] gpio: inverter: document the inverter bindings"
>     https://lore.kernel.org/linux-gpio/1561699236-18620-3-git-send-email-harish_kandiga@mentor.com/
>
> [2] Devicetree Specification v0.3-rc2, Section 2.5
>     https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3-rc2
>
> [3] "[PATCH] wlcore/wl18xx: Add invert-irq OF property for physically
>     inverted IRQ"
>     https://lore.kernel.org/linux-renesas-soc/20190607172958.20745-1-erosca@de.adit-jv.com/
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v3:
>   - New.
> ---
>  .../bindings/gpio/gpio-repeater.yaml          | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> new file mode 100644
> index 0000000000000000..efdee0c3be43f731
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/gpio-repeater.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GPIO Repeater
> +
> +maintainers:
> +  - Harish Jenny K N <harish_kandiga@mentor.com>
> +  - Geert Uytterhoeven <geert+renesas@glider.be>
> +
> +description:
> +  This represents a repeater for one or more GPIOs, possibly including physical
> +  signal property translation (e.g. polarity inversion).
> +
> +properties:
> +  compatible:
> +    const: gpio-repeater
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-controller: true
> +
> +  gpios:
> +    description:
> +      Phandle and specifier, one for each repeated GPIO.
> +
> +  gpio-line-names:
> +    description:
> +      Strings defining the names of the GPIO lines going out of the GPIO
> +      controller.
> +
> +required:
> +  - compatible
> +  - "#gpio-cells"
> +  - gpio-controller
> +  - gpios
> +
> +additionalProperties: false
> +
> +examples:
> +  # Device node describing a polarity inverter for a single GPIO
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    inverter: gpio-repeater {
> +        compatible = "gpio-repeater";
> +        #gpio-cells = <2>;
> +        gpio-controller;
> +        gpios = <&gpio 95 GPIO_ACTIVE_LOW>;
> +    };


just a suggestion: giving a gpio-line-names in the example would look useful.
Rob Herring Dec. 5, 2019, 9:06 p.m. UTC | #3
On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
> Add Device Tree bindings for a GPIO repeater, with optional translation
> of physical signal properties.  This is useful for describing explicitly
> the presence of e.g. an inverter on a GPIO line, and was inspired by the
> non-YAML gpio-inverter bindings by Harish Jenny K N
> <harish_kandiga@mentor.com>[1].
> 
> Note that this is different from a GPIO Nexus Node[2], which cannot do
> physical signal property translation.

It can't? Why not? The point of the passthru mask is to not do 
translation of flags, but without it you are always doing translation of 
cells.

> 
> While an inverter can be described implicitly by exchanging the
> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> th provider and consumer sides:
>   1. The GPIO provider (controller) looks at the flags to know the
>      polarity, so it can translate between logical (active/not active)
>      and physical (high/low) signal levels.
>   2. While the signal polarity is usually fixed on the GPIO consumer
>      side (e.g. an LED is tied to either the supply voltage or GND),
>      it may be configurable on some devices, and both sides need to
>      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>      match the actual polarity.
>      There exists a similar issue with interrupt flags, where both the
>      interrupt controller and the device generating the interrupt need
>      to agree, which breaks in the presence of a physical inverter not
>      described in DT (see e.g. [3]).

Adding an inverted flag as I've suggested would also solve this issue.

> 
> [1] "[PATCH V4 2/2] gpio: inverter: document the inverter bindings"
>     https://lore.kernel.org/linux-gpio/1561699236-18620-3-git-send-email-harish_kandiga@mentor.com/
> 
> [2] Devicetree Specification v0.3-rc2, Section 2.5
>     https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3-rc2
> 
> [3] "[PATCH] wlcore/wl18xx: Add invert-irq OF property for physically
>     inverted IRQ"
>     https://lore.kernel.org/linux-renesas-soc/20190607172958.20745-1-erosca@de.adit-jv.com/
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Geert Uytterhoeven Dec. 6, 2019, 9:17 a.m. UTC | #4
Hi Rob,

On Thu, Dec 5, 2019 at 10:06 PM Rob Herring <robh@kernel.org> wrote:
> On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
> > Add Device Tree bindings for a GPIO repeater, with optional translation
> > of physical signal properties.  This is useful for describing explicitly
> > the presence of e.g. an inverter on a GPIO line, and was inspired by the
> > non-YAML gpio-inverter bindings by Harish Jenny K N
> > <harish_kandiga@mentor.com>[1].
> >
> > Note that this is different from a GPIO Nexus Node[2], which cannot do
> > physical signal property translation.
>
> It can't? Why not? The point of the passthru mask is to not do
> translation of flags, but without it you are always doing translation of
> cells.

Thanks for pushing me deeper into nexuses!
You're right, you can map from one type to another.
However, you cannot handle the "double inversion" of an ACTIVE_LOW
signal with a physical inverter added:

        nexus: led-nexus {
                #gpio-cells = <2>;
                gpio-map = <0 0 &gpio2 19 GPIO_ACTIVE_LOW>,     // inverted
                           <1 0 &gpio2 20 GPIO_ACTIVE_HIGH>,    // noninverted
                           <2 0 &gpio2 21 GPIO_ACTIVE_LOW>;     // inverted
                gpio-map-mask = <3 0>;
                // default gpio-map-pass-thru = <0 0>;
        };

        leds {
                compatible = "gpio-leds";
                led6-inverted {
                        gpios = <&nexus 0 GPIO_ACTIVE_HIGH>;
                };
                led7-noninverted {
                        gpios = <&nexus 1 GPIO_ACTIVE_HIGH>;
                };
                led8-double-inverted {  // FAILS: still inverted
                        gpios = <&nexus 2 GPIO_ACTIVE_LOW>;
                };
        };

It "works" if the last entry in gpio-map is changed to GPIO_ACTIVE_HIGH.
Still, the consumer would see the final translated polarity, and not the
actual one it needs to program the consumer for.

> > While an inverter can be described implicitly by exchanging the
> > GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> > Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> > th provider and consumer sides:
> >   1. The GPIO provider (controller) looks at the flags to know the
> >      polarity, so it can translate between logical (active/not active)
> >      and physical (high/low) signal levels.
> >   2. While the signal polarity is usually fixed on the GPIO consumer
> >      side (e.g. an LED is tied to either the supply voltage or GND),
> >      it may be configurable on some devices, and both sides need to
> >      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
> >      match the actual polarity.
> >      There exists a similar issue with interrupt flags, where both the
> >      interrupt controller and the device generating the interrupt need
> >      to agree, which breaks in the presence of a physical inverter not
> >      described in DT (see e.g. [3]).
>
> Adding an inverted flag as I've suggested would also solve this issue.

As per your suggestion in "Re: [PATCH V4 2/2] gpio: inverter: document
the inverter bindings"?
https://lore.kernel.org/linux-devicetree/CAL_JsqLp___2O-naU+2PPQy0QmJX6+aN3hByz-OB9+qFvWgN9Q@mail.gmail.com/

Oh, now I understand. I was misguided by Harish' interpretation
https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/
which assumed an "inverted" property, e.g.

    inverted = /bits/ 8 <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0>;

But you actually meant a new GPIO_INVERTED flag, to be ORed into the 2nd
cell of a GPIO specifier? I.e. add to include/dt-bindings/gpio/gpio.h"

    /* Bit 6 expresses the presence of a physical inverter */
    #define GPIO_INVERTED 64

We need to be very careful in defining to which side the GPIO_ACTIVE_*
applies to (consumer?), and which side the GPIO_INVERTED flag (provider?).
Still, this doesn't help if e.g. a FET is used instead of a push-pull
inverter, as the former needs translation of other flags (which the
nexus can do, the caveats above still applies, though).

Same for adding IRQ_TYPE_INVERTED.

Related issue: how to handle physical inverters on SPI chip select lines,
if the SPI slave can be configured for both polarities?

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Rob Herring Dec. 6, 2019, 3:03 p.m. UTC | #5
On Fri, Dec 6, 2019 at 3:17 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Rob,
>
> On Thu, Dec 5, 2019 at 10:06 PM Rob Herring <robh@kernel.org> wrote:
> > On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
> > > Add Device Tree bindings for a GPIO repeater, with optional translation
> > > of physical signal properties.  This is useful for describing explicitly
> > > the presence of e.g. an inverter on a GPIO line, and was inspired by the
> > > non-YAML gpio-inverter bindings by Harish Jenny K N
> > > <harish_kandiga@mentor.com>[1].
> > >
> > > Note that this is different from a GPIO Nexus Node[2], which cannot do
> > > physical signal property translation.
> >
> > It can't? Why not? The point of the passthru mask is to not do
> > translation of flags, but without it you are always doing translation of
> > cells.
>
> Thanks for pushing me deeper into nexuses!
> You're right, you can map from one type to another.
> However, you cannot handle the "double inversion" of an ACTIVE_LOW
> signal with a physical inverter added:
>
>         nexus: led-nexus {
>                 #gpio-cells = <2>;
>                 gpio-map = <0 0 &gpio2 19 GPIO_ACTIVE_LOW>,     // inverted
>                            <1 0 &gpio2 20 GPIO_ACTIVE_HIGH>,    // noninverted
>                            <2 0 &gpio2 21 GPIO_ACTIVE_LOW>;     // inverted
>                 gpio-map-mask = <3 0>;
>                 // default gpio-map-pass-thru = <0 0>;
>         };
>
>         leds {
>                 compatible = "gpio-leds";
>                 led6-inverted {
>                         gpios = <&nexus 0 GPIO_ACTIVE_HIGH>;
>                 };
>                 led7-noninverted {
>                         gpios = <&nexus 1 GPIO_ACTIVE_HIGH>;
>                 };
>                 led8-double-inverted {  // FAILS: still inverted
>                         gpios = <&nexus 2 GPIO_ACTIVE_LOW>;
>                 };
>         };
>
> It "works" if the last entry in gpio-map is changed to GPIO_ACTIVE_HIGH.
> Still, the consumer would see the final translated polarity, and not the
> actual one it needs to program the consumer for.

I'm not really following. Why isn't a double inversion just the same
as no inversion?

> > > While an inverter can be described implicitly by exchanging the
> > > GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> > > Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> > > th provider and consumer sides:
> > >   1. The GPIO provider (controller) looks at the flags to know the
> > >      polarity, so it can translate between logical (active/not active)
> > >      and physical (high/low) signal levels.
> > >   2. While the signal polarity is usually fixed on the GPIO consumer
> > >      side (e.g. an LED is tied to either the supply voltage or GND),
> > >      it may be configurable on some devices, and both sides need to
> > >      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
> > >      match the actual polarity.
> > >      There exists a similar issue with interrupt flags, where both the
> > >      interrupt controller and the device generating the interrupt need
> > >      to agree, which breaks in the presence of a physical inverter not
> > >      described in DT (see e.g. [3]).
> >
> > Adding an inverted flag as I've suggested would also solve this issue.
>
> As per your suggestion in "Re: [PATCH V4 2/2] gpio: inverter: document
> the inverter bindings"?
> https://lore.kernel.org/linux-devicetree/CAL_JsqLp___2O-naU+2PPQy0QmJX6+aN3hByz-OB9+qFvWgN9Q@mail.gmail.com/
>
> Oh, now I understand. I was misguided by Harish' interpretation
> https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/
> which assumed an "inverted" property, e.g.
>
>     inverted = /bits/ 8 <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0>;
>
> But you actually meant a new GPIO_INVERTED flag, to be ORed into the 2nd
> cell of a GPIO specifier? I.e. add to include/dt-bindings/gpio/gpio.h"
>
>     /* Bit 6 expresses the presence of a physical inverter */
>     #define GPIO_INVERTED 64

Exactly.

> We need to be very careful in defining to which side the GPIO_ACTIVE_*
> applies to (consumer?), and which side the GPIO_INVERTED flag (provider?).
> Still, this doesn't help if e.g. a FET is used instead of a push-pull
> inverter, as the former needs translation of other flags (which the
> nexus can do, the caveats above still applies, though).

Yes. Historically the cells values are meaningful to the provider and
opaque to the consumer. Standardized cell values changes that
somewhat. I think we want the active flag to be from the provider's
prospective because the provider always needs to know. The consumer
often doesn't need to know. That also means things work without the
GPIO_INVERTED flag if the consumer doesn't care which is what we have
today already and we can't go back in time.


> Same for adding IRQ_TYPE_INVERTED.

I suppose so, yes.

> Related issue: how to handle physical inverters on SPI chip select lines,
> if the SPI slave can be configured for both polarities?

Good question. Perhaps in a different way because we have to handle
both h/w controlled and gpio chip selects.

However, how would one configure the polarity in the device in the
first place? You have to assert the CS first to give a command to
reprogram it.

Rob
Geert Uytterhoeven Jan. 6, 2020, 8:12 a.m. UTC | #6
Hi Rob,

On Fri, Dec 6, 2019 at 4:04 PM Rob Herring <robh@kernel.org> wrote:
> On Fri, Dec 6, 2019 at 3:17 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Thu, Dec 5, 2019 at 10:06 PM Rob Herring <robh@kernel.org> wrote:
> > > On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
> > > > Add Device Tree bindings for a GPIO repeater, with optional translation
> > > > of physical signal properties.  This is useful for describing explicitly
> > > > the presence of e.g. an inverter on a GPIO line, and was inspired by the
> > > > non-YAML gpio-inverter bindings by Harish Jenny K N
> > > > <harish_kandiga@mentor.com>[1].
> > > >
> > > > Note that this is different from a GPIO Nexus Node[2], which cannot do
> > > > physical signal property translation.
> > >
> > > It can't? Why not? The point of the passthru mask is to not do
> > > translation of flags, but without it you are always doing translation of
> > > cells.
> >
> > Thanks for pushing me deeper into nexuses!
> > You're right, you can map from one type to another.
> > However, you cannot handle the "double inversion" of an ACTIVE_LOW
> > signal with a physical inverter added:
> >
> >         nexus: led-nexus {
> >                 #gpio-cells = <2>;
> >                 gpio-map = <0 0 &gpio2 19 GPIO_ACTIVE_LOW>,     // inverted
> >                            <1 0 &gpio2 20 GPIO_ACTIVE_HIGH>,    // noninverted
> >                            <2 0 &gpio2 21 GPIO_ACTIVE_LOW>;     // inverted
> >                 gpio-map-mask = <3 0>;
> >                 // default gpio-map-pass-thru = <0 0>;
> >         };
> >
> >         leds {
> >                 compatible = "gpio-leds";
> >                 led6-inverted {
> >                         gpios = <&nexus 0 GPIO_ACTIVE_HIGH>;
> >                 };
> >                 led7-noninverted {
> >                         gpios = <&nexus 1 GPIO_ACTIVE_HIGH>;
> >                 };
> >                 led8-double-inverted {  // FAILS: still inverted
> >                         gpios = <&nexus 2 GPIO_ACTIVE_LOW>;
> >                 };
> >         };
> >
> > It "works" if the last entry in gpio-map is changed to GPIO_ACTIVE_HIGH.
> > Still, the consumer would see the final translated polarity, and not the
> > actual one it needs to program the consumer for.
>
> I'm not really following. Why isn't a double inversion just the same
> as no inversion?

Because the nexus can only mask and/or substitute bits.
It cannot do a XOR operation on the GPIO flags.

> > > > While an inverter can be described implicitly by exchanging the
> > > > GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> > > > Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> > > > th provider and consumer sides:
> > > >   1. The GPIO provider (controller) looks at the flags to know the
> > > >      polarity, so it can translate between logical (active/not active)
> > > >      and physical (high/low) signal levels.
> > > >   2. While the signal polarity is usually fixed on the GPIO consumer
> > > >      side (e.g. an LED is tied to either the supply voltage or GND),
> > > >      it may be configurable on some devices, and both sides need to
> > > >      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
> > > >      match the actual polarity.
> > > >      There exists a similar issue with interrupt flags, where both the
> > > >      interrupt controller and the device generating the interrupt need
> > > >      to agree, which breaks in the presence of a physical inverter not
> > > >      described in DT (see e.g. [3]).
> > >
> > > Adding an inverted flag as I've suggested would also solve this issue.
> >
> > As per your suggestion in "Re: [PATCH V4 2/2] gpio: inverter: document
> > the inverter bindings"?
> > https://lore.kernel.org/linux-devicetree/CAL_JsqLp___2O-naU+2PPQy0QmJX6+aN3hByz-OB9+qFvWgN9Q@mail.gmail.com/
> >
> > Oh, now I understand. I was misguided by Harish' interpretation
> > https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/
> > which assumed an "inverted" property, e.g.
> >
> >     inverted = /bits/ 8 <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0>;
> >
> > But you actually meant a new GPIO_INVERTED flag, to be ORed into the 2nd
> > cell of a GPIO specifier? I.e. add to include/dt-bindings/gpio/gpio.h"
> >
> >     /* Bit 6 expresses the presence of a physical inverter */
> >     #define GPIO_INVERTED 64
>
> Exactly.

OK, makes sense.

> > We need to be very careful in defining to which side the GPIO_ACTIVE_*
> > applies to (consumer?), and which side the GPIO_INVERTED flag (provider?).
> > Still, this doesn't help if e.g. a FET is used instead of a push-pull
> > inverter, as the former needs translation of other flags (which the
> > nexus can do, the caveats above still applies, though).
>
> Yes. Historically the cells values are meaningful to the provider and
> opaque to the consumer. Standardized cell values changes that
> somewhat. I think we want the active flag to be from the provider's
> prospective because the provider always needs to know. The consumer
> often doesn't need to know. That also means things work without the
> GPIO_INVERTED flag if the consumer doesn't care which is what we have
> today already and we can't go back in time.
>
>
> > Same for adding IRQ_TYPE_INVERTED.
>
> I suppose so, yes.
>
> > Related issue: how to handle physical inverters on SPI chip select lines,
> > if the SPI slave can be configured for both polarities?
>
> Good question. Perhaps in a different way because we have to handle
> both h/w controlled and gpio chip selects.
>
> However, how would one configure the polarity in the device in the
> first place? You have to assert the CS first to give a command to
> reprogram it.

That's indeed true for a simple SPI slave.
But if it is a smarter device (e.g. a generic micro controller), it may use the
system's DTB to configure itself.

Gr{oetje,eeting}s,

                        Geert
Harish Jenny K N Jan. 7, 2020, 9:22 a.m. UTC | #7
On 06/01/20 1:42 PM, Geert Uytterhoeven wrote:
> Hi Rob,
>
> On Fri, Dec 6, 2019 at 4:04 PM Rob Herring <robh@kernel.org> wrote:
>> On Fri, Dec 6, 2019 at 3:17 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>>> On Thu, Dec 5, 2019 at 10:06 PM Rob Herring <robh@kernel.org> wrote:
>>>> On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
>>>>> Add Device Tree bindings for a GPIO repeater, with optional translation
>>>>> of physical signal properties.  This is useful for describing explicitly
>>>>> the presence of e.g. an inverter on a GPIO line, and was inspired by the
>>>>> non-YAML gpio-inverter bindings by Harish Jenny K N
>>>>> <harish_kandiga@mentor.com>[1].
>>>>>
>>>>> Note that this is different from a GPIO Nexus Node[2], which cannot do
>>>>> physical signal property translation.
>>>> It can't? Why not? The point of the passthru mask is to not do
>>>> translation of flags, but without it you are always doing translation of
>>>> cells.
>>> Thanks for pushing me deeper into nexuses!
>>> You're right, you can map from one type to another.
>>> However, you cannot handle the "double inversion" of an ACTIVE_LOW
>>> signal with a physical inverter added:
>>>
>>>         nexus: led-nexus {
>>>                 #gpio-cells = <2>;
>>>                 gpio-map = <0 0 &gpio2 19 GPIO_ACTIVE_LOW>,     // inverted
>>>                            <1 0 &gpio2 20 GPIO_ACTIVE_HIGH>,    // noninverted
>>>                            <2 0 &gpio2 21 GPIO_ACTIVE_LOW>;     // inverted
>>>                 gpio-map-mask = <3 0>;
>>>                 // default gpio-map-pass-thru = <0 0>;
>>>         };
>>>
>>>         leds {
>>>                 compatible = "gpio-leds";
>>>                 led6-inverted {
>>>                         gpios = <&nexus 0 GPIO_ACTIVE_HIGH>;
>>>                 };
>>>                 led7-noninverted {
>>>                         gpios = <&nexus 1 GPIO_ACTIVE_HIGH>;
>>>                 };
>>>                 led8-double-inverted {  // FAILS: still inverted
>>>                         gpios = <&nexus 2 GPIO_ACTIVE_LOW>;
>>>                 };
>>>         };
>>>
>>> It "works" if the last entry in gpio-map is changed to GPIO_ACTIVE_HIGH.
>>> Still, the consumer would see the final translated polarity, and not the
>>> actual one it needs to program the consumer for.
>> I'm not really following. Why isn't a double inversion just the same
>> as no inversion?
> Because the nexus can only mask and/or substitute bits.
> It cannot do a XOR operation on the GPIO flags.
>
>>>>> While an inverter can be described implicitly by exchanging the
>>>>> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
>>>>> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
>>>>> th provider and consumer sides:
>>>>>   1. The GPIO provider (controller) looks at the flags to know the
>>>>>      polarity, so it can translate between logical (active/not active)
>>>>>      and physical (high/low) signal levels.
>>>>>   2. While the signal polarity is usually fixed on the GPIO consumer
>>>>>      side (e.g. an LED is tied to either the supply voltage or GND),
>>>>>      it may be configurable on some devices, and both sides need to
>>>>>      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>>>>>      match the actual polarity.
>>>>>      There exists a similar issue with interrupt flags, where both the
>>>>>      interrupt controller and the device generating the interrupt need
>>>>>      to agree, which breaks in the presence of a physical inverter not
>>>>>      described in DT (see e.g. [3]).
>>>> Adding an inverted flag as I've suggested would also solve this issue.
>>> As per your suggestion in "Re: [PATCH V4 2/2] gpio: inverter: document
>>> the inverter bindings"?
>>> https://lore.kernel.org/linux-devicetree/CAL_JsqLp___2O-naU+2PPQy0QmJX6+aN3hByz-OB9+qFvWgN9Q@mail.gmail.com/
>>>
>>> Oh, now I understand. I was misguided by Harish' interpretation
>>> https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/
>>> which assumed an "inverted" property, e.g.
>>>
>>>     inverted = /bits/ 8 <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0>;
>>>
>>> But you actually meant a new GPIO_INVERTED flag, to be ORed into the 2nd
>>> cell of a GPIO specifier? I.e. add to include/dt-bindings/gpio/gpio.h"
>>>
>>>     /* Bit 6 expresses the presence of a physical inverter */
>>>     #define GPIO_INVERTED 64
>> Exactly.
> OK, makes sense.


The reason I went for "inverted" property is because, we can specify this for gpios at provider side.

The usecase needed to define the polarity which did not have kernel space consumer driver.


I am not sure how do we achieve this using GPIO_INVERTED flag. We need some sort of node/gpio-hog to specify these

type of properties? Otherwise gpio-pin will be held by kernel or the module using the hog property and the user space application will not be able to access pin.


or please let me know if I am missing something.


>
>>> We need to be very careful in defining to which side the GPIO_ACTIVE_*
>>> applies to (consumer?), and which side the GPIO_INVERTED flag (provider?).
>>> Still, this doesn't help if e.g. a FET is used instead of a push-pull
>>> inverter, as the former needs translation of other flags (which the
>>> nexus can do, the caveats above still applies, though).
>> Yes. Historically the cells values are meaningful to the provider and
>> opaque to the consumer. Standardized cell values changes that
>> somewhat. I think we want the active flag to be from the provider's
>> prospective because the provider always needs to know. The consumer
>> often doesn't need to know. That also means things work without the
>> GPIO_INVERTED flag if the consumer doesn't care which is what we have
>> today already and we can't go back in time.
>>

Things will work without GPIO_INVERTED flag for consumers which can specify GPIO_ACTIVE_* flags.



>>> Same for adding IRQ_TYPE_INVERTED.
>> I suppose so, yes.
>>
>>> Related issue: how to handle physical inverters on SPI chip select lines,
>>> if the SPI slave can be configured for both polarities?
>> Good question. Perhaps in a different way because we have to handle
>> both h/w controlled and gpio chip selects.
>>
>> However, how would one configure the polarity in the device in the
>> first place? You have to assert the CS first to give a command to
>> reprogram it.
> That's indeed true for a simple SPI slave.
> But if it is a smarter device (e.g. a generic micro controller), it may use the
> system's DTB to configure itself.
>
> Gr{oetje,eeting}s,
>
>                         Geert
>
Harish Jenny K N Jan. 16, 2020, 5:09 a.m. UTC | #8
Hi Linus,


On 07/01/20 2:52 PM, Harish Jenny K N wrote:
> On 06/01/20 1:42 PM, Geert Uytterhoeven wrote:
>> Hi Rob,
>>
>> On Fri, Dec 6, 2019 at 4:04 PM Rob Herring <robh@kernel.org> wrote:
>>> On Fri, Dec 6, 2019 at 3:17 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>>>> On Thu, Dec 5, 2019 at 10:06 PM Rob Herring <robh@kernel.org> wrote:
>>>>> On Wed, Nov 27, 2019 at 09:42:50AM +0100, Geert Uytterhoeven wrote:
>>>>>> Add Device Tree bindings for a GPIO repeater, with optional translation
>>>>>> of physical signal properties.  This is useful for describing explicitly
>>>>>> the presence of e.g. an inverter on a GPIO line, and was inspired by the
>>>>>> non-YAML gpio-inverter bindings by Harish Jenny K N
>>>>>> <harish_kandiga@mentor.com>[1].
>>>>>>
>>>>>> Note that this is different from a GPIO Nexus Node[2], which cannot do
>>>>>> physical signal property translation.
>>>>> It can't? Why not? The point of the passthru mask is to not do
>>>>> translation of flags, but without it you are always doing translation of
>>>>> cells.
>>>> Thanks for pushing me deeper into nexuses!
>>>> You're right, you can map from one type to another.
>>>> However, you cannot handle the "double inversion" of an ACTIVE_LOW
>>>> signal with a physical inverter added:
>>>>
>>>>         nexus: led-nexus {
>>>>                 #gpio-cells = <2>;
>>>>                 gpio-map = <0 0 &gpio2 19 GPIO_ACTIVE_LOW>,     // inverted
>>>>                            <1 0 &gpio2 20 GPIO_ACTIVE_HIGH>,    // noninverted
>>>>                            <2 0 &gpio2 21 GPIO_ACTIVE_LOW>;     // inverted
>>>>                 gpio-map-mask = <3 0>;
>>>>                 // default gpio-map-pass-thru = <0 0>;
>>>>         };
>>>>
>>>>         leds {
>>>>                 compatible = "gpio-leds";
>>>>                 led6-inverted {
>>>>                         gpios = <&nexus 0 GPIO_ACTIVE_HIGH>;
>>>>                 };
>>>>                 led7-noninverted {
>>>>                         gpios = <&nexus 1 GPIO_ACTIVE_HIGH>;
>>>>                 };
>>>>                 led8-double-inverted {  // FAILS: still inverted
>>>>                         gpios = <&nexus 2 GPIO_ACTIVE_LOW>;
>>>>                 };
>>>>         };
>>>>
>>>> It "works" if the last entry in gpio-map is changed to GPIO_ACTIVE_HIGH.
>>>> Still, the consumer would see the final translated polarity, and not the
>>>> actual one it needs to program the consumer for.
>>> I'm not really following. Why isn't a double inversion just the same
>>> as no inversion?
>> Because the nexus can only mask and/or substitute bits.
>> It cannot do a XOR operation on the GPIO flags.
>>
>>>>>> While an inverter can be described implicitly by exchanging the
>>>>>> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
>>>>>> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
>>>>>> th provider and consumer sides:
>>>>>>   1. The GPIO provider (controller) looks at the flags to know the
>>>>>>      polarity, so it can translate between logical (active/not active)
>>>>>>      and physical (high/low) signal levels.
>>>>>>   2. While the signal polarity is usually fixed on the GPIO consumer
>>>>>>      side (e.g. an LED is tied to either the supply voltage or GND),
>>>>>>      it may be configurable on some devices, and both sides need to
>>>>>>      agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>>>>>>      match the actual polarity.
>>>>>>      There exists a similar issue with interrupt flags, where both the
>>>>>>      interrupt controller and the device generating the interrupt need
>>>>>>      to agree, which breaks in the presence of a physical inverter not
>>>>>>      described in DT (see e.g. [3]).
>>>>> Adding an inverted flag as I've suggested would also solve this issue.
>>>> As per your suggestion in "Re: [PATCH V4 2/2] gpio: inverter: document
>>>> the inverter bindings"?
>>>> https://lore.kernel.org/linux-devicetree/CAL_JsqLp___2O-naU+2PPQy0QmJX6+aN3hByz-OB9+qFvWgN9Q@mail.gmail.com/
>>>>
>>>> Oh, now I understand. I was misguided by Harish' interpretation
>>>> https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/
>>>> which assumed an "inverted" property, e.g.
>>>>
>>>>     inverted = /bits/ 8 <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0>;
>>>>
>>>> But you actually meant a new GPIO_INVERTED flag, to be ORed into the 2nd
>>>> cell of a GPIO specifier? I.e. add to include/dt-bindings/gpio/gpio.h"
>>>>
>>>>     /* Bit 6 expresses the presence of a physical inverter */
>>>>     #define GPIO_INVERTED 64
>>> Exactly.
>> OK, makes sense.
>
> The reason I went for "inverted" property is because, we can specify this for gpios at provider side.
>
> The usecase needed to define the polarity which did not have kernel space consumer driver.
>
>
> I am not sure how do we achieve this using GPIO_INVERTED flag. We need some sort of node/gpio-hog to specify these
>
> type of properties? Otherwise gpio-pin will be held by kernel or the module using the hog property and the user space application will not be able to access pin.
>
>
> or please let me know if I am missing something.
>
>
>>>> We need to be very careful in defining to which side the GPIO_ACTIVE_*
>>>> applies to (consumer?), and which side the GPIO_INVERTED flag (provider?).
>>>> Still, this doesn't help if e.g. a FET is used instead of a push-pull
>>>> inverter, as the former needs translation of other flags (which the
>>>> nexus can do, the caveats above still applies, though).
>>> Yes. Historically the cells values are meaningful to the provider and
>>> opaque to the consumer. Standardized cell values changes that
>>> somewhat. I think we want the active flag to be from the provider's
>>> prospective because the provider always needs to know. The consumer
>>> often doesn't need to know. That also means things work without the
>>> GPIO_INVERTED flag if the consumer doesn't care which is what we have
>>> today already and we can't go back in time.
>>>
> Things will work without GPIO_INVERTED flag for consumers which can specify GPIO_ACTIVE_* flags.
>
>
>
>>>> Same for adding IRQ_TYPE_INVERTED.
>>> I suppose so, yes.
>>>
>>>> Related issue: how to handle physical inverters on SPI chip select lines,
>>>> if the SPI slave can be configured for both polarities?
>>> Good question. Perhaps in a different way because we have to handle
>>> both h/w controlled and gpio chip selects.
>>>
>>> However, how would one configure the polarity in the device in the
>>> first place? You have to assert the CS first to give a command to
>>> reprogram it.
>> That's indeed true for a simple SPI slave.
>> But if it is a smarter device (e.g. a generic micro controller), it may use the
>> system's DTB to configure itself.
>>
>> Gr{oetje,eeting}s,
>>
>>                         Geert
>>


Can you please let me know your inputs on this ?


Now that Geert has sent v4 patch of GPIO Aggregator by "Dropping controversial GPIO repeater", I do not see the above mentioned inverter usecase can be handled anymore.


Is the observation/patch submitted in https://lore.kernel.org/linux-devicetree/dde73334-a26d-b53f-6b97-4101c1cdc185@mentor.com/ still not acceptable?



Thanks,

Harish

Patch
diff mbox series

diff --git a/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
new file mode 100644
index 0000000000000000..efdee0c3be43f731
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
@@ -0,0 +1,53 @@ 
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-repeater.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO Repeater
+
+maintainers:
+  - Harish Jenny K N <harish_kandiga@mentor.com>
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description:
+  This represents a repeater for one or more GPIOs, possibly including physical
+  signal property translation (e.g. polarity inversion).
+
+properties:
+  compatible:
+    const: gpio-repeater
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+  gpios:
+    description:
+      Phandle and specifier, one for each repeated GPIO.
+
+  gpio-line-names:
+    description:
+      Strings defining the names of the GPIO lines going out of the GPIO
+      controller.
+
+required:
+  - compatible
+  - "#gpio-cells"
+  - gpio-controller
+  - gpios
+
+additionalProperties: false
+
+examples:
+  # Device node describing a polarity inverter for a single GPIO
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    inverter: gpio-repeater {
+        compatible = "gpio-repeater";
+        #gpio-cells = <2>;
+        gpio-controller;
+        gpios = <&gpio 95 GPIO_ACTIVE_LOW>;
+    };