svn commit: r204963 - stable/8/sys/dev/acpica
Jung-uk Kim
jkim at FreeBSD.org
Wed Mar 10 17:58:33 UTC 2010
Author: jkim
Date: Wed Mar 10 17:58:32 2010
New Revision: 204963
URL: http://svn.freebsd.org/changeset/base/204963
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/8/sys/dev/acpica/acpi_video.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/acpica/acpi_video.c
==============================================================================
--- stable/8/sys/dev/acpica/acpi_video.c Wed Mar 10 17:45:58 2010 (r204962)
+++ stable/8/sys/dev/acpica/acpi_video.c Wed Mar 10 17:58:32 2010 (r204963)
@@ -83,6 +83,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);
@@ -93,56 +94,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),
@@ -269,7 +275,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);
@@ -290,8 +296,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);
@@ -578,6 +583,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);
}
@@ -591,8 +599,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:
@@ -628,6 +639,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)
@@ -901,6 +985,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)
{
More information about the svn-src-all
mailing list