PERFORCE change 37285 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sun Aug 31 15:52:50 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=37285
Change 37285 by marcel at 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);
}
More information about the p4-projects
mailing list