All of lore.kernel.org
 help / color / mirror / Atom feed
* Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 13:05 ` Marc Gonzalez
  0 siblings, 0 replies; 10+ messages in thread
From: Marc Gonzalez @ 2019-12-11 13:05 UTC (permalink / raw)
  To: GPIO; +Cc: Linux ARM, Linus Walleij, Uwe Kleine-Konig

Hello,

I've asked linusw a few times on IRC, and every time, I /think/ I understand,
then I get confused again later. So I'm trying to understand once and for all.

Please do not hesitate to correct any mistake/misconception below.

I want to discuss a "simple" GPIO reset pin.

1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
receive power, clocks don't tick, nothing changes state.

2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
on the line is HIGH (e.g. 3.3V or 5V)

2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
on the line is LOW (e.g. 0V, connected to ground)

3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
and current has not propagated everywhere, LOW voltage on the reset pin means
the circuit is "held" in reset, until we are ready to set voltage HIGH on the
reset pin to disable the reset, and enable the circuit.


Suppose a circuit's HW description states:

RESET_N:
External Reset.
Active LOW reset signal to the device.
See Figure 4.6 on page 21 for reset timing requirements.
Figure 4.6 shows the minimum timing interval for RESET_N.
RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.


4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:

	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;


OK, now we're getting into the parts of the GPIO API I don't understand well.

If I just call

	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);

then I am able to interact with the device. How can that be?

Is GPIOD_OUT_LOW a /logical/ low?
In other words, does the call above really set the line HIGH
=> RESET INACTIVE => CIRCUIT ENABLED ?

The problem is that it does not guarantee that the line was LOW for 200 µs
before being set HIGH, right?

It would appear that the correct sequence of calls for my circuit should be:

a)	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
b)	usleep_range(200, 300);
c)	gpiod_set_value_cansleep(reset, 0);

If I understand correctly:
a) configures the pin as an output, and sets it to LOGICAL HIGH, i.e. PHYSICAL LOW
b) keeps the RESET_N signal at PHYSICAL LOW for 200-300 µs
c) sets the pin to LOGICAL 0/LOW = PHYSICAL HIGH


For my own reference, I'll paste the last conversation I had on IRC:

(10:33:29 AM) marc|gonzalez: Heya! linusw: for an optional reset GPIO pin, IIRC, just doing devm_gpiod_get_optional(cdev, "reset", GPIOD_OUT_LOW);  will have the gpiod framework "do the right thing" to tweak/frob/toggle the pin to bring the device out of reset.  Am I misremembering?
(10:34:53 AM) marc|gonzalez: and also, properly naming the pin in the DT : reset-gpios = <&tlmm 84 GPIO_ACTIVE_LOW>;
(10:35:00 AM) ukleinek: marc|gonzalez: IMHO this should be: GPIOD_OUT_INACTIVE (not sure this exists, but the purpose would be much more obvious.)
(11:02:45 AM) linusw: marc|gonzalez: it will do the right thing provided you don't want devm_gpiod_get_optional() to assert reset, since it is active low, this will bring it inactive (de-asserted).
(11:03:33 AM) linusw: marc|gonzalez: you would have to request it GPIOD_OUT_HIGH if you also want it to assert reset (then later you need to toggle it to low explicitly).
(11:04:15 AM) linusw: marc|gonzalez: sometimes you want to request it GPIO_ASIS and take full control of asserting/deasserting the reset.


AFAIU, linusw is precisely describing the a) b) c) sequence above.

I'd be happy to read anyone's thoughts on the topic.

Regards.

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

* Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 13:05 ` Marc Gonzalez
  0 siblings, 0 replies; 10+ messages in thread
From: Marc Gonzalez @ 2019-12-11 13:05 UTC (permalink / raw)
  To: GPIO; +Cc: Linus Walleij, Linux ARM, Uwe Kleine-Konig

Hello,

I've asked linusw a few times on IRC, and every time, I /think/ I understand,
then I get confused again later. So I'm trying to understand once and for all.

Please do not hesitate to correct any mistake/misconception below.

I want to discuss a "simple" GPIO reset pin.

1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
receive power, clocks don't tick, nothing changes state.

2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
on the line is HIGH (e.g. 3.3V or 5V)

2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
on the line is LOW (e.g. 0V, connected to ground)

3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
and current has not propagated everywhere, LOW voltage on the reset pin means
the circuit is "held" in reset, until we are ready to set voltage HIGH on the
reset pin to disable the reset, and enable the circuit.


Suppose a circuit's HW description states:

RESET_N:
External Reset.
Active LOW reset signal to the device.
See Figure 4.6 on page 21 for reset timing requirements.
Figure 4.6 shows the minimum timing interval for RESET_N.
RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.


4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:

	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;


OK, now we're getting into the parts of the GPIO API I don't understand well.

If I just call

	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);

then I am able to interact with the device. How can that be?

Is GPIOD_OUT_LOW a /logical/ low?
In other words, does the call above really set the line HIGH
=> RESET INACTIVE => CIRCUIT ENABLED ?

The problem is that it does not guarantee that the line was LOW for 200 µs
before being set HIGH, right?

It would appear that the correct sequence of calls for my circuit should be:

a)	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
b)	usleep_range(200, 300);
c)	gpiod_set_value_cansleep(reset, 0);

If I understand correctly:
a) configures the pin as an output, and sets it to LOGICAL HIGH, i.e. PHYSICAL LOW
b) keeps the RESET_N signal at PHYSICAL LOW for 200-300 µs
c) sets the pin to LOGICAL 0/LOW = PHYSICAL HIGH


For my own reference, I'll paste the last conversation I had on IRC:

(10:33:29 AM) marc|gonzalez: Heya! linusw: for an optional reset GPIO pin, IIRC, just doing devm_gpiod_get_optional(cdev, "reset", GPIOD_OUT_LOW);  will have the gpiod framework "do the right thing" to tweak/frob/toggle the pin to bring the device out of reset.  Am I misremembering?
(10:34:53 AM) marc|gonzalez: and also, properly naming the pin in the DT : reset-gpios = <&tlmm 84 GPIO_ACTIVE_LOW>;
(10:35:00 AM) ukleinek: marc|gonzalez: IMHO this should be: GPIOD_OUT_INACTIVE (not sure this exists, but the purpose would be much more obvious.)
(11:02:45 AM) linusw: marc|gonzalez: it will do the right thing provided you don't want devm_gpiod_get_optional() to assert reset, since it is active low, this will bring it inactive (de-asserted).
(11:03:33 AM) linusw: marc|gonzalez: you would have to request it GPIOD_OUT_HIGH if you also want it to assert reset (then later you need to toggle it to low explicitly).
(11:04:15 AM) linusw: marc|gonzalez: sometimes you want to request it GPIO_ASIS and take full control of asserting/deasserting the reset.


AFAIU, linusw is precisely describing the a) b) c) sequence above.

I'd be happy to read anyone's thoughts on the topic.

Regards.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: Trying to understand basic concepts about GPIO reset pin
  2019-12-11 13:05 ` Marc Gonzalez
@ 2019-12-11 13:22   ` Russell King - ARM Linux admin
  -1 siblings, 0 replies; 10+ messages in thread
From: Russell King - ARM Linux admin @ 2019-12-11 13:22 UTC (permalink / raw)
  To: Marc Gonzalez; +Cc: GPIO, Linus Walleij, Linux ARM, Uwe Kleine-Konig

On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:
> Hello,
> 
> I've asked linusw a few times on IRC, and every time, I /think/ I understand,
> then I get confused again later. So I'm trying to understand once and for all.
> 
> Please do not hesitate to correct any mistake/misconception below.
> 
> I want to discuss a "simple" GPIO reset pin.
> 
> 1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
> In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
> receive power, clocks don't tick, nothing changes state.

Not necessarily.  Whether a circuit is powered or clocked has nothing
really to do with whether it is in reset or not.  Many devices specify
that power and clocks must be applied prior to reset being released,
which is sensible because it allows the reset to set the initial state
of the circuitry.

> 2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
> on the line is HIGH (e.g. 3.3V or 5V)

Correct.

> 2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
> on the line is LOW (e.g. 0V, connected to ground)

Correct.

> 3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
> and current has not propagated everywhere, LOW voltage on the reset pin means
> the circuit is "held" in reset, until we are ready to set voltage HIGH on the
> reset pin to disable the reset, and enable the circuit.

I don't think there's a "usually" about it.  Some devices take an
active high reset, others take an active low reset.

> Suppose a circuit's HW description states:
> 
> RESET_N:
> External Reset.
> Active LOW reset signal to the device.
> See Figure 4.6 on page 21 for reset timing requirements.
> Figure 4.6 shows the minimum timing interval for RESET_N.
> RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.
> 
> 
> 4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:
> 
> 	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;

I would say so - the reset is active low, so specifying it as active low
in DT seems entirely sensible.

> OK, now we're getting into the parts of the GPIO API I don't understand well.
> 
> If I just call
> 
> 	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> 
> then I am able to interact with the device. How can that be?

This is where things get complicated.  GPIOD_OUT_LOW is
GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:

	gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));

which will be zero.  gpiod_direction_output() respects the inversion
that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
the reset signal _high_.

I don't blame you for thinking this is confusing - the terminology
adopted in the kernel certainly is.

Thnk of whatever you give to the non-raw functions as "low means
inactive, high means active".

> 
> Is GPIOD_OUT_LOW a /logical/ low?
> In other words, does the call above really set the line HIGH
> => RESET INACTIVE => CIRCUIT ENABLED ?

Correct.

> The problem is that it does not guarantee that the line was LOW for 200 µs
> before being set HIGH, right?

Correct.

> It would appear that the correct sequence of calls for my circuit should be:
> 
> a)	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> b)	usleep_range(200, 300);
> c)	gpiod_set_value_cansleep(reset, 0);

Correct.

> If I understand correctly:
> a) configures the pin as an output, and sets it to LOGICAL HIGH, i.e. PHYSICAL LOW
> b) keeps the RESET_N signal at PHYSICAL LOW for 200-300 µs
> c) sets the pin to LOGICAL 0/LOW = PHYSICAL HIGH

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

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

* Re: Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 13:22   ` Russell King - ARM Linux admin
  0 siblings, 0 replies; 10+ messages in thread
From: Russell King - ARM Linux admin @ 2019-12-11 13:22 UTC (permalink / raw)
  To: Marc Gonzalez; +Cc: GPIO, Linus Walleij, Linux ARM, Uwe Kleine-Konig

On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:
> Hello,
> 
> I've asked linusw a few times on IRC, and every time, I /think/ I understand,
> then I get confused again later. So I'm trying to understand once and for all.
> 
> Please do not hesitate to correct any mistake/misconception below.
> 
> I want to discuss a "simple" GPIO reset pin.
> 
> 1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
> In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
> receive power, clocks don't tick, nothing changes state.

Not necessarily.  Whether a circuit is powered or clocked has nothing
really to do with whether it is in reset or not.  Many devices specify
that power and clocks must be applied prior to reset being released,
which is sensible because it allows the reset to set the initial state
of the circuitry.

> 2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
> on the line is HIGH (e.g. 3.3V or 5V)

Correct.

> 2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
> on the line is LOW (e.g. 0V, connected to ground)

Correct.

> 3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
> and current has not propagated everywhere, LOW voltage on the reset pin means
> the circuit is "held" in reset, until we are ready to set voltage HIGH on the
> reset pin to disable the reset, and enable the circuit.

I don't think there's a "usually" about it.  Some devices take an
active high reset, others take an active low reset.

> Suppose a circuit's HW description states:
> 
> RESET_N:
> External Reset.
> Active LOW reset signal to the device.
> See Figure 4.6 on page 21 for reset timing requirements.
> Figure 4.6 shows the minimum timing interval for RESET_N.
> RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.
> 
> 
> 4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:
> 
> 	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;

I would say so - the reset is active low, so specifying it as active low
in DT seems entirely sensible.

> OK, now we're getting into the parts of the GPIO API I don't understand well.
> 
> If I just call
> 
> 	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> 
> then I am able to interact with the device. How can that be?

This is where things get complicated.  GPIOD_OUT_LOW is
GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:

	gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));

which will be zero.  gpiod_direction_output() respects the inversion
that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
the reset signal _high_.

I don't blame you for thinking this is confusing - the terminology
adopted in the kernel certainly is.

Thnk of whatever you give to the non-raw functions as "low means
inactive, high means active".

> 
> Is GPIOD_OUT_LOW a /logical/ low?
> In other words, does the call above really set the line HIGH
> => RESET INACTIVE => CIRCUIT ENABLED ?

Correct.

> The problem is that it does not guarantee that the line was LOW for 200 µs
> before being set HIGH, right?

Correct.

> It would appear that the correct sequence of calls for my circuit should be:
> 
> a)	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> b)	usleep_range(200, 300);
> c)	gpiod_set_value_cansleep(reset, 0);

Correct.

> If I understand correctly:
> a) configures the pin as an output, and sets it to LOGICAL HIGH, i.e. PHYSICAL LOW
> b) keeps the RESET_N signal at PHYSICAL LOW for 200-300 µs
> c) sets the pin to LOGICAL 0/LOW = PHYSICAL HIGH

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: Trying to understand basic concepts about GPIO reset pin
  2019-12-11 13:22   ` Russell King - ARM Linux admin
@ 2019-12-11 13:38     ` Marc Gonzalez
  -1 siblings, 0 replies; 10+ messages in thread
From: Marc Gonzalez @ 2019-12-11 13:38 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: GPIO, Linus Walleij, Linux ARM, Uwe Kleine-Konig

On 11/12/2019 14:22, Russell King - ARM Linux admin wrote: [snip]

Thanks, Russell. Your confirmation helps a lot.

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

* Re: Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 13:38     ` Marc Gonzalez
  0 siblings, 0 replies; 10+ messages in thread
From: Marc Gonzalez @ 2019-12-11 13:38 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: GPIO, Linus Walleij, Linux ARM, Uwe Kleine-Konig

On 11/12/2019 14:22, Russell King - ARM Linux admin wrote: [snip]

Thanks, Russell. Your confirmation helps a lot.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: Trying to understand basic concepts about GPIO reset pin
  2019-12-11 13:22   ` Russell King - ARM Linux admin
@ 2019-12-11 13:45     ` Uwe Kleine-König
  -1 siblings, 0 replies; 10+ messages in thread
From: Uwe Kleine-König @ 2019-12-11 13:45 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: Marc Gonzalez, GPIO, Linus Walleij, Linux ARM

On Wed, Dec 11, 2019 at 01:22:03PM +0000, Russell King - ARM Linux admin wrote:
> On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:
> > Hello,
> > 
> > I've asked linusw a few times on IRC, and every time, I /think/ I understand,
> > then I get confused again later. So I'm trying to understand once and for all.
> > 
> > Please do not hesitate to correct any mistake/misconception below.
> > 
> > I want to discuss a "simple" GPIO reset pin.
> > 
> > 1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
> > In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
> > receive power, clocks don't tick, nothing changes state.
> 
> Not necessarily.  Whether a circuit is powered or clocked has nothing
> really to do with whether it is in reset or not.  Many devices specify
> that power and clocks must be applied prior to reset being released,
> which is sensible because it allows the reset to set the initial state
> of the circuitry.
> 
> > 2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
> > on the line is HIGH (e.g. 3.3V or 5V)
> 
> Correct.
> 
> > 2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
> > on the line is LOW (e.g. 0V, connected to ground)
> 
> Correct.
> 
> > 3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
> > and current has not propagated everywhere, LOW voltage on the reset pin means
> > the circuit is "held" in reset, until we are ready to set voltage HIGH on the
> > reset pin to disable the reset, and enable the circuit.
> 
> I don't think there's a "usually" about it.  Some devices take an
> active high reset, others take an active low reset.
> 
> > Suppose a circuit's HW description states:
> > 
> > RESET_N:
> > External Reset.
> > Active LOW reset signal to the device.
> > See Figure 4.6 on page 21 for reset timing requirements.
> > Figure 4.6 shows the minimum timing interval for RESET_N.
> > RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.
> > 
> > 
> > 4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:
> > 
> > 	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
> 
> I would say so - the reset is active low, so specifying it as active low
> in DT seems entirely sensible.
> 
> > OK, now we're getting into the parts of the GPIO API I don't understand well.
> > 
> > If I just call
> > 
> > 	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > 
> > then I am able to interact with the device. How can that be?
> 
> This is where things get complicated.  GPIOD_OUT_LOW is
> GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
> GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:
> 
> 	gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
> 
> which will be zero.  gpiod_direction_output() respects the inversion
> that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
> the reset signal _high_.
> 
> I don't blame you for thinking this is confusing - the terminology
> adopted in the kernel certainly is.
> 
> Thnk of whatever you give to the non-raw functions as "low means
> inactive, high means active".

I think it would be good to not pass GPIOD_OUT_LOW to
devm_gpiod_get_optional (et al). Something like

	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_ACTIVE);

would be much less confusing. Not sure this exists, but it would make a
good alias for GPIOD_OUT_HIGH.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

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

* Re: Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 13:45     ` Uwe Kleine-König
  0 siblings, 0 replies; 10+ messages in thread
From: Uwe Kleine-König @ 2019-12-11 13:45 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: GPIO, Linus Walleij, Linux ARM, Marc Gonzalez

On Wed, Dec 11, 2019 at 01:22:03PM +0000, Russell King - ARM Linux admin wrote:
> On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:
> > Hello,
> > 
> > I've asked linusw a few times on IRC, and every time, I /think/ I understand,
> > then I get confused again later. So I'm trying to understand once and for all.
> > 
> > Please do not hesitate to correct any mistake/misconception below.
> > 
> > I want to discuss a "simple" GPIO reset pin.
> > 
> > 1) When a reset pin is ACTIVE, the corresponding circuit is "held" in reset.
> > In other words, when a reset pin is ACTIVE, the circuit is DISABLED / does not
> > receive power, clocks don't tick, nothing changes state.
> 
> Not necessarily.  Whether a circuit is powered or clocked has nothing
> really to do with whether it is in reset or not.  Many devices specify
> that power and clocks must be applied prior to reset being released,
> which is sensible because it allows the reset to set the initial state
> of the circuitry.
> 
> > 2a) If a signal is ACTIVE HIGH, that means the signal is ACTIVE when the voltage
> > on the line is HIGH (e.g. 3.3V or 5V)
> 
> Correct.
> 
> > 2b) If a signal is ACTIVE LOW, that means the signal is ACTIVE when the voltage
> > on the line is LOW (e.g. 0V, connected to ground)
> 
> Correct.
> 
> > 3) Usually(?) a reset signal is ACTIVE LOW. That way, when the SoC is coming up,
> > and current has not propagated everywhere, LOW voltage on the reset pin means
> > the circuit is "held" in reset, until we are ready to set voltage HIGH on the
> > reset pin to disable the reset, and enable the circuit.
> 
> I don't think there's a "usually" about it.  Some devices take an
> active high reset, others take an active low reset.
> 
> > Suppose a circuit's HW description states:
> > 
> > RESET_N:
> > External Reset.
> > Active LOW reset signal to the device.
> > See Figure 4.6 on page 21 for reset timing requirements.
> > Figure 4.6 shows the minimum timing interval for RESET_N.
> > RESET_N must be driven LOW for at least the period of 200 µs before accessing registers.
> > 
> > 
> > 4) The DT node for this device should describe the reset pin as GPIO_ACTIVE_LOW:
> > 
> > 	reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
> 
> I would say so - the reset is active low, so specifying it as active low
> in DT seems entirely sensible.
> 
> > OK, now we're getting into the parts of the GPIO API I don't understand well.
> > 
> > If I just call
> > 
> > 	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > 
> > then I am able to interact with the device. How can that be?
> 
> This is where things get complicated.  GPIOD_OUT_LOW is
> GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
> GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:
> 
> 	gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
> 
> which will be zero.  gpiod_direction_output() respects the inversion
> that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
> the reset signal _high_.
> 
> I don't blame you for thinking this is confusing - the terminology
> adopted in the kernel certainly is.
> 
> Thnk of whatever you give to the non-raw functions as "low means
> inactive, high means active".

I think it would be good to not pass GPIOD_OUT_LOW to
devm_gpiod_get_optional (et al). Something like

	devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_ACTIVE);

would be much less confusing. Not sure this exists, but it would make a
good alias for GPIOD_OUT_HIGH.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: Trying to understand basic concepts about GPIO reset pin
  2019-12-11 13:45     ` Uwe Kleine-König
@ 2019-12-11 15:32       ` Linus Walleij
  -1 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2019-12-11 15:32 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Russell King - ARM Linux admin, Marc Gonzalez, GPIO, Linux ARM

On Wed, Dec 11, 2019 at 2:45 PM Uwe Kleine-König
<u.kleine-koenig@pengutronix.de> wrote:
> On Wed, Dec 11, 2019 at 01:22:03PM +0000, Russell King - ARM Linux admin wrote:
> > On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:

> > >     devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > >
> > > then I am able to interact with the device. How can that be?
> >
> > This is where things get complicated.  GPIOD_OUT_LOW is
> > GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
> > GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:
> >
> >       gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
> >
> > which will be zero.  gpiod_direction_output() respects the inversion
> > that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
> > the reset signal _high_.
> >
> > I don't blame you for thinking this is confusing - the terminology
> > adopted in the kernel certainly is.
> >
> > Thnk of whatever you give to the non-raw functions as "low means
> > inactive, high means active".
>
> I think it would be good to not pass GPIOD_OUT_LOW to
> devm_gpiod_get_optional (et al). Something like
>
>         devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_ACTIVE);
>
> would be much less confusing. Not sure this exists, but it would make a
> good alias for GPIOD_OUT_HIGH.

I have suggested in some other thread to create an alias
GPIO_OUT_ASSERTED / GPIO_OUT_DEASSERTED
and likewise change the name of the prototype
gpiod_set_value(gpiod, int value) to
gpiod_set_state(gpiod, bool asserted) rather than the
current int value so it is [more] clear what the argument to
these functions mean: that it is a logical level not
a physical level.

Then gradually or with a sed script just mass-convert
all users of the API to this signature. A single swift
conversion would be preferred by me personally.

I'll try to add it to my GPIO public TODO so that others
see it and be able to pick it up, because there are so
many ongoing refurbishing tasks that I need to tend to
personally.

Yours,
Linus Walleij

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

* Re: Trying to understand basic concepts about GPIO reset pin
@ 2019-12-11 15:32       ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2019-12-11 15:32 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: GPIO, Russell King - ARM Linux admin, Linux ARM, Marc Gonzalez

On Wed, Dec 11, 2019 at 2:45 PM Uwe Kleine-König
<u.kleine-koenig@pengutronix.de> wrote:
> On Wed, Dec 11, 2019 at 01:22:03PM +0000, Russell King - ARM Linux admin wrote:
> > On Wed, Dec 11, 2019 at 02:05:45PM +0100, Marc Gonzalez wrote:

> > >     devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > >
> > > then I am able to interact with the device. How can that be?
> >
> > This is where things get complicated.  GPIOD_OUT_LOW is
> > GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT without
> > GPIOD_FLAGS_BIT_DIR_VAL.  The above will therefore call:
> >
> >       gpiod_direction_output(gpiod, !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
> >
> > which will be zero.  gpiod_direction_output() respects the inversion
> > that GPIO_ACTIVE_LOW specified in DT.  So, GPIOD_OUT_LOW will set
> > the reset signal _high_.
> >
> > I don't blame you for thinking this is confusing - the terminology
> > adopted in the kernel certainly is.
> >
> > Thnk of whatever you give to the non-raw functions as "low means
> > inactive, high means active".
>
> I think it would be good to not pass GPIOD_OUT_LOW to
> devm_gpiod_get_optional (et al). Something like
>
>         devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_ACTIVE);
>
> would be much less confusing. Not sure this exists, but it would make a
> good alias for GPIOD_OUT_HIGH.

I have suggested in some other thread to create an alias
GPIO_OUT_ASSERTED / GPIO_OUT_DEASSERTED
and likewise change the name of the prototype
gpiod_set_value(gpiod, int value) to
gpiod_set_state(gpiod, bool asserted) rather than the
current int value so it is [more] clear what the argument to
these functions mean: that it is a logical level not
a physical level.

Then gradually or with a sed script just mass-convert
all users of the API to this signature. A single swift
conversion would be preferred by me personally.

I'll try to add it to my GPIO public TODO so that others
see it and be able to pick it up, because there are so
many ongoing refurbishing tasks that I need to tend to
personally.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2019-12-11 15:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-11 13:05 Trying to understand basic concepts about GPIO reset pin Marc Gonzalez
2019-12-11 13:05 ` Marc Gonzalez
2019-12-11 13:22 ` Russell King - ARM Linux admin
2019-12-11 13:22   ` Russell King - ARM Linux admin
2019-12-11 13:38   ` Marc Gonzalez
2019-12-11 13:38     ` Marc Gonzalez
2019-12-11 13:45   ` Uwe Kleine-König
2019-12-11 13:45     ` Uwe Kleine-König
2019-12-11 15:32     ` Linus Walleij
2019-12-11 15:32       ` Linus Walleij

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.