1 /* $NetBSD: cpi_nubus.c,v 1.3 2008/06/11 23:54:45 cegger Exp $ */
4 * Copyright (c) 2008 Hauke Fath
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.3 2008/06/11 23:54:45 cegger Exp $");
30 #include <sys/param.h>
31 #include <sys/systm.h>
33 #include <sys/device.h>
34 #include <sys/malloc.h>
35 #include <sys/event.h>
36 #include <sys/callout.h>
40 #include <sys/ioctl.h>
43 #include <sys/kernel.h>
44 #include <sys/syslog.h>
45 #include <sys/errno.h>
47 #include <machine/intr.h>
48 #include <machine/bus.h>
49 #include <machine/viareg.h>
51 #include <dev/ic/z8536reg.h>
52 #include <mac68k/nubus/nubus.h>
53 #include <mac68k/nubus/cpi_nubusvar.h>
62 * Stuff taken from Egan/Teixeira ch 8: 'if(TRACE_FOO)' debug output
63 * statements don't break indentation, and when DEBUG is not defined,
64 * the compiler code optimizer drops them as dead code.
67 #define M_TRACE_CONFIG 0x0001
68 #define M_TRACE_OPEN 0x0002
69 #define M_TRACE_CLOSE 0x0004
70 #define M_TRACE_READ 0x0008
71 #define M_TRACE_WRITE 0x0010
72 #define M_TRACE_IOCTL 0x0020
73 #define M_TRACE_STATUS 0x0040
74 #define M_TRACE_ALL 0xFFFF
75 #define M_TRACE_NONE 0x0000
77 #define TRACE_CONFIG (cpi_debug_mask & M_TRACE_CONFIG)
78 #define TRACE_OPEN (cpi_debug_mask & M_TRACE_OPEN)
79 #define TRACE_CLOSE (cpi_debug_mask & M_TRACE_CLOSE)
80 #define TRACE_READ (cpi_debug_mask & M_TRACE_READ)
81 #define TRACE_WRITE (cpi_debug_mask & M_TRACE_WRITE)
82 #define TRACE_IOCTL (cpi_debug_mask & M_TRACE_IOCTL)
83 #define TRACE_STATUS (cpi_debug_mask & M_TRACE_STATUS)
84 #define TRACE_ALL (cpi_debug_mask & M_TRACE_ALL)
85 #define TRACE_NONE (cpi_debug_mask & M_TRACE_NONE)
87 uint32_t cpi_debug_mask
= M_TRACE_NONE
/* | M_TRACE_WRITE */ ;
90 #define TRACE_CONFIG 0
96 #define TRACE_STATUS 0
101 #undef USE_CIO_TIMERS /* TBD */
103 /* autoconf interface */
104 int cpi_nubus_match(device_t
, cfdata_t
, void *);
105 void cpi_nubus_attach(device_t
, device_t
, void *);
106 void cpi_nubus_intr(void *);
108 CFATTACH_DECL(cpi
, sizeof(struct cpi_softc
),
109 cpi_nubus_match
, cpi_nubus_attach
, NULL
, NULL
);
111 dev_type_open(cpi_open
);
112 dev_type_close(cpi_close
);
113 dev_type_read(cpi_read
);
114 dev_type_write(cpi_write
);
115 dev_type_ioctl(cpi_ioctl
);
117 const struct cdevsw cpi_cdevsw
= {
118 cpi_open
, cpi_close
, noread
, cpi_write
, cpi_ioctl
,
119 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
123 static void cpi_lpreset(struct cpi_softc
*);
124 static int cpi_notready(struct cpi_softc
*);
125 static void cpi_wakeup(void *);
126 static int cpi_flush(struct cpi_softc
*);
127 static void cpi_intr(void *);
129 #ifdef USE_CIO_TIMERS
130 static void cpi_initclock(struct cpi_softc
*);
131 static u_int
cpi_get_timecount(struct timecounter
*);
134 static inline void z8536_reg_set(bus_space_tag_t
, bus_space_handle_t
,
136 static inline uint8_t z8536_reg_get(bus_space_tag_t
, bus_space_handle_t
,
140 const uint8_t cio_reset
[] = {
143 Z8536_MICR
, MICR_RESET
,
147 const uint8_t cio_init
[] = {
150 /* Interrupt vectors - clear all */
153 Z8536_IVRCT
, 0x20 /* ??? Do we use this? */,
156 * Port A specification - bit port, single buffered,
157 * latched output, pulsed handshake, all bits non-inverting
160 Z8536_PMSRA
, PMSR_PTS_OUT
| PMSR_LPM
,
161 Z8536_PHSRA
, PHSR_HTS_PUL
,
167 * Port B specification - bit port, transparent output,
168 * pulsed handshake, all bits non-inverting
169 * bits 0, 4 output; bits 1-3, 5-8 input,
171 * Pattern matching: Bit 6 (BUSY) matching "1"
172 * Alternatively: Bit 3 (/ACK) matching "0"
174 Z8536_PMSRB
, PMSR_PMS_OR_PEV
,
177 Z8536_DDRB
, 0xee /*11101110b*/,
181 Z8536_PMRB
, 0x40 /*01000000b = PB6 */,
183 Z8536_PDRB
, 0xFE, /* Assign printer -RESET */
184 Z8536_PCSRA
, 0x00, /* Clear port A interrupt bits */
187 * Port C specification - bit 3 out, bits 0-2 in,
188 * all 4 non-inverting, non-special I/O
190 Z8536_DDRC
, 0x07 /*00000111b*/,
194 #ifdef USE_CIO_TIMERS
196 * Counter/Timers 1+2 are joined to form a free-running
199 Z8536_CTMSR1
, CTMS_CSC
,
200 Z8536_CTTCR1_MSB
, 0x00,
201 Z8536_CTTCR1_LSB
, 0x00,
202 Z8536_CTMSR2
, CTMS_CSC
,
203 Z8536_CTTCR2_MSB
, 0x00,
204 Z8536_CTTCR2_LSB
, 0x00,
205 #endif /* USE_CIO_TIMERS */
208 * We need Timer 3 for running port A in strobed mode.
210 * Counter/Timer 3 specification -- clear IP & IUS, trigger +
211 * gate command bit, one-shot operation
213 Z8536_CTCSR3
, CTCS_CLR_IP_IUS
| CTCS_GCB
| CTCS_TCB
,
214 Z8536_CTMSR3
, CTMS_DCS_ONESHOT
,
215 Z8536_CTTCR3_MSB
, 0x00,
216 Z8536_CTTCR3_LSB
, 0x03,
219 * Enable ports A+B+C+CT3
220 * Set timer 1 to clock timer 2, but not yet enabled.
222 Z8536_MCCR
, MCCR_PAE
| MCCR_PBE
| MCCR_CT1CT2
| MCCR_PC_CT3E
,
223 /* Master Interrupt Enable, Disable Lower Chain,
224 * No Vector, port A+B+CT vectors include status */
225 Z8536_MICR
, MICR_MIE
| MICR_DLC
| MICR_NV
| MICR_PAVIS
|
226 MICR_PBVIS
| MICR_CTVIS
,
227 Z8536_PDRB
, 0xFE, /* Clear printer -RESET */
232 * Look for Creative Systems Inc. "Hurdler Centronics Parallel Interface"
235 cpi_nubus_match(device_t parent
, cfdata_t cf
, void *aux
)
237 struct nubus_attach_args
*na
;
240 if ((na
->category
== NUBUS_CATEGORY_COMMUNICATIONS
) &&
241 (na
->type
== NUBUS_TYPE_CENTRONICS
) &&
242 (na
->drsw
== NUBUS_DRSW_CPI
) &&
243 (na
->drhw
== NUBUS_DRHW_CPI
))
250 cpi_nubus_attach(device_t parent
, device_t self
, void *aux
)
252 struct cpi_softc
*sc
;
253 struct nubus_attach_args
*na
;
256 sc
= device_private(self
);
258 sc
->sc_bst
= na
->na_tag
;
259 memcpy(&sc
->sc_slot
, na
->fmt
, sizeof(nubus_slot
));
260 sc
->sc_basepa
= (bus_addr_t
)NUBUS_SLOT2PA(na
->slot
);
263 * The CIO sits on the MSB (top byte lane) of the 32 bit
264 * Nubus, so map 16 byte.
268 printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n",
269 sc
->sc_basepa
+ CIO_BASE_OFFSET
);
272 err
= bus_space_map(sc
->sc_bst
, sc
->sc_basepa
+ CIO_BASE_OFFSET
,
273 (Z8536_IOSIZE
<< 4), 0, &sc
->sc_bsh
);
275 aprint_normal(": failed to map memory space.\n");
279 sc
->sc_lpstate
= LP_INITIAL
;
281 sc
->sc_bytestoport
= 0;
284 printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n");
286 for (ii
= 0; ii
< sizeof(cio_reset
); ii
+= 2)
287 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, cio_reset
[ii
],
290 delay(1000); /* Just in case */
291 for (ii
= 0; ii
< sizeof(cio_init
); ii
+= 2) {
292 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, cio_init
[ii
],
297 printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n");
299 /* XXX Get the information strings from the card's ROM */
300 aprint_normal(": CSI Hurdler II Centronics\n");
302 #ifdef USE_CIO_TIMERS
303 /* Attach CIO timers as timecounters */
305 printf("\tcpi_nubus_attach() about to attach timers\n");
308 #endif /* USE_CIO_TIMERS */
310 callout_init(&sc
->sc_wakeupchan
, 0); /* XXX */
312 /* make sure interrupts are vectored to us */
313 add_nubus_intr(na
->slot
, cpi_nubus_intr
, sc
);
317 cpi_nubus_intr(void *arg
)
319 struct cpi_softc
*sc
;
322 sc
= (struct cpi_softc
*)arg
;
328 /* Check for interrupt source, and clear interrupt */
331 * Clear port A interrupt
332 * Interrupt from register A, clear "pending"
333 * and set "under service"
335 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IE
);
336 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IP
);
337 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_SET_IUS
);
341 /* Interrupt from register A, mark serviced */
342 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IUS
);
343 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_SET_IE
);
349 /* cpi nuts and bolts */
352 cpi_open(dev_t device
, int flag
, int mode
, struct lwp
*l
)
355 struct cpi_softc
*sc
;
358 printf("\tcpi_open() called...\n");
360 /* Consistency checks: Valid unit number, softc, device state */
361 sc
= device_lookup_private(&cpi_cd
, CPI_UNIT(device
));
364 printf("Tried to cpi_open() with NULL softc\n");
367 if (sc
->sc_lpstate
!= LP_INITIAL
) {
369 printf("%s not in initial state (%x).\n",
370 sc
->sc_dev
.dv_xname
, sc
->sc_lpstate
);
373 sc
->sc_lpstate
= LP_OPENING
;
376 printf("\tcpi_open() resetting the printer...\n");
380 printf("\tcpi_open() waiting for printer ready...\n");
382 /* Wait max 15 sec for printer to get ready */
383 for (ii
= 15; cpi_notready(sc
); ii
--) {
385 sc
->sc_lpstate
= LP_INITIAL
;
388 /* sleep for a second, unless we get a signal */
389 err
= ltsleep(sc
, PZERO
| PCATCH
, "cpi_open", hz
, NULL
);
390 if (err
!= EWOULDBLOCK
) {
391 sc
->sc_lpstate
= LP_INITIAL
;
396 printf("\tcpi_open() allocating printer buffer...\n");
398 /* Allocate the driver's line buffer */
399 sc
->sc_printbuf
= malloc(CPI_BUFSIZE
, M_DEVBUF
, M_WAITOK
);
401 sc
->sc_lpstate
= LP_OPEN
;
405 sc
->sc_bytestoport
= 0;
407 /* Kick off transfer */
411 * Reset "interrupt {pending, under service}" bits, then
412 * enable Port A interrupts
416 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IP_IUS
);
417 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_SET_IE
);
421 printf("\tcpi_open() done...\n");
427 cpi_close(dev_t device
, int flag
, int mode
, struct lwp
*l
)
429 struct cpi_softc
*sc
;
431 sc
= device_lookup_private(&cpi_cd
, CPI_UNIT(device
));
434 printf("\tcpi_close() called (%lu hard, %lu bytes to port)\n",
435 sc
->sc_intcount
, sc
->sc_bytestoport
);
437 /* Flush the remaining buffer content, ignoring any errors */
438 if (0 < sc
->sc_bufbytes
)
441 callout_stop(&sc
->sc_wakeupchan
);
443 /* Disable Port A interrupts */
444 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IE
);
445 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PCSRA
, PCSR_CLR_IP_IUS
);
447 sc
->sc_lpstate
= LP_INITIAL
;
448 free(sc
->sc_printbuf
, M_DEVBUF
);
454 cpi_write(dev_t device
, struct uio
*uio
, int flags
)
458 struct cpi_softc
*sc
;
463 printf("\tcpi_write() called for %u bytes\n", uio
->uio_resid
);
465 sc
= device_lookup_private(&cpi_cd
, CPI_UNIT(device
));
467 /* Send data to printer, a line buffer full at a time */
468 while (uio
->uio_resid
> 0) {
469 numbytes
= min(CPI_BUFSIZE
, uio
->uio_resid
);
470 sc
->sc_cp
= sc
->sc_printbuf
;
471 uiomove(sc
->sc_cp
, numbytes
, uio
);
472 sc
->sc_bufbytes
= numbytes
;
475 printf("\tQueuing %u bytes\n", numbytes
);
478 /* Failure; adjust residual counter */
480 printf("\tQueuing failed with %d\n", err
);
481 uio
->uio_resid
+= sc
->sc_bufbytes
;
490 cpi_ioctl(dev_t device
, unsigned long cmd
, void *data
,
491 int flag
, struct lwp
*l
)
498 printf("\tcpi_ioctl() called with %ld...\n", cmd
);
503 printf("\tcpi_ioctl() unknown ioctl %ld\n", cmd
);
511 * Flush the print buffer that our top half uses to provide data to
512 * our bottom, interrupt-driven half.
515 cpi_flush(struct cpi_softc
*sc
)
520 while (0 < sc
->sc_bufbytes
) {
521 /* Feed the printer a char, if it's ready */
522 if ( !cpi_notready(sc
)) {
524 printf("\tcpi_flush() writes %u bytes "
525 "(%lu hard, %lu bytes to port)\n",
526 sc
->sc_bufbytes
, sc
->sc_intcount
,
532 /* XXX Sure we want to wait forever for the printer? */
533 err
= ltsleep((void *)sc
, PZERO
| PCATCH
,
534 "cpi_flush", (60 * hz
), NULL
);
541 cpi_wakeup(void *param
)
543 struct cpi_softc
*sc
;
552 callout_reset(&sc
->sc_wakeupchan
, hz
, cpi_wakeup
, sc
);
557 cpi_lpreset(struct cpi_softc
*sc
)
559 uint8_t portb
; /* Centronics -RESET is on port B, bit 0 */
560 #ifdef DIRECT_PORT_ACCESS
565 portb
= bus_space_read_1(sc
->sc_bst
, sc
->sc_bsh
, CIO_PORTB
);
566 bus_space_write_1(sc
->sc_bst
, sc
->sc_bsh
,
567 CIO_PORTB
, portb
& ~CPI_RESET
);
569 portb
= bus_space_read_1(sc
->sc_bst
, sc
->sc_bsh
, CIO_PORTB
);
570 bus_space_write_1(sc
->sc_bst
, sc
->sc_bsh
,
571 CIO_PORTB
, portb
| CPI_RESET
);
575 portb
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PDRB
);
576 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PDRB
, portb
& ~CPI_RESET
);
578 portb
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PDRB
);
579 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_PDRB
, portb
| CPI_RESET
);
580 #endif /* DIRECT_PORT_ACCESS */
585 * Centronics BUSY is on port B, bit 6
586 * SELECT is on Port B, bit 5
587 * /FAULT is on Port B, bit 1
588 * PAPER EMPTY is on Port C, bit 1
591 cpi_notready(struct cpi_softc
*sc
)
593 uint8_t portb
, portc
;
594 int is_busy
, is_select
, is_fault
, is_paper_empty
;
597 printf("\tcpi_notready() checking printer status...\n");
599 portb
= bus_space_read_1(sc
->sc_bst
, sc
->sc_bsh
, CIO_PORTB
);
601 printf("\tPort B has 0x0%X\n", portb
);
603 is_busy
= CPI_BUSY
& portb
;
605 printf("\t\tBUSY = %d\n", is_busy
);
607 is_select
= CPI_SELECT
& portb
;
609 printf("\t\tSELECT = %d\n", is_select
);
611 is_fault
= CPI_FAULT
& portb
;
613 printf("\t\t/FAULT = %d\n", is_fault
);
615 portc
= bus_space_read_1(sc
->sc_bst
, sc
->sc_bsh
, CIO_PORTC
);
617 printf("\tPort C has 0x0%X\n", portc
);
619 is_paper_empty
= CPI_PAPER_EMPTY
& portc
;
621 printf("\t\tPAPER EMPTY = %d\n", is_paper_empty
);
623 return (is_busy
|| !is_select
|| !is_fault
|| is_paper_empty
);
629 struct cpi_softc
*sc
;
633 /* Printer ready for output? */
634 if (cpi_notready(sc
))
637 if (0 && TRACE_WRITE
)
638 printf("\tcpi_soft_intr() has %u bytes.\n", sc
->sc_bufbytes
);
640 /* Anything to print? */
641 if (sc
->sc_bufbytes
) {
643 bus_space_write_1(sc
->sc_bst
, sc
->sc_bsh
,
644 CIO_PORTA
, *sc
->sc_cp
++);
646 sc
->sc_bytestoport
++;
648 if (0 == sc
->sc_bufbytes
)
649 /* line buffer empty, wake up our top half */
653 #ifdef USE_CIO_TIMERS
655 * Z8536 CIO timers 1 + 2 used for timecounter(9) support
658 cpi_initclock(struct cpi_softc
*sc
)
660 static struct timecounter cpi_timecounter
= {
661 .tc_get_timecount
= cpi_get_timecount
,
663 .tc_counter_mask
= 0x0ffffu
,
664 .tc_frequency
= CLK_FREQ
,
665 .tc_name
= "CPI Z8536 CIO",
672 * Set up timers A and B as a single, free-running 32 bit counter
675 /* Disable counters A and B */
676 reg
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_MCCR
);
677 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_MCCR
,
678 reg
& ~(MCCR_CT1E
| MCCR_CT2E
));
680 /* Make sure interrupt enable bits are cleared */
681 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR1
,
683 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR2
,
686 /* Initialise counter start values, and set to continuous cycle */
687 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTMSR1
, CTMS_CSC
);
688 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTTCR1_MSB
, 0x00);
689 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTTCR1_LSB
, 0x00);
691 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTMSR2
, CTMS_CSC
);
692 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTTCR2_MSB
, 0x00);
693 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTTCR2_LSB
, 0x00);
695 /* Re-enable counters A and B */
696 reg
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_MCCR
);
697 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_MCCR
,
698 reg
| MCCR_CT1E
| MCCR_CT2E
| MCCR_CT1CT2
);
700 /* Start counters A and B */
701 reg
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR1
);
702 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR1
,
704 reg
= z8536_reg_get(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR2
);
705 z8536_reg_set(sc
->sc_bst
, sc
->sc_bsh
, Z8536_CTCSR2
,
708 tc_init(&cpi_timecounter
);
712 cpi_get_timecount(struct timecounter
*tc
)
714 uint8_t high
, high2
, low
;
718 * Make the timer access atomic
720 * XXX How expensive is this? And is it really necessary?
727 #endif /* USE_CIO_TIMERS */
731 * Z8536 CIO nuts and bolts
735 z8536_reg_set(bus_space_tag_t bspace
, bus_space_handle_t bhandle
,
736 uint8_t reg
, uint8_t val
)
741 bus_space_write_1(bspace
, bhandle
, CIO_CTRL
, reg
);
743 bus_space_write_1(bspace
, bhandle
, CIO_CTRL
, val
);
747 static inline uint8_t
748 z8536_reg_get(bus_space_tag_t bspace
, bus_space_handle_t bhandle
, uint8_t reg
)
754 bus_space_write_1(bspace
, bhandle
, CIO_CTRL
, reg
);
756 val
= bus_space_read_1(bspace
, bhandle
, CIO_CTRL
);