[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-arm-kernel
Subject:    [PATCH 9/10] pxafb: add support for more fine-grained LCD
From:       Philipp Zabel <philipp.zabel () gmail ! com>
Date:       2007-12-28 12:32:23
Message-ID: 1198845143.8701.54.camel () localhost ! localdomain
[Download RAW message or body]


This adds the ability to configure LCD voltages before and after
enabling/disabling the PXA LCD controller.

>From reverse engineering the wince drivers on a HTC Magician, something
like this seems to be needed on some devices for flicker-free blanking.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 arch/arm/mach-pxa/corgi_lcd.c    |   14 +++++++++++---
 arch/arm/mach-pxa/idp.c          |   12 +++++++++---
 drivers/video/pxafb.c            |   18 +++++++++++-------
 include/asm-arm/arch-pxa/pxafb.h |    6 ++++++
 4 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 365b943..17043ca 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -431,12 +431,20 @@ struct platform_device corgifb_device = {
 
 #include <asm/arch/pxafb.h>
 
-void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
+void spitz_lcd_power(int state, struct fb_var_screeninfo *var)
 {
-	if (on)
+	switch (state) {
+	case PXAFB_LCD_POWER_ENABLE_PRE:
+		break;
+	case PXAFB_LCD_POWER_ENABLE_POST:
 		lcdtg_hw_init(var->xres);
-	else
+		break;
+	case PXAFB_LCD_POWER_DISABLE_PRE:
 		lcdtg_suspend();
+		break;
+	case PXAFB_LCD_POWER_DISABLE_POST:
+		break;
+	}
 }
 
 #endif
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 465108d..4b20ac3 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -83,12 +83,18 @@ static void idp_vlcd(int on)
 	}
 }
 
-static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
+static void idp_lcd_power(int state, struct fb_var_screeninfo *var)
 {
-	if (on) {
+	switch (state) {
+	case PXAFB_LCD_POWER_ENABLE_PRE:
+		break;
+	case PXAFB_LCD_POWER_ENABLE_POST:
 		IDP_CPLD_LCD |= (1<<0);
-	} else {
+		break;
+	case PXAFB_LCD_POWER_DISABLE_PRE:
 		IDP_CPLD_LCD &= ~(1<<0);
+		break;
+	case PXAFB_LCD_POWER_DISABLE_POST:
 	}
 
 	/* call idp_vlcd for now as core driver does not support
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 10f912d..38639d7 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -776,12 +776,12 @@ static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on)
  		pxafb_backlight_power(on);
 }
 
-static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
+static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int state)
 {
-	pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
+	pr_debug("pxafb: LCD power o%s\n", (state & 1) ? "n" : "ff");
 
 	if (pxafb_lcd_power)
-		pxafb_lcd_power(on, &fbi->fb.var);
+		pxafb_lcd_power(state, &fbi->fb.var);
 }
 
 static void pxafb_setup_gpio(struct pxafb_info *fbi)
@@ -933,9 +933,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
 		if (old_state != C_DISABLE) {
 			fbi->state = state;
 			__pxafb_backlight_power(fbi, 0);
-			__pxafb_lcd_power(fbi, 0);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_DISABLE_PRE);
 			if (old_state != C_DISABLE_CLKCHANGE)
 				pxafb_disable_controller(fbi);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_DISABLE_POST);
 		}
 		break;
 
@@ -958,11 +959,13 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
 		 * registers.
 		 */
 		if (old_state == C_ENABLE) {
-			__pxafb_lcd_power(fbi, 0);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_DISABLE_PRE);
 			pxafb_disable_controller(fbi);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_DISABLE_POST);
 			pxafb_setup_gpio(fbi);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_ENABLE_PRE);
 			pxafb_enable_controller(fbi);
-			__pxafb_lcd_power(fbi, 1);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_ENABLE_POST);
 		}
 		break;
 
@@ -984,8 +987,9 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
 		if (old_state != C_ENABLE) {
 			fbi->state = C_ENABLE;
 			pxafb_setup_gpio(fbi);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_ENABLE_PRE);
 			pxafb_enable_controller(fbi);
-			__pxafb_lcd_power(fbi, 1);
+			__pxafb_lcd_power(fbi, PXAFB_LCD_POWER_ENABLE_POST);
 			__pxafb_backlight_power(fbi, 1);
 		}
 		break;
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index ea2336a..6471834 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -83,3 +83,9 @@ struct pxafb_mach_info {
 void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
 void set_pxa_fb_parent(struct device *parent_dev);
 unsigned long pxafb_get_hsync_time(struct device *dev);
+
+#define PXAFB_LCD_POWER_ENABLE_PRE	3
+#define PXAFB_LCD_POWER_ENABLE_POST	1
+#define PXAFB_LCD_POWER_DISABLE_PRE	0
+#define PXAFB_LCD_POWER_DISABLE_POST	2
+
-- 
1.5.3.7



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic