summaryrefslogtreecommitdiffstats
path: root/sys/arch/sparc/dev/tctrl.c
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2016-09-01 09:23:41 +0000
committertedu <tedu@openbsd.org>2016-09-01 09:23:41 +0000
commit1bf2da8204446fb8228393ba6b9334574c4140ff (patch)
tree7fe6dd93f95f5b3bab1995aa73671e23a1fb13bd /sys/arch/sparc/dev/tctrl.c
parentRTM_CHANGE should not allow to change the gateway of a mpath route. (diff)
downloadwireguard-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.c1194
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);
-}