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