1139749Simp/*- 2119815Smarcel * Copyright (c) 2003 Marcel Moolenaar 3119815Smarcel * All rights reserved. 4119815Smarcel * 5119815Smarcel * Redistribution and use in source and binary forms, with or without 6119815Smarcel * modification, are permitted provided that the following conditions 7119815Smarcel * are met: 8119815Smarcel * 9119815Smarcel * 1. Redistributions of source code must retain the above copyright 10119815Smarcel * notice, this list of conditions and the following disclaimer. 11119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12119815Smarcel * notice, this list of conditions and the following disclaimer in the 13119815Smarcel * documentation and/or other materials provided with the distribution. 14119815Smarcel * 15119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18119815Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19119815Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20119815Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21119815Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22119815Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23119815Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24119815Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25119815Smarcel * 26119815Smarcel * $FreeBSD$ 27119815Smarcel */ 28119815Smarcel 29119815Smarcel#ifndef _DEV_UART_BUS_H_ 30119815Smarcel#define _DEV_UART_BUS_H_ 31119815Smarcel 32119996Smarcel#ifndef KLD_MODULE 33119996Smarcel#include "opt_uart.h" 34119996Smarcel#endif 35119996Smarcel 36131043Sphk#include <sys/serial.h> 37119996Smarcel#include <sys/timepps.h> 38119996Smarcel 39119815Smarcel/* Drain and flush targets. */ 40119815Smarcel#define UART_DRAIN_RECEIVER 0x0001 41119815Smarcel#define UART_DRAIN_TRANSMITTER 0x0002 42119815Smarcel#define UART_FLUSH_RECEIVER UART_DRAIN_RECEIVER 43119815Smarcel#define UART_FLUSH_TRANSMITTER UART_DRAIN_TRANSMITTER 44119815Smarcel 45119815Smarcel/* Received character status bits. */ 46119815Smarcel#define UART_STAT_BREAK 0x0100 47119815Smarcel#define UART_STAT_FRAMERR 0x0200 48119815Smarcel#define UART_STAT_OVERRUN 0x0400 49119815Smarcel#define UART_STAT_PARERR 0x0800 50119815Smarcel 51119815Smarcel/* UART_IOCTL() requests */ 52119815Smarcel#define UART_IOCTL_BREAK 1 53119815Smarcel#define UART_IOCTL_IFLOW 2 54119815Smarcel#define UART_IOCTL_OFLOW 3 55137706Smarcel#define UART_IOCTL_BAUD 4 56119815Smarcel 57119815Smarcel/* 58119815Smarcel * UART class & instance (=softc) 59119815Smarcel */ 60119815Smarcelstruct uart_class { 61119815Smarcel KOBJ_CLASS_FIELDS; 62168281Smarcel struct uart_ops *uc_ops; /* Low-level console operations. */ 63119815Smarcel u_int uc_range; /* Bus space address range. */ 64119815Smarcel u_int uc_rclk; /* Default rclk for this device. */ 65119815Smarcel}; 66119815Smarcel 67119815Smarcelstruct uart_softc { 68119815Smarcel KOBJ_FIELDS; 69119815Smarcel struct uart_class *sc_class; 70119815Smarcel struct uart_bas sc_bas; 71119815Smarcel device_t sc_dev; 72119815Smarcel 73157300Smarcel struct mtx sc_hwmtx_s; /* Spinlock protecting hardware. */ 74157300Smarcel struct mtx *sc_hwmtx; 75120143Smarcel 76119815Smarcel struct resource *sc_rres; /* Register resource. */ 77119815Smarcel int sc_rrid; 78119815Smarcel int sc_rtype; /* SYS_RES_{IOPORT|MEMORY}. */ 79119815Smarcel struct resource *sc_ires; /* Interrupt resource. */ 80119815Smarcel void *sc_icookie; 81119815Smarcel int sc_irid; 82234194Sgrehan struct callout sc_timer; 83119815Smarcel 84119815Smarcel int sc_callout:1; /* This UART is opened for callout. */ 85119815Smarcel int sc_fastintr:1; /* This UART uses fast interrupts. */ 86119815Smarcel int sc_hwiflow:1; /* This UART has HW input flow ctl. */ 87119815Smarcel int sc_hwoflow:1; /* This UART has HW output flow ctl. */ 88119815Smarcel int sc_leaving:1; /* This UART is going away. */ 89119815Smarcel int sc_opened:1; /* This UART is open for business. */ 90119815Smarcel int sc_polled:1; /* This UART has no interrupts. */ 91119815Smarcel int sc_txbusy:1; /* This UART is transmitting. */ 92197721Smarcel int sc_isquelch:1; /* This UART has input squelched. */ 93286059Smarius int sc_testintr:1; /* This UART is under int. testing. */ 94119815Smarcel 95119815Smarcel struct uart_devinfo *sc_sysdev; /* System device (or NULL). */ 96119815Smarcel 97119815Smarcel int sc_altbrk; /* State for alt break sequence. */ 98119815Smarcel uint32_t sc_hwsig; /* Signal state. Used by HW driver. */ 99119815Smarcel 100119815Smarcel /* Receiver data. */ 101119815Smarcel uint16_t *sc_rxbuf; 102119815Smarcel int sc_rxbufsz; 103119815Smarcel int sc_rxput; 104119815Smarcel int sc_rxget; 105119815Smarcel int sc_rxfifosz; /* Size of RX FIFO. */ 106119815Smarcel 107119815Smarcel /* Transmitter data. */ 108119815Smarcel uint8_t *sc_txbuf; 109119815Smarcel int sc_txdatasz; 110119815Smarcel int sc_txfifosz; /* Size of TX FIFO and buffer. */ 111119815Smarcel 112119996Smarcel /* Pulse capturing support (PPS). */ 113119996Smarcel struct pps_state sc_pps; 114287037Sian int sc_pps_mode; 115294229Sian sbintime_t sc_pps_captime; 116119996Smarcel 117119815Smarcel /* Upper layer data. */ 118119815Smarcel void *sc_softih; 119119815Smarcel uint32_t sc_ttypend; 120119815Smarcel union { 121119815Smarcel /* TTY specific data. */ 122119815Smarcel struct { 123119815Smarcel struct tty *tp; 124119815Smarcel } u_tty; 125119815Smarcel /* Keyboard specific data. */ 126119815Smarcel struct { 127119815Smarcel } u_kbd; 128119815Smarcel } sc_u; 129119815Smarcel}; 130119815Smarcel 131119815Smarcelextern devclass_t uart_devclass; 132286059Smariusextern const char uart_driver_name[]; 133119815Smarcel 134119815Smarcelint uart_bus_attach(device_t dev); 135119815Smarcelint uart_bus_detach(device_t dev); 136246243Savgint uart_bus_resume(device_t dev); 137157300Smarcelserdev_intr_t *uart_bus_ihand(device_t dev, int ipend); 138158119Smarcelint uart_bus_ipend(device_t dev); 139120452Smarcelint uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan); 140157300Smarcelint uart_bus_sysdev(device_t dev); 141119815Smarcel 142197721Smarcelvoid uart_sched_softih(struct uart_softc *, uint32_t); 143197721Smarcel 144119815Smarcelint uart_tty_attach(struct uart_softc *); 145119815Smarcelint uart_tty_detach(struct uart_softc *); 146287037Sianstruct mtx *uart_tty_getlock(struct uart_softc *); 147119815Smarcelvoid uart_tty_intr(void *arg); 148119815Smarcel 149119815Smarcel/* 150119815Smarcel * Receive buffer operations. 151119815Smarcel */ 152119815Smarcelstatic __inline int 153119815Smarceluart_rx_empty(struct uart_softc *sc) 154119815Smarcel{ 155286059Smarius 156119815Smarcel return ((sc->sc_rxget == sc->sc_rxput) ? 1 : 0); 157119815Smarcel} 158119815Smarcel 159119815Smarcelstatic __inline int 160119815Smarceluart_rx_full(struct uart_softc *sc) 161119815Smarcel{ 162286059Smarius 163286059Smarius return ((sc->sc_rxput + 1 < sc->sc_rxbufsz) ? 164286059Smarius (sc->sc_rxput + 1 == sc->sc_rxget) : (sc->sc_rxget == 0)); 165119815Smarcel} 166119815Smarcel 167119815Smarcelstatic __inline int 168119815Smarceluart_rx_get(struct uart_softc *sc) 169119815Smarcel{ 170119815Smarcel int ptr, xc; 171119815Smarcel 172119815Smarcel ptr = sc->sc_rxget; 173119815Smarcel if (ptr == sc->sc_rxput) 174119815Smarcel return (-1); 175119815Smarcel xc = sc->sc_rxbuf[ptr++]; 176119815Smarcel sc->sc_rxget = (ptr < sc->sc_rxbufsz) ? ptr : 0; 177119815Smarcel return (xc); 178119815Smarcel} 179119815Smarcel 180119815Smarcelstatic __inline int 181197721Smarceluart_rx_next(struct uart_softc *sc) 182197721Smarcel{ 183197721Smarcel int ptr; 184197721Smarcel 185197721Smarcel ptr = sc->sc_rxget; 186197721Smarcel if (ptr == sc->sc_rxput) 187197721Smarcel return (-1); 188197721Smarcel ptr += 1; 189197721Smarcel sc->sc_rxget = (ptr < sc->sc_rxbufsz) ? ptr : 0; 190197721Smarcel return (0); 191197721Smarcel} 192197721Smarcel 193197721Smarcelstatic __inline int 194197721Smarceluart_rx_peek(struct uart_softc *sc) 195197721Smarcel{ 196197721Smarcel int ptr; 197197721Smarcel 198197721Smarcel ptr = sc->sc_rxget; 199197721Smarcel return ((ptr == sc->sc_rxput) ? -1 : sc->sc_rxbuf[ptr]); 200197721Smarcel} 201197721Smarcel 202197721Smarcelstatic __inline int 203119815Smarceluart_rx_put(struct uart_softc *sc, int xc) 204119815Smarcel{ 205119815Smarcel int ptr; 206119815Smarcel 207119815Smarcel ptr = (sc->sc_rxput + 1 < sc->sc_rxbufsz) ? sc->sc_rxput + 1 : 0; 208119815Smarcel if (ptr == sc->sc_rxget) 209119815Smarcel return (ENOSPC); 210119815Smarcel sc->sc_rxbuf[sc->sc_rxput] = xc; 211119815Smarcel sc->sc_rxput = ptr; 212119815Smarcel return (0); 213119815Smarcel} 214119815Smarcel 215119815Smarcel#endif /* _DEV_UART_BUS_H_ */ 216