Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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