From owner-p4-projects@FreeBSD.ORG Sun Aug 31 15:52:50 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0C35416A4C1; Sun, 31 Aug 2003 15:52:50 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C396C16A4BF for ; Sun, 31 Aug 2003 15:52:49 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 366A843FD7 for ; Sun, 31 Aug 2003 15:52:49 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h7VMqm0U087050 for ; Sun, 31 Aug 2003 15:52:48 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7VMqmSx087047 for perforce@freebsd.org; Sun, 31 Aug 2003 15:52:48 -0700 (PDT) Date: Sun, 31 Aug 2003 15:52:48 -0700 (PDT) Message-Id: <200308312252.h7VMqmSx087047@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 37285 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Aug 2003 22:52:50 -0000 http://perforce.freebsd.org/chv.cgi?CH=37285 Change 37285 by marcel@marcel_nfs on 2003/08/31 15:52:17 Implement UART_GETSIG and UART_SETSIG. This was not so trivial, because we cannot set/clear DTR or RTS without knowing what the correct value of WR5 (=TPC) is. So, we keep an image of that register in the softc. For system devices we luckily have all the line settings to reconstruct the image. Pheeuw, Unfortunately, getty(8) doesn't give me a prompt yet. Maybe some signals need to be inverted... Affected files ... .. //depot/projects/uart/dev/uart/uart_dev_z8530.c#8 edit Differences ... ==== //depot/projects/uart/dev/uart/uart_dev_z8530.c#8 (text+ko) ==== @@ -89,14 +89,14 @@ static int z8530_param(struct uart_bas *bas, int baudrate, int databits, int stopbits, - int parity, int tpc) + int parity, uint8_t *tpcp) { int divisor; - uint8_t rpc, mpm; + uint8_t mpm, rpc, tpc; rpc = RPC_RXE; mpm = MPM_CM16; - tpc = TPC_TXE | (tpc & (TPC_DTR | TPC_RTS)); + tpc = TPC_TXE | (*tpcp & (TPC_DTR | TPC_RTS)); if (databits >= 8) { rpc |= RPC_RB8; @@ -136,9 +136,36 @@ uart_barrier(bas); uart_setmreg(bas, WR_TPC, tpc); uart_barrier(bas); + *tpcp = tpc; return (0); } +static int +z8530_setup(struct uart_bas *bas, int baudrate, int databits, int stopbits, + int parity) +{ + uint8_t tpc; + + if (bas->rclk == 0) + bas->rclk = DEFAULT_RCLK; + + /* Assume we don't need to perform a full hardware reset. */ + uart_setmreg(bas, WR_MIC, ((IS_CHANNEL_A(bas)) ? MIC_CRA : MIC_CRB) | + MIC_MIE | MIC_NV); + uart_barrier(bas); + /* Set clock sources and enable BRG. */ + uart_setmreg(bas, WR_CMC, CMC_RC_BRG | CMC_TC_BRG); + uart_setmreg(bas, WR_MCB2, MCB2_PCLK | MCB2_BRGE); + uart_barrier(bas); + /* Set data encoding. */ + uart_setmreg(bas, WR_MCB1, MCB1_NRZ); + uart_barrier(bas); + + tpc = TPC_DTR | TPC_RTS; + z8530_param(bas, baudrate, databits, stopbits, parity, &tpc); + return (int)tpc; +} + /* * Low-level UART interface. */ @@ -170,23 +197,7 @@ int parity) { - if (bas->rclk == 0) - bas->rclk = DEFAULT_RCLK; - - /* Assume we don't need to perform a full hardware reset. */ - uart_setmreg(bas, WR_MIC, ((IS_CHANNEL_A(bas)) ? MIC_CRA : MIC_CRB) | - MIC_MIE | MIC_NV); - uart_barrier(bas); - /* Set clock sources and enable BRG. */ - uart_setmreg(bas, WR_CMC, CMC_RC_BRG | CMC_TC_BRG); - uart_setmreg(bas, WR_MCB2, MCB2_PCLK | MCB2_BRGE); - uart_barrier(bas); - /* Set data encoding. */ - uart_setmreg(bas, WR_MCB1, MCB1_NRZ); - uart_barrier(bas); - - z8530_param(bas, baudrate, databits, stopbits, parity, - TPC_DTR | TPC_RTS); + z8530_setup(bas, baudrate, databits, stopbits, parity); } static void @@ -227,6 +238,7 @@ */ struct z8530_softc { struct uart_softc base; + uint8_t tpc; }; static int z8530_bus_attach(struct uart_softc *); @@ -272,19 +284,32 @@ static int z8530_bus_attach(struct uart_softc *sc) { + struct z8530_softc *z8530 = (struct z8530_softc*)sc; struct uart_bas *bas; + struct uart_devinfo *di; bas = &sc->sc_bas; - if (sc->sc_sysdev == NULL) - z8530_init(bas, 9600, 8, 1, UART_PARITY_NONE); + if (sc->sc_sysdev != NULL) { + di = sc->sc_sysdev; + z8530->tpc = TPC_DTR|TPC_RTS; + z8530_param(bas, di->baudrate, di->databits, di->stopbits, + di->parity, &z8530->tpc); + } else { + z8530->tpc = z8530_setup(bas, 9600, 8, 1, UART_PARITY_NONE); + z8530->tpc &= ~(TPC_DTR|TPC_RTS); + } sc->sc_rxfifosz = 1; sc->sc_txfifosz = 1; uart_setmreg(bas, WR_IC, IC_BRK | IC_CTS | IC_DCD); + uart_barrier(bas); uart_setmreg(bas, WR_IDT, IDT_TIE | IDT_RIA); + uart_barrier(bas); uart_setmreg(bas, WR_IV, 0); uart_barrier(bas); + uart_setmreg(bas, WR_TPC, z8530->tpc); + uart_barrier(bas); return (0); } @@ -305,8 +330,15 @@ static int z8530_bus_getsig(struct uart_softc *sc) { + int sig; + uint8_t bes; - return (0); + sig = sc->sc_hwsig; + bes = uart_getmreg(&sc->sc_bas, RR_BES); + SIGCHG(bes & BES_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS); + SIGCHG(bes & BES_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD); + sc->sc_hwsig = sig & ~UART_SIGMASK_DELTA; + return (sig); } static int @@ -347,10 +379,12 @@ z8530_bus_param(struct uart_softc *sc, int baudrate, int databits, int stopbits, int parity) { - struct uart_bas *bas; + struct z8530_softc *z8530 = (struct z8530_softc*)sc; + int error; - bas = &sc->sc_bas; - return (z8530_param(bas, baudrate, databits, stopbits, parity, 0)); + error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity, + &z8530->tpc); + return (error); } static int @@ -382,7 +416,34 @@ static int z8530_bus_setsig(struct uart_softc *sc, int sig) { + struct z8530_softc *z8530 = (struct z8530_softc*)sc; + struct uart_bas *bas; + bas = &sc->sc_bas; + if (sig & UART_SIG_DDTR) { + SIGCHG(sig & UART_SIG_DTR, sc->sc_hwsig, UART_SIG_DTR, + UART_SIG_DDTR); + } + if (sig & UART_SIG_DRTS) { + SIGCHG(sig & UART_SIG_RTS, sc->sc_hwsig, UART_SIG_RTS, + UART_SIG_DRTS); + } + if (sc->sc_hwsig & UART_SIG_DTR) + z8530->tpc |= TPC_DTR; + else + z8530->tpc &= ~TPC_DTR; + if (sc->sc_hwsig & UART_SIG_RTS) + z8530->tpc |= TPC_RTS; + else + z8530->tpc &= ~TPC_RTS; + if (sig & UART_SIG_DBREAK) { + if (sig & UART_SIG_BREAK) + z8530->tpc |= TPC_BRK; + else + z8530->tpc &= ~TPC_BRK; + } + uart_setmreg(bas, WR_TPC, z8530->tpc); + uart_barrier(bas); return (0); }