gpiolib.c 7.4 KB

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