root/drivers/macintosh/via-cuda.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. TREQ_asserted
  2. assert_TIP
  3. assert_TIP_and_TACK
  4. assert_TACK
  5. toggle_TACK
  6. negate_TACK
  7. negate_TIP_and_TACK
  8. find_via_cuda
  9. find_via_cuda
  10. via_cuda_start
  11. cuda_probe
  12. sync_egret
  13. cuda_init_via
  14. cuda_send_request
  15. cuda_adb_autopoll
  16. cuda_reset_adb_bus
  17. cuda_request
  18. cuda_write
  19. cuda_start
  20. cuda_poll
  21. cuda_interrupt
  22. cuda_input
  23. cuda_get_time
  24. cuda_set_rtc_time

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Device driver for the Cuda and Egret system controllers found on PowerMacs
   4  * and 68k Macs.
   5  *
   6  * The Cuda or Egret is a 6805 microcontroller interfaced to the 6522 VIA.
   7  * This MCU controls system power, Parameter RAM, Real Time Clock and the
   8  * Apple Desktop Bus (ADB) that connects to the keyboard and mouse.
   9  *
  10  * Copyright (C) 1996 Paul Mackerras.
  11  */
  12 #include <stdarg.h>
  13 #include <linux/types.h>
  14 #include <linux/errno.h>
  15 #include <linux/kernel.h>
  16 #include <linux/delay.h>
  17 #include <linux/adb.h>
  18 #include <linux/cuda.h>
  19 #include <linux/spinlock.h>
  20 #include <linux/interrupt.h>
  21 #ifdef CONFIG_PPC
  22 #include <asm/prom.h>
  23 #include <asm/machdep.h>
  24 #else
  25 #include <asm/macintosh.h>
  26 #include <asm/macints.h>
  27 #include <asm/mac_via.h>
  28 #endif
  29 #include <asm/io.h>
  30 #include <linux/init.h>
  31 
  32 static volatile unsigned char __iomem *via;
  33 static DEFINE_SPINLOCK(cuda_lock);
  34 
  35 /* VIA registers - spaced 0x200 bytes apart */
  36 #define RS              0x200           /* skip between registers */
  37 #define B               0               /* B-side data */
  38 #define A               RS              /* A-side data */
  39 #define DIRB            (2*RS)          /* B-side direction (1=output) */
  40 #define DIRA            (3*RS)          /* A-side direction (1=output) */
  41 #define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
  42 #define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
  43 #define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
  44 #define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
  45 #define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
  46 #define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
  47 #define SR              (10*RS)         /* Shift register */
  48 #define ACR             (11*RS)         /* Auxiliary control register */
  49 #define PCR             (12*RS)         /* Peripheral control register */
  50 #define IFR             (13*RS)         /* Interrupt flag register */
  51 #define IER             (14*RS)         /* Interrupt enable register */
  52 #define ANH             (15*RS)         /* A-side data, no handshake */
  53 
  54 /*
  55  * When the Cuda design replaced the Egret, some signal names and
  56  * logic sense changed. They all serve the same purposes, however.
  57  *
  58  *   VIA pin       |  Egret pin
  59  * ----------------+------------------------------------------
  60  *   PB3 (input)   |  Transceiver session   (active low)
  61  *   PB4 (output)  |  VIA full              (active high)
  62  *   PB5 (output)  |  System session        (active high)
  63  *
  64  *   VIA pin       |  Cuda pin
  65  * ----------------+------------------------------------------
  66  *   PB3 (input)   |  Transfer request      (active low)
  67  *   PB4 (output)  |  Byte acknowledge      (active low)
  68  *   PB5 (output)  |  Transfer in progress  (active low)
  69  */
  70 
  71 /* Bits in Port B data register */
  72 #define TREQ            0x08            /* Transfer request */
  73 #define TACK            0x10            /* Transfer acknowledge */
  74 #define TIP             0x20            /* Transfer in progress */
  75 
  76 /* Bits in ACR */
  77 #define SR_CTRL         0x1c            /* Shift register control bits */
  78 #define SR_EXT          0x0c            /* Shift on external clock */
  79 #define SR_OUT          0x10            /* Shift out if 1 */
  80 
  81 /* Bits in IFR and IER */
  82 #define IER_SET         0x80            /* set bits in IER */
  83 #define IER_CLR         0               /* clear bits in IER */
  84 #define SR_INT          0x04            /* Shift register full/empty */
  85 
  86 /* Duration of byte acknowledgement pulse (us) */
  87 #define EGRET_TACK_ASSERTED_DELAY       300
  88 #define EGRET_TACK_NEGATED_DELAY        400
  89 
  90 /* Interval from interrupt to start of session (us) */
  91 #define EGRET_SESSION_DELAY             450
  92 
  93 #ifdef CONFIG_PPC
  94 #define mcu_is_egret    false
  95 #else
  96 static bool mcu_is_egret;
  97 #endif
  98 
  99 static inline bool TREQ_asserted(u8 portb)
 100 {
 101         return !(portb & TREQ);
 102 }
 103 
 104 static inline void assert_TIP(void)
 105 {
 106         if (mcu_is_egret) {
 107                 udelay(EGRET_SESSION_DELAY);
 108                 out_8(&via[B], in_8(&via[B]) | TIP);
 109         } else
 110                 out_8(&via[B], in_8(&via[B]) & ~TIP);
 111 }
 112 
 113 static inline void assert_TIP_and_TACK(void)
 114 {
 115         if (mcu_is_egret) {
 116                 udelay(EGRET_SESSION_DELAY);
 117                 out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 118         } else
 119                 out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 120 }
 121 
 122 static inline void assert_TACK(void)
 123 {
 124         if (mcu_is_egret) {
 125                 udelay(EGRET_TACK_NEGATED_DELAY);
 126                 out_8(&via[B], in_8(&via[B]) | TACK);
 127         } else
 128                 out_8(&via[B], in_8(&via[B]) & ~TACK);
 129 }
 130 
 131 static inline void toggle_TACK(void)
 132 {
 133         out_8(&via[B], in_8(&via[B]) ^ TACK);
 134 }
 135 
 136 static inline void negate_TACK(void)
 137 {
 138         if (mcu_is_egret) {
 139                 udelay(EGRET_TACK_ASSERTED_DELAY);
 140                 out_8(&via[B], in_8(&via[B]) & ~TACK);
 141         } else
 142                 out_8(&via[B], in_8(&via[B]) | TACK);
 143 }
 144 
 145 static inline void negate_TIP_and_TACK(void)
 146 {
 147         if (mcu_is_egret) {
 148                 udelay(EGRET_TACK_ASSERTED_DELAY);
 149                 out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 150         } else
 151                 out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 152 }
 153 
 154 static enum cuda_state {
 155     idle,
 156     sent_first_byte,
 157     sending,
 158     reading,
 159     read_done,
 160     awaiting_reply
 161 } cuda_state;
 162 
 163 static struct adb_request *current_req;
 164 static struct adb_request *last_req;
 165 static unsigned char cuda_rbuf[16];
 166 static unsigned char *reply_ptr;
 167 static int reading_reply;
 168 static int data_index;
 169 static int cuda_irq;
 170 #ifdef CONFIG_PPC
 171 static struct device_node *vias;
 172 #endif
 173 static int cuda_fully_inited;
 174 
 175 #ifdef CONFIG_ADB
 176 static int cuda_probe(void);
 177 static int cuda_send_request(struct adb_request *req, int sync);
 178 static int cuda_adb_autopoll(int devs);
 179 static int cuda_reset_adb_bus(void);
 180 #endif /* CONFIG_ADB */
 181 
 182 static int cuda_init_via(void);
 183 static void cuda_start(void);
 184 static irqreturn_t cuda_interrupt(int irq, void *arg);
 185 static void cuda_input(unsigned char *buf, int nb);
 186 void cuda_poll(void);
 187 static int cuda_write(struct adb_request *req);
 188 
 189 int cuda_request(struct adb_request *req,
 190                  void (*done)(struct adb_request *), int nbytes, ...);
 191 
 192 #ifdef CONFIG_ADB
 193 struct adb_driver via_cuda_driver = {
 194         .name         = "CUDA",
 195         .probe        = cuda_probe,
 196         .send_request = cuda_send_request,
 197         .autopoll     = cuda_adb_autopoll,
 198         .poll         = cuda_poll,
 199         .reset_bus    = cuda_reset_adb_bus,
 200 };
 201 #endif /* CONFIG_ADB */
 202 
 203 #ifdef CONFIG_MAC
 204 int __init find_via_cuda(void)
 205 {
 206     struct adb_request req;
 207     int err;
 208 
 209     if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 210         macintosh_config->adb_type != MAC_ADB_EGRET)
 211         return 0;
 212 
 213     via = via1;
 214     cuda_state = idle;
 215     mcu_is_egret = macintosh_config->adb_type == MAC_ADB_EGRET;
 216 
 217     err = cuda_init_via();
 218     if (err) {
 219         printk(KERN_ERR "cuda_init_via() failed\n");
 220         via = NULL;
 221         return 0;
 222     }
 223 
 224     /* enable autopoll */
 225     cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 226     while (!req.complete)
 227         cuda_poll();
 228 
 229     return 1;
 230 }
 231 #else
 232 int __init find_via_cuda(void)
 233 {
 234     struct adb_request req;
 235     phys_addr_t taddr;
 236     const u32 *reg;
 237     int err;
 238 
 239     if (vias != 0)
 240         return 1;
 241     vias = of_find_node_by_name(NULL, "via-cuda");
 242     if (vias == 0)
 243         return 0;
 244 
 245     reg = of_get_property(vias, "reg", NULL);
 246     if (reg == NULL) {
 247             printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
 248             goto fail;
 249     }
 250     taddr = of_translate_address(vias, reg);
 251     if (taddr == 0) {
 252             printk(KERN_ERR "via-cuda: Can't translate address !\n");
 253             goto fail;
 254     }
 255     via = ioremap(taddr, 0x2000);
 256     if (via == NULL) {
 257             printk(KERN_ERR "via-cuda: Can't map address !\n");
 258             goto fail;
 259     }
 260 
 261     cuda_state = idle;
 262     sys_ctrler = SYS_CTRLER_CUDA;
 263 
 264     err = cuda_init_via();
 265     if (err) {
 266         printk(KERN_ERR "cuda_init_via() failed\n");
 267         via = NULL;
 268         return 0;
 269     }
 270 
 271     /* Clear and enable interrupts, but only on PPC. On 68K it's done  */
 272     /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 273 
 274     out_8(&via[IFR], 0x7f);     /* clear interrupts by writing 1s */
 275     out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
 276 
 277     /* enable autopoll */
 278     cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 279     while (!req.complete)
 280         cuda_poll();
 281 
 282     return 1;
 283 
 284  fail:
 285     of_node_put(vias);
 286     vias = NULL;
 287     return 0;
 288 }
 289 #endif /* !defined CONFIG_MAC */
 290 
 291 static int __init via_cuda_start(void)
 292 {
 293     if (via == NULL)
 294         return -ENODEV;
 295 
 296 #ifdef CONFIG_MAC
 297     cuda_irq = IRQ_MAC_ADB;
 298 #else
 299     cuda_irq = irq_of_parse_and_map(vias, 0);
 300     if (!cuda_irq) {
 301         printk(KERN_ERR "via-cuda: can't map interrupts for %pOF\n",
 302                vias);
 303         return -ENODEV;
 304     }
 305 #endif
 306 
 307     if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
 308         printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq);
 309         return -EAGAIN;
 310     }
 311 
 312     pr_info("Macintosh Cuda and Egret driver.\n");
 313 
 314     cuda_fully_inited = 1;
 315     return 0;
 316 }
 317 
 318 device_initcall(via_cuda_start);
 319 
 320 #ifdef CONFIG_ADB
 321 static int
 322 cuda_probe(void)
 323 {
 324 #ifdef CONFIG_PPC
 325     if (sys_ctrler != SYS_CTRLER_CUDA)
 326         return -ENODEV;
 327 #else
 328     if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 329         macintosh_config->adb_type != MAC_ADB_EGRET)
 330         return -ENODEV;
 331 #endif
 332     if (via == NULL)
 333         return -ENODEV;
 334     return 0;
 335 }
 336 #endif /* CONFIG_ADB */
 337 
 338 static int __init sync_egret(void)
 339 {
 340         if (TREQ_asserted(in_8(&via[B]))) {
 341                 /* Complete the inbound transfer */
 342                 assert_TIP_and_TACK();
 343                 while (1) {
 344                         negate_TACK();
 345                         mdelay(1);
 346                         (void)in_8(&via[SR]);
 347                         assert_TACK();
 348                         if (!TREQ_asserted(in_8(&via[B])))
 349                                 break;
 350                 }
 351                 negate_TIP_and_TACK();
 352         } else if (in_8(&via[B]) & TIP) {
 353                 /* Terminate the outbound transfer */
 354                 negate_TACK();
 355                 assert_TACK();
 356                 mdelay(1);
 357                 negate_TIP_and_TACK();
 358         }
 359         /* Clear shift register interrupt */
 360         if (in_8(&via[IFR]) & SR_INT)
 361                 (void)in_8(&via[SR]);
 362         return 0;
 363 }
 364 
 365 #define WAIT_FOR(cond, what)                                    \
 366     do {                                                        \
 367         int x;                                                  \
 368         for (x = 1000; !(cond); --x) {                          \
 369             if (x == 0) {                                       \
 370                 pr_err("Timeout waiting for " what "\n");       \
 371                 return -ENXIO;                                  \
 372             }                                                   \
 373             udelay(100);                                        \
 374         }                                                       \
 375     } while (0)
 376 
 377 static int
 378 __init cuda_init_via(void)
 379 {
 380 #ifdef CONFIG_PPC
 381     out_8(&via[IER], 0x7f);                                     /* disable interrupts from VIA */
 382     (void)in_8(&via[IER]);
 383 #else
 384     out_8(&via[IER], SR_INT);                                   /* disable SR interrupt from VIA */
 385 #endif
 386 
 387     out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */
 388     out_8(&via[ACR], (in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);    /* SR data in */
 389     (void)in_8(&via[SR]);                                       /* clear any left-over data */
 390 
 391     if (mcu_is_egret)
 392         return sync_egret();
 393 
 394     negate_TIP_and_TACK();
 395 
 396     /* delay 4ms and then clear any pending interrupt */
 397     mdelay(4);
 398     (void)in_8(&via[SR]);
 399     out_8(&via[IFR], SR_INT);
 400 
 401     /* sync with the CUDA - assert TACK without TIP */
 402     assert_TACK();
 403 
 404     /* wait for the CUDA to assert TREQ in response */
 405     WAIT_FOR(TREQ_asserted(in_8(&via[B])), "CUDA response to sync");
 406 
 407     /* wait for the interrupt and then clear it */
 408     WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
 409     (void)in_8(&via[SR]);
 410     out_8(&via[IFR], SR_INT);
 411 
 412     /* finish the sync by negating TACK */
 413     negate_TACK();
 414 
 415     /* wait for the CUDA to negate TREQ and the corresponding interrupt */
 416     WAIT_FOR(!TREQ_asserted(in_8(&via[B])), "CUDA response to sync (3)");
 417     WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
 418     (void)in_8(&via[SR]);
 419     out_8(&via[IFR], SR_INT);
 420 
 421     return 0;
 422 }
 423 
 424 #ifdef CONFIG_ADB
 425 /* Send an ADB command */
 426 static int
 427 cuda_send_request(struct adb_request *req, int sync)
 428 {
 429     int i;
 430 
 431     if ((via == NULL) || !cuda_fully_inited) {
 432         req->complete = 1;
 433         return -ENXIO;
 434     }
 435   
 436     req->reply_expected = 1;
 437 
 438     i = cuda_write(req);
 439     if (i)
 440         return i;
 441 
 442     if (sync) {
 443         while (!req->complete)
 444             cuda_poll();
 445     }
 446     return 0;
 447 }
 448 
 449 
 450 /* Enable/disable autopolling */
 451 static int
 452 cuda_adb_autopoll(int devs)
 453 {
 454     struct adb_request req;
 455 
 456     if ((via == NULL) || !cuda_fully_inited)
 457         return -ENXIO;
 458 
 459     cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, (devs? 1: 0));
 460     while (!req.complete)
 461         cuda_poll();
 462     return 0;
 463 }
 464 
 465 /* Reset adb bus - how do we do this?? */
 466 static int
 467 cuda_reset_adb_bus(void)
 468 {
 469     struct adb_request req;
 470 
 471     if ((via == NULL) || !cuda_fully_inited)
 472         return -ENXIO;
 473 
 474     cuda_request(&req, NULL, 2, ADB_PACKET, 0);         /* maybe? */
 475     while (!req.complete)
 476         cuda_poll();
 477     return 0;
 478 }
 479 #endif /* CONFIG_ADB */
 480 
 481 /* Construct and send a cuda request */
 482 int
 483 cuda_request(struct adb_request *req, void (*done)(struct adb_request *),
 484              int nbytes, ...)
 485 {
 486     va_list list;
 487     int i;
 488 
 489     if (via == NULL) {
 490         req->complete = 1;
 491         return -ENXIO;
 492     }
 493 
 494     req->nbytes = nbytes;
 495     req->done = done;
 496     va_start(list, nbytes);
 497     for (i = 0; i < nbytes; ++i)
 498         req->data[i] = va_arg(list, int);
 499     va_end(list);
 500     req->reply_expected = 1;
 501     return cuda_write(req);
 502 }
 503 EXPORT_SYMBOL(cuda_request);
 504 
 505 static int
 506 cuda_write(struct adb_request *req)
 507 {
 508     unsigned long flags;
 509 
 510     if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
 511         req->complete = 1;
 512         return -EINVAL;
 513     }
 514     req->next = NULL;
 515     req->sent = 0;
 516     req->complete = 0;
 517     req->reply_len = 0;
 518 
 519     spin_lock_irqsave(&cuda_lock, flags);
 520     if (current_req != 0) {
 521         last_req->next = req;
 522         last_req = req;
 523     } else {
 524         current_req = req;
 525         last_req = req;
 526         if (cuda_state == idle)
 527             cuda_start();
 528     }
 529     spin_unlock_irqrestore(&cuda_lock, flags);
 530 
 531     return 0;
 532 }
 533 
 534 static void
 535 cuda_start(void)
 536 {
 537     /* assert cuda_state == idle */
 538     if (current_req == NULL)
 539         return;
 540     data_index = 0;
 541     if (TREQ_asserted(in_8(&via[B])))
 542         return;                 /* a byte is coming in from the CUDA */
 543 
 544     /* set the shift register to shift out and send a byte */
 545     out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
 546     out_8(&via[SR], current_req->data[data_index++]);
 547     if (mcu_is_egret)
 548         assert_TIP_and_TACK();
 549     else
 550         assert_TIP();
 551     cuda_state = sent_first_byte;
 552 }
 553 
 554 void
 555 cuda_poll(void)
 556 {
 557         cuda_interrupt(0, NULL);
 558 }
 559 EXPORT_SYMBOL(cuda_poll);
 560 
 561 #define ARRAY_FULL(a, p)        ((p) - (a) == ARRAY_SIZE(a))
 562 
 563 static irqreturn_t
 564 cuda_interrupt(int irq, void *arg)
 565 {
 566     unsigned long flags;
 567     u8 status;
 568     struct adb_request *req = NULL;
 569     unsigned char ibuf[16];
 570     int ibuf_len = 0;
 571     int complete = 0;
 572     bool full;
 573     
 574     spin_lock_irqsave(&cuda_lock, flags);
 575 
 576     /* On powermacs, this handler is registered for the VIA IRQ. But they use
 577      * just the shift register IRQ -- other VIA interrupt sources are disabled.
 578      * On m68k macs, the VIA IRQ sources are dispatched individually. Unless
 579      * we are polling, the shift register IRQ flag has already been cleared.
 580      */
 581 
 582 #ifdef CONFIG_MAC
 583     if (!arg)
 584 #endif
 585     {
 586         if ((in_8(&via[IFR]) & SR_INT) == 0) {
 587             spin_unlock_irqrestore(&cuda_lock, flags);
 588             return IRQ_NONE;
 589         } else {
 590             out_8(&via[IFR], SR_INT);
 591         }
 592     }
 593 
 594     status = in_8(&via[B]) & (TIP | TACK | TREQ);
 595 
 596     switch (cuda_state) {
 597     case idle:
 598         /* System controller has unsolicited data for us */
 599         (void)in_8(&via[SR]);
 600 idle_state:
 601         assert_TIP();
 602         cuda_state = reading;
 603         reply_ptr = cuda_rbuf;
 604         reading_reply = 0;
 605         break;
 606 
 607     case awaiting_reply:
 608         /* System controller has reply data for us */
 609         (void)in_8(&via[SR]);
 610         assert_TIP();
 611         cuda_state = reading;
 612         reply_ptr = current_req->reply;
 613         reading_reply = 1;
 614         break;
 615 
 616     case sent_first_byte:
 617         if (TREQ_asserted(status)) {
 618             /* collision */
 619             out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 620             (void)in_8(&via[SR]);
 621             negate_TIP_and_TACK();
 622             cuda_state = idle;
 623             /* Egret does not raise an "aborted" interrupt */
 624             if (mcu_is_egret)
 625                 goto idle_state;
 626         } else {
 627             out_8(&via[SR], current_req->data[data_index++]);
 628             toggle_TACK();
 629             if (mcu_is_egret)
 630                 assert_TACK();
 631             cuda_state = sending;
 632         }
 633         break;
 634 
 635     case sending:
 636         req = current_req;
 637         if (data_index >= req->nbytes) {
 638             out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 639             (void)in_8(&via[SR]);
 640             negate_TIP_and_TACK();
 641             req->sent = 1;
 642             if (req->reply_expected) {
 643                 cuda_state = awaiting_reply;
 644             } else {
 645                 current_req = req->next;
 646                 complete = 1;
 647                 /* not sure about this */
 648                 cuda_state = idle;
 649                 cuda_start();
 650             }
 651         } else {
 652             out_8(&via[SR], req->data[data_index++]);
 653             toggle_TACK();
 654             if (mcu_is_egret)
 655                 assert_TACK();
 656         }
 657         break;
 658 
 659     case reading:
 660         full = reading_reply ? ARRAY_FULL(current_req->reply, reply_ptr)
 661                              : ARRAY_FULL(cuda_rbuf, reply_ptr);
 662         if (full)
 663             (void)in_8(&via[SR]);
 664         else
 665             *reply_ptr++ = in_8(&via[SR]);
 666         if (!TREQ_asserted(status) || full) {
 667             if (mcu_is_egret)
 668                 assert_TACK();
 669             /* that's all folks */
 670             negate_TIP_and_TACK();
 671             cuda_state = read_done;
 672             /* Egret does not raise a "read done" interrupt */
 673             if (mcu_is_egret)
 674                 goto read_done_state;
 675         } else {
 676             toggle_TACK();
 677             if (mcu_is_egret)
 678                 negate_TACK();
 679         }
 680         break;
 681 
 682     case read_done:
 683         (void)in_8(&via[SR]);
 684 read_done_state:
 685         if (reading_reply) {
 686             req = current_req;
 687             req->reply_len = reply_ptr - req->reply;
 688             if (req->data[0] == ADB_PACKET) {
 689                 /* Have to adjust the reply from ADB commands */
 690                 if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
 691                     /* the 0x2 bit indicates no response */
 692                     req->reply_len = 0;
 693                 } else {
 694                     /* leave just the command and result bytes in the reply */
 695                     req->reply_len -= 2;
 696                     memmove(req->reply, req->reply + 2, req->reply_len);
 697                 }
 698             }
 699             current_req = req->next;
 700             complete = 1;
 701             reading_reply = 0;
 702         } else {
 703             /* This is tricky. We must break the spinlock to call
 704              * cuda_input. However, doing so means we might get
 705              * re-entered from another CPU getting an interrupt
 706              * or calling cuda_poll(). I ended up using the stack
 707              * (it's only for 16 bytes) and moving the actual
 708              * call to cuda_input to outside of the lock.
 709              */
 710             ibuf_len = reply_ptr - cuda_rbuf;
 711             memcpy(ibuf, cuda_rbuf, ibuf_len);
 712         }
 713         reply_ptr = cuda_rbuf;
 714         cuda_state = idle;
 715         cuda_start();
 716         if (cuda_state == idle && TREQ_asserted(in_8(&via[B]))) {
 717             assert_TIP();
 718             cuda_state = reading;
 719         }
 720         break;
 721 
 722     default:
 723         pr_err("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
 724     }
 725     spin_unlock_irqrestore(&cuda_lock, flags);
 726     if (complete && req) {
 727         void (*done)(struct adb_request *) = req->done;
 728         mb();
 729         req->complete = 1;
 730         /* Here, we assume that if the request has a done member, the
 731          * struct request will survive to setting req->complete to 1
 732          */
 733         if (done)
 734                 (*done)(req);
 735     }
 736     if (ibuf_len)
 737         cuda_input(ibuf, ibuf_len);
 738     return IRQ_HANDLED;
 739 }
 740 
 741 static void
 742 cuda_input(unsigned char *buf, int nb)
 743 {
 744     switch (buf[0]) {
 745     case ADB_PACKET:
 746 #ifdef CONFIG_XMON
 747         if (nb == 5 && buf[2] == 0x2c) {
 748             extern int xmon_wants_key, xmon_adb_keycode;
 749             if (xmon_wants_key) {
 750                 xmon_adb_keycode = buf[3];
 751                 return;
 752             }
 753         }
 754 #endif /* CONFIG_XMON */
 755 #ifdef CONFIG_ADB
 756         adb_input(buf+2, nb-2, buf[1] & 0x40);
 757 #endif /* CONFIG_ADB */
 758         break;
 759 
 760     case TIMER_PACKET:
 761         /* Egret sends these periodically. Might be useful as a 'heartbeat'
 762          * to trigger a recovery for the VIA shift register errata.
 763          */
 764         break;
 765 
 766     default:
 767         print_hex_dump(KERN_INFO, "cuda_input: ", DUMP_PREFIX_NONE, 32, 1,
 768                        buf, nb, false);
 769     }
 770 }
 771 
 772 /* Offset between Unix time (1970-based) and Mac time (1904-based) */
 773 #define RTC_OFFSET      2082844800
 774 
 775 time64_t cuda_get_time(void)
 776 {
 777         struct adb_request req;
 778         u32 now;
 779 
 780         if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
 781                 return 0;
 782         while (!req.complete)
 783                 cuda_poll();
 784         if (req.reply_len != 7)
 785                 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
 786         now = (req.reply[3] << 24) + (req.reply[4] << 16) +
 787               (req.reply[5] << 8) + req.reply[6];
 788         return (time64_t)now - RTC_OFFSET;
 789 }
 790 
 791 int cuda_set_rtc_time(struct rtc_time *tm)
 792 {
 793         u32 now;
 794         struct adb_request req;
 795 
 796         now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
 797         if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
 798                          now >> 24, now >> 16, now >> 8, now) < 0)
 799                 return -ENXIO;
 800         while (!req.complete)
 801                 cuda_poll();
 802         if ((req.reply_len != 3) && (req.reply_len != 7))
 803                 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
 804         return 0;
 805 }

/* [<][>][^][v][top][bottom][index][help] */