Skip to contentSkip to conversation

backlight dimmer

PATCH In review [email protected] 5 participants 7 messages Oct 28, 2007 – Nov 1, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 backlight dimmer

Hello,
this patch implements a macbook like backlight dimmer on top of backlight.c.

The dimmer is entirely in kernelspace and is suitable for an embedded context in order to avoid the overhead of a daemon controlling the backlight. Implementing this functionality in userspace has other advantages and is a perfectly reasonable alternative, so this patch is not the definitive solution.

activate dimmer:
echo 1 > /sys/devices/virtual/backlight/*/dimmer_control

other attributes (britness levels & timeout):
/sys/devices/virtual/backlight/*/dimmer_high_level /sys/devices/virtual/backlight/*/dimmer_low_level /sys/devices/virtual/backlight/*/dimmer_timeout

regards,
jacopo antonello

******************************* diff follows

include/linux/backlight.h +0 -0
@@ -11,6 +11,7 @@

#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
+#include <linux/timeout.h>

/* Notes on locking:
*

@@ -70,6 +71,12 @@ struct backlight_device {
	/* The framebuffer notifier block */
	struct notifier_block fb_notif;
+  /* dimmer stuff */
+  struct timeout *timeout;
+  struct input_handler *input_handler;
+  unsigned short dimmer_low_level;
+  unsigned short dimmer_high_level;
+
	struct device dev;
};
drivers/video/backlight/Makefile +0 -0
@@ -1,7 +1,7 @@

# Backlight & LCD drivers

obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
-obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o +obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o timeout.o
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o

include/linux/timeout.h +66 -0

66 lines not on this page · raw message

drivers/video/backlight/timeout.c +143 -0

143 lines not on this page · raw message

drivers/video/backlight/backlight.c +0 -0
@@ -8,7 +8,8 @@

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
-#include <linux/backlight.h>
+#include <linux/input.h>
+#include <linux/backlight.h> #include <linux/notifier.h> #include <linux/ctype.h>
#include <linux/err.h>
@@ -172,6 +173,267 @@ static void bl_device_release(struct dev

	kfree(bd);
}

+/*
+ * ---------------------------------------------------
+ * backlight dimmer
+ * --------------------------------------------------
+ */
+
+static const struct input_device_id idi_dimmer[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT(EV_KEY) },
+ }, /* key event */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_RELBIT,
+ .relbit = { BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) },
+ }, /* rel axes */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+ }, /* abs axes */
+ { }
+};
+
+static void handler_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) +{
+ struct backlight_device *dev = (struct backlight_device *)handle->private;
+
+ switch(type) {
+ case EV_KEY:
+ case EV_REL:
+ timeout_touch(dev->timeout);
+ }
+}
+
+static void dimmer_start(unsigned long data)
+{
+ struct backlight_device *bd = (struct backlight_device *)data;
+

+  printk(KERN_DEBUG "SWITCH TO HIGH\n");
+  bd->props.brightness = bd->dimmer_high_level;
+  backlight_update_status(bd);

+}
+
+static void dimmer_trigger(unsigned long data)
+{
+ struct backlight_device *bd = (struct backlight_device *)data;
+

+  printk(KERN_DEBUG "SWITCH TO LOW\n");
+  bd->props.brightness = bd->dimmer_low_level;
+  backlight_update_status(bd);

+}
+
+static int handler_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ int error = 0;
+ struct input_handle *handle;
+
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+

+  handle->handler = handler;
+  handle->dev = dev;
+  handle->name = "backlight";
+  handle->private = handler->private;

+
+ error = input_register_handle(handle);
+ if (error)
+ goto err_free_handle;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err_unregister_handle;
+
+ return 0;
+
+ err_unregister_handle:
+ input_unregister_handle(handle);
+ err_free_handle:
+ kfree(handle);
+ return error;
+}
+
+static void handler_disconnect(struct input_handle *handle) +{

+  input_close_device(handle);
+  input_unregister_handle(handle);
+  kfree(handle);

+}
+
+static int enable_dimmer(struct backlight_device *dev) +{

+  printk(KERN_DEBUG "enable_dimmer()...\n");
+  dev->input_handler = kzalloc(sizeof(struct input_handler), GFP_KERNEL);
+  if (!dev->input_handler)

+ return -ENOMEM;
+
+ if (!dev->dimmer_low_level)
+ dev->dimmer_low_level = dev->props.max_brightness/2;
+ if (!dev->dimmer_high_level)
+ dev->dimmer_high_level = dev->props.max_brightness;
+

+  dev->input_handler->event = handler_event;
+  dev->input_handler->connect = handler_connect;
+  dev->input_handler->disconnect = handler_disconnect;
+  dev->input_handler->name = "backlight";
+  dev->input_handler->id_table = idi_dimmer;
+  dev->input_handler->private = dev;

+
+ dev->timeout = kzalloc(sizeof(struct timeout), GFP_KERNEL);
+ if (!dev->timeout)
+ goto free_handler;
+

+  timeout_init(dev->timeout);
+  dev->timeout->duration = timeout_sec2jiffies(5);
+  dev->timeout->data = (unsigned long)dev;
+  dev->timeout->trigger = dimmer_trigger;
+  dev->timeout->start = dimmer_start;

+
+ if (!input_register_handler(dev->input_handler))
+ return 0; /* success */
+ /* else go on & cleanup */
+
+ free_handler:

+    kfree(dev->input_handler);
+    dev->input_handler=NULL;
+    return -ENOMEM;

+}
+
+static void disable_dimmer(struct backlight_device *dev) +{
+ if (!dev->input_handler)
+ return;
+

+  input_unregister_handler(dev->input_handler);
+  timeout_kill(dev->timeout);
+  kfree(dev->input_handler);
+  kfree(dev->timeout);
+  dev->input_handler = NULL;
+  dev->timeout = NULL;
+  printk(KERN_DEBUG "disable_dimmer()\n");

+}
+
+/* show */
+static ssize_t show_dimmer_control(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (bd->input_handler != NULL));
+}
+
+static ssize_t show_dimmer_timeout(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ if (bd->timeout)
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ timeout_jif2sec(bd->timeout->duration));
+ else
+ return 0;
+}
+
+static ssize_t show_dimmer_low_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ bd->dimmer_low_level);
+}
+
+static ssize_t show_dimmer_high_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ bd->dimmer_high_level);
+}
+
+/* store */
+static ssize_t store_dimmer_control(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int control = simple_strtoul(buf, &endp, 0);
+
+ mutex_lock(&bd->ops_lock);
+ if (control == 1 && !bd->input_handler)
+ enable_dimmer(bd);
+ else if (control == 0 && bd->input_handler)
+ disable_dimmer(bd);
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_timeout(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int timeout = simple_strtoul(buf, &endp, 0);
+
+ if (timeout <= 0 || timeout >= 60*30)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ if (!bd->timeout) {
+ mutex_unlock(&bd->ops_lock);
+ return -ENXIO;
+ }
+ bd->timeout->duration = timeout_sec2jiffies(timeout);
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_low_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int low = simple_strtoul(buf, &endp, 0);
+
+ if (low < 0 || low > bd->props.max_brightness)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ bd->dimmer_low_level = low;
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_high_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int high = simple_strtoul(buf, &endp, 0);
+
+ if (high < 0 || high > bd->props.max_brightness)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ bd->dimmer_high_level = high;
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
static struct device_attribute bl_device_attributes[] = {
__ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), __ATTR(brightness, 0644, backlight_show_brightness,
@@ -179,6 +441,10 @@ static struct device_attribute bl_device
__ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
NULL),
__ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+ __ATTR(dimmer_control, 0666, show_dimmer_control, store_dimmer_control),
+ __ATTR(dimmer_timeout, 0666, show_dimmer_timeout, store_dimmer_timeout),
+ __ATTR(dimmer_low_level, 0666, show_dimmer_low_level, store_dimmer_low_level),
+ __ATTR(dimmer_high_level, 0666, show_dimmer_high_level, store_dimmer_high_level),

	__ATTR_NULL,
};

@@ -259,6 +525,7 @@ void backlight_device_unregister(struct #endif

	mutex_lock(&bd->ops_lock);
	bd->ops = NULL;
+  disable_dimmer(bd);
	mutex_unlock(&bd->ops_lock);

	backlight_unregister_fb(bd);
#1 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Jacopo" == jack <[email protected]> writes:

Jacopo> this patch implements a macbook like backlight dimmer on top Jacopo> of backlight.c.

Jacopo, if you want your patch to be reviewed, you should first put it in an acceptable form. You can start by running it through scripts/checkpatch.pl.

Sam

Signature · 1 line
Samuel Tardieu -- [email protected] -- http://www.rfc1149.net/
#2 lore raw

Ok,
now checkpatch.pl only complains about a missing signed-off-by.
Is this ok for review?

jacopo

include/linux/backlight.h +0 -0
@@ -11,6 +11,7 @@

#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
+#include <linux/timeout.h>

/* Notes on locking:
*

@@ -70,6 +71,12 @@ struct backlight_device {
	/* The framebuffer notifier block */
	struct notifier_block fb_notif;

+ /* dimmer stuff */
+ struct timeout *timeout;
+ struct input_handler *input_handler;
+ unsigned short dimmer_low_level;
+ unsigned short dimmer_high_level;
+

	struct device dev;
};
drivers/video/backlight/Makefile +0 -0
@@ -1,7 +1,7 @@

# Backlight & LCD drivers

obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
-obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o +obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o timeout.o
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o

include/linux/timeout.h +68 -0

68 lines not on this page · raw message

drivers/video/backlight/timeout.c +135 -0

135 lines not on this page · raw message

drivers/video/backlight/backlight.c +0 -0
@@ -8,6 +8,7 @@

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/input.h>
#include <linux/backlight.h>
#include <linux/notifier.h>
#include <linux/ctype.h>
@@ -172,13 +173,282 @@ static void bl_device_release(struct dev

	kfree(bd);
}

+/*
+ * ---------------------------------------------------
+ * backlight dimmer
+ * --------------------------------------------------
+ */
+
+static const struct input_device_id idi_dimmer[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT(EV_KEY) },
+ }, /* key event */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_RELBIT,
+ .relbit = { BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) },
+ }, /* rel axes */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+ }, /* abs axes */
+ { }
+};
+
+static void handler_event(struct input_handle *handle, unsigned int type,
+ unsigned int code, int value)
+{
+ struct backlight_device *dev =
+ (struct backlight_device *)handle->private;
+
+ switch (type) {
+ case EV_KEY:
+ case EV_REL:
+ timeout_touch(dev->timeout);
+ }
+}
+
+static void dimmer_start(unsigned long data)
+{
+ struct backlight_device *bd = (struct backlight_device *)data;
+
+ pr_debug("switch to high level\n");
+ bd->props.brightness = bd->dimmer_high_level;
+ backlight_update_status(bd);
+}
+
+static void dimmer_trigger(unsigned long data)
+{
+ struct backlight_device *bd = (struct backlight_device *)data;
+
+ pr_debug("switch to low level\n");
+ bd->props.brightness = bd->dimmer_low_level;
+ backlight_update_status(bd);
+}
+
+static int handler_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ int error = 0;
+ struct input_handle *handle;
+
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->handler = handler;
+ handle->dev = dev;
+ handle->name = "backlight";
+ handle->private = handler->private;
+
+ error = input_register_handle(handle);
+ if (error)
+ goto err_free_handle;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err_unregister_handle;
+
+ return 0;
+
+err_unregister_handle:
+ input_unregister_handle(handle);
+err_free_handle:
+ kfree(handle);
+ return error;
+}
+
+static void handler_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+ kfree(handle);
+}
+
+static int enable_dimmer(struct backlight_device *dev)
+{
+ pr_debug("enable_dimmer()\n");
+ dev->input_handler = kzalloc(sizeof(struct input_handler), GFP_KERNEL);
+ if (!dev->input_handler)
+ return -ENOMEM;
+
+ if (!dev->dimmer_low_level)
+ dev->dimmer_low_level = dev->props.max_brightness/2;
+ if (!dev->dimmer_high_level)
+ dev->dimmer_high_level = dev->props.max_brightness;
+
+ dev->input_handler->event = handler_event;
+ dev->input_handler->connect = handler_connect;
+ dev->input_handler->disconnect = handler_disconnect;
+ dev->input_handler->name = "backlight";
+ dev->input_handler->id_table = idi_dimmer;
+ dev->input_handler->private = dev;
+
+ dev->timeout = kzalloc(sizeof(struct timeout), GFP_KERNEL);
+ if (!dev->timeout)
+ goto free_handler;
+
+ timeout_init(dev->timeout);
+ dev->timeout->duration = timeout_sec2jiffies(5);
+ dev->timeout->data = (unsigned long)dev;
+ dev->timeout->trigger = dimmer_trigger;
+ dev->timeout->start = dimmer_start;
+
+ if (!input_register_handler(dev->input_handler))
+ return 0; /* success */
+ /* else go on & cleanup */
+
+free_handler:
+ kfree(dev->input_handler);
+ dev->input_handler = NULL;
+ return -ENOMEM;
+}
+
+static void disable_dimmer(struct backlight_device *dev)
+{
+ if (!dev->input_handler)
+ return;
+
+ input_unregister_handler(dev->input_handler);
+ timeout_kill(dev->timeout);
+ kfree(dev->input_handler);
+ kfree(dev->timeout);
+ dev->input_handler = NULL;
+ dev->timeout = NULL;
+ pr_debug("disable_dimmer()\n");
+}
+
+/* show */
+static ssize_t show_dimmer_control(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (bd->input_handler != NULL));
+}
+
+static ssize_t show_dimmer_timeout(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ if (bd->timeout)
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ timeout_jif2sec(bd->timeout->duration));
+ else
+ return 0;
+}
+
+static ssize_t show_dimmer_low_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ bd->dimmer_low_level);
+}
+
+static ssize_t show_dimmer_high_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ bd->dimmer_high_level);
+}
+
+/* store */
+static ssize_t store_dimmer_control(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int control = simple_strtoul(buf, &endp, 0);
+
+ mutex_lock(&bd->ops_lock);
+ if (control == 1 && !bd->input_handler)
+ enable_dimmer(bd);
+ else if (control == 0 && bd->input_handler)
+ disable_dimmer(bd);
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_timeout(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int timeout = simple_strtoul(buf, &endp, 0);
+
+ if (timeout <= 0 || timeout >= 60*30)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ if (!bd->timeout) {
+ mutex_unlock(&bd->ops_lock);
+ return -ENXIO;
+ }
+ bd->timeout->duration = timeout_sec2jiffies(timeout);
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_low_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int low = simple_strtoul(buf, &endp, 0);
+
+ if (low < 0 || low > bd->props.max_brightness)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ bd->dimmer_low_level = low;
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
+static ssize_t store_dimmer_high_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct backlight_device *bd = to_backlight_device(dev);
+
+ char *endp;
+ int high = simple_strtoul(buf, &endp, 0);
+
+ if (high < 0 || high > bd->props.max_brightness)
+ return -ENXIO;
+
+ mutex_lock(&bd->ops_lock);
+ bd->dimmer_high_level = high;
+ mutex_unlock(&bd->ops_lock);
+
+ return count;
+}
+
static struct device_attribute bl_device_attributes[] = {
__ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), __ATTR(brightness, 0644, backlight_show_brightness,
- backlight_store_brightness),
+ backlight_store_brightness),
__ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
- NULL),
+ NULL),
__ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+ __ATTR(dimmer_control, 0666, show_dimmer_control, store_dimmer_control),
+ __ATTR(dimmer_timeout, 0666, show_dimmer_timeout, store_dimmer_timeout),
+ __ATTR(dimmer_low_level, 0666, show_dimmer_low_level,
+ store_dimmer_low_level),
+ __ATTR(dimmer_high_level, 0666, show_dimmer_high_level,
+ store_dimmer_high_level),

	__ATTR_NULL,
};

@@ -259,6 +529,7 @@ void backlight_device_unregister(struct #endif

	mutex_lock(&bd->ops_lock);
	bd->ops = NULL;
+	disable_dimmer(bd);
	mutex_unlock(&bd->ops_lock);

	backlight_unregister_fb(bd);
#3 lore raw
Quoted 3 lines · On Sun, 28 Oct 2007 22:30:55 +0100 "[email protected]" <[email protected]>…

Ok,
now checkpatch.pl only complains about a missing signed-off-by.
Is this ok for review?

hi,

when going over your patch.. is there a reason you introduce yet another timeout infrastructure? Is there something wrong with the existing ones that maybe should be fixed instead?
Either way.. please put justification for such new mechanism in the patch changelog....

Greetings,
Arjan van de Ven

Signature · 3 lines
If you want to reach me at my work email, use [email protected]
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org
#4 lore raw
Quoted 10 lines · Arjan van de Ven
Quoted 3 lines · On Sun, 28 Oct 2007 22:30:55 +0100 "[email protected]" <[email protected]>…

Ok,
now checkpatch.pl only complains about a missing signed-off-by.
Is this ok for review?

hi,

Quoted 9 lines

when going over your patch.. is there a reason you introduce yet another timeout infrastructure? Is there something wrong with the existing ones that maybe should be fixed instead?
Either way.. please put justification for such new mechanism in the patch changelog....

Greetings,
Arjan van de Ven

hi,

i don't think there are similar infrastructures. This timeout is not quite a timer.

The timeout starts counting when timeout_touch() is first called. At this point the start() function is executed in non-atomic context. Then either it is reset if timeout_touch() is called in time (and thus starts to count again). Else it triggers, and executes the trigger() function in non-atomic context and it stays idle unless timeout_touch() is called again.

The non-atomic context is needed to use backlight.c mutexes and that is enabled with the use of workqueues.

I don't mean to add some new infrastructure to the base kernel, but it seemed a general functionality to me. In fact it may also be fully included in backlight.c. Since backlight.h is in include/linux, i was forced to put timeout.h in include/linux also. But this is just a temporary fix.

jacopo

#5 lore raw
In reply to [email protected]
Quoted 11 lines · On Sun 2007-10-28 17:10:53, [email protected] wrote:

Hello,
this patch implements a macbook like backlight dimmer on top of backlight.c.

The dimmer is entirely in kernelspace and is suitable for an embedded context in order to avoid the overhead of a daemon controlling the backlight. Implementing this functionality in userspace has other advantages and is a perfectly reasonable alternative, so this patch is not the definitive solution.

Quoted 7 lines

activate dimmer:
echo 1 > /sys/devices/virtual/backlight/*/dimmer_control

other attributes (britness levels & timeout):
/sys/devices/virtual/backlight/*/dimmer_high_level /sys/devices/virtual/backlight/*/dimmer_low_level /sys/devices/virtual/backlight/*/dimmer_timeout

I'd say that userspace makes sense here. I'd want backlight to go down slowly, for example.

But... maybe undimming should be done in kernel, so it keeps low,latency?

Hmm, maybe existing screen blanking infrastructure can be reused?

Review line 16

Quoted 11 lines

--- linux-2.6.23.1/include/linux/backlight.h 2007-10-12 18:43:44.000000000 +0200
+++ b/include/linux/backlight.h 2007-10-28
13:45:21.000000000 +0100

(quoted diff) +1 -0
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/timeout.h>
 
 /* Notes on locking:

Your mail client damages patches?

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#6 lore raw
Quoted 33 lines · Pavel Machek
Quoted 6 lines · On Sun 2007-10-28 17:10:53, [email protected] wrote:

Hello,
this patch implements a macbook like backlight dimmer on top of backlight.c.

The dimmer is entirely in kernelspace and is suitable for an embedded context in order to avoid the overhead of a daemon controlling the backlight. Implementing this functionality in userspace has other advantages and is a perfectly reasonable alternative, so this patch is not the definitive solution.

Quoted 7 lines

activate dimmer:
echo 1 > /sys/devices/virtual/backlight/*/dimmer_control

other attributes (britness levels & timeout):
/sys/devices/virtual/backlight/*/dimmer_high_level /sys/devices/virtual/backlight/*/dimmer_low_level /sys/devices/virtual/backlight/*/dimmer_timeout

I'd say that userspace makes sense here. I'd want backlight to go down slowly, for example.

But... maybe undimming should be done in kernel, so it keeps low,latency?

Hmm, maybe existing screen blanking infrastructure can be reused?

Quoted 10 lines

--- linux-2.6.23.1/include/linux/backlight.h 2007-10-12 18:43:44.000000000 +0200
+++ b/include/linux/backlight.h 2007-10-28
13:45:21.000000000 +0100

(quoted diff) +1 -0
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/timeout.h>
 
Quoted 4 lines

Review line 16

Quoted 1 line
(quoted diff) +0 -0
 /* Notes on locking:

Your mail client damages patches?

Hi,
incremental dimming can be easily implemented on top of this patch. It's just about posting the timeout repeatedly. I will post something in the near future :).

I believe the userspace vs kernelspace argument is very arbitrary.

As i said, the dimmer can be completely coded in userspace. There are good reasons for that. Userspace apps can work out better than the kernel what the user is doing. If the user is watching a movie for instance, the dimmer should be stopped.

However, the patch is just a light addition to backlight.c. If the dimmer is stopped/unused, just a few pointers and some code are wasted.

Userspace apps can start, stop and change the timeout value for the dimmer on the fly, as if they were doing the dimming themselves. In this case, userspace only notifies the kernel to stop the dimmer whenever such action is deemed right. Instead when the dimmer is on, which is most of the time, no kernespace/userspace switch is necessary.

Changing the brightness might occur every 10 seconds or so. IMHO this is more of a realtime (and thus kernelspace) requirement rather than userspace. This also saves us from having a whole (heavyweight) dedicated process managing such a basic functionality.

Finally, implementing the dimmer in kernelspace delivers this functionality everywhere provided Linux is used. No additional software is necessary. This latter would usually have to be tailored to different audiences such as desktop, embedded, whatever.

I don't think thunderbird is breaking the patch, since i was able to apply it from my previous posts. However here is a web location for it, just in case: http://www.antonello.org/dimmer/. Please let me know if you can't test it!

jacopo