The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/uart/uart_dev_sab82532.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b42734fa3e71f792ab9649d23842b688


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.