summaryrefslogtreecommitdiffstats
path: root/libopenbmc_intf
diff options
context:
space:
mode:
authorAnthony Wilson <wilsonan@us.ibm.com>2019-03-06 10:54:58 -0600
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2019-04-10 01:44:48 +0000
commitc0c74e7cca35179a9c4496a49f64e00db4c47870 (patch)
treea4f72ff8f6843da2505f28a5892f618b2223eb06 /libopenbmc_intf
parentc0da84767c00657c0b3b1afff7d9c5c2f1ed5fdb (diff)
downloadtalos-skeleton-c0c74e7cca35179a9c4496a49f64e00db4c47870.tar.gz
talos-skeleton-c0c74e7cca35179a9c4496a49f64e00db4c47870.zip
skeleton: Use ioctl gpio handling
Now that chassiskill is a standalone app and is using ioctl gpio handling (through the gpioplus library), the gpio libraries here need to use ioctl as well for chassiskill to be compatible. Tested: Verified chassiskill works as intended and checked that nothing else broke. Change-Id: I67c431027d31e87c332c3e1771fc2d3423f56652 Signed-off-by: Anthony Wilson <wilsonan@us.ibm.com>
Diffstat (limited to 'libopenbmc_intf')
-rw-r--r--libopenbmc_intf/gpio.c249
-rw-r--r--libopenbmc_intf/gpio.h8
2 files changed, 60 insertions, 197 deletions
diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c
index 33a9ffe..afa0914 100644
--- a/libopenbmc_intf/gpio.c
+++ b/libopenbmc_intf/gpio.c
@@ -14,97 +14,53 @@
#include "gpio.h"
#include "gpio_json.h"
+#include <sys/ioctl.h>
+#include <linux/gpio.h>
+
#define GPIO_PORT_OFFSET 8
#define GPIO_BASE_PATH "/sys/class/gpio"
cJSON* gpio_json = NULL;
-int gpio_writec(GPIO* gpio, char value)
+int gpio_write(GPIO* gpio, uint8_t value)
{
g_assert (gpio != NULL);
- int rc = GPIO_OK;
- char buf[1];
- buf[0] = value;
+ struct gpiohandle_data data;
+ memset(&data, 0, sizeof(data));
+ data.values[0] = value;
- if (lseek(gpio->fd, 0, SEEK_SET) == -1)
+ if (gpio->fd <= 0)
{
return GPIO_ERROR;
}
- if (write(gpio->fd, buf, 1) != 1)
+ if (ioctl(gpio->fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data) < 0)
{
- rc = GPIO_WRITE_ERROR;
+ return GPIO_WRITE_ERROR;
}
- return rc;
+
+ return GPIO_OK;
}
-int gpio_write(GPIO* gpio, uint8_t value)
+int gpio_read(GPIO* gpio, uint8_t *value)
{
g_assert (gpio != NULL);
- int rc = GPIO_OK;
- char buf[1];
- buf[0] = '0';
- if (value==1)
- {
- buf[0]='1';
- }
+ struct gpiohandle_data data;
+ memset(&data, 0, sizeof(data));
- if (lseek(gpio->fd, 0, SEEK_SET) == -1)
+ if (gpio->fd <= 0)
{
return GPIO_ERROR;
}
- if (write(gpio->fd, buf, 1) != 1)
+ if (ioctl(gpio->fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data) < 0)
{
- rc = GPIO_WRITE_ERROR;
+ return GPIO_READ_ERROR;
}
- return rc;
-}
-int gpio_read(GPIO* gpio, uint8_t *value)
-{
- g_assert (gpio != NULL);
- char buf[1];
- int r = GPIO_OK;
- if (gpio->fd <= 0)
- {
- r = GPIO_ERROR;
- }
- else
- {
- if (lseek(gpio->fd, 0, SEEK_SET) == -1)
- {
- return GPIO_ERROR;
- }
+ *value = data.values[0];
- if (read(gpio->fd,&buf,1) != 1)
- {
- r = GPIO_READ_ERROR;
- } else {
- if (buf[0]=='1') {
- *value = 1;
- } else {
- *value = 0;
- }
- }
- }
- return r;
-}
-int gpio_clock_cycle(GPIO* gpio, int num_clks) {
- g_assert (gpio != NULL);
- int i=0;
- int r=GPIO_OK;
- for (i=0;i<num_clks;i++) {
- if (gpio_writec(gpio,'0') == -1) {
- r = GPIO_WRITE_ERROR;
- break;
- }
- if (gpio_writec(gpio,'1') == -1) {
- r = GPIO_WRITE_ERROR;
- break;
- }
- }
- return r;
+ return GPIO_OK;
}
/**
@@ -215,16 +171,6 @@ int get_gpio_base()
*/
int convert_gpio_to_num(const char* gpio)
{
- static int gpio_base = -1;
- if (gpio_base == -1)
- {
- gpio_base = get_gpio_base();
- if (gpio_base < 0)
- {
- return gpio_base;
- }
- }
-
size_t len = strlen(gpio);
if (len < 2)
{
@@ -255,7 +201,7 @@ int convert_gpio_to_num(const char* gpio)
port += 26 * (toupper(gpio[len-3]) - 'A' + 1);
}
- return gpio_base + (port * GPIO_PORT_OFFSET) + offset;
+ return (port * GPIO_PORT_OFFSET) + offset;
}
/**
@@ -351,145 +297,64 @@ int gpio_get_params(GPIO* gpio)
return GPIO_LOOKUP_ERROR;
}
}
+ // TODO: For the purposes of skeleton and the projects that use it,
+ // it should be safe to assume this will always be 0. Eventually skeleton
+ // should be going away, but if the need arises before then this may need
+ // to be updated to handle non-zero cases.
+ gpio->chip_id = 0;
return GPIO_OK;
}
-// Gets the gpio device path from gpio manager object
-int gpio_init(GPIO* gpio)
+int gpio_open(GPIO* gpio, uint8_t default_value)
{
- int rc = gpio_get_params(gpio);
- if (rc != GPIO_OK)
- {
- return rc;
- }
-
- g_print("GPIO Lookup: %s = %d,%s\n",gpio->name,gpio->num,gpio->direction);
-
- //export and set direction
- char dev[254];
- char data[4];
- int fd;
- do {
- struct stat st;
-
- sprintf(dev,"%s/gpio%d/value",gpio->dev,gpio->num);
- //check if gpio is exported, if not export
- int result = stat(dev, &st);
- if (result)
- {
- sprintf(dev,"%s/export",gpio->dev);
- fd = open(dev, O_WRONLY);
- if (fd == GPIO_ERROR) {
- rc = GPIO_OPEN_ERROR;
- break;
- }
- sprintf(data,"%d",gpio->num);
- rc = write(fd,data,strlen(data));
- close(fd);
- if (rc != strlen(data)) {
- rc = GPIO_WRITE_ERROR;
- break;
- }
- }
- const char* file = "edge";
- const char* direction = gpio->direction;
- if (strcmp(direction, "in") == 0)
- {
- file = "direction";
- }
- else if (strcmp(direction, "out") == 0)
- {
- file = "direction";
-
- // Read current value, so we can set 'high' or 'low'.
- // Setting direction directly to 'out' is the same as
- // setting to 'low' which can change the value in the
- // GPIO.
- uint8_t value = 0;
- rc = gpio_open(gpio);
- if (rc) break;
- rc = gpio_read(gpio, &value);
- if (rc) break;
- gpio_close(gpio);
-
- direction = (value ? "high" : "low");
- }
- sprintf(dev,"%s/gpio%d/%s",gpio->dev,gpio->num,file);
- fd = open(dev,O_WRONLY);
- if (fd == GPIO_ERROR) {
- rc = GPIO_WRITE_ERROR;
- break;
- }
- rc = write(fd,direction,strlen(direction));
- if (rc != strlen(direction)) {
- rc = GPIO_WRITE_ERROR;
- break;
- }
-
- close(fd);
- rc = GPIO_OK;
- } while(0);
-
- return rc;
-}
-
-
-
-
-char* get_gpio_dev(GPIO* gpio)
-{
- char* buf;
- asprintf(&buf, "%s/gpio%d/value", gpio->dev, gpio->num);
- return buf;
-}
+ g_assert (gpio != NULL);
-int gpio_open_interrupt(GPIO* gpio, GIOFunc func, gpointer user_data)
-{
- int rc = GPIO_OK;
char buf[255];
- sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
- gpio->fd = open(buf, O_RDONLY | O_NONBLOCK );
- gpio->irq_inited = false;
+ sprintf(buf, "/dev/gpiochip%d", gpio->chip_id);
+ gpio->fd = open(buf, 0);
if (gpio->fd == -1)
{
- rc = GPIO_OPEN_ERROR;
- }
- else
- {
- GIOChannel* channel = g_io_channel_unix_new( gpio->fd);
- guint id = g_io_add_watch( channel, G_IO_PRI, func, user_data );
+ return GPIO_OPEN_ERROR;
}
- return rc;
-}
-int gpio_open(GPIO* gpio)
-{
- g_assert (gpio != NULL);
+ struct gpiohandle_request req;
+ memset(&req, 0, sizeof(req));
+ strncpy(req.consumer_label, "skeleton-gpio", sizeof(req.consumer_label));
+
// open gpio for writing or reading
- char buf[254];
- int rc = 0;
- gpio->fd = -1;
- if (gpio->direction == NULL) {
+ if (gpio->direction == NULL)
+ {
+ gpio_close(gpio);
return GPIO_OPEN_ERROR;
}
- if (strcmp(gpio->direction,"in")==0)
+ req.flags = (strcmp(gpio->direction,"in") == 0) ? GPIOHANDLE_REQUEST_INPUT
+ : GPIOHANDLE_REQUEST_OUTPUT;
+
+ req.lineoffsets[0] = gpio->num;
+ req.lines = 1;
+
+ if (strcmp(gpio->direction,"out") == 0)
{
- sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
- gpio->fd = open(buf, O_RDONLY);
+ req.default_values[0] = default_value;
}
- else
- {
- sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
- gpio->fd = open(buf, O_RDWR);
- }
- if (gpio->fd == -1) {
+ int rc = ioctl(gpio->fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
+ if (rc < 0)
+ {
+ gpio_close(gpio);
return GPIO_OPEN_ERROR;
}
+ gpio_close(gpio);
+ gpio->fd = req.fd;
+
return GPIO_OK;
}
void gpio_close(GPIO* gpio)
{
+ if(gpio->fd < 0)
+ return;
+
close(gpio->fd);
+ gpio->fd = -1;
}
diff --git a/libopenbmc_intf/gpio.h b/libopenbmc_intf/gpio.h
index dc439c8..54ff6af 100644
--- a/libopenbmc_intf/gpio.h
+++ b/libopenbmc_intf/gpio.h
@@ -9,6 +9,7 @@ typedef struct {
gchar* name;
gchar* dev;
uint16_t num;
+ uint16_t chip_id;
gchar* direction;
int fd;
bool irq_inited;
@@ -24,13 +25,10 @@ typedef struct {
#define GPIO_WRITE_ERROR 0x10
#define GPIO_LOOKUP_ERROR 0x20
-int gpio_init(GPIO*);
void gpio_close(GPIO*);
-int gpio_open(GPIO*);
-int gpio_open_interrupt(GPIO*, GIOFunc, gpointer);
+int gpio_open(GPIO*, uint8_t);
int gpio_write(GPIO*, uint8_t);
-int gpio_writec(GPIO*, char);
-int gpio_clock_cycle(GPIO*, int);
+int gpio_get_params(GPIO*);
int gpio_read(GPIO*,uint8_t*);
void gpio_inits_done();
OpenPOWER on IntegriCloud