gpio: configure STATUS input gpio

RI won't be accessible due to it being used by the kernel as an 
interrupt source, so we can check the STATUS pin (CE only) which will 
allow us to know precisely when the modem is shut down.
This commit is contained in:
Arnaud Ferraris
2020-12-10 17:03:11 +01:00
parent e3387e85ca
commit 1170a2c7f7
2 changed files with 62 additions and 16 deletions

View File

@@ -11,6 +11,8 @@
#define MAX_GPIOCHIP_LINES 352
#define GPIO_IDX_INVAL 0xffff
enum {
GPIO_OUT_DTR = 0,
GPIO_OUT_PWRKEY,
@@ -20,7 +22,7 @@ enum {
GPIO_OUT_COUNT
};
static unsigned gpio_idx_bh[] = {
static unsigned gpio_out_idx_bh[] = {
358,
35,
68,
@@ -28,7 +30,7 @@ static unsigned gpio_idx_bh[] = {
232
};
static unsigned gpio_idx_ce[] = {
static unsigned gpio_out_idx_ce[] = {
34,
35,
68,
@@ -36,6 +38,19 @@ static unsigned gpio_idx_ce[] = {
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)
{
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 1);
@@ -83,7 +98,8 @@ int gpio_sequence_resume(struct EG25Manager *manager)
int gpio_init(struct EG25Manager *manager)
{
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);
if (!manager->gpiochip[0]) {
@@ -91,42 +107,71 @@ int gpio_init(struct EG25Manager *manager)
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) {
// BH have DTR on the 2nd gpiochip
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;
}
gpio_idx = gpio_idx_bh;
gpio_in_idx = gpio_in_idx_bh;
gpio_out_idx = gpio_out_idx_bh;
} 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++) {
unsigned int offset, chipidx;
if (gpio_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_idx[i];
if (gpio_out_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_out_idx[i];
chipidx = 0;
} else {
offset = gpio_idx[i] - MAX_GPIOCHIP_LINES;
offset = gpio_out_idx[i] - MAX_GPIOCHIP_LINES;
chipidx = 1;
}
manager->gpio_out[i] = gpiod_chip_get_line(manager->gpiochip[chipidx], offset);
if (!manager->gpio_out[i]) {
g_critical("Unable to get line %d", i);
g_critical("Unable to get output GPIO %d", i);
return 1;
}
ret = gpiod_line_request_output(manager->gpio_out[i], "eg25manager", 0);
if (ret < 0) {
g_critical("Unable to request line %d", i);
g_critical("Unable to request output GPIO %d", i);
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;
}

View File

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