gpiolib.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /* arch/arm/plat-s3c64xx/gpiolib.c
  2. *
  3. * Copyright 2008 Openmoko, Inc.
  4. * Copyright 2008 Simtec Electronics
  5. * Ben Dooks <ben@simtec.co.uk>
  6. * http://armlinux.simtec.co.uk/
  7. *
  8. * S3C64XX - GPIOlib support
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/irq.h>
  16. #include <linux/io.h>
  17. #include <mach/map.h>
  18. #include <mach/gpio.h>
  19. #include <plat/gpio-core.h>
  20. #include <plat/gpio-cfg.h>
  21. #include <plat/gpio-cfg-helpers.h>
  22. #include <mach/regs-gpio.h>
  23. /* GPIO bank summary:
  24. *
  25. * Bank GPIOs Style SlpCon ExtInt Group
  26. * A 8 4Bit Yes 1
  27. * B 7 4Bit Yes 1
  28. * C 8 4Bit Yes 2
  29. * D 5 4Bit Yes 3
  30. * E 5 4Bit Yes None
  31. * F 16 2Bit Yes 4 [1]
  32. * G 7 4Bit Yes 5
  33. * H 10 4Bit[2] Yes 6
  34. * I 16 2Bit Yes None
  35. * J 12 2Bit Yes None
  36. * K 16 4Bit[2] No None
  37. * L 15 4Bit[2] No None
  38. * M 6 4Bit No IRQ_EINT
  39. * N 16 2Bit No IRQ_EINT
  40. * O 16 2Bit Yes 7
  41. * P 15 2Bit Yes 8
  42. * Q 9 2Bit Yes 9
  43. *
  44. * [1] BANKF pins 14,15 do not form part of the external interrupt sources
  45. * [2] BANK has two control registers, GPxCON0 and GPxCON1
  46. */
  47. static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
  48. .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
  49. .set_pull = s3c_gpio_setpull_updown,
  50. .get_pull = s3c_gpio_getpull_updown,
  51. };
  52. static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
  53. .cfg_eint = 7,
  54. .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
  55. .set_pull = s3c_gpio_setpull_updown,
  56. .get_pull = s3c_gpio_getpull_updown,
  57. };
  58. static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
  59. .cfg_eint = 3,
  60. .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
  61. .set_pull = s3c_gpio_setpull_updown,
  62. .get_pull = s3c_gpio_getpull_updown,
  63. };
  64. int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
  65. {
  66. return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
  67. }
  68. static struct s3c_gpio_chip gpio_4bit[] = {
  69. {
  70. .base = S3C64XX_GPA_BASE,
  71. .config = &gpio_4bit_cfg_eint0111,
  72. .chip = {
  73. .base = S3C64XX_GPA(0),
  74. .ngpio = S3C64XX_GPIO_A_NR,
  75. .label = "GPA",
  76. },
  77. }, {
  78. .base = S3C64XX_GPB_BASE,
  79. .config = &gpio_4bit_cfg_eint0111,
  80. .chip = {
  81. .base = S3C64XX_GPB(0),
  82. .ngpio = S3C64XX_GPIO_B_NR,
  83. .label = "GPB",
  84. },
  85. }, {
  86. .base = S3C64XX_GPC_BASE,
  87. .config = &gpio_4bit_cfg_eint0111,
  88. .chip = {
  89. .base = S3C64XX_GPC(0),
  90. .ngpio = S3C64XX_GPIO_C_NR,
  91. .label = "GPC",
  92. },
  93. }, {
  94. .base = S3C64XX_GPD_BASE,
  95. .config = &gpio_4bit_cfg_eint0111,
  96. .chip = {
  97. .base = S3C64XX_GPD(0),
  98. .ngpio = S3C64XX_GPIO_D_NR,
  99. .label = "GPD",
  100. },
  101. }, {
  102. .base = S3C64XX_GPE_BASE,
  103. .config = &gpio_4bit_cfg_noint,
  104. .chip = {
  105. .base = S3C64XX_GPE(0),
  106. .ngpio = S3C64XX_GPIO_E_NR,
  107. .label = "GPE",
  108. },
  109. }, {
  110. .base = S3C64XX_GPG_BASE,
  111. .config = &gpio_4bit_cfg_eint0111,
  112. .chip = {
  113. .base = S3C64XX_GPG(0),
  114. .ngpio = S3C64XX_GPIO_G_NR,
  115. .label = "GPG",
  116. },
  117. }, {
  118. .base = S3C64XX_GPM_BASE,
  119. .config = &gpio_4bit_cfg_eint0011,
  120. .chip = {
  121. .base = S3C64XX_GPM(0),
  122. .ngpio = S3C64XX_GPIO_M_NR,
  123. .label = "GPM",
  124. .to_irq = s3c64xx_gpio2int_gpm,
  125. },
  126. },
  127. };
  128. int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
  129. {
  130. return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
  131. }
  132. static struct s3c_gpio_chip gpio_4bit2[] = {
  133. {
  134. .base = S3C64XX_GPH_BASE + 0x4,
  135. .config = &gpio_4bit_cfg_eint0111,
  136. .chip = {
  137. .base = S3C64XX_GPH(0),
  138. .ngpio = S3C64XX_GPIO_H_NR,
  139. .label = "GPH",
  140. },
  141. }, {
  142. .base = S3C64XX_GPK_BASE + 0x4,
  143. .config = &gpio_4bit_cfg_noint,
  144. .chip = {
  145. .base = S3C64XX_GPK(0),
  146. .ngpio = S3C64XX_GPIO_K_NR,
  147. .label = "GPK",
  148. },
  149. }, {
  150. .base = S3C64XX_GPL_BASE + 0x4,
  151. .config = &gpio_4bit_cfg_eint0011,
  152. .chip = {
  153. .base = S3C64XX_GPL(0),
  154. .ngpio = S3C64XX_GPIO_L_NR,
  155. .label = "GPL",
  156. .to_irq = s3c64xx_gpio2int_gpl,
  157. },
  158. },
  159. };
  160. static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
  161. .set_config = s3c_gpio_setcfg_s3c24xx,
  162. .set_pull = s3c_gpio_setpull_updown,
  163. .get_pull = s3c_gpio_getpull_updown,
  164. };
  165. static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
  166. .cfg_eint = 2,
  167. .set_config = s3c_gpio_setcfg_s3c24xx,
  168. .set_pull = s3c_gpio_setpull_updown,
  169. .get_pull = s3c_gpio_getpull_updown,
  170. };
  171. static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
  172. .cfg_eint = 3,
  173. .set_config = s3c_gpio_setcfg_s3c24xx,
  174. .set_pull = s3c_gpio_setpull_updown,
  175. .get_pull = s3c_gpio_getpull_updown,
  176. };
  177. int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
  178. {
  179. return IRQ_EINT(0) + pin;
  180. }
  181. static struct s3c_gpio_chip gpio_2bit[] = {
  182. {
  183. .base = S3C64XX_GPF_BASE,
  184. .config = &gpio_2bit_cfg_eint11,
  185. .chip = {
  186. .base = S3C64XX_GPF(0),
  187. .ngpio = S3C64XX_GPIO_F_NR,
  188. .label = "GPF",
  189. },
  190. }, {
  191. .base = S3C64XX_GPI_BASE,
  192. .config = &gpio_2bit_cfg_noint,
  193. .chip = {
  194. .base = S3C64XX_GPI(0),
  195. .ngpio = S3C64XX_GPIO_I_NR,
  196. .label = "GPI",
  197. },
  198. }, {
  199. .base = S3C64XX_GPJ_BASE,
  200. .config = &gpio_2bit_cfg_noint,
  201. .chip = {
  202. .base = S3C64XX_GPJ(0),
  203. .ngpio = S3C64XX_GPIO_J_NR,
  204. .label = "GPJ",
  205. },
  206. }, {
  207. .base = S3C64XX_GPN_BASE,
  208. .config = &gpio_2bit_cfg_eint10,
  209. .chip = {
  210. .base = S3C64XX_GPN(0),
  211. .ngpio = S3C64XX_GPIO_N_NR,
  212. .label = "GPN",
  213. .to_irq = s3c64xx_gpio2int_gpn,
  214. },
  215. }, {
  216. .base = S3C64XX_GPO_BASE,
  217. .config = &gpio_2bit_cfg_eint11,
  218. .chip = {
  219. .base = S3C64XX_GPO(0),
  220. .ngpio = S3C64XX_GPIO_O_NR,
  221. .label = "GPO",
  222. },
  223. }, {
  224. .base = S3C64XX_GPP_BASE,
  225. .config = &gpio_2bit_cfg_eint11,
  226. .chip = {
  227. .base = S3C64XX_GPP(0),
  228. .ngpio = S3C64XX_GPIO_P_NR,
  229. .label = "GPP",
  230. },
  231. }, {
  232. .base = S3C64XX_GPQ_BASE,
  233. .config = &gpio_2bit_cfg_eint11,
  234. .chip = {
  235. .base = S3C64XX_GPQ(0),
  236. .ngpio = S3C64XX_GPIO_Q_NR,
  237. .label = "GPQ",
  238. },
  239. },
  240. };
  241. static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
  242. {
  243. chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
  244. }
  245. static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
  246. int nr_chips,
  247. void (*fn)(struct s3c_gpio_chip *))
  248. {
  249. for (; nr_chips > 0; nr_chips--, chips++) {
  250. if (fn)
  251. (fn)(chips);
  252. s3c_gpiolib_add(chips);
  253. }
  254. }
  255. static __init int s3c64xx_gpiolib_init(void)
  256. {
  257. s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
  258. samsung_gpiolib_add_4bit);
  259. s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
  260. samsung_gpiolib_add_4bit2);
  261. s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
  262. s3c64xx_gpiolib_add_2bit);
  263. return 0;
  264. }
  265. core_initcall(s3c64xx_gpiolib_init);