From owner-svn-src-all@FreeBSD.ORG Wed Mar 10 18:13:18 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3FCC5106566C; Wed, 10 Mar 2010 18:13:18 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2DF088FC24; Wed, 10 Mar 2010 18:13:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2AIDI4j020119; Wed, 10 Mar 2010 18:13:18 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2AIDIlr020117; Wed, 10 Mar 2010 18:13:18 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201003101813.o2AIDIlr020117@svn.freebsd.org> From: Jung-uk Kim Date: Wed, 10 Mar 2010 18:13:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r204964 - stable/7/sys/dev/acpica X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Mar 2010 18:13:18 -0000 Author: jkim Date: Wed Mar 10 18:13:17 2010 New Revision: 204964 URL: http://svn.freebsd.org/changeset/base/204964 Log: MFC: r197438, r203810, r203813, r203935, r203936 Sync acpi_video(4) with HEAD. r197438: Uninline an instance of STAILQ_FOREACH_SAFE(). r203810: Implement LCD brightness control notify handler. r203813: Make sanity check slightly more useful and tweak an error message. r203935: Add support for `cycle' and `zero' events for LCD brightness control. r203936: Rename some macros to clarify their intentions and fix style nits. Modified: stable/7/sys/dev/acpica/acpi_video.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/acpica/acpi_video.c ============================================================================== --- stable/7/sys/dev/acpica/acpi_video.c Wed Mar 10 17:58:32 2010 (r204963) +++ stable/7/sys/dev/acpica/acpi_video.c Wed Mar 10 18:13:17 2010 (r204964) @@ -82,6 +82,7 @@ static struct acpi_video_output *acpi_vi static void acpi_video_vo_bind(struct acpi_video_output *, ACPI_HANDLE); static void acpi_video_vo_destroy(struct acpi_video_output *); static int acpi_video_vo_check_level(struct acpi_video_output *, int); +static void acpi_video_vo_notify_handler(ACPI_HANDLE, UINT32, void *); static int acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS); @@ -92,56 +93,61 @@ static void vid_set_switch_policy(ACPI_H static int vid_enum_outputs(ACPI_HANDLE, void(*)(ACPI_HANDLE, UINT32, void *), void *); static int vo_get_brightness_levels(ACPI_HANDLE, int **); +static int vo_get_brightness(ACPI_HANDLE); static void vo_set_brightness(ACPI_HANDLE, int); static UINT32 vo_get_device_status(ACPI_HANDLE); static UINT32 vo_get_graphics_state(ACPI_HANDLE); static void vo_set_device_state(ACPI_HANDLE, UINT32); /* events */ -#define VID_NOTIFY_SWITCHED 0x80 -#define VID_NOTIFY_REPROBE 0x81 +#define VID_NOTIFY_SWITCHED 0x80 +#define VID_NOTIFY_REPROBE 0x81 +#define VID_NOTIFY_CYCLE_BRN 0x85 +#define VID_NOTIFY_INC_BRN 0x86 +#define VID_NOTIFY_DEC_BRN 0x87 +#define VID_NOTIFY_ZERO_BRN 0x88 /* _DOS (Enable/Disable Output Switching) argument bits */ -#define DOS_SWITCH_MASK 3 -#define DOS_SWITCH_BY_OSPM 0 -#define DOS_SWITCH_BY_BIOS 1 -#define DOS_SWITCH_LOCKED 2 -#define DOS_BRIGHTNESS_BY_BIOS (1 << 2) +#define DOS_SWITCH_MASK 3 +#define DOS_SWITCH_BY_OSPM 0 +#define DOS_SWITCH_BY_BIOS 1 +#define DOS_SWITCH_LOCKED 2 +#define DOS_BRIGHTNESS_BY_OSPM (1 << 2) /* _DOD and subdev's _ADR */ -#define DOD_DEVID_MASK 0x0f00 -#define DOD_DEVID_MASK_FULL 0xffff -#define DOD_DEVID_MASK_DISPIDX 0x000f -#define DOD_DEVID_MASK_DISPPORT 0x00f0 -#define DOD_DEVID_MONITOR 0x0100 -#define DOD_DEVID_LCD 0x0110 -#define DOD_DEVID_TV 0x0200 -#define DOD_DEVID_EXT 0x0300 -#define DOD_DEVID_INTDFP 0x0400 -#define DOD_BIOS (1 << 16) -#define DOD_NONVGA (1 << 17) -#define DOD_HEAD_ID_SHIFT 18 -#define DOD_HEAD_ID_BITS 3 -#define DOD_HEAD_ID_MASK \ +#define DOD_DEVID_MASK 0x0f00 +#define DOD_DEVID_MASK_FULL 0xffff +#define DOD_DEVID_MASK_DISPIDX 0x000f +#define DOD_DEVID_MASK_DISPPORT 0x00f0 +#define DOD_DEVID_MONITOR 0x0100 +#define DOD_DEVID_LCD 0x0110 +#define DOD_DEVID_TV 0x0200 +#define DOD_DEVID_EXT 0x0300 +#define DOD_DEVID_INTDFP 0x0400 +#define DOD_BIOS (1 << 16) +#define DOD_NONVGA (1 << 17) +#define DOD_HEAD_ID_SHIFT 18 +#define DOD_HEAD_ID_BITS 3 +#define DOD_HEAD_ID_MASK \ (((1 << DOD_HEAD_ID_BITS) - 1) << DOD_HEAD_ID_SHIFT) -#define DOD_DEVID_SCHEME_STD (1 << 31) +#define DOD_DEVID_SCHEME_STD (1 << 31) /* _BCL related constants */ -#define BCL_FULLPOWER 0 -#define BCL_ECONOMY 1 +#define BCL_FULLPOWER 0 +#define BCL_ECONOMY 1 /* _DCS (Device Currrent Status) value bits and masks. */ -#define DCS_EXISTS (1 << 0) -#define DCS_ACTIVE (1 << 1) -#define DCS_READY (1 << 2) -#define DCS_FUNCTIONAL (1 << 3) -#define DCS_ATTACHED (1 << 4) +#define DCS_EXISTS (1 << 0) +#define DCS_ACTIVE (1 << 1) +#define DCS_READY (1 << 2) +#define DCS_FUNCTIONAL (1 << 3) +#define DCS_ATTACHED (1 << 4) /* _DSS (Device Set Status) argument bits and masks. */ -#define DSS_INACTIVE 0 -#define DSS_ACTIVE (1 << 0) -#define DSS_SETNEXT (1 << 30) -#define DSS_COMMIT (1 << 31) +#define DSS_INACTIVE 0 +#define DSS_ACTIVE (1 << 0) +#define DSS_SETNEXT (1 << 30) +#define DSS_COMMIT (1 << 31) static device_method_t acpi_video_methods[] = { DEVMETHOD(device_identify, acpi_video_identify), @@ -268,7 +274,7 @@ acpi_video_attach(device_t dev) * brightness levels. */ vid_set_switch_policy(sc->handle, DOS_SWITCH_BY_OSPM | - DOS_BRIGHTNESS_BY_BIOS); + DOS_BRIGHTNESS_BY_OSPM); acpi_video_power_profile(sc); @@ -289,8 +295,7 @@ acpi_video_detach(device_t dev) acpi_video_notify_handler); ACPI_SERIAL_BEGIN(video); - for (vo = STAILQ_FIRST(&sc->vid_outputs); vo != NULL; vo = vn) { - vn = STAILQ_NEXT(vo, vo_next); + STAILQ_FOREACH_SAFE(vo, &sc->vid_outputs, vo_next, vn) { acpi_video_vo_destroy(vo); } ACPI_SERIAL_END(video); @@ -577,6 +582,9 @@ acpi_video_vo_bind(struct acpi_video_out /* XXX - see above. */ vo->vo_economy = vo->vo_levels[BCL_ECONOMY]; } + if (vo->vo_levels != NULL) + AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, + acpi_video_vo_notify_handler, vo); ACPI_SERIAL_END(video_output); } @@ -590,8 +598,11 @@ acpi_video_vo_destroy(struct acpi_video_ vo->vo_sysctl_tree = NULL; sysctl_ctx_free(&vo->vo_sysctl_ctx); } - if (vo->vo_levels != NULL) + if (vo->vo_levels != NULL) { + AcpiRemoveNotifyHandler(vo->handle, ACPI_DEVICE_NOTIFY, + acpi_video_vo_notify_handler); AcpiOsFree(vo->vo_levels); + } switch (vo->adr & DOD_DEVID_MASK) { case DOD_DEVID_MONITOR: @@ -627,6 +638,79 @@ acpi_video_vo_check_level(struct acpi_vi return (EINVAL); } +static void +acpi_video_vo_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context) +{ + struct acpi_video_output *vo; + int i, j, level, new_level; + + vo = context; + ACPI_SERIAL_BEGIN(video_output); + if (vo->handle != handle) + goto out; + + switch (notify) { + case VID_NOTIFY_CYCLE_BRN: + if (vo->vo_numlevels <= 3) + goto out; + /* FALLTHROUGH */ + case VID_NOTIFY_INC_BRN: + case VID_NOTIFY_DEC_BRN: + case VID_NOTIFY_ZERO_BRN: + if (vo->vo_levels == NULL) + goto out; + level = vo_get_brightness(handle); + if (level < 0) + goto out; + break; + default: + printf("unknown notify event 0x%x from %s\n", + notify, acpi_name(handle)); + goto out; + } + + new_level = level; + switch (notify) { + case VID_NOTIFY_CYCLE_BRN: + for (i = 2; i < vo->vo_numlevels; i++) + if (vo->vo_levels[i] == level) { + new_level = vo->vo_numlevels > i + 1 ? + vo->vo_levels[i + 1] : vo->vo_levels[2]; + break; + } + break; + case VID_NOTIFY_INC_BRN: + case VID_NOTIFY_DEC_BRN: + for (i = 0; i < vo->vo_numlevels; i++) { + j = vo->vo_levels[i]; + if (notify == VID_NOTIFY_INC_BRN) { + if (j > level && + (j < new_level || level == new_level)) + new_level = j; + } else { + if (j < level && + (j > new_level || level == new_level)) + new_level = j; + } + } + break; + case VID_NOTIFY_ZERO_BRN: + for (i = 0; i < vo->vo_numlevels; i++) + if (vo->vo_levels[i] == 0) { + new_level = 0; + break; + } + break; + } + if (new_level != level) { + vo_set_brightness(handle, new_level); + vo->vo_brightness = new_level; + } + +out: + ACPI_SERIAL_END(video_output); +} + /* ARGSUSED */ static int acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS) @@ -900,6 +984,25 @@ out: return (num); } +static int +vo_get_brightness(ACPI_HANDLE handle) +{ + UINT32 level; + ACPI_STATUS status; + + ACPI_SERIAL_ASSERT(video_output); + status = acpi_GetInteger(handle, "_BQC", &level); + if (ACPI_FAILURE(status)) { + printf("can't evaluate %s._BQC - %s\n", acpi_name(handle), + AcpiFormatException(status)); + return (-1); + } + if (level > 100) + return (-1); + + return (level); +} + static void vo_set_brightness(ACPI_HANDLE handle, int level) {