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$");
   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 
   51 static int
   52 sab82532_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 
   67 static int
   68 sab82532_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 
  102 static void
  103 sab82532_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 
  120 static int
  121 sab82532_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  */
  171 static int sab82532_probe(struct uart_bas *bas);
  172 static void sab82532_init(struct uart_bas *bas, int, int, int, int);
  173 static void sab82532_term(struct uart_bas *bas);
  174 static void sab82532_putc(struct uart_bas *bas, int);
  175 static int sab82532_poll(struct uart_bas *bas);
  176 static int sab82532_getc(struct uart_bas *bas);
  177 
  178 struct 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 
  187 static int
  188 sab82532_probe(struct uart_bas *bas)
  189 {
  190 
  191         return (0);
  192 }
  193 
  194 static void
  195 sab82532_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 
  269 static void
  270 sab82532_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 
  287 static void
  288 sab82532_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 
  304 static int
  305 sab82532_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 
  313 static int
  314 sab82532_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  */
  346 struct sab82532_softc {
  347         struct uart_softc base;
  348 };
  349 
  350 static int sab82532_bus_attach(struct uart_softc *);
  351 static int sab82532_bus_detach(struct uart_softc *);
  352 static int sab82532_bus_flush(struct uart_softc *, int);
  353 static int sab82532_bus_getsig(struct uart_softc *);
  354 static int sab82532_bus_ioctl(struct uart_softc *, int, intptr_t);
  355 static int sab82532_bus_ipend(struct uart_softc *);
  356 static int sab82532_bus_param(struct uart_softc *, int, int, int, int);
  357 static int sab82532_bus_probe(struct uart_softc *);
  358 static int sab82532_bus_receive(struct uart_softc *);
  359 static int sab82532_bus_setsig(struct uart_softc *, int);
  360 static int sab82532_bus_transmit(struct uart_softc *);
  361 
  362 static 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 
  377 struct 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 
  392 static int
  393 sab82532_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, SER_DDTR|SER_DRTS);
  414         (void)sab82532_bus_getsig(sc);
  415         return (0);
  416 }
  417 
  418 static int
  419 sab82532_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 
  435 static int
  436 sab82532_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 
  445 static int
  446 sab82532_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, SER_CTS, SER_DCTS);
  459                 vstr = uart_getreg(bas, SAB_VSTR);
  460                 SIGCHG(vstr & SAB_VSTR_CD, sig, SER_DCD, SER_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, SER_DSR, SER_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 
  477 static int
  478 sab82532_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 
  526 static int
  527 sab82532_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 
  561 static int
  562 sab82532_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 
  575 static int
  576 sab82532_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 
  611 static int
  612 sab82532_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 
  647 static int
  648 sab82532_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 & SER_DDTR) {
  659                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  660                             SER_DDTR);
  661                 }
  662                 if (sig & SER_DRTS) {
  663                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  664                             SER_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 & SER_DTR)
  674                         pvr &= ~SAB_PVR_DTR_A;
  675                 else
  676                         pvr |= SAB_PVR_DTR_A;
  677                 break;
  678         case 2:
  679                 if (new & SER_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 & SER_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 
  699 static int
  700 sab82532_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 }

Cache object: f622443b8addf947cacb9c8ea52a080a


[ 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.