gpio: chardev interface / multiple gpio support for sysfs
Signed-off-by: Mihai Stefanescu <mihai.t.gh.stefanescu@gmail.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
1299
src/gpio/gpio.c
1299
src/gpio/gpio.c
File diff suppressed because it is too large
Load Diff
@@ -50,38 +50,74 @@
|
||||
void
|
||||
_mraa_free_gpio_groups(mraa_gpio_context dev)
|
||||
{
|
||||
mraa_gpiod_group_t gpio_group = dev->gpio_group;
|
||||
mraa_gpiod_group_t gpio_iter;
|
||||
|
||||
for (int i = 0; i < dev->num_chips; ++i) {
|
||||
if (gpio_group[i].is_required) {
|
||||
free(gpio_group[i].gpio_lines);
|
||||
free(gpio_group[i].rw_values);
|
||||
free(gpio_group[i].gpio_group_to_pins_table);
|
||||
for_each_gpio_group(gpio_iter, dev) {
|
||||
free(gpio_iter->gpio_lines);
|
||||
free(gpio_iter->rw_values);
|
||||
free(gpio_iter->gpio_group_to_pins_table);
|
||||
|
||||
if (gpio_group[i].gpiod_handle != -1) {
|
||||
close(gpio_group[i].gpiod_handle);
|
||||
}
|
||||
|
||||
if (gpio_group[i].event_handles != NULL) {
|
||||
for (int j = 0; j < gpio_group[i].num_gpio_lines; ++j) {
|
||||
close(gpio_group[i].event_handles[j]);
|
||||
}
|
||||
|
||||
free(gpio_group[i].event_handles);
|
||||
}
|
||||
|
||||
close(gpio_group[i].dev_fd);
|
||||
if (gpio_iter->gpiod_handle != -1) {
|
||||
close(gpio_iter->gpiod_handle);
|
||||
}
|
||||
|
||||
if (gpio_iter->event_handles != NULL) {
|
||||
for (int j = 0; j < gpio_iter->num_gpio_lines; ++j) {
|
||||
close(gpio_iter->event_handles[j]);
|
||||
}
|
||||
|
||||
free(gpio_iter->event_handles);
|
||||
}
|
||||
|
||||
close(gpio_iter->dev_fd);
|
||||
}
|
||||
|
||||
free(gpio_group);
|
||||
free(dev->gpio_group);
|
||||
|
||||
/* Also delete the pin to gpio chip mapping. */
|
||||
free(dev->pin_to_gpio_table);
|
||||
|
||||
/* User provided array saved internally. */
|
||||
free(dev->provided_pins);
|
||||
|
||||
/* Finally, delete event array. */
|
||||
free(dev->events);
|
||||
}
|
||||
|
||||
void
|
||||
_mraa_close_gpio_event_handles(mraa_gpio_context dev)
|
||||
{
|
||||
mraa_gpiod_group_t gpio_iter;
|
||||
|
||||
for_each_gpio_group(gpio_iter, dev) {
|
||||
if (gpio_iter->event_handles != NULL) {
|
||||
for (int j = 0; j < gpio_iter->num_gpio_lines; ++j) {
|
||||
close(gpio_iter->event_handles[j]);
|
||||
}
|
||||
|
||||
free(gpio_iter->event_handles);
|
||||
|
||||
/* In the end, _mraa_free_gpio_groups will be called. */
|
||||
gpio_iter->event_handles = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_mraa_close_gpio_desc(mraa_gpio_context dev)
|
||||
{
|
||||
mraa_gpiod_group_t gpio_iter;
|
||||
|
||||
for_each_gpio_group(gpio_iter, dev) {
|
||||
if (gpio_iter->gpiod_handle != -1) {
|
||||
close(gpio_iter->gpiod_handle);
|
||||
gpio_iter->gpiod_handle = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_mraa__mraa_gpiod_ioctl(int fd, unsigned long gpio_request, void* data)
|
||||
_mraa_gpiod_ioctl(int fd, unsigned long gpio_request, void* data)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -319,6 +355,37 @@ mraa_get_line_values(int line_handle, unsigned int num_lines, unsigned char outp
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
mraa_boolean_t
|
||||
mraa_is_gpio_line_kernel_owned(mraa_gpiod_line_info *linfo)
|
||||
{
|
||||
return (linfo->flags & GPIOLINE_FLAG_IS_OUT);
|
||||
}
|
||||
|
||||
mraa_boolean_t
|
||||
mraa_is_gpio_line_dir_out(mraa_gpiod_line_info *linfo)
|
||||
{
|
||||
return (linfo->flags & GPIOLINE_FLAG_IS_OUT);
|
||||
}
|
||||
|
||||
mraa_boolean_t
|
||||
mraa_is_gpio_line_active_low(mraa_gpiod_line_info *linfo)
|
||||
{
|
||||
return (linfo->flags & GPIOLINE_FLAG_ACTIVE_LOW);
|
||||
}
|
||||
|
||||
mraa_boolean_t
|
||||
mraa_is_gpio_line_open_drain(mraa_gpiod_line_info *linfo)
|
||||
{
|
||||
return (linfo->flags & GPIOLINE_FLAG_OPEN_DRAIN);
|
||||
}
|
||||
|
||||
mraa_boolean_t
|
||||
mraa_is_gpio_line_open_source(mraa_gpiod_line_info *linfo)
|
||||
{
|
||||
return (linfo->flags & GPIOHANDLE_REQUEST_OPEN_SOURCE);
|
||||
}
|
||||
|
||||
int
|
||||
mraa_get_number_of_gpio_chips()
|
||||
{
|
||||
@@ -343,4 +410,3 @@ mraa_get_number_of_gpio_chips()
|
||||
/* Assume opendir() error. */
|
||||
return num_chips;
|
||||
}
|
||||
|
||||
|
||||
39
src/mraa.c
39
src/mraa.c
@@ -57,6 +57,7 @@
|
||||
#include "firmata/firmata_mraa.h"
|
||||
#include "grovepi/grovepi.h"
|
||||
#include "gpio.h"
|
||||
#include "gpio/gpio_chardev.h"
|
||||
#include "version.h"
|
||||
#include "i2c.h"
|
||||
#include "pwm.h"
|
||||
@@ -100,43 +101,7 @@ mraa_set_log_level(int level)
|
||||
|
||||
mraa_boolean_t mraa_is_kernel_chardev_interface_compatible()
|
||||
{
|
||||
struct utsname buf;
|
||||
int status;
|
||||
|
||||
status = uname(&buf);
|
||||
|
||||
if (status) {
|
||||
syslog(LOG_ERR, "uname() error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int major, minor;
|
||||
char *token;
|
||||
|
||||
token = strtok(buf.release, ".");
|
||||
if (token == NULL) {
|
||||
syslog(LOG_ERR, "Could not find kernel version major number");
|
||||
return 0;
|
||||
}
|
||||
status = mraa_atoi(token, &major);
|
||||
if (status) {
|
||||
syslog(LOG_ERR, "mraa_atoi() error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = strtok(NULL, ".");
|
||||
if (token == NULL) {
|
||||
syslog(LOG_ERR, "Could not find kernel version minor number");
|
||||
return 0;
|
||||
}
|
||||
status = mraa_atoi(token, &minor);
|
||||
if (status) {
|
||||
syslog(LOG_ERR, "mraa_atoi() error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (major < 4 || minor < 8) {
|
||||
syslog(LOG_ERR, "Kernel version %i.%i not supported for chardev interface. Need version 4.8 or newer!", major, minor);
|
||||
if (mraa_get_number_of_gpio_chips() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user