diff --git a/data/pine64,pinephone-1.0.toml b/data/pine64,pinephone-1.0.toml index c0e9192..e1f5b24 100644 --- a/data/pine64,pinephone-1.0.toml +++ b/data/pine64,pinephone-1.0.toml @@ -3,6 +3,9 @@ need_libusb = true usb_vid = 0x2c7c usb_pid = 0x0125 +# Delay between setting GPIO and PWRKEY sequence, set in microseconds +poweron_delay = 100000 + # Uncomment the following if you need to change the modem detection timeout on # resume and/or the time during which suspend is blocked after modem boot #[suspend] @@ -39,17 +42,14 @@ configure = [ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000" }, { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1" }, { cmd = "QCFG", subcmd = "urc/delay", expect = "1" }, - { cmd = "QURCCFG", subcmd = "urcport", expect = "\"usbat\"" }, + { cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" }, { cmd = "QGPS", value = "1" }, { cmd = "QSCLK", value = "1" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "0" } ] suspend = [ { cmd = "QGPSEND" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "1" } ] resume = [ - { cmd = "QCFG", subcmd = "urc/cache", value = "0" }, { cmd = "QGPS", value = "1" } ] reset = [ { cmd = "CFUN", value = "1,1" } ] diff --git a/data/pine64,pinephone-1.1.toml b/data/pine64,pinephone-1.1.toml index c0e9192..e1f5b24 100644 --- a/data/pine64,pinephone-1.1.toml +++ b/data/pine64,pinephone-1.1.toml @@ -3,6 +3,9 @@ need_libusb = true usb_vid = 0x2c7c usb_pid = 0x0125 +# Delay between setting GPIO and PWRKEY sequence, set in microseconds +poweron_delay = 100000 + # Uncomment the following if you need to change the modem detection timeout on # resume and/or the time during which suspend is blocked after modem boot #[suspend] @@ -39,17 +42,14 @@ configure = [ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000" }, { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1" }, { cmd = "QCFG", subcmd = "urc/delay", expect = "1" }, - { cmd = "QURCCFG", subcmd = "urcport", expect = "\"usbat\"" }, + { cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" }, { cmd = "QGPS", value = "1" }, { cmd = "QSCLK", value = "1" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "0" } ] suspend = [ { cmd = "QGPSEND" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "1" } ] resume = [ - { cmd = "QCFG", subcmd = "urc/cache", value = "0" }, { cmd = "QGPS", value = "1" } ] reset = [ { cmd = "CFUN", value = "1,1" } ] diff --git a/data/pine64,pinephone-1.2.toml b/data/pine64,pinephone-1.2.toml index 566ac80..4ca1274 100644 --- a/data/pine64,pinephone-1.2.toml +++ b/data/pine64,pinephone-1.2.toml @@ -1,3 +1,7 @@ +[manager] +# Delay between setting GPIO and PWRKEY sequence, set in microseconds +poweron_delay = 100000 + # Uncomment the following if you need to change the modem detection timeout on # resume and/or the time during which suspend is blocked after modem boot #[suspend] @@ -32,17 +36,14 @@ configure = [ { cmd = "QCFG", subcmd = "risignaltype", expect = "\"physical\"" }, { cmd = "QCFG", subcmd = "ims", expect = "1" }, { cmd = "QCFG", subcmd = "apready", expect = "1,0,500" }, - { cmd = "QURCCFG", subcmd = "urcport", expect = "\"usbat\"" }, + { cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" }, { cmd = "QGPS", value = "1" }, { cmd = "QSCLK", value = "1" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "0" } ] suspend = [ { cmd = "QGPSEND" }, - { cmd = "QCFG", subcmd = "urc/cache", value = "1" } ] resume = [ - { cmd = "QCFG", subcmd = "urc/cache", value = "0" }, { cmd = "QGPS", value = "1" } ] reset = [ { cmd = "CFUN", value = "1,1" } ] diff --git a/meson.build b/meson.build index fffeada..d57d2cb 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project ( 'eg25-manager', 'c', - version : '0.2.0', + version : '0.3.0', license : 'GPLv3+', meson_version : '>= 0.50.0', default_options : @@ -47,13 +47,18 @@ eg25_datadir = join_paths(full_datadir, meson.project_name()) add_global_arguments('-D@0@="@1@"'.format('EG25_CONFDIR', eg25_confdir), language : 'c') add_global_arguments('-D@0@="@1@"'.format('EG25_DATADIR', eg25_datadir), language : 'c') +mmglib_dep = dependency('mm-glib', required : false) +if mmglib_dep.found() + add_global_arguments('-DHAVE_MMGLIB=1', language : 'c') +endif + mgr_deps = [ dependency('glib-2.0'), dependency('gio-unix-2.0'), dependency('gudev-1.0'), dependency('libgpiod'), dependency('libusb-1.0'), - dependency('mm-glib'), + mmglib_dep, ] subdir('data') diff --git a/src/at.c b/src/at.c index 4b5cd62..a34025f 100644 --- a/src/at.c +++ b/src/at.c @@ -76,12 +76,18 @@ static gboolean send_at_command(struct EG25Manager *manager) g_message("Sending command: %s", g_strstrip(command)); } else if (manager->modem_state < EG25_STATE_CONFIGURED) { - MMModemState modem_state = mm_modem_get_state(manager->mm_modem); + if (manager->modem_iface == MODEM_IFACE_MODEMMANAGER) { +#ifdef HAVE_MMGLIB + MMModemState modem_state = mm_modem_get_state(manager->mm_modem); - if (manager->mm_modem && modem_state >= MM_MODEM_STATE_REGISTERED) - modem_update_state(manager, modem_state); - else + if (manager->mm_modem && modem_state >= MM_MODEM_STATE_REGISTERED) + modem_update_state(manager, modem_state); + else + manager->modem_state = EG25_STATE_CONFIGURED; +#endif + } else { manager->modem_state = EG25_STATE_CONFIGURED; + } } else if (manager->modem_state == EG25_STATE_SUSPENDING) { modem_suspend_post(manager); } else if (manager->modem_state == EG25_STATE_RESETTING) { diff --git a/src/libgdbofono/dbus-introspect.sh b/src/libgdbofono/dbus-introspect.sh new file mode 100755 index 0000000..5a851ad --- /dev/null +++ b/src/libgdbofono/dbus-introspect.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DEST="$1" +OBJ_PATH="$2" +METHOD="$3" +shift 3 + +dbus-send "$@" --print-reply --dest="$DEST" "$OBJ_PATH" "$METHOD" | \ + grep -v '^method return' | \ + sed -e 's/^[[:space:]]\+string ""__' diff --git a/src/libgdbofono/manager.xml b/src/libgdbofono/manager.xml new file mode 100644 index 0000000..13e9d56 --- /dev/null +++ b/src/libgdbofono/manager.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/libgdbofono/meson.build b/src/libgdbofono/meson.build new file mode 100644 index 0000000..98eb9a3 --- /dev/null +++ b/src/libgdbofono/meson.build @@ -0,0 +1,50 @@ +# +# Copyright (C) 2018 Purism SPC +# +# This file is part of Calls. +# +# Calls is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Calls is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Calls. If not, see . +# +# Author: Bob Ham +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + + +gnome = import('gnome') +dbus_interfaces = ['manager', 'modem'] + +gdbofono_src = [] +gdbofono_headers = [] +foreach iface: dbus_interfaces + src = gnome.gdbus_codegen( + 'gdbo-' + iface, + iface + '.xml', + interface_prefix: 'org.ofono.', + namespace: 'GDBO' + ) + gdbofono_src += src + gdbofono_headers += src[1] +endforeach + +gdbofono_deps = [ + dependency('gio-2.0'), + dependency('gio-unix-2.0'), +] + +gdbofono_lib = static_library( + 'gdbofono', + gdbofono_src, + dependencies: gdbofono_deps +) diff --git a/src/libgdbofono/modem-full.xml b/src/libgdbofono/modem-full.xml new file mode 100644 index 0000000..5319672 --- /dev/null +++ b/src/libgdbofono/modem-full.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libgdbofono/modem.xml b/src/libgdbofono/modem.xml new file mode 100644 index 0000000..c02d250 --- /dev/null +++ b/src/libgdbofono/modem.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/manager.c b/src/manager.c index aaa3905..c0b8a43 100644 --- a/src/manager.c +++ b/src/manager.c @@ -7,7 +7,12 @@ #include "at.h" #include "gpio.h" #include "manager.h" + +#ifdef HAVE_MMGLIB #include "mm-iface.h" +#endif + +#include "ofono-iface.h" #include "suspend.h" #include "udev.h" @@ -34,7 +39,10 @@ static gboolean quit_app(struct EG25Manager *manager) g_message("Request to quit..."); at_destroy(manager); +#ifdef HAVE_MMGLIB mm_iface_destroy(manager); +#endif + ofono_iface_destroy(manager); suspend_destroy(manager); udev_destroy(manager); @@ -86,6 +94,9 @@ static gboolean modem_start(struct EG25Manager *manager) if (should_boot) { g_message("Starting modem..."); + // Modem might crash on boot (especially with worn battery) if we don't delay here + if (manager->poweron_delay > 0) + g_usleep(manager->poweron_delay); gpio_sequence_poweron(manager); manager->modem_state = EG25_STATE_POWERED; } else { @@ -95,6 +106,7 @@ static gboolean modem_start(struct EG25Manager *manager) return FALSE; } +#ifdef HAVE_MMGLIB void modem_update_state(struct EG25Manager *manager, MMModemState state) { switch (state) { @@ -111,6 +123,7 @@ void modem_update_state(struct EG25Manager *manager, MMModemState state) break; } } +#endif void modem_configure(struct EG25Manager *manager) { @@ -131,6 +144,14 @@ void modem_reset(struct EG25Manager *manager) if (manager->reset_timer) return; + /* + * If we are managing the modem through lets say ofono, we should not + * reset the modem based on the availability of USB ID + * TODO: Improve ofono plugin and add support for fetching USB ID + */ + if (manager->modem_iface != MODEM_IFACE_MODEMMANAGER) + return; + if (manager->modem_recovery_timer) { g_source_remove(manager->modem_recovery_timer); manager->modem_recovery_timer = 0; @@ -300,11 +321,25 @@ int main(int argc, char *argv[]) toml_value = toml_int_in(toml_manager, "usb_pid"); if (toml_value.ok) manager.usb_pid = toml_value.u.i; + + toml_value = toml_int_in(toml_manager, "poweron_delay"); + if (toml_value.ok) { + if (toml_value.u.i >= 0 && toml_value.u.i <= G_MAXULONG) { + // Safe to cast into gulong + manager.poweron_delay = (gulong) toml_value.u.i; + } else { + // Changed from initialized default value but not in range + g_message("Configured poweron_delay out of range, using default"); + } + } } at_init(&manager, toml_table_in(toml_config, "at")); gpio_init(&manager, toml_table_in(toml_config, "gpio")); +#ifdef HAVE_MMGLIB mm_iface_init(&manager, toml_table_in(toml_config, "mm-iface")); +#endif + ofono_iface_init(&manager); suspend_init(&manager, toml_table_in(toml_config, "suspend")); udev_init(&manager, toml_table_in(toml_config, "udev")); diff --git a/src/manager.h b/src/manager.h index 48ff237..30028e6 100644 --- a/src/manager.h +++ b/src/manager.h @@ -9,7 +9,10 @@ #include #include #include +#ifdef HAVE_MMGLIB #include +#endif +#include #include "toml.h" @@ -27,12 +30,19 @@ enum EG25State { EG25_STATE_FINISHING }; +enum ModemIface { + MODEM_IFACE_NONE = 0, + MODEM_IFACE_MODEMMANAGER, + MODEM_IFACE_OFONO +}; + struct EG25Manager { GMainLoop *loop; guint reset_timer; gboolean use_libusb; guint usb_vid; guint usb_pid; + gulong poweron_delay; int at_fd; guint at_source; @@ -41,9 +51,15 @@ struct EG25Manager { enum EG25State modem_state; gchar *modem_usb_id; + enum ModemIface modem_iface; guint mm_watch; +#ifdef HAVE_MMGLIB MMManager *mm_manager; MMModem *mm_modem; +#endif + guint ofono_watch; + GDBOManager *ofono_manager; + GDBusConnection *ofono_connection; GDBusProxy *suspend_proxy; int suspend_delay_fd; @@ -67,4 +83,6 @@ 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); +#ifdef HAVE_MMGLIB void modem_update_state(struct EG25Manager *data, MMModemState state); +#endif diff --git a/src/meson.build b/src/meson.build index 0d10362..f9eb27f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,17 +4,27 @@ # SPDX-License-Identifier: GPL-3.0-or-later # -executable ( - 'eg25manager', - [ + +subdir('libgdbofono') + +src = [ 'at.c', 'at.h', 'gpio.c', 'gpio.h', 'manager.c', 'manager.h', - 'mm-iface.c', 'mm-iface.h', + 'ofono-iface.c', 'ofono-iface.h', 'suspend.c', 'suspend.h', 'toml.c', 'toml.h', 'udev.c', 'udev.h', - ], +] + +if mmglib_dep.found() + src += ['mm-iface.c', 'mm-iface.h'] +endif + +executable ( + 'eg25manager', + src, dependencies : mgr_deps, + link_with: gdbofono_lib, install : true ) diff --git a/src/mm-iface.c b/src/mm-iface.c index 8afe2ea..d6a74f8 100644 --- a/src/mm-iface.c +++ b/src/mm-iface.c @@ -163,6 +163,12 @@ static void mm_appeared_cb(GDBusConnection *connection, { g_message("ModemManager appeared on D-Bus"); + if (manager->modem_iface != MODEM_IFACE_NONE) { + g_critical("Modem interface already found! Make sure to only run either of ModemManager or oFono."); + return; + } + manager->modem_iface = MODEM_IFACE_MODEMMANAGER; + mm_manager_new(connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, NULL, (GAsyncReadyCallback)mm_manager_new_cb, manager); } diff --git a/src/ofono-iface.c b/src/ofono-iface.c new file mode 100644 index 0000000..bc37f38 --- /dev/null +++ b/src/ofono-iface.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2020 Oliver Smith + * Copyright (C) 2021 Bhushan Shah + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "ofono-iface.h" + +#include + +#include +#include + +#define OFONO_SERVICE "org.ofono" + +static void modem_added_cb(GDBOManager *manager_proxy, + const gchar *path, + GVariant *properties, + struct EG25Manager *manager) +{ + GVariant *modem_path; + g_debug("Adding ofono modem '%s'", path); + + if (manager->modem_state == EG25_STATE_RESUMING) { + if (manager->modem_recovery_timer) { + g_source_remove(manager->modem_recovery_timer); + manager->modem_recovery_timer = 0; + } + modem_resume_post(manager); + manager->modem_state = EG25_STATE_CONFIGURED; + } + + if (manager->modem_state < EG25_STATE_ACQUIRED) + manager->modem_state = EG25_STATE_ACQUIRED; + + if (manager->modem_state < EG25_STATE_CONFIGURED) + modem_configure(manager); + + modem_path = g_variant_lookup_value(properties, "SystemPath", G_VARIANT_TYPE_STRING); + if (manager->modem_usb_id) + g_free(manager->modem_usb_id); + manager->modem_usb_id = g_strdup(strrchr(g_variant_dup_string(modem_path, NULL), '/') + 1); +} + +static void modem_removed_cb(GDBOManager *manager_proxy, + const gchar *path, + struct EG25Manager *manager) +{ +} + +static void get_modems_cb(GDBOManager *manager_proxy, + GAsyncResult *res, + struct EG25Manager *manager) +{ + gboolean ok; + GVariant *modems; + GVariantIter *modems_iter = NULL; + g_autoptr(GError) error = NULL; + + const gchar *path; + GVariant *properties; + + ok = gdbo_manager_call_get_modems_finish(manager_proxy, &modems, + res, &error); + if (!ok) { + g_warning("Error getting modems from ofono manager: %s", error->message); + return; + } + + g_variant_get(modems, "a(oa{sv})", &modems_iter); + while(g_variant_iter_loop(modems_iter, "(&o@a{sv})", &path, &properties)) { + g_debug("Got modem object path '%s'", path); + modem_added_cb(manager_proxy, path, properties, manager); + } + g_variant_iter_free(modems_iter); + g_variant_unref(modems); +} + +static void ofono_appeared_cb(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + struct EG25Manager *manager) +{ + GError *error = NULL; + + g_message("oFono appeared on D-Bus"); + + if (manager->modem_iface != MODEM_IFACE_NONE) { + g_critical("Modem interface already found! Make sure to only run either of ModemManager or oFono."); + return; + } + /* now connect to oFono! */ + manager->ofono_connection = connection; + manager->ofono_manager = gdbo_manager_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + OFONO_SERVICE, + "/", + NULL, + &error); + if (!manager->ofono_manager) { + g_critical("Error creating ofono object manager proxy: %s", error->message); + return; + } + + manager->modem_iface = MODEM_IFACE_OFONO; + + g_signal_connect(manager->ofono_manager, "modem-added", + G_CALLBACK(modem_added_cb), manager); + g_signal_connect(manager->ofono_manager, "modem-removed", + G_CALLBACK(modem_removed_cb), manager); + + gdbo_manager_call_get_modems(manager->ofono_manager, + NULL, + (GAsyncReadyCallback) get_modems_cb, + manager); +} + +static void ofono_vanished_cb(GDBusConnection *connection, + const gchar *name, + struct EG25Manager *manager) +{ + g_message("oFono vanished from D-Bus"); + + if (manager->modem_iface == MODEM_IFACE_OFONO) { + manager->modem_iface = MODEM_IFACE_NONE; + ofono_iface_destroy(manager); + } +} + +void ofono_iface_init(struct EG25Manager *manager) +{ + manager->ofono_watch = g_bus_watch_name(G_BUS_TYPE_SYSTEM, OFONO_SERVICE, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + (GBusNameAppearedCallback)ofono_appeared_cb, + (GBusNameVanishedCallback)ofono_vanished_cb, + manager, NULL); +} + +void ofono_iface_destroy(struct EG25Manager *manager) +{ + if (manager->modem_usb_id) { + g_free(manager->modem_usb_id); + manager->modem_usb_id = NULL; + } + if (manager->ofono_watch != 0) { + g_bus_unwatch_name(manager->ofono_watch); + manager->ofono_watch = 0; + } +} diff --git a/src/ofono-iface.h b/src/ofono-iface.h new file mode 100644 index 0000000..fd3766e --- /dev/null +++ b/src/ofono-iface.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2020 Oliver Smith + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "manager.h" + +void ofono_iface_init(struct EG25Manager *data); +void ofono_iface_destroy(struct EG25Manager *data); diff --git a/src/suspend.c b/src/suspend.c index 256636e..f9bedf9 100644 --- a/src/suspend.c +++ b/src/suspend.c @@ -170,11 +170,18 @@ static void signal_cb(GDBusProxy *proxy, g_message("system is resuming"); take_inhibitor(manager, FALSE); modem_resume_pre(manager); - if (manager->mm_modem) { + if ( +#ifdef HAVE_MMGLIB + manager->mm_modem || +#endif + manager->modem_iface == MODEM_IFACE_OFONO) { /* * On some systems ModemManager doesn't handle suspend/resume, so * we still have a valid/managed modem when resuming. In this case, * do the whole resume sequence immediately. + * + * If modem is managed by ofono, we also do resume sequence immediately + * as ofono handles resuming from sleep itself. */ manager->modem_state = EG25_STATE_CONFIGURED; modem_resume_post(manager); diff --git a/udev/80-modem-eg25.rules b/udev/80-modem-eg25.rules index 0ea9e6f..5fb6970 100644 --- a/udev/80-modem-eg25.rules +++ b/udev/80-modem-eg25.rules @@ -1 +1,5 @@ -ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{MINOR}=="0", RUN+="/usr/bin/eg25-configure-usb %p" +ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ATTR{power/control}="auto" +ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ATTR{power/autosuspend_delay_ms}="3000" +ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ATTR{power/wakeup}="enabled" +ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ATTR{avoid_reset_quirk}="1" +ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ATTR{power/persist}="0" diff --git a/udev/eg25-configure-usb b/udev/eg25-configure-usb deleted file mode 100755 index 9972af7..0000000 --- a/udev/eg25-configure-usb +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -DEVPATH=/sys/$1 -USB_ID= - -[ -d ${DEVPATH} ] || exit 1 - -while [ ! "${USB_ID}" ]; do - if [ -f ${DEVPATH}/avoid_reset_quirk ]; then - USB_ID=$(basename ${DEVPATH}) - break - fi - DEVPATH=$(dirname ${DEVPATH}) -done - -# Avoid USB resets -echo "auto" > /sys/bus/usb/devices/${USB_ID}/power/control -echo "3000" > /sys/bus/usb/devices/${USB_ID}/power/autosuspend_delay_ms -echo "enabled" > /sys/bus/usb/devices/${USB_ID}/power/wakeup -echo "1" > /sys/bus/usb/devices/${USB_ID}/avoid_reset_quirk -echo "0" > /sys/bus/usb/devices/${USB_ID}/power/persist diff --git a/udev/meson.build b/udev/meson.build index fe558fc..1488660 100644 --- a/udev/meson.build +++ b/udev/meson.build @@ -4,5 +4,4 @@ # SPDX-License-Identifier: GPL-3.0-or-later # -install_data ('eg25-configure-usb', install_dir: bindir) install_data ('80-modem-eg25.rules', install_dir: udevrulesdir)