Merge branch 'nfs-for-2.6.32'
[pandora-kernel.git] / drivers / macintosh / via-maciisi.c
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  * 
14  * 7/13/2000- extensive changes by Andrew McPherson <andrew@macduff.dhs.org>
15  * Works about 30% of the time now.
16  */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/kernel.h>
21 #include <linux/adb.h>
22 #include <linux/cuda.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
25 #include <asm/macintosh.h>
26 #include <asm/macints.h>
27 #include <asm/mac_via.h>
28
29 static volatile unsigned char *via;
30
31 /* VIA registers - spaced 0x200 bytes apart - only the ones we actually use */
32 #define RS              0x200           /* skip between registers */
33 #define B               0               /* B-side data */
34 #define A               RS              /* A-side data */
35 #define DIRB            (2*RS)          /* B-side direction (1=output) */
36 #define DIRA            (3*RS)          /* A-side direction (1=output) */
37 #define SR              (10*RS)         /* Shift register */
38 #define ACR             (11*RS)         /* Auxiliary control register */
39 #define IFR             (13*RS)         /* Interrupt flag register */
40 #define IER             (14*RS)         /* Interrupt enable register */
41
42 /* Bits in B data register: all active low */
43 #define TREQ            0x08            /* Transfer request (input) */
44 #define TACK            0x10            /* Transfer acknowledge (output) */
45 #define TIP             0x20            /* Transfer in progress (output) */
46 #define ST_MASK         0x30            /* mask for selecting ADB state bits */
47
48 /* Bits in ACR */
49 #define SR_CTRL         0x1c            /* Shift register control bits */
50 #define SR_EXT          0x0c            /* Shift on external clock */
51 #define SR_OUT          0x10            /* Shift out if 1 */
52
53 /* Bits in IFR and IER */
54 #define IER_SET         0x80            /* set bits in IER */
55 #define IER_CLR         0               /* clear bits in IER */
56 #define SR_INT          0x04            /* Shift register full/empty */
57 #define SR_DATA         0x08            /* Shift register data */
58 #define SR_CLOCK        0x10            /* Shift register clock */
59
60 #define ADB_DELAY 150
61
62 #undef DEBUG_MACIISI_ADB
63
64 static struct adb_request* current_req;
65 static struct adb_request* last_req;
66 static unsigned char maciisi_rbuf[16];
67 static unsigned char *reply_ptr;
68 static int data_index;
69 static int reading_reply;
70 static int reply_len;
71 static int tmp;
72 static int need_sync;
73
74 static enum maciisi_state {
75     idle,
76     sending,
77     reading,
78 } maciisi_state;
79
80 static int maciisi_probe(void);
81 static int maciisi_init(void);
82 static int maciisi_send_request(struct adb_request* req, int sync);
83 static void maciisi_sync(struct adb_request *req);
84 static int maciisi_write(struct adb_request* req);
85 static irqreturn_t maciisi_interrupt(int irq, void* arg);
86 static void maciisi_input(unsigned char *buf, int nb);
87 static int maciisi_init_via(void);
88 static void maciisi_poll(void);
89 static int maciisi_start(void);
90
91 struct adb_driver via_maciisi_driver = {
92         "Mac IIsi",
93         maciisi_probe,
94         maciisi_init,
95         maciisi_send_request,
96         NULL, /* maciisi_adb_autopoll, */
97         maciisi_poll,
98         NULL /* maciisi_reset_adb_bus */
99 };
100
101 static int
102 maciisi_probe(void)
103 {
104         if (macintosh_config->adb_type != MAC_ADB_IISI)
105                 return -ENODEV;
106
107         via = via1;
108         return 0;
109 }
110
111 static int
112 maciisi_init(void)
113 {
114         int err;
115
116         if (via == NULL)
117                 return -ENODEV;
118
119         if ((err = maciisi_init_via())) {
120                 printk(KERN_ERR "maciisi_init: maciisi_init_via() failed, code %d\n", err);
121                 via = NULL;
122                 return err;
123         }
124
125         if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, 
126                         "ADB", maciisi_interrupt)) {
127                 printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
128                 return -EAGAIN;
129         }
130
131         printk("adb: Mac IIsi driver v0.2 for Unified ADB.\n");
132         return 0;
133 }
134
135 /* Flush data from the ADB controller */
136 static void
137 maciisi_stfu(void)
138 {
139         int status = via[B] & (TIP|TREQ);
140
141         if (status & TREQ) {
142 #ifdef DEBUG_MACIISI_ADB
143                 printk (KERN_DEBUG "maciisi_stfu called with TREQ high!\n");
144 #endif
145                 return;
146         }
147         
148         udelay(ADB_DELAY);
149         via[ACR] &= ~SR_OUT;
150         via[IER] = IER_CLR | SR_INT;
151
152         udelay(ADB_DELAY);
153
154         status = via[B] & (TIP|TREQ);
155
156         if (!(status & TREQ))
157         {
158                 via[B] |= TIP;
159
160                 while(1)
161                 {
162                         int poll_timeout = ADB_DELAY * 5;
163                         /* Poll for SR interrupt */
164                         while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
165                                 status = via[B] & (TIP|TREQ);
166
167                         tmp = via[SR]; /* Clear shift register */
168 #ifdef DEBUG_MACIISI_ADB
169                         printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d data %x\n",
170                                status, poll_timeout, tmp);
171 #endif  
172                         if(via[B] & TREQ)
173                                 break;
174         
175                         /* ACK on-off */
176                         via[B] |= TACK;
177                         udelay(ADB_DELAY);
178                         via[B] &= ~TACK;
179                 }
180
181                 /* end frame */
182                 via[B] &= ~TIP;
183                 udelay(ADB_DELAY);
184         }
185
186         via[IER] = IER_SET | SR_INT;    
187 }
188
189 /* All specifically VIA-related initialization goes here */
190 static int
191 maciisi_init_via(void)
192 {
193         int     i;
194         
195         /* Set the lines up. We want TREQ as input TACK|TIP as output */
196         via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
197         /* Shift register on input */
198         via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
199 #ifdef DEBUG_MACIISI_ADB
200         printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
201 #endif
202         /* Wipe any pending data and int */
203         tmp = via[SR];
204         /* Enable keyboard interrupts */
205         via[IER] = IER_SET | SR_INT;
206         /* Set initial state: idle */
207         via[B] &= ~(TACK|TIP);
208         /* Clear interrupt bit */
209         via[IFR] = SR_INT;
210
211         for(i = 0; i < 60; i++) {
212                 udelay(ADB_DELAY);
213                 maciisi_stfu();
214                 udelay(ADB_DELAY);
215                 if(via[B] & TREQ)
216                         break;
217         }
218         if (i == 60)
219                 printk(KERN_ERR "maciisi_init_via: bus jam?\n");
220
221         maciisi_state = idle;
222         need_sync = 0;
223
224         return 0;
225 }
226
227 /* Send a request, possibly waiting for a reply */
228 static int
229 maciisi_send_request(struct adb_request* req, int sync)
230 {
231         int i;
232
233 #ifdef DEBUG_MACIISI_ADB
234         static int dump_packet = 0;
235 #endif
236
237         if (via == NULL) {
238                 req->complete = 1;
239                 return -ENXIO;
240         }
241
242 #ifdef DEBUG_MACIISI_ADB
243         if (dump_packet) {
244                 printk(KERN_DEBUG "maciisi_send_request:");
245                 for (i = 0; i < req->nbytes; i++) {
246                         printk(" %.2x", req->data[i]);
247                 }
248                 printk(" sync %d\n", sync);
249         }
250 #endif
251
252         req->reply_expected = 1;
253         
254         i = maciisi_write(req);
255         if (i)
256         {
257                 /* Normally, if a packet requires syncing, that happens at the end of
258                  * maciisi_send_request. But if the transfer fails, it will be restarted
259                  * by maciisi_interrupt(). We use need_sync to tell maciisi_interrupt
260                  * when to sync a packet that it sends out.
261                  * 
262                  * Suggestions on a better way to do this are welcome.
263                  */
264                 if(i == -EBUSY && sync)
265                         need_sync = 1;
266                 else
267                         need_sync = 0;
268                 return i;
269         }
270         if(sync)
271                 maciisi_sync(req);
272         
273         return 0;
274 }
275
276 /* Poll the ADB chip until the request completes */
277 static void maciisi_sync(struct adb_request *req)
278 {
279         int count = 0; 
280
281 #ifdef DEBUG_MACIISI_ADB
282         printk(KERN_DEBUG "maciisi_sync called\n");
283 #endif
284
285         /* If for some reason the ADB chip shuts up on us, we want to avoid an endless loop. */
286         while (!req->complete && count++ < 50) {
287                 maciisi_poll();
288         }
289         /* This could be BAD... when the ADB controller doesn't respond
290          * for this long, it's probably not coming back :-( */
291         if (count > 50) /* Hopefully shouldn't happen */
292                 printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
293 }
294
295 int
296 maciisi_request(struct adb_request *req, void (*done)(struct adb_request *),
297             int nbytes, ...)
298 {
299         va_list list;
300         int i;
301
302         req->nbytes = nbytes;
303         req->done = done;
304         req->reply_expected = 0;
305         va_start(list, nbytes);
306         for (i = 0; i < nbytes; i++)
307                 req->data[i++] = va_arg(list, int);
308         va_end(list);
309
310         return maciisi_send_request(req, 1);
311 }
312
313 /* Enqueue a request, and run the queue if possible */
314 static int
315 maciisi_write(struct adb_request* req)
316 {
317         unsigned long flags;
318         int i;
319
320         /* We will accept CUDA packets - the VIA sends them to us, so
321            it figures that we should be able to send them to it */
322         if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
323                 printk(KERN_ERR "maciisi_write: packet too small or not an ADB or CUDA packet\n");
324                 req->complete = 1;
325                 return -EINVAL;
326         }
327         req->next = NULL;
328         req->sent = 0;
329         req->complete = 0;
330         req->reply_len = 0;
331         
332         local_irq_save(flags);
333
334         if (current_req) {
335                 last_req->next = req;
336                 last_req = req;
337         } else {
338                 current_req = req;
339                 last_req = req;
340         }
341         if (maciisi_state == idle)
342         {
343                 i = maciisi_start();
344                 if(i != 0)
345                 {
346                         local_irq_restore(flags);
347                         return i;
348                 }
349         }
350         else
351         {
352 #ifdef DEBUG_MACIISI_ADB
353                 printk(KERN_DEBUG "maciisi_write: would start, but state is %d\n", maciisi_state);
354 #endif
355                 local_irq_restore(flags);
356                 return -EBUSY;
357         }
358
359         local_irq_restore(flags);
360
361         return 0;
362 }
363
364 static int
365 maciisi_start(void)
366 {
367         struct adb_request* req;
368         int status;
369
370 #ifdef DEBUG_MACIISI_ADB
371         status = via[B] & (TIP | TREQ);
372
373         printk(KERN_DEBUG "maciisi_start called, state=%d, status=%x, ifr=%x\n", maciisi_state, status, via[IFR]);
374 #endif
375
376         if (maciisi_state != idle) {
377                 /* shouldn't happen */
378                 printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!\n");
379                 return -EBUSY;
380         }
381
382         req = current_req;
383         if (req == NULL)
384                 return -EINVAL;
385
386         status = via[B] & (TIP|TREQ);
387         if (!(status & TREQ)) {
388 #ifdef DEBUG_MACIISI_ADB
389                 printk(KERN_DEBUG "maciisi_start: bus busy - aborting\n");
390 #endif
391                 return -EBUSY;
392         }
393
394         /* Okay, send */
395 #ifdef DEBUG_MACIISI_ADB
396         printk(KERN_DEBUG "maciisi_start: sending\n");
397 #endif
398         /* Set state to active */
399         via[B] |= TIP;
400         /* ACK off */
401         via[B] &= ~TACK;
402         /* Delay */
403         udelay(ADB_DELAY);
404         /* Shift out and send */
405         via[ACR] |= SR_OUT;
406         via[SR] = req->data[0];
407         data_index = 1;
408         /* ACK on */
409         via[B] |= TACK;
410         maciisi_state = sending;
411
412         return 0;
413 }
414
415 void
416 maciisi_poll(void)
417 {
418         unsigned long flags;
419
420         local_irq_save(flags);
421         if (via[IFR] & SR_INT) {
422                 maciisi_interrupt(0, NULL);
423         }
424         else /* avoid calling this function too quickly in a loop */
425                 udelay(ADB_DELAY);
426
427         local_irq_restore(flags);
428 }
429
430 /* Shift register interrupt - this is *supposed* to mean that the
431    register is either full or empty. In practice, I have no idea what
432    it means :( */
433 static irqreturn_t
434 maciisi_interrupt(int irq, void* arg)
435 {
436         int status;
437         struct adb_request *req;
438 #ifdef DEBUG_MACIISI_ADB
439         static int dump_reply = 0;
440 #endif
441         int i;
442         unsigned long flags;
443
444         local_irq_save(flags);
445
446         status = via[B] & (TIP|TREQ);
447 #ifdef DEBUG_MACIISI_ADB
448         printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
449 #endif
450
451         if (!(via[IFR] & SR_INT)) {
452                 /* Shouldn't happen, we hope */
453                 printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
454                 local_irq_restore(flags);
455                 return IRQ_NONE;
456         }
457
458         /* Clear the interrupt */
459         /* via[IFR] = SR_INT; */
460
461  switch_start:
462         switch (maciisi_state) {
463         case idle:
464                 if (status & TIP)
465                         printk(KERN_ERR "maciisi_interrupt: state is idle but TIP asserted!\n");
466
467                 if(!reading_reply)
468                         udelay(ADB_DELAY);
469                 /* Shift in */
470                 via[ACR] &= ~SR_OUT;
471                 /* Signal start of frame */
472                 via[B] |= TIP;
473                 /* Clear the interrupt (throw this value on the floor, it's useless) */
474                 tmp = via[SR];
475                 /* ACK adb chip, high-low */
476                 via[B] |= TACK;
477                 udelay(ADB_DELAY);
478                 via[B] &= ~TACK;
479                 reply_len = 0;
480                 maciisi_state = reading;
481                 if (reading_reply) {
482                         reply_ptr = current_req->reply;
483                 } else {
484                         reply_ptr = maciisi_rbuf;
485                 }
486                 break;
487
488         case sending:
489                 /* via[SR]; */
490                 /* Set ACK off */
491                 via[B] &= ~TACK;
492                 req = current_req;
493
494                 if (!(status & TREQ)) {
495                         /* collision */
496                         printk(KERN_ERR "maciisi_interrupt: send collision\n");
497                         /* Set idle and input */
498                         via[ACR] &= ~SR_OUT;
499                         tmp = via[SR];
500                         via[B] &= ~TIP;
501                         /* Must re-send */
502                         reading_reply = 0;
503                         reply_len = 0;
504                         maciisi_state = idle;
505                         udelay(ADB_DELAY);
506                         /* process this now, because the IFR has been cleared */
507                         goto switch_start;
508                 }
509
510                 udelay(ADB_DELAY);
511
512                 if (data_index >= req->nbytes) {
513                         /* Sent the whole packet, put the bus back in idle state */
514                         /* Shift in, we are about to read a reply (hopefully) */
515                         via[ACR] &= ~SR_OUT;
516                         tmp = via[SR];
517                         /* End of frame */
518                         via[B] &= ~TIP;
519                         req->sent = 1;
520                         maciisi_state = idle;
521                         if (req->reply_expected) {
522                                 /* Note: only set this once we've
523                                    successfully sent the packet */
524                                 reading_reply = 1;
525                         } else {
526                                 current_req = req->next;
527                                 if (req->done)
528                                         (*req->done)(req);
529                                 /* Do any queued requests now */
530                                 i = maciisi_start();
531                                 if(i == 0 && need_sync) {
532                                         /* Packet needs to be synced */
533                                         maciisi_sync(current_req);
534                                 }
535                                 if(i != -EBUSY)
536                                         need_sync = 0;
537                         }
538                 } else {
539                         /* Sending more stuff */
540                         /* Shift out */
541                         via[ACR] |= SR_OUT;
542                         /* Write */
543                         via[SR] = req->data[data_index++];
544                         /* Signal 'byte ready' */
545                         via[B] |= TACK;
546                 }
547                 break;
548
549         case reading:
550                 /* Shift in */
551                 /* via[ACR] &= ~SR_OUT; */ /* Not in 2.2 */
552                 if (reply_len++ > 16) {
553                         printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
554                         via[B] |= TACK;
555                         udelay(ADB_DELAY);
556                         via[B] &= ~(TACK|TIP);
557                         maciisi_state = idle;
558                         i = maciisi_start();
559                         if(i == 0 && need_sync) {
560                                 /* Packet needs to be synced */
561                                 maciisi_sync(current_req);
562                         }
563                         if(i != -EBUSY)
564                                 need_sync = 0;
565                         break;
566                 }
567                 /* Read data */
568                 *reply_ptr++ = via[SR];
569                 status = via[B] & (TIP|TREQ);
570                 /* ACK on/off */
571                 via[B] |= TACK;
572                 udelay(ADB_DELAY);
573                 via[B] &= ~TACK;        
574                 if (!(status & TREQ))
575                         break; /* more stuff to deal with */
576                 
577                 /* end of frame */
578                 via[B] &= ~TIP;
579                 tmp = via[SR]; /* That's what happens in 2.2 */
580                 udelay(ADB_DELAY); /* Give controller time to recover */
581
582                 /* end of packet, deal with it */
583                 if (reading_reply) {
584                         req = current_req;
585                         req->reply_len = reply_ptr - req->reply;
586                         if (req->data[0] == ADB_PACKET) {
587                                 /* Have to adjust the reply from ADB commands */
588                                 if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
589                                         /* the 0x2 bit indicates no response */
590                                         req->reply_len = 0;
591                                 } else {
592                                         /* leave just the command and result bytes in the reply */
593                                         req->reply_len -= 2;
594                                         memmove(req->reply, req->reply + 2, req->reply_len);
595                                 }
596                         }
597 #ifdef DEBUG_MACIISI_ADB
598                         if (dump_reply) {
599                                 int i;
600                                 printk(KERN_DEBUG "maciisi_interrupt: reply is ");
601                                 for (i = 0; i < req->reply_len; ++i)
602                                         printk(" %.2x", req->reply[i]);
603                                 printk("\n");
604                         }
605 #endif
606                         req->complete = 1;
607                         current_req = req->next;
608                         if (req->done)
609                                 (*req->done)(req);
610                         /* Obviously, we got it */
611                         reading_reply = 0;
612                 } else {
613                         maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf);
614                 }
615                 maciisi_state = idle;
616                 status = via[B] & (TIP|TREQ);
617                 if (!(status & TREQ)) {
618                         /* Timeout?! More likely, another packet coming in already */
619 #ifdef DEBUG_MACIISI_ADB
620                         printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
621                                status, via[IFR]);
622 #endif
623 #if 0
624                         udelay(ADB_DELAY);
625                         via[B] |= TIP;
626
627                         maciisi_state = reading;
628                         reading_reply = 0;
629                         reply_ptr = maciisi_rbuf;
630 #else
631                         /* Process the packet now */
632                         reading_reply = 0;
633                         goto switch_start;
634 #endif
635                         /* We used to do this... but the controller might actually have data for us */
636                         /* maciisi_stfu(); */
637                 }
638                 else {
639                         /* Do any queued requests now if possible */
640                         i = maciisi_start();
641                         if(i == 0 && need_sync) {
642                                 /* Packet needs to be synced */
643                                 maciisi_sync(current_req);
644                         }
645                         if(i != -EBUSY)
646                                 need_sync = 0;
647                 }
648                 break;
649
650         default:
651                 printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
652         }
653         local_irq_restore(flags);
654         return IRQ_HANDLED;
655 }
656
657 static void
658 maciisi_input(unsigned char *buf, int nb)
659 {
660 #ifdef DEBUG_MACIISI_ADB
661     int i;
662 #endif
663
664     switch (buf[0]) {
665     case ADB_PACKET:
666             adb_input(buf+2, nb-2, buf[1] & 0x40);
667             break;
668     default:
669 #ifdef DEBUG_MACIISI_ADB
670             printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
671             for (i = 0; i < nb; ++i)
672                     printk(" %.2x", buf[i]);
673             printk("\n");
674 #endif
675             break;
676     }
677 }