Module Name:    src
Committed By:   hkenken
Date:           Tue May  6 11:22:53 UTC 2014

Modified Files:
        src/sys/arch/arm/imx: files.imx51 imx51_ipuv3.c imx51_ipuv3var.h
        src/sys/arch/evbarm/conf: NETWALKER files.netwalker
        src/sys/arch/evbarm/netwalker: netwalker_lcd.c netwalker_machdep.c
            netwalker_start.S
Added Files:
        src/sys/arch/arm/imx: imx51_pwm.c imxpwm.c imxpwmreg.h imxpwmvar.h
        src/sys/arch/evbarm/netwalker: netwalker_backlight.c
            netwalker_backlightvar.h

Log Message:
Add support for LCD Backlight control on NetWalker.
+ use imxpwm driver (PWM control driver for i.MX)


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/imx/files.imx51
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imx51_ipuv3.c \
    src/sys/arch/arm/imx/imx51_ipuv3var.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imx51_pwm.c \
    src/sys/arch/arm/imx/imxpwm.c src/sys/arch/arm/imx/imxpwmreg.h \
    src/sys/arch/arm/imx/imxpwmvar.h
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/evbarm/conf/NETWALKER
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbarm/conf/files.netwalker
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/netwalker/netwalker_backlight.c \
    src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/netwalker/netwalker_lcd.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/evbarm/netwalker/netwalker_machdep.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/netwalker/netwalker_start.S

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/arm/imx/files.imx51
diff -u src/sys/arch/arm/imx/files.imx51:1.8 src/sys/arch/arm/imx/files.imx51:1.9
--- src/sys/arch/arm/imx/files.imx51:1.8	Sat Mar 22 09:28:08 2014
+++ src/sys/arch/arm/imx/files.imx51	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx51,v 1.8 2014/03/22 09:28:08 hkenken Exp $
+#	$NetBSD: files.imx51,v 1.9 2014/05/06 11:22:53 hkenken Exp $
 #
 # Configuration info for the Freescale i.MX51
 #
@@ -123,3 +123,8 @@ defparam opt_imxspi.h				IMXSPI_DEBUG
 # iis sound Controller (SSI module)
 # device	imxi2s {} : bus_dma_generic
 # file	arch/arm/imx/imx51_i2s.c		imxi2s needs-flag
+
+# PWM controlloer
+device	imxpwm
+file	arch/arm/imx/imxpwm.c			imxpwm
+file	arch/arm/imx/imx51_pwm.c		imxpwm

Index: src/sys/arch/arm/imx/imx51_ipuv3.c
diff -u src/sys/arch/arm/imx/imx51_ipuv3.c:1.1 src/sys/arch/arm/imx/imx51_ipuv3.c:1.2
--- src/sys/arch/arm/imx/imx51_ipuv3.c:1.1	Tue Apr 17 10:19:57 2012
+++ src/sys/arch/arm/imx/imx51_ipuv3.c	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_ipuv3.c,v 1.1 2012/04/17 10:19:57 bsh Exp $	*/
+/*	$NetBSD: imx51_ipuv3.c,v 1.2 2014/05/06 11:22:53 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2011, 2012  Genetec Corporation.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.c,v 1.1 2012/04/17 10:19:57 bsh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.c,v 1.2 2014/05/06 11:22:53 hkenken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.
 #include <sys/uio.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>			/* for cold */
+#include <sys/pmf.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -66,7 +67,10 @@ __KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.
  * before devices get attached.
  */
 struct {
-	int				is_console;
+	int is_console;
+	struct imx51_wsscreen_descr *descr;
+	struct wsdisplay_accessops *accessops;
+	const struct lcd_panel_geometry *geom;
 } imx51_ipuv3_console;
 
 #define	IPUV3_READ(ipuv3, module, reg)					      \
@@ -92,45 +96,8 @@ static void imx51_ipuv3_setup_rasops(str
 #endif
 static void imx51_ipuv3_set_idma_param(uint32_t *, uint32_t, uint32_t);
 
-#if NWSDISPLAY > 0
-/*
- * wsdisplay glue
- */
-static struct imx51_wsscreen_descr imx51_ipuv3_stdscreen = {
-	.c = {
-		.name	      = "std",
-		.ncols	      = 0,
-		.nrows	      = 0,
-		.textops      = NULL,
-		.fontwidth    = 8,
-		.fontheight   = 16,
-		.capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
-		.modecookie   = NULL
-	},
-	.depth = 16,		/* bits per pixel */
-	.flags = RI_CENTER | RI_FULLCLEAR
-};
-
-static const struct wsscreen_descr *imx51_ipuv3_scr_descr[] = {
-	&imx51_ipuv3_stdscreen.c,
-};
-
-const struct wsscreen_list imx51_ipuv3_screen_list = {
-	sizeof imx51_ipuv3_scr_descr / sizeof imx51_ipuv3_scr_descr[0],
-	imx51_ipuv3_scr_descr
-};
-
-struct wsdisplay_accessops imx51_ipuv3_accessops = {
-	.ioctl	      = imx51_ipuv3_ioctl,
-	.mmap	      = imx51_ipuv3_mmap,
-	.alloc_screen = NULL,
-	.free_screen  = NULL,
-	.show_screen  = NULL,
-	.load_font    = NULL,
-	.pollc	      = NULL,
-	.scroll	      = NULL
-};
-#endif
+static bool imx51_ipuv3_resume(device_t, const pmf_qual_t *);
+static bool imx51_ipuv3_suspend(device_t, const pmf_qual_t *);
 
 #ifdef IPUV3_DEBUG
 static void
@@ -621,7 +588,7 @@ imx51_ipuv3_init_screen(void *cookie, st
 
 	struct imx51_ipuv3_softc *sc = cookie;
 	struct rasops_info *ri = &scr->scr_ri;
-	struct imx51_wsscreen_descr *descr = &imx51_ipuv3_stdscreen;
+	struct imx51_wsscreen_descr *descr = imx51_ipuv3_console.descr;
 
 	if ((scr == &sc->console) && (sc->vd.active != NULL))
 		return;
@@ -726,7 +693,7 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	imx51_ipuv3_initialize(sc, geom);
 
 #if NWSDISPLAY > 0
-	struct imx51_wsscreen_descr *descr = &imx51_ipuv3_stdscreen;
+	struct imx51_wsscreen_descr *descr = imx51_ipuv3_console.descr;
 	struct imx51_ipuv3_screen *scr;
 
 	sc->mode = WSDISPLAYIO_MODE_EMUL;
@@ -738,8 +705,8 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	}
 	sc->active = scr;
 
-	vcons_init(&sc->vd, sc, &imx51_ipuv3_stdscreen.c,
-	    &imx51_ipuv3_accessops);
+	vcons_init(&sc->vd, sc, &descr->c,
+	    imx51_ipuv3_console.accessops);
 	sc->vd.init_screen = imx51_ipuv3_init_screen;
 
 #ifdef IPUV3_DEBUG
@@ -750,39 +717,30 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	long defattr;
 	ri = &sc->console.scr_ri;
 
-	if (imx51_ipuv3_console.is_console) {
-		vcons_init_screen(&sc->vd, &sc->console, 1,
-		    &defattr);
-		sc->console.scr_flags |= VCONS_SCREEN_IS_STATIC;
-
-		imx51_ipuv3_stdscreen.c.nrows = ri->ri_rows;
-		imx51_ipuv3_stdscreen.c.ncols = ri->ri_cols;
-		imx51_ipuv3_stdscreen.c.textops = &ri->ri_ops;
-		imx51_ipuv3_stdscreen.c.capabilities = ri->ri_caps;
+	vcons_init_screen(&sc->vd, &sc->console, 1,
+	    &defattr);
+	sc->console.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+	descr->c.nrows = ri->ri_rows;
+	descr->c.ncols = ri->ri_cols;
+	descr->c.textops = &ri->ri_ops;
+	descr->c.capabilities = ri->ri_caps;
 
+	if (imx51_ipuv3_console.is_console) {
 		wsdisplay_cnattach(&descr->c, ri, 0, 0, defattr);
-		vcons_replay_msgbuf(&sc->console);
-
-		imx51_ipuv3_start_dma(sc, scr);
-
 		aprint_normal_dev(sc->dev, "console\n");
-	} else {
-		/*
-		 * since we're not the console we can postpone the rest
-		 * until someone actually allocates a screen for us
-		 */
-		(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
 	}
 
-	struct wsemuldisplaydev_attach_args aa;
-	aa.console = imx51_ipuv3_console.is_console;
-	aa.scrdata = &imx51_ipuv3_screen_list;
-	aa.accessops = &imx51_ipuv3_accessops;
-	aa.accesscookie = &sc->vd;
+	vcons_replay_msgbuf(&sc->console);
 
-	config_found(sc->dev, &aa, wsemuldisplaydevprint);
+	imx51_ipuv3_start_dma(sc, scr);
 #endif
 
+	if (!pmf_device_register(sc->dev, imx51_ipuv3_suspend,
+		imx51_ipuv3_resume)) {
+		aprint_error_dev(sc->dev, "can't establish power hook\n");
+	}
+
 	return;
 
 fail_retarn_dctmpl:
@@ -806,10 +764,15 @@ fail_retarn_cm:
 }
 
 int
-imx51_ipuv3_cnattach(const struct lcd_panel_geometry *geom)
+imx51_ipuv3_cnattach(bool isconsole, struct imx51_wsscreen_descr *descr,
+    struct wsdisplay_accessops *accessops,
+    const struct lcd_panel_geometry *geom)
 {
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-	imx51_ipuv3_console.is_console = 1;
+	imx51_ipuv3_console.descr = descr;
+	imx51_ipuv3_console.geom = geom;
+	imx51_ipuv3_console.accessops = accessops;
+	imx51_ipuv3_console.is_console = isconsole;
 	return 0;
 }
 
@@ -1161,58 +1124,127 @@ imx51_ipuv3_setup_rasops(struct imx51_ip
 /*
  * Power management
  */
-void
-imx51_ipuv3_suspend(struct imx51_ipuv3_softc *sc)
+static bool
+imx51_ipuv3_suspend(device_t dv, const pmf_qual_t *qual)
 {
+	struct imx51_ipuv3_softc *sc = device_private(dv);
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	if (sc->active) {
+	if (sc->active)
 		imx51_ipuv3_stop_dma(sc);
-	}
+	return true;
 }
 
-void
-imx51_ipuv3_resume(struct imx51_ipuv3_softc *sc)
+static bool
+imx51_ipuv3_resume(device_t dv, const pmf_qual_t *qual)
 {
+	struct imx51_ipuv3_softc *sc = device_private(dv);
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
 	if (sc->active) {
 		imx51_ipuv3_initialize(sc, sc->geometry);
 		imx51_ipuv3_start_dma(sc, sc->active);
 	}
+	return true;
+}
+
+#if NWSDISPLAY > 0
+int
+imx51_ipuv3_show_screen(void *v, void *cookie, int waitok,
+    void (*cb)(void *, int, int), void *cbarg)
+{
+	struct vcons_data *vd = v;
+	struct imx51_ipuv3_softc *sc = vd->cookie;
+	struct imx51_ipuv3_screen *scr = cookie, *old;
+	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+	old = sc->active;
+	if (old == scr)
+		return 0;
+	if (old)
+		imx51_ipuv3_stop_dma(sc);
+	imx51_ipuv3_start_dma(sc, scr);
+	sc->active = scr;
+	return 0;
+}
+
+int
+imx51_ipuv3_alloc_screen(void *v, const struct wsscreen_descr *_type,
+    void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+	struct vcons_data *vd = v;
+	struct imx51_ipuv3_softc *sc = vd->cookie;
+	struct imx51_ipuv3_screen *scr;
+	const struct imx51_wsscreen_descr *type =
+		(const struct imx51_wsscreen_descr *)_type;
+	int error;
+	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+	error = imx51_ipuv3_new_screen(sc, type->depth, &scr);
+	if (error)
+		return error;
+
+	/*
+	 * initialize raster operation for this screen.
+	 */
+	scr->rinfo.ri_flg = 0;
+	scr->rinfo.ri_depth = type->depth;
+	scr->rinfo.ri_bits = scr->buf_va;
+	scr->rinfo.ri_width = sc->geometry->panel_width;
+	scr->rinfo.ri_height = sc->geometry->panel_height;
+	scr->rinfo.ri_stride = scr->rinfo.ri_width * scr->rinfo.ri_depth / 8;
+#ifdef CPU_XSCALE_PXA270
+	if (scr->rinfo.ri_depth > 16)
+		scr->rinfo.ri_stride = scr->rinfo.ri_width * 4;
+#endif
+	scr->rinfo.ri_wsfcookie = -1;	/* XXX */
+
+	rasops_init(&scr->rinfo, type->c.nrows, type->c.ncols);
+
+	(*scr->rinfo.ri_ops.allocattr)(&scr->rinfo, 0, 0, 0, attrp);
+
+	*cookiep = scr;
+	*curxp = 0;
+	*curyp = 0;
+
+	return 0;
 }
 
 void
-imx51_ipuv3_power(int why, void *v)
+imx51_ipuv3_free_screen(void *v, void *cookie)
 {
+	struct vcons_data *vd = v;
+	struct imx51_ipuv3_softc *sc = vd->cookie;
+	struct imx51_ipuv3_screen *scr = cookie;
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
 
-	struct imx51_ipuv3_softc *sc = v;
+	LIST_REMOVE(scr, link);
+	sc->n_screens--;
+	if (scr == sc->active) {
+		/* at first, we need to stop LCD DMA */
+		sc->active = NULL;
 
-	switch (why) {
-	case PWR_SUSPEND:
-	case PWR_STANDBY:
-		imx51_ipuv3_suspend(sc);
-		break;
+		printf("lcd_free on active screen\n");
 
-	case PWR_RESUME:
-		imx51_ipuv3_resume(sc);
-		break;
+		imx51_ipuv3_stop_dma(sc);
 	}
+
+	if (scr->buf_va)
+		bus_dmamem_unmap(sc->dma_tag, scr->buf_va, scr->map_size);
+	if (scr->nsegs > 0)
+		bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
+	free(scr, M_DEVBUF);
 }
 
-#if NWSDISPLAY > 0
 int
 imx51_ipuv3_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
     struct lwp *l)
 {
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
 	struct vcons_data *vd = v;
 	struct imx51_ipuv3_softc *sc = vd->cookie;
 	struct wsdisplay_fbinfo *wsdisp_info;
 	struct vcons_screen *ms = vd->active;
 
+	DPRINTFN(5, ("%s : cmd 0x%X (%d)\n", __func__, (u_int)cmd, (int)IOCGROUP(cmd)));
+
 	switch (cmd) {
 	case WSDISPLAYIO_GTYPE:
 		*(int *)data = WSDISPLAY_TYPE_IMXIPU;
Index: src/sys/arch/arm/imx/imx51_ipuv3var.h
diff -u src/sys/arch/arm/imx/imx51_ipuv3var.h:1.1 src/sys/arch/arm/imx/imx51_ipuv3var.h:1.2
--- src/sys/arch/arm/imx/imx51_ipuv3var.h:1.1	Tue Apr 17 10:19:57 2012
+++ src/sys/arch/arm/imx/imx51_ipuv3var.h	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_ipuv3var.h,v 1.1 2012/04/17 10:19:57 bsh Exp $	*/
+/*	$NetBSD: imx51_ipuv3var.h,v 1.2 2014/05/06 11:22:53 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2009, 2011, 2012  Genetec Corporation.  All rights reserved.
@@ -51,6 +51,9 @@ struct imx51_ipuv3_screen {
 	/* DMA frame descriptor */
 	struct	ipuv3_dma_descriptor *dma_desc;
 	paddr_t	dma_desc_pa;
+
+	/* rasterop */
+	struct rasops_info rinfo;
 };
 
 struct lcd_panel_geometry {
@@ -116,7 +119,9 @@ struct imx51_ipuv3_softc;
 
 void	imx51_ipuv3_attach_sub(struct imx51_ipuv3_softc *,
 	    struct axi_attach_args *, const struct lcd_panel_geometry *);
-int	imx51_ipuv3_cnattach(const struct lcd_panel_geometry *);
+int	imx51_ipuv3_cnattach(bool, struct imx51_wsscreen_descr *,
+	    struct wsdisplay_accessops *,
+	    const struct lcd_panel_geometry *);
 void	imx51_ipuv3_start_dma(struct imx51_ipuv3_softc *,
 	    struct imx51_ipuv3_screen *);
 
@@ -125,12 +130,13 @@ void	imx51_ipuv3_geometry(struct imx51_i
 int	imx51_ipuv3_new_screen(struct imx51_ipuv3_softc *, int,
 	    struct imx51_ipuv3_screen **);
 
+int	imx51_ipuv3_alloc_screen(void *, const struct wsscreen_descr *,
+	    void **, int *, int *, long *);
+void	imx51_ipuv3_free_screen(void *, void *);
 int	imx51_ipuv3_ioctl(void *, void *, u_long, void *, int, struct lwp *);
 paddr_t	imx51_ipuv3_mmap(void *, void *, off_t, int);
-
-void	imx51_ipuv3_power(int, void *);
-void	imx51_ipuv3_suspend(struct imx51_ipuv3_softc *);
-void	imx51_ipuv3_resume(struct imx51_ipuv3_softc *);
+int	imx51_ipuv3_show_screen(void *, void *, int, void (*)(void *, int, int),
+	    void *);
 
 extern const struct wsdisplay_emulops imx51_ipuv3_emulops;
 

Index: src/sys/arch/evbarm/conf/NETWALKER
diff -u src/sys/arch/evbarm/conf/NETWALKER:1.26 src/sys/arch/evbarm/conf/NETWALKER:1.27
--- src/sys/arch/evbarm/conf/NETWALKER:1.26	Tue May  6 11:08:51 2014
+++ src/sys/arch/evbarm/conf/NETWALKER	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: NETWALKER,v 1.26 2014/05/06 11:08:51 hkenken Exp $
+#	$NetBSD: NETWALKER,v 1.27 2014/05/06 11:22:53 hkenken Exp $
 #
 #	NETWALKER -- http://www.sharp.co.jp/netwalker/
 #
@@ -236,6 +236,7 @@ wsmouse*	at mousebtn? mux 0
 
 pwrbtn0		at gpio1 offset 21 mask 0x01 # intr 181
 lidsw0		at gpio3 offset 12 mask 0x01 # intr 236
+imxpwm0		at axi? addr 0x73FB4000 irq 61
 
 # SPI NOR-Flash
 #spiflash0	at spiflashbus?

Index: src/sys/arch/evbarm/conf/files.netwalker
diff -u src/sys/arch/evbarm/conf/files.netwalker:1.6 src/sys/arch/evbarm/conf/files.netwalker:1.7
--- src/sys/arch/evbarm/conf/files.netwalker:1.6	Tue May  6 11:08:51 2014
+++ src/sys/arch/evbarm/conf/files.netwalker	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: files.netwalker,v 1.6 2014/05/06 11:08:51 hkenken Exp $
+#	$NetBSD: files.netwalker,v 1.7 2014/05/06 11:22:53 hkenken Exp $
 #
 # Sharp Netwalker configuration info
 #
@@ -44,6 +44,10 @@ device	lidsw: sysmon_envsys
 attach	lidsw at gpio with netwalker_lid
 file	arch/evbarm/netwalker/netwalker_lid.c	netwalker_lid
 
+# LCD BackLight
+attach	imxpwm at axi with netwalker_backlight
+file	arch/evbarm/netwalker/netwalker_backlight.c	netwalker_backlight
+
 # OJ6SH-T25 Optical Joystick
 device  oj6sh: wsmousedev
 attach  oj6sh at spi

Index: src/sys/arch/evbarm/netwalker/netwalker_lcd.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.2 src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.3
--- src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.2	Sun Mar 16 05:20:24 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_lcd.c	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_lcd.c,v 1.2 2014/03/16 05:20:24 dholland Exp $	*/
+/*	$NetBSD: netwalker_lcd.c,v 1.3 2014/05/06 11:22:53 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2011, 2012 Genetec corp. All rights reserved.
@@ -25,12 +25,24 @@
  * 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: netwalker_lcd.c,v 1.3 2014/05/06 11:22:53 hkenken Exp $");
+
+#include "opt_imx51_ipuv3.h"
+#include "opt_netwalker_lcd.h"
+
+#include "wsdisplay.h"
+#include "ioconf.h"
+#include "netwalker_backlight.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/uio.h>
 #include <sys/malloc.h>
 #include <sys/device.h>
+#include <sys/pmf.h>
 
 #include <dev/cons.h>
 #include <dev/wscons/wsconsio.h>
@@ -42,14 +54,9 @@
 #include <arm/imx/imx51reg.h>
 #include <arm/imx/imx51_ipuv3var.h>
 #include <arm/imx/imx51_ipuv3reg.h>
-#include <arm/imx/imx51_iomuxreg.h>
 #include <arm/imx/imxgpiovar.h>
 
-#include "opt_imx51_ipuv3.h"
-#include "opt_netwalker_lcd.h"
-
-#include "wsdisplay.h"
-#include "ioconf.h"
+#include <evbarm/netwalker/netwalker_backlightvar.h>
 
 int lcd_match(device_t, cfdata_t, void *);
 void lcd_attach(device_t, device_t, void *);
@@ -57,6 +64,50 @@ void lcd_attach(device_t, device_t, void
 void netwalker_cnattach(void);
 
 #if NWSDISPLAY > 0
+static int netwalker_lcd_ioctl(void *, void *, u_long, void *, int,
+    struct lwp *);
+static int netwalker_lcd_show_screen(void *, void *, int,
+    void (*)(void *, int, int), void *);
+
+bool netwalker_lcd_console = 0;
+
+/*
+ * wsdisplay glue
+ */
+static struct imx51_wsscreen_descr netwalker_lcd_stdscreen = {
+	.c = {
+		.name	      = "std",
+		.ncols	      = 0,
+		.nrows	      = 0,
+		.textops      = NULL,
+		.fontwidth    = 8,
+		.fontheight   = 16,
+		.capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
+		.modecookie   = NULL
+	},
+	.depth = 16,		/* bits per pixel */
+	.flags = RI_CENTER | RI_FULLCLEAR
+};
+
+static const struct wsscreen_descr *netwalker_lcd_scr_descr[] = {
+	&netwalker_lcd_stdscreen.c,
+};
+
+const struct wsscreen_list netwalker_lcd_screen_list = {
+	sizeof netwalker_lcd_scr_descr / sizeof netwalker_lcd_scr_descr[0],
+	netwalker_lcd_scr_descr
+};
+
+struct wsdisplay_accessops netwalker_lcd_accessops = {
+	.ioctl	      = netwalker_lcd_ioctl,
+	.mmap	      = imx51_ipuv3_mmap,
+	.alloc_screen = imx51_ipuv3_alloc_screen,
+	.free_screen  = imx51_ipuv3_free_screen,
+	.show_screen  = netwalker_lcd_show_screen,
+	.load_font    = NULL,
+	.pollc	      = NULL,
+	.scroll	      = NULL
+};
 #else
 #ifdef LCD_DEBUG
 static void draw_test_pattern(struct imx51_ipuv3_softc *,
@@ -116,8 +167,6 @@ static const struct lcd_panel_geometry s
 	.panel_info = 0,
 };
 
-#define PANEL	sharp_panel
-
 void lcd_attach( device_t parent, device_t self, void *aux )
 {
 	struct imx51_ipuv3_softc *sc = device_private(self);
@@ -126,13 +175,11 @@ void lcd_attach( device_t parent, device
 
 	sc->dev = self;
 
-#if (NWSDISPLAY > 0) && defined(IMXIPUCONSOLE)
-	netwalker_cnattach();
+#if defined(IMXIPUCONSOLE)
+	netwalker_lcd_console = 1;
 #endif
-
-#if 0
-	/* IOMUX registers are already set correctly for LCD display */
-	iomux_mux_config(iomux_ipuv3_config);
+#if (NWSDISPLAY > 0)
+	netwalker_cnattach();
 #endif
 
 	/* XXX move this to imx51_ipuv3.c */
@@ -163,29 +210,36 @@ void lcd_attach( device_t parent, device
 	delay(180 * 1000);
 	gpio_data_write(GPIO_NO(4, 10), 1);
 
-	/* pwm pin (100%) */
-	gpio_set_direction(GPIO_NO(1, 2), GPIO_DIR_OUT);
-	gpio_data_write(GPIO_NO(1, 2), 1);
-
 	gpio_set_direction(GPIO_NO(2, 13), GPIO_DIR_OUT);
 	gpio_data_write(GPIO_NO(2, 13), 1);
 
-	imx51_ipuv3_attach_sub(sc, aux, &PANEL);
+	imx51_ipuv3_attach_sub(sc, aux, &sharp_panel);
 
 #if NWSDISPLAY == 0
-	{
-		struct imx51_ipuv3_screen *screen;
-		int error;
+	struct imx51_ipuv3_screen *screen;
+	int error;
 
-		error = imx51_ipuv3_new_screen(sc, 16, &screen);
+	error = imx51_ipuv3_new_screen(sc, 16, &screen);
 #ifdef LCD_DEBUG
-		draw_test_pattern(sc, screen);
+	draw_test_pattern(sc, screen);
 #endif
-		if (error == 0) {
-			sc->active = screen;
-			imx51_ipuv3_start_dma(sc, screen);
-		}
+	if (error == 0) {
+		sc->active = screen;
+		imx51_ipuv3_start_dma(sc, screen);
 	}
+#else
+	struct wsemuldisplaydev_attach_args aa;
+
+#if defined(IMXIPUCONSOLE)
+	aa.console = true;
+#else
+	aa.console = false;
+#endif
+	aa.scrdata = &netwalker_lcd_screen_list;
+	aa.accessops = &netwalker_lcd_accessops;
+	aa.accesscookie = &sc->vd;
+
+	(void) config_found(sc->dev, &aa, wsemuldisplaydevprint);
 #endif
 }
 
@@ -193,9 +247,45 @@ void lcd_attach( device_t parent, device
 void
 netwalker_cnattach(void)
 {
-	imx51_ipuv3_cnattach(&PANEL);
+	imx51_ipuv3_cnattach(netwalker_lcd_console, &netwalker_lcd_stdscreen,
+	    &netwalker_lcd_accessops, &sharp_panel);
 	return;
 }
+
+/*
+ * wsdisplay accessops overrides
+ */
+static int
+netwalker_lcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	int res = EINVAL;
+
+	switch (cmd) {
+#if NNETWALKER_BACKLIGHT > 0
+	case WSDISPLAYIO_GETPARAM:
+	case WSDISPLAYIO_SETPARAM:
+		res = netwalker_lcd_param_ioctl(cmd, (struct wsdisplay_param *)data);
+		break;
+#endif
+	}
+
+	if (res == EINVAL)
+		res = imx51_ipuv3_ioctl(v, vs, cmd, data, flag, l);
+	return res;
+}
+
+static int
+netwalker_lcd_show_screen(void *v, void *cookie, int waitok,
+    void (*cb_func)(void *, int, int), void *cb_arg)
+{
+	int error;
+
+	error = imx51_ipuv3_show_screen(v, cookie, waitok, cb_func, cb_arg);
+	if (error)
+		return (error);
+
+	return 0;
+}
 #else
 
 int

Index: src/sys/arch/evbarm/netwalker/netwalker_machdep.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.15 src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.16
--- src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.15	Wed Apr  9 04:00:50 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_machdep.c	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_machdep.c,v 1.15 2014/04/09 04:00:50 hkenken Exp $	*/
+/*	$NetBSD: netwalker_machdep.c,v 1.16 2014/05/06 11:22:53 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005, 2010  Genetec Corporation.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.15 2014/04/09 04:00:50 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.16 2014/05/06 11:22:53 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_cputypes.h"
@@ -115,6 +115,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma
 #include "opt_imx.h"
 #include "opt_imx51_ipuv3.h"
 #include "wsdisplay.h"
+#include "opt_machdep.h"
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -448,18 +449,16 @@ const struct iomux_setup iomux_setup_dat
 	IOMUX_DATA(IOMUXC_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT, INPUT_DAISY_0),
 	IOMUX_MP(CSI2_D12, ALT3, KEEPER | DSEHIGH | SRE), /* GPIO4_9 */
 	IOMUX_MP(CSI2_D13, ALT3, KEEPER | DSEHIGH | SRE),
-	IOMUX_MP(GPIO1_2, ALT0, ODE | DSEHIGH),
+#if 1
+	IOMUX_MP(GPIO1_2, ALT1, DSEHIGH | ODE),	/* LCD backlight by PWM */
+#else
+	IOMUX_MP(GPIO1_2, ALT0, DSEHIGH | ODE),	/* LCD backlight by GPIO */
+#endif
 	IOMUX_MP(EIM_A19, ALT1, SRE | DSEHIGH),
 	/* XXX VGA pins */
 	IOMUX_M(DI_GP4, ALT4),
 	IOMUX_M(GPIO1_8, SION | ALT0),
 
-
-#if 0
-	IOMUX_MP(GPIO1_2, ALT1, DSEHIGH | ODE),	/* LCD backlight by PWM */
-#else
-	IOMUX_P(GPIO1_2, DSEHIGH | ODE),	/* LCD backlight by GPIO */
-#endif
 	IOMUX_MP(GPIO1_8, SION | ALT0, HYS | DSEMID | PU_100K),
 	/* I2C1 */
 	IOMUX_MP(EIM_D16, SION | ALT4, HYS | ODE | DSEHIGH | SRE),

Index: src/sys/arch/evbarm/netwalker/netwalker_start.S
diff -u src/sys/arch/evbarm/netwalker/netwalker_start.S:1.4 src/sys/arch/evbarm/netwalker/netwalker_start.S:1.5
--- src/sys/arch/evbarm/netwalker/netwalker_start.S:1.4	Wed Apr  9 12:35:34 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_start.S	Tue May  6 11:22:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_start.S,v 1.4 2014/04/09 12:35:34 hkenken Exp $	*/
+/*	$NetBSD: netwalker_start.S,v 1.5 2014/05/06 11:22:53 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2009 SHIMIZU Ryo <r...@nerv.org>
@@ -66,7 +66,7 @@
 #include <arm/imx/imxuartreg.h>
 #include <evbarm/netwalker/netwalker_reg.h>
 
-RCSID("$NetBSD: netwalker_start.S,v 1.4 2014/04/09 12:35:34 hkenken Exp $")
+RCSID("$NetBSD: netwalker_start.S,v 1.5 2014/05/06 11:22:53 hkenken Exp $")
 
 #if defined(VERBOSE_INIT_ARM)
 #define DEBUG_STARTUP
@@ -198,6 +198,8 @@ relocated:
 	/* Move into supervisor mode and disable IRQs/FIQs. */
 	cpsid   if, #PSR_SVC32_MODE
 
+	bl	cortex_init
+
 	movw	r0, #:lower16:TEMP_L1_TABLE
 	movt	r0, #:upper16:TEMP_L1_TABLE
 	adr	r1, .Lmmu_init_table

Added files:

Index: src/sys/arch/arm/imx/imx51_pwm.c
diff -u /dev/null src/sys/arch/arm/imx/imx51_pwm.c:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/arm/imx/imx51_pwm.c	Tue May  6 11:22:53 2014
@@ -0,0 +1,71 @@
+/*	$NetBSD: imx51_pwm.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*-
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 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 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: imx51_pwm.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $");
+
+#include "locators.h"
+#include "opt_imx.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+
+#include <arm/imx/imxpwmvar.h>
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imx51_ccmvar.h>
+
+int
+imxpwm_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct axi_attach_args *aa = aux;
+
+	switch (aa->aa_addr) {
+	case PWM1_BASE:
+	case PWM2_BASE:
+		return 1;
+	}
+
+	return 0;
+}
+
+void
+imxpwm_attach(struct imxpwm_softc *sc, void *aux)
+{
+	struct axi_attach_args *aa = aux;
+
+	if (aa->aa_size == AXICF_SIZE_DEFAULT)
+		aa->aa_size = PWM_SIZE;
+	sc->sc_iot = aa->aa_iot;
+	sc->sc_intr = aa->aa_irq;
+	sc->sc_freq = imx51_get_clock(IMX51CLK_IPG_CLK_ROOT);
+	if (bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size, 0, &sc->sc_ioh))
+		panic("%s: couldn't map", device_xname(sc->sc_dev));
+	imxpwm_attach_common(sc);
+}
Index: src/sys/arch/arm/imx/imxpwm.c
diff -u /dev/null src/sys/arch/arm/imx/imxpwm.c:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/arm/imx/imxpwm.c	Tue May  6 11:22:53 2014
@@ -0,0 +1,114 @@
+/*	$NetBSD: imxpwm.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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: imxpwm.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $");
+
+#include "opt_imx.h"
+#include "locators.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+
+#include <arm/imx/imxpwmreg.h>
+#include <arm/imx/imxpwmvar.h>
+
+static inline uint32_t
+imxpwm_read(struct imxpwm_softc *sc, bus_size_t o)
+{
+	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, o);
+}
+
+static inline void
+imxpwm_write(struct imxpwm_softc *sc, bus_size_t o, uint32_t v)
+{
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, o, v);
+}
+
+static int
+imxpwm_intr(void *arg)
+{
+	struct imxpwm_softc *sc = arg;
+	uint32_t sts = imxpwm_read(sc, PWM_SR);
+
+	imxpwm_write(sc, PWM_SR, sts);
+
+	if ((sts & SR_ROV) && (sc->sc_handler != NULL))
+		sc->sc_handler(sc->sc_cookie);
+
+	return 1;
+}
+
+void
+imxpwm_attach_common(struct imxpwm_softc *sc)
+{
+	uint32_t reg;
+	int div;
+
+	if (sc->sc_handler != NULL) {
+		sc->sc_ih = intr_establish(sc->sc_intr, IPL_BIO, IST_LEVEL,
+		    imxpwm_intr, sc);
+
+		reg = IR_RIE;
+		imxpwm_write(sc, PWM_IR, reg);
+	}
+
+	if (sc->sc_hz <= 0)
+		sc->sc_hz = IMXPWM_DEFAULT_HZ;
+	div = 0;
+	do {
+		div++;
+		sc->sc_cycle = sc->sc_freq / div / sc->sc_hz;
+	} while (sc->sc_cycle > 0xffff);
+
+	imxpwm_write(sc, PWM_PR, __SHIFTIN(sc->sc_cycle - 2, PR_PERIOD));
+
+	reg = 0;
+	reg |= __SHIFTIN(CLKSRC_IPG_CLK, CR_CLKSRC);
+	reg |= __SHIFTIN(div - 1, CR_PRESCALER);
+	reg |= CR_EN;
+	imxpwm_write(sc, PWM_CR, reg);
+}
+
+int
+imxpwm_set_pwm(struct imxpwm_softc *sc, int duty)
+{
+	if (duty < 0 || IMXPWM_DUTY_MAX < duty)
+		return EINVAL;
+
+	sc->sc_duty = duty;
+
+	uint16_t reg = sc->sc_cycle * sc->sc_duty / IMXPWM_DUTY_MAX;
+	if (reg != 0)
+		reg -= 1;
+	imxpwm_write(sc, PWM_SAR, __SHIFTIN(reg, SAR_SAMPLE));
+
+	return 0;
+}
Index: src/sys/arch/arm/imx/imxpwmreg.h
diff -u /dev/null src/sys/arch/arm/imx/imxpwmreg.h:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/arm/imx/imxpwmreg.h	Tue May  6 11:22:53 2014
@@ -0,0 +1,66 @@
+/*	$NetBSD: imxpwmreg.h,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+#ifndef	_ARM_IMX_IMXPWMREG_H_
+#define	_ARM_IMX_IMXPWMREG_H_
+
+#define PWM_CR		0x00	/* PWM Control Register */
+#define  CR_FWM		__BITS(27, 26)
+#define  CR_STOPEN	__BIT(25)
+#define  CR_DOZEN	__BIT(24)
+#define  CR_WAITEN	__BIT(23)
+#define  CR_DBGEN	__BIT(22)
+#define  CR_BCTR	__BIT(21)
+#define  CR_HCTR	__BIT(20)
+#define  CR_POUTC	__BITS(19, 18)
+#define  CR_CLKSRC	__BITS(17, 16)
+#define   CLKSRC_IPG_CLK		1
+#define   CLKSRC_IPG_CLK_HIGHFREQ	2
+#define   CLKSRC_IPG_CLK_32K		3
+#define  CR_PRESCALER	__BITS(15, 4)
+#define  CR_SWR		__BIT(3)
+#define  CR_REPEAT	__BITS(2, 1)
+#define  CR_EN		__BIT(0)
+#define PWM_SR		0x04	/* PWM Status Register */
+#define  SR_FWE		__BIT(6)
+#define  SR_CMP		__BIT(5)
+#define  SR_ROV		__BIT(4)
+#define  SR_FE		__BIT(3)
+#define  SR_FIFOAV	__BITS(2, 0)
+#define PWM_IR		0x08	/* PWM Interrupt Register */
+#define  IR_CIE		__BIT(2)
+#define  IR_RIE		__BIT(1)
+#define  IR_FIE		__BIT(0)
+#define PWM_SAR		0x0C	/* PWM Sample Register */
+#define  SAR_SAMPLE	__BITS(15, 0)
+#define PWM_PR		0x10	/* PWM Period Register */
+#define  PR_PERIOD	__BITS(15, 0)
+#define PWM_CNR		0x14	/* PWM Counter Register */
+#define  CNR_COUNT	__BITS(15, 0)
+
+#endif	/* _ARM_IMX_IMXPWMREG_H_ */
Index: src/sys/arch/arm/imx/imxpwmvar.h
diff -u /dev/null src/sys/arch/arm/imx/imxpwmvar.h:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/arm/imx/imxpwmvar.h	Tue May  6 11:22:53 2014
@@ -0,0 +1,56 @@
+/*	$NetBSD: imxpwmvar.h,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+#ifndef	_ARM_IMX_IMXPWMVAR_H_
+#define	_ARM_IMX_IMXPWMVAR_H_
+
+struct imxpwm_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	int sc_intr;
+	void *sc_ih;
+
+	long sc_freq;
+	long sc_hz;
+#define IMXPWM_DEFAULT_HZ	1000
+	long	sc_cycle;
+	int	sc_duty;
+#define IMXPWM_DUTY_MAX		1000
+
+	int (*sc_handler)(void *);
+	void *sc_cookie;
+};
+
+int imxpwm_match(device_t, cfdata_t, void *);
+void imxpwm_attach(struct imxpwm_softc *, void *);
+void imxpwm_attach_common(struct imxpwm_softc *);
+
+int imxpwm_set_pwm(struct imxpwm_softc *, int);
+
+#endif	/* _ARM_IMX_IMXPWMVAR_H_ */

Index: src/sys/arch/evbarm/netwalker/netwalker_backlight.c
diff -u /dev/null src/sys/arch/evbarm/netwalker/netwalker_backlight.c:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_backlight.c	Tue May  6 11:22:53 2014
@@ -0,0 +1,252 @@
+/*	$NetBSD: netwalker_backlight.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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: netwalker_backlight.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/pmf.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_taskq.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imx51_ccmvar.h>
+#include <arm/imx/imxpwmvar.h>
+
+#include <evbarm/netwalker/netwalker_backlightvar.h>
+
+#define BRIGHTNESS_MAX	16
+
+struct netwalker_backlight_softc {
+	struct imxpwm_softc sc_imxpwm;
+
+	int sc_brightness;
+	bool sc_islit;
+};
+
+static struct netwalker_backlight_softc *netwalker_backlight_sc;
+
+static int netwalker_backlight_match(device_t, cfdata_t, void *);
+static void netwalker_backlight_attach(device_t, device_t, void *);
+static int netwalker_backlight_detach(device_t, int);
+
+CFATTACH_DECL_NEW(netwalker_backlight, sizeof(struct netwalker_backlight_softc),
+    netwalker_backlight_match, netwalker_backlight_attach, netwalker_backlight_detach, NULL);
+
+static bool netwalker_backlight_resume(device_t, const pmf_qual_t *);
+static bool netwalker_backlight_suspend(device_t, const pmf_qual_t *);
+static void netwalker_backlight_on(device_t);
+static void netwalker_backlight_off(device_t);
+static void netwalker_brightness_up(device_t);
+static void netwalker_brightness_down(device_t);
+static void netwalker_set_brightness(struct netwalker_backlight_softc *, int);
+
+static int
+netwalker_backlight_match(device_t parent, cfdata_t cf, void * aux)
+{
+	return imxpwm_match(parent, cf, aux);
+}
+
+static void
+netwalker_backlight_attach(device_t parent, device_t self, void *aux)
+{
+	struct netwalker_backlight_softc *sc = device_private(self);
+	struct imxpwm_softc *imxpwm = &sc->sc_imxpwm;
+
+	imxpwm->sc_dev = self;
+	imxpwm->sc_hz = 1000; /* 1000 Hz */
+	imxpwm->sc_handler = NULL;
+	imxpwm->sc_cookie = sc;
+	imxpwm_attach(imxpwm, aux);
+
+	aprint_normal(": LCD BackLight Control\n");
+	aprint_naive(": LCD BackLight Control\n");
+
+	netwalker_backlight_sc = sc;
+
+	/* BackLight 100% On */
+	sc->sc_brightness = BRIGHTNESS_MAX;
+	sc->sc_islit = true;
+	imxpwm_set_pwm(imxpwm, 1000);
+
+	if (!pmf_device_register(self, netwalker_backlight_suspend,
+		netwalker_backlight_resume))
+		aprint_error_dev(self,
+		    "couldn't establish backlight handler\n");
+
+	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
+		netwalker_brightness_up, true))
+		aprint_error_dev(self,
+		    "couldn't register BRIGHTNESS UP event handler\n");
+	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
+		netwalker_brightness_down, true))
+		aprint_error_dev(self,
+		    "couldn't register BRIGHTNESS DOWN event handler\n");
+	if (!pmf_event_register(self, PMFE_DISPLAY_ON,
+		netwalker_backlight_on, true))
+		aprint_error_dev(self,
+		    "couldn't register DISPLAY ON event handler\n");
+	if (!pmf_event_register(self, PMFE_DISPLAY_OFF,
+		netwalker_backlight_off, true))
+		aprint_error_dev(self,
+		    "couldn't register DISPLAY OFF event handler\n");
+	if (!pmf_event_register(self, PMFE_CHASSIS_LID_OPEN,
+		netwalker_backlight_on, true))
+		aprint_error_dev(self,
+		    "couldn't register LID OPEN event handler\n");
+	if (!pmf_event_register(self, PMFE_CHASSIS_LID_CLOSE,
+		netwalker_backlight_off, true))
+		aprint_error_dev(self,
+		    "couldn't register LID CLOSE event handler\n");
+}
+
+static int
+netwalker_backlight_detach(device_t self, int flags)
+{
+	struct netwalker_backlight_softc *sc = device_private(self);
+	struct imxpwm_softc *imxpwm = &sc->sc_imxpwm;
+
+	imxpwm_set_pwm(imxpwm, 0);
+	pmf_device_deregister(self);
+	return 0;
+}
+
+/*
+ * Power management
+ */
+static bool
+netwalker_backlight_suspend(device_t dv, const pmf_qual_t *qual)
+{
+	netwalker_backlight_off(dv);
+ 	return true;
+}
+
+static bool
+netwalker_backlight_resume(device_t dv, const pmf_qual_t *qual)
+{
+	netwalker_backlight_on(dv);
+	return true;
+}
+
+static void
+netwalker_backlight_on(device_t dv)
+{
+	struct netwalker_backlight_softc *sc = device_private(dv);
+	sc->sc_islit = true;
+	netwalker_set_brightness(sc, sc->sc_brightness);
+}
+
+static void
+netwalker_backlight_off(device_t dv)
+{
+	struct netwalker_backlight_softc *sc = device_private(dv);
+	sc->sc_islit = false;
+	netwalker_set_brightness(sc, sc->sc_brightness);
+}
+
+static void
+netwalker_brightness_up(device_t dv)
+{
+	struct netwalker_backlight_softc *sc = device_private(dv);
+	netwalker_set_brightness(sc, sc->sc_brightness + 1);
+}
+
+static void
+netwalker_brightness_down(device_t dv)
+{
+	struct netwalker_backlight_softc *sc = device_private(dv);
+	netwalker_set_brightness(sc, sc->sc_brightness - 1);
+}
+
+static void
+netwalker_set_brightness(struct netwalker_backlight_softc *sc, int newval)
+{
+	struct imxpwm_softc *imxpwm = &sc->sc_imxpwm;
+
+	if (newval < 0)
+		newval = 0;
+	else if (newval > BRIGHTNESS_MAX)
+		newval = BRIGHTNESS_MAX;
+	sc->sc_brightness = newval;
+
+	if (sc->sc_islit)
+		imxpwm_set_pwm(imxpwm, 1000 * sc->sc_brightness / BRIGHTNESS_MAX);
+	else
+		imxpwm_set_pwm(imxpwm, 0);
+}
+
+int
+netwalker_lcd_param_ioctl(u_long cmd, struct wsdisplay_param *dp)
+{
+	struct netwalker_backlight_softc *sc = netwalker_backlight_sc;
+	int rv = EINVAL;
+
+	switch (dp->param) {
+	case WSDISPLAYIO_PARAM_BACKLIGHT:
+		if (cmd == WSDISPLAYIO_GETPARAM) {
+			dp->min = 0;
+			dp->max = 1;
+			dp->curval = sc->sc_islit ? 1 : 0;
+			rv = 0;
+		} else if (cmd == WSDISPLAYIO_SETPARAM) {
+			if (dp->curval != 0)
+				netwalker_backlight_on(sc->sc_imxpwm.sc_dev);
+			else
+				netwalker_backlight_off(sc->sc_imxpwm.sc_dev);
+			rv = 0;
+		}
+		break;
+
+	case WSDISPLAYIO_PARAM_CONTRAST:
+		/* unsupported */
+		rv = ENOTSUP;
+		break;
+
+	case WSDISPLAYIO_PARAM_BRIGHTNESS:
+		if (cmd == WSDISPLAYIO_GETPARAM) {
+			dp->min = 0;
+			dp->max = BRIGHTNESS_MAX;
+			dp->curval = sc->sc_brightness;
+			rv = 0;
+		} else if (cmd == WSDISPLAYIO_SETPARAM) {
+			netwalker_set_brightness(sc, dp->curval);
+			rv = 0;
+		}
+		break;
+	}
+
+	return rv;
+}
Index: src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h
diff -u /dev/null src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h:1.1
--- /dev/null	Tue May  6 11:22:53 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h	Tue May  6 11:22:53 2014
@@ -0,0 +1,34 @@
+/*	$NetBSD: netwalker_backlightvar.h,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+#ifndef _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H
+#define _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H
+
+int netwalker_lcd_param_ioctl(u_long cmd, struct wsdisplay_param *dp);
+
+#endif	/* _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H */

Reply via email to