Message ID | 20231103225601.6499-4-wsa+renesas@sang-engineering.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Geert Uytterhoeven |
Headers | show |
Series | gnss: ubx: support the reset pin of the Neo-M8 variant | expand |
On Fri, Nov 03, 2023 at 11:56:00PM +0100, Wolfram Sang wrote: > The Renesas KingFisher board includes a U-Blox Neo-M8 chip. This chip > has a reset pin which is also wired on the board. Add code to the driver > to support this reset pin. Because my GNSS device is hooked up via UART > and I2C simultaneously, I could verify functionality by opening/closing > the GNSS device using UART and see if the corresponding I2C device was > visible on the bus. > static int ubx_set_active(struct gnss_serial *gserial) > @@ -29,6 +31,8 @@ static int ubx_set_active(struct gnss_serial *gserial) > if (ret) > return ret; > > + gpiod_set_value_cansleep(data->reset_gpio, 0); > + > return 0; > } > > @@ -37,6 +41,8 @@ static int ubx_set_standby(struct gnss_serial *gserial) > struct ubx_data *data = gnss_serial_get_drvdata(gserial); > int ret; > > + gpiod_set_value_cansleep(data->reset_gpio, 1); > + > ret = regulator_disable(data->vcc); > if (ret) > return ret; > @@ -90,6 +96,13 @@ static int ubx_probe(struct serdev_device *serdev) > if (ret < 0 && ret != -ENODEV) > goto err_free_gserial; > > + /* Start with reset asserted */ > + data->reset_gpio = devm_gpiod_get_optional(&serdev->dev, "reset", GPIOD_OUT_HIGH); > + if (IS_ERR(data->reset_gpio)) { > + ret = PTR_ERR(data->reset_gpio); > + goto err_free_gserial; > + } > + > ret = gnss_serial_register(gserial); > if (ret) > goto err_free_gserial; So as I just replied to you v3, the hardware integration manual for NEO-M8 and the datasheets for some of the other modules explicitly says that the RESET_N pin should not be used this way: 1.5 I/O pins RESET_N: Reset input Driving RESET_N low activates a hardware reset of the system. Use this pin only to reset the module. Do not use RESET_N to turn the module on and off, since the reset state increases power consumption. (and AFAIU you should generally not try to use reset this way unless it is explicitly said to be supported). Johan
> 1.5 I/O pins > RESET_N: Reset input > Driving RESET_N low activates a hardware reset of the system. > Use this pin only to reset the module. Do not use RESET_N to > turn the module on and off, since the reset state increases > power consumption. > > (and AFAIU you should generally not try to use reset this way unless it > is explicitly said to be supported). Oh! That's the opposite of my intention :/ Okay, today I learnt something. Thank you for pointing this out. I will remember this and double check reset handling in the future. That means I only need to de-assert reset in probe() for now, right?
diff --git a/drivers/gnss/ubx.c b/drivers/gnss/ubx.c index 9b76b101ba5e..e7d151cbc8c3 100644 --- a/drivers/gnss/ubx.c +++ b/drivers/gnss/ubx.c @@ -7,6 +7,7 @@ #include <linux/errno.h> #include <linux/gnss.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> @@ -18,6 +19,7 @@ struct ubx_data { struct regulator *vcc; + struct gpio_desc *reset_gpio; }; static int ubx_set_active(struct gnss_serial *gserial) @@ -29,6 +31,8 @@ static int ubx_set_active(struct gnss_serial *gserial) if (ret) return ret; + gpiod_set_value_cansleep(data->reset_gpio, 0); + return 0; } @@ -37,6 +41,8 @@ static int ubx_set_standby(struct gnss_serial *gserial) struct ubx_data *data = gnss_serial_get_drvdata(gserial); int ret; + gpiod_set_value_cansleep(data->reset_gpio, 1); + ret = regulator_disable(data->vcc); if (ret) return ret; @@ -90,6 +96,13 @@ static int ubx_probe(struct serdev_device *serdev) if (ret < 0 && ret != -ENODEV) goto err_free_gserial; + /* Start with reset asserted */ + data->reset_gpio = devm_gpiod_get_optional(&serdev->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(data->reset_gpio)) { + ret = PTR_ERR(data->reset_gpio); + goto err_free_gserial; + } + ret = gnss_serial_register(gserial); if (ret) goto err_free_gserial;