[ARM] 4952/1: magician: add LCD detection, LCD power switching, update pxafb settings
authorPhilipp Zabel <philipp.zabel@gmail.com>
Wed, 9 Apr 2008 18:27:10 +0000 (19:27 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 19 Apr 2008 10:29:07 +0000 (11:29 +0100)
All magician devices I've encountered so far have featured the Toppoly
TD028STEB1 display, so the Samsung LTP280QV support is untested.
The power-on sequence is not correct because pxafb doesn't yet support
enabling the LCD controller in the middle of the it.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-pxa/magician.c
include/asm-arm/arch-pxa/magician.h

index d152a086e7346059a5305cb0a6938c49715fb37a..7de3bfe543b474569d3178405a2f60039b8fc6c3 100644 (file)
@@ -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>
@@ -144,7 +145,7 @@ static struct platform_device egpio = {
 };
 
 /*
- * LCD - Toppoly TD028STEB1
+ * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
  */
 
 static struct pxafb_mode_info toppoly_modes[] = {
@@ -163,12 +164,99 @@ static struct pxafb_mode_info toppoly_modes[] = {
        },
 };
 
+static struct pxafb_mode_info samsung_modes[] = {
+       {
+               .pixclock     = 96153,
+               .bpp          = 16,
+               .xres         = 240,
+               .yres         = 320,
+               .hsync_len    = 8,
+               .vsync_len    = 4,
+               .left_margin  = 9,
+               .upper_margin = 4,
+               .right_margin = 9,
+               .lower_margin = 4,
+               .sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       },
+};
+
+static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+       pr_debug("Toppoly LCD power\n");
+
+       if (on) {
+               pr_debug("on\n");
+               gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+               udelay(2000);
+               gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
+               udelay(2000);
+               /* FIXME: enable LCDC here */
+               udelay(2000);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+               udelay(2000);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+       } else {
+               pr_debug("off\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 on, struct fb_var_screeninfo *si)
+{
+       pr_debug("Samsung LCD power\n");
+
+       if (on) {
+               pr_debug("on\n");
+               if (system_rev < 3)
+                       gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
+               else
+                       gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
+               mdelay(10);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+               mdelay(10);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+               mdelay(30);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+               mdelay(10);
+       } else {
+               pr_debug("off\n");
+               mdelay(10);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+               mdelay(30);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+               mdelay(10);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+               mdelay(10);
+               if (system_rev < 3)
+                       gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
+               else
+                       gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
+       }
+}
+
 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_LDDALT | LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3           = LCCR3_PixFlEdg,
+       .pxafb_lcd_power = samsung_lcd_power,
 };
 
 /*
@@ -358,12 +446,31 @@ static struct platform_device *devices[] __initdata = {
 
 static void __init magician_init(void)
 {
+       void __iomem *cpld;
+       int lcd_select;
+
        platform_add_devices(devices, ARRAY_SIZE(devices));
        pxa_set_i2c_info(NULL);
        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) {
+               u8 board_id = __raw_readb(cpld+0x14);
+               system_rev = board_id & 0x7;
+               lcd_select = board_id & 0x8;
+               iounmap(cpld);
+               pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
+               if (lcd_select && (system_rev < 3))
+                       pxa_gpio_mode(GPIO75_MAGICIAN_SAMSUNG_POWER_MD);
+               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);
+               set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
+       } else
+               pr_err("LCD detection: CPLD mapping failed\n");
 }
 
 
index 216921db9d6304dc04e127a72ad9bf54ac420eee..b34fd5683e2d20876805e6b7abe25a8708babced 100644 (file)
@@ -35,6 +35,7 @@
 #define GPIO48_MAGICIAN_UNKNOWN                        48
 #define GPIO56_MAGICIAN_UNKNOWN                        56
 #define GPIO57_MAGICIAN_CAM_RESET              57
+#define GPIO75_MAGICIAN_SAMSUNG_POWER          75
 #define GPIO83_MAGICIAN_nIR_EN                 83
 #define GPIO86_MAGICIAN_GSM_RESET              86
 #define GPIO87_MAGICIAN_GSM_SELECT             87
@@ -82,6 +83,7 @@
 #define GPIO48_MAGICIAN_UNKNOWN_MD             (48 | GPIO_OUT)
 #define GPIO56_MAGICIAN_UNKNOWN_MD             (56 | GPIO_OUT)
 #define GPIO57_MAGICIAN_CAM_RESET_MD           (57 | GPIO_OUT)
+#define GPIO75_MAGICIAN_SAMSUNG_POWER_MD       (75 | GPIO_OUT)
 #define GPIO83_MAGICIAN_nIR_EN_MD              (83 | GPIO_OUT)
 #define GPIO86_MAGICIAN_GSM_RESET_MD           (86 | GPIO_OUT)
 #define GPIO87_MAGICIAN_GSM_SELECT_MD          (87 | GPIO_OUT)