Module Name: src
Committed By: matt
Date: Wed Dec 29 07:19:28 UTC 2010
Modified Files:
src/sys/arch/sgimips/conf [matt-nb5-mips64]: GENERIC32_IP2x
majors.sgimips
src/sys/arch/sgimips/gio [matt-nb5-mips64]: files.gio newport.c
newportreg.h
src/sys/arch/sgimips/hpc [matt-nb5-mips64]: files.hpc haltwo.c hpc.c
src/sys/arch/sgimips/ioc [matt-nb5-mips64]: ioc.c
Added Files:
src/sys/arch/sgimips/hpc [matt-nb5-mips64]: panel.c
Log Message:
Merge changes from netbsd-5.
To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.75.8.1 src/sys/arch/sgimips/conf/GENERIC32_IP2x
cvs rdiff -u -r1.20 -r1.20.24.1 src/sys/arch/sgimips/conf/majors.sgimips
cvs rdiff -u -r1.9 -r1.9.66.1 src/sys/arch/sgimips/gio/files.gio
cvs rdiff -u -r1.10 -r1.10.62.1 src/sys/arch/sgimips/gio/newport.c
cvs rdiff -u -r1.3 -r1.3.96.1 src/sys/arch/sgimips/gio/newportreg.h
cvs rdiff -u -r1.12 -r1.12.78.1 src/sys/arch/sgimips/hpc/files.hpc
cvs rdiff -u -r1.15 -r1.15.12.1 src/sys/arch/sgimips/hpc/haltwo.c
cvs rdiff -u -r1.60.38.1 -r1.60.38.2 src/sys/arch/sgimips/hpc/hpc.c
cvs rdiff -u -r0 -r1.1.10.2 src/sys/arch/sgimips/hpc/panel.c
cvs rdiff -u -r1.7 -r1.7.38.1 src/sys/arch/sgimips/ioc/ioc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sgimips/conf/GENERIC32_IP2x
diff -u src/sys/arch/sgimips/conf/GENERIC32_IP2x:1.75 src/sys/arch/sgimips/conf/GENERIC32_IP2x:1.75.8.1
--- src/sys/arch/sgimips/conf/GENERIC32_IP2x:1.75 Fri Aug 15 15:17:18 2008
+++ src/sys/arch/sgimips/conf/GENERIC32_IP2x Wed Dec 29 07:19:27 2010
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC32_IP2x,v 1.75 2008/08/15 15:17:18 tsutsui Exp $
+# $NetBSD: GENERIC32_IP2x,v 1.75.8.1 2010/12/29 07:19:27 matt Exp $
#
# GENERIC32_IP2x machine description file
#
@@ -29,7 +29,7 @@
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC32-IP2x-$Revision: 1.75 $"
+#ident "GENERIC32-IP2x-$Revision: 1.75.8.1 $"
maxusers 32
@@ -245,6 +245,7 @@
dpclock* at hpc0 offset ? # IP12 / IP20
dsclock* at hpc0 offset ? # IP22 / 24
haltwo* at hpc0 offset ? # IP22 / 24
+panel* at hpc0 offset ? # front panel buttons on Indy
pckbc* at hpc0 offset ?
pckbd* at pckbc?
Index: src/sys/arch/sgimips/conf/majors.sgimips
diff -u src/sys/arch/sgimips/conf/majors.sgimips:1.20 src/sys/arch/sgimips/conf/majors.sgimips:1.20.24.1
--- src/sys/arch/sgimips/conf/majors.sgimips:1.20 Mon Dec 31 15:32:05 2007
+++ src/sys/arch/sgimips/conf/majors.sgimips Wed Dec 29 07:19:27 2010
@@ -1,4 +1,4 @@
-# $NetBSD: majors.sgimips,v 1.20 2007/12/31 15:32:05 ad Exp $
+# $NetBSD: majors.sgimips,v 1.20.24.1 2010/12/29 07:19:27 matt Exp $
#
# Device majors for sgimips
#
@@ -67,7 +67,7 @@
device-major uscanner char 76 uscanner
device-major ksyms char 77 ksyms
device-major lpt char 78 lpt
-
+device-major sysmon char 79 sysmon_envsys | sysmon_wdog
device-major nsmb char 98 nsmb
# Majors up to 143 are reserved for machine-dependant drivers.
Index: src/sys/arch/sgimips/gio/files.gio
diff -u src/sys/arch/sgimips/gio/files.gio:1.9 src/sys/arch/sgimips/gio/files.gio:1.9.66.1
--- src/sys/arch/sgimips/gio/files.gio:1.9 Fri Dec 29 00:42:01 2006
+++ src/sys/arch/sgimips/gio/files.gio Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-# $NetBSD: files.gio,v 1.9 2006/12/29 00:42:01 rumble Exp $
+# $NetBSD: files.gio,v 1.9.66.1 2010/12/29 07:19:28 matt Exp $
device gio {[slot = -1], [addr = -1]}
attach gio at giobus
@@ -12,7 +12,7 @@
include "arch/sgimips/hpc/files.hpc"
# XL graphics
-device newport: wsemuldisplaydev
+device newport: wsemuldisplaydev, vcons, rasops8
attach newport at gio
file arch/sgimips/gio/newport.c newport needs-flag
Index: src/sys/arch/sgimips/gio/newport.c
diff -u src/sys/arch/sgimips/gio/newport.c:1.10 src/sys/arch/sgimips/gio/newport.c:1.10.62.1
--- src/sys/arch/sgimips/gio/newport.c:1.10 Sun Mar 4 06:00:39 2007
+++ src/sys/arch/sgimips/gio/newport.c Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: newport.c,v 1.10 2007/03/04 06:00:39 christos Exp $ */
+/* $NetBSD: newport.c,v 1.10.62.1 2010/12/29 07:19:28 matt Exp $ */
/*
* Copyright (c) 2003 Ilpo Ruotsalainen
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.10 2007/03/04 06:00:39 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.10.62.1 2010/12/29 07:19:28 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -42,15 +42,18 @@
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
#include <sgimips/gio/giovar.h>
#include <sgimips/gio/newportvar.h>
#include <sgimips/gio/newportreg.h>
struct newport_softc {
- struct device sc_dev;
+ device_t sc_dev;
struct newport_devconfig *sc_dc;
+
};
struct newport_devconfig {
@@ -69,17 +72,21 @@
int dc_depth;
int dc_font;
+ struct wsscreen_descr *dc_screen;
struct wsdisplay_font *dc_fontdata;
+ int dc_mode;
+ struct vcons_data dc_vd;
};
-static int newport_match(struct device *, struct cfdata *, void *);
-static void newport_attach(struct device *, struct device *, void *);
+static int newport_match(device_t, struct cfdata *, void *);
+static void newport_attach(device_t, device_t, void *);
-CFATTACH_DECL(newport, sizeof(struct newport_softc),
+CFATTACH_DECL_NEW(newport, sizeof(struct newport_softc),
newport_match, newport_attach, NULL, NULL);
/* textops */
static void newport_cursor(void *, int, int, int);
+static void newport_cursor_dummy(void *, int, int, int);
static int newport_mapchar(void *, int, unsigned int *);
static void newport_putchar(void *, int, int, u_int, long);
static void newport_copycols(void *, int, int, int, int);
@@ -88,18 +95,20 @@
static void newport_eraserows(void *, int, int, long);
static int newport_allocattr(void *, int, int, int, long *);
+static void newport_init_screen(void *, struct vcons_screen *, int, long *);
+
/* accessops */
static int newport_ioctl(void *, void *, u_long, void *, int,
struct lwp *);
static paddr_t newport_mmap(void *, void *, off_t, int);
-static int newport_alloc_screen(void *, const struct wsscreen_descr *,
- void **, int *, int *, long *);
-static void newport_free_screen(void *, void *);
-static int newport_show_screen(void *, void *, int,
- void (*)(void *, int, int), void *);
-static const struct wsdisplay_emulops newport_textops = {
- .cursor = newport_cursor,
+static struct wsdisplay_accessops newport_accessops = {
+ .ioctl = newport_ioctl,
+ .mmap = newport_mmap,
+};
+
+static struct wsdisplay_emulops newport_textops = {
+ .cursor = newport_cursor_dummy,
.mapchar = newport_mapchar,
.putchar = newport_putchar,
.copycols = newport_copycols,
@@ -109,26 +118,8 @@
.allocattr = newport_allocattr
};
-static const struct wsdisplay_accessops newport_accessops = {
- .ioctl = newport_ioctl,
- .mmap = newport_mmap,
- .alloc_screen = newport_alloc_screen,
- .free_screen = newport_free_screen,
- .show_screen = newport_show_screen,
-};
-
-static const struct wsscreen_descr newport_screen_1024x768 = {
- .name = "1024x768",
- .ncols = 128,
- .nrows = 48,
- .textops = &newport_textops,
- .fontwidth = 8,
- .fontheight = 16,
- .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
-};
-
-static const struct wsscreen_descr newport_screen_1280x1024 = {
- .name = "1280x1024",
+static struct wsscreen_descr newport_screen = {
+ .name = "default",
.ncols = 160,
.nrows = 64,
.textops = &newport_textops,
@@ -138,8 +129,7 @@
};
static const struct wsscreen_descr *_newport_screenlist[] = {
- &newport_screen_1024x768,
- &newport_screen_1280x1024
+ &newport_screen
};
static const struct wsscreen_list newport_screenlist = {
@@ -147,6 +137,7 @@
_newport_screenlist
};
+static struct vcons_screen newport_console_screen;
static struct newport_devconfig newport_console_dc;
static int newport_is_console = 0;
@@ -154,97 +145,7 @@
#define NEWPORT_ATTR_BG(a) ((a) & 0xff)
#define NEWPORT_ATTR_FG(a) (((a) >> 8) & 0xff)
-static const uint16_t newport_cursor_data[128] = {
- /* Bit 0 */
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0xff00, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
-
- /* Bit 1 */
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
-};
-
-static const uint8_t newport_defcmap[16*3] = {
- /* Normal colors */
- 0x00, 0x00, 0x00, /* black */
- 0x7f, 0x00, 0x00, /* red */
- 0x00, 0x7f, 0x00, /* green */
- 0x7f, 0x7f, 0x00, /* brown */
- 0x00, 0x00, 0x7f, /* blue */
- 0x7f, 0x00, 0x7f, /* magenta */
- 0x00, 0x7f, 0x7f, /* cyan */
- 0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
-
- /* Hilite colors */
- 0x7f, 0x7f, 0x7f, /* black */
- 0xff, 0x00, 0x00, /* red */
- 0x00, 0xff, 0x00, /* green */
- 0xff, 0xff, 0x00, /* brown */
- 0x00, 0x00, 0xff, /* blue */
- 0xff, 0x00, 0xff, /* magenta */
- 0x00, 0xff, 0xff, /* cyan */
- 0xff, 0xff, 0xff, /* white */
-};
+extern const u_char rasops_cmap[768];
/**** Low-level hardware register groveling functions ****/
static void
@@ -327,6 +228,7 @@
return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
}
+#if 0
static void
vc2_write_ram(struct newport_devconfig *dc, uint16_t addr, uint16_t val)
{
@@ -341,6 +243,7 @@
rex3_write(dc, REX3_REG_DCBDATA0, val << 16);
}
+#endif
static u_int32_t
xmap9_read(struct newport_devconfig *dc, int crs)
@@ -393,6 +296,15 @@
rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
+ rex3_write(dc, REX3_REG_DRAWMODE1,
+ REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 |
+ REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 |
+ REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ |
+ REX3_DRAWMODE1_COMPARE_GT |
+ REX3_DRAWMODE1_LO_SRC);
rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
rex3_write(dc, REX3_REG_COLORI, color);
rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
@@ -401,21 +313,46 @@
}
static void
-newport_copy_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
- int y2, int dx, int dy)
+newport_bitblt(struct newport_devconfig *dc, int xs, int ys, int xd,
+ int yd, int wi, int he, int rop)
{
+ int xe, ye;
uint32_t tmp;
rex3_wait_gfifo(dc);
-
+ if (yd > ys) {
+ /* need to copy bottom up */
+ ye = ys;
+ yd += he - 1;
+ ys += he - 1;
+ } else
+ ye = ys + he - 1;
+
+ if (xd > xs) {
+ /* need to copy right to left */
+ xe = xs;
+ xd += wi - 1;
+ xs += wi - 1;
+ } else
+ xe = xs + wi - 1;
+
rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR |
REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
- rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
- rex3_write(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
+ rex3_write(dc, REX3_REG_DRAWMODE1,
+ REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 |
+ REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 |
+ REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ |
+ REX3_DRAWMODE1_COMPARE_GT |
+ ((rop << 28) & REX3_DRAWMODE1_LOGICOP_MASK));
+ rex3_write(dc, REX3_REG_XYSTARTI, (xs << REX3_XYSTARTI_XSHIFT) | ys);
+ rex3_write(dc, REX3_REG_XYENDI, (xe << REX3_XYENDI_XSHIFT) | ye);
- tmp = (dy - y1) & 0xffff;
- tmp |= (dx - x1) << REX3_XYMOVE_XSHIFT;
+ tmp = (yd - ys) & 0xffff;
+ tmp |= (xd - xs) << REX3_XYMOVE_XSHIFT;
rex3_write_go(dc, REX3_REG_XYMOVE, tmp);
}
@@ -520,17 +457,14 @@
/* Setup cursor glyph */
curp = vc2_read_ireg(dc, VC2_IREG_CURSOR_ENTRY);
- for (i=0; i<128; i++)
- vc2_write_ram(dc, curp + i, newport_cursor_data[i]);
-
/* Setup VC2 to a known state */
tmp = vc2_read_ireg(dc, VC2_IREG_CONTROL) & VC2_CONTROL_INTERLACE;
vc2_write_ireg(dc, VC2_IREG_CONTROL, tmp |
VC2_CONTROL_DISPLAY_ENABLE |
VC2_CONTROL_VTIMING_ENABLE |
VC2_CONTROL_DID_ENABLE |
- VC2_CONTROL_CURSORFUNC_ENABLE |
- VC2_CONTROL_CURSOR_ENABLE);
+ VC2_CONTROL_CURSORFUNC_ENABLE /*|
+ VC2_CONTROL_CURSOR_ENABLE*/);
/* Setup XMAP9s */
xmap9_write(dc, XMAP9_DCBCRS_CONFIG,
@@ -544,27 +478,18 @@
xmap9_write(dc, XMAP9_DCBCRS_MODE_SELECT, 0);
/* Setup REX3 */
- rex3_write(dc, REX3_REG_DRAWMODE1,
- REX3_DRAWMODE1_PLANES_CI |
- REX3_DRAWMODE1_DD_DD8 |
- REX3_DRAWMODE1_RWPACKED |
- REX3_DRAWMODE1_HD_HD8 |
- REX3_DRAWMODE1_COMPARE_LT |
- REX3_DRAWMODE1_COMPARE_EQ |
- REX3_DRAWMODE1_COMPARE_GT |
- REX3_DRAWMODE1_LO_SRC);
rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096);
rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */
/* Setup CMAP */
- for (i=0; i<16; i++)
- newport_cmap_setrgb(dc, i, newport_defcmap[i*3],
- newport_defcmap[i*3 + 1], newport_defcmap[i*3 + 2]);
+ for (i = 0; i < 256; i++)
+ newport_cmap_setrgb(dc, i, rasops_cmap[i * 3],
+ rasops_cmap[i * 3 + 1], rasops_cmap[i * 3 + 2]);
}
/**** Attach routines ****/
static int
-newport_match(struct device *parent, struct cfdata *self, void *aux)
+newport_match(device_t parent, struct cfdata *self, void *aux)
{
struct gio_attach_args *ga = aux;
@@ -621,15 +546,20 @@
newport_get_resolution(dc);
newport_fill_rectangle(dc, 0, 0, dc->dc_xres, dc->dc_yres, 0);
+ dc->dc_screen = &newport_screen;
+
+ dc->dc_mode = WSDISPLAYIO_MODE_EMUL;
}
static void
-newport_attach(struct device *parent, struct device *self, void *aux)
+newport_attach(device_t parent, device_t self, void *aux)
{
struct gio_attach_args *ga = aux;
- struct newport_softc *sc = (void *)self;
+ struct newport_softc *sc = device_private(self);
struct wsemuldisplaydev_attach_args wa;
+ unsigned long defattr;
+ sc->sc_dev = self;
if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) {
wa.console = 1;
sc->sc_dc = &newport_console_dc;
@@ -648,19 +578,30 @@
aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n",
sc->sc_dc->dc_boardrev, sc->sc_dc->dc_cmaprev,
sc->sc_dc->dc_xmaprev, sc->sc_dc->dc_vc2rev, sc->sc_dc->dc_depth);
-
+ vcons_init(&sc->sc_dc->dc_vd, sc->sc_dc, sc->sc_dc->dc_screen,
+ &newport_accessops);
+ sc->sc_dc->dc_vd.init_screen = newport_init_screen;
+ if (newport_is_console) {
+ newport_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+ vcons_init_screen(&sc->sc_dc->dc_vd, &newport_console_screen,
+ 1, &defattr);
+ sc->sc_dc->dc_screen->textops =
+ &newport_console_screen.scr_ri.ri_ops;
+ memcpy(&newport_textops, &newport_console_screen.scr_ri.ri_ops,
+ sizeof(struct wsdisplay_emulops));
+ }
wa.scrdata = &newport_screenlist;
wa.accessops = &newport_accessops;
- wa.accesscookie = sc->sc_dc;
+ wa.accesscookie = &sc->sc_dc->dc_vd;
- config_found(&sc->sc_dev, &wa, wsemuldisplaydevprint);
+ config_found(sc->sc_dev, &wa, wsemuldisplaydevprint);
}
int
newport_cnattach(struct gio_attach_args *ga)
{
+ struct rasops_info *ri = &newport_console_screen.scr_ri;
long defattr = NEWPORT_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK);
- const struct wsscreen_descr *screen;
if (!newport_match(NULL, NULL, ga)) {
return ENXIO;
@@ -668,55 +609,107 @@
newport_attach_common(&newport_console_dc, ga);
- if (newport_console_dc.dc_xres >= 1280 &&
- newport_console_dc.dc_yres >= 1024)
- screen = &newport_screen_1280x1024;
- else
- screen = &newport_screen_1024x768;
+ newport_screen.ncols = newport_console_dc.dc_xres / 8;
+ newport_screen.nrows = newport_console_dc.dc_yres / 16;
- wsdisplay_cnattach(screen, &newport_console_dc, 0, 0, defattr);
+ ri->ri_hw = &newport_console_screen;
+ ri->ri_depth = newport_console_dc.dc_depth;
+ ri->ri_width = newport_console_dc.dc_xres;
+ ri->ri_height = newport_console_dc.dc_yres;
+ ri->ri_stride = newport_console_dc.dc_xres; /* XXX */
+ ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
+ ri->ri_ops.copyrows = newport_copyrows;
+ ri->ri_ops.eraserows = newport_eraserows;
+ ri->ri_ops.copycols = newport_copycols;
+ ri->ri_ops.erasecols = newport_erasecols;
+ ri->ri_ops.cursor = newport_cursor_dummy;
+ ri->ri_ops.mapchar = newport_mapchar;
+ ri->ri_ops.putchar = newport_putchar;
+ ri->ri_ops.allocattr = newport_allocattr;
+ ri->ri_font = newport_console_dc.dc_fontdata;
+ newport_console_screen.scr_cookie = &newport_console_dc;
+
+ wsdisplay_cnattach(&newport_screen, ri, 0, 0, defattr);
newport_is_console = 1;
return 0;
}
+static void
+newport_init_screen(void *cookie, struct vcons_screen *scr,
+ int existing, long *defattr)
+{
+ struct newport_devconfig *dc = cookie;
+ struct rasops_info *ri = &scr->scr_ri;
+
+ ri->ri_depth = dc->dc_depth;
+ ri->ri_width = dc->dc_xres;
+ ri->ri_height = dc->dc_yres;
+ ri->ri_stride = dc->dc_xres; /* XXX */
+ ri->ri_flg = RI_CENTER;
+
+ /*&ri->ri_bits = (char *)sc->sc_fb.fb_pixels;*/
+
+ rasops_init(ri, dc->dc_yres / 8, dc->dc_xres / 8);
+ ri->ri_caps = WSSCREEN_WSCOLORS;
+
+ rasops_reconfig(ri, dc->dc_yres / ri->ri_font->fontheight,
+ dc->dc_xres / ri->ri_font->fontwidth);
+
+ ri->ri_hw = scr;
+ ri->ri_ops.copyrows = newport_copyrows;
+ ri->ri_ops.eraserows = newport_eraserows;
+ ri->ri_ops.copycols = newport_copycols;
+ ri->ri_ops.erasecols = newport_erasecols;
+ ri->ri_ops.cursor = newport_cursor;
+ ri->ri_ops.mapchar = newport_mapchar;
+ ri->ri_ops.putchar = newport_putchar;
+ ri->ri_ops.allocattr = newport_allocattr;
+}
+
/**** wsdisplay textops ****/
static void
+newport_cursor_dummy(void *c, int on, int row, int col)
+{
+}
+
+static void
newport_cursor(void *c, int on, int row, int col)
{
- struct newport_devconfig *dc = (void *)c;
- uint16_t control;
- int x_offset;
-
- control = vc2_read_ireg(dc, VC2_IREG_CONTROL);
-
- if (!on) {
- vc2_write_ireg(dc, VC2_IREG_CONTROL,
- control & ~VC2_CONTROL_CURSOR_ENABLE);
- } else {
- /* Work around bug in some board revisions */
- if (dc->dc_boardrev < 6)
- x_offset = 21;
- else if (dc->dc_vc2rev == 0)
- x_offset = 29;
- else
- x_offset = 31;
-
- vc2_write_ireg(dc, VC2_IREG_CURSOR_X,
- col * dc->dc_fontdata->fontwidth + x_offset);
- vc2_write_ireg(dc, VC2_IREG_CURSOR_Y,
- row * dc->dc_fontdata->fontheight + 31);
-
- vc2_write_ireg(dc, VC2_IREG_CONTROL,
- control | VC2_CONTROL_CURSOR_ENABLE);
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
+ int x, y, wi,he;
+
+ wi = ri->ri_font->fontwidth;
+ he = ri->ri_font->fontheight;
+
+ if (ri->ri_flg & RI_CURSOR) {
+ x = ri->ri_ccol * wi + ri->ri_xorigin;
+ y = ri->ri_crow * he + ri->ri_yorigin;
+ newport_bitblt(dc, x, y, x, y, wi, he, 12);
+ ri->ri_flg &= ~RI_CURSOR;
+ }
+
+ ri->ri_crow = row;
+ ri->ri_ccol = col;
+
+ if (on)
+ {
+ x = ri->ri_ccol * wi + ri->ri_xorigin;
+ y = ri->ri_crow * he + ri->ri_yorigin;
+ newport_bitblt(dc, x, y, x, y, wi, he, 12);
+ ri->ri_flg |= RI_CURSOR;
}
}
static int
newport_mapchar(void *c, int ch, unsigned int *cp)
{
- struct newport_devconfig *dc = (void *)c;
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
ch = wsfont_map_unichar(dc->dc_fontdata, ch);
@@ -740,14 +733,16 @@
static void
newport_putchar(void *c, int row, int col, u_int ch, long attr)
{
- struct newport_devconfig *dc = (void *)c;
- struct wsdisplay_font *font = dc->dc_fontdata;
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
+ struct wsdisplay_font *font = ri->ri_font;
uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) *
font->fontheight * font->stride;
uint32_t pattern;
int i;
- int x = col * font->fontwidth;
- int y = row * font->fontheight;
+ int x = col * font->fontwidth + ri->ri_xorigin;
+ int y = row * font->fontheight + ri->ri_yorigin;
rex3_wait_gfifo(dc);
@@ -755,6 +750,16 @@
REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX |
REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE);
+ rex3_write(dc, REX3_REG_DRAWMODE1,
+ REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 |
+ REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 |
+ REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ |
+ REX3_DRAWMODE1_COMPARE_GT |
+ REX3_DRAWMODE1_LO_SRC);
+
rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y);
rex3_write(dc, REX3_REG_XYENDI,
(x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT);
@@ -764,7 +769,7 @@
rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
- for (i=0; i<font->fontheight; i++) {
+ for (i = 0; i < font->fontheight; i++) {
/* XXX Works only with font->fontwidth == 8 XXX */
pattern = *bitmap << 24;
@@ -777,29 +782,32 @@
static void
newport_copycols(void *c, int row, int srccol, int dstcol, int ncols)
{
- struct newport_devconfig *dc = (void *)c;
- struct wsdisplay_font *font = dc->dc_fontdata;
-
- newport_copy_rectangle(dc,
- srccol * font->fontwidth, /* x1 */
- row * font->fontheight, /* y1 */
- (srccol + ncols + 1) * font->fontwidth - 1, /* x2 */
- (row + 1) * font->fontheight - 1, /* y2 */
- dstcol * font->fontheight, /* dx */
- row * font->fontheight); /* dy */
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
+ int32_t xs, xd, y, width, height;
+
+ xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
+ xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
+ y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+ width = ri->ri_font->fontwidth * ncols;
+ height = ri->ri_font->fontheight;
+ newport_bitblt(dc, xs, y, xd, y, width, height, 3);
}
static void
newport_erasecols(void *c, int row, int startcol, int ncols,
long attr)
{
- struct newport_devconfig *dc = (void *)c;
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
struct wsdisplay_font *font = dc->dc_fontdata;
newport_fill_rectangle(dc,
startcol * font->fontwidth, /* x1 */
row * font->fontheight, /* y1 */
- (startcol + ncols + 1) * font->fontwidth - 1, /* x2 */
+ (startcol + ncols) * font->fontwidth - 1, /* x2 */
(row + 1) * font->fontheight - 1, /* y2 */
NEWPORT_ATTR_BG(attr));
}
@@ -807,29 +815,33 @@
static void
newport_copyrows(void *c, int srcrow, int dstrow, int nrows)
{
- struct newport_devconfig *dc = (void *)c;
- struct wsdisplay_font *font = dc->dc_fontdata;
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
+ int32_t x, ys, yd, width, height;
+
+ x = ri->ri_xorigin;
+ ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
+ yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
+ width = ri->ri_emuwidth;
+ height = ri->ri_font->fontheight * nrows;
- newport_copy_rectangle(dc,
- 0, /* x1 */
- srcrow * font->fontheight, /* y1 */
- dc->dc_xres, /* x2 */
- (srcrow + nrows + 1) * font->fontheight - 1, /* y2 */
- 0, /* dx */
- dstrow * font->fontheight); /* dy */
+ newport_bitblt(dc, x, ys, x, yd, width, height, 3);
}
static void
newport_eraserows(void *c, int startrow, int nrows, long attr)
{
- struct newport_devconfig *dc = (void *)c;
+ struct rasops_info *ri = c;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct newport_devconfig *dc = scr->scr_cookie;
struct wsdisplay_font *font = dc->dc_fontdata;
newport_fill_rectangle(dc,
0, /* x1 */
startrow * font->fontheight, /* y1 */
dc->dc_xres, /* x2 */
- (startrow + nrows + 1) * font->fontheight - 1, /* y2 */
+ (startrow + nrows) * font->fontheight - 1, /* y2 */
NEWPORT_ATTR_BG(attr));
}
@@ -861,56 +873,56 @@
/**** wsdisplay accessops ****/
static int
-newport_ioctl(void *c, void *vs, u_long cmd, void *data, int flag,
+newport_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
struct lwp *l)
{
- struct newport_softc *sc = c;
+ struct vcons_data *vd;
+ struct newport_devconfig *dc;
+ struct vcons_screen *ms;
+ int nmode;
+
+ vd = (struct vcons_data *)v;
+ dc = (struct newport_devconfig *)vd->cookie;
+ ms = (struct vcons_screen *)vd->active;
#define FBINFO (*(struct wsdisplay_fbinfo*)data)
switch (cmd) {
case WSDISPLAYIO_GINFO:
- FBINFO.width = sc->sc_dc->dc_xres;
- FBINFO.height = sc->sc_dc->dc_yres;
- FBINFO.depth = sc->sc_dc->dc_depth;
+ FBINFO.width = dc->dc_xres;
+ FBINFO.height = dc->dc_yres;
+ FBINFO.depth = dc->dc_depth;
FBINFO.cmsize = 1 << FBINFO.depth;
return 0;
case WSDISPLAYIO_GTYPE:
*(u_int *)data = WSDISPLAY_TYPE_NEWPORT;
return 0;
+ case WSDISPLAYIO_SMODE:
+ nmode = *(int *)data;
+ if (nmode != dc->dc_mode) {
+ dc->dc_mode = nmode;
+ if (nmode == WSDISPLAYIO_MODE_EMUL) {
+ rex3_wait_gfifo(dc);
+ newport_setup_hw(dc);
+ vcons_redraw_screen(vd->active);
+ }
+ }
+ return 0;
}
return EPASSTHROUGH;
}
static paddr_t
-newport_mmap(void *c, void *vs, off_t offset, int prot)
+newport_mmap(void *v, void *vs, off_t offset, int prot)
{
- struct newport_devconfig *dc = c;
+ struct vcons_data *vd;
+ struct newport_devconfig *dc;
+
+ vd = (struct vcons_data *)v;
+ dc = (struct newport_devconfig *)vd->cookie;
if ( offset >= 0xfffff)
return -1;
return mips_btop(dc->dc_addr + offset);
}
-
-static int
-newport_alloc_screen(void *c, const struct wsscreen_descr *type, void **cookiep,
- int *cursxp, int *cursyp, long *attrp)
-{
- /* This won't get called for console screen and we don't support
- * virtual screens */
-
- return ENOMEM;
-}
-
-static void
-newport_free_screen(void *c, void *cookie)
-{
- panic("newport_free_screen");
-}
-static int
-newport_show_screen(void *c, void *cookie, int waitok,
- void (*cb)(void *, int, int), void *cbarg)
-{
- return 0;
-}
Index: src/sys/arch/sgimips/gio/newportreg.h
diff -u src/sys/arch/sgimips/gio/newportreg.h:1.3 src/sys/arch/sgimips/gio/newportreg.h:1.3.96.1
--- src/sys/arch/sgimips/gio/newportreg.h:1.3 Sun Dec 11 12:18:53 2005
+++ src/sys/arch/sgimips/gio/newportreg.h Wed Dec 29 07:19:28 2010
@@ -1,5 +1,5 @@
-/* $NetBSD: newportreg.h,v 1.3 2005/12/11 12:18:53 christos Exp $ */
+/* $NetBSD: newportreg.h,v 1.3.96.1 2010/12/29 07:19:28 matt Exp $ */
/*
* Copyright (c) 2003 Ilpo Ruotsalainen
@@ -128,7 +128,13 @@
#define REX3_DRAWMODE0_LSADVLAST 0x00004000
#define REX3_DRAWMODE0_LENGTH32 0x00008000
#define REX3_DRAWMODE0_ZPOPAQUE 0x00010000
-
+#define REX3_DRAWMODE0_LSOPAQUE 0x00020000
+#define REX3_DRAWMODE0_SHADE 0x00040000
+#define REX3_DRAWMODE0_LRONLY 0x00080000
+#define REX3_DRAWMODE0_XYOFFSET 0x00100000
+#define REX3_DRAWMODE0_CICLAMP 0x00200000
+#define REX3_DRAWMODE0_ENDPTFILTER 0x00400000
+#define REX3_DRAWMODE0_YSTRIDE 0x00800000
#define REX3_REG_LSMODE 0x0008
#define REX3_REG_LSPATTERN 0x000c
Index: src/sys/arch/sgimips/hpc/files.hpc
diff -u src/sys/arch/sgimips/hpc/files.hpc:1.12 src/sys/arch/sgimips/hpc/files.hpc:1.12.78.1
--- src/sys/arch/sgimips/hpc/files.hpc:1.12 Sun Aug 27 10:05:23 2006
+++ src/sys/arch/sgimips/hpc/files.hpc Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-# $NetBSD: files.hpc,v 1.12 2006/08/27 10:05:23 bjh21 Exp $
+# $NetBSD: files.hpc,v 1.12.78.1 2010/12/29 07:19:28 matt Exp $
device sq: arp, ether, ifnet
attach sq at hpc
@@ -33,3 +33,6 @@
attach pi1ppc at hpc
file arch/sgimips/hpc/pi1ppc.c pi1ppc
+device panel : sysmon_power, sysmon_taskq
+attach panel at hpc
+file arch/sgimips/hpc/panel.c panel
Index: src/sys/arch/sgimips/hpc/haltwo.c
diff -u src/sys/arch/sgimips/hpc/haltwo.c:1.15 src/sys/arch/sgimips/hpc/haltwo.c:1.15.12.1
--- src/sys/arch/sgimips/hpc/haltwo.c:1.15 Sun Aug 24 13:03:39 2008
+++ src/sys/arch/sgimips/hpc/haltwo.c Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: haltwo.c,v 1.15 2008/08/24 13:03:39 tsutsui Exp $ */
+/* $NetBSD: haltwo.c,v 1.15.12.1 2010/12/29 07:19:28 matt Exp $ */
/*
* Copyright (c) 2003 Ilpo Ruotsalainen
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.15 2008/08/24 13:03:39 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.15.12.1 2010/12/29 07:19:28 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -609,6 +609,7 @@
dev->prev = dev->next = AUDIO_MIXER_LAST;
strcpy(dev->label.name, AudioNmaster);
dev->un.v.num_channels = 2;
+ dev->un.v.delta = 16;
strcpy(dev->un.v.units.name, AudioNvolume);
break;
Index: src/sys/arch/sgimips/hpc/hpc.c
diff -u src/sys/arch/sgimips/hpc/hpc.c:1.60.38.1 src/sys/arch/sgimips/hpc/hpc.c:1.60.38.2
--- src/sys/arch/sgimips/hpc/hpc.c:1.60.38.1 Wed Aug 26 03:46:40 2009
+++ src/sys/arch/sgimips/hpc/hpc.c Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: hpc.c,v 1.60.38.1 2009/08/26 03:46:40 matt Exp $ */
+/* $NetBSD: hpc.c,v 1.60.38.2 2010/12/29 07:19:28 matt Exp $ */
/*
* Copyright (c) 2000 Soren S. Jorvang
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.60.38.1 2009/08/26 03:46:40 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.60.38.2 2010/12/29 07:19:28 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -214,6 +214,12 @@
-1,
HPCDEV_IP22 | HPCDEV_IP24 },
+ { "panel", /* Indy front panel */
+ HPC_BASE_ADDRESS_0,
+ HPC3_PBUS_CH6_DEVREGS + IOC_PANEL, 0,
+ 9,
+ HPCDEV_IP24 },
+
{ NULL,
0,
0, 0,
Index: src/sys/arch/sgimips/ioc/ioc.c
diff -u src/sys/arch/sgimips/ioc/ioc.c:1.7 src/sys/arch/sgimips/ioc/ioc.c:1.7.38.1
--- src/sys/arch/sgimips/ioc/ioc.c:1.7 Wed Oct 17 19:57:05 2007
+++ src/sys/arch/sgimips/ioc/ioc.c Wed Dec 29 07:19:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ioc.c,v 1.7 2007/10/17 19:57:05 garbled Exp $ */
+/* $NetBSD: ioc.c,v 1.7.38.1 2010/12/29 07:19:28 matt Exp $ */
/*
* Copyright (c) 2003 Christopher Sekiya
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ioc.c,v 1.7 2007/10/17 19:57:05 garbled Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ioc.c,v 1.7.38.1 2010/12/29 07:19:28 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -140,10 +140,13 @@
IOC_WRITE_ENET_AUTO | IOC_WRITE_ENET_UTP |
IOC_WRITE_PC_UART2 | IOC_WRITE_PC_UART1);
+/* XXX: the firmware should have taken care of this already */
+#if 0
if (mach_subtype == MACH_SGI_IP22_GUINNESS) {
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IOC_GCSEL, 0xff);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IOC_GCREG, 0xff);
}
+#endif
#if defined(BLINK)
ioc_blink(sc);
Added files:
Index: src/sys/arch/sgimips/hpc/panel.c
diff -u /dev/null src/sys/arch/sgimips/hpc/panel.c:1.1.10.2
--- /dev/null Wed Dec 29 07:19:28 2010
+++ src/sys/arch/sgimips/hpc/panel.c Wed Dec 29 07:19:28 2010
@@ -0,0 +1,149 @@
+/* $NetBSD: panel.c,v 1.1.10.2 2010/12/29 07:19:28 matt Exp $ */
+
+/*-
+ * Copyright (c) 2009 Michael Lorenz
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: panel.c,v 1.1.10.2 2010/12/29 07:19:28 matt Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+
+#include <sys/bus.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_taskq.h>
+
+#include <machine/autoconf.h>
+#include <machine/machtype.h>
+
+#include <sgimips/ioc/iocreg.h>
+#include <sgimips/hpc/hpcvar.h>
+#include <sgimips/hpc/hpcreg.h>
+
+struct panel_softc {
+ device_t sc_dev;
+ struct sysmon_pswitch sc_pbutton;
+ bus_space_tag_t sc_tag;
+ bus_space_handle_t sc_hreg;
+ int sc_last, sc_fired;
+};
+
+static int panel_match(device_t, cfdata_t, void *);
+static void panel_attach(device_t, device_t, void *);
+
+static int panel_intr(void *);
+static void panel_powerbutton(void *);
+
+CFATTACH_DECL_NEW(panel, sizeof(struct panel_softc),
+ panel_match,
+ panel_attach,
+ NULL,
+ NULL);
+
+static int
+panel_match(device_t parent, cfdata_t match, void *aux)
+{
+ if (mach_type == MACH_SGI_IP22)
+ return 1;
+
+ return 0;
+}
+
+static void
+panel_attach(device_t parent, device_t self, void *aux)
+{
+ struct panel_softc *sc;
+ struct hpc_attach_args *haa;
+
+ sc = device_private(self);
+ sc->sc_dev = self;
+ haa = aux;
+ sc->sc_tag = haa->ha_st;
+ sc->sc_fired = 0;
+
+ aprint_normal("\n");
+ if (bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff,
+ 0x1, /* just a single register */
+ &sc->sc_hreg)) {
+ aprint_error(": unable to map panel register\n");
+ return;
+ }
+
+ if ((cpu_intr_establish(haa->ha_irq, IPL_BIO,
+ panel_intr, sc)) == NULL) {
+ printf(": unable to establish interrupt!\n");
+ return;
+ }
+
+ sc->sc_last = 0;
+
+ sysmon_task_queue_init();
+ memset(&sc->sc_pbutton, 0, sizeof(struct sysmon_pswitch));
+ sc->sc_pbutton.smpsw_name = device_xname(sc->sc_dev);
+ sc->sc_pbutton.smpsw_type = PSWITCH_TYPE_POWER;
+ if (sysmon_pswitch_register(&sc->sc_pbutton) != 0)
+ aprint_error_dev(sc->sc_dev,
+ "unable to register power button with sysmon\n");
+ pmf_device_register(self, NULL, NULL);
+}
+
+static int
+panel_intr(void *cookie)
+{
+ struct panel_softc *sc = cookie;
+ uint8_t reg;
+
+ reg = bus_space_read_1(sc->sc_tag, sc->sc_hreg, 0);
+ bus_space_write_1(sc->sc_tag, sc->sc_hreg, 0,
+ IOC_PANEL_VDOWN_IRQ | IOC_PANEL_VUP_IRQ | IOC_PANEL_POWER_IRQ);
+ if ((reg & IOC_PANEL_POWER_IRQ) == 0) {
+ if (!sc->sc_fired)
+ sysmon_task_queue_sched(0, panel_powerbutton, sc);
+ sc->sc_fired = 1;
+ }
+ if (time_second == sc->sc_last)
+ return 1;
+ sc->sc_last = time_second;
+ if ((reg & IOC_PANEL_VDOWN_HOLD) == 0)
+ pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_DOWN);
+ if ((reg & IOC_PANEL_VUP_HOLD) == 0)
+ pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_UP);
+
+ return 1;
+}
+
+static void
+panel_powerbutton(void *cookie)
+{
+ struct panel_softc *sc = cookie;
+
+ sysmon_pswitch_event(&sc->sc_pbutton, PSWITCH_EVENT_PRESSED);
+}