summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2009-10-30 09:37:07 +0100
committerEgbert Eich <eich@freedesktop.org>2009-10-30 09:37:07 +0100
commit209505b3af2558920578a8572a9930b413380190 (patch)
tree48244ff2b1b0060f87338283fba8641ba9167367
parent5cd4cca8c00db39f6fcfae27d142451eb5de0ebb (diff)
Backlight: ACPI backlight support for FreeBSD
This patch adds support for FreeBSD and DragonFlyBSD via acpi_video(4). Signed-off-by: Egbert Eich <eich@freedesktop.org>
-rw-r--r--src/rhd_acpi.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/src/rhd_acpi.c b/src/rhd_acpi.c
index 78751e5..1f2d4d7 100644
--- a/src/rhd_acpi.c
+++ b/src/rhd_acpi.c
@@ -48,6 +48,70 @@
#include "rhd_acpi.h"
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+
+#include <stdlib.h>
+#include <sys/sysctl.h>
+
+#define ACPI_VIDEO_LEVELS "hw.acpi.video.lcd0.levels"
+#define ACPI_VIDEO_BRIGHTNESS "hw.acpi.video.lcd0.brightness"
+
+/*
+ * Get/Set LCD backlight brightness via acpi_video(4).
+ */
+static Bool
+rhdDoBacklight(struct rhdOutput *Output, Bool do_write, int *val)
+{
+ int *levels;
+ size_t len;
+ int level, max_val, num_levels;
+ int i;
+ RHDFUNC(Output);
+
+ if (sysctlbyname(ACPI_VIDEO_LEVELS, NULL, &len, NULL, 0) != 0 || len == 0)
+ return FALSE;
+ levels = (int *)malloc(len);
+ if (levels == NULL)
+ return FALSE;
+ if (sysctlbyname(ACPI_VIDEO_LEVELS, levels, &len, NULL, 0) != 0) {
+ free(levels);
+ return FALSE;
+ }
+
+ num_levels = len / sizeof(*levels);
+ for (i = 0, max_val = 0; i < num_levels; i++)
+ if (levels[i] > max_val)
+ max_val = levels[i];
+
+ if (do_write) {
+ int d1 = max_val * RHD_BACKLIGHT_PROPERTY_MAX + 1;
+ for (i = 0, level = -1; i < num_levels; i++) {
+ int d2 = abs(*val * max_val - levels[i] * RHD_BACKLIGHT_PROPERTY_MAX);
+ if (d2 < d1) {
+ level = levels[i];
+ d1 = d2;
+ }
+ }
+ free(levels);
+ if (level < 0)
+ return FALSE;
+ if (sysctlbyname(ACPI_VIDEO_BRIGHTNESS, NULL, 0, &level, sizeof(level)) != 0)
+ return FALSE;
+ RHDDebug(Output->scrnIndex, "%s: Wrote value %i (ACPI %i)\n", __func__, *val, level);
+ } else {
+ free(levels);
+ len = sizeof(level);
+ if (sysctlbyname(ACPI_VIDEO_BRIGHTNESS, &level, &len, NULL, 0) != 0)
+ return FALSE;
+ *val = level * RHD_BACKLIGHT_PROPERTY_MAX / max_val;
+ RHDDebug(Output->scrnIndex, "%s: Read value %i (ACPI %i)\n", __func__, *val, level);
+ }
+
+ return TRUE;
+}
+
+#elif defined(__linux__)
+
#define ACPI_PATH "/sys/class/backlight"
/*
@@ -121,6 +185,7 @@ rhdDoBacklight(struct rhdOutput *Output, Bool do_write, int *val)
return FALSE;
}
+#endif
/*
* RhdACPIGetBacklightControl(): return backlight value in range 0..255;
@@ -129,7 +194,7 @@ rhdDoBacklight(struct rhdOutput *Output, Bool do_write, int *val)
int
RhdACPIGetBacklightControl(struct rhdOutput *Output)
{
-#ifdef __linux__
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__)
int ret;
RHDFUNC(Output);
if (rhdDoBacklight(Output, FALSE, &ret))
@@ -145,7 +210,7 @@ void
RhdACPISetBacklightControl(struct rhdOutput *Output, int val)
{
RHDFUNC(Output);
-#ifdef __linux__
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__)
rhdDoBacklight(Output, TRUE, &val);
#endif
}