Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********************************************************************
- * Description: sunxi_gpio.c
- * Driver for the sunxi GPIO pins
- ********************************************************************/
- #include "rtapi.h" /* RTAPI realtime OS API */
- #include "rtapi_bitops.h"
- #include "rtapi_app.h" /* RTAPI realtime module decls */
- /* this also includes config.h */
- #include "hal.h" /* HAL public API decls */
- #if !defined(BUILD_SYS_USER_DSO)
- #error "This driver is for usermode threads only"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <errno.h>
- /* Allwinner A1X port mode numbers */
- #define SUNXI_GPIO_G 6
- /* PIO data registers */
- #define PIO_PG_DATA_OFFSET (SUNXI_GPIO_G * 0x24) + 0x10
- /* Allwinner A1X gpio mode numbers */
- #define SUNXI_GPIO_INPUT 0
- #define SUNXI_GPIO_OUTPUT 1
- /* PIO controller defines */
- #define PIO_BASE_ADDRESS SW_PA_PORTC_IO_BASE
- #define PIO_RANGE_SIZE (0x400)
- /* Set GPIO pin mode (input, output, etc) */
- /* GPIO port has 4 cfg 32bit registers (8 pins each) */
- /* First port cfg register addr = port_num * 0x24 */
- #define SUNXI_SET_GPIO_MODE(addr, port, pin, mode) ({ \
- __u32 reg_val = 0; \
- __u32 pin_idx = pin >> 3; \
- void *raddr = addr + (((port)-1)*0x24 + ((pin_idx)<<2) + 0x00); \
- reg_val = readl(raddr); \
- reg_val &= ~(0x07 << (((pin - (pin_idx<<3))<<2))); \
- reg_val |= mode << (((pin - (pin_idx<<3))<<2)); \
- writel(reg_val, raddr); \
- })
- static unsigned int mmap_Base = 0;
- static unsigned char rev1_gpios[] = {0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25};
- static unsigned char rev1_pins[] = {3, 5, 7, 26, 24, 21, 19, 23, 8, 10, 11, 12, 13, 15, 16, 18, 22};
- static int npins;
- static int mem_fd;
- // I/O access
- volatile unsigned *gpio;
- MODULE_AUTHOR("uMinded");
- MODULE_DESCRIPTION("Driver for sunxi GPIO pins");
- MODULE_LICENSE("GPL");
- // port direction bits, 1=output
- static char *dir = "-1"; // all output
- RTAPI_MP_STRING(dir, "port direction, 1=output");
- static unsigned dir_map;
- // exclude pins from usage
- static char *exclude = "0"; // all used
- RTAPI_MP_STRING(exclude, "exclude pins, 1=dont use");
- static unsigned exclude_map;
- static int comp_id; /* component ID */
- static unsigned char *pins, *gpios;
- hal_bit_t **port_data;
- static void write_port(void *arg, long period);
- static void read_port(void *arg, long period);
- int init_base(unsigned long port_base)
- {
- int fd;
- unsigned int addr_start, addr_offset, addr;
- unsigned int PageSize, PageMask;
- void* address;
- fd = open("/dev/mem", O_RDWR);
- if(fd < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: /dev/mem failed: %d - %s\n", errno, strerror(errno));
- return -ENOMEM;;
- }
- PageSize = sysconf(_SC_PAGESIZE);
- PageMask = (~(PageSize-1));
- addr_start = port_base & PageMask;
- addr_offset = port_base & ~PageMask;
- address = (void*)mmap(0, PageSize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr_start);
- if(address == MAP_FAILED) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: mmap failed: %d - %s\n", errno, strerror(errno));
- return -ENOMEM;;
- }
- mmap_Base = (unsigned int)address;
- mmap_Base += addr_offset;
- close(fd);
- return 0;
- }
- int rtapi_app_main(void) {
- // __iomem *GADDR = ioremap(PIO_BASE_ADDRESS, PIO_RANGE_SIZE);
- int n, retval = 0;
- int rev, pinno;
- char *endptr;
- pins = rev1_pins;
- gpios = rev1_gpios;
- npins = sizeof(rev1_pins);
- if( init_base(PIO_BASE_ADDRESS) ) {
- printf("init_base(SUNXI_TIMER_BASE) ERROR\n");
- exit(-1);
- }
- port_data = hal_malloc(npins * sizeof(void *));
- if (port_data == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
- if (dir == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: no config string\n");
- return -1;
- }
- dir_map = strtoul(dir, &endptr, 0);
- if (*endptr) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: dir=%s - trailing garbage: '%s'\n", dir, endptr);
- return -1;
- }
- if (exclude == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: no exclude string\n");
- return -1;
- }
- exclude_map = strtoul(exclude, &endptr,0);
- if (*endptr) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: exclude=%s - trailing garbage: '%s'\n", exclude, endptr);
- return -1;
- }
- /*
- * Set Up the HAL component structure
- */
- comp_id = hal_init("sunxi_gpio");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: hal_init() failed\n");
- return -1;
- }
- SUNXI_SET_GPIO_MODE(mmap_Base, SUNXI_GPIO_G, 9, SUNXI_GPIO_OUTPUT);
- if ((retval = hal_pin_bit_newf(HAL_IN, &port_data[n], comp_id, "sunxi_gpio.pin-%02d-out", pinno)) < 0)
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: pin %d export failed with err=%i\n", n,retval);
- hal_exit(comp_id);
- return -1;
- }
- retval = hal_export_funct("sunxi_gpio.write", hal_write_port, 0, 0, 0, comp_id);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: write funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO, "SUNXI_GPIO: installed driver\n");
- hal_ready(comp_id);
- return 0;
- }
- void rtapi_app_exit(void)
- {
- //iounmap(GADDR);
- hal_exit(comp_id);
- }
- static void hal_write_port(void *arg, long period)
- {
- int value;
- value = atoi(arg);
- if (value > 0) {
- write_port(PIO_PG_DATA_OFFSET, (1<<9));
- }
- if (value <= 0) {
- write_port(PIO_PG_DATA_OFFSET, (0<<9));
- }
- }
- void write_port(unsigned int port_offset, unsigned int port_data)
- {
- *(unsigned int*)(mmap_Base + port_offset) = port_data;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement