macio-adb.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Driver for the ADB controller in the Mac I/O (Hydra) chip.
  3.  */
  4. #include <stdarg.h>
  5. #include <linux/types.h>
  6. #include <linux/errno.h>
  7. #include <linux/kernel.h>
  8. #include <linux/delay.h>
  9. #include <linux/sched.h>
  10. #include <asm/prom.h>
  11. #include <linux/adb.h>
  12. #include <asm/io.h>
  13. #include <asm/pgtable.h>
  14. #include <asm/hydra.h>
  15. #include <asm/irq.h>
  16. #include <asm/system.h>
  17. #include <linux/init.h>
  18. struct preg {
  19. unsigned char r;
  20. char pad[15];
  21. };
  22. struct adb_regs {
  23. struct preg intr;
  24. struct preg data[9];
  25. struct preg intr_enb;
  26. struct preg dcount;
  27. struct preg error;
  28. struct preg ctrl;
  29. struct preg autopoll;
  30. struct preg active_hi;
  31. struct preg active_lo;
  32. struct preg test;
  33. };
  34. /* Bits in intr and intr_enb registers */
  35. #define DFB 1 /* data from bus */
  36. #define TAG 2 /* transfer access grant */
  37. /* Bits in dcount register */
  38. #define HMB 0x0f /* how many bytes */
  39. #define APD 0x10 /* auto-poll data */
  40. /* Bits in error register */
  41. #define NRE 1 /* no response error */
  42. #define DLE 2 /* data lost error */
  43. /* Bits in ctrl register */
  44. #define TAR 1 /* transfer access request */
  45. #define DTB 2 /* data to bus */
  46. #define CRE 4 /* command response expected */
  47. #define ADB_RST 8 /* ADB reset */
  48. /* Bits in autopoll register */
  49. #define APE 1 /* autopoll enable */
  50. static volatile struct adb_regs *adb;
  51. static struct adb_request *current_req, *last_req;
  52. static unsigned char adb_rbuf[16];
  53. static int macio_probe(void);
  54. static int macio_init(void);
  55. static void macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs);
  56. static int macio_send_request(struct adb_request *req, int sync);
  57. static int macio_adb_autopoll(int devs);
  58. static void macio_adb_poll(void);
  59. static int macio_adb_reset_bus(void);
  60. static void completed(void);
  61. struct adb_driver macio_adb_driver = {
  62. "MACIO",
  63. macio_probe,
  64. macio_init,
  65. macio_send_request,
  66. /*macio_write,*/
  67. macio_adb_autopoll,
  68. macio_adb_poll,
  69. macio_adb_reset_bus
  70. };
  71. int macio_probe(void)
  72. {
  73. return find_compatible_devices("adb", "chrp,adb0")? 0: -ENODEV;
  74. }
  75. int macio_init(void)
  76. {
  77. struct device_node *adbs;
  78. adbs = find_compatible_devices("adb", "chrp,adb0");
  79. if (adbs == 0)
  80. return -ENXIO;
  81. #if 0
  82. { int i;
  83. printk("macio_adb_init: node = %p, addrs =", adbs->node);
  84. for (i = 0; i < adbs->n_addrs; ++i)
  85. printk(" %x(%x)", adbs->addrs[i].address, adbs->addrs[i].size);
  86. printk(", intrs =");
  87. for (i = 0; i < adbs->n_intrs; ++i)
  88. printk(" %x", adbs->intrs[i].line);
  89. printk("n"); }
  90. #endif
  91. adb = (volatile struct adb_regs *)
  92. ioremap(adbs->addrs->address, sizeof(struct adb_regs));
  93. if (request_irq(adbs->intrs[0].line, macio_adb_interrupt,
  94. 0, "ADB", (void *)0)) {
  95. printk(KERN_ERR "ADB: can't get irq %dn",
  96.        adbs->intrs[0].line);
  97. return -EAGAIN;
  98. }
  99. out_8(&adb->ctrl.r, 0);
  100. out_8(&adb->intr.r, 0);
  101. out_8(&adb->error.r, 0);
  102. out_8(&adb->active_hi.r, 0xff); /* for now, set all devices active */
  103. out_8(&adb->active_lo.r, 0xff);
  104. out_8(&adb->autopoll.r, APE);
  105. out_8(&adb->intr_enb.r, DFB | TAG);
  106. printk("adb: mac-io driver 1.0 for unified ADBn");
  107. return 0;
  108. }
  109. static int macio_adb_autopoll(int devs)
  110. {
  111. out_8(&adb->active_hi.r, devs >> 8);
  112. out_8(&adb->active_lo.r, devs);
  113. out_8(&adb->autopoll.r, devs? APE: 0);
  114. return 0;
  115. }
  116. static int macio_adb_reset_bus(void)
  117. {
  118. int timeout = 1000000;
  119. out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST);
  120. while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) {
  121. if (--timeout == 0) {
  122. out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
  123. return -1;
  124. }
  125. }
  126. return 0;
  127. }
  128. /* Send an ADB command */
  129. static int macio_send_request(struct adb_request *req, int sync)
  130. {
  131. unsigned long mflags;
  132. int i;
  133. if (req->data[0] != ADB_PACKET)
  134. return -EINVAL;
  135. for (i = 0; i < req->nbytes - 1; ++i)
  136. req->data[i] = req->data[i+1];
  137. --req->nbytes;
  138. req->next = 0;
  139. req->sent = 0;
  140. req->complete = 0;
  141. req->reply_len = 0;
  142. save_flags(mflags);
  143. cli();
  144. if (current_req != 0) {
  145. last_req->next = req;
  146. last_req = req;
  147. } else {
  148. current_req = last_req = req;
  149. out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
  150. }
  151. restore_flags(mflags);
  152. if (sync) {
  153. while (!req->complete)
  154. macio_adb_poll();
  155. }
  156. return 0;
  157. }
  158. static void macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs)
  159. {
  160. int i, n, err;
  161. struct adb_request *req;
  162. if (in_8(&adb->intr.r) & TAG) {
  163. if ((req = current_req) != 0) {
  164. /* put the current request in */
  165. for (i = 0; i < req->nbytes; ++i)
  166. out_8(&adb->data[i].r, req->data[i]);
  167. out_8(&adb->dcount.r, req->nbytes & HMB);
  168. req->sent = 1;
  169. if (req->reply_expected) {
  170. out_8(&adb->ctrl.r, DTB + CRE);
  171. } else {
  172. out_8(&adb->ctrl.r, DTB);
  173. completed();
  174. }
  175. }
  176. out_8(&adb->intr.r, 0);
  177. }
  178. if (in_8(&adb->intr.r) & DFB) {
  179. err = in_8(&adb->error.r);
  180. if (current_req && current_req->sent) {
  181. /* this is the response to a command */
  182. req = current_req;
  183. if (err == 0) {
  184. req->reply_len = in_8(&adb->dcount.r) & HMB;
  185. for (i = 0; i < req->reply_len; ++i)
  186. req->reply[i] = in_8(&adb->data[i].r);
  187. }
  188. completed();
  189. } else if (err == 0) {
  190. /* autopoll data */
  191. n = in_8(&adb->dcount.r) & HMB;
  192. for (i = 0; i < n; ++i)
  193. adb_rbuf[i] = in_8(&adb->data[i].r);
  194. adb_input(adb_rbuf, n, regs,
  195.   in_8(&adb->dcount.r) & APD);
  196. }
  197. out_8(&adb->error.r, 0);
  198. out_8(&adb->intr.r, 0);
  199. }
  200. }
  201. static void completed(void)
  202. {
  203. struct adb_request *req = current_req;
  204. req->complete = 1;
  205. current_req = req->next;
  206. if (current_req)
  207. out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
  208. if (req->done)
  209. (*req->done)(req);
  210. }
  211. static void macio_adb_poll(void)
  212. {
  213. unsigned long flags;
  214. save_flags(flags);
  215. cli();
  216. if (in_8(&adb->intr.r) != 0)
  217. macio_adb_interrupt(0, 0, 0);
  218. restore_flags(flags);
  219. }