gpio.c 4.6 KB

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