android_kernel_cmhtcleo/arch/arm/mach-msm/board-supersonic-panel.c
2010-08-27 11:19:57 +02:00

922 lines
19 KiB
C

/* linux/arch/arm/mach-msm/board-supersonic-panel.c
*
* Copyright (C) 2008 HTC Corporation.
* Author: Jay Tu <jay_tu@htc.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <mach/msm_fb.h>
#include <mach/msm_iomap.h>
#include <mach/vreg.h>
/* #include <mach/pmic.h> */
#include "board-supersonic.h"
#include "devices.h"
#include "proc_comm.h"
#if 1
#define B(s...) printk(s)
#else
#define B(s...) do {} while(0)
#endif
extern int panel_type;
enum {
PANEL_SHARP,
PANEL_AUO,
};
static struct cabc_t {
struct led_classdev lcd_backlight;
struct msm_mddi_client_data *client_data;
struct mutex lock;
unsigned long status;
} cabc;
enum {
GATE_ON = 1 << 0,
};
static struct vreg *vreg_lcd_2v8;
static struct vreg *vreg_lcd_1v8;
#define REG_WAIT (0xffff)
struct nov_regs {
unsigned reg;
unsigned val;
} nov_init_seq[] = {
{0xc000, 0x86},
{0xc001, 0x00},
{0xc002, 0x86},
{0xc003, 0x00},
{0xc100, 0x40},
{0xc200, 0x02},
{0xc202, 0x32},
{0xe000, 0x0e},
{0xe001, 0x34},
{0xe002, 0x3F},
{0xe003, 0x49},
{0xe004, 0x1D},
{0xe005, 0x2C},
{0xe006, 0x5F},
{0xe007, 0x3A},
{0xe008, 0x20},
{0xe009, 0x28},
{0xe00a, 0x80},
{0xe00b, 0x13},
{0xe00c, 0x32},
{0xe00d, 0x56},
{0xe00e, 0x79},
{0xe00f, 0xB8},
{0xe010, 0x55},
{0xe011, 0x57},
{0xe100, 0x0e},
{0xe101, 0x34},
{0xe102, 0x3F},
{0xe103, 0x49},
{0xe104, 0x1D},
{0xe105, 0x2C},
{0xe106, 0x5F},
{0xe107, 0x3A},
{0xe108, 0x20},
{0xe109, 0x28},
{0xe10a, 0x80},
{0xe10b, 0x13},
{0xe10c, 0x32},
{0xe10d, 0x56},
{0xe10e, 0x79},
{0xe10f, 0xB8},
{0xe110, 0x55},
{0xe111, 0x57},
{0xe200, 0x0E},
{0xe201, 0x34},
{0xe202, 0x3F},
{0xe203, 0x49},
{0xe204, 0x1D},
{0xe205, 0x2C},
{0xe206, 0x5F},
{0xe207, 0x3A},
{0xe208, 0x20},
{0xe209, 0x28},
{0xe20A, 0x80},
{0xe20B, 0x13},
{0xe20C, 0x32},
{0xe20D, 0x56},
{0xe20E, 0x79},
{0xe20F, 0xB8},
{0xe210, 0x55},
{0xe211, 0x57},
{0xe300, 0x0E},
{0xe301, 0x34},
{0xe302, 0x3F},
{0xe303, 0x49},
{0xe304, 0x1D},
{0xe305, 0x2C},
{0xe306, 0x5F},
{0xe307, 0x3A},
{0xe308, 0x20},
{0xe309, 0x28},
{0xe30A, 0x80},
{0xe30B, 0x13},
{0xe30C, 0x32},
{0xe30D, 0x56},
{0xe30E, 0x79},
{0xe30F, 0xB8},
{0xe310, 0x55},
{0xe311, 0x57},
{0xe400, 0x0E},
{0xe401, 0x34},
{0xe402, 0x3F},
{0xe403, 0x49},
{0xe404, 0x1D},
{0xe405, 0x2C},
{0xe406, 0x5F},
{0xe407, 0x3A},
{0xe408, 0x20},
{0xe409, 0x28},
{0xe40A, 0x80},
{0xe40B, 0x13},
{0xe40C, 0x32},
{0xe40D, 0x56},
{0xe40E, 0x79},
{0xe40F, 0xB8},
{0xe410, 0x55},
{0xe411, 0x57},
{0xe500, 0x0E},
{0xe501, 0x34},
{0xe502, 0x3F},
{0xe503, 0x49},
{0xe504, 0x1D},
{0xe505, 0x2C},
{0xe506, 0x5F},
{0xe507, 0x3A},
{0xe508, 0x20},
{0xe509, 0x28},
{0xe50A, 0x80},
{0xe50B, 0x13},
{0xe50C, 0x32},
{0xe50D, 0x56},
{0xe50E, 0x79},
{0xe50F, 0xB8},
{0xe510, 0x55},
{0xe511, 0x57},
{0x3a00, 0x05},
/* cabc */
{0x4e00, 0x00},
{0x5e00, 0x00},
{0x6a01, 0x00},
{0x6a02, 0x03},
{0x5100, 0xff},
{0x5301, 0x10},
{0x6A18, 0xff},
{0x6A17, 0x01},
{0xF402, 0x14},
{0x3500, 0x00},
{0x1100, 0x0},
{REG_WAIT, 120},
};
struct s1d_regs {
unsigned reg;
unsigned val;
} s1d13775_init_seq[] = {
{0x001C, 0x1500},
{0x0020, 0x3047},
{0x0024, 0x401A},
{0x0028, 0x031A},
{0x002C, 0x0001},
{REG_WAIT, 0x0004}, /* increase delay 1ms -> 4ms */
{0x0084, 0x0215},
{0x0088, 0x0038},
{0x008C, 0x2113},
{0x002C, 0x0002},
{REG_WAIT, 0x0004}, /* increase delay 1ms -> 4ms */
{0x002C, 0x0003},
{0x0100, 0x3702},
{0x0104, 0x0180},
{0x0140, 0x003F},
{0x0144, 0x00EF},
{0x0148, 0x0016},
{0x014C, 0x0005},
{0x0150, 0x0006},
{0x0154, 0x032B},
{0x0158, 0x031F},
{0x015C, 0x0009},
{0x0160, 0x0002},
{0x0164, 0x0003},
{0x0168, 0x00A2},
{0x0180, 0x0057},
{0x0184, 0x00DB},
{0x0188, 0x00E3},
{0x018C, 0x0000},
{0x0190, 0x0000},
{0x0280, 0x0000},
{0x0284, 0x0002},
{0x0288, 0x0000},
{0x028C, 0x0001},
{0x0294, 0x0000},
{0x0400, 0x8000},
{0x0404, 0x1001},
{0x0480, 0x0001},
{0x0500, 0x0000},
{0x0504, 0x0011},
{0x0508, 0x0000},
{0x0510, 0x0000},
{0x0518, 0x002E},
{0x051C, 0x00c7},
{0x0520, 0x01DF},
{0x0524, 0x031f},
{0x0528, 0x0000},
{0x052C, 0x0000},
{0x0530, 0x0000},
{0x0534, 0x0000},
{0x0604, 0x0108},
{0x060C, 0x0000},
{0x0610, 0x00ff},
{0x0648, 0x0020},
{0x0800, 0x0000},
{0x0804, 0x000A},
{0x0808, 0x0400},
{0x080C, 0x0400},
{0x0814, 0x0000},
{0x081C, 0x0000},
{0x0824, 0x002E},
{0x0828, 0x00C7},
{0x082C, 0x01DF},
{0x0830, 0x031F},
{0x0834, 0x0000},
{0x0838, 0x0000},
{0x083C, 0x0000},
{0x0840, 0x0000},
{0x0844, 0x01DF},
{0x0848, 0x031F},
{0x0870, 0x0064},
{0x0874, 0x0064},
{0x0878, 0x00C7},
{0x087C, 0x00C7},
{0x1410, 0x0004},
{0x1414, 0x00FF},
{0x1420, 0x0000},
{0x1424, 0x0000},
{0x1428, 0x01DF},
{0x142C, 0x031F},
{0x1430, 0xDC00},
{0x1434, 0x0005},
{0x1440, 0x0000},
{0x1444, 0x0000},
{0x1448, 0x01DF},
{0x144C, 0x031F},
{0x1450, 0x0000},
{0x1454, 0x0000},
{0x1458, 0x01DF},
{0x145C, 0x031F},
{0x1460, 0x0000},
{0x1464, 0x0000},
{0x1468, 0x01DF},
{0x146C, 0x031F},
{0x1470, 0x0000},
{0x1474, 0x0000},
{0x1478, 0x01DF},
{0x147C, 0x031F},
{0x14A4, 0x0110},
{0x14A8, 0xAFC8},
{0x14AC, 0x0FF0},
{0x14B0, 0x0202},
{0x14B4, 0x0080},
{0x14A0, 0x0002},
{0x1508, 0x0000},
{0x150C, 0x0000},
{0x1510, 0x0000},
{0x1514, 0x0000},
{0x1520, 0x0000},
{0x1524, 0x0000},
{0x1528, 0x0000},
{0x152C, 0x0000},
{0x1530, 0x0000},
{0x1534, 0x0000},
{0x1538, 0x0000},
{0x153C, 0x0000},
{0x1540, 0x0000},
{0x1544, 0x0000},
{0x1548, 0x0000},
{0x154C, 0x0000},
{0x1550, 0x0000},
{0x1554, 0x0000},
{0x1558, 0x0000},
{0x1600, 0x0000},
{0x1604, 0x0020},
{0x1608, 0x0040},
{0x160C, 0x0060},
{0x1610, 0x0080},
{0x1614, 0x00A0},
{0x1618, 0x00C0},
{0x161C, 0x00E0},
{0x1620, 0x0100},
{0x1624, 0x0000},
{0x1628, 0x0020},
{0x162C, 0x0040},
{0x1630, 0x0060},
{0x1634, 0x0080},
{0x1638, 0x00A0},
{0x163C, 0x00C0},
{0x1640, 0x00E0},
{0x1644, 0x0100},
{0x1648, 0x0000},
{0x164C, 0x0020},
{0x1650, 0x0040},
{0x1654, 0x0060},
{0x1658, 0x0080},
{0x165C, 0x00A0},
{0x1660, 0x00C0},
{0x1664, 0x00E0},
{0x1668, 0x0100},
{0x1680, 0x0000},
{0x1684, 0x0000},
{0x1688, 0x0000},
{0x168C, 0x0000},
{0x1694, 0x0000},
{0x16A0, 0x0000},
{0x16A4, 0x0000},
{0x16A8, 0x0000},
{0x16AC, 0x0000},
{0x16B4, 0x0000},
{0x16C0, 0x0000},
{0x16C4, 0x0000},
{0x16C8, 0x0000},
{0x16CC, 0x0000},
{0x16D4, 0x0000},
{0x16E0, 0x0000},
{0x16E4, 0x0000},
{0x16E8, 0x0000},
{0x16EC, 0x0000},
{0x16F4, 0x0000},
{0x1700, 0x0000},
{0x1704, 0x0000},
{0x1708, 0x0000},
{0x170C, 0x0000},
{0x1714, 0x0000},
{0x1720, 0x0000},
{0x1724, 0x0000},
{0x1728, 0x0000},
{0x172C, 0x0000},
{0x1734, 0x0000},
{0x1740, 0x0000},
{0x1744, 0x0000},
{0x1748, 0x0000},
{0x174C, 0x0000},
{0x1754, 0x0000},
{0x1760, 0x0000},
{0x1764, 0x0000},
{0x1768, 0x0000},
{0x176C, 0x0000},
{0x1774, 0x0000},
{0x0300, 0x7000},
{0x0304, 0x0000},
{0x0308, 0x0000},
{0x030C, 0x0000},
{0x0310, 0x0000},
{0x0314, 0x0000},
{0x0318, 0xF7FF},
{0x031C, 0xFFFF},
{0x0320, 0x000F},
{0x0324, 0x0000},
{0x0328, 0x0000},
{0x032C, 0x0000},
};
struct s1d_regs pwm_seq[] = {
{0x001C, 0x0010},
{0x14A0, 0x0001},
{0x14A4, 0x0110},
{0x14B0, 0x3030},
{0x14A8, 0x09C4},
{0x14AC, 0x0FF0},
};
extern int qspi_send_9bit(unsigned char id, unsigned data);
extern int qspi_send_16bit(unsigned char id, unsigned data);
static void suc_set_brightness(struct led_classdev *led_cdev,
enum led_brightness val)
{
struct msm_mddi_client_data *client = cabc.client_data;
unsigned int shrink_br = val;
printk(KERN_DEBUG "set brightness = %d\n", val);
if (test_bit(GATE_ON, &cabc.status) == 0)
return;
if (val < 30)
shrink_br = 5;
else if ((val >= 30) && (val <= 143))
shrink_br = 104 * (val - 30) / 113 + 5;
else
shrink_br = 145 * (val - 144) / 111 + 110;
mutex_lock(&cabc.lock);
if (panel_type == PANEL_SHARP) {
int i, reg, val;
for (i = 0; i < ARRAY_SIZE(pwm_seq); i++) {
reg = pwm_seq[i].reg;
val = pwm_seq[i].val;
if (reg == REG_WAIT)
hr_msleep(val);
else
client->remote_write(client, cpu_to_le32(val), reg);
}
client->remote_write(client, shrink_br, 0x14B4);
} else {
qspi_send_16bit(0x1, 0x55);
qspi_send_16bit(0x0, 0x00);
qspi_send_16bit(0x2, 0x00);
qspi_send_16bit(0x1, 0x51);
qspi_send_16bit(0x0, 0x00);
qspi_send_16bit(0x2, shrink_br);
}
mutex_unlock(&cabc.lock);
}
static enum led_brightness
suc_get_brightness(struct led_classdev *led_cdev)
{
struct msm_mddi_client_data *client = cabc.client_data;
if (panel_type == PANEL_SHARP)
return client->remote_read(client, 0x14B4);
else
return client->remote_read(client, 0x5100);
}
#define DEFAULT_BRIGHTNESS 100
static void suc_backlight_switch(int on)
{
enum led_brightness val;
if (on) {
printk(KERN_DEBUG "turn on backlight\n");
set_bit(GATE_ON, &cabc.status);
val = cabc.lcd_backlight.brightness;
/* LED core uses get_brightness for default value
* If the physical layer is not ready, we should
* not count on it */
if (val == 0)
val = DEFAULT_BRIGHTNESS;
suc_set_brightness(&cabc.lcd_backlight, val);
} else {
clear_bit(GATE_ON, &cabc.status);
suc_set_brightness(&cabc.lcd_backlight, 0);
}
}
static int suc_backlight_probe(struct platform_device *pdev)
{
int err = -EIO;
mutex_init(&cabc.lock);
cabc.client_data = pdev->dev.platform_data;
cabc.lcd_backlight.name = "lcd-backlight";
cabc.lcd_backlight.brightness_set = suc_set_brightness;
cabc.lcd_backlight.brightness_get = suc_get_brightness;
err = led_classdev_register(&pdev->dev, &cabc.lcd_backlight);
if (err)
goto err_register_lcd_bl;
return 0;
err_register_lcd_bl:
led_classdev_unregister(&cabc.lcd_backlight);
return err;
}
/* ------------------------------------------------------------------- */
static struct resource resources_msm_fb[] = {
{
.start = MSM_FB_BASE,
.end = MSM_FB_BASE + MSM_FB_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
static int
supersonic_mddi_init(struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
int i = 0, ret;
unsigned reg, val;
if (panel_type == PANEL_SHARP) {
client_data->auto_hibernate(client_data, 0);
for (i = 0; i < ARRAY_SIZE(s1d13775_init_seq); i++) {
reg = s1d13775_init_seq[i].reg;
val = s1d13775_init_seq[i].val;
if (reg == REG_WAIT)
hr_msleep(val);
else
client_data->remote_write(client_data, cpu_to_le32(val), reg);
}
client_data->auto_hibernate(client_data, 1);
struct spi_cmd {
unsigned char reg;
unsigned char val;
unsigned int delay;
} sharp_spi[] = {
{0x0, 0x11, 100},
{0x0, 0xB9, 0},
{0x1, 0xFF, 0},
{0x1, 0x83, 0},
{0x1, 0x63, 0},
{0x0, 0x3A, 0},
{0x1, 0x50, 0},
};
/* FIXME */
for (i = 0; i < ARRAY_SIZE(sharp_spi); i++) {
ret = qspi_send_9bit(sharp_spi[i].reg, sharp_spi[i].val);
if (ret < 0)
printk("%s: spi_write fail!\n", __func__);
else if (sharp_spi[i].delay)
hr_msleep(sharp_spi[i].delay);
}
}
else {
client_data->auto_hibernate(client_data, 0);
for (i = 0; i < ARRAY_SIZE(nov_init_seq); i++) {
reg = cpu_to_le32(nov_init_seq[i].reg);
val = cpu_to_le32(nov_init_seq[i].val);
if (reg == REG_WAIT)
msleep(val);
else
client_data->remote_write(client_data, val, reg);
}
client_data->auto_hibernate(client_data, 1);
}
return 0;
}
static int
supersonic_mddi_uninit(struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
if (panel_type == PANEL_SHARP) {
int i, ret;
struct spi_cmd {
unsigned char reg;
unsigned char val;
unsigned int delay;
} sharp_spi[] = {
{0x0, 0x28, 0},
{0x0, 0x10, 100},
};
/* FIXME */
for (i = 0; i < ARRAY_SIZE(sharp_spi); i++) {
ret = qspi_send_9bit(sharp_spi[i].reg, sharp_spi[i].val);
if (ret < 0)
printk("%s: spi_write fail!\n", __func__);
else if (sharp_spi[i].delay)
hr_msleep(sharp_spi[i].delay);
}
}
else
client_data->remote_write(client_data, 0, 0x2800);
return 0;
}
/* FIXME: remove after XA03 */
static int backlight_control(int on)
{
struct i2c_adapter *adap = i2c_get_adapter(0);
struct i2c_msg msg;
u8 buf[] = {0x90, 0x00, 0x00, 0x08};
int ret = -EIO, max_retry = 3;
msg.addr = 0xcc >> 1;
msg.flags = 0;
msg.len = sizeof(buf);
msg.buf = buf;
if (on == 0)
buf[0] = 0x91;
while (max_retry--) {
ret = i2c_transfer(adap, &msg, 1);
if (ret != 1)
msleep(1);
else {
ret = 0;
break;
}
ret = -EIO;
}
if (ret)
printk(KERN_ERR "backlight control fail\n");
return 0;
}
static int
supersonic_panel_blank(struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
B(KERN_DEBUG "%s\n", __func__);
suc_backlight_switch(LED_OFF);
backlight_control(0);
return 0;
}
static int
supersonic_panel_unblank(struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
B(KERN_DEBUG "%s\n", __func__);
if (panel_type == PANEL_AUO) {
suc_backlight_switch(LED_FULL);
client_data->remote_write(client_data, 0x00, 0x2900);
msleep(100);
client_data->remote_write(client_data, 0x24, 0x5300);
} else {
suc_backlight_switch(LED_FULL);
client_data->remote_write(client_data, 0x4000, 0x0600);
msleep(10);
qspi_send_9bit(0x0, 0x29);
client_data->remote_write(client_data, 0x7000, 0x0324);
client_data->remote_write(client_data, 0x4000, 0x0600);
}
backlight_control(1);
return 0;
}
static struct msm_mddi_bridge_platform_data novatec_client_data = {
.init = supersonic_mddi_init,
.uninit = supersonic_mddi_uninit,
.blank = supersonic_panel_blank,
.unblank = supersonic_panel_unblank,
.fb_data = {
.xres = 480,
.yres = 800,
.width = 48,
.height = 80,
.output_format = 0,
},
.panel_conf = {
.caps = MSMFB_CAP_CABC,
},
};
static struct msm_mddi_bridge_platform_data epson_client_data = {
.init = supersonic_mddi_init,
.uninit = supersonic_mddi_uninit,
.blank = supersonic_panel_blank,
.unblank = supersonic_panel_unblank,
.fb_data = {
.xres = 480,
.yres = 800,
.width = 48,
.height = 80,
.output_format = 0,
},
.panel_conf = {
.caps = MSMFB_CAP_CABC,
},
};
#define SPI_CLK 17
#define SPI_DO 18
#define SPI_DI 19
#define SPI_CS 20
#define LCM_GPIO_CFG(gpio, func) \
PCOM_GPIO_CFG(gpio, func, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_16MA)
static uint32_t spi_on_gpio_table[] = {
LCM_GPIO_CFG(SPI_CLK, 1),
LCM_GPIO_CFG(SPI_CS, 1),
LCM_GPIO_CFG(SPI_DO, 1),
PCOM_GPIO_CFG(SPI_DI, 1, GPIO_INPUT, GPIO_NO_PULL, GPIO_16MA),
};
static uint32_t spi_off_gpio_table[] = {
LCM_GPIO_CFG(SPI_CLK, 0),
LCM_GPIO_CFG(SPI_CS, 0),
LCM_GPIO_CFG(SPI_DO, 0),
PCOM_GPIO_CFG(SPI_DI, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_16MA),
};
static int spi_gpio_switch(int on)
{
config_gpio_table(
!!on ? spi_on_gpio_table : spi_off_gpio_table,
ARRAY_SIZE(spi_on_gpio_table));
return 0;
}
static void
mddi_novatec_power(struct msm_mddi_client_data *client_data, int on)
{
unsigned id, on_off = 1;
B(KERN_DEBUG "%s: power %s.\n", __func__, on ? "on" : "off");
if (on) {
on_off = 1;
/* 2V8 */
id = PM_VREG_PDOWN_SYNT_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_enable(vreg_lcd_2v8);
/* 1V8 */
id = PM_VREG_PDOWN_AUX_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_enable(vreg_lcd_1v8);
hr_msleep(15);
gpio_set_value(SUPERSONIC_LCD_RST, 1);
hr_msleep(1);
gpio_set_value(SUPERSONIC_LCD_RST, 0);
hr_msleep(5);
gpio_set_value(SUPERSONIC_LCD_RST, 1);
hr_msleep(50);
spi_gpio_switch(1);
} else {
on_off = 0;
gpio_set_value(SUPERSONIC_LCD_RST, 0);
hr_msleep(120);
/* 1V8 */
id = PM_VREG_PDOWN_AUX_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_disable(vreg_lcd_1v8);
/* 2V8 */
id = PM_VREG_PDOWN_SYNT_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_disable(vreg_lcd_2v8);
spi_gpio_switch(0);
}
}
static void
mddi_epson_power(struct msm_mddi_client_data *client_data, int on)
{
unsigned id, on_off = 1;
B(KERN_DEBUG "%s: power %s.\n", __func__, on ? "on" : "off");
if (on) {
on_off = 1;
/* 2V8 */
gpio_set_value(149, 1);
id = PM_VREG_PDOWN_SYNT_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_enable(vreg_lcd_2v8);
hr_msleep(5);
/* 1V8 */
gpio_set_value(16, 1);
id = PM_VREG_PDOWN_AUX_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_enable(vreg_lcd_1v8);
hr_msleep(10);
gpio_set_value(151, 1);
hr_msleep(2);
gpio_set_value(SUPERSONIC_LCD_RST, 1);
hr_msleep(1);
gpio_set_value(SUPERSONIC_LCD_RST, 0);
hr_msleep(5);
gpio_set_value(SUPERSONIC_LCD_RST, 1);
hr_msleep(50);
spi_gpio_switch(1);
} else {
on_off = 0;
gpio_set_value(SUPERSONIC_LCD_RST, 0);
hr_msleep(2);
gpio_set_value(151, 0);
hr_msleep(120);
/* 1V8 */
gpio_set_value(16, 0);
id = PM_VREG_PDOWN_AUX_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_disable(vreg_lcd_1v8);
hr_msleep(5);
/* 2V8 */
gpio_set_value(149, 0);
id = PM_VREG_PDOWN_SYNT_ID;
msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
vreg_disable(vreg_lcd_2v8);
spi_gpio_switch(0);
}
}
static struct msm_mddi_platform_data mddi_pdata = {
.clk_rate = 384000000,
.fb_resource = resources_msm_fb,
.num_clients = 2,
.client_platform_data = {
{
.product_id = (0xb9f6 << 16 | 0x5582),
.name = "mddi_c_b9f6_5582",
.id = 1,
.client_data = &novatec_client_data,
.clk_rate = 0,
},
{
.product_id = (0x4ca3 << 16 | 0x0000),
.name = "mddi_c_4ca3_0000",
.id = 0,
.client_data = &epson_client_data,
.clk_rate = 0,
},
},
};
static struct platform_driver suc_backlight_driver = {
.probe = suc_backlight_probe,
.driver = {
.owner = THIS_MODULE,
},
};
static struct msm_mdp_platform_data mdp_pdata = {
.dma_channel = MDP_DMA_S,
};
int __init supersonic_init_panel(void)
{
int rc;
B(KERN_INFO "%s: enter.\n", __func__);
vreg_lcd_1v8 = vreg_get(0, "gp4");
if (IS_ERR(vreg_lcd_1v8))
return PTR_ERR(vreg_lcd_1v8);
vreg_lcd_2v8 = vreg_get(0, "synt");
if (IS_ERR(vreg_lcd_2v8))
return PTR_ERR(vreg_lcd_2v8);
if (panel_type == PANEL_SHARP)
mdp_pdata.overrides |= MSM_MDP_PANEL_IGNORE_PIXEL_DATA;
else
mdp_pdata.overrides &= ~MSM_MDP_PANEL_IGNORE_PIXEL_DATA;
msm_device_mdp.dev.platform_data = &mdp_pdata;
rc = platform_device_register(&msm_device_mdp);
if (rc)
return rc;
if (panel_type)
mddi_pdata.power_client = mddi_novatec_power;
else
mddi_pdata.power_client = mddi_epson_power;
msm_device_mddi0.dev.platform_data = &mddi_pdata;
rc = platform_device_register(&msm_device_mddi0);
if (rc)
return rc;
if (panel_type)
suc_backlight_driver.driver.name = "nov_cabc";
else
suc_backlight_driver.driver.name = "eps_cabc";
rc = platform_driver_register(&suc_backlight_driver);
if (rc)
return rc;
return 0;
}