adb-iop.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * I/O Processor (IOP) ADB Driver
  4. * Written and (C) 1999 by Joshua M. Thompson ([email protected])
  5. * Based on via-cuda.c by Paul Mackerras.
  6. *
  7. * 1999-07-01 (jmt) - First implementation for new driver architecture.
  8. *
  9. * 1999-07-31 (jmt) - First working version.
  10. */
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mm.h>
  14. #include <linux/delay.h>
  15. #include <linux/init.h>
  16. #include <asm/macintosh.h>
  17. #include <asm/macints.h>
  18. #include <asm/mac_iop.h>
  19. #include <asm/adb_iop.h>
  20. #include <asm/unaligned.h>
  21. #include <linux/adb.h>
  22. static struct adb_request *current_req;
  23. static struct adb_request *last_req;
  24. static unsigned int autopoll_devs;
  25. static u8 autopoll_addr;
  26. static enum adb_iop_state {
  27. idle,
  28. sending,
  29. awaiting_reply
  30. } adb_iop_state;
  31. static void adb_iop_start(void);
  32. static int adb_iop_probe(void);
  33. static int adb_iop_init(void);
  34. static int adb_iop_send_request(struct adb_request *, int);
  35. static int adb_iop_write(struct adb_request *);
  36. static int adb_iop_autopoll(int);
  37. static void adb_iop_poll(void);
  38. static int adb_iop_reset_bus(void);
  39. /* ADB command byte structure */
  40. #define ADDR_MASK 0xF0
  41. #define OP_MASK 0x0C
  42. #define TALK 0x0C
  43. struct adb_driver adb_iop_driver = {
  44. .name = "ISM IOP",
  45. .probe = adb_iop_probe,
  46. .init = adb_iop_init,
  47. .send_request = adb_iop_send_request,
  48. .autopoll = adb_iop_autopoll,
  49. .poll = adb_iop_poll,
  50. .reset_bus = adb_iop_reset_bus
  51. };
  52. static void adb_iop_done(void)
  53. {
  54. struct adb_request *req = current_req;
  55. adb_iop_state = idle;
  56. req->complete = 1;
  57. current_req = req->next;
  58. if (req->done)
  59. (*req->done)(req);
  60. if (adb_iop_state == idle)
  61. adb_iop_start();
  62. }
  63. /*
  64. * Completion routine for ADB commands sent to the IOP.
  65. *
  66. * This will be called when a packet has been successfully sent.
  67. */
  68. static void adb_iop_complete(struct iop_msg *msg)
  69. {
  70. unsigned long flags;
  71. local_irq_save(flags);
  72. adb_iop_state = awaiting_reply;
  73. local_irq_restore(flags);
  74. }
  75. /*
  76. * Listen for ADB messages from the IOP.
  77. *
  78. * This will be called when unsolicited IOP messages are received.
  79. * These IOP messages can carry ADB autopoll responses and also occur
  80. * after explicit ADB commands.
  81. */
  82. static void adb_iop_listen(struct iop_msg *msg)
  83. {
  84. struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
  85. u8 addr = (amsg->cmd & ADDR_MASK) >> 4;
  86. u8 op = amsg->cmd & OP_MASK;
  87. unsigned long flags;
  88. bool req_done = false;
  89. local_irq_save(flags);
  90. /* Responses to Talk commands may be unsolicited as they are
  91. * produced when the IOP polls devices. They are mostly timeouts.
  92. */
  93. if (op == TALK && ((1 << addr) & autopoll_devs))
  94. autopoll_addr = addr;
  95. switch (amsg->flags & (ADB_IOP_EXPLICIT |
  96. ADB_IOP_AUTOPOLL |
  97. ADB_IOP_TIMEOUT)) {
  98. case ADB_IOP_EXPLICIT:
  99. case ADB_IOP_EXPLICIT | ADB_IOP_TIMEOUT:
  100. if (adb_iop_state == awaiting_reply) {
  101. struct adb_request *req = current_req;
  102. if (req->reply_expected) {
  103. req->reply_len = amsg->count + 1;
  104. memcpy(req->reply, &amsg->cmd, req->reply_len);
  105. }
  106. req_done = true;
  107. }
  108. break;
  109. case ADB_IOP_AUTOPOLL:
  110. if (((1 << addr) & autopoll_devs) &&
  111. amsg->cmd == ADB_READREG(addr, 0))
  112. adb_input(&amsg->cmd, amsg->count + 1, 1);
  113. break;
  114. }
  115. msg->reply[0] = autopoll_addr ? ADB_IOP_AUTOPOLL : 0;
  116. msg->reply[1] = 0;
  117. msg->reply[2] = autopoll_addr ? ADB_READREG(autopoll_addr, 0) : 0;
  118. iop_complete_message(msg);
  119. if (req_done)
  120. adb_iop_done();
  121. local_irq_restore(flags);
  122. }
  123. /*
  124. * Start sending an ADB packet, IOP style
  125. *
  126. * There isn't much to do other than hand the packet over to the IOP
  127. * after encapsulating it in an adb_iopmsg.
  128. */
  129. static void adb_iop_start(void)
  130. {
  131. struct adb_request *req;
  132. struct adb_iopmsg amsg;
  133. /* get the packet to send */
  134. req = current_req;
  135. if (!req)
  136. return;
  137. /* The IOP takes MacII-style packets, so strip the initial
  138. * ADB_PACKET byte.
  139. */
  140. amsg.flags = ADB_IOP_EXPLICIT;
  141. amsg.count = req->nbytes - 2;
  142. /* amsg.data immediately follows amsg.cmd, effectively making
  143. * &amsg.cmd a pointer to the beginning of a full ADB packet.
  144. */
  145. memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1);
  146. req->sent = 1;
  147. adb_iop_state = sending;
  148. /* Now send it. The IOP manager will call adb_iop_complete
  149. * when the message has been sent.
  150. */
  151. iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *)&amsg,
  152. adb_iop_complete);
  153. }
  154. static int adb_iop_probe(void)
  155. {
  156. if (!iop_ism_present)
  157. return -ENODEV;
  158. return 0;
  159. }
  160. static int adb_iop_init(void)
  161. {
  162. pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n");
  163. iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
  164. return 0;
  165. }
  166. static int adb_iop_send_request(struct adb_request *req, int sync)
  167. {
  168. int err;
  169. err = adb_iop_write(req);
  170. if (err)
  171. return err;
  172. if (sync) {
  173. while (!req->complete)
  174. adb_iop_poll();
  175. }
  176. return 0;
  177. }
  178. static int adb_iop_write(struct adb_request *req)
  179. {
  180. unsigned long flags;
  181. if ((req->nbytes < 2) || (req->data[0] != ADB_PACKET)) {
  182. req->complete = 1;
  183. return -EINVAL;
  184. }
  185. req->next = NULL;
  186. req->sent = 0;
  187. req->complete = 0;
  188. req->reply_len = 0;
  189. local_irq_save(flags);
  190. if (current_req) {
  191. last_req->next = req;
  192. last_req = req;
  193. } else {
  194. current_req = req;
  195. last_req = req;
  196. }
  197. if (adb_iop_state == idle)
  198. adb_iop_start();
  199. local_irq_restore(flags);
  200. return 0;
  201. }
  202. static void adb_iop_set_ap_complete(struct iop_msg *msg)
  203. {
  204. struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
  205. autopoll_devs = get_unaligned_be16(amsg->data);
  206. if (autopoll_devs & (1 << autopoll_addr))
  207. return;
  208. autopoll_addr = autopoll_devs ? (ffs(autopoll_devs) - 1) : 0;
  209. }
  210. static int adb_iop_autopoll(int devs)
  211. {
  212. struct adb_iopmsg amsg;
  213. unsigned long flags;
  214. unsigned int mask = (unsigned int)devs & 0xFFFE;
  215. local_irq_save(flags);
  216. amsg.flags = ADB_IOP_SET_AUTOPOLL | (mask ? ADB_IOP_AUTOPOLL : 0);
  217. amsg.count = 2;
  218. amsg.cmd = 0;
  219. put_unaligned_be16(mask, amsg.data);
  220. iop_send_message(ADB_IOP, ADB_CHAN, NULL, sizeof(amsg), (__u8 *)&amsg,
  221. adb_iop_set_ap_complete);
  222. local_irq_restore(flags);
  223. return 0;
  224. }
  225. static void adb_iop_poll(void)
  226. {
  227. iop_ism_irq_poll(ADB_IOP);
  228. }
  229. static int adb_iop_reset_bus(void)
  230. {
  231. struct adb_request req;
  232. /* Command = 0, Address = ignored */
  233. adb_request(&req, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
  234. adb_iop_send_request(&req, 1);
  235. /* Don't want any more requests during the Global Reset low time. */
  236. mdelay(3);
  237. return 0;
  238. }