svn commit: r204964 - stable/7/sys/dev/acpica

Jung-uk Kim jkim at FreeBSD.org
Wed Mar 10 18:13:18 UTC 2010


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)
 {


More information about the svn-src-all mailing list