diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-05-09 15:25:30 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-05-09 15:25:30 +0000 |
commit | 9a6a9f058b587409d1ec4d8b8cbe0a90a9b3affa (patch) | |
tree | bdc959a12bf9f7a194ea092c98d0fe174326af07 /sys/arch/arm/xscale | |
parent | a6df8e6c034709f554d1179192515b0216ea9c0b (diff) |
Permit one of the PXA2X0's UARTs to operate in Slow Infrared (SIR) mode
(half-duplex). I couldn't verify that the real serial port still works
(a special serial cable is needed for that).
Diffstat (limited to 'sys/arch/arm/xscale')
-rw-r--r-- | sys/arch/arm/xscale/pxacom.c | 93 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxacomreg.h | 13 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxacomvar.h | 4 |
3 files changed, 105 insertions, 5 deletions
diff --git a/sys/arch/arm/xscale/pxacom.c b/sys/arch/arm/xscale/pxacom.c index f9f7ee938b8..8314358afd7 100644 --- a/sys/arch/arm/xscale/pxacom.c +++ b/sys/arch/arm/xscale/pxacom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pxacom.c,v 1.1 2004/12/30 23:46:14 drahn Exp $ */ +/* $OpenBSD: pxacom.c,v 1.2 2005/05/09 15:25:29 uwe Exp $ */ /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ /* @@ -74,7 +74,6 @@ #include <sys/uio.h> #include <sys/kernel.h> #include <sys/syslog.h> -#include <sys/types.h> #include <sys/device.h> #include <sys/vnode.h> #ifdef DDB @@ -91,6 +90,16 @@ #include <dev/ic/ns16550reg.h> #define com_lcr com_cfcr +#ifdef COM_PXA2X0 +#define com_isr 8 +#define ISR_SEND (ISR_RXPL | ISR_XMODE | ISR_XMITIR) +#define ISR_RECV (ISR_RXPL | ISR_XMODE | ISR_RCVEIR) +#endif + +#ifdef __zaurus__ +void scoop_set_irled(int); /* XXX */ +#endif + #include "com.h" /* XXX: These belong elsewhere */ @@ -108,6 +117,7 @@ struct cfdriver com_cd = { int comdefaultrate = TTYDEF_SPEED; int comconsinit; bus_addr_t comconsaddr; +bus_addr_t comsiraddr; int comconsattached; int comconsfreq; bus_space_tag_t comconsiot; @@ -291,9 +301,14 @@ com_attach_subr(sc) printf(": ns16550, no working fifo\n"); break; case COM_UART_16550A: - printf(": ns16550a, 16 byte fifo\n"); + printf(": ns16550a, 16 byte fifo"); SET(sc->sc_hwflags, COM_HW_FIFO); sc->sc_fifolen = 16; + if (sc->sc_iobase == comsiraddr) { + SET(sc->sc_hwflags, COM_HW_SIR); + printf(" (SIR)"); + } + printf("\n"); break; case COM_UART_ST16650: printf(": st16650, no working fifo\n"); @@ -620,6 +635,14 @@ comopen(dev, flag, mode, p) SET(tp->t_state, TS_CARR_ON); else CLR(tp->t_state, TS_CARR_ON); +#ifdef COM_PXA2X0 + if (ISSET(sc->sc_hwflags, COM_HW_SIR)) { + bus_space_write_1(iot, ioh, com_isr, ISR_RECV); +#ifdef __zaurus__ + scoop_set_irled(1); +#endif + } +#endif } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) return EBUSY; else @@ -751,6 +774,11 @@ compwroff(sc) bus_space_write_1(iot, ioh, com_ier, IER_SLEEP); break; } + +#if defined(COM_PXA2X0) && defined(__zaurus__) + if (ISSET(sc->sc_hwflags, COM_HW_SIR)) + scoop_set_irled(0); +#endif } void @@ -1114,6 +1142,12 @@ comstart(tp) } SET(tp->t_state, TS_BUSY); +#ifdef COM_PXA2X0 + /* Enable transmitter slow infrared mode. */ + if (ISSET(sc->sc_hwflags, COM_HW_SIR)) + bus_space_write_1(iot, ioh, com_isr, ISR_SEND); +#endif + /* Enable transmit completion interrupts. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); @@ -1138,6 +1172,20 @@ stopped: if (ISSET(sc->sc_ier, IER_ETXRDY)) { CLR(sc->sc_ier, IER_ETXRDY); bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); +#ifdef COM_PXA2X0 + if (ISSET(sc->sc_hwflags, COM_HW_SIR)) { + int timo; + + /* Wait for empty transmit shift register. */ + timo = 20000; + while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), + LSR_TSRE) && --timo) + delay(1); + + /* Enable receiver slow infrared mode. */ + bus_space_write_1(iot, ioh, com_isr, ISR_RECV); + } +#endif } splx(s); } @@ -1401,6 +1449,11 @@ comintr(arg) (*linesw[tp->t_line].l_start)(tp); } +#ifdef COM_PXA2X0 + if (ISSET(lsr, LSR_TXRDY) && ISSET(lsr, LSR_TSRE)) + bus_space_write_1(iot, ioh, com_isr, ISR_RECV); +#endif + if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND)) return (1); } @@ -1430,6 +1483,15 @@ com_common_getc(iot, ioh) int s = splhigh(); u_char stat, c; +#ifdef COM_PXA2X0 + if ((comconsioh == ioh && comconsaddr == comsiraddr) +#ifdef KGDB + || (com_kgdb_ioh == ioh && com_kgdb_addr == comsiraddr) +#endif + ) + bus_space_write_1(iot, ioh, com_isr, ISR_RECV); +#endif + /* block until a character becomes available */ while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) continue; @@ -1455,6 +1517,15 @@ com_common_putc(iot, ioh, c) while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo) delay(1); +#ifdef COM_PXA2X0 + if ((comconsioh == ioh && comconsaddr == comsiraddr) +#ifdef KGDB + || (com_kgdb_ioh == ioh && com_kgdb_addr == comsiraddr) +#endif + ) + bus_space_write_1(iot, ioh, com_isr, ISR_SEND); +#endif + bus_space_write_1(iot, ioh, com_data, c &0xff); bus_space_barrier(iot, ioh, 0, COM_NPORTS, (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)); @@ -1464,6 +1535,22 @@ com_common_putc(iot, ioh, c) while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo) delay(1); +#ifdef COM_PXA2X0 + if ((comconsioh == ioh && comconsaddr == comsiraddr) +#ifdef KGDB + || (com_kgdb_ioh == ioh && com_kgdb_addr == comsiraddr) +#endif + ) { + /* wait for transmit shift register to become empty */ + timo = 20000; + while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TSRE) + && --timo) + delay(1); + + bus_space_write_1(iot, ioh, com_isr, ISR_RECV); + } +#endif + splx(s); } diff --git a/sys/arch/arm/xscale/pxacomreg.h b/sys/arch/arm/xscale/pxacomreg.h index 6d4a1bfdb9a..284d0e661bb 100644 --- a/sys/arch/arm/xscale/pxacomreg.h +++ b/sys/arch/arm/xscale/pxacomreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pxacomreg.h,v 1.1 2004/12/30 23:46:14 drahn Exp $ */ +/* $OpenBSD: pxacomreg.h,v 1.2 2005/05/09 15:25:29 uwe Exp $ */ /* $NetBSD: comreg.h,v 1.8 1996/02/05 23:01:50 scottr Exp $ */ /* @@ -172,7 +172,18 @@ #define FCTL_TRIGGER2 0x10 #define FCTL_TRIGGER3 0x20 +/* infrared selection register */ +#define ISR_XMITIR 0x01 /* transmitter SIR enable */ +#define ISR_RCVEIR 0x02 /* receiver SIR enable */ +#define ISR_XMODE 0x04 /* 1.6us transmit pulse width */ +#define ISR_TXPL 0x08 /* negative transmit data polarity */ +#define ISR_RXPL 0x10 /* negative receive data polarity */ + +#ifdef COM_PXA2X0 +#define COM_NPORTS 9 +#else #define COM_NPORTS 8 +#endif /* * WARNING: Serial console is assumed to be at COM1 address diff --git a/sys/arch/arm/xscale/pxacomvar.h b/sys/arch/arm/xscale/pxacomvar.h index 000df8bb37f..d327fabc5dd 100644 --- a/sys/arch/arm/xscale/pxacomvar.h +++ b/sys/arch/arm/xscale/pxacomvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pxacomvar.h,v 1.1 2004/12/30 23:46:14 drahn Exp $ */ +/* $OpenBSD: pxacomvar.h,v 1.2 2005/05/09 15:25:29 uwe Exp $ */ /* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */ /* @@ -107,6 +107,7 @@ struct com_softc { u_char sc_hwflags; #define COM_HW_NOIEN 0x01 #define COM_HW_FIFO 0x02 +#define COM_HW_SIR 0x20 #define COM_HW_CONSOLE 0x40 #define COM_HW_KGDB 0x80 u_char sc_swflags; @@ -166,6 +167,7 @@ void com_attach_subr(struct com_softc *); extern int comdefaultrate; extern bus_addr_t comconsaddr; +extern bus_addr_t comsiraddr; extern int comconsinit; extern int comconsattached; extern bus_space_tag_t comconsiot; |