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

List:       linux-arm-kernel
Subject:    [PATCH 10/10] magician: add LCD detection, power switching
From:       Philipp Zabel <philipp.zabel () gmail ! com>
Date:       2007-12-28 12:32:26
Message-ID: 1198845146.8701.55.camel () localhost ! localdomain
[Download RAW message or body]


This adds LCD detection, Toppoly power switching and Samsung pxafb
settings. All magician devices I've encountered so far have featured the
Toppoly TD028STEB1 display, so the Samsung LTP280QV support is untested.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 arch/arm/mach-pxa/magician.c |   99 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 92 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 78a850b..d857653 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/mfd/htc-egpio.h>
@@ -143,7 +144,7 @@ static struct platform_device egpio = {
 };
 
 /*
- * LCD - Toppoly TD028STEB1
+ * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
  */
 
 static struct pxafb_mode_info toppoly_modes[] = {
@@ -162,12 +163,83 @@ static struct pxafb_mode_info toppoly_modes[] = {
 	},
 };
 
+static struct pxafb_mode_info samsung_modes[] = {
+	{
+		.pixclock     = 96153,
+		.bpp          = 16,
+		.xres         = 240,
+		.yres         = 320,
+		.hsync_len    = 4,
+		.vsync_len    = 1,
+		.left_margin  = 20,
+		.upper_margin = 7,
+		.right_margin = 8,
+		.lower_margin = 8,
+		.sync         = 0,
+	},
+};
+
+static void toppoly_lcd_power(int state, struct fb_var_screeninfo *si)
+{
+	pr_debug("Toppoly LCD power\n");
+
+	switch (state) {
+	case PXAFB_LCD_POWER_ENABLE_PRE:
+		pr_debug("on (pre)\n");
+		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
+		pxa_gpio_mode(GPIO104_MAGICIAN_LCD_POWER_1_MD);
+		pxa_gpio_mode(GPIO105_MAGICIAN_LCD_POWER_2_MD);
+		pxa_gpio_mode(GPIO106_MAGICIAN_LCD_POWER_3_MD);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+		udelay(2000);
+		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
+		udelay(2000);
+		break;
+	case PXAFB_LCD_POWER_ENABLE_POST:
+		pr_debug("on (post)\n");
+		udelay(2000);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+		udelay(2000);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+		break;
+	case PXAFB_LCD_POWER_DISABLE_PRE:
+		pr_debug("off (pre)\n");
+		break;
+	case PXAFB_LCD_POWER_DISABLE_POST:
+		pr_debug("off (post)\n");
+		msleep(15);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+		udelay(500);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+		udelay(1000);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
+	}
+}
+
+static void samsung_lcd_power(int state, struct fb_var_screeninfo *si)
+{
+	/* REVISIT: implement samsung power switching */
+	pr_err("Samsung LCD power not yet implemented");
+	return;
+}
+
 static struct pxafb_mach_info toppoly_info = {
-	.modes       = toppoly_modes,
-	.num_modes   = 1,
-	.fixed_modes = 1,
-	.lccr0       = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3       = LCCR3_PixRsEdg,
+	.modes           = toppoly_modes,
+	.num_modes       = 1,
+	.fixed_modes     = 1,
+	.lccr0           = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3           = LCCR3_PixRsEdg,
+	.pxafb_lcd_power = toppoly_lcd_power,
+};
+
+static struct pxafb_mach_info samsung_info = {
+	.modes           = samsung_modes,
+	.num_modes       = 1,
+	.fixed_modes     = 1,
+	.lccr0           = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3           = LCCR3_PixFlEdg,
+	.pxafb_lcd_power = samsung_lcd_power,
 };
 
 /*
@@ -371,13 +443,26 @@ static struct platform_device *devices[] __initdata = {
 
 static void __init magician_init(void)
 {
+	void __iomem *cpld;
+	int lcd_select;
+
 	gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
 	pxa_set_ficp_info(&magician_ficp_info);
-	set_pxa_fb_info(&toppoly_info);
+
+	/* Check LCD type we have */
+	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
+	if (cpld) {
+		lcd_select = __raw_readb(cpld+0x14) & 0x8;
+		iounmap(cpld);
+		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
+		set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
+	} else
+		pr_err("LCD detection: CPLD mapping failed\n");
+	iounmap(cpld);
 }
 
 
-- 
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