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 v5.15-rc2 805 lines 20 kB view raw
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#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 32static volatile unsigned char __iomem *via; 33static 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 96static bool mcu_is_egret; 97#endif 98 99static inline bool TREQ_asserted(u8 portb) 100{ 101 return !(portb & TREQ); 102} 103 104static 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 113static 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 122static 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 131static inline void toggle_TACK(void) 132{ 133 out_8(&via[B], in_8(&via[B]) ^ TACK); 134} 135 136static 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 145static 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 154static enum cuda_state { 155 idle, 156 sent_first_byte, 157 sending, 158 reading, 159 read_done, 160 awaiting_reply 161} cuda_state; 162 163static struct adb_request *current_req; 164static struct adb_request *last_req; 165static unsigned char cuda_rbuf[16]; 166static unsigned char *reply_ptr; 167static int reading_reply; 168static int data_index; 169static int cuda_irq; 170#ifdef CONFIG_PPC 171static struct device_node *vias; 172#endif 173static int cuda_fully_inited; 174 175#ifdef CONFIG_ADB 176static int cuda_probe(void); 177static int cuda_send_request(struct adb_request *req, int sync); 178static int cuda_adb_autopoll(int devs); 179static int cuda_reset_adb_bus(void); 180#endif /* CONFIG_ADB */ 181 182static int cuda_init_via(void); 183static void cuda_start(void); 184static irqreturn_t cuda_interrupt(int irq, void *arg); 185static void cuda_input(unsigned char *buf, int nb); 186void cuda_poll(void); 187static int cuda_write(struct adb_request *req); 188 189int cuda_request(struct adb_request *req, 190 void (*done)(struct adb_request *), int nbytes, ...); 191 192#ifdef CONFIG_ADB 193struct 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 204int __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 232int __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 291static 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 318device_initcall(via_cuda_start); 319 320#ifdef CONFIG_ADB 321static int 322cuda_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 338static 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 377static 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 */ 426static int 427cuda_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 */ 451static int 452cuda_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?? */ 466static int 467cuda_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 */ 482int 483cuda_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} 503EXPORT_SYMBOL(cuda_request); 504 505static int 506cuda_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 534static void 535cuda_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 554void 555cuda_poll(void) 556{ 557 cuda_interrupt(0, NULL); 558} 559EXPORT_SYMBOL(cuda_poll); 560 561#define ARRAY_FULL(a, p) ((p) - (a) == ARRAY_SIZE(a)) 562 563static irqreturn_t 564cuda_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]); 600idle_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]); 684read_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 741static void 742cuda_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 775time64_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 791int 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}