gpiolib.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /* linux/arch/arm/plat-s3c24xx/gpiolib.c
  2. *
  3. * Copyright (c) 2008 Simtec Electronics
  4. * http://armlinux.simtec.co.uk/
  5. * Ben Dooks <ben@simtec.co.uk>
  6. *
  7. * S3C24XX GPIOlib support
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/ioport.h>
  18. #include <linux/io.h>
  19. #include <linux/gpio.h>
  20. #include <mach/hardware.h>
  21. #include <asm/irq.h>
  22. #include <mach/regs-gpio.h>
  23. struct s3c24xx_gpio_chip {
  24. struct gpio_chip chip;
  25. void __iomem *base;
  26. };
  27. static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc)
  28. {
  29. return container_of(gpc, struct s3c24xx_gpio_chip, chip);
  30. }
  31. /* these routines are exported for use by other parts of the platform
  32. * and system support, but are not intended to be used directly by the
  33. * drivers themsevles.
  34. */
  35. static int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
  36. {
  37. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  38. void __iomem *base = ourchip->base;
  39. unsigned long flags;
  40. unsigned long con;
  41. local_irq_save(flags);
  42. con = __raw_readl(base + 0x00);
  43. con &= ~(3 << (offset * 2));
  44. con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2);
  45. __raw_writel(con, base + 0x00);
  46. local_irq_restore(flags);
  47. return 0;
  48. }
  49. static int s3c24xx_gpiolib_output(struct gpio_chip *chip,
  50. unsigned offset, int value)
  51. {
  52. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  53. void __iomem *base = ourchip->base;
  54. unsigned long flags;
  55. unsigned long dat;
  56. unsigned long con;
  57. local_irq_save(flags);
  58. dat = __raw_readl(base + 0x04);
  59. dat &= ~(1 << offset);
  60. if (value)
  61. dat |= 1 << offset;
  62. __raw_writel(dat, base + 0x04);
  63. con = __raw_readl(base + 0x00);
  64. con &= ~(3 << (offset * 2));
  65. con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2);
  66. __raw_writel(con, base + 0x00);
  67. __raw_writel(dat, base + 0x04);
  68. local_irq_restore(flags);
  69. return 0;
  70. }
  71. static void s3c24xx_gpiolib_set(struct gpio_chip *chip,
  72. unsigned offset, int value)
  73. {
  74. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  75. void __iomem *base = ourchip->base;
  76. unsigned long flags;
  77. unsigned long dat;
  78. local_irq_save(flags);
  79. dat = __raw_readl(base + 0x04);
  80. dat &= ~(1 << offset);
  81. if (value)
  82. dat |= 1 << offset;
  83. __raw_writel(dat, base + 0x04);
  84. local_irq_restore(flags);
  85. }
  86. static int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset)
  87. {
  88. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  89. unsigned long val;
  90. val = __raw_readl(ourchip->base + 0x04);
  91. val >>= offset;
  92. val &= 1;
  93. return val;
  94. }
  95. static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
  96. {
  97. return -EINVAL;
  98. }
  99. static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
  100. unsigned offset, int value)
  101. {
  102. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  103. void __iomem *base = ourchip->base;
  104. unsigned long flags;
  105. unsigned long dat;
  106. unsigned long con;
  107. local_irq_save(flags);
  108. con = __raw_readl(base + 0x00);
  109. dat = __raw_readl(base + 0x04);
  110. dat &= ~(1 << offset);
  111. if (value)
  112. dat |= 1 << offset;
  113. __raw_writel(dat, base + 0x04);
  114. con &= ~(1 << offset);
  115. __raw_writel(con, base + 0x00);
  116. __raw_writel(dat, base + 0x04);
  117. local_irq_restore(flags);
  118. return 0;
  119. }
  120. static struct s3c24xx_gpio_chip gpios[] = {
  121. [0] = {
  122. .base = S3C24XX_GPIO_BASE(S3C2410_GPA0),
  123. .chip = {
  124. .base = S3C2410_GPA0,
  125. .owner = THIS_MODULE,
  126. .label = "GPIOA",
  127. .ngpio = 24,
  128. .direction_input = s3c24xx_gpiolib_banka_input,
  129. .direction_output = s3c24xx_gpiolib_banka_output,
  130. .set = s3c24xx_gpiolib_set,
  131. .get = s3c24xx_gpiolib_get,
  132. },
  133. },
  134. [1] = {
  135. .base = S3C24XX_GPIO_BASE(S3C2410_GPB0),
  136. .chip = {
  137. .base = S3C2410_GPB0,
  138. .owner = THIS_MODULE,
  139. .label = "GPIOB",
  140. .ngpio = 16,
  141. .direction_input = s3c24xx_gpiolib_input,
  142. .direction_output = s3c24xx_gpiolib_output,
  143. .set = s3c24xx_gpiolib_set,
  144. .get = s3c24xx_gpiolib_get,
  145. },
  146. },
  147. [2] = {
  148. .base = S3C24XX_GPIO_BASE(S3C2410_GPC0),
  149. .chip = {
  150. .base = S3C2410_GPC0,
  151. .owner = THIS_MODULE,
  152. .label = "GPIOC",
  153. .ngpio = 16,
  154. .direction_input = s3c24xx_gpiolib_input,
  155. .direction_output = s3c24xx_gpiolib_output,
  156. .set = s3c24xx_gpiolib_set,
  157. .get = s3c24xx_gpiolib_get,
  158. },
  159. },
  160. [3] = {
  161. .base = S3C24XX_GPIO_BASE(S3C2410_GPD0),
  162. .chip = {
  163. .base = S3C2410_GPD0,
  164. .owner = THIS_MODULE,
  165. .label = "GPIOD",
  166. .ngpio = 16,
  167. .direction_input = s3c24xx_gpiolib_input,
  168. .direction_output = s3c24xx_gpiolib_output,
  169. .set = s3c24xx_gpiolib_set,
  170. .get = s3c24xx_gpiolib_get,
  171. },
  172. },
  173. [4] = {
  174. .base = S3C24XX_GPIO_BASE(S3C2410_GPE0),
  175. .chip = {
  176. .base = S3C2410_GPE0,
  177. .label = "GPIOE",
  178. .owner = THIS_MODULE,
  179. .ngpio = 16,
  180. .direction_input = s3c24xx_gpiolib_input,
  181. .direction_output = s3c24xx_gpiolib_output,
  182. .set = s3c24xx_gpiolib_set,
  183. .get = s3c24xx_gpiolib_get,
  184. },
  185. },
  186. [5] = {
  187. .base = S3C24XX_GPIO_BASE(S3C2410_GPF0),
  188. .chip = {
  189. .base = S3C2410_GPF0,
  190. .owner = THIS_MODULE,
  191. .label = "GPIOF",
  192. .ngpio = 8,
  193. .direction_input = s3c24xx_gpiolib_input,
  194. .direction_output = s3c24xx_gpiolib_output,
  195. .set = s3c24xx_gpiolib_set,
  196. .get = s3c24xx_gpiolib_get,
  197. },
  198. },
  199. [6] = {
  200. .base = S3C24XX_GPIO_BASE(S3C2410_GPG0),
  201. .chip = {
  202. .base = S3C2410_GPG0,
  203. .owner = THIS_MODULE,
  204. .label = "GPIOG",
  205. .ngpio = 10,
  206. .direction_input = s3c24xx_gpiolib_input,
  207. .direction_output = s3c24xx_gpiolib_output,
  208. .set = s3c24xx_gpiolib_set,
  209. .get = s3c24xx_gpiolib_get,
  210. },
  211. },
  212. };
  213. static __init int s3c24xx_gpiolib_init(void)
  214. {
  215. struct s3c24xx_gpio_chip *chip = gpios;
  216. int gpn;
  217. for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++)
  218. gpiochip_add(&chip->chip);
  219. return 0;
  220. }
  221. arch_initcall(s3c24xx_gpiolib_init);