mirror of
https://gitlab.com/mobian1/eg25-manager.git
synced 2025-08-29 15:22:20 +02:00
gpio: libgpiod 2.0: port gpiod_chip_open_by_label
This commit is contained in:
92
src/gpio.c
92
src/gpio.c
@@ -8,6 +8,8 @@
|
|||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/* Those defines are used for legacy config files only */
|
/* Those defines are used for legacy config files only */
|
||||||
#define GPIO_CHIP1_LABEL "1c20800.pinctrl"
|
#define GPIO_CHIP1_LABEL "1c20800.pinctrl"
|
||||||
@@ -133,6 +135,90 @@ struct gpiod_line *gpio_get_input_line(struct EG25Manager *manager, int chip, in
|
|||||||
return gpio_line;
|
return gpio_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gpio_chip_dir_filter(const struct dirent *entry)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
int ret = 0;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (asprintf(&path, "/dev/%s", entry->d_name) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((lstat(path, &sb) == 0) && (!S_ISLNK(sb.st_mode)) &&
|
||||||
|
gpiod_is_gpiochip_device(path))
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpio_all_chip_paths(char ***paths_ptr)
|
||||||
|
{
|
||||||
|
int i, j, num_chips, ret = 0;
|
||||||
|
struct dirent **entries;
|
||||||
|
char **paths;
|
||||||
|
|
||||||
|
num_chips = scandir("/dev/", &entries, gpio_chip_dir_filter, alphasort);
|
||||||
|
if (num_chips < 0)
|
||||||
|
g_error("gpio: unable to scan /dev: %s", g_strerror(errno));
|
||||||
|
|
||||||
|
paths = calloc(num_chips, sizeof(*paths));
|
||||||
|
if (paths == NULL)
|
||||||
|
g_error("gpio: out of memory");
|
||||||
|
|
||||||
|
for (i = 0; i < num_chips; i++) {
|
||||||
|
if (asprintf(&paths[i], "/dev/%s", entries[i]->d_name) < 0) {
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
free(paths[j]);
|
||||||
|
|
||||||
|
free(paths);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*paths_ptr = paths;
|
||||||
|
ret = num_chips;
|
||||||
|
|
||||||
|
for (i = 0; i < num_chips; i++)
|
||||||
|
free(entries[i]);
|
||||||
|
|
||||||
|
free(entries);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gpiod_chip *gpio_chip_open_by_label(const char *label)
|
||||||
|
{
|
||||||
|
int num_chips, i;
|
||||||
|
char **paths;
|
||||||
|
const char *clabel;
|
||||||
|
struct gpiod_chip *chip;
|
||||||
|
struct gpiod_chip_info *cinfo;
|
||||||
|
|
||||||
|
num_chips = gpio_all_chip_paths(&paths);
|
||||||
|
|
||||||
|
for (i = 0; i < num_chips; i++) {
|
||||||
|
chip = gpiod_chip_open(paths[i]);
|
||||||
|
if (!chip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cinfo = gpiod_chip_get_info(chip);
|
||||||
|
if (!cinfo)
|
||||||
|
goto clean_chip_open;
|
||||||
|
|
||||||
|
clabel = gpiod_chip_info_get_label(cinfo);
|
||||||
|
|
||||||
|
if (strcmp(label, clabel) == 0) {
|
||||||
|
return chip;
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_chip_open:
|
||||||
|
gpiod_chip_close(chip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
|
int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -169,7 +255,7 @@ int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
|
|||||||
toml_datum_t data = toml_string_at(chipslist, i);
|
toml_datum_t data = toml_string_at(chipslist, i);
|
||||||
if (!data.ok)
|
if (!data.ok)
|
||||||
continue;
|
continue;
|
||||||
manager->gpiochip[i] = gpiod_chip_open_by_label(data.u.s);
|
manager->gpiochip[i] = gpio_chip_open_by_label(data.u.s);
|
||||||
if (!manager->gpiochip[i])
|
if (!manager->gpiochip[i])
|
||||||
g_error("Unable to find GPIO chip '%s'", data.u.s);
|
g_error("Unable to find GPIO chip '%s'", data.u.s);
|
||||||
}
|
}
|
||||||
@@ -220,11 +306,11 @@ int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
|
|||||||
guint offset, chipidx, gpio_idx;
|
guint offset, chipidx, gpio_idx;
|
||||||
|
|
||||||
/* Legacy config file, only used on the OG PinePhone */
|
/* Legacy config file, only used on the OG PinePhone */
|
||||||
manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
|
manager->gpiochip[0] = gpio_chip_open_by_label(GPIO_CHIP1_LABEL);
|
||||||
if (!manager->gpiochip[0])
|
if (!manager->gpiochip[0])
|
||||||
g_error("Unable to open GPIO chip " GPIO_CHIP1_LABEL);
|
g_error("Unable to open GPIO chip " GPIO_CHIP1_LABEL);
|
||||||
|
|
||||||
manager->gpiochip[1] = gpiod_chip_open_by_label(GPIO_CHIP2_LABEL);
|
manager->gpiochip[1] = gpio_chip_open_by_label(GPIO_CHIP2_LABEL);
|
||||||
if (!manager->gpiochip[1])
|
if (!manager->gpiochip[1])
|
||||||
g_error("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
|
g_error("Unable to open GPIO chip " GPIO_CHIP2_LABEL);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user