Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e07ff8d8 authored by Philipp Zabel's avatar Philipp Zabel Committed by Russell King
Browse files

[ARM] 4952/1: magician: add LCD detection, LCD power switching, update pxafb settings



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: default avatarPhilipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 350d115d
Loading
Loading
Loading
Loading
+114 −7
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio_keys.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/input.h>
#include <linux/mfd/htc-egpio.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[] = {
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 = {
static struct pxafb_mach_info toppoly_info = {
	.modes           = toppoly_modes,
	.modes           = toppoly_modes,
	.num_modes       = 1,
	.num_modes       = 1,
	.fixed_modes     = 1,
	.fixed_modes     = 1,
	.lccr0           = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr0           = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr3           = LCCR3_PixRsEdg,
	.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)
static void __init magician_init(void)
{
{
	void __iomem *cpld;
	int lcd_select;

	platform_add_devices(devices, ARRAY_SIZE(devices));
	platform_add_devices(devices, ARRAY_SIZE(devices));
	pxa_set_i2c_info(NULL);
	pxa_set_i2c_info(NULL);
	pxa_set_mci_info(&magician_mci_info);
	pxa_set_mci_info(&magician_mci_info);
	pxa_set_ohci_info(&magician_ohci_info);
	pxa_set_ohci_info(&magician_ohci_info);
	pxa_set_ficp_info(&magician_ficp_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");
}
}




+2 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
#define GPIO48_MAGICIAN_UNKNOWN			48
#define GPIO48_MAGICIAN_UNKNOWN			48
#define GPIO56_MAGICIAN_UNKNOWN			56
#define GPIO56_MAGICIAN_UNKNOWN			56
#define GPIO57_MAGICIAN_CAM_RESET		57
#define GPIO57_MAGICIAN_CAM_RESET		57
#define GPIO75_MAGICIAN_SAMSUNG_POWER		75
#define GPIO83_MAGICIAN_nIR_EN			83
#define GPIO83_MAGICIAN_nIR_EN			83
#define GPIO86_MAGICIAN_GSM_RESET		86
#define GPIO86_MAGICIAN_GSM_RESET		86
#define GPIO87_MAGICIAN_GSM_SELECT		87
#define GPIO87_MAGICIAN_GSM_SELECT		87
@@ -82,6 +83,7 @@
#define GPIO48_MAGICIAN_UNKNOWN_MD		(48 | GPIO_OUT)
#define GPIO48_MAGICIAN_UNKNOWN_MD		(48 | GPIO_OUT)
#define GPIO56_MAGICIAN_UNKNOWN_MD		(56 | GPIO_OUT)
#define GPIO56_MAGICIAN_UNKNOWN_MD		(56 | GPIO_OUT)
#define GPIO57_MAGICIAN_CAM_RESET_MD		(57 | 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 GPIO83_MAGICIAN_nIR_EN_MD		(83 | GPIO_OUT)
#define GPIO86_MAGICIAN_GSM_RESET_MD		(86 | GPIO_OUT)
#define GPIO86_MAGICIAN_GSM_RESET_MD		(86 | GPIO_OUT)
#define GPIO87_MAGICIAN_GSM_SELECT_MD		(87 | GPIO_OUT)
#define GPIO87_MAGICIAN_GSM_SELECT_MD		(87 | GPIO_OUT)