gpio.c 7.4 KB

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