gpio.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * arch/arm/mach-pnx4008/gpio.c
  3. *
  4. * PNX4008 GPIO driver
  5. *
  6. * Author: Dmitry Chigirev <source@mvista.com>
  7. *
  8. * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
  9. * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
  10. *
  11. * 2005 (c) MontaVista Software, Inc. This file is licensed under
  12. * the terms of the GNU General Public License version 2. This program
  13. * is licensed "as is" without any warranty of any kind, whether express
  14. * or implied.
  15. */
  16. #include <linux/types.h>
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/io.h>
  20. #include <mach/platform.h>
  21. #include <mach/gpio.h>
  22. /* register definitions */
  23. #define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
  24. #define PIO_INP_STATE (0x00U)
  25. #define PIO_OUTP_SET (0x04U)
  26. #define PIO_OUTP_CLR (0x08U)
  27. #define PIO_OUTP_STATE (0x0CU)
  28. #define PIO_DRV_SET (0x10U)
  29. #define PIO_DRV_CLR (0x14U)
  30. #define PIO_DRV_STATE (0x18U)
  31. #define PIO_SDINP_STATE (0x1CU)
  32. #define PIO_SDOUTP_SET (0x20U)
  33. #define PIO_SDOUTP_CLR (0x24U)
  34. #define PIO_MUX_SET (0x28U)
  35. #define PIO_MUX_CLR (0x2CU)
  36. #define PIO_MUX_STATE (0x30U)
  37. static inline void gpio_lock(void)
  38. {
  39. local_irq_disable();
  40. }
  41. static inline void gpio_unlock(void)
  42. {
  43. local_irq_enable();
  44. }
  45. /* Inline functions */
  46. static inline int gpio_read_bit(u32 reg, int gpio)
  47. {
  48. u32 bit, val;
  49. int ret = -EFAULT;
  50. if (gpio < 0)
  51. goto out;
  52. bit = GPIO_BIT(gpio);
  53. if (bit) {
  54. val = __raw_readl(PIO_VA_BASE + reg);
  55. ret = (val & bit) ? 1 : 0;
  56. }
  57. out:
  58. return ret;
  59. }
  60. static inline int gpio_set_bit(u32 reg, int gpio)
  61. {
  62. u32 bit, val;
  63. int ret = -EFAULT;
  64. if (gpio < 0)
  65. goto out;
  66. bit = GPIO_BIT(gpio);
  67. if (bit) {
  68. val = __raw_readl(PIO_VA_BASE + reg);
  69. val |= bit;
  70. __raw_writel(val, PIO_VA_BASE + reg);
  71. ret = 0;
  72. }
  73. out:
  74. return ret;
  75. }
  76. /* Very simple access control, bitmap for allocated/free */
  77. static unsigned long access_map[4];
  78. #define INP_INDEX 0
  79. #define OUTP_INDEX 1
  80. #define GPIO_INDEX 2
  81. #define MUX_INDEX 3
  82. /*GPIO to Input Mapping */
  83. static short gpio_to_inp_map[32] = {
  84. -1, -1, -1, -1, -1, -1, -1, -1,
  85. -1, -1, -1, -1, -1, -1, -1, -1,
  86. -1, -1, -1, -1, -1, -1, -1, -1,
  87. -1, 10, 11, 12, 13, 14, 24, -1
  88. };
  89. /*GPIO to Mux Mapping */
  90. static short gpio_to_mux_map[32] = {
  91. -1, -1, -1, -1, -1, -1, -1, -1,
  92. -1, -1, -1, -1, -1, -1, -1, -1,
  93. -1, -1, -1, -1, -1, -1, -1, -1,
  94. -1, -1, -1, 0, 1, 4, 5, -1
  95. };
  96. /*Output to Mux Mapping */
  97. static short outp_to_mux_map[32] = {
  98. -1, -1, -1, 6, -1, -1, -1, -1,
  99. -1, -1, -1, -1, -1, -1, -1, -1,
  100. -1, -1, -1, -1, -1, 2, -1, -1,
  101. -1, -1, -1, -1, -1, -1, -1, -1
  102. };
  103. int pnx4008_gpio_register_pin(unsigned short pin)
  104. {
  105. unsigned long bit = GPIO_BIT(pin);
  106. int ret = -EBUSY; /* Already in use */
  107. gpio_lock();
  108. if (GPIO_ISBID(pin)) {
  109. if (access_map[GPIO_INDEX] & bit)
  110. goto out;
  111. access_map[GPIO_INDEX] |= bit;
  112. } else if (GPIO_ISRAM(pin)) {
  113. if (access_map[GPIO_INDEX] & bit)
  114. goto out;
  115. access_map[GPIO_INDEX] |= bit;
  116. } else if (GPIO_ISMUX(pin)) {
  117. if (access_map[MUX_INDEX] & bit)
  118. goto out;
  119. access_map[MUX_INDEX] |= bit;
  120. } else if (GPIO_ISOUT(pin)) {
  121. if (access_map[OUTP_INDEX] & bit)
  122. goto out;
  123. access_map[OUTP_INDEX] |= bit;
  124. } else if (GPIO_ISIN(pin)) {
  125. if (access_map[INP_INDEX] & bit)
  126. goto out;
  127. access_map[INP_INDEX] |= bit;
  128. } else
  129. goto out;
  130. ret = 0;
  131. out:
  132. gpio_unlock();
  133. return ret;
  134. }
  135. EXPORT_SYMBOL(pnx4008_gpio_register_pin);
  136. int pnx4008_gpio_unregister_pin(unsigned short pin)
  137. {
  138. unsigned long bit = GPIO_BIT(pin);
  139. int ret = -EFAULT; /* Not registered */
  140. gpio_lock();
  141. if (GPIO_ISBID(pin)) {
  142. if (~access_map[GPIO_INDEX] & bit)
  143. goto out;
  144. access_map[GPIO_INDEX] &= ~bit;
  145. } else if (GPIO_ISRAM(pin)) {
  146. if (~access_map[GPIO_INDEX] & bit)
  147. goto out;
  148. access_map[GPIO_INDEX] &= ~bit;
  149. } else if (GPIO_ISMUX(pin)) {
  150. if (~access_map[MUX_INDEX] & bit)
  151. goto out;
  152. access_map[MUX_INDEX] &= ~bit;
  153. } else if (GPIO_ISOUT(pin)) {
  154. if (~access_map[OUTP_INDEX] & bit)
  155. goto out;
  156. access_map[OUTP_INDEX] &= ~bit;
  157. } else if (GPIO_ISIN(pin)) {
  158. if (~access_map[INP_INDEX] & bit)
  159. goto out;
  160. access_map[INP_INDEX] &= ~bit;
  161. } else
  162. goto out;
  163. ret = 0;
  164. out:
  165. gpio_unlock();
  166. return ret;
  167. }
  168. EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
  169. unsigned long pnx4008_gpio_read_pin(unsigned short pin)
  170. {
  171. unsigned long ret = -EFAULT;
  172. int gpio = GPIO_BIT_MASK(pin);
  173. gpio_lock();
  174. if (GPIO_ISOUT(pin)) {
  175. ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
  176. } else if (GPIO_ISRAM(pin)) {
  177. if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
  178. ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
  179. }
  180. } else if (GPIO_ISBID(pin)) {
  181. ret = gpio_read_bit(PIO_DRV_STATE, gpio);
  182. if (ret > 0)
  183. ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
  184. else if (ret == 0)
  185. ret =
  186. gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
  187. } else if (GPIO_ISIN(pin)) {
  188. ret = gpio_read_bit(PIO_INP_STATE, gpio);
  189. }
  190. gpio_unlock();
  191. return ret;
  192. }
  193. EXPORT_SYMBOL(pnx4008_gpio_read_pin);
  194. /* Write Value to output */
  195. int pnx4008_gpio_write_pin(unsigned short pin, int output)
  196. {
  197. int gpio = GPIO_BIT_MASK(pin);
  198. int ret = -EFAULT;
  199. gpio_lock();
  200. if (GPIO_ISOUT(pin)) {
  201. printk( "writing '%x' to '%x'\n",
  202. gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
  203. ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
  204. } else if (GPIO_ISRAM(pin)) {
  205. if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
  206. ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
  207. PIO_SDOUTP_CLR, gpio);
  208. } else if (GPIO_ISBID(pin)) {
  209. if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
  210. ret = gpio_set_bit(output ? PIO_OUTP_SET :
  211. PIO_OUTP_CLR, gpio);
  212. }
  213. gpio_unlock();
  214. return ret;
  215. }
  216. EXPORT_SYMBOL(pnx4008_gpio_write_pin);
  217. /* Value = 1 : Set GPIO pin as output */
  218. /* Value = 0 : Set GPIO pin as input */
  219. int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
  220. {
  221. int gpio = GPIO_BIT_MASK(pin);
  222. int ret = -EFAULT;
  223. gpio_lock();
  224. if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
  225. ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
  226. }
  227. gpio_unlock();
  228. return ret;
  229. }
  230. EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
  231. /* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
  232. int pnx4008_gpio_read_pin_direction(unsigned short pin)
  233. {
  234. int gpio = GPIO_BIT_MASK(pin);
  235. int ret = -EFAULT;
  236. gpio_lock();
  237. if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
  238. ret = gpio_read_bit(PIO_DRV_STATE, gpio);
  239. }
  240. gpio_unlock();
  241. return ret;
  242. }
  243. EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
  244. /* Value = 1 : Set pin to muxed function */
  245. /* Value = 0 : Set pin as GPIO */
  246. int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
  247. {
  248. int gpio = GPIO_BIT_MASK(pin);
  249. int ret = -EFAULT;
  250. gpio_lock();
  251. if (GPIO_ISBID(pin)) {
  252. ret =
  253. gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
  254. gpio_to_mux_map[gpio]);
  255. } else if (GPIO_ISOUT(pin)) {
  256. ret =
  257. gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
  258. outp_to_mux_map[gpio]);
  259. } else if (GPIO_ISMUX(pin)) {
  260. ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
  261. }
  262. gpio_unlock();
  263. return ret;
  264. }
  265. EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
  266. /* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
  267. int pnx4008_gpio_read_pin_mux(unsigned short pin)
  268. {
  269. int gpio = GPIO_BIT_MASK(pin);
  270. int ret = -EFAULT;
  271. gpio_lock();
  272. if (GPIO_ISBID(pin)) {
  273. ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
  274. } else if (GPIO_ISOUT(pin)) {
  275. ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
  276. } else if (GPIO_ISMUX(pin)) {
  277. ret = gpio_read_bit(PIO_MUX_STATE, gpio);
  278. }
  279. gpio_unlock();
  280. return ret;
  281. }
  282. EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);