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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Device driver for the IIsi-style ADB on some Mac LC and II-class machines
  3.  *
  4.  * Based on via-cuda.c and via-macii.c, as well as the original
  5.  * adb-bus.c, which in turn is somewhat influenced by (but uses no
  6.  * code from) the NetBSD HWDIRECT ADB code.  Original IIsi driver work
  7.  * was done by Robert Thompson and integrated into the old style
  8.  * driver by Michael Schmitz.
  9.  *
  10.  * Original sources (c) Alan Cox, Paul Mackerras, and others.
  11.  *
  12.  * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org> */
  13. #include <linux/types.h>
  14. #include <linux/errno.h>
  15. #include <linux/kernel.h>
  16. #include <linux/sched.h>
  17. #include <linux/adb.h>
  18. #include <linux/cuda.h>
  19. #include <linux/delay.h>
  20. #include <asm/macintosh.h>
  21. #include <asm/macints.h>
  22. #include <asm/machw.h>
  23. #include <asm/mac_via.h>
  24. static volatile unsigned char *via;
  25. /* VIA registers - spaced 0x200 bytes apart - only the ones we actually use */
  26. #define RS 0x200 /* skip between registers */
  27. #define B 0 /* B-side data */
  28. #define A RS /* A-side data */
  29. #define DIRB (2*RS) /* B-side direction (1=output) */
  30. #define DIRA (3*RS) /* A-side direction (1=output) */
  31. #define SR (10*RS) /* Shift register */
  32. #define ACR (11*RS) /* Auxiliary control register */
  33. #define IFR (13*RS) /* Interrupt flag register */
  34. #define IER (14*RS) /* Interrupt enable register */
  35. /* Bits in B data register: all active low */
  36. #define TREQ 0x08 /* Transfer request (input) */
  37. #define TACK 0x10 /* Transfer acknowledge (output) */
  38. #define TIP 0x20 /* Transfer in progress (output) */
  39. #define ST_MASK 0x30 /* mask for selecting ADB state bits */
  40. /* Bits in ACR */
  41. #define SR_CTRL 0x1c /* Shift register control bits */
  42. #define SR_EXT 0x0c /* Shift on external clock */
  43. #define SR_OUT 0x10 /* Shift out if 1 */
  44. /* Bits in IFR and IER */
  45. #define IER_SET 0x80 /* set bits in IER */
  46. #define IER_CLR 0 /* clear bits in IER */
  47. #define SR_INT 0x04 /* Shift register full/empty */
  48. #define SR_DATA 0x08 /* Shift register data */
  49. #define SR_CLOCK 0x10 /* Shift register clock */
  50. #define ADB_DELAY 150
  51. static struct adb_request* current_req = NULL;
  52. static struct adb_request* last_req = NULL;
  53. static unsigned char maciisi_rbuf[16];
  54. static unsigned char *reply_ptr = NULL;
  55. static int data_index;
  56. static int reading_reply;
  57. static int reply_len;
  58. static enum maciisi_state {
  59.     idle,
  60.     sending,
  61.     reading,
  62. } maciisi_state;
  63. static int maciisi_probe(void);
  64. static int maciisi_init(void);
  65. static int maciisi_send_request(struct adb_request* req, int sync);
  66. static int maciisi_write(struct adb_request* req);
  67. static void maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
  68. static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
  69. static int maciisi_init_via(void);
  70. static void maciisi_poll(void);
  71. static void maciisi_start(void);
  72. struct adb_driver via_maciisi_driver = {
  73. "Mac IIsi",
  74. maciisi_probe,
  75. maciisi_init,
  76. maciisi_send_request,
  77. NULL, /* maciisi_adb_autopoll, */
  78. maciisi_poll,
  79. NULL /* maciisi_reset_adb_bus */
  80. };
  81. static int
  82. maciisi_probe(void)
  83. {
  84. if (macintosh_config->adb_type != MAC_ADB_IISI)
  85. return -ENODEV;
  86. via = via1;
  87. return 0;
  88. }
  89. static int
  90. maciisi_init(void)
  91. {
  92. int err;
  93. if (via == NULL)
  94. return -ENODEV;
  95. if ((err = maciisi_init_via())) {
  96. printk(KERN_ERR "maciisi_init: maciisi_init_via() failed, code %dn", err);
  97. via = NULL;
  98. return err;
  99. }
  100. if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK, 
  101. "ADB", maciisi_interrupt)) {
  102. printk(KERN_ERR "maciisi_init: can't get irq %dn", IRQ_MAC_ADB);
  103. return -EAGAIN;
  104. }
  105. printk("adb: Mac IIsi driver v0.1 for Unified ADB.n");
  106. return 0;
  107. }
  108. static void
  109. maciisi_stfu(void)
  110. {
  111. int status = via[B] & (TIP|TREQ);
  112. if (status & TREQ) {
  113. printk (KERN_DEBUG "maciisi_stfu called with TREQ high!n");
  114. return;
  115. }
  116. /* start transfer */
  117. via[B] |= TIP;
  118. while (!(status & TREQ)) {
  119. int poll_timeout = ADB_DELAY * 5;
  120. /* Poll for SR interrupt */
  121. while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
  122. status = via[B] & (TIP|TREQ);
  123. via[SR]; /* Clear shift register */
  124. printk(KERN_DEBUG "maciisi_stfu: status %x timeout %dn",
  125.        status, poll_timeout);
  126. /* ACK on-off */
  127. via[B] |= TACK;
  128. udelay(ADB_DELAY);
  129. via[B] &= ~TACK;
  130. }
  131. /* end frame */
  132. via[B] &= ~TIP;
  133. }
  134. /* All specifically VIA-related initialization goes here */
  135. static int
  136. maciisi_init_via(void)
  137. {
  138. /* Set the lines up. We want TREQ as input TACK|TIP as output */
  139. via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
  140. /* Shift register on input */
  141. via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
  142. printk(KERN_DEBUG "maciisi_init_via: initial status %xn", via[B] & (TIP|TREQ));
  143. /* Set initial state: idle */
  144. via[B] &= ~(TACK|TIP);
  145. /* Wipe any pending data and int */
  146. via[SR];
  147. if (!(via[B] & TREQ))
  148. maciisi_stfu();
  149. via[IER] = IER_SET | SR_INT;
  150. maciisi_state = idle;
  151. return 0;
  152. }
  153. /* Send a request, possibly waiting for a reply */
  154. static int
  155. maciisi_send_request(struct adb_request* req, int sync)
  156. {
  157. int i;
  158. static int dump_packet = 1;
  159. if (via == NULL) {
  160. req->complete = 1;
  161. return -ENXIO;
  162. }
  163. if (dump_packet) {
  164. printk(KERN_DEBUG "maciisi_send_request:");
  165. for (i = 0; i < req->nbytes; i++) {
  166. printk(" %.2x", req->data[i]);
  167. }
  168. printk("n");
  169. }
  170. req->reply_expected = 1;
  171. i = maciisi_write(req);
  172. if (i)
  173. return i;
  174. if (sync) {
  175. while (!req->complete) {
  176. maciisi_poll();
  177. }
  178. }
  179. return 0;
  180. }
  181. /* Enqueue a request, and run the queue if possible */
  182. static int
  183. maciisi_write(struct adb_request* req)
  184. {
  185. unsigned long flags;
  186.    printk(KERN_DEBUG "maciisi_write called, state=%d ifr=%xn", maciisi_state, via[IFR]);
  187. /* We will accept CUDA packets - the VIA sends them to us, so
  188.            it figures that we should be able to send them to it */
  189. if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
  190. printk(KERN_ERR "maciisi_write: packet too small or not an ADB or CUDA packetn");
  191. req->complete = 1;
  192. return -EINVAL;
  193. }
  194. req->next = 0;
  195. req->sent = 0;
  196. req->complete = 0;
  197. req->reply_len = 0;
  198. save_flags(flags); cli();
  199. if (current_req) {
  200. last_req->next = req;
  201. last_req = req;
  202. } else {
  203. current_req = req;
  204. last_req = req;
  205. }
  206. if (maciisi_state == idle)
  207. maciisi_start();
  208. else
  209. printk(KERN_DEBUG "maciisi_write: would start, but state is %dn", maciisi_state);
  210. restore_flags(flags);
  211. return 0;
  212. }
  213. static void
  214. maciisi_start(void)
  215. {
  216. struct adb_request* req;
  217. int status;
  218. printk(KERN_DEBUG "maciisi_start called, state=%d, ifr=%xn", maciisi_state, via[IFR]);
  219. if (maciisi_state != idle) {
  220. /* shouldn't happen */
  221. printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!n");
  222. return;
  223. }
  224. req = current_req;
  225. if (req == NULL)
  226. return;
  227. status = via[B] & (TIP|TREQ);
  228. if (!(status & TREQ)) {
  229. /* Bus is busy, set up for reading */
  230. printk(KERN_DEBUG "maciisi_start: bus busy - abortingn");
  231. return;
  232. }
  233. /* Okay, send */
  234. printk(KERN_DEBUG "maciisi_start: sendingn");
  235. /* Set state to active */
  236. via[B] |= TIP;
  237. /* ACK off */
  238. via[B] &= ~TACK;
  239. /* Shift out and send */
  240. via[ACR] |= SR_OUT;
  241. via[SR] = req->data[0];
  242. data_index = 1;
  243. /* ACK on */
  244. via[B] |= TACK;
  245. maciisi_state = sending;
  246. }
  247. void
  248. maciisi_poll(void)
  249. {
  250. unsigned long flags;
  251. save_flags(flags);
  252. cli();
  253. if (via[IFR] & SR_INT) {
  254. maciisi_interrupt(0, 0, 0);
  255. }
  256. restore_flags(flags);
  257. }
  258. /* Shift register interrupt - this is *supposed* to mean that the
  259.    register is either full or empty. In practice, I have no idea what
  260.    it means :( */
  261. static void
  262. maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
  263. {
  264. int status;
  265. struct adb_request *req;
  266. static int dump_reply = 1;
  267. if (!(via[IFR] & SR_INT)) {
  268. /* Shouldn't happen, we hope */
  269. printk(KERN_DEBUG "maciisi_interrupt: called without interrupt flag setn");
  270. return;
  271. }
  272. status = via[B] & (TIP|TREQ);
  273. printk(KERN_DEBUG "state %d status %x ifr %xn", maciisi_state, status, via[IFR]);
  274.  switch_start:
  275. switch (maciisi_state) {
  276. case idle:
  277. printk(KERN_DEBUG "maciisi_interrupt: state=idle, status %xn", status);
  278. if (status & TIP)
  279. printk(KERN_DEBUG "maciisi_interrupt: state is idle but TIP asserted!n");
  280. udelay(ADB_DELAY);
  281. /* Shift in */
  282. via[ACR] &= ~SR_OUT;
  283.   /* Signal start of frame */
  284. via[B] |= TIP;
  285. /* Clear the interrupt (throw this value on the floor, it's useless) */
  286. via[SR];
  287. /* ACK adb chip, high-low */
  288. via[B] |= TACK;
  289. udelay(ADB_DELAY);
  290. via[B] &= ~TACK;
  291. reply_len = 0;
  292. maciisi_state = reading;
  293. if (reading_reply) {
  294. reply_ptr = current_req->reply;
  295. } else {
  296. printk(KERN_DEBUG "maciisi_interrupt: received unsolicited packetn");
  297. reply_ptr = maciisi_rbuf;
  298. }
  299. break;
  300. case sending:
  301. printk(KERN_DEBUG "maciisi_interrupt: state=sending, status=%xn", status);
  302. /* Clear interrupt */
  303. via[SR];
  304. /* Set ACK off */
  305. via[B] &= ~TACK;
  306. req = current_req;
  307. if (!(status & TREQ)) {
  308. /* collision */
  309. printk(KERN_DEBUG "maciisi_interrupt: send collisionn");
  310. /* Set idle and input */
  311. via[B] &= ~TIP;
  312. via[ACR] &= ~SR_OUT;
  313. /* Must re-send */
  314. reading_reply = 0;
  315. reply_len = 0;
  316. maciisi_state = idle;
  317. /* process this now, because the IFR has been cleared */
  318. goto switch_start;
  319. }
  320. if (data_index >= req->nbytes) {
  321. /* Sent the whole packet, put the bus back in idle state */
  322. /* Shift in, we are about to read a reply (hopefully) */
  323. via[ACR] &= ~SR_OUT;
  324. /* End of frame */
  325. via[B] &= ~TIP;
  326. req->sent = 1;
  327. maciisi_state = idle;
  328. if (req->reply_expected) {
  329. /* Note: only set this once we've
  330.                                    successfully sent the packet */
  331. reading_reply = 1;
  332. } else {
  333. current_req = req->next;
  334. if (req->done)
  335. (*req->done)(req);
  336. }
  337. } else {
  338. /* Sending more stuff */
  339. /* Shift out */
  340. via[ACR] |= SR_OUT;
  341. /* Delay */
  342. udelay(ADB_DELAY);
  343. /* Write */
  344. via[SR] = req->data[data_index++];
  345. /* Signal 'byte ready' */
  346. via[B] |= TACK;
  347. }
  348. break;
  349. case reading:
  350. printk(KERN_DEBUG "maciisi_interrupt: state=reading, status=%xn", status);
  351. /* Shift in */
  352. via[ACR] &= ~SR_OUT;
  353. if (reply_len++ > 16) {
  354. printk(KERN_ERR "maciisi_interrupt: reply too long, aborting readn");
  355. via[B] |= TACK;
  356. udelay(ADB_DELAY);
  357. via[B] &= ~(TACK|TIP);
  358. maciisi_state = idle;
  359. maciisi_start();
  360. break;
  361. }
  362. *reply_ptr++ = via[SR];
  363. status = via[B] & (TIP|TREQ);
  364. /* ACK on/off */
  365. via[B] |= TACK;
  366. udelay(ADB_DELAY);
  367. via[B] &= ~TACK;
  368. if (!(status & TREQ))
  369. break; /* more stuff to deal with */
  370. /* end of frame */
  371. via[B] &= ~TIP;
  372. /* end of packet, deal with it */
  373. if (reading_reply) {
  374. req = current_req;
  375. req->reply_len = reply_ptr - req->reply;
  376. if (req->data[0] == ADB_PACKET) {
  377. /* Have to adjust the reply from ADB commands */
  378. if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
  379. /* the 0x2 bit indicates no response */
  380. req->reply_len = 0;
  381. } else {
  382. /* leave just the command and result bytes in the reply */
  383. req->reply_len -= 2;
  384. memmove(req->reply, req->reply + 2, req->reply_len);
  385. }
  386. }
  387. if (dump_reply) {
  388. int i;
  389. printk(KERN_DEBUG "maciisi_interrupt: reply is ");
  390. for (i = 0; i < req->reply_len; ++i)
  391. printk(" %.2x", req->reply[i]);
  392. printk("n");
  393. }
  394. req->complete = 1;
  395. current_req = req->next;
  396. if (req->done)
  397. (*req->done)(req);
  398. /* Obviously, we got it */
  399. reading_reply = 0;
  400. } else {
  401. maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf, regs);
  402. }
  403. maciisi_state = idle;
  404. status = via[B] & (TIP|TREQ);
  405. if (!(status & TREQ)) {
  406. /* Timeout?! */
  407. printk(KERN_DEBUG "extra data after packet: status %x ifr %xn",
  408.        status, via[IFR]);
  409. maciisi_stfu();
  410. }
  411. /* Do any queued requests now if possible */
  412. maciisi_start();
  413. break;
  414. default:
  415. printk("maciisi_interrupt: unknown maciisi_state %d?n", maciisi_state);
  416. }
  417. }
  418. static void
  419. maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
  420. {
  421.     int i;
  422.     switch (buf[0]) {
  423.     case ADB_PACKET:
  424.     adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
  425.     break;
  426.     default:
  427.     printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
  428.     for (i = 0; i < nb; ++i)
  429.     printk(" %.2x", buf[i]);
  430.     printk("n");
  431.     }
  432. }