cuda.c revision 1.29.2.6 1 /* $NetBSD: cuda.c,v 1.29.2.6 2021/09/13 14:47:28 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 2006 Michael Lorenz
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: cuda.c,v 1.29.2.6 2021/09/13 14:47:28 thorpej Exp $");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
36 #include <sys/proc.h>
37 #include <sys/mutex.h>
38
39 #include <sys/bus.h>
40 #include <machine/autoconf.h>
41 #include <machine/pio.h>
42 #include <dev/clock_subr.h>
43 #include <dev/i2c/i2cvar.h>
44 #include <dev/i2c/i2c_enum.h>
45
46 #include <macppc/dev/viareg.h>
47 #include <macppc/dev/cudavar.h>
48
49 #include <dev/ofw/openfirm.h>
50 #include <dev/adb/adbvar.h>
51 #include "opt_cuda.h"
52
53 #ifdef CUDA_DEBUG
54 #define DPRINTF printf
55 #else
56 #define DPRINTF while (0) printf
57 #endif
58
59 #define CUDA_NOTREADY 0x1 /* has not been initialized yet */
60 #define CUDA_IDLE 0x2 /* the bus is currently idle */
61 #define CUDA_OUT 0x3 /* sending out a command */
62 #define CUDA_IN 0x4 /* receiving data */
63 #define CUDA_POLLING 0x5 /* polling - II only */
64
65 static void cuda_attach(device_t, device_t, void *);
66 static int cuda_match(device_t, struct cfdata *, void *);
67 static void cuda_autopoll(void *, int);
68
69 static int cuda_intr(void *);
70
71 typedef struct _cuda_handler {
72 int (*handler)(void *, int, uint8_t *);
73 void *cookie;
74 } CudaHandler;
75
76 #define CUDA_MAX_I2C_DEVICES 2
77
78 struct cuda_softc {
79 device_t sc_dev;
80 void *sc_ih;
81 CudaHandler sc_handlers[16];
82 struct todr_chip_handle sc_todr;
83 struct adb_bus_accessops sc_adbops;
84 struct i2c_controller sc_i2c;
85 bus_space_tag_t sc_memt;
86 bus_space_handle_t sc_memh;
87
88 /*
89 * We provide our own i2c device enumeration method, so we
90 * need to provide our own devhandle_impl.
91 */
92 struct devhandle_impl sc_devhandle_impl;
93
94 struct i2c_deventry sc_i2c_devices[CUDA_MAX_I2C_DEVICES];
95 unsigned int sc_ni2c_devices;
96
97 int sc_node;
98 int sc_state;
99 int sc_waiting;
100 int sc_polling;
101 int sc_sent;
102 int sc_out_length;
103 int sc_received;
104 int sc_iic_done;
105 int sc_error;
106 /* time */
107 uint32_t sc_tod;
108 uint32_t sc_autopoll;
109 uint32_t sc_todev;
110 /* ADB */
111 void (*sc_adb_handler)(void *, int, uint8_t *);
112 void *sc_adb_cookie;
113 uint32_t sc_i2c_read_len;
114 /* internal buffers */
115 uint8_t sc_in[256];
116 uint8_t sc_out[256];
117 };
118
119 CFATTACH_DECL_NEW(cuda, sizeof(struct cuda_softc),
120 cuda_match, cuda_attach, NULL, NULL);
121
122 static inline void cuda_write_reg(struct cuda_softc *, int, uint8_t);
123 static inline uint8_t cuda_read_reg(struct cuda_softc *, int);
124 static void cuda_idle(struct cuda_softc *);
125 static void cuda_tip(struct cuda_softc *);
126 static void cuda_clear_tip(struct cuda_softc *);
127 static void cuda_in(struct cuda_softc *);
128 static void cuda_out(struct cuda_softc *);
129 static void cuda_toggle_ack(struct cuda_softc *);
130 static void cuda_ack_off(struct cuda_softc *);
131 static int cuda_intr_state(struct cuda_softc *);
132
133 static void cuda_init(struct cuda_softc *);
134
135 /*
136 * send a message to Cuda.
137 */
138 /* cookie, flags, length, data */
139 static int cuda_send(void *, int, int, uint8_t *);
140 static void cuda_poll(void *);
141 static void cuda_adb_poll(void *);
142 static int cuda_set_handler(void *, int, int (*)(void *, int, uint8_t *), void *);
143
144 static int cuda_error_handler(void *, int, uint8_t *);
145
146 static int cuda_todr_handler(void *, int, uint8_t *);
147 static int cuda_todr_set(todr_chip_handle_t, struct timeval *);
148 static int cuda_todr_get(todr_chip_handle_t, struct timeval *);
149
150 static int cuda_adb_handler(void *, int, uint8_t *);
151 static void cuda_final(device_t);
152
153 static struct cuda_attach_args *cuda0 = NULL;
154
155 /* ADB bus attachment stuff */
156 static int cuda_adb_send(void *, int, int, int, uint8_t *);
157 static int cuda_adb_set_handler(void *, void (*)(void *, int, uint8_t *), void *);
158
159 /* i2c stuff */
160 static int cuda_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
161 void *, size_t, int);
162
163 static void
164 cuda_add_i2c_device(struct cuda_softc *sc, const char *name,
165 const char *compatible, i2c_addr_t addr)
166 {
167 KASSERT(sc->sc_ni2c_devices < CUDA_MAX_I2C_DEVICES);
168 sc->sc_i2c_devices[sc->sc_ni2c_devices].name = name;
169 sc->sc_i2c_devices[sc->sc_ni2c_devices].compat = compatible;
170 sc->sc_i2c_devices[sc->sc_ni2c_devices].addr = addr;
171 sc->sc_ni2c_devices++;
172 }
173
174 static int
175 cuda_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
176 {
177 struct i2c_enumerate_devices_args *args = v;
178
179 /* dev is the "iicbus" instance. Cuda softc is in args. */
180 struct cuda_softc *sc = args->ia->ia_tag->ic_cookie;
181
182 return i2c_enumerate_deventries(dev, call_handle, args,
183 sc->sc_i2c_devices, sc->sc_ni2c_devices);
184 }
185
186 static device_call_t
187 cuda_devhandle_lookup_device_call(devhandle_t handle, const char *name,
188 devhandle_t *call_handlep)
189 {
190 if (strcmp(name, "i2c-enumerate-devices") == 0) {
191 return cuda_i2c_enumerate_devices;
192 }
193
194 /* Defer everything else to the "super". */
195 return NULL;
196 }
197
198 static int
199 cuda_match(device_t parent, struct cfdata *cf, void *aux)
200 {
201 struct confargs *ca = aux;
202
203 if (ca->ca_nreg < 8)
204 return 0;
205
206 if (ca->ca_nintr < 4)
207 return 0;
208
209 if (strcmp(ca->ca_name, "via-cuda") == 0) {
210 return 10; /* beat adb* at obio? */
211 }
212
213 return 0;
214 }
215
216 static void
217 cuda_attach(device_t parent, device_t self, void *aux)
218 {
219 struct confargs *ca = aux;
220 struct cuda_softc *sc = device_private(self);
221 struct i2cbus_attach_args iba;
222 static struct cuda_attach_args caa;
223 int irq = ca->ca_intr[0];
224 int node, i, child;
225 char name[32];
226
227 sc->sc_dev = self;
228 node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
229 if (node)
230 OF_getprop(node, "interrupts", &irq, 4);
231
232 aprint_normal(" irq %d", irq);
233
234 sc->sc_node = ca->ca_node;
235 sc->sc_memt = ca->ca_tag;
236
237 sc->sc_sent = 0;
238 sc->sc_received = 0;
239 sc->sc_waiting = 0;
240 sc->sc_polling = 0;
241 sc->sc_state = CUDA_NOTREADY;
242 sc->sc_error = 0;
243 sc->sc_i2c_read_len = 0;
244
245 if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
246 ca->ca_reg[1], 0, &sc->sc_memh) != 0) {
247
248 aprint_normal(": unable to map registers\n");
249 return;
250 }
251 sc->sc_ih = intr_establish_xname(irq, IST_EDGE, IPL_TTY, cuda_intr, sc,
252 device_xname(self));
253 printf("\n");
254
255 for (i = 0; i < 16; i++) {
256 sc->sc_handlers[i].handler = NULL;
257 sc->sc_handlers[i].cookie = NULL;
258 }
259
260 cuda_init(sc);
261
262 /* now attach children */
263 config_interrupts(self, cuda_final);
264 cuda_set_handler(sc, CUDA_ERROR, cuda_error_handler, sc);
265 cuda_set_handler(sc, CUDA_PSEUDO, cuda_todr_handler, sc);
266
267 child = OF_child(ca->ca_node);
268 while (child != 0) {
269
270 if (OF_getprop(child, "name", name, 32) == 0)
271 continue;
272 if (strncmp(name, "adb", 4) == 0) {
273
274 cuda_set_handler(sc, CUDA_ADB, cuda_adb_handler, sc);
275 sc->sc_adbops.cookie = sc;
276 sc->sc_adbops.send = cuda_adb_send;
277 sc->sc_adbops.poll = cuda_adb_poll;
278 sc->sc_adbops.autopoll = cuda_autopoll;
279 sc->sc_adbops.set_handler = cuda_adb_set_handler;
280 config_found(self, &sc->sc_adbops, nadb_print,
281 CFARGS(.iattr = "adb_bus"));
282 } else if (strncmp(name, "rtc", 4) == 0) {
283
284 sc->sc_todr.todr_gettime = cuda_todr_get;
285 sc->sc_todr.todr_settime = cuda_todr_set;
286 sc->sc_todr.cookie = sc;
287 todr_attach(&sc->sc_todr);
288 }
289 child = OF_peer(child);
290 }
291
292 caa.cookie = sc;
293 caa.set_handler = cuda_set_handler;
294 caa.send = cuda_send;
295 caa.poll = cuda_poll;
296 #if notyet
297 config_found(self, &caa, cuda_print, CFARGS_NONE);
298 #endif
299 /* we don't have OF nodes for i2c devices so we have to make our own */
300 node = OF_finddevice("/valkyrie");
301 if (node != -1) {
302 cuda_add_i2c_device(sc, "videopll",
303 "aapl,valkyrie-videopll", 0x50);
304 }
305 node = OF_finddevice("/perch");
306 if (node != -1) {
307 cuda_add_i2c_device(sc, "sgsmix", "st,tda7433", 0x8a);
308 }
309
310 /*
311 * Subclass our device handle so we can override
312 * "i2c-enumerate-devices" and give that to the
313 * i2c bus instance.
314 */
315 devhandle_t devhandle = devhandle_subclass(device_handle(self),
316 &sc->sc_devhandle_impl, cuda_devhandle_lookup_device_call);
317
318 iic_tag_init(&sc->sc_i2c);
319 sc->sc_i2c.ic_cookie = sc;
320 sc->sc_i2c.ic_exec = cuda_i2c_exec;
321
322 memset(&iba, 0, sizeof(iba));
323 iba.iba_tag = &sc->sc_i2c;
324 config_found(self, &iba, iicbus_print,
325 CFARGS(.iattr = "i2cbus",
326 .devhandle = devhandle));
327
328 if (cuda0 == NULL)
329 cuda0 = &caa;
330 }
331
332 static void
333 cuda_init(struct cuda_softc *sc)
334 {
335 uint8_t reg;
336
337 reg = cuda_read_reg(sc, vDirB);
338 reg |= 0x30; /* register B bits 4 and 5: outputs */
339 cuda_write_reg(sc, vDirB, reg);
340
341 reg = cuda_read_reg(sc, vDirB);
342 reg &= 0xf7; /* register B bit 3: input */
343 cuda_write_reg(sc, vDirB, reg);
344
345 reg = cuda_read_reg(sc, vACR);
346 reg &= ~vSR_OUT; /* make sure SR is set to IN */
347 cuda_write_reg(sc, vACR, reg);
348
349 cuda_write_reg(sc, vACR, (cuda_read_reg(sc, vACR) | 0x0c) & ~0x10);
350
351 sc->sc_state = CUDA_IDLE; /* used by all types of hardware */
352
353 cuda_write_reg(sc, vIER, 0x84); /* make sure VIA interrupts are on */
354 cuda_idle(sc); /* set ADB bus state to idle */
355
356 /* sort of a device reset */
357 (void)cuda_read_reg(sc, vSR); /* clear interrupt */
358 cuda_write_reg(sc, vIER, 0x04); /* no interrupts while clearing */
359 cuda_idle(sc); /* reset state to idle */
360 delay(150);
361 cuda_tip(sc); /* signal start of frame */
362 delay(150);
363 cuda_toggle_ack(sc);
364 delay(150);
365 cuda_clear_tip(sc);
366 delay(150);
367 cuda_idle(sc); /* back to idle state */
368 (void)cuda_read_reg(sc, vSR); /* clear interrupt */
369 cuda_write_reg(sc, vIER, 0x84); /* ints ok now */
370 }
371
372 static void
373 cuda_final(device_t dev)
374 {
375 struct cuda_softc *sc = device_private(dev);
376
377 sc->sc_polling = 0;
378 }
379
380 static inline void
381 cuda_write_reg(struct cuda_softc *sc, int offset, uint8_t value)
382 {
383
384 bus_space_write_1(sc->sc_memt, sc->sc_memh, offset, value);
385 }
386
387 static inline uint8_t
388 cuda_read_reg(struct cuda_softc *sc, int offset)
389 {
390
391 return bus_space_read_1(sc->sc_memt, sc->sc_memh, offset);
392 }
393
394 static int
395 cuda_set_handler(void *cookie, int type,
396 int (*handler)(void *, int, uint8_t *), void *hcookie)
397 {
398 struct cuda_softc *sc = cookie;
399 CudaHandler *me;
400
401 if ((type >= 0) && (type < 16)) {
402 me = &sc->sc_handlers[type];
403 me->handler = handler;
404 me->cookie = hcookie;
405 return 0;
406 }
407 return -1;
408 }
409
410 static int
411 cuda_send(void *cookie, int poll, int length, uint8_t *msg)
412 {
413 struct cuda_softc *sc = cookie;
414 int s;
415
416 DPRINTF("cuda_send %08x\n", (uint32_t)cookie);
417 if (sc->sc_state == CUDA_NOTREADY)
418 return -1;
419
420 s = splhigh();
421
422 if (sc->sc_state == CUDA_IDLE /*&&
423 (cuda_read_reg(sc, vBufB) & vPB3) == vPB3*/) {
424 /* fine */
425 DPRINTF("chip is idle\n");
426 } else {
427 DPRINTF("cuda state is %d\n", sc->sc_state);
428 if (sc->sc_waiting == 0) {
429 sc->sc_waiting = 1;
430 } else {
431 splx(s);
432 return -1;
433 }
434 }
435
436 sc->sc_error = 0;
437 memcpy(sc->sc_out, msg, length);
438 sc->sc_out_length = length;
439 sc->sc_sent = 0;
440
441 if (sc->sc_waiting != 1) {
442
443 delay(150);
444 sc->sc_state = CUDA_OUT;
445 cuda_out(sc);
446 cuda_write_reg(sc, vSR, sc->sc_out[0]);
447 cuda_ack_off(sc);
448 cuda_tip(sc);
449 }
450 sc->sc_waiting = 1;
451
452 if (sc->sc_polling || poll || cold) {
453 cuda_poll(sc);
454 }
455
456 splx(s);
457
458 return 0;
459 }
460
461 static void
462 cuda_poll(void *cookie)
463 {
464 struct cuda_softc *sc = cookie;
465 int s;
466
467 DPRINTF("polling\n");
468 while ((sc->sc_state != CUDA_IDLE) ||
469 (cuda_intr_state(sc)) ||
470 (sc->sc_waiting == 1)) {
471 if ((cuda_read_reg(sc, vIFR) & vSR_INT) == vSR_INT) {
472 s = splhigh();
473 cuda_intr(sc);
474 splx(s);
475 }
476 }
477 }
478
479 static void
480 cuda_adb_poll(void *cookie)
481 {
482 struct cuda_softc *sc = cookie;
483 int s;
484
485 s = splhigh();
486 cuda_intr(sc);
487 splx(s);
488 }
489
490 static void
491 cuda_idle(struct cuda_softc *sc)
492 {
493 uint8_t reg;
494
495 reg = cuda_read_reg(sc, vBufB);
496 reg |= (vPB4 | vPB5);
497 cuda_write_reg(sc, vBufB, reg);
498 }
499
500 static void
501 cuda_tip(struct cuda_softc *sc)
502 {
503 uint8_t reg;
504
505 reg = cuda_read_reg(sc, vBufB);
506 reg &= ~vPB5;
507 cuda_write_reg(sc, vBufB, reg);
508 }
509
510 static void
511 cuda_clear_tip(struct cuda_softc *sc)
512 {
513 uint8_t reg;
514
515 reg = cuda_read_reg(sc, vBufB);
516 reg |= vPB5;
517 cuda_write_reg(sc, vBufB, reg);
518 }
519
520 static void
521 cuda_in(struct cuda_softc *sc)
522 {
523 uint8_t reg;
524
525 reg = cuda_read_reg(sc, vACR);
526 reg &= ~vSR_OUT;
527 cuda_write_reg(sc, vACR, reg);
528 }
529
530 static void
531 cuda_out(struct cuda_softc *sc)
532 {
533 uint8_t reg;
534
535 reg = cuda_read_reg(sc, vACR);
536 reg |= vSR_OUT;
537 cuda_write_reg(sc, vACR, reg);
538 }
539
540 static void
541 cuda_toggle_ack(struct cuda_softc *sc)
542 {
543 uint8_t reg;
544
545 reg = cuda_read_reg(sc, vBufB);
546 reg ^= vPB4;
547 cuda_write_reg(sc, vBufB, reg);
548 }
549
550 static void
551 cuda_ack_off(struct cuda_softc *sc)
552 {
553 uint8_t reg;
554
555 reg = cuda_read_reg(sc, vBufB);
556 reg |= vPB4;
557 cuda_write_reg(sc, vBufB, reg);
558 }
559
560 static int
561 cuda_intr_state(struct cuda_softc *sc)
562 {
563 return ((cuda_read_reg(sc, vBufB) & vPB3) == 0);
564 }
565
566 static int
567 cuda_intr(void *arg)
568 {
569 struct cuda_softc *sc = arg;
570 int ending, type;
571 uint8_t reg;
572
573 reg = cuda_read_reg(sc, vIFR); /* Read the interrupts */
574 DPRINTF("[");
575 if ((reg & 0x80) == 0) {
576 DPRINTF("irq %02x]", reg);
577 return 0; /* No interrupts to process */
578 }
579 DPRINTF(":");
580
581 cuda_write_reg(sc, vIFR, 0x7f); /* Clear 'em */
582
583 switch_start:
584 switch (sc->sc_state) {
585 case CUDA_IDLE:
586 /*
587 * This is an unexpected packet, so grab the first (dummy)
588 * byte, set up the proper vars, and tell the chip we are
589 * starting to receive the packet by setting the TIP bit.
590 */
591 sc->sc_in[1] = cuda_read_reg(sc, vSR);
592 DPRINTF("start: %02x", sc->sc_in[1]);
593 if (cuda_intr_state(sc) == 0) {
594 /* must have been a fake start */
595 DPRINTF(" ... fake start\n");
596 if (sc->sc_waiting) {
597 /* start over */
598 delay(150);
599 sc->sc_state = CUDA_OUT;
600 sc->sc_sent = 0;
601 cuda_out(sc);
602 cuda_write_reg(sc, vSR, sc->sc_out[1]);
603 cuda_ack_off(sc);
604 cuda_tip(sc);
605 }
606 break;
607 }
608
609 cuda_in(sc);
610 cuda_tip(sc);
611
612 sc->sc_received = 1;
613 sc->sc_state = CUDA_IN;
614 DPRINTF(" CUDA_IN");
615 break;
616
617 case CUDA_IN:
618 sc->sc_in[sc->sc_received] = cuda_read_reg(sc, vSR);
619 DPRINTF(" %02x", sc->sc_in[sc->sc_received]);
620 ending = 0;
621 if (sc->sc_received > 255) {
622 /* bitch only once */
623 if (sc->sc_received == 256) {
624 aprint_error_dev(sc->sc_dev,
625 "input overflow\n");
626 ending = 1;
627 }
628 } else
629 sc->sc_received++;
630 if (sc->sc_received > 3) {
631 if ((sc->sc_in[3] == CMD_IIC) &&
632 (sc->sc_received > (sc->sc_i2c_read_len + 4))) {
633 ending = 1;
634 }
635 }
636
637 /* intr off means this is the last byte (end of frame) */
638 if (cuda_intr_state(sc) == 0) {
639 ending = 1;
640 DPRINTF(".\n");
641 } else {
642 cuda_toggle_ack(sc);
643 }
644
645 if (ending == 1) { /* end of message? */
646
647 sc->sc_in[0] = sc->sc_received - 1;
648
649 /* reset vars and signal the end of this frame */
650 cuda_idle(sc);
651
652 /* check if we have a handler for this message */
653 type = sc->sc_in[1];
654 if ((type >= 0) && (type < 16)) {
655 CudaHandler *me = &sc->sc_handlers[type];
656
657 if (me->handler != NULL) {
658 me->handler(me->cookie,
659 sc->sc_received - 1, &sc->sc_in[1]);
660 } else {
661 aprint_error_dev(sc->sc_dev,
662 "no handler for type %02x\n", type);
663 panic("barf");
664 }
665 }
666
667 DPRINTF("CUDA_IDLE");
668 sc->sc_state = CUDA_IDLE;
669
670 sc->sc_received = 0;
671
672 /*
673 * If there is something waiting to be sent out,
674 * set everything up and send the first byte.
675 */
676 if (sc->sc_waiting == 1) {
677
678 DPRINTF("pending write\n");
679 delay(1500); /* required */
680 sc->sc_sent = 0;
681 sc->sc_state = CUDA_OUT;
682
683 /*
684 * If the interrupt is on, we were too slow
685 * and the chip has already started to send
686 * something to us, so back out of the write
687 * and start a read cycle.
688 */
689 if (cuda_intr_state(sc)) {
690 cuda_in(sc);
691 cuda_idle(sc);
692 sc->sc_sent = 0;
693 sc->sc_state = CUDA_IDLE;
694 sc->sc_received = 0;
695 delay(150);
696 DPRINTF("too slow - incoming message\n");
697 goto switch_start;
698 }
699 /*
700 * If we got here, it's ok to start sending
701 * so load the first byte and tell the chip
702 * we want to send.
703 */
704 DPRINTF("sending ");
705
706 cuda_out(sc);
707 cuda_write_reg(sc, vSR,
708 sc->sc_out[sc->sc_sent]);
709 cuda_ack_off(sc);
710 cuda_tip(sc);
711 }
712 }
713 break;
714
715 case CUDA_OUT:
716 (void)cuda_read_reg(sc, vSR); /* reset SR-intr in IFR */
717
718 sc->sc_sent++;
719 if (cuda_intr_state(sc)) { /* ADB intr low during write */
720
721 DPRINTF("incoming msg during send\n");
722 cuda_in(sc); /* make sure SR is set to IN */
723 cuda_idle(sc);
724 sc->sc_sent = 0; /* must start all over */
725 sc->sc_state = CUDA_IDLE; /* new state */
726 sc->sc_received = 0;
727 sc->sc_waiting = 1; /* must retry when done with
728 * read */
729 delay(150);
730 goto switch_start; /* process next state right
731 * now */
732 break;
733 }
734 if (sc->sc_out_length == sc->sc_sent) { /* check for done */
735
736 sc->sc_waiting = 0; /* done writing */
737 sc->sc_state = CUDA_IDLE; /* signal bus is idle */
738 cuda_in(sc);
739 cuda_idle(sc);
740 DPRINTF("done sending\n");
741 } else {
742 /* send next byte */
743 cuda_write_reg(sc, vSR, sc->sc_out[sc->sc_sent]);
744 DPRINTF("%02x", sc->sc_out[sc->sc_sent]);
745 cuda_toggle_ack(sc); /* signal byte ready to
746 * shift */
747 }
748 break;
749
750 case CUDA_NOTREADY:
751 DPRINTF("adb: not yet initialized\n");
752 break;
753
754 default:
755 DPRINTF("intr: unknown ADB state\n");
756 break;
757 }
758
759 DPRINTF("]");
760 return 1;
761 }
762
763 static int
764 cuda_error_handler(void *cookie, int len, uint8_t *data)
765 {
766 struct cuda_softc *sc = cookie;
767
768 /*
769 * something went wrong
770 * byte 3 seems to be the failed command
771 */
772 sc->sc_error = 1;
773 wakeup(&sc->sc_todev);
774 return 0;
775 }
776
777
778 /* real time clock */
779
780 static int
781 cuda_todr_handler(void *cookie, int len, uint8_t *data)
782 {
783 struct cuda_softc *sc = cookie;
784
785 #ifdef CUDA_DEBUG
786 int i;
787 printf("msg: %02x", data[0]);
788 for (i = 1; i < len; i++) {
789 printf(" %02x", data[i]);
790 }
791 printf("\n");
792 #endif
793
794 switch(data[2]) {
795 case CMD_READ_RTC:
796 memcpy(&sc->sc_tod, &data[3], 4);
797 break;
798 case CMD_WRITE_RTC:
799 sc->sc_tod = 0xffffffff;
800 break;
801 case CMD_AUTOPOLL:
802 sc->sc_autopoll = 1;
803 break;
804 case CMD_IIC:
805 sc->sc_iic_done = len;
806 break;
807 }
808 wakeup(&sc->sc_todev);
809 return 0;
810 }
811
812 #define DIFF19041970 2082844800
813
814 static int
815 cuda_todr_get(todr_chip_handle_t tch, struct timeval *tvp)
816 {
817 struct cuda_softc *sc = tch->cookie;
818 int cnt = 0;
819 uint8_t cmd[] = { CUDA_PSEUDO, CMD_READ_RTC};
820
821 sc->sc_tod = 0;
822 while (sc->sc_tod == 0) {
823 cuda_send(sc, 0, 2, cmd);
824
825 while ((sc->sc_tod == 0) && (cnt < 10)) {
826 tsleep(&sc->sc_todev, 0, "todr", 10);
827 cnt++;
828 }
829
830 if (sc->sc_tod == 0) {
831 aprint_error_dev(sc->sc_dev,
832 "unable to read a sane RTC value\n");
833 return EIO;
834 }
835 if ((sc->sc_tod > 0xf0000000UL) ||
836 (sc->sc_tod < DIFF19041970)) {
837 /* huh? try again */
838 sc->sc_tod = 0;
839 aprint_verbose_dev(sc->sc_dev,
840 "got garbage reading RTC, trying again\n");
841 }
842 }
843
844 tvp->tv_sec = sc->sc_tod - DIFF19041970;
845 DPRINTF("tod: %" PRIo64 "\n", tvp->tv_sec);
846 tvp->tv_usec = 0;
847 return 0;
848 }
849
850 static int
851 cuda_todr_set(todr_chip_handle_t tch, struct timeval *tvp)
852 {
853 struct cuda_softc *sc = tch->cookie;
854 uint32_t sec;
855 uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0};
856
857 sec = tvp->tv_sec + DIFF19041970;
858 memcpy(&cmd[2], &sec, 4);
859 sc->sc_tod = 0;
860 if (cuda_send(sc, 0, 6, cmd) == 0) {
861 while (sc->sc_tod == 0) {
862 tsleep(&sc->sc_todev, 0, "todr", 10);
863 }
864 return 0;
865 }
866 aprint_error_dev(sc->sc_dev, "%s failed\n", __func__);
867 return -1;
868
869 }
870
871 /* poweroff and reboot */
872
873 void
874 cuda_poweroff(void)
875 {
876 struct cuda_softc *sc;
877 uint8_t cmd[] = {CUDA_PSEUDO, CMD_POWEROFF};
878
879 if (cuda0 == NULL)
880 return;
881 sc = cuda0->cookie;
882 sc->sc_polling = 1;
883 cuda0->poll(sc);
884 if (cuda0->send(sc, 1, 2, cmd) == 0)
885 while (1);
886 }
887
888 void
889 cuda_restart(void)
890 {
891 struct cuda_softc *sc;
892 uint8_t cmd[] = {CUDA_PSEUDO, CMD_RESET};
893
894 if (cuda0 == NULL)
895 return;
896 sc = cuda0->cookie;
897 sc->sc_polling = 1;
898 cuda0->poll(sc);
899 if (cuda0->send(sc, 1, 2, cmd) == 0)
900 while (1);
901 }
902
903 /* ADB message handling */
904
905 static void
906 cuda_autopoll(void *cookie, int flag)
907 {
908 struct cuda_softc *sc = cookie;
909 uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, (flag != 0)};
910
911 if (cmd[2] == sc->sc_autopoll)
912 return;
913
914 sc->sc_autopoll = -1;
915 cuda_send(sc, 0, 3, cmd);
916 while(sc->sc_autopoll == -1) {
917 if (sc->sc_polling || cold) {
918 cuda_poll(sc);
919 } else
920 tsleep(&sc->sc_todev, 0, "autopoll", 100);
921 }
922 }
923
924 static int
925 cuda_adb_handler(void *cookie, int len, uint8_t *data)
926 {
927 struct cuda_softc *sc = cookie;
928
929 if (sc->sc_adb_handler != NULL) {
930 sc->sc_adb_handler(sc->sc_adb_cookie, len - 1,
931 &data[1]);
932 return 0;
933 }
934 return -1;
935 }
936
937 static int
938 cuda_adb_send(void *cookie, int poll, int command, int len, uint8_t *data)
939 {
940 struct cuda_softc *sc = cookie;
941 int i, s = 0;
942 uint8_t packet[16];
943
944 /* construct an ADB command packet and send it */
945 packet[0] = CUDA_ADB;
946 packet[1] = command;
947 for (i = 0; i < len; i++)
948 packet[i + 2] = data[i];
949 if (poll || cold) {
950 s = splhigh();
951 cuda_poll(sc);
952 }
953 cuda_send(sc, poll, len + 2, packet);
954 if (poll || cold) {
955 cuda_poll(sc);
956 splx(s);
957 }
958 return 0;
959 }
960
961 static int
962 cuda_adb_set_handler(void *cookie, void (*handler)(void *, int, uint8_t *),
963 void *hcookie)
964 {
965 struct cuda_softc *sc = cookie;
966
967 /* register a callback for incoming ADB messages */
968 sc->sc_adb_handler = handler;
969 sc->sc_adb_cookie = hcookie;
970 return 0;
971 }
972
973 /* i2c message handling */
974
975 static int
976 cuda_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *_send,
977 size_t send_len, void *_recv, size_t recv_len, int flags)
978 {
979 struct cuda_softc *sc = cookie;
980 const uint8_t *send = _send;
981 uint8_t *recv = _recv;
982 uint8_t command[16] = {CUDA_PSEUDO, CMD_IIC};
983
984 DPRINTF("cuda_i2c_exec(%02x)\n", addr);
985 command[2] = addr;
986
987 /* Copy command and output data bytes, if any, to buffer */
988 if (send_len > 0)
989 memcpy(&command[3], send, uimin((int)send_len, 12));
990 else if (I2C_OP_READ_P(op) && (recv_len == 0)) {
991 /*
992 * If no data bytes in either direction, it's a "quick"
993 * i2c operation. We don't know how to do a quick_read
994 * since that requires us to set the low bit of the
995 * address byte after it has been left-shifted.
996 */
997 sc->sc_error = 0;
998 return -1;
999 }
1000
1001 sc->sc_iic_done = 0;
1002 cuda_send(sc, sc->sc_polling, send_len + 3, command);
1003
1004 while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
1005 if (sc->sc_polling || cold) {
1006 cuda_poll(sc);
1007 } else
1008 tsleep(&sc->sc_todev, 0, "i2c", 1000);
1009 }
1010
1011 if (sc->sc_error) {
1012 sc->sc_error = 0;
1013 aprint_error_dev(sc->sc_dev, "error doing I2C\n");
1014 return -1;
1015 }
1016
1017 /* see if we're supposed to do a read */
1018 if (recv_len > 0) {
1019 sc->sc_iic_done = 0;
1020 command[2] |= 1;
1021 command[3] = 0;
1022
1023 /*
1024 * XXX we need to do something to limit the size of the answer
1025 * - apparently the chip keeps sending until we tell it to stop
1026 */
1027 sc->sc_i2c_read_len = recv_len;
1028 DPRINTF("rcv_len: %d\n", recv_len);
1029 cuda_send(sc, sc->sc_polling, 3, command);
1030 while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
1031 if (sc->sc_polling || cold) {
1032 cuda_poll(sc);
1033 } else
1034 tsleep(&sc->sc_todev, 0, "i2c", 1000);
1035 }
1036
1037 if (sc->sc_error) {
1038 aprint_error_dev(sc->sc_dev,
1039 "error trying to read from I2C\n");
1040 sc->sc_error = 0;
1041 return -1;
1042 }
1043 }
1044
1045 DPRINTF("received: %d\n", sc->sc_iic_done);
1046 if ((sc->sc_iic_done > 3) && (recv_len > 0)) {
1047 int rlen;
1048
1049 /* we got an answer */
1050 rlen = uimin(sc->sc_iic_done - 3, recv_len);
1051 memcpy(recv, &sc->sc_in[4], rlen);
1052 #ifdef CUDA_DEBUG
1053 {
1054 int i;
1055 printf("ret:");
1056 for (i = 0; i < rlen; i++)
1057 printf(" %02x", recv[i]);
1058 printf("\n");
1059 }
1060 #endif
1061 return rlen;
1062 }
1063 return 0;
1064 }
1065