gpio.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2009
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #include <asm/arch/gpio.h>
  24. static struct gpio_register *addr_gpio_register[] = {
  25. (void *)U8500_GPIO_0_BASE,
  26. (void *)U8500_GPIO_1_BASE,
  27. (void *)U8500_GPIO_2_BASE,
  28. (void *)U8500_GPIO_3_BASE,
  29. (void *)U8500_GPIO_4_BASE,
  30. (void *)U8500_GPIO_5_BASE,
  31. (void *)U8500_GPIO_6_BASE,
  32. (void *)U8500_GPIO_7_BASE,
  33. (void *)U8500_GPIO_8_BASE,
  34. };
  35. struct gpio_altfun_data altfun_table[] = {
  36. {
  37. .altfun = GPIO_ALT_I2C_0,
  38. .start = 147,
  39. .end = 148,
  40. .cont = 0,
  41. .type = GPIO_ALTF_A,
  42. },
  43. {
  44. .altfun = GPIO_ALT_I2C_1,
  45. .start = 16,
  46. .end = 17,
  47. .cont = 0,
  48. .type = GPIO_ALTF_B,
  49. },
  50. {
  51. .altfun = GPIO_ALT_I2C_2,
  52. .start = 10,
  53. .end = 11,
  54. .cont = 0,
  55. .type = GPIO_ALTF_B,
  56. },
  57. {
  58. .altfun = GPIO_ALT_I2C_3,
  59. .start = 229,
  60. .end = 230,
  61. .cont = 0,
  62. .type = GPIO_ALTF_C,
  63. },
  64. {
  65. .altfun = GPIO_ALT_UART_0_MODEM,
  66. .start = 0,
  67. .end = 3,
  68. .cont = 1,
  69. .type = GPIO_ALTF_A,
  70. },
  71. {
  72. .altfun = GPIO_ALT_UART_0_MODEM,
  73. .start = 33,
  74. .end = 36,
  75. .cont = 0,
  76. .type = GPIO_ALTF_C,
  77. },
  78. {
  79. .altfun = GPIO_ALT_UART_1,
  80. .start = 4,
  81. .end = 7,
  82. .cont = 0,
  83. .type =
  84. GPIO_ALTF_A,
  85. },
  86. {
  87. .altfun = GPIO_ALT_UART_2,
  88. .start = 18,
  89. .end = 19,
  90. .cont = 1,
  91. .type = GPIO_ALTF_B,
  92. },
  93. {
  94. .altfun = GPIO_ALT_UART_2,
  95. .start = 29,
  96. .end = 32,
  97. .cont = 0,
  98. .type = GPIO_ALTF_C,
  99. },
  100. {
  101. .altfun = GPIO_ALT_MSP_0,
  102. .start = 12,
  103. .end = 17,
  104. .cont = 1,
  105. .type = GPIO_ALTF_A,
  106. },
  107. {
  108. .altfun = GPIO_ALT_MSP_0,
  109. .start = 21,
  110. .end = 21,
  111. .cont = 0,
  112. .type = GPIO_ALTF_B,
  113. },
  114. {
  115. .altfun = GPIO_ALT_MSP_1,
  116. .start = 33,
  117. .end = 36,
  118. .cont = 0,
  119. .type = GPIO_ALTF_A,
  120. },
  121. {
  122. .altfun = GPIO_ALT_MSP_2,
  123. .start = 192,
  124. .end = 196,
  125. .cont = 0,
  126. .type = GPIO_ALTF_A,
  127. },
  128. {
  129. .altfun = GPIO_ALT_LCD_PANEL,
  130. .start = 64,
  131. .end = 93,
  132. .cont = 1,
  133. .type = GPIO_ALTF_A,
  134. },
  135. {
  136. .altfun = GPIO_ALT_LCD_PANEL,
  137. .start = 150,
  138. .end = 171,
  139. .cont = 0,
  140. .type = GPIO_ALTF_B,
  141. },
  142. {
  143. .altfun = GPIO_ALT_SD_CARD0,
  144. .start = 18,
  145. .end = 28,
  146. .cont = 0,
  147. .type = GPIO_ALTF_A,
  148. },
  149. {
  150. .altfun = GPIO_ALT_MM_CARD0,
  151. .start = 18,
  152. .end = 32,
  153. .cont = 0,
  154. .type = GPIO_ALTF_A,
  155. },
  156. {
  157. .altfun = GPIO_ALT_USB_OTG,
  158. .start = 256,
  159. .end = 267,
  160. .cont = 0,
  161. .type = GPIO_ALTF_A,
  162. },
  163. {
  164. .altfun = GPIO_ALT_EMMC,
  165. .start = 197,
  166. .end = 207,
  167. .cont = 0,
  168. .type = GPIO_ALTF_A,
  169. },
  170. {
  171. .altfun = GPIO_ALT_POP_EMMC,
  172. .start = 128,
  173. .end = 138,
  174. .cont = 0,
  175. .type = GPIO_ALTF_A,
  176. },
  177. };
  178. /*
  179. * Static Function declarations
  180. */
  181. enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
  182. {
  183. struct gpio_register *p_gpio_register =
  184. addr_gpio_register[GPIO_BLOCK(pin_id)];
  185. u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
  186. enum gpio_error error = GPIO_OK;
  187. u32 temp_reg;
  188. switch (config->mode) {
  189. case GPIO_ALTF_A:
  190. temp_reg = readl(&p_gpio_register->gpio_afsa);
  191. temp_reg |= mask;
  192. writel(temp_reg, &p_gpio_register->gpio_afsa);
  193. temp_reg = readl(&p_gpio_register->gpio_afsb);
  194. temp_reg &= ~mask;
  195. writel(temp_reg, &p_gpio_register->gpio_afsb);
  196. break;
  197. case GPIO_ALTF_B:
  198. temp_reg = readl(&p_gpio_register->gpio_afsa);
  199. temp_reg &= ~mask;
  200. writel(temp_reg, &p_gpio_register->gpio_afsa);
  201. temp_reg = readl(&p_gpio_register->gpio_afsb);
  202. temp_reg |= mask;
  203. writel(temp_reg, &p_gpio_register->gpio_afsb);
  204. break;
  205. case GPIO_ALTF_C:
  206. temp_reg = readl(&p_gpio_register->gpio_afsa);
  207. temp_reg |= mask;
  208. writel(temp_reg, &p_gpio_register->gpio_afsa);
  209. temp_reg = readl(&p_gpio_register->gpio_afsb);
  210. temp_reg |= mask;
  211. writel(temp_reg, &p_gpio_register->gpio_afsb);
  212. break;
  213. case GPIO_MODE_SOFTWARE:
  214. temp_reg = readl(&p_gpio_register->gpio_afsa);
  215. temp_reg &= ~mask;
  216. writel(temp_reg, &p_gpio_register->gpio_afsa);
  217. temp_reg = readl(&p_gpio_register->gpio_afsb);
  218. temp_reg &= ~mask;
  219. writel(temp_reg, &p_gpio_register->gpio_afsb);
  220. switch (config->direction) {
  221. case GPIO_DIR_INPUT:
  222. writel(mask, &p_gpio_register->gpio_dirc);
  223. break;
  224. case GPIO_DIR_OUTPUT:
  225. writel(mask, &p_gpio_register->gpio_dirs);
  226. break;
  227. case GPIO_DIR_LEAVE_UNCHANGED:
  228. break;
  229. default:
  230. return GPIO_INVALID_PARAMETER;
  231. }
  232. break;
  233. case GPIO_MODE_LEAVE_UNCHANGED:
  234. break;
  235. default:
  236. return GPIO_INVALID_PARAMETER;
  237. }
  238. return error;
  239. }
  240. enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
  241. {
  242. struct gpio_register *p_gpio_register =
  243. addr_gpio_register[GPIO_BLOCK(pin_id)];
  244. u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
  245. enum gpio_error error = GPIO_OK;
  246. u32 temp_reg;
  247. temp_reg = readl(&p_gpio_register->gpio_afsa);
  248. temp_reg &= ~mask;
  249. writel(temp_reg, &p_gpio_register->gpio_afsa);
  250. temp_reg = readl(&p_gpio_register->gpio_afsb);
  251. temp_reg &= ~mask;
  252. writel(temp_reg, &p_gpio_register->gpio_afsb);
  253. writel(mask, &p_gpio_register->gpio_dirc);
  254. return error;
  255. }
  256. struct gpio_config altfun_pinconfig;
  257. enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
  258. int which_altfunc, char *dev_name)
  259. {
  260. int i, j, start, end;
  261. enum gpio_error error = -1;
  262. for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
  263. if (altfun_table[i].altfun != alt_func)
  264. continue;
  265. start = altfun_table[i].start;
  266. end = altfun_table[i].end;
  267. for (j = start; j <= end; j++) {
  268. if (which_altfunc == GPIO_ALTF_FIND)
  269. altfun_pinconfig.mode = altfun_table[i].type;
  270. else
  271. altfun_pinconfig.mode = which_altfunc;
  272. altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
  273. altfun_pinconfig.dev_name = dev_name;
  274. if (which_altfunc != GPIO_ALTF_DISABLE)
  275. error = gpio_setpinconfig(j, &altfun_pinconfig);
  276. else
  277. error = gpio_resetgpiopin(j, dev_name);
  278. if (!error)
  279. continue;
  280. printf("GPIO %d configuration failure (nmdk_error:%d)",
  281. j, error);
  282. error = GPIO_INVALID_PARAMETER;
  283. return error;
  284. }
  285. if (!altfun_table[i].cont)
  286. break;
  287. }
  288. return error;
  289. }
  290. int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
  291. {
  292. struct gpio_register *p_gpio_register =
  293. addr_gpio_register[GPIO_BLOCK(pin_id)];
  294. u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
  295. switch (value) {
  296. case GPIO_DATA_HIGH:
  297. writel(mask, &p_gpio_register->gpio_dats);
  298. break;
  299. case GPIO_DATA_LOW:
  300. writel(mask, &p_gpio_register->gpio_datc);
  301. break;
  302. default:
  303. printf("Invalid value passed in %s", __FUNCTION__);
  304. return GPIO_INVALID_PARAMETER;
  305. }
  306. return GPIO_OK;
  307. }
  308. int gpio_readpin(int pin_id, enum gpio_data *rv)
  309. {
  310. struct gpio_register *p_gpio_register =
  311. addr_gpio_register[GPIO_BLOCK(pin_id)];
  312. u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
  313. if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
  314. *rv = GPIO_DATA_HIGH;
  315. else
  316. *rv = GPIO_DATA_LOW;
  317. return GPIO_OK;
  318. }
  319. int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
  320. {
  321. return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
  322. }
  323. int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
  324. {
  325. return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
  326. }