gpio.c
上传用户:beauty0755
上传日期:2022-02-24
资源大小:7k
文件大小:4k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/delay.h>
  5. #include <linux/proc_fs.h>
  6. #include <asm/uaccess.h>
  7. #include "gpio.h"
  8. #ifdef DEBUG
  9. #define PRINTK(format,argument...) printk(format,##argument)
  10. #else
  11. #define PRINTK(format,argument...)
  12. #endif
  13. MODULE_DESCRIPTION("IXP400 GPIO driver");
  14. MODULE_LICENSE("GPL");
  15. MODULE_AUTHOR("ONet Corporation");
  16. #define MODULE_NAME "gpio"
  17. #define MOD_VERSION "0.1"
  18. static struct semaphore   led_sem;
  19. static spinlock_t         device_lock;
  20. static struct timer_list led_slow_timer;
  21. int led_atoi( char *name)
  22. {
  23. int val = 0;
  24.    for(;;name++)
  25. {
  26. switch(*name)
  27. {
  28. case '0'...'9':
  29. val = val*10+(*name - '0');
  30. break;
  31. default:
  32. return val;
  33. }
  34. }
  35. }
  36. void led_on(unsigned long gpio,int logic)
  37. {
  38. *IXP4XX_GPIO_GPOUTR |= gpio;
  39. *IXP4XX_GPIO_GPOER &= ~gpio;
  40. }
  41. void led_off(unsigned long gpio,int logic)
  42. {
  43. *IXP4XX_GPIO_GPOUTR &= ~gpio;
  44. *IXP4XX_GPIO_GPOER &= ~gpio;
  45. }
  46. static void led_blink_timer(unsigned long speed)
  47. {
  48. if(speed)
  49. {
  50. led_on (1 << 10,-1);
  51. led_slow_timer.expires=jiffies+FAST_INTERVAL;
  52. }
  53. else
  54. {
  55. led_off(1 << 10,-1);
  56. led_slow_timer.expires=jiffies+SLOW_INTERVAL;
  57. }
  58. led_slow_timer.data = !speed;  
  59.     add_timer(&led_slow_timer);
  60. }
  61. void led_getall(void)
  62. {
  63. PRINTK("IXP4XX_GPIO_GPINR == 0x%08xn", *IXP4XX_GPIO_GPINR);
  64. }
  65. ssize_t proc_read_gpio_fops(struct file *filp,
  66.                                  char *buf, size_t count, loff_t *offp)
  67. {
  68. char tmp[32]="";
  69. int len;
  70. memset(tmp, '', 32);
  71. sprintf(tmp,"%d", *IXP4XX_GPIO_GPINR);
  72. // printk("IXP4XX_GPIO_GPINR == 0x%04x, tmp is %sn", *IXP4XX_GPIO_GPINR, tmp);
  73. if (copy_to_user(buf, tmp, strlen(tmp)+1))
  74.       return -EFAULT;
  75. *offp = strlen(tmp)+1;
  76. // printk("len is %dn", strlen(tmp)+1);
  77. return 0;
  78. }
  79. ssize_t proc_write_gpio_fops(struct file *filp,const char *buffer,
  80.                                      size_t count , loff_t *offp)
  81. {
  82. char line[10];
  83. unsigned long irqflags = 0x00;
  84. int k;
  85.   
  86. copy_from_user(line,buffer,count);
  87. line[count]=0x00;
  88. if(count<1) 
  89. return count;
  90. down_interruptible(&led_sem);
  91. spin_lock_irqsave(&device_lock, irqflags);
  92. switch(line[0])
  93. {
  94. case 'i':
  95. for(k = 0; k < 16; k++)
  96.              led_on(1 << k,-1);
  97.             break;
  98.         case 'I':
  99. for(k = 0; k < 16; k++)
  100.              led_off(1 << k,-1);
  101.             break;    
  102.         case 'b':
  103.         case 'x':
  104.             led_on(1 << led_atoi(&line[1]),-1);
  105.             break;
  106.         case 'l':
  107.         case 'X':
  108.             led_off(1 << led_atoi(&line[1]),-1);
  109.             mdelay(50);
  110.             break;
  111.         case 'a':
  112.             led_getall();
  113.             break;          
  114.         default:
  115.          break;    
  116. }
  117.    spin_unlock_irqrestore(&device_lock, irqflags);
  118. up(&led_sem);
  119. return count;
  120. }
  121. static struct proc_dir_entry *gpio_module_file;
  122. struct file_operations gpio_module_fops = {
  123.         read: proc_read_gpio_fops,
  124.         write: proc_write_gpio_fops,
  125. };
  126. static int __init gpio_module_init(void)
  127. {
  128. gpio_module_file = create_proc_entry("gpio",0666,&proc_root);
  129. gpio_module_file->owner = THIS_MODULE;
  130. gpio_module_file->proc_fops = &gpio_module_fops;
  131. init_timer(&led_slow_timer);
  132. led_slow_timer.data=1;
  133.     led_slow_timer.expires=jiffies+FAST_INTERVAL;     
  134. led_slow_timer.function=led_blink_timer;
  135. add_timer(&led_slow_timer);
  136. sema_init(&led_sem,1);
  137. return 0;
  138. }
  139. static void __exit gpio_module_cleanup(void)
  140. {
  141. del_timer(&led_slow_timer);
  142. remove_proc_entry("gpio",&proc_root);
  143. }
  144. module_init(gpio_module_init);
  145. module_exit(gpio_module_cleanup);