FreeBSD/Linux Kernel Cross Reference
sys/dev/sx/sx_util.h
1 /*-
2 * Device driver for Specialix I/O8+ multiport serial card.
3 *
4 * Copyright 2003 Frank Mayhar <frank@exit.com>
5 *
6 * Derived from the "si" driver by Peter Wemm <peter@netplex.com.au>, using
7 * lots of information from the Linux "specialix" driver by Roger Wolff
8 * <R.E.Wolff@BitWizard.nl> and from the Intel CD1865 "Intelligent Eight-
9 * Channel Communications Controller" datasheet. Roger was also nice
10 * enough to answer numerous questions about stuff specific to the I/O8+
11 * not covered by the CD1865 datasheet.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notices, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notices, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE.
26 *
27 * $FreeBSD$
28 */
29
30
31 /* Utility functions and macros for the Specialix I/O8+ driver. */
32
33 /*
34 * sx_cd1865_out()
35 * Write a CD1865 register on the card.
36 */
37 static __inline void
38 sx_cd1865_out(
39 struct sx_softc *sc,
40 unsigned int reg,
41 unsigned char val)
42 {
43 bus_space_write_1(sc->sc_st, sc->sc_sh, SX_ADDR_REG, reg);
44 bus_space_write_1(sc->sc_st, sc->sc_sh, SX_DATA_REG, val);
45 }
46
47 /*
48 * sx_cd1865_in()
49 * Read a register from the card.
50 */
51 static __inline unsigned char
52 sx_cd1865_in(
53 struct sx_softc *sc,
54 unsigned int reg)
55 {
56 bus_space_write_1(sc->sc_st, sc->sc_sh, SX_ADDR_REG, reg);
57 return(bus_space_read_1(sc->sc_st, sc->sc_sh, SX_DATA_REG));
58 }
59
60 /*
61 * sx_cd1865_bis()
62 * Set bits in a CD1865 register.
63 */
64 static __inline void
65 sx_cd1865_bis(
66 struct sx_softc *sc,
67 unsigned int reg,
68 unsigned char bits)
69 {
70 register unsigned char rval;
71
72 rval = sx_cd1865_in(sc, reg);
73 rval |= bits;
74 sx_cd1865_out(sc, reg, rval);
75 }
76
77 /*
78 * sx_cd1865_bic()
79 * Clear bits in a CD1865 register.
80 */
81 static __inline void
82 sx_cd1865_bic(
83 struct sx_softc *sc,
84 unsigned int reg,
85 unsigned char bits)
86 {
87 register unsigned char rval;
88
89 rval = sx_cd1865_in(sc, reg);
90 rval &= ~bits;
91 sx_cd1865_out(sc, reg, rval);
92 }
93
94 /*
95 * sx_cd1865_wait_CCR()
96 * Spin waiting for the board Channel Command Register to clear.
97 *
98 * Description:
99 * The CD1865 processor clears the Channel Command Register to
100 * indicate that it has completed the last command. This routine
101 * waits for the CCR to become zero by watching the register,
102 * delaying ten microseconds between each check. We time out after
103 * ten milliseconds (or SX_CCR_TIMEOUT microseconds).
104 */
105 static __inline void
106 sx_cd1865_wait_CCR(
107 struct sx_softc *sc,
108 unsigned int ei_flag)
109 {
110 unsigned int to = SX_CCR_TIMEOUT/10;
111
112 while (to-- > 0) {
113 if (sx_cd1865_in(sc, CD1865_CCR|ei_flag) == 0)
114 return;
115 DELAY(10);
116 }
117 printf("sx: Timeout waiting for CCR to clear.\n");
118 }
119
120 /*
121 * sx_cd1865_etcmode()
122 * Set or clear embedded transmit command mode on a CD1865 port.
123 *
124 * Description:
125 * We can use commands embedded in the transmit data stream to do
126 * things like start and stop breaks or insert time delays. We normally
127 * run with embedded commands disabled; this routine selects the channel
128 * we're dealing with and enables or disables embedded commands depending
129 * on the flag passed to it. The caller must remember this state and
130 * escape any NULs it sends while embedded commands are enabled.
131 * Should be called at spltty(). Disables interrupts for the duration
132 * of the routine.
133 */
134 static __inline void
135 sx_cd1865_etcmode(
136 struct sx_softc *sc,
137 unsigned int ei_flag,
138 int chan,
139 int mode)
140 {
141 sx_cd1865_out(sc, CD1865_CAR|ei_flag, chan); /* Select channel. */
142 if (mode) { /* Enable embedded commands? */
143 sx_cd1865_bis(sc, CD1865_COR2|ei_flag, CD1865_COR2_ETC);
144 }
145 else {
146 sx_cd1865_bic(sc, CD1865_COR2|ei_flag, CD1865_COR2_ETC);
147 }
148 /*
149 * Wait for the CCR to clear, ding the card, let it know stuff
150 * changed, then wait for CCR to clear again.
151 */
152 sx_cd1865_wait_CCR(sc, ei_flag);
153 sx_cd1865_out(sc, CD1865_CCR|ei_flag, CD1865_CCR_CORCHG2);
154 sx_cd1865_wait_CCR(sc, ei_flag);
155 }
156
157 int sx_probe_io8(device_t dev);
158 int sx_init_cd1865(struct sx_softc *sc, int unit);
159 struct sx_port *sx_int_port(struct sx_softc *sc, int unit);
Cache object: a3d06fe0e232124329d0bd52467d5a40
|