98 lines
1.8 KiB
C
98 lines
1.8 KiB
C
#include <common.h>
|
|
#include <asm/gpio.h>
|
|
#include <stdlib.h>
|
|
#include "nbhw_gpio.h"
|
|
|
|
struct gpio_node {
|
|
struct gpio_node* next;
|
|
struct gpio_desc desc;
|
|
const char* name;
|
|
int is_output;
|
|
};
|
|
|
|
static struct gpio_node* gl = NULL;
|
|
|
|
static struct gpio_desc* lookup_gpio(const char* gpio_name, int is_output) {
|
|
struct gpio_node* cur = gl;
|
|
|
|
while (cur) {
|
|
if ((strcmp(gpio_name, cur->name)==0) &&
|
|
(is_output == cur->is_output)) {
|
|
return &(cur->desc);
|
|
}
|
|
cur = cur->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static struct gpio_desc* acquire_gpio(const char* gpio_name, int is_output) {
|
|
struct gpio_node* gn = 0;
|
|
int node;
|
|
|
|
/* Check, if we already requested this gpio */
|
|
struct gpio_desc* desc = lookup_gpio(gpio_name, is_output);
|
|
|
|
if (desc) return desc;
|
|
|
|
/* If we do not have it try to request it now. */
|
|
node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "nm,gpios");
|
|
if (node < 0) {
|
|
goto abort;
|
|
}
|
|
|
|
gn = (struct gpio_node*)malloc(sizeof(struct gpio_node));
|
|
if (!gn) goto abort;
|
|
|
|
if (gpio_request_by_name_nodev(offset_to_ofnode(node), gpio_name, 0, &(gn->desc), is_output ? GPIOD_IS_OUT : GPIOD_IS_IN) < 0) {
|
|
goto abort;
|
|
}
|
|
|
|
gn->name = gpio_name;
|
|
gn->is_output = is_output;
|
|
gn->next = gl;
|
|
gl = gn;
|
|
|
|
desc = &(gn->desc);
|
|
|
|
return desc;
|
|
|
|
abort:
|
|
if (gn) free(gn);
|
|
printk("Could not acquire gpio %s as %s!\n", gpio_name, is_output ? "output" : "input");
|
|
return 0;
|
|
}
|
|
|
|
int get_gpio(const char* gpio_name)
|
|
{
|
|
struct gpio_desc* d;
|
|
int res;
|
|
|
|
d = acquire_gpio(gpio_name, 0);
|
|
if (!d) goto abort;
|
|
|
|
res = dm_gpio_get_value(d);
|
|
|
|
return res;
|
|
|
|
abort:
|
|
printf("Could not set gpio %s!\n", gpio_name);
|
|
return -1;
|
|
}
|
|
|
|
int set_gpio(const char* gpio_name, int value)
|
|
{
|
|
struct gpio_desc* d;
|
|
|
|
d = acquire_gpio(gpio_name, 1);
|
|
if (!d) goto abort;
|
|
|
|
dm_gpio_set_value(d, value);
|
|
|
|
return 0;
|
|
|
|
abort:
|
|
printf("Could not set gpio %s!\n", gpio_name);
|
|
return -1;
|
|
}
|
|
|