diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2015-02-23 13:02:39 +0100 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2015-04-17 01:10:17 +0200 |
commit | 3bb41226e0941b86d58ecb97f7d292677de573c8 (patch) | |
tree | 907aa270343f7c6d1bc08bf73288fb9b10da6197 /c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c | |
parent | LEON: added network device configuration helper function (diff) | |
download | rtems-3bb41226e0941b86d58ecb97f7d292677de573c8.tar.bz2 |
LEON: added new drivers to the LEON2/LEON3 BSPs
Most drivers use the Driver Manager for device probing, they
work on AMBA-over-PCI systems if PCI is big-endian.
New APIs:
* GPIO Library, interfaced to GRGPIO
* GENIRQ, Generic interrupt service implementation helper
New GRLIB Drivers:
* ACTEL 1553 RT, user interface is similar to 1553 BRM driver
* GR1553 (1553 BC, RT and BM core)
* AHBSTAT (AHB error status core)
* GRADCDAC (Core interfacing to ADC/DAC hardware)
* GRGPIO (GPIO port accessed from GPIO Library)
* MCTRL (Memory controller settings configuration)
* GRETH (10/100/1000 Ethernet driver using Driver manager)
* GRPWM (Pulse Width Modulation core)
* SPICTRL (SPI master interface)
* GRSPW_ROUTER (SpaceWire Router AMBA configuration interface)
* GRCTM (SpaceCraft on-board Time Management core)
* SPWCUC (Time distribution over SpaceWire)
* GRTC (SpaceCraft up-link Tele core)
* GRTM (SpaceCraft down-link Tele Metry core)
GR712RC ASIC specific interfaces:
* GRASCS
* CANMUX (select between OCCAN and SATCAN)
* SATCAN
* SLINK
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c b/c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c new file mode 100644 index 0000000000..22f1baa5f3 --- /dev/null +++ b/c/src/lib/libbsp/sparc/shared/gpio/gpiolib.c @@ -0,0 +1,265 @@ +/* GPIOLIB interface implementation + * + * COPYRIGHT (c) 2009. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <gpiolib.h> + +struct gpiolib_port; + +struct gpiolib_port { + struct gpiolib_port *next; + int minor; + struct gpiolib_drv *drv; + void *handle; + + int open; +}; + +/* Root of GPIO Ports */ +struct gpiolib_port *gpiolib_ports; + +/* Number of GPIO ports registered */ +static int port_nr; + +/* 1 if libraray initialized */ +static int gpiolib_initied = 0; + +/* Insert a port first in ports list */ +void gpiolib_list_add(struct gpiolib_port *port) +{ + port->next = gpiolib_ports; + gpiolib_ports = port; +} + +struct gpiolib_port *gpiolib_find(int minor) +{ + struct gpiolib_port *p; + + p = gpiolib_ports; + while ( p && (p->minor != minor) ) { + p = p->next; + } + return p; +} + +struct gpiolib_port *gpiolib_find_by_name(char *name) +{ + struct gpiolib_port *p; + struct gpiolib_info info; + int (*get_info)(void *, struct gpiolib_info *); + + p = gpiolib_ports; + while ( p ) { + get_info = p->drv->ops->get_info; + if ( get_info && (get_info(p->handle, &info) == 0) ) { + if ( strncmp(name, (char *)&info.devName[0], 64) == 0 ) { + break; + } + } + p = p->next; + } + return p; +} + +void gpiolib_list_remove(struct gpiolib_port *port) +{ + +} + +int gpiolib_drv_register(struct gpiolib_drv *drv, void *handle) +{ + struct gpiolib_port *port; + + if ( !drv || !drv->ops ) + return -1; + + port = malloc(sizeof(*port)); + if ( port == NULL ) + return -1; + + memset(port, 0, sizeof(*port)); + port->handle = handle; + port->minor = port_nr++; + port->drv = drv; + + gpiolib_list_add(port); + + return 0; +} + +void gpiolib_show(int port, void *handle) +{ + struct gpiolib_port *p; + + if ( port == -1 ) { + p = gpiolib_ports; + while (p != NULL) { + if ( p->drv->ops->show ) + p->drv->ops->show(p->handle); + p = p->next; + } + } else { + if ( handle ) { + p = handle; + } else { + p = gpiolib_find(port); + } + if ( p == NULL ) { + printf("PORT %d NOT FOUND\n", port); + return; + } + if ( p->drv->ops->show ) + p->drv->ops->show(p->handle); + } +} + +void *gpiolib_open_internal(int port, char *devName) +{ + struct gpiolib_port *p; + + if ( gpiolib_initied == 0 ) + return NULL; + + /* Find */ + if ( port >= 0 ) { + p = gpiolib_find(port); + } else { + p = gpiolib_find_by_name(devName); + } + if ( p == NULL ) + return NULL; + + if ( p->open ) + return NULL; + + p->open = 1; + return p; +} + +void *gpiolib_open(int port) +{ + return gpiolib_open_internal(port, NULL); +} + +void *gpiolib_open_by_name(char *devName) +{ + return gpiolib_open_internal(-1, devName); +} + +void gpiolib_close(void *handle) +{ + struct gpiolib_port *p = handle; + + if ( p && p->open ) { + p->open = 0; + } +} + +int gpiolib_set_config(void *handle, struct gpiolib_config *cfg) +{ + struct gpiolib_port *port = handle; + + if ( !port || !cfg ) + return -1; + + if ( !port->drv->ops->config ) + return -1; + + return port->drv->ops->config(port->handle, cfg); +} + +int gpiolib_set(void *handle, int dir, int outval) +{ + struct gpiolib_port *port = handle; + + if ( !port ) + return -1; + + if ( !port->drv->ops->set ) + return -1; + + return port->drv->ops->set(port->handle, dir, outval); +} + +int gpiolib_get(void *handle, int *inval) +{ + struct gpiolib_port *port = handle; + + if ( !port || !inval) + return -1; + + if ( !port->drv->ops->get ) + return -1; + + return port->drv->ops->get(port->handle, inval); +} + +/*** IRQ Functions ***/ +int gpiolib_irq_register(void *handle, void *func, void *arg) +{ + struct gpiolib_port *port = handle; + + if ( !port ) + return -1; + + if ( !port->drv->ops->irq_register ) + return -1; + + return port->drv->ops->irq_register(port->handle, func, arg); +} + +int gpiolib_irq_opts(void *handle, unsigned int options) +{ + struct gpiolib_port *port = handle; + + if ( !port ) + return -1; + + if ( !port->drv->ops->irq_opts ) + return -1; + + return port->drv->ops->irq_opts(port->handle, options); +} + +int gpiolib_irq_clear(void *handle) +{ + return gpiolib_irq_opts(handle, GPIOLIB_IRQ_CLEAR); +} + +int gpiolib_irq_force(void *handle) +{ + return gpiolib_irq_opts(handle, GPIOLIB_IRQ_FORCE); +} + +int gpiolib_irq_enable(void *handle) +{ + return gpiolib_irq_opts(handle, GPIOLIB_IRQ_ENABLE); +} + +int gpiolib_irq_disable(void *handle) +{ + return gpiolib_irq_opts(handle, GPIOLIB_IRQ_DISABLE); +} + +/*** Initialization ***/ +int gpiolib_initialize(void) +{ + if ( gpiolib_initied != 0 ) + return 0; + + /* Initialize Libarary */ + port_nr = 0; + gpiolib_ports = 0; + gpiolib_initied = 1; + return 0; +} |