adi_gpio2.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /*
  2. * ADI GPIO2 Abstraction Layer
  3. * Support BF54x, BF60x and future processors.
  4. *
  5. * Copyright 2008-2013 Analog Devices Inc.
  6. *
  7. * Licensed under the GPL-2 or later
  8. */
  9. #include <common.h>
  10. #include <malloc.h>
  11. #include <linux/bug.h>
  12. #include <linux/errno.h>
  13. #include <asm/gpio.h>
  14. #define RESOURCE_LABEL_SIZE 16
  15. static struct str_ident {
  16. char name[RESOURCE_LABEL_SIZE];
  17. } str_ident[MAX_RESOURCES];
  18. static void gpio_error(unsigned gpio)
  19. {
  20. printf("adi_gpio2: GPIO %d wasn't requested!\n", gpio);
  21. }
  22. static void set_label(unsigned short ident, const char *label)
  23. {
  24. if (label) {
  25. strncpy(str_ident[ident].name, label,
  26. RESOURCE_LABEL_SIZE);
  27. str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
  28. }
  29. }
  30. static char *get_label(unsigned short ident)
  31. {
  32. return *str_ident[ident].name ? str_ident[ident].name : "UNKNOWN";
  33. }
  34. static int cmp_label(unsigned short ident, const char *label)
  35. {
  36. if (label == NULL)
  37. printf("adi_gpio2: please provide none-null label\n");
  38. if (label)
  39. return strcmp(str_ident[ident].name, label);
  40. else
  41. return -EINVAL;
  42. }
  43. #define map_entry(m, i) reserved_##m##_map[gpio_bank(i)]
  44. #define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
  45. #define reserve(m, i) (map_entry(m, i) |= gpio_bit(i))
  46. #define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i))
  47. #define DECLARE_RESERVED_MAP(m, c) unsigned short reserved_##m##_map[c]
  48. static DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
  49. static DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
  50. inline int check_gpio(unsigned gpio)
  51. {
  52. #if defined(CONFIG_BF54x)
  53. if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 ||
  54. gpio == GPIO_PH14 || gpio == GPIO_PH15 ||
  55. gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
  56. return -EINVAL;
  57. #endif
  58. if (gpio >= MAX_GPIOS)
  59. return -EINVAL;
  60. return 0;
  61. }
  62. static void port_setup(unsigned gpio, unsigned short usage)
  63. {
  64. #if defined(CONFIG_BF54x)
  65. if (usage == GPIO_USAGE)
  66. gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
  67. else
  68. gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
  69. #else
  70. if (usage == GPIO_USAGE)
  71. gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio);
  72. else
  73. gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio);
  74. #endif
  75. }
  76. inline void portmux_setup(unsigned short per)
  77. {
  78. u32 pmux;
  79. u16 ident = P_IDENT(per);
  80. u16 function = P_FUNCT2MUX(per);
  81. pmux = gpio_array[gpio_bank(ident)]->port_mux;
  82. pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
  83. pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
  84. gpio_array[gpio_bank(ident)]->port_mux = pmux;
  85. }
  86. inline u16 get_portmux(unsigned short per)
  87. {
  88. u32 pmux;
  89. u16 ident = P_IDENT(per);
  90. pmux = gpio_array[gpio_bank(ident)]->port_mux;
  91. return pmux >> (2 * gpio_sub_n(ident)) & 0x3;
  92. }
  93. unsigned short get_gpio_dir(unsigned gpio)
  94. {
  95. return 0x01 &
  96. (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio));
  97. }
  98. /***********************************************************
  99. *
  100. * FUNCTIONS: Peripheral Resource Allocation
  101. * and PortMux Setup
  102. *
  103. * INPUTS/OUTPUTS:
  104. * per Peripheral Identifier
  105. * label String
  106. *
  107. * DESCRIPTION: Peripheral Resource Allocation and Setup API
  108. **************************************************************/
  109. int peripheral_request(unsigned short per, const char *label)
  110. {
  111. unsigned short ident = P_IDENT(per);
  112. /*
  113. * Don't cares are pins with only one dedicated function
  114. */
  115. if (per & P_DONTCARE)
  116. return 0;
  117. if (!(per & P_DEFINED))
  118. return -EINVAL;
  119. BUG_ON(ident >= MAX_RESOURCES);
  120. /* If a pin can be muxed as either GPIO or peripheral, make
  121. * sure it is not already a GPIO pin when we request it.
  122. */
  123. if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
  124. printf("%s: Peripheral %d is already reserved as GPIO by %s!\n",
  125. __func__, ident, get_label(ident));
  126. return -EBUSY;
  127. }
  128. if (unlikely(is_reserved(peri, ident, 1))) {
  129. /*
  130. * Pin functions like AMC address strobes my
  131. * be requested and used by several drivers
  132. */
  133. if (!((per & P_MAYSHARE) &&
  134. get_portmux(per) == P_FUNCT2MUX(per))) {
  135. /*
  136. * Allow that the identical pin function can
  137. * be requested from the same driver twice
  138. */
  139. if (cmp_label(ident, label) == 0)
  140. goto anyway;
  141. printf("%s: Peripheral %d function %d is already "
  142. "reserved by %s!\n", __func__, ident,
  143. P_FUNCT2MUX(per), get_label(ident));
  144. return -EBUSY;
  145. }
  146. }
  147. anyway:
  148. reserve(peri, ident);
  149. portmux_setup(per);
  150. port_setup(ident, PERIPHERAL_USAGE);
  151. set_label(ident, label);
  152. return 0;
  153. }
  154. int peripheral_request_list(const unsigned short per[], const char *label)
  155. {
  156. u16 cnt;
  157. int ret;
  158. for (cnt = 0; per[cnt] != 0; cnt++) {
  159. ret = peripheral_request(per[cnt], label);
  160. if (ret < 0) {
  161. for (; cnt > 0; cnt--)
  162. peripheral_free(per[cnt - 1]);
  163. return ret;
  164. }
  165. }
  166. return 0;
  167. }
  168. void peripheral_free(unsigned short per)
  169. {
  170. unsigned short ident = P_IDENT(per);
  171. if (per & P_DONTCARE)
  172. return;
  173. if (!(per & P_DEFINED))
  174. return;
  175. if (unlikely(!is_reserved(peri, ident, 0)))
  176. return;
  177. if (!(per & P_MAYSHARE))
  178. port_setup(ident, GPIO_USAGE);
  179. unreserve(peri, ident);
  180. set_label(ident, "free");
  181. }
  182. void peripheral_free_list(const unsigned short per[])
  183. {
  184. u16 cnt;
  185. for (cnt = 0; per[cnt] != 0; cnt++)
  186. peripheral_free(per[cnt]);
  187. }
  188. /***********************************************************
  189. *
  190. * FUNCTIONS: GPIO Driver
  191. *
  192. * INPUTS/OUTPUTS:
  193. * gpio PIO Number between 0 and MAX_GPIOS
  194. * label String
  195. *
  196. * DESCRIPTION: GPIO Driver API
  197. **************************************************************/
  198. int gpio_request(unsigned gpio, const char *label)
  199. {
  200. if (check_gpio(gpio) < 0)
  201. return -EINVAL;
  202. /*
  203. * Allow that the identical GPIO can
  204. * be requested from the same driver twice
  205. * Do nothing and return -
  206. */
  207. if (cmp_label(gpio, label) == 0)
  208. return 0;
  209. if (unlikely(is_reserved(gpio, gpio, 1))) {
  210. printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
  211. gpio, get_label(gpio));
  212. return -EBUSY;
  213. }
  214. if (unlikely(is_reserved(peri, gpio, 1))) {
  215. printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
  216. "by %s!\n", gpio, get_label(gpio));
  217. return -EBUSY;
  218. }
  219. reserve(gpio, gpio);
  220. set_label(gpio, label);
  221. port_setup(gpio, GPIO_USAGE);
  222. return 0;
  223. }
  224. int gpio_free(unsigned gpio)
  225. {
  226. if (check_gpio(gpio) < 0)
  227. return -1;
  228. if (unlikely(!is_reserved(gpio, gpio, 0))) {
  229. gpio_error(gpio);
  230. return -1;
  231. }
  232. unreserve(gpio, gpio);
  233. set_label(gpio, "free");
  234. return 0;
  235. }
  236. #ifdef ADI_SPECIAL_GPIO_BANKS
  237. static DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
  238. int special_gpio_request(unsigned gpio, const char *label)
  239. {
  240. /*
  241. * Allow that the identical GPIO can
  242. * be requested from the same driver twice
  243. * Do nothing and return -
  244. */
  245. if (cmp_label(gpio, label) == 0)
  246. return 0;
  247. if (unlikely(is_reserved(special_gpio, gpio, 1))) {
  248. printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
  249. gpio, get_label(gpio));
  250. return -EBUSY;
  251. }
  252. if (unlikely(is_reserved(peri, gpio, 1))) {
  253. printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
  254. "by %s!\n", gpio, get_label(gpio));
  255. return -EBUSY;
  256. }
  257. reserve(special_gpio, gpio);
  258. reserve(peri, gpio);
  259. set_label(gpio, label);
  260. port_setup(gpio, GPIO_USAGE);
  261. return 0;
  262. }
  263. void special_gpio_free(unsigned gpio)
  264. {
  265. if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
  266. gpio_error(gpio);
  267. return;
  268. }
  269. unreserve(special_gpio, gpio);
  270. unreserve(peri, gpio);
  271. set_label(gpio, "free");
  272. }
  273. #endif
  274. static inline void __gpio_direction_input(unsigned gpio)
  275. {
  276. gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
  277. #if defined(CONFIG_BF54x)
  278. gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
  279. #else
  280. gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio);
  281. #endif
  282. }
  283. int gpio_direction_input(unsigned gpio)
  284. {
  285. unsigned long flags;
  286. if (!is_reserved(gpio, gpio, 0)) {
  287. gpio_error(gpio);
  288. return -EINVAL;
  289. }
  290. local_irq_save(flags);
  291. __gpio_direction_input(gpio);
  292. local_irq_restore(flags);
  293. return 0;
  294. }
  295. int gpio_set_value(unsigned gpio, int arg)
  296. {
  297. if (arg)
  298. gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
  299. else
  300. gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
  301. return 0;
  302. }
  303. int gpio_direction_output(unsigned gpio, int value)
  304. {
  305. unsigned long flags;
  306. if (!is_reserved(gpio, gpio, 0)) {
  307. gpio_error(gpio);
  308. return -EINVAL;
  309. }
  310. local_irq_save(flags);
  311. #if defined(CONFIG_BF54x)
  312. gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
  313. #else
  314. gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio);
  315. #endif
  316. gpio_set_value(gpio, value);
  317. gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
  318. local_irq_restore(flags);
  319. return 0;
  320. }
  321. int gpio_get_value(unsigned gpio)
  322. {
  323. return 1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
  324. }
  325. void gpio_labels(void)
  326. {
  327. int c, gpio;
  328. for (c = 0; c < MAX_RESOURCES; c++) {
  329. gpio = is_reserved(gpio, c, 1);
  330. if (!check_gpio(c) && gpio)
  331. printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c),
  332. get_gpio_dir(c) ? "OUTPUT" : "INPUT");
  333. else if (is_reserved(peri, c, 1))
  334. printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
  335. else
  336. continue;
  337. }
  338. }