gpio.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * s6000 gpio driver
  3. *
  4. * Copyright (c) 2009 emlix GmbH
  5. * Authors: Oskar Schirmer <os@emlix.com>
  6. * Johannes Weiner <jw@emlix.com>
  7. * Daniel Gloeckner <dg@emlix.com>
  8. */
  9. #include <linux/bitops.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/io.h>
  14. #include <linux/irq.h>
  15. #include <linux/gpio.h>
  16. #include <variant/hardware.h>
  17. #define IRQ_BASE XTENSA_NR_IRQS
  18. #define S6_GPIO_DATA 0x000
  19. #define S6_GPIO_IS 0x404
  20. #define S6_GPIO_IBE 0x408
  21. #define S6_GPIO_IEV 0x40C
  22. #define S6_GPIO_IE 0x410
  23. #define S6_GPIO_RIS 0x414
  24. #define S6_GPIO_MIS 0x418
  25. #define S6_GPIO_IC 0x41C
  26. #define S6_GPIO_AFSEL 0x420
  27. #define S6_GPIO_DIR 0x800
  28. #define S6_GPIO_BANK(nr) ((nr) * 0x1000)
  29. #define S6_GPIO_MASK(nr) (4 << (nr))
  30. #define S6_GPIO_OFFSET(nr) \
  31. (S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
  32. static int direction_input(struct gpio_chip *chip, unsigned int off)
  33. {
  34. writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
  35. return 0;
  36. }
  37. static int get(struct gpio_chip *chip, unsigned int off)
  38. {
  39. return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
  40. }
  41. static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
  42. {
  43. unsigned rel = S6_GPIO_OFFSET(off);
  44. writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
  45. writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
  46. return 0;
  47. }
  48. static void set(struct gpio_chip *chip, unsigned int off, int val)
  49. {
  50. writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
  51. }
  52. static int to_irq(struct gpio_chip *chip, unsigned offset)
  53. {
  54. if (offset < 8)
  55. return offset + IRQ_BASE;
  56. return -EINVAL;
  57. }
  58. static struct gpio_chip gpiochip = {
  59. .owner = THIS_MODULE,
  60. .direction_input = direction_input,
  61. .get = get,
  62. .direction_output = direction_output,
  63. .set = set,
  64. .to_irq = to_irq,
  65. .base = 0,
  66. .ngpio = 24,
  67. .can_sleep = 0, /* no blocking io needed */
  68. .exported = 0, /* no exporting to userspace */
  69. };
  70. int s6_gpio_init(u32 afsel)
  71. {
  72. writeb(afsel, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL);
  73. writeb(afsel >> 8, S6_REG_GPIO + S6_GPIO_BANK(1) + S6_GPIO_AFSEL);
  74. writeb(afsel >> 16, S6_REG_GPIO + S6_GPIO_BANK(2) + S6_GPIO_AFSEL);
  75. return gpiochip_add(&gpiochip);
  76. }
  77. static void ack(unsigned int irq)
  78. {
  79. writeb(1 << (irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC);
  80. }
  81. static void mask(unsigned int irq)
  82. {
  83. u8 r = readb(S6_REG_GPIO + S6_GPIO_IE);
  84. r &= ~(1 << (irq - IRQ_BASE));
  85. writeb(r, S6_REG_GPIO + S6_GPIO_IE);
  86. }
  87. static void unmask(unsigned int irq)
  88. {
  89. u8 m = readb(S6_REG_GPIO + S6_GPIO_IE);
  90. m |= 1 << (irq - IRQ_BASE);
  91. writeb(m, S6_REG_GPIO + S6_GPIO_IE);
  92. }
  93. static int set_type(unsigned int irq, unsigned int type)
  94. {
  95. const u8 m = 1 << (irq - IRQ_BASE);
  96. irq_flow_handler_t handler;
  97. struct irq_desc *desc;
  98. u8 reg;
  99. if (type == IRQ_TYPE_PROBE) {
  100. if ((readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL) & m)
  101. || (readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE) & m)
  102. || readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_DIR
  103. + S6_GPIO_MASK(irq - IRQ_BASE)))
  104. return 0;
  105. type = IRQ_TYPE_EDGE_BOTH;
  106. }
  107. reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS);
  108. if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
  109. reg |= m;
  110. handler = handle_level_irq;
  111. } else {
  112. reg &= ~m;
  113. handler = handle_edge_irq;
  114. }
  115. writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS);
  116. desc = irq_to_desc(irq);
  117. desc->handle_irq = handler;
  118. reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV);
  119. if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING))
  120. reg |= m;
  121. else
  122. reg &= ~m;
  123. writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV);
  124. reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE);
  125. if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
  126. reg |= m;
  127. else
  128. reg &= ~m;
  129. writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE);
  130. return 0;
  131. }
  132. static struct irq_chip gpioirqs = {
  133. .name = "GPIO",
  134. .ack = ack,
  135. .mask = mask,
  136. .unmask = unmask,
  137. .set_type = set_type,
  138. };
  139. static u8 demux_masks[4];
  140. static void demux_irqs(unsigned int irq, struct irq_desc *desc)
  141. {
  142. u8 *mask = get_irq_desc_data(desc);
  143. u8 pending;
  144. int cirq;
  145. desc->chip->mask(irq);
  146. desc->chip->ack(irq);
  147. pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask;
  148. cirq = IRQ_BASE - 1;
  149. while (pending) {
  150. int n = ffs(pending);
  151. cirq += n;
  152. pending >>= n;
  153. generic_handle_irq(cirq);
  154. }
  155. desc->chip->unmask(irq);
  156. }
  157. extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS];
  158. void __init variant_init_irq(void)
  159. {
  160. int irq, n;
  161. writeb(0, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE);
  162. for (irq = n = 0; irq < XTENSA_NR_IRQS; irq++) {
  163. const signed char *mapping = platform_irq_mappings[irq];
  164. int alone = 1;
  165. u8 mask;
  166. if (!mapping)
  167. continue;
  168. for(mask = 0; *mapping != -1; mapping++)
  169. switch (*mapping) {
  170. case S6_INTC_GPIO(0):
  171. mask |= 1 << 0;
  172. break;
  173. case S6_INTC_GPIO(1):
  174. mask |= 1 << 1;
  175. break;
  176. case S6_INTC_GPIO(2):
  177. mask |= 1 << 2;
  178. break;
  179. case S6_INTC_GPIO(3):
  180. mask |= 0x1f << 3;
  181. break;
  182. default:
  183. alone = 0;
  184. }
  185. if (mask) {
  186. int cirq, i;
  187. if (!alone) {
  188. printk(KERN_ERR "chained irq chips can't share"
  189. " parent irq %i\n", irq);
  190. continue;
  191. }
  192. demux_masks[n] = mask;
  193. cirq = IRQ_BASE - 1;
  194. do {
  195. i = ffs(mask);
  196. cirq += i;
  197. mask >>= i;
  198. set_irq_chip(cirq, &gpioirqs);
  199. set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
  200. } while (mask);
  201. set_irq_data(irq, demux_masks + n);
  202. set_irq_chained_handler(irq, demux_irqs);
  203. if (++n == ARRAY_SIZE(demux_masks))
  204. break;
  205. }
  206. }
  207. }