gpio: libgpiod 2.0: port gpiod_chip_open_by_label

This commit is contained in:
marcin
2024-05-13 21:43:58 +02:00
parent e7790f941c
commit b8ff1ef3d4

View File

@@ -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);