gpio.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <linux/cdev.h>
  5. #include <linux/fs.h>
  6. #include <linux/errno.h>
  7. #include <asm/current.h>
  8. #include <linux/kernel.h>
  9. #include <linux/sched.h>
  10. #include <linux/device.h>
  11. #include <linux/err.h>
  12. //#include <stdint.h>
  13. #include "gpio.h"
  14. #include "./../../stm32f429xx.h"
  15. #include "asm/uaccess.h"
  16. static int major = 100;
  17. static int minor = 0;
  18. static dev_t devno;
  19. static struct cdev *gpio_cdev = NULL;
  20. static int count = 3;
  21. #define DEVNAME "gpio"
  22. static int gpio_open(struct inode *inode, struct file *filep);
  23. static int gpio_close(struct inode *inode, struct file *filep);
  24. static ssize_t gpio_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
  25. static ssize_t gpio_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
  26. static int gpio_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
  27. static struct file_operations gpio_ops =
  28. {
  29. .owner = THIS_MODULE,
  30. .open = gpio_open,
  31. .release = gpio_close,
  32. .ioctl = gpio_ioctl,
  33. .read = gpio_read,
  34. .write = gpio_write,
  35. };
  36. static int gpio_open(struct inode *inode, struct file *filep)
  37. {
  38. return 0;
  39. }
  40. static int gpio_close(struct inode *inode, struct file *filep)
  41. {
  42. return 0;
  43. }
  44. static int enable_gpio_clock(gpio_data_t *gpin_data)
  45. {
  46. RCC_TypeDef *rcc_dev = RCC;
  47. switch((int)gpin_data->port)
  48. {
  49. //AHB1
  50. case (int)GPIOA: rcc_dev->AHB1ENR |= 0x001; break;
  51. case (int)GPIOB: rcc_dev->AHB1ENR |= 0x002; break;
  52. case (int)GPIOC: rcc_dev->AHB1ENR |= 0x004; break;
  53. case (int)GPIOD: rcc_dev->AHB1ENR |= 0x008; break;
  54. case (int)GPIOE: rcc_dev->AHB1ENR |= 0x010; break;
  55. case (int)GPIOF: rcc_dev->AHB1ENR |= 0x020; break;
  56. case (int)GPIOG: rcc_dev->AHB1ENR |= 0x040; break;
  57. case (int)GPIOH: rcc_dev->AHB1ENR |= 0x080; break;
  58. case (int)GPIOI: rcc_dev->AHB1ENR |= 0x100; break;
  59. case (int)GPIOJ: rcc_dev->AHB1ENR |= 0x200; break;
  60. case (int)GPIOK: rcc_dev->AHB1ENR |= 0x400; break;
  61. default: printk("---> invalid gpio port!\n");break;
  62. }
  63. return 0;
  64. }
  65. static int gpio_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
  66. {
  67. uint8_t position;
  68. gpio_data_t gpin_data;
  69. GPIO_TypeDef *gpio_dev;
  70. if ( copy_from_user(&gpin_data, (void*)arg, sizeof(gpio_data_t)) )
  71. return -EFAULT;
  72. gpio_dev = (GPIO_TypeDef*)gpin_data.port;
  73. //get gpio pin position
  74. for(position=0;position<16;position++)
  75. {
  76. if(gpin_data.pin == 0x01<<position)
  77. break;
  78. }
  79. switch(cmd)
  80. {
  81. case SET_GPIO_INPUT:
  82. enable_gpio_clock(&gpin_data);
  83. gpio_dev->MODER &= ~((0x03) << (position<<1));
  84. break;
  85. case SET_GPIO_PUSH_PULL_OUTPUT:
  86. enable_gpio_clock(&gpin_data);
  87. gpio_dev->MODER &= ~((0x03) << (position<<1));
  88. gpio_dev->MODER |= ((0x01) << (position<<1));
  89. gpio_dev->OTYPER &= (~gpin_data.pin);
  90. break;
  91. case SET_GPIO_OPEN_DRAIN_OUTPUT:
  92. enable_gpio_clock(&gpin_data);
  93. gpio_dev->MODER &= ~((0x03) << (position<<1));
  94. gpio_dev->MODER |= ((0x01) << (position<<1));
  95. gpio_dev->OTYPER |= gpin_data.pin;
  96. break;
  97. case SET_GPIO_PULL_UP:
  98. gpio_dev->PUPDR &= ~((0x03) << (position<<1));
  99. gpio_dev->PUPDR |= ((0x01) << (position<<1));
  100. break;
  101. case SET_GPIO_PULL_DOWN:
  102. gpio_dev->PUPDR &= ~((0x03) << (position<<1));
  103. gpio_dev->PUPDR |= ((0x02) << (position<<1));
  104. break;
  105. case SET_GPIO_NO_PULL:
  106. gpio_dev->PUPDR &= ~((0x03) << (position<<1));
  107. break;
  108. case SET_GPIO_SPEED:
  109. switch(gpin_data.data)
  110. {
  111. case GPIO_LOW_SPEED:
  112. gpio_dev->OSPEEDR &= ~((0x03) << (position<<1));
  113. break;
  114. case GPIO_MEDIUM_SPEED:
  115. gpio_dev->OSPEEDR &= ~((0x03) << (position<<1));
  116. gpio_dev->OSPEEDR |= ((0x01) << (position<<1));
  117. break;
  118. case GPIO_FAST_SPEED:
  119. gpio_dev->OSPEEDR &= ~((0x03) << (position<<1));
  120. gpio_dev->OSPEEDR |= ((0x02) << (position<<1));
  121. break;
  122. case GPIO_HIGH_SPEED:
  123. gpio_dev->OSPEEDR |= ((0x03) << (position<<1));
  124. break;
  125. default:break;
  126. }
  127. break;
  128. case SET_GPIO_VALUE:
  129. if(gpin_data.data)
  130. gpio_dev->ODR |= gpin_data.pin;
  131. else
  132. gpio_dev->ODR &= ~gpin_data.pin;
  133. break;
  134. case GET_GPIO_VALUE:
  135. if(gpio_dev->IDR & gpin_data.pin)
  136. gpin_data.data = 0x01;
  137. else
  138. gpin_data.data = 0x00;
  139. break;
  140. default:
  141. printk("---> Invalid action\n");
  142. return -EINVAL;
  143. break;
  144. }
  145. return 0;
  146. }
  147. static ssize_t gpio_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
  148. {
  149. return 0;
  150. }
  151. static ssize_t gpio_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
  152. {
  153. return 0;
  154. }
  155. static int __init gpio_init(void)
  156. {
  157. int ret;
  158. gpio_cdev = cdev_alloc();
  159. if(gpio_cdev == NULL){
  160. return -ENOMEM;
  161. }
  162. cdev_init(gpio_cdev,&gpio_ops);
  163. devno = MKDEV(major,minor);
  164. ret = register_chrdev_region(devno, count, DEVNAME);
  165. if(ret){
  166. goto ERR_STEP;
  167. }
  168. ret = cdev_add(gpio_cdev, devno, count);
  169. if(ret){
  170. goto ERR_STEP1;
  171. }
  172. return 0;
  173. ERR_STEP1:
  174. unregister_chrdev_region(devno,count);
  175. ERR_STEP:
  176. cdev_del(gpio_cdev);
  177. return ret;
  178. }
  179. static void __exit gpio_exit(void)
  180. {
  181. unregister_chrdev_region(MKDEV(major,minor),count);
  182. cdev_del(gpio_cdev);
  183. }
  184. module_init(gpio_init);
  185. module_exit(gpio_exit);
  186. MODULE_LICENSE("GPL");
  187. MODULE_AUTHOR("Jimbo");
  188. MODULE_DESCRIPTION("this is gpio module");