diff options
| author | 2016-09-01 09:23:41 +0000 | |
|---|---|---|
| committer | 2016-09-01 09:23:41 +0000 | |
| commit | 1bf2da8204446fb8228393ba6b9334574c4140ff (patch) | |
| tree | 7fe6dd93f95f5b3bab1995aa73671e23a1fb13bd /sys/arch/sparc/dev/tctrl.c | |
| parent | RTM_CHANGE should not allow to change the gateway of a mpath route. (diff) | |
| download | wireguard-openbsd-1bf2da8204446fb8228393ba6b9334574c4140ff.tar.xz wireguard-openbsd-1bf2da8204446fb8228393ba6b9334574c4140ff.zip | |
Celebrate OpenBSD 6.0 release by retiring the sparc port.
You've served us well, good friend, but now it's time to rest.
ok deraadt
Diffstat (limited to 'sys/arch/sparc/dev/tctrl.c')
| -rw-r--r-- | sys/arch/sparc/dev/tctrl.c | 1194 |
1 files changed, 0 insertions, 1194 deletions
diff --git a/sys/arch/sparc/dev/tctrl.c b/sys/arch/sparc/dev/tctrl.c deleted file mode 100644 index a72b9aafa74..00000000000 --- a/sys/arch/sparc/dev/tctrl.c +++ /dev/null @@ -1,1194 +0,0 @@ -/* $OpenBSD: tctrl.c,v 1.21 2011/07/02 22:20:07 nicm Exp $ */ -/* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The /dev/apm{,ctl} interface code falls under the following license - * terms: - * - * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved. - * Copyright (c) 1995 John T. Kohl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/event.h> -#include <sys/fcntl.h> -#include <sys/ioctl.h> -#include <sys/proc.h> -#include <sys/timeout.h> - -#include <machine/apmvar.h> -#include <machine/autoconf.h> -#include <machine/conf.h> -#include <machine/cpu.h> - -#include <sparc/sparc/auxioreg.h> - -#include <sparc/dev/ts102reg.h> -#include <sparc/dev/tctrlvar.h> - -/* - * Flags to control kernel display - * SCFLAG_NOPRINT: do not output APM power messages due to - * a power change event. - * - * SCFLAG_PCTPRINT: do not output APM power messages due to - * to a power change event unless the battery - * percentage changes. - */ - -#define SCFLAG_NOPRINT 0x0008000 -#define SCFLAG_PCTPRINT 0x0004000 -#define SCFLAG_PRINT (SCFLAG_NOPRINT|SCFLAG_PCTPRINT) - -const char *tctrl_ext_status[16] = { - "main power available", - "internal battery attached", - "external battery attached", - "external VGA attached", - "external keyboard attached", - "external mouse attached", - "lid down", - "internal battery charging", - "external battery charging", - "internal battery discharging", - "external battery discharging", -}; - -/* Request "packet" */ -struct tctrl_req { - u_int8_t cmdbuf[16]; - u_int cmdlen; - u_int8_t rspbuf[16]; - u_int rsplen; -}; - -struct tctrl_softc { - struct device sc_dev; - struct uctrl_regs *sc_regs; - struct intrhand sc_ih; - u_int sc_ext_status; - u_int sc_flags; -#define TCTRL_SEND_REQUEST 0x0001 -#define TCTRL_ISXT 0x0002 - u_int sc_wantdata; - enum { TCTRL_IDLE, TCTRL_ARGS, - TCTRL_ACK, TCTRL_DATA } sc_state; - u_int8_t sc_cmdbuf[16]; - u_int8_t sc_rspbuf[16]; - u_int8_t sc_tft_on; - u_int8_t sc_pcmcia_on; - u_int8_t sc_brightness; - u_int8_t sc_op; - u_int sc_cmdoff; - u_int sc_cmdlen; - u_int sc_rspoff; - u_int sc_rsplen; - u_int sc_rspack; - u_int sc_bellfreq; - u_int sc_bellvol; - - struct timeout sc_tmo; - - /* /dev/apm{,ctl} fields */ - struct klist sc_note; - u_int sc_apmflags; - - /* external video control callback */ - void (*sc_evcb)(void *, int); - void *sc_evdata; -}; - -int tctrl_match(struct device *, void *, void *); -void tctrl_attach(struct device *, struct device *, void *); - -void tctrl_bell(struct tctrl_softc *, int, int); -void tctrl_brightness(struct tctrl_softc *, int, int); -void tctrl_init_lcd(struct tctrl_softc *); -int tctrl_intr(void *); -void tctrl_lcd(struct tctrl_softc *, int, int); -u_int8_t tctrl_read_data(struct tctrl_softc *); -void tctrl_read_event_status(void *); -void tctrl_read_ext_status(struct tctrl_softc *); -int tctrl_request(struct tctrl_softc *, struct tctrl_req *); -void tctrl_tft(struct tctrl_softc *); -void tctrl_write_data(struct tctrl_softc *, u_int8_t); - -int apm_record_event(struct tctrl_softc *, u_int); - -struct cfattach tctrl_ca = { - sizeof(struct tctrl_softc), tctrl_match, tctrl_attach -}; - -struct cfdriver tctrl_cd = { - NULL, "tctrl", DV_DULL -}; - -int -tctrl_match(parent, vcf, aux) - struct device *parent; - void *vcf; - void *aux; -{ - struct confargs *ca = aux; - struct romaux *ra = &ca->ca_ra; - - /* - * Tadpole 3GX/3GS uses "uctrl" for the Tadpole Microcontroller - * (which is really part of the TS102 PCMCIA controller, but there - * exists a distinct OpenProm node for the microcontroller interface). - */ - if (strcmp("uctrl", ra->ra_name)) - return (0); - - return (1); -} - -void -tctrl_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct confargs *ca = aux; - struct tctrl_softc *sc = (void *)self; - u_int i, v; - int pri; - - if (ca->ca_ra.ra_nintr != 1) { - printf(": expected 1 interrupt, got %d\n", - ca->ca_ra.ra_nintr); - return; - } - pri = ca->ca_ra.ra_intr[0].int_pri; - - if (ca->ca_ra.ra_nreg != 1) { - printf(": expected 1 register, got %d\n", - ca->ca_ra.ra_nreg); - return; - } - sc->sc_regs = mapiodev(&(ca->ca_ra.ra_reg[0]), 0, - ca->ca_ra.ra_reg[0].rr_len); - - printf(" pri %d\n", pri); - - /* - * We need to check if we are running on the SPARCbook S3XT, which - * needs extra work to control the TFT power. - */ - sc->sc_flags = 0; - if (strcmp(mainbus_model, "Tadpole_S3000XT") == 0) - sc->sc_flags |= TCTRL_ISXT; - sc->sc_tft_on = 1; - - /* clear any pending data */ - for (i = 0; i < 10000; i++) { - if ((TS102_UCTRL_STS_RXNE_STA & sc->sc_regs->stat) == 0) - break; - v = sc->sc_regs->data; - sc->sc_regs->stat = TS102_UCTRL_STS_RXNE_STA; - } - - sc->sc_ih.ih_fun = tctrl_intr; - sc->sc_ih.ih_arg = sc; - intr_establish(pri, &sc->sc_ih, -1, self->dv_xname); - - timeout_set(&sc->sc_tmo, tctrl_read_event_status, sc); - - /* See what the external status is */ - tctrl_read_ext_status(sc); - if (sc->sc_ext_status != 0) { - const char *sep; - u_int len; - - v = sc->sc_ext_status; - len = 0; - sep = ""; - for (i = 0; v != 0; i++, v >>= 1) { - if ((v & 1) == 0) - continue; - /* wrap to next line if necessary */ - if (len != 0 && len + strlen(sep) + - strlen(tctrl_ext_status[i]) > 80) { - printf("\n"); - len = 0; - } - if (len == 0) { - printf("%s: ", sc->sc_dev.dv_xname); - len = 2 + strlen(sc->sc_dev.dv_xname); - sep = ""; - } - printf("%s%s", sep, tctrl_ext_status[i]); - len += strlen(sep) + strlen(tctrl_ext_status[i]); - sep = ", "; - } - if (len != 0) - printf("\n"); - } - - /* Get a few status values */ - tctrl_bell(sc, 0xff, 0); - tctrl_brightness(sc, 0xff, 0); - - /* Blank video if lid is closed during boot */ - if (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) - tctrl_tft(sc); - - sc->sc_regs->intr = TS102_UCTRL_INT_RXNE_REQ|TS102_UCTRL_INT_RXNE_MSK; - - sc->sc_wantdata = 0; - - /* Initialize the LCD icons */ - tctrl_init_lcd(sc); -} - -int -tctrl_intr(void *arg) -{ - struct tctrl_softc *sc = arg; - unsigned int v, d; - int progress = 0; - -again: - /* find out the cause(s) of the interrupt */ - v = sc->sc_regs->stat & TS102_UCTRL_STS_MASK; - - /* clear the cause(s) of the interrupt */ - sc->sc_regs->stat = v; - - v &= ~(TS102_UCTRL_STS_RXO_STA|TS102_UCTRL_STS_TXE_STA); - if (sc->sc_cmdoff >= sc->sc_cmdlen) { - v &= ~TS102_UCTRL_STS_TXNF_STA; - if (sc->sc_regs->intr & TS102_UCTRL_INT_TXNF_REQ) { - sc->sc_regs->intr = 0; - progress = 1; - } - } - if (v == 0 && ((sc->sc_flags & TCTRL_SEND_REQUEST) == 0 || - sc->sc_state != TCTRL_IDLE)) { - return (progress); - } - - progress = 1; - if (v & TS102_UCTRL_STS_RXNE_STA) { - d = tctrl_read_data(sc); - switch (sc->sc_state) { - case TCTRL_IDLE: - if (d == TS102_UCTRL_INTR) { - /* external event */ - timeout_add(&sc->sc_tmo, 1); - } else { - printf("%s: (op=0x%02x): unexpected data (0x%02x)\n", - sc->sc_dev.dv_xname, sc->sc_op, d); - } - goto again; - case TCTRL_ACK: -#ifdef TCTRLDEBUG - printf(" ack=0x%02x", d); -#endif - switch (d) { - case TS102_UCTRL_ACK: - sc->sc_rspack = 1; - sc->sc_rsplen--; - sc->sc_rspoff = 0; - sc->sc_state = - sc->sc_rsplen ? TCTRL_DATA : TCTRL_IDLE; - sc->sc_wantdata = sc->sc_rsplen ? 1 : 0; -#ifdef TCTRLDEBUG - if (sc->sc_rsplen > 0) { - printf(" [data(%u)]", sc->sc_rsplen); - } else { - printf(" [idle]\n"); - } -#endif - goto again; - default: - printf("%s: (op=0x%02x): unexpected return value (0x%02x)\n", - sc->sc_dev.dv_xname, sc->sc_op, d); - /* FALLTHROUGH */ - case TS102_UCTRL_NACK: - printf("%s: command %x failed\n", - sc->sc_dev.dv_xname, sc->sc_op); - sc->sc_rspack = 0; - sc->sc_wantdata = 0; - sc->sc_state = TCTRL_IDLE; - break; - } - break; - case TCTRL_DATA: - sc->sc_rspbuf[sc->sc_rspoff++] = d; -#ifdef TCTRLDEBUG - printf(" [%d]=0x%02x", sc->sc_rspoff-1, d); -#endif - if (sc->sc_rspoff == sc->sc_rsplen) { -#ifdef TCTRLDEBUG - printf(" [idle]\n"); -#endif - sc->sc_state = TCTRL_IDLE; - sc->sc_wantdata = 0; - } - 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); - goto again; - } - } - if ((sc->sc_state == TCTRL_IDLE && sc->sc_wantdata == 0) || - (sc->sc_flags & TCTRL_SEND_REQUEST)) { - if (sc->sc_flags & TCTRL_SEND_REQUEST) { - sc->sc_flags &= ~TCTRL_SEND_REQUEST; - sc->sc_wantdata = 1; - } - if (sc->sc_cmdlen > 0) { - sc->sc_regs->intr = - sc->sc_regs->intr | TS102_UCTRL_INT_TXNF_MSK - |TS102_UCTRL_INT_TXNF_REQ; - v = sc->sc_regs->stat; - } - } - if ((sc->sc_cmdoff < sc->sc_cmdlen) && (v & TS102_UCTRL_STS_TXNF_STA)) { - tctrl_write_data(sc, sc->sc_cmdbuf[sc->sc_cmdoff++]); -#ifdef TCTRLDEBUG - 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; -#ifdef TCTRLDEBUG - printf(" %s", sc->sc_rsplen ? "[ack]" : "[idle]\n"); -#endif - if (sc->sc_cmdoff == 1) { - sc->sc_op = sc->sc_cmdbuf[0]; - } - sc->sc_regs->intr = - sc->sc_regs->intr & (~TS102_UCTRL_INT_TXNF_MSK - |TS102_UCTRL_INT_TXNF_REQ); - } else if (sc->sc_state == TCTRL_IDLE) { - sc->sc_op = sc->sc_cmdbuf[0]; - sc->sc_state = TCTRL_ARGS; -#ifdef TCTRLDEBUG - printf(" [args]"); -#endif - } - } - goto again; -} - -/* - * The Tadpole microcontroller is not preprogrammed with icon - * representations. The machine boots with the DC-IN light as - * a blank (all 0x00) and the other lights, as 4 rows of horizontal - * bars. The below code initializes the few icons the system will use - * to sane values. - * - * Programming the icons is simple. It is a 5x8 matrix, with each row a - * bitfield in the order 0x10 0x08 0x04 0x02 0x01. - */ - -static void tctrl_set_glyph(struct tctrl_softc *, u_int, const u_int8_t *); - -static const u_int8_t - tctrl_glyph_dc[] = { 0x00, 0x00, 0x1f, 0x00, 0x15, 0x00, 0x00, 0x00 }, -#if 0 - tctrl_glyph_bs[] = { 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00 }, - tctrl_glyph_w1[] = { 0x0c, 0x16, 0x10, 0x15, 0x10, 0x16, 0x0c, 0x00 }, - tctrl_glyph_w2[] = { 0x0c, 0x0d, 0x01, 0x15, 0x01, 0x0d, 0x0c, 0x00 }, - tctrl_glyph_l1[] = { 0x00, 0x04, 0x08, 0x13, 0x08, 0x04, 0x00, 0x00 }, - tctrl_glyph_l2[] = { 0x00, 0x04, 0x02, 0x19, 0x02, 0x04, 0x00, 0x00 }, -#endif - tctrl_glyph_pc[] = { 0x00, 0x0e, 0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x00 }; - -void -tctrl_init_lcd(struct tctrl_softc *sc) -{ - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_DC_GOOD, tctrl_glyph_dc); -#if 0 - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_BACKSLASH, tctrl_glyph_bs); - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_WAN1, tctrl_glyph_w1); - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_WAN2, tctrl_glyph_w2); - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_LAN1, tctrl_glyph_l1); - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_LAN2, tctrl_glyph_l2); -#endif - tctrl_set_glyph(sc, TS102_BLK_OFF_DEF_PCMCIA, tctrl_glyph_pc); -} - -static void -tctrl_set_glyph(struct tctrl_softc *sc, u_int glyph, const u_int8_t *data) -{ - struct tctrl_req req; - - req.cmdbuf[0] = TS102_OP_BLK_DEF_SPCL_CHAR; - req.cmdbuf[1] = 8; - req.cmdbuf[2] = glyph; - bcopy(data, req.cmdbuf + 3, 8); - req.cmdlen = 3 + 8; - req.rsplen = 1; - - tctrl_request(sc, &req); -} - -void -tctrl_read_event_status(void *arg) -{ - struct tctrl_softc *sc = (struct tctrl_softc *)arg; - struct tctrl_req req; - unsigned int v; - - req.cmdbuf[0] = TS102_OP_RD_EVENT_STATUS; - req.cmdlen = 1; - req.rsplen = 3; - - tctrl_request(sc, &req); - - v = req.rspbuf[0] * 256 + req.rspbuf[1]; - - /* - * Read the new external status value if necessary - */ - if (v & (TS102_EVENT_STATUS_DC_STATUS_CHANGE | - TS102_EVENT_STATUS_LID_STATUS_CHANGE | - TS102_EVENT_STATUS_EXTERNAL_VGA_STATUS_CHANGE)) - tctrl_read_ext_status(sc); - - if (v & TS102_EVENT_STATUS_SHUTDOWN_REQUEST) { - printf("%s: SHUTDOWN REQUEST!\n", sc->sc_dev.dv_xname); - } -#ifdef TCTRLDEBUG - /* Obviously status change */ - if (v & TS102_EVENT_STATUS_VERY_LOW_POWER_WARNING) { - if (sc->sc_apmflags & SCFLAG_PCTPRINT) - printf("%s: Battery level change\n", - sc->sc_dev.dv_xname); - } -#endif - if (v & TS102_EVENT_STATUS_LOW_POWER_WARNING) { - if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0) - printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname); - apm_record_event(sc, APM_BATTERY_LOW); - } - if (v & TS102_EVENT_STATUS_DC_STATUS_CHANGE) { - if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0) - printf("%s: main power %s\n", sc->sc_dev.dv_xname, - (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ? - "restored" : "removed"); - apm_record_event(sc, APM_POWER_CHANGE); -#if 0 /* automatically done for us */ - tctrl_lcd(sc, ~TS102_LCD_DC_OK, - sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE ? - TS102_LCD_DC_OK : 0); -#endif - } - if (v & TS102_EVENT_STATUS_LID_STATUS_CHANGE) { - /* blank or restore video if necessary */ - if (sc->sc_tft_on) - tctrl_tft(sc); -#ifdef TCTRLDEBUG - printf("%s: lid %s\n", sc->sc_dev.dv_xname, - (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) ? - "closed" : "opened"); -#endif - } - if (v & TS102_EVENT_STATUS_EXTERNAL_VGA_STATUS_CHANGE) { - printf("%s: external vga %s\n", sc->sc_dev.dv_xname, - sc->sc_ext_status & TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED ? - "attached" : "detached"); -#ifdef TCTRLDEBUG - req.cmdbuf[0] = TS102_OP_RD_EXT_VGA_PORT; - req.cmdlen = 1; - req.rsplen = 2; - tctrl_request(sc, &req); - printf("%s: vga status %x\n", sc->sc_dev.dv_xname, - req.rspbuf[0]); -#endif - if (sc->sc_evcb != NULL) - (*sc->sc_evcb)(sc->sc_evdata, sc->sc_ext_status & - TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED); - } -} - -void -tctrl_read_ext_status(struct tctrl_softc *sc) -{ - struct tctrl_req req; - - req.cmdbuf[0] = TS102_OP_RD_EXT_STATUS; - req.cmdlen = 1; - req.rsplen = 3; -#ifdef TCTRLDEBUG - printf("tctrl_read_ext_status: before, ext_status = %x\n", - sc->sc_ext_status); -#endif - - tctrl_request(sc, &req); - - sc->sc_ext_status = req.rspbuf[0] * 256 + req.rspbuf[1]; - -#ifdef TCTRLDEBUG - printf("tctrl_read_ext_status: after, ext_status = %x\n", - sc->sc_ext_status); -#endif -} - -void -tctrl_bell(struct tctrl_softc *sc, int mask, int value) -{ - struct tctrl_req req; - - req.cmdbuf[0] = TS102_OP_CTL_SPEAKER_VOLUME; - req.cmdbuf[1] = mask; - req.cmdbuf[2] = value; - req.cmdlen = 3; - req.rsplen = 2; - - tctrl_request(sc, &req); - - /* - * Note that rspbuf[0] returns the previous value, before any - * adjustment happened. - */ - if (mask == 0) - sc->sc_bellvol = value; - else - sc->sc_bellvol = req.rspbuf[0]; -} - -void -tctrl_brightness(struct tctrl_softc *sc, int mask, int value) -{ - struct tctrl_req req; - - req.cmdbuf[0] = TS102_OP_CTL_TFT_BRIGHTNESS; - req.cmdbuf[1] = mask; - req.cmdbuf[2] = value; - req.cmdlen = 3; - req.rsplen = 2; - - tctrl_request(sc, &req); - - /* - * Note that rspbuf[0] returns the previous value, before any - * adjustment happened. - */ - if (mask == 0) - sc->sc_brightness = value; - else - sc->sc_brightness = req.rspbuf[0]; -} - -void -tctrl_tft(struct tctrl_softc *sc) -{ - struct tctrl_req req; - int enable; - - enable = (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) == 0 && - sc->sc_tft_on; - - req.cmdbuf[0] = TS102_OP_CTL_BITPORT; - req.cmdbuf[1] = ~TS102_BITPORT_TFTPWR; - req.cmdbuf[2] = enable ? 0 : TS102_BITPORT_TFTPWR; - req.cmdlen = 3; - req.rsplen = 2; - - if ((sc->sc_flags & TCTRL_ISXT) != 0 && enable) { - sb_auxregbisc(0, AUXIO_TFT, 0); - delay(100000); /* XXX is such a long delay really necessary? */ - } - - tctrl_request(sc, &req); - - if ((sc->sc_flags & TCTRL_ISXT) != 0 && !enable) { - delay(100000); /* XXX is such a long delay really necessary? */ - sb_auxregbisc(0, 0, AUXIO_TFT); - } -} - -void -tctrl_lcd(struct tctrl_softc *sc, int mask, int value) -{ - struct tctrl_req req; - - req.cmdbuf[0] = TS102_OP_CTL_LCD; - - /* - * The mask setup for this particular command is *very* bizarre - * and totally undocumented. - * One would expect the cmdlen and rsplen to be 5 and 3, - * respectively, as well. Though luck, they are not... - */ - - req.cmdbuf[1] = mask & 0xff; - req.cmdbuf[4] = (mask >> 8) & 0x01; - - req.cmdbuf[2] = value & 0xff; - req.cmdbuf[3] = (value >> 8 & 0x01); - - req.cmdlen = 3; - req.rsplen = 2; - - tctrl_request(sc, &req); -} - -int -tctrl_request(struct tctrl_softc *sc, struct tctrl_req *req) -{ - int s, rv; - - while (sc->sc_wantdata != 0) { - DELAY(1); - } - - s = splhigh(); - sc->sc_flags |= TCTRL_SEND_REQUEST; - bcopy(req->cmdbuf, sc->sc_cmdbuf, req->cmdlen); - sc->sc_wantdata = 1; - sc->sc_rsplen = req->rsplen; - sc->sc_cmdlen = req->cmdlen; - sc->sc_cmdoff = sc->sc_rspoff = 0; - - do { - tctrl_intr(sc); - } while (sc->sc_state != TCTRL_IDLE); - - sc->sc_wantdata = 0; /* just in case... */ - - rv = sc->sc_rspack; - if (rv != 0) - bcopy(sc->sc_rspbuf, req->rspbuf, sc->sc_rsplen); - else - bzero(req->rspbuf, req->rsplen); /* safety */ - splx(s); - - return (rv); -} - -void -tctrl_write_data(sc, v) - struct tctrl_softc *sc; - u_int8_t v; -{ - unsigned int i; - - for (i = 0; i < 100; i++) { - if (sc->sc_regs->stat & TS102_UCTRL_STS_TXNF_STA) - break; - } - sc->sc_regs->data = v; -} - -u_int8_t -tctrl_read_data(sc) - struct tctrl_softc *sc; -{ - unsigned int i, v; - - for (i = 0; i < 100000; i++) { - if (sc->sc_regs->stat & TS102_UCTRL_STS_RXNE_STA) - break; - DELAY(1); - } - - v = sc->sc_regs->data; - sc->sc_regs->stat = TS102_UCTRL_STS_RXNE_STA; - return v; -} - -/* - * External interfaces, used by the display and pcmcia drivers, as well - * as the powerdown code. - */ - -void -tadpole_powerdown(void) -{ - struct tctrl_softc *sc; - struct tctrl_req req; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - req.cmdbuf[0] = TS102_OP_ADMIN_POWER_OFF; - req.cmdlen = 1; - req.rsplen = 1; - - tctrl_request(sc, &req); -} - -void -tadpole_set_brightness(int value) -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - if (value != sc->sc_brightness) - tctrl_brightness(sc, 0, value); -} - -int -tadpole_get_brightness() -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return 0; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - return sc->sc_brightness; -} - -void -tadpole_set_video(int enabled) -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - if (sc->sc_tft_on ^ enabled) { - sc->sc_tft_on = enabled; - /* nothing to do if the lid is down */ - if ((sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) == 0) - tctrl_tft(sc); - } -} - -u_int -tadpole_get_video() -{ - struct tctrl_softc *sc; - unsigned int status; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return 0; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - status = sc->sc_tft_on ? TV_ON : 0; - - return status; -} - -void -tadpole_register_extvideo(void (*cb)(void *, int), void *data) -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - sc->sc_evcb = cb; - sc->sc_evdata = data; - - (*cb)(data, sc->sc_ext_status & TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED); -} - -void -tadpole_set_pcmcia(int slot, int enabled) -{ - struct tctrl_softc *sc; - int mask; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return; - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - mask = 1 << slot; - enabled = enabled ? mask : 0; - if ((sc->sc_pcmcia_on ^ enabled) & mask) { - sc->sc_pcmcia_on ^= mask; - tctrl_lcd(sc, ~TS102_LCD_PCMCIA_ACTIVE, - sc->sc_pcmcia_on ? TS102_LCD_PCMCIA_ACTIVE : 0); - } -} - -int -tadpole_bell(u_int duration, u_int freq, u_int volume) -{ - struct tctrl_softc *sc; - struct tctrl_req req; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return (0); - } - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - - /* Adjust frequency if necessary (first time or frequence change) */ - if (freq > 0 && freq <= 0xffff && freq != sc->sc_bellfreq) { - req.cmdbuf[0] = TS102_OP_CMD_SET_BELL_FREQ; - req.cmdbuf[1] = (freq >> 8) & 0xff; - req.cmdbuf[2] = freq & 0xff; - req.cmdlen = 3; - req.rsplen = 1; - - tctrl_request(sc, &req); - - sc->sc_bellfreq = freq; - } - - /* Adjust volume if necessary */ - if (volume >= 0 && volume <= 100) { - volume = (volume * 255) / 100; - if (volume != sc->sc_bellvol) - tctrl_bell(sc, 0, volume); - - } - - req.cmdbuf[0] = TS102_OP_CMD_RING_BELL; - req.cmdbuf[1] = (duration >> 8) & 0xff; - req.cmdbuf[2] = duration & 0xff; - req.cmdlen = 3; - req.rsplen = 1; - - tctrl_request(sc, &req); - - return (1); -} - -/* - * /dev/apm{,ctl} interface code - */ - -#define APMUNIT(dev) (minor(dev)&0xf0) -#define APMDEV(dev) (minor(dev)&0x0f) -#define APMDEV_NORMAL 0 -#define APMDEV_CTL 8 - -int apmkqfilter(dev_t dev, struct knote *kn); -void filt_apmrdetach(struct knote *kn); -int filt_apmread(struct knote *kn, long hint); - -struct filterops apmread_filtops = - { 1, NULL, filt_apmrdetach, filt_apmread}; - -#define SCFLAG_OREAD (1 << 0) -#define SCFLAG_OWRITE (1 << 1) -#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE) - -int -apmopen(dev_t dev, int flag, int mode, struct proc *p) -{ - struct tctrl_softc *sc; - int error = 0; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return (ENXIO); - } - - /* apm0 only */ - if (APMUNIT(dev) != 0) - return (ENODEV); - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - - switch (APMDEV(dev)) { - case APMDEV_CTL: - if (!(flag & FWRITE)) { - error = EINVAL; - break; - } - if (sc->sc_apmflags & SCFLAG_OWRITE) { - error = EBUSY; - break; - } - sc->sc_apmflags |= SCFLAG_OWRITE; - break; - case APMDEV_NORMAL: - if (!(flag & FREAD) || (flag & FWRITE)) { - error = EINVAL; - break; - } - sc->sc_apmflags |= SCFLAG_OREAD; - break; - default: - error = ENXIO; - break; - } - return (error); -} - -int -apmclose(dev_t dev, int flag, int mode, struct proc *p) -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return (ENXIO); - } - - /* apm0 only */ - if (APMUNIT(dev) != 0) - return (ENODEV); - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - - switch (APMDEV(dev)) { - case APMDEV_CTL: - sc->sc_apmflags &= ~SCFLAG_OWRITE; - break; - case APMDEV_NORMAL: - sc->sc_apmflags &= ~SCFLAG_OREAD; - break; - } - return (0); -} - -int -apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - struct tctrl_softc *sc; - struct tctrl_req req; - struct apm_power_info *power; - u_int8_t c; - int error = 0; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return (ENXIO); - } - - /* apm0 only */ - if (APMUNIT(dev) != 0) - return (ENODEV); - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - - switch (cmd) { - /* some ioctl names from linux */ - case APM_IOC_STANDBY: - if ((flag & FWRITE) == 0) - error = EBADF; - else - error = EOPNOTSUPP; /* XXX */ - break; - case APM_IOC_SUSPEND: - if ((flag & FWRITE) == 0) - error = EBADF; - else - error = EOPNOTSUPP; /* XXX */ - break; - case APM_IOC_PRN_CTL: - if ((flag & FWRITE) == 0) - error = EBADF; - else { - int flag = *(int *)data; - switch (flag) { - case APM_PRINT_ON: /* enable printing */ - sc->sc_apmflags &= ~SCFLAG_PRINT; - break; - case APM_PRINT_OFF: /* disable printing */ - sc->sc_apmflags &= ~SCFLAG_PRINT; - sc->sc_apmflags |= SCFLAG_NOPRINT; - break; - case APM_PRINT_PCT: /* disable some printing */ - sc->sc_apmflags &= ~SCFLAG_PRINT; - sc->sc_apmflags |= SCFLAG_PCTPRINT; - break; - default: - error = EINVAL; - break; - } - } - break; - case APM_IOC_GETPOWER: - power = (struct apm_power_info *)data; - - if (sc->sc_ext_status & - TS102_EXT_STATUS_INTERNAL_BATTERY_ATTACHED) { - req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_RATE; - req.cmdlen = 1; - req.rsplen = 2; - tctrl_request(sc, &req); - if (req.rspbuf[0] != 0) - power->battery_state = APM_BATT_CHARGING; - else - power->battery_state = APM_BATT_UNKNOWN; - - req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_LEVEL; - req.cmdlen = 1; - req.rsplen = 3; - tctrl_request(sc, &req); - - c = req.rspbuf[0]; - if (c >= TS102_CHARGE_UNKNOWN) - power->battery_life = 0; - else { - power->battery_life = c; - if (power->battery_state != APM_BATT_CHARGING) { - if (c < 0x20) - power->battery_state = - APM_BATT_CRITICAL; - else if (c < 0x40) - power->battery_state = - APM_BATT_HIGH; - else if (c < 0x66) - power->battery_state = - APM_BATT_HIGH; - } - } - } else { - power->battery_state = APM_BATTERY_ABSENT; - power->battery_life = 0; - } - power->minutes_left = (u_int)-1; /* unknown */ - - if (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) - power->ac_state = APM_AC_ON; - else - power->ac_state = APM_AC_OFF; - break; - case APM_IOC_STANDBY_REQ: - if ((flag & FWRITE) == 0) - error = EBADF; - else - error = EOPNOTSUPP; /* XXX */ - break; - case APM_IOC_SUSPEND_REQ: - if ((flag & FWRITE) == 0) - error = EBADF; - else - error = EOPNOTSUPP; /* XXX */ - break; - default: - error = ENOTTY; - } - - return (error); -} - -int -apm_record_event(struct tctrl_softc *sc, u_int type) -{ - static int apm_evindex; - - /* skip if no user waiting */ - if ((sc->sc_apmflags & SCFLAG_OPEN) == 0) - return (1); - - apm_evindex++; - KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex)); - - return (0); -} - -void -filt_apmrdetach(struct knote *kn) -{ - struct tctrl_softc *sc = (struct tctrl_softc *)kn->kn_hook; - - SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext); -} - -int -filt_apmread(struct knote *kn, long hint) -{ - /* XXX weird kqueue_scan() semantics */ - if (hint && !kn->kn_data) - kn->kn_data = (int)hint; - - return (1); -} - -int -apmkqfilter(dev_t dev, struct knote *kn) -{ - struct tctrl_softc *sc; - - if (tctrl_cd.cd_ndevs == 0 || tctrl_cd.cd_devs[0] == NULL) { - return (ENXIO); - } - - /* apm0 only */ - if (APMUNIT(dev) != 0) - return (ENODEV); - - sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; - - switch (kn->kn_filter) { - case EVFILT_READ: - kn->kn_fop = &apmread_filtops; - break; - default: - return (EINVAL); - } - - kn->kn_hook = (caddr_t)sc; - SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext); - - return (0); -} |
