1 /* $NetBSD: cuda.c,v 1.14 2009/03/18 10:22:31 cegger Exp $ */
4 * Copyright (c) 2006 Michael Lorenz
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: cuda.c,v 1.14 2009/03/18 10:22:31 cegger Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
37 #include <sys/mutex.h>
39 #include <machine/bus.h>
40 #include <machine/autoconf.h>
41 #include <machine/pio.h>
42 #include <dev/clock_subr.h>
43 #include <dev/i2c/i2cvar.h>
45 #include <macppc/dev/viareg.h>
46 #include <macppc/dev/cudavar.h>
48 #include <dev/ofw/openfirm.h>
49 #include <dev/adb/adbvar.h>
53 #define DPRINTF printf
55 #define DPRINTF while (0) printf
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 */
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);
68 static int cuda_intr(void *);
70 typedef struct _cuda_handler
{
71 int (*handler
)(void *, int, uint8_t *);
78 CudaHandler sc_handlers
[16];
79 struct todr_chip_handle sc_todr
;
80 struct adb_bus_accessops sc_adbops
;
81 struct i2c_controller sc_i2c
;
83 bus_space_tag_t sc_memt
;
84 bus_space_handle_t sc_memh
;
99 void (*sc_adb_handler
)(void *, int, uint8_t *);
101 uint32_t sc_i2c_read_len
;
102 /* internal buffers */
107 CFATTACH_DECL_NEW(cuda
, sizeof(struct cuda_softc
),
108 cuda_match
, cuda_attach
, NULL
, NULL
);
110 static inline void cuda_write_reg(struct cuda_softc
*, int, uint8_t);
111 static inline uint8_t cuda_read_reg(struct cuda_softc
*, int);
112 static void cuda_idle(struct cuda_softc
*);
113 static void cuda_tip(struct cuda_softc
*);
114 static void cuda_clear_tip(struct cuda_softc
*);
115 static void cuda_in(struct cuda_softc
*);
116 static void cuda_out(struct cuda_softc
*);
117 static void cuda_toggle_ack(struct cuda_softc
*);
118 static void cuda_ack_off(struct cuda_softc
*);
119 static int cuda_intr_state(struct cuda_softc
*);
121 static void cuda_init(struct cuda_softc
*);
124 * send a message to Cuda.
126 /* cookie, flags, length, data */
127 static int cuda_send(void *, int, int, uint8_t *);
128 static void cuda_poll(void *);
129 static void cuda_adb_poll(void *);
130 static int cuda_set_handler(void *, int, int (*)(void *, int, uint8_t *), void *);
132 static int cuda_error_handler(void *, int, uint8_t *);
134 static int cuda_todr_handler(void *, int, uint8_t *);
135 static int cuda_todr_set(todr_chip_handle_t
, struct timeval
*);
136 static int cuda_todr_get(todr_chip_handle_t
, struct timeval
*);
138 static int cuda_adb_handler(void *, int, uint8_t *);
139 static void cuda_final(device_t
);
141 static struct cuda_attach_args
*cuda0
= NULL
;
143 /* ADB bus attachment stuff */
144 static int cuda_adb_send(void *, int, int, int, uint8_t *);
145 static int cuda_adb_set_handler(void *, void (*)(void *, int, uint8_t *), void *);
148 static int cuda_i2c_acquire_bus(void *, int);
149 static void cuda_i2c_release_bus(void *, int);
150 static int cuda_i2c_exec(void *, i2c_op_t
, i2c_addr_t
, const void *, size_t,
151 void *, size_t, int);
154 cuda_match(device_t parent
, struct cfdata
*cf
, void *aux
)
156 struct confargs
*ca
= aux
;
161 if (ca
->ca_nintr
< 4)
164 if (strcmp(ca
->ca_name
, "via-cuda") == 0) {
165 return 10; /* beat adb* at obio? */
172 cuda_attach(device_t parent
, device_t dev
, void *aux
)
174 struct confargs
*ca
= aux
;
175 struct cuda_softc
*sc
= device_private(dev
);
176 struct i2cbus_attach_args iba
;
177 static struct cuda_attach_args caa
;
178 int irq
= ca
->ca_intr
[0];
183 node
= of_getnode_byname(OF_parent(ca
->ca_node
), "extint-gpio1");
185 OF_getprop(node
, "interrupts", &irq
, 4);
187 printf(" irq %d", irq
);
189 sc
->sc_node
= ca
->ca_node
;
190 sc
->sc_memt
= ca
->ca_tag
;
196 sc
->sc_state
= CUDA_NOTREADY
;
198 sc
->sc_i2c_read_len
= 0;
200 if (bus_space_map(sc
->sc_memt
, ca
->ca_reg
[0] + ca
->ca_baseaddr
,
201 ca
->ca_reg
[1], 0, &sc
->sc_memh
) != 0) {
203 printf(": unable to map registers\n");
206 sc
->sc_ih
= intr_establish(irq
, IST_EDGE
, IPL_TTY
, cuda_intr
, sc
);
209 for (i
= 0; i
< 16; i
++) {
210 sc
->sc_handlers
[i
].handler
= NULL
;
211 sc
->sc_handlers
[i
].cookie
= NULL
;
216 /* now attach children */
217 config_interrupts(dev
, cuda_final
);
218 cuda_set_handler(sc
, CUDA_ERROR
, cuda_error_handler
, sc
);
219 cuda_set_handler(sc
, CUDA_PSEUDO
, cuda_todr_handler
, sc
);
221 child
= OF_child(ca
->ca_node
);
224 if (OF_getprop(child
, "name", name
, 32) == 0)
226 if (strncmp(name
, "adb", 4) == 0) {
228 cuda_set_handler(sc
, CUDA_ADB
, cuda_adb_handler
, sc
);
229 sc
->sc_adbops
.cookie
= sc
;
230 sc
->sc_adbops
.send
= cuda_adb_send
;
231 sc
->sc_adbops
.poll
= cuda_adb_poll
;
232 sc
->sc_adbops
.autopoll
= cuda_autopoll
;
233 sc
->sc_adbops
.set_handler
= cuda_adb_set_handler
;
234 config_found_ia(dev
, "adb_bus", &sc
->sc_adbops
,
236 } else if (strncmp(name
, "rtc", 4) == 0) {
238 sc
->sc_todr
.todr_gettime
= cuda_todr_get
;
239 sc
->sc_todr
.todr_settime
= cuda_todr_set
;
240 sc
->sc_todr
.cookie
= sc
;
241 todr_attach(&sc
->sc_todr
);
243 child
= OF_peer(child
);
247 caa
.set_handler
= cuda_set_handler
;
248 caa
.send
= cuda_send
;
249 caa
.poll
= cuda_poll
;
251 config_found(dev
, &caa
, cuda_print
);
253 mutex_init(&sc
->sc_buslock
, MUTEX_DEFAULT
, IPL_NONE
);
254 iba
.iba_tag
= &sc
->sc_i2c
;
255 sc
->sc_i2c
.ic_cookie
= sc
;
256 sc
->sc_i2c
.ic_acquire_bus
= cuda_i2c_acquire_bus
;
257 sc
->sc_i2c
.ic_release_bus
= cuda_i2c_release_bus
;
258 sc
->sc_i2c
.ic_send_start
= NULL
;
259 sc
->sc_i2c
.ic_send_stop
= NULL
;
260 sc
->sc_i2c
.ic_initiate_xfer
= NULL
;
261 sc
->sc_i2c
.ic_read_byte
= NULL
;
262 sc
->sc_i2c
.ic_write_byte
= NULL
;
263 sc
->sc_i2c
.ic_exec
= cuda_i2c_exec
;
264 config_found_ia(sc
->sc_dev
, "i2cbus", &iba
, iicbus_print
);
271 cuda_init(struct cuda_softc
*sc
)
276 reg
= cuda_read_reg(sc
, vDirB
);
277 reg
|= 0x30; /* register B bits 4 and 5: outputs */
278 cuda_write_reg(sc
, vDirB
, reg
);
280 reg
= cuda_read_reg(sc
, vDirB
);
281 reg
&= 0xf7; /* register B bit 3: input */
282 cuda_write_reg(sc
, vDirB
, reg
);
284 reg
= cuda_read_reg(sc
, vACR
);
285 reg
&= ~vSR_OUT
; /* make sure SR is set to IN */
286 cuda_write_reg(sc
, vACR
, reg
);
288 cuda_write_reg(sc
, vACR
, (cuda_read_reg(sc
, vACR
) | 0x0c) & ~0x10);
290 sc
->sc_state
= CUDA_IDLE
; /* used by all types of hardware */
292 cuda_write_reg(sc
, vIER
, 0x84); /* make sure VIA interrupts are on */
293 cuda_idle(sc
); /* set ADB bus state to idle */
295 /* sort of a device reset */
296 i
= cuda_read_reg(sc
, vSR
); /* clear interrupt */
297 cuda_write_reg(sc
, vIER
, 0x04); /* no interrupts while clearing */
298 cuda_idle(sc
); /* reset state to idle */
300 cuda_tip(sc
); /* signal start of frame */
306 cuda_idle(sc
); /* back to idle state */
307 i
= cuda_read_reg(sc
, vSR
); /* clear interrupt */
308 cuda_write_reg(sc
, vIER
, 0x84); /* ints ok now */
312 cuda_final(device_t dev
)
314 struct cuda_softc
*sc
= device_private(dev
);
320 cuda_write_reg(struct cuda_softc
*sc
, int offset
, uint8_t value
)
323 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, offset
, value
);
326 static inline uint8_t
327 cuda_read_reg(struct cuda_softc
*sc
, int offset
)
330 return bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, offset
);
334 cuda_set_handler(void *cookie
, int type
,
335 int (*handler
)(void *, int, uint8_t *), void *hcookie
)
337 struct cuda_softc
*sc
= cookie
;
340 if ((type
>= 0) && (type
< 16)) {
341 me
= &sc
->sc_handlers
[type
];
342 me
->handler
= handler
;
343 me
->cookie
= hcookie
;
350 cuda_send(void *cookie
, int poll
, int length
, uint8_t *msg
)
352 struct cuda_softc
*sc
= cookie
;
355 DPRINTF("cuda_send %08x\n", (uint32_t)cookie
);
356 if (sc
->sc_state
== CUDA_NOTREADY
)
361 if ((sc
->sc_state
== CUDA_IDLE
) /*&&
362 ((cuda_read_reg(sc, vBufB) & vPB3) == vPB3)*/) {
364 DPRINTF("chip is idle\n");
366 DPRINTF("cuda state is %d\n", sc
->sc_state
);
367 if (sc
->sc_waiting
== 0) {
376 memcpy(sc
->sc_out
, msg
, length
);
377 sc
->sc_out_length
= length
;
380 if (sc
->sc_waiting
!= 1) {
383 sc
->sc_state
= CUDA_OUT
;
385 cuda_write_reg(sc
, vSR
, sc
->sc_out
[0]);
391 if (sc
->sc_polling
|| poll
|| cold
) {
401 cuda_poll(void *cookie
)
403 struct cuda_softc
*sc
= cookie
;
406 DPRINTF("polling\n");
407 while ((sc
->sc_state
!= CUDA_IDLE
) ||
408 (cuda_intr_state(sc
)) ||
409 (sc
->sc_waiting
== 1)) {
410 if ((cuda_read_reg(sc
, vIFR
) & vSR_INT
) == vSR_INT
) {
419 cuda_adb_poll(void *cookie
)
421 struct cuda_softc
*sc
= cookie
;
430 cuda_idle(struct cuda_softc
*sc
)
434 reg
= cuda_read_reg(sc
, vBufB
);
435 reg
|= (vPB4
| vPB5
);
436 cuda_write_reg(sc
, vBufB
, reg
);
440 cuda_tip(struct cuda_softc
*sc
)
444 reg
= cuda_read_reg(sc
, vBufB
);
446 cuda_write_reg(sc
, vBufB
, reg
);
450 cuda_clear_tip(struct cuda_softc
*sc
)
454 reg
= cuda_read_reg(sc
, vBufB
);
456 cuda_write_reg(sc
, vBufB
, reg
);
460 cuda_in(struct cuda_softc
*sc
)
464 reg
= cuda_read_reg(sc
, vACR
);
466 cuda_write_reg(sc
, vACR
, reg
);
470 cuda_out(struct cuda_softc
*sc
)
474 reg
= cuda_read_reg(sc
, vACR
);
476 cuda_write_reg(sc
, vACR
, reg
);
480 cuda_toggle_ack(struct cuda_softc
*sc
)
484 reg
= cuda_read_reg(sc
, vBufB
);
486 cuda_write_reg(sc
, vBufB
, reg
);
490 cuda_ack_off(struct cuda_softc
*sc
)
494 reg
= cuda_read_reg(sc
, vBufB
);
496 cuda_write_reg(sc
, vBufB
, reg
);
500 cuda_intr_state(struct cuda_softc
*sc
)
502 return ((cuda_read_reg(sc
, vBufB
) & vPB3
) == 0);
508 struct cuda_softc
*sc
= arg
;
512 reg
= cuda_read_reg(sc
, vIFR
); /* Read the interrupts */
514 if ((reg
& 0x80) == 0) {
515 DPRINTF("irq %02x]", reg
);
516 return 0; /* No interrupts to process */
520 cuda_write_reg(sc
, vIFR
, 0x7f); /* Clear 'em */
523 switch (sc
->sc_state
) {
526 * This is an unexpected packet, so grab the first (dummy)
527 * byte, set up the proper vars, and tell the chip we are
528 * starting to receive the packet by setting the TIP bit.
530 sc
->sc_in
[1] = cuda_read_reg(sc
, vSR
);
531 DPRINTF("start: %02x", sc
->sc_in
[1]);
532 if (cuda_intr_state(sc
) == 0) {
533 /* must have been a fake start */
534 DPRINTF(" ... fake start\n");
535 if (sc
->sc_waiting
) {
538 sc
->sc_state
= CUDA_OUT
;
541 cuda_write_reg(sc
, vSR
, sc
->sc_out
[1]);
552 sc
->sc_state
= CUDA_IN
;
557 sc
->sc_in
[sc
->sc_received
] = cuda_read_reg(sc
, vSR
);
558 DPRINTF(" %02x", sc
->sc_in
[sc
->sc_received
]);
560 if (sc
->sc_received
> 255) {
561 /* bitch only once */
562 if (sc
->sc_received
== 256) {
563 printf("%s: input overflow\n",
564 device_xname(sc
->sc_dev
));
569 if (sc
->sc_received
> 3) {
570 if ((sc
->sc_in
[3] == CMD_IIC
) &&
571 (sc
->sc_received
> (sc
->sc_i2c_read_len
+ 4))) {
576 /* intr off means this is the last byte (end of frame) */
577 if (cuda_intr_state(sc
) == 0) {
584 if (ending
== 1) { /* end of message? */
586 sc
->sc_in
[0] = sc
->sc_received
- 1;
588 /* reset vars and signal the end of this frame */
591 /* check if we have a handler for this message */
593 if ((type
>= 0) && (type
< 16)) {
594 CudaHandler
*me
= &sc
->sc_handlers
[type
];
596 if (me
->handler
!= NULL
) {
597 me
->handler(me
->cookie
,
598 sc
->sc_received
- 1, &sc
->sc_in
[1]);
600 printf("no handler for type %02x\n", type
);
605 DPRINTF("CUDA_IDLE");
606 sc
->sc_state
= CUDA_IDLE
;
611 * If there is something waiting to be sent out,
612 * set everything up and send the first byte.
614 if (sc
->sc_waiting
== 1) {
616 DPRINTF("pending write\n");
617 delay(1500); /* required */
619 sc
->sc_state
= CUDA_OUT
;
622 * If the interrupt is on, we were too slow
623 * and the chip has already started to send
624 * something to us, so back out of the write
625 * and start a read cycle.
627 if (cuda_intr_state(sc
)) {
631 sc
->sc_state
= CUDA_IDLE
;
634 DPRINTF("too slow - incoming message\n");
638 * If we got here, it's ok to start sending
639 * so load the first byte and tell the chip
645 cuda_write_reg(sc
, vSR
,
646 sc
->sc_out
[sc
->sc_sent
]);
654 i
= cuda_read_reg(sc
, vSR
); /* reset SR-intr in IFR */
657 if (cuda_intr_state(sc
)) { /* ADB intr low during write */
659 DPRINTF("incoming msg during send\n");
660 cuda_in(sc
); /* make sure SR is set to IN */
662 sc
->sc_sent
= 0; /* must start all over */
663 sc
->sc_state
= CUDA_IDLE
; /* new state */
665 sc
->sc_waiting
= 1; /* must retry when done with
668 goto switch_start
; /* process next state right
672 if (sc
->sc_out_length
== sc
->sc_sent
) { /* check for done */
674 sc
->sc_waiting
= 0; /* done writing */
675 sc
->sc_state
= CUDA_IDLE
; /* signal bus is idle */
678 DPRINTF("done sending\n");
681 cuda_write_reg(sc
, vSR
, sc
->sc_out
[sc
->sc_sent
]);
682 cuda_toggle_ack(sc
); /* signal byte ready to
688 DPRINTF("adb: not yet initialized\n");
692 DPRINTF("intr: unknown ADB state\n");
701 cuda_error_handler(void *cookie
, int len
, uint8_t *data
)
703 struct cuda_softc
*sc
= cookie
;
706 * something went wrong
707 * byte 3 seems to be the failed command
710 wakeup(&sc
->sc_todev
);
715 /* real time clock */
718 cuda_todr_handler(void *cookie
, int len
, uint8_t *data
)
720 struct cuda_softc
*sc
= cookie
;
724 printf("msg: %02x", data
[0]);
725 for (i
= 1; i
< len
; i
++) {
726 printf(" %02x", data
[i
]);
733 memcpy(&sc
->sc_tod
, &data
[3], 4);
736 sc
->sc_tod
= 0xffffffff;
742 sc
->sc_iic_done
= len
;
745 wakeup(&sc
->sc_todev
);
749 #define DIFF19041970 2082844800
752 cuda_todr_get(todr_chip_handle_t tch
, struct timeval
*tvp
)
754 struct cuda_softc
*sc
= tch
->cookie
;
756 uint8_t cmd
[] = { CUDA_PSEUDO
, CMD_READ_RTC
};
759 cuda_send(sc
, 0, 2, cmd
);
761 while ((sc
->sc_tod
== 0) && (cnt
< 10)) {
762 tsleep(&sc
->sc_todev
, 0, "todr", 10);
769 tvp
->tv_sec
= sc
->sc_tod
- DIFF19041970
;
770 DPRINTF("tod: %" PRIo64
"\n", tvp
->tv_sec
);
776 cuda_todr_set(todr_chip_handle_t tch
, struct timeval
*tvp
)
778 struct cuda_softc
*sc
= tch
->cookie
;
780 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_WRITE_RTC
, 0, 0, 0, 0};
782 sec
= tvp
->tv_sec
+ DIFF19041970
;
783 memcpy(&cmd
[2], &sec
, 4);
785 if (cuda_send(sc
, 0, 6, cmd
) == 0) {
786 while (sc
->sc_tod
== 0) {
787 tsleep(&sc
->sc_todev
, 0, "todr", 10);
795 /* poweroff and reboot */
800 struct cuda_softc
*sc
;
801 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_POWEROFF
};
808 if (cuda0
->send(sc
, 1, 2, cmd
) == 0)
815 struct cuda_softc
*sc
;
816 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_RESET
};
823 if (cuda0
->send(sc
, 1, 2, cmd
) == 0)
827 /* ADB message handling */
830 cuda_autopoll(void *cookie
, int flag
)
832 struct cuda_softc
*sc
= cookie
;
833 uint8_t cmd
[] = {CUDA_PSEUDO
, CMD_AUTOPOLL
, (flag
!= 0)};
835 if (cmd
[2] == sc
->sc_autopoll
)
838 sc
->sc_autopoll
= -1;
839 cuda_send(sc
, 0, 3, cmd
);
840 while(sc
->sc_autopoll
== -1) {
841 if (sc
->sc_polling
|| cold
) {
844 tsleep(&sc
->sc_todev
, 0, "autopoll", 100);
849 cuda_adb_handler(void *cookie
, int len
, uint8_t *data
)
851 struct cuda_softc
*sc
= cookie
;
853 if (sc
->sc_adb_handler
!= NULL
) {
854 sc
->sc_adb_handler(sc
->sc_adb_cookie
, len
- 1,
862 cuda_adb_send(void *cookie
, int poll
, int command
, int len
, uint8_t *data
)
864 struct cuda_softc
*sc
= cookie
;
868 /* construct an ADB command packet and send it */
869 packet
[0] = CUDA_ADB
;
871 for (i
= 0; i
< len
; i
++)
872 packet
[i
+ 2] = data
[i
];
877 cuda_send(sc
, poll
, len
+ 2, packet
);
886 cuda_adb_set_handler(void *cookie
, void (*handler
)(void *, int, uint8_t *),
889 struct cuda_softc
*sc
= cookie
;
891 /* register a callback for incoming ADB messages */
892 sc
->sc_adb_handler
= handler
;
893 sc
->sc_adb_cookie
= hcookie
;
897 /* i2c message handling */
900 cuda_i2c_acquire_bus(void *cookie
, int flags
)
902 struct cuda_softc
*sc
= cookie
;
904 mutex_enter(&sc
->sc_buslock
);
909 cuda_i2c_release_bus(void *cookie
, int flags
)
911 struct cuda_softc
*sc
= cookie
;
913 mutex_exit(&sc
->sc_buslock
);
917 cuda_i2c_exec(void *cookie
, i2c_op_t op
, i2c_addr_t addr
, const void *_send
,
918 size_t send_len
, void *_recv
, size_t recv_len
, int flags
)
920 struct cuda_softc
*sc
= cookie
;
921 const uint8_t *send
= _send
;
922 uint8_t *recv
= _recv
;
923 uint8_t command
[16] = {CUDA_PSEUDO
, CMD_IIC
};
925 DPRINTF("cuda_i2c_exec(%02x)\n", addr
);
928 /* Copy command and output data bytes, if any, to buffer */
930 memcpy(&command
[3], send
, min((int)send_len
, 12));
931 else if (I2C_OP_READ_P(op
) && (recv_len
== 0)) {
933 * If no data bytes in either direction, it's a "quick"
934 * i2c operation. We don't know how to do a quick_read
935 * since that requires us to set the low bit of the
936 * address byte after it has been left-shifted.
943 cuda_send(sc
, sc
->sc_polling
, send_len
+ 3, command
);
945 while ((sc
->sc_iic_done
== 0) && (sc
->sc_error
== 0)) {
946 if (sc
->sc_polling
|| cold
) {
949 tsleep(&sc
->sc_todev
, 0, "i2c", 1000);
957 /* see if we're supposed to do a read */
964 * XXX we need to do something to limit the size of the answer
965 * - apparently the chip keeps sending until we tell it to stop
967 sc
->sc_i2c_read_len
= recv_len
;
968 DPRINTF("rcv_len: %d\n", recv_len
);
969 cuda_send(sc
, sc
->sc_polling
, 3, command
);
970 while ((sc
->sc_iic_done
== 0) && (sc
->sc_error
== 0)) {
971 if (sc
->sc_polling
|| cold
) {
974 tsleep(&sc
->sc_todev
, 0, "i2c", 1000);
978 printf("error trying to read\n");
984 DPRINTF("received: %d\n", sc
->sc_iic_done
);
985 if ((sc
->sc_iic_done
> 3) && (recv_len
> 0)) {
988 /* we got an answer */
989 rlen
= min(sc
->sc_iic_done
- 3, recv_len
);
990 memcpy(recv
, &sc
->sc_in
[4], rlen
);
995 for (i
= 0; i
< rlen
; i
++)
996 printf(" %02x", recv
[i
]);