[-]
[+]
|
Changed |
_service:tar_git:eg25-manager.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,7 +2,7 @@
<service name="tar_git">
<param name="url">https://github.com/sailfish-on-dontbeevil/eg25-manager</param>
<param name="branch">main</param>
- <param name="revision">0.4.1+git2</param>
+ <param name="revision">0.4.2+git1</param>
<param name="token"/>
<param name="debian">N</param>
<param name="dumb">N</param>
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/data/meson.build
^
|
@@ -8,6 +8,7 @@
'pine64,pinephone-1.0.toml',
'pine64,pinephone-1.1.toml',
'pine64,pinephone-1.2.toml',
+'pine64,pinephone-pro.toml',
]
install_data(conf_files)
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/data/pine64,pinephone-1.0.toml
^
|
@@ -1,4 +1,5 @@
[manager]
+monitor_udev = true
need_libusb = true
usb_vid = 0x2c7c
usb_pid = 0x0125
@@ -13,11 +14,12 @@
#recovery_timeout = 9
[gpio]
-dtr = 358
-pwrkey = 35
-reset = 68
-apready = 231
-disable = 232
+chips = [ "1c20800.pinctrl", "1f02c00.pinctrl" ]
+dtr = { chip = 1, line = 6 }
+pwrkey = { chip = 0, line = 35 }
+reset = { chip = 0, line = 68 }
+apready = { chip = 0, line = 231 }
+disable = { chip = 0, line = 232 }
[at]
uart = "/dev/ttyS2"
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/data/pine64,pinephone-1.1.toml
^
|
@@ -1,4 +1,5 @@
[manager]
+monitor_udev = true
need_libusb = true
usb_vid = 0x2c7c
usb_pid = 0x0125
@@ -13,11 +14,12 @@
#recovery_timeout = 9
[gpio]
-dtr = 358
-pwrkey = 35
-reset = 68
-apready = 231
-disable = 232
+chips = [ "1c20800.pinctrl", "1f02c00.pinctrl" ]
+dtr = { chip = 1, line = 6 }
+pwrkey = { chip = 0, line = 35 }
+reset = { chip = 0, line = 68 }
+apready = { chip = 0, line = 231 }
+disable = { chip = 0, line = 232 }
[at]
uart = "/dev/ttyS2"
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/data/pine64,pinephone-1.2.toml
^
|
@@ -1,4 +1,5 @@
[manager]
+monitor_udev = true
# Delay between setting GPIO and PWRKEY sequence, set in microseconds
poweron_delay = 100000
@@ -9,12 +10,13 @@
#recovery_timeout = 9
[gpio]
-dtr = 34
-pwrkey = 35
-reset = 68
-apready = 231
-disable = 232
-status = 233
+chips = [ "1c20800.pinctrl" ]
+dtr = { chip = 0, line = 34 }
+pwrkey = { chip = 0, line = 35 }
+reset = { chip = 0, line = 68 }
+apready = { chip = 0, line = 231 }
+disable = { chip = 0, line = 232 }
+status = { chip = 0, line = 233 }
[at]
uart = "/dev/ttyS2"
|
[-]
[+]
|
Added |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/data/pine64,pinephone-pro.toml
^
|
@@ -0,0 +1,98 @@
+[manager]
+monitor_udev = false
+# 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]
+#boot_timeout = 120
+#recovery_timeout = 9
+
+[gpio]
+chips = [ "gpio0", "gpio3" ]
+dtr = { chip = 0, line = 3 }
+pwrkey = { chip = 0, line = 13 }
+reset = { chip = 1, line = 8 }
+apready = { chip = 0, line = 12 }
+disable = { chip = 0, line = 8 }
+status = { chip = 1, line = 6 }
+
+[at]
+uart = "/dev/ttyS3"
+configure = [
+# Each command has 4 possible elements:
+# * `cmd` : the AT command itself, which will be translated to "AT+`cmd`"
+# * `subcmd`: the subcommand in case a single AT command can be used
+# to change multiple parameters, such as QCFG (optional)
+# * `value` : the commands, argument, usually used to set the value of
+# a specific parameter (optional)
+# * `expect`: the expected return value; the command is first executed
+# without any value in order to query the current state. This
+# state is then compared to the `expect` string; if they don't
+# match, the command is then executed with value `expect` in
+# order to set the parameter to the configured value (optional)
+# A command can have `expect` OR `value` configured, but it shouldn't have both
+# Print software version
+ { cmd = "QGMR" },
+# Configure audio
+ { cmd = "QDAI", expect = "3,0,0,4,0,1,1,1" },
+# RI signaling using physical RI pin
+ { cmd = "QCFG", subcmd = "risignaltype", expect = "\"physical\"" },
+# Enable VoLTE support
+ { cmd = "QCFG", subcmd = "ims", expect = "1" },
+# Enable APREADY for PP 1.2
+ { cmd = "QCFG", subcmd = "apready", expect = "1,0,500" },
+# URC configuration for PP 1.2 (APREADY pin connected):
+# * RING URC: normal pulse length
+# * Incoming SMS URC: default pulse length
+# * Other URC: default length
+# * Report URCs on all ports (serial and USB) for FOSS firmware
+# * Reporting of URCs without any delay
+# * Configure URC pin to UART Ring Indicator
+ { cmd = "QCFG", subcmd = "urc/ri/ring", expect = "\"pulse\",120,1000,5000,\"off\",1" },
+ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",120,1" },
+ { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
+ { cmd = "QCFG", subcmd = "urc/delay", expect = "0" },
+ { cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
+ { cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
+ { cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
+# Allow sleeping for power saving
+ { cmd = "QSCLK", value = "1" },
+# GNSS configuration:
+# * Enable A-GPS data upload support (XTRA)
+# * Disable On-Demand-Positioning (ODP) mode
+# to avoid running the GNSS system in the background, even when not enabled.
+# * Enable Dynamic Power Optimizations (DPO) mode to turn off GNSS RF radios
+# when they are not in use.
+# * Only enable GPS and GLONASS, disable other GNSS systems.
+# A-GPS data upload doesn't work for Galileo anyway.
+# * Avoid turning on GNSS support automatically when the modem boots.
+ { cmd = "QGPSXTRA", expect = "1" },
+ { cmd = "QGPSCFG", subcmd = "gnssconfig", expect = "4" },
+ { cmd = "QGPSCFG", subcmd = "odpcontrol", expect = "0" },
+ { cmd = "QGPSCFG", subcmd = "dpoenable", expect = "1" },
+ { cmd = "QGPSCFG", subcmd = "gpsnmeatype", expect = "31" },
+ { cmd = "QGPSCFG", subcmd = "glonassnmeatype", expect = "7" },
+ { cmd = "QGPSCFG", subcmd = "galileonmeatype", expect = "0" },
+ { cmd = "QGPSCFG", subcmd = "beidounmeatype", expect = "0" },
+ { cmd = "QGPSCFG", subcmd = "autogps", expect = "0" },
+# Disable fast poweroff for stability
+ { cmd = "QCFG", subcmd = "fast/poweroff", expect = "0" },
+# Configure sleep and wake up pin levels to active low
+ { cmd = "QCFG", subcmd = "sleepind/level", expect = "0" },
+ { cmd = "QCFG", subcmd = "wakeupin/level", expect = "0,0" },
+# Do not enter RAMDUMP mode, auto-reset instead
+ { cmd = "QCFG", subcmd = "ApRstLevel", expect = "1" },
+ { cmd = "QCFG", subcmd = "ModemRstLevel", expect = "1" },
+]
+suspend = [
+]
+resume = [
+]
+reset = [ { cmd = "CFUN", value = "1,1" } ]
+
+[gnss]
+enabled = true
+url = "https://xtrapath4.izatcloud.net"
+file = "xtra2.bin"
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/meson.build
^
|
@@ -8,7 +8,7 @@
project (
'eg25-manager',
'c',
- version : '0.4.1',
+ version : '0.4.2',
license : 'GPLv3+',
meson_version : '>= 0.50.0',
default_options :
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/at.c
^
|
@@ -245,7 +245,14 @@
*/
do {
ret = read(fd, tmp, sizeof(tmp));
+
if (ret > 0) {
+ /* If we're going to overflow truncate the data we read to fit */
+ if (pos + ret >= sizeof(response)) {
+ g_critical("AT response buffer full, truncating");
+ ret = sizeof(response) - (pos + 1);
+ }
+
memcpy(&response[pos], tmp, ret);
pos += ret;
usleep(10000);
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/config.c
^
|
@@ -81,3 +81,17 @@
return !!array;
}
+
+gboolean config_get_table(toml_table_t **config, const gchar *key, toml_table_t **result)
+{
+ toml_table_t *table = NULL;
+
+ if (config[EG25_CONFIG_USER])
+ table = toml_table_in(config[EG25_CONFIG_USER], key);
+ if (!table)
+ table = toml_table_in(config[EG25_CONFIG_SYS], key);
+ if (table && result)
+ *result = table;
+
+ return !!table;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/config.h
^
|
@@ -24,3 +24,4 @@
gboolean config_get_uint(toml_table_t **config, const gchar *key, guint *result);
gboolean config_get_string(toml_table_t **config, const gchar *key, gchar **result);
gboolean config_get_array(toml_table_t **config, const gchar *key, toml_array_t **result);
+gboolean config_get_table(toml_table_t **config, const gchar *key, toml_table_t **result);
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/gpio.c
^
|
@@ -9,9 +9,9 @@
#include <unistd.h>
+/* Those defines are used for legacy config files only */
#define GPIO_CHIP1_LABEL "1c20800.pinctrl"
#define GPIO_CHIP2_LABEL "1f02c00.pinctrl"
-
#define MAX_GPIOCHIP_LINES 352
enum {
@@ -101,77 +101,160 @@
return 0;
}
-int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
+struct gpiod_line *gpio_get_output_line(struct EG25Manager *manager, int chip, int line)
{
- int i, ret;
- guint offset, chipidx, gpio_idx;
- toml_table_t *gpio_config[EG25_CONFIG_COUNT];
+ struct gpiod_line *gpio_line;
- for (i = 0; i < EG25_CONFIG_COUNT; i++)
- gpio_config[i] = config[i] ? toml_table_in(config[i], "gpio") : NULL;
+ gpio_line = gpiod_chip_get_line(manager->gpiochip[chip], line);
+ if (!gpio_line)
+ return NULL;
- if (!gpio_config[EG25_CONFIG_SYS])
- g_error("Default config file lacks the 'gpio' section!");
-
- manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
- if (!manager->gpiochip[0]) {
- g_critical("Unable to open GPIO chip " GPIO_CHIP1_LABEL);
- return 1;
+ if (gpiod_line_request_output(gpio_line, "eg25manager", 0) < 0) {
+ gpiod_line_release(gpio_line);
+ return NULL;
}
- manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL);
- if (!manager->gpiochip[1]) {
- g_critical("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
- return 1;
- }
+ return gpio_line;
+}
- for (i = 0; i < GPIO_OUT_COUNT; i++) {
- if (!config_get_uint(gpio_config, gpio_out_names[i], &gpio_idx))
- g_error("Unable to get config for output GPIO '%s'", gpio_out_names[i]);
-
- if (gpio_idx < MAX_GPIOCHIP_LINES) {
- offset = gpio_idx;
- chipidx = 0;
- } else {
- offset = gpio_idx - MAX_GPIOCHIP_LINES;
- chipidx = 1;
- }
+struct gpiod_line *gpio_get_input_line(struct EG25Manager *manager, int chip, int line)
+{
+ struct gpiod_line *gpio_line;
- manager->gpio_out[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset);
- if (!manager->gpio_out[i]) {
- g_error("Unable to get output GPIO %d", i);
- return 1;
- }
+ gpio_line = gpiod_chip_get_line(manager->gpiochip[chip], line);
+ if (!gpio_line)
+ return NULL;
- ret = gpiod_line_request_output(manager->gpio_out[i], "eg25manager", 0);
- if (ret < 0) {
- g_error("Unable to request output GPIO %d", i);
- return 1;
- }
+ if (gpiod_line_request_input(gpio_line, "eg25manager") < 0) {
+ gpiod_line_release(gpio_line);
+ return NULL;
}
- for (i = 0; i < GPIO_IN_COUNT; i++) {
- if (!config_get_uint(gpio_config, gpio_in_names[i], &gpio_idx))
- continue;
-
- if (gpio_idx < MAX_GPIOCHIP_LINES) {
- offset = gpio_idx;
- chipidx = 0;
- } else {
- offset = gpio_idx - MAX_GPIOCHIP_LINES;
- chipidx = 1;
- }
+ return gpio_line;
+}
- manager->gpio_in[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset);
- if (!manager->gpio_in[i]) {
- g_warning("Unable to get input GPIO %d", i);
- continue;
- }
+int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
+{
+ int i;
+ toml_table_t *gpio_config[EG25_CONFIG_COUNT];
+
+ for (i = 0; i < EG25_CONFIG_COUNT; i++)
+ gpio_config[i] = config[i] ? toml_table_in(config[i], "gpio") : NULL;
+
+ if (!gpio_config[EG25_CONFIG_SYS])
+ g_error("Default config file lacks the 'gpio' section!");
- ret = gpiod_line_request_input(manager->gpio_in[i], "eg25manager");
- if (ret < 0) {
- g_warning("Unable to request input GPIO %d", i);
- manager->gpio_in[i] = NULL;
+ /*
+ * The system config could have the `chips` key, but the user one
+ * could still use the old format! In order to avoid problems, we
+ * should use the new format only if:
+ * - there's no user config file
+ or
+ * - the user config file contains the `chips` key
+ * Otherwise we might start parsing the system config with the new
+ * format, but error out if user config overrides gpios using the
+ * old format
+ */
+ if (!gpio_config[EG25_CONFIG_USER] || toml_array_in(gpio_config[EG25_CONFIG_USER], "chips"))
+ {
+ int numchips;
+ toml_array_t *chipslist = NULL;
+
+ config_get_array(gpio_config, "chips", &chipslist);
+ numchips = toml_array_nelem(chipslist);
+ if (numchips > 2)
+ g_error("Requesting too many GPIO chips!");
+
+ for (i = 0; i < numchips; i++) {
+ toml_datum_t data = toml_string_at(chipslist, i);
+ if (!data.ok)
+ continue;
+ manager->gpiochip[i] = gpiod_chip_open_by_label(data.u.s);
+ if (!manager->gpiochip[i])
+ g_error("Unable to find GPIO chip '%s'", data.u.s);
+ }
+
+ for (i = 0; i < GPIO_OUT_COUNT; i++) {
+ toml_table_t *table;
+ toml_datum_t chip, line;
+ if (!config_get_table(gpio_config, gpio_out_names[i], &table))
+ g_error("Unable to get config for output GPIO '%s'", gpio_out_names[i]);
+
+ chip = toml_int_in(table, "chip");
+ if (!chip.ok || chip.u.i < 0 || chip.u.i > 2)
+ g_error("Wrong chip ID for output GPIO '%s'", gpio_out_names[i]);
+
+ line = toml_int_in(table, "line");
+ if (!line.ok || line.u.i < 0 || line.u.i > gpiod_chip_num_lines(manager->gpiochip[chip.u.i]))
+ g_error("Wrong line ID for output GPIO '%s'", gpio_out_names[i]);
+
+ manager->gpio_out[i] = gpio_get_output_line(manager, chip.u.i, line.u.i);
+ if (!manager->gpio_out[i])
+ g_error("Unable to get output GPIO %d", i);
+ }
+
+ for (i = 0; i < GPIO_IN_COUNT; i++) {
+ toml_table_t *table;
+ toml_datum_t chip, line;
+ if (!config_get_table(gpio_config, gpio_in_names[i], &table))
+ g_error("Unable to get config for input GPIO '%s'", gpio_in_names[i]);
+
+ chip = toml_int_in(table, "chip");
+ if (!chip.ok || chip.u.i < 0 || chip.u.i > 2)
+ g_error("Wrong chip ID for input GPIO '%s'", gpio_in_names[i]);
+
+ line = toml_int_in(table, "line");
+ if (!line.ok || line.u.i < 0 || line.u.i > gpiod_chip_num_lines(manager->gpiochip[chip.u.i]))
+ g_error("Wrong line ID for input GPIO '%s'", gpio_in_names[i]);
+
+ manager->gpio_in[i] = gpio_get_input_line(manager, chip.u.i, line.u.i);
+ if (!manager->gpio_in[i])
+ g_error("Unable to get input GPIO %d", i);
+ }
+ } else {
+ guint offset, chipidx, gpio_idx;
+
+ /* Legacy config file, only used on the OG PinePhone */
+ manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
+ if (!manager->gpiochip[0])
+ g_error("Unable to open GPIO chip " GPIO_CHIP1_LABEL);
+
+ manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL);
+ if (!manager->gpiochip[1])
+ g_error("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
+
+ for (i = 0; i < GPIO_OUT_COUNT; i++) {
+ if (!config_get_uint(gpio_config, gpio_out_names[i], &gpio_idx))
+ g_error("Unable to get config for output GPIO '%s'", gpio_out_names[i]);
+
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/manager.c
^
|
@@ -314,6 +314,7 @@
struct EG25Manager manager;
gchar *config_file = NULL;
gboolean show_version = FALSE;
+ gboolean monitor_udev = TRUE;
toml_table_t *toml_config[EG25_CONFIG_COUNT];
toml_table_t *manager_config[EG25_CONFIG_COUNT];
const GOptionEntry options[] = {
@@ -363,6 +364,7 @@
if (!manager_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'manager' section!");
+ config_get_bool(manager_config, "monitor_udev", &monitor_udev);
config_get_bool(manager_config, "need_libusb", &manager.use_libusb);
config_get_uint(manager_config, "usb_vid", &manager.usb_vid);
config_get_uint(manager_config, "usb_pid", &manager.usb_pid);
@@ -375,7 +377,8 @@
#endif
ofono_iface_init(&manager, toml_config);
suspend_init(&manager, toml_config);
- udev_init(&manager, toml_config);
+ if (monitor_udev)
+ udev_init(&manager, toml_config);
gnss_init(&manager, toml_config);
for (int i = 0; i < EG25_CONFIG_COUNT; i++) {
|
[-]
[+]
|
Changed |
_service:tar_git:eg25-manager-0.4.2+git1.tar.bz2/eg25-manager/src/suspend.c
^
|
@@ -18,10 +18,24 @@
#define SD_PATH "/org/freedesktop/login1"
#define SD_INTERFACE "org.freedesktop.login1.Manager"
+static void resume_ok(struct EG25Manager *manager)
+{
+ manager->modem_state = EG25_STATE_CONFIGURED;
+ modem_resume_post(manager);
+}
+
static gboolean check_modem_resume(struct EG25Manager *manager)
{
- g_message("Modem wasn't probed in time, restart it!");
manager->modem_recovery_timer = 0;
+
+#ifdef HAVE_MMGLIB
+ if (manager->mm_modem) {
+ resume_ok(manager);
+ return FALSE;
+ }
+#endif
+
+ g_message("Modem wasn't probed in time, restart it!");
modem_reset(manager);
return FALSE;
@@ -184,8 +198,7 @@
* 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);
+ resume_ok(manager);
} else {
manager->modem_state = EG25_STATE_RESUMING;
manager->modem_recovery_timer = g_timeout_add_seconds(manager->modem_recovery_timeout,
|