uart_dev_sab82532.c revision 128631
1/* 2 * Copyright (c) 2003 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 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. 14 * 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. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_sab82532.c 128631 2004-04-25 04:30:40Z marcel $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/conf.h> 34#include <machine/bus.h> 35 36#include <dev/uart/uart.h> 37#include <dev/uart/uart_cpu.h> 38#include <dev/uart/uart_bus.h> 39#include <dev/uart/uart_dev_sab82532.h> 40 41#include "uart_if.h" 42 43#define DEFAULT_RCLK 29491200 44 45/* 46 * NOTE: To allow us to read the baudrate divisor from the chip, we 47 * copy the value written to the write-only BGR register to an unused 48 * read-write register. We use TCR for that. 49 */ 50 51static int 52sab82532_delay(struct uart_bas *bas) 53{ 54 int divisor, m, n; 55 uint8_t bgr, ccr2; 56 57 bgr = uart_getreg(bas, SAB_TCR); 58 ccr2 = uart_getreg(bas, SAB_CCR2); 59 n = (bgr & 0x3f) + 1; 60 m = (bgr >> 6) | ((ccr2 >> 4) & 0xC); 61 divisor = n * (1<<m); 62 63 /* 1/10th the time to transmit 1 character (estimate). */ 64 return (16000000 * divisor / bas->rclk); 65} 66 67static int 68sab82532_divisor(int rclk, int baudrate) 69{ 70 int act_baud, act_div, divisor; 71 int error, m, n; 72 73 if (baudrate == 0) 74 return (0); 75 76 divisor = (rclk / (baudrate << 3) + 1) >> 1; 77 if (divisor < 2 || divisor >= 1048576) 78 return (0); 79 80 /* Find the best (N+1,M) pair. */ 81 for (m = 1; m < 15; m++) { 82 n = divisor / (1<<m); 83 if (n < 1 || n > 63) 84 continue; 85 act_div = n * (1<<m); 86 act_baud = rclk / (act_div << 4); 87 88 /* 10 times error in percent: */ 89 error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1; 90 91 /* 3.0% maximum error tolerance: */ 92 if (error < -30 || error > 30) 93 continue; 94 95 /* Got it. */ 96 return ((n - 1) | (m << 6)); 97 } 98 99 return (0); 100} 101 102static void 103sab82532_flush(struct uart_bas *bas, int what) 104{ 105 106 if (what & UART_FLUSH_TRANSMITTER) { 107 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 108 ; 109 uart_setreg(bas, SAB_CMDR, SAB_CMDR_XRES); 110 uart_barrier(bas); 111 } 112 if (what & UART_FLUSH_RECEIVER) { 113 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 114 ; 115 uart_setreg(bas, SAB_CMDR, SAB_CMDR_RRES); 116 uart_barrier(bas); 117 } 118} 119 120static int 121sab82532_param(struct uart_bas *bas, int baudrate, int databits, int stopbits, 122 int parity) 123{ 124 int divisor; 125 uint8_t ccr2, dafo; 126 127 if (databits >= 8) 128 dafo = SAB_DAFO_CHL_CS8; 129 else if (databits == 7) 130 dafo = SAB_DAFO_CHL_CS7; 131 else if (databits == 6) 132 dafo = SAB_DAFO_CHL_CS6; 133 else 134 dafo = SAB_DAFO_CHL_CS5; 135 if (stopbits > 1) 136 dafo |= SAB_DAFO_STOP; 137 switch (parity) { 138 case UART_PARITY_EVEN: dafo |= SAB_DAFO_PAR_EVEN; break; 139 case UART_PARITY_MARK: dafo |= SAB_DAFO_PAR_MARK; break; 140 case UART_PARITY_NONE: dafo |= SAB_DAFO_PAR_NONE; break; 141 case UART_PARITY_ODD: dafo |= SAB_DAFO_PAR_ODD; break; 142 case UART_PARITY_SPACE: dafo |= SAB_DAFO_PAR_SPACE; break; 143 default: return (EINVAL); 144 } 145 146 /* Set baudrate. */ 147 if (baudrate > 0) { 148 divisor = sab82532_divisor(bas->rclk, baudrate); 149 if (divisor == 0) 150 return (EINVAL); 151 uart_setreg(bas, SAB_BGR, divisor & 0xff); 152 uart_barrier(bas); 153 /* Allow reading the (n-1,m) tuple from the chip. */ 154 uart_setreg(bas, SAB_TCR, divisor & 0xff); 155 uart_barrier(bas); 156 ccr2 = uart_getreg(bas, SAB_CCR2); 157 ccr2 &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8); 158 ccr2 |= (divisor >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8); 159 uart_setreg(bas, SAB_CCR2, ccr2); 160 uart_barrier(bas); 161 } 162 163 uart_setreg(bas, SAB_DAFO, dafo); 164 uart_barrier(bas); 165 return (0); 166} 167 168/* 169 * Low-level UART interface. 170 */ 171static int sab82532_probe(struct uart_bas *bas); 172static void sab82532_init(struct uart_bas *bas, int, int, int, int); 173static void sab82532_term(struct uart_bas *bas); 174static void sab82532_putc(struct uart_bas *bas, int); 175static int sab82532_poll(struct uart_bas *bas); 176static int sab82532_getc(struct uart_bas *bas); 177 178struct uart_ops uart_sab82532_ops = { 179 .probe = sab82532_probe, 180 .init = sab82532_init, 181 .term = sab82532_term, 182 .putc = sab82532_putc, 183 .poll = sab82532_poll, 184 .getc = sab82532_getc, 185}; 186 187static int 188sab82532_probe(struct uart_bas *bas) 189{ 190 191 return (0); 192} 193 194static void 195sab82532_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 196 int parity) 197{ 198 uint8_t ccr0, pvr; 199 200 if (bas->rclk == 0) 201 bas->rclk = DEFAULT_RCLK; 202 203 /* 204 * Set all pins, except the DTR pins (pin 1 and 2) to be inputs. 205 * Pin 4 is magical, meaning that I don't know what it does, but 206 * it too has to be set to output. 207 */ 208 uart_setreg(bas, SAB_PCR, 209 ~(SAB_PVR_DTR_A|SAB_PVR_DTR_B|SAB_PVR_MAGIC)); 210 uart_barrier(bas); 211 /* Disable port interrupts. */ 212 uart_setreg(bas, SAB_PIM, 0xff); 213 uart_barrier(bas); 214 /* Interrupts are active low. */ 215 uart_setreg(bas, SAB_IPC, SAB_IPC_ICPL); 216 uart_barrier(bas); 217 /* Set DTR. */ 218 pvr = uart_getreg(bas, SAB_PVR); 219 switch (bas->chan) { 220 case 1: 221 pvr &= ~SAB_PVR_DTR_A; 222 break; 223 case 2: 224 pvr &= ~SAB_PVR_DTR_B; 225 break; 226 } 227 uart_setreg(bas, SAB_PVR, pvr | SAB_PVR_MAGIC); 228 uart_barrier(bas); 229 230 /* power down */ 231 uart_setreg(bas, SAB_CCR0, 0); 232 uart_barrier(bas); 233 234 /* set basic configuration */ 235 ccr0 = SAB_CCR0_MCE|SAB_CCR0_SC_NRZ|SAB_CCR0_SM_ASYNC; 236 uart_setreg(bas, SAB_CCR0, ccr0); 237 uart_barrier(bas); 238 uart_setreg(bas, SAB_CCR1, SAB_CCR1_ODS|SAB_CCR1_BCR|SAB_CCR1_CM_7); 239 uart_barrier(bas); 240 uart_setreg(bas, SAB_CCR2, SAB_CCR2_BDF|SAB_CCR2_SSEL|SAB_CCR2_TOE); 241 uart_barrier(bas); 242 uart_setreg(bas, SAB_CCR3, 0); 243 uart_barrier(bas); 244 uart_setreg(bas, SAB_CCR4, SAB_CCR4_MCK4|SAB_CCR4_EBRG|SAB_CCR4_ICD); 245 uart_barrier(bas); 246 uart_setreg(bas, SAB_MODE, SAB_MODE_FCTS|SAB_MODE_RTS|SAB_MODE_RAC); 247 uart_barrier(bas); 248 uart_setreg(bas, SAB_RFC, SAB_RFC_DPS|SAB_RFC_RFDF| 249 SAB_RFC_RFTH_32CHAR); 250 uart_barrier(bas); 251 252 sab82532_param(bas, baudrate, databits, stopbits, parity); 253 254 /* Clear interrupts. */ 255 uart_setreg(bas, SAB_IMR0, (unsigned char)~SAB_IMR0_TCD); 256 uart_setreg(bas, SAB_IMR1, 0xff); 257 uart_barrier(bas); 258 uart_getreg(bas, SAB_ISR0); 259 uart_getreg(bas, SAB_ISR1); 260 uart_barrier(bas); 261 262 sab82532_flush(bas, UART_FLUSH_TRANSMITTER|UART_FLUSH_RECEIVER); 263 264 /* Power up. */ 265 uart_setreg(bas, SAB_CCR0, ccr0|SAB_CCR0_PU); 266 uart_barrier(bas); 267} 268 269static void 270sab82532_term(struct uart_bas *bas) 271{ 272 uint8_t pvr; 273 274 pvr = uart_getreg(bas, SAB_PVR); 275 switch (bas->chan) { 276 case 1: 277 pvr |= SAB_PVR_DTR_A; 278 break; 279 case 2: 280 pvr |= SAB_PVR_DTR_B; 281 break; 282 } 283 uart_setreg(bas, SAB_PVR, pvr); 284 uart_barrier(bas); 285} 286 287static void 288sab82532_putc(struct uart_bas *bas, int c) 289{ 290 int delay, limit; 291 292 /* 1/10th the time to transmit 1 character (estimate). */ 293 delay = sab82532_delay(bas); 294 295 limit = 20; 296 while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit) 297 DELAY(delay); 298 uart_setreg(bas, SAB_TIC, c); 299 limit = 20; 300 while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit) 301 DELAY(delay); 302} 303 304static int 305sab82532_poll(struct uart_bas *bas) 306{ 307 308 if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) 309 return (sab82532_getc(bas)); 310 return (-1); 311} 312 313static int 314sab82532_getc(struct uart_bas *bas) 315{ 316 int c, delay; 317 318 /* 1/10th the time to transmit 1 character (estimate). */ 319 delay = sab82532_delay(bas); 320 321 while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)) 322 DELAY(delay); 323 324 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 325 ; 326 uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); 327 uart_barrier(bas); 328 329 while (!(uart_getreg(bas, SAB_ISR0) & SAB_ISR0_TCD)) 330 DELAY(delay); 331 332 c = uart_getreg(bas, SAB_RFIFO); 333 uart_barrier(bas); 334 335 /* Blow away everything left in the FIFO... */ 336 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 337 ; 338 uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); 339 uart_barrier(bas); 340 return (c); 341} 342 343/* 344 * High-level UART interface. 345 */ 346struct sab82532_softc { 347 struct uart_softc base; 348}; 349 350static int sab82532_bus_attach(struct uart_softc *); 351static int sab82532_bus_detach(struct uart_softc *); 352static int sab82532_bus_flush(struct uart_softc *, int); 353static int sab82532_bus_getsig(struct uart_softc *); 354static int sab82532_bus_ioctl(struct uart_softc *, int, intptr_t); 355static int sab82532_bus_ipend(struct uart_softc *); 356static int sab82532_bus_param(struct uart_softc *, int, int, int, int); 357static int sab82532_bus_probe(struct uart_softc *); 358static int sab82532_bus_receive(struct uart_softc *); 359static int sab82532_bus_setsig(struct uart_softc *, int); 360static int sab82532_bus_transmit(struct uart_softc *); 361 362static kobj_method_t sab82532_methods[] = { 363 KOBJMETHOD(uart_attach, sab82532_bus_attach), 364 KOBJMETHOD(uart_detach, sab82532_bus_detach), 365 KOBJMETHOD(uart_flush, sab82532_bus_flush), 366 KOBJMETHOD(uart_getsig, sab82532_bus_getsig), 367 KOBJMETHOD(uart_ioctl, sab82532_bus_ioctl), 368 KOBJMETHOD(uart_ipend, sab82532_bus_ipend), 369 KOBJMETHOD(uart_param, sab82532_bus_param), 370 KOBJMETHOD(uart_probe, sab82532_bus_probe), 371 KOBJMETHOD(uart_receive, sab82532_bus_receive), 372 KOBJMETHOD(uart_setsig, sab82532_bus_setsig), 373 KOBJMETHOD(uart_transmit, sab82532_bus_transmit), 374 { 0, 0 } 375}; 376 377struct uart_class uart_sab82532_class = { 378 "sab82532 class", 379 sab82532_methods, 380 sizeof(struct sab82532_softc), 381 .uc_range = 64, 382 .uc_rclk = DEFAULT_RCLK 383}; 384 385#define SIGCHG(c, i, s, d) \ 386 if (c) { \ 387 i |= (i & s) ? s : s | d; \ 388 } else { \ 389 i = (i & s) ? (i & ~s) | d : i; \ 390 } 391 392static int 393sab82532_bus_attach(struct uart_softc *sc) 394{ 395 struct uart_bas *bas; 396 uint8_t imr0, imr1; 397 398 bas = &sc->sc_bas; 399 if (sc->sc_sysdev == NULL) 400 sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE); 401 402 sc->sc_rxfifosz = 32; 403 sc->sc_txfifosz = 32; 404 405 imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO| 406 SAB_IMR0_RPF; 407 uart_setreg(bas, SAB_IMR0, 0xff & ~imr0); 408 imr1 = SAB_IMR1_BRKT|SAB_IMR1_ALLS|SAB_IMR1_CSC; 409 uart_setreg(bas, SAB_IMR1, 0xff & ~imr1); 410 uart_barrier(bas); 411 412 if (sc->sc_sysdev == NULL) 413 sab82532_bus_setsig(sc, UART_SIG_DDTR|UART_SIG_DRTS); 414 (void)sab82532_bus_getsig(sc); 415 return (0); 416} 417 418static int 419sab82532_bus_detach(struct uart_softc *sc) 420{ 421 struct uart_bas *bas; 422 423 bas = &sc->sc_bas; 424 uart_setreg(bas, SAB_IMR0, 0xff); 425 uart_setreg(bas, SAB_IMR1, 0xff); 426 uart_barrier(bas); 427 uart_getreg(bas, SAB_ISR0); 428 uart_getreg(bas, SAB_ISR1); 429 uart_barrier(bas); 430 uart_setreg(bas, SAB_CCR0, 0); 431 uart_barrier(bas); 432 return (0); 433} 434 435static int 436sab82532_bus_flush(struct uart_softc *sc, int what) 437{ 438 439 mtx_lock_spin(&sc->sc_hwmtx); 440 sab82532_flush(&sc->sc_bas, what); 441 mtx_unlock_spin(&sc->sc_hwmtx); 442 return (0); 443} 444 445static int 446sab82532_bus_getsig(struct uart_softc *sc) 447{ 448 struct uart_bas *bas; 449 uint32_t new, old, sig; 450 uint8_t pvr, star, vstr; 451 452 bas = &sc->sc_bas; 453 do { 454 old = sc->sc_hwsig; 455 sig = old; 456 mtx_lock_spin(&sc->sc_hwmtx); 457 star = uart_getreg(bas, SAB_STAR); 458 SIGCHG(star & SAB_STAR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS); 459 vstr = uart_getreg(bas, SAB_VSTR); 460 SIGCHG(vstr & SAB_VSTR_CD, sig, UART_SIG_DCD, UART_SIG_DDCD); 461 pvr = uart_getreg(bas, SAB_PVR); 462 switch (bas->chan) { 463 case 1: 464 pvr &= SAB_PVR_DSR_A; 465 break; 466 case 2: 467 pvr &= SAB_PVR_DSR_B; 468 break; 469 } 470 SIGCHG(~pvr, sig, UART_SIG_DSR, UART_SIG_DDSR); 471 mtx_unlock_spin(&sc->sc_hwmtx); 472 new = sig & ~UART_SIGMASK_DELTA; 473 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 474 return (sig); 475} 476 477static int 478sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 479{ 480 struct uart_bas *bas; 481 uint8_t dafo, mode; 482 int error; 483 484 bas = &sc->sc_bas; 485 error = 0; 486 mtx_lock_spin(&sc->sc_hwmtx); 487 switch (request) { 488 case UART_IOCTL_BREAK: 489 dafo = uart_getreg(bas, SAB_DAFO); 490 if (data) 491 dafo |= SAB_DAFO_XBRK; 492 else 493 dafo &= ~SAB_DAFO_XBRK; 494 uart_setreg(bas, SAB_DAFO, dafo); 495 uart_barrier(bas); 496 break; 497 case UART_IOCTL_IFLOW: 498 mode = uart_getreg(bas, SAB_MODE); 499 if (data) { 500 mode &= ~SAB_MODE_RTS; 501 mode |= SAB_MODE_FRTS; 502 } else { 503 mode |= SAB_MODE_RTS; 504 mode &= ~SAB_MODE_FRTS; 505 } 506 uart_setreg(bas, SAB_MODE, mode); 507 uart_barrier(bas); 508 break; 509 case UART_IOCTL_OFLOW: 510 mode = uart_getreg(bas, SAB_MODE); 511 if (data) 512 mode &= ~SAB_MODE_FCTS; 513 else 514 mode |= SAB_MODE_FCTS; 515 uart_setreg(bas, SAB_MODE, mode); 516 uart_barrier(bas); 517 break; 518 default: 519 error = EINVAL; 520 break; 521 } 522 mtx_unlock_spin(&sc->sc_hwmtx); 523 return (error); 524} 525 526static int 527sab82532_bus_ipend(struct uart_softc *sc) 528{ 529 struct uart_bas *bas; 530 int ipend; 531 uint8_t isr0, isr1; 532 533 bas = &sc->sc_bas; 534 mtx_lock_spin(&sc->sc_hwmtx); 535 isr0 = uart_getreg(bas, SAB_ISR0); 536 isr1 = uart_getreg(bas, SAB_ISR1); 537 uart_barrier(bas); 538 if (isr0 & SAB_ISR0_TIME) { 539 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 540 ; 541 uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); 542 uart_barrier(bas); 543 } 544 mtx_unlock_spin(&sc->sc_hwmtx); 545 546 ipend = 0; 547 if (isr1 & SAB_ISR1_BRKT) 548 ipend |= UART_IPEND_BREAK; 549 if (isr0 & SAB_ISR0_RFO) 550 ipend |= UART_IPEND_OVERRUN; 551 if (isr0 & (SAB_ISR0_TCD|SAB_ISR0_RPF)) 552 ipend |= UART_IPEND_RXREADY; 553 if ((isr0 & SAB_ISR0_CDSC) || (isr1 & SAB_ISR1_CSC)) 554 ipend |= UART_IPEND_SIGCHG; 555 if (isr1 & SAB_ISR1_ALLS) 556 ipend |= UART_IPEND_TXIDLE; 557 558 return (ipend); 559} 560 561static int 562sab82532_bus_param(struct uart_softc *sc, int baudrate, int databits, 563 int stopbits, int parity) 564{ 565 struct uart_bas *bas; 566 int error; 567 568 bas = &sc->sc_bas; 569 mtx_lock_spin(&sc->sc_hwmtx); 570 error = sab82532_param(bas, baudrate, databits, stopbits, parity); 571 mtx_unlock_spin(&sc->sc_hwmtx); 572 return (error); 573} 574 575static int 576sab82532_bus_probe(struct uart_softc *sc) 577{ 578 char buf[80]; 579 const char *vstr; 580 int error; 581 char ch; 582 583 error = sab82532_probe(&sc->sc_bas); 584 if (error) 585 return (error); 586 587 ch = sc->sc_bas.chan - 1 + 'A'; 588 589 switch (uart_getreg(&sc->sc_bas, SAB_VSTR) & SAB_VSTR_VMASK) { 590 case SAB_VSTR_V_1: 591 vstr = "v1"; 592 break; 593 case SAB_VSTR_V_2: 594 vstr = "v2"; 595 break; 596 case SAB_VSTR_V_32: 597 vstr = "v3.2"; 598 sc->sc_hwiflow = 0; /* CTS doesn't work with RFC:RFDF. */ 599 sc->sc_hwoflow = 1; 600 break; 601 default: 602 vstr = "v4?"; 603 break; 604 } 605 606 snprintf(buf, sizeof(buf), "SAB 82532 %s, channel %c", vstr, ch); 607 device_set_desc_copy(sc->sc_dev, buf); 608 return (0); 609} 610 611static int 612sab82532_bus_receive(struct uart_softc *sc) 613{ 614 struct uart_bas *bas; 615 int i, rbcl, xc; 616 uint8_t s; 617 618 bas = &sc->sc_bas; 619 mtx_lock_spin(&sc->sc_hwmtx); 620 if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) { 621 rbcl = uart_getreg(bas, SAB_RBCL) & 31; 622 if (rbcl == 0) 623 rbcl = 32; 624 for (i = 0; i < rbcl; i += 2) { 625 if (uart_rx_full(sc)) { 626 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 627 break; 628 } 629 xc = uart_getreg(bas, SAB_RFIFO); 630 s = uart_getreg(bas, SAB_RFIFO + 1); 631 if (s & SAB_RSTAT_FE) 632 xc |= UART_STAT_FRAMERR; 633 if (s & SAB_RSTAT_PE) 634 xc |= UART_STAT_PARERR; 635 uart_rx_put(sc, xc); 636 } 637 } 638 639 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 640 ; 641 uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); 642 uart_barrier(bas); 643 mtx_unlock_spin(&sc->sc_hwmtx); 644 return (0); 645} 646 647static int 648sab82532_bus_setsig(struct uart_softc *sc, int sig) 649{ 650 struct uart_bas *bas; 651 uint32_t new, old; 652 uint8_t mode, pvr; 653 654 bas = &sc->sc_bas; 655 do { 656 old = sc->sc_hwsig; 657 new = old; 658 if (sig & UART_SIG_DDTR) { 659 SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR, 660 UART_SIG_DDTR); 661 } 662 if (sig & UART_SIG_DRTS) { 663 SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS, 664 UART_SIG_DRTS); 665 } 666 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 667 668 mtx_lock_spin(&sc->sc_hwmtx); 669 /* Set DTR pin. */ 670 pvr = uart_getreg(bas, SAB_PVR); 671 switch (bas->chan) { 672 case 1: 673 if (new & UART_SIG_DTR) 674 pvr &= ~SAB_PVR_DTR_A; 675 else 676 pvr |= SAB_PVR_DTR_A; 677 break; 678 case 2: 679 if (new & UART_SIG_DTR) 680 pvr &= ~SAB_PVR_DTR_B; 681 else 682 pvr |= SAB_PVR_DTR_B; 683 break; 684 } 685 uart_setreg(bas, SAB_PVR, pvr); 686 687 /* Set RTS pin. */ 688 mode = uart_getreg(bas, SAB_MODE); 689 if (new & UART_SIG_RTS) 690 mode &= ~SAB_MODE_FRTS; 691 else 692 mode |= SAB_MODE_FRTS; 693 uart_setreg(bas, SAB_MODE, mode); 694 uart_barrier(bas); 695 mtx_unlock_spin(&sc->sc_hwmtx); 696 return (0); 697} 698 699static int 700sab82532_bus_transmit(struct uart_softc *sc) 701{ 702 struct uart_bas *bas; 703 int i; 704 705 bas = &sc->sc_bas; 706 mtx_lock_spin(&sc->sc_hwmtx); 707 while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_XFW)) 708 ; 709 for (i = 0; i < sc->sc_txdatasz; i++) 710 uart_setreg(bas, SAB_XFIFO + i, sc->sc_txbuf[i]); 711 uart_barrier(bas); 712 while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC) 713 ; 714 uart_setreg(bas, SAB_CMDR, SAB_CMDR_XF); 715 sc->sc_txbusy = 1; 716 mtx_unlock_spin(&sc->sc_hwmtx); 717 return (0); 718} 719