diff mbox series

[RESEND] iio: adis: set GPIO reset pin direction

Message ID 20210706092922.v555jjvxbyv52ifw@haukka.localdomain (mailing list archive)
State Superseded
Delegated to: Jonathan Cameron
Headers show
Series [RESEND] iio: adis: set GPIO reset pin direction | expand

Commit Message

Antti Keränen July 6, 2021, 9:29 a.m. UTC
Use GPIOD_OUT_LOW instead of GPIOD_ASIS as the reset pin needs to be an
active low output pin.

Suggested-by: Hannu Hartikainen <hannu@hrtk.in>
Signed-off-by: Antti Keränen <detegr@rbx.email>
---
The documentation of GPIO consumer interface states:

Be aware that there is no default direction for GPIOs. Therefore,
**using a GPIO without setting its direction first is illegal and will
result in undefined behavior!**

Therefore the direction of the reset GPIO pin should be set as output.

 drivers/iio/imu/adis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Lars-Peter Clausen July 7, 2021, 8:18 a.m. UTC | #1
On 7/6/21 11:29 AM, Antti Keränen wrote:
> Use GPIOD_OUT_LOW instead of GPIOD_ASIS as the reset pin needs to be an
> active low output pin.
>
> Suggested-by: Hannu Hartikainen <hannu@hrtk.in>
> Signed-off-by: Antti Keränen <detegr@rbx.email>

Hi,

Thanks for the patch, this looks good.

How about requesting it as GPIOD_OUT_HIGH and removing the 
gpiod_set_value_cansleep(gpio, 1) to avoid unnecessary toggling of the pin.

> ---
> The documentation of GPIO consumer interface states:
>
> Be aware that there is no default direction for GPIOs. Therefore,
> **using a GPIO without setting its direction first is illegal and will
> result in undefined behavior!**
>
> Therefore the direction of the reset GPIO pin should be set as output.
>
>   drivers/iio/imu/adis.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
> index 319b64b2fd88..7f13b3763732 100644
> --- a/drivers/iio/imu/adis.c
> +++ b/drivers/iio/imu/adis.c
> @@ -415,7 +415,7 @@ int __adis_initial_startup(struct adis *adis)
>   	int ret;
>   
>   	/* check if the device has rst pin low */
> -	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_ASIS);
> +	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_OUT_LOW);
>   	if (IS_ERR(gpio))
>   		return PTR_ERR(gpio);
>
Nuno Sa July 7, 2021, 8:36 a.m. UTC | #2
> From: Antti Keränen <detegr@rbx.email>
> Sent: Tuesday, July 6, 2021 11:29 AM
> To: linux-iio@vger.kernel.org
> Cc: Antti Keränen <detegr@rbx.email>; Hannu Hartikainen
> <hannu@hrtk.in>; Lars-Peter Clausen <lars@metafoo.de>; Hennerich,
> Michael <Michael.Hennerich@analog.com>; Sa, Nuno
> <Nuno.Sa@analog.com>; Jonathan Cameron <jic23@kernel.org>
> Subject: [RESEND PATCH] iio: adis: set GPIO reset pin direction
> 
> Use GPIOD_OUT_LOW instead of GPIOD_ASIS as the reset pin needs
> to be an
> active low output pin.
> 
> Suggested-by: Hannu Hartikainen <hannu@hrtk.in>
> Signed-off-by: Antti Keränen <detegr@rbx.email>
> ---
> The documentation of GPIO consumer interface states:
> 
> Be aware that there is no default direction for GPIOs. Therefore,
> **using a GPIO without setting its direction first is illegal and will
> result in undefined behavior!**
> 
> Therefore the direction of the reset GPIO pin should be set as output.
> 
>  drivers/iio/imu/adis.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
> index 319b64b2fd88..7f13b3763732 100644
> --- a/drivers/iio/imu/adis.c
> +++ b/drivers/iio/imu/adis.c
> @@ -415,7 +415,7 @@ int __adis_initial_startup(struct adis *adis)
>  	int ret;
> 
>  	/* check if the device has rst pin low */
> -	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset",
> GPIOD_ASIS);
> +	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset",
> GPIOD_OUT_LOW);
>  	if (IS_ERR(gpio))
>  		return PTR_ERR(gpio);
> 

Hi,

Thanks for the patch. Forcing the device reset was intentional
(thus the GPIO_ASIS). But what Lars is suggesting is a good idea
and a neat improvement here.

- Nuno Sá
Hannu Hartikainen July 7, 2021, 11:53 a.m. UTC | #3
Hi!

Thanks for reviewing the patch. I'll also chime in. We were working on
an ADIS device together with Antti so I've read some of the relevant
code, documentation and datasheets.

On Wed, 7 Jul 2021 08:36:47 +0000, "Sa, Nuno" <Nuno.Sa@analog.com> wrote:
> Thanks for the patch. Forcing the device reset was intentional
> (thus the GPIO_ASIS). But what Lars is suggesting is a good idea
> and a neat improvement here.

I don't understand what you mean. The GPIO consumer documentation[0]
states that if GPIO_ASIS is used, the pin direction must be set in
driver code later. AFAICT that doesn't happen.

If a pin was defined as input by default by the manufacturer, I don't
think there's a way to make an ADIS device work with RST on it without
patching the driver. Device trees couldn't be used to do that IIRC. I.e.
this patch is needed so the device reset works.

On Wed, 7 Jul 2021 10:18:57 +0200, Lars-Peter Clausen <lars@metafoo.de> wrote:
> How about requesting it as GPIOD_OUT_HIGH and removing the 
> gpiod_set_value_cansleep(gpio, 1) to avoid unnecessary toggling of the pin.

GPIOD_OUT_LOW and GPIOD_OUT_HIGH have different semantics.[1] Is setting
the pin to use wrong semantics to save one line of code and possibly
toggle the pin one time less worth it? (The ADIS devices whose
datasheets I've read have the RST pin as active low, ie. GPIOD_OUT_LOW
is semantically correct.)

If we really want that, I think the better choice is to use GPIO_ASIS,
gpiod_direction_output and gpiod_set_raw_value_cansleep and skip
semantically describing the pin altogether.

Hannu

[0]: https://www.kernel.org/doc/html/latest/driver-api/gpio/consumer.html
> GPIOD_ASIS or 0 to not initialize the GPIO at all. The direction must
> be set later with one of the dedicated functions.
[1]: https://www.kernel.org/doc/html/latest/driver-api/gpio/consumer.html#the-active-low-and-open-drain-semantics
Lars-Peter Clausen July 7, 2021, 12:25 p.m. UTC | #4
On 7/7/21 1:53 PM, Hannu Hartikainen wrote:
> [...]
> GPIOD_OUT_LOW and GPIOD_OUT_HIGH have different semantics.[1] Is setting
> the pin to use wrong semantics to save one line of code and possibly
> toggle the pin one time less worth it? (The ADIS devices whose
> datasheets I've read have the RST pin as active low, ie. GPIOD_OUT_LOW
> is semantically correct.)

GPIOD_OUT_LOW does not mean that the GPIO is active low. OUT_LOW just 
means that the GPIO is configured as output in the non-asserted 
state[1]. Whether it is active low or active high is configured through 
the flags associated with the GPIO descriptor. E.g. when using 
devicetree this is typically the field after the GPIO offset.

>
> If we really want that, I think the better choice is to use GPIO_ASIS,
> gpiod_direction_output and gpiod_set_raw_value_cansleep and skip
> semantically describing the pin altogether.
Requesting as output is the right solution.


[1] 
https://www.kernel.org/doc/html/latest/driver-api/gpio/consumer.html#obtaining-and-disposing-gpios
Lars-Peter Clausen July 7, 2021, 12:32 p.m. UTC | #5
On 7/7/21 10:36 AM, Sa, Nuno wrote:
>> From: Antti Keränen <detegr@rbx.email>
>> Sent: Tuesday, July 6, 2021 11:29 AM
>> To: linux-iio@vger.kernel.org
>> Cc: Antti Keränen <detegr@rbx.email>; Hannu Hartikainen
>> <hannu@hrtk.in>; Lars-Peter Clausen <lars@metafoo.de>; Hennerich,
>> Michael <Michael.Hennerich@analog.com>; Sa, Nuno
>> <Nuno.Sa@analog.com>; Jonathan Cameron <jic23@kernel.org>
>> Subject: [RESEND PATCH] iio: adis: set GPIO reset pin direction
>>
>> Use GPIOD_OUT_LOW instead of GPIOD_ASIS as the reset pin needs
>> to be an
>> active low output pin.
>>
>> Suggested-by: Hannu Hartikainen <hannu@hrtk.in>
>> Signed-off-by: Antti Keränen <detegr@rbx.email>
>> ---
>> The documentation of GPIO consumer interface states:
>>
>> Be aware that there is no default direction for GPIOs. Therefore,
>> **using a GPIO without setting its direction first is illegal and will
>> result in undefined behavior!**
>>
>> Therefore the direction of the reset GPIO pin should be set as output.
>>
>>   drivers/iio/imu/adis.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
>> index 319b64b2fd88..7f13b3763732 100644
>> --- a/drivers/iio/imu/adis.c
>> +++ b/drivers/iio/imu/adis.c
>> @@ -415,7 +415,7 @@ int __adis_initial_startup(struct adis *adis)
>>   	int ret;
>>
>>   	/* check if the device has rst pin low */
>> -	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset",
>> GPIOD_ASIS);
>> +	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset",
>> GPIOD_OUT_LOW);
>>   	if (IS_ERR(gpio))
>>   		return PTR_ERR(gpio);
>>
> Hi,
>
> Thanks for the patch. Forcing the device reset was intentional
> (thus the GPIO_ASIS). But what Lars is suggesting is a good idea
> and a neat improvement here.
>
GPIO_ASIS leaves the direction of the GPIO untouched. If the default is 
input, the GPIO will stay as an input, in which case triggering the 
reset does not work.
Nuno Sa July 7, 2021, 12:32 p.m. UTC | #6
Hi,

> From: Hannu Hartikainen <hannu@hrtk.in>
> Sent: Wednesday, July 7, 2021 1:53 PM
> To: Sa, Nuno <Nuno.Sa@analog.com>; Antti Keränen
> <detegr@rbx.email>; linux-iio@vger.kernel.org
> Cc: Lars-Peter Clausen <lars@metafoo.de>; Hennerich, Michael
> <Michael.Hennerich@analog.com>; Jonathan Cameron
> <jic23@kernel.org>
> Subject: RE: [RESEND PATCH] iio: adis: set GPIO reset pin direction
> 
> Hi!
> 
> Thanks for reviewing the patch. I'll also chime in. We were working on
> an ADIS device together with Antti so I've read some of the relevant
> code, documentation and datasheets.
> 
> On Wed, 7 Jul 2021 08:36:47 +0000, "Sa, Nuno"
> <Nuno.Sa@analog.com> wrote:
> > Thanks for the patch. Forcing the device reset was intentional
> > (thus the GPIO_ASIS). But what Lars is suggesting is a good idea
> > and a neat improvement here.
> 
> I don't understand what you mean. The GPIO consumer
> documentation[0]
> states that if GPIO_ASIS is used, the pin direction must be set in
> driver code later. AFAICT that doesn't happen.
> 
> If a pin was defined as input by default by the manufacturer, I don't
> think there's a way to make an ADIS device work with RST on it without
> patching the driver. Device trees couldn't be used to do that IIRC. I.e.
> this patch is needed so the device reset works.

Yes, you're right. This is pretty much assuming that the pin is already an output
one. Though you can typically make sure that the pin will be configured as
an output one (through pinctrl) which is what we are doing in the devicetree
overlays for the adis16475 device for example (in ADI trees).

> On Wed, 7 Jul 2021 10:18:57 +0200, Lars-Peter Clausen
> <lars@metafoo.de> wrote:
> > How about requesting it as GPIOD_OUT_HIGH and removing the
> > gpiod_set_value_cansleep(gpio, 1) to avoid unnecessary toggling of
> the pin.
> 
> GPIOD_OUT_LOW and GPIOD_OUT_HIGH have different
> semantics.[1] Is setting
> the pin to use wrong semantics to save one line of code and possibly
> toggle the pin one time less worth it? (The ADIS devices whose
> datasheets I've read have the RST pin as active low, ie.
> GPIOD_OUT_LOW
> is semantically correct.)

Well, AFAIK all the ADIS devices so far have the RST pin active low
so this a very fair assumption to make and use GPIOD_OUT_HIGH.
It can always be changed afterwards or even add a flag to the adis_data
structure...

> If we really want that, I think the better choice is to use GPIO_ASIS,
> gpiod_direction_output and gpiod_set_raw_value_cansleep and skip
> semantically describing the pin altogether.

Yes, we want to make sure a reset is done on the device. So, personally,
I'm fine with either approach. Either using GPIOD_OUT_HIGH or GPIO_ASIS
with the extra 'gpiod_direction_output()'...

- Nuno Sá
Hannu Hartikainen July 7, 2021, 1:30 p.m. UTC | #7
On Wed, 7 Jul 2021 14:25:06 +0200, Lars-Peter Clausen <lars@metafoo.de> wrote:
> GPIOD_OUT_LOW does not mean that the GPIO is active low. OUT_LOW just 
> means that the GPIO is configured as output in the non-asserted 
> state[1]. Whether it is active low or active high is configured through 
> the flags associated with the GPIO descriptor. E.g. when using 
> devicetree this is typically the field after the GPIO offset.

Oh, I misunderstood that. Thanks for pointing it out and sorry for the
confusion!

Your original suggestion of using GPIOD_OUT_HIGH sounds good to me,
then.

Hannu
diff mbox series

Patch

diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
index 319b64b2fd88..7f13b3763732 100644
--- a/drivers/iio/imu/adis.c
+++ b/drivers/iio/imu/adis.c
@@ -415,7 +415,7 @@  int __adis_initial_startup(struct adis *adis)
 	int ret;
 
 	/* check if the device has rst pin low */
-	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_ASIS);
+	gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(gpio))
 		return PTR_ERR(gpio);