New upstream release 0.0.2

This commit is contained in:
Arnaud Ferraris
2020-12-10 19:50:32 +01:00
4 changed files with 93 additions and 28 deletions

View File

@@ -11,6 +11,8 @@
#define MAX_GPIOCHIP_LINES 352 #define MAX_GPIOCHIP_LINES 352
#define GPIO_IDX_INVAL 0xffff
enum { enum {
GPIO_OUT_DTR = 0, GPIO_OUT_DTR = 0,
GPIO_OUT_PWRKEY, GPIO_OUT_PWRKEY,
@@ -20,7 +22,7 @@ enum {
GPIO_OUT_COUNT GPIO_OUT_COUNT
}; };
static unsigned gpio_idx_bh[] = { static unsigned gpio_out_idx_bh[] = {
358, 358,
35, 35,
68, 68,
@@ -28,7 +30,7 @@ static unsigned gpio_idx_bh[] = {
232 232
}; };
static unsigned gpio_idx_ce[] = { static unsigned gpio_out_idx_ce[] = {
34, 34,
35, 35,
68, 68,
@@ -36,6 +38,19 @@ static unsigned gpio_idx_ce[] = {
232 232
}; };
enum {
GPIO_IN_STATUS = 0,
GPIO_IN_COUNT
};
static unsigned gpio_in_idx_bh[] = {
GPIO_IDX_INVAL,
};
static unsigned gpio_in_idx_ce[] = {
233,
};
int gpio_sequence_poweron(struct EG25Manager *manager) int gpio_sequence_poweron(struct EG25Manager *manager)
{ {
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 1); gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 1);
@@ -49,11 +64,8 @@ int gpio_sequence_poweron(struct EG25Manager *manager)
int gpio_sequence_shutdown(struct EG25Manager *manager) int gpio_sequence_shutdown(struct EG25Manager *manager)
{ {
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_RESET], 1);
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_DISABLE], 1); gpiod_line_set_value(manager->gpio_out[GPIO_OUT_DISABLE], 1);
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 1); gpio_sequence_poweron(manager);
sleep(1);
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 0);
g_message("Executed power-off sequence"); g_message("Executed power-off sequence");
@@ -83,7 +95,8 @@ int gpio_sequence_resume(struct EG25Manager *manager)
int gpio_init(struct EG25Manager *manager) int gpio_init(struct EG25Manager *manager)
{ {
int i, ret; int i, ret;
unsigned *gpio_idx; unsigned *gpio_in_idx;
unsigned *gpio_out_idx;
manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL); manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
if (!manager->gpiochip[0]) { if (!manager->gpiochip[0]) {
@@ -91,45 +104,87 @@ int gpio_init(struct EG25Manager *manager)
return 1; return 1;
} }
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;
}
if (manager->braveheart) { if (manager->braveheart) {
// BH have DTR on the 2nd gpiochip gpio_in_idx = gpio_in_idx_bh;
manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL); gpio_out_idx = gpio_out_idx_bh;
if (!manager->gpiochip[1]) {
g_critical("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
return 1;
}
gpio_idx = gpio_idx_bh;
} else { } else {
gpio_idx = gpio_idx_ce; gpio_in_idx = gpio_in_idx_ce;
gpio_out_idx = gpio_out_idx_ce;
} }
for (i = 0; i < GPIO_OUT_COUNT; i++) { for (i = 0; i < GPIO_OUT_COUNT; i++) {
unsigned int offset, chipidx; unsigned int offset, chipidx;
if (gpio_idx[i] < MAX_GPIOCHIP_LINES) { if (gpio_out_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_idx[i]; offset = gpio_out_idx[i];
chipidx = 0; chipidx = 0;
} else { } else {
offset = gpio_idx[i] - MAX_GPIOCHIP_LINES; offset = gpio_out_idx[i] - MAX_GPIOCHIP_LINES;
chipidx = 1; chipidx = 1;
} }
manager->gpio_out[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset); manager->gpio_out[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset);
if (!manager->gpio_out[i]) { if (!manager->gpio_out[i]) {
g_critical("Unable to get line %d", i); g_critical("Unable to get output GPIO %d", i);
return 1; return 1;
} }
ret = gpiod_line_request_output(manager->gpio_out[i], "eg25manager", 0); ret = gpiod_line_request_output(manager->gpio_out[i], "eg25manager", 0);
if (ret < 0) { if (ret < 0) {
g_critical("Unable to request line %d", i); g_critical("Unable to request output GPIO %d", i);
return 1; return 1;
} }
} }
for (i = 0; i < GPIO_IN_COUNT; i++) {
unsigned int offset, chipidx;
if (gpio_in_idx[i] == GPIO_IDX_INVAL)
continue;
if (gpio_in_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_in_idx[i];
chipidx = 0;
} else {
offset = gpio_in_idx[i] - MAX_GPIOCHIP_LINES;
chipidx = 1;
}
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;
}
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;
}
}
return 0; return 0;
} }
gboolean gpio_check_poweroff(struct EG25Manager *manager)
{
if (manager->gpio_in[GPIO_IN_STATUS] &&
gpiod_line_get_value(manager->gpio_in[GPIO_IN_STATUS]) == 1) {
// Asserting RESET line to prevent modem from rebooting
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_RESET], 1);
return TRUE;
}
return FALSE;
}
void gpio_destroy(struct EG25Manager *manager) void gpio_destroy(struct EG25Manager *manager)
{ {
int i; int i;

View File

@@ -15,3 +15,5 @@ int gpio_sequence_poweron(struct EG25Manager *state);
int gpio_sequence_shutdown(struct EG25Manager *state); int gpio_sequence_shutdown(struct EG25Manager *state);
int gpio_sequence_suspend(struct EG25Manager *state); int gpio_sequence_suspend(struct EG25Manager *state);
int gpio_sequence_resume(struct EG25Manager *state); int gpio_sequence_resume(struct EG25Manager *state);
gboolean gpio_check_poweroff(struct EG25Manager *manager);

View File

@@ -22,12 +22,19 @@ static gboolean quit_timeout_cb(struct EG25Manager *manager)
g_message("Modem down, quitting..."); g_message("Modem down, quitting...");
g_main_loop_quit(manager->loop); g_main_loop_quit(manager->loop);
at_destroy(manager);
gpio_destroy(manager);
return FALSE; return FALSE;
} }
static gboolean gpio_poll_cb(struct EG25Manager *manager)
{
if (gpio_check_poweroff(manager)) {
quit_timeout_cb(manager);
return FALSE;
}
return TRUE;
}
static gboolean quit_app(struct EG25Manager *manager) static gboolean quit_app(struct EG25Manager *manager)
{ {
g_message("Request to quit..."); g_message("Request to quit...");
@@ -36,10 +43,7 @@ static gboolean quit_app(struct EG25Manager *manager)
g_message("Powering down the modem..."); g_message("Powering down the modem...");
gpio_sequence_shutdown(manager); gpio_sequence_shutdown(manager);
manager->modem_state = EG25_STATE_FINISHING; manager->modem_state = EG25_STATE_FINISHING;
/* g_timeout_add(500, G_SOURCE_FUNC(gpio_poll_cb), manager);
* TODO: add a polling function to check STATUS and RI pins state
* (that way we could reduce the poweroff delay)
*/
g_timeout_add_seconds(30, G_SOURCE_FUNC(quit_timeout_cb), manager); g_timeout_add_seconds(30, G_SOURCE_FUNC(quit_timeout_cb), manager);
} }
@@ -140,7 +144,7 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
read(fd, compatible, sizeof(compatible)); read(fd, compatible, sizeof(compatible));
if (strstr(compatible, "pine64,pinephone-1.1")) if (!strstr(compatible, "pine64,pinephone-1.2"))
manager.braveheart = TRUE; manager.braveheart = TRUE;
close(fd); close(fd);
@@ -156,5 +160,8 @@ int main(int argc, char *argv[])
g_main_loop_run(manager.loop); g_main_loop_run(manager.loop);
at_destroy(&manager);
gpio_destroy(&manager);
return 0; return 0;
} }

View File

@@ -46,6 +46,7 @@ struct EG25Manager {
struct gpiod_chip *gpiochip[2]; struct gpiod_chip *gpiochip[2];
struct gpiod_line *gpio_out[5]; struct gpiod_line *gpio_out[5];
struct gpiod_line *gpio_in[2];
}; };
void modem_configure(struct EG25Manager *data); void modem_configure(struct EG25Manager *data);