at91_gpio.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * Memory Setup stuff - taken from blob memsetup.S
  3. *
  4. * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
  5. *
  6. * Copyright (C) 2005 HP Labs
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. /*
  27. * WARNING:
  28. *
  29. * As the code is right now, it expects all PIO ports A,B,C,...
  30. * to be evenly spaced in the memory map:
  31. * ATMEL_BASE_PIOA + port * sizeof at91pio_t
  32. * This might not necessaryly be true in future Atmel SoCs.
  33. * This code should be fixed to use a pointer array to the ports.
  34. */
  35. #include <config.h>
  36. #include <common.h>
  37. #include <asm/io.h>
  38. #include <asm/sizes.h>
  39. #include <asm/arch/hardware.h>
  40. #include <asm/arch/at91_pio.h>
  41. int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
  42. {
  43. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  44. u32 mask;
  45. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  46. mask = 1 << pin;
  47. if (use_pullup)
  48. writel(1 << pin, &pio->port[port].puer);
  49. else
  50. writel(1 << pin, &pio->port[port].pudr);
  51. writel(mask, &pio->port[port].per);
  52. }
  53. return 0;
  54. }
  55. /*
  56. * mux the pin to the "GPIO" peripheral role.
  57. */
  58. int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
  59. {
  60. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  61. u32 mask;
  62. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  63. mask = 1 << pin;
  64. writel(mask, &pio->port[port].idr);
  65. at91_set_pio_pullup(port, pin, use_pullup);
  66. writel(mask, &pio->port[port].per);
  67. }
  68. return 0;
  69. }
  70. /*
  71. * mux the pin to the "A" internal peripheral role.
  72. */
  73. int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
  74. {
  75. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  76. u32 mask;
  77. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  78. mask = 1 << pin;
  79. writel(mask, &pio->port[port].idr);
  80. at91_set_pio_pullup(port, pin, use_pullup);
  81. #if defined(CPU_HAS_PIO3)
  82. writel(readl(&pio->port[port].abcdsr1) & ~mask,
  83. &pio->port[port].abcdsr1);
  84. writel(readl(&pio->port[port].abcdsr2) & ~mask,
  85. &pio->port[port].abcdsr2);
  86. #else
  87. writel(mask, &pio->port[port].asr);
  88. #endif
  89. writel(mask, &pio->port[port].pdr);
  90. }
  91. return 0;
  92. }
  93. /*
  94. * mux the pin to the "B" internal peripheral role.
  95. */
  96. int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
  97. {
  98. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  99. u32 mask;
  100. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  101. mask = 1 << pin;
  102. writel(mask, &pio->port[port].idr);
  103. at91_set_pio_pullup(port, pin, use_pullup);
  104. #if defined(CPU_HAS_PIO3)
  105. writel(readl(&pio->port[port].abcdsr1) | mask,
  106. &pio->port[port].abcdsr1);
  107. writel(readl(&pio->port[port].abcdsr2) & ~mask,
  108. &pio->port[port].abcdsr2);
  109. #else
  110. writel(mask, &pio->port[port].bsr);
  111. #endif
  112. writel(mask, &pio->port[port].pdr);
  113. }
  114. return 0;
  115. }
  116. #if defined(CPU_HAS_PIO3)
  117. /*
  118. * mux the pin to the "C" internal peripheral role.
  119. */
  120. int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
  121. {
  122. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  123. u32 mask;
  124. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  125. mask = 1 << pin;
  126. writel(mask, &pio->port[port].idr);
  127. at91_set_pio_pullup(port, pin, use_pullup);
  128. writel(readl(&pio->port[port].abcdsr1) & ~mask,
  129. &pio->port[port].abcdsr1);
  130. writel(readl(&pio->port[port].abcdsr2) | mask,
  131. &pio->port[port].abcdsr2);
  132. writel(mask, &pio->port[port].pdr);
  133. }
  134. return 0;
  135. }
  136. /*
  137. * mux the pin to the "D" internal peripheral role.
  138. */
  139. int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
  140. {
  141. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  142. u32 mask;
  143. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  144. mask = 1 << pin;
  145. writel(mask, &pio->port[port].idr);
  146. at91_set_pio_pullup(port, pin, use_pullup);
  147. writel(readl(&pio->port[port].abcdsr1) | mask,
  148. &pio->port[port].abcdsr1);
  149. writel(readl(&pio->port[port].abcdsr2) | mask,
  150. &pio->port[port].abcdsr2);
  151. writel(mask, &pio->port[port].pdr);
  152. }
  153. return 0;
  154. }
  155. #endif
  156. /*
  157. * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
  158. * configure it for an input.
  159. */
  160. int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
  161. {
  162. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  163. u32 mask;
  164. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  165. mask = 1 << pin;
  166. writel(mask, &pio->port[port].idr);
  167. at91_set_pio_pullup(port, pin, use_pullup);
  168. writel(mask, &pio->port[port].odr);
  169. writel(mask, &pio->port[port].per);
  170. }
  171. return 0;
  172. }
  173. /*
  174. * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
  175. * and configure it for an output.
  176. */
  177. int at91_set_pio_output(unsigned port, u32 pin, int value)
  178. {
  179. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  180. u32 mask;
  181. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  182. mask = 1 << pin;
  183. writel(mask, &pio->port[port].idr);
  184. writel(mask, &pio->port[port].pudr);
  185. if (value)
  186. writel(mask, &pio->port[port].sodr);
  187. else
  188. writel(mask, &pio->port[port].codr);
  189. writel(mask, &pio->port[port].oer);
  190. writel(mask, &pio->port[port].per);
  191. }
  192. return 0;
  193. }
  194. /*
  195. * enable/disable the glitch filter. mostly used with IRQ handling.
  196. */
  197. int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
  198. {
  199. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  200. u32 mask;
  201. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  202. mask = 1 << pin;
  203. if (is_on) {
  204. #if defined(CPU_HAS_PIO3)
  205. writel(mask, &pio->port[port].ifscdr);
  206. #endif
  207. writel(mask, &pio->port[port].ifer);
  208. } else {
  209. writel(mask, &pio->port[port].ifdr);
  210. }
  211. }
  212. return 0;
  213. }
  214. #if defined(CPU_HAS_PIO3)
  215. /*
  216. * enable/disable the debounce filter.
  217. */
  218. int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
  219. {
  220. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  221. u32 mask;
  222. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  223. mask = 1 << pin;
  224. if (is_on) {
  225. writel(mask, &pio->port[port].ifscer);
  226. writel(div & PIO_SCDR_DIV, &pio->port[port].scdr);
  227. writel(mask, &pio->port[port].ifer);
  228. } else {
  229. writel(mask, &pio->port[port].ifdr);
  230. }
  231. }
  232. return 0;
  233. }
  234. /*
  235. * enable/disable the pull-down.
  236. * If pull-up already enabled while calling the function, we disable it.
  237. */
  238. int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
  239. {
  240. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  241. u32 mask;
  242. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  243. mask = 1 << pin;
  244. writel(mask, &pio->port[port].pudr);
  245. if (is_on)
  246. writel(mask, &pio->port[port].ppder);
  247. else
  248. writel(mask, &pio->port[port].ppddr);
  249. }
  250. return 0;
  251. }
  252. /*
  253. * disable Schmitt trigger
  254. */
  255. int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
  256. {
  257. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  258. u32 mask;
  259. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  260. mask = 1 << pin;
  261. writel(readl(&pio->port[port].schmitt) | mask,
  262. &pio->port[port].schmitt);
  263. }
  264. return 0;
  265. }
  266. #endif
  267. /*
  268. * enable/disable the multi-driver. This is only valid for output and
  269. * allows the output pin to run as an open collector output.
  270. */
  271. int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
  272. {
  273. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  274. u32 mask;
  275. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  276. mask = 1 << pin;
  277. if (is_on)
  278. writel(mask, &pio->port[port].mder);
  279. else
  280. writel(mask, &pio->port[port].mddr);
  281. }
  282. return 0;
  283. }
  284. /*
  285. * assuming the pin is muxed as a gpio output, set its value.
  286. */
  287. int at91_set_pio_value(unsigned port, unsigned pin, int value)
  288. {
  289. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  290. u32 mask;
  291. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  292. mask = 1 << pin;
  293. if (value)
  294. writel(mask, &pio->port[port].sodr);
  295. else
  296. writel(mask, &pio->port[port].codr);
  297. }
  298. return 0;
  299. }
  300. /*
  301. * read the pin's value (works even if it's not muxed as a gpio).
  302. */
  303. int at91_get_pio_value(unsigned port, unsigned pin)
  304. {
  305. u32 pdsr = 0;
  306. at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  307. u32 mask;
  308. if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  309. mask = 1 << pin;
  310. pdsr = readl(&pio->port[port].pdsr) & mask;
  311. }
  312. return pdsr != 0;
  313. }