mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-05-26 15:26:12 +00:00
Issue #255: libgpiod 2.0 API supported
Thanks for @jpalus for #249 with compatibility code
This commit is contained in:
@@ -42,7 +42,7 @@ endef
|
|||||||
|
|
||||||
ifneq ($(call optbool,$(WITH_GPIO)),)
|
ifneq ($(call optbool,$(WITH_GPIO)),)
|
||||||
_USTR_LIBS += -lgpiod
|
_USTR_LIBS += -lgpiod
|
||||||
override _CFLAGS += -DWITH_GPIO
|
override _CFLAGS += -DWITH_GPIO $(shell pkg-config --atleast-version=2 libgpiod 2> /dev/null && echo -DHAVE_GPIOD2)
|
||||||
_USTR_SRCS += $(shell ls ustreamer/gpio/*.c)
|
_USTR_SRCS += $(shell ls ustreamer/gpio/*.c)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -34,24 +34,26 @@ us_gpio_s us_g_gpio = {
|
|||||||
.line = NULL, \
|
.line = NULL, \
|
||||||
.state = false \
|
.state = false \
|
||||||
}
|
}
|
||||||
|
|
||||||
.prog_running = MAKE_OUTPUT("prog-running"),
|
.prog_running = MAKE_OUTPUT("prog-running"),
|
||||||
.stream_online = MAKE_OUTPUT("stream-online"),
|
.stream_online = MAKE_OUTPUT("stream-online"),
|
||||||
.has_http_clients = MAKE_OUTPUT("has-http-clients"),
|
.has_http_clients = MAKE_OUTPUT("has-http-clients"),
|
||||||
|
|
||||||
# undef MAKE_OUTPUT
|
# undef MAKE_OUTPUT
|
||||||
|
|
||||||
// mutex uninitialized
|
# ifndef HAVE_GPIOD2
|
||||||
.chip = NULL
|
.chip = NULL,
|
||||||
|
# endif
|
||||||
|
.initialized = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void _gpio_output_init(us_gpio_output_s *output);
|
static void _gpio_output_init(us_gpio_output_s *output, struct gpiod_chip *chip);
|
||||||
static void _gpio_output_destroy(us_gpio_output_s *output);
|
static void _gpio_output_destroy(us_gpio_output_s *output);
|
||||||
|
|
||||||
|
|
||||||
void us_gpio_init(void) {
|
void us_gpio_init(void) {
|
||||||
|
# ifndef HAVE_GPIOD2
|
||||||
assert(us_g_gpio.chip == NULL);
|
assert(us_g_gpio.chip == NULL);
|
||||||
|
# endif
|
||||||
if (
|
if (
|
||||||
us_g_gpio.prog_running.pin >= 0
|
us_g_gpio.prog_running.pin >= 0
|
||||||
|| us_g_gpio.stream_online.pin >= 0
|
|| us_g_gpio.stream_online.pin >= 0
|
||||||
@@ -59,10 +61,17 @@ void us_gpio_init(void) {
|
|||||||
) {
|
) {
|
||||||
US_MUTEX_INIT(us_g_gpio.mutex);
|
US_MUTEX_INIT(us_g_gpio.mutex);
|
||||||
US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path);
|
US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path);
|
||||||
if ((us_g_gpio.chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
|
struct gpiod_chip *chip;
|
||||||
_gpio_output_init(&us_g_gpio.prog_running);
|
if ((chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
|
||||||
_gpio_output_init(&us_g_gpio.stream_online);
|
_gpio_output_init(&us_g_gpio.prog_running, chip);
|
||||||
_gpio_output_init(&us_g_gpio.has_http_clients);
|
_gpio_output_init(&us_g_gpio.stream_online, chip);
|
||||||
|
_gpio_output_init(&us_g_gpio.has_http_clients, chip);
|
||||||
|
# ifdef HAVE_GPIOD2
|
||||||
|
gpiod_chip_close(chip);
|
||||||
|
# else
|
||||||
|
us_g_gpio.chip = chip;
|
||||||
|
# endif
|
||||||
|
us_g_gpio.initialized = true;
|
||||||
} else {
|
} else {
|
||||||
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path);
|
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path);
|
||||||
}
|
}
|
||||||
@@ -73,23 +82,32 @@ void us_gpio_destroy(void) {
|
|||||||
_gpio_output_destroy(&us_g_gpio.prog_running);
|
_gpio_output_destroy(&us_g_gpio.prog_running);
|
||||||
_gpio_output_destroy(&us_g_gpio.stream_online);
|
_gpio_output_destroy(&us_g_gpio.stream_online);
|
||||||
_gpio_output_destroy(&us_g_gpio.has_http_clients);
|
_gpio_output_destroy(&us_g_gpio.has_http_clients);
|
||||||
if (us_g_gpio.chip != NULL) {
|
if (us_g_gpio.initialized) {
|
||||||
|
# ifndef HAVE_GPIOD2
|
||||||
gpiod_chip_close(us_g_gpio.chip);
|
gpiod_chip_close(us_g_gpio.chip);
|
||||||
us_g_gpio.chip = NULL;
|
us_g_gpio.chip = NULL;
|
||||||
|
# endif
|
||||||
US_MUTEX_DESTROY(us_g_gpio.mutex);
|
US_MUTEX_DESTROY(us_g_gpio.mutex);
|
||||||
|
us_g_gpio.initialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
|
# ifndef HAVE_GPIOD2
|
||||||
assert(us_g_gpio.chip != NULL);
|
assert(us_g_gpio.chip != NULL);
|
||||||
|
# endif
|
||||||
assert(output->line != NULL);
|
assert(output->line != NULL);
|
||||||
assert(output->state != state); // Must be checked in macro for the performance
|
assert(output->state != state); // Must be checked in macro for the performance
|
||||||
US_MUTEX_LOCK(us_g_gpio.mutex);
|
US_MUTEX_LOCK(us_g_gpio.mutex);
|
||||||
|
|
||||||
if (gpiod_line_set_value(output->line, (int)state) < 0) { \
|
# ifdef HAVE_GPIOD2
|
||||||
US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \
|
if (gpiod_line_request_set_value(output->line, output->pin, state) < 0) {
|
||||||
|
# else
|
||||||
|
if (gpiod_line_set_value(output->line, (int)state) < 0) {
|
||||||
|
# endif
|
||||||
|
US_LOG_PERROR("GPIO: Can't write value %d to line %s", state, output->consumer); \
|
||||||
_gpio_output_destroy(output);
|
_gpio_output_destroy(output);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
@@ -98,14 +116,53 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gpio_output_init(us_gpio_output_s *output) {
|
static void _gpio_output_init(us_gpio_output_s *output, struct gpiod_chip *chip) {
|
||||||
assert(us_g_gpio.chip != NULL);
|
|
||||||
assert(output->line == NULL);
|
assert(output->line == NULL);
|
||||||
|
|
||||||
US_ASPRINTF(output->consumer, "%s::%s", us_g_gpio.consumer_prefix, output->role);
|
US_ASPRINTF(output->consumer, "%s::%s", us_g_gpio.consumer_prefix, output->role);
|
||||||
|
|
||||||
if (output->pin >= 0) {
|
if (output->pin >= 0) {
|
||||||
if ((output->line = gpiod_chip_get_line(us_g_gpio.chip, output->pin)) != NULL) {
|
# ifdef HAVE_GPIOD2
|
||||||
|
struct gpiod_line_settings *line_settings = NULL;
|
||||||
|
struct gpiod_line_config *line_config = NULL;
|
||||||
|
struct gpiod_request_config *request_config = NULL;
|
||||||
|
|
||||||
|
assert(line_settings = gpiod_line_settings_new());
|
||||||
|
if (gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_OUTPUT) < 0) {
|
||||||
|
US_LOG_PERROR("GPIO: Can't set output direction for pin=%d as %s", output->pin, output->consumer);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (gpiod_line_settings_set_output_value(line_settings, false) < 0) {
|
||||||
|
US_LOG_PERROR("GPIO: Can't set default output value for pin=%d as %s", output->pin, output->consumer);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(line_config = gpiod_line_config_new());
|
||||||
|
const unsigned offset = output->pin;
|
||||||
|
if (gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings) < 0) {
|
||||||
|
US_LOG_PERROR("GPIO: Can't set line settings for pin=%d as %s", output->pin, output->consumer);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(request_config = gpiod_request_config_new());
|
||||||
|
gpiod_request_config_set_consumer(request_config, output->consumer);
|
||||||
|
|
||||||
|
if ((output->line = gpiod_chip_request_lines(chip, request_config, line_config)) == NULL) {
|
||||||
|
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
US_DELETE(request_config, gpiod_request_config_free);
|
||||||
|
US_DELETE(line_config, gpiod_line_config_free);
|
||||||
|
US_DELETE(line_settings, gpiod_line_settings_free);
|
||||||
|
if (output->line == NULL) {
|
||||||
|
_gpio_output_destroy(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
if ((output->line = gpiod_chip_get_line(chip, output->pin)) != NULL) {
|
||||||
if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) {
|
if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) {
|
||||||
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
||||||
_gpio_output_destroy(output);
|
_gpio_output_destroy(output);
|
||||||
@@ -113,12 +170,17 @@ static void _gpio_output_init(us_gpio_output_s *output) {
|
|||||||
} else {
|
} else {
|
||||||
US_LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer);
|
US_LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer);
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gpio_output_destroy(us_gpio_output_s *output) {
|
static void _gpio_output_destroy(us_gpio_output_s *output) {
|
||||||
if (output->line != NULL) {
|
if (output->line != NULL) {
|
||||||
|
# ifdef HAVE_GPIOD2
|
||||||
|
gpiod_line_request_release(output->line);
|
||||||
|
# else
|
||||||
gpiod_line_release(output->line);
|
gpiod_line_release(output->line);
|
||||||
|
# endif
|
||||||
output->line = NULL;
|
output->line = NULL;
|
||||||
}
|
}
|
||||||
if (output->consumer != NULL) {
|
if (output->consumer != NULL) {
|
||||||
|
|||||||
@@ -36,11 +36,15 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int pin;
|
int pin;
|
||||||
const char *role;
|
const char *role;
|
||||||
char *consumer;
|
char *consumer;
|
||||||
struct gpiod_line *line;
|
# ifdef HAVE_GPIOD2
|
||||||
bool state;
|
struct gpiod_line_request *line;
|
||||||
|
# else
|
||||||
|
struct gpiod_line *line;
|
||||||
|
# endif
|
||||||
|
bool state;
|
||||||
} us_gpio_output_s;
|
} us_gpio_output_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -52,7 +56,11 @@ typedef struct {
|
|||||||
us_gpio_output_s has_http_clients;
|
us_gpio_output_s has_http_clients;
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
|
# ifndef HAVE_GPIOD2
|
||||||
struct gpiod_chip *chip;
|
struct gpiod_chip *chip;
|
||||||
|
# endif
|
||||||
|
bool initialized;
|
||||||
} us_gpio_s;
|
} us_gpio_s;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user