gpio-exynos4.c 7.8 KB

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