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