gpio-exynos4.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * EXYNOS4 - GPIOlib support
  3. *
  4. * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
  5. * http://www.samsung.com
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/irq.h>
  13. #include <linux/io.h>
  14. #include <linux/gpio.h>
  15. #include <mach/map.h>
  16. #include <plat/gpio-core.h>
  17. #include <plat/gpio-cfg.h>
  18. #include <plat/gpio-cfg-helpers.h>
  19. static struct s3c_gpio_cfg gpio_cfg = {
  20. .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
  21. .set_pull = s3c_gpio_setpull_updown,
  22. .get_pull = s3c_gpio_getpull_updown,
  23. };
  24. static struct s3c_gpio_cfg gpio_cfg_noint = {
  25. .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
  26. .set_pull = s3c_gpio_setpull_updown,
  27. .get_pull = s3c_gpio_getpull_updown,
  28. };
  29. /*
  30. * Following are the gpio banks in v310.
  31. *
  32. * The 'config' member when left to NULL, is initialized to the default
  33. * structure gpio_cfg in the init function below.
  34. *
  35. * The 'base' member is also initialized in the init function below.
  36. * Note: The initialization of 'base' member of s3c_gpio_chip structure
  37. * uses the above macro and depends on the banks being listed in order here.
  38. */
  39. static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
  40. {
  41. .chip = {
  42. .base = EXYNOS4_GPA0(0),
  43. .ngpio = EXYNOS4_GPIO_A0_NR,
  44. .label = "GPA0",
  45. },
  46. }, {
  47. .chip = {
  48. .base = EXYNOS4_GPA1(0),
  49. .ngpio = EXYNOS4_GPIO_A1_NR,
  50. .label = "GPA1",
  51. },
  52. }, {
  53. .chip = {
  54. .base = EXYNOS4_GPB(0),
  55. .ngpio = EXYNOS4_GPIO_B_NR,
  56. .label = "GPB",
  57. },
  58. }, {
  59. .chip = {
  60. .base = EXYNOS4_GPC0(0),
  61. .ngpio = EXYNOS4_GPIO_C0_NR,
  62. .label = "GPC0",
  63. },
  64. }, {
  65. .chip = {
  66. .base = EXYNOS4_GPC1(0),
  67. .ngpio = EXYNOS4_GPIO_C1_NR,
  68. .label = "GPC1",
  69. },
  70. }, {
  71. .chip = {
  72. .base = EXYNOS4_GPD0(0),
  73. .ngpio = EXYNOS4_GPIO_D0_NR,
  74. .label = "GPD0",
  75. },
  76. }, {
  77. .chip = {
  78. .base = EXYNOS4_GPD1(0),
  79. .ngpio = EXYNOS4_GPIO_D1_NR,
  80. .label = "GPD1",
  81. },
  82. }, {
  83. .chip = {
  84. .base = EXYNOS4_GPE0(0),
  85. .ngpio = EXYNOS4_GPIO_E0_NR,
  86. .label = "GPE0",
  87. },
  88. }, {
  89. .chip = {
  90. .base = EXYNOS4_GPE1(0),
  91. .ngpio = EXYNOS4_GPIO_E1_NR,
  92. .label = "GPE1",
  93. },
  94. }, {
  95. .chip = {
  96. .base = EXYNOS4_GPE2(0),
  97. .ngpio = EXYNOS4_GPIO_E2_NR,
  98. .label = "GPE2",
  99. },
  100. }, {
  101. .chip = {
  102. .base = EXYNOS4_GPE3(0),
  103. .ngpio = EXYNOS4_GPIO_E3_NR,
  104. .label = "GPE3",
  105. },
  106. }, {
  107. .chip = {
  108. .base = EXYNOS4_GPE4(0),
  109. .ngpio = EXYNOS4_GPIO_E4_NR,
  110. .label = "GPE4",
  111. },
  112. }, {
  113. .chip = {
  114. .base = EXYNOS4_GPF0(0),
  115. .ngpio = EXYNOS4_GPIO_F0_NR,
  116. .label = "GPF0",
  117. },
  118. }, {
  119. .chip = {
  120. .base = EXYNOS4_GPF1(0),
  121. .ngpio = EXYNOS4_GPIO_F1_NR,
  122. .label = "GPF1",
  123. },
  124. }, {
  125. .chip = {
  126. .base = EXYNOS4_GPF2(0),
  127. .ngpio = EXYNOS4_GPIO_F2_NR,
  128. .label = "GPF2",
  129. },
  130. }, {
  131. .chip = {
  132. .base = EXYNOS4_GPF3(0),
  133. .ngpio = EXYNOS4_GPIO_F3_NR,
  134. .label = "GPF3",
  135. },
  136. },
  137. };
  138. static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
  139. {
  140. .chip = {
  141. .base = EXYNOS4_GPJ0(0),
  142. .ngpio = EXYNOS4_GPIO_J0_NR,
  143. .label = "GPJ0",
  144. },
  145. }, {
  146. .chip = {
  147. .base = EXYNOS4_GPJ1(0),
  148. .ngpio = EXYNOS4_GPIO_J1_NR,
  149. .label = "GPJ1",
  150. },
  151. }, {
  152. .chip = {
  153. .base = EXYNOS4_GPK0(0),
  154. .ngpio = EXYNOS4_GPIO_K0_NR,
  155. .label = "GPK0",
  156. },
  157. }, {
  158. .chip = {
  159. .base = EXYNOS4_GPK1(0),
  160. .ngpio = EXYNOS4_GPIO_K1_NR,
  161. .label = "GPK1",
  162. },
  163. }, {
  164. .chip = {
  165. .base = EXYNOS4_GPK2(0),
  166. .ngpio = EXYNOS4_GPIO_K2_NR,
  167. .label = "GPK2",
  168. },
  169. }, {
  170. .chip = {
  171. .base = EXYNOS4_GPK3(0),
  172. .ngpio = EXYNOS4_GPIO_K3_NR,
  173. .label = "GPK3",
  174. },
  175. }, {
  176. .chip = {
  177. .base = EXYNOS4_GPL0(0),
  178. .ngpio = EXYNOS4_GPIO_L0_NR,
  179. .label = "GPL0",
  180. },
  181. }, {
  182. .chip = {
  183. .base = EXYNOS4_GPL1(0),
  184. .ngpio = EXYNOS4_GPIO_L1_NR,
  185. .label = "GPL1",
  186. },
  187. }, {
  188. .chip = {
  189. .base = EXYNOS4_GPL2(0),
  190. .ngpio = EXYNOS4_GPIO_L2_NR,
  191. .label = "GPL2",
  192. },
  193. }, {
  194. .config = &gpio_cfg_noint,
  195. .chip = {
  196. .base = EXYNOS4_GPY0(0),
  197. .ngpio = EXYNOS4_GPIO_Y0_NR,
  198. .label = "GPY0",
  199. },
  200. }, {
  201. .config = &gpio_cfg_noint,
  202. .chip = {
  203. .base = EXYNOS4_GPY1(0),
  204. .ngpio = EXYNOS4_GPIO_Y1_NR,
  205. .label = "GPY1",
  206. },
  207. }, {
  208. .config = &gpio_cfg_noint,
  209. .chip = {
  210. .base = EXYNOS4_GPY2(0),
  211. .ngpio = EXYNOS4_GPIO_Y2_NR,
  212. .label = "GPY2",
  213. },
  214. }, {
  215. .config = &gpio_cfg_noint,
  216. .chip = {
  217. .base = EXYNOS4_GPY3(0),
  218. .ngpio = EXYNOS4_GPIO_Y3_NR,
  219. .label = "GPY3",
  220. },
  221. }, {
  222. .config = &gpio_cfg_noint,
  223. .chip = {
  224. .base = EXYNOS4_GPY4(0),
  225. .ngpio = EXYNOS4_GPIO_Y4_NR,
  226. .label = "GPY4",
  227. },
  228. }, {
  229. .config = &gpio_cfg_noint,
  230. .chip = {
  231. .base = EXYNOS4_GPY5(0),
  232. .ngpio = EXYNOS4_GPIO_Y5_NR,
  233. .label = "GPY5",
  234. },
  235. }, {
  236. .config = &gpio_cfg_noint,
  237. .chip = {
  238. .base = EXYNOS4_GPY6(0),
  239. .ngpio = EXYNOS4_GPIO_Y6_NR,
  240. .label = "GPY6",
  241. },
  242. }, {
  243. .base = (S5P_VA_GPIO2 + 0xC00),
  244. .config = &gpio_cfg_noint,
  245. .irq_base = IRQ_EINT(0),
  246. .chip = {
  247. .base = EXYNOS4_GPX0(0),
  248. .ngpio = EXYNOS4_GPIO_X0_NR,
  249. .label = "GPX0",
  250. .to_irq = samsung_gpiolib_to_irq,
  251. },
  252. }, {
  253. .base = (S5P_VA_GPIO2 + 0xC20),
  254. .config = &gpio_cfg_noint,
  255. .irq_base = IRQ_EINT(8),
  256. .chip = {
  257. .base = EXYNOS4_GPX1(0),
  258. .ngpio = EXYNOS4_GPIO_X1_NR,
  259. .label = "GPX1",
  260. .to_irq = samsung_gpiolib_to_irq,
  261. },
  262. }, {
  263. .base = (S5P_VA_GPIO2 + 0xC40),
  264. .config = &gpio_cfg_noint,
  265. .irq_base = IRQ_EINT(16),
  266. .chip = {
  267. .base = EXYNOS4_GPX2(0),
  268. .ngpio = EXYNOS4_GPIO_X2_NR,
  269. .label = "GPX2",
  270. .to_irq = samsung_gpiolib_to_irq,
  271. },
  272. }, {
  273. .base = (S5P_VA_GPIO2 + 0xC60),
  274. .config = &gpio_cfg_noint,
  275. .irq_base = IRQ_EINT(24),
  276. .chip = {
  277. .base = EXYNOS4_GPX3(0),
  278. .ngpio = EXYNOS4_GPIO_X3_NR,
  279. .label = "GPX3",
  280. .to_irq = samsung_gpiolib_to_irq,
  281. },
  282. },
  283. };
  284. static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
  285. {
  286. .chip = {
  287. .base = EXYNOS4_GPZ(0),
  288. .ngpio = EXYNOS4_GPIO_Z_NR,
  289. .label = "GPZ",
  290. },
  291. },
  292. };
  293. static __init int exynos4_gpiolib_init(void)
  294. {
  295. struct s3c_gpio_chip *chip;
  296. int i;
  297. int group = 0;
  298. int nr_chips;
  299. /* GPIO part 1 */
  300. chip = exynos4_gpio_part1_4bit;
  301. nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
  302. for (i = 0; i < nr_chips; i++, chip++) {
  303. if (chip->config == NULL) {
  304. chip->config = &gpio_cfg;
  305. /* Assign the GPIO interrupt group */
  306. chip->group = group++;
  307. }
  308. if (chip->base == NULL)
  309. chip->base = S5P_VA_GPIO1 + (i) * 0x20;
  310. }
  311. samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
  312. /* GPIO part 2 */
  313. chip = exynos4_gpio_part2_4bit;
  314. nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
  315. for (i = 0; i < nr_chips; i++, chip++) {
  316. if (chip->config == NULL) {
  317. chip->config = &gpio_cfg;
  318. /* Assign the GPIO interrupt group */
  319. chip->group = group++;
  320. }
  321. if (chip->base == NULL)
  322. chip->base = S5P_VA_GPIO2 + (i) * 0x20;
  323. }
  324. samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
  325. /* GPIO part 3 */
  326. chip = exynos4_gpio_part3_4bit;
  327. nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
  328. for (i = 0; i < nr_chips; i++, chip++) {
  329. if (chip->config == NULL) {
  330. chip->config = &gpio_cfg;
  331. /* Assign the GPIO interrupt group */
  332. chip->group = group++;
  333. }
  334. if (chip->base == NULL)
  335. chip->base = S5P_VA_GPIO3 + (i) * 0x20;
  336. }
  337. samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
  338. s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
  339. s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
  340. return 0;
  341. }
  342. core_initcall(exynos4_gpiolib_init);