gpiolib.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /* linux/arch/arm/mach-s5pv210/gpiolib.c
  2. *
  3. * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  4. * http://www.samsung.com/
  5. *
  6. * S5PV210 - 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 <plat/gpio-core.h>
  17. #include <plat/gpio-cfg.h>
  18. #include <plat/gpio-cfg-helpers.h>
  19. #include <mach/map.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. /* GPIO bank's base address given the index of the bank in the
  31. * list of all gpio banks.
  32. */
  33. #define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
  34. /*
  35. * Following are the gpio banks in v210.
  36. *
  37. * The 'config' member when left to NULL, is initialized to the default
  38. * structure gpio_cfg in the init function below.
  39. *
  40. * The 'base' member is also initialized in the init function below.
  41. * Note: The initialization of 'base' member of s3c_gpio_chip structure
  42. * uses the above macro and depends on the banks being listed in order here.
  43. */
  44. static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
  45. {
  46. .chip = {
  47. .base = S5PV210_GPA0(0),
  48. .ngpio = S5PV210_GPIO_A0_NR,
  49. .label = "GPA0",
  50. },
  51. }, {
  52. .chip = {
  53. .base = S5PV210_GPA1(0),
  54. .ngpio = S5PV210_GPIO_A1_NR,
  55. .label = "GPA1",
  56. },
  57. }, {
  58. .chip = {
  59. .base = S5PV210_GPB(0),
  60. .ngpio = S5PV210_GPIO_B_NR,
  61. .label = "GPB",
  62. },
  63. }, {
  64. .chip = {
  65. .base = S5PV210_GPC0(0),
  66. .ngpio = S5PV210_GPIO_C0_NR,
  67. .label = "GPC0",
  68. },
  69. }, {
  70. .chip = {
  71. .base = S5PV210_GPC1(0),
  72. .ngpio = S5PV210_GPIO_C1_NR,
  73. .label = "GPC1",
  74. },
  75. }, {
  76. .chip = {
  77. .base = S5PV210_GPD0(0),
  78. .ngpio = S5PV210_GPIO_D0_NR,
  79. .label = "GPD0",
  80. },
  81. }, {
  82. .chip = {
  83. .base = S5PV210_GPD1(0),
  84. .ngpio = S5PV210_GPIO_D1_NR,
  85. .label = "GPD1",
  86. },
  87. }, {
  88. .chip = {
  89. .base = S5PV210_GPE0(0),
  90. .ngpio = S5PV210_GPIO_E0_NR,
  91. .label = "GPE0",
  92. },
  93. }, {
  94. .chip = {
  95. .base = S5PV210_GPE1(0),
  96. .ngpio = S5PV210_GPIO_E1_NR,
  97. .label = "GPE1",
  98. },
  99. }, {
  100. .chip = {
  101. .base = S5PV210_GPF0(0),
  102. .ngpio = S5PV210_GPIO_F0_NR,
  103. .label = "GPF0",
  104. },
  105. }, {
  106. .chip = {
  107. .base = S5PV210_GPF1(0),
  108. .ngpio = S5PV210_GPIO_F1_NR,
  109. .label = "GPF1",
  110. },
  111. }, {
  112. .chip = {
  113. .base = S5PV210_GPF2(0),
  114. .ngpio = S5PV210_GPIO_F2_NR,
  115. .label = "GPF2",
  116. },
  117. }, {
  118. .chip = {
  119. .base = S5PV210_GPF3(0),
  120. .ngpio = S5PV210_GPIO_F3_NR,
  121. .label = "GPF3",
  122. },
  123. }, {
  124. .chip = {
  125. .base = S5PV210_GPG0(0),
  126. .ngpio = S5PV210_GPIO_G0_NR,
  127. .label = "GPG0",
  128. },
  129. }, {
  130. .chip = {
  131. .base = S5PV210_GPG1(0),
  132. .ngpio = S5PV210_GPIO_G1_NR,
  133. .label = "GPG1",
  134. },
  135. }, {
  136. .chip = {
  137. .base = S5PV210_GPG2(0),
  138. .ngpio = S5PV210_GPIO_G2_NR,
  139. .label = "GPG2",
  140. },
  141. }, {
  142. .chip = {
  143. .base = S5PV210_GPG3(0),
  144. .ngpio = S5PV210_GPIO_G3_NR,
  145. .label = "GPG3",
  146. },
  147. }, {
  148. .config = &gpio_cfg_noint,
  149. .chip = {
  150. .base = S5PV210_GPI(0),
  151. .ngpio = S5PV210_GPIO_I_NR,
  152. .label = "GPI",
  153. },
  154. }, {
  155. .chip = {
  156. .base = S5PV210_GPJ0(0),
  157. .ngpio = S5PV210_GPIO_J0_NR,
  158. .label = "GPJ0",
  159. },
  160. }, {
  161. .chip = {
  162. .base = S5PV210_GPJ1(0),
  163. .ngpio = S5PV210_GPIO_J1_NR,
  164. .label = "GPJ1",
  165. },
  166. }, {
  167. .chip = {
  168. .base = S5PV210_GPJ2(0),
  169. .ngpio = S5PV210_GPIO_J2_NR,
  170. .label = "GPJ2",
  171. },
  172. }, {
  173. .chip = {
  174. .base = S5PV210_GPJ3(0),
  175. .ngpio = S5PV210_GPIO_J3_NR,
  176. .label = "GPJ3",
  177. },
  178. }, {
  179. .chip = {
  180. .base = S5PV210_GPJ4(0),
  181. .ngpio = S5PV210_GPIO_J4_NR,
  182. .label = "GPJ4",
  183. },
  184. }, {
  185. .config = &gpio_cfg_noint,
  186. .chip = {
  187. .base = S5PV210_MP01(0),
  188. .ngpio = S5PV210_GPIO_MP01_NR,
  189. .label = "MP01",
  190. },
  191. }, {
  192. .config = &gpio_cfg_noint,
  193. .chip = {
  194. .base = S5PV210_MP02(0),
  195. .ngpio = S5PV210_GPIO_MP02_NR,
  196. .label = "MP02",
  197. },
  198. }, {
  199. .config = &gpio_cfg_noint,
  200. .chip = {
  201. .base = S5PV210_MP03(0),
  202. .ngpio = S5PV210_GPIO_MP03_NR,
  203. .label = "MP03",
  204. },
  205. }, {
  206. .config = &gpio_cfg_noint,
  207. .chip = {
  208. .base = S5PV210_MP04(0),
  209. .ngpio = S5PV210_GPIO_MP04_NR,
  210. .label = "MP04",
  211. },
  212. }, {
  213. .config = &gpio_cfg_noint,
  214. .chip = {
  215. .base = S5PV210_MP05(0),
  216. .ngpio = S5PV210_GPIO_MP05_NR,
  217. .label = "MP05",
  218. },
  219. }, {
  220. .base = (S5P_VA_GPIO + 0xC00),
  221. .config = &gpio_cfg_noint,
  222. .irq_base = IRQ_EINT(0),
  223. .chip = {
  224. .base = S5PV210_GPH0(0),
  225. .ngpio = S5PV210_GPIO_H0_NR,
  226. .label = "GPH0",
  227. .to_irq = samsung_gpiolib_to_irq,
  228. },
  229. }, {
  230. .base = (S5P_VA_GPIO + 0xC20),
  231. .config = &gpio_cfg_noint,
  232. .irq_base = IRQ_EINT(8),
  233. .chip = {
  234. .base = S5PV210_GPH1(0),
  235. .ngpio = S5PV210_GPIO_H1_NR,
  236. .label = "GPH1",
  237. .to_irq = samsung_gpiolib_to_irq,
  238. },
  239. }, {
  240. .base = (S5P_VA_GPIO + 0xC40),
  241. .config = &gpio_cfg_noint,
  242. .irq_base = IRQ_EINT(16),
  243. .chip = {
  244. .base = S5PV210_GPH2(0),
  245. .ngpio = S5PV210_GPIO_H2_NR,
  246. .label = "GPH2",
  247. .to_irq = samsung_gpiolib_to_irq,
  248. },
  249. }, {
  250. .base = (S5P_VA_GPIO + 0xC60),
  251. .config = &gpio_cfg_noint,
  252. .irq_base = IRQ_EINT(24),
  253. .chip = {
  254. .base = S5PV210_GPH3(0),
  255. .ngpio = S5PV210_GPIO_H3_NR,
  256. .label = "GPH3",
  257. .to_irq = samsung_gpiolib_to_irq,
  258. },
  259. },
  260. };
  261. static __init int s5pv210_gpiolib_init(void)
  262. {
  263. struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
  264. int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
  265. int gpioint_group = 0;
  266. int i = 0;
  267. for (i = 0; i < nr_chips; i++, chip++) {
  268. if (chip->config == NULL) {
  269. chip->config = &gpio_cfg;
  270. chip->group = gpioint_group++;
  271. }
  272. if (chip->base == NULL)
  273. chip->base = S5PV210_BANK_BASE(i);
  274. }
  275. samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
  276. s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
  277. return 0;
  278. }
  279. core_initcall(s5pv210_gpiolib_init);