Advertisement
Guest User

Untitled

a guest
Mar 17th, 2013
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.43 KB | None | 0 0
  1. /********************************************************************
  2. * Description:  sunxi_gpio.c
  3. *               Driver for the sunxi GPIO pins
  4. ********************************************************************/
  5.  
  6. #include "rtapi.h"         /* RTAPI realtime OS API */
  7. #include "rtapi_bitops.h"  
  8. #include "rtapi_app.h"     /* RTAPI realtime module decls */
  9.                            /* this also includes config.h */
  10. #include "hal.h"           /* HAL public API decls */
  11.  
  12. #if !defined(BUILD_SYS_USER_DSO)
  13. #error "This driver is for usermode threads only"
  14. #endif
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <fcntl.h>
  19. #include <sys/mman.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <unistd.h>
  23. #include <errno.h>
  24.  
  25. /* Allwinner A1X port mode numbers */
  26. #define SUN5I_GPIO_A    0
  27. #define SUN5I_GPIO_B    1
  28. #define SUN5I_GPIO_C    2
  29. #define SUN5I_GPIO_D    3
  30. #define SUN5I_GPIO_E    4
  31. #define SUN5I_GPIO_F    5
  32. #define SUN5I_GPIO_G    6
  33. #define SUN5I_GPIO_H    7
  34. #define SUN5I_GPIO_I    8
  35.  
  36. /* PA registers */
  37. #define SUN5I_PA_CFG0(n)    ((n * 0x24) + 0x00)
  38. #define SUN5I_PA_CFG1(n)    ((n * 0x24) + 0x04)
  39. #define SUN5I_PA_CFG2(n)    ((n * 0x24) + 0x08)
  40. #define SUN5I_PA_CFG3(n)    ((n * 0x24) + 0x0C)
  41. #define SUN5I_PA_DAT(n)     ((n * 0x24) + 0x10)
  42. #define SUN5I_PA_DRV0(n)    ((n * 0x24) + 0x14)
  43. #define SUN5I_PA_DRV1(n)    ((n * 0x24) + 0x18)
  44. #define SUN5I_PA_PUL0(n)    ((n * 0x24) + 0x1C)
  45. #define SUN5I_PA_PUL1(n)    ((n * 0x24) + 0x20)
  46.  
  47. /* PIO data registers */
  48. #define PIO_PG_DATA_OFFSET  ((SUN5I_GPIO_G * 0x24) + 0x10)
  49.  
  50. #define PIO_PG_CFG1_OFFSET  ((SUN5I_GPIO_G * 0x24) + 0x04)
  51.  
  52. /* Allwinner A1X gpio mode numbers */
  53. #define SUN5I_GPIO_INPUT    0
  54. #define SUN5I_GPIO_OUTPUT   1
  55.  
  56. /* PIO controller defines */
  57. #define PIO_BASE_ADDRESS    (0x01c20800)
  58. #define PIO_RANGE_SIZE      (0x400)
  59.  
  60. /* Set GPIO pin mode (input, output, etc)            */
  61. /* GPIO port has 4 cfg 32bit registers (8 pins each) */
  62. /* First port cfg register addr = port_num * 0x24    
  63. #define SUNXI_SET_GPIO_MODE(addr, port, pin, mode) ({ \
  64.     __u32 reg_val = 0; \
  65.     __u32 pin_idx = pin >> 3; \
  66.     void *raddr = addr + (((port)-1)*0x24 + ((pin_idx)<<2) + 0x00); \
  67.     reg_val = readl(raddr); \
  68.     reg_val &= ~(0x07 << (((pin - (pin_idx<<3))<<2))); \
  69.     reg_val |= mode << (((pin - (pin_idx<<3))<<2)); \
  70.     writel(reg_val, raddr); \
  71. }) */
  72.  
  73. static unsigned int mmap_Base = 0;
  74.  
  75. static unsigned char rev1_gpios[] = {0, 1, 4, 7,   8,  9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25};
  76. static unsigned char rev1_pins[] = {3, 5, 7, 26, 24, 21, 19, 23,  8, 10, 11, 12, 13, 15, 16, 18, 22};
  77.  
  78. static int npins;
  79. static int  mem_fd;
  80. // I/O access
  81. volatile unsigned *gpio;
  82.  
  83. MODULE_AUTHOR("uMinded");
  84. MODULE_DESCRIPTION("Driver for sunxi GPIO pins");
  85. MODULE_LICENSE("GPL");
  86.  
  87. // port direction bits, 1=output
  88. static char *dir = "-1"; // all output
  89. RTAPI_MP_STRING(dir, "port direction, 1=output");
  90. static unsigned dir_map;
  91.  
  92. // exclude pins from usage
  93. static char *exclude = "0"; // all used
  94. RTAPI_MP_STRING(exclude, "exclude pins, 1=dont use");
  95. static unsigned exclude_map;
  96.  
  97. static int comp_id;     /* component ID */
  98. static unsigned char *pins, *gpios;
  99. hal_bit_t **port_data;
  100.  
  101. static void write_port(void *arg, long period);
  102.  
  103. void SUNXI_SET_GPIO_MODE(addr, port, pin, mode) {
  104.   __u32 reg_val = 0;
  105.   __u32 pin_idx = pin >> 3;
  106.   void *raddr = addr + (((port)-1)*0x24 + ((pin_idx)<<2) + 0x00);
  107.   reg_val = *(unsigned int*)(mmap_Base + raddr);
  108.   reg_val &= ~(0x07 << (((pin - (pin_idx<<3))<<2)));
  109.   reg_val |= mode << (((pin - (pin_idx<<3))<<2));
  110.   *(unsigned int*)(mmap_Base + raddr) = reg_val;
  111. }
  112.  
  113. int init_base(unsigned long port_base)
  114. {
  115.    int fd;
  116.    unsigned int addr_start, addr_offset, addr;
  117.    unsigned int PageSize, PageMask;
  118.    void* address;
  119.  
  120.    rtapi_print("SUN5I_GPIO: Attempting to access /dev/mem\n");
  121.    fd = open("/dev/mem", O_RDWR);
  122.    if(fd < 0) {
  123.       rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: /dev/mem failed: %d - %s\n", errno, strerror(errno));
  124.     return -ENOMEM;;
  125.    }
  126.  
  127.    PageSize = sysconf(_SC_PAGESIZE);
  128.    PageMask = (~(PageSize-1));
  129.      
  130.    addr_start  = port_base &  PageMask;
  131.    addr_offset = port_base & ~PageMask;
  132.    
  133.    rtapi_print("SUN5I_GPIO: Attempting to run mmap\n");
  134.    address = (void*)mmap(0, PageSize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr_start);
  135.    if(address == MAP_FAILED) {
  136.     rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: mmap failed: %d - %s\n", errno, strerror(errno));
  137.     return -ENOMEM;;
  138.    }
  139.          
  140.    mmap_Base = (unsigned int)address;
  141.    mmap_Base += addr_offset;
  142.        
  143.    close(fd);
  144.    return 0;
  145. }
  146.  
  147. int rtapi_app_main(void) {
  148. //    __iomem *GADDR = ioremap(PIO_BASE_ADDRESS, PIO_RANGE_SIZE);
  149.  
  150.     rtapi_print("SUN5I_GPIO: comp_id: %i\n", comp_id);
  151.  
  152.     int n, retval = 0;
  153.     int rev, pinno;
  154.     char *endptr;
  155.  
  156.     pins = rev1_pins;
  157.     gpios = rev1_gpios;
  158.     npins = sizeof(rev1_pins);
  159.  
  160.     rtapi_print("SUN5I_GPIO: Loading gloabal PIO address pointer\n");
  161.     if( init_base(PIO_BASE_ADDRESS) ) {
  162.         printf("init_base(SUNXI_TIMER_BASE) ERROR\n");
  163.         exit(-1);
  164.     }
  165.    
  166.     port_data = hal_malloc(npins * sizeof(void *));
  167.     if (port_data == 0) {
  168.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: hal_malloc() failed\n");
  169.         hal_exit(comp_id);
  170.         return -1;
  171.     }
  172.  
  173.     if (dir == 0) {
  174.             rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: no config string\n");
  175.         return -1;
  176.     }
  177.  
  178.     dir_map = strtoul(dir, &endptr, 0);
  179.     if (*endptr) {
  180.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: dir=%s - trailing garbage: '%s'\n", dir, endptr);
  181.         return -1;
  182.     }
  183.  
  184.     if (exclude == 0) {
  185.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: no exclude string\n");
  186.         return -1;
  187.     }
  188.     exclude_map = strtoul(exclude, &endptr,0);
  189.     if (*endptr) {
  190.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: exclude=%s - trailing garbage: '%s'\n", exclude, endptr);
  191.         return -1;
  192.     }
  193.  
  194.     /*
  195.      * Set Up the HAL component structure
  196.      */
  197.     comp_id = hal_init("sunxi_gpio");
  198.     if (comp_id < 0) {
  199.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: hal_init() failed\n");
  200.         return -1;
  201.     }
  202.     rtapi_print("SUN5I_GPIO: comp_id: %i\n", comp_id);
  203.  
  204.     rtapi_print("SUN5I_GPIO: Set the GPIO pin as an output\n");
  205.     //SUNXI_SET_GPIO_MODE(mmap_Base, SUN5I_GPIO_G, 9, SUN5I_GPIO_OUTPUT);
  206.     *(volatile unsigned int*)(mmap_Base + PIO_PG_CFG1_OFFSET) = (1<<4);
  207.     rtapi_print("SUN5I_GPIO: Set up hal_pin_bit_newf()\n");
  208.     if ((retval = hal_pin_bit_newf(HAL_IN, &port_data[9], comp_id, "sun5i_gpio.pin-%02d-out", 9)) < 0)
  209.     if (retval < 0) {
  210.       rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: pin %d export failed with err=%i\n", n,retval);
  211.       hal_exit(comp_id);
  212.       return -1;
  213.     }
  214.  
  215.     rtapi_print("SUN5I_GPIO: Set up hal_export_funct()\n");
  216.     retval = hal_export_funct("sun5i_gpio.write", write_port, 0, 0, 0, comp_id);
  217.     if (retval < 0) {
  218.         rtapi_print_msg(RTAPI_MSG_ERR, "SUN5I_GPIO: ERROR: write funct export failed\n");
  219.         hal_exit(comp_id);
  220.         return -1;
  221.     }
  222.  
  223.     hal_ready(comp_id);
  224.     rtapi_print("SUN5I_GPIO: installed driver\n");
  225.     return 0;
  226. }
  227.  
  228. void rtapi_app_exit(void)
  229. {
  230.     //iounmap(GADDR);
  231.     hal_exit(comp_id);
  232. }
  233.  
  234. static void write_port(void *arg, long period)
  235. {
  236.   //rtapi_print("SUN5I_GPIO: port_data[9] = %i\n", (int)*port_data[9]);
  237.     if (*(port_data[9])) {
  238.     *(volatile unsigned int*)(mmap_Base + PIO_PG_DATA_OFFSET) = (1<<9);
  239.     } else {
  240.         *(volatile unsigned int*)(mmap_Base + PIO_PG_DATA_OFFSET) = (0<<9);
  241.     }
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement