ar7_gpio.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (C) 2007 Nicolas Thill <nico@openwrt.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <linux/device.h>
  19. #include <linux/fs.h>
  20. #include <linux/module.h>
  21. #include <linux/errno.h>
  22. #include <linux/kernel.h>
  23. #include <linux/init.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/uaccess.h>
  26. #include <linux/io.h>
  27. #include <linux/types.h>
  28. #include <linux/cdev.h>
  29. #include <gpio.h>
  30. #define DRVNAME "ar7_gpio"
  31. #define LONGNAME "TI AR7 GPIOs Driver"
  32. MODULE_AUTHOR("Nicolas Thill <nico@openwrt.org>");
  33. MODULE_DESCRIPTION(LONGNAME);
  34. MODULE_LICENSE("GPL");
  35. static int ar7_gpio_major;
  36. static ssize_t ar7_gpio_write(struct file *file, const char __user *buf,
  37. size_t len, loff_t *ppos)
  38. {
  39. int pin = iminor(file->f_path.dentry->d_inode);
  40. size_t i;
  41. for (i = 0; i < len; ++i) {
  42. char c;
  43. if (get_user(c, buf + i))
  44. return -EFAULT;
  45. switch (c) {
  46. case '0':
  47. gpio_set_value(pin, 0);
  48. break;
  49. case '1':
  50. gpio_set_value(pin, 1);
  51. break;
  52. case 'd':
  53. case 'D':
  54. ar7_gpio_disable(pin);
  55. break;
  56. case 'e':
  57. case 'E':
  58. ar7_gpio_enable(pin);
  59. break;
  60. case 'i':
  61. case 'I':
  62. case '<':
  63. gpio_direction_input(pin);
  64. break;
  65. case 'o':
  66. case 'O':
  67. case '>':
  68. gpio_direction_output(pin, 0);
  69. break;
  70. default:
  71. return -EINVAL;
  72. }
  73. }
  74. return len;
  75. }
  76. static ssize_t ar7_gpio_read(struct file *file, char __user *buf,
  77. size_t len, loff_t *ppos)
  78. {
  79. int pin = iminor(file->f_path.dentry->d_inode);
  80. int value;
  81. value = gpio_get_value(pin);
  82. if (put_user(value ? '1' : '0', buf))
  83. return -EFAULT;
  84. return 1;
  85. }
  86. static int ar7_gpio_open(struct inode *inode, struct file *file)
  87. {
  88. int m = iminor(inode);
  89. if (m >= (ar7_is_titan() ? TITAN_GPIO_MAX : AR7_GPIO_MAX))
  90. return -EINVAL;
  91. return nonseekable_open(inode, file);
  92. }
  93. static int ar7_gpio_release(struct inode *inode, struct file *file)
  94. {
  95. return 0;
  96. }
  97. static const struct file_operations ar7_gpio_fops = {
  98. .owner = THIS_MODULE,
  99. .write = ar7_gpio_write,
  100. .read = ar7_gpio_read,
  101. .open = ar7_gpio_open,
  102. .release = ar7_gpio_release,
  103. .llseek = no_llseek,
  104. };
  105. static struct platform_device *ar7_gpio_device;
  106. static int __init ar7_gpio_char_init(void)
  107. {
  108. int rc;
  109. ar7_gpio_device = platform_device_alloc(DRVNAME, -1);
  110. if (!ar7_gpio_device)
  111. return -ENOMEM;
  112. rc = platform_device_add(ar7_gpio_device);
  113. if (rc < 0)
  114. goto out_put;
  115. rc = register_chrdev(ar7_gpio_major, DRVNAME, &ar7_gpio_fops);
  116. if (rc < 0)
  117. goto out_put;
  118. ar7_gpio_major = rc;
  119. rc = 0;
  120. goto out;
  121. out_put:
  122. platform_device_put(ar7_gpio_device);
  123. out:
  124. return rc;
  125. }
  126. static void __exit ar7_gpio_char_exit(void)
  127. {
  128. unregister_chrdev(ar7_gpio_major, DRVNAME);
  129. platform_device_unregister(ar7_gpio_device);
  130. }
  131. module_init(ar7_gpio_char_init);
  132. module_exit(ar7_gpio_char_exit);