From d990ab667ef73f047aa5b5acda2e9e0a08df8a6f Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 30 Dec 2020 16:10:41 +0100 Subject: [PATCH 1/7] at: make sure URC cache is disabled on startup --- src/at.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/at.c b/src/at.c index e035d34..a7b8b73 100644 --- a/src/at.c +++ b/src/at.c @@ -271,6 +271,8 @@ void at_sequence_configure(struct EG25Manager *manager) append_at_command(manager, "QURCCFG", "urcport", NULL, "\"usbat\""); append_at_command(manager, "QGPS", NULL, NULL, "1"); append_at_command(manager, "QSCLK", NULL, "1", NULL); + // Make sure URC cache is disabled + append_at_command(manager, "QCFG", "urc/cache", "0", NULL); send_at_command(manager); } From abc05e86e56b660c8fe00aebce31e5ad2e715da6 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 30 Dec 2020 16:20:32 +0100 Subject: [PATCH 2/7] manager: only toggle GPIOs for suspend after executing all AT commands --- src/at.c | 3 +-- src/manager.c | 10 ++++++++-- src/manager.h | 3 ++- src/suspend.c | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/at.c b/src/at.c index a7b8b73..45ba844 100644 --- a/src/at.c +++ b/src/at.c @@ -80,8 +80,7 @@ static gboolean send_at_command(struct EG25Manager *manager) else manager->modem_state = EG25_STATE_CONFIGURED; } else if (manager->modem_state == EG25_STATE_SUSPENDING) { - g_message("suspend sequence is over, drop inhibitor"); - suspend_inhibit(manager, FALSE); + modem_suspend_post(manager); } else if (manager->modem_state == EG25_STATE_RESETTING) { manager->modem_state = EG25_STATE_POWERED; } diff --git a/src/manager.c b/src/manager.c index bc08ddb..17e58b2 100644 --- a/src/manager.c +++ b/src/manager.c @@ -162,10 +162,16 @@ error: at_sequence_reset(manager); } -void modem_suspend(struct EG25Manager *manager) +void modem_suspend_pre(struct EG25Manager *manager) +{ + at_sequence_suspend(manager); +} + +void modem_suspend_post(struct EG25Manager *manager) { gpio_sequence_suspend(manager); - at_sequence_suspend(manager); + g_message("suspend sequence is over, drop inhibitor"); + suspend_inhibit(manager, FALSE); } void modem_resume_pre(struct EG25Manager *manager) diff --git a/src/manager.h b/src/manager.h index c51f32f..605d73e 100644 --- a/src/manager.h +++ b/src/manager.h @@ -54,7 +54,8 @@ struct EG25Manager { void modem_configure(struct EG25Manager *data); void modem_reset(struct EG25Manager *data); -void modem_suspend(struct EG25Manager *data); +void modem_suspend_pre(struct EG25Manager *data); +void modem_suspend_post(struct EG25Manager *data); void modem_resume_pre(struct EG25Manager *data); void modem_resume_post(struct EG25Manager *data); void modem_update_state(struct EG25Manager *data, MMModemState state); diff --git a/src/suspend.c b/src/suspend.c index 2e1301e..6d34594 100644 --- a/src/suspend.c +++ b/src/suspend.c @@ -94,7 +94,7 @@ static void signal_cb(GDBusProxy *proxy, if (is_about_to_suspend) { g_message("system is about to suspend"); manager->modem_state = EG25_STATE_SUSPENDING; - modem_suspend(manager); + modem_suspend_pre(manager); } else { g_message("system is resuming"); take_inhibitor(manager); From cb5220a1b8ae59ff70b4d9627cd5e666118d6c0f Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 30 Dec 2020 16:28:39 +0100 Subject: [PATCH 3/7] at: reduce delay between retries There's no reason we should wait 3s before retrying a failed AT command. This can even cause issues with suspend inhibition: 3 retries of a failed command would take 9s, while logind ignores the inhibitor after only 5s. Reducing the delay to 500ms should be enough and wouldn't interfere with suspend inhibition. Fixes #3 --- src/at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/at.c b/src/at.c index 45ba844..c417ffa 100644 --- a/src/at.c +++ b/src/at.c @@ -121,7 +121,7 @@ static void retry_at_command(struct EG25Manager *manager) g_critical("Command %s retried %d times, aborting...", at_cmd->cmd, at_cmd->retries); next_at_command(manager); } else { - g_timeout_add_seconds(3, G_SOURCE_FUNC(send_at_command), manager); + g_timeout_add(500, G_SOURCE_FUNC(send_at_command), manager); } } From c2e83f15a6e6308a2959db10e9f81c81cfa88621 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 30 Dec 2020 17:31:44 +0100 Subject: [PATCH 4/7] manager: improve error checking in modem_reset() --- src/manager.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/manager.c b/src/manager.c index 17e58b2..423cbfa 100644 --- a/src/manager.c +++ b/src/manager.c @@ -121,7 +121,7 @@ static gboolean modem_reset_done(struct EG25Manager* manager) void modem_reset(struct EG25Manager *manager) { - int fd, ret, len = strlen(manager->modem_usb_id); + int fd, ret, len; if (manager->reset_timer) return; @@ -131,6 +131,13 @@ void modem_reset(struct EG25Manager *manager) manager->suspend_timer = 0; } + if (!manager->modem_usb_id) { + g_warning("Unknown modem USB ID"); + goto error; + } + + len = strlen(manager->modem_usb_id); + manager->modem_state = EG25_STATE_RESETTING; fd = open("/sys/bus/usb/drivers/usb/unbind", O_WRONLY); From 150ff67e7b6850516c63292ca6648b2e3565384c Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 13 Jan 2021 23:46:38 +0100 Subject: [PATCH 5/7] udev: only check if modem USB ID is set --- src/udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev.c b/src/udev.c index acf10f8..1c5ebd8 100644 --- a/src/udev.c +++ b/src/udev.c @@ -12,7 +12,7 @@ static void udev_event_cb(GUdevClient *client, gchar *action, GUdevDevice *devic { struct EG25Manager *manager = data; - if (strcmp(action, "unbind") != 0 || manager->modem_state == EG25_STATE_RESETTING) + if (strcmp(action, "unbind") != 0 || manager->modem_state == EG25_STATE_RESETTING || !manager->modem_usb_id) return; if (strncmp(g_udev_device_get_name(device), manager->modem_usb_id, strlen(manager->modem_usb_id)) == 0 && From 79974bc9ee494d5890f78ba74ecb63e6d51e228b Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Thu, 14 Jan 2021 00:06:55 +0100 Subject: [PATCH 6/7] manager: don't manage the GNSS by default --- src/at.c | 9 ++++++--- src/manager.c | 13 +++++++++++++ src/manager.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/at.c b/src/at.c index c417ffa..39a857a 100644 --- a/src/at.c +++ b/src/at.c @@ -268,7 +268,8 @@ void at_sequence_configure(struct EG25Manager *manager) append_at_command(manager, "QCFG", "apready", NULL, "1,0,500"); } append_at_command(manager, "QURCCFG", "urcport", NULL, "\"usbat\""); - append_at_command(manager, "QGPS", NULL, NULL, "1"); + if (manager->manage_gnss) + append_at_command(manager, "QGPS", NULL, NULL, "1"); append_at_command(manager, "QSCLK", NULL, "1", NULL); // Make sure URC cache is disabled append_at_command(manager, "QCFG", "urc/cache", "0", NULL); @@ -277,7 +278,8 @@ void at_sequence_configure(struct EG25Manager *manager) void at_sequence_suspend(struct EG25Manager *manager) { - append_at_command(manager, "QGPSEND", NULL, NULL, NULL); + if (manager->manage_gnss) + append_at_command(manager, "QGPSEND", NULL, NULL, NULL); append_at_command(manager, "QCFG", "urc/cache", "1", NULL); send_at_command(manager); } @@ -285,7 +287,8 @@ void at_sequence_suspend(struct EG25Manager *manager) void at_sequence_resume(struct EG25Manager *manager) { append_at_command(manager, "QCFG", "urc/cache", "0", NULL); - append_at_command(manager, "QGPS", NULL, "1", NULL); + if (manager->manage_gnss) + append_at_command(manager, "QGPS", NULL, "1", NULL); send_at_command(manager); } diff --git a/src/manager.c b/src/manager.c index 423cbfa..6445e0f 100644 --- a/src/manager.c +++ b/src/manager.c @@ -193,14 +193,27 @@ void modem_resume_post(struct EG25Manager *manager) int main(int argc, char *argv[]) { + g_autoptr(GOptionContext) opt_context = NULL; + g_autoptr(GError) err = NULL; struct EG25Manager manager; char compatible[32]; int fd, ret; + const GOptionEntry options[] = { + { "gnss", 'g', 0, G_OPTION_ARG_NONE, &manager.manage_gnss, "Manage the GNSS feature.", NULL }, + { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } + }; memset(&manager, 0, sizeof(manager)); manager.at_fd = -1; manager.suspend_inhibit_fd = -1; + opt_context = g_option_context_new ("- Power management for the Quectel EG25 modem"); + g_option_context_add_main_entries (opt_context, options, NULL); + if (!g_option_context_parse (opt_context, &argc, &argv, &err)) { + g_warning ("%s", err->message); + return 1; + } + manager.loop = g_main_loop_new(NULL, FALSE); fd = open("/proc/device-tree/compatible", O_RDONLY); diff --git a/src/manager.h b/src/manager.h index 605d73e..f6351be 100644 --- a/src/manager.h +++ b/src/manager.h @@ -28,6 +28,7 @@ enum EG25State { struct EG25Manager { GMainLoop *loop; guint reset_timer; + gboolean manage_gnss; int at_fd; guint at_source; From 31133affa07c14d5af6b9d297110bbfc5f6c666d Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Thu, 14 Jan 2021 00:07:15 +0100 Subject: [PATCH 7/7] meson.build: release version 0.1.2 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index cb0d72e..069147b 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project ( 'eg25manager', 'c', - version : '0.1.1', + version : '0.1.2', license : 'GPLv3+', meson_version : '>= 0.50.0', default_options :