Advertisement
Guest User

Untitled

a guest
Mar 14th, 2013
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.98 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 SUNXI_GPIO_G 6
  27.  
  28. /* PIO data registers */
  29. #define PIO_PG_DATA_OFFSET (SUNXI_GPIO_G * 0x24) + 0x10
  30.  
  31. /* Allwinner A1X gpio mode numbers */
  32. #define SUNXI_GPIO_INPUT 0
  33. #define SUNXI_GPIO_OUTPUT 1
  34.  
  35. /* PIO controller defines */
  36. #define PIO_BASE_ADDRESS SW_PA_PORTC_IO_BASE
  37. #define PIO_RANGE_SIZE (0x400)
  38.  
  39. /* Set GPIO pin mode (input, output, etc) */
  40. /* GPIO port has 4 cfg 32bit registers (8 pins each) */
  41. /* First port cfg register addr = port_num * 0x24 */
  42. #define SUNXI_SET_GPIO_MODE(addr, port, pin, mode) ({ \
  43. __u32 reg_val = 0; \
  44. __u32 pin_idx = pin >> 3; \
  45. void *raddr = addr + (((port)-1)*0x24 + ((pin_idx)<<2) + 0x00); \
  46. reg_val = readl(raddr); \
  47. reg_val &= ~(0x07 << (((pin - (pin_idx<<3))<<2))); \
  48. reg_val |= mode << (((pin - (pin_idx<<3))<<2)); \
  49. writel(reg_val, raddr); \
  50. })
  51.  
  52. static unsigned int mmap_Base = 0;
  53.  
  54. static unsigned char rev1_gpios[] = {0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25};
  55. static unsigned char rev1_pins[] = {3, 5, 7, 26, 24, 21, 19, 23, 8, 10, 11, 12, 13, 15, 16, 18, 22};
  56.  
  57. static int npins;
  58. static int mem_fd;
  59. // I/O access
  60. volatile unsigned *gpio;
  61.  
  62. MODULE_AUTHOR("uMinded");
  63. MODULE_DESCRIPTION("Driver for sunxi GPIO pins");
  64. MODULE_LICENSE("GPL");
  65.  
  66. // port direction bits, 1=output
  67. static char *dir = "-1"; // all output
  68. RTAPI_MP_STRING(dir, "port direction, 1=output");
  69. static unsigned dir_map;
  70.  
  71. // exclude pins from usage
  72. static char *exclude = "0"; // all used
  73. RTAPI_MP_STRING(exclude, "exclude pins, 1=dont use");
  74. static unsigned exclude_map;
  75.  
  76. static int comp_id; /* component ID */
  77. static unsigned char *pins, *gpios;
  78. hal_bit_t **port_data;
  79.  
  80. static void write_port(void *arg, long period);
  81. static void read_port(void *arg, long period);
  82.  
  83. int init_base(unsigned long port_base)
  84. {
  85. int fd;
  86. unsigned int addr_start, addr_offset, addr;
  87. unsigned int PageSize, PageMask;
  88. void* address;
  89.  
  90. fd = open("/dev/mem", O_RDWR);
  91. if(fd < 0) {
  92. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: /dev/mem failed: %d - %s\n", errno, strerror(errno));
  93. return -ENOMEM;;
  94. }
  95.  
  96. PageSize = sysconf(_SC_PAGESIZE);
  97. PageMask = (~(PageSize-1));
  98.  
  99. addr_start = port_base & PageMask;
  100. addr_offset = port_base & ~PageMask;
  101.  
  102. address = (void*)mmap(0, PageSize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr_start);
  103. if(address == MAP_FAILED) {
  104. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: mmap failed: %d - %s\n", errno, strerror(errno));
  105. return -ENOMEM;;
  106. }
  107.  
  108. mmap_Base = (unsigned int)address;
  109. mmap_Base += addr_offset;
  110.  
  111. close(fd);
  112. return 0;
  113. }
  114.  
  115. int rtapi_app_main(void) {
  116. // __iomem *GADDR = ioremap(PIO_BASE_ADDRESS, PIO_RANGE_SIZE);
  117.  
  118. int n, retval = 0;
  119. int rev, pinno;
  120. char *endptr;
  121.  
  122. pins = rev1_pins;
  123. gpios = rev1_gpios;
  124. npins = sizeof(rev1_pins);
  125.  
  126. if( init_base(PIO_BASE_ADDRESS) ) {
  127. printf("init_base(SUNXI_TIMER_BASE) ERROR\n");
  128. exit(-1);
  129. }
  130.  
  131. port_data = hal_malloc(npins * sizeof(void *));
  132. if (port_data == 0) {
  133. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: hal_malloc() failed\n");
  134. hal_exit(comp_id);
  135. return -1;
  136. }
  137.  
  138. if (dir == 0) {
  139. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: no config string\n");
  140. return -1;
  141. }
  142.  
  143. dir_map = strtoul(dir, &endptr, 0);
  144. if (*endptr) {
  145. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: dir=%s - trailing garbage: '%s'\n", dir, endptr);
  146. return -1;
  147. }
  148.  
  149. if (exclude == 0) {
  150. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: no exclude string\n");
  151. return -1;
  152. }
  153. exclude_map = strtoul(exclude, &endptr,0);
  154. if (*endptr) {
  155. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: exclude=%s - trailing garbage: '%s'\n", exclude, endptr);
  156. return -1;
  157. }
  158.  
  159. /*
  160. * Set Up the HAL component structure
  161. */
  162. comp_id = hal_init("sunxi_gpio");
  163. if (comp_id < 0) {
  164. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: hal_init() failed\n");
  165. return -1;
  166. }
  167.  
  168. SUNXI_SET_GPIO_MODE(mmap_Base, SUNXI_GPIO_G, 9, SUNXI_GPIO_OUTPUT);
  169. if ((retval = hal_pin_bit_newf(HAL_IN, &port_data[n], comp_id, "sunxi_gpio.pin-%02d-out", pinno)) < 0)
  170. if (retval < 0) {
  171. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: pin %d export failed with err=%i\n", n,retval);
  172. hal_exit(comp_id);
  173. return -1;
  174. }
  175.  
  176. retval = hal_export_funct("sunxi_gpio.write", hal_write_port, 0, 0, 0, comp_id);
  177. if (retval < 0) {
  178. rtapi_print_msg(RTAPI_MSG_ERR, "SUNXI_GPIO: ERROR: write funct export failed\n");
  179. hal_exit(comp_id);
  180. return -1;
  181. }
  182.  
  183. rtapi_print_msg(RTAPI_MSG_INFO, "SUNXI_GPIO: installed driver\n");
  184. hal_ready(comp_id);
  185. return 0;
  186. }
  187.  
  188. void rtapi_app_exit(void)
  189. {
  190. //iounmap(GADDR);
  191. hal_exit(comp_id);
  192. }
  193.  
  194. static void hal_write_port(void *arg, long period)
  195. {
  196. int value;
  197. value = atoi(arg);
  198. if (value > 0) {
  199. write_port(PIO_PG_DATA_OFFSET, (1<<9));
  200. }
  201. if (value <= 0) {
  202. write_port(PIO_PG_DATA_OFFSET, (0<<9));
  203. }
  204. }
  205.  
  206. void write_port(unsigned int port_offset, unsigned int port_data)
  207. {
  208. *(unsigned int*)(mmap_Base + port_offset) = port_data;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement