1 /* $NetBSD: spif.c,v 1.24 2009/09/17 16:39:48 tsutsui Exp $ */
2 /* $OpenBSD: spif.c,v 1.12 2003/10/03 16:44:51 miod Exp $ */
5 * Copyright (c) 1999-2002 Jason L. Wright (jason@thought.net)
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * Effort sponsored in part by the Defense Advanced Research Projects
30 * Agency (DARPA) and Air Force Research Laboratory, Air Force
31 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board
37 * based heavily on Iain Hibbert's driver for the MAGMA cards
40 /* Ported to NetBSD 2.0 by Hauke Fath */
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.24 2009/09/17 16:39:48 tsutsui Exp $");
49 #include <sys/param.h>
50 #include <sys/systm.h>
52 #include <sys/device.h>
54 #include <sys/ioctl.h>
55 #include <sys/malloc.h>
58 #include <sys/kernel.h>
59 #include <sys/syslog.h>
61 #include <sys/errno.h>
62 #include <sys/kauth.h>
66 #include <machine/autoconf.h>
67 #include <machine/promlib.h>
69 #include <dev/sbus/sbusvar.h>
71 #include <dev/sbus/spifvar.h>
72 #include <dev/sbus/spifreg.h>
76 /* Autoconfig stuff */
78 CFATTACH_DECL(spif
, sizeof(struct spif_softc
),
79 spif_match
, spif_attach
, NULL
, NULL
);
81 CFATTACH_DECL(stty
, sizeof(struct stty_softc
),
82 stty_match
, stty_attach
, NULL
, NULL
);
84 CFATTACH_DECL(sbpp
, sizeof(struct sbpp_softc
),
85 sbpp_match
, sbpp_attach
, NULL
, NULL
);
87 dev_type_open(stty_open
);
88 dev_type_close(stty_close
);
89 dev_type_read(stty_read
);
90 dev_type_write(stty_write
);
91 dev_type_ioctl(stty_ioctl
);
92 dev_type_stop(stty_stop
);
93 dev_type_tty(stty_tty
);
94 dev_type_poll(stty_poll
);
96 const struct cdevsw stty_cdevsw
= {
97 stty_open
, stty_close
, stty_read
, stty_write
, stty_ioctl
,
98 stty_stop
, stty_tty
, stty_poll
, nommap
, ttykqfilter
, D_TTY
101 dev_type_open(sbpp_open
);
102 dev_type_close(sbpp_close
);
103 dev_type_read(sbpp_read
);
104 dev_type_write(sbpp_write
);
105 dev_type_ioctl(sbpp_ioctl
);
106 dev_type_poll(sbpp_poll
);
108 const struct cdevsw sbpp_cdevsw
= {
109 sbpp_open
, sbpp_close
, sbpp_read
, sbpp_write
, sbpp_ioctl
,
110 nostop
, notty
, sbpp_poll
, nommap
, nokqfilter
, D_OTHER
114 /* normal STC access */
115 #define STC_WRITE(sc,r,v) \
116 bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v))
117 #define STC_READ(sc,r) \
118 bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r))
120 /* IACK STC access */
121 #define ISTC_WRITE(sc,r,v) \
122 bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v))
123 #define ISTC_READ(sc,r) \
124 bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r))
127 #define PPC_WRITE(sc,r,v) \
128 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v))
129 #define PPC_READ(sc,r) \
130 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r))
132 #define DTR_WRITE(sc,port,v) \
134 sc->sc_ttys->sc_port[(port)].sp_dtr = v; \
135 bus_space_write_1((sc)->sc_bustag, \
136 sc->sc_dtrh, port, (v == 0) ? 1 : 0); \
139 #define DTR_READ(sc,port) ((sc)->sc_ttys->sc_port[(port)].sp_dtr)
143 spif_match(device_t parent
, cfdata_t vcf
, void *aux
)
145 struct sbus_attach_args
*sa
= aux
;
147 if (strcmp(vcf
->cf_name
, sa
->sa_name
) &&
148 strcmp("SUNW,spif", sa
->sa_name
))
154 spif_attach(device_t parent
, device_t self
, void *aux
)
156 struct spif_softc
*sc
= device_private(self
);
157 struct sbus_attach_args
*sa
= aux
;
159 if (sa
->sa_nintr
!= 2) {
160 printf(": expected %d interrupts, got %d\n", 2, sa
->sa_nintr
);
164 if (sa
->sa_nreg
!= 1) {
165 printf(": expected %d registers, got %d\n", 1, sa
->sa_nreg
);
169 sc
->sc_bustag
= sa
->sa_bustag
;
170 if (sbus_bus_map(sa
->sa_bustag
, sa
->sa_slot
,
171 sa
->sa_offset
, sa
->sa_size
,
172 0, &sc
->sc_regh
) != 0) {
173 printf(": can't map registers\n");
177 if (bus_space_subregion(sc
->sc_bustag
, sc
->sc_regh
,
178 DTR_REG_OFFSET
, DTR_REG_LEN
, &sc
->sc_dtrh
) != 0) {
179 printf(": can't map dtr regs\n");
183 if (bus_space_subregion(sc
->sc_bustag
, sc
->sc_regh
,
184 STC_REG_OFFSET
, STC_REG_LEN
, &sc
->sc_stch
) != 0) {
185 printf(": can't map dtr regs\n");
189 if (bus_space_subregion(sc
->sc_bustag
, sc
->sc_regh
,
190 ISTC_REG_OFFSET
, ISTC_REG_LEN
, &sc
->sc_istch
) != 0) {
191 printf(": can't map dtr regs\n");
195 if (bus_space_subregion(sc
->sc_bustag
, sc
->sc_regh
,
196 PPC_REG_OFFSET
, PPC_REG_LEN
, &sc
->sc_ppch
) != 0) {
197 printf(": can't map dtr regs\n");
201 sc
->sc_ppcih
= bus_intr_establish(sa
->sa_bustag
,
202 sa
->sa_intr
[PARALLEL_INTR
].oi_pri
, IPL_SERIAL
, spif_ppcintr
, sc
);
203 if (sc
->sc_ppcih
== NULL
) {
204 printf(": failed to establish ppc interrupt\n");
208 sc
->sc_stcih
= bus_intr_establish(sa
->sa_bustag
,
209 sa
->sa_intr
[SERIAL_INTR
].oi_pri
, IPL_SERIAL
, spif_stcintr
, sc
);
210 if (sc
->sc_stcih
== NULL
) {
211 printf(": failed to establish stc interrupt\n");
215 sc
->sc_softih
= softint_establish(SOFTINT_SERIAL
, spif_softintr
, sc
);
216 if (sc
->sc_softih
== NULL
) {
217 printf(": can't get soft intr\n");
221 sc
->sc_node
= sa
->sa_node
;
223 sc
->sc_rev
= prom_getpropint(sc
->sc_node
, "revlev", 0);
225 sc
->sc_osc
= prom_getpropint(sc
->sc_node
, "verosc", 0);
226 switch (sc
->sc_osc
) {
228 sc
->sc_osc
= 10000000;
232 sc
->sc_osc
= 9830400;
239 sc
->sc_rev2
= STC_READ(sc
, STC_GFRCR
);
240 STC_WRITE(sc
, STC_GSVR
, 0);
242 stty_write_ccr(sc
, CD180_CCR_CMD_RESET
| CD180_CCR_RESETALL
);
243 while (STC_READ(sc
, STC_GSVR
) != 0xff);
244 while (STC_READ(sc
, STC_GFRCR
) != sc
->sc_rev2
);
246 STC_WRITE(sc
, STC_PPRH
, CD180_PPRH
);
247 STC_WRITE(sc
, STC_PPRL
, CD180_PPRL
);
248 STC_WRITE(sc
, STC_MSMR
, SPIF_MSMR
);
249 STC_WRITE(sc
, STC_TSMR
, SPIF_TSMR
);
250 STC_WRITE(sc
, STC_RSMR
, SPIF_RSMR
);
251 STC_WRITE(sc
, STC_GSVR
, 0);
252 STC_WRITE(sc
, STC_GSCR1
, 0);
253 STC_WRITE(sc
, STC_GSCR2
, 0);
254 STC_WRITE(sc
, STC_GSCR3
, 0);
256 printf(": rev %x chiprev %x osc %sMHz\n",
257 sc
->sc_rev
, sc
->sc_rev2
, clockfreq(sc
->sc_osc
));
259 (void)config_found(self
, stty_match
, NULL
);
260 (void)config_found(self
, sbpp_match
, NULL
);
265 bus_space_unmap(sa
->sa_bustag
, sc
->sc_regh
, sa
->sa_size
);
269 stty_match(device_t parent
, cfdata_t vcf
, void *aux
)
271 struct spif_softc
*sc
= device_private(parent
);
273 return (aux
== stty_match
&& sc
->sc_ttys
== NULL
);
277 stty_attach(device_t parent
, device_t dev
, void *aux
)
279 struct spif_softc
*sc
= device_private(parent
);
280 struct stty_softc
*ssc
= device_private(dev
);
285 for (port
= 0; port
< sc
->sc_nser
; port
++) {
286 struct stty_port
*sp
= &ssc
->sc_port
[port
];
289 DTR_WRITE(sc
, port
, 0);
293 tp
->t_oproc
= stty_start
;
294 tp
->t_param
= stty_param
;
298 sp
->sp_channel
= port
;
300 sp
->sp_rbuf
= malloc(STTY_RBUF_SIZE
, M_DEVBUF
, M_NOWAIT
);
301 if(sp
->sp_rbuf
== NULL
)
304 sp
->sp_rend
= sp
->sp_rbuf
+ STTY_RBUF_SIZE
;
307 ssc
->sc_nports
= port
;
309 printf(": %d tty%s\n", port
, port
== 1 ? "" : "s");
313 stty_open(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
315 struct spif_softc
*csc
;
316 struct stty_softc
*sc
;
317 struct stty_port
*sp
;
319 int card
= SPIF_CARD(dev
);
320 int port
= SPIF_PORT(dev
);
322 sc
= device_lookup_private(&stty_cd
, card
);
323 csc
= device_lookup_private(&spif_cd
, card
);
324 if (sc
== NULL
|| csc
== NULL
)
327 if (port
>= sc
->sc_nports
)
330 sp
= &sc
->sc_port
[port
];
334 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
337 mutex_spin_enter(&tty_lock
);
338 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
340 tp
->t_iflag
= TTYDEF_IFLAG
;
341 tp
->t_oflag
= TTYDEF_OFLAG
;
342 tp
->t_cflag
= TTYDEF_CFLAG
;
343 if (ISSET(sp
->sp_openflags
, TIOCFLAG_CLOCAL
))
344 SET(tp
->t_cflag
, CLOCAL
);
345 if (ISSET(sp
->sp_openflags
, TIOCFLAG_CRTSCTS
))
346 SET(tp
->t_cflag
, CRTSCTS
);
347 if (ISSET(sp
->sp_openflags
, TIOCFLAG_MDMBUF
))
348 SET(tp
->t_cflag
, MDMBUF
);
349 tp
->t_lflag
= TTYDEF_LFLAG
;
350 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
352 sp
->sp_rput
= sp
->sp_rget
= sp
->sp_rbuf
;
354 STC_WRITE(csc
, STC_CAR
, sp
->sp_channel
);
355 stty_write_ccr(csc
, CD180_CCR_CMD_RESET
|CD180_CCR_RESETCHAN
);
356 STC_WRITE(csc
, STC_CAR
, sp
->sp_channel
);
358 stty_param(tp
, &tp
->t_termios
);
362 STC_WRITE(csc
, STC_SRER
, CD180_SRER_CD
| CD180_SRER_RXD
);
364 if (ISSET(sp
->sp_openflags
, TIOCFLAG_SOFTCAR
) || sp
->sp_carrier
)
365 SET(tp
->t_state
, TS_CARR_ON
);
367 CLR(tp
->t_state
, TS_CARR_ON
);
370 if (!ISSET(flags
, O_NONBLOCK
)) {
371 while (!ISSET(tp
->t_cflag
, CLOCAL
) &&
372 !ISSET(tp
->t_state
, TS_CARR_ON
)) {
374 error
= ttysleep(tp
, &tp
->t_rawcv
, true, 0);
376 mutex_spin_exit(&tty_lock
);
381 mutex_spin_exit(&tty_lock
);
383 return ((*tp
->t_linesw
->l_open
)(dev
, tp
));
387 stty_close(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
389 struct stty_softc
*sc
= device_lookup_private(&stty_cd
, SPIF_CARD(dev
));
390 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(dev
)];
391 struct spif_softc
*csc
= sp
->sp_sc
;
392 struct tty
*tp
= sp
->sp_tty
;
393 int port
= SPIF_PORT(dev
);
396 (*tp
->t_linesw
->l_close
)(tp
, flags
);
399 if (ISSET(tp
->t_cflag
, HUPCL
) || !ISSET(tp
->t_state
, TS_ISOPEN
)) {
400 stty_modem_control(sp
, 0, DMSET
);
401 STC_WRITE(csc
, STC_CAR
, port
);
402 STC_WRITE(csc
, STC_CCR
,
403 CD180_CCR_CMD_RESET
|CD180_CCR_RESETCHAN
);
412 stty_ioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
414 struct stty_softc
*stc
= device_lookup_private(&stty_cd
,
416 struct stty_port
*sp
= &stc
->sc_port
[SPIF_PORT(dev
)];
417 struct spif_softc
*sc
= sp
->sp_sc
;
418 struct tty
*tp
= sp
->sp_tty
;
421 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flags
, l
);
425 error
= ttioctl(tp
, cmd
, data
, flags
, l
);
433 SET(sp
->sp_flags
, STTYF_SET_BREAK
);
434 STC_WRITE(sc
, STC_CAR
, sp
->sp_channel
);
435 STC_WRITE(sc
, STC_SRER
,
436 STC_READ(sc
, STC_SRER
) | CD180_SRER_TXD
);
439 SET(sp
->sp_flags
, STTYF_CLR_BREAK
);
440 STC_WRITE(sc
, STC_CAR
, sp
->sp_channel
);
441 STC_WRITE(sc
, STC_SRER
,
442 STC_READ(sc
, STC_SRER
) | CD180_SRER_TXD
);
445 stty_modem_control(sp
, TIOCM_DTR
, DMBIS
);
448 stty_modem_control(sp
, TIOCM_DTR
, DMBIC
);
451 stty_modem_control(sp
, *((int *)data
), DMBIS
);
454 stty_modem_control(sp
, *((int *)data
), DMBIC
);
457 *((int *)data
) = stty_modem_control(sp
, 0, DMGET
);
460 stty_modem_control(sp
, *((int *)data
), DMSET
);
463 *((int *)data
) = sp
->sp_openflags
;
466 if (kauth_authorize_device_tty(l
->l_cred
,
467 KAUTH_DEVICE_TTY_PRIVSET
, tp
))
470 sp
->sp_openflags
= *((int *)data
) &
471 (TIOCFLAG_SOFTCAR
| TIOCFLAG_CLOCAL
|
472 TIOCFLAG_CRTSCTS
| TIOCFLAG_MDMBUF
);
482 stty_modem_control(struct stty_port
*sp
, int bits
, int how
)
484 struct spif_softc
*csc
= sp
->sp_sc
;
485 struct tty
*tp
= sp
->sp_tty
;
489 STC_WRITE(csc
, STC_CAR
, sp
->sp_channel
);
494 if (DTR_READ(csc
, sp
->sp_channel
))
496 msvr
= STC_READ(csc
, STC_MSVR
);
497 if (ISSET(msvr
, CD180_MSVR_DSR
))
499 if (ISSET(msvr
, CD180_MSVR_CD
))
501 if (ISSET(msvr
, CD180_MSVR_CTS
))
503 if (ISSET(msvr
, CD180_MSVR_RTS
))
507 DTR_WRITE(csc
, sp
->sp_channel
, ISSET(bits
, TIOCM_DTR
) ? 1 : 0);
508 if (ISSET(bits
, TIOCM_RTS
))
509 STC_WRITE(csc
, STC_MSVR
,
510 STC_READ(csc
, STC_MSVR
) & (~CD180_MSVR_RTS
));
512 STC_WRITE(csc
, STC_MSVR
,
513 STC_READ(csc
, STC_MSVR
) | CD180_MSVR_RTS
);
516 if (ISSET(bits
, TIOCM_DTR
))
517 DTR_WRITE(csc
, sp
->sp_channel
, 1);
518 if (ISSET(bits
, TIOCM_RTS
) && !ISSET(tp
->t_cflag
, CRTSCTS
))
519 STC_WRITE(csc
, STC_MSVR
,
520 STC_READ(csc
, STC_MSVR
) & (~CD180_MSVR_RTS
));
523 if (ISSET(bits
, TIOCM_DTR
))
524 DTR_WRITE(csc
, sp
->sp_channel
, 0);
525 if (ISSET(bits
, TIOCM_RTS
))
526 STC_WRITE(csc
, STC_MSVR
,
527 STC_READ(csc
, STC_MSVR
) | CD180_MSVR_RTS
);
536 stty_param(struct tty
*tp
, struct termios
*t
)
538 struct stty_softc
*st
= device_lookup_private(&stty_cd
,
539 SPIF_CARD(tp
->t_dev
));
540 struct stty_port
*sp
= &st
->sc_port
[SPIF_PORT(tp
->t_dev
)];
541 struct spif_softc
*sc
= sp
->sp_sc
;
542 uint8_t rbprl
, rbprh
, tbprl
, tbprh
;
546 stty_compute_baud(t
->c_ospeed
, sc
->sc_osc
, &tbprl
, &tbprh
))
550 stty_compute_baud(t
->c_ispeed
, sc
->sc_osc
, &rbprl
, &rbprh
))
555 /* hang up line if ospeed is zero, otherwise raise DTR */
556 stty_modem_control(sp
, TIOCM_DTR
,
557 (t
->c_ospeed
== 0 ? DMBIC
: DMBIS
));
559 STC_WRITE(sc
, STC_CAR
, sp
->sp_channel
);
562 if (ISSET(t
->c_cflag
, PARENB
)) {
563 opt
|= CD180_COR1_PARMODE_NORMAL
;
564 opt
|= (ISSET(t
->c_cflag
, PARODD
) ?
569 opt
|= CD180_COR1_PARMODE_NO
;
571 if (!ISSET(t
->c_iflag
, INPCK
))
572 opt
|= CD180_COR1_IGNPAR
;
574 if (ISSET(t
->c_cflag
, CSTOPB
))
575 opt
|= CD180_COR1_STOP2
;
577 switch (t
->c_cflag
& CSIZE
) {
579 opt
|= CD180_COR1_CS5
;
582 opt
|= CD180_COR1_CS6
;
585 opt
|= CD180_COR1_CS7
;
588 opt
|= CD180_COR1_CS8
;
591 STC_WRITE(sc
, STC_COR1
, opt
);
592 stty_write_ccr(sc
, CD180_CCR_CMD_COR
|CD180_CCR_CORCHG1
);
594 opt
= CD180_COR2_ETC
;
595 if (ISSET(t
->c_cflag
, CRTSCTS
))
596 opt
|= CD180_COR2_CTSAE
;
597 STC_WRITE(sc
, STC_COR2
, opt
);
598 stty_write_ccr(sc
, CD180_CCR_CMD_COR
|CD180_CCR_CORCHG2
);
600 STC_WRITE(sc
, STC_COR3
, STTY_RX_FIFO_THRESHOLD
);
601 stty_write_ccr(sc
, CD180_CCR_CMD_COR
|CD180_CCR_CORCHG3
);
603 STC_WRITE(sc
, STC_SCHR1
, 0x11);
604 STC_WRITE(sc
, STC_SCHR2
, 0x13);
605 STC_WRITE(sc
, STC_SCHR3
, 0x11);
606 STC_WRITE(sc
, STC_SCHR4
, 0x13);
607 STC_WRITE(sc
, STC_RTPR
, 0x12);
609 STC_WRITE(sc
, STC_MCOR1
, CD180_MCOR1_CDZD
| STTY_RX_DTR_THRESHOLD
);
610 STC_WRITE(sc
, STC_MCOR2
, CD180_MCOR2_CDOD
);
611 STC_WRITE(sc
, STC_MCR
, 0);
614 STC_WRITE(sc
, STC_TBPRH
, tbprh
);
615 STC_WRITE(sc
, STC_TBPRL
, tbprl
);
619 STC_WRITE(sc
, STC_RBPRH
, rbprh
);
620 STC_WRITE(sc
, STC_RBPRL
, rbprl
);
623 stty_write_ccr(sc
, CD180_CCR_CMD_CHAN
|
624 CD180_CCR_CHAN_TXEN
| CD180_CCR_CHAN_RXEN
);
626 sp
->sp_carrier
= STC_READ(sc
, STC_MSVR
) & CD180_MSVR_CD
;
633 stty_read(dev_t dev
, struct uio
*uio
, int flags
)
635 struct stty_softc
*sc
= device_lookup_private(&stty_cd
, SPIF_CARD(dev
));
636 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(dev
)];
637 struct tty
*tp
= sp
->sp_tty
;
639 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flags
));
643 stty_write(dev_t dev
, struct uio
*uio
, int flags
)
645 struct stty_softc
*sc
= device_lookup_private(&stty_cd
, SPIF_CARD(dev
));
646 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(dev
)];
647 struct tty
*tp
= sp
->sp_tty
;
649 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flags
));
653 stty_poll(dev_t dev
, int events
, struct lwp
*l
)
655 struct stty_softc
*sc
= device_lookup_private(&stty_cd
, SPIF_CARD(dev
));
656 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(dev
)];
657 struct tty
*tp
= sp
->sp_tty
;
659 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
665 struct stty_softc
*sc
= device_lookup_private(&stty_cd
, SPIF_CARD(dev
));
666 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(dev
)];
672 stty_stop(struct tty
*tp
, int flags
)
674 struct stty_softc
*sc
= device_lookup_private(&stty_cd
,
675 SPIF_CARD(tp
->t_dev
));
676 struct stty_port
*sp
= &sc
->sc_port
[SPIF_PORT(tp
->t_dev
)];
680 if (ISSET(tp
->t_state
, TS_BUSY
)) {
681 if (!ISSET(tp
->t_state
, TS_TTSTOP
))
682 SET(tp
->t_state
, TS_FLUSH
);
683 SET(sp
->sp_flags
, STTYF_STOP
);
689 stty_start(struct tty
*tp
)
691 struct stty_softc
*stc
= device_lookup_private(&stty_cd
,
692 SPIF_CARD(tp
->t_dev
));
693 struct stty_port
*sp
= &stc
->sc_port
[SPIF_PORT(tp
->t_dev
)];
694 struct spif_softc
*sc
= sp
->sp_sc
;
699 if (!ISSET(tp
->t_state
, TS_TTSTOP
| TS_TIMEOUT
| TS_BUSY
)) {
701 sp
->sp_txc
= ndqb(&tp
->t_outq
, 0);
702 sp
->sp_txp
= tp
->t_outq
.c_cf
;
703 SET(tp
->t_state
, TS_BUSY
);
704 STC_WRITE(sc
, STC_CAR
, sp
->sp_channel
);
705 STC_WRITE(sc
, STC_SRER
,
706 STC_READ(sc
, STC_SRER
) | CD180_SRER_TXD
);
714 spif_stcintr_rxexception(struct spif_softc
*sc
, int *needsoftp
)
716 struct stty_port
*sp
;
717 uint8_t channel
, *ptr
;
719 channel
= CD180_GSCR_CHANNEL(STC_READ(sc
, STC_GSCR1
));
720 sp
= &sc
->sc_ttys
->sc_port
[channel
];
722 *ptr
++ = STC_READ(sc
, STC_RCSR
);
723 *ptr
++ = STC_READ(sc
, STC_RDR
);
724 if (ptr
== sp
->sp_rend
)
726 if (ptr
== sp
->sp_rget
) {
727 if (ptr
== sp
->sp_rbuf
)
730 SET(sp
->sp_flags
, STTYF_RING_OVERFLOW
);
732 STC_WRITE(sc
, STC_EOSRR
, 0);
739 spif_stcintr_rx(struct spif_softc
*sc
, int *needsoftp
)
741 struct stty_port
*sp
;
742 uint8_t channel
, *ptr
, cnt
, rcsr
;
745 channel
= CD180_GSCR_CHANNEL(STC_READ(sc
, STC_GSCR1
));
746 sp
= &sc
->sc_ttys
->sc_port
[channel
];
748 cnt
= STC_READ(sc
, STC_RDCR
);
749 for (i
= 0; i
< cnt
; i
++) {
751 rcsr
= STC_READ(sc
, STC_RCSR
);
752 *ptr
++ = STC_READ(sc
, STC_RDR
);
753 if (ptr
== sp
->sp_rend
)
755 if (ptr
== sp
->sp_rget
) {
756 if (ptr
== sp
->sp_rbuf
)
759 SET(sp
->sp_flags
, STTYF_RING_OVERFLOW
);
763 STC_WRITE(sc
, STC_EOSRR
, 0);
772 spif_stcintr_tx(struct spif_softc
*sc
, int *needsoftp
)
774 struct stty_port
*sp
;
778 channel
= CD180_GSCR_CHANNEL(STC_READ(sc
, STC_GSCR1
));
779 sp
= &sc
->sc_ttys
->sc_port
[channel
];
780 if (!ISSET(sp
->sp_flags
, STTYF_STOP
)) {
781 if (ISSET(sp
->sp_flags
, STTYF_SET_BREAK
)) {
782 STC_WRITE(sc
, STC_TDR
, 0);
783 STC_WRITE(sc
, STC_TDR
, 0x81);
784 CLR(sp
->sp_flags
, STTYF_SET_BREAK
);
787 if (ISSET(sp
->sp_flags
, STTYF_CLR_BREAK
)) {
788 STC_WRITE(sc
, STC_TDR
, 0);
789 STC_WRITE(sc
, STC_TDR
, 0x83);
790 CLR(sp
->sp_flags
, STTYF_CLR_BREAK
);
794 while (sp
->sp_txc
> 0 && cnt
< (CD180_TX_FIFO_SIZE
-1)) {
800 STC_WRITE(sc
, STC_TDR
, ch
);
803 STC_WRITE(sc
, STC_TDR
, ch
);
808 if (sp
->sp_txc
== 0 ||
809 ISSET(sp
->sp_flags
, STTYF_STOP
)) {
810 STC_WRITE(sc
, STC_SRER
, STC_READ(sc
, STC_SRER
) &
812 CLR(sp
->sp_flags
, STTYF_STOP
);
813 SET(sp
->sp_flags
, STTYF_DONE
);
817 STC_WRITE(sc
, STC_EOSRR
, 0);
823 spif_stcintr_mx(struct spif_softc
*sc
, int *needsoftp
)
825 struct stty_port
*sp
;
826 uint8_t channel
, mcr
;
828 channel
= CD180_GSCR_CHANNEL(STC_READ(sc
, STC_GSCR1
));
829 sp
= &sc
->sc_ttys
->sc_port
[channel
];
830 mcr
= STC_READ(sc
, STC_MCR
);
831 if (mcr
& CD180_MCR_CD
) {
832 SET(sp
->sp_flags
, STTYF_CDCHG
);
835 STC_WRITE(sc
, STC_MCR
, 0);
836 STC_WRITE(sc
, STC_EOSRR
, 0);
841 spif_stcintr(void *vsc
)
843 struct spif_softc
*sc
= (struct spif_softc
*)vsc
;
844 int needsoft
= 0, r
= 0, i
;
847 for (i
= 0; i
< 8; i
++) {
848 ar
= ISTC_READ(sc
, STC_RRAR
) & CD180_GSVR_IMASK
;
849 if (ar
== CD180_GSVR_RXGOOD
)
850 r
|= spif_stcintr_rx(sc
, &needsoft
);
851 else if (ar
== CD180_GSVR_RXEXCEPTION
)
852 r
|= spif_stcintr_rxexception(sc
, &needsoft
);
855 for (i
= 0; i
< 8; i
++) {
856 ar
= ISTC_READ(sc
, STC_TRAR
) & CD180_GSVR_IMASK
;
857 if (ar
== CD180_GSVR_TXDATA
)
858 r
|= spif_stcintr_tx(sc
, &needsoft
);
861 for (i
= 0; i
< 8; i
++) {
862 ar
= ISTC_READ(sc
, STC_MRAR
) & CD180_GSVR_IMASK
;
863 if (ar
== CD180_GSVR_STATCHG
)
864 r
|= spif_stcintr_mx(sc
, &needsoft
);
868 softint_schedule(sc
->sc_softih
);
873 spif_softintr(void *vsc
)
875 struct spif_softc
*sc
= (struct spif_softc
*)vsc
;
876 struct stty_softc
*stc
= sc
->sc_ttys
;
877 int r
= 0, i
, data
, s
, flags
;
879 struct stty_port
*sp
;
883 for (i
= 0; i
< stc
->sc_nports
; i
++) {
884 sp
= &stc
->sc_port
[i
];
887 if (!ISSET(tp
->t_state
, TS_ISOPEN
))
890 while (sp
->sp_rget
!= sp
->sp_rput
) {
891 stat
= sp
->sp_rget
[0];
892 data
= sp
->sp_rget
[1];
894 if (sp
->sp_rget
== sp
->sp_rend
)
895 sp
->sp_rget
= sp
->sp_rbuf
;
897 if (stat
& (CD180_RCSR_BE
| CD180_RCSR_FE
))
900 if (stat
& CD180_RCSR_PE
)
903 (*tp
->t_linesw
->l_rint
)(data
, tp
);
908 flags
= sp
->sp_flags
;
909 CLR(sp
->sp_flags
, STTYF_DONE
| STTYF_CDCHG
|
910 STTYF_RING_OVERFLOW
);
913 if (ISSET(flags
, STTYF_CDCHG
)) {
915 STC_WRITE(sc
, STC_CAR
, i
);
916 msvr
= STC_READ(sc
, STC_MSVR
);
919 sp
->sp_carrier
= msvr
& CD180_MSVR_CD
;
920 (*tp
->t_linesw
->l_modem
)(tp
,
925 if (ISSET(flags
, STTYF_RING_OVERFLOW
)) {
926 log(LOG_WARNING
, "%s-%x: ring overflow\n",
927 device_xname(&stc
->sc_dev
), i
);
931 if (ISSET(flags
, STTYF_DONE
)) {
933 sp
->sp_txp
- tp
->t_outq
.c_cf
);
934 CLR(tp
->t_state
, TS_BUSY
);
935 (*tp
->t_linesw
->l_start
)(tp
);
943 stty_write_ccr(struct spif_softc
*sc
, uint8_t val
)
947 while (STC_READ(sc
, STC_CCR
) && tries
--)
950 aprint_error_dev(&sc
->sc_dev
, "ccr timeout\n");
951 STC_WRITE(sc
, STC_CCR
, val
);
955 stty_compute_baud(speed_t speed
, int clock
, uint8_t *bprlp
, uint8_t *bprhp
)
959 rate
= (2 * clock
) / (16 * speed
);
961 rate
= (rate
>> 1) + 1;
965 if (rate
> 0xffff || rate
== 0)
968 *bprlp
= rate
& 0xff;
969 *bprhp
= (rate
>> 8) & 0xff;
974 sbpp_match(device_t parent
, cfdata_t vcf
, void *aux
)
976 struct spif_softc
*sc
= device_private(parent
);
978 return (aux
== sbpp_match
&& sc
->sc_bpps
== NULL
);
982 sbpp_attach(device_t parent
, device_t dev
, void *aux
)
984 struct spif_softc
*sc
= device_private(parent
);
985 struct sbpp_softc
*psc
= device_private(dev
);
990 for (port
= 0; port
< sc
->sc_npar
; port
++) {
993 psc
->sc_nports
= port
;
994 printf(": %d port%s\n", port
, port
== 1 ? "" : "s");
998 sbpp_open(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
1004 sbpp_close(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
1010 spif_ppcintr(void *v
)
1016 sbpp_read(dev_t dev
, struct uio
*uio
, int flags
)
1018 return (sbpp_rw(dev
, uio
));
1022 sbpp_write(dev_t dev
, struct uio
*uio
, int flags
)
1024 return (sbpp_rw(dev
, uio
));
1028 sbpp_rw(dev_t dev
, struct uio
*uio
)
1034 sbpp_poll(dev_t dev
, int events
, struct lwp
*l
)
1036 return (seltrue(dev
, events
, l
));
1040 sbpp_ioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)