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