gpio: Add gpio chardev interface
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:
committed by
Brendan Le Foll
parent
aa7006cce9
commit
1665e09928
@@ -61,7 +61,10 @@ typedef enum {
|
||||
MRAA_GPIO_STRONG = 0, /**< Default. Strong high and low */
|
||||
MRAA_GPIO_PULLUP = 1, /**< Resistive High */
|
||||
MRAA_GPIO_PULLDOWN = 2, /**< Resistive Low */
|
||||
MRAA_GPIO_HIZ = 3 /**< High Z State */
|
||||
MRAA_GPIO_HIZ = 3, /**< High Z State */
|
||||
MRAA_GPIOD_ACTIVE_LOW = 4,
|
||||
MRAA_GPIOD_OPEN_DRAIN = 5,
|
||||
MRAA_GPIOD_OPEN_SOURCE = 6,
|
||||
} mraa_gpio_mode_t;
|
||||
|
||||
/**
|
||||
@@ -109,6 +112,8 @@ typedef enum {
|
||||
*/
|
||||
mraa_gpio_context mraa_gpio_init(int pin);
|
||||
|
||||
mraa_gpio_context mraa_gpio_init_multiple(int pins[], int num_pins);
|
||||
|
||||
/**
|
||||
* Initialise gpio context without any mapping to a pin
|
||||
*
|
||||
@@ -126,6 +131,8 @@ mraa_gpio_context mraa_gpio_init_raw(int gpiopin);
|
||||
*/
|
||||
mraa_result_t mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode);
|
||||
|
||||
mraa_result_t mraa_gpio_edge_mode_multiple(mraa_gpio_context dev, mraa_gpio_edge_t mode);
|
||||
|
||||
/**
|
||||
* Set an interrupt on pin
|
||||
*
|
||||
@@ -138,6 +145,8 @@ mraa_result_t mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode);
|
||||
*/
|
||||
mraa_result_t mraa_gpio_isr(mraa_gpio_context dev, mraa_gpio_edge_t edge, void (*fptr)(void*), void* args);
|
||||
|
||||
mraa_result_t mraa_gpio_isr_multiple(mraa_gpio_context dev, mraa_gpio_edge_t edge, void (*fptr)(void*), void* args);
|
||||
|
||||
/**
|
||||
* Stop the current interrupt watcher on this Gpio, and set the Gpio edge mode
|
||||
* to MRAA_GPIO_EDGE_NONE
|
||||
@@ -165,6 +174,8 @@ mraa_result_t mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode);
|
||||
*/
|
||||
mraa_result_t mraa_gpio_dir(mraa_gpio_context dev, mraa_gpio_dir_t dir);
|
||||
|
||||
mraa_result_t mraa_gpio_dir_multiple(mraa_gpio_context dev, mraa_gpio_dir_t dir);
|
||||
|
||||
/**
|
||||
* Read Gpio direction
|
||||
*
|
||||
@@ -183,6 +194,8 @@ mraa_result_t mraa_gpio_read_dir(mraa_gpio_context dev, mraa_gpio_dir_t *dir);
|
||||
*/
|
||||
mraa_result_t mraa_gpio_close(mraa_gpio_context dev);
|
||||
|
||||
mraa_result_t mraa_gpio_close_multiple(mraa_gpio_context dev);
|
||||
|
||||
/**
|
||||
* Read the Gpio value. This can be 0 or 1. A resonse of -1 means that there
|
||||
* was a fatal error.
|
||||
@@ -192,6 +205,11 @@ mraa_result_t mraa_gpio_close(mraa_gpio_context dev);
|
||||
*/
|
||||
int mraa_gpio_read(mraa_gpio_context dev);
|
||||
|
||||
/* Values array is provided by user. Must be the same size as the array passed in init.
|
||||
* It will be overwritten with the read results.
|
||||
*/
|
||||
mraa_result_t mraa_gpio_read_multiple(mraa_gpio_context dev, int output_values[]);
|
||||
|
||||
/**
|
||||
* Write to the Gpio Value.
|
||||
*
|
||||
@@ -201,6 +219,8 @@ int mraa_gpio_read(mraa_gpio_context dev);
|
||||
*/
|
||||
mraa_result_t mraa_gpio_write(mraa_gpio_context dev, int value);
|
||||
|
||||
mraa_result_t mraa_gpio_write_multiple(mraa_gpio_context dev, int input_values[]);
|
||||
|
||||
/**
|
||||
* Change ownership of the context.
|
||||
*
|
||||
|
||||
@@ -106,6 +106,26 @@ struct _firmata {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct _gpio_group {
|
||||
int is_required;
|
||||
int dev_fd;
|
||||
int gpiod_handle;
|
||||
unsigned int gpio_chip;
|
||||
/* We can have multiple lines in a gpio group. */
|
||||
unsigned int num_gpio_lines;
|
||||
unsigned int *gpio_lines;
|
||||
|
||||
/* R/W stuff.*/
|
||||
unsigned char *rw_values;
|
||||
/* Reverse mapping to original pin number indexes. */
|
||||
unsigned int *gpio_group_to_pins_table;
|
||||
|
||||
unsigned int flags;
|
||||
|
||||
/* Event specific fields. */
|
||||
int *event_handles;
|
||||
};
|
||||
|
||||
/**
|
||||
* A structure representing a gpio pin.
|
||||
*/
|
||||
@@ -134,8 +154,30 @@ struct _gpio {
|
||||
#ifdef PERIPHERALMAN
|
||||
AGpio *bgpio;
|
||||
#endif
|
||||
|
||||
/* TODO: The below members should be integrated in gpio_group struct. */
|
||||
int dev_fd;
|
||||
int gpiod_handle;
|
||||
unsigned int gpio_chip;
|
||||
unsigned int gpio_line;
|
||||
|
||||
/* Multiple gpio support. These members are treated separately for now until multiple gpio support is accepted. */
|
||||
unsigned int num_chips;
|
||||
struct _gpio_group *gpio_group;
|
||||
/* Pin index passed by the user to gpio_group structures. */
|
||||
int *pin_to_gpio_table;
|
||||
unsigned int num_pins;
|
||||
|
||||
struct _gpio *next;
|
||||
};
|
||||
|
||||
/* Macro for looping over gpio chips. */
|
||||
#define for_each_gpio_group(group, dev) \
|
||||
for (int k = 0; \
|
||||
k < dev->num_chips && (group = &dev->gpio_group[k]); \
|
||||
++k) \
|
||||
if (dev->gpio_group[k].is_required)
|
||||
|
||||
/**
|
||||
* A structure representing a I2C bus
|
||||
*/
|
||||
@@ -315,6 +357,10 @@ typedef struct {
|
||||
mraa_mux_t mux[6]; /** Array holding information about mux */
|
||||
unsigned int output_enable; /** Output Enable GPIO, for level shifting */
|
||||
mraa_pin_cap_complex_t complex_cap;
|
||||
|
||||
/* GPIOD_INTERFACE */
|
||||
unsigned int gpio_chip;
|
||||
unsigned int gpio_line;
|
||||
/*@}*/
|
||||
} mraa_pin_t;
|
||||
|
||||
@@ -447,6 +493,7 @@ typedef struct _board_t {
|
||||
mraa_pininfo_t* pins; /**< Pointer to pin array */
|
||||
mraa_adv_func_t* adv_func; /**< Pointer to advanced function disptach table */
|
||||
struct _board_t* sub_platform; /**< Pointer to sub platform */
|
||||
mraa_boolean_t chardev_capable; /**< Decide what interface is being used: old sysfs or new char device*/
|
||||
/*@}*/
|
||||
} mraa_board_t;
|
||||
|
||||
|
||||
1587
src/gpio/gpio.c
1587
src/gpio/gpio.c
File diff suppressed because it is too large
Load Diff
58
src/mraa.c
58
src/mraa.c
@@ -45,7 +45,7 @@
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#if defined(IMRAA)
|
||||
#include <json-c/json.h>
|
||||
@@ -98,6 +98,57 @@ mraa_set_log_level(int level)
|
||||
return MRAA_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO: Add all relevant checks here and return the overall result. */
|
||||
mraa_boolean_t mraa_is_platform_chardev_interface_capable()
|
||||
{
|
||||
return mraa_is_kernel_chardev_interface_compatible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whilst the actual mraa init function is now called imraa_init, it's only
|
||||
* callable externally if IMRAA is enabled
|
||||
@@ -218,6 +269,11 @@ imraa_init()
|
||||
return MRAA_ERROR_NO_RESOURCES;
|
||||
}
|
||||
|
||||
plat->chardev_capable = mraa_is_platform_chardev_interface_capable();
|
||||
if (plat->chardev_capable) {
|
||||
syslog(LOG_NOTICE, "libmraa: support for chardev interface is activated");
|
||||
}
|
||||
|
||||
syslog(LOG_NOTICE, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), mraa_get_platform_type());
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user