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);
+}

Reply via email to