diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index 10ab8d4a511..5b754996422 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -159,6 +159,14 @@ Flash General Purpose I/O (GPIO) ========================== +GNSS +==== + +* Basic power management support has been added to the ``gnss-nmea-generic`` driver. + If ``CONFIG_PM_DEVICE=y`` the driver is now initialized in suspended mode and the + application needs to call :c:func:`pm_device_action_run` with :c:macro:`PM_DEVICE_ACTION_RESUME` + to start up the driver. + Input ===== diff --git a/drivers/gnss/gnss_nmea_generic.c b/drivers/gnss/gnss_nmea_generic.c index 2f23f4d7353..a50b5b4cae0 100644 --- a/drivers/gnss/gnss_nmea_generic.c +++ b/drivers/gnss/gnss_nmea_generic.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "gnss_nmea0183.h" @@ -29,6 +30,7 @@ LOG_MODULE_REGISTER(gnss_nmea_generic, CONFIG_GNSS_LOG_LEVEL); struct gnss_nmea_generic_config { const struct device *uart; + const struct modem_chat_script *const init_chat_script; }; struct gnss_nmea_generic_data { @@ -60,6 +62,7 @@ MODEM_CHAT_MATCHES_DEFINE(unsol_matches, static int gnss_nmea_generic_resume(const struct device *dev) { + const struct gnss_nmea_generic_config *cfg = dev->config; struct gnss_nmea_generic_data *data = dev->data; int ret; @@ -69,11 +72,14 @@ static int gnss_nmea_generic_resume(const struct device *dev) } ret = modem_chat_attach(&data->chat, data->uart_pipe); - if (ret < 0) { - modem_pipe_close(data->uart_pipe); - return ret; + + if (ret == 0) { + ret = modem_chat_run_script(&data->chat, cfg->init_chat_script); } + if (ret < 0) { + modem_pipe_close(data->uart_pipe); + } return ret; } @@ -148,24 +154,49 @@ static int gnss_nmea_generic_init(const struct device *dev) return ret; } +#if CONFIG_PM_DEVICE + pm_device_init_suspended(dev); +#else ret = gnss_nmea_generic_resume(dev); if (ret < 0) { return ret; } +#endif return 0; } +#if CONFIG_PM_DEVICE +static int gnss_nmea_generic_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: + return gnss_nmea_generic_resume(dev); + default: + return -ENOTSUP; + } +} +#endif + +#if DT_HAS_COMPAT_STATUS_OKAY(gnss_nmea_generic) +MODEM_CHAT_SCRIPT_EMPTY_DEFINE(gnss_nmea_generic_init_chat_script); +#endif + #define GNSS_NMEA_GENERIC(inst) \ static struct gnss_nmea_generic_config gnss_nmea_generic_cfg_##inst = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .init_chat_script = &_CONCAT(DT_DRV_COMPAT, _init_chat_script), \ }; \ \ static struct gnss_nmea_generic_data gnss_nmea_generic_data_##inst; \ \ - DEVICE_DT_INST_DEFINE(inst, gnss_nmea_generic_init, NULL, \ + PM_DEVICE_DT_INST_DEFINE(inst, gnss_nmea_generic_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, gnss_nmea_generic_init, PM_DEVICE_DT_INST_GET(inst),\ &gnss_nmea_generic_data_##inst, \ &gnss_nmea_generic_cfg_##inst, \ POST_KERNEL, CONFIG_GNSS_INIT_PRIORITY, &gnss_api); +#define DT_DRV_COMPAT gnss_nmea_generic DT_INST_FOREACH_STATUS_OKAY(GNSS_NMEA_GENERIC) +#undef DT_DRV_COMPAT