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 <asm/hardware.h>
  21. #include <asm/irq.h>
  22. #include <asm/arch/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. 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. 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. void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value)
  72. {
  73. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  74. void __iomem *base = ourchip->base;
  75. unsigned long flags;
  76. unsigned long dat;
  77. local_irq_save(flags);
  78. dat = __raw_readl(base + 0x04);
  79. dat &= ~(1 << offset);
  80. if (value)
  81. dat |= 1 << offset;
  82. __raw_writel(dat, base + 0x04);
  83. local_irq_restore(flags);
  84. }
  85. int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset)
  86. {
  87. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  88. unsigned long val;
  89. val = __raw_readl(ourchip->base + 0x04);
  90. val >>= offset;
  91. val &= 1;
  92. return val;
  93. }
  94. static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
  95. {
  96. return -EINVAL;
  97. }
  98. static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
  99. unsigned offset, int value)
  100. {
  101. struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
  102. void __iomem *base = ourchip->base;
  103. unsigned long flags;
  104. unsigned long dat;
  105. unsigned long con;
  106. local_irq_save(flags);
  107. con = __raw_readl(base + 0x00);
  108. dat = __raw_readl(base + 0x04);
  109. dat &= ~(1 << offset);
  110. if (value)
  111. dat |= 1 << offset;
  112. __raw_writel(dat, base + 0x04);
  113. con &= ~(1 << offset);
  114. __raw_writel(con, base + 0x00);
  115. __raw_writel(dat, base + 0x04);
  116. local_irq_restore(flags);
  117. return 0;
  118. }
  119. struct s3c24xx_gpio_chip gpios[] = {
  120. [0] = {
  121. .base = S3C24XX_GPIO_BASE(S3C2410_GPA0),
  122. .chip = {
  123. .base = S3C2410_GPA0,
  124. .owner = THIS_MODULE,
  125. .label = "GPIOA",
  126. .ngpio = 24,
  127. .direction_input = s3c24xx_gpiolib_banka_input,
  128. .direction_output = s3c24xx_gpiolib_banka_output,
  129. .set = s3c24xx_gpiolib_set,
  130. .get = s3c24xx_gpiolib_get,
  131. },
  132. },
  133. [1] = {
  134. .base = S3C24XX_GPIO_BASE(S3C2410_GPB0),
  135. .chip = {
  136. .base = S3C2410_GPB0,
  137. .owner = THIS_MODULE,
  138. .label = "GPIOB",
  139. .ngpio = 16,
  140. .direction_input = s3c24xx_gpiolib_input,
  141. .direction_output = s3c24xx_gpiolib_output,
  142. .set = s3c24xx_gpiolib_set,
  143. .get = s3c24xx_gpiolib_get,
  144. },
  145. },
  146. [2] = {
  147. .base = S3C24XX_GPIO_BASE(S3C2410_GPC0),
  148. .chip = {
  149. .base = S3C2410_GPC0,
  150. .owner = THIS_MODULE,
  151. .label = "GPIOC",
  152. .ngpio = 16,
  153. .direction_input = s3c24xx_gpiolib_input,
  154. .direction_output = s3c24xx_gpiolib_output,
  155. .set = s3c24xx_gpiolib_set,
  156. .get = s3c24xx_gpiolib_get,
  157. },
  158. },
  159. [3] = {
  160. .base = S3C24XX_GPIO_BASE(S3C2410_GPD0),
  161. .chip = {
  162. .base = S3C2410_GPD0,
  163. .owner = THIS_MODULE,
  164. .label = "GPIOD",
  165. .ngpio = 16,
  166. .direction_input = s3c24xx_gpiolib_input,
  167. .direction_output = s3c24xx_gpiolib_output,
  168. .set = s3c24xx_gpiolib_set,
  169. .get = s3c24xx_gpiolib_get,
  170. },
  171. },
  172. [4] = {
  173. .base = S3C24XX_GPIO_BASE(S3C2410_GPE0),
  174. .chip = {
  175. .base = S3C2410_GPE0,
  176. .label = "GPIOE",
  177. .owner = THIS_MODULE,
  178. .ngpio = 16,
  179. .direction_input = s3c24xx_gpiolib_input,
  180. .direction_output = s3c24xx_gpiolib_output,
  181. .set = s3c24xx_gpiolib_set,
  182. .get = s3c24xx_gpiolib_get,
  183. },
  184. },
  185. [5] = {
  186. .base = S3C24XX_GPIO_BASE(S3C2410_GPF0),
  187. .chip = {
  188. .base = S3C2410_GPF0,
  189. .owner = THIS_MODULE,
  190. .label = "GPIOF",
  191. .ngpio = 8,
  192. .direction_input = s3c24xx_gpiolib_input,
  193. .direction_output = s3c24xx_gpiolib_output,
  194. .set = s3c24xx_gpiolib_set,
  195. .get = s3c24xx_gpiolib_get,
  196. },
  197. },
  198. [6] = {
  199. .base = S3C24XX_GPIO_BASE(S3C2410_GPG0),
  200. .chip = {
  201. .base = S3C2410_GPG0,
  202. .owner = THIS_MODULE,
  203. .label = "GPIOG",
  204. .ngpio = 10,
  205. .direction_input = s3c24xx_gpiolib_input,
  206. .direction_output = s3c24xx_gpiolib_output,
  207. .set = s3c24xx_gpiolib_set,
  208. .get = s3c24xx_gpiolib_get,
  209. },
  210. },
  211. };
  212. static __init int s3c24xx_gpiolib_init(void)
  213. {
  214. struct s3c24xx_gpio_chip *chip = gpios;
  215. int gpn;
  216. for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++)
  217. gpiochip_add(&chip->chip);
  218. return 0;
  219. }
  220. arch_initcall(s3c24xx_gpiolib_init);