121 lines
3.5 KiB
Diff
121 lines
3.5 KiB
Diff
From 9aa87d67df2e59eea15f70c4e58f8bde10e5953b Mon Sep 17 00:00:00 2001
|
|
From: Harald Welte <laforge@openmoko.org>
|
|
Date: Wed, 8 Oct 2008 11:13:46 +0100
|
|
Subject: [PATCH] This patch adds a framebuffer notifier in order to detect
|
|
FB_BLANK events and switch the JBT6K74 LCM controller into
|
|
its power saving mode.
|
|
|
|
This has the potential of saving something like 50mW during screen blank.
|
|
|
|
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
|
---
|
|
drivers/video/display/jbt6k74.c | 48 +++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 48 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
|
|
index b406298..9570543 100644
|
|
--- a/drivers/video/display/jbt6k74.c
|
|
+++ b/drivers/video/display/jbt6k74.c
|
|
@@ -3,6 +3,7 @@
|
|
* Copyright (C) 2006-2007 by Openmoko, Inc.
|
|
* Author: Harald Welte <laforge@openmoko.org>,
|
|
* Stefan Schmidt <stefan@openmoko.org>
|
|
+ * Copyright (C) 2008 by Harald Welte <laforge@openmoko.org>
|
|
* All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
@@ -21,6 +22,7 @@
|
|
* MA 02111-1307 USA
|
|
*
|
|
*/
|
|
+
|
|
#include <linux/kernel.h>
|
|
#include <linux/types.h>
|
|
#include <linux/module.h>
|
|
@@ -28,6 +30,7 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/jbt6k74.h>
|
|
+#include <linux/fb.h>
|
|
|
|
enum jbt_register {
|
|
JBT_REG_SLEEP_IN = 0x10,
|
|
@@ -111,6 +114,7 @@ struct jbt_info {
|
|
enum jbt_state state, last_state;
|
|
struct spi_device *spi_dev;
|
|
struct mutex lock; /* protects tx_buf and reg_cache */
|
|
+ struct notifier_block fb_notif;
|
|
u16 tx_buf[8];
|
|
u16 reg_cache[0xEE];
|
|
int have_resumed;
|
|
@@ -548,6 +552,40 @@ static struct attribute_group jbt_attr_group = {
|
|
.attrs = jbt_sysfs_entries,
|
|
};
|
|
|
|
+static int fb_notifier_callback(struct notifier_block *self,
|
|
+ unsigned long event, void *data)
|
|
+{
|
|
+ struct jbt_info *jbt;
|
|
+ struct fb_event *evdata = data;
|
|
+ int fb_blank;
|
|
+
|
|
+ if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
|
|
+ return 0;
|
|
+
|
|
+ fb_blank = *(int *)evdata->data;
|
|
+ jbt = container_of(self, struct jbt_info, fb_notif);
|
|
+
|
|
+ switch (fb_blank) {
|
|
+ case FB_BLANK_UNBLANK:
|
|
+ case FB_BLANK_NORMAL:
|
|
+ jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
|
+ jbt6k74_display_onoff(jbt, 1);
|
|
+ break;
|
|
+ case FB_BLANK_VSYNC_SUSPEND:
|
|
+ case FB_BLANK_HSYNC_SUSPEND:
|
|
+ /* FIXME: we disable SLEEP since it would result in
|
|
+ * a visible artefact (white screen) before the backlight
|
|
+ * is dimmed to a dark enough level */
|
|
+ /* jbt6k74_enter_state(jbt, JBT_STATE_SLEEP); */
|
|
+ break;
|
|
+ case FB_BLANK_POWERDOWN:
|
|
+ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* linux device model infrastructure */
|
|
|
|
static int __devinit jbt_probe(struct spi_device *spi)
|
|
@@ -595,8 +633,17 @@ static int __devinit jbt_probe(struct spi_device *spi)
|
|
goto err_off;
|
|
}
|
|
|
|
+ jbt->fb_notif.notifier_call = fb_notifier_callback;
|
|
+ rc = fb_register_client(&jbt->fb_notif);
|
|
+ if (rc < 0) {
|
|
+ dev_err(&spi->dev, "cannot register notifier\n");
|
|
+ goto err_sysfs;
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
+err_sysfs:
|
|
+ sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
|
|
err_off:
|
|
jbt6k74_display_onoff(jbt, 0);
|
|
err_standby:
|
|
@@ -615,6 +662,7 @@ static int __devexit jbt_remove(struct spi_device *spi)
|
|
/* We don't want to switch off the display in case the user
|
|
* accidentially onloads the module (whose use count normally is 0) */
|
|
|
|
+ fb_unregister_client(&jbt->fb_notif);
|
|
sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
|
|
dev_set_drvdata(&spi->dev, NULL);
|
|
kfree(jbt);
|
|
--
|
|
1.5.6.5
|
|
|