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 */