Update upstream source from tag '0.4.2'

Update to upstream version '0.4.2'
with Debian dir ad2c13f51c
This commit is contained in:
Arnaud Ferraris
2021-12-08 18:23:57 +01:00
10 changed files with 273 additions and 67 deletions

View File

@@ -8,6 +8,7 @@ conf_files = [
'pine64,pinephone-1.0.toml', 'pine64,pinephone-1.0.toml',
'pine64,pinephone-1.1.toml', 'pine64,pinephone-1.1.toml',
'pine64,pinephone-1.2.toml', 'pine64,pinephone-1.2.toml',
'pine64,pinephone-pro.toml',
] ]
install_data(conf_files) install_data(conf_files)

View File

@@ -13,11 +13,12 @@ poweron_delay = 100000
#recovery_timeout = 9 #recovery_timeout = 9
[gpio] [gpio]
dtr = 358 chips = [ "1c20800.pinctrl", "1f02c00.pinctrl" ]
pwrkey = 35 dtr = { chip = 1, line = 6 }
reset = 68 pwrkey = { chip = 0, line = 35 }
apready = 231 reset = { chip = 0, line = 68 }
disable = 232 apready = { chip = 0, line = 231 }
disable = { chip = 0, line = 232 }
[at] [at]
uart = "/dev/ttyS2" uart = "/dev/ttyS2"

View File

@@ -13,11 +13,12 @@ poweron_delay = 100000
#recovery_timeout = 9 #recovery_timeout = 9
[gpio] [gpio]
dtr = 358 chips = [ "1c20800.pinctrl", "1f02c00.pinctrl" ]
pwrkey = 35 dtr = { chip = 1, line = 6 }
reset = 68 pwrkey = { chip = 0, line = 35 }
apready = 231 reset = { chip = 0, line = 68 }
disable = 232 apready = { chip = 0, line = 231 }
disable = { chip = 0, line = 232 }
[at] [at]
uart = "/dev/ttyS2" uart = "/dev/ttyS2"

View File

@@ -9,12 +9,13 @@ poweron_delay = 100000
#recovery_timeout = 9 #recovery_timeout = 9
[gpio] [gpio]
dtr = 34 chips = [ "1c20800.pinctrl" ]
pwrkey = 35 dtr = { chip = 0, line = 34 }
reset = 68 pwrkey = { chip = 0, line = 35 }
apready = 231 reset = { chip = 0, line = 68 }
disable = 232 apready = { chip = 0, line = 231 }
status = 233 disable = { chip = 0, line = 232 }
status = { chip = 0, line = 233 }
[at] [at]
uart = "/dev/ttyS2" uart = "/dev/ttyS2"

View File

@@ -0,0 +1,97 @@
[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]
#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,0,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"

View File

@@ -8,7 +8,7 @@
project ( project (
'eg25-manager', 'eg25-manager',
'c', 'c',
version : '0.4.1', version : '0.4.2',
license : 'GPLv3+', license : 'GPLv3+',
meson_version : '>= 0.50.0', meson_version : '>= 0.50.0',
default_options : default_options :

View File

@@ -245,7 +245,14 @@ static gboolean modem_response(gint fd,
*/ */
do { do {
ret = read(fd, tmp, sizeof(tmp)); ret = read(fd, tmp, sizeof(tmp));
if (ret > 0) { 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); memcpy(&response[pos], tmp, ret);
pos += ret; pos += ret;
usleep(10000); usleep(10000);

View File

@@ -81,3 +81,17 @@ gboolean config_get_array(toml_table_t **config, const gchar *key, toml_array_t
return !!array; 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;
}

View File

@@ -24,3 +24,4 @@ gboolean config_get_int(toml_table_t **config, const gchar *key, gint *result);
gboolean config_get_uint(toml_table_t **config, const gchar *key, guint *result); 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_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_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);

View File

@@ -9,9 +9,9 @@
#include <unistd.h> #include <unistd.h>
/* Those defines are used for legacy config files only */
#define GPIO_CHIP1_LABEL "1c20800.pinctrl" #define GPIO_CHIP1_LABEL "1c20800.pinctrl"
#define GPIO_CHIP2_LABEL "1f02c00.pinctrl" #define GPIO_CHIP2_LABEL "1f02c00.pinctrl"
#define MAX_GPIOCHIP_LINES 352 #define MAX_GPIOCHIP_LINES 352
enum { enum {
@@ -101,10 +101,41 @@ int gpio_sequence_sleep(struct EG25Manager *manager)
return 0; return 0;
} }
struct gpiod_line *gpio_get_output_line(struct EG25Manager *manager, int chip, int line)
{
struct gpiod_line *gpio_line;
gpio_line = gpiod_chip_get_line(manager->gpiochip[chip], line);
if (!gpio_line)
return NULL;
if (gpiod_line_request_output(gpio_line, "eg25manager", 0) < 0) {
gpiod_line_release(gpio_line);
return NULL;
}
return gpio_line;
}
struct gpiod_line *gpio_get_input_line(struct EG25Manager *manager, int chip, int line)
{
struct gpiod_line *gpio_line;
gpio_line = gpiod_chip_get_line(manager->gpiochip[chip], line);
if (!gpio_line)
return NULL;
if (gpiod_line_request_input(gpio_line, "eg25manager") < 0) {
gpiod_line_release(gpio_line);
return NULL;
}
return gpio_line;
}
int gpio_init(struct EG25Manager *manager, toml_table_t *config[]) int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
{ {
int i, ret; int i;
guint offset, chipidx, gpio_idx;
toml_table_t *gpio_config[EG25_CONFIG_COUNT]; toml_table_t *gpio_config[EG25_CONFIG_COUNT];
for (i = 0; i < EG25_CONFIG_COUNT; i++) for (i = 0; i < EG25_CONFIG_COUNT; i++)
@@ -113,65 +144,117 @@ int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
if (!gpio_config[EG25_CONFIG_SYS]) if (!gpio_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'gpio' section!"); g_error("Default config file lacks the 'gpio' section!");
manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL); /*
if (!manager->gpiochip[0]) { * The system config could have the `chips` key, but the user one
g_critical("Unable to open GPIO chip " GPIO_CHIP1_LABEL); * could still use the old format! In order to avoid problems, we
return 1; * 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;
manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL); config_get_array(gpio_config, "chips", &chipslist);
if (!manager->gpiochip[1]) { numchips = toml_array_nelem(chipslist);
g_critical("Unable to open GPIO chip " GPIO_CHIP2_LABEL); if (numchips > 2)
return 1; g_error("Requesting too many GPIO chips!");
}
for (i = 0; i < GPIO_OUT_COUNT; i++) { for (i = 0; i < numchips; i++) {
if (!config_get_uint(gpio_config, gpio_out_names[i], &gpio_idx)) toml_datum_t data = toml_string_at(chipslist, i);
g_error("Unable to get config for output GPIO '%s'", gpio_out_names[i]); if (!data.ok)
continue;
if (gpio_idx < MAX_GPIOCHIP_LINES) { manager->gpiochip[i] = gpiod_chip_open_by_label(data.u.s);
offset = gpio_idx; if (!manager->gpiochip[i])
chipidx = 0; g_error("Unable to find GPIO chip '%s'", data.u.s);
} else {
offset = gpio_idx - MAX_GPIOCHIP_LINES;
chipidx = 1;
} }
manager->gpio_out[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset); for (i = 0; i < GPIO_OUT_COUNT; i++) {
if (!manager->gpio_out[i]) { toml_table_t *table;
g_error("Unable to get output GPIO %d", i); toml_datum_t chip, line;
return 1; 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);
} }
ret = gpiod_line_request_output(manager->gpio_out[i], "eg25manager", 0); for (i = 0; i < GPIO_IN_COUNT; i++) {
if (ret < 0) { toml_table_t *table;
g_error("Unable to request output GPIO %d", i); toml_datum_t chip, line;
return 1; 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;
for (i = 0; i < GPIO_IN_COUNT; i++) { /* Legacy config file, only used on the OG PinePhone */
if (!config_get_uint(gpio_config, gpio_in_names[i], &gpio_idx)) manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
continue; if (!manager->gpiochip[0])
g_error("Unable to open GPIO chip " GPIO_CHIP1_LABEL);
if (gpio_idx < MAX_GPIOCHIP_LINES) { manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL);
offset = gpio_idx; if (!manager->gpiochip[1])
chipidx = 0; g_error("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
} else {
offset = gpio_idx - MAX_GPIOCHIP_LINES; for (i = 0; i < GPIO_OUT_COUNT; i++) {
chipidx = 1; 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;
}
manager->gpio_out[i] = gpio_get_input_line(manager, chipidx, offset);
if (!manager->gpio_out[i])
g_error("Unable to get output GPIO %d", i);
} }
manager->gpio_in[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset); for (i = 0; i < GPIO_IN_COUNT; i++) {
if (!manager->gpio_in[i]) { if (!config_get_uint(gpio_config, gpio_in_names[i], &gpio_idx))
g_warning("Unable to get input GPIO %d", i); continue;
continue;
}
ret = gpiod_line_request_input(manager->gpio_in[i], "eg25manager"); if (gpio_idx < MAX_GPIOCHIP_LINES) {
if (ret < 0) { offset = gpio_idx;
g_warning("Unable to request input GPIO %d", i); chipidx = 0;
manager->gpio_in[i] = NULL; } else {
offset = gpio_idx - MAX_GPIOCHIP_LINES;
chipidx = 1;
}
manager->gpio_in[i] = gpio_get_input_line(manager, chipidx, offset);
if (!manager->gpio_in[i])
g_error("Unable to get input GPIO %d", i);
} }
} }