Index: sys/external/bsd/drm2/dist/drm/i915/intel_drv.h =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm2/dist/drm/i915/intel_drv.h,v retrieving revision 1.8 diff -p -u -r1.8 intel_drv.h --- sys/external/bsd/drm2/dist/drm/i915/intel_drv.h 28 Feb 2015 03:27:38 -0000 1.8 +++ sys/external/bsd/drm2/dist/drm/i915/intel_drv.h 17 Jan 2016 08:31:20 -0000 @@ -898,6 +898,7 @@ void intel_pch_panel_fitting(struct inte void intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); +u32 intel_panel_get_backlight(struct intel_connector *connector); void intel_panel_set_backlight(struct intel_connector *connector, u32 level, u32 max); int intel_panel_setup_backlight(struct drm_connector *connector); Index: sys/external/bsd/drm2/dist/drm/i915/intel_panel.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm2/dist/drm/i915/intel_panel.c,v retrieving revision 1.6 diff -p -u -r1.6 intel_panel.c --- sys/external/bsd/drm2/dist/drm/i915/intel_panel.c 4 Nov 2014 03:05:36 -0000 1.6 +++ sys/external/bsd/drm2/dist/drm/i915/intel_panel.c 17 Jan 2016 08:31:20 -0000 @@ -398,8 +398,7 @@ static u32 vlv_get_backlight(struct inte return _vlv_get_backlight(dev, pipe); } -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) -static u32 intel_panel_get_backlight(struct intel_connector *connector) +u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -416,7 +415,6 @@ static u32 intel_panel_get_backlight(str DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); return val; } -#endif static void bdw_set_backlight(struct intel_connector *connector, u32 level) { Index: sys/external/bsd/drm2/i915drm/intelfb.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm2/i915drm/intelfb.c,v retrieving revision 1.13 diff -p -u -r1.13 intelfb.c --- sys/external/bsd/drm2/i915drm/intelfb.c 4 Apr 2015 15:12:39 -0000 1.13 +++ sys/external/bsd/drm2/i915drm/intelfb.c 17 Jan 2016 08:31:20 -0000 @@ -53,6 +53,12 @@ static void intelfb_attach_task(struct i static bool intelfb_shutdown(device_t, int); static paddr_t intelfb_drmfb_mmapfb(struct drmfb_softc *, off_t, int); +static int intelfb_drmfb_ioctl(struct drmfb_softc *, unsigned long, + void *, int, struct lwp *); + +static void intelfb_brightness_up(device_t); +static void intelfb_brightness_down(device_t); +static void intelfb_adjust_brightness(device_t, int); struct intelfb_softc { struct drmfb_softc sc_drmfb; /* XXX Must be first. */ @@ -68,7 +74,7 @@ struct intelfb_softc { static const struct drmfb_params intelfb_drmfb_params = { .dp_mmapfb = intelfb_drmfb_mmapfb, .dp_mmap = drmfb_pci_mmap, - .dp_ioctl = drmfb_pci_ioctl, + .dp_ioctl = intelfb_drmfb_ioctl, .dp_is_vga_console = drmfb_pci_is_vga_console, .dp_disable_vga = i915_disable_vga, }; @@ -138,12 +144,22 @@ intelfb_detach(device_t self, int flags) return EBUSY; if (sc->sc_attached) { + pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, + &intelfb_brightness_up, true); + pmf_event_deregister(self, PMFE_DISPLAY_BRIGHTNESS_UP, + &intelfb_brightness_up, true); pmf_device_deregister(self); error = drmfb_detach(&sc->sc_drmfb, flags); if (error) { /* XXX Ugh. */ (void)pmf_device_register1(self, NULL, NULL, &intelfb_shutdown); + (void)pmf_event_register(self, + PMFE_DISPLAY_BRIGHTNESS_UP, + &intelfb_brightness_up, true); + (void)pmf_event_register(self, + PMFE_DISPLAY_BRIGHTNESS_DOWN, + &intelfb_brightness_down, true); return error; } sc->sc_attached = false; @@ -183,6 +199,14 @@ intelfb_attach_task(struct i915drmkms_ta if (!pmf_device_register1(sc->sc_dev, NULL, NULL, &intelfb_shutdown)) aprint_error_dev(sc->sc_dev, "failed to register shutdown handler\n"); + if (!pmf_event_register(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_UP, + &intelfb_brightness_up, true)) + aprint_error_dev(sc->sc_dev, + "failed to register brightness-up handler\n"); + if (!pmf_event_register(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_DOWN, + &intelfb_brightness_up, true)) + aprint_error_dev(sc->sc_dev, + "failed to register brightness-down handler\n"); sc->sc_attached = true; } @@ -213,3 +237,144 @@ intelfb_drmfb_mmapfb(struct drmfb_softc i915_gem_obj_ggtt_offset(fbdev->fb->obj) + offset, prot, BUS_SPACE_MAP_PREFETCHABLE); } + +static struct intel_connector * +intelfb_get_backlit_connector(struct drm_fb_helper *fb_helper) +{ + struct drm_fb_helper_connector *fb_conn; + struct intel_connector *conn; + unsigned i; + + for (i = 0; i < fb_helper->connector_count; i++) { + fb_conn = fb_helper->connector_info[i]; + KASSERT(fb_conn != NULL); + KASSERT(fb_conn->connector != NULL); + conn = container_of(fb_conn->connector, struct intel_connector, + base); + if (conn->panel.backlight.present) + return conn; + } + + return NULL; +} + +static int +intelfb_drmfb_ioctl(struct drmfb_softc *drmfb, unsigned long cmd, void *data, + int flag, struct lwp *l) +{ + struct intelfb_softc *const sc = container_of(drmfb, + struct intelfb_softc, sc_drmfb); + struct drm_fb_helper *const fb_helper = sc->sc_ifa.ifa_fb_helper; + struct drm_fb_helper_connector *fb_conn; + struct intel_connector *conn; + struct wsdisplay_param *param; + unsigned i; + + switch (cmd) { + case WSDISPLAYIO_GETPARAM: + param = data; + switch (param->param) { + case WSDISPLAYIO_PARAM_BACKLIGHT: + conn = intelfb_get_backlit_connector(fb_helper); + if (conn == NULL) + return ENODEV; + param->min = 0; + param->max = 1; + param->curval = conn->panel.backlight.enabled; + return 0; + case WSDISPLAYIO_PARAM_BRIGHTNESS: + conn = intelfb_get_backlit_connector(fb_helper); + if (conn == NULL) + return ENODEV; + param->min = 0; + param->max = conn->panel.backlight.max; + param->curval = conn->panel.backlight.level; + return 0; + default: + return EPASSTHROUGH; + } + case WSDISPLAYIO_SETPARAM: + param = data; + switch (param->param) { + case WSDISPLAYIO_PARAM_BACKLIGHT: + for (i = 0; i < fb_helper->connector_count; i++) { + fb_conn = fb_helper->connector_info[i]; + KASSERT(fb_conn != NULL); + KASSERT(fb_conn->connector != NULL); + conn = container_of(fb_conn->connector, + struct intel_connector, base); + if (!conn->panel.backlight.present) + continue; + if (param->curval) + intel_panel_enable_backlight(conn); + else + intel_panel_disable_backlight(conn); + } + return 0; + case WSDISPLAYIO_PARAM_BRIGHTNESS: { + for (i = 0; i < fb_helper->connector_count; i++) { + fb_conn = fb_helper->connector_info[i]; + KASSERT(fb_conn != NULL); + KASSERT(fb_conn->connector != NULL); + conn = container_of(fb_conn->connector, + struct intel_connector, base); + if (!conn->panel.backlight.present) + continue; + intel_panel_set_backlight(conn, + (MAX(param->curval, param->min) + - param->min), + (MAX(param->max, param->min) + - param->min)); + } + return 0; + } + default: + return EPASSTHROUGH; + } + default: + return drmfb_pci_ioctl(drmfb, cmd, data, flag, l); + } +} + +static void +intelfb_brightness_up(device_t self) +{ + + intelfb_adjust_brightness(self, +1); +} + +static void +intelfb_brightness_down(device_t self) +{ + + intelfb_adjust_brightness(self, -1); +} + +static void +intelfb_adjust_brightness(device_t self, int delta) +{ + struct intelfb_softc *const sc = device_private(self); + struct drm_fb_helper *const fb_helper = sc->sc_ifa.ifa_fb_helper; + struct drm_fb_helper_connector *fb_conn; + struct intel_connector *conn; + uint32_t brightness; + unsigned i; + + for (i = 0; i < fb_helper->connector_count; i++) { + fb_conn = fb_helper->connector_info[i]; + KASSERT(fb_conn != NULL); + KASSERT(fb_conn->connector != NULL); + conn = container_of(fb_conn->connector, struct intel_connector, + base); + if (!conn->panel.backlight.present) + continue; + brightness = intel_panel_get_backlight(conn); + if (delta == -1 && brightness == 0) + continue; + if (delta == +1 && brightness == conn->panel.backlight.max) + continue; + brightness += delta; + intel_panel_set_backlight(conn, brightness, + conn->panel.backlight.max); + } +} Index: sys/dev/wsfb/genfb.c =================================================================== RCS file: /cvsroot/src/sys/dev/wsfb/genfb.c,v retrieving revision 1.58 diff -p -u -r1.58 genfb.c --- sys/dev/wsfb/genfb.c 1 Jun 2015 20:47:59 -0000 1.58 +++ sys/dev/wsfb/genfb.c 17 Jan 2016 08:31:20 -0000 @@ -422,7 +422,7 @@ genfb_ioctl(void *v, void *vs, u_long cm switch (param->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: if (sc->sc_brightness == NULL) - return EPASSTHROUGH; + break; param->min = 0; param->max = 255; return sc->sc_brightness->gpc_get_parameter( @@ -430,21 +430,21 @@ genfb_ioctl(void *v, void *vs, u_long cm ¶m->curval); case WSDISPLAYIO_PARAM_BACKLIGHT: if (sc->sc_backlight == NULL) - return EPASSTHROUGH; + break; param->min = 0; param->max = 1; return sc->sc_backlight->gpc_get_parameter( sc->sc_backlight->gpc_cookie, ¶m->curval); } - return EPASSTHROUGH; + break; case WSDISPLAYIO_SETPARAM: param = (struct wsdisplay_param *)data; switch (param->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: if (sc->sc_brightness == NULL) - return EPASSTHROUGH; + break; val = param->curval; if (val < 0) val = 0; if (val > 255) val = 255; @@ -452,14 +452,14 @@ genfb_ioctl(void *v, void *vs, u_long cm sc->sc_brightness->gpc_cookie, val); case WSDISPLAYIO_PARAM_BACKLIGHT: if (sc->sc_backlight == NULL) - return EPASSTHROUGH; + break; val = param->curval; if (val < 0) val = 0; if (val > 1) val = 1; return sc->sc_backlight->gpc_set_parameter( sc->sc_backlight->gpc_cookie, val); } - return EPASSTHROUGH; + break; } ret = EPASSTHROUGH; if (sc->sc_ops.genfb_ioctl)