abcio.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * abcio.c
  3. *
  4. * Handle ABC-bus I/O operations
  5. */
  6. #include "fw.h"
  7. #include "io.h"
  8. #include "irq.h"
  9. #include "abcio.h"
  10. static struct abc_dev *abc_device[65]; /* 65 == post-RST# = always NULL */
  11. static struct abc_dev *selected_dev;
  12. static uint8_t abc_devsel = 64;
  13. #define EVENT_MASK_ALWAYS 0x0082 /* RST# and CS# */
  14. static inline __attribute__((always_inline))
  15. uint16_t event_mask(const struct abc_dev *dev)
  16. {
  17. if (!dev)
  18. return EVENT_MASK_ALWAYS;
  19. return EVENT_MASK_ALWAYS | dev->callback_mask |
  20. (dev->out_cnt ? 1 : 0) | (dev->inp_cnt ? 0x100 : 0);
  21. }
  22. /* Not inlining this makes the code larger...! */
  23. static inline __attribute__((always_inline))
  24. void refresh_dev(struct abc_dev *dev)
  25. {
  26. if (dev == selected_dev) {
  27. ABC_BUSY_MASK = event_mask(dev);
  28. ABC_INP = dev ? dev->inp_data_w : 0;
  29. }
  30. }
  31. static inline __attribute__((always_inline))
  32. void abc_select(struct abc_dev *dev)
  33. {
  34. selected_dev = dev;
  35. refresh_dev(dev);
  36. }
  37. IRQHANDLER(abc)
  38. {
  39. unsigned int what = ABC_BUSY_STATUS;
  40. struct abc_dev *dev = selected_dev;
  41. unsigned int callback = dev ? (what & dev->callback_mask) : 0;
  42. if (what & 0xff) {
  43. unsigned int addr = ABC_OUT_ADDR;
  44. unsigned int data = ABC_OUT_DATA;
  45. switch (addr) {
  46. case 0:
  47. if (!dev)
  48. break;
  49. if (dev->out_cnt) {
  50. *dev->out_buf++ = data;
  51. dev->inp_data[1] &= dev->status_first_out_mask;
  52. ABC_INP1_DATA = dev->inp_data[1];
  53. if (--dev->out_cnt)
  54. break; /* No callback, don't set out_data[] */
  55. }
  56. goto handle_out;
  57. case 1:
  58. dev = abc_device[abc_devsel = data & 0x3f];
  59. abc_select(dev);
  60. if (!dev)
  61. break;
  62. callback = dev->callback_mask & what;
  63. goto handle_out;
  64. case 2 ... 5:
  65. goto handle_out;
  66. handle_out:
  67. dev->out_data[addr] = data;
  68. if (callback & (1 << addr))
  69. dev->callback_out[addr](dev, data, addr);
  70. break;
  71. case 7:
  72. {
  73. struct abc_dev **devp;
  74. uint8_t old_devsel = abc_devsel;
  75. abc_devsel = DEVSEL_NONE;
  76. abc_select(NULL);
  77. devp = &abc_device[0];
  78. while (devp <= &abc_device[63]) {
  79. dev = *devp++;
  80. if (dev && (dev->callback_mask & 0x0080))
  81. dev->callback_rst(dev, old_devsel, 7);
  82. }
  83. dev = NULL;
  84. break;
  85. }
  86. default:
  87. break;
  88. }
  89. }
  90. if (what & 0x100) {
  91. if (dev->inp_cnt && --dev->inp_cnt) {
  92. dev->inp_data[1] &= dev->status_first_inp_mask;
  93. ABC_INP1_DATA = dev->inp_data[1];
  94. ABC_INP0_DATA = dev->inp_data[0] = *dev->inp_buf++;
  95. /* No callback */
  96. } else {
  97. uint8_t old_data = ABC_INP0_DATA;
  98. ABC_INP0_DATA = dev->inp_data[0] = dev->inp_data_def;
  99. if (callback & 0x100)
  100. dev->callback_inp[0](dev, old_data, 0);
  101. }
  102. }
  103. if (what & 0x200) {
  104. uint8_t old_data = ABC_INP1_DATA;
  105. ABC_INP1_DATA = dev->inp_data[1];
  106. if (callback & 0x200)
  107. dev->callback_inp[1](dev, old_data, 1);
  108. }
  109. /* May need to change event_mask here */
  110. ABC_BUSY = what | (event_mask(dev) << 16);
  111. }
  112. void abc_setup_out_queue(struct abc_dev *dev, void *buf, size_t len,
  113. uint8_t status)
  114. {
  115. irqmask_t irqmask = mask_irq(ABC_IRQ);
  116. dev->out_buf = buf;
  117. dev->out_cnt = len;
  118. dev->inp_data[1] = status;
  119. refresh_dev(dev); /* Update registers as needed */
  120. restore_irq(irqmask, ABC_IRQ);
  121. }
  122. void abc_setup_inp_queue(struct abc_dev *dev, const void *buf, size_t len,
  123. uint8_t status)
  124. {
  125. irqmask_t irqmask = mask_irq(ABC_IRQ);
  126. dev->inp_buf = buf;
  127. dev->inp_cnt = len;
  128. dev->inp_data[0] = *dev->inp_buf++;
  129. dev->inp_data[1] = status;
  130. refresh_dev(dev); /* Update registers as needed */
  131. restore_irq(irqmask, ABC_IRQ);
  132. }
  133. void abc_set_inp_default(struct abc_dev *dev, uint8_t val)
  134. {
  135. irqmask_t irqmask = mask_irq(ABC_IRQ);
  136. dev->inp_data_def = val;
  137. if (!dev->inp_cnt) {
  138. dev->inp_data[0] = val;
  139. if (dev == selected_dev)
  140. ABC_INP0_DATA = val;
  141. }
  142. restore_irq(irqmask, ABC_IRQ);
  143. }
  144. void abc_set_inp_status(struct abc_dev *dev, uint8_t val)
  145. {
  146. irqmask_t irqmask = mask_irq(ABC_IRQ);
  147. dev->inp_data[1] = val;
  148. if (dev == selected_dev)
  149. ABC_INP1_DATA = val;
  150. restore_irq(irqmask, ABC_IRQ);
  151. }
  152. /*
  153. * This can be called before or after abc_init()!
  154. */
  155. void abc_register(struct abc_dev *dev, unsigned int devsel)
  156. {
  157. if (devsel > 63)
  158. return;
  159. irqmask_t irqmask = mask_irq(ABC_IRQ);
  160. if (!dev->inp_cnt)
  161. dev->inp_data[0] = dev->inp_data_def;
  162. abc_device[devsel] = dev;
  163. if (devsel == abc_devsel)
  164. abc_select(dev);
  165. restore_irq(irqmask, ABC_IRQ);
  166. }
  167. void abc_init(void)
  168. {
  169. unsigned int devsel;
  170. mask_irq(ABC_IRQ);
  171. devsel = ABC_IOSEL;
  172. abc_devsel = (devsel & 0x100) ? DEVSEL_NONE : (devsel & 63);
  173. abc_select(abc_device[abc_devsel]);
  174. unmask_irq(ABC_IRQ); /* Start ABC bus unconditionally */
  175. }