1 1.31 martin /* $NetBSD: z8530sc.c,v 1.31 2013/09/15 16:13:33 martin Exp $ */ 2 1.1 gwr 3 1.1 gwr /* 4 1.1 gwr * Copyright (c) 1992, 1993 5 1.1 gwr * The Regents of the University of California. All rights reserved. 6 1.1 gwr * 7 1.1 gwr * This software was developed by the Computer Systems Engineering group 8 1.1 gwr * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 1.1 gwr * contributed to Berkeley. 10 1.1 gwr * 11 1.1 gwr * All advertising materials mentioning features or use of this software 12 1.1 gwr * must display the following acknowledgement: 13 1.1 gwr * This product includes software developed by the University of 14 1.1 gwr * California, Lawrence Berkeley Laboratory. 15 1.1 gwr * 16 1.1 gwr * Redistribution and use in source and binary forms, with or without 17 1.1 gwr * modification, are permitted provided that the following conditions 18 1.1 gwr * are met: 19 1.1 gwr * 1. Redistributions of source code must retain the above copyright 20 1.1 gwr * notice, this list of conditions and the following disclaimer. 21 1.1 gwr * 2. Redistributions in binary form must reproduce the above copyright 22 1.1 gwr * notice, this list of conditions and the following disclaimer in the 23 1.1 gwr * documentation and/or other materials provided with the distribution. 24 1.19 agc * 3. Neither the name of the University nor the names of its contributors 25 1.19 agc * may be used to endorse or promote products derived from this software 26 1.19 agc * without specific prior written permission. 27 1.19 agc * 28 1.19 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 1.19 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 1.19 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 1.19 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 1.19 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 1.19 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 1.19 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 1.19 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 1.19 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 1.19 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 1.19 agc * SUCH DAMAGE. 39 1.19 agc * 40 1.19 agc * @(#)zs.c 8.1 (Berkeley) 7/19/93 41 1.19 agc */ 42 1.19 agc 43 1.19 agc /* 44 1.19 agc * Copyright (c) 1994 Gordon W. Ross 45 1.19 agc * 46 1.19 agc * This software was developed by the Computer Systems Engineering group 47 1.19 agc * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 48 1.19 agc * contributed to Berkeley. 49 1.19 agc * 50 1.19 agc * All advertising materials mentioning features or use of this software 51 1.19 agc * must display the following acknowledgement: 52 1.19 agc * This product includes software developed by the University of 53 1.19 agc * California, Lawrence Berkeley Laboratory. 54 1.19 agc * 55 1.19 agc * Redistribution and use in source and binary forms, with or without 56 1.19 agc * modification, are permitted provided that the following conditions 57 1.19 agc * are met: 58 1.19 agc * 1. Redistributions of source code must retain the above copyright 59 1.19 agc * notice, this list of conditions and the following disclaimer. 60 1.19 agc * 2. Redistributions in binary form must reproduce the above copyright 61 1.19 agc * notice, this list of conditions and the following disclaimer in the 62 1.19 agc * documentation and/or other materials provided with the distribution. 63 1.1 gwr * 3. All advertising materials mentioning features or use of this software 64 1.1 gwr * must display the following acknowledgement: 65 1.1 gwr * This product includes software developed by the University of 66 1.1 gwr * California, Berkeley and its contributors. 67 1.1 gwr * 4. Neither the name of the University nor the names of its contributors 68 1.1 gwr * may be used to endorse or promote products derived from this software 69 1.1 gwr * without specific prior written permission. 70 1.1 gwr * 71 1.1 gwr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 72 1.1 gwr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 73 1.1 gwr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 74 1.1 gwr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 75 1.1 gwr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 76 1.1 gwr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 77 1.1 gwr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 78 1.1 gwr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 79 1.1 gwr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 80 1.1 gwr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 81 1.1 gwr * SUCH DAMAGE. 82 1.1 gwr * 83 1.1 gwr * @(#)zs.c 8.1 (Berkeley) 7/19/93 84 1.1 gwr */ 85 1.1 gwr 86 1.1 gwr /* 87 1.1 gwr * Zilog Z8530 Dual UART driver (common part) 88 1.1 gwr * 89 1.1 gwr * This file contains the machine-independent parts of the 90 1.1 gwr * driver common to tty and keyboard/mouse sub-drivers. 91 1.1 gwr */ 92 1.16 lukem 93 1.16 lukem #include <sys/cdefs.h> 94 1.31 martin __KERNEL_RCSID(0, "$NetBSD: z8530sc.c,v 1.31 2013/09/15 16:13:33 martin Exp $"); 95 1.1 gwr 96 1.1 gwr #include <sys/param.h> 97 1.1 gwr #include <sys/systm.h> 98 1.1 gwr #include <sys/proc.h> 99 1.1 gwr #include <sys/device.h> 100 1.1 gwr #include <sys/conf.h> 101 1.1 gwr #include <sys/file.h> 102 1.1 gwr #include <sys/ioctl.h> 103 1.1 gwr #include <sys/tty.h> 104 1.1 gwr #include <sys/time.h> 105 1.1 gwr #include <sys/kernel.h> 106 1.1 gwr #include <sys/syslog.h> 107 1.1 gwr 108 1.1 gwr #include <dev/ic/z8530reg.h> 109 1.1 gwr #include <machine/z8530var.h> 110 1.1 gwr 111 1.5 gwr void 112 1.28 tsutsui zs_break(struct zs_chanstate *cs, int set) 113 1.1 gwr { 114 1.1 gwr 115 1.1 gwr if (set) { 116 1.1 gwr cs->cs_preg[5] |= ZSWR5_BREAK; 117 1.1 gwr cs->cs_creg[5] |= ZSWR5_BREAK; 118 1.1 gwr } else { 119 1.1 gwr cs->cs_preg[5] &= ~ZSWR5_BREAK; 120 1.1 gwr cs->cs_creg[5] &= ~ZSWR5_BREAK; 121 1.1 gwr } 122 1.2 gwr zs_write_reg(cs, 5, cs->cs_creg[5]); 123 1.1 gwr } 124 1.1 gwr 125 1.1 gwr 126 1.1 gwr /* 127 1.1 gwr * drain on-chip fifo 128 1.1 gwr */ 129 1.1 gwr void 130 1.28 tsutsui zs_iflush(struct zs_chanstate *cs) 131 1.1 gwr { 132 1.31 martin uint8_t rr0, rr1; 133 1.8 wrstuden int i; 134 1.1 gwr 135 1.8 wrstuden /* 136 1.8 wrstuden * Count how many times we loop. Some systems, such as some 137 1.8 wrstuden * Apple PowerBooks, claim to have SCC's which they really don't. 138 1.8 wrstuden */ 139 1.10 mycroft for (i = 0; i < 32; i++) { 140 1.1 gwr /* Is there input available? */ 141 1.2 gwr rr0 = zs_read_csr(cs); 142 1.1 gwr if ((rr0 & ZSRR0_RX_READY) == 0) 143 1.1 gwr break; 144 1.1 gwr 145 1.3 gwr /* 146 1.3 gwr * First read the status, because reading the data 147 1.3 gwr * destroys the status of this char. 148 1.3 gwr */ 149 1.3 gwr rr1 = zs_read_reg(cs, 1); 150 1.31 martin (void)zs_read_data(cs); 151 1.1 gwr 152 1.1 gwr if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { 153 1.1 gwr /* Clear the receive error. */ 154 1.2 gwr zs_write_csr(cs, ZSWR0_RESET_ERRORS); 155 1.1 gwr } 156 1.1 gwr } 157 1.1 gwr } 158 1.21 perry 159 1.1 gwr 160 1.1 gwr /* 161 1.1 gwr * Write the given register set to the given zs channel in the proper order. 162 1.1 gwr * The channel must not be transmitting at the time. The receiver will 163 1.1 gwr * be disabled for the time it takes to write all the registers. 164 1.1 gwr * Call this with interrupts disabled. 165 1.1 gwr */ 166 1.1 gwr void 167 1.28 tsutsui zs_loadchannelregs(struct zs_chanstate *cs) 168 1.1 gwr { 169 1.28 tsutsui uint8_t *reg, v; 170 1.1 gwr 171 1.13 wdk zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */ 172 1.1 gwr 173 1.1 gwr #if 1 174 1.1 gwr /* 175 1.1 gwr * XXX: Is this really a good idea? 176 1.1 gwr * XXX: Should go elsewhere! -gwr 177 1.1 gwr */ 178 1.1 gwr zs_iflush(cs); /* XXX */ 179 1.1 gwr #endif 180 1.13 wdk 181 1.17 ad if (cs->cs_ctl_chan != NULL) 182 1.17 ad v = ((cs->cs_ctl_chan->cs_creg[5] & (ZSWR5_RTS | ZSWR5_DTR)) != 183 1.17 ad (cs->cs_ctl_chan->cs_preg[5] & (ZSWR5_RTS | ZSWR5_DTR))); 184 1.17 ad else 185 1.17 ad v = 0; 186 1.17 ad 187 1.23 christos if (memcmp((void *)cs->cs_preg, (void *)cs->cs_creg, 16) == 0 && !v) 188 1.17 ad return; /* only change if values are different */ 189 1.13 wdk 190 1.13 wdk /* Copy "pending" regs to "current" */ 191 1.23 christos memcpy((void *)cs->cs_creg, (void *)cs->cs_preg, 16); 192 1.13 wdk reg = cs->cs_creg; /* current regs */ 193 1.1 gwr 194 1.5 gwr /* disable interrupts */ 195 1.5 gwr zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK); 196 1.5 gwr 197 1.1 gwr /* baud clock divisor, stop bits, parity */ 198 1.2 gwr zs_write_reg(cs, 4, reg[4]); 199 1.1 gwr 200 1.1 gwr /* misc. TX/RX control bits */ 201 1.2 gwr zs_write_reg(cs, 10, reg[10]); 202 1.1 gwr 203 1.1 gwr /* char size, enable (RX/TX) */ 204 1.2 gwr zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE); 205 1.2 gwr zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE); 206 1.1 gwr 207 1.5 gwr /* synchronous mode stuff */ 208 1.5 gwr zs_write_reg(cs, 6, reg[6]); 209 1.5 gwr zs_write_reg(cs, 7, reg[7]); 210 1.1 gwr 211 1.1 gwr #if 0 212 1.1 gwr /* 213 1.1 gwr * Registers 2 and 9 are special because they are 214 1.1 gwr * actually common to both channels, but must be 215 1.1 gwr * programmed through channel A. The "zsc" attach 216 1.1 gwr * function takes care of setting these registers 217 1.1 gwr * and they should not be touched thereafter. 218 1.1 gwr */ 219 1.1 gwr /* interrupt vector */ 220 1.2 gwr zs_write_reg(cs, 2, reg[2]); 221 1.1 gwr /* master interrupt control */ 222 1.2 gwr zs_write_reg(cs, 9, reg[9]); 223 1.1 gwr #endif 224 1.1 gwr 225 1.5 gwr /* Shut down the BRG */ 226 1.5 gwr zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA); 227 1.5 gwr 228 1.5 gwr #ifdef ZS_MD_SETCLK 229 1.5 gwr /* Let the MD code setup any external clock. */ 230 1.5 gwr ZS_MD_SETCLK(cs); 231 1.5 gwr #endif /* ZS_MD_SETCLK */ 232 1.5 gwr 233 1.1 gwr /* clock mode control */ 234 1.2 gwr zs_write_reg(cs, 11, reg[11]); 235 1.1 gwr 236 1.1 gwr /* baud rate (lo/hi) */ 237 1.2 gwr zs_write_reg(cs, 12, reg[12]); 238 1.2 gwr zs_write_reg(cs, 13, reg[13]); 239 1.1 gwr 240 1.1 gwr /* Misc. control bits */ 241 1.2 gwr zs_write_reg(cs, 14, reg[14]); 242 1.1 gwr 243 1.1 gwr /* which lines cause status interrupts */ 244 1.2 gwr zs_write_reg(cs, 15, reg[15]); 245 1.1 gwr 246 1.5 gwr /* 247 1.5 gwr * Zilog docs recommend resetting external status twice at this 248 1.5 gwr * point. Mainly as the status bits are latched, and the first 249 1.5 gwr * interrupt clear might unlatch them to new values, generating 250 1.5 gwr * a second interrupt request. 251 1.5 gwr */ 252 1.5 gwr zs_write_csr(cs, ZSM_RESET_STINT); 253 1.5 gwr zs_write_csr(cs, ZSM_RESET_STINT); 254 1.5 gwr 255 1.1 gwr /* char size, enable (RX/TX)*/ 256 1.2 gwr zs_write_reg(cs, 3, reg[3]); 257 1.2 gwr zs_write_reg(cs, 5, reg[5]); 258 1.17 ad 259 1.17 ad /* Write the status bits on the alternate channel also. */ 260 1.17 ad if (cs->cs_ctl_chan != NULL) { 261 1.17 ad v = cs->cs_ctl_chan->cs_preg[5]; 262 1.17 ad cs->cs_ctl_chan->cs_creg[5] = v; 263 1.17 ad zs_write_reg(cs->cs_ctl_chan, 5, v); 264 1.17 ad } 265 1.5 gwr 266 1.5 gwr /* interrupt enables: RX, TX, STATUS */ 267 1.5 gwr zs_write_reg(cs, 1, reg[1]); 268 1.1 gwr } 269 1.1 gwr 270 1.25 ad void 271 1.25 ad zs_lock_init(struct zs_chanstate *cs) 272 1.25 ad { 273 1.25 ad 274 1.27 ad mutex_init(&cs->cs_lock, MUTEX_NODEBUG, IPL_ZS); 275 1.25 ad } 276 1.1 gwr 277 1.30 mrg void 278 1.30 mrg zs_lock_chan(struct zs_chanstate *cs) 279 1.30 mrg { 280 1.30 mrg 281 1.30 mrg mutex_spin_enter(&cs->cs_lock); 282 1.30 mrg } 283 1.30 mrg 284 1.30 mrg void 285 1.30 mrg zs_unlock_chan(struct zs_chanstate *cs) 286 1.30 mrg { 287 1.30 mrg 288 1.30 mrg mutex_spin_exit(&cs->cs_lock); 289 1.30 mrg } 290 1.30 mrg 291 1.1 gwr /* 292 1.1 gwr * ZS hardware interrupt. Scan all ZS channels. NB: we know here that 293 1.1 gwr * channels are kept in (A,B) pairs. 294 1.1 gwr * 295 1.1 gwr * Do just a little, then get out; set a software interrupt if more 296 1.1 gwr * work is needed. 297 1.1 gwr * 298 1.1 gwr * We deliberately ignore the vectoring Zilog gives us, and match up 299 1.1 gwr * only the number of `reset interrupt under service' operations, not 300 1.1 gwr * the order. 301 1.1 gwr */ 302 1.1 gwr int 303 1.28 tsutsui zsc_intr_hard(void *arg) 304 1.1 gwr { 305 1.6 gwr struct zsc_softc *zsc = arg; 306 1.29 tsutsui struct zs_chanstate *cs0, *cs1; 307 1.29 tsutsui int handled; 308 1.28 tsutsui uint8_t rr3; 309 1.1 gwr 310 1.29 tsutsui handled = 0; 311 1.29 tsutsui 312 1.6 gwr /* First look at channel A. */ 313 1.29 tsutsui cs0 = zsc->zsc_cs[0]; 314 1.29 tsutsui cs1 = zsc->zsc_cs[1]; 315 1.1 gwr 316 1.6 gwr /* 317 1.29 tsutsui * We have to clear interrupt first to avoid a race condition, 318 1.29 tsutsui * but it will be done in each MD handler. 319 1.6 gwr */ 320 1.29 tsutsui for (;;) { 321 1.29 tsutsui /* Lock both channels */ 322 1.29 tsutsui mutex_spin_enter(&cs1->cs_lock); 323 1.29 tsutsui mutex_spin_enter(&cs0->cs_lock); 324 1.29 tsutsui /* Note: only channel A has an RR3 */ 325 1.29 tsutsui rr3 = zs_read_reg(cs0, 3); 326 1.29 tsutsui 327 1.29 tsutsui if ((rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT | 328 1.29 tsutsui ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) == 0) { 329 1.29 tsutsui mutex_spin_exit(&cs0->cs_lock); 330 1.29 tsutsui mutex_spin_exit(&cs1->cs_lock); 331 1.29 tsutsui break; 332 1.29 tsutsui } 333 1.29 tsutsui handled = 1; 334 1.29 tsutsui 335 1.29 tsutsui /* First look at channel A. */ 336 1.29 tsutsui if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) 337 1.29 tsutsui zs_write_csr(cs0, ZSWR0_CLR_INTR); 338 1.29 tsutsui 339 1.5 gwr if (rr3 & ZSRR3_IP_A_RX) 340 1.29 tsutsui (*cs0->cs_ops->zsop_rxint)(cs0); 341 1.5 gwr if (rr3 & ZSRR3_IP_A_STAT) 342 1.29 tsutsui (*cs0->cs_ops->zsop_stint)(cs0, 0); 343 1.5 gwr if (rr3 & ZSRR3_IP_A_TX) 344 1.29 tsutsui (*cs0->cs_ops->zsop_txint)(cs0); 345 1.29 tsutsui 346 1.29 tsutsui /* Done with channel A */ 347 1.29 tsutsui mutex_spin_exit(&cs0->cs_lock); 348 1.1 gwr 349 1.29 tsutsui /* Now look at channel B. */ 350 1.29 tsutsui if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) 351 1.29 tsutsui zs_write_csr(cs1, ZSWR0_CLR_INTR); 352 1.18 pk 353 1.6 gwr if (rr3 & ZSRR3_IP_B_RX) 354 1.29 tsutsui (*cs1->cs_ops->zsop_rxint)(cs1); 355 1.6 gwr if (rr3 & ZSRR3_IP_B_STAT) 356 1.29 tsutsui (*cs1->cs_ops->zsop_stint)(cs1, 0); 357 1.6 gwr if (rr3 & ZSRR3_IP_B_TX) 358 1.29 tsutsui (*cs1->cs_ops->zsop_txint)(cs1); 359 1.29 tsutsui 360 1.29 tsutsui mutex_spin_exit(&cs1->cs_lock); 361 1.1 gwr } 362 1.18 pk 363 1.5 gwr /* Note: caller will check cs_x->cs_softreq and DTRT. */ 364 1.29 tsutsui return handled; 365 1.1 gwr } 366 1.1 gwr 367 1.1 gwr 368 1.1 gwr /* 369 1.1 gwr * ZS software interrupt. Scan all channels for deferred interrupts. 370 1.1 gwr */ 371 1.1 gwr int 372 1.28 tsutsui zsc_intr_soft(void *arg) 373 1.1 gwr { 374 1.12 augustss struct zsc_softc *zsc = arg; 375 1.12 augustss struct zs_chanstate *cs; 376 1.12 augustss int rval, chan; 377 1.1 gwr 378 1.1 gwr rval = 0; 379 1.5 gwr for (chan = 0; chan < 2; chan++) { 380 1.5 gwr cs = zsc->zsc_cs[chan]; 381 1.1 gwr 382 1.3 gwr /* 383 1.3 gwr * The softint flag can be safely cleared once 384 1.3 gwr * we have decided to call the softint routine. 385 1.3 gwr * (No need to do splzs() first.) 386 1.3 gwr */ 387 1.3 gwr if (cs->cs_softreq) { 388 1.3 gwr cs->cs_softreq = 0; 389 1.1 gwr (*cs->cs_ops->zsop_softint)(cs); 390 1.5 gwr rval++; 391 1.1 gwr } 392 1.1 gwr } 393 1.1 gwr return (rval); 394 1.1 gwr } 395 1.1 gwr 396 1.5 gwr /* 397 1.5 gwr * Provide a null zs "ops" vector. 398 1.5 gwr */ 399 1.5 gwr 400 1.20 perry static void zsnull_rxint (struct zs_chanstate *); 401 1.20 perry static void zsnull_stint (struct zs_chanstate *, int); 402 1.20 perry static void zsnull_txint (struct zs_chanstate *); 403 1.20 perry static void zsnull_softint(struct zs_chanstate *); 404 1.1 gwr 405 1.3 gwr static void 406 1.28 tsutsui zsnull_rxint(struct zs_chanstate *cs) 407 1.11 mycroft { 408 1.28 tsutsui 409 1.11 mycroft /* Ask for softint() call. */ 410 1.11 mycroft cs->cs_softreq = 1; 411 1.11 mycroft } 412 1.11 mycroft 413 1.11 mycroft static void 414 1.28 tsutsui zsnull_stint(struct zs_chanstate *cs, int force) 415 1.11 mycroft { 416 1.28 tsutsui 417 1.11 mycroft /* Ask for softint() call. */ 418 1.11 mycroft cs->cs_softreq = 1; 419 1.11 mycroft } 420 1.11 mycroft 421 1.11 mycroft static void 422 1.28 tsutsui zsnull_txint(struct zs_chanstate *cs) 423 1.1 gwr { 424 1.28 tsutsui 425 1.5 gwr /* Ask for softint() call. */ 426 1.5 gwr cs->cs_softreq = 1; 427 1.1 gwr } 428 1.1 gwr 429 1.3 gwr static void 430 1.28 tsutsui zsnull_softint(struct zs_chanstate *cs) 431 1.1 gwr { 432 1.28 tsutsui 433 1.5 gwr zs_write_reg(cs, 1, 0); 434 1.5 gwr zs_write_reg(cs, 15, 0); 435 1.1 gwr } 436 1.1 gwr 437 1.1 gwr struct zsops zsops_null = { 438 1.11 mycroft zsnull_rxint, /* receive char available */ 439 1.11 mycroft zsnull_stint, /* external/status */ 440 1.11 mycroft zsnull_txint, /* xmit buffer empty */ 441 1.1 gwr zsnull_softint, /* process software interrupt */ 442 1.1 gwr }; 443