gpio.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Atheros AR71XX/AR724X/AR913X GPIO API support
  3. *
  4. * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  5. * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
  6. * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7. *
  8. * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License version 2 as published
  12. * by the Free Software Foundation.
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/types.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/io.h>
  20. #include <linux/ioport.h>
  21. #include <linux/gpio.h>
  22. #include <asm/mach-ath79/ar71xx_regs.h>
  23. #include <asm/mach-ath79/ath79.h>
  24. #include "common.h"
  25. static void __iomem *ath79_gpio_base;
  26. static unsigned long ath79_gpio_count;
  27. static DEFINE_SPINLOCK(ath79_gpio_lock);
  28. static void __ath79_gpio_set_value(unsigned gpio, int value)
  29. {
  30. void __iomem *base = ath79_gpio_base;
  31. if (value)
  32. __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
  33. else
  34. __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
  35. }
  36. static int __ath79_gpio_get_value(unsigned gpio)
  37. {
  38. return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
  39. }
  40. static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  41. {
  42. return __ath79_gpio_get_value(offset);
  43. }
  44. static void ath79_gpio_set_value(struct gpio_chip *chip,
  45. unsigned offset, int value)
  46. {
  47. __ath79_gpio_set_value(offset, value);
  48. }
  49. static int ath79_gpio_direction_input(struct gpio_chip *chip,
  50. unsigned offset)
  51. {
  52. void __iomem *base = ath79_gpio_base;
  53. unsigned long flags;
  54. spin_lock_irqsave(&ath79_gpio_lock, flags);
  55. __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
  56. base + AR71XX_GPIO_REG_OE);
  57. spin_unlock_irqrestore(&ath79_gpio_lock, flags);
  58. return 0;
  59. }
  60. static int ath79_gpio_direction_output(struct gpio_chip *chip,
  61. unsigned offset, int value)
  62. {
  63. void __iomem *base = ath79_gpio_base;
  64. unsigned long flags;
  65. spin_lock_irqsave(&ath79_gpio_lock, flags);
  66. if (value)
  67. __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
  68. else
  69. __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
  70. __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
  71. base + AR71XX_GPIO_REG_OE);
  72. spin_unlock_irqrestore(&ath79_gpio_lock, flags);
  73. return 0;
  74. }
  75. static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  76. {
  77. void __iomem *base = ath79_gpio_base;
  78. unsigned long flags;
  79. spin_lock_irqsave(&ath79_gpio_lock, flags);
  80. __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
  81. base + AR71XX_GPIO_REG_OE);
  82. spin_unlock_irqrestore(&ath79_gpio_lock, flags);
  83. return 0;
  84. }
  85. static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
  86. int value)
  87. {
  88. void __iomem *base = ath79_gpio_base;
  89. unsigned long flags;
  90. spin_lock_irqsave(&ath79_gpio_lock, flags);
  91. if (value)
  92. __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
  93. else
  94. __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
  95. __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
  96. base + AR71XX_GPIO_REG_OE);
  97. spin_unlock_irqrestore(&ath79_gpio_lock, flags);
  98. return 0;
  99. }
  100. static struct gpio_chip ath79_gpio_chip = {
  101. .label = "ath79",
  102. .get = ath79_gpio_get_value,
  103. .set = ath79_gpio_set_value,
  104. .direction_input = ath79_gpio_direction_input,
  105. .direction_output = ath79_gpio_direction_output,
  106. .base = 0,
  107. };
  108. static void __iomem *ath79_gpio_get_function_reg(void)
  109. {
  110. u32 reg = 0;
  111. if (soc_is_ar71xx() ||
  112. soc_is_ar724x() ||
  113. soc_is_ar913x() ||
  114. soc_is_ar933x())
  115. reg = AR71XX_GPIO_REG_FUNC;
  116. else if (soc_is_ar934x())
  117. reg = AR934X_GPIO_REG_FUNC;
  118. else
  119. BUG();
  120. return ath79_gpio_base + reg;
  121. }
  122. void ath79_gpio_function_setup(u32 set, u32 clear)
  123. {
  124. void __iomem *reg = ath79_gpio_get_function_reg();
  125. unsigned long flags;
  126. spin_lock_irqsave(&ath79_gpio_lock, flags);
  127. __raw_writel((__raw_readl(reg) & ~clear) | set, reg);
  128. /* flush write */
  129. __raw_readl(reg);
  130. spin_unlock_irqrestore(&ath79_gpio_lock, flags);
  131. }
  132. void ath79_gpio_function_enable(u32 mask)
  133. {
  134. ath79_gpio_function_setup(mask, 0);
  135. }
  136. void ath79_gpio_function_disable(u32 mask)
  137. {
  138. ath79_gpio_function_setup(0, mask);
  139. }
  140. void __init ath79_gpio_init(void)
  141. {
  142. int err;
  143. if (soc_is_ar71xx())
  144. ath79_gpio_count = AR71XX_GPIO_COUNT;
  145. else if (soc_is_ar7240())
  146. ath79_gpio_count = AR7240_GPIO_COUNT;
  147. else if (soc_is_ar7241() || soc_is_ar7242())
  148. ath79_gpio_count = AR7241_GPIO_COUNT;
  149. else if (soc_is_ar913x())
  150. ath79_gpio_count = AR913X_GPIO_COUNT;
  151. else if (soc_is_ar933x())
  152. ath79_gpio_count = AR933X_GPIO_COUNT;
  153. else if (soc_is_ar934x())
  154. ath79_gpio_count = AR934X_GPIO_COUNT;
  155. else if (soc_is_qca955x())
  156. ath79_gpio_count = QCA955X_GPIO_COUNT;
  157. else
  158. BUG();
  159. ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  160. ath79_gpio_chip.ngpio = ath79_gpio_count;
  161. if (soc_is_ar934x() || soc_is_qca955x()) {
  162. ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
  163. ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
  164. }
  165. err = gpiochip_add(&ath79_gpio_chip);
  166. if (err)
  167. panic("cannot add AR71xx GPIO chip, error=%d", err);
  168. }
  169. int gpio_get_value(unsigned gpio)
  170. {
  171. if (gpio < ath79_gpio_count)
  172. return __ath79_gpio_get_value(gpio);
  173. return __gpio_get_value(gpio);
  174. }
  175. EXPORT_SYMBOL(gpio_get_value);
  176. void gpio_set_value(unsigned gpio, int value)
  177. {
  178. if (gpio < ath79_gpio_count)
  179. __ath79_gpio_set_value(gpio, value);
  180. else
  181. __gpio_set_value(gpio, value);
  182. }
  183. EXPORT_SYMBOL(gpio_set_value);
  184. int gpio_to_irq(unsigned gpio)
  185. {
  186. /* FIXME */
  187. return -EINVAL;
  188. }
  189. EXPORT_SYMBOL(gpio_to_irq);
  190. int irq_to_gpio(unsigned irq)
  191. {
  192. /* FIXME */
  193. return -EINVAL;
  194. }
  195. EXPORT_SYMBOL(irq_to_gpio);