This now works properly and uses interrupts. If you close the lid, the

screen will turn off and when you open the lid screen turns on.  If you
do too rapidly, the driver won't be notified but you can press the micro
switch and it will come back.  Also "halt -p" now works so you don't
have to do Pause-P to powerdown.
This commit is contained in:
matt 1999-08-11 00:46:06 +00:00
parent 14693e0ca1
commit 385ed7074b
2 changed files with 121 additions and 65 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: tctrl.c,v 1.1 1999/08/09 18:39:58 matt Exp $ */
/* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -83,6 +83,7 @@ struct tctrl_softc {
#define TCTRL_SEND_POWEROFF 0x0002
#define TCTRL_SEND_RD_EXT_STATUS 0x0004
#define TCTRL_SEND_RD_EVENT_STATUS 0x0008
#define TCTRL_SEND_BITPORT_NOP 0x0010
enum { TCTRL_IDLE, TCTRL_ARGS,
TCTRL_ACK, TCTRL_DATA } sc_state;
u_int8_t sc_cmdbuf[16];
@ -106,7 +107,7 @@ static u_int8_t tctrl_read(struct tctrl_softc *sc, bus_size_t off);
static void tctrl_write_data(struct tctrl_softc *sc, u_int8_t v);
static u_int8_t tctrl_read_data(struct tctrl_softc *sc);
static int tctrl_intr(void *arg);
static void tctrl_setup_bitport(struct tctrl_softc *sc);
static void tctrl_setup_bitport(struct tctrl_softc *sc, int nop);
static void tctrl_process_response(struct tctrl_softc *sc);
struct cfattach tctrl_ca = {
@ -138,9 +139,10 @@ tctrl_attach(struct device *parent, struct device *self, void *aux)
struct tctrl_softc *sc = (void *)self;
union obio_attach_args *uoba = aux;
struct sbus_attach_args *sa = &uoba->uoba_sbus;
unsigned int ack, msb, lsb;
unsigned int i, v;
const char *sep;
#if 0
unsigned int ack, msb, lsb;
#endif
/* We're living on a sbus slot that looks like an obio that
* looks like an sbus slot.
@ -154,27 +156,35 @@ tctrl_attach(struct device *parent, struct device *self, void *aux)
return;
}
printf("\n");
sc->sc_tft_on = 1;
/* clear any pending data.
*/
for (i = 0; i < 10000; i++) {
if ((TS102_UCTRL_STS_RXNE_REQ & tctrl_read(sc, TS102_REG_UCTRL_STS)) == 0) {
if ((TS102_UCTRL_STS_RXNE_STA & tctrl_read(sc, TS102_REG_UCTRL_STS)) == 0) {
break;
}
v = tctrl_read(sc, TS102_REG_UCTRL_DATA);
tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_REQ);
tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_STA);
}
printf("\n");
(void)bus_intr_establish(sc->sc_memt, sa->sa_pri, 0, tctrl_intr, sc);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
tctrl_write_data(sc, TS102_OP_RD_EXT_STATUS);
ack = tctrl_read_data(sc);
msb = tctrl_read_data(sc);
lsb = tctrl_read_data(sc);
sc->sc_ext_status = v = msb * 256 + lsb;
/* See what the external status is
*/
sc->sc_pending |= TCTRL_SEND_RD_EXT_STATUS;
do {
tctrl_intr(sc);
} while (sc->sc_state != TCTRL_IDLE);
if (sc->sc_ext_status != 0) {
const char *sep;
if (sc->sc_ext_status) {
printf("%s: ", sc->sc_dev.dv_xname);
v = sc->sc_ext_status;
for (i = 0, sep = ""; v != 0; i++, v >>= 1) {
if (v & 1) {
printf("%s%s", sep, tctrl_ext_statuses[i]);
@ -184,22 +194,16 @@ tctrl_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
}
sc->sc_pending |= TCTRL_SEND_BITPORT;
/* Get a current of the control bitport;
*/
sc->sc_pending |= TCTRL_SEND_BITPORT_NOP;
do {
tctrl_intr(sc);
} while (sc->sc_state != TCTRL_IDLE);
(void)bus_intr_establish(sc->sc_memt, sa->sa_pri, 0, tctrl_intr, sc);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
tctrl_write(sc, TS102_REG_UCTRL_STS,
tctrl_read(sc, TS102_REG_UCTRL_STS)
|TS102_UCTRL_INT_RXNE_MSK|TS102_UCTRL_INT_TXNF_MSK);
tctrl_write(sc, TS102_REG_UCTRL_INT,
TS102_UCTRL_INT_RXNE_REQ|TS102_UCTRL_INT_TXNF_REQ|
TS102_UCTRL_INT_RXNE_MSK|TS102_UCTRL_INT_TXNF_MSK);
#if 0
printf("%s: int=0x%02x sts=0x%02x\n", sc->sc_dev.dv_xname,
tctrl_read(sc, TS102_REG_UCTRL_INT),
tctrl_read(sc, TS102_REG_UCTRL_STS));
#endif
TS102_UCTRL_INT_RXNE_REQ|TS102_UCTRL_INT_RXNE_MSK);
}
static int
@ -216,49 +220,67 @@ tctrl_intr(void *arg)
/* clear the cause(s) of the interrupt */
tctrl_write(sc, TS102_REG_UCTRL_STS, v);
v &= ~(TS102_UCTRL_STS_RXO_REQ|TS102_UCTRL_STS_TXE_REQ);
v &= ~(TS102_UCTRL_STS_RXO_STA|TS102_UCTRL_STS_TXE_STA);
if (sc->sc_cmdoff >= sc->sc_cmdlen) {
v &= ~TS102_UCTRL_STS_TXNF_REQ;
v &= ~TS102_UCTRL_STS_TXNF_STA;
}
if ((v == 0) && (sc->sc_pending == 0 || sc->sc_state != TCTRL_IDLE)) {
return progress;
}
progress = 1;
if (v & TS102_UCTRL_STS_RXNE_REQ) {
if (v & TS102_UCTRL_STS_RXNE_STA) {
d = tctrl_read_data(sc);
switch (sc->sc_state) {
case TCTRL_IDLE:
if (d == 0xfb) {
if (d == 0xfa) {
sc->sc_pending |= TCTRL_SEND_RD_EVENT_STATUS;
}
break;
case TCTRL_ACK:
if (d != 0xfe) {
printf("%s: (op=0x%02x): unexpected value for ack (0x%02x)\n",
} else {
printf("%s: (op=0x%02x): unexpected data (0x%02x)\n",
sc->sc_dev.dv_xname, sc->sc_op, d);
}
sc->sc_state = sc->sc_rsplen ? TCTRL_DATA : TCTRL_IDLE;
sc->sc_rspoff = 0;
goto again;
case TCTRL_ACK:
if (d != 0xfe) {
printf("%s: (op=0x%02x): unexpected ack value (0x%02x)\n",
sc->sc_dev.dv_xname, sc->sc_op, d);
}
#if 0
printf(" ack=0x%02x", d);
#endif
sc->sc_rsplen--;
break;
sc->sc_rspoff = 0;
sc->sc_state = sc->sc_rsplen ? TCTRL_DATA : TCTRL_IDLE;
#if 0
if (sc->sc_rsplen > 0) {
printf(" [data(%u)]", sc->sc_rsplen);
} else {
printf(" [idle]\n");
}
#endif
goto again;
case TCTRL_DATA:
sc->sc_rspbuf[sc->sc_rspoff++] = d;
#if 0
printf(" [%d]=0x%02x", sc->sc_rspoff-1, d);
#endif
if (sc->sc_rspoff == sc->sc_rsplen) {
#if 0
printf(" [idle]\n");
#endif
sc->sc_state = TCTRL_IDLE;
if (sc->sc_rsplen > 0) {
tctrl_process_response(sc);
}
tctrl_process_response(sc);
}
break;
goto again;
default:
printf("%s: (op=0x%02x): unexpected data (0x%02x) in state %d\n",
sc->sc_dev.dv_xname, sc->sc_op, d, sc->sc_state);
break;
goto again;
}
}
if (sc->sc_state == TCTRL_IDLE) {
sc->sc_cmdoff = 0;
sc->sc_cmdlen = 0;
if (sc->sc_pending & TCTRL_SEND_POWEROFF) {
sc->sc_pending &= ~TCTRL_SEND_POWEROFF;
sc->sc_cmdbuf[0] = TS102_OP_ADMIN_POWER_OFF;
@ -274,9 +296,12 @@ tctrl_intr(void *arg)
sc->sc_cmdbuf[0] = TS102_OP_RD_EXT_STATUS;
sc->sc_cmdlen = 1;
sc->sc_rsplen = 3;
} else if (sc->sc_pending & TCTRL_SEND_BITPORT_NOP) {
sc->sc_pending &= ~TCTRL_SEND_BITPORT_NOP;
tctrl_setup_bitport(sc, 1);
} else if (sc->sc_pending & TCTRL_SEND_BITPORT) {
sc->sc_pending &= ~TCTRL_SEND_BITPORT;
tctrl_setup_bitport(sc);
tctrl_setup_bitport(sc, 0);
}
if (sc->sc_cmdlen > 0) {
tctrl_write(sc, TS102_REG_UCTRL_INT,
@ -286,10 +311,25 @@ tctrl_intr(void *arg)
v = tctrl_read(sc, TS102_REG_UCTRL_STS);
}
}
if ((sc->sc_cmdoff < sc->sc_cmdlen) && (v & TS102_UCTRL_STS_TXNF_REQ)) {
if ((sc->sc_cmdoff < sc->sc_cmdlen) && (v & TS102_UCTRL_STS_TXNF_STA)) {
tctrl_write_data(sc, sc->sc_cmdbuf[sc->sc_cmdoff++]);
#if 0
if (sc->sc_cmdoff == 1) {
printf("%s: op=0x%02x(l=%u)", sc->sc_dev.dv_xname,
sc->sc_cmdbuf[0], sc->sc_rsplen);
} else {
printf(" [%d]=0x%02x", sc->sc_cmdoff-1,
sc->sc_cmdbuf[sc->sc_cmdoff-1]);
}
#endif
if (sc->sc_cmdoff == sc->sc_cmdlen) {
sc->sc_state = sc->sc_rsplen ? TCTRL_ACK : TCTRL_IDLE;
#if 0
printf(" %s", sc->sc_rsplen ? "[ack]" : "[idle]\n");
#endif
if (sc->sc_cmdoff == 1) {
sc->sc_op = sc->sc_cmdbuf[0];
}
tctrl_write(sc, TS102_REG_UCTRL_INT,
tctrl_read(sc, TS102_REG_UCTRL_INT)
& (~TS102_UCTRL_INT_TXNF_MSK
@ -297,23 +337,35 @@ tctrl_intr(void *arg)
} else if (sc->sc_state == TCTRL_IDLE) {
sc->sc_op = sc->sc_cmdbuf[0];
sc->sc_state = TCTRL_ARGS;
#if 0
printf(" [args]");
#endif
}
}
goto again;
}
static void
tctrl_setup_bitport(struct tctrl_softc *sc)
tctrl_setup_bitport(struct tctrl_softc *sc, int nop)
{
sc->sc_cmdbuf[0] = TS102_OP_CTL_BITPORT;
sc->sc_cmdbuf[1] = ~TS102_BITPORT_TFTPWR;
if (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) {
if (nop) {
sc->sc_cmdbuf[0] = TS102_OP_CTL_BITPORT;
sc->sc_cmdbuf[1] = 0xff;
sc->sc_cmdbuf[2] = 0;
sc->sc_cmdlen = 3;
sc->sc_rsplen = 2;
} else {
sc->sc_cmdbuf[2] = sc->sc_tft_on ? TS102_BITPORT_TFTPWR : 0;
if ((sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN)
|| (!sc->sc_tft_on)) {
sc->sc_cmdbuf[2] = TS102_BITPORT_TFTPWR;
} else {
sc->sc_cmdbuf[2] = 0;
}
sc->sc_cmdbuf[0] = TS102_OP_CTL_BITPORT;
sc->sc_cmdbuf[1] = ~TS102_BITPORT_TFTPWR;
sc->sc_cmdlen = 3;
sc->sc_rsplen = 2;
}
sc->sc_cmdlen = 3;
sc->sc_rsplen = 2;
}
static void
@ -343,11 +395,15 @@ tctrl_process_response(struct tctrl_softc *sc)
if (v & TS102_EVENT_STATUS_LID_STATUS_CHANGE) {
sc->sc_pending |= TCTRL_SEND_RD_EXT_STATUS;
sc->sc_pending |= TCTRL_SEND_BITPORT;
#if 0
printf("%s: lid %s\n", sc->sc_dev.dv_xname,
(sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) ? "opened" : "closed");
#endif
}
break;
}
case TS102_OP_CTL_BITPORT:
sc->sc_bitport = sc->sc_rspbuf[0];
sc->sc_bitport = (sc->sc_rspbuf[0] & sc->sc_cmdbuf[1]) ^ sc->sc_cmdbuf[2];
break;
default:
break;
@ -407,7 +463,7 @@ tctrl_write_data(struct tctrl_softc *sc, u_int8_t v)
{
unsigned int i;
for (i = 0; i < 100; i++) {
if (TS102_UCTRL_STS_TXNF_REQ & tctrl_read(sc, TS102_REG_UCTRL_STS))
if (TS102_UCTRL_STS_TXNF_STA & tctrl_read(sc, TS102_REG_UCTRL_STS))
break;
}
tctrl_write(sc, TS102_REG_UCTRL_DATA, v);
@ -419,20 +475,20 @@ tctrl_read_data(struct tctrl_softc *sc)
unsigned int i, v;
for (i = 0; i < 100000; i++) {
if (TS102_UCTRL_STS_RXNE_REQ & tctrl_read(sc, TS102_REG_UCTRL_STS))
if (TS102_UCTRL_STS_RXNE_STA & tctrl_read(sc, TS102_REG_UCTRL_STS))
break;
DELAY(1);
}
v = tctrl_read(sc, TS102_REG_UCTRL_DATA);
tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_REQ);
tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_STA);
return v;
}
static u_int8_t
tctrl_read(struct tctrl_softc *sc, bus_size_t off)
{
sc->sc_junk = bus_space_read_4(sc->sc_memt, sc->sc_memh, off) >> 24;
sc->sc_junk = bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
return sc->sc_junk;
}
@ -440,5 +496,5 @@ static void
tctrl_write(struct tctrl_softc *sc, bus_size_t off, u_int8_t v)
{
sc->sc_junk = v;
bus_space_write_4(sc->sc_memt, sc->sc_memh, off, v << 24);
bus_space_write_1(sc->sc_memt, sc->sc_memh, off, v);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ts102reg.h,v 1.1 1999/08/09 18:39:58 matt Exp $ */
/* $NetBSD: ts102reg.h,v 1.2 1999/08/11 00:46:06 matt Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -147,10 +147,10 @@
* read 1 if asserted
* write 1 to clear
*/
#define TS102_UCTRL_STS_TXE_REQ 0x01 /* transmit FIFO empty */
#define TS102_UCTRL_STS_TXNF_REQ 0x02 /* transmit FIFO not full */
#define TS102_UCTRL_STS_RXNE_REQ 0x04 /* receive FIFO not empty */
#define TS102_UCTRL_STS_RXO_REQ 0x08 /* receive FIFO overflow */
#define TS102_UCTRL_STS_TXE_STA 0x01 /* transmit FIFO empty */
#define TS102_UCTRL_STS_TXNF_STA 0x02 /* transmit FIFO not full */
#define TS102_UCTRL_STS_RXNE_STA 0x04 /* receive FIFO not empty */
#define TS102_UCTRL_STS_RXO_STA 0x08 /* receive FIFO overflow */
enum ts102_opcode { /* Argument Returned */
TS102_OP_RD_SERIAL_NUM=0x01, /* none ack + 4 bytes */
@ -240,7 +240,7 @@ enum ts102_opcode { /* Argument Returned */
#define TS102_LCD_DC_OK 0x0080
#define TS102_LCD_COMPOSE 0x0100
TS102_OP_CTL_BITPORT=0x21, /* mask ack + 1 byte */
#define TS102_BITPORT_TFTPWR 0x02 /* TFT power (high) */
#define TS102_BITPORT_TFTPWR 0x01 /* TFT power (low) */
#define TS102_BITPORT_SYNCINVA 0x04 /* ext. monitor sync (low) */
#define TS102_BITPORT_SYNCINVB 0x08 /* ext. monitor sync (low) */
#define TS102_BITPORT_BP_DIS 0x10 /* no bootprom from pcmcia (high) */