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