summaryrefslogtreecommitdiff
path: root/drivers/video/sprdfb/lcd
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/video/sprdfb/lcd
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/video/sprdfb/lcd')
-rw-r--r--drivers/video/sprdfb/lcd/Makefile50
-rw-r--r--drivers/video/sprdfb/lcd/lcd_dummy.c104
-rw-r--r--drivers/video/sprdfb/lcd/lcd_fl10802_mipi.c364
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8363_mcu.c406
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi.c445
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi_viva.c442
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369.c391
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_hx8369b_grandneo_mipi.c338
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi.c348
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite.c348
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite_marlin.c348
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_kiran3g.c384
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_sharkls_z3lte.c348
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_vivaltoVE.c283
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_hx8369b_tshark2_j3_mipi.c290
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8379a_mipi.c312
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_hx8389c_mipi.c318
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8394a_mipi.c295
-rw-r--r--drivers/video/sprdfb/lcd/lcd_hx8394d_mipi.c430
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili6150_lvds.c81
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9341.c428
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9486.c434
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9486_rgb_spi.c397
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9486s1_mipi.c268
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9806e_2_mipi.c487
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ili9806e_mipi.c632
-rw-r--r--drivers/video/sprdfb/lcd/lcd_jd9161_mipi.c380
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_nt35502_mipi.c300
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35510_mipi.c291
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35512_mipi.c183
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35516_mcu.c585
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35516_mipi.c441
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35516_rgb_i2c.c623
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_nt35516_rgb_spi.c624
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt35596h_mipi.c841
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_nt51017_goyal_mipi.c296
-rw-r--r--drivers/video/sprdfb/lcd/lcd_nt51017_mipi_lvds.c589
-rw-r--r--drivers/video/sprdfb/lcd/lcd_otm1283a_mipi.c560
-rw-r--r--drivers/video/sprdfb/lcd/lcd_otm8019a_mipi.c516
-rw-r--r--drivers/video/sprdfb/lcd/lcd_otm_8018b_mipi.c296
-rw-r--r--drivers/video/sprdfb/lcd/lcd_rm68180_mipi.c383
-rw-r--r--drivers/video/sprdfb/lcd/lcd_s6d0139.c244
-rw-r--r--drivers/video/sprdfb/lcd/lcd_s6d77a1_pikeA_mipi.c330
-rw-r--r--drivers/video/sprdfb/lcd/lcd_s6d7aa0x62_t8_mipi.c350
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_sc7798_rgb_spi.c561
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_sd7798d_mipi.c261
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_sd7798d_mipi_sharkls_z3lte.c261
-rw-r--r--drivers/video/sprdfb/lcd/lcd_ssd2075_mipi.c375
-rw-r--r--drivers/video/sprdfb/lcd/lcd_st7789v_mcu.c336
-rw-r--r--drivers/video/sprdfb/lcd/lcd_t8861_mipi.c485
-rwxr-xr-xdrivers/video/sprdfb/lcd/lcd_vx5b3d_mipi.c965
51 files changed, 20047 insertions, 0 deletions
diff --git a/drivers/video/sprdfb/lcd/Makefile b/drivers/video/sprdfb/lcd/Makefile
new file mode 100644
index 00000000..6d392745
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/Makefile
@@ -0,0 +1,50 @@
+obj-$(CONFIG_FB_LCD_HX8363_RGB_SPI) += lcd_hx8363_rgb_spi.o
+obj-$(CONFIG_FB_LCD_HX8363_MCU) += lcd_hx8363_mcu.o
+obj-$(CONFIG_FB_LCD_HX8369) += lcd_hx8369.o
+obj-$(CONFIG_FB_LCD_S6D0139) += lcd_s6d0139.o
+obj-$(CONFIG_FB_LCD_NT35516_MCU) += lcd_nt35516_mcu.o
+obj-$(CONFIG_FB_LCD_NT35516_MIPI) += lcd_nt35516_mipi.o
+obj-$(CONFIG_FB_LCD_NT35516_RGB_I2C) += lcd_nt35516_rgb_i2c.o
+obj-$(CONFIG_FB_LCD_NT35516_RGB_SPI) += lcd_nt35516_rgb_spi.o
+obj-$(CONFIG_FB_LCD_NT35510_MIPI) += lcd_nt35510_mipi.o
+obj-$(CONFIG_FB_LCD_NT35512_MIPI) += lcd_nt35512_mipi.o
+obj-$(CONFIG_FB_LCD_OTM8018B_MIPI) += lcd_otm_8018b_mipi.o
+obj-$(CONFIG_FB_LCD_SSD2075_MIPI) += lcd_ssd2075_mipi.o
+obj-$(CONFIG_FB_LCD_ILI9486) += lcd_ili9486.o
+obj-$(CONFIG_FB_LCD_ILI9486_RGB_SPI) += lcd_ili9486_rgb_spi.o
+obj-$(CONFIG_FB_LCD_NT51017_MIPI_LVDS) += lcd_nt51017_mipi_lvds.o
+obj-$(CONFIG_FB_LCD_HX8369B_MIPI) += lcd_hx8369b_mipi.o
+obj-$(CONFIG_FB_LCD_HX8369B_MIPI_KIRAN3G) += lcd_hx8369b_mipi_kiran3g.o
+obj-$(CONFIG_FB_LCD_HX8369B_MIPI_COREPRIMELITE) += lcd_hx8369b_mipi_coreprimelite.o
+obj-$(CONFIG_FB_LCD_SD7798D_MIPI_COREPRIMELITE) += lcd_sd7798d_mipi.o
+obj-$(CONFIG_FB_LCD_HX8369B_MIPI_SHARKLS_Z3LTE) += lcd_hx8369b_mipi_sharkls_z3lte.o
+obj-$(CONFIG_FB_LCD_SD7798D_MIPI_SHARKLS_Z3LTE) += lcd_sd7798d_mipi_sharkls_z3lte.o
+obj-$(CONFIG_FB_LCD_ILI9341) += lcd_ili9341.o
+obj-$(CONFIG_FB_LCD_ST7789V_MCU) += lcd_st7789v_mcu.o
+obj-$(CONFIG_FB_LCD_OTM1283A_MIPI) += lcd_otm1283a_mipi.o
+obj-$(CONFIG_FB_LCD_NT35502_MIPI) += lcd_nt35502_mipi.o
+obj-$(CONFIG_FB_LCD_VIVA_RGB_SPI) += lcd_hx8363_rgb_spi_viva.o
+obj-$(CONFIG_FB_LCD_SC7798_RGB_SPI) += lcd_sc7798_rgb_spi.o
+obj-$(CONFIG_FB_LCD_ILI9806E_MIPI) += lcd_ili9806e_mipi.o
+obj-$(CONFIG_FB_LCD_ILI9806E_2_MIPI) += lcd_ili9806e_2_mipi.o
+obj-$(CONFIG_FB_LCD_T8861_MIPI) += lcd_t8861_mipi.o
+obj-$(CONFIG_FB_LCD_HX8379A_MIPI) += lcd_hx8379a_mipi.o
+obj-$(CONFIG_FB_LCD_HX8389C_MIPI) += lcd_hx8389c_mipi.o
+obj-$(CONFIG_FB_LCD_ILI6150_LVDS) += lcd_ili6150_lvds.o
+obj-$(CONFIG_FB_LCD_RM68180_MIPI) += lcd_rm68180_mipi.o
+obj-$(CONFIG_FB_LCD_ILI9486S1_MIPI) += lcd_ili9486s1_mipi.o
+obj-$(CONFIG_FB_LCD_VX5B3D_MIPI) += lcd_vx5b3d_mipi.o
+obj-$(CONFIG_FB_LCD_HX8369B_MIPI_VIVALTO_VE) += lcd_hx8369b_mipi_vivaltoVE.o
+obj-$(CONFIG_FB_LCD_GRANDNEO_MIPI) += lcd_hx8369b_grandneo_mipi.o
+obj-$(CONFIG_FB_LCD_TSHARK2_J3_MIPI) += lcd_hx8369b_tshark2_j3_mipi.o
+obj-$(CONFIG_FB_LCD_SD7798D_MIPI) += lcd_sd7798d_mipi.o
+obj-$(CONFIG_FB_LCD_S6D77A1_MIPI_PIKEA_J1) += lcd_s6d77a1_pikeA_mipi.o
+obj-$(CONFIG_FB_LCD_NT51017_MIPI) += lcd_nt51017_goyal_mipi.o
+obj-$(CONFIG_FB_LCD_OTM8019A_MIPI) += lcd_otm8019a_mipi.o
+obj-$(CONFIG_FB_LCD_FL10802_MIPI) += lcd_fl10802_mipi.o
+obj-$(CONFIG_FB_LCD_JD9161_MIPI) += lcd_jd9161_mipi.o
+obj-$(CONFIG_FB_LCD_HX8394D_MIPI) += lcd_hx8394d_mipi.o
+obj-$(CONFIG_FB_LCD_HX8394A_MIPI) += lcd_hx8394a_mipi.o
+obj-$(CONFIG_FB_LCD_NT35596H_MIPI) += lcd_nt35596h_mipi.o
+obj-$(CONFIG_FB_LCD_S6D7AA0X62_MIPI) += lcd_s6d7aa0x62_t8_mipi.o
+obj-$(CONFIG_FB_LCD_DUMMY) += lcd_dummy.o
diff --git a/drivers/video/sprdfb/lcd/lcd_dummy.c b/drivers/video/sprdfb/lcd/lcd_dummy.c
new file mode 100644
index 00000000..6254daf5
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_dummy.c
@@ -0,0 +1,104 @@
+/* drivers/video/sc8825/lcd_dummy.c
+ *
+ * Support for dummy LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+static int32_t dummy_mipi_init(struct panel_spec *self)
+{
+ pr_debug(KERN_DEBUG "dummy_init\n");
+ return 0;
+}
+
+static uint32_t dummy_readid(struct panel_spec *self)
+{
+ printk("lcd_dummy read id!\n");
+ printk("lcd_dummy read id success!\n");
+ return 0xFFFFFFFF;
+}
+
+static int32_t dummy_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ printk(KERN_DEBUG "dummy_enter_sleep, is_sleep = %d\n", is_sleep);
+ return 0;
+}
+
+static int32_t dummy_check_esd(struct panel_spec *self)
+{
+ pr_debug("dummy_check_esd!\n");
+ pr_debug("dummy_check_esd OK!\n");
+ return 1;
+}
+
+static struct panel_operations lcd_dummy_operations = {
+ .panel_init = dummy_mipi_init,
+ .panel_readid = dummy_readid,
+ .panel_enter_sleep = dummy_enter_sleep,
+ .panel_esd_check = dummy_check_esd,
+};
+
+static struct timing_rgb lcd_dummy_timing = {
+ .hfp = 20, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 20,//4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_dummy_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 3,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_dummy_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_dummy_spec = {
+ .width = 320,
+ .height = 480,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_dummy_info
+ },
+ .ops = &lcd_dummy_operations,
+};
+
+struct panel_cfg lcd_dummy = {
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0xFFFFFFFF,
+ .lcd_name = "lcd_dummy",
+ .panel = &lcd_dummy_spec,
+};
+
+static int __init lcd_dummy_init(void)
+{
+ return sprdfb_panel_register(&lcd_dummy);
+}
+
+subsys_initcall(lcd_dummy_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_fl10802_mipi.c b/drivers/video/sprdfb/lcd/lcd_fl10802_mipi.c
new file mode 100644
index 00000000..48565bb5
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_fl10802_mipi.c
@@ -0,0 +1,364 @@
+/* drivers/video/sc8825/lcd_fl10802_mipi.c
+ *
+ * Support for fl10802 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 80//48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39,LCM_SEND(6), {4,0,0xb9,0xf1,0x08,0x01}},
+ {0x39,LCM_SEND(20), {18,0,0xba,0x31,0x00,0x44,0x25,0xb1,0x0a,0x00,0x00,0xc1,0x00,0x00,0x00,0x0d,0x02,0x5d,0xb5,0xee}},
+
+ {0x37,{LCM_SEND(2),{0x3,0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x39,LCM_SEND(6), {4,0,0xb9,0xf1,0x08,0x01}},
+ {0x39,LCM_SEND(20), {18,0,0xba,0x31,0x00,0x44,0x25,0xb1,0x0a,0x00,0x00,0xc1,0x00,0x00,0x00,0x0d,0x02,0x5d,0xb5,0xee}},
+
+ {0x37,{LCM_SEND(2),{0x1,0}}},
+};
+
+
+static LCM_Init_Code init_data[] = {
+
+
+{LCM_SEND(6), {4,0,0xB9,0xF1,0x08,0x01}},
+
+{LCM_SEND(10), {8,0,0xB1,0x21,0x1E,0x1E,0x87,0x30,0x01,0x8B}},
+
+{LCM_SEND(2), {0xB2,0x23}},
+
+{LCM_SEND(11), {9,0,0xB3,0x00,0x00,0x06,0x06,0x20,0x20,0x30,0x30}},
+
+{LCM_SEND(20), {18,0,0xBA,0x31,0x00,0x44,0x25,0x91,0x0A,0x00,0x00,0xC1,
+ 0x00,0x00,0x00,0x0D,0x02,0x1D,0xB9,0xEE}},
+
+{LCM_SEND(8), {6,0,0xE3,0x04,0x04,0x01,0x01,0x00}},
+
+{LCM_SEND(2), {0xB4,0x02}}, // 2-dot
+
+{LCM_SEND(5), {3,0,0xB5,0x05,0x05}},
+
+{LCM_SEND(5), {3,0,0xB6,0x8C,0x8C}}, //VCOM //0x8C
+
+{LCM_SEND(5), {3,0,0xB8,0x64,0x28}}, //2x, -2.5x
+
+{LCM_SEND(2), {0xCC,0x00}},
+
+{LCM_SEND(2), {0xBC,0x44}},
+
+{LCM_SEND(54), {52,0,0xE9,0x00,0x00,0x07,0x00,0x00,0x81,0x89,0x12,0x31,
+ 0x23,0x23,0x08,0x81,0x80,0x23,0x00,0x00,0x10,0x00,
+ 0x00,0x00,0x0F,0x89,0x13,0x18,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x89,0x02,0x08,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00}},
+
+{LCM_SEND(25), {23,0,0xEA,0x90,0x00,0x00,0x00,0x88,0x20,0x09,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x31,0x19,0x88,0x88,0x88,
+ 0x88,0x88,0x88}},
+
+{LCM_SEND(37), {35,0,0xE0,0x00,0x00,0x00,0x16,0x17,0x27,0x2D,0x3C,0x0A,
+ 0x13,0x12,0x17,0x19,0x17,0x17,0x12,0x16,
+ 0x00,0x00,0x00,0x16,0x17,0x27,0x2D,0x3C,0x0A,
+ 0x13,0x12,0x17,0x19,0x17,0x17,0x12,0x16}},
+
+
+
+{LCM_SEND(2), {0x11,0x00}},
+{LCM_SLEEP(120),},
+
+{LCM_SEND(2), {0x29,0x00}},
+{LCM_SLEEP(10),},
+
+};
+
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(20)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static int32_t fl10802_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug(KERN_DEBUG "fl10802_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+ return 0;
+}
+
+static uint32_t fl10802_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[5] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel lcd_fl10802_mipi read id!\n");
+ #if 1
+ //self->info.mipi->ops->mipi_set_lp_mode();
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000);
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x04, 3,(uint8_t *)read_data);
+ printk("kernel lcd_fl10802_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+ mipi_eotp_set(1,1);
+ if((0x10 == read_data[0])&&(0x80== read_data[1])&&(0x1A == read_data[2])){
+ printk(" kernel lcd_fl10802_mipi read id success!\n");
+ return 0x1080;
+ }
+ }
+ #endif
+ printk("lcd_fl10802_mipi identify fail!\n");
+ //self->info.mipi->ops->mipi_set_hs_mode();
+ return 0x0;
+}
+
+static uint32_t fl10802_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_fl10802_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ printk("lcd_fl10802_mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_fl10802a_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ printk("lcd_fl10802_mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t fl10802_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("fl10802_check_esd!\n");
+ power_mode = fl10802_readpowermode(self);
+ //power_mode = 0x0;
+ if(power_mode == 0x9c){
+ pr_debug("fl10802_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("fl10802_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+
+static int32_t fl10802_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "fl10802_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(1,1);
+ return 0;
+}
+
+static struct panel_operations lcd_fl10802_mipi_operations = {
+ .panel_init = fl10802_mipi_init,
+ .panel_readid = fl10802_readid,
+ .panel_esd_check = fl10802_check_esd,
+ .panel_enter_sleep = fl10802_enter_sleep,
+};
+
+static struct timing_rgb lcd_fl10802_mipi_timing = {
+ .hfp = 80, /* unit: pixel */
+ .hbp = 80,
+ .hsync = 10,
+ .vfp = 17, /*unit: line*/
+ .vbp = 11,
+ .vsync = 3,
+};
+
+static struct info_mipi lcd_fl10802_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 400*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ //.te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_fl10802_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_fl10802_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 59,
+ .reset_timing = {5,10,120},
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_fl10802_mipi_info
+ },
+ .ops = &lcd_fl10802_mipi_operations,
+};
+
+struct panel_cfg lcd_fl10802_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x1080,
+ .lcd_name = "lcd_fl10802_mipi",
+ .panel = &lcd_fl10802_mipi_spec,
+};
+
+static int __init lcd_fl10802_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_fl10802_mipi);
+}
+
+subsys_initcall(lcd_fl10802_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8363_mcu.c b/drivers/video/sprdfb/lcd/lcd_hx8363_mcu.c
new file mode 100644
index 00000000..1f7e4875
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8363_mcu.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+
+static int32_t hx8363_init(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ printk("hx8363_init\n");
+
+ send_cmd(0xB9); // SET password
+ send_data(0xFF); //
+ send_data(0x83); //
+ send_data(0x63); //
+
+ send_cmd(0xB0);//Enable internal oscillator
+ send_data(0x01);
+ send_data(0x0B);
+
+ send_cmd(0xB1);
+ send_data(0x01);
+ send_data(0x00);
+ send_data(0x44);
+ send_data(0x08);
+ send_data(0x01);
+ send_data(0x11);
+ send_data(0x11);
+ send_data(0x36);
+ send_data(0x3E);
+ send_data(0x3F);
+ send_data(0x3F);
+ send_data(0x40);
+ send_data(0x32);
+ send_data(0x00);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+
+ send_cmd(0xB2); // SET DISP
+ send_data(0x08); //
+ send_data(0x00); //
+
+ send_cmd(0xB4);
+ send_data(0x00);//Column inversion
+ send_data(0x18);
+ send_data(0x9C);
+ send_data(0x08);
+ send_data(0x18);
+ send_data(0x04);
+ send_data(0x72);//72
+
+ send_cmd(0xB6);//Set_VCOM
+ send_data(0x1B);
+
+ send_cmd(0xCC);// SET Panel
+ send_data(0x01); //
+
+ LCD_DelayMS(5);
+
+ send_cmd(0xE0); // SET Gamma
+ send_data(0x00);
+ send_data(0x05);
+ send_data(0x07);
+ send_data(0x0C);
+ send_data(0x13);
+ send_data(0x2F);
+ send_data(0x0B);
+ send_data(0x1D);
+ send_data(0x86);
+ send_data(0x0D);
+ send_data(0x91);
+ send_data(0x16);
+ send_data(0x99);
+ send_data(0x16);
+ send_data(0x16);
+ send_data(0x09);
+ send_data(0x05);
+ send_data(0x00);
+ send_data(0x05);
+ send_data(0x07);
+ send_data(0x0C);
+ send_data(0x13);
+ send_data(0x2F);
+ send_data(0x0B);
+ send_data(0x1D);
+ send_data(0x86);
+ send_data(0x0D);
+ send_data(0x91);
+ send_data(0x16);
+ send_data(0x99);
+ send_data(0x16);
+ send_data(0x16);
+ send_data(0x09);
+ send_data(0x05);
+
+ send_cmd(0xC1); //COLMOD
+ send_data(0x01); //
+ //R
+ send_data(0x07 );
+ send_data(0x0A );
+ send_data(0x1A );
+ send_data(0x2F );
+ send_data(0x3E );
+ send_data(0x4A );
+ send_data(0x52 );
+ send_data(0x5A );
+ send_data(0x62 );
+ send_data(0x69 );
+ send_data(0x70 );
+ send_data(0x76 );
+ send_data(0x7D );
+ send_data(0x82 );
+ send_data(0x86 );
+ send_data(0x8C );
+ send_data(0x93 );
+ send_data(0x9A );
+ send_data(0x9F );
+ send_data(0xA4 );
+ send_data(0xA9 );
+ send_data(0xB0 );
+ send_data(0xB6 );
+ send_data(0xBB );
+ send_data(0xC2 );
+ send_data(0xC9 );
+ send_data(0xCF );
+ send_data(0xD7 );
+ send_data(0xE0 );
+ send_data(0xE7 );
+ send_data(0xEF );
+ send_data(0xF8 );
+ send_data(0xFF );
+ send_data(0x34 );
+ send_data(0x1E );
+ send_data(0x92 );
+ send_data(0x9E );
+ send_data(0x01 );
+ send_data(0xE6 );
+ send_data(0x08 );
+ send_data(0x6F );
+ send_data(0x02 );
+ //G
+ send_data(0x07 );
+ send_data(0x0A );
+ send_data(0x1A );
+ send_data(0x2F );
+ send_data(0x3E );
+ send_data(0x4A );
+ send_data(0x52 );
+ send_data(0x5A );
+ send_data(0x62 );
+ send_data(0x69 );
+ send_data(0x70 );
+ send_data(0x76 );
+ send_data(0x7D );
+ send_data(0x82 );
+ send_data(0x86 );
+ send_data(0x8C );
+ send_data(0x93 );
+ send_data(0x9A );
+ send_data(0x9F );
+ send_data(0xA4 );
+ send_data(0xA9 );
+ send_data(0xB0 );
+ send_data(0xB6 );
+ send_data(0xBB );
+ send_data(0xC2 );
+ send_data(0xC9 );
+ send_data(0xCF );
+ send_data(0xD7 );
+ send_data(0xE0 );
+ send_data(0xE7 );
+ send_data(0xEF );
+ send_data(0xF8 );
+ send_data(0xFF );
+ send_data(0x34 );
+ send_data(0x1E );
+ send_data(0x92 );
+ send_data(0x9E );
+ send_data(0x01 );
+ send_data(0xE6 );
+ send_data(0x08 );
+ send_data(0x6F );
+ send_data(0x02 );
+ //B
+ send_data(0x07 );
+ send_data(0x0A );
+ send_data(0x1A );
+ send_data(0x2F );
+ send_data(0x3E );
+ send_data(0x4A );
+ send_data(0x52 );
+ send_data(0x5A );
+ send_data(0x62 );
+ send_data(0x69 );
+ send_data(0x70 );
+ send_data(0x76 );
+ send_data(0x7D );
+ send_data(0x82 );
+ send_data(0x86 );
+ send_data(0x8C );
+ send_data(0x93 );
+ send_data(0x9A );
+ send_data(0x9F );
+ send_data(0xA4 );
+ send_data(0xA9 );
+ send_data(0xB0 );
+ send_data(0xB6 );
+ send_data(0xBB );
+ send_data(0xC2 );
+ send_data(0xC9 );
+ send_data(0xCF );
+ send_data(0xD7 );
+ send_data(0xE0 );
+ send_data(0xE7 );
+ send_data(0xEF );
+ send_data(0xF8 );
+ send_data(0xFF );
+ send_data(0x34 );
+ send_data(0x1E );
+ send_data(0x92 );
+ send_data(0x9E );
+ send_data(0x01 );
+ send_data(0xE6 );
+ send_data(0x08 );
+ send_data(0x6F );
+ send_data(0x02 );
+
+ send_cmd(0x3A); //COLMOD
+ send_data(0x07); //
+
+ send_cmd(0x11);//Sleep Out
+ LCD_DelayMS(120);
+
+ send_cmd(0xC2);// SET DISPIF
+ send_data(0x04); //24bit
+ send_cmd(0x35); //Tearing Effect
+ send_data(0x00); //
+ send_cmd(0x36);
+ send_data(0x02); //
+ send_cmd(0x29);
+ LCD_DelayMS(10);
+ send_cmd(0x2c);
+
+ return 0;
+}
+
+static int32_t hx8363_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ if(is_sleep==1){
+ //Sleep In
+ send_cmd(0x28);
+ LCD_DelayMS(120);
+ send_cmd(0x10);
+ LCD_DelayMS(120);
+ }else{
+ //Sleep Out
+ send_cmd(0x11);
+ LCD_DelayMS(120);
+ send_cmd(0x29);
+ LCD_DelayMS(120);
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t hx8363_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("hx8363_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
+
+ send_cmd(0x2A); // col
+ send_data((left >> 8));
+ send_data((left & 0xFF));
+ send_data((right >> 8));
+ send_data((right & 0xFF));
+
+ send_cmd(0x2B); // row
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+ send_data((bottom >> 8));
+ send_data((bottom & 0xFF));
+
+ send_cmd(0x2C); //Write data
+
+ return 0;
+}
+static int32_t hx8363_invalidate(struct panel_spec *self)
+{
+ pr_debug("hx8363_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+
+
+static int32_t hx8363_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+ pr_debug("hx8363_invalidate_rect \n");
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t hx8363_read_id(struct panel_spec *self)
+{
+ int32_t id = 0;
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ //Get ID
+
+
+ return 0x18; // id;
+}
+
+static struct panel_operations lcd_hx8363_mcu_operations = {
+ .panel_init = hx8363_init,
+ .panel_set_window = hx8363_set_window,
+ .panel_invalidate_rect= hx8363_invalidate_rect,
+ .panel_invalidate = hx8363_invalidate,
+ .panel_enter_sleep = hx8363_enter_sleep,
+ .panel_readid = hx8363_read_id
+};
+
+static struct timing_mcu lcd_hx8363_mcu_timing[] = {
+[MCU_LCD_REGISTER_TIMING] = { // read/write register timing
+ .rcss = 15, // 15ns
+ .rlpw = 60,
+ .rhpw = 60,
+ .wcss = 10,
+ .wlpw = 35,
+ .whpw = 35,
+ },
+[MCU_LCD_GRAM_TIMING] = { // read/write gram timing
+ .rcss = 15, // 15ns
+ .rlpw = 60,
+ .rhpw = 60,
+ .wcss = 0,
+ .wlpw = 16,
+ .whpw = 16,
+ },
+};
+
+static struct info_mcu lcd_hx8363_mcu_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 24,
+ .bpp = 24,
+ .timing =lcd_hx8363_mcu_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8363_mcu_spec = {
+ .width = 480,
+ .height = 854,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_hx8363_mcu_info
+ },
+ .ops = &lcd_hx8363_mcu_operations,
+};
+
+struct panel_cfg lcd_hx8363_mcu = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_UNDEFINELCD_ID,
+ .lcd_id = 0x18,
+ .lcd_name = "lcd_hx8363_mcu",
+ .panel = &lcd_hx8363_mcu_spec,
+};
+
+static int __init lcd_hx8363_mcu_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8363_mcu);
+}
+
+subsys_initcall(lcd_hx8363_mcu_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi.c b/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi.c
new file mode 100644
index 00000000..18742b53
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi.c
@@ -0,0 +1,445 @@
+/* drivers/video/sc8810/lcd_hx8363_rgb_spi.c
+ *
+ *
+ *
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+#define HX8363_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define HX8363_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+
+static int32_t hx8363_init(struct panel_spec *self)
+{
+ uint32_t test_data[8] = {0};
+ uint32_t left = 0;
+ uint32_t top = 0;
+ uint32_t right = 480;
+ uint32_t bottom = 854;
+ uint32_t data = 0;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+
+ printk("hx8363_init\n");
+
+ HX8363_SpiWriteCmd(0xB9); // SET password
+ HX8363_SpiWriteData(0xFF); //
+ HX8363_SpiWriteData(0x83); //
+ HX8363_SpiWriteData(0x63); //
+
+ HX8363_SpiWriteCmd(0xB1);
+ HX8363_SpiWriteData(0x01);
+ HX8363_SpiWriteData(0x00);
+ HX8363_SpiWriteData(0x44);
+ HX8363_SpiWriteData(0x08);
+ HX8363_SpiWriteData(0x01);
+// HX8363_SpiWriteData(0x0E); //
+// HX8363_SpiWriteData(0x0E); //
+// HX8363_SpiWriteData(0x1B); //the lower ,Saturation is better
+// HX8363_SpiWriteData(0x23); //the lower ,Saturation is better
+ HX8363_SpiWriteData(0x0F); //
+ HX8363_SpiWriteData(0x0F); //
+ HX8363_SpiWriteData(0x22); //the lower ,Saturation is better
+ HX8363_SpiWriteData(0x2A); //the lower ,Saturation is better
+ HX8363_SpiWriteData(0x3F);
+ HX8363_SpiWriteData(0x3F);
+ HX8363_SpiWriteData(0x40);
+ HX8363_SpiWriteData(0x32);
+ HX8363_SpiWriteData(0x00);
+ HX8363_SpiWriteData(0xE6);
+ HX8363_SpiWriteData(0xE6);
+ HX8363_SpiWriteData(0xE6);
+ HX8363_SpiWriteData(0xE6);
+ HX8363_SpiWriteData(0xE6);
+
+ HX8363_SpiWriteCmd(0xB2); // SET DISP
+ HX8363_SpiWriteData(0x08); //
+ HX8363_SpiWriteData(0x03); //
+
+ HX8363_SpiWriteCmd(0xB4);
+ HX8363_SpiWriteData(0x00);//Column inversion
+ HX8363_SpiWriteData(0x18);
+ HX8363_SpiWriteData(0x9C);
+ HX8363_SpiWriteData(0x08);
+ HX8363_SpiWriteData(0x18);
+ HX8363_SpiWriteData(0x04);
+ HX8363_SpiWriteData(0x82);
+
+ HX8363_SpiWriteCmd(0xB6); //Set_VCOM
+ HX8363_SpiWriteData(0x1B); //0x10
+
+ HX8363_SpiWriteCmd(0xCC); // SET Panel
+ HX8363_SpiWriteData(0x01); //
+ msleep(5);
+
+ HX8363_SpiWriteCmd(0xE0); // SET Gamma
+ HX8363_SpiWriteData(0x00);
+ HX8363_SpiWriteData(0x05);
+ HX8363_SpiWriteData(0x07);
+ HX8363_SpiWriteData(0x0C);
+ HX8363_SpiWriteData(0x13);
+ HX8363_SpiWriteData(0x2F);
+ HX8363_SpiWriteData(0x0B);
+ HX8363_SpiWriteData(0x1D);
+ HX8363_SpiWriteData(0x86);
+ HX8363_SpiWriteData(0x0D);
+ HX8363_SpiWriteData(0x91);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x99);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x09);
+ HX8363_SpiWriteData(0x05);
+ HX8363_SpiWriteData(0x00);
+ HX8363_SpiWriteData(0x05);
+ HX8363_SpiWriteData(0x07);
+ HX8363_SpiWriteData(0x0C);
+ HX8363_SpiWriteData(0x13);
+ HX8363_SpiWriteData(0x2F);
+ HX8363_SpiWriteData(0x0B);
+ HX8363_SpiWriteData(0x1D);
+ HX8363_SpiWriteData(0x86);
+ HX8363_SpiWriteData(0x0D);
+ HX8363_SpiWriteData(0x91);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x99);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x16);
+ HX8363_SpiWriteData(0x09);
+ HX8363_SpiWriteData(0x05);
+
+ HX8363_SpiWriteCmd(0xC1); //COLMOD
+ HX8363_SpiWriteData(0x01); //
+ //R
+ HX8363_SpiWriteData(0x07 );
+ HX8363_SpiWriteData(0x0A );
+ HX8363_SpiWriteData(0x1A );
+ HX8363_SpiWriteData(0x2F );
+ HX8363_SpiWriteData(0x3E );
+ HX8363_SpiWriteData(0x4A );
+ HX8363_SpiWriteData(0x52 );
+ HX8363_SpiWriteData(0x5A );
+ HX8363_SpiWriteData(0x62 );
+ HX8363_SpiWriteData(0x69 );
+ HX8363_SpiWriteData(0x70 );
+ HX8363_SpiWriteData(0x76 );
+ HX8363_SpiWriteData(0x7D );
+ HX8363_SpiWriteData(0x82 );
+ HX8363_SpiWriteData(0x86 );
+ HX8363_SpiWriteData(0x8C );
+ HX8363_SpiWriteData(0x93 );
+ HX8363_SpiWriteData(0x9A );
+ HX8363_SpiWriteData(0x9F );
+ HX8363_SpiWriteData(0xA4 );
+ HX8363_SpiWriteData(0xA9 );
+ HX8363_SpiWriteData(0xB0 );
+ HX8363_SpiWriteData(0xB6 );
+ HX8363_SpiWriteData(0xBB );
+ HX8363_SpiWriteData(0xC2 );
+ HX8363_SpiWriteData(0xC9 );
+ HX8363_SpiWriteData(0xCF );
+ HX8363_SpiWriteData(0xD7 );
+ HX8363_SpiWriteData(0xE0 );
+ HX8363_SpiWriteData(0xE7 );
+ HX8363_SpiWriteData(0xEF );
+ HX8363_SpiWriteData(0xF8 );
+ HX8363_SpiWriteData(0xFF );
+ HX8363_SpiWriteData(0x34 );
+ HX8363_SpiWriteData(0x1E );
+ HX8363_SpiWriteData(0x92 );
+ HX8363_SpiWriteData(0x9E );
+ HX8363_SpiWriteData(0x01 );
+ HX8363_SpiWriteData(0xE6 );
+ HX8363_SpiWriteData(0x08 );
+ HX8363_SpiWriteData(0x6F );
+ HX8363_SpiWriteData(0x02 );
+ //G
+ HX8363_SpiWriteData(0x07 );
+ HX8363_SpiWriteData(0x0A );
+ HX8363_SpiWriteData(0x1A );
+ HX8363_SpiWriteData(0x2F );
+ HX8363_SpiWriteData(0x3E );
+ HX8363_SpiWriteData(0x4A );
+ HX8363_SpiWriteData(0x52 );
+ HX8363_SpiWriteData(0x5A );
+ HX8363_SpiWriteData(0x62 );
+ HX8363_SpiWriteData(0x69 );
+ HX8363_SpiWriteData(0x70 );
+ HX8363_SpiWriteData(0x76 );
+ HX8363_SpiWriteData(0x7D );
+ HX8363_SpiWriteData(0x82 );
+ HX8363_SpiWriteData(0x86 );
+ HX8363_SpiWriteData(0x8C );
+ HX8363_SpiWriteData(0x93 );
+ HX8363_SpiWriteData(0x9A );
+ HX8363_SpiWriteData(0x9F );
+ HX8363_SpiWriteData(0xA4 );
+ HX8363_SpiWriteData(0xA9 );
+ HX8363_SpiWriteData(0xB0 );
+ HX8363_SpiWriteData(0xB6 );
+ HX8363_SpiWriteData(0xBB );
+ HX8363_SpiWriteData(0xC2 );
+ HX8363_SpiWriteData(0xC9 );
+ HX8363_SpiWriteData(0xCF );
+ HX8363_SpiWriteData(0xD7 );
+ HX8363_SpiWriteData(0xE0 );
+ HX8363_SpiWriteData(0xE7 );
+ HX8363_SpiWriteData(0xEF );
+ HX8363_SpiWriteData(0xF8 );
+ HX8363_SpiWriteData(0xFF );
+ HX8363_SpiWriteData(0x34 );
+ HX8363_SpiWriteData(0x1E );
+ HX8363_SpiWriteData(0x92 );
+ HX8363_SpiWriteData(0x9E );
+ HX8363_SpiWriteData(0x01 );
+ HX8363_SpiWriteData(0xE6 );
+ HX8363_SpiWriteData(0x08 );
+ HX8363_SpiWriteData(0x6F );
+ HX8363_SpiWriteData(0x02 );
+ //B
+ HX8363_SpiWriteData(0x07 );
+ HX8363_SpiWriteData(0x0A );
+ HX8363_SpiWriteData(0x1A );
+ HX8363_SpiWriteData(0x2F );
+ HX8363_SpiWriteData(0x3E );
+ HX8363_SpiWriteData(0x4A );
+ HX8363_SpiWriteData(0x52 );
+ HX8363_SpiWriteData(0x5A );
+ HX8363_SpiWriteData(0x62 );
+ HX8363_SpiWriteData(0x69 );
+ HX8363_SpiWriteData(0x70 );
+ HX8363_SpiWriteData(0x76 );
+ HX8363_SpiWriteData(0x7D );
+ HX8363_SpiWriteData(0x82 );
+ HX8363_SpiWriteData(0x86 );
+ HX8363_SpiWriteData(0x8C );
+ HX8363_SpiWriteData(0x93 );
+ HX8363_SpiWriteData(0x9A );
+ HX8363_SpiWriteData(0x9F );
+ HX8363_SpiWriteData(0xA4 );
+ HX8363_SpiWriteData(0xA9 );
+ HX8363_SpiWriteData(0xB0 );
+ HX8363_SpiWriteData(0xB6 );
+ HX8363_SpiWriteData(0xBB );
+ HX8363_SpiWriteData(0xC2 );
+ HX8363_SpiWriteData(0xC9 );
+ HX8363_SpiWriteData(0xCF );
+ HX8363_SpiWriteData(0xD7 );
+ HX8363_SpiWriteData(0xE0 );
+ HX8363_SpiWriteData(0xE7 );
+ HX8363_SpiWriteData(0xEF );
+ HX8363_SpiWriteData(0xF8 );
+ HX8363_SpiWriteData(0xFF );
+ HX8363_SpiWriteData(0x34 );
+ HX8363_SpiWriteData(0x1E );
+ HX8363_SpiWriteData(0x92 );
+ HX8363_SpiWriteData(0x9E );
+ HX8363_SpiWriteData(0x01 );
+ HX8363_SpiWriteData(0xE6 );
+ HX8363_SpiWriteData(0x08 );
+ HX8363_SpiWriteData(0x6F );
+ HX8363_SpiWriteData(0x02 );
+
+ HX8363_SpiWriteCmd(0x3A); //COLMOD
+ HX8363_SpiWriteData(0x77); //
+
+ HX8363_SpiWriteCmd(0x11);//Sleep Out
+ msleep(120);
+ HX8363_SpiWriteCmd(0x35); //Tearing Effect
+ HX8363_SpiWriteData(0x00); //
+ HX8363_SpiWriteCmd(0x36);
+ HX8363_SpiWriteData(0x02);
+ HX8363_SpiWriteCmd(0x29);
+ msleep(10);
+ HX8363_SpiWriteCmd(0x2C);
+
+}
+
+static int32_t hx8363_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+
+ if(is_sleep==1){
+ //Sleep In
+ HX8363_SpiWriteCmd(0x28);
+ msleep(120);
+ HX8363_SpiWriteCmd(0x10);
+ msleep(10);
+ }else{
+ //Sleep Out
+ HX8363_SpiWriteCmd(0x11);
+ msleep(120);
+ HX8363_SpiWriteCmd(0x29);
+ msleep(10);
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t hx8363_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ uint32_t *test_data[4] = {0};
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+#if 0
+
+ printk("zxdbg add -hx8363_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
+
+ HX8363_SpiWriteCmd(0x2A00);
+ HX8363_SpiWriteData((left>>8));// set left address
+ HX8363_SpiWriteData((left&0xff));
+ HX8363_SpiWriteData((right>>8));// set right address
+ HX8363_SpiWriteData((right&0xff));
+
+ HX8363_SpiWriteCmd(0x2B00);
+ HX8363_SpiWriteData((top>>8));// set left address
+ HX8363_SpiWriteData((top&0xff));
+ HX8363_SpiWriteData((bottom>>8));// set bottom address
+ HX8363_SpiWriteData((bottom&0xff));
+
+// HX8363_SpiWriteCmd(0x2C00);
+
+ HX8363_SpiWriteCmd(0x2A00);
+ spi_read(test_data);
+ spi_read(test_data+1);
+ HX8363_SpiWriteCmd(0x2B00);
+ spi_read(test_data+2);
+ spi_read(test_data+3);
+#endif
+// printk("zxdbg add -hx8363_read read: %x, %x, %x, %x\n",test_data[0], test_data[1], test_data[2], test_data[3]);
+
+ return 0;
+}
+static int32_t hx8363_invalidate(struct panel_spec *self)
+{
+// printk("hx8363_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+
+
+static int32_t hx8363_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+// printk("hx8363_invalidate_rect \n");
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t hx8363_read_id(struct panel_spec *self)
+{
+ int32_t id = 0x62;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+ printk("sprdfb hx8363_read_id \n");
+ HX8363_SpiWriteCmd(0xB9); // SET password
+ HX8363_SpiWriteData(0xFF); //
+ HX8363_SpiWriteData(0x83); //
+ HX8363_SpiWriteData(0x63); //
+
+ HX8363_SpiWriteCmd(0xFE); // SET SPI READ INDEX
+ HX8363_SpiWriteData(0xF4); // GETHXID
+ HX8363_SpiWriteCmd(0xFF); // GET SPI READ
+
+ spi_read(&id);
+ id &= 0xff;
+ printk(" hx8363_read_id kernel id = %x\n",id);
+// return id;
+ return 0x63;
+}
+
+static struct panel_operations lcd_hx8363_rgb_spi_operations = {
+ .panel_init = hx8363_init,
+ .panel_set_window = hx8363_set_window,
+ .panel_invalidate_rect= hx8363_invalidate_rect,
+ .panel_invalidate = hx8363_invalidate,
+ .panel_enter_sleep = hx8363_enter_sleep,
+ .panel_readid = hx8363_read_id
+};
+
+static struct timing_rgb lcd_hx8363_rgb_timing = {
+ .hfp = 15,//10, /* unit: pixel */
+ .hbp = 15,//6,
+ .hsync = 10, //8,
+ .vfp = 8, // 3, /*unit: line*/
+ .vbp = 8, // 3,
+ .vsync = 6, // 4,
+};
+
+static struct spi_info lcd_hx8363_rgb_spi_info = {
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_hx8363_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_SPI,
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_NEG,
+ .v_sync_pol = SPRDFB_POLARITY_NEG,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_hx8363_rgb_timing,
+ .bus_info = {
+ .spi = &lcd_hx8363_rgb_spi_info,
+ }
+};
+
+struct panel_spec lcd_panel_hx8363_rgb_spi_spec = {
+ .width = 480,
+ .height = 854,
+ .reset_timing = {20, 10, 120},
+ .fps = 61,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .rgb = &lcd_hx8363_rgb_info
+ },
+ .ops = &lcd_hx8363_rgb_spi_operations,
+};
+
+struct panel_cfg lcd_hx8363_rgb_spi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x63,
+ .lcd_name = "lcd_hx8363_rgb_spi",
+ .panel = &lcd_panel_hx8363_rgb_spi_spec,
+};
+static int __init lcd_hx8363_rgb_spi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8363_rgb_spi);
+}
+
+subsys_initcall(lcd_hx8363_rgb_spi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi_viva.c b/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi_viva.c
new file mode 100644
index 00000000..76b8b12a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8363_rgb_spi_viva.c
@@ -0,0 +1,442 @@
+/* drivers/video/sc8810/lcd_hx8363_rgb_spi.c
+ *
+ *
+ *
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+
+
+#define HX8363_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define HX8363_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+#define HX8369b_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define HX8369b_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+static int32_t hx8363_init(struct panel_spec *self)
+{
+ uint32_t test_data[8] = {0};
+ uint32_t left = 0;
+ uint32_t top = 0;
+ uint32_t right = 480;
+ uint32_t bottom = 800;
+ uint32_t data = 0;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+
+ printk("hx8363_init\n");
+
+ HX8369b_SpiWriteCmd(0xB9); // SET EXTC
+ HX8369b_SpiWriteData(0xFF); //
+ HX8369b_SpiWriteData(0x83); //
+ HX8369b_SpiWriteData(0x69); //
+
+ //Power Setting Sequence
+
+ HX8369b_SpiWriteCmd(0xB1); //Set Power
+ HX8369b_SpiWriteData(0x0B);
+ HX8369b_SpiWriteData(0x83);
+ HX8369b_SpiWriteData(0xA7);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x11);
+ HX8369b_SpiWriteData(0x11);
+ HX8369b_SpiWriteData(0x08);
+ HX8369b_SpiWriteData(0x08);
+ HX8369b_SpiWriteData(0x0C);
+ HX8369b_SpiWriteData(0x22);
+
+
+ HX8369b_SpiWriteCmd(0xC6); //Set Source EQ
+ HX8369b_SpiWriteData(0x41);
+ HX8369b_SpiWriteData(0xFF);
+ HX8369b_SpiWriteData(0x7A);
+ HX8369b_SpiWriteData(0xFF);
+
+ HX8369b_SpiWriteCmd(0xE3); //Set Source EQ
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+
+ HX8369b_SpiWriteCmd(0xC0); //Set Source Option
+ HX8369b_SpiWriteData(0x73);
+ HX8369b_SpiWriteData(0x50);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x34);
+ HX8369b_SpiWriteData(0xC4);
+ HX8369b_SpiWriteData(0x00);
+
+ // Initializing Sequence
+
+ HX8369b_SpiWriteCmd(0x3A); //Interface Pixel
+ HX8369b_SpiWriteData(0x70);
+
+ HX8369b_SpiWriteCmd(0xB3); //Set RGB Interface
+ HX8369b_SpiWriteData(0x83);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x31);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x01);
+ HX8369b_SpiWriteData(0x13);
+ HX8369b_SpiWriteData(0x06);
+
+ HX8369b_SpiWriteCmd(0xB4); //Set column inversion
+ HX8369b_SpiWriteData(0x00);
+
+ HX8369b_SpiWriteCmd(0xCC); //Set DGC
+ HX8369b_SpiWriteData(0x0C);
+
+ HX8369b_SpiWriteCmd(0xEA); //Set Color
+ HX8369b_SpiWriteData(0x72);
+
+ HX8369b_SpiWriteCmd(0xB2); //Set Display
+ HX8369b_SpiWriteData(0x03);
+
+ HX8369b_SpiWriteCmd(0xD5); //GIP Timing SET
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x0D);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x12);
+ HX8369b_SpiWriteData(0x40);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x01);
+ HX8369b_SpiWriteData(0x60);
+ HX8369b_SpiWriteData(0x37);
+ HX8369b_SpiWriteData(0x00);
+
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x0F);
+ HX8369b_SpiWriteData(0x01);
+ HX8369b_SpiWriteData(0x05);
+ HX8369b_SpiWriteData(0x47);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x18);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x89);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x11);
+ HX8369b_SpiWriteData(0x33);
+ HX8369b_SpiWriteData(0x55);
+ HX8369b_SpiWriteData(0x77);
+ HX8369b_SpiWriteData(0x31);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x98);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x66);
+ HX8369b_SpiWriteData(0x44);
+ HX8369b_SpiWriteData(0x22);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x02);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x89);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x22);
+ HX8369b_SpiWriteData(0x44);
+ HX8369b_SpiWriteData(0x66);
+ HX8369b_SpiWriteData(0x20);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x98);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x77);
+ HX8369b_SpiWriteData(0x55);
+ HX8369b_SpiWriteData(0x33);
+ HX8369b_SpiWriteData(0x11);
+ HX8369b_SpiWriteData(0x13);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x01);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0xCF);
+ HX8369b_SpiWriteData(0xFF);
+ HX8369b_SpiWriteData(0xFF);
+ HX8369b_SpiWriteData(0x03);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0xCF);
+ HX8369b_SpiWriteData(0xFF);
+ HX8369b_SpiWriteData(0xFF);
+ HX8369b_SpiWriteData(0x20);
+ HX8369b_SpiWriteData(0x8C);
+ HX8369b_SpiWriteData(0x5A);
+
+ //Gamam Setting Sequence
+
+ HX8369b_SpiWriteCmd(0xE0); //Gamma
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x02);
+ HX8369b_SpiWriteData(0x0D);
+ HX8369b_SpiWriteData(0x0C);
+ HX8369b_SpiWriteData(0x3F);
+ HX8369b_SpiWriteData(0x19);
+ HX8369b_SpiWriteData(0x2D);
+ HX8369b_SpiWriteData(0x04);
+ HX8369b_SpiWriteData(0x0F);
+ HX8369b_SpiWriteData(0x0E);
+ HX8369b_SpiWriteData(0x14);
+ HX8369b_SpiWriteData(0x17);
+
+ HX8369b_SpiWriteData(0x15);
+ HX8369b_SpiWriteData(0x16);
+ HX8369b_SpiWriteData(0x10);
+ HX8369b_SpiWriteData(0x11);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x00);
+ HX8369b_SpiWriteData(0x02);
+ HX8369b_SpiWriteData(0x0C);
+ HX8369b_SpiWriteData(0x12);
+ HX8369b_SpiWriteData(0x3F);
+ HX8369b_SpiWriteData(0x19);
+ HX8369b_SpiWriteData(0x2C);
+ HX8369b_SpiWriteData(0x05);
+ HX8369b_SpiWriteData(0x08);
+ HX8369b_SpiWriteData(0x0E);
+ HX8369b_SpiWriteData(0x12);
+ HX8369b_SpiWriteData(0x16);
+ HX8369b_SpiWriteData(0x14);
+ HX8369b_SpiWriteData(0x15);
+ HX8369b_SpiWriteData(0x10);
+ HX8369b_SpiWriteData(0x12);
+ HX8369b_SpiWriteData(0x01);
+
+ //Dispaly on
+ HX8369b_SpiWriteCmd(0x11);
+ mdelay(120);
+ HX8369b_SpiWriteCmd(0x29);
+
+
+}
+
+static int32_t hx8363_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+
+ if(is_sleep==1){
+ //Sleep In
+ HX8363_SpiWriteCmd(0x28);
+ mdelay(120);
+ HX8363_SpiWriteCmd(0x10);
+ mdelay(10);
+ }else{
+ //Sleep Out
+ HX8363_SpiWriteCmd(0x11);
+ mdelay(120);
+ HX8363_SpiWriteCmd(0x29);
+ mdelay(10);
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t hx8363_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ uint32_t *test_data[4] = {0};
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+#if 0
+
+ printk("zxdbg add -hx8363_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
+
+ HX8363_SpiWriteCmd(0x2A00);
+ HX8363_SpiWriteData((left>>8));// set left address
+ HX8363_SpiWriteData((left&0xff));
+ HX8363_SpiWriteData((right>>8));// set right address
+ HX8363_SpiWriteData((right&0xff));
+
+ HX8363_SpiWriteCmd(0x2B00);
+ HX8363_SpiWriteData((top>>8));// set left address
+ HX8363_SpiWriteData((top&0xff));
+ HX8363_SpiWriteData((bottom>>8));// set bottom address
+ HX8363_SpiWriteData((bottom&0xff));
+
+// HX8363_SpiWriteCmd(0x2C00);
+
+ HX8363_SpiWriteCmd(0x2A00);
+ spi_read(test_data);
+ spi_read(test_data+1);
+ HX8363_SpiWriteCmd(0x2B00);
+ spi_read(test_data+2);
+ spi_read(test_data+3);
+#endif
+// printk("zxdbg add -hx8363_read read: %x, %x, %x, %x\n",test_data[0], test_data[1], test_data[2], test_data[3]);
+
+ return 0;
+}
+static int32_t hx8363_invalidate(struct panel_spec *self)
+{
+// printk("hx8363_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+
+
+static int32_t hx8363_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+// printk("hx8363_invalidate_rect \n");
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t hx8363_read_id(struct panel_spec *self)
+{
+ int32_t id = 0x62;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+/*
+ printk("sprdfb hx8363_read_id \n");
+ HX8363_SpiWriteCmd(0xB9); // SET password
+ HX8363_SpiWriteData(0xFF); //
+ HX8363_SpiWriteData(0x83); //
+ HX8363_SpiWriteData(0x63); //
+
+ HX8363_SpiWriteCmd(0xFE); // SET SPI READ INDEX
+ HX8363_SpiWriteData(0xF4); // GETHXID
+ HX8363_SpiWriteCmd(0xFF); // GET SPI READ
+
+ spi_read(&id);
+*/
+ id &= 0xff;
+ printk(" hx8363_read_id kernel id = %x\n",id);
+// return id;
+ return 0x63;
+}
+
+static struct panel_operations lcd_hx8363_rgb_spi_operations = {
+ .panel_init = hx8363_init,
+ .panel_set_window = hx8363_set_window,
+ .panel_invalidate_rect= hx8363_invalidate_rect,
+ .panel_invalidate = hx8363_invalidate,
+ .panel_enter_sleep = hx8363_enter_sleep,
+ .panel_readid = hx8363_read_id
+};
+
+static struct timing_rgb lcd_hx8363_rgb_timing = {
+#if 1
+ .hfp = 30,//10, /* unit: pixel */
+ .hbp = 55, //6,
+ .hsync = 10, //8,
+ .vfp = 6, // 3, /*unit: line*/
+ .vbp = 19, // 3,
+ .vsync = 6, // 4,
+#else
+ .hfp = 15,//10, /* unit: pixel */
+ .hbp = 15,//6,
+ .hsync = 10, //8,
+ .vfp = 8, // 3, /*unit: line*/
+ .vbp = 8, // 3,
+ .vsync = 6, // 4,
+#endif
+};
+
+static struct spi_info lcd_hx8363_rgb_spi_info = {
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_hx8363_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_SPI,
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_NEG,
+ .v_sync_pol = SPRDFB_POLARITY_NEG,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_hx8363_rgb_timing,
+ .bus_info = {
+ .spi = &lcd_hx8363_rgb_spi_info,
+ }
+};
+
+struct panel_spec lcd_panel_hx8363_rgb_spi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 61,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .rgb = &lcd_hx8363_rgb_info
+ },
+ .ops = &lcd_hx8363_rgb_spi_operations,
+};
+
+struct panel_cfg lcd_hx8363_rgb_spi_spec_viva = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x63,
+ .lcd_name = "lcd_hx8363_rgb_spi",
+ .panel = &lcd_panel_hx8363_rgb_spi_spec,
+};
+
+static int __init lcd_hx8363_rgb_spi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8363_rgb_spi_spec_viva);
+
+}
+
+subsys_initcall(lcd_hx8363_rgb_spi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369.c b/drivers/video/sprdfb/lcd/lcd_hx8369.c
new file mode 100644
index 00000000..5c143a9a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * 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/delay.h>
+#include "lcdpanel.h"
+
+static int32_t hx8369_init(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ /* SET password */
+ send_cmd(0xB9);
+ send_data(0xFF);
+ send_data(0x83);
+ send_data(0x69);
+
+ /* Set Power */
+ send_cmd(0xB1);
+ send_data(0x9D);
+ send_data(0x00);
+ send_data(0x34);
+ send_data(0x07);
+ send_data(0x00);
+ send_data(0x0B);
+ send_data(0x0B);
+ send_data(0x1A);
+ send_data(0x22);
+ send_data(0x3F);
+ send_data(0x3F);
+ send_data(0x01);
+ send_data(0x23);
+ send_data(0x01);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+ send_data(0xE6);
+
+ /* SET Display 480x800 */
+ send_cmd(0xB2);
+ send_data(0x00);
+ send_data(0x20);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x70);
+ send_data(0x00);
+ send_data(0xFF);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x00);
+ send_data(0x01);
+
+ /* SET Display 480x800 */
+ send_cmd(0xB4);
+ send_data(0x00);
+ send_data(0x18);
+ send_data(0x80);
+ send_data(0x06);
+ send_data(0x02);
+
+ /* OSC */
+ send_cmd(0xB0);
+ send_data(0x00);
+ send_data(0x09); /*05 42HZ 07 50HZ 0B 100% 67HZ */
+
+ /* SET VCOM */
+ send_cmd(0xB6);
+ send_data(0x4A);
+ send_data(0x4A);
+
+ /* SET GIP */
+ send_cmd(0xD5);
+ send_data(0x00);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x00);
+ send_data(0x01);
+ send_data(0x02);
+
+ send_data(0x28);
+ send_data(0x70);
+ send_data(0x11);
+ send_data(0x13);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x40);
+ send_data(0x06);
+ send_data(0x51);
+ send_data(0x07);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x41);
+ send_data(0x06);
+ send_data(0x50);
+ send_data(0x07);
+ send_data(0x07);
+ send_data(0x0F);
+ send_data(0x04);
+ send_data(0x00);
+
+ /* Set Gamma */
+ send_cmd(0xE0);
+ send_data(0x00);
+ send_data(0x01);
+ send_data(0x04);
+ send_data(0x23);
+ send_data(0x22);
+ send_data(0x3F);
+ send_data(0x13);
+ send_data(0x39);
+ send_data(0x06);
+ send_data(0x0B);
+ send_data(0x0E);
+ send_data(0x12);
+ send_data(0x15);
+ send_data(0x13);
+ send_data(0x15);
+ send_data(0x13);
+ send_data(0x1B);
+ send_data(0x00);
+ send_data(0x01);
+ send_data(0x04);
+ send_data(0x23);
+ send_data(0x22);
+ send_data(0x3F);
+ send_data(0x13);
+ send_data(0x39);
+ send_data(0x06);
+ send_data(0x0B);
+ send_data(0x0E);
+ send_data(0x12);
+ send_data(0x15);
+ send_data(0x13);
+ send_data(0x15);
+ send_data(0x13);
+ send_data(0x1B);
+ send_cmd(0x35); /* TE on*/
+ send_data(0x00);
+
+ /* set CSEL */
+ send_cmd(0x3A);
+ send_data(0x07); /* CSEL=0x06, 16bit-color CSEL=0x06, 18bit-color CSEL=0x07, 24bit-color */
+
+ /*24 bit don't need to set 2DH*/
+
+ /* Sleep Out */
+ send_cmd(0x11);
+
+ LCD_DelayMS(120);
+
+ #if 0
+ { /* for test the lcd */
+ int i;
+
+ send_cmd(0x2C); //Write data
+ for (i = 0; i < 480*800/3; i++)
+ send_data(0xff);
+ for (i = 0; i < 480*800/3; i++)
+ send_data(0xff00);
+ for (i = 0; i < 480*800/3; i++)
+ send_data(0xff0000);
+ }
+ #endif
+ /* Display On */
+ send_cmd(0x29);
+
+ LCD_DelayMS (120);
+
+ /* Write data */
+ send_cmd(0x2C);
+
+ return 0;
+}
+
+static int32_t hx8369_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("hx8369_set_window:%d, %d, %d, %d\n", left, top, right, bottom);
+
+ /* col */
+ send_cmd(0x2A);
+ send_data((left >> 8));
+ send_data((left & 0xFF));
+ send_data((right >> 8));
+ send_data((right & 0xFF));
+
+ /* row */
+ send_cmd(0x2B);
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+ send_data((bottom >> 8));
+ send_data((bottom & 0xFF));
+
+ /* Write data */
+ send_cmd(0x2C);
+
+ return 0;
+}
+
+
+static int32_t hx8369_invalidate(struct panel_spec *self)
+{
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width-1, self->height-1);
+
+}
+
+static int32_t hx8369_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("hx8369_invalidate_rect\n");
+
+ /* TE scanline */
+ send_cmd(0x44);
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t hx8369_set_direction(struct panel_spec *self, uint16_t direction)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("hx8369_set_direction\n");
+ send_cmd(0x36);
+
+ switch (direction) {
+ case LCD_DIRECT_NORMAL:
+ send_data(0);
+ break;
+ case LCD_DIRECT_ROT_90:
+ send_data(0xA0);
+ break;
+ case LCD_DIRECT_ROT_180:
+ send_data(0x60);
+ break;
+ case LCD_DIRECT_ROT_270:
+ send_data(0xB0);
+ break;
+ case LCD_DIRECT_MIR_H:
+ send_data(0x40);
+ break;
+ case LCD_DIRECT_MIR_V:
+ send_data(0x10);
+ break;
+ case LCD_DIRECT_MIR_HV:
+ send_data(0xE0);
+ break;
+ default:
+ pr_debug("unknown lcd direction!\n");
+ send_data(0x0);
+ direction = LCD_DIRECT_NORMAL;
+ break;
+ }
+
+ self->direction = direction;
+
+ return 0;
+}
+
+static int32_t hx8369_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+
+ if(is_sleep) {
+ /* Sleep In */
+ send_cmd(0x28);
+ LCD_DelayMS(120);
+ send_cmd(0x10);
+ LCD_DelayMS(120);
+ }
+ else {
+#if 1
+ /* Sleep Out */
+ send_cmd(0x11);
+ LCD_DelayMS(120);
+ send_cmd(0x29);
+ LCD_DelayMS(120);
+#else
+ /* re init */
+ se1f->ops->reset(self);
+ se1f->ops->lcd_init(self);
+#endif
+ }
+ return 0;
+}
+
+static uint32_t hx8369_read_id(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+
+ send_cmd(0xB9);
+ send_data(0xFF);
+ send_data(0x83);
+ send_data(0x69);
+
+ send_cmd(0xF4);
+ read_data();
+ return read_data();
+}
+
+static struct panel_operations lcd_hx8369_operations = {
+ .panel_init = hx8369_init,
+ .panel_set_window = hx8369_set_window,
+ .panel_invalidate = hx8369_invalidate,
+ .panel_invalidate_rect = hx8369_invalidate_rect,
+ .panel_set_direction = hx8369_set_direction,
+ .panel_enter_sleep = hx8369_enter_sleep,
+ .panel_readid = hx8369_read_id,
+};
+
+static struct timing_mcu lcd_hx8369_timing[] = {
+[LCD_REGISTER_TIMING] = { /* read/write register timing (ns) */
+ .rcss = 25, /* 25 ns */
+ .rlpw = 70,
+ .rhpw = 70,
+ .wcss = 10,
+ .wlpw = 50,
+ .whpw = 50,
+ },
+[LCD_GRAM_TIMING] = { /* read/write gram timing (ns) */
+ .rcss = 25,
+ .rlpw = 70,
+ .rhpw = 70,
+ .wcss = 0,
+ .wlpw = 15,
+ .whpw = 24,
+ }
+};
+
+static struct info_mcu lcd_hx8369_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 24,
+ .timing = lcd_hx8369_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369_spec = {
+ .width = 480,
+ .height = 800,
+ .mode = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_hx8369_info,
+ },
+ .ops = &lcd_hx8369_operations,
+};
+
+struct panel_cfg lcd_hx8369 = {
+ /* this panel may on both CS0/1 */
+ .lcd_cs = -1,
+ .lcd_id = 0x69,
+ .lcd_name = "lcd_hx8369",
+ .panel = &lcd_hx8369_spec,
+};
+
+static int __init lcd_hx8369_init(void)
+{
+ return sprd_register_panel(&lcd_hx8369);
+}
+
+subsys_initcall(lcd_hx8369_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_grandneo_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_grandneo_mipi.c
new file mode 100755
index 00000000..35c2178b
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_grandneo_mipi.c
@@ -0,0 +1,338 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+//#define NEW_PANAL_BOE
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#ifndef NEW_PANAL_BOE
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x08,0x03,0x30,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x39,0x45,0x00,0x00,\
+ 0x0D,0x44,0x39,0x37,0x00,0x00,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x37,0x59,\
+ 0x18,0x10,0x00,0x00,0x05,0x00,0x00,0x40,0x28,0x69,0x40,0x00,0x00,0x00,0x00,0x00,0x26,0x49,0x08,0x00,0x00,0x00,\
+ 0x04,0x00,0x00,0x51,0x39,0x78,0x50,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x07,\
+ 0xF8,0x0F,0xFF,0xFF,0x07,0xF8,0x0F,0xFF,0xFF,0x00,0x20,0x5A,\
+}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(15),{13,0,0xB1,0x12,0x83,0x77,0x00,0x10,0x10,0x1E,0x1E,0x0C,0x1A,0x20,0xD6}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x3A,0x17}},
+ {LCM_SEND(2),{0xB4,0x01}},
+ {LCM_SEND(5),{3,0,0xB6,0x96,0x96}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x20,0xC4,0x00}},
+ //gamma setting
+ {LCM_SEND(130),{128,0,0xC1,0x03,0x00,0x06,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,\
+ 0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7C,0x84,0x8C,\
+ 0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,\
+ 0xE4,0xEC,0xF3,0xFD,0x0F,0xFA,0x95,0x40,0xFF,0xAA,\
+ 0x54,0x03,0xC0,0x00,0x07,0x0F,0x17,0x1F,0x27,0x2F,\
+ 0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F,\
+ 0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,\
+ 0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x17,0x1F,\
+ 0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,\
+ 0x77,0x7F,0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,\
+ 0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
+ {LCM_SEND(7),{5,0,0xE3,0x0F,0x0F,0x11,0x11}},
+ {LCM_SEND(2),{0xEA,0x7A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(38),{36,0,0xE0,0x01,0x0D,0x18,0x14,0x13,0x2F,0x31,0x3B,0x09,0x10,0x12,0x16,0x17,0x16,0x16,0x11,0x14,0x01,\
+ 0x0D,0x18,0x14,0x13,0x2F,0x30,0x3B,0x09,0x10,0x11,0x16,0x17,0x15,0x16,0x11,0x14,0x01}},
+ {LCM_SEND(2),{0x51,0x80}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(120)}, //40
+
+#else
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x0B,0x0B,0x0C,0x0A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(6),{4,0,0xC3,0x55,0xB8,0x90}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x02,0x04,0x2C,0x33,0x3F,0x0D,0x32,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x00,\
+0x02,0x04,0x2C,0x32,0x3F,0x0F,0x31,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x01,
+}},
+
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x51,0x80}},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+#ifndef NEW_PANAL_BOE
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+#else
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0x90 == read_data[2]))
+#endif
+ {
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8369b_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 90, /* unit: pixel */
+ .hbp = 70,
+ .hsync = 60,
+ .vfp = 8, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi.c
new file mode 100644
index 00000000..65e7014a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi.c
@@ -0,0 +1,348 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+#define NEW_PANAL_BOE
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#ifndef NEW_PANAL_BOE
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(2),{0x36,0x00}},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x16,0x16,0x0C,0x0A}},
+ {LCM_SEND(2),{0xB2,0x03}},
+// {LCM_SEND(5),{3,0,0xB2,0x00,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(5),{3,0,0xB6,0xA3,0xA3}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xc4,0x00}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x01,0x0D,0x18,0x14,0x13,0x2F,0x31,0x3B,0x09,0x10,0x12,0x16,0x17,0x16,0x16,0x11,0x14,0x01,\
+ 0x0D,0x18,0x14,0x13,0x2F,0x30,0x3B,0x09,0x10,0x11,0x16,0x17,0x15,0x16,0x11,0x14,0x01}},
+ {LCM_SEND(130),{128,0,0xC1,0x03,0x00,0x06,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,\
+ 0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7C,0x84,0x8C,\
+ 0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,\
+ 0xE4,0xEC,0xF3,0xFD,0x0F,0xFA,0x95,0x40,0xFF,0xAA,\
+ 0x54,0x03,0xC0,0x00,0x07,0x0F,0x17,0x1F,0x27,0x2F,\
+ 0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F,\
+ 0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,\
+ 0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x17,0x1F,\
+ 0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,\
+ 0x77,0x7F,0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,\
+ 0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x51,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#else
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x0B,0x0B,0x0C,0x0A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(6),{4,0,0xC3,0x55,0xB8,0x90}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x02,0x04,0x2C,0x33,0x3F,0x0D,0x32,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x00,\
+0x02,0x04,0x2C,0x32,0x3F,0x0F,0x31,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x01,
+}},
+
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x51,0x80}},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+#ifndef NEW_PANAL_BOE
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+#else
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0x90 == read_data[2]))
+#endif
+ {
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8369b_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 110, /* unit: pixel */
+ .hbp = 110,
+ .hsync = 4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite.c
new file mode 100644
index 00000000..65e7014a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite.c
@@ -0,0 +1,348 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+#define NEW_PANAL_BOE
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#ifndef NEW_PANAL_BOE
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(2),{0x36,0x00}},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x16,0x16,0x0C,0x0A}},
+ {LCM_SEND(2),{0xB2,0x03}},
+// {LCM_SEND(5),{3,0,0xB2,0x00,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(5),{3,0,0xB6,0xA3,0xA3}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xc4,0x00}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x01,0x0D,0x18,0x14,0x13,0x2F,0x31,0x3B,0x09,0x10,0x12,0x16,0x17,0x16,0x16,0x11,0x14,0x01,\
+ 0x0D,0x18,0x14,0x13,0x2F,0x30,0x3B,0x09,0x10,0x11,0x16,0x17,0x15,0x16,0x11,0x14,0x01}},
+ {LCM_SEND(130),{128,0,0xC1,0x03,0x00,0x06,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,\
+ 0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7C,0x84,0x8C,\
+ 0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,\
+ 0xE4,0xEC,0xF3,0xFD,0x0F,0xFA,0x95,0x40,0xFF,0xAA,\
+ 0x54,0x03,0xC0,0x00,0x07,0x0F,0x17,0x1F,0x27,0x2F,\
+ 0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F,\
+ 0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,\
+ 0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x17,0x1F,\
+ 0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,\
+ 0x77,0x7F,0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,\
+ 0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x51,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#else
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x0B,0x0B,0x0C,0x0A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(6),{4,0,0xC3,0x55,0xB8,0x90}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x02,0x04,0x2C,0x33,0x3F,0x0D,0x32,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x00,\
+0x02,0x04,0x2C,0x32,0x3F,0x0F,0x31,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x01,
+}},
+
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x51,0x80}},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+#ifndef NEW_PANAL_BOE
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+#else
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0x90 == read_data[2]))
+#endif
+ {
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8369b_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 110, /* unit: pixel */
+ .hbp = 110,
+ .hsync = 4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite_marlin.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite_marlin.c
new file mode 100644
index 00000000..65e7014a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_coreprimelite_marlin.c
@@ -0,0 +1,348 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+#define NEW_PANAL_BOE
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#ifndef NEW_PANAL_BOE
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(2),{0x36,0x00}},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x16,0x16,0x0C,0x0A}},
+ {LCM_SEND(2),{0xB2,0x03}},
+// {LCM_SEND(5),{3,0,0xB2,0x00,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(5),{3,0,0xB6,0xA3,0xA3}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xc4,0x00}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x01,0x0D,0x18,0x14,0x13,0x2F,0x31,0x3B,0x09,0x10,0x12,0x16,0x17,0x16,0x16,0x11,0x14,0x01,\
+ 0x0D,0x18,0x14,0x13,0x2F,0x30,0x3B,0x09,0x10,0x11,0x16,0x17,0x15,0x16,0x11,0x14,0x01}},
+ {LCM_SEND(130),{128,0,0xC1,0x03,0x00,0x06,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,\
+ 0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7C,0x84,0x8C,\
+ 0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,\
+ 0xE4,0xEC,0xF3,0xFD,0x0F,0xFA,0x95,0x40,0xFF,0xAA,\
+ 0x54,0x03,0xC0,0x00,0x07,0x0F,0x17,0x1F,0x27,0x2F,\
+ 0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F,\
+ 0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,\
+ 0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x17,0x1F,\
+ 0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,\
+ 0x77,0x7F,0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,\
+ 0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x51,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#else
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x0B,0x0B,0x0C,0x0A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(6),{4,0,0xC3,0x55,0xB8,0x90}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x02,0x04,0x2C,0x33,0x3F,0x0D,0x32,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x00,\
+0x02,0x04,0x2C,0x32,0x3F,0x0F,0x31,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x01,
+}},
+
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x51,0x80}},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+#ifndef NEW_PANAL_BOE
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+#else
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0x90 == read_data[2]))
+#endif
+ {
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8369b_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 110, /* unit: pixel */
+ .hbp = 110,
+ .hsync = 4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_kiran3g.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_kiran3g.c
new file mode 100644
index 00000000..9926fd76
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_kiran3g.c
@@ -0,0 +1,384 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+#define LCD_NEW_PANEL
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+#ifndef LCD_NEW_PANEL
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x11,0x11,0x08,0x08,0x0C,0x12}},
+ {LCM_SEND(7),{5,0,0xC6,0x41,0xFF,0x7A,0xFF}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB0,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(10),{8,0,0xB3,0x83,0x00,0x31,0x03,0x01,0x13,0x06}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+ //set GIP timing control
+ {LCM_SEND(95),{93, 0, 0xD5,
+ 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x12, 0x40, 0x00,\
+ 0x00, 0x00, 0x01, 0x60, 0x37, 0x00, 0x00, 0x0F, 0x01, 0x02,\
+ 0x47, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x89, 0x00,\
+ 0x11, 0x33, 0x55, 0x77, 0x31, 0x00, 0x00, 0x98, 0x00, 0x66,\
+ 0x44, 0x22, 0x00, 0x02, 0x00, 0x00, 0x89, 0x00, 0x00, 0x22,\
+ 0x44, 0x66, 0x20, 0x00, 0x00, 0x98, 0x00, 0x77, 0x55, 0x33,\
+ 0x11, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,\
+ 0x00, 0xCF, 0xFF, 0xFF, 0x03, 0x00, 0xCF, 0xFF, 0xFF, 0x20,\
+ 0x8C, 0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36, 0, 0xE0,
+ 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x3F, 0x18, 0x2C, 0x04, 0x0F,\
+ 0x0E, 0x14, 0x17, 0x15, 0x16, 0x10, 0x13, 0x00, 0x00, 0x00,\
+ 0x0C, 0x12, 0x3F, 0x17, 0x2C, 0x05, 0x08, 0x0E, 0x12, 0x16,\
+ 0x14, 0x15, 0x11, 0x13, 0x01}},
+ {LCM_SEND(130),{128, 0, 0xC1,
+ 0x01, 0x00, 0x08, 0x10, 0x18, 0x1F, 0x27, 0x2E, 0x34, 0x3E,\
+ 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90,\
+ 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0, 0xD8, 0xE0,\
+ 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x1F, 0x27, 0x2E,\
+ 0x34, 0x3E, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80,\
+ 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0,\
+ 0xD8, 0xE0, 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00,\
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x1F,\
+ 0x27, 0x2E, 0x34, 0x3E, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70,\
+ 0x78, 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0,\
+ 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00,\
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+#else
+ /* Password */
+ {LCM_SEND(5),{3,0,0xF0,0x5A,0x5A}},
+ {LCM_SEND(5),{3,0,0xF1,0x5A,0x5A}},
+ {LCM_SEND(5),{3,0,0xFC,0xA5,0xA5}},
+
+ /* Resolution Control */
+ {LCM_SEND(2),{0xB3, 0x01}},
+ {LCM_SEND(2),{0xB5, 0x10}},
+ {LCM_SEND(6),{4,0,0xBC,0x00,0x29,0x51}}, /* 141006 Battery detect function disabled */
+
+ /* MIPI SETTING */
+ {LCM_SEND(5),{3,0,0xE3,0x24,0x2C}},
+
+ /* Display Inversion Off */
+ {LCM_SEND(1),{0x21}},
+
+ /* Display Control */
+ {LCM_SEND(11), {9,0,0xF2,0x11,0x04,0x08,0x10,0x10,0x72,0x4A,0x0A}},
+
+ /* power control 1 */
+ {LCM_SEND(8),{6,0,0xF3,0x91,0x00,0x00,0x00,0x10}},
+
+ /* power control 2 */
+ {LCM_SEND(46),{44,0,0xF4,0x01,0x02,0x23,0x24,0x25,0x25,0x26,0x26,0x29,0x29,0x2C,0x2B,0x2C,0x07,0x08,0x05,0x04,0x04,0x01,0x01,0x22,0x0A,0x17,0x0F,0x11,0x23,0x0D,0x0A,0x0B,0x02,0x19,0x13,0x1E,0x1F,0x23,0x20,0x05,0x16,0x1A,0x16,0x1E,0x24,0x1E}},
+
+ /* power control 3 */
+ {LCM_SEND(31),{29,0,0xF5,0x14,0x14,0xB9,0x21,0x35,0x55,0x36,0x0A,0x00,0x39,0x00,0x00,0x0B,0x4B,0xC4,0xCB,0x4B,0x12,0x12,0x1A,0x00,0x10,0xE0,0xE2,0x0E,0x34,0x34,0x03}},
+
+ /* 9.4 */
+ {LCM_SEND(20),{18,0,0xFE,0x00,0x02,0x01,0x39,0x60,0x40,0x21,0x00,0x4B,0x00,0x80,0x00,0xF0,0x00,0x00,0x00,0x06}},
+
+ /* ASG EQ Control */
+ {LCM_SEND(13),{11,0,0xEE,0x40,0xA0,0x40,0xA0,0x00,0x00,0x00,0x00,0x00,0x00}},
+
+ {LCM_SEND(23),{21,0,0xEF,0x23,0x01,0x00,0x00,0x2A,0x49,0x08,0x27,0x21,0x40,0x10,0x24,0x02,0x21,0x21,0x03,0x03,0x40,0x00,0x08}},
+
+ /* Panel Gate Control */
+ {LCM_SEND(33),{31,0,0xF7,0x02,0x1B,0x1A,0x00,0x01,0x0E,0x0E,0x0A,0x0A,0x0F,0x0F,0x0B,0x0B,0x05,0x07,0x02,0x1B,0x1A,0x00,0x01,0x0C,0x0C,0x08,0x08,0x0D,0x0D,0x09,0x09,0x04,0x06}},
+
+ /* Source Control */
+ {LCM_SEND(9),{7,0,0xF6,0x63,0x25,0x15,0x00,0x00,0x20}},
+
+ /* Memory Data Access Control */
+ {LCM_SEND(2),{0x36,0x10}},
+
+ /* Positive Gamma Control */
+ {LCM_SEND(20),{18,0,0xFA,0x0C,0x36,0x0B,0x10,0x07,0x0C,0x10,0x10,0x14,0x1D,0x1F,0x1F,0x20,0x21,0x22,0x25,0x2F}},
+
+ /* Negative Gamma Control */
+ {LCM_SEND(20),{18,0,0xFB,0x0C,0x36,0x0B,0x10,0x07,0x0C,0x10,0x0E,0x0E,0x15,0x1B,0x1E,0x20,0x1F,0x20,0x25,0x2F}},
+
+ /* display on */
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(120)},
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+ {
+ int32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+#ifndef LCD_NEW_PANEL
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ if((0x55 == read_data[0])&&(0xbf == read_data[1] || 0xc0 == read_data[1] || 0xbe == read_data[1])&&(0x90 == read_data[2])){
+ LCD_PRINT("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+#else
+ param[0] = 0x03;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0x04, 3, read_data);
+ LCD_PRINT("lcd_s6d77a1_mipi read id 0xda, 0xdb,0xdc is 0x%x,0x%x,0x%x!\n",
+ read_data[0], read_data[1], read_data[2]);
+ if ((0x55 == read_data[0]) && (0xB8 == read_data[1])
+ && (0x10 == read_data[2])) {
+ LCD_PRINT("lcd_s6d77a1_mipi read id success!\n");
+ return 0x8369;
+ }
+#endif
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+#ifndef LCD_NEW_PANEL
+ .hfp = 115, /* unit: pixel */
+ .hbp = 55,
+ .hsync = 4,
+ .vfp = 6, /*unit: line*/
+ .vbp = 19,
+ .vsync = 4,
+#else
+ .hfp = 74, /* unit: pixel */
+ .hbp = 88,
+ .hsync = 26,
+ .vfp = 16, /* unit: line */
+ .vbp = 12,
+ .vsync = 4,
+#endif
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_sharkls_z3lte.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_sharkls_z3lte.c
new file mode 100644
index 00000000..65e7014a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_sharkls_z3lte.c
@@ -0,0 +1,348 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+#define NEW_PANAL_BOE
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#ifndef NEW_PANAL_BOE
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(2),{0x36,0x00}},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x16,0x16,0x0C,0x0A}},
+ {LCM_SEND(2),{0xB2,0x03}},
+// {LCM_SEND(5),{3,0,0xB2,0x00,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(5),{3,0,0xB6,0xA3,0xA3}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xc4,0x00}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x01,0x0D,0x18,0x14,0x13,0x2F,0x31,0x3B,0x09,0x10,0x12,0x16,0x17,0x16,0x16,0x11,0x14,0x01,\
+ 0x0D,0x18,0x14,0x13,0x2F,0x30,0x3B,0x09,0x10,0x11,0x16,0x17,0x15,0x16,0x11,0x14,0x01}},
+ {LCM_SEND(130),{128,0,0xC1,0x03,0x00,0x06,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,\
+ 0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7C,0x84,0x8C,\
+ 0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,\
+ 0xE4,0xEC,0xF3,0xFD,0x0F,0xFA,0x95,0x40,0xFF,0xAA,\
+ 0x54,0x03,0xC0,0x00,0x07,0x0F,0x17,0x1F,0x27,0x2F,\
+ 0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F,\
+ 0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,\
+ 0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x17,0x1F,\
+ 0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,\
+ 0x77,0x7F,0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,\
+ 0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x51,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#else
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x0F,0x0F,0x0B,0x0B,0x0C,0x0A}},
+ {LCM_SEND(6),{4,0,0xC6,0x41,0xFF,0x7D}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(6),{4,0,0xC3,0x55,0xB8,0x90}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB1,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(7),{5,0,0xB3,0x83,0x00,0x31,0x03}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+
+
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x07,0x00,0x09,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x01,0x42,0x37,\
+ 0x00,0x00,0x08,0x2A,0x08,0x47,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x15,0x00,0x00,0x98,0x98,0x44,0x66,0x00,0x22,0x51,0x00,0x00,0x89,0x98,0x33,0x11,0x77,0x55,0x04,0x00,\
+ 0x00,0x98,0x98,0x55,0x77,0x11,0x33,0x40,0x00,0x00,0x89,0x98,0x22,0x00,0x66,0x44,0x15,0x00,0x00,0x00,\
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x0F,0xFF,0xFF,0x03,0x00,0x0F,0xFF,0xFF,0x00,0x8C,0x5A}},
+
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x02,0x04,0x2C,0x33,0x3F,0x0D,0x32,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x00,\
+0x02,0x04,0x2C,0x32,0x3F,0x0F,0x31,0x05,0x0B,0x0E,0x11,0x14,0x12,0x13,0x13,0x1A,0x01,
+}},
+
+
+ {LCM_SEND(5),{3,0,0xC9,0x0F,0x00}},
+ {LCM_SLEEP(5)},
+// {LCM_SEND(2),{0x51,0x80}},
+// {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+#ifndef NEW_PANAL_BOE
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+#else
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0x90 == read_data[2]))
+#endif
+ {
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8369b_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 110, /* unit: pixel */
+ .hbp = 110,
+ .hsync = 4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_vivaltoVE.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_vivaltoVE.c
new file mode 100644
index 00000000..6ffe813e
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_mipi_vivaltoVE.c
@@ -0,0 +1,283 @@
+/* drivers/video/sprdfb/lcd_hx8369b_mipi.c
+ *
+ * Support for hx8369b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},
+ //{LCM_SLEEP(10)},
+ {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x11,0x11,0x08,0x08,0x0C,0x12}},
+ {LCM_SEND(7),{5,0,0xC6,0x41,0xFF,0x7A,0xFF}},
+ {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},
+ {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB0,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(10),{8,0,0xB3,0x83,0x00,0x31,0x03,0x01,0x13,0x06}},
+ {LCM_SEND(2),{0xB4,0x00}},
+ {LCM_SEND(2),{0xCC,0x0C}},
+ {LCM_SEND(2),{0xEA,0x72}},
+ {LCM_SEND(2),{0xB2,0x03}},
+ //set GIP timing control
+ {LCM_SEND(95),{93,0,0xD5,0x00,0x00,0x0D,0x00,0x00,0x00,0x00,0x12,0x40,0x00,0x00,0x00,0x01,0x60,0x37,0x00,0x00,0x0F,
+ 0x01,0x02,0x47,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x18,
+ 0x00,0x00,0x89,0x00,0x11,0x33,0x55,0x77,0x31,0x00,0x00,0x98,0x00,0x66,0x44,0x22,0x00,0x02,
+ 0x00,0x00,0x89,0x00,0x00,0x22,0x44,0x66,0x20,0x00,0x00,0x98,0x00,0x77,0x55,0x33,0x11,0x13,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0xCF,0xFF,0xFF,0x03,0x00,0xCF,0xFF,0xFF,0x20,0x8C,0x5A}},
+ //gamma setting
+ {LCM_SEND(38),{36,0,0xE0,0x00,0x00,0x00,0x0D,0x0C,0x3F,0x18,0x2C,0x04,0x0F,0x0E,0x14,0x17,0x15,0x16,0x10,
+ 0x13,0x00,0x00,0x00,0x0C,0x12,0x3F,0x17,0x2C,0x05,0x08,0x0E,0x12,0x16,0x14,0x15,
+ 0x11,0x13,0x01}},
+ {LCM_SEND(130),{128,0,0xC1,0x01,0x00,0x08,0x10,0x18,0x1F,0x27,0x2E,0x34,0x3E,0x48,0x50,0x58,0x60,0x68,0x70,0x78,
+ 0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF7,0xFF,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x18,0x1F,0x27,0x2E,0x34,
+ 0x3E,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,
+ 0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF7,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x08,0x10,0x18,0x1F,0x27,0x2E,0x34,0x3E,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,
+ 0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF7,0xFF,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)}, //40
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t hx8369b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8369b_readid(struct panel_spec *self)
+ {
+ int32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8369b_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_hx8369b_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ if((0x55 == read_data[0])&&(0x0c == read_data[1])&&(0x90 == read_data[2])){
+ printk("lcd_hx8369b_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+
+static int32_t hx8369b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8369b_mipi_operations = {
+ .panel_init = hx8369b_mipi_init,
+ .panel_readid = hx8369b_readid,
+ .panel_enter_sleep = hx8369b_enter_sleep,
+};
+
+static struct timing_rgb lcd_hx8369b_mipi_timing = {
+ .hfp = 115, /* unit: pixel */
+ .hbp = 55,
+ .hsync = 50,
+ .vfp = 6, /*unit: line*/
+ .vbp = 19,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8369b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8369b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8369b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8369b_mipi_info
+ },
+ .ops = &lcd_hx8369b_mipi_operations,
+};
+struct panel_cfg lcd_hx8369b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_hx8369b_mipi",
+ .panel = &lcd_hx8369b_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8369b_mipi_init(void)
+{
+/*
+ printk("hx8369b_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_hx8369b_mipi);
+}
+
+subsys_initcall(lcd_hx8369b_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8369b_tshark2_j3_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8369b_tshark2_j3_mipi.c
new file mode 100755
index 00000000..5afb97e7
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8369b_tshark2_j3_mipi.c
@@ -0,0 +1,290 @@
+/* drivers/video/sprdfb/lcd_tshark2_j3_mipi.c
+ *
+ * Support for tshark2_j3 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x89}},
+ {LCM_SEND(23),{21,0,0xB1,0x7F,0x10,0x10,0xD2,0x32,0x80,0x10,0xF0,0x56,0x80,0x20,0x20,0xF8,0xAA,0xAA,0xA1,0x00,0x80,0x30,0x00}},
+ {LCM_SEND(13),{11,0,0xB2,0x82,0x50,0x05,0x07,0xF0,0x38,0x11,0x64,0x5D,0x09}},
+ {LCM_SEND(14),{12,0,0xB4,0x66,0x66,0x66,0x70,0x00,0x00,0x18,0x76,0x28,0x76,0xA8}},
+ {LCM_SEND(2),{0xD2,0x33}},
+ {LCM_SEND(7),{5,0,0xC0,0x30,0x17,0x00,0x03}},
+ {LCM_SEND(7),{5,0,0xC7,0x00,0x80,0x00,0xC0}},
+ {LCM_SEND(7),{5,0,0xBF,0x05,0x50,0x00,0x3E}},
+ {LCM_SLEEP(10)},
+ //{LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x89}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(38),{36,0,0xD3,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x32,0x10,0x00,0x00,0x00,0x03,0xC6,0x03,0xC6,0x00,0x00,0x00,0x00 \
+ ,0x35,0x33,0x04,0x04,0x37,0x00,0x00,0x00,0x05,0x08,0x00,0x00,0x0A,0x00,0x01}},
+ {LCM_SEND(41),{39,0,0xD5,0x18,0x18,0x18,0x18,0x19,0x19,0x18,0x18,0x20,0x21,0x24,0x25,0x18,0x18,0x18,0x18,0x00,0x01,0x04,0x05 \
+ ,0x02,0x03,0x06,0x07,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+ {LCM_SEND(41),{0x39,0,0xD6,0x18,0x18,0x18,0x18,0x18,0x18,0x19,0x19,0x25,0x24,0x21,0x20,0x18,0x18 \
+ ,0x18,0x18,0x07,0x06,0x03,0x02,0x05,0x04,0x01,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 \
+ ,0x18,0x18,0x18,0x18,0x18,0x18}},
+ {LCM_SEND(6),{4,0,0xB7,0x20,0x80,0x00}},
+
+//gamma
+ {LCM_SEND(45),{43,0,0xE0,0x00,0x02,0x06,0x38,0x3C,0x3F,0x1B,0x46,0x06,0x09,0x0C,0x17 \
+ ,0x10,0x13,0x16,0x13,0x14,0x08,0x13,0x15,0x19,0x00,0x02,0x06,0x37,0x3C,0x3F \
+ ,0x1A,0x45,0x05,0x09,0x0B,0x16,0x0F,0x13,0x15,0x13,0x14,0x07,0x12,0x14,0x18}},
+
+ {LCM_SEND(2),{0xBD,0x00}},
+ {LCM_SEND(46),{44,0,0xC1,0x00,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50 \
+ ,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8 \
+ ,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xBD,0x01}},
+ {LCM_SEND(45),{43,0,0xC1,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 \
+ ,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00 \
+ ,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xBD,0x02}},
+ {LCM_SEND(45),{43,0,0xC1,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x90 \
+ ,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+}},
+
+//CABC
+ {LCM_SEND(2),{0x51,0x80}},
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(16),{14,0,0xC9,0x1F,0x2E,0x0A,0x1E,0x81,0x1E,0x00,0x00,0x01,0x19,0x00,0x00,0x20}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x55,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+
+//display on
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)},
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+
+static int32_t tshark2_j3_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel J3_tshark2_j3_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t tshark2_j3_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_tshark2_j3_mipi_J3 read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+ {
+ printk("lcd_tshark2_j3_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_tshark2_j3_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t tshark2_j3_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel tshark2_j3_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_tshark2_j3_mipi_operations = {
+ .panel_init = tshark2_j3_mipi_init,
+ .panel_readid = tshark2_j3_readid,
+ .panel_enter_sleep = tshark2_j3_enter_sleep,
+};
+
+static struct timing_rgb lcd_tshark2_j3_mipi_timing = {
+ .hfp = 80, /* unit: pixel */
+ .hbp = 80,
+ .hsync = 20,
+ .vfp = 18, /*unit: line*/
+ .vbp = 13,
+ .vsync = 2,
+};
+
+
+static struct info_mipi lcd_tshark2_j3_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_tshark2_j3_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_tshark2_j3_mipi_spec = {
+ .width = 540,
+ .height = 960,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_tshark2_j3_mipi_info
+ },
+ .ops = &lcd_tshark2_j3_mipi_operations,
+};
+struct panel_cfg lcd_tshark2_j3_mipi = {
+
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8369,
+ .lcd_name = "lcd_tshark2_j3_mipi",
+ .panel = &lcd_tshark2_j3_mipi_spec,
+};
+
+//temp code
+static int __init lcd_tshark2_j3_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_tshark2_j3_mipi);
+}
+
+subsys_initcall(lcd_tshark2_j3_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8379a_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8379a_mipi.c
new file mode 100644
index 00000000..4b6c4a08
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8379a_mipi.c
@@ -0,0 +1,312 @@
+/* drivers/video/sprdfb/lcd_hx8379a_mipi.c
+ *
+ * Support for hx8379a mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 100
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+// Set EXTC
+{LCM_SEND(6), {4, 0, 0xb9,0xff,0x83,0x79}},
+
+// Set MIPI
+{LCM_SEND(5), {3, 0, 0xba,0x51,0x93}},
+//Set Power
+{LCM_SEND(34), {32, 0, 0xB1,0x00,0x50,0x24,0xF5,0x98,0x08,0x11,0x17,0x77,0x29,0x31,0x9A,
+ 0x1A,0x12,0x0B,0x76,0xF1,0x00,0xE6,0xE6,0xE6,0xE6,0xE6,0x00,0x04,0x05,
+ 0x0A,0x0B,0x04,0x05,0x6F}},
+// Set Display
+{LCM_SEND(16), {14, 0, 0xB2,0x00,0x00,0xFE,0x0E,0x0A,0x19,0xE2,0x00,0xFF,0x0E,0x0A,0x19,0x20}},
+// Set CYC
+{LCM_SEND(34), {32, 0, 0xB4,0x80,0x12,0x00,0x32,0x10,0x03,0x54,0x13,0x67,0x32,0x13,0x6B,
+ 0x39,0x00,0x42,0x05,0x37,0x00,0x41,0x08,0x3C,0x3C,0x08,0x00,0x40,0x08,
+ 0x28,0x08,0x30,0x30,0x04}},
+// Set GIP
+{LCM_SEND(50), {48, 0, 0xD5,0x00,0x00,0x0A,0x00,0x01,0x00,0x00,0x06,0x01,0x01,0x01,
+ 0x23,0x45,0x67,0xAA,0xBB,0x88,0x88,0x67,0x45,0x88,0x88,0x88,0x88,0x88,
+ 0x54,0x10,0x76,0x54,0x32,0xAA,0xBB,0x88,0x88,0x76,0x10,0x88,0x88,0x88,
+ 0x88,0x88,0x39,0x01,0x00,0x00,0x00,0x00}},
+// Set Gamma
+{LCM_SEND(38), {36, 0, 0xE0,0x79,0x00,0x01,0x0F,0x25,0x26,0x3F,0x33,0x47,0x0A,0x11,0x11,
+ 0x15,0x17,0x14,0x16,0x11,0x17,0x00,0x01,0x0F,0x25,0x26,0x3F,0x33,0x47,
+ 0x0A,0x11,0x11,0x15,0x17,0x14,0x16,0x11,0x17}},
+// Set Panel
+//{LCM_SEND(2), {0xcc,0x02}}, //no rotation
+{LCM_SEND(2), {0xcc,0x0E}},//rotation 180
+// Set VCOM
+{LCM_SEND(7), {5, 0, 0xB6,0x00,0xAC,0x00,0xAC}},
+//set TE
+{LCM_SEND(2), {0x35,0x00}},
+
+{LCM_SEND(1), {0x11}},//0x11
+{LCM_SLEEP(200)},
+{LCM_SEND(1), {0x29}},//0x29
+{LCM_SLEEP(100)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+static int32_t hx8379a_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8369b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8379a_readid(struct panel_spec *self)
+{
+ uint32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_hx8379a_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcd_hx8379a_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_hx8379a_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_hx8379a_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ if((0x83 == read_data[0])&&(0x79 == read_data[1])&&(0x0a == read_data[2])){
+ LCD_PRINT("lcd_hx8379a_mipi read id success!\n");
+ return 0x8379;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8379a_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_nt35516_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ pr_debug("lcd_hx8379a mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x1c == read_data[0]) && (0 == read_rtn)){
+ //printk("lcd_hx8379a_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x1c;
+ }
+ }
+
+ printk("lcd_hx8379a mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t hx8379a_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("hx8379a_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+#endif
+ power_mode = hx8379a_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+#endif
+ if(power_mode == 0x1c){
+ pr_debug("hx8379a_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("hx8379a_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_hx8379a_mipi_operations = {
+ .panel_init = hx8379a_mipi_init,
+ .panel_readid = hx8379a_readid,
+ .panel_esd_check = hx8379a_check_esd,
+};
+
+static struct timing_rgb lcd_hx8379a_mipi_timing = {
+ .hfp = 25, /* unit: pixel */
+ .hbp = 25,
+ .hsync = 11,
+ .vfp = 22, /*unit: line*/
+ .vbp = 12,
+ .vsync = 3,
+};
+
+
+static struct info_mipi lcd_hx8379a_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8379a_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8379a_mipi_spec = {
+ .width = 480,
+ .height = 854,
+ .fps = 62,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8379a_mipi_info
+ },
+ .ops = &lcd_hx8379a_mipi_operations,
+};
+struct panel_cfg lcd_hx8379a_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8379,
+ .lcd_name = "lcd_hx8379a_mipi",
+ .panel = &lcd_hx8379a_mipi_spec,
+};
+
+static int __init lcd_hx8379a_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8379a_mipi);
+}
+
+subsys_initcall(lcd_hx8379a_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8389c_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8389c_mipi.c
new file mode 100755
index 00000000..9ef8ed43
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8389c_mipi.c
@@ -0,0 +1,318 @@
+/* drivers/video/sprdfb/lcd_hx8389c_mipi.c
+ *
+ * Support for hx8389c mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#if defined(CONFIG_MACH_GRANDPRIME3G_VE) || defined(CONFIG_MACH_GRANDPRIME_DTV)
+static int is_gpio_request2=0;
+#endif
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+ {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x89}},
+ {LCM_SEND(23),{21,0,0xB1,0x7F,0x10,0x10,0xD2,0x32,0x80,0x10,0xF0,0x56,0x80,0x20,0x20,0xF8,0xAA,0xAA,0xA1,0x00,0x80,0x30,0x00}},
+ {LCM_SEND(13),{11,0,0xB2,0x82,0x50,0x05,0x07,0xF0,0x38,0x11,0x64,0x5D,0x09}},
+ {LCM_SEND(14),{12,0,0xB4,0x66,0x66,0x66,0x70,0x00,0x00,0x18,0x76,0x28,0x76,0xA8}},
+ {LCM_SEND(2),{0xD2,0x33}},
+ {LCM_SEND(7),{5,0,0xC0,0x30,0x17,0x00,0x03}},
+ {LCM_SEND(7),{5,0,0xC7,0x00,0x80,0x00,0xC0}},
+ {LCM_SEND(7),{5,0,0xBF,0x05,0x50,0x00,0x3E}},
+ {LCM_SLEEP(10)},
+ //{LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x89}},
+ {LCM_SEND(2),{0xCC,0x0E}},
+ {LCM_SEND(38),{36,0,0xD3,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x32,0x10,0x00,0x00,0x00,0x03,0xC6,0x03,0xC6,0x00,0x00,0x00,0x00 \
+ ,0x35,0x33,0x04,0x04,0x37,0x00,0x00,0x00,0x05,0x08,0x00,0x00,0x0A,0x00,0x01}},
+ {LCM_SEND(41),{39,0,0xD5,0x18,0x18,0x18,0x18,0x19,0x19,0x18,0x18,0x20,0x21,0x24,0x25,0x18,0x18,0x18,0x18,0x00,0x01,0x04,0x05 \
+ ,0x02,0x03,0x06,0x07,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+ {LCM_SEND(41),{39,0,0xD6,0x18,0x18,0x18,0x18,0x18,0x18,0x19,0x19,0x25,0x24,0x21,0x20,0x18,0x18 \
+ ,0x18,0x18,0x07,0x06,0x03,0x02,0x05,0x04,0x01,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 \
+ ,0x18,0x18,0x18,0x18,0x18,0x18}},
+ {LCM_SEND(6),{4,0,0xB7,0x20,0x80,0x00}},
+
+//gamma
+ {LCM_SEND(45),{43,0,0xE0,0x00,0x02,0x06,0x38,0x3C,0x3F,0x1B,0x46,0x06,0x09,0x0C,0x17 \
+ ,0x10,0x13,0x16,0x13,0x14,0x08,0x13,0x15,0x19,0x00,0x02,0x06,0x37,0x3C,0x3F \
+ ,0x1A,0x45,0x05,0x09,0x0B,0x16,0x0F,0x13,0x15,0x13,0x14,0x07,0x12,0x14,0x18}},
+
+ {LCM_SEND(2),{0xBD,0x00}},
+ {LCM_SEND(46),{44,0,0xC1,0x00,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50 \
+ ,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8 \
+ ,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xBD,0x01}},
+ {LCM_SEND(45),{43,0,0xC1,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 \
+ ,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00 \
+ ,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0xBD,0x02}},
+ {LCM_SEND(45),{43,0,0xC1,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x90 \
+ ,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+}},
+
+//CABC
+ {LCM_SEND(2),{0x51,0x80}},
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(16),{14,0,0xC9,0x1F,0x2E,0x0A,0x1E,0x81,0x1E,0x00,0x00,0x01,0x19,0x00,0x00,0x20}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x55,0x00}},
+ {LCM_SLEEP(5)},
+ {LCM_SEND(2),{0x53,0x24}},
+ {LCM_SLEEP(5)},
+
+//display on
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(180)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(10)},
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+
+static int32_t hx8389c_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+#if defined(CONFIG_MACH_GRANDPRIME3G_VE) || defined(CONFIG_MACH_GRANDPRIME_DTV)
+static uint32_t hx8389c_before_resume(struct panel_spec *self)
+{
+ if(is_gpio_request2==0){
+ if (gpio_request(167, "LCD LDO")) {
+ printk("Failed ro request GPIO_%d \n",167);
+ return 0;
+ }
+ gpio_direction_output(167, 0);
+ is_gpio_request2=1;
+ }
+ gpio_set_value(167, 1);
+ return 0;
+}
+
+static uint32_t hx8389c_after_suspend(struct panel_spec *self)
+{
+ if(is_gpio_request2==0){
+ if (gpio_request(167, "LCD LDO")) {
+ printk("Failed ro request GPIO_%d \n",167);
+ return 0;
+ }
+ gpio_direction_output(167, 0);
+ is_gpio_request2=1;
+ }
+ gpio_set_value(167, 0);
+ return 0;
+}
+#endif
+
+static uint32_t hx8389c_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_hx8389c_mipi_J3 read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+
+ if((0x55 == read_data[0])&&(0xc0 == read_data[1])&&(0x90 == read_data[2]))
+ {
+ printk("lcd_hx8389c_mipi read id success!\n");
+ return 0x8389;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_hx8389c_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t hx8389c_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8389c_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_hx8389c_mipi_operations = {
+ .panel_init = hx8389c_mipi_init,
+ .panel_readid = hx8389c_readid,
+ .panel_enter_sleep = hx8389c_enter_sleep,
+#if defined(CONFIG_MACH_GRANDPRIME3G_VE) || defined(CONFIG_MACH_GRANDPRIME_DTV)
+ .panel_after_suspend=hx8389c_after_suspend,
+ .panel_before_resume=hx8389c_before_resume,
+#endif
+};
+
+static struct timing_rgb lcd_hx8389c_mipi_timing = {
+ .hfp = 80, /* unit: pixel */
+ .hbp = 80,
+ .hsync = 20,
+ .vfp = 18, /*unit: line*/
+ .vbp = 13,
+ .vsync = 2,
+};
+
+
+static struct info_mipi lcd_hx8389c_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8389c_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8389c_mipi_spec = {
+ .width = 540,
+ .height = 960,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8389c_mipi_info
+ },
+ .ops = &lcd_hx8389c_mipi_operations,
+};
+struct panel_cfg lcd_hx8389c_mipi = {
+
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8389,
+ .lcd_name = "lcd_hx8389c_mipi",
+ .panel = &lcd_hx8389c_mipi_spec,
+};
+
+//temp code
+static int __init lcd_hx8389c_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8389c_mipi);
+}
+
+subsys_initcall(lcd_hx8389c_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8394a_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8394a_mipi.c
new file mode 100644
index 00000000..b52eb976
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8394a_mipi.c
@@ -0,0 +1,295 @@
+/* drivers/video/sprdfb/lcd_hx8389b_mipi.c
+ *
+ * Support for hx8389b mipi LCD device
+ *
+ * Copyright (C) 2015 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+{LCM_SEND(6), {4, 0, 0xB9,0xFF,0x83,0x94}},
+{LCM_SEND(19), {17, 0, 0xBA,0x63,0x82,0x00,0x16,0xC5,0x00,0x10,0xFF,0x0F,0x24,0x03,0x21,0x24,0x25,0x20,0x08}},
+{LCM_SEND(20), {18, 0, 0xB1,0x01,0x00,0x04,0xC4,0x03,0x12,0xF1,0x24,0x2C,0x3F,0x3F,0x57,0x02,0x00,0xE6,0xE2,0xA6}},
+{LCM_SEND(9), {7, 0, 0xB2,0x00,0xC8,0x0E,0x30,0x00,0x33}},
+{LCM_SEND(34), {32, 0, 0xB4,0x80,0x04,0x32,0x10,0x08,0x54,0x15,0x0F,0x22,0x10,0x08,0x47,0x53,0x54,0x0A,0x4B,0x53,0x54,0x02,0x61,0x61,0x02,0x06,0x44,0x06,0x5F,0x0A,0x6B,0x70,0x05,0x08}},
+{LCM_SEND(2), {0xB6, 0x21}},
+{LCM_SEND(57), {55, 0, 0xD5,0x00,0x00,0x00,0x00,0x0A,0x00,0x01,0x22,0x00,0x33,0xCC,0x00,0xAA,0xBB,0x01,0x23,0x45,0x67,0x9A,0xBC,0x45,0x67,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x01,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x3C,0x01}},
+
+{LCM_SEND(2), {0xCC, 0x09}},
+
+{LCM_SEND(7), {5, 0, 0xBF,0x06,0x02,0x10,0x04}},
+
+{LCM_SEND(7), {5, 0, 0xC7,0x00,0x10,0x00,0x10}},
+
+{LCM_SEND(28), {26, 0, 0xE0,0x00,0x04,0x08,0x28,0x2F,0x3F,0x15,0x34,0x06,0x0C,0x0E,0x12,0x14,0x13,0x14,0x11,0x19,0x00,0x04,0x08,0x29,0x2E,0x3F,0x15,0x35}},
+{LCM_SEND(19), {17, 0, 0x07,0x0C,0x0F,0x11,0x13,0x11,0x12,0x10,0x16,0x0A,0x17,0x07,0x12,0x0A,0x17,0x06,0x11}},
+
+{LCM_SEND(5), {3, 0, 0xC0,0x0C,0x17}},
+
+{LCM_SEND(5), {3, 0, 0xC6,0x08,0x08}},
+
+{LCM_SEND(2), {0xD4, 0x32}},
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(200)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(100)},
+
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+static int32_t hx8394a_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel hx8394a_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8394a_readid(struct panel_spec *self)
+{
+ uint32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_hx8394a_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x03;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0x04,3, &read_data[0]);
+ LCD_PRINT("lcd_hx8394a_mipi read id 0x04 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if(0x83 == read_data[0] && 0x94 == read_data[1] && 0x1A == read_data[2]){
+ LCD_PRINT("hx8394a success!\n");
+ return 0x8394;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t hx8394a_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_hx8394a_mipi read power mode!\n");
+ mipi_eotp_set(0,0);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ pr_debug("lcd_hx8389b mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x1c == read_data[0])){
+ //printk("lcd_hx8389b_mipi read power mode success!\n");
+ mipi_eotp_set(0,0);
+ return 0x1c;
+ }
+ }
+
+ printk("lcd_hx8394a mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(0,0);
+ return 0x0;
+}
+
+static int32_t hx8394a_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("hx8394a_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+#endif
+ power_mode = hx8394a_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+#endif
+ if(power_mode == 0x1c){
+ pr_debug("hx8394a_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("hx8394a_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_hx8394a_mipi_operations = {
+ .panel_init = hx8394a_mipi_init,
+ .panel_readid = hx8394a_readid,
+ .panel_esd_check = hx8394a_check_esd,
+};
+
+static struct timing_rgb lcd_hx8394a_mipi_timing = {
+ .hfp = 80, /* unit: pixel */
+ .hbp = 60,
+ .hsync = 60,
+ .vfp = 38, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_hx8394a_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq = 450*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_hx8394a_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_hx8394a_mipi_spec = {
+ .width = 720,
+ .height = 1280,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8394a_mipi_info
+ },
+ .ops = &lcd_hx8394a_mipi_operations,
+};
+
+struct panel_cfg lcd_hx8394a_mipi = {
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8394,
+ .lcd_name = "lcd_hx8394a_mipi",
+ .panel = &lcd_hx8394a_mipi_spec,
+};
+
+static int __init lcd_hx8394a_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8394a_mipi);
+}
+
+subsys_initcall(lcd_hx8394a_mipi_init);
+
+
diff --git a/drivers/video/sprdfb/lcd/lcd_hx8394d_mipi.c b/drivers/video/sprdfb/lcd/lcd_hx8394d_mipi.c
new file mode 100644
index 00000000..9643cf60
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_hx8394d_mipi.c
@@ -0,0 +1,430 @@
+/* drivers/video/sprdfb/lcd_hx8394d_mipi.c
+ *
+ * Support for hx8394d mipi LCD device
+ *
+ * Copyright (C) 2014 Spreadtrum
+ * Author: Haibing.Yang <haibing.yang@spreadtrum.com>
+ *
+ * The panel info is got from raolihua@trulyopto.cn
+ * Panel: 5.0HD(720*1280) LG LTPS
+ * Driver IC: HX8394D
+ * Interface: MIPI 4LANES
+ * Test condition: IOVCC=VCC=2.8V
+ * DATE: 20150105
+ * Version: 1.0
+ *
+ * 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.
+ */
+
+
+#define pr_fmt(fmt) "sprdfb_hx8394b: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+
+#include "../sprdfb_panel.h"
+
+#define MAX_DATA 100
+#define DATA_TYPE_SET_RX_PKT_SIZE 0x37
+#define PANEL_READ_CNT 3
+
+#define PANEL_ID_LENGTH 3
+#define PANEL_RETURN_ID 0x8394
+#define PANEL_ACTUAL_ID 0x8394
+#define PANEL_ID_REG 0x04
+#define PANEL_ID_OFFSET 0
+
+#define PANEL_POWER_MODE_REG 0x0A
+#define PANEL_POWER_MODE_LEN 2
+#define PANEL_NOT_DEAD_STS 0x1C
+#define PANEL_POWER_MODE_OFFSET 1
+
+#define LCM_TAG_SHIFT 24
+#define LCM_DATA_TYPE_SHIFT 16
+#define LCM_TAG_MASK ((1 << LCM_DATA_TYPE_SHIFT) - 1)
+
+#define LCM_TAG_SEND (1 << LCM_TAG_SHIFT)
+#define LCM_TAG_SLEEP (2 << LCM_TAG_SHIFT)
+
+#define LCM_SEND(len) (LCM_TAG_SEND | len)
+#define LCM_SEND_WITH_TYPE(len, type) \
+ (LCM_TAG_SEND | len | (type << LCM_DATA_TYPE_SHIFT))
+#define LCM_SLEEP(ms) (LCM_TAG_SLEEP | ms)
+
+struct panel_cmds {
+ u32 tag;
+ u8 data[MAX_DATA];
+};
+
+static struct panel_cmds hx8394d_init_cmds[] = {
+ {
+ LCM_SEND(06), {04, 0,
+ 0xB9, 0xFF, 0x83, 0x94}
+ },
+ {
+ LCM_SEND(05), {03, 0,
+ 0xBA,0x33,0x83}
+ },
+ { /* Set power */
+ LCM_SEND(20), {18, 0,
+ 0xB1, 0x6C, 0x12, 0x12, 0x26, 0x04, 0x11, 0xF1,
+ 0x81, 0x3A, 0x54, 0x23, 0x80, 0xC0, 0xD2, 0x58}
+ },
+ { /* Set display related register */
+ LCM_SEND(14), {12, 0,
+ 0xB2, 0x00, 0x64, 0x0E, 0x0D, 0x22, 0x1C, 0x08,
+ 0x08, 0x1C, 0x4D, 0x00}
+ },
+ { /* Set panel driving timing */
+ LCM_SEND(15), {13, 0,
+ 0xB4, 0x00, 0xFF, 0x51, 0x5A, 0x59, 0x5A, 0x03,
+ 0x5A, 0x01, 0x70, 0x01, 0x70}
+ },
+ {LCM_SEND(2), {0xBC, 0x07}},
+ {
+ LCM_SEND(06), {04, 0,
+ 0xBF, 0x41, 0x0E, 0x01}
+ },
+ { /* Set GIP */
+ LCM_SEND(40), {38, 0,
+ 0xD3, 0x00, 0x0F, 0x00, 0x40, 0x07, 0x10, 0x00,
+ 0x08, 0x10, 0x08, 0x00, 0x08, 0x54, 0x15, 0x0E,
+ 0x05, 0x0E, 0x02, 0x15, 0x06, 0x05, 0x06, 0x47,
+ 0x44, 0x0A, 0x0A, 0x4B, 0x10, 0x07, 0x07, 0x08,
+ 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01}
+ },
+ { /* Set GIP */
+ LCM_SEND(47), {45, 0,
+ 0xD5, 0x1A, 0x1A, 0x1B, 0x1B, 0x00, 0x01, 0x02,
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x24, 0x25, 0x18, 0x18, 0x26, 0x27, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20,
+ 0x21, 0x18, 0x18, 0x18, 0x18}
+ },
+ { /* Set GIP */
+ LCM_SEND(47), {45, 0,
+ 0xD6, 0x1A, 0x1A, 0x1B, 0x1B, 0x0B, 0x0A, 0x09,
+ 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
+ 0x00, 0x21, 0x20, 0x58, 0x58, 0x27, 0x26, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x25,
+ 0x24, 0x18, 0x18, 0x18, 0x18}
+ },
+ /* SETPANEL CCh: can set normally-white/black panel */
+ {LCM_SEND(2), {0xCC, 0x09}},
+ {
+ LCM_SEND(5), {3, 0,
+ 0xC0, 0x30, 0x14}
+ },
+ {
+ LCM_SEND(7), {5, 0,
+ 0xC7, 0x00, 0xC0, 0x40, 0xC0}
+ },
+ {
+ LCM_SEND(5), {3, 0,
+ 0xB6, 0x6B, 0x6B}
+ },
+ { /* Analog gamma setting */
+ LCM_SEND(45), {43, 0,
+ 0xE0, 0x00, 0x0A, 0x0F, 0x24, 0x3A, 0x3F, 0x20,
+ 0x3B, 0x08, 0x0D, 0x0E, 0x16, 0x0F, 0x12, 0x15,
+ 0x13, 0x15, 0x09, 0x12, 0x12, 0x18, 0x00, 0x0A,
+ 0x0F, 0x24, 0x3A, 0x3F, 0x20, 0x3B, 0x08, 0x0D,
+ 0x0E, 0x16, 0x0F, 0x12, 0x15, 0x13, 0x15, 0x09,
+ 0x12, 0x12, 0x18}
+ },
+
+ {LCM_SEND(2), {0xBD, 0x00}}, /* BANK: RED */
+ {
+ LCM_SEND(46), {44, 0,
+ 0xC1, 0x01, 0x00, 0x06, 0x0C, 0x14, 0x1D, 0x27,
+ 0x2F, 0x38, 0x41, 0x49, 0x51, 0x59, 0x61, 0x69,
+ 0x71, 0x79, 0x81, 0x89, 0x91, 0x99, 0xA1, 0xA9,
+ 0xB2, 0xB9, 0xC1, 0xCA, 0xD1, 0xD8, 0xE2, 0xEA,
+ 0xF0, 0xF7, 0xFF, 0x38, 0xFC, 0x3F, 0x0B, 0xC1,
+ 0x13, 0xF1, 0x0D, 0xC0}
+ },
+ {LCM_SEND(2), {0xBD, 0x01}}, /* BANK: GREEN */
+ {
+ LCM_SEND(45), {43, 0,
+ 0xC1, 0x00, 0x06, 0x0C, 0x14, 0x1D, 0x27, 0x2F,
+ 0x38, 0x41, 0x49, 0x51, 0x59, 0x61, 0x69, 0x71,
+ 0x79, 0x81, 0x89, 0x91, 0x99, 0xA1, 0xA9, 0xB2,
+ 0xB9, 0xC1, 0xCA, 0xD1, 0xD8, 0xE2, 0xEA, 0xF0,
+ 0xF7, 0xFF, 0x38, 0xFC, 0x3F, 0x0B, 0xC1, 0x13,
+ 0xF1, 0x0D, 0xC0}
+ },
+ {LCM_SEND(2), {0xBD, 0x02}}, /* BANK: BLUE */
+ {
+ LCM_SEND(45), {43, 0,
+ 0xC1, 0x00, 0x06, 0x0C, 0x14, 0x1D, 0x27, 0x2F,
+ 0x38, 0x41, 0x49, 0x51, 0x59, 0x61, 0x69, 0x71,
+ 0x79, 0x81, 0x89, 0x91, 0x99, 0xA1, 0xA9, 0xB2,
+ 0xB9, 0xC1, 0xCA, 0xD1, 0xD8, 0xE2, 0xEA, 0xF0,
+ 0xF7, 0xFF, 0x38, 0xFC, 0x3F, 0x0B, 0xC1, 0x13,
+ 0xF1, 0x0D, 0xC0}
+ },
+
+ /* Set_address_mode (36h): RGB order and source/gate dir */
+ {LCM_SEND(2), {0x36, 0x03}},
+
+ /* sleep out */
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(10)},
+};
+
+static struct panel_cmds sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(120)},
+};
+
+static struct panel_cmds sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(10)},
+};
+
+int sprdfb_dsi_tx_cmds(struct panel_spec *panel,
+ struct panel_cmds *cmds, u32 cmds_len, bool force_lp)
+{
+ int i, time;
+ struct ops_mipi *ops = panel->info.mipi->ops;
+ u16 work_mode = panel->info.mipi->work_mode;
+ u8 write_type = (cmds->tag >> 16) & 0xff;
+
+ pr_info("%s, len: %d\n", __func__, cmds_len);
+
+ if (!ops->mipi_set_cmd_mode ||
+ !ops->mipi_dcs_write ||
+ !ops->mipi_set_hs_mode ||
+ !ops->mipi_set_lp_mode ||
+ !ops->mipi_force_write) {
+ pr_err("%s: Expected functions are NULL.\n", __func__);
+ return -EFAULT;
+ }
+ if (force_lp) {
+ if (work_mode == SPRDFB_MIPI_MODE_CMD)
+ ops->mipi_set_lp_mode();
+ else
+ ops->mipi_set_data_lp_mode();
+ }
+
+ ops->mipi_set_cmd_mode();
+
+ for (i = 0; i < cmds_len; i++) {
+ if (cmds->tag & LCM_TAG_SEND) {
+ if (write_type)
+ ops->mipi_force_write(write_type, cmds->data,
+ cmds->tag & LCM_TAG_MASK);
+ else
+ ops->mipi_dcs_write(cmds->data, cmds->tag & LCM_TAG_MASK);
+ udelay(20);
+ } else if (cmds->tag & LCM_TAG_SLEEP) {
+ time = (cmds->tag & LCM_TAG_MASK) * 1000;
+ usleep_range(time, time);
+ }
+ cmds++;
+ }
+
+ if (force_lp) {
+ if (work_mode == SPRDFB_MIPI_MODE_CMD)
+ ops->mipi_set_hs_mode();
+ else
+ ops->mipi_set_data_hs_mode();
+ }
+ return 0;
+}
+
+int sprdfb_dsi_rx_cmds(struct panel_spec *panel,
+ u8 regs, u16 get_len, u8 *data, bool in_bllp)
+{
+ int ret;
+ struct ops_mipi *ops = panel->info.mipi->ops;
+ u8 pkt_size[2];
+ u16 work_mode = panel->info.mipi->work_mode;
+
+ pr_debug("%s, read data len: %d\n", __func__, get_len);
+ if (!data) {
+ pr_err("Expected registers or data is NULL.\n");
+ return -EIO;
+ }
+ if (!ops->mipi_set_cmd_mode ||
+ !ops->mipi_force_read ||
+ !ops->mipi_force_write) {
+ pr_err("%s: Expected functions are NULL.\n", __func__);
+ return -EFAULT;
+ }
+
+ if (!in_bllp) {
+ if (work_mode == SPRDFB_MIPI_MODE_CMD)
+ ops->mipi_set_lp_mode();
+ else
+ ops->mipi_set_data_lp_mode();
+ /*
+ * If cmds is transmitted in LP mode, not in BLLP,
+ * commands mode should be enabled
+ * */
+ ops->mipi_set_cmd_mode();
+ }
+
+ pkt_size[0] = get_len & 0xff;
+ pkt_size[1] = (get_len >> 8) & 0xff;
+
+ ops->mipi_force_write(DATA_TYPE_SET_RX_PKT_SIZE,
+ pkt_size, sizeof(pkt_size));
+
+ ret = ops->mipi_force_read(regs, get_len, data);
+ if (ret < 0) {
+ pr_err("%s: dsi read id fail\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!in_bllp) {
+ if (work_mode == SPRDFB_MIPI_MODE_CMD)
+ ops->mipi_set_hs_mode();
+ else
+ ops->mipi_set_data_hs_mode();
+ }
+
+ return 0;
+}
+
+int sprdfb_dsi_panel_sleep(struct panel_spec *panel, u8 is_sleep)
+{
+ int len;
+ struct panel_cmds *sleep_inout;
+
+ if (is_sleep) {
+ sleep_inout = sleep_in;
+ len = ARRAY_SIZE(sleep_in);
+ } else {
+ sleep_inout = sleep_out;
+ len = ARRAY_SIZE(sleep_out);
+ }
+
+ return sprdfb_dsi_tx_cmds(panel, sleep_inout, len, false);
+}
+
+u32 sprdfb_dsi_panel_readid(struct panel_spec *panel)
+{
+ int i, cnt = PANEL_READ_CNT;
+ u8 regs = PANEL_ID_REG;
+ u8 data[PANEL_ID_LENGTH] = { 0 };
+ u8 id[PANEL_ID_LENGTH] = { 0 };
+
+ i = PANEL_ID_OFFSET;
+ id[i++] = (PANEL_RETURN_ID >> 8) & 0xFF;
+ id[i] = PANEL_RETURN_ID & 0xFF;
+ do {
+ sprdfb_dsi_rx_cmds(panel, regs, PANEL_ID_LENGTH, data, true);
+ i = PANEL_ID_OFFSET;
+ pr_debug("%s: reading panel id(0x%2x) is 0x%x, 0x%x",
+ __func__, regs, data[i], data[i+1]);
+ if (data[i] == id[i] && data[i + 1] == id[i + 1])
+ return PANEL_ACTUAL_ID;
+ } while (cnt-- > 0);
+
+ pr_err("%s: failed to read panel id, 0x%x, 0x%x.\n",
+ __func__, data[i], data[i + 1]);
+ return 0;
+}
+
+static int hx8394d_dsi_panel_dead(struct panel_spec *panel)
+{
+ int i, cnt = PANEL_READ_CNT;
+ u8 regs = PANEL_POWER_MODE_REG;
+ u8 data[PANEL_POWER_MODE_LEN] = { 0 };
+ bool in_bllp = false;
+
+#ifdef FB_CHECK_ESD_IN_VFP
+ in_bllp = true;
+#endif
+ do {
+ sprdfb_dsi_rx_cmds(panel, regs, PANEL_POWER_MODE_LEN, data, in_bllp);
+ i = PANEL_POWER_MODE_OFFSET;
+ pr_debug("%s: reading panel power mode(0x%2x) is 0x%x",
+ __func__, regs, data[i]);
+ if ((data[i] & PANEL_NOT_DEAD_STS) == PANEL_NOT_DEAD_STS)
+ return true;
+ } while (cnt-- > 0);
+
+ pr_err("panel is dead, read power mode is 0x%x.\n", data[i]);
+ return false;
+}
+
+static int hx8394d_dsi_panel_init(struct panel_spec *panel)
+{
+ return sprdfb_dsi_tx_cmds(panel, hx8394d_init_cmds,
+ ARRAY_SIZE(hx8394d_init_cmds), false);
+}
+
+static struct panel_operations lcd_hx8394d_mipi_ops = {
+ .panel_init = hx8394d_dsi_panel_init,
+ .panel_readid = sprdfb_dsi_panel_readid,
+ .panel_enter_sleep = sprdfb_dsi_panel_sleep,
+ .panel_esd_check = hx8394d_dsi_panel_dead,
+};
+
+static struct timing_rgb lcd_hx8394d_mipi_timing = {
+ .hfp = 16, /* unit: pixel */
+ .hbp = 16,
+ .hsync = 10,
+ .vfp = 12, /*unit: line */
+ .vbp = 15,
+ .vsync = 4,
+};
+
+static struct info_mipi lcd_hx8394d_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24,
+ .lan_number = 4,
+ .phy_feq = 430000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_POS,
+ .shut_down_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_hx8394d_mipi_timing,
+ .ops = NULL,
+};
+
+static struct panel_spec lcd_hx8394d_mipi_spec = {
+ .width = 720,
+ .height = 1280,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_hx8394d_mipi_info
+ },
+ .ops = &lcd_hx8394d_mipi_ops,
+};
+
+static struct panel_cfg lcd_hx8394d_mipi = {
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = PANEL_ACTUAL_ID,
+ .lcd_name = "lcd_hx8394d_mipi",
+ .panel = &lcd_hx8394d_mipi_spec,
+};
+
+static int __init lcd_hx8394d_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_hx8394d_mipi);
+}
+subsys_initcall(lcd_hx8394d_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_ili6150_lvds.c b/drivers/video/sprdfb/lcd/lcd_ili6150_lvds.c
new file mode 100644
index 00000000..b6d5b12c
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili6150_lvds.c
@@ -0,0 +1,81 @@
+/*
+ * drivers/video/sprdfb/lcd/lcd_ili6150_lvds.c
+ *
+ * Copyright (C) 2014 Spreadtrum Communications Inc.
+ *
+ * Author: Haibing.Yang <haibing.yang@spreadtrum.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 "../sprdfb.h"
+#include "../sprdfb_panel.h"
+
+static uint32_t ili6150_lvds_readid(struct panel_spec *self)
+{
+ return 0x1806;
+}
+
+static struct panel_operations ili6150_lvds_ops = {
+ .panel_init = sprdchip_lvds_init,
+ .panel_readid = ili6150_lvds_readid,
+};
+
+static struct timing_rgb ili6150_lvds_timing = {
+ .hfp = 150, /* unit: pixel */
+ .hbp = 150,
+ .hsync = 1,//4
+ .vfp = 16, /*unit: line*/
+ .vbp = 16,
+ .vsync = 1,
+};
+
+static struct info_rgb ili6150_lvds_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_LVDS,
+ .video_bus_width = 24, /*18,16*/
+#if 0
+ .h_sync_pol = SPRDFB_POLARITY_NEG,
+ .v_sync_pol = SPRDFB_POLARITY_NEG,
+ .de_pol = SPRDFB_POLARITY_POS,
+#endif
+ .timing = &ili6150_lvds_timing,
+ .bus_info = {
+ .spi = NULL,
+ }
+};
+
+static struct panel_spec ili6150_lvds_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 1024,
+ .height = 600,
+ .fps = 60,
+ .type = SPRDFB_PANEL_TYPE_LVDS,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .rgb = &ili6150_lvds_info
+ },
+ .ops = &ili6150_lvds_ops,
+};
+
+struct panel_cfg lcd_ili6150_lvds = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x1806,
+ .lcd_name = "lcd_ili6150_lvds",
+ .panel = &ili6150_lvds_spec,
+};
+
+static int __init lcd_ili6150_lvds_init(void)
+{
+ return sprdfb_panel_register(&lcd_ili6150_lvds);
+}
+
+subsys_initcall(lcd_ili6150_lvds_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9341.c b/drivers/video/sprdfb/lcd/lcd_ili9341.c
new file mode 100644
index 00000000..c857c4bc
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9341.c
@@ -0,0 +1,428 @@
+/* drivers/video/sc8810/lcd_ili9341.c
+ *
+ * Support for ili9341 LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+static int32_t ili9341_init(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("ili9341_init\n");
+
+ //Power Setting
+ send_cmd(0xCF);
+ send_data(0x00);
+ send_data(0xE1);
+ send_data(0x30);
+
+ send_cmd(0xED);
+ send_data(0x64);
+ send_data(0x03);
+ send_data(0x12);
+ send_data(0x81);
+
+ send_cmd(0xCB);
+ send_data(0x39);
+ send_data(0x2C);
+ send_data(0x00);
+ send_data(0x34);
+ send_data(0x02);
+
+ send_cmd(0xF7);
+ send_data(0x20);
+
+ send_cmd(0xEA);
+ send_data(0x00);
+ send_data(0x00);
+
+ send_cmd(0xC5);
+ send_data(0x4C);
+ send_data(0x2B);
+
+ send_cmd(0xC7);
+ send_data(0x00);
+
+ send_cmd(0xC0);
+ send_data(0x22);
+
+ send_cmd(0xC1);
+ send_data(0x11);
+
+ //Initializing Sequence
+ send_cmd(0x35);
+ send_data(0x00);
+
+ send_cmd(0x36);
+ send_data(0x08);
+
+ send_cmd(0x3A);
+ send_data(0x05);
+
+ send_cmd(0xF2);
+ send_data(0x02);
+
+ send_cmd(0xB6);
+ send_data(0x01);
+ send_data(0xC2);
+
+ send_cmd(0xF6);
+ send_data(0x01);
+ send_data(0x10);
+ send_data(0x00);
+
+ send_cmd(0xB1);
+ send_data(0x00);
+ send_data(0x1A);
+
+ send_cmd(0xB5);
+ send_data(0x02);
+ send_data(0x02);
+ send_data(0x0A);
+ send_data(0x14);
+
+ send_cmd(0xE8);
+ send_data(0x85);
+ send_data(0x01);
+ send_data(0x78);
+
+ //Gamma Setting
+ send_cmd(0xE0);
+ send_data(0x0F);
+ send_data(0x31);
+ send_data(0x2F);
+ send_data(0x0D);
+ send_data(0x10);
+ send_data(0x08);
+ send_data(0x5F);
+ send_data(0xB6);
+ send_data(0x50);
+ send_data(0x07);
+ send_data(0x14);
+ send_data(0x07);
+ send_data(0x2A);
+ send_data(0x1F);
+ send_data(0x08);
+
+ send_cmd(0xE1);
+ send_data(0x00);
+ send_data(0x0E);
+ send_data(0x10);
+ send_data(0x04);
+ send_data(0x10);
+ send_data(0x04);
+ send_data(0x23);
+ send_data(0x54);
+ send_data(0x35);
+ send_data(0x03);
+ send_data(0x0B);
+ send_data(0x09);
+ send_data(0x20);
+ send_data(0x2A);
+ send_data(0x08);
+
+ send_cmd(0xE2);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+
+ send_cmd(0xE3);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x22);
+ send_data(0x22);
+ send_data(0x22);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x33);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x03);
+ send_data(0x02);
+ send_data(0x01);
+ send_data(0x00);
+#if 1
+ //Display on
+ send_cmd(0x11); // (SLPOUT)
+ mdelay(10); // 100ms
+ send_cmd(0x29); // (DISPON)
+ mdelay(10); // 100ms
+ pr_debug("ili9341_init: end\n");
+
+ return 0;
+#else
+ if (1) { // for test the lcd
+ int i;
+ send_cmd(0x2C); //Write data
+ for (i = 0; i < 240*320/3; i++)
+ send_data(0xff);
+ for (i = 0; i < 240*320/3; i++)
+ send_data(0xff00);
+ for (i = 0; i < 24*320/3; i++)
+ send_data(0xff0000);
+ }
+ send_cmd(0x11); //Display On
+ mdelay(10); //120ms
+ send_cmd(0x29); //Write data
+ mdelay(10); //120ms
+#endif
+ pr_debug("ili9341_init: end\n");
+
+ return 0;
+}
+
+static int32_t ili9341_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("ili9341_set_window\n");
+
+ send_cmd(0x2A); // col
+ send_data((left >> 8));
+ send_data((left & 0xFF));
+ send_data((right >> 8));
+ send_data((right & 0xFF));
+
+ send_cmd(0x2B); // row
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+ send_data((bottom >> 8));
+ send_data((bottom & 0xFF));
+
+ send_cmd(0x2C);
+
+ return 0;
+}
+
+
+static int32_t ili9341_invalidate(struct panel_spec *self)
+{
+ pr_debug("ili9341_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width-1, self->height-1);
+}
+
+static int32_t ili9341_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+
+ pr_debug("ili9341_invalidate_rect : (%d, %d, %d, %d)\n",left, top, right, bottom);
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t ili9341_set_direction(struct panel_spec *self, uint16_t direction)
+{
+
+ pr_debug("ili9341_set_direction\n");
+ return 0;
+}
+
+static int32_t ili9341_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ //send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+
+ if(is_sleep) {
+ //send_cmd(0x10);
+ mdelay(120);
+ }
+ else {
+ //send_cmd(0x11);
+ mdelay(120);
+ }
+ return 0;
+}
+
+static uint32_t ili9341_read_id(struct panel_spec *self)
+{
+ int32_t read_value = 0;
+#if 0
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+
+ send_cmd(0x04);
+
+ read_data();
+ read_value += read_data()<< 16;
+ read_value += read_data()<< 8;
+ read_value += read_data();
+#endif
+ pr_debug("ili9341_read_id=%x\n",read_value);
+
+ read_value = 0x9341;
+
+ return read_value;
+}
+
+static int32_t ili9341_change_epf(struct panel_spec *self, bool is_default)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ return 0;
+
+ if(is_default){
+ send_cmd(0xF6);
+ send_data(0x01);
+ send_data(0x30);
+ send_data(0x00);
+ }else{
+ send_cmd(0xF6);
+ send_data(0x01);
+ send_data(0x10);
+ send_data(0x00);
+ }
+
+ return 0;
+}
+
+static struct panel_operations lcd_ili9341_operations = {
+ .panel_init = ili9341_init,
+ .panel_set_window = ili9341_set_window,
+ .panel_invalidate = ili9341_invalidate,
+ //.lcd_invalidate_rect = ili9341_invalidate_rect,
+ .panel_set_direction = ili9341_set_direction,
+ .panel_enter_sleep = ili9341_enter_sleep,
+ .panel_readid = ili9341_read_id,
+ .panel_change_epf = ili9341_change_epf,
+};
+
+static struct timing_mcu lcd_ili9341_timing[] = {
+ [MCU_LCD_REGISTER_TIMING] = {
+ .rcss = 25,
+ .rlpw = 45,
+ .rhpw = 90,
+ .wcss = 30,
+ .wlpw = 20,
+ .whpw = 20,
+ },
+ [MCU_LCD_GRAM_TIMING] = {
+ .rcss = 25,
+ .rlpw = 45,
+ .rhpw = 90,
+ .wcss = 30,
+ .wlpw = 20,
+ .whpw = 20,
+ }
+};
+
+static struct info_mcu lcd_ili9341_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 16,
+ .bpp = 16, /*RGB88*/
+ .timing = &lcd_ili9341_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_panel_ili9341 = {
+ .width = 240,
+ .height = 320,
+ .fps = 60,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_ili9341_info
+ },
+ .ops = &lcd_ili9341_operations,
+};
+
+struct panel_cfg lcd_ili9341 = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x9341,
+ .lcd_name = "lcd_ili9341",
+ .panel = &lcd_panel_ili9341,
+};
+
+static int __init lcd_ili9341_init(void)
+{
+ printk(KERN_INFO "sprdfb_111: [%s]: 0x%x!\n", __FUNCTION__,lcd_ili9341.lcd_id);
+
+ return sprdfb_panel_register(&lcd_ili9341);
+}
+
+subsys_initcall(lcd_ili9341_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9486.c b/drivers/video/sprdfb/lcd/lcd_ili9486.c
new file mode 100644
index 00000000..885e8f76
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9486.c
@@ -0,0 +1,434 @@
+/* drivers/video/sc8810/lcd_ili9486.c
+ *
+ * Support for ili9486 LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+static int32_t ili9486_init(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("ili9486_init\n");
+#if 0
+ // Hidden register setting
+ send_cmd(0xF9);
+ send_data(0x00);
+ send_data(0x08);
+
+ send_cmd(0xF2);
+ send_data(0x18);
+ send_data(0xA3);
+ send_data(0x02);
+ send_data(0x02);
+ send_data(0xB2);
+ send_data(0x12);
+ send_data(0xFF);
+ send_data(0x10);
+ send_data(0x00);
+
+ send_cmd(0xF1);
+ send_data(0x36);
+ send_data(0x04);
+ send_data(0x00);
+ send_data(0x3C);
+ send_data(0x0F);
+ send_data(0x8F);
+#endif
+ //Power setting sequence
+ send_cmd(0xC0);
+ send_data(0x0B);
+ send_data(0x0B);
+
+ send_cmd(0xC1);
+ send_data(0x45);
+
+ send_cmd(0xC2);
+ send_data(0x22);
+
+ mdelay(150); // 150ms
+
+ //Display parameter setting
+ send_cmd(0x2A);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x01);
+ send_data(0x3F);
+
+ send_cmd(0x2B);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x01);
+ send_data(0xDF);
+
+ send_cmd(0xB1);
+ send_data(0xB0);
+ send_data(0x12);//11: 67hz, 12:63.5hz
+
+ send_cmd(0xB4);
+ send_data(0x02);
+
+ send_cmd(0xB5);
+ send_data(0x08);
+ send_data(0x0C);
+ send_data(0x10);
+ send_data(0x0A);
+
+ send_cmd(0xB6);
+ send_data(0x02);
+ send_data(0x22);//0x42
+ send_data(0x3B);
+
+ send_cmd(0xB7);
+ send_data(0xC6);
+
+ send_cmd(0xF2);
+ send_data(0x18);
+ send_data(0xA3);
+ send_data(0x12);
+ send_data(0x02);
+ send_data(0xB2);
+ send_data(0x12);
+ send_data(0xFF);
+ send_data(0x10);
+ send_data(0x00);
+
+ send_cmd(0xF4);
+ send_data(0x00);
+ send_data(0x00);
+ send_data(0x08);
+ send_data(0x91);
+ send_data(0x04);
+
+ send_cmd(0x3A);
+ send_data(0x06);
+
+ send_cmd(0x35);
+
+ send_cmd(0x36);
+ send_data(0xD8);//0xC8
+
+ send_cmd(0x44);
+ send_data(0x01);
+ send_data(0xD5);
+
+ //Gamma setting
+ send_cmd(0xF8);
+ send_data(0x21);
+ send_data(0x06);
+
+ send_cmd(0xE0);
+ send_data(0x0F);
+ send_data(0x18);
+ send_data(0x13);
+ send_data(0x08);
+ send_data(0x0B);
+ send_data(0x07);
+ send_data(0x4A);
+ send_data(0xA7);
+ send_data(0x3A);
+ send_data(0x0C);
+ send_data(0x16);
+ send_data(0x07);
+ send_data(0x09);
+ send_data(0x06);
+ send_data(0x00);
+
+ send_cmd(0xE1);
+ send_data(0x0F);
+ send_data(0x34);
+ send_data(0x31);
+ send_data(0x09);
+ send_data(0x0B);
+ send_data(0x02);
+ send_data(0x41);
+ send_data(0x53);
+ send_data(0x30);
+ send_data(0x04);
+ send_data(0x0F);
+ send_data(0x02);
+ send_data(0x17);
+ send_data(0x14);
+ send_data(0x00);
+
+ send_cmd(0xE2);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x1A);
+ send_data(0x1A);
+ send_data(0x1A);
+ send_data(0x1A);
+ send_data(0x1A);
+ send_data(0x1A);
+ send_data(0x19);
+ send_data(0x19);
+ send_data(0x09);
+ send_data(0x09);
+
+ send_cmd(0xE3);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x04);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x24);
+ send_data(0x25);
+ send_data(0x3D);
+ send_data(0x4D);
+ send_data(0x4D);
+ send_data(0x4D);
+ send_data(0x4C);
+ send_data(0x7C);
+ send_data(0x6D);
+ send_data(0x6D);
+ send_data(0x7D);
+ send_data(0x6D);
+ send_data(0x6E);
+ send_data(0x6D);
+ send_data(0x6D);
+ send_data(0x6D);
+ send_data(0x6D);
+ send_data(0x6D);
+ send_data(0x5C);
+ send_data(0x5C);
+ send_data(0x5C);
+ send_data(0x6B);
+ send_data(0x6B);
+ send_data(0x6A);
+ send_data(0x5B);
+ send_data(0x5B);
+ send_data(0x53);
+ send_data(0x53);
+ send_data(0x53);
+ send_data(0x53);
+ send_data(0x53);
+ send_data(0x53);
+ send_data(0x43);
+ send_data(0x33);
+ send_data(0xB4);
+ send_data(0x94);
+ send_data(0x74);
+ send_data(0x64);
+ send_data(0x64);
+ send_data(0x43);
+ send_data(0x13);
+ send_data(0x24);
+#if 1
+ //Display on
+ send_cmd(0x11); // (SLPOUT)
+
+ mdelay(120); // 100ms
+
+ send_cmd(0x29); // (DISPON)
+
+ mdelay(100); // 100ms
+#else
+ if (1) { // for test the lcd
+ int i;
+ send_cmd(0x2C); //Write data
+ for (i = 0; i < 480*320/3; i++)
+ send_data(0xff);
+ for (i = 0; i < 480*320/3; i++)
+ send_data(0xff00);
+ for (i = 0; i < 480*320/3; i++)
+ send_data(0xff0000);
+ }
+ send_cmd(0x29); //Display On
+ mdelay(120); //120ms
+ send_cmd(0x2C); //Write data
+ mdelay(1200); //120ms
+#endif
+ pr_debug("ili9486_init: end\n");
+
+ return 0;
+}
+
+static int32_t ili9486_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("ili9486_set_window\n");
+
+ send_cmd(0x2A); // col
+ send_data((left >> 8));
+ send_data((left & 0xFF));
+ send_data((right >> 8));
+ send_data((right & 0xFF));
+
+ send_cmd(0x2B); // row
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+ send_data((bottom >> 8));
+ send_data((bottom & 0xFF));
+
+ send_cmd(0x2C);
+
+ return 0;
+}
+
+
+static int32_t ili9486_invalidate(struct panel_spec *self)
+{
+ pr_debug("ili9486_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width-1, self->height-1);
+}
+
+static int32_t ili9486_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+
+ pr_debug("ili9486_invalidate_rect : (%d, %d, %d, %d)\n",left, top, right, bottom);
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t ili9486_set_direction(struct panel_spec *self, uint16_t direction)
+{
+
+ pr_debug("ili9486_set_direction\n");
+ return 0;
+}
+
+static int32_t ili9486_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ //send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+
+ if(is_sleep) {
+ //send_cmd(0x10);
+ mdelay(120);
+ }
+ else {
+ //send_cmd(0x11);
+ mdelay(120);
+ }
+ return 0;
+}
+
+static uint32_t ili9486_read_id(struct panel_spec *self)
+{
+ int32_t read_value = 0;
+#if 0
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+
+ send_cmd(0x04);
+
+ read_data();
+ read_value += read_data()<< 16;
+ read_value += read_data()<< 8;
+ read_value += read_data();
+#endif
+ pr_debug("ili9486_read_id=%x\n",read_value);
+
+ read_value = 0x9486;
+
+ return read_value;
+}
+
+static struct panel_operations lcd_ili9486_operations = {
+ .panel_init = ili9486_init,
+ .panel_set_window = ili9486_set_window,
+ .panel_invalidate = ili9486_invalidate,
+ //.lcd_invalidate_rect = ili9486_invalidate_rect,
+ .panel_set_direction = ili9486_set_direction,
+ .panel_enter_sleep = ili9486_enter_sleep,
+ .panel_readid = ili9486_read_id,
+};
+
+static struct timing_mcu lcd_ili9486_timing[] = {
+ [MCU_LCD_REGISTER_TIMING] = {
+ .rcss = 25,
+ .rlpw = 45,
+ .rhpw = 90,
+ .wcss = 30,
+ .wlpw = 20,
+ .whpw = 20,
+ },
+ [MCU_LCD_GRAM_TIMING] = {
+ .rcss = 25,
+ .rlpw = 45,
+ .rhpw = 90,
+ .wcss = 30,
+ .wlpw = 20,
+ .whpw = 20,
+ }
+};
+
+static struct info_mcu lcd_ili9486_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 18,
+ .bpp = 18, /*RGB88*/
+ .timing = &lcd_ili9486_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_panel_ili9486 = {
+ .width = 320,
+ .height = 480,
+ .fps = 60,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_ili9486_info
+ },
+ .ops = &lcd_ili9486_operations,
+};
+
+struct panel_cfg lcd_ili9486 = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x9486,
+ .lcd_name = "lcd_ili9486",
+ .panel = &lcd_panel_ili9486,
+};
+
+static int __init lcd_ili9486_init(void)
+{
+ printk(KERN_INFO "sprdfb_111: [%s]: 0x%x!\n", __FUNCTION__,lcd_ili9486.lcd_id);
+
+ return sprdfb_panel_register(&lcd_ili9486);
+}
+
+subsys_initcall(lcd_ili9486_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9486_rgb_spi.c b/drivers/video/sprdfb/lcd/lcd_ili9486_rgb_spi.c
new file mode 100644
index 00000000..1eac114c
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9486_rgb_spi.c
@@ -0,0 +1,397 @@
+/* drivers/video/sc8810/lcd_ili9486_rgb_spi.c
+ *
+ *
+ *
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+#define ili9486_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define ili9486_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+
+
+static int32_t ili9486_init(struct panel_spec *self)
+{
+ uint32_t test_data[8] = {0};
+ uint32_t left = 0;
+ uint32_t top = 0;
+ uint32_t right = 480;
+ uint32_t bottom = 854;
+ uint32_t data = 0;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+
+ printk("ili9486_init\n");
+
+ ili9486_SpiWriteCmd(0xC0);
+
+ ili9486_SpiWriteData(0x15);
+ ili9486_SpiWriteData(0x15);
+
+ ili9486_SpiWriteCmd(0xC1);
+ ili9486_SpiWriteData(0x42);
+
+ ili9486_SpiWriteCmd(0xC2);
+ ili9486_SpiWriteData(0x22);
+
+ ili9486_SpiWriteCmd(0xC5);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x3A);
+
+ //Display parameter setting
+ ili9486_SpiWriteCmd(0x2A);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x01);
+ ili9486_SpiWriteData(0x3F);
+
+ ili9486_SpiWriteCmd(0x2B);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x01);
+ ili9486_SpiWriteData(0xDF);
+
+ ili9486_SpiWriteCmd(0x36);
+ ili9486_SpiWriteData(0x08);
+
+ ili9486_SpiWriteCmd(0x35);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0x3A);
+ ili9486_SpiWriteData(0x66);
+
+ ili9486_SpiWriteCmd(0xB0);
+ ili9486_SpiWriteData(0x80);
+
+ ili9486_SpiWriteCmd(0xB4);
+ ili9486_SpiWriteData(0x02);
+
+ ili9486_SpiWriteCmd(0xB5);
+ ili9486_SpiWriteData(0x0C);
+ ili9486_SpiWriteData(0x08);
+ ili9486_SpiWriteData(0x2C);
+ ili9486_SpiWriteData(0x26);
+
+ ili9486_SpiWriteCmd(0xB6);
+ ili9486_SpiWriteData(0x20);
+ ili9486_SpiWriteData(0x42);//0x42
+ ili9486_SpiWriteData(0x3B);
+
+ ili9486_SpiWriteCmd(0xB7);
+ ili9486_SpiWriteData(0x07);
+
+ ili9486_SpiWriteCmd(0xF9);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x08);
+
+ //Gamma setting
+ ili9486_SpiWriteCmd(0xE0);
+ ili9486_SpiWriteData(0x1E);
+ ili9486_SpiWriteData(0x21);
+ ili9486_SpiWriteData(0x1F);
+ ili9486_SpiWriteData(0x0C);
+ ili9486_SpiWriteData(0x0B);
+ ili9486_SpiWriteData(0x0C);
+ ili9486_SpiWriteData(0x4E);
+ ili9486_SpiWriteData(0xB9);
+ ili9486_SpiWriteData(0x40);
+ ili9486_SpiWriteData(0x07);
+ ili9486_SpiWriteData(0x16);
+ ili9486_SpiWriteData(0x06);
+ ili9486_SpiWriteData(0x12);
+ ili9486_SpiWriteData(0x12);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0xE1);
+ ili9486_SpiWriteData(0x1F);
+ ili9486_SpiWriteData(0x2A);
+ ili9486_SpiWriteData(0x25);
+ ili9486_SpiWriteData(0x0C);
+ ili9486_SpiWriteData(0x11);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x4C);
+ ili9486_SpiWriteData(0x42);
+ ili9486_SpiWriteData(0x35);
+ ili9486_SpiWriteData(0x08);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x02);
+ ili9486_SpiWriteData(0x26);
+ ili9486_SpiWriteData(0x23);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0xF8);
+ ili9486_SpiWriteData(0x21);
+ ili9486_SpiWriteData(0x07);
+ ili9486_SpiWriteData(0x02);
+
+ ili9486_SpiWriteCmd(0xE2);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x09);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0xE3);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x04);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0xF4);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x08);
+ ili9486_SpiWriteData(0x91);
+ ili9486_SpiWriteData(0x04);
+
+ ili9486_SpiWriteCmd(0xF2);
+ ili9486_SpiWriteData(0x18);
+ ili9486_SpiWriteData(0xA3);
+ ili9486_SpiWriteData(0x12);
+ ili9486_SpiWriteData(0x02);
+ ili9486_SpiWriteData(0x82);
+ ili9486_SpiWriteData(0x32);
+ ili9486_SpiWriteData(0xFF);
+ ili9486_SpiWriteData(0x10);
+ ili9486_SpiWriteData(0x00);
+
+ ili9486_SpiWriteCmd(0xFC);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x00);
+ ili9486_SpiWriteData(0x83);
+
+ //Display on
+ ili9486_SpiWriteCmd(0x11); // (SLPOUT)
+ mdelay(120); // 100ms
+ ili9486_SpiWriteCmd(0x29); // (DISPON)
+ mdelay(10); // 100ms
+ printk("ili9486_init: end\n");
+
+ return 0;
+}
+
+static int32_t ili9486_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+
+ if(is_sleep==1){
+ //Sleep In
+ ili9486_SpiWriteCmd(0x28);
+ mdelay(120);
+ ili9486_SpiWriteCmd(0x10);
+ mdelay(10);
+ }else{
+ //Sleep Out
+ ili9486_SpiWriteCmd(0x11);
+ mdelay(120);
+ ili9486_SpiWriteCmd(0x29);
+ mdelay(10);
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t ili9486_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ uint32_t *test_data[4] = {0};
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+ return 0;
+}
+static int32_t ili9486_invalidate(struct panel_spec *self)
+{
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+static int32_t ili9486_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t ili9486_read_id(struct panel_spec *self)
+{
+ int32_t id = 0x62;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+ printk("sprdfb ili9486_read_id \n");
+ ili9486_SpiWriteCmd(0xB9); // SET password
+ ili9486_SpiWriteData(0xFF); //
+ ili9486_SpiWriteData(0x83); //
+ ili9486_SpiWriteData(0x63); //
+
+ ili9486_SpiWriteCmd(0xFE); // SET SPI READ INDEX
+ ili9486_SpiWriteData(0xF4); // GETHXID
+ ili9486_SpiWriteCmd(0xFF); // GET SPI READ
+
+ spi_read(&id);
+ id &= 0xff;
+ printk(" ili9486_read_id kernel id = %x\n",id);
+ return 0x9486;
+}
+
+static struct panel_operations lcd_ili9486_rgb_spi_operations = {
+ .panel_init = ili9486_init,
+ .panel_set_window = ili9486_set_window,
+ .panel_invalidate_rect= ili9486_invalidate_rect,
+ .panel_invalidate = ili9486_invalidate,
+ .panel_enter_sleep = ili9486_enter_sleep,
+ .panel_readid = ili9486_read_id
+};
+
+static struct timing_rgb lcd_ili9486_rgb_timing = {
+ .hfp = 30,
+ .hbp = 26,
+ .hsync = 4,
+ .vfp = 12,
+ .vbp = 8,
+ .vsync = 2,
+};
+
+static struct spi_info lcd_ili9486_rgb_spi_info = {
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_ili9486_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_SPI,
+ .video_bus_width = 18, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_NEG,
+ .v_sync_pol = SPRDFB_POLARITY_NEG,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_ili9486_rgb_timing,
+ .bus_info = {
+ .spi = &lcd_ili9486_rgb_spi_info,
+ }
+};
+
+struct panel_spec lcd_panel_ili9486_rgb_spi = {
+ .width = 320,
+ .height = 480,
+ .fps = 61,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .rgb = &lcd_ili9486_rgb_info
+ },
+ .ops = &lcd_ili9486_rgb_spi_operations,
+};
+
+struct panel_cfg lcd_ili9486_rgb_spi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x9486,
+ .lcd_name = "lcd_ili9486_rgb_spi",
+ .panel = &lcd_panel_ili9486_rgb_spi,
+};
+static int __init lcd_ili9486_rgb_spi_init(void)
+{
+ return sprdfb_panel_register(&lcd_ili9486_rgb_spi);
+}
+
+subsys_initcall(lcd_ili9486_rgb_spi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9486s1_mipi.c b/drivers/video/sprdfb/lcd/lcd_ili9486s1_mipi.c
new file mode 100644
index 00000000..b25e6390
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9486s1_mipi.c
@@ -0,0 +1,268 @@
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 100
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ //Power setting Sequence
+ {LCM_SEND(5),{3,0,0xC0,0x0A,0x0A}},
+ {LCM_SEND(2),{0xc1,0x45}},
+ {LCM_SEND(2),{0xc2, 0x00}},
+
+ //Initializing Sequence
+ {LCM_SEND(7),{5,0,0x2A,0x00,0x00,0x01,0x3F}},
+ {LCM_SEND(7),{5,0,0x2B,0x00,0x00,0x01,0xDF}},
+ {LCM_SEND(2),{0x36,0xc8}},
+ {LCM_SEND(2),{0x3A,0x66}},
+ {LCM_SEND(2),{0xB0,0x8c}},
+ {LCM_SEND(2),{0xB4,0x02}},
+ {LCM_SEND(6),{4,0,0xB6,0x32,0x22,0x3B}},
+ {LCM_SEND(2),{0xB7,0xC6}},
+ {LCM_SEND(5),{3,0,0xF9,0x00,0x08}},
+ {LCM_SEND(7),{5,0,0xF7,0xA9,0x91,0x2D,0x8A}},
+ {LCM_SEND(6),{4,0,0xF8,0x21,0x07,0x02}},
+ {LCM_SEND(11),{9,0,0xF1,0x36,0x04,0x00,0x3C,0x0F,0x0F,0x04,0x02}},
+ {LCM_SEND(12),{10,0,0xF2,0x18,0xA3,0x12,0x02,0xB2,0x12,0xFF,0x10,0x00}},
+ {LCM_SEND(6),{4,0,0xFC,0x00,0x0C,0x80}},
+ //gamma setting
+ {LCM_SEND(18),{16,0,0xE0,0x01,0x15,0x17,0x0C,0x0F,0x07,0x44,0x65,0x35,0x07,0x12,0x04,0x09,0x06,0x06}},
+ {LCM_SEND(18),{16,0,0xE1,0x0F,0x38,0x34,0x0B,0x0B,0x03,0x43,0x22,0x30,0x03,0x0E,0x03,0x21,0x1B,0x00}},
+ // 3Gamma Setting Sequence
+ {LCM_SEND(19),{17,0,0xE2,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x00}},
+ {LCM_SEND(67),{65,0,0xE3,0x00,0x00,0x00,0x00,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00}},
+
+ //Display on
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(100)},
+
+};
+
+static LCM_Init_Code disp_on[] = {
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(100)},
+};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(50)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(120)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+static int32_t ili9486s1_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel ili9486s1_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t ili9486s1_readid(struct panel_spec *self)
+{
+#if 0
+ uint8_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("ili9486s1_readid!\n");
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+
+ mipi_force_write(0x04, param, 2);
+
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcdili9486s1_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_ili9486s1_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_ili9486s1_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ if((0x55 == read_data[0])&&(0x4c == read_data[1])&&(0xc0 == read_data[2])){
+ printk("lcd_nili9486s1_mipi read id success!\n");
+ return 0x8370;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+#endif
+ return 0x8370;
+}
+
+
+
+static int32_t ili9486s1_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel nt35502_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_ili9486s1_mipi_operations = {
+ .panel_init = ili9486s1_mipi_init,
+ .panel_readid = ili9486s1_readid,
+ .panel_enter_sleep = ili9486s1_enter_sleep,
+};
+
+static struct timing_rgb lcd_ili9486s1_mipi_timing = {
+ .hfp = 30, /* unit: pixel */
+ .hbp = 26,
+ .hsync = 0,
+ .vfp = 12, /*unit: line*/
+ .vbp = 8,
+ .vsync = 1,
+};
+
+
+
+static struct info_mipi lcd_ili9486s1_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 18, /*18,16*/
+ .lan_number = 1,
+ .phy_feq =340*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_ili9486s1_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_ili9486s1_mipi_spec = {
+ .width = 320,
+ .height = 480,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_ili9486s1_mipi_info
+ },
+ .ops = &lcd_ili9486s1_mipi_operations,
+};
+struct panel_cfg lcd_ili9486s1_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8370,
+ .lcd_name = "lcd_ili9486s1_mipi",
+ .panel = &lcd_ili9486s1_mipi_spec,
+};
+
+//temp code
+static int __init lcd_ili9486s1_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_ili9486s1_mipi);
+}
+
+subsys_initcall(lcd_ili9486s1_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9806e_2_mipi.c b/drivers/video/sprdfb/lcd/lcd_ili9806e_2_mipi.c
new file mode 100644
index 00000000..e391ef26
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9806e_2_mipi.c
@@ -0,0 +1,487 @@
+/* drivers/video/sc8825/lcd_ili9806e_2_mipi.c
+ *
+ * Support for ili9806e_2 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(2), {0x08,0x10}},// output SDA
+
+ {LCM_SEND(2), {0x21,0x01}},// DE = 1 Active
+
+ {LCM_SEND(2), {0x30,0x02}},// 480 X 800 Ó¦¸ÃÉèΪ2
+ {LCM_SEND(2), {0x31,0x02}}, // 2-dot Inversion
+
+ {LCM_SEND(2), {0x50,0x78}},// VGMP
+ {LCM_SEND(2), {0x51,0x78}},// VGMN
+ {LCM_SEND(2), {0x52,0x00}}, //Flicker
+ {LCM_SEND(2), {0x53,0x77}},//Flicker
+ {LCM_SEND(2), {0x54,0x00}},//Flicker
+ {LCM_SEND(2), {0x55,0x77}},//Flicker
+
+ {LCM_SEND(2), {0x60,0x07}},// SDTI
+ {LCM_SEND(2), {0x61,0x00}},// CRTI
+ {LCM_SEND(2), {0x62,0x08}},// EQTI
+ {LCM_SEND(2), {0x63,0x00}}, // PCTI
+
+ {LCM_SEND(2), {0x40,0x10}},// VGH/VGL
+ {LCM_SEND(2), {0x41,0x33}}, // VGH/VGL
+ {LCM_SEND(2), {0x42,0x02}},// VGH/VGL
+ {LCM_SEND(2), {0x43,0x09}},// VGH/VGL
+ {LCM_SEND(2), {0x44,0x07}},// VGH/VGL
+
+//++++++++++++++++++ Gamma Setting ++++++++++++++++++//
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1
+
+ {LCM_SEND(2), {0xA0,0x00}},// Gamma 0
+ {LCM_SEND(2), {0xA1,0x04}},// Gamma 4
+ {LCM_SEND(2), {0xA2,0x0A}},// Gamma 8
+ {LCM_SEND(2), {0xA3,0x11}},// Gamma 16
+ {LCM_SEND(2), {0xA4,0x0C}},// Gamma 24
+ {LCM_SEND(2), {0xA5,0x1D}},// Gamma 52
+ {LCM_SEND(2), {0xA6,0x0D}},// Gamma 80
+ {LCM_SEND(2), {0xA7,0x07}},// Gamma 108
+ {LCM_SEND(2), {0xA8,0x05}},// Gamma 147
+ {LCM_SEND(2), {0xA9,0x0B}},// Gamma 175
+ {LCM_SEND(2), {0xAA,0x07}},// Gamma 203
+ {LCM_SEND(2), {0xAB,0x04}},// Gamma 231
+ {LCM_SEND(2), {0xAC,0x0F}},// Gamma 239
+ {LCM_SEND(2), {0xAD,0x2B}},// Gamma 247
+ {LCM_SEND(2), {0xAE,0x24}},// Gamma 251
+ {LCM_SEND(2), {0xAF,0x00}},// Gamma 255
+
+///==============Nagitive
+ {LCM_SEND(2), {0xC0,0x00}}, // Gamma 0
+ {LCM_SEND(2), {0xC1,0x04}}, // Gamma 4
+ {LCM_SEND(2), {0xC2,0x0D}}, // Gamma 8
+ {LCM_SEND(2), {0xC3,0x0E}}, // Gamma 16
+ {LCM_SEND(2), {0xC4,0x0B}}, // Gamma 24
+ {LCM_SEND(2), {0xC5,0x15}}, // Gamma 52
+ {LCM_SEND(2), {0xC6,0x07}}, // Gamma 80
+ {LCM_SEND(2), {0xC7,0x09}}, // Gamma 108
+ {LCM_SEND(2), {0xC8,0x02}}, // Gamma 147
+ {LCM_SEND(2), {0xC9,0x06}}, // Gamma 175
+ {LCM_SEND(2), {0xCA,0x05}}, // Gamma 203
+ {LCM_SEND(2), {0xCB,0x04}}, // Gamma 231
+ {LCM_SEND(2), {0xCC,0x09}}, // Gamma 239
+ {LCM_SEND(2), {0xCD,0x2C}}, // Gamma 247
+ {LCM_SEND(2), {0xCE,0x27}}, // Gamma 251
+ {LCM_SEND(2), {0xCF,0x00}}, // Gamma 255
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}}, // Change to Page 6
+
+ {LCM_SEND(2), {0x00,0x21}},
+ {LCM_SEND(2), {0x01,0x09}},
+ {LCM_SEND(2), {0x02,0x00}},
+ {LCM_SEND(2), {0x03,0x00}},
+ {LCM_SEND(2), {0x04,0x01}},
+ {LCM_SEND(2), {0x05,0x01}},
+ {LCM_SEND(2), {0x06,0x80}},
+ {LCM_SEND(2), {0x07,0x05}},
+ {LCM_SEND(2), {0x08,0x02}},
+ {LCM_SEND(2), {0x09,0x80}},
+ {LCM_SEND(2), {0x0A,0x00}},
+ {LCM_SEND(2), {0x0B,0x00}},
+ {LCM_SEND(2), {0x0C,0x0a}},
+ {LCM_SEND(2), {0x0D,0x0a}},
+ {LCM_SEND(2), {0x0E,0x00}},
+ {LCM_SEND(2), {0x0F,0x00}},
+
+ {LCM_SEND(2), {0x10,0xE0}},
+ {LCM_SEND(2), {0x11,0xE4}},
+ {LCM_SEND(2), {0x12,0x04}},
+ {LCM_SEND(2), {0x13,0x00}},
+ {LCM_SEND(2), {0x14,0x00}},
+ {LCM_SEND(2), {0x15,0xC0}},
+ {LCM_SEND(2), {0x16,0x08}},
+ {LCM_SEND(2), {0x17,0x00}},
+ {LCM_SEND(2), {0x18,0x00}},
+ {LCM_SEND(2), {0x19,0x00}},
+ {LCM_SEND(2), {0x1A,0x00}},
+ {LCM_SEND(2), {0x1B,0x00}},
+ {LCM_SEND(2), {0x1C,0x00}},
+ {LCM_SEND(2), {0x1D,0x00}},
+
+ {LCM_SEND(2), {0x20,0x01}},
+ {LCM_SEND(2), {0x21,0x23}},
+ {LCM_SEND(2), {0x22,0x45}},
+ {LCM_SEND(2), {0x23,0x67}},
+ {LCM_SEND(2), {0x24,0x01}},
+ {LCM_SEND(2), {0x25,0x23}},
+ {LCM_SEND(2), {0x26,0x45}},
+ {LCM_SEND(2), {0x27,0x67}},
+
+ {LCM_SEND(2), {0x30,0x01}},
+ {LCM_SEND(2), {0x31,0x11}},
+ {LCM_SEND(2), {0x32,0x00}},
+ {LCM_SEND(2), {0x33,0xee}},
+ {LCM_SEND(2), {0x34,0xff}},
+ {LCM_SEND(2), {0x35,0xCB}},
+ {LCM_SEND(2), {0x36,0xDA}},
+ {LCM_SEND(2), {0x37,0xAD}},
+ {LCM_SEND(2), {0x38,0xBC}},
+ {LCM_SEND(2), {0x39,0x76}},
+ {LCM_SEND(2), {0x3A,0x67}},
+ {LCM_SEND(2), {0x3B,0x22}},
+ {LCM_SEND(2), {0x3C,0x22}},
+ {LCM_SEND(2), {0x3D,0x22}},
+ {LCM_SEND(2), {0x3E,0x22}},
+ {LCM_SEND(2), {0x3F,0x22}},
+
+ {LCM_SEND(2), {0x40,0x22}},
+
+ {LCM_SEND(2), {0x52,0x10}},
+
+ {LCM_SEND(2), {0x53,0x10}},
+
+// {LCM_SEND(2), {0x58,0x97}},
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}}, // Change to Page 7
+ {LCM_SEND(2), {0x17,0x22}},
+
+ {LCM_SEND(2), {0x02,0x77}},
+
+ {LCM_SEND(2), {0xe1,0x79}},
+ {LCM_SEND(2), {0x26,0xB2}},
+ //{LCM_SEND(2), {0x06,0x13}},
+
+//****************************************************************************//
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}}, // Change to Page 0
+
+ {LCM_SEND(2), {0x35,0x00}},
+ {LCM_SEND(2), {0x55,0xB0}},
+
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)},
+ };
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(20)},
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(120)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(8), {0x6, 0, 0xFF, 0xFF, 0x98, 0x06,0x04,0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t ili9806e_2_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug(KERN_DEBUG "ili9806e_2_mipi_init\n");
+
+ msleep(2);
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((init->tag & LCM_TAG_MASK) * 1000);
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t ili9806e_2_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_ili9806e_2_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x02, 3,(uint8_t *)read_data);
+ printk("lcd_ili9806e_2_mipi read id 0xc5 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if((0x04 == read_data[0])){
+ printk("lcd_ili9806e_2_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x980602;
+ }
+ }
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t ili9806e_2_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "ili9806e_2_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((sleep_in_out->tag & LCM_TAG_MASK) * 1000);
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t ili9806e_2_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ uint32_t reg_val_1 = 0;
+ uint32_t reg_val_2 = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_ili9806e_2_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_ili9806e_2 mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_ili9806e_2_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+
+static uint32_t ili9806e_2_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ pr_debug("ili9806e_2_check_esd!\n");
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = ili9806e_2_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("ili9806e_2_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("ili9806e_2_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static uint32_t ili9806e_2_mipi_after_suspend(struct panel_spec *self)
+{
+ return 0;
+}
+
+static struct panel_operations lcd_ili9806e_2_mipi_operations = {
+ .panel_init = ili9806e_2_mipi_init,
+ .panel_readid = ili9806e_2_readid,
+ .panel_enter_sleep = ili9806e_2_enter_sleep,
+ .panel_esd_check = ili9806e_2_check_esd,
+ .panel_after_suspend = ili9806e_2_mipi_after_suspend,
+};
+
+static struct timing_rgb lcd_ili9806e_2_mipi_timing = {
+ .hfp = 80, //60 /* unit: pixel */// 100
+ .hbp = 80,//80
+ .hsync = 10,//60
+ .vfp = 20, /*unit: line*/
+ .vbp = 16, //14
+ .vsync =4, //6,
+};
+
+static struct info_mipi lcd_ili9806e_2_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 400*1000, //500->10MHz,400->8M in lp mode
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_ili9806e_2_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_ili9806e_2_mipi_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 480,
+ .height = 800,
+ .fps = 59,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .reset_timing = {5, 15, 120},
+ .info = {
+ .mipi = &lcd_ili9806e_2_mipi_info
+ },
+ .ops = &lcd_ili9806e_2_mipi_operations,
+};
+
+struct panel_cfg lcd_ili9806e_2_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x980602,
+ .lcd_name = "lcd_ili9806e_2_mipi",
+ .panel = &lcd_ili9806e_2_mipi_spec,
+};
+
+static int __init lcd_ili9806e_2_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_ili9806e_2_mipi);
+}
+
+subsys_initcall(lcd_ili9806e_2_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_ili9806e_mipi.c b/drivers/video/sprdfb/lcd/lcd_ili9806e_mipi.c
new file mode 100644
index 00000000..075c7058
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ili9806e_mipi.c
@@ -0,0 +1,632 @@
+/* drivers/video/sc8825/lcd_ili9806e_mipi.c
+ *
+ * Support for ili9806e mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+#if 0 /*For SS*/
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(2), {0x08,0x10}},
+
+ {LCM_SEND(2), {0x21,0x01}},
+
+ {LCM_SEND(2), {0x30,0x02}},
+ {LCM_SEND(2), {0x31,0x00}}, //0x02
+
+ {LCM_SEND(2), {0x60,0x07}},
+ {LCM_SEND(2), {0x61,0x06}},
+ {LCM_SEND(2), {0x62,0x06}},
+ {LCM_SEND(2), {0x63,0x04}},
+
+ {LCM_SEND(2), {0x40,0x14}},
+ {LCM_SEND(2), {0x41,0x44}},//22
+ {LCM_SEND(2), {0x42,0x01}},
+ {LCM_SEND(2), {0x43,0x89}},
+ {LCM_SEND(2), {0x44,0x89}},
+ {LCM_SEND(2), {0x45,0x1b}},
+ {LCM_SEND(2), {0x46,0x44}},
+ {LCM_SEND(2), {0x47,0x44}},
+
+ {LCM_SEND(2), {0x50,0x85}},
+ {LCM_SEND(2), {0x51,0x85}},
+ {LCM_SEND(2), {0x52,0x00}},
+ {LCM_SEND(2), {0x53,0x64}},//90
+
+ //{LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+
+ {LCM_SEND(2), {0xA0,0x00}},
+ {LCM_SEND(2), {0xA1,0x00}},//01
+ {LCM_SEND(2), {0xA2,0x03}},//08
+ {LCM_SEND(2), {0xA3,0x0e}},//0e
+ {LCM_SEND(2), {0xA4,0x08}},//08
+ {LCM_SEND(2), {0xA5,0x1f}},//19
+ {LCM_SEND(2), {0xA6,0x0f}},//0b
+ {LCM_SEND(2), {0xA7,0x0b}},//0a
+ {LCM_SEND(2), {0xA8,0x03}},//02
+ {LCM_SEND(2), {0xA9,0x06}},//08
+ {LCM_SEND(2), {0xAA,0x05}},//04
+ {LCM_SEND(2), {0xAB,0x02}},//03
+ {LCM_SEND(2), {0xAC,0x0e}},//0a
+ {LCM_SEND(2), {0xAD,0x25}},//2c
+ {LCM_SEND(2), {0xAE,0x1d}},//28
+ {LCM_SEND(2), {0xAF,0x00}},
+
+ {LCM_SEND(2), {0xC0,0x00}},//00
+ {LCM_SEND(2), {0xC1,0x04}},//02
+ {LCM_SEND(2), {0xC2,0x0f}},//09
+ {LCM_SEND(2), {0xC3,0x10}},//0e
+ {LCM_SEND(2), {0xC4,0x0b}},//09
+ {LCM_SEND(2), {0xC5,0x1e}},//19
+ {LCM_SEND(2), {0xC6,0x09}},//0a
+ {LCM_SEND(2), {0xC7,0x0a}},//0a
+ {LCM_SEND(2), {0xC8,0x00}},//02
+ {LCM_SEND(2), {0xC9,0x0a}},//07
+ {LCM_SEND(2), {0xCA,0x01}},//05
+ {LCM_SEND(2), {0xCB,0x06}},//04
+ {LCM_SEND(2), {0xCC,0x09}},//0a
+ {LCM_SEND(2), {0xCD,0x2a}},//2d
+ {LCM_SEND(2), {0xCE,0x28}},//28
+ {LCM_SEND(2), {0xCF,0x00}},//00
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}},
+ {LCM_SEND(2), {0x00,0xa0}},
+ {LCM_SEND(2), {0x01,0x05}},
+ {LCM_SEND(2), {0x02,0x00}},
+ {LCM_SEND(2), {0x03,0x00}},
+ {LCM_SEND(2), {0x04,0x01}},
+ {LCM_SEND(2), {0x05,0x01}},
+ {LCM_SEND(2), {0x06,0x88}},
+ {LCM_SEND(2), {0x07,0x04}},
+ {LCM_SEND(2), {0x08,0x01}},
+ {LCM_SEND(2), {0x09,0x90}},
+ {LCM_SEND(2), {0x0A,0x04}},
+ {LCM_SEND(2), {0x0B,0x01}},
+ {LCM_SEND(2), {0x0C,0x01}},
+ {LCM_SEND(2), {0x0D,0x01}},
+ {LCM_SEND(2), {0x0E,0x00}},
+ {LCM_SEND(2), {0x0F,0x00}},
+
+ {LCM_SEND(2), {0x10,0x55}},
+ {LCM_SEND(2), {0x11,0x50}},
+ {LCM_SEND(2), {0x12,0x01}},
+ {LCM_SEND(2), {0x13,0x85}},
+ {LCM_SEND(2), {0x14,0x85}},
+ {LCM_SEND(2), {0x15,0xc0}},
+ {LCM_SEND(2), {0x16,0x0B}},
+ {LCM_SEND(2), {0x17,0x00}},
+ {LCM_SEND(2), {0x18,0x00}},
+ {LCM_SEND(2), {0x19,0x00}},
+ {LCM_SEND(2), {0x1A,0x00}},
+ {LCM_SEND(2), {0x1B,0x00}},
+ {LCM_SEND(2), {0x1C,0x00}},
+ {LCM_SEND(2), {0x1D,0x00}},
+
+ {LCM_SEND(2), {0x20,0x01}},
+ {LCM_SEND(2), {0x21,0x23}},
+ {LCM_SEND(2), {0x22,0x45}},
+ {LCM_SEND(2), {0x23,0x67}},
+ {LCM_SEND(2), {0x24,0x01}},
+ {LCM_SEND(2), {0x25,0x23}},
+ {LCM_SEND(2), {0x26,0x45}},
+ {LCM_SEND(2), {0x27,0x67}},
+
+ {LCM_SEND(2), {0x30,0x02}},
+ {LCM_SEND(2), {0x31,0x22}},
+ {LCM_SEND(2), {0x32,0x11}},
+ {LCM_SEND(2), {0x33,0xaa}},
+ {LCM_SEND(2), {0x34,0xbb}},
+ {LCM_SEND(2), {0x35,0x66}},
+ {LCM_SEND(2), {0x36,0x00}},
+ {LCM_SEND(2), {0x37,0x22}},
+ {LCM_SEND(2), {0x38,0x22}},
+ {LCM_SEND(2), {0x39,0x22}},
+ {LCM_SEND(2), {0x3A,0x22}},
+ {LCM_SEND(2), {0x3B,0x22}},
+ {LCM_SEND(2), {0x3C,0x22}},
+ {LCM_SEND(2), {0x3D,0x22}},
+ {LCM_SEND(2), {0x3E,0x22}},
+ {LCM_SEND(2), {0x3F,0x22}},
+
+ {LCM_SEND(2), {0x40,0x22}},
+ {LCM_SEND(2), {0x53,0x1a}},
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}},
+ {LCM_SEND(2), {0x18,0x1d}},
+ {LCM_SEND(2), {0x17,0x12}},
+
+ {LCM_SEND(2), {0x02,0x77}},
+
+ {LCM_SEND(2), {0xe1,0x79}},
+
+ {LCM_SEND(2), {0x06,0x13}},
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+
+// {LCM_SEND(2), {0x35,0x00}},
+
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(1)},
+
+// {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x08}},
+};
+
+#else /*For SPRD*/
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(2), {0x08,0x10}},// output SDA
+
+ {LCM_SEND(2), {0x21,0x01}},// DE = 1 Active
+
+ {LCM_SEND(2), {0x30,0x02}},// 480 X 800
+ {LCM_SEND(2), {0x31,0x02}}, // 2-dot Inversion
+
+ {LCM_SEND(2), {0x50,0x78}},// VGMP
+ {LCM_SEND(2), {0x51,0x78}},// VGMN
+ {LCM_SEND(2), {0x52,0x00}}, //Flicker
+ {LCM_SEND(2), {0x53,0x61}},//Flicker
+
+ {LCM_SEND(2), {0x60,0x07}},// SDTI
+ {LCM_SEND(2), {0x61,0x00}},// CRTI
+ {LCM_SEND(2), {0x62,0x08}},// EQTI
+ {LCM_SEND(2), {0x63,0x00}}, // PCTI
+
+ {LCM_SEND(2), {0x40,0x15}},// VGH/VGL
+ {LCM_SEND(2), {0x41,0x44}}, // VGH/VGL
+ {LCM_SEND(2), {0x42,0x03}},// VGH/VGL
+ {LCM_SEND(2), {0x43,0x89}},// VGH/VGL
+ {LCM_SEND(2), {0x44,0x82}},// VGH/VGL
+
+//++++++++++++++++++ Gamma Setting ++++++++++++++++++//
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1
+
+ {LCM_SEND(2), {0xA0,0x00}},// Gamma 0
+ {LCM_SEND(2), {0xA1,0x06}},// Gamma 4
+ {LCM_SEND(2), {0xA2,0x0c}},// Gamma 8
+ {LCM_SEND(2), {0xA3,0x12}},// Gamma 16
+ {LCM_SEND(2), {0xA4,0x0d}},// Gamma 24
+ {LCM_SEND(2), {0xA5,0x1f}},// Gamma 52
+ {LCM_SEND(2), {0xA6,0x0b}},// Gamma 80
+ {LCM_SEND(2), {0xA7,0x08}},// Gamma 108
+ {LCM_SEND(2), {0xA8,0x04}},// Gamma 147
+ {LCM_SEND(2), {0xA9,0x0a}},// Gamma 175
+ {LCM_SEND(2), {0xAA,0x06}},// Gamma 203
+ {LCM_SEND(2), {0xAB,0x04}},// Gamma 231
+ {LCM_SEND(2), {0xAC,0x10}},// Gamma 239
+ {LCM_SEND(2), {0xAD,0x37}},// Gamma 247
+ {LCM_SEND(2), {0xAE,0x30}},// Gamma 251
+ {LCM_SEND(2), {0xAF,0x07}},// Gamma 255
+
+///==============Nagitive
+ {LCM_SEND(2), {0xC0,0x00}}, // Gamma 0
+ {LCM_SEND(2), {0xC1,0x06}}, // Gamma 4
+ {LCM_SEND(2), {0xC2,0x1f}}, // Gamma 8
+ {LCM_SEND(2), {0xC3,0x06}}, // Gamma 16
+ {LCM_SEND(2), {0xC4,0x04}}, // Gamma 24
+ {LCM_SEND(2), {0xC5,0x13}}, // Gamma 52
+ {LCM_SEND(2), {0xC6,0x05}}, // Gamma 80
+ {LCM_SEND(2), {0xC7,0x05}}, // Gamma 108
+ {LCM_SEND(2), {0xC8,0x03}}, // Gamma 147
+ {LCM_SEND(2), {0xC9,0x06}}, // Gamma 175
+ {LCM_SEND(2), {0xCA,0x06}}, // Gamma 203
+ {LCM_SEND(2), {0xCB,0x03}}, // Gamma 231
+ {LCM_SEND(2), {0xCC,0x01}}, // Gamma 239
+ {LCM_SEND(2), {0xCD,0x27}}, // Gamma 247
+ {LCM_SEND(2), {0xCE,0x24}}, // Gamma 251
+ {LCM_SEND(2), {0xCF,0x07}}, // Gamma 255
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}}, // Change to Page 6
+
+ {LCM_SEND(2), {0x00,0x3c}},
+ {LCM_SEND(2), {0x01,0x06}},
+ {LCM_SEND(2), {0x02,0x00}},
+ {LCM_SEND(2), {0x03,0x00}},
+ {LCM_SEND(2), {0x04,0x0d}},
+ {LCM_SEND(2), {0x05,0x0d}},
+ {LCM_SEND(2), {0x06,0x80}},
+ {LCM_SEND(2), {0x07,0x04}},
+ {LCM_SEND(2), {0x08,0x03}},
+ {LCM_SEND(2), {0x09,0x00}},
+ {LCM_SEND(2), {0x0A,0x00}},
+ {LCM_SEND(2), {0x0B,0x00}},
+ {LCM_SEND(2), {0x0C,0x0d}},
+ {LCM_SEND(2), {0x0D,0x0d}},
+ {LCM_SEND(2), {0x0E,0x00}},
+ {LCM_SEND(2), {0x0F,0x00}},
+
+ {LCM_SEND(2), {0x10,0x50}},
+ {LCM_SEND(2), {0x11,0xd0}},
+ {LCM_SEND(2), {0x12,0x00}},
+ {LCM_SEND(2), {0x13,0x00}},
+ {LCM_SEND(2), {0x14,0x00}},
+ {LCM_SEND(2), {0x15,0xc0}},
+ {LCM_SEND(2), {0x16,0x08}},
+ {LCM_SEND(2), {0x17,0x00}},
+ {LCM_SEND(2), {0x18,0x00}},
+ {LCM_SEND(2), {0x19,0x00}},
+ {LCM_SEND(2), {0x1A,0x00}},
+ {LCM_SEND(2), {0x1B,0x00}},
+ {LCM_SEND(2), {0x1C,0x48}},
+ {LCM_SEND(2), {0x1D,0x00}},
+
+ {LCM_SEND(2), {0x20,0x01}},
+ {LCM_SEND(2), {0x21,0x23}},
+ {LCM_SEND(2), {0x22,0x45}},
+ {LCM_SEND(2), {0x23,0x67}},
+ {LCM_SEND(2), {0x24,0x01}},
+ {LCM_SEND(2), {0x25,0x23}},
+ {LCM_SEND(2), {0x26,0x45}},
+ {LCM_SEND(2), {0x27,0x67}},
+
+ {LCM_SEND(2), {0x30,0x13}},
+ {LCM_SEND(2), {0x31,0x22}},
+ {LCM_SEND(2), {0x32,0xdd}},
+ {LCM_SEND(2), {0x33,0xcc}},
+ {LCM_SEND(2), {0x34,0xbb}},
+ {LCM_SEND(2), {0x35,0xaa}},
+ {LCM_SEND(2), {0x36,0x22}},
+ {LCM_SEND(2), {0x37,0x26}},
+ {LCM_SEND(2), {0x38,0x72}},
+ {LCM_SEND(2), {0x39,0xff}},
+ {LCM_SEND(2), {0x3A,0x22}},
+ {LCM_SEND(2), {0x3B,0xee}},
+ {LCM_SEND(2), {0x3C,0x22}},
+ {LCM_SEND(2), {0x3D,0x22}},
+ {LCM_SEND(2), {0x3E,0x22}},
+ {LCM_SEND(2), {0x3F,0x22}},
+ {LCM_SEND(2), {0x52,0x10}}, /*reduce current when battery charging*/
+
+ {LCM_SEND(2), {0x40,0x22}},
+
+ {LCM_SEND(2), {0x58,0xa7}},//refresh black after resume
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}}, // Change to Page 7
+ {LCM_SEND(2), {0x17,0x22}},
+
+ {LCM_SEND(2), {0x02,0x77}},
+
+//****************************************************************************//
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}}, // Change to Page 0
+
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(10)},
+ };
+
+#endif
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(2), {0x58,0x91}},
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(8), {0x6, 0, 0xFF, 0xFF, 0x98, 0x06,0x04,0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t ili9806e_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug(KERN_DEBUG "ili9806e_mipi_init\n");
+
+ msleep(2);
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((init->tag & LCM_TAG_MASK) * 1000);
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t ili9806e_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_ili9806e_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x02, 3,(uint8_t *)read_data);
+ printk("lcd_ili9806e_mipi read id 0xc5 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if((0x04 == read_data[0])){
+ printk("lcd_ili9806e_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x04;
+ }
+ }
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t ili9806e_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "ili9806e_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((sleep_in_out->tag & LCM_TAG_MASK) * 1000);
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t ili9806e_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ uint32_t reg_val_1 = 0;
+ uint32_t reg_val_2 = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_ili9806e_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_ili9806e mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_ili9806e_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+
+static uint32_t ili9806e_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ pr_debug("ili9806e_check_esd!\n");
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = ili9806e_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("ili9806e_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("ili9806e_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static uint32_t ili9806e_mipi_after_suspend(struct panel_spec *self)
+{
+ return 0;
+}
+
+static struct panel_operations lcd_ili9806e_mipi_operations = {
+ .panel_init = ili9806e_mipi_init,
+ .panel_readid = ili9806e_readid,
+ .panel_enter_sleep = ili9806e_enter_sleep,
+ .panel_esd_check = ili9806e_check_esd,
+ .panel_after_suspend = ili9806e_mipi_after_suspend,
+
+};
+
+static struct timing_rgb lcd_ili9806e_mipi_timing = {
+ .hfp = 60, /* unit: pixel */// 100
+ .hbp = 80,//80
+ .hsync = 60,//6
+ .vfp = 20, /*unit: line*/
+ .vbp = 14,
+ .vsync =6, //6,
+};
+
+static struct info_mipi lcd_ili9806e_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000, //500->10MHz,400->8M in lp mode
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_ili9806e_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_ili9806e_mipi_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .reset_timing = {5, 15, 120},
+ .info = {
+ .mipi = &lcd_ili9806e_mipi_info
+ },
+ .ops = &lcd_ili9806e_mipi_operations,
+};
+
+struct panel_cfg lcd_ili9806e_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x04,
+ .lcd_name = "lcd_ili9806e_mipi",
+ .panel = &lcd_ili9806e_mipi_spec,
+};
+
+static int __init lcd_ili9806e_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_ili9806e_mipi);
+}
+
+subsys_initcall(lcd_ili9806e_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_jd9161_mipi.c b/drivers/video/sprdfb/lcd/lcd_jd9161_mipi.c
new file mode 100644
index 00000000..ae6311cf
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_jd9161_mipi.c
@@ -0,0 +1,380 @@
+/* drivers/video/sc8825/lcd_jd9161_mipi.c
+ *
+ * Support for jd9161 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(6), {4,0,0xBF,0x91,0x61,0xF2}},
+ {LCM_SLEEP(1)},
+ {LCM_SEND(5), {3,0,0xB3,0x00,0x7F}},//VCOM
+ {LCM_SLEEP(1)},
+ {LCM_SEND(5), {3,0,0xB4,0x00,0x7F}},//VCOM_R
+ {LCM_SLEEP(1)},
+ {LCM_SEND(9), {7,0,0xB8,0x00,0xB6,0x01,0x00,0xB6,0x01}},//VGMP, VGSP, VGMN
+ {LCM_SLEEP(1)},
+ {LCM_SEND(6), {4,0,0xBA,0x34,0x23,0x00}},//GIP output volta
+ {LCM_SLEEP(1)},
+ {LCM_SEND(2), {0xC3,0x02}},//column
+ {LCM_SLEEP(1)},
+ {LCM_SEND(5), {3,0,0xC4,0x00,0x64}},//TCON
+ {LCM_SLEEP(1)},
+ {LCM_SEND(12), {10,0,0xC7,0x00,0x01,0x32,0x05,0x65,0x2C,0x13,0xA5,0xA5}},//POWER CTRL
+ {LCM_SLEEP(1)},
+ //Gamma
+ {LCM_SEND(41), {39,0,0xC8,0x74,0x70,0x2C,0x3A,0x1C,0x11,0x17,0x06,0x24,0x29,
+ 0x2F,0x55,0x4B,0x5D,0x58,0x61,0x5D,0x57,0x50,
+ 0x74,0x70,0x2C,0x3A,0x1C,0x11,0x17,0x06,0x24,0x29,
+ 0x2F,0x55,0x4B,0x5D,0x58,0x61,0x5D,0x57,0x50}},
+ {LCM_SLEEP(1)},
+ {LCM_SEND(19), {17,0,0xD4,0x1F,0x1E,0x1F,0x00,0x10,0x1F,0x1F,0x04,0x08,0x06,
+ 0x0A,0x1F,0x1F,0x1F,0x1F,0x1F}}, //SET GIP_L
+ {LCM_SLEEP(1)},
+ {LCM_SEND(19), {17,0,0xD5,0x1F,0x1E,0x1F,0x01,0x11,0x1F,0x1F,0x05,0x09,0x07,
+ 0x0B,0x1F,0x1F,0x1F,0x1F,0x1F}}, //SET GIP_R
+ {LCM_SLEEP(1)},
+ {LCM_SEND(19), {17,0,0xD6,0x1F,0x1F,0x1E,0x11,0x01,0x1F,0x1F,0x0B,0x07,0x09,
+ 0x05,0x1F,0x1F,0x1F,0x1F,0x1F}}, //SET GIP_GS_L
+ {LCM_SLEEP(1)},
+ {LCM_SEND(19), {17,0,0xD7,0x1F,0x1F,0x1E,0x10,0x00,0x1F,0x1F,0x0A,0x06,0x08,
+ 0x04,0x1F,0x1F,0x1F,0x1F,0x1F}}, //SET GIP_GS_R
+ {LCM_SLEEP(1)},
+ {LCM_SEND(23), {21,0,0xD8,0x20,0x02,0x0A,0x10,0x05,0x30,0x01,0x02,0x30,0x01,0x02,0x06,0x70,
+ 0x53,0x2C,0x73,0x09,0x06,0x70,0x08}}, //SET GIP1
+ {LCM_SLEEP(1)},
+ {LCM_SEND(22), {20,0,0xD9,0x00,0x0A,0x0A,0x88,0x00,0x00,0x06,0x7B,0x00,0x00,
+ 0x00,0x3B,0x2F,0x1F,0x00,0x00,0x00,0x03,0x7B}}, //SET GIP2
+ {LCM_SLEEP(1)},
+ {LCM_SEND(1), {0x11}},//SLP OUT
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},//DISP ON
+ {LCM_SLEEP(50)},
+
+ };
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(10)},
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(2), {0x58,0x91}},
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(6), {4,0,0xBF,0x91,0x61,0xF2}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t jd9161_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk( "kernel jd9161_mipi_init\n");
+
+ msleep(2);
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((init->tag & LCM_TAG_MASK) * 1000);
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t jd9161_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel lcd_jd9161_mipi read id!\n");
+#if 1
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x04, 3,(uint8_t *)read_data);
+ printk("lcd_jd9161_mipi read id 0x04 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if((0x91 == read_data[0])){
+ printk("lcd_jd9161_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x916100;
+ }
+ }
+ mipi_eotp_set(1,1);
+ #endif
+ return 0x916100;
+}
+
+static int32_t jd9161_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("jd9161_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((sleep_in_out->tag & LCM_TAG_MASK) * 1000);
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t jd9161_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ uint32_t reg_val_1 = 0;
+ uint32_t reg_val_2 = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_jd9161_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_jd9161 mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_jd9161_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+
+static uint32_t jd9161_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ pr_debug("jd9161_check_esd!\n");
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = jd9161_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("jd9161_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("jd9161_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+
+static struct panel_operations lcd_jd9161_mipi_operations = {
+ .panel_init = jd9161_mipi_init,
+ .panel_readid = jd9161_readid,
+ .panel_enter_sleep = jd9161_enter_sleep,
+ .panel_esd_check = jd9161_check_esd,
+};
+
+static struct timing_rgb lcd_jd9161_mipi_timing = {
+ .hfp = 20, /* unit: pixel */// 100
+ .hbp = 20,//80
+ .hsync = 20,//6
+ .vfp = 6, /*unit: line*/
+ .vbp = 6,
+ .vsync =6, //6,
+};
+
+static struct info_mipi lcd_jd9161_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 450*1000, //500->10MHz,400->8M in lp mode
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_jd9161_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_jd9161_mipi_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .reset_timing = {5, 15, 120},
+ .info = {
+ .mipi = &lcd_jd9161_mipi_info
+ },
+ .ops = &lcd_jd9161_mipi_operations,
+};
+
+struct panel_cfg lcd_jd9161_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x916100,
+ .lcd_name = "lcd_jd9161_mipi",
+ .panel = &lcd_jd9161_mipi_spec,
+};
+
+static int __init lcd_jd9161_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_jd9161_mipi);
+}
+
+subsys_initcall(lcd_jd9161_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35502_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt35502_mipi.c
new file mode 100755
index 00000000..cccb146f
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35502_mipi.c
@@ -0,0 +1,300 @@
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 100
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ //Power setting Sequence
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x01}},
+ {LCM_SEND(4),{2,0,0xB0,0x08}},
+ {LCM_SEND(4),{2,0,0xB2,0x40}},
+ {LCM_SEND(4),{2,0,0xB3,0x28}},
+ {LCM_SEND(4),{2,0,0xB4,0x19}},
+ {LCM_SEND(4),{2,0,0xB5,0x54}},
+ {LCM_SEND(4),{2,0,0xB9,0x36}},
+ {LCM_SEND(4),{2,0,0xBA,0x024}},
+ {LCM_SEND(5),{3,0,0xBC,0xA0,0x00}},
+ {LCM_SEND(5),{3,0,0xBD,0xA0,0x00}},
+
+
+ //gamma setting
+ {LCM_SEND(19),{17,0,0xD1,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xD2,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xD3,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xD4,0x03,0x5A,0x03,0x9A}},
+ {LCM_SEND(19),{17,0,0xD5,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xD6,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xD7,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xD8,0x03,0x5A,0x03,0x9A}},
+ {LCM_SEND(19),{17,0,0xD9,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xDD,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xDE,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xDF,0x03,0x5A,0x03,0x9A}},
+ {LCM_SEND(19),{17,0,0xE0,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xE1,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xE2,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xE3,0x03,0x5A,0x03,0x9A}},
+ {LCM_SEND(19),{17,0,0xE4,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xE5,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xE6,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xE7,0x03,0x5A,0x03,0x9A}},
+ {LCM_SEND(19),{17,0,0xE8,0x00,0x3D,0x00,0x67,0x00,0x97,0x00,0xBE,0x00,0xE4,0x01,0x1B,0x01,0x45,0x01,0x80}},
+ {LCM_SEND(19),{17,0,0xE9,0x01,0xA8,0x01,0xDF,0x02,0x06,0x02,0x3C,0x02,0x65,0x02,0x66,0x02,0x89,0x02,0xAC}},
+ {LCM_SEND(19),{17,0,0xEA,0x02,0xC0,0x02,0xD8,0x02,0xE6,0x02,0xF8,0x03,0x04,0x03,0x14,0x03,0x1E,0x03,0x2B}},
+ {LCM_SEND(7),{5,0,0xEB,0x03,0x5A,0x03,0x9A}},
+
+ //initializing sequence
+
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x00}},
+ {LCM_SEND(5),{3,0,0xB1,0x16,0x08}},
+ {LCM_SEND(5),{3,0,0xB4,0x08,0x50}},
+ {LCM_SEND(4),{2,0,0xB6,0x03}},
+ {LCM_SEND(5),{3,0,0xB7,0x70,0x70}},
+ {LCM_SEND(5),{3,0,0xB8,0x61,0x66}},
+ {LCM_SEND(4),{2,0,0xBC,0x02}},
+
+ {LCM_SEND(21),{19,0,0xC8,0x80,0x00,0x46,0x64,0x46,0x64,0x46,0x64,0x46,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64}},
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x00,0x00}},
+ {LCM_SEND(7),{5,0,0xFF,0xAA,0x55,0x25,0x01}},
+ {LCM_SEND(4),{2,0,0x6F,0x02}},
+ {LCM_SEND(4),{2,0,0xF4,0x57}},
+ {LCM_SEND(6),{4,0,0xAA,0x55,0x25,0x00}},
+ {LCM_SEND(4),{2,0,0x36,0x00}},
+ {LCM_SEND(4),{2,0,0x35,0x00}},
+ {LCM_SEND(4),{2,0,0x0B,0xD8}},
+
+ //Display on
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(100)},
+
+};
+
+static LCM_Init_Code disp_on[] = {
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(100)},
+
+};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t nt35502_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel nt35502_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t nt35502_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_nt35502_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x04, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcd_nt35502_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_nt35502_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_nt35502_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ // if((0x55 == read_data[0])&&(0xbc == read_data[1])&&(0x90 == read_data[2])){
+ printk("lcd_nt35502_mipi read id success!\n");
+ return 0x8370;
+ // }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+
+static int32_t nt35502_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel nt35502_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_nt35502_mipi_operations = {
+ .panel_init = nt35502_mipi_init,
+ .panel_readid = nt35502_readid,
+ .panel_enter_sleep = nt35502_enter_sleep,
+};
+
+static struct timing_rgb lcd_nt35502_mipi_timing = {
+ .hfp = 160, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 20,
+ .vfp = 1, /*unit: line*/
+ .vbp = 11,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_nt35502_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt35502_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt35502_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 62,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_nt35502_mipi_info
+ },
+ .ops = &lcd_nt35502_mipi_operations,
+};
+struct panel_cfg lcd_nt35502_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8370,
+ .lcd_name = "lcd_nt35502_mipi",
+ .panel = &lcd_nt35502_mipi_spec,
+};
+
+//temp code
+static int __init lcd_nt35502_mipi_init(void)
+{
+/*
+ printk("nt35502_mipi_init: set lcd backlight.\n");
+
+ if (gpio_request(214, "LCD_BL")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",
+ 214);
+ return -ENODEV;
+ }
+ gpio_direction_output(214, 1);
+ gpio_set_value(214, 1);
+*/
+
+ return sprdfb_panel_register(&lcd_nt35502_mipi);
+}
+
+subsys_initcall(lcd_nt35502_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35510_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt35510_mipi.c
new file mode 100644
index 00000000..3ef26edb
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35510_mipi.c
@@ -0,0 +1,291 @@
+/* drivers/video/sc8825/lcd_nt35516_mipi.c
+ *
+ * Support for nt35516 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 56
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x01}},
+
+{LCM_SEND(6), {4, 0, 0xB0,0x09,0x09,0x09}},
+{LCM_SEND(6), {4, 0, 0xB6,0x34,0x34,0x34}},
+{LCM_SEND(6), {4, 0, 0xB1,0x09,0x09,0x09}},
+{LCM_SEND(6), {4, 0, 0xB7,0x24,0x24,0x24}},
+{LCM_SEND(6), {4, 0, 0xB3,0x05,0x05,0x05}},
+{LCM_SEND(6), {4, 0, 0xB9,0x24,0x24,0x24}},
+
+{LCM_SEND(2), {0xBF,0x01}},
+
+{LCM_SEND(6), {4, 0, 0xB5,0x0B,0x0B,0x0B}},
+{LCM_SEND(6), {4, 0, 0xBA,0x24,0x24,0x24}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0xA3,0x00}},
+{LCM_SEND(6), {4, 0, 0xBD,0x00,0xA3,0x00}},
+
+{LCM_SEND(5), {3, 0, 0xBE,0x00,0x58}},
+
+{LCM_SEND(55), {53, 0, 0xD1,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD2,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD3,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD4,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD5,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD6,0x00,0x01,0x00,0x43,0x00,0x6B,0x00,0x87,0x00,0xA3,
+0x00,0xCE,0x00,0xF1,0x01,0x27,0x01,0x53,0x01,0x98,0x01,0xCE,0x02,0x22,0x02,
+0x83,0x02,0x78,0x02,0x9E,0x02,0xDD,0x03,0x00,0x03,0x2E,0x03,0x54,0x03,0x7F,
+0x03,0x95,0x03,0xB3,0x03,0xC2,0x03,0xE1,0x03,0xF1,0x03,0xFE}},
+
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+
+{LCM_SEND(5), {3, 0, 0xB1,0xFC,0x04}},
+{LCM_SEND(2), {0x36,0x02}},
+{LCM_SEND(2), {0xB6,0x0A}},
+{LCM_SEND(5), {3, 0, 0xB7,0x00,0x00}},
+{LCM_SEND(7), {5, 0, 0xB8,0x01,0x05,0x05,0x05}},
+{LCM_SEND(2), {0xBA,0x01}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0x00,0x00}},
+{LCM_SEND(8), {6, 0, 0xBD,0x01,0x84,0x07,0x32,0x00}},
+{LCM_SEND(8), {6, 0, 0xBE,0x01,0x84,0x07,0x31,0x00}},
+{LCM_SEND(8), {6, 0, 0xBF,0x01,0x84,0x07,0x31,0x00}},
+{LCM_SEND(2), {0x35,0x00}},// Tearing Effect On
+{LCM_SEND(6), {4, 0, 0xCC,0x03,0x00,0x00}},
+{LCM_SEND(2), {0x3A, 0x77}},
+
+{LCM_SEND(1), {0x11}}, // sleep out
+{LCM_SLEEP(120),},
+{LCM_SEND(1), {0x29}}, // display on
+{LCM_SLEEP(100),},
+{LCM_SEND(1), {0x2c}}, // normal on
+
+
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+{LCM_SEND(2), {0x4f, 0x01}},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Init_Code change_fps_40[] = {
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+{LCM_SEND(8), {6, 0, 0xBD,0x02,0x46,0x1C,0x1C,0x00}},
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x00,0x00}},
+};
+
+static LCM_Init_Code change_fps_60[] = {
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+{LCM_SEND(8), {6, 0, 0xBD,0x01,0x84,0x1C,0x1C,0x00}},
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x00,0x00}},
+};
+
+static int32_t nt35510_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+
+ pr_debug(KERN_DEBUG "nt35510_mipi_init\n");
+
+ mipi_set_cmd_mode();
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ return 0;
+}
+
+static uint32_t nt35510_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ return 0x10;
+}
+
+static int32_t nt35510_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "nt35516_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static int32_t nt35510_change_fps(struct panel_spec *self, int fps_level)
+{
+ int32_t i = 0;
+ LCM_Init_Code *change_fps = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "nt35510_change_fps, fps_level = %d\n", fps_level);
+
+ if(fps_level < 50){
+ change_fps = change_fps_40;
+ size = ARRAY_SIZE(change_fps_40);
+ }else{
+ change_fps = change_fps_60;
+ size = ARRAY_SIZE(change_fps_60);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (change_fps->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(change_fps->data, (change_fps->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((change_fps->tag & LCM_TAG_MASK));
+ }
+ change_fps++;
+ }
+ return 0;
+
+}
+
+static struct panel_operations lcd_nt35510_mipi_operations = {
+ .panel_init = nt35510_mipi_init,
+ .panel_readid = nt35510_readid,
+ .panel_enter_sleep = nt35510_enter_sleep,
+ .panel_change_fps= nt35510_change_fps,
+};
+
+static struct timing_rgb lcd_nt35510_mipi_timing = {
+ .hfp = 20, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_nt35510_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_CMD,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt35510_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt35510_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_nt35510_mipi_info
+ },
+ .ops = &lcd_nt35510_mipi_operations,
+};
+
+
+struct panel_cfg lcd_nt35510_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x10,
+ .lcd_name = "lcd_nt35510_mipi",
+ .panel = &lcd_nt35510_mipi_spec,
+};
+
+static int __init lcd_nt35510_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35510_mipi);
+}
+
+subsys_initcall(lcd_nt35510_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35512_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt35512_mipi.c
new file mode 100644
index 00000000..f17864e8
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35512_mipi.c
@@ -0,0 +1,183 @@
+/* drivers/video/sc8825/lcd_nt35516_mipi.c
+ *
+ * Support for nt35516 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 56
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x01}},
+
+{LCM_SEND(6), {4, 0, 0xB0,0x09,0x09,0x09}},
+{LCM_SEND(6), {4, 0, 0xB6,0x34,0x34,0x34}},
+{LCM_SEND(6), {4, 0, 0xB1,0x09,0x09,0x09}},
+{LCM_SEND(6), {4, 0, 0xB7,0x24,0x24,0x24}},
+{LCM_SEND(6), {4, 0, 0xB3,0x05,0x05,0x05}},
+{LCM_SEND(6), {4, 0, 0xB9,0x24,0x24,0x24}},
+
+{LCM_SEND(2), {0xBF,0x01}},
+
+{LCM_SEND(6), {4, 0, 0xB5,0x03,0x03,0x03}},
+{LCM_SEND(6), {4, 0, 0xBA,0x24,0x24,0x24}},
+{LCM_SEND(2), {0xC2,0x01}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0x90,0x00}},
+{LCM_SEND(6), {4, 0, 0xBD,0x00,0x90,0x00}},
+
+{LCM_SEND(5), {3, 0, 0xBE,0x00,0x57}},
+
+{LCM_SEND(55), {53, 0, 0xD1,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD2,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD3,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD4,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD5,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+{LCM_SEND(55), {53, 0, 0xD6,0x00,0x01,0x00,0x1D,0x00,0x48,0x00,0x64,0x00,0x7E,0x00,0xB1,0x00,0xD3,0x01,0x07,0x01,0x35,0x01,0x7B,0x01,0xB3,0x02,0x03,0x02,0x48,0x02,0x49,0x02,0x88,0x02,0xC7,0x02,0xF3,0x03,0x21,0x03,0x46,0x03,0x74,0x03,0x8F,0x03,0xA3,0x03,0xAC,0x03,0xB7,0x03,0xBF,0x03,0xFE}},
+
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+
+{LCM_SEND(2), {0xB6,0x0A}},
+{LCM_SEND(5), {3, 0, 0xB7,0x00,0x00}},
+{LCM_SEND(7), {5, 0, 0xB8,0x01,0x05,0x05,0x05}},
+{LCM_SEND(2), {0xBA,0x01}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0x00,0x00}},
+//{LCM_SEND(8), {6, 0, 0xBD,0x01,0x4D,0x07,0x31,0x00}},
+//{LCM_SEND(8), {6, 0, 0xBE,0x01,0x84,0x07,0x31,0x00}},
+//{LCM_SEND(8), {6, 0, 0xBF,0x01,0x84,0x07,0x31,0x00}},
+{LCM_SEND(6), {4, 0, 0xCC,0x03,0x00,0x00}},
+{LCM_SEND(5), {3, 0, 0xB1,0xFC,0x00}},
+{LCM_SEND(2), {0x35,0x00}}, // Tearing Effect On
+{LCM_SEND(2), {0x36,0xC2}},
+{LCM_SEND(2), {0x3A, 0x77}},
+
+
+
+{LCM_SEND(1), {0x11}}, // sleep out
+{LCM_SLEEP(120),},
+{LCM_SEND(1), {0x29}}, // display on
+{LCM_SLEEP(100),},
+{LCM_SEND(1), {0x2c}}, // normal on
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in = {LCM_SEND(1), {0x10}};
+
+static LCM_Init_Code sleep_out = {LCM_SEND(1), {0x11}};
+
+static int32_t nt35512_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ pr_debug(KERN_DEBUG "nt35512_init\n");
+
+ mipi_set_cmd_mode();
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ return 0;
+}
+
+static uint32_t nt35512_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ return 0x12;
+}
+
+static struct panel_operations lcd_nt35512_mipi_operations = {
+ .panel_init = nt35516_mipi_init,
+ .panel_readid = nt35516_readid,
+};
+
+static struct timing_rgb lcd_nt35512_mipi_timing = {
+ .hfp = 200, /* unit: pixel */
+ .hbp = 200,
+ .hsync = 8,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_nt35512_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt35512_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt35512_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_nt35512_mipi_info
+ },
+ .ops = &lcd_nt35512_mipi_operations,
+};
+
+struct panel_cfg lcd_nt35512_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x12,
+ .lcd_name = "lcd_nt35516_mipi",
+ .panel = &lcd_nt35516_mipi_spec,
+};
+
+static int __init lcd_nt35512_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35516_mipi);
+}
+
+subsys_initcall(lcd_nt35512_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35516_mcu.c b/drivers/video/sprdfb/lcd/lcd_nt35516_mcu.c
new file mode 100644
index 00000000..af2df710
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35516_mcu.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+static int32_t nt35516_init(struct panel_spec *self)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("nt35516_init\n");
+
+ send_cmd(0xFF00); send_data(0x00AA); /*AA*/
+ send_cmd(0xFF01); send_data(0x0055);/*55*/
+ send_cmd(0xFF02); send_data(0x0025);/*08*/
+ send_cmd(0xFF03); send_data(0x0001);/*01*/
+
+ send_cmd(0xF300); send_data(0x0002);
+ send_cmd(0xF303); send_data(0x0015);
+
+ /*ENABPAGE 0*/
+ send_cmd(0xF000); send_data(0x0055); /*Manufacture Command Set Control*/
+ send_cmd(0xF001); send_data(0x00AA);
+ send_cmd(0xF002); send_data(0x0052);
+ send_cmd(0xF003); send_data(0x0008);
+ send_cmd(0xF004); send_data(0x0000);
+
+ send_cmd(0xB800); send_data(0x0001);
+ send_cmd(0xB801); send_data(0x0002);
+ send_cmd(0xB802); send_data(0x0002);
+ send_cmd(0xB803); send_data(0x0002);
+
+ send_cmd(0xBC00); send_data(0x0005); /*Zig-Zag Inversion*/
+ send_cmd(0xBC01); send_data(0x0005);
+ send_cmd(0xBC02); send_data(0x0005);
+
+ send_cmd(0xBD00);send_data(0x0001);
+ send_cmd(0xBD01);send_data(0x0063);//54fps
+ send_cmd(0xBD02);send_data(0x0010);
+ send_cmd(0xBD03);send_data(0x0038);
+ send_cmd(0xBD04);send_data(0x0001);
+
+
+ send_cmd(0x4C00); send_data(0x0011); /*DB4=1,Enable Vivid Color,DB4=0 Disable Vivid Color*/
+
+ /* ENA PAGE 1*/
+ send_cmd(0xF000); send_data(0x0055); /*Manufacture Command Set Control */
+ send_cmd(0xF001); send_data(0x00AA);
+ send_cmd(0xF002); send_data(0x0052);
+ send_cmd(0xF003); send_data(0x0008);
+ send_cmd(0xF004); send_data(0x0001);/*Page1*/
+
+ send_cmd(0xB000); send_data(0x0005); /*Setting AVDD Voltage 6V*/
+ send_cmd(0xB001); send_data(0x0005);
+ send_cmd(0xB002); send_data(0x0005);
+
+ send_cmd(0xB600); send_data(0x0044); /* Setting AVEE boosting time 2.5*vpnl */
+ send_cmd(0xB601); send_data(0x0044);
+ send_cmd(0xB602); send_data(0x0044);
+
+ send_cmd(0xB100); send_data(0x0005); /*Setting AVEE Voltage -6V*/
+ send_cmd(0xB101); send_data(0x0005);
+ send_cmd(0xB102); send_data(0x0005);
+
+ /*Sett AVEE boosting time -2.5NL*/
+ send_cmd(0xB700); send_data(0x0034);
+ send_cmd(0xB701); send_data(0x0034);
+ send_cmd(0xB702); send_data(0x0034);
+
+ /*Sett VGLX boosting time AVEVDD */
+ send_cmd(0xBA00); send_data(0x0014); /*0x24 --> 0x14*/
+ send_cmd(0xBA01); send_data(0x0014);
+ send_cmd(0xBA02); send_data(0x0014);
+
+ /*Gammoltage */
+ send_cmd(0xBC00); send_data(0x0000);
+ send_cmd(0xBC01); send_data(0x00A0);/*VGMP 0x88=4.7V 0x78=4.5V 0xA0=5.0V */
+ send_cmd(0xBC02); send_data(0x0000);/*VGSP*/
+
+ //Gammoltage */
+ send_cmd(0xBD00); send_data(0x0000);
+ send_cmd(0xBD01); send_data(0x00A0);/*VGMN 0x88=-4.7V 0x78=-4.5V 0xA0=-5.0V*/
+ send_cmd(0xBD02); send_data(0x0000);/*VGSN*/
+
+ send_cmd(0xBE00); send_data(0x0057); /* Setting VCOM Offset Voltage 0x4E\u017eÄΪ0x57 20111019 LIYAN*/
+
+ /*GAMMED Positive*/
+ send_cmd(0xD100); send_data(0x0000);
+ send_cmd(0xD101); send_data(0x0032);
+ send_cmd(0xD102); send_data(0x0000);
+ send_cmd(0xD103); send_data(0x0041);
+ send_cmd(0xD104); send_data(0x0000);
+ send_cmd(0xD105); send_data(0x0054);
+ send_cmd(0xD106); send_data(0x0000);
+ send_cmd(0xD107); send_data(0x0067);
+ send_cmd(0xD108); send_data(0x0000);
+ send_cmd(0xD109); send_data(0x007A);
+ send_cmd(0xD10A); send_data(0x0000);
+ send_cmd(0xD10B); send_data(0x0098);
+ send_cmd(0xD10C); send_data(0x0000);
+ send_cmd(0xD10D); send_data(0x00B0);
+ send_cmd(0xD10E); send_data(0x0000);
+ send_cmd(0xD10F); send_data(0x00DB);
+ send_cmd(0xD200); send_data(0x0001);
+ send_cmd(0xD201); send_data(0x0001);
+ send_cmd(0xD202); send_data(0x0001);
+ send_cmd(0xD203); send_data(0x003F);
+ send_cmd(0xD204); send_data(0x0001);
+ send_cmd(0xD205); send_data(0x0070);
+ send_cmd(0xD206); send_data(0x0001);
+ send_cmd(0xD207); send_data(0x00B4);
+ send_cmd(0xD208); send_data(0x0001);
+ send_cmd(0xD209); send_data(0x00EC);
+ send_cmd(0xD20A); send_data(0x0001);
+ send_cmd(0xD20B); send_data(0x00ED);
+ send_cmd(0xD20C); send_data(0x0002);
+ send_cmd(0xD20D); send_data(0x001E);
+ send_cmd(0xD20E); send_data(0x0002);
+ send_cmd(0xD20F); send_data(0x0051);
+ send_cmd(0xD300); send_data(0x0002);
+ send_cmd(0xD301); send_data(0x006C);
+ send_cmd(0xD302); send_data(0x0002);
+ send_cmd(0xD303); send_data(0x008D);
+ send_cmd(0xD304); send_data(0x0002);
+ send_cmd(0xD305); send_data(0x00A5);
+ send_cmd(0xD306); send_data(0x0002);
+ send_cmd(0xD307); send_data(0x00C9);
+ send_cmd(0xD308); send_data(0x0002);
+ send_cmd(0xD309); send_data(0x00EA);
+ send_cmd(0xD30A); send_data(0x0003);
+ send_cmd(0xD30B); send_data(0x0019);
+ send_cmd(0xD30C); send_data(0x0003);
+ send_cmd(0xD30D); send_data(0x0045);
+ send_cmd(0xD30E); send_data(0x0003);
+ send_cmd(0xD30F); send_data(0x007A);
+ send_cmd(0xD400); send_data(0x0003);
+ send_cmd(0xD401); send_data(0x00B0);
+ send_cmd(0xD402); send_data(0x0003);
+ send_cmd(0xD403); send_data(0x00F4);
+
+ /*Posie Gamma for GREEN*/
+ send_cmd(0xD500); send_data(0x0000);
+ send_cmd(0xD501); send_data(0x0037);
+ send_cmd(0xD502); send_data(0x0000);
+ send_cmd(0xD503); send_data(0x0041);
+ send_cmd(0xD504); send_data(0x0000);
+ send_cmd(0xD505); send_data(0x0054);
+ send_cmd(0xD506); send_data(0x0000);
+ send_cmd(0xD507); send_data(0x0067);
+ send_cmd(0xD508); send_data(0x0000);
+ send_cmd(0xD509); send_data(0x007A);
+ send_cmd(0xD50A); send_data(0x0000);
+ send_cmd(0xD50B); send_data(0x0098);
+ send_cmd(0xD50C); send_data(0x0000);
+ send_cmd(0xD50D); send_data(0x00B0);
+ send_cmd(0xD50E); send_data(0x0000);
+ send_cmd(0xD50F); send_data(0x00DB);
+ send_cmd(0xD600); send_data(0x0001);
+ send_cmd(0xD601); send_data(0x0001);
+ send_cmd(0xD602); send_data(0x0001);
+ send_cmd(0xD603); send_data(0x003F);
+ send_cmd(0xD604); send_data(0x0001);
+ send_cmd(0xD605); send_data(0x0070);
+ send_cmd(0xD606); send_data(0x0001);
+ send_cmd(0xD607); send_data(0x00B4);
+ send_cmd(0xD608); send_data(0x0001);
+ send_cmd(0xD609); send_data(0x00EC);
+ send_cmd(0xD60A); send_data(0x0001);
+ send_cmd(0xD60B); send_data(0x00ED);
+ send_cmd(0xD60C); send_data(0x0002);
+ send_cmd(0xD60D); send_data(0x001E);
+ send_cmd(0xD60E); send_data(0x0002);
+ send_cmd(0xD60F); send_data(0x0051);
+ send_cmd(0xD700); send_data(0x0002);
+ send_cmd(0xD701); send_data(0x006C);
+ send_cmd(0xD702); send_data(0x0002);
+ send_cmd(0xD703); send_data(0x008D);
+ send_cmd(0xD704); send_data(0x0002);
+ send_cmd(0xD705); send_data(0x00A5);
+ send_cmd(0xD706); send_data(0x0002);
+ send_cmd(0xD707); send_data(0x00C9);
+ send_cmd(0xD708); send_data(0x0002);
+ send_cmd(0xD709); send_data(0x00EA);
+ send_cmd(0xD70A); send_data(0x0003);
+ send_cmd(0xD70B); send_data(0x0019);
+ send_cmd(0xD70C); send_data(0x0003);
+ send_cmd(0xD70D); send_data(0x0045);
+ send_cmd(0xD70E); send_data(0x0003);
+ send_cmd(0xD70F); send_data(0x007A);
+ send_cmd(0xD800); send_data(0x0003);
+ send_cmd(0xD801); send_data(0x00A0);
+ send_cmd(0xD802); send_data(0x0003);
+ send_cmd(0xD803); send_data(0x00F4);
+
+ /*Posie Gamma for BLUE*/
+ send_cmd(0xD900); send_data(0x0000);
+ send_cmd(0xD901); send_data(0x0032);
+ send_cmd(0xD902); send_data(0x0000);
+ send_cmd(0xD903); send_data(0x0041);
+ send_cmd(0xD904); send_data(0x0000);
+ send_cmd(0xD905); send_data(0x0054);
+ send_cmd(0xD906); send_data(0x0000);
+ send_cmd(0xD907); send_data(0x0067);
+ send_cmd(0xD908); send_data(0x0000);
+ send_cmd(0xD909); send_data(0x007A);
+ send_cmd(0xD90A); send_data(0x0000);
+ send_cmd(0xD90B); send_data(0x0098);
+ send_cmd(0xD90C); send_data(0x0000);
+ send_cmd(0xD90D); send_data(0x00B0);
+ send_cmd(0xD90E); send_data(0x0000);
+ send_cmd(0xD90F); send_data(0x00DB);
+ send_cmd(0xDD00); send_data(0x0001);
+ send_cmd(0xDD01); send_data(0x0001);
+ send_cmd(0xDD02); send_data(0x0001);
+ send_cmd(0xDD03); send_data(0x003F);
+ send_cmd(0xDD04); send_data(0x0001);
+ send_cmd(0xDD05); send_data(0x0070);
+ send_cmd(0xDD06); send_data(0x0001);
+ send_cmd(0xDD07); send_data(0x00B4);
+ send_cmd(0xDD08); send_data(0x0001);
+ send_cmd(0xDD09); send_data(0x00EC);
+ send_cmd(0xDD0A); send_data(0x0001);
+ send_cmd(0xDD0B); send_data(0x00ED);
+ send_cmd(0xDD0C); send_data(0x0002);
+ send_cmd(0xDD0D); send_data(0x001E);
+ send_cmd(0xDD0E); send_data(0x0002);
+ send_cmd(0xDD0F); send_data(0x0051);
+ send_cmd(0xDE00); send_data(0x0002);
+ send_cmd(0xDE01); send_data(0x006C);
+ send_cmd(0xDE02); send_data(0x0002);
+ send_cmd(0xDE03); send_data(0x008D);
+ send_cmd(0xDE04); send_data(0x0002);
+ send_cmd(0xDE05); send_data(0x00A5);
+ send_cmd(0xDE06); send_data(0x0002);
+ send_cmd(0xDE07); send_data(0x00C9);
+ send_cmd(0xDE08); send_data(0x0002);
+ send_cmd(0xDE09); send_data(0x00EA);
+ send_cmd(0xDE0A); send_data(0x0003);
+ send_cmd(0xDE0B); send_data(0x0019);
+ send_cmd(0xDE0C); send_data(0x0003);
+ send_cmd(0xDE0D); send_data(0x0045);
+ send_cmd(0xDE0E); send_data(0x0003);
+ send_cmd(0xDE0F); send_data(0x007A);
+ send_cmd(0xDF00); send_data(0x0003);
+ send_cmd(0xDF01); send_data(0x00A0);
+ send_cmd(0xDF02); send_data(0x0003);
+ send_cmd(0xDF03); send_data(0x00F4);
+
+ /*Negae Gamma for RED*/
+ send_cmd(0xE000); send_data(0x0000);
+ send_cmd(0xE001); send_data(0x0032);
+ send_cmd(0xE002); send_data(0x0000);
+ send_cmd(0xE003); send_data(0x0041);
+ send_cmd(0xE004); send_data(0x0000);
+ send_cmd(0xE005); send_data(0x0054);
+ send_cmd(0xE006); send_data(0x0000);
+ send_cmd(0xE007); send_data(0x0067);
+ send_cmd(0xE008); send_data(0x0000);
+ send_cmd(0xE009); send_data(0x007A);
+ send_cmd(0xE00A); send_data(0x0000);
+ send_cmd(0xE00B); send_data(0x0098);
+ send_cmd(0xE00C); send_data(0x0000);
+ send_cmd(0xE00D); send_data(0x00B0);
+ send_cmd(0xE00E); send_data(0x0000);
+ send_cmd(0xE00F); send_data(0x00DB);
+ send_cmd(0xE100); send_data(0x0001);
+ send_cmd(0xE101); send_data(0x0001);
+ send_cmd(0xE102); send_data(0x0001);
+ send_cmd(0xE103); send_data(0x003F);
+ send_cmd(0xE104); send_data(0x0001);
+ send_cmd(0xE105); send_data(0x0070);
+ send_cmd(0xE106); send_data(0x0001);
+ send_cmd(0xE107); send_data(0x00B4);
+ send_cmd(0xE108); send_data(0x0001);
+ send_cmd(0xE109); send_data(0x00EC);
+ send_cmd(0xE10A); send_data(0x0001);
+ send_cmd(0xE10B); send_data(0x00ED);
+ send_cmd(0xE10C); send_data(0x0002);
+ send_cmd(0xE10D); send_data(0x001E);
+ send_cmd(0xE10E); send_data(0x0002);
+ send_cmd(0xE10F); send_data(0x0051);
+ send_cmd(0xE200); send_data(0x0002);
+ send_cmd(0xE201); send_data(0x006C);
+ send_cmd(0xE202); send_data(0x0002);
+ send_cmd(0xE203); send_data(0x008D);
+ send_cmd(0xE204); send_data(0x0002);
+ send_cmd(0xE205); send_data(0x00A5);
+ send_cmd(0xE206); send_data(0x0002);
+ send_cmd(0xE207); send_data(0x00C9);
+ send_cmd(0xE208); send_data(0x0002);
+ send_cmd(0xE209); send_data(0x00EA);
+ send_cmd(0xE20A); send_data(0x0003);
+ send_cmd(0xE20B); send_data(0x0019);
+ send_cmd(0xE20C); send_data(0x0003);
+ send_cmd(0xE20D); send_data(0x0045);
+ send_cmd(0xE20E); send_data(0x0003);
+ send_cmd(0xE20F); send_data(0x007A);
+ send_cmd(0xE300); send_data(0x0003);
+ send_cmd(0xE301); send_data(0x00A0);
+ send_cmd(0xE302); send_data(0x0003);
+ send_cmd(0xE303); send_data(0x00F4);
+
+ /*Negae Gamma for GERREN*/
+ send_cmd(0xE400); send_data(0x0000);
+ send_cmd(0xE401); send_data(0x0032);
+ send_cmd(0xE402); send_data(0x0000);
+ send_cmd(0xE403); send_data(0x0041);
+ send_cmd(0xE404); send_data(0x0000);
+ send_cmd(0xE405); send_data(0x0054);
+ send_cmd(0xE406); send_data(0x0000);
+ send_cmd(0xE407); send_data(0x0067);
+ send_cmd(0xE408); send_data(0x0000);
+ send_cmd(0xE409); send_data(0x007A);
+ send_cmd(0xE40A); send_data(0x0000);
+ send_cmd(0xE40B); send_data(0x0098);
+ send_cmd(0xE40C); send_data(0x0000);
+ send_cmd(0xE40D); send_data(0x00B0);
+ send_cmd(0xE40E); send_data(0x0000);
+ send_cmd(0xE40F); send_data(0x00DB);
+ send_cmd(0xE500); send_data(0x0001);
+ send_cmd(0xE501); send_data(0x0001);
+ send_cmd(0xE502); send_data(0x0001);
+ send_cmd(0xE503); send_data(0x003F);
+ send_cmd(0xE504); send_data(0x0001);
+ send_cmd(0xE505); send_data(0x0070);
+ send_cmd(0xE506); send_data(0x0001);
+ send_cmd(0xE507); send_data(0x00B4);
+ send_cmd(0xE508); send_data(0x0001);
+ send_cmd(0xE509); send_data(0x00EC);
+ send_cmd(0xE50A); send_data(0x0001);
+ send_cmd(0xE50B); send_data(0x00ED);
+ send_cmd(0xE50C); send_data(0x0002);
+ send_cmd(0xE50D); send_data(0x001E);
+ send_cmd(0xE50E); send_data(0x0002);
+ send_cmd(0xE50F); send_data(0x0051);
+ send_cmd(0xE600); send_data(0x0002);
+ send_cmd(0xE601); send_data(0x006C);
+ send_cmd(0xE602); send_data(0x0002);
+ send_cmd(0xE603); send_data(0x008D);
+ send_cmd(0xE604); send_data(0x0002);
+ send_cmd(0xE605); send_data(0x00A5);
+ send_cmd(0xE606); send_data(0x0002);
+ send_cmd(0xE607); send_data(0x00C9);
+ send_cmd(0xE608); send_data(0x0002);
+ send_cmd(0xE609); send_data(0x00EA);
+ send_cmd(0xE60A); send_data(0x0003);
+ send_cmd(0xE60B); send_data(0x0019);
+ send_cmd(0xE60C); send_data(0x0003);
+ send_cmd(0xE60D); send_data(0x0045);
+ send_cmd(0xE60E); send_data(0x0003);
+ send_cmd(0xE60F); send_data(0x007A);
+ send_cmd(0xE700); send_data(0x0003);
+ send_cmd(0xE701); send_data(0x00A0);
+ send_cmd(0xE702); send_data(0x0003);
+ send_cmd(0xE703); send_data(0x00F4);
+
+ /*Negae Gamma for BLUE*/
+ send_cmd(0xE800); send_data(0x0000);
+ send_cmd(0xE801); send_data(0x0032);
+ send_cmd(0xE802); send_data(0x0000);
+ send_cmd(0xE803); send_data(0x0041);
+ send_cmd(0xE804); send_data(0x0000);
+ send_cmd(0xE805); send_data(0x0054);
+ send_cmd(0xE806); send_data(0x0000);
+ send_cmd(0xE807); send_data(0x0067);
+ send_cmd(0xE808); send_data(0x0000);
+ send_cmd(0xE809); send_data(0x007A);
+ send_cmd(0xE80A); send_data(0x0000);
+ send_cmd(0xE80B); send_data(0x0098);
+ send_cmd(0xE80C); send_data(0x0000);
+ send_cmd(0xE80D); send_data(0x00B0);
+ send_cmd(0xE80E); send_data(0x0000);
+ send_cmd(0xE80F); send_data(0x00DB);
+ send_cmd(0xE900); send_data(0x0001);
+ send_cmd(0xE901); send_data(0x0001);
+ send_cmd(0xE902); send_data(0x0001);
+ send_cmd(0xE903); send_data(0x003F);
+ send_cmd(0xE904); send_data(0x0001);
+ send_cmd(0xE905); send_data(0x0070);
+ send_cmd(0xE906); send_data(0x0001);
+ send_cmd(0xE907); send_data(0x00B4);
+ send_cmd(0xE908); send_data(0x0001);
+ send_cmd(0xE909); send_data(0x00EC);
+ send_cmd(0xE90A); send_data(0x0001);
+ send_cmd(0xE90B); send_data(0x00ED);
+ send_cmd(0xE90C); send_data(0x0002);
+ send_cmd(0xE90D); send_data(0x001E);
+ send_cmd(0xE90E); send_data(0x0002);
+ send_cmd(0xE90F); send_data(0x0051);
+ send_cmd(0xEA00); send_data(0x0002);
+ send_cmd(0xEA01); send_data(0x006C);
+ send_cmd(0xEA02); send_data(0x0002);
+ send_cmd(0xEA03); send_data(0x008D);
+ send_cmd(0xEA04); send_data(0x0002);
+ send_cmd(0xEA05); send_data(0x00A5);
+ send_cmd(0xEA06); send_data(0x0002);
+ send_cmd(0xEA07); send_data(0x00C9);
+ send_cmd(0xEA08); send_data(0x0002);
+ send_cmd(0xEA09); send_data(0x00EA);
+ send_cmd(0xEA0A); send_data(0x0003);
+ send_cmd(0xEA0B); send_data(0x0019);
+ send_cmd(0xEA0C); send_data(0x0003);
+ send_cmd(0xEA0D); send_data(0x0045);
+ send_cmd(0xEA0E); send_data(0x0003);
+ send_cmd(0xEA0F); send_data(0x007A);
+ send_cmd(0xEB00); send_data(0x0003);
+ send_cmd(0xEB01); send_data(0x00A0);
+ send_cmd(0xEB02); send_data(0x0003);
+ send_cmd(0xEB03); send_data(0x00F4);
+
+ send_cmd(0x3A00); send_data(0x0007);
+
+ send_cmd(0x3500); send_data(0x0000);
+
+ send_cmd(0x1100); /* Sleep out*/
+ LCD_DelayMS(120);
+ send_cmd(0x2900); /* Display On*/
+
+ send_cmd(0x2900); /* Display On*/
+ return 0;
+}
+
+static int32_t nt35516_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ return 0;
+
+ if(is_sleep==1){
+ send_cmd(0x2800);
+ LCD_DelayMS(200);
+ send_cmd(0x1000);
+ LCD_DelayMS(200);
+ /*Lcd_EnvidOnOff(0);*//*RGB TIMENG OFF*/
+ /*LCD_Delay(200);*/
+ }else{
+ /*Lcd_EnvidOnOff(1);*//*RGB TIMENG ON*/
+ /*LCD_Delay(200);*/
+ /*LCDinit_TFT();*/
+ /*LCD_Delay(200);*/
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t nt35516_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("nt35516_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
+
+ send_cmd(0x2A00); send_data((left>>8));// set left address
+ send_cmd(0x2A01); send_data((left&0xff));
+ send_cmd(0x2A02); send_data((right>>8));// set right address
+ send_cmd(0x2A03); send_data((right&0xff));
+
+ send_cmd(0x2B00); send_data((top>>8));// set left address
+ send_cmd(0x2B01); send_data((top&0xff));
+ send_cmd(0x2B02); send_data((bottom>>8));// set bottom address
+ send_cmd(0x2B03); send_data((bottom&0xff));
+
+ send_cmd(0x2C00);
+
+ return 0;
+}
+static int32_t nt35516_invalidate(struct panel_spec *self)
+{
+ pr_debug("nt35516_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+
+
+static int32_t nt35516_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+ pr_debug("nt35516_invalidate_rect \n");
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static uint32_t nt35516_read_id(struct panel_spec *self)
+{
+ int32_t id = 0;
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ //Get ID
+ send_cmd(0xF000); send_data(0x0055); /*Manufacture Command Set Control */
+ send_cmd(0xF001); send_data(0x00AA);
+ send_cmd(0xF002); send_data(0x0052);
+ send_cmd(0xF003); send_data(0x0008);
+ send_cmd(0xF004); send_data(0x0001);/*Page1*/
+
+ send_cmd(0xc501); //0xc500
+ id = read_data();
+
+ return id;
+}
+
+static struct panel_operations lcd_nt35516_operations = {
+ .panel_init = nt35516_init,
+ .panel_set_window = nt35516_set_window,
+ .panel_invalidate_rect= nt35516_invalidate_rect,
+ .panel_invalidate = nt35516_invalidate,
+ .panel_enter_sleep = nt35516_enter_sleep,
+ .panel_readid = nt35516_read_id
+};
+
+static struct timing_mcu lcd_nt35516_timing[] = {
+[MCU_LCD_REGISTER_TIMING] = { // read/write register timing
+ .rcss = 15, // 15ns
+ .rlpw = 60,
+ .rhpw = 60,
+ .wcss = 10,
+ .wlpw = 35,
+ .whpw = 35,
+ },
+[MCU_LCD_GRAM_TIMING] = { // read/write gram timing
+ .rcss = 15, // 15ns
+ .rlpw = 60,
+ .rhpw = 60,
+ .wcss = 0,
+ .wlpw = 16,
+ .whpw = 16,
+ },
+};
+
+static struct info_mcu lcd_nt35516_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 24,
+ .bpp = 24, /*RGB88*/
+ .timing = lcd_nt35516_timing,
+ .ops = NULL,
+};
+
+//lcd_panel_nt35516
+struct panel_spec lcd_nt35516_spec = {
+ .width = 540,
+ .height = 960,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_nt35516_info
+ },
+ .ops = &lcd_nt35516_operations,
+};
+
+struct panel_cfg lcd_nt35516 = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_UNDEFINELCD_ID,
+ .lcd_id = 0x16,
+ .lcd_name = "lcd_nt35516",
+ .panel = &lcd_nt35516_spec,
+};
+
+static int __init lcd_nt35516_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35516);
+}
+
+subsys_initcall(lcd_nt35516_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35516_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt35516_mipi.c
new file mode 100644
index 00000000..0fa94268
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35516_mipi.c
@@ -0,0 +1,441 @@
+/* drivers/video/sc8825/lcd_nt35516_mipi.c
+ *
+ * Support for nt35516 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#if 1
+// NT35516, LGD
+// VCC=2.8V, IOVCC=1.8V
+{LCM_SEND(7), {5, 0, 0xFF,0xAA,0x55,0x25,0x01}},
+{LCM_SEND(38), {36, 0, 0xF2,0x00,0x00,0x4A,0x0A,0xA8,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x51,
+ 0x00,0x01,0x00,0x01}},
+{LCM_SEND(10), {8, 0, 0xF3,0x02,0x03,0x07,0x45,0x88,0xD1,0x0D}},
+// Manufacture Command Set for Page 0
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+{LCM_SEND(6), {4, 0, 0xB1,0x7C,0x00,0x00}}, // command/video mode
+#if (defined CONFIG_FB_SCX35) || (defined CONFIG_FB_SCX30G)
+{LCM_SEND(6), {4, 0, 0xB1,0x7C,0x06,0x00}}, // command/video mode,rotate 180^M
+#else
+ {LCM_SEND(6), {4, 0, 0xB1,0x7C,0x00,0x00}}, // command/video mode
+#endif
+{LCM_SEND(7), {5, 0, 0xB8,0x01,0x02,0x02,0x02}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0x00,0x00}}, // inversion
+{LCM_SEND(9), {7, 0, 0xC9,0x63,0x06,0x0D,0x1A,0x17,0x00}},
+// Manufacture Command Set for Page 1
+{LCM_SEND(8), {6, 0, 0xF0,0x55,0xAA,0x52,0x08,0x01}},
+{LCM_SEND(6), {4, 0, 0xB0,0x05,0x05,0x05}},
+{LCM_SEND(6), {4, 0, 0xB1,0x05,0x05,0x05}},
+{LCM_SEND(6), {4, 0, 0xB2,0x01,0x01,0x01}},
+{LCM_SEND(6), {4, 0, 0xB3,0x0D,0x0D,0x0D}},
+{LCM_SEND(6), {4, 0, 0xB4,0x09,0x09,0x09}},
+{LCM_SEND(6), {4, 0, 0xB6,0x44,0x44,0x44}},
+{LCM_SEND(6), {4, 0, 0xB7,0x34,0x34,0x34}},
+{LCM_SEND(6), {4, 0, 0xB8,0x10,0x10,0x10}},
+{LCM_SEND(6), {4, 0, 0xB9,0x36,0x36,0x36}},
+{LCM_SEND(6), {4, 0, 0xBA,0x24,0x24,0x24}},
+{LCM_SEND(6), {4, 0, 0xBC,0x00,0xD0,0x00}},
+{LCM_SEND(6), {4, 0, 0xBD,0x00,0xD0,0x00}},
+{LCM_SEND(2), {0xBE,0x5D}},
+{LCM_SEND(5), {3, 0, 0xC0,0x04,0x00}},
+{LCM_SEND(2), {0xCA,0x00}},
+// Gradient Control for Gamma Voltage
+{LCM_SEND(7), {5, 0, 0xD0,0x0A,0x10,0x0D,0x0F}},
+{LCM_SEND(19), {17, 0, 0xD1,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xD2,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xD3,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xD4,0x03,0xEF,0x03,0xFF}},
+{LCM_SEND(19), {17, 0, 0xD5,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xD6,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xD7,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xD8,0x03,0xEF,0x03,0xFF}},
+{LCM_SEND(19), {17, 0, 0xD9,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xDD,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xDE,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xDF,0x03,0xEF,0x03,0xFF}},
+{LCM_SEND(19), {17, 0, 0xE0,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xE1,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xE2,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xE3,0x03,0xEF,0x03,0xFF}},
+{LCM_SEND(19), {17, 0, 0xE4,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xE5,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xE6,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xE7,0x03,0xEF,0x03,0xFF}},
+{LCM_SEND(19), {17, 0, 0xE8,0x00,0xA7,0x01,0x0F,0x01,0x34,0x01,0x49,0x01,0x56,0x01,0x75,0x01,0x8F,0x01,0xB7}},
+{LCM_SEND(19), {17, 0, 0xE9,0x01,0xD1,0x02,0x03,0x02,0x23,0x02,0x57,0x02,0x85,0x02,0x87,0x02,0xAA,0x02,0xE1}},
+{LCM_SEND(19), {17, 0, 0xEA,0x03,0x04,0x03,0x31,0x03,0x42,0x03,0x6D,0x03,0x83,0x03,0x9C,0x03,0xAA,0x03,0xCD}},
+{LCM_SEND(7), {5, 0, 0xEB,0x03,0xEF,0x03,0xFF}},
+// User Command Set
+{LCM_SEND(2), {0x35,0x00}}, // Tearing Effect On
+{LCM_SEND(5), {3, 0, 0x44, 0x03, 0x98}}, //set te scan line to 920
+{LCM_SEND(2), {0x3A,0x77}}, // Interface Pixel Format
+{LCM_SEND(2), {0x36,0x00}}, // Memory Data Access Control
+{LCM_SEND(1), {0x22}}, // all pixel off
+{LCM_SEND(1), {0x11}}, // sleep out
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}}, // display on
+{LCM_SLEEP(100)},
+{LCM_SEND(2), {0x13,0x00}}, // normal on
+#endif
+
+#if 0
+{LCM_SEND(7), {0x5, 0, 0xFF, 0xAA, 0x55, 0x25, 0x01}},
+{LCM_SEND(7), {0x5, 0, 0xF3, 0x02, 0x03, 0x07, 0x15}},
+{LCM_SEND(8), {0x6, 0, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00}},
+//{LCM_SEND(8), {0x06, 0, 0xF0,0x55,0xAA,0x52,0x08,0x00}},
+//{LCM_SEND(8), {0x06, 0, 0xBD,0x02,0xC8,0x14,0x3C,0x01}},
+{LCM_SEND(2), {0xB1, 0xFC}},
+
+{LCM_SEND(7), {0x5, 0, 0xB8, 0x01, 0x02, 0x02, 0x02}},
+{LCM_SEND(6), {0x4, 0, 0xBC, 0x05, 0x05, 0x05}}, //Zig-Zag Inversion
+{LCM_SEND(8), {0x6, 0, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01}},
+{LCM_SEND(6), {0x4, 0, 0xB0, 0x05, 0x05, 0x05}},
+{LCM_SEND(6), {0x4, 0, 0xB1, 0x05, 0x05, 0x05}},
+{LCM_SEND(6), {0x4, 0, 0xB6, 0x34, 0x34, 0x34}},
+{LCM_SEND(6), {0x4, 0, 0xB7, 0x24, 0x24, 0x24}},
+{LCM_SEND(6), {0x4, 0, 0xB3, 0x10, 0x10, 0x10}},
+{LCM_SEND(6), {0x4, 0, 0xB9, 0x34, 0x34, 0x34}},
+{LCM_SEND(6), {0x4, 0, 0xB4, 0x0A, 0x0A, 0x0A}},
+{LCM_SEND(6), {0x4, 0, 0xBA, 0x14, 0x14, 0x14}},
+{LCM_SEND(6), {0x4, 0, 0xBC, 0x00, 0xA0, 0x00}},
+{LCM_SEND(6), {0x4, 0, 0xBD, 0x00, 0xA0, 0x00}},
+{LCM_SEND(2), {0xBE, 0x4E}},
+
+{LCM_SEND(19),{17, 0, 0xD1, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0, 0xD2, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0, 0xD3, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), { 5, 0, 0xD4, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(19),{17, 0, 0xD5, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0, 0xD6, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0, 0xD7, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), {0x7, 0, 0xD8, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(19),{17, 0, 0xD9, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0,0xDD, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0, 0xDE, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), {0x5, 0, 0xDF, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(19),{17, 0, 0xE0, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0 ,0xE1, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0,0xE2, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), {5, 0, 0xE3, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(19),{17, 0, 0xE4, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0,0xE5, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0, 0xE6, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), {5, 0, 0xE7, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(19),{17 , 0, 0xE8, 0x00, 0x32, 0x00, 0x41, 0x00, 0x54, 0x00, 0x67, 0x00, 0x7A, 0x00, 0x98, 0x00, 0xB0, 0x00, 0xDB}},
+{LCM_SEND(19),{17, 0, 0xE9, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x70, 0x01, 0xB4, 0x01, 0xEC, 0x01, 0xED, 0x02, 0x1E, 0x02, 0x51}},
+{LCM_SEND(19),{17, 0, 0xEA, 0x02, 0x6C, 0x02, 0x8D, 0x02, 0xA5, 0x02, 0xC9, 0x02, 0xEA, 0x03, 0x19, 0x03, 0x45, 0x03, 0x7A}},
+{LCM_SEND(7), {0x5, 0, 0xEB, 0x03, 0xB0, 0x03, 0xF4}},
+{LCM_SEND(2), {0x3A, 0x77}},
+{LCM_SEND(2), {0x35, 0x00}},
+{LCM_SEND(2), {0x4C, 0x11}},
+
+#endif
+#if 0
+{LCM_SEND(1), {0x11}},//0x11
+{LCM_SLEEP(200),},
+{LCM_SEND(1), {0x29}},//0x29
+#endif
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+//{LCM_SEND(2), {0x4f, 0x01}}, /* this code may cause not resume bug*/
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(8), {0x6, 0, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t nt35516_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ pr_debug(KERN_DEBUG "nt35516_mipi_init\n");
+
+ mipi_set_cmd_mode();
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ return 0;
+}
+
+static uint32_t nt35516_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_nt35516_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0xc5, 3,(uint8_t *)read_data);
+ printk("lcd_nt35516_mipi read id 0xc5 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if((0x55 == read_data[0])&&(0x16 == read_data[1])){
+ printk("lcd_nt35516_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x16;
+ }
+ }
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t nt35516_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "nt35516_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t nt35516_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_nt35516_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_nt35516 mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_nt35516_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ printk("lcd_nt35516 mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t nt35516_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+#ifndef FB_CHECK_ESD_IN_VFP
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+#endif
+
+ pr_debug("nt35516_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+#endif
+ power_mode = nt35516_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+#endif
+ if(power_mode == 0x9c){
+ pr_debug("nt35516_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("nt35516_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_nt35516_mipi_operations = {
+ .panel_init = nt35516_mipi_init,
+ .panel_readid = nt35516_readid,
+ .panel_enter_sleep = nt35516_enter_sleep,
+ .panel_esd_check = nt35516_check_esd,
+};
+
+static struct timing_rgb lcd_nt35516_mipi_timing = {
+ .hfp = 20, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 20,//4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_nt35516_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 3,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt35516_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt35516_mipi_spec = {
+ .width = 540,
+ .height = 960,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_nt35516_mipi_info
+ },
+ .ops = &lcd_nt35516_mipi_operations,
+};
+
+struct panel_cfg lcd_nt35516_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x16,
+ .lcd_name = "lcd_nt35516_mipi",
+ .panel = &lcd_nt35516_mipi_spec,
+};
+
+static int __init lcd_nt35516_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35516_mipi);
+}
+
+subsys_initcall(lcd_nt35516_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_i2c.c b/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_i2c.c
new file mode 100644
index 00000000..cdbfd220
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_i2c.c
@@ -0,0 +1,623 @@
+/* drivers/video/sc8825/lcd_nt35516_i2c.c
+ *
+ * Support for nt35516 i2c LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+#define NT35516_I2C_ADDR 0x4C
+#define NT35516_I2C_DATA_LENGHT 0x2
+#define NT35516_I2C_ACK 0x01
+//#define Set_NT35516_I2C_Send(len, data) I2C_WriteCmdArr(NT35516_I2C_ADDR, data ,len, NT35516_I2C_ACK)
+#define Set_NT35516_I2C_Send(len, data) i2c_write_burst(data ,len)
+#define LCDI2C_ID_ADDR 0xDB00
+
+#define NT35516_MAX_PARAM 4
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[NT35516_MAX_PARAM];
+}LCM_Init_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(4), {0xFF, 0x00, 0x00, 0xAA}},//AA
+ {LCM_SEND(4), {0xFF, 0x01, 0x00, 0x55}},//55
+ {LCM_SEND(4), {0xFF, 0x02, 0x00, 0x25}},//08
+ {LCM_SEND(4), {0xFF, 0x03, 0x00, 0x01}},//01
+ {LCM_SEND(4), {0xF3, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xF3, 0x03, 0x00, 0x15}},
+ {LCM_SEND(4), {0xF0, 0x00, 0x00, 0x55}}, //Manufacture Command Set Control
+ {LCM_SEND(4), {0xF0, 0x01, 0x00, 0xAA}},
+ {LCM_SEND(4), {0xF0, 0x02, 0x00, 0x52}},
+ {LCM_SEND(4), {0xF0, 0x03, 0x00, 0x08}},
+ {LCM_SEND(4), {0xF0, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xB8, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xB8, 0x01, 0x00, 0x02}},
+ {LCM_SEND(4), {0xB8, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xB8, 0x03, 0x00, 0x02}},
+ {LCM_SEND(4), {0xBC, 0x00, 0x00, 0x05}}, //Zig-Zag Inversion
+ {LCM_SEND(4), {0xBC, 0x01, 0x00, 0x05}},
+ {LCM_SEND(4), {0xBC, 0x02, 0x00, 0x05}},
+ {LCM_SEND(4), {0x4C, 0x00, 0x00, 0x11}}, //DB4=1,Enable Vivid Color,DB4=0 Disable Vivid Color
+ {LCM_SEND(4), {0xF0, 0x00, 0x00, 0x55}}, //Manufacture Command Set Control
+ {LCM_SEND(4), {0xF0, 0x01, 0x00, 0xAA}},
+ {LCM_SEND(4), {0xF0, 0x02, 0x00, 0x52}},
+ {LCM_SEND(4), {0xF0, 0x03, 0x00, 0x08}},
+ {LCM_SEND(4), {0xF0, 0x04, 0x00, 0x01}},//Page1
+ {LCM_SEND(4), {0xB0, 0x00, 0x00, 0x05}}, // Setting AVDD Voltage 6V
+ {LCM_SEND(4), {0xB0, 0x01, 0x00, 0x05}},
+ {LCM_SEND(4), {0xB0, 0x02, 0x00, 0x05}},
+ {LCM_SEND(4), {0xB6, 0x00, 0x00, 0x44}}, // Setting AVEE boosting time 2.5*vpnl
+ {LCM_SEND(4), {0xB6, 0x01, 0x00, 0x44}},
+ {LCM_SEND(4), {0xB6, 0x02, 0x00, 0x44}},
+ {LCM_SEND(4), {0xB1, 0x00, 0x00, 0x05}}, // Setting AVEE Voltage -6V
+ {LCM_SEND(4), {0xB1, 0x01, 0x00, 0x05}},
+ {LCM_SEND(4), {0xB1, 0x02, 0x00, 0x05}},
+ {LCM_SEND(4), {0xB7, 0x00, 0x00, 0x34}},
+ {LCM_SEND(4), {0xB7, 0x01, 0x00, 0x34}},
+ {LCM_SEND(4), {0xB7, 0x02, 0x00, 0x34}},
+ {LCM_SEND(4), {0xBA, 0x00, 0x00, 0x14}}, //0x24 --> 0x14
+ {LCM_SEND(4), {0xBA, 0x01, 0x00, 0x14}},
+ {LCM_SEND(4), {0xBA, 0x02, 0x00, 0x14}},
+ {LCM_SEND(4), {0xBC, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xBC, 0x01, 0x00, 0xA0}},//VGMP 0x88=4.7V 0x78=4.5V 0xA0=5.0V
+ {LCM_SEND(4), {0xBC, 0x02, 0x00, 0x00}},//VGSP
+ {LCM_SEND(4), {0xBD, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xBD, 0x01, 0x00, 0xA0}},//VGMN 0x88=-4.7V 0x78=-4.5V 0xA0=-5.0V
+ {LCM_SEND(4), {0xBD, 0x02, 0x00, 0x00}},//VGSN
+ {LCM_SEND(4), {0xBE, 0x00, 0x00, 0x57}}, // Setting VCOM Offset Voltage 0x4E¸ÄΪ0x57 20111019 LIYAN
+ {LCM_SEND(4), {0xD1, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x01, 0x00, 0x32}},
+ {LCM_SEND(4), {0xD1, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xD1, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xD1, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xD1, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xD1, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xD1, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xD1, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD1, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xD2, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xD2, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xD2, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xD2, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xD2, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD2, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xD2, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD2, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xD2, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD2, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xD3, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD3, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xD3, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD3, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xD3, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD3, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xD3, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD3, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xD3, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD3, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xD3, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD3, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xD3, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD3, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xD3, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD3, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xD4, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD4, 0x01, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xD4, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD4, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0xD5, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x01, 0x00, 0x37}},
+ {LCM_SEND(4), {0xD5, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xD5, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xD5, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xD5, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xD5, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xD5, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xD5, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD5, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xD6, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xD6, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xD6, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xD6, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xD6, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xD6, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xD6, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD6, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xD6, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD6, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xD7, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD7, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xD7, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD7, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xD7, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD7, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xD7, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD7, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xD7, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xD7, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xD7, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD7, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xD7, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD7, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xD7, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD7, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xD8, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD8, 0x01, 0x00, 0xA0}},
+ {LCM_SEND(4), {0xD8, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xD8, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0xD9, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x01, 0x00, 0x32}},
+ {LCM_SEND(4), {0xD9, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xD9, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xD9, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xD9, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xD9, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xD9, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xD9, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xD9, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xDD, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xDD, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xDD, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xDD, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xDD, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xDD, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xDD, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDD, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xDD, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDD, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xDE, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDE, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xDE, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDE, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xDE, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDE, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xDE, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDE, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xDE, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xDE, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xDE, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xDE, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xDE, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xDE, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xDE, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xDE, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xDF, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xDF, 0x01, 0x00, 0xA0}},
+ {LCM_SEND(4), {0xDF, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xDF, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0xE0, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x01, 0x00, 0x32}},
+ {LCM_SEND(4), {0xE0, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xE0, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xE0, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xE0, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xE0, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xE0, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xE0, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE0, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xE1, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xE1, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xE1, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xE1, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xE1, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE1, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xE1, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE1, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xE1, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE1, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xE2, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE2, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xE2, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE2, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xE2, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE2, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xE2, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE2, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xE2, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE2, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xE2, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE2, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xE2, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE2, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xE2, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE2, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xE3, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE3, 0x01, 0x00, 0xA0}},
+ {LCM_SEND(4), {0xE3, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE3, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0xE4, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x01, 0x00, 0x32}},
+ {LCM_SEND(4), {0xE4, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xE4, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xE4, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xE4, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xE4, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xE4, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xE4, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE4, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xE5, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xE5, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xE5, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xE5, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xE5, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE5, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xE5, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE5, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xE5, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE5, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xE6, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE6, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xE6, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE6, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xE6, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE6, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xE6, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE6, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xE6, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE6, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xE6, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE6, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xE6, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE6, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xE6, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE6, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xE7, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE7, 0x01, 0x00, 0xA0}},
+ {LCM_SEND(4), {0xE7, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xE7, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0xE8, 0x00, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x01, 0x00, 0x32}},
+ {LCM_SEND(4), {0xE8, 0x02, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x03, 0x00, 0x41}},
+ {LCM_SEND(4), {0xE8, 0x04, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x05, 0x00, 0x54}},
+ {LCM_SEND(4), {0xE8, 0x06, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x07, 0x00, 0x67}},
+ {LCM_SEND(4), {0xE8, 0x08, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x09, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xE8, 0x0A, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x0B, 0x00, 0x98}},
+ {LCM_SEND(4), {0xE8, 0x0C, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x0D, 0x00, 0xB0}},
+ {LCM_SEND(4), {0xE8, 0x0E, 0x00, 0x00}},
+ {LCM_SEND(4), {0xE8, 0x0F, 0x00, 0xDB}},
+ {LCM_SEND(4), {0xE9, 0x00, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x01, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x02, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x03, 0x00, 0x3F}},
+ {LCM_SEND(4), {0xE9, 0x04, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x05, 0x00, 0x70}},
+ {LCM_SEND(4), {0xE9, 0x06, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x07, 0x00, 0xB4}},
+ {LCM_SEND(4), {0xE9, 0x08, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x09, 0x00, 0xEC}},
+ {LCM_SEND(4), {0xE9, 0x0A, 0x00, 0x01}},
+ {LCM_SEND(4), {0xE9, 0x0B, 0x00, 0xED}},
+ {LCM_SEND(4), {0xE9, 0x0C, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE9, 0x0D, 0x00, 0x1E}},
+ {LCM_SEND(4), {0xE9, 0x0E, 0x00, 0x02}},
+ {LCM_SEND(4), {0xE9, 0x0F, 0x00, 0x51}},
+ {LCM_SEND(4), {0xEA, 0x00, 0x00, 0x02}},
+ {LCM_SEND(4), {0xEA, 0x01, 0x00, 0x6C}},
+ {LCM_SEND(4), {0xEA, 0x02, 0x00, 0x02}},
+ {LCM_SEND(4), {0xEA, 0x03, 0x00, 0x8D}},
+ {LCM_SEND(4), {0xEA, 0x04, 0x00, 0x02}},
+ {LCM_SEND(4), {0xEA, 0x05, 0x00, 0xA5}},
+ {LCM_SEND(4), {0xEA, 0x06, 0x00, 0x02}},
+ {LCM_SEND(4), {0xEA, 0x07, 0x00, 0xC9}},
+ {LCM_SEND(4), {0xEA, 0x08, 0x00, 0x02}},
+ {LCM_SEND(4), {0xEA, 0x09, 0x00, 0xEA}},
+ {LCM_SEND(4), {0xEA, 0x0A, 0x00, 0x03}},
+ {LCM_SEND(4), {0xEA, 0x0B, 0x00, 0x19}},
+ {LCM_SEND(4), {0xEA, 0x0C, 0x00, 0x03}},
+ {LCM_SEND(4), {0xEA, 0x0D, 0x00, 0x45}},
+ {LCM_SEND(4), {0xEA, 0x0E, 0x00, 0x03}},
+ {LCM_SEND(4), {0xEA, 0x0F, 0x00, 0x7A}},
+ {LCM_SEND(4), {0xEB, 0x00, 0x00, 0x03}},
+ {LCM_SEND(4), {0xEB, 0x01, 0x00, 0xA0}},
+ {LCM_SEND(4), {0xEB, 0x02, 0x00, 0x03}},
+ {LCM_SEND(4), {0xEB, 0x03, 0x00, 0xF4}},
+ {LCM_SEND(4), {0x3A, 0x00, 0x00, 0x07}},
+ {LCM_SEND(4), {0x35, 0x00, 0x00, 0x00}},
+
+ {LCM_SEND(2), {0x11, 0x00}},
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(2), {0x29, 0x00}};
+
+#if 0
+LCD_ERR_E Set_NT35516_I2C_Read(uint16 addr, uint32 addr_len, uint16* data, uint32 data_len)
+{
+ uint32 rtn=LCD_ERR_NONE;
+ uint8 cmd[2]={0x00};
+ uint8 value[4]={0x00};
+ //uint8 value=0;
+
+ cmd[0]=(uint8)((addr>>0x08)&0xff);
+ cmd[1]=(uint8)(addr&0xff);
+
+ rtn=I2C_WriteCmdArr(NT35516_I2C_ADDR, cmd, addr_len, NT35516_I2C_ACK);
+ rtn=I2C_ReadCmdArr(NT35516_I2C_ADDR, value, data_len,NT35516_I2C_ACK );
+
+ *data=(value[0]<<0x08)|value[1];
+ // *data = value;
+ return rtn;
+}
+#endif
+
+static int32_t nt35516_rgb_i2c_init(struct panel_spec *self)
+{
+ unsigned int i = 0;
+ unsigned int tag;
+ uint16_t data=0x00;
+ uint16_t data1=0x00;
+ uint16_t data2=0x00;
+ LCM_Init_Code *init = init_data;
+
+ i2c_write_8bits_t i2c_write_8bits = self->info.rgb->bus_info.i2c->ops->i2c_write_8bits;
+ i2c_read_8bits_t i2c_read_8bits = self->info.rgb->bus_info.i2c->ops->i2c_read_8bits;
+ i2c_write_16bits_t i2c_write_16bits = self->info.rgb->bus_info.i2c->ops->i2c_write_16bits;
+ i2c_read_16bits_t i2c_read_16bits = self->info.rgb->bus_info.i2c->ops->i2c_read_16bits;
+ i2c_write_burst_t i2c_write_burst = self->info.rgb->bus_info.i2c->ops->i2c_write_burst;
+
+ printk(KERN_DEBUG "nt35516_rgb_i2c_init\n");
+
+
+ // Set_NT35516_I2C_Read(LCDI2C_ID_ADDR, 2, &data, 2);
+ i2c_read_16bits(0xda00, false, &data, false);
+ i2c_read_16bits(0xdb00, false, &data1, false);
+ i2c_read_16bits(0xdc00, false, &data2, false);
+
+ for (i = 0 ; i < ARRAY_SIZE(init_data); i++ ) {
+ tag = (init->tag >> 24);
+ if (tag & LCM_TAG_SEND) {
+ Set_NT35516_I2C_Send((init->tag & LCM_TAG_MASK) , init->data);
+ printk(KERN_DEBUG "send one i2c data!\n");
+ } else if (tag & LCM_TAG_SLEEP) {
+ udelay((init->tag & LCM_TAG_MASK)*1000);
+ printk(KERN_DEBUG "delay!\n");
+ }
+ init++;
+ }
+ udelay(200);
+ // while(1)
+ // {
+ printk(KERN_DEBUG "send disp_on!\n");
+ Set_NT35516_I2C_Send((disp_on.tag & LCM_TAG_MASK) , disp_on.data);
+ // }
+
+ //I2C_ReadCmd(0xDB00,pCmd,NT35516_I2C_ACK);
+ //Set_NT35516_I2C_Read(0xdb00, 2, &data, 2);
+ printk(KERN_DEBUG "nt35516_rgb_i2c_init finish\n");
+
+ return 0;
+}
+
+static uint32_t nt35516_rgb_i2c_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ return 0x16;
+}
+
+#if 0
+void NT35516_RGB_I2C_set_display_window(
+ uint16 left, // start Horizon address
+ uint16 right, // end Horizon address
+ uint16 top, // start Vertical address
+ uint16 bottom // end Vertical address
+ )
+{
+ unsigned char data[4];
+ data[0] = 0x2A;
+ data[1] = 0x00; data[2] = (left>>8);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x01; data[2] = (left&0xff);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x02; data[2] = (right>>8);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x03; data[2] = (right&0xff);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[0] = 0x2B;
+
+ data[1] = 0x00; data[2] = (top>>8);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x01; data[2] = (top&0xff);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x02; data[2] = (bottom>>8);
+ Set_NT35516_I2C_Send(3, data);
+
+ data[1] = 0x03; data[2] = (bottom&0xff);
+ Set_NT35516_I2C_Send(3, data);
+
+}
+
+LCD_ERR_E NT35516_RGB_I2C_EnterSleep(BOOLEAN is_sleep)
+{
+ unsigned char data[4];
+ if(is_sleep==1)
+ {
+ data[0] = 0x28;data[1] = 0x00;
+ Set_NT35516_I2C_Send(2, data);
+ LCD_Delay(200);
+
+ data[0] = 0x10;data[1] = 0x00;
+ Set_NT35516_I2C_Send(2, data);
+ LCD_Delay(200);
+ //Lcd_EnvidOnOff(0);//RGB TIMENG OFF
+ //LCD_Delay(200);
+ }
+ else
+ {
+ //Lcd_EnvidOnOff(1);//RGB TIMENG ON
+ //LCD_Delay(200);
+ //LCDinit_TFT();
+ //LCD_Delay(200);
+
+ }
+
+ return 0;
+}
+
+LCD_ERR_E NT35516_RGB_I2C_SetDisplayWindow(
+ uint16 left, //left of the window
+ uint16 top, //top of the window
+ uint16 right, //right of the window
+ uint16 bottom //bottom of the window
+ )
+{
+ unsigned char data[4];
+ //NT35516_RGB_I2C_set_display_window(left, right, top, bottom);
+ data[0] = 0x2C; data[1] = 0x00;
+ Set_NT35516_I2C_Send(2, data);
+ return TRUE;
+}
+#endif
+
+
+
+static struct panel_operations lcd_nt35516_rgb_i2c_operations = {
+ .panel_init = nt35516_rgb_i2c_init,
+ .panel_readid = nt35516_rgb_i2c_readid,
+};
+
+static struct timing_rgb lcd_nt35516_rgb_timing = {
+ .hfp = 16, /* unit: pixel */
+ .hbp = 16,
+ .hsync = 1,
+ .vfp = 16, /*unit: line*/
+ .vbp = 16,
+ .vsync = 1,
+};
+
+static struct i2c_info lcd_nt35516_rgb_i2c_info = {
+ .i2c_addr = NT35516_I2C_ADDR,
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_nt35516_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_I2C,
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_NEG, //SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_NEG, //SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_nt35516_rgb_timing,
+ .bus_info = {
+ .i2c = &lcd_nt35516_rgb_i2c_info,
+ }
+};
+
+struct panel_spec lcd_nt35516_rgb_i2c_spec = {
+ .width = 540,
+ .height = 960,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .rgb = &lcd_nt35516_rgb_info
+ },
+ .ops = &lcd_nt35516_rgb_i2c_operations,
+};
+
+struct panel_cfg lcd_nt35516_rgb_i2c = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x16,
+ .lcd_name = "lcd_nt35516_rgb_i2c",
+ .panel = &lcd_nt35516_rgb_i2c_spec,
+};
+
+static int __init lcd_nt35516_rgb_i2c_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35516_rgb_i2c);
+}
+
+subsys_initcall(lcd_nt35516_rgb_i2c_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_spi.c b/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_spi.c
new file mode 100755
index 00000000..0ca42500
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35516_rgb_spi.c
@@ -0,0 +1,624 @@
+/* drivers/video/sc8825/lcd_nt35516_spi.c
+ *
+ * Support for nt35516 spi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+#define NT35516_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define NT35516_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+
+static int32_t nt35516_rgb_spi_init(struct panel_spec *self)
+{
+ uint32_t data = 0;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+ // NT35516 + AUO 4.29'
+ // VCC=IOVCC=3.3V RGB_24Bit
+
+ //NT35516_SpiWriteCmd(0xDB00);
+ //spi_read(&data);
+
+ //TEST Commands
+
+ NT35516_SpiWriteCmd(0xFF);
+ NT35516_SpiWriteData(0xAA);//AA
+ NT35516_SpiWriteData(0x55);//55
+ NT35516_SpiWriteData(0x25);//08
+ NT35516_SpiWriteData(0x01);//01
+
+ //NT35516_SpiWriteCmd(0xFA0F); NT35516_SpiWriteData(0x20);
+
+ //NT35516_SpiWriteCmd(0xF300); NT35516_SpiWriteData(0x02);
+ //NT35516_SpiWriteCmd(0xF303); NT35516_SpiWriteData(0x15);
+
+ //ENABLE PAGE 0
+ NT35516_SpiWriteCmd(0xF0);
+ NT35516_SpiWriteData(0x55); //Manufacture Command Set Control
+ NT35516_SpiWriteData(0xAA);
+ NT35516_SpiWriteData(0x52);
+ NT35516_SpiWriteData(0x08);
+ NT35516_SpiWriteData(0x00);
+
+ NT35516_SpiWriteCmd(0xB8);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x02);
+
+ //NT35516_SpiWriteCmd(0xBC00); NT35516_SpiWriteData(0x05); //Zig-Zag Inversion
+ //NT35516_SpiWriteCmd(0xBC01); NT35516_SpiWriteData(0x05);
+ //NT35516_SpiWriteCmd(0xBC02); NT35516_SpiWriteData(0x05);
+
+ //NT35516_SpiWriteCmd(0x4C00); NT35516_SpiWriteData(0x11); //DB4=1,Enable Vivid Color,DB4=0 Disable Vivid Color
+
+ // ENABLE PAGE 1
+ NT35516_SpiWriteCmd(0xF0);
+ NT35516_SpiWriteData(0x55); //Manufacture Command Set Control
+ NT35516_SpiWriteData(0xAA);
+ NT35516_SpiWriteData(0x52);
+ NT35516_SpiWriteData(0x08);
+ NT35516_SpiWriteData(0x01);//Page1
+
+ NT35516_SpiWriteCmd(0xB0);
+ NT35516_SpiWriteData(0x05); // Setting AVDD Voltage 6V
+ NT35516_SpiWriteData(0x05);
+ NT35516_SpiWriteData(0x05);
+
+ NT35516_SpiWriteCmd(0xB6);
+ NT35516_SpiWriteData(0x44); // Setting AVEE boosting time 2.5*vpnl
+ NT35516_SpiWriteData(0x44);
+ NT35516_SpiWriteData(0x44);
+
+ NT35516_SpiWriteCmd(0xB1);
+ NT35516_SpiWriteData(0x05); // Setting AVEE Voltage -6V
+ NT35516_SpiWriteData(0x05);
+ NT35516_SpiWriteData(0x05);
+
+ //Setting AVEE boosting time -2.5xVPNL
+ NT35516_SpiWriteCmd(0xB7);
+ NT35516_SpiWriteData(0x34);
+ NT35516_SpiWriteData(0x34);
+ NT35516_SpiWriteData(0x34);
+
+ //Setting VGLX boosting time AVEE-AVDD
+ NT35516_SpiWriteCmd(0xBA);
+ NT35516_SpiWriteData(0x14); //0x24 --> 0x14
+ NT35516_SpiWriteData(0x14);
+ NT35516_SpiWriteData(0x14);
+
+ //Gamma Voltage
+ NT35516_SpiWriteCmd(0xBC);
+ NT35516_SpiWriteData(0x00);
+NT35516_SpiWriteData(0xA0);//VGMP 0x88=4.7V 0x78=4.5V 0xA0=5.0V
+NT35516_SpiWriteData(0x00);//VGSP
+
+ //Gamma Voltage
+ NT35516_SpiWriteCmd(0xBD);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xA0);//VGMN 0x88=-4.7V 0x78=-4.5V 0xA0=-5.0V
+ NT35516_SpiWriteData(0x00);//VGSN
+
+ NT35516_SpiWriteCmd(0xBE);
+ NT35516_SpiWriteData(0x57); // Setting VCOM Offset Voltage 0x4E¸ÄΪ0x57 20111019 LIYAN
+
+ //GAMMA RED Positive
+ NT35516_SpiWriteCmd(0xD1);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x32);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xD2);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xD3);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xD4);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ //Positive Gamma for GREEN
+ NT35516_SpiWriteCmd(0xD5);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x37);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xD6);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xD7);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xD8);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xA0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ //Positive Gamma for BLUE
+ NT35516_SpiWriteCmd(0xD9);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x32);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xDD);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xDE);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xDF);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xA0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ //Negative Gamma for RED
+ NT35516_SpiWriteCmd(0xE0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x32);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xE1);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xE2);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xE3);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xA0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ //Negative Gamma for GERREN
+ NT35516_SpiWriteCmd(0xE4);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x32);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xE5);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xE6);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xE7);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xA0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ //Negative Gamma for BLUE
+ NT35516_SpiWriteCmd(0xE8);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x32);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x41);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x54);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x67);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x7A);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0x98);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xB0);
+ NT35516_SpiWriteData(0x00);
+ NT35516_SpiWriteData(0xDB);
+
+ NT35516_SpiWriteCmd(0xE9);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x3F);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0x70);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xB4);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xEC);
+ NT35516_SpiWriteData(0x01);
+ NT35516_SpiWriteData(0xED);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x1E);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x51);
+
+ NT35516_SpiWriteCmd(0xEA);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x6C);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0x8D);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xA5);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xC9);
+ NT35516_SpiWriteData(0x02);
+ NT35516_SpiWriteData(0xEA);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x19);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x45);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0x7A);
+
+ NT35516_SpiWriteCmd(0xEB);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xA0);
+ NT35516_SpiWriteData(0x03);
+ NT35516_SpiWriteData(0xF4);
+
+ NT35516_SpiWriteCmd(0x3A); NT35516_SpiWriteData(0x77);
+
+ NT35516_SpiWriteCmd(0x35); NT35516_SpiWriteData(0x00);
+
+ NT35516_SpiWriteCmd(0x11); // Sleep out
+ mdelay(140);
+
+ NT35516_SpiWriteCmd(0x29); // Display On
+ mdelay(10);
+}
+
+static uint32_t nt35516_rgb_spi_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ return 0x16;
+}
+
+#if 0
+void NT35516_RGB_SPI_set_display_window(
+ uint16 left, // start Horizon address
+ uint16 right, // end Horizon address
+ uint16 top, // start Vertical address
+ uint16 bottom // end Vertical address
+ )
+{
+ NT35516_SpiWriteCmd(0x2A00); NT35516_SpiWriteData((left>>8));// set left address
+ NT35516_SpiWriteCmd(0x2A01); NT35516_SpiWriteData((left&0xff));
+ NT35516_SpiWriteCmd(0x2A02); NT35516_SpiWriteData((right>>8));// set right address
+ NT35516_SpiWriteCmd(0x2A03); NT35516_SpiWriteData((right&0xff));
+
+ NT35516_SpiWriteCmd(0x2B00); NT35516_SpiWriteData((top>>8));// set left address
+ NT35516_SpiWriteCmd(0x2B01); NT35516_SpiWriteData((top&0xff));
+ NT35516_SpiWriteCmd(0x2B02); NT35516_SpiWriteData((bottom>>8));// set bottom address
+ NT35516_SpiWriteCmd(0x2B03); NT35516_SpiWriteData((bottom&0xff));
+}
+
+LCD_ERR_E NT35516_RGB_SPI_EnterSleep(BOOLEAN is_sleep)
+{
+ if(is_sleep==1)
+ {
+ NT35516_SpiWriteCmd(0x28);
+ LCD_Delay(200);
+ NT35516_SpiWriteCmd(0x10);
+ LCD_Delay(200);
+ //Lcd_EnvidOnOff(0);//RGB TIMENG OFF
+ //LCD_Delay(200);
+
+ }
+ else
+ {
+ //Lcd_EnvidOnOff(1);//RGB TIMENG ON
+ //LCD_Delay(200);
+ //LCDinit_TFT();
+ //LCD_Delay(200);
+
+ }
+
+ return 0;
+}
+
+LCD_ERR_E NT35516_RGB_SPI_SetDisplayWindow(
+ uint16 left, //left of the window
+ uint16 top, //top of the window
+ uint16 right, //right of the window
+ uint16 bottom //bottom of the window
+ )
+{
+ //NT35516_RGB_SPI_set_display_window(left, right, top, bottom);
+
+ NT35516_SpiWriteCmd(0x2C);
+ return TRUE;
+}
+#endif
+
+
+static struct panel_operations lcd_nt35516_rgb_spi_operations = {
+ .panel_init = nt35516_rgb_spi_init,
+ .panel_readid = nt35516_rgb_spi_readid,
+};
+
+static struct timing_rgb lcd_nt35516_rgb_timing = {
+ .hfp = 30, /* unit: pixel */
+ .hbp = 16,
+ .hsync = 1,
+ .vfp = 16, /*unit: line*/
+ .vbp = 16,
+ .vsync = 1,
+};
+
+static struct spi_info lcd_nt35516_rgb_spi_info = {
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_nt35516_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_SPI,
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_nt35516_rgb_timing,
+ .bus_info = {
+ .spi = &lcd_nt35516_rgb_spi_info,
+ }
+};
+
+struct panel_spec lcd_nt35516_rgb_spi_spec = {
+ .width = 540,
+ .height = 960,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+#ifdef CONFIG_FB_SCX15
+ .fps = 56,
+#endif
+ .info = {
+ .rgb = &lcd_nt35516_rgb_info
+ },
+ .ops = &lcd_nt35516_rgb_spi_operations,
+};
+
+struct panel_cfg lcd_nt35516_rgb_spi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x16,
+ .lcd_name = "lcd_nt35516_rgb_spi",
+ .panel = &lcd_nt35516_rgb_spi_spec,
+};
+static int __init lcd_nt35516_rgb_spi_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35516_rgb_spi);
+}
+
+subsys_initcall(lcd_nt35516_rgb_spi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt35596h_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt35596h_mipi.c
new file mode 100644
index 00000000..ea7da76f
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt35596h_mipi.c
@@ -0,0 +1,841 @@
+/* drivers/video/sprdfb/lcd_nt35516_mipi.c
+ *
+ * Support for nt35516 mipi LCD device
+ *
+ * Copyright (C) 2015 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+
+#define MAX_DATA 10
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+{LCM_SEND(2), {0xFF,0x05}},
+{LCM_SEND(2), {0xFB,0x01}},
+{LCM_SEND(2), {0xc5,0x01}}, //Turn On NT50198
+
+{LCM_SLEEP(25)},
+{LCM_SEND(2), {0xFF,0xEE}},
+{LCM_SEND(2), {0xFB,0x01}},
+{LCM_SEND(2), {0x1F,0x45}},
+{LCM_SEND(2), {0x24,0x4F}},
+{LCM_SEND(2), {0x38,0xC8}},
+{LCM_SEND(2), {0x39,0x2C}},
+{LCM_SEND(2), {0x1E,0xBB}},
+{LCM_SEND(2), {0x1D,0x0F}},
+{LCM_SEND(2), {0x7E,0xB1}},
+{LCM_SEND(2), {0xFF,0x00}},
+{LCM_SEND(2), {0xFB,0x01}},
+{LCM_SEND(2), {0x35,0x01}},
+{LCM_SEND(2), {0xFF,0x01}},
+{LCM_SEND(2), {0xFB,0x01}},
+{LCM_SEND(2), {0x00,0x01}},
+{LCM_SEND(2), {0x01,0x55}},
+{LCM_SEND(2), {0x02,0x40}},
+{LCM_SEND(2), {0x05,0x40}},
+{LCM_SEND(2), {0x06,0x4A}},
+{LCM_SEND(2), {0x07,0x24}},
+{LCM_SEND(2), {0x08,0x0C}},
+{LCM_SEND(2), {0x0B,0x87}},
+{LCM_SEND(2), {0x0C,0x87}},
+{LCM_SEND(2), {0x0E,0xB0}},
+{LCM_SEND(2), {0x0F,0xB3}},
+{LCM_SEND(2), {0x11,0x10}},
+{LCM_SEND(2), {0x12,0x10}},
+{LCM_SEND(2), {0x13,0x05}},
+{LCM_SEND(2), {0x14,0x4A}},
+{LCM_SEND(2), {0x15,0x18}},
+{LCM_SEND(2), {0x16,0x18}},
+{LCM_SEND(2), {0x18,0x00}},
+{LCM_SEND(2), {0x19,0x77}},
+{LCM_SEND(2), {0x1A,0x55}},
+{LCM_SEND(2), {0x1B,0x13}},
+{LCM_SEND(2), {0x1C,0x00}},
+{LCM_SEND(2), {0x1D,0x00}},
+{LCM_SEND(2), {0x1E,0x13}},
+{LCM_SEND(2), {0x1F,0x00}},
+{LCM_SEND(2), {0x23,0x00}},
+{LCM_SEND(2), {0x24,0x00}},
+{LCM_SEND(2), {0x25,0x00}},
+{LCM_SEND(2), {0x26,0x00}},
+{LCM_SEND(2), {0x27,0x00}},
+{LCM_SEND(2), {0x28,0x00}},
+{LCM_SEND(2), {0x35,0x00}},
+{LCM_SEND(2), {0x66,0x00}},
+{LCM_SEND(2), {0x58,0x82}},
+{LCM_SEND(2), {0x59,0x02}},
+{LCM_SEND(2), {0x5a,0x02}},
+{LCM_SEND(2), {0x5B,0x02}},
+{LCM_SEND(2), {0x5C,0x82}},
+{LCM_SEND(2), {0x5D,0x82}},
+{LCM_SEND(2), {0x5E,0x02}},
+{LCM_SEND(2), {0x5F,0x02}},
+{LCM_SEND(2), {0x72,0x31}},
+{LCM_SEND(2), {0xFF,0x05}},
+{LCM_SEND(2), {0xFB,0x01}},
+{LCM_SEND(2), {0x00,0x01}},
+{LCM_SEND(2), {0x01,0x0B}},
+{LCM_SEND(2), {0x02,0x0C}},
+{LCM_SEND(2), {0x03,0x09}},
+{LCM_SEND(2), {0x04,0x0a}},
+{LCM_SEND(2), {0x05,0x00}},
+{LCM_SEND(2), {0x06,0x0F}},
+{LCM_SEND(2), {0x07,0x10}},
+{LCM_SEND(2), {0x08,0x00}},
+{LCM_SEND(2), {0x09,0x00}},
+{LCM_SEND(2), {0x0A,0x00}},
+{LCM_SEND(2), {0x0B,0x00}},
+{LCM_SEND(2), {0x0C,0x00}},
+{LCM_SEND(2), {0x0d,0x13}},
+{LCM_SEND(2), {0x0e,0x15}},
+{LCM_SEND(2), {0x0f,0x17}},
+{LCM_SEND(2), {0x10,0x01}},
+{LCM_SEND(2), {0x11,0x0b}},
+{LCM_SEND(2), {0x12,0x0c}},
+{LCM_SEND(2), {0x13,0x09}},
+{LCM_SEND(2), {0x14,0x0a}},
+{LCM_SEND(2), {0x15,0x00}},
+{LCM_SEND(2), {0x16,0x0f}},
+{LCM_SEND(2), {0x17,0x10}},
+{LCM_SEND(2), {0x18,0x00}},
+{LCM_SEND(2), {0x19,0x00}},
+{LCM_SEND(2), {0x1a,0x00}},
+{LCM_SEND(2), {0x1b,0x00}},
+{LCM_SEND(2), {0x1c,0x00}},
+{LCM_SEND(2), {0x1d,0x13}},
+{LCM_SEND(2), {0x1e,0x15}},
+{LCM_SEND(2), {0x1f,0x17}},
+{LCM_SEND(2), {0x20,0x00}},
+{LCM_SEND(2), {0x21,0x03}},
+{LCM_SEND(2), {0x22,0x01}},
+{LCM_SEND(2), {0x23,0x40}},
+{LCM_SEND(2), {0x24,0x40}},
+{LCM_SEND(2), {0x25,0xed}},
+{LCM_SEND(2), {0x29,0x58}},
+{LCM_SEND(2), {0x2a,0x12}},
+{LCM_SEND(2), {0x2b,0x01}},
+{LCM_SEND(2), {0x4b,0x06}},
+{LCM_SEND(2), {0x4c,0x11}},
+{LCM_SEND(2), {0x4d,0x20}},
+{LCM_SEND(2), {0x4e,0x02}},
+{LCM_SEND(2), {0x4f,0x02}},
+{LCM_SEND(2), {0x50,0x20}},
+{LCM_SEND(2), {0x51,0x61}},
+{LCM_SEND(2), {0x52,0x01}},
+{LCM_SEND(2), {0x53,0x63}},
+{LCM_SEND(2), {0x54,0x77}},
+{LCM_SEND(2), {0x55,0xed}},
+{LCM_SEND(2), {0x5b,0x00}},
+{LCM_SEND(2), {0x5c,0x00}},
+{LCM_SEND(2), {0x5d,0x00}},
+{LCM_SEND(2), {0x5e,0x00}},
+{LCM_SEND(2), {0x5f,0x15}},
+{LCM_SEND(2), {0x60,0x75}},
+{LCM_SEND(2), {0x61,0x00}},
+{LCM_SEND(2), {0x62,0x00}},
+{LCM_SEND(2), {0x63,0x00}},
+{LCM_SEND(2), {0x64,0x00}},
+{LCM_SEND(2), {0x65,0x00}},
+{LCM_SEND(2), {0x66,0x00}},
+{LCM_SEND(2), {0x67,0x00}},
+{LCM_SEND(2), {0x68,0x04}},
+{LCM_SEND(2), {0x69,0x00}},
+{LCM_SEND(2), {0x6a,0x00}},
+{LCM_SEND(2), {0x6c,0x40}},
+{LCM_SEND(2), {0x75,0x01}},
+{LCM_SEND(2), {0x76,0x01}},
+{LCM_SEND(2), {0x7a,0x80}},
+{LCM_SEND(2), {0x7b,0xc5}},
+{LCM_SEND(2), {0x7c,0xd8}},
+{LCM_SEND(2), {0x7d,0x60}},
+{LCM_SEND(2), {0x7f,0x15}},
+{LCM_SEND(2), {0x80,0x81}},
+{LCM_SEND(2), {0x83,0x05}},
+{LCM_SEND(2), {0x93,0x08}},
+{LCM_SEND(2), {0x94,0x10}},
+{LCM_SEND(2), {0x8a,0x00}},
+{LCM_SEND(2), {0x9b,0x0f}},
+{LCM_SEND(2), {0xea,0xff}},
+{LCM_SEND(2), {0xec,0x00}},
+
+{LCM_SEND(2), {0xff,0x01}}, //GAMMA
+{LCM_SEND(2), {0xfb,0x01}},
+{LCM_SEND(2), {0x75,0x00}},
+{LCM_SEND(2), {0x76,0x18}},
+{LCM_SEND(2), {0x77,0x00}},
+{LCM_SEND(2), {0x78,0x38}},
+{LCM_SEND(2), {0x79,0x00}},
+{LCM_SEND(2), {0x7a,0x65}},
+{LCM_SEND(2), {0x7b,0x00}},
+{LCM_SEND(2), {0x7c,0x84}},
+{LCM_SEND(2), {0x7d,0x00}},
+{LCM_SEND(2), {0x7e,0x9b}},
+{LCM_SEND(2), {0x7f,0x00}},
+{LCM_SEND(2), {0x80,0xaf}},
+{LCM_SEND(2), {0x81,0x00}},
+{LCM_SEND(2), {0x82,0xc1}},
+{LCM_SEND(2), {0x83,0x00}},
+{LCM_SEND(2), {0x84,0xd2}},
+{LCM_SEND(2), {0x85,0x00}},
+{LCM_SEND(2), {0x86,0xdf}},
+{LCM_SEND(2), {0x87,0x01}},
+{LCM_SEND(2), {0x88,0x11}},
+{LCM_SEND(2), {0x89,0x01}},
+{LCM_SEND(2), {0x8a,0x38}},
+{LCM_SEND(2), {0x8b,0x01}},
+{LCM_SEND(2), {0x8c,0x76}},
+{LCM_SEND(2), {0x8d,0x01}},
+{LCM_SEND(2), {0x8e,0xa7}},
+{LCM_SEND(2), {0x8f,0x01}},
+{LCM_SEND(2), {0x90,0xf3}},
+{LCM_SEND(2), {0x91,0x02}},
+{LCM_SEND(2), {0x92,0x2f}},
+{LCM_SEND(2), {0x93,0x02}},
+{LCM_SEND(2), {0x94,0x30}},
+{LCM_SEND(2), {0x95,0x02}},
+{LCM_SEND(2), {0x96,0x66}},
+{LCM_SEND(2), {0x97,0x02}},
+{LCM_SEND(2), {0x98,0xa0}},
+{LCM_SEND(2), {0x99,0x02}},
+{LCM_SEND(2), {0x9a,0xc5}},
+{LCM_SEND(2), {0x9b,0x02}},
+{LCM_SEND(2), {0x9c,0xf8}},
+{LCM_SEND(2), {0x9d,0x03}},
+{LCM_SEND(2), {0x9e,0x1b}},
+{LCM_SEND(2), {0x9f,0x03}},
+{LCM_SEND(2), {0xa0,0x46}},
+{LCM_SEND(2), {0xa2,0x03}},
+{LCM_SEND(2), {0xa3,0x52}},
+{LCM_SEND(2), {0xa4,0x03}},
+{LCM_SEND(2), {0xa5,0x62}},
+{LCM_SEND(2), {0xa6,0x03}},
+{LCM_SEND(2), {0xa7,0x71}},
+{LCM_SEND(2), {0xa9,0x03}},
+{LCM_SEND(2), {0xaa,0x83}},
+{LCM_SEND(2), {0xab,0x03}},
+{LCM_SEND(2), {0xac,0x94}},
+{LCM_SEND(2), {0xad,0x03}},
+{LCM_SEND(2), {0xae,0xa3}},
+{LCM_SEND(2), {0xaf,0x03}},
+{LCM_SEND(2), {0xb0,0xad}},
+{LCM_SEND(2), {0xb1,0x03}},
+{LCM_SEND(2), {0xb2,0xcc}},
+{LCM_SEND(2), {0xb3,0x00}},
+{LCM_SEND(2), {0xb4,0x18}},
+{LCM_SEND(2), {0xb5,0x00}},
+{LCM_SEND(2), {0xb6,0x38}},
+{LCM_SEND(2), {0xb7,0x00}},
+{LCM_SEND(2), {0xb8,0x65}},
+{LCM_SEND(2), {0xb9,0x00}},
+{LCM_SEND(2), {0xba,0x84}},
+{LCM_SEND(2), {0xbb,0x00}},
+{LCM_SEND(2), {0xbc,0x9b}},
+{LCM_SEND(2), {0xbd,0x00}},
+{LCM_SEND(2), {0xbe,0xaf}},
+{LCM_SEND(2), {0xbf,0x00}},
+{LCM_SEND(2), {0xc0,0xc1}},
+{LCM_SEND(2), {0xc1,0x00}},
+{LCM_SEND(2), {0xc2,0xd2}},
+{LCM_SEND(2), {0xc3,0x00}},
+{LCM_SEND(2), {0xc4,0xdf}},
+{LCM_SEND(2), {0xc5,0x01}},
+{LCM_SEND(2), {0xc6,0x11}},
+{LCM_SEND(2), {0xc7,0x01}},
+{LCM_SEND(2), {0xc8,0x38}},
+{LCM_SEND(2), {0xc9,0x01}},
+{LCM_SEND(2), {0xca,0x76}},
+{LCM_SEND(2), {0xcb,0x01}},
+{LCM_SEND(2), {0xcc,0xa7}},
+{LCM_SEND(2), {0xcd,0x01}},
+{LCM_SEND(2), {0xce,0xf3}},
+{LCM_SEND(2), {0xcf,0x02}},
+{LCM_SEND(2), {0xd0,0x2f}},
+{LCM_SEND(2), {0xd1,0x02}},
+{LCM_SEND(2), {0xd2,0x30}},
+{LCM_SEND(2), {0xd3,0x02}},
+{LCM_SEND(2), {0xd4,0x66}},
+{LCM_SEND(2), {0xd5,0x02}},
+{LCM_SEND(2), {0xd6,0xa0}},
+{LCM_SEND(2), {0xd7,0x02}},
+{LCM_SEND(2), {0xd8,0xc5}},
+{LCM_SEND(2), {0xd9,0x02}},
+{LCM_SEND(2), {0xda,0xf8}},
+{LCM_SEND(2), {0xdb,0x03}},
+{LCM_SEND(2), {0xdc,0x1b}},
+{LCM_SEND(2), {0xdd,0x03}},
+{LCM_SEND(2), {0xde,0x46}},
+{LCM_SEND(2), {0xdf,0x03}},
+{LCM_SEND(2), {0xe0,0x52}},
+{LCM_SEND(2), {0xe1,0x03}},
+{LCM_SEND(2), {0xe2,0x62}},
+{LCM_SEND(2), {0xe3,0x03}},
+{LCM_SEND(2), {0xe4,0x71}},
+{LCM_SEND(2), {0xe5,0x03}},
+{LCM_SEND(2), {0xe6,0x83}},
+{LCM_SEND(2), {0xe7,0x03}},
+{LCM_SEND(2), {0xe8,0x94}},
+{LCM_SEND(2), {0xe9,0x03}},
+{LCM_SEND(2), {0xea,0xa3}},
+{LCM_SEND(2), {0xeb,0x03}},
+{LCM_SEND(2), {0xec,0xad}},
+{LCM_SEND(2), {0xed,0x03}},
+{LCM_SEND(2), {0xee,0xcc}},
+{LCM_SEND(2), {0xef,0x00}},
+{LCM_SEND(2), {0xf0,0x18}},
+{LCM_SEND(2), {0xf1,0x00}},
+{LCM_SEND(2), {0xf2,0x38}},
+{LCM_SEND(2), {0xf3,0x00}},
+{LCM_SEND(2), {0xf4,0x65}},
+{LCM_SEND(2), {0xf5,0x00}},
+{LCM_SEND(2), {0xf6,0x84}},
+{LCM_SEND(2), {0xf7,0x00}},
+{LCM_SEND(2), {0xf8,0x9b}},
+{LCM_SEND(2), {0xf9,0x00}},
+{LCM_SEND(2), {0xfa,0xaf}},
+{LCM_SEND(2), {0xff,0x02}},
+{LCM_SEND(2), {0xfb,0x01}},
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(2), {0x01,0xc1}},
+{LCM_SEND(2), {0x02,0x00}},
+{LCM_SEND(2), {0x03,0xd2}},
+{LCM_SEND(2), {0x04,0x00}},
+{LCM_SEND(2), {0x05,0xdf}},
+{LCM_SEND(2), {0x06,0x01}},
+{LCM_SEND(2), {0x07,0x11}},
+{LCM_SEND(2), {0x08,0x01}},
+{LCM_SEND(2), {0x09,0x38}},
+{LCM_SEND(2), {0x0a,0x01}},
+{LCM_SEND(2), {0x0b,0x76}},
+{LCM_SEND(2), {0x0c,0x01}},
+{LCM_SEND(2), {0x0d,0xa7}},
+{LCM_SEND(2), {0x0e,0x01}},
+{LCM_SEND(2), {0x0f,0xf3}},
+{LCM_SEND(2), {0x10,0x02}},
+{LCM_SEND(2), {0x11,0x2f}},
+{LCM_SEND(2), {0x12,0x02}},
+{LCM_SEND(2), {0x13,0x30}},
+{LCM_SEND(2), {0x14,0x02}},
+{LCM_SEND(2), {0x15,0x66}},
+{LCM_SEND(2), {0x16,0x02}},
+{LCM_SEND(2), {0x17,0xa0}},
+{LCM_SEND(2), {0x18,0x02}},
+{LCM_SEND(2), {0x19,0xc5}},
+{LCM_SEND(2), {0x1a,0x02}},
+{LCM_SEND(2), {0x1b,0xf8}},
+{LCM_SEND(2), {0x1c,0x03}},
+{LCM_SEND(2), {0x1d,0x1b}},
+{LCM_SEND(2), {0x1e,0x03}},
+{LCM_SEND(2), {0x1f,0x46}},
+{LCM_SEND(2), {0x20,0x03}},
+{LCM_SEND(2), {0x21,0x52}},
+{LCM_SEND(2), {0x22,0x03}},
+{LCM_SEND(2), {0x23,0x62}},
+{LCM_SEND(2), {0x24,0x03}},
+{LCM_SEND(2), {0x25,0x71}},
+{LCM_SEND(2), {0x26,0x03}},
+{LCM_SEND(2), {0x27,0x83}},
+{LCM_SEND(2), {0x28,0x03}},
+{LCM_SEND(2), {0x29,0x94}},
+{LCM_SEND(2), {0x2a,0x03}},
+{LCM_SEND(2), {0x2b,0xa3}},
+{LCM_SEND(2), {0x2d,0x03}},
+{LCM_SEND(2), {0x2f,0xad}},
+{LCM_SEND(2), {0x30,0x03}},
+{LCM_SEND(2), {0x31,0xcc}},
+{LCM_SEND(2), {0x32,0x00}},
+{LCM_SEND(2), {0x33,0x18}},
+{LCM_SEND(2), {0x34,0x00}},
+{LCM_SEND(2), {0x35,0x38}},
+{LCM_SEND(2), {0x36,0x00}},
+{LCM_SEND(2), {0x37,0x65}},
+{LCM_SEND(2), {0x38,0x00}},
+{LCM_SEND(2), {0x39,0x84}},
+{LCM_SEND(2), {0x3a,0x00}},
+{LCM_SEND(2), {0x3b,0x9b}},
+{LCM_SEND(2), {0x3d,0x00}},
+{LCM_SEND(2), {0x3f,0xaf}},
+{LCM_SEND(2), {0x40,0x00}},
+{LCM_SEND(2), {0x41,0xc1}},
+{LCM_SEND(2), {0x42,0x00}},
+{LCM_SEND(2), {0x43,0xd2}},
+{LCM_SEND(2), {0x44,0x00}},
+{LCM_SEND(2), {0x45,0xdf}},
+{LCM_SEND(2), {0x46,0x01}},
+{LCM_SEND(2), {0x47,0x11}},
+{LCM_SEND(2), {0x48,0x01}},
+{LCM_SEND(2), {0x49,0x38}},
+{LCM_SEND(2), {0x4a,0x01}},
+{LCM_SEND(2), {0x4b,0x76}},
+{LCM_SEND(2), {0x4c,0x01}},
+{LCM_SEND(2), {0x4d,0xa7}},
+{LCM_SEND(2), {0x4e,0x01}},
+{LCM_SEND(2), {0x4f,0xf3}},
+{LCM_SEND(2), {0x50,0x02}},
+{LCM_SEND(2), {0x51,0x2f}},
+{LCM_SEND(2), {0x52,0x02}},
+{LCM_SEND(2), {0x53,0x30}},
+{LCM_SEND(2), {0x54,0x02}},
+{LCM_SEND(2), {0x55,0x66}},
+{LCM_SEND(2), {0x56,0x02}},
+{LCM_SEND(2), {0x58,0xa0}},
+{LCM_SEND(2), {0x59,0x02}},
+{LCM_SEND(2), {0x5a,0xc5}},
+{LCM_SEND(2), {0x5b,0x02}},
+{LCM_SEND(2), {0x5c,0xf8}},
+{LCM_SEND(2), {0x5d,0x03}},
+{LCM_SEND(2), {0x5e,0x1b}},
+{LCM_SEND(2), {0x5f,0x03}},
+{LCM_SEND(2), {0x60,0x46}},
+{LCM_SEND(2), {0x61,0x03}},
+{LCM_SEND(2), {0x62,0x52}},
+{LCM_SEND(2), {0x63,0x03}},
+{LCM_SEND(2), {0x64,0x62}},
+{LCM_SEND(2), {0x65,0x03}},
+{LCM_SEND(2), {0x66,0x71}},
+{LCM_SEND(2), {0x67,0x03}},
+{LCM_SEND(2), {0x68,0x83}},
+{LCM_SEND(2), {0x69,0x03}},
+{LCM_SEND(2), {0x6a,0x94}},
+{LCM_SEND(2), {0x6b,0x03}},
+{LCM_SEND(2), {0x6c,0xa3}},
+{LCM_SEND(2), {0x6d,0x03}},
+{LCM_SEND(2), {0x6e,0xad}},
+{LCM_SEND(2), {0x6f,0x03}},
+{LCM_SEND(2), {0x70,0xcc}},
+{LCM_SEND(2), {0x71,0x00}},
+{LCM_SEND(2), {0x72,0x18}},
+{LCM_SEND(2), {0x73,0x00}},
+{LCM_SEND(2), {0x74,0x38}},
+{LCM_SEND(2), {0x75,0x00}},
+{LCM_SEND(2), {0x76,0x65}},
+{LCM_SEND(2), {0x77,0x00}},
+{LCM_SEND(2), {0x78,0x84}},
+{LCM_SEND(2), {0x79,0x00}},
+{LCM_SEND(2), {0x7a,0x9b}},
+{LCM_SEND(2), {0x7b,0x00}},
+{LCM_SEND(2), {0x7c,0xaf}},
+{LCM_SEND(2), {0x7d,0x00}},
+{LCM_SEND(2), {0x7e,0xc1}},
+{LCM_SEND(2), {0x7f,0x00}},
+{LCM_SEND(2), {0x80,0xd2}},
+{LCM_SEND(2), {0x81,0x00}},
+{LCM_SEND(2), {0x82,0xdf}},
+{LCM_SEND(2), {0x83,0x01}},
+{LCM_SEND(2), {0x84,0x11}},
+{LCM_SEND(2), {0x85,0x01}},
+{LCM_SEND(2), {0x86,0x38}},
+{LCM_SEND(2), {0x87,0x01}},
+{LCM_SEND(2), {0x88,0x76}},
+{LCM_SEND(2), {0x89,0x01}},
+{LCM_SEND(2), {0x8a,0xa7}},
+{LCM_SEND(2), {0x8b,0x01}},
+{LCM_SEND(2), {0x8c,0xf3}},
+{LCM_SEND(2), {0x8d,0x02}},
+{LCM_SEND(2), {0x8e,0x2f}},
+{LCM_SEND(2), {0x8f,0x02}},
+{LCM_SEND(2), {0x90,0x30}},
+{LCM_SEND(2), {0x91,0x02}},
+{LCM_SEND(2), {0x92,0x66}},
+{LCM_SEND(2), {0x93,0x02}},
+{LCM_SEND(2), {0x94,0xa0}},
+{LCM_SEND(2), {0x95,0x02}},
+{LCM_SEND(2), {0x96,0xc5}},
+{LCM_SEND(2), {0x97,0x02}},
+{LCM_SEND(2), {0x98,0xf8}},
+{LCM_SEND(2), {0x99,0x03}},
+{LCM_SEND(2), {0x9a,0x1b}},
+{LCM_SEND(2), {0x9b,0x03}},
+{LCM_SEND(2), {0x9c,0x46}},
+{LCM_SEND(2), {0x9d,0x03}},
+{LCM_SEND(2), {0x9e,0x52}},
+{LCM_SEND(2), {0x9f,0x03}},
+{LCM_SEND(2), {0xa0,0x62}},
+{LCM_SEND(2), {0xa2,0x03}},
+{LCM_SEND(2), {0xa3,0x71}},
+{LCM_SEND(2), {0xa4,0x03}},
+{LCM_SEND(2), {0xa5,0x83}},
+{LCM_SEND(2), {0xa6,0x03}},
+{LCM_SEND(2), {0xa7,0x94}},
+{LCM_SEND(2), {0xa9,0x03}},
+{LCM_SEND(2), {0xaa,0xa3}},
+{LCM_SEND(2), {0xab,0x03}},
+{LCM_SEND(2), {0xac,0xad}},
+{LCM_SEND(2), {0xad,0x03}},
+{LCM_SEND(2), {0xae,0xcc}},
+{LCM_SEND(2), {0xaf,0x00}},
+{LCM_SEND(2), {0xb0,0x18}},
+{LCM_SEND(2), {0xb1,0x00}},
+{LCM_SEND(2), {0xb2,0x38}},
+{LCM_SEND(2), {0xb3,0x00}},
+{LCM_SEND(2), {0xb4,0x65}},
+{LCM_SEND(2), {0xb5,0x00}},
+{LCM_SEND(2), {0xb6,0x84}},
+{LCM_SEND(2), {0xb7,0x00}},
+{LCM_SEND(2), {0xb8,0x9b}},
+{LCM_SEND(2), {0xb9,0x00}},
+{LCM_SEND(2), {0xba,0xaf}},
+{LCM_SEND(2), {0xbb,0x00}},
+{LCM_SEND(2), {0xbc,0xc1}},
+{LCM_SEND(2), {0xbd,0x00}},
+{LCM_SEND(2), {0xbe,0xd2}},
+{LCM_SEND(2), {0xbf,0x00}},
+{LCM_SEND(2), {0xc0,0xdf}},
+{LCM_SEND(2), {0xc1,0x01}},
+{LCM_SEND(2), {0xc2,0x11}},
+{LCM_SEND(2), {0xc3,0x01}},
+{LCM_SEND(2), {0xc4,0x38}},
+{LCM_SEND(2), {0xc5,0x01}},
+{LCM_SEND(2), {0xc6,0x76}},
+{LCM_SEND(2), {0xc7,0x01}},
+{LCM_SEND(2), {0xc8,0xa7}},
+{LCM_SEND(2), {0xc9,0x01}},
+{LCM_SEND(2), {0xca,0xf3}},
+{LCM_SEND(2), {0xcb,0x02}},
+{LCM_SEND(2), {0xcc,0x2f}},
+{LCM_SEND(2), {0xcd,0x02}},
+{LCM_SEND(2), {0xce,0x30}},
+{LCM_SEND(2), {0xcf,0x02}},
+{LCM_SEND(2), {0xd0,0x66}},
+{LCM_SEND(2), {0xd1,0x02}},
+{LCM_SEND(2), {0xd2,0xa0}},
+{LCM_SEND(2), {0xd3,0x02}},
+{LCM_SEND(2), {0xd4,0xc5}},
+{LCM_SEND(2), {0xd6,0xf8}},
+{LCM_SEND(2), {0xd7,0x03}},
+{LCM_SEND(2), {0xd8,0x1b}},
+{LCM_SEND(2), {0xd9,0x03}},
+{LCM_SEND(2), {0xda,0x46}},
+{LCM_SEND(2), {0xdb,0x03}},
+{LCM_SEND(2), {0xdc,0x52}},
+{LCM_SEND(2), {0xdd,0x03}},
+{LCM_SEND(2), {0xde,0x62}},
+{LCM_SEND(2), {0xdf,0x03}},
+{LCM_SEND(2), {0xe0,0x71}},
+{LCM_SEND(2), {0xe1,0x03}},
+{LCM_SEND(2), {0xe2,0x83}},
+{LCM_SEND(2), {0xe3,0x03}},
+{LCM_SEND(2), {0xe4,0x94}},
+{LCM_SEND(2), {0xe5,0x03}},
+{LCM_SEND(2), {0xe6,0xa3}},
+{LCM_SEND(2), {0xe7,0x03}},
+{LCM_SEND(2), {0xe8,0xad}},
+{LCM_SEND(2), {0xe9,0x03}},
+{LCM_SEND(2), {0xea,0xcc}}, //GAMMA END
+
+{LCM_SEND(2), {0xff,0x01}},
+{LCM_SEND(2), {0xfb,0x01}},
+{LCM_SEND(2), {0xff,0x02}},
+{LCM_SEND(2), {0xfb,0x01}},
+{LCM_SEND(2), {0xff,0x04}},
+{LCM_SEND(2), {0xfb,0x01}},
+{LCM_SEND(2), {0xff,0x00}},
+{LCM_SEND(2), {0xD3,0x05}}, //VBP VFP VSPW
+{LCM_SEND(2), {0xD4,0x04}},
+
+{LCM_SEND(1), {0x11}}, //sleep out
+{LCM_SLEEP(150)},
+
+{LCM_SEND(2), {0xff,0x00}}, //Tearing Effect Line ON
+{LCM_SEND(2), {0x35,0x00}},
+
+{LCM_SEND(1), {0x29}}, //display on
+{LCM_SLEEP(100)},
+
+{LCM_SEND(2), {0x51,0x00}}, //CABC setting
+{LCM_SEND(2), {0x5e,0x00}},
+{LCM_SEND(2), {0x53,0x2c}},
+{LCM_SEND(2), {0x55,0x00}},
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+//{LCM_SEND(2), {0x4f, 0x01}}, /* this code may cause not resume bug*/
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+// {0x39, {LCM_SEND(8), {0x6, 0, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t nt35596h_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ pr_debug(KERN_DEBUG "sprdfb:nt35596h_mipi_init\n");
+
+ mipi_set_cmd_mode();
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ return 0;
+}
+
+static uint32_t nt35596h_readid(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("sprdfb:lcd_nt35596h_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0xF4, 1,(uint8_t *)read_data);
+ printk("lcd_nt35596h_mipi read id 0xF4 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if(0x96 == read_data[0]){
+ printk("lcd_nt35596h_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x96;
+ }
+ }
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t nt35596h_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "nt35596h_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t nt35596h_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_nt35596h_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_nt35516 mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if(0x08 == read_data[0]){
+ pr_debug("lcd_nt35596h_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ printk("lcd_nt35596h mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t nt35596h_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+#ifndef FB_CHECK_ESD_IN_VFP
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+#endif
+
+ pr_debug("nt35596h_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+#endif
+ power_mode = nt35596h_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+#endif
+ if(power_mode == 0x9c){
+ pr_debug("nt35596h_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("nt35596h_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_nt35596h_mipi_operations = {
+ .panel_init = nt35596h_mipi_init,
+ .panel_readid = nt35596h_readid,
+ .panel_enter_sleep = nt35596h_enter_sleep,
+ .panel_esd_check = nt35596h_check_esd,
+};
+
+static struct timing_rgb lcd_nt35596h_mipi_timing = {
+ .hfp = 20, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 20,//4,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_nt35596h_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq = 1000*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt35596h_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt35596h_mipi_spec = {
+ .width = 1080,
+ .height = 1920,
+ .fps = 40,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_nt35596h_mipi_info
+ },
+ .ops = &lcd_nt35596h_mipi_operations,
+};
+
+struct panel_cfg lcd_nt35596h_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x96,
+ .lcd_name = "lcd_nt35596h_mipi",
+ .panel = &lcd_nt35596h_mipi_spec,
+};
+
+static int __init lcd_nt35596h_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt35596h_mipi);
+}
+
+subsys_initcall(lcd_nt35596h_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt51017_goyal_mipi.c b/drivers/video/sprdfb/lcd/lcd_nt51017_goyal_mipi.c
new file mode 100755
index 00000000..1f081bee
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt51017_goyal_mipi.c
@@ -0,0 +1,296 @@
+/* drivers/video/sprdfb/lcd_nt51017_mipi.c
+ *
+ * Support for nt51017 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+
+
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(2), {0x83, 0x96} },
+ {LCM_SEND(2), {0x84, 0x69} },
+ {LCM_SEND(2), {0x92, 0x19} },
+ {LCM_SEND(2), {0x83, 0x00} },
+ {LCM_SEND(2), {0x84, 0x00} },
+ {LCM_SEND(2), {0x96, 0x00} },
+
+};
+
+
+static LCM_Init_Code sleep_in[] = {
+
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(170)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(170)},
+
+};
+
+
+static int32_t nt51017_mipi_init(struct panel_spec *self)
+{
+
+ if (gpio_request(232, "LED_EN0")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",232);
+ return -ENODEV;
+ }
+ gpio_direction_output(232, 1);
+ gpio_set_value(232, 1);
+
+ if (gpio_request(233, "LED_EN1")) {
+ printk("Failed ro request LCD_BL GPIO_%d \n",233);
+ return -ENODEV;
+ }
+ gpio_direction_output(233, 1);
+ gpio_set_value(233, 1);
+
+ mdelay(200);
+
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_nt51017_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ mdelay(init->tag & LCM_TAG_MASK);//udelay((init->tag & LCM_TAG_MASK) * 1000);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t nt51017_readid(struct panel_spec *self)
+{
+#if 0
+ uint32 j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_nt51017_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ printk("lcd_nt51017_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ printk("lcd_nt51017_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ printk("lcd_nt51017_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ if((0x55 == read_data[0])&&(0xbf == read_data[1] || 0xc0 == read_data[1] || 0xbe == read_data[1])&&(0x90 == read_data[2])){
+ printk("lcd_nt51017_mipi read id success!\n");
+ return 0x8369;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ printk("lcd_s6d77a1_mipi read id failed!\n");
+ return 0;
+#endif
+ return 0x51017;
+}
+
+static int32_t nt51017_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel nt51017_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static int32_t nt51017_before_resume(struct panel_spec *self, uint8_t is_sleep)
+{
+ gpio_set_value(152, 1);
+ gpio_set_value(155, 1);
+ gpio_set_value(232, 1);
+ gpio_set_value(233, 1);
+}
+
+static int32_t nt51017_after_suspend(struct panel_spec *self, uint8_t is_sleep)
+{
+ gpio_set_value(152, 0);
+ gpio_set_value(155, 0);
+ gpio_set_value(232, 0);
+ gpio_set_value(233, 0);
+}
+
+static struct panel_operations lcd_nt51017_mipi_operations = {
+ .panel_init = nt51017_mipi_init,
+ .panel_readid = nt51017_readid,
+ .panel_enter_sleep = nt51017_enter_sleep,
+ .panel_before_resume = nt51017_before_resume,
+ .panel_after_suspend = nt51017_after_suspend,
+};
+
+static struct timing_rgb lcd_nt51017_mipi_timing = {
+
+ .hfp = 80, /* unit: pixel */
+ .hbp = 80,
+ .hsync = 1,
+ .vfp = 18, /*unit: line*/
+ .vbp = 23,
+ .vsync = 1,
+
+};
+
+
+static struct info_mipi lcd_nt51017_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt51017_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt51017_mipi_spec = {
+ .width = 800,
+ .height =1280,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .suspend_mode = SEND_SLEEP_CMD,
+ .info = {
+ .mipi = &lcd_nt51017_mipi_info
+ },
+ .ops = &lcd_nt51017_mipi_operations,
+};
+struct panel_cfg lcd_nt51017_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x51017,
+ .lcd_name = "lcd_nt51017_mipi",
+ .panel = &lcd_nt51017_mipi_spec,
+};
+
+
+static int __init lcd_nt51017_mipi_init(void)
+{
+ if (gpio_request(152, "LCD_3V3")) {
+ printk("Failed ro request LCD_3V3 GPIO_%d \n",152);
+ return -ENODEV;
+ }
+ if (gpio_request(155, "BL_EN")) {
+ printk("Failed ro request BL_EN GPIO_%d \n",155);
+ return -ENODEV;
+ }
+ if (gpio_request(232, "CABC_EN0")) {
+ printk("Failed ro request CABC_EN0 GPIO_%d \n",232);
+ return -ENODEV;
+ }
+ if (gpio_request(233, "CABC_EN1")) {
+ printk("Failed ro request CABC_EN1 GPIO_%d \n",233);
+ return -ENODEV;
+ }
+ gpio_direction_output(152, 1);
+ gpio_direction_output(155, 1);
+ gpio_direction_output(232, 1);
+ gpio_direction_output(233, 1);
+
+ return sprdfb_panel_register(&lcd_nt51017_mipi);
+}
+
+subsys_initcall(lcd_nt51017_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_nt51017_mipi_lvds.c b/drivers/video/sprdfb/lcd/lcd_nt51017_mipi_lvds.c
new file mode 100644
index 00000000..e5689072
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_nt51017_mipi_lvds.c
@@ -0,0 +1,589 @@
+/* drivers/video/sprdfb/lcd_nt51017_mipi_lvds.c
+ *
+ * Support for nt51017 lvds LCD device
+ *
+ * Copyright (C) 2013 Spreadtrum
+ *
+ * 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 <asm/arch/sprd_lcd.h>
+//#include <asm/arch/sprd_i2c.h>
+#include <linux/kernel.h>
+//#include <linux/bug.h>
+#include <linux/delay.h>
+//#include <linux/platform_device.h>
+#include <linux/i2c.h>
+//#include <include/asm/gpio.h>
+//#include "sp8830_i2c.h"
+#include "../sprdfb_panel.h"
+
+//#define printk printf
+
+//#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+/***************** Important Macro! *****************/
+/* For TI! ONLY ONE of the flowing marco can be defined! */
+//#define LINES_ALL_RIGHT_TI
+#define LINES_ONLY_CLK_RIGHT_TI
+
+/* For CHIPONE! ONLY ONE of the flowing marco can be defined! */
+#if 1
+#define LINES_ALL_WRONG_C1
+#else // 5735A-2 v1.0.1
+#define LINES_ALL_RIGHT_C1
+#endif
+/***************** Important Macro! *****************/
+
+struct bridge_ops {
+ int32_t (*init)(struct panel_spec *self);
+ int32_t (*suspend)(struct panel_spec *self);
+};
+
+static struct bridge_ops b_ops = {
+ .init = NULL,
+ .suspend = NULL,
+};
+
+
+#define I2CID_BRIDGE 2
+#define I2C_NT50366_ADDR_WRITE 0x9E /* NT50169 100_1111 0 */
+#define I2C_NT51017_ADDR_WRITE 0xD0 /* NT51017 110_1000 0 */
+#define I2C_BRIDGE_ADDR_WRITE0 0x2C /* 0 010_1100 ADDR=Low */
+#define I2C_BRIDGE_ADDR_WRITE1 0x2D /* 0 010_1101 ADDR=High */
+#define I2C_BRIDGE_ADDR I2C_BRIDGE_ADDR_WRITE0
+
+
+#define GPIOID_LCMRSTN 103 /* should modify pinmap */
+#define GPIOID_STBYB 230 /* should modify pinmap */
+#define GPIOID_BRIDGE_EN 231
+#define GPIOID_VDDPWR 232
+#define GPIOID_ADDR 234 /* should modify pinmap */
+#define GPIOID_LCDPWR 235
+
+#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+extern int gpio_direction_output(unsigned gpio, int value);
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+
+const static __u8 i2c_msg_buf_ti[][2] = {
+ {0x09, 0x00},
+ {0x0A, 0x03},
+ {0x0B, 0x18},
+ {0x0D, 0x00},
+ {0x10, 0x26},
+ {0x11, 0x00},
+ {0x12, 0x31},
+ {0x13, 0x00},
+#ifdef LINES_ALL_RIGHT_TI
+ {0x18, 0x18},/* all the line is right */
+#elif defined LINES_ONLY_CLK_RIGHT_TI
+ {0x18, 0xF8},/* only clock line is right */
+#endif
+ {0x19, 0x0C},/* 0x00 */
+ {0x1A, 0x03},
+ {0x1B, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x03},
+ {0x22, 0x00},
+ {0x23, 0x00},
+ {0x24, 0x00},
+ {0x25, 0x00},
+ {0x26, 0x00},
+ {0x27, 0x00},
+ {0x28, 0x20},
+ {0x29, 0x00},
+ {0x2A, 0x00},
+ {0x2B, 0x00},
+ {0x2C, 0x04},/*0x04*/
+ {0x2D, 0x00},
+ {0x2E, 0x00},
+ {0x2F, 0x00},
+ {0x30, 0x04},/*0x04*/
+ {0x31, 0x00},
+ {0x32, 0x00},
+ {0x33, 0x00},
+ {0x34, 0x4C},
+ {0x35, 0x00},
+ {0x36, 0x00},
+ {0x37, 0x00},
+ {0x38, 0x00},
+ {0x39, 0x00},
+ {0x3A, 0x00},
+ {0x3B, 0x00},
+ {0x3C, 0x00},
+ {0x3D, 0x00},
+ {0x3E, 0x00},
+};
+const static __u8 i2c_msg_buf_c1[][2] = {
+ /*{0x10, 0x4E},add*/
+ {0x20, 0x00},
+ {0x21, 0x00},
+ {0x22, 0x43},
+ {0x23, 0x28},
+ {0x24, 0x04},
+ {0x25, 0x4C},
+ {0x26, 0x00},
+ {0x27, 0x12},
+ {0x28, 0x04},/*0x02*/
+ {0x29, 0x13},
+ {0x2A, 0x01},
+ {0x34, 0xF0},/*add*/
+ {0x36, 0x50},/*add*/
+ {0x86, 0x2B},
+ {0xB5, 0xA0},
+ {0x51, 0x20},
+ {0x56, 0x92},
+ {0x69, 0x1C},/*0x1F*/
+ {0x6B, 0x22},
+ {0x5C, 0xFF},
+ {0xB6, 0x20},
+#ifdef LINES_ALL_RIGHT_C1
+ {0x13, 0x10},
+#elif defined LINES_ONLY_CLK_RIGHT_C1
+ {0x13, 0x1F},
+#elif defined LINES_ALL_WRONG_C1
+ {0x13, 0x5F},
+#endif
+ /*{0x10, 0x47},add*/
+ /*{0x2A, 0x31},modify*/
+ /*{0x2E, 0x40},add*/
+ /*{0x2F, 0x40},add*/
+ {0x09, 0x10},
+ /*{0x7B, 0xF2},*/
+ /*{0x7C, 0xF3},*/
+};
+
+static struct i2c_msg msg_w = {
+ .addr = I2C_BRIDGE_ADDR,
+ .flags = 0,
+ .len = 2,
+ .buf = NULL,
+};
+
+static struct i2c_msg msg_r[] = {
+ [0] = {
+ .addr = I2C_BRIDGE_ADDR,
+ .flags = 0,
+ .len = 1,
+ .buf = NULL,
+ },
+ [1] = {
+ .addr = I2C_BRIDGE_ADDR,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = NULL,
+ },
+};
+
+static int32_t sn65dsi83_reg_read(struct panel_spec *self)
+{
+ __u8 reg[] = {0x09,0x0A,0x0B,0x0D,0x10,0x11,0x12,0x13,0x18,0x19,0x1A,0x1B,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E};
+ __u8 val[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+ int32_t ret_i2c = 0;
+ int32_t i = 0;
+ struct i2c_adapter *adap = i2c_get_adapter(I2CID_BRIDGE);
+
+ for (i=0; i<ARRAY_SIZE(reg); i++){
+ msg_r[0].buf = &reg[i];
+ msg_r[1].buf = &val[i];
+ ret_i2c = i2c_transfer(adap, &msg_r, 2);
+ LCD_PRINT("kernel Read All Regs! SendMsgNum=%d, Reg=0x%x, Src=0x%x,Read=0x%x,\n", ret_i2c,reg[i],i2c_msg_buf_ti[2*i+1],val[i]);
+ }
+
+ LCD_PRINT("kernel sn65dsi83_reg_read! adap_addr=0x%x, name=%s, nr=%d\n", adap, adap->name, adap->nr);
+
+ return 0;
+}
+
+/* set pin, return 0:OK, other value:failed */
+static int32_t set_en_pin(struct panel_spec *self, uint8_t value, uint8_t delays)//value 0 : set low, value not 0 : set high
+{
+ static uint8_t gpio_is_requested = 0;
+
+ /* request gpio */
+ if (!gpio_is_requested){
+ if (gpio_request(GPIOID_BRIDGE_EN, "BRIDGE_EN")){
+ printk("kernel GPIO%d requeste failed!\n",GPIOID_BRIDGE_EN);
+ return 1;
+ }
+ gpio_is_requested = 1;
+ }
+
+ if (value) {//set high
+ gpio_direction_output(GPIOID_BRIDGE_EN, 0);
+ msleep(delays);
+ gpio_direction_output(GPIOID_BRIDGE_EN, 1);
+ } else {//set low
+ gpio_direction_output(GPIOID_BRIDGE_EN, 0);
+ gpio_free(GPIOID_BRIDGE_EN);
+ gpio_is_requested = 0;
+ }
+
+ return 0;
+}
+
+/* Init SN65DSI83 */
+static int32_t sn65dsi83_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ int32_t ret_i2c = 0;
+
+ __u8 i2c_msg_buf_pll_en[] = {0x0D, i2c_msg_buf_ti[3][1]|0x01};// PLL_EN (CSR 0x0D.0)
+ __u8 i2c_msg_buf_soft_reset[] = {0x09, i2c_msg_buf_ti[0][1]|0x01};// SOFT_RESET (CSR 0x09.0)
+
+ struct i2c_adapter *adap = i2c_get_adapter(I2CID_BRIDGE);
+
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;/* u-boot\arch\arm\include\asm\arch\sprd_lcd.h */
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ mipi_set_video_mode_t mipi_set_video_mode = self->info.mipi->ops->mipi_set_video_mode;
+
+ /* step 1 : All DSI into LP11*/
+ mipi_set_lp_mode();
+
+ /* step 2 : Set EN*/
+ if (set_en_pin(self, 1, 30)){
+ printk("kernel Set EN failed!\n");
+ return 0;
+ }
+
+ /* step 3 : Delay*/
+ udelay(2000);
+
+ /* step 4 : init CSR reg*/
+ for (i=0; i<ARRAY_SIZE(i2c_msg_buf_ti); i++) {
+ msg_w.buf = i2c_msg_buf_ti[i];
+ ret_i2c = i2c_transfer(adap, &msg_w, 1);
+ }
+
+ /* step 5 : Start the DSI video stream */
+ mipi_set_hs_mode();
+ mipi_set_video_mode();
+ udelay(1000);
+
+ /* step 6 : Set the PLL_EN bit(CSR 0x0D.0) */
+ msg_w.buf = i2c_msg_buf_pll_en;
+ ret_i2c = i2c_transfer(adap, &msg_w, 1);
+
+ /* step 7 : Wait for the PLL_LOCK bit to be set(CSR 0x0A.7) */
+ udelay(1000);
+
+ /* step 8 : Set the SOFT_RESET bit (CSR 0x09.0) */
+ msg_w.buf = i2c_msg_buf_soft_reset;
+ ret_i2c = i2c_transfer(adap, &msg_w, 1);
+
+ return 0;
+}
+
+static int32_t chipone_init(struct panel_spec *self)
+{
+ int32_t ret_i2c = 0;
+ int32_t i = 0;
+
+ struct i2c_adapter *adap = i2c_get_adapter(I2CID_BRIDGE);
+
+ /* Set EN pin */
+ if (set_en_pin(self, 1, 10)){
+ printk("kernel Set EN failed!\n");
+ return 0;
+ }
+ udelay(1000);
+
+ /* init chipone */
+ for (i=0; i<ARRAY_SIZE(i2c_msg_buf_c1); i++) {
+ msg_w.buf = i2c_msg_buf_c1[i];
+ ret_i2c = i2c_transfer(adap, &msg_w, 1);
+ }
+
+ return 0;
+}
+
+/* reset sn65dsi83 */
+static int32_t sn65dsi83_suspend(struct panel_spec *self)
+{
+ __u8 i2c_msg_buf_pll_en[] = {0x0D, i2c_msg_buf_ti[3][1] & 0xFE};// PLL_EN (CSR 0x0D.0)
+ int32_t ret_i2c = 0;
+
+ struct i2c_adapter *adap = i2c_get_adapter(I2CID_BRIDGE);
+
+ LCD_PRINT("kernel sn65dsi83_suspend! adap_addr=0x%x, name=%s, nr=%d\n", adap, adap->name, adap->nr);
+
+ /*1. Clear the PLL_EN bit to 0(CSR 0x0D.0*/
+ msg_w.buf = i2c_msg_buf_pll_en;
+ ret_i2c = i2c_transfer(adap, &msg_w, 1);
+
+ /* set EN to 0 */
+ if (set_en_pin(self, 0, 1)){
+ printk("kernel Set EN failed!\n");
+ return 0;
+ }
+
+ return 0;
+}
+
+static int32_t chipone_suspend(struct panel_spec *self)
+{
+ /* set EN to 0 */
+ if (set_en_pin(self, 0, 1)){
+ printk("kernel Set EN failed!\n");
+ return 0;
+ }
+ return 0;
+}
+
+static int32_t nt51017_power(struct panel_spec *self, uint8_t power)//0:power down, 1:power up
+{
+ static uint8_t is_requested = 0;
+
+ if(!is_requested){//should request gpio
+ if (gpio_request(GPIOID_VDDPWR, "VDDPWR")){
+ printk("kernel GPIO%d requeste failed!\n", GPIOID_VDDPWR);
+ return 0;
+ }
+
+ if (gpio_request(GPIOID_LCDPWR, "LCDPWR")){
+ printk("kernel GPIO%d requeste failed!\n", GPIOID_LCDPWR);
+ return 0;
+ }
+
+ is_requested = 1;
+ }
+
+ if (is_requested){
+ gpio_direction_output(GPIOID_VDDPWR, power);
+ gpio_direction_output(GPIOID_LCDPWR, power);
+
+ if (!power){//power down, should free gpio
+ gpio_free(GPIOID_VDDPWR);
+ gpio_free(GPIOID_LCDPWR);
+ is_requested = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int32_t get_bridge_info(struct panel_spec *self)
+{
+ __u8 reg = 0x00;
+ __u8 flag = 0xFF;
+ int32_t ret_i2c = 0;
+
+ struct i2c_adapter *adap = i2c_get_adapter(I2CID_BRIDGE);
+
+ if (set_en_pin(self, 1, 30)){
+ printk("kernel Set EN failed!\n");
+ return 1;
+ }
+
+ if (gpio_request(GPIOID_ADDR, "ADDR")){
+ printk("kernel GPIO%d requeste failed!\n", GPIOID_ADDR);
+ return 1;
+ }
+ gpio_direction_output(GPIOID_ADDR, 0);// drive ADDR to low
+ udelay(1000);
+
+ msg_r[0].buf = &reg;
+ msg_r[1].buf = &flag;
+ ret_i2c = i2c_transfer(adap, &msg_r, 2);
+ if (0 == ret_i2c){
+ printk("get_bridge_info, I2C Read Failed!\n");
+ return 1;
+ }
+
+ if (0x35 == flag){//TI
+ b_ops.init = sn65dsi83_init;
+ b_ops.suspend = sn65dsi83_suspend;
+ } else if (0xC1 == flag) {//ChipOne
+ b_ops.init = chipone_init;
+ b_ops.suspend = chipone_suspend;
+ } else {
+ printk("get_bridge_info, Unknown bridge! flag=0x%x\n", flag);
+ gpio_free(GPIOID_ADDR);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int32_t nt51017_mipi_lvds_init(struct panel_spec *self)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_init\n");
+
+ /* init */
+ if (b_ops.init) {
+ b_ops.init(self);
+ } else {
+ if (get_bridge_info(self)){//get bridge info fail
+ printk("Get bridge info fail!\n");
+ return 0;
+ } else {
+ b_ops.init(self);
+ }
+ }
+
+ /* power up */
+ nt51017_power(self, 1);
+
+ LCD_PRINT("kernel nt51017_mipi_lvds_init over!\n");
+
+ return 0;
+}
+
+static int32_t nt51017_mipi_lvds_reset(struct panel_spec *self)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_reset\n");
+
+ return 0;
+}
+
+static int32_t nt51017_mipi_lvds_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_enter_sleep! is_sleep=%d\n",is_sleep);
+
+ if (is_sleep){//sleep in
+ nt51017_power(self, 0);// power down
+ if (b_ops.suspend) {
+ b_ops.suspend(self);
+ } else {
+ if (get_bridge_info(self)){
+ printk("Get bridge info fail when suspend!\n");
+ return 0;
+ } else {
+ b_ops.suspend(self);
+ }
+ }
+ } else {//sleep out
+ nt51017_power(self, 1);// power up
+ if (b_ops.init) {
+ b_ops.init(self);
+ } else {
+ if (get_bridge_info(self)){//get bridge info fail
+ printk("Get bridge info fail!\n");
+ return 0;
+ } else {
+ b_ops.init(self);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static uint32_t nt51017_mipi_lvds_after_suspend(struct panel_spec *self)
+{
+ nt51017_power(self, 0);// power down
+
+ if (b_ops.suspend) {
+ b_ops.suspend(self);
+ }else {
+ if (get_bridge_info(self)){
+ printk("Get bridge info fail when suspend!\n");
+ return 0;
+ } else {
+ b_ops.suspend(self);
+ }
+ }
+
+ LCD_PRINT("kernel nt51017_mipi_lvds_after_suspend\n");
+
+ return 0;
+}
+
+static uint32_t nt51017_mipi_lvds_before_resume(struct panel_spec *self)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_before_resume\n");
+
+ return 0;
+}
+
+static uint32_t nt51017_mipi_lvds_readid(struct panel_spec *self)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_readid\n");
+
+ return 0xC749;/*51017*/
+}
+
+static int32_t nt51017_mipi_lvds_check_esd(struct panel_spec *self)
+{
+ LCD_PRINT("kernel nt51017_mipi_lvds_check_esd\n");
+
+ return 1;
+}
+
+static struct panel_operations lcd_nt51017_mipi_lvds_operations = {
+ .panel_init = nt51017_mipi_lvds_init,
+ .panel_reset = NULL,//nt51017_mipi_lvds_reset,
+ .panel_enter_sleep = nt51017_mipi_lvds_enter_sleep,
+ .panel_after_suspend = nt51017_mipi_lvds_after_suspend,
+ .panel_before_resume = NULL,
+ .panel_readid = nt51017_mipi_lvds_readid,
+ .panel_esd_check = NULL,
+};
+
+static struct timing_rgb lcd_nt51017_mipi_lvds_timing = {
+ .hfp = 110, /* unit: pixel */
+ .hbp = 76,
+ .hsync = 4,//4
+ .vfp = 18, /*unit: line*/
+ .vbp = 19,
+ .vsync = 4,
+};
+
+static struct info_mipi lcd_nt51017_mipi_lvds_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq = 512*1000,/*494*/
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_nt51017_mipi_lvds_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_nt51017_mipi_lvds_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 768,
+ .height = 1024,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,//bug 273509
+ .info = {
+ .mipi = &lcd_nt51017_mipi_lvds_info
+ },
+ .ops = &lcd_nt51017_mipi_lvds_operations,
+};
+
+struct panel_cfg lcd_nt51017_mipi_lvds = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0xC749,
+ .lcd_name = "lcd_nt51017_mipi_lvds",
+ .panel = &lcd_nt51017_mipi_lvds_spec,
+};
+
+static int __init lcd_nt51017_mipi_lvds_init(void)
+{
+ return sprdfb_panel_register(&lcd_nt51017_mipi_lvds);
+}
+
+subsys_initcall(lcd_nt51017_mipi_lvds_init);
+
+
diff --git a/drivers/video/sprdfb/lcd/lcd_otm1283a_mipi.c b/drivers/video/sprdfb/lcd/lcd_otm1283a_mipi.c
new file mode 100644
index 00000000..06875681
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_otm1283a_mipi.c
@@ -0,0 +1,560 @@
+/* drivers/video/sprdfb/lcd_otm1283a_mipi.c
+ *
+ * Support for otm1283a mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+//#define printk printf
+
+#define LCD_DEBUG
+//#define THREE_LANE_SUPPORT
+
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x37, {LCM_SEND(2), {0x5, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(6),{4,0,0xFF,0x12,0x83,0x01}},
+ {LCM_SEND(2),{0x00,0x80}},
+
+ {LCM_SEND(5),{3,0,0xFF,0x12,0x83}},
+
+#ifdef THREE_LANE_SUPPORT
+ {LCM_SEND(2),{0x00,0x92}},
+ {LCM_SEND(5),{3,0,0xFF,0x20,0x02}}, //0x20:3lane 0x30:4lanes
+#endif
+ //---------------PANEL setting -----------//
+ {LCM_SEND(2),{0x00,0x80}},
+ {LCM_SEND(10),{8,0,0xC0,0x00,0x64,0x00,0x10,0x10,0x00,0x64}},
+ {LCM_SEND(2),{0x00,0x87}},
+ {LCM_SEND(5),{3,0,0xC0,0x10,0x10}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(9),{7,0,0xC0,0x00,0x5C,0x00,0x01,0x00,0x04}},
+ {LCM_SEND(2),{0x00,0xA4}},
+ {LCM_SEND(2),{0xC0,0x22}},
+ {LCM_SEND(2),{0x00,0xB3}},
+ {LCM_SEND(5),{3,0,0xC0,0x00,0x50}},
+ {LCM_SEND(2),{0x00,0xB4}},
+ {LCM_SEND(2),{0xC0,0x55}},
+ {LCM_SEND(2),{0x00,0x81}},
+ //if(!TC358768_Gen_write_1A_1P(0xC1,0x55)) return -1;//xufei 2013-08-26 delete
+ //or
+ {LCM_SEND(2),{0xC1,0x66}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(2),{0xC4,0x49}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(2),{0x35,0x01}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(2),{0x36,0x00}},
+ //-----------------POWER SETTING-----------------
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(10),{8,0,0xC4,0x05,0x10,0x06,0x02,0x05,0x15,0x10}},
+ {LCM_SEND(2),{0x00,0xA7}},
+ {LCM_SEND(10),{8,0,0xC4,0x05,0x10,0x07,0x02,0x05,0x15,0x10}},
+ {LCM_SEND(2),{0x00,0xB0}},
+ {LCM_SEND(5),{3,0,0xC4,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x91}},
+ {LCM_SEND(5),{3,0,0xC5,0x46,0x40}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(5),{3,0,0xD8,0xC7,0xC7}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(2),{0xD9,0x6B}},
+ {LCM_SEND(2),{0x00,0x81}},
+ {LCM_SEND(2),{0xC4,0x82}},
+ {LCM_SEND(2),{0x00,0xB0}},
+
+ //if(!TC358768_Gen_write_1A_2P(0xC5,0x04,0xB8)) return -1;//xufei 2013-08-26 delete
+ //or
+ {LCM_SEND(5),{3,0,0xC5,0x04,0x58}},
+ {LCM_SEND(2),{0x00,0xBB}},
+ {LCM_SEND(2),{0xC5,0x80}},
+ {LCM_SEND(2),{0x00,0x82}},
+ {LCM_SEND(2),{0xC4,0x02}},
+ {LCM_SEND(2),{0x00,0xC6}},
+ {LCM_SEND(2),{0xB0,0x03}},
+ {LCM_SEND(2),{0x00,0xB1}},
+ {LCM_SEND(2),{0xC6,0x03}},
+ //-----------------CONTROL SETTING---------------
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(2),{0xD0,0x40}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(5),{3,0,0xD1,0x00,0x00}},
+ //-----------------PANEL TIMING STATE-------------------
+ {LCM_SEND(2),{0x00,0x80}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x87}},
+ {LCM_SEND(6),{4,0,0xCB,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x97}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x9E}},
+ {LCM_SEND(2),{0xCB,0x00}},
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xA7}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xAE}},
+ {LCM_SEND(2),{0xCB,0x00}},
+ {LCM_SEND(2),{0x00,0xB0}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB7}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xBE}},
+ {LCM_SEND(2),{0xCB,0x00}},
+ {LCM_SEND(2),{0x00,0xC0}},
+ {LCM_SEND(10),{8,0,0xCB,0x05,0x05,0x05,0x05,0x05,0x05,0x00}},
+ {LCM_SEND(2),{0x00,0xC7}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x05,0x05,0x00,0x05}},
+ {LCM_SEND(2),{0x00,0xCE}},
+ {LCM_SEND(2),{0xCB,0x05}},
+ {LCM_SEND(2),{0x00,0xD0}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xD7}},
+ {LCM_SEND(10),{8,0,0xCB,0x05,0x05,0x05,0x05,0x05,0x05,0x00}},
+ {LCM_SEND(2),{0x00,0xDE}},
+ {LCM_SEND(2),{0xCB,0x00}},
+ {LCM_SEND(2),{0x00,0xE0}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x05,0x05,0x00,0x05,0x05}},
+ {LCM_SEND(2),{0x00,0xE7}},
+ {LCM_SEND(10),{8,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xF0}},
+ {LCM_SEND(10),{8,0,0xCB,0xff,0xff,0xff,0xff,0xff,0xff,0xff}},
+ {LCM_SEND(2),{0x00,0xF7}},
+ {LCM_SEND(6),{4,0,0xCB,0xff,0xff,0xff,0xff}},
+ //--------------PANEL PAD MAPPING-------------
+ {LCM_SEND(2),{0x00,0x80}},
+ {LCM_SEND(10),{8,0,0xCC,0x0E,0x10,0x0A,0x0C,0x02,0x04,0x00}},
+ {LCM_SEND(2),{0x00,0x87}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x2E,0x2D,0x00,0x29}},
+ {LCM_SEND(2),{0x00,0x8E}},
+ {LCM_SEND(2),{0xCC,0x2A}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x97}},
+ {LCM_SEND(10),{8,0,0xCC,0x0D,0x0F,0x09,0x0B,0x01,0x03,0x00}},
+ {LCM_SEND(2),{0x00,0x9E}},
+ {LCM_SEND(2),{0xCC,0x00}},
+
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x2E,0x2D,0x00,0x29,0x2A}},
+ {LCM_SEND(2),{0x00,0xA7}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB0}},
+ {LCM_SEND(10),{8,0,0xCC,0x0B,0x09,0x0F,0x0D,0x03,0x01,0x00}},
+ {LCM_SEND(2),{0x00,0xB7}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x2D,0x2E,0x00,0x29}},
+ {LCM_SEND(2),{0x00,0xBE}},
+ {LCM_SEND(2),{0xCC,0x2A}},
+ {LCM_SEND(2),{0x00,0xC0}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xC7}},
+ {LCM_SEND(10),{8,0,0xCC,0x0C,0x0A,0x10,0x0E,0x04,0x02,0x00}},
+ {LCM_SEND(2),{0x00,0xCE}},
+ {LCM_SEND(2),{0xCC,0x00}},
+ {LCM_SEND(2),{0x00,0xD0}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x2D,0x2E,0x00,0x29,0x2A}},
+ {LCM_SEND(2),{0x00,0xD7}},
+ {LCM_SEND(10),{8,0,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ //-----------PANEL TIMING SETTING
+ {LCM_SEND(2),{0x00,0x80}},
+ {LCM_SEND(10),{8,0,0xCE,0x8B,0x03,0x18,0x8A,0x03,0x18,0x89}},
+ {LCM_SEND(2),{0x00,0x87}},
+ {LCM_SEND(8),{6,0,0xCE,0x03,0x18,0x88,0x03,0x18}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(10),{8,0,0xCE,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x97}},
+ {LCM_SEND(10),{8,0,0xCE,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x07,0x05,0x00,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xA7}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x06,0x05,0x01,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xB0}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x05,0x05,0x02,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xB7}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x04,0x05,0x03,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xC0}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x03,0x05,0x04,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xC7}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x02,0x05,0x05,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xD0}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x01,0x05,0x06,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0xD7}},
+ {LCM_SEND(10),{8,0,0xCE,0x38,0x00,0x05,0x07,0x00,0x48,0x00}},
+ {LCM_SEND(2),{0x00,0x80}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x87}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x97}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xA7}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB0}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB7}},
+ {LCM_SEND(10),{8,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xC0}},
+ {LCM_SEND(10),{8,0,0xCF,0x02,0x01,0x20,0x20,0x00,0x00,0x01}},
+ {LCM_SEND(2),{0x00,0xC7}},
+ {LCM_SEND(6),{4,0,0xCF,0x81,0x00,0x03,0x08}},
+ {LCM_SEND(2),{0x00,0xB5}},
+ {LCM_SEND(9),{7,0,0xC5,0x00,0x6F,0xFF,0x00,0x6F,0xFF}},
+ //-----------------FOR POWER IC--------------------------
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(6),{4,0,0xF5,0x02,0x11,0x02,0x11}},
+ {LCM_SEND(2),{0x00,0x90}},
+ {LCM_SEND(2),{0xC5,0x50}},
+ {LCM_SEND(2),{0x00,0x94}},
+ {LCM_SEND(2),{0xC5,0x66}},
+ //-----------------VGL01/02----------------------------------
+ {LCM_SEND(2),{0x00,0xB2}},
+ {LCM_SEND(5),{3,0,0xF5,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB4}},
+ {LCM_SEND(5),{3,0,0xF5,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB6}},
+ {LCM_SEND(5),{3,0,0xF5,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0xB8}},
+ {LCM_SEND(5),{3,0,0xF5,0x00,0x00}},
+ {LCM_SEND(2),{0x00,0x94}},
+ {LCM_SEND(2),{0xF5,0x02}},
+ {LCM_SEND(2),{0x00,0xBA}},
+ {LCM_SEND(2),{0xF5,0x03}},
+ {LCM_SEND(2),{0x00,0xB4}},
+ {LCM_SEND(2),{0xC5,0xC0}},
+ {LCM_SEND(2),{0x00,0xc6}},
+ {LCM_SEND(2),{0xB0,0x03}},
+ //spread frame range
+ {LCM_SEND(2),{0x00,0xA0}},
+ {LCM_SEND(2),{0xC1,0x02}},
+ {LCM_SEND(2),{0x00,0xA3}},
+ {LCM_SEND(2),{0xC1,0xF0}},
+ //-----------------GAMMA------------------------------
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(10),{8,0,0xE1,0x00,0x0d,0x14,0x0d,0x06,0x0e,0x0a}},
+ {LCM_SEND(10),{8,0,0xE1,0x09,0x05,0x08,0x0f,0x08,0x0f,0x10}},
+ {LCM_SEND(5),{3,0,0xE1,0x0a,0x05}},
+ {LCM_SEND(2),{0x00,0x00}},
+ {LCM_SEND(10),{8,0,0xE2,0x00,0x0d,0x14,0x0d,0x06,0x0e,0x0a}},
+ {LCM_SEND(10),{8,0,0xE2,0x09,0x05,0x08,0x0f,0x08,0x0f,0x10}},
+ {LCM_SEND(5),{3,0,0xE2,0x0a,0x05}},
+
+ {LCM_SEND(1), {0x11}}, // sleep out
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29}}, // display on
+ {LCM_SLEEP(50),}, //30, 100
+ {LCM_SEND(1), {0x2C}}, // normal on
+};
+
+static int32_t otm1283a_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("otm1283a_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ mdelay((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+ return 0;
+}
+
+static uint32_t otm1283a_readid(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[5] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_otm1283a_mipi read id!\n");
+ return 0x1283;
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ mdelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0xa1, 5,(uint8_t *)read_data);
+ LCD_PRINT("lcd_otm1283a_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x, 0x%x, 0x%x!\n",
+ read_data[0], read_data[1], read_data[2], read_data[3], read_data[4]);
+
+ mipi_eotp_set(1,1);
+
+ if((0x01 == read_data[0])&&(0x8b == read_data[1])&&(0x12 == read_data[2])&&(0x83 == read_data[3])&&(0xff == read_data[4])){
+ LCD_PRINT("lcd_otm1283a_mipi read id success!\n");
+ return 0x1283;
+ }
+ }
+
+ printk("lcd_otm1283a_mipi identify fail!\n");
+ return 0;
+}
+
+static uint32_t otm1283a_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_otm1283a_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+// printk("lcd_otm1283a_mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_otm1283a_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ printk("lcd_otm1283a_mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t otm1283a_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("otm1283a_check_esd!\n");
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = otm1283a_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("otm1283a_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("otm1283a_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static int32_t otm1283a_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "otm1283a_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static struct panel_operations lcd_otm1283a_mipi_operations = {
+ .panel_init = otm1283a_mipi_init,
+ .panel_readid = otm1283a_readid,
+ .panel_esd_check = otm1283a_check_esd,
+ .panel_enter_sleep = otm1283a_enter_sleep,
+};
+
+static struct timing_rgb lcd_otm1283a_mipi_timing = {
+ .hfp =32,
+ .hbp = 4,
+ .hsync =8,
+ .vfp = 17,
+ .vbp = 18,
+ .vsync = 7,
+};
+
+static struct info_mipi lcd_otm1283a_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+#ifdef THREE_LANE_SUPPORT
+ .lan_number = 3,
+ .phy_feq = 550*1000,
+#else
+ .lan_number = 4,
+ .phy_feq = 500*1000,
+#endif
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_otm1283a_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_otm1283a_mipi_spec = {
+ .width = 720,
+ .height = 1280,
+ .fps = 60,
+ .reset_timing = {5,40,20},
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+// .suspend_mode = SEND_SLEEP_CMD,
+ .info = {
+ .mipi = &lcd_otm1283a_mipi_info
+ },
+ .ops = &lcd_otm1283a_mipi_operations,
+};
+
+struct panel_cfg lcd_otm1283a_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x1283,
+ .lcd_name = "lcd_otm1283a_mipi",
+ .panel = &lcd_otm1283a_mipi_spec,
+};
+
+static int __init lcd_otm1283_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_otm1283a_mipi);
+}
+
+subsys_initcall(lcd_otm1283_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_otm8019a_mipi.c b/drivers/video/sprdfb/lcd/lcd_otm8019a_mipi.c
new file mode 100644
index 00000000..a9ac2829
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_otm8019a_mipi.c
@@ -0,0 +1,516 @@
+/* drivers/video/sprdfb/lcd_otm8019a_mipi.c
+ *
+ * Support for otm8019a mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+//#define printk printf
+
+#define LCD_DEBUG
+//#define THREE_LANE_SUPPORT
+
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x37, {LCM_SEND(2), {0x5, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(6), {4, 0, 0xFF, 0x80, 0x19, 0x01} },
+
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(5), {3, 0, 0xFF, 0x80, 0x19} },
+
+ {LCM_SEND(2), {0x00, 0x03} },
+ {LCM_SEND(2), {0xFF, 0x01} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(5), {3, 0, 0xD8, 0x7F, 0X7F} },/*6f*/
+
+ {LCM_SEND(2), {0x00, 0x082} },
+ {LCM_SEND(2), {0xC5, 0xB0} },
+
+ {LCM_SEND(2), {0x00, 0xA1} },
+ {LCM_SEND(2), {0xC1, 0x08} },
+
+ {LCM_SEND(2), {0x00, 0xA3} },
+ {LCM_SEND(2), {0xC0, 0x1B} },
+
+ {LCM_SEND(2), {0x00, 0xB4} },
+ {LCM_SEND(2), {0xC0, 0x77} },
+
+ {LCM_SEND(2), {0x00, 0x81} },
+ {LCM_SEND(2), {0xC4, 0x83} },
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(6), {4, 0, 0xC5, 0x4E, 0xA7, 0x01} },
+
+ {LCM_SEND(2), {0x00, 0xB1} },
+ {LCM_SEND(2), {0xC5, 0xA9} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(2), {0xD9, 0x17} },
+
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(2), {0xD8, 0x58} },
+
+/***************Gamma 2.2********************/
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(23), {21, 0, 0xE1, 0x00, 0x06, 0x14, 0x25, 0x3d, 0x4e, 0x5a,
+ 0x8d, 0x7c, 0x91, 0x75, 0x64, 0x7d, 0x69, 0x6e, 0x67, 0x5f, 0x55,
+ 0x5c, 0x02} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(23), {21, 0, 0xE2, 0x00, 0x06, 0x14, 0x25, 0x3d, 0x4e, 0x5a,
+ 0x8d, 0x7b, 0x91, 0x75, 0x64, 0x7d, 0x69, 0x6e, 0x67, 0x5f, 0x55,
+ 0x5c, 0x02} },
+/********************************************/
+/***************Gamma 2.5********************/
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(23), {21, 0, 0xE1, 0x00, 0x02, 0x07, 0x12, 0x22, 0x37, 0x41,
+ 0x78, 0x6b, 0x85, 0x7f, 0x6b, 0x82, 0x6b, 0x71, 0x69, 0x61, 0x58,
+ 0x4c, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(23), {21, 0, 0xE2, 0x00, 0x02, 0x07, 0x12, 0x22, 0x37, 0x41,
+ 0x78, 0x6b, 0x85, 0x7f, 0x6b, 0x82, 0x6b, 0x71, 0x69, 0x61, 0x58,
+ 0x4c, 0x00} },
+/********************************************/
+
+ {LCM_SEND(2), {0x00, 0xA7} },
+ {LCM_SEND(2), {0xB3, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0x92} },
+ {LCM_SEND(2), {0xB3, 0x45} },
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(2), {0xB3, 0x02} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(2), {0x36, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(9), {7, 0, 0xC0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03} },
+
+ {LCM_SEND(2), {0x00, 0xA0} },
+ {LCM_SEND(2), {0xC1, 0xE8} },
+
+ {LCM_SEND(2), {0x00, 0xA6} },
+ {LCM_SEND(6), {4, 0, 0xC1, 0x01, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(9), {7, 0, 0xCE, 0x87, 0x03, 0x00, 0x86, 0x03, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(9), {7, 0, 0xCE, 0x33, 0x54, 0x00, 0x33, 0x55, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0xA0} },
+ {LCM_SEND(17), {15, 0, 0xCE, 0x38, 0x03, 0x03, 0x58, 0x00, 0x00, 0x00,
+ 0x38, 0x02, 0x03, 0x59, 0x00, 0x00, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0xB0} },
+ {LCM_SEND(17), {15, 0, 0xCE, 0x38, 0x01, 0x03, 0x5A, 0x00, 0x00, 0x00,
+ 0x38, 0x00, 0x03, 0x5B, 0x00, 0x00, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0xC0} },
+ {LCM_SEND(17), {15, 0, 0xCE, 0x30, 0x00, 0x03, 0x5C, 0x00, 0x00, 0x00,
+ 0x30, 0x01, 0x03, 0x5D, 0x00, 0x00, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0xD0} },
+ {LCM_SEND(17), {15, 0, 0xCE, 0x38, 0x05, 0x03, 0x5E, 0x00, 0x00, 0x00,
+ 0x38, 0x04, 0x03, 0x5F, 0x00, 0x00, 0x00} },
+ {LCM_SLEEP(2)},
+
+ {LCM_SEND(2), {0x00, 0xC0} },
+ {LCM_SEND(13), {11, 0, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x80, 0x00, 0x09} },
+
+ {LCM_SEND(2), {0x00, 0xC0} },
+ {LCM_SEND(18), {16, 0, 0xCB, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0xD0} },
+ {LCM_SEND(18), {16, 0, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0xE0} },
+ {LCM_SEND(13), {11, 0, 0xCB, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(13), {11, 0, 0xCC, 0x00, 0x26, 0x25, 0x02, 0x06, 0x00, 0x00,
+ 0x0A, 0x0E, 0x0C} },
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(18), {16, 0, 0xCC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0xA0} },
+ {LCM_SEND(18), {16, 0, 0xCC, 0x0f, 0x0b, 0x0d, 0x09, 0x00, 0x00, 0x05,
+ 0x01, 0x25, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0xB0} },
+ {LCM_SEND(13), {11, 0, 0xCC, 0x00, 0x25, 0x26, 0x05, 0x01, 0x00, 0x00,
+ 0x0D, 0x09, 0x0B} },
+
+ {LCM_SEND(2), {0x00, 0xC0} },
+ {LCM_SEND(18), {16, 0, 0xCC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
+
+ {LCM_SEND(2), {0x00, 0xD0} },
+ {LCM_SEND(18), {16, 0, 0xCC, 0x10, 0x0c, 0x0a, 0x0e, 0x00, 0x00, 0x02,
+ 0x06, 0x26, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00} },
+
+/*-----------------AUTO SHIFT-------------------*/
+ {LCM_SEND(2), {0x00, 0x98} },
+ {LCM_SEND(2), {0xC0, 0x00} },
+ {LCM_SEND(2), {0x00, 0xA9} },
+ {LCM_SEND(2), {0xC0, 0x06} },
+ {LCM_SEND(2), {0x00, 0xB0} },
+ {LCM_SEND(6), {4, 0, 0xC1, 0x20, 0x00, 0x00} },
+ {LCM_SEND(2), {0x00, 0xE1} },
+ {LCM_SEND(5), {3, 0, 0xC0, 0x40, 0x18} },
+/*----------------------------------------------*/
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(2), {0xC4, 0x30} }, /*source blanking area=GND*/
+
+ {LCM_SEND(2), {0x00, 0x80} },
+ {LCM_SEND(5), {3, 0, 0xC1, 0x03, 0x33} },
+
+ {LCM_SEND(2), {0x00, 0x90} },
+ {LCM_SEND(2), {0xB6, 0xB4} },/*command fia*/
+ {LCM_SLEEP(10)},
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(2), {0xfb, 0x01} },
+
+ {LCM_SEND(2), {0x00, 0x00} },
+ {LCM_SEND(2), {4, 0, 0xFF, 0xFF, 0xFF, 0xFF} },
+
+ {LCM_SEND(1), {0x11} }, /*sleep out*/
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29} }, /*display on*/
+ {LCM_SLEEP(5)}, /*30, 100 ,50*/
+ {LCM_SEND(1), {0x2C} } /*normal on*/
+};
+
+static int32_t otm8019a_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode =
+ self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("otm8019a_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for (i = 0; i < ARRAY_SIZE(init_data); i++) {
+ tag = (init->tag >> 24);
+ if (tag & LCM_TAG_SEND) {
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ } else if (tag & LCM_TAG_SLEEP) {
+ mdelay((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+ return 0;
+}
+
+static uint32_t otm8019a_readid(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[5] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode =
+ self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_otm8019a_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1, 0);
+
+ for (j = 0; j < 4; j++) {
+ rd_prepare = rd_prep_code;
+ for (i = 0; i < ARRAY_SIZE(rd_prep_code); i++) {
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if (tag & LCM_TAG_SEND)
+ mipi_force_write(rd_prepare->datatype,
+ rd_prepare->real_cmd_code.data,
+ (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ else if (tag & LCM_TAG_SLEEP)
+ mdelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0xa1, 5, (uint8_t *)read_data);
+ LCD_PRINT("lcd_otm8019a_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x, 0x%x, 0x%x!\n",
+ read_data[0], read_data[1], read_data[2], read_data[3],
+ read_data[4]);
+
+ mipi_eotp_set(1, 1);
+
+ if ((0x01 == read_data[0]) && (0x8b == read_data[1]) &&
+ (0x80 == read_data[2]) && (0x19 == read_data[3]) &&
+ (0xff == read_data[4])) {
+ LCD_PRINT("lcd_otm8019a_mipi read id success!\n");
+ return 0x8019;
+ }
+ }
+
+ printk(KERN_ERR "lcd_otm8019a_mipi identify fail!\n");
+ return 0;
+}
+
+static uint32_t otm8019a_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_otm8019a_mipi read power mode!\n");
+ mipi_eotp_set(0, 1);
+ for (j = 0; j < 4; j++) {
+ rd_prepare = rd_prep_code_1;
+ for (i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++) {
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if (tag & LCM_TAG_SEND)
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data,
+ (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ else if (tag & LCM_TAG_SLEEP)
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1, (uint8_t *)read_data);
+ /*printk("lcd_otm80193a_mipi read power mode 0x0A value is 0x%x!,
+ read result(%d)\n", read_data[0], read_rtn);*/
+ if ((0x9c == read_data[0]) && (0 == read_rtn)) {
+ pr_debug("lcd_otm8019a_mipi read power mode success!\n");
+ mipi_eotp_set(1, 1);
+ return 0x9c;
+ }
+ }
+
+ printk(KERN_ERR "lcd_otm8019a_mipi read power mode fail!0x0A value is 0x%x!, read result(%d)\n",
+ read_data[0], read_rtn);
+ mipi_eotp_set(1, 1);
+ return 0x0;
+}
+
+static int32_t otm8019a_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+#ifndef FB_CHECK_ESD_IN_VFP
+ mipi_set_lp_mode_t mipi_set_data_lp_mode =
+ self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode =
+ self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+#endif
+
+ pr_debug("otm8019a_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if (SPRDFB_MIPI_MODE_CMD == work_mode)
+ mipi_set_lp_mode();
+ else
+ mipi_set_data_lp_mode();
+#endif
+ power_mode = otm8019a_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if (SPRDFB_MIPI_MODE_CMD == work_mode)
+ mipi_set_hs_mode();
+ else
+ mipi_set_data_hs_mode();
+#endif
+ if (power_mode == 0x9c) {
+ pr_debug("otm8019a_check_esd OK!\n");
+ return 1;
+ } else {
+ printk(KERN_ERR "otm8019a_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static int32_t otm8019a_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "otm8019a_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if (is_sleep) {
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ } else {
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1, 0);
+
+ for (i = 0; i < size; i++) {
+ tag = (sleep_in_out->tag >> 24);
+ if (tag & LCM_TAG_SEND)
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ else if (tag & LCM_TAG_SLEEP)
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ sleep_in_out++;
+ }
+ mipi_eotp_set(1, 1);
+
+ return 0;
+}
+
+static struct panel_operations lcd_otm8019a_mipi_operations = {
+ .panel_init = otm8019a_mipi_init,
+ .panel_readid = otm8019a_readid,
+ .panel_esd_check = otm8019a_check_esd,
+ .panel_enter_sleep = otm8019a_enter_sleep,
+};
+
+static struct timing_rgb lcd_otm8019a_mipi_timing = {
+ .hfp = 48, /*46*/
+ .hbp = 48, /*44*/
+ .hsync = 8,
+ .vfp = 16, /*14*/
+ .vbp = 16,
+ .vsync = 8,/* 2*/
+};
+
+static struct info_mipi lcd_otm8019a_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_otm8019a_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_otm8019a_mipi_spec = {
+ .width = 480,
+ .height = 854,
+ .fps = 60,
+ .reset_timing = {5, 40, 20},
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ /*.suspend_mode = SEND_SLEEP_CMD,*/
+ .info = {
+ .mipi = &lcd_otm8019a_mipi_info
+ },
+ .ops = &lcd_otm8019a_mipi_operations,
+};
+
+struct panel_cfg lcd_otm8019a_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8019,
+ .lcd_name = "lcd_otm8019a_mipi",
+ .panel = &lcd_otm8019a_mipi_spec,
+};
+
+static int __init lcd_otm8019a_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_otm8019a_mipi);
+}
+
+subsys_initcall(lcd_otm8019a_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_otm_8018b_mipi.c b/drivers/video/sprdfb/lcd/lcd_otm_8018b_mipi.c
new file mode 100644
index 00000000..7651fd4e
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_otm_8018b_mipi.c
@@ -0,0 +1,296 @@
+/* drivers/video/sc8825/lcd_otm8018b_mipi.c
+ *
+ * Support for otm8018b mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+#if 1
+{LCM_SEND(6), {4, 0, 0xff,0x80,0x09,0x01}},
+
+{LCM_SEND(2), {0x00,0x80}},
+{LCM_SEND(5), {3, 0, 0xff,0x80,0x09}},
+
+{LCM_SEND(2), {0x00,0x03}},
+{LCM_SEND(2), {0xFF,0x01}},
+
+{LCM_SEND(2), {0x00,0xB4}},
+{LCM_SEND(2), {0xC0,0x10}},
+
+{LCM_SEND(2), {0x00,0x82}},
+{LCM_SEND(2), {0xC5,0xA3}},
+
+{LCM_SEND(2), {0x00,0x90}},
+{LCM_SEND(5), {3, 0, 0xC5,0xC6,0x76}},
+
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(5), {3, 0, 0xD8,0x75,0x73}},
+
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(2), {0xD9,0x4E}},
+
+/*-------------Gamma+ ------*/
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(19), {17, 0, 0xE1,0x0C,0x0D,0x11,0x10,0x0A,0x1B,0x0B,0x0B,0x00,0x03,0x03,0x05,0x0D,0x24,0x21,0x05}},
+
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(19), {17, 0, 0xE2,0x0C,0x0D,0x11,0x12,0x0E,0x1D,0x0B,0x0B,0x00,0x03,0x03,0x05,0x0D,0x25,0x21,0x05}},
+
+{LCM_SEND(2), {0x00,0x81}},
+{LCM_SEND(2), {0xC1,0x66}},
+{LCM_SEND(2), {0x00,0xA1}},
+{LCM_SEND(2), {0xC1,0x08}},
+
+{LCM_SEND(2), {0x00,0x89}},
+{LCM_SEND(2), {0xC4,0x08}},
+
+{LCM_SEND(2), {0x00,0xA2}},
+{LCM_SEND(6), {4, 0, 0xC0,0x1B,0x00,0x02}},
+
+{LCM_SEND(2), {0x00,0x81}},
+{LCM_SEND(2), {0xC4,0x83}},
+
+{LCM_SEND(2), {0x00,0x92}},
+{LCM_SEND(2), {0xC5,0x01}},
+
+{LCM_SEND(2), {0x00,0xB1}},
+{LCM_SEND(2), {0xC5,0xA9}},
+
+/*C09x : mck_shift1/mck_shift2/mck_shift3*/
+{LCM_SEND(2), {0x00,0x90}},
+{LCM_SEND(9), {7, 0, 0xC0,0x00,0x44,0x00,0x00,0x00,0x03}},
+
+/*C1Ax : hs_shift/vs_shift*/
+{LCM_SEND(2), {0x00,0xA6}},
+{LCM_SEND(6), {4, 0, 0xC1,0x00,0x00,0x00}},
+
+//CE8x : vst1, vst2, vst3, vst4
+{LCM_SEND(2), {0x00,0x80}},
+{LCM_SEND(15), {13, 0, 0xCE,0x87,0x03,0x00,0x85,0x03,0x00,0x86,0x03,0x00,0x84,0x03,0x00}},
+
+//CEAx : clka1, clka2
+{LCM_SEND(2), {0x00,0xA0}},
+{LCM_SEND(17), {15, 0, 0xCE,0x38,0x03,0x03,0x58,0x00,0x00,0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00}},
+
+//CEBx : clka3, clka4
+{LCM_SEND(2), {0x00,0xB0}},
+{LCM_SEND(17), {15, 0, 0xCE,0x38,0x01,0x03,0x5A,0x00,0x00,0x00,0x38,0x00,0x03,0x5B,0x00,0x00,0x00}},
+
+//CECx : clkb1, clkb2
+{LCM_SEND(2), {0x00,0xC0}},
+{LCM_SEND(17), {15, 0, 0xCE,0x30,0x00,0x03,0x5C,0x00,0x00,0x00,0x30,0x01,0x03,0x5D,0x00,0x00,0x00}},
+
+//CEDx : clkb3, clkb4
+{LCM_SEND(2), {0x00,0xD0}},
+{LCM_SEND(17), {15, 0, 0xCE,0x30,0x02,0x03,0x5E,0x00,0x00,0x00,0x30,0x03,0x03,0x5F,0x00,0x00,0x00}},
+
+{LCM_SEND(2), {0x00, 0xC7}},
+{LCM_SEND(2), {0xCF, 0x00}},
+
+{LCM_SEND(2), {0x00, 0xC9}},
+{LCM_SEND(2), {0xCF, 0x00}},
+
+{LCM_SEND(2), {0x00, 0xC4}},
+{LCM_SEND(9), {7, 0, 0xCB,0x04,0x04,0x04,0x04,0x04,0x04}},
+
+{LCM_SEND(2), {0x00, 0xD9}},
+{LCM_SEND(9), {7, 0, 0xCB,0x04,0x04,0x04,0x04,0x04,0x04}},
+
+{LCM_SEND(2), {0x00, 0x84}},
+{LCM_SEND(9), {7, 0, 0xCC,0x0C,0x0A,0x10,0x0E,0x03,0x04}},
+
+{LCM_SEND(2), {0x00,0x9E}},
+{LCM_SEND(2), {0xCC,0x0B}},
+
+{LCM_SEND(2), {0x00,0xA0}},
+{LCM_SEND(8), {6, 0, 0xCC,0x09,0x0F,0x0D,0x01,0x02}},
+
+{LCM_SEND(2), {0x00,0xB4}},
+{LCM_SEND(9), {7, 0, 0xCC,0x0D,0x0F,0x09,0x0B,0x02,0x01}},
+
+{LCM_SEND(2), {0x00,0xCE}},
+{LCM_SEND(2), {0xCC,0x0E}},
+
+{LCM_SEND(2), {0x00,0xD0}},
+{LCM_SEND(8), {6, 0, 0xCC,0x10,0x0A,0x0C,0x04,0x03}},
+
+{LCM_SEND(2), {0x00,0x00}},
+{LCM_SEND(2), {0x3A,0x77}},
+
+{LCM_SEND(2), {0x11, 0x00}}, // sleep out
+{LCM_SLEEP(200),},
+{LCM_SEND(2), {0x29, 0x00}}, // display on
+
+{LCM_SEND(1), {0x2C}}, // normal on
+
+#endif
+
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static int32_t otm8018b_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ pr_debug(KERN_DEBUG "otm8018b_mipi_init\n");
+
+ mipi_set_cmd_mode();
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ return 0;
+}
+
+static uint32_t otm8018b_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ return 0x18;
+}
+
+static int32_t otm8018b_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "otm8018b_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static struct panel_operations lcd_otm8018b_mipi_operations = {
+ .panel_init = otm8018b_mipi_init,
+ .panel_readid = otm8018b_readid,
+ .panel_enter_sleep = otm8018b_enter_sleep,
+};
+
+static struct timing_rgb lcd_otm8018b_mipi_timing = {
+ .hfp = 80, /* unit: pixel */
+ .hbp = 80,
+ .hsync = 6,
+ .vfp = 10, /*unit: line*/
+ .vbp = 10,
+ .vsync = 6,
+};
+
+static struct info_mipi lcd_otm8018b_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_POS,
+ .shut_down_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_otm8018b_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_otm8018b_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_otm8018b_mipi_info
+ },
+ .ops = &lcd_otm8018b_mipi_operations,
+};
+
+struct panel_cfg lcd_otm8018b_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x18,
+ .lcd_name = "lcd_otm8018b_mipi",
+ .panel = &lcd_otm8018b_mipi_spec,
+};
+
+static int __init lcd_otm8018b_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_otm8018b_mipi);
+}
+
+subsys_initcall(lcd_otm8018b_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_rm68180_mipi.c b/drivers/video/sprdfb/lcd/lcd_rm68180_mipi.c
new file mode 100644
index 00000000..e100f38d
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_rm68180_mipi.c
@@ -0,0 +1,383 @@
+/* drivers/video/srpdfb/lcd_rm68180_mipi.c
+ *
+ * Support for rm68180 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_Delay(ms) uDelay(ms*1000)
+
+#define MAX_DATA 58
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code init_data[] = {
+#if 1 //l901 shengjing rm68180
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x01}},
+ {LCM_SEND(6),{4,0,0xB0,0x0D,0x0D,0x0D}},
+ {LCM_SEND(6),{4,0,0xB1,0x05,0x05,0x05}},
+ {LCM_SEND(6),{4,0,0xB6,0x34,0x34,0x34}},
+ {LCM_SEND(6),{4,0,0xB7,0x34,0x34,0x34}},
+ {LCM_SEND(6),{4,0,0xB8,0x24,0x24,0x24}},
+ {LCM_SEND(6),{4,0,0xB9,0x34,0x34,0x34}},
+ {LCM_SEND(6),{4,0,0xBA,0x04,0x04,0x04}},
+ {LCM_SEND(6),{4,0,0xBC,0x00,0x90,0x00}},
+ {LCM_SEND(6),{4,0,0xBD,0x00,0x90,0x00}},
+ {LCM_SEND(5),{3,0,0xBE,0x00,0x75}},
+ {LCM_SEND(2),{0xCC,0x05}},
+ {LCM_SEND(55),{53,0,0xD1,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(55),{53,0,0xD2,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(55),{53,0,0xD3,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(55),{53,0,0xD4,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(55),{53,0,0xD5,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(55),{53,0,0xD6,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x3B,0x00,0x60,0x00,0x9E,0x00,0xCF,0x01,0x17,0x01,0x4B,0x01,0x93,0x01,0xC6,0x02,0x10,0x02,0x48,0x02,0x49,0x02,0x79,0x02,0xAA,0x02,0xC4,0x02,0xE4,0x02,0xF8,0x03,0x10,0x03,0x20,0x03,0x36,0x03,0x46,0x03,0x5C,0x03,0x8B,0x03,0xFF}},
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x00}},
+ {LCM_SEND(2),{0xB1,0xFC}},
+ {LCM_SEND(2),{0xB4,0x10}},
+ {LCM_SEND(2),{0xB6,0x01}},
+ {LCM_SEND(7),{5,0,0xB8,0x01,0x04,0x04,0x04}},
+ {LCM_SEND(2),{0xBA,0x01}},
+ {LCM_SEND(6),{4,0,0xBC,0x02,0x02,0x02}},
+ {LCM_SEND(2),{0x3A,0x77}}, //0x55
+ {LCM_SEND(5),{3,0,0xC9,0xC0,0x01}},
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x02}},
+ {LCM_SEND(2),{0xF6,0x60}},
+ {LCM_SEND(2),{0x35,0x00}},
+ {LCM_SEND(2),{0x36,0x00}},
+ {LCM_SEND(5),{3,0,0x44,0x00,0x50}},
+ {LCM_SEND(8),{6,0,0xF0,0x55,0xAA,0x52,0x08,0x01}},
+ {LCM_SEND(7),{5,0,0x2A,0x00,0x00,0x01,0xDF}},
+ {LCM_SEND(7),{5,0,0x2B,0x00,0x00,0x03,0x1F}}, //0x355
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(100)},
+#endif
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(8), {0x6, 0, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(100)},
+{LCM_SEND(2), {0x4F,0x01}},
+//{LCM_SEND(2), {0x4f, 0x01}},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(100)},
+};
+
+static int32_t rm68180_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug(KERN_DEBUG "rm68180_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+ return 0;
+}
+
+static uint32_t rm68180_readid(struct panel_spec *self)
+{
+//{LCM_SEND(8), {6,0,0xF0,0x55,0xAA,0x52,0x08,0x01}},
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_rm68180_mipi read id!\n");
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+ //mipi_force_read(0x0, 3,(uint8_t *)read_data);
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000);
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x04, 3,(uint8_t *)read_data);
+ printk("lcd_rm68180_mipi read id value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+ //0x00 0x80 0x00
+ //return 0x80;
+ if((0x80 == read_data[1])){
+ self->info.mipi->ops->mipi_set_hs_mode();
+ printk("lcd_rm68180_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x80;
+ }
+ else
+ printk("lcd_rm68180_mipi read id failed!\n");
+
+ }
+ mipi_eotp_set(1,1);
+ return 0x00;
+}
+
+static uint32_t rm68180_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_rm68180_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_rm68180_mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_rm68180_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ printk("lcd_rm68180_mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t rm68180_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("rm68180_check_esd!\n");
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = rm68180_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("rm68180_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("rm68180_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static int32_t rm68180_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+
+ printk(KERN_DEBUG "rm68180_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+// printk(KERN_DEBUG "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy = %d\n", is_sleep);
+ //if (!is_sleep)
+// {
+// printk(KERN_DEBUG "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = %d\n", is_sleep);
+// mdelay(6000);
+// }
+ return 0;
+}
+
+static int32_t rm68180_mipi_after_suspend(struct panel_spec *self)
+{
+ return 0;
+}
+
+
+static struct panel_operations lcd_rm68180_mipi_operations = {
+ .panel_init = rm68180_mipi_init,
+ .panel_readid = rm68180_readid,
+ .panel_enter_sleep = rm68180_enter_sleep,
+ .panel_after_suspend = rm68180_mipi_after_suspend,
+ .panel_esd_check = rm68180_check_esd,
+};
+
+static struct timing_rgb lcd_rm68180_mipi_timing = {
+#if 1
+ .hfp = 20, /* unit: pixel */
+ .hbp = 20,
+ .hsync = 6,//4,
+ .vfp = 20, /*unit: line*/
+ .vbp = 20,
+ .vsync = 6,//6
+#else
+/*
+ .hfp = 120,
+ .hbp = 120,
+ .hsync = 60,
+ .vfp = 6,
+ .vbp = 6,
+ .vsync = 4,
+*/
+ .hfp =70,
+ .hbp = 40,
+ .hsync = 10,
+ .vfp = 10,
+ .vbp = 10,
+ .vsync = 12,
+#endif
+};
+
+static struct info_mipi lcd_rm68180_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 360*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_rm68180_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_rm68180_mipi_spec = {
+ .width = 480,
+ .height = 800, //854,
+ .fps = 60,
+ .reset_timing = {20,20,120},
+ //.suspend_mode = SEND_SLEEP_CMD,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_rm68180_mipi_info
+ },
+ .ops = &lcd_rm68180_mipi_operations,
+};
+
+struct panel_cfg lcd_rm68180_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x80,
+ .lcd_name = "lcd_rm68180_mipi",
+ .panel = &lcd_rm68180_mipi_spec,
+};
+
+static int __init lcd_rm68180_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_rm68180_mipi);
+}
+
+subsys_initcall(lcd_rm68180_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_s6d0139.c b/drivers/video/sprdfb/lcd/lcd_s6d0139.c
new file mode 100644
index 00000000..9ed5f1e0
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_s6d0139.c
@@ -0,0 +1,244 @@
+/* drivers/video/sc8800g/sc8800g_lcd_s6d0139.c
+ *
+ * Support for s6d0139 LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+static int32_t s6d0139_init(struct panel_spec *self)
+{
+ send_cmd_data_t send_cmd_data = self->info.mcu->ops->send_cmd_data;
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+ pr_debug(KERN_DEBUG "s6d0139_init\n");
+
+ /* reset the lcd */
+ self->ops->panel_reset(self);
+ mdelay(100);
+ /* start init sequence */
+ send_cmd_data(0x0000, 0x0001);
+ mdelay(10);
+
+ send_cmd_data(0x0007, 0x0000);
+ send_cmd_data(0x0013, 0x0000);
+ send_cmd_data(0x0011, 0x2604);
+ send_cmd_data(0x0014, 0x1212);
+ send_cmd_data(0x0010, 0x3C00);
+ send_cmd_data(0x0013, 0x0040);
+ mdelay(10);
+ send_cmd_data(0x0013, 0x0060);
+ mdelay(50);
+ send_cmd_data(0x0013, 0x0070);
+ mdelay(40);
+ send_cmd_data(0x0001, 0x0127);
+ send_cmd_data(0x0002, 0x0700);
+ send_cmd_data(0x0003, 0x1030);
+ send_cmd_data(0x0007, 0x0000);
+ send_cmd_data(0x0008, 0x0404);
+ send_cmd_data(0x000B, 0x0200);
+ send_cmd_data(0x000C, 0x0000);
+ send_cmd_data(0x0015, 0x0000);
+
+ //gamma setting
+ send_cmd_data(0x0030, 0x0000);
+ send_cmd_data(0x0031, 0x0606);
+ send_cmd_data(0x0032, 0x0006);
+ send_cmd_data(0x0033, 0x0403);
+ send_cmd_data(0x0034, 0x0107);
+ send_cmd_data(0x0035, 0x0101);
+ send_cmd_data(0x0036, 0x0707);
+ send_cmd_data(0x0037, 0x0304);
+ send_cmd_data(0x0038, 0x0A00);
+ send_cmd_data(0x0039, 0x0706);
+ send_cmd_data(0x0040, 0x0000);
+ send_cmd_data(0x0041, 0x0000);
+ send_cmd_data(0x0042, 0x013F);
+ send_cmd_data(0x0043, 0x0000);
+ send_cmd_data(0x0044, 0x0000);
+ send_cmd_data(0x0045, 0x0000);
+ send_cmd_data(0x0046, 0xEF00);
+ send_cmd_data(0x0047, 0x013F);
+ send_cmd_data(0x0048, 0x0000);
+ send_cmd_data(0x0007, 0x0011);
+ mdelay(40);
+ send_cmd_data(0x0007, 0x0017);
+ send_cmd_data(0x0020, 0x0000);
+ send_cmd_data(0x0021, 0x0000);
+ mdelay(40);
+
+ send_cmd(0x0022);
+
+
+ if(1){
+ int i = 0;
+ for (i=0; i<320*240/3; i++)
+ send_data(0xf800);
+ for (i=0; i< 320*240/3; i++)
+ send_data(0x07e0);
+ for (i=0; i< 320*240/3; i++)
+ send_data(0x001f);
+ }
+
+ return 0;
+}
+
+static int32_t s6d0139_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_cmd_data_t send_cmd_data = self->info.mcu->ops->send_cmd_data;
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ pr_debug(KERN_DEBUG "s6d0139_set_window\n");
+
+ send_cmd_data(0x46, ((right << 8) & 0xff00)|(left&0xff));
+ send_cmd_data(0x47, bottom);
+ send_cmd_data(0x48, top);
+
+ switch (self->direction) {
+ case LCD_DIRECT_NORMAL:
+ case LCD_DIRECT_ROT_270:
+ send_cmd_data(0x0020, left);
+ send_cmd_data(0x0021, top);
+ break;
+ case LCD_DIRECT_ROT_90:
+ case LCD_DIRECT_MIR_H:
+ send_cmd_data(0x0020, right);
+ send_cmd_data(0x0021, top);
+ break;
+ case LCD_DIRECT_ROT_180:
+ case LCD_DIRECT_MIR_HV:
+ send_cmd_data(0x0020, right);
+ send_cmd_data(0x0021, bottom);
+ break;
+ case LCD_DIRECT_MIR_V:
+ send_cmd_data(0x0020, left);
+ send_cmd_data(0x0021, bottom);
+ break;
+ default:
+ pr_debug(KERN_ERR "unknown lcd direction!\n");
+ break;
+ }
+
+ send_cmd(0x0022);
+
+ return 0;
+}
+
+static int32_t s6d0139_invalidate(struct panel_spec *self)
+{
+ pr_debug(KERN_DEBUG "s6d0139_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width-1, self->height-1);
+
+}
+
+static int32_t s6d0139_set_direction(struct panel_spec *self, uint16_t direction)
+{
+ send_cmd_data_t send_cmd_data = self->info.mcu->ops->send_cmd_data;
+ pr_debug(KERN_DEBUG "s6d0139_set_direction\n");
+
+ switch (direction) {
+ case LCD_DIRECT_NORMAL:
+ send_cmd_data(0x0003, 0x1030);
+ break;
+ case LCD_DIRECT_ROT_90:
+ send_cmd_data(0x0003, 0x1028);
+ break;
+ case LCD_DIRECT_ROT_180:
+ case LCD_DIRECT_MIR_HV:
+ send_cmd_data(0x0003, 0x1000);
+ break;
+ case LCD_DIRECT_ROT_270:
+ send_cmd_data(0x0003, 0x1018);
+ break;
+ case LCD_DIRECT_MIR_H:
+ send_cmd_data(0x0003, 0x1020);
+ break;
+ case LCD_DIRECT_MIR_V:
+ send_cmd_data(0x0003, 0x1010);
+ break;
+ default:
+ pr_debug(KERN_ERR "unknown lcd direction!\n");
+ send_cmd_data(0x0003, 0x1030);
+ direction = LCD_DIRECT_NORMAL;
+ break;
+ }
+
+ self->direction = direction;
+
+ return 0;
+}
+
+static struct panel_operations lcd_s6d0139_operations = {
+ .panel_init = s6d0139_init,
+ .panel_set_window = s6d0139_set_window,
+ .panel_invalidate = s6d0139_invalidate,
+ .panel_set_direction = s6d0139_set_direction,
+};
+
+
+static struct timing_mcu lcd_s6d0139_timing[] = {
+[MCU_LCD_REGISTER_TIMING] = { /* read/write register timing (ns) */
+ .rcss = 15,
+ .rlpw = 250,
+ .rhpw = 250,
+ .wcss = 10,
+ .wlpw = 28,
+ .whpw = 28,
+ },
+[MCU_LCD_GRAM_TIMING] = { /* read/write gram timing (ns) */
+ .rcss = 25, /* 25 ns */
+ .rlpw = 70,
+ .rhpw = 70,
+ .wcss = 10,
+ .wlpw = 50,
+ .whpw = 50,
+ }
+};
+
+static struct info_mcu lcd_s6d0139_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 16,
+ .bpp = 16, /*RGB565*/
+ .timing = lcd_s6d0139_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_s6d0139_spec = {
+ .width = 240,
+ .height = 320,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_s6d0139_info
+ },
+ .ops = &lcd_s6d0139_operations,
+};
+
+struct panel_cfg lcd_s6d0139 = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_UNDEFINELCD_ID,
+ .lcd_id = 0x139,
+ .lcd_name = "lcd_s6d0139",
+ .panel = &lcd_s6d0139_spec,
+};
+
+static int __init lcd_s6d0139_init(void)
+{
+ return sprdfb_panel_register(&lcd_s6d0139);
+}
+
+subsys_initcall(lcd_s6d0139_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_s6d77a1_pikeA_mipi.c b/drivers/video/sprdfb/lcd/lcd_s6d77a1_pikeA_mipi.c
new file mode 100644
index 00000000..9b186b7a
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_s6d77a1_pikeA_mipi.c
@@ -0,0 +1,330 @@
+/* drivers/video/sprdfb/lcd_s6d77a1_pikeA_mipi.c
+ *
+ * Support for s6d77a1 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+#define PIKEA_J1_NBW_PANEL
+
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+#ifndef PIKEA_J1_NBW_PANEL
+ {LCM_SEND(1),{0x11}},
+ {LCM_SEND(5),{3,0,0xF0,0x5A,0x5A}},
+ {LCM_SEND(5),{3,0,0xFC,0xA5,0xA5}},
+ {LCM_SEND(5),{3,0,0xF1,0x5A,0xA5}},
+
+ {LCM_SEND(2),{0xB3, 0x01}},
+ {LCM_SEND(2),{0xB5, 0x10}},
+ {LCM_SEND(6),{4,0,0xBC,0x01,0x29,0x51}}, /* 141006 Battery detect function disabled */
+
+ /* MIPI SETTING */
+ {LCM_SEND(5),{3,0,0xE3,0x24,0x2C}},
+
+ /* Display Inversion Off */
+ {LCM_SEND(1),{0x21}},
+
+ /* Display Control */
+ {LCM_SEND(10), {8,0,0xF2,0x11,0x04,0x08,0x10,0x10,0x82,0x54}},
+
+ /* power control 1 */
+ {LCM_SEND(8),{6,0,0xF3,0x91,0x00,0x00,0x00,0x10}},
+
+ /* power control 2 */
+ {LCM_SEND(46),{44,0,0xF4,0x01,0x02,0x23,0x24,0x25,0x25,0x26,0x26,0x29,0x29,0x2C,0x2B,0x2C,0x07,0x08,0x05,0x04,0x04,0x01,0x01,0x22,0x0A,0x17,0x0F,0x11,0x23,0x0D,0x0A,0x0B,0x02,0x19,0x13,0x1E,0x1F,0x23,0x20,0x05,0x16,0x1A,0x16,0x1E,0x24,0x1E}},
+
+ /* power control 3 */
+ {LCM_SEND(31),{29,0,0xF5,0x28,0x28,0xB9,0x21,0x35,0x55,0x36,0x0A,0x00,0x39,0x00,0x00,0x0B,0x4B,0xC4,0xCB,0x4B,0x12,0x12,0x1A,0x00,0x10,0xE0,0xE2,0x0E,0x34,0x34,0x03}},
+
+ /* 9.4 */
+ {LCM_SEND(20),{18,0,0xFE,0x00,0x02,0x01,0x39,0x60,0x40,0x21,0x00,0x4B,0x00,0x80,0x00,0xF0,0x00,0x00,0x00,0x02}},
+
+ /* ASG EQ Control */
+ {LCM_SEND(13),{11,0,0xEE,0x00,0xA8,0x00,0xA8,0x00,0x00,0x00,0x00,0x00,0x00}},
+
+ {LCM_SEND(24),{22,0,0xEF,0x23,0x01,0x00,0x00,0x2A,0x49,0x08,0x27,0x21,0x40,0x10,0x28,0x02,0x21,0x21,0x03,0x03,0x40,0x00,0x08,0x00}},
+
+ /* Panel Gate Control */
+ {LCM_SEND(33),{31,0,0xF7,0x02,0x1B,0x0D,0x0D,0x09,0x09,0x0C,0x0C,0x08,0x08,0x04,0x06,0x1A,0x02,0x02,0x02,0x1B,0x0F,0x0F,0x0B,0x0B,0x0E,0x0E,0x0A,0x0A,0x05,0x07,0x1A,0x02,0x02}},
+
+ /* Source Control */
+ {LCM_SEND(9),{7,0,0xF6,0x63,0x25,0x15,0x00,0x00,0x2A}},
+
+ /* Memory Data Access Control */
+ {LCM_SEND(2),{0x36,0x10}},
+
+ /* Positive Gamma Control */
+ {LCM_SEND(20),{18,0,0xFA,0x0C,0x36,0x11,0x17,0x0E,0x14,0x19,0x18,0x1A,0x21,0x23,0x22,0x22,0x21,0x22,0x22,0x29}},
+
+ /* Negative Gamma Control */
+ {LCM_SEND(20),{18,0,0xFB,0x0C,0x36,0x12,0x17,0x0F,0x14,0x19,0x18,0x1A,0x21,0x24,0x22,0x23,0x21,0x22,0x22,0x29}},
+
+ /* display on */
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(120)},
+#else
+
+ {LCM_SEND(5), {3, 0x00, 0xF0, 0x5A, 0x5A} },
+ {LCM_SEND(5), {3, 0x00, 0xFC, 0xA5, 0xA5} },
+ {LCM_SEND(2), {0xB3, 0x01} },
+ {LCM_SEND(2), {0xB5, 0x10} },
+ {LCM_SEND(6), {4, 0x00, 0xBC, 0x00, 0x29, 0x51} },
+ {LCM_SEND(5), {3, 0x00, 0xE3, 0x24, 0x2C} },
+ {LCM_SEND(1), {0x21} },
+ {LCM_SEND(10), {8, 0x00, 0xF2, 0x11, 0x04, 0x08, 0x10, 0x10, 0x82, 0x54} },
+ {LCM_SEND(8), {6, 0x00, 0xF3, 0x91, 0x00, 0x00, 0x00, 0x10} },
+ {LCM_SEND(46), {44, 0x00, 0xF4, 0x01, 0x02, 0x23, 0x24, 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2C, 0x2B, 0x2C,
+ 0x07, 0x08, 0x05, 0x04, 0x04, 0x01, 0x01, 0x22, 0x0A, 0x17, 0x0F, 0x11, 0x23, 0x0D, 0x0A, 0x0B,
+ 0x02, 0x19, 0x13, 0x1E, 0x1F, 0x23, 0x20, 0x05, 0x16, 0x1A, 0x16, 0x1E, 0x24, 0x1E} },
+ {LCM_SEND(31), {29, 0x00, 0xF5, 0x5A, 0x62, 0xB9, 0x21, 0x35, 0x55, 0x06, 0x08, 0x00, 0x39, 0x00, 0x00, 0x0B,
+ 0x4B, 0xC4, 0xCB, 0x4B, 0x12, 0x12, 0x1A, 0x00, 0x10, 0xE0, 0xE2, 0x0E, 0x34, 0x34, 0x03} },
+ {LCM_SEND(20), {18, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x39, 0x60, 0x40, 0x21, 0x00, 0x4B, 0x00, 0x80, 0x00, 0xF0,
+ 0x00, 0x00, 0x00, 0x02} },
+ {LCM_SEND(13), {11, 0x00, 0xEE, 0x86, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
+ {LCM_SEND(24), {22, 0x00, 0xEF, 0x34, 0x12, 0x00, 0x00, 0x0A, 0x29, 0x08, 0x27, 0x21, 0x40, 0x10, 0x28, 0x02,
+ 0x21, 0x21, 0x03, 0x03, 0x40, 0x00, 0x00, 0x00} },
+ {LCM_SEND(33), {31, 0x00, 0xF7, 0x02, 0x1B, 0x1A, 0x00, 0x01, 0x0D, 0x0D, 0x09, 0x09, 0x0C, 0x0C, 0x08, 0x08,
+ 0x04, 0x06, 0x02, 0x1B, 0x1A, 0x00, 0x01, 0x0F, 0x0F, 0x0B, 0x0B, 0x0E, 0x0E, 0x0A, 0x0A, 0x05, 0x07} },
+ {LCM_SEND(9), {7, 0x00, 0xF6, 0x63, 0x25, 0x15, 0x00, 0x00, 0x2E} },
+ {LCM_SEND(2), {0x36, 0x10} },
+ {LCM_SEND(20), {18, 0x00, 0xFA, 0x00, 0x3F, 0x09, 0x10, 0x08, 0x0D, 0x12, 0x12, 0x12, 0x18, 0x1B, 0x1B, 0x1D, 0x1E, 0x21, 0x25, 0x2D} },
+ {LCM_SEND(20), {18, 0x00, 0xFB, 0x00, 0x3F, 0x09, 0x11, 0x08, 0x0E, 0x13, 0x12, 0x13, 0x19, 0x1B, 0x1C, 0x1D, 0x1E, 0x21, 0x25, 0x2D} },
+ {LCM_SEND(10), {8, 0x00, 0xFD, 0x00, 0x10, 0x11, 0x20, 0x21, 0x1F, 0xCC} },
+ {LCM_SEND(5), {3, 0x00, 0xFC, 0x5A, 0x5A} },
+/* display on */
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+ {LCM_SLEEP(120)},
+#endif
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t s6d77a1_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel s6d77a1_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t s6d77a1_readid(struct panel_spec *self)
+ {
+ uint8_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_s6d77a1_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x03;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0x04, 3, read_data);
+ LCD_PRINT("lcd_s6d77a1_mipi read id 0xda, 0xdb,0xdc is 0x%x,0x%x,0x%x!\n",
+ read_data[0], read_data[1], read_data[2]);
+ if ((0x55 == read_data[0]) && (0xB8 == read_data[1])
+ && (0x10 == read_data[2])) {
+ LCD_PRINT("lcd_s6d77a1_mipi read id success!\n");
+ return 0x55b810;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ LCD_PRINT("lcd_s6d77a1_mipi read id failed!\n");
+ return 0;
+
+}
+
+
+static int32_t s6d77a1_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel s6d77a1_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_s6d77a1_mipi_operations = {
+ .panel_init = s6d77a1_mipi_init,
+ .panel_readid = s6d77a1_readid,
+ .panel_enter_sleep = s6d77a1_enter_sleep,
+};
+
+static struct timing_rgb lcd_s6d77a1_mipi_timing = {
+ .hfp = 84, /* unit: pixel */
+ .hbp = 90,
+ .hsync = 40,
+ .vfp = 16, /* unit: line */
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_s6d77a1_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_s6d77a1_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_s6d77a1_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_s6d77a1_mipi_info
+ },
+ .ops = &lcd_s6d77a1_mipi_operations,
+};
+struct panel_cfg lcd_s6d77a1_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x55b810,
+ .lcd_name = "lcd_s6d77a1_mipi",
+ .panel = &lcd_s6d77a1_mipi_spec,
+};
+
+
+static int __init lcd_s6d77a1_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_s6d77a1_mipi);
+}
+
+subsys_initcall(lcd_s6d77a1_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_s6d7aa0x62_t8_mipi.c b/drivers/video/sprdfb/lcd/lcd_s6d7aa0x62_t8_mipi.c
new file mode 100644
index 00000000..67f8df1b
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_s6d7aa0x62_t8_mipi.c
@@ -0,0 +1,350 @@
+/* drivers/video/sprdfb/lcd_hx8389b_mipi.c
+ *
+ * Support for hx8389b mipi LCD device
+ *
+ * Copyright (C) 2015 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <linux/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+ //Initializing Sequence(1)
+ {LCM_SEND(5), {3, 0, 0xF0, 0x5A, 0x5A} },
+ {LCM_SEND(5), {3, 0, 0xF1, 0x5A, 0x5A} },
+ {LCM_SEND(5), {3, 0, 0xFC, 0xA5, 0xA5} },
+ {LCM_SEND(5), {3, 0, 0xD0, 0x00, 0x10} },
+
+ //Initializing Sequence(2)
+ {LCM_SEND(2), {0xB1, 0x12} },
+ {LCM_SEND(7), {5, 0, 0xB2,0x14, 0x22, 0x2F, 0x18} },
+ {LCM_SEND(2), {0xB3, 0x11} },
+ {LCM_SEND(12), {10, 0, 0xBA,0x03,0x19,0x19,0x11,0x03,0x05,0x18,0x18,0x77} },
+ {LCM_SEND(6), {4, 0, 0xBC,0x00, 0x4E, 0x0B} },
+ {LCM_SEND(6), {4, 0, 0xC0,0x80, 0x80, 0x30} },
+ {LCM_SEND(2), {0xC1, 0x03} },
+ {LCM_SEND(2), {0xC2, 0x00} },
+ {LCM_SEND(6), {4, 0, 0xC3, 0x40,0x00, 0x28} },
+ {LCM_SEND(8), {6, 0, 0xE1, 0x03,0x10, 0x1C, 0xA0, 0x10} },
+ {LCM_SEND(11), {9, 0, 0xEE, 0xA5,0x00,0x98,0x00,0xA5,0x00,0x98,0x00} },
+ {LCM_SEND(8), {6, 0, 0xF2, 0x02,0x10, 0x10, 0x44, 0x10} },
+ {LCM_SEND(13), {11, 0, 0xF3, 0x01,0x93,0x20,0x22,0x80,0x05,0x25,0x3C,0x26,0x00} },
+ {LCM_SEND(48), {46, 0, 0xF4, 0x02,0x02,0x10,0x26,0x10,0x02,0x03,0x03,0x03,0x10,0x16,0x03, \
+ 0x00,0x0C,0x0C,0x03,0x04,0x05,0x13,0x1E,0x09,0x0A,0x05,0x05,0x01,0x04,0x02, \
+ 0x61,0x74,0x75,0x72,0x83,0x80,0x80,0x00,0x00,0x01,0x01,0x28,0x04,0x03,0x28, \
+ 0x01,0xD1,0x32} },
+ {LCM_SEND(35), {33, 0, 0xF7,0x01,0x1B,0x08,0x0C,0x09,0x0D,0x01,0x01,0x01,0x04,0x06,0x01,0x01, \
+ 0x00,0x00,0x1A,0x01,0x1B,0x0A,0x0E,0x0B,0x0F,0x01,0x01,0x01,0x05,0x07,0x01,0x01,
+ 0x00,0x00,0x1A} },
+ {LCM_SEND(9), {7, 0, 0xF6, 0x60,0x25, 0x05, 0x00, 0x00, 0x00} },
+ {LCM_SEND(8), {6, 0, 0xFD, 0x16,0x10, 0x11, 0x23, 0x09} },
+ {LCM_SEND(9), {7, 0, 0xFE, 0x00,0x02, 0x03, 0x21, 0x80, 0x78} },
+ {LCM_SEND(20), {18, 0, 0xEF,0x34,0x12,0x98,0xBA,0x10,0x80,0x24,0x80,0x80,0x80,0x00,0x00,0x00, \
+ 0x44,0xA0,0x82,0x00} },
+ {LCM_SEND(16), {14, 0, 0xCD,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E} },
+ {LCM_SEND(16), {14, 0, 0xCE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+ {LCM_SEND(2), {0x51, 0xFF} },
+ {LCM_SEND(2), {0x53, 0x2C} },
+ {LCM_SEND(2), {0x55, 0x01} },
+
+ // Initializing Sequence(3)
+ {LCM_SEND(20), {18, 0, 0xFA,0x08,0x3F,0x0D,0x12,0x07,0x0C,0x11,0x0F,0x11,0x18,0x1D,0x1E,0x21,\
+ 0x23,0x24,0x27,0x30,} },
+ {LCM_SEND(20), {18, 0, 0xF8,0x08,0x3F,0x0C,0x12,0x07,0x0C,0x10,0x0F,0x11,0x18,0x1D,0x1E,0x21,\
+ 0x23,0x23,0x26,0x2F} },
+
+ // Initializing Sequence(1-1)
+ {LCM_SEND(5), {3, 0, 0xF0, 0xA5, 0xA5} },
+ {LCM_SEND(5), {3, 0, 0xF1, 0xA5, 0xA5} },
+ {LCM_SEND(5), {3, 0, 0xFC, 0x5A, 0x5A} },
+
+ // power on
+ {LCM_SEND(1), {0x11} },
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29} },
+ {LCM_SLEEP(20)},
+
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+
+static int32_t s6d7aa0x62_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel s6d7aa0x62_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t s6d7aa0x62_readid(struct panel_spec *self)
+{
+#if 0
+ uint32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("lcd_s6d7aa0x62_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x03;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0x04,3, &read_data[0]);
+ LCD_PRINT("lcd_s6d7aa0x62_mipi read id 0x04 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if(0x83 == read_data[0] && 0x94 == read_data[1] && 0x1A == read_data[2]){
+ LCD_PRINT("s6d7aa0x62 success!\n");
+ return 0xaa62;
+ }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+#endif
+ return 0x6262;
+}
+
+static uint32_t s6d7aa0x62_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_s6d7aa0x62_mipi read power mode!\n");
+ mipi_eotp_set(0,0);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ pr_debug("lcd_hx8389b mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ if((0x1c == read_data[0])){
+ //printk("lcd_hx8389b_mipi read power mode success!\n");
+ mipi_eotp_set(0,0);
+ return 0x1c;
+ }
+ }
+
+ printk("lcd_s6d7aa0x62 mipi read power mode fail!0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+ mipi_eotp_set(0,0);
+ return 0x0;
+}
+
+static int32_t s6d7aa0x62_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ pr_debug("s6d7aa0x62_check_esd!\n");
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+#endif
+ power_mode = s6d7aa0x62_readpowermode(self);
+ //power_mode = 0x0;
+#ifndef FB_CHECK_ESD_IN_VFP
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+#endif
+ if(power_mode == 0x1c){
+ pr_debug("s6d7aa0x62_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("s6d7aa0x62_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_s6d7aa0x62_mipi_operations = {
+ .panel_init = s6d7aa0x62_mipi_init,
+ .panel_readid = s6d7aa0x62_readid,
+ .panel_esd_check = s6d7aa0x62_check_esd,
+};
+
+static struct timing_rgb lcd_s6d7aa0x62_mipi_timing = {
+ .hfp = 104, /* unit: pixel */
+ .hbp = 154,
+ .hsync = 1,
+ .vfp = 16, /*unit: line*/
+ .vbp = 12,
+ .vsync = 1,
+};
+
+
+static struct info_mipi lcd_s6d7aa0x62_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq = 481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_s6d7aa0x62_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_s6d7aa0x62_mipi_spec = {
+ .width = 720,
+ .height = 1280,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_s6d7aa0x62_mipi_info
+ },
+ .ops = &lcd_s6d7aa0x62_mipi_operations,
+};
+
+struct panel_cfg lcd_s6d7aa0x62_mipi = {
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x6262,
+ .lcd_name = "lcd_s6d7aa0x62_mipi",
+ .panel = &lcd_s6d7aa0x62_mipi_spec,
+};
+
+static int __init lcd_s6d7aa0x62_mipi_init(void)
+{
+#if 0
+ if (gpio_request(152, "LCD_3V3")) {
+ printk("Failed ro request LCD_3V3 GPIO_%d \n",152);
+ return -ENODEV;
+ }
+ if (gpio_request(155, "BL_EN")) {
+ printk("Failed ro request BL_EN GPIO_%d \n",155);
+ return -ENODEV;
+ }
+ if (gpio_request(232, "CABC_EN0")) {
+ printk("Failed ro request CABC_EN0 GPIO_%d \n",232);
+ return -ENODEV;
+ }
+ if (gpio_request(233, "CABC_EN1")) {
+ printk("Failed ro request CABC_EN1 GPIO_%d \n",233);
+ return -ENODEV;
+ }
+ gpio_direction_output(152, 1);
+ gpio_direction_output(155, 1);
+ gpio_direction_output(232, 1);
+ gpio_direction_output(233, 1);
+#endif
+ return sprdfb_panel_register(&lcd_s6d7aa0x62_mipi);
+}
+
+subsys_initcall(lcd_s6d7aa0x62_mipi_init);
+
+
diff --git a/drivers/video/sprdfb/lcd/lcd_sc7798_rgb_spi.c b/drivers/video/sprdfb/lcd/lcd_sc7798_rgb_spi.c
new file mode 100755
index 00000000..0b9d7a73
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_sc7798_rgb_spi.c
@@ -0,0 +1,561 @@
+/* drivers/video/sc8810/lcd_hx8363_rgb_spi.c
+ *
+ *
+ *
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+
+
+
+#define sc7798_SpiWriteCmd(cmd) \
+{ \
+ spi_send_cmd((cmd & 0xFF));\
+}
+
+#define sc7798_SpiWriteData(data)\
+{ \
+ spi_send_data((data & 0xFF));\
+}
+static int32_t sc7798_init(struct panel_spec *self)
+{
+ uint32_t test_data[8] = {0};
+ uint32_t left = 0;
+ uint32_t top = 0;
+ uint32_t right = 480;
+ uint32_t bottom = 800;
+ uint32_t data = 0;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+
+
+ printk("sc7798_init\n");
+
+ sc7798_SpiWriteCmd(0xB9);
+ sc7798_SpiWriteData(0xF1);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x00);
+
+ sc7798_SpiWriteCmd(0xBC);
+ sc7798_SpiWriteData(0x67);
+
+ sc7798_SpiWriteCmd(0x3A);
+ sc7798_SpiWriteData(0x70);
+
+ sc7798_SpiWriteCmd(0xB2);
+ sc7798_SpiWriteData(0x23);
+
+ sc7798_SpiWriteCmd(0xB4);
+ sc7798_SpiWriteData(0x00);
+
+ sc7798_SpiWriteCmd(0xB1);
+ sc7798_SpiWriteData(0x22);
+ sc7798_SpiWriteData(0x1B);
+ sc7798_SpiWriteData(0x1B);
+ sc7798_SpiWriteData(0xB7);
+ sc7798_SpiWriteData(0x22);
+ sc7798_SpiWriteData(0x02);
+ sc7798_SpiWriteData(0xA8);
+
+ sc7798_SpiWriteCmd(0xC6);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0xFF);
+
+ sc7798_SpiWriteCmd(0xCC);
+ sc7798_SpiWriteData(0x0C);
+
+ sc7798_SpiWriteCmd(0xE3);
+ sc7798_SpiWriteData(0x02);
+ sc7798_SpiWriteData(0x02);
+ sc7798_SpiWriteData(0x02);
+ sc7798_SpiWriteData(0x02);
+
+
+ sc7798_SpiWriteCmd(0xB8);
+ sc7798_SpiWriteData(0x07);
+ sc7798_SpiWriteData(0x22);
+
+ sc7798_SpiWriteCmd(0xB5);
+ sc7798_SpiWriteData(0x09);
+ sc7798_SpiWriteData(0x09);
+
+ sc7798_SpiWriteCmd(0xC0);
+ sc7798_SpiWriteData(0x73);
+ sc7798_SpiWriteData(0x50);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x70);
+
+ sc7798_SpiWriteCmd(0xB3);
+ sc7798_SpiWriteData(0x01);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x06);
+ sc7798_SpiWriteData(0x06);
+ sc7798_SpiWriteData(0x10);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x45);
+ sc7798_SpiWriteData(0x40);
+
+ sc7798_SpiWriteCmd(0xB9);
+ sc7798_SpiWriteData(0xF1);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x00);
+
+ sc7798_SpiWriteCmd(0xE9);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x03);
+ sc7798_SpiWriteData(0x2F);
+ sc7798_SpiWriteData(0x89);
+ sc7798_SpiWriteData(0x6A);
+ sc7798_SpiWriteData(0x12);
+ sc7798_SpiWriteData(0x31);
+ sc7798_SpiWriteData(0x23);
+ sc7798_SpiWriteData(0x48);
+ sc7798_SpiWriteData(0x0C);
+ sc7798_SpiWriteData(0x89);
+ sc7798_SpiWriteData(0x6A);
+ sc7798_SpiWriteData(0x47);
+ sc7798_SpiWriteData(0x02);
+ sc7798_SpiWriteData(0x04);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x20);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x40);
+ sc7798_SpiWriteData(0x28);
+ sc7798_SpiWriteData(0x69);
+ sc7798_SpiWriteData(0x48);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x80);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x51);
+ sc7798_SpiWriteData(0x38);
+ sc7798_SpiWriteData(0x79);
+ sc7798_SpiWriteData(0x58);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x81);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+
+ sc7798_SpiWriteCmd(0xEA);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x37);
+ sc7798_SpiWriteData(0x59);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x85);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x26);
+ sc7798_SpiWriteData(0x49);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x08);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x84);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0xFF);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x50);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+
+ sc7798_SpiWriteCmd(0xE0);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x04);
+ sc7798_SpiWriteData(0x04);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x2B);
+ sc7798_SpiWriteData(0x05);
+ sc7798_SpiWriteData(0x0C);
+ sc7798_SpiWriteData(0x11);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x15);
+ sc7798_SpiWriteData(0x19);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x04);
+ sc7798_SpiWriteData(0x04);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x2C);
+ sc7798_SpiWriteData(0x05);
+ sc7798_SpiWriteData(0x0C);
+ sc7798_SpiWriteData(0x12);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x18);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x17);
+ sc7798_SpiWriteData(0x16);
+ sc7798_SpiWriteData(0x19);
+
+#if 0
+ sc7798_SpiWriteCmd(0xC1);
+ sc7798_SpiWriteData(0x01);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x03);
+ sc7798_SpiWriteData(0x0B);
+ sc7798_SpiWriteData(0x17);
+ sc7798_SpiWriteData(0x20);
+ sc7798_SpiWriteData(0x26);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0x36);
+ sc7798_SpiWriteData(0x3F);
+ sc7798_SpiWriteData(0x48);
+ sc7798_SpiWriteData(0x50);
+ sc7798_SpiWriteData(0x58);
+ sc7798_SpiWriteData(0x5F);
+ sc7798_SpiWriteData(0x68);
+ sc7798_SpiWriteData(0x71);
+ sc7798_SpiWriteData(0x79);
+ sc7798_SpiWriteData(0x82);
+ sc7798_SpiWriteData(0x89);
+ sc7798_SpiWriteData(0x91);
+ sc7798_SpiWriteData(0x99);
+ sc7798_SpiWriteData(0xA1);
+ sc7798_SpiWriteData(0xA9);
+ sc7798_SpiWriteData(0xB0);
+ sc7798_SpiWriteData(0xB8);
+ sc7798_SpiWriteData(0xC0);
+ sc7798_SpiWriteData(0xC8);
+ sc7798_SpiWriteData(0xD0);
+ sc7798_SpiWriteData(0xD6);
+ sc7798_SpiWriteData(0xDC);
+ sc7798_SpiWriteData(0xE4);
+ sc7798_SpiWriteData(0xED);
+ sc7798_SpiWriteData(0xF7);
+ sc7798_SpiWriteData(0xFF);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0xC0);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x80);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0xE8);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x03);
+ sc7798_SpiWriteData(0x0B);
+ sc7798_SpiWriteData(0x17);
+ sc7798_SpiWriteData(0x20);
+ sc7798_SpiWriteData(0x27);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0x37);
+ sc7798_SpiWriteData(0x40);
+ sc7798_SpiWriteData(0x48);
+ sc7798_SpiWriteData(0x50);
+ sc7798_SpiWriteData(0x58);
+ sc7798_SpiWriteData(0x5F);
+ sc7798_SpiWriteData(0x67);
+ sc7798_SpiWriteData(0x70);
+ sc7798_SpiWriteData(0x78);
+ sc7798_SpiWriteData(0x80);
+ sc7798_SpiWriteData(0x88);
+ sc7798_SpiWriteData(0x90);
+ sc7798_SpiWriteData(0x98);
+ sc7798_SpiWriteData(0xA0);
+ sc7798_SpiWriteData(0xA8);
+ sc7798_SpiWriteData(0xAF);
+ sc7798_SpiWriteData(0xB7);
+ sc7798_SpiWriteData(0xBF);
+ sc7798_SpiWriteData(0xC7);
+ sc7798_SpiWriteData(0xCF);
+ sc7798_SpiWriteData(0xD5);
+ sc7798_SpiWriteData(0xDC);
+ sc7798_SpiWriteData(0xE4);
+ sc7798_SpiWriteData(0xED);
+ sc7798_SpiWriteData(0xF7);
+ sc7798_SpiWriteData(0xFF);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0xC0);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x80);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0xE8);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x03);
+ sc7798_SpiWriteData(0x0D);
+ sc7798_SpiWriteData(0x19);
+ sc7798_SpiWriteData(0x23);
+ sc7798_SpiWriteData(0x29);
+ sc7798_SpiWriteData(0x31);
+ sc7798_SpiWriteData(0x38);
+ sc7798_SpiWriteData(0x41);
+ sc7798_SpiWriteData(0x48);
+ sc7798_SpiWriteData(0x4F);
+ sc7798_SpiWriteData(0x57);
+ sc7798_SpiWriteData(0x5D);
+ sc7798_SpiWriteData(0x65);
+ sc7798_SpiWriteData(0x6C);
+ sc7798_SpiWriteData(0x74);
+ sc7798_SpiWriteData(0x7B);
+ sc7798_SpiWriteData(0x84);
+ sc7798_SpiWriteData(0x8B);
+ sc7798_SpiWriteData(0x94);
+ sc7798_SpiWriteData(0x9B);
+ sc7798_SpiWriteData(0xA4);
+ sc7798_SpiWriteData(0xAA);
+ sc7798_SpiWriteData(0xB4);
+ sc7798_SpiWriteData(0xB9);
+ sc7798_SpiWriteData(0xC3);
+ sc7798_SpiWriteData(0xCC);
+ sc7798_SpiWriteData(0xD6);
+ sc7798_SpiWriteData(0xDC);
+ sc7798_SpiWriteData(0xE4);
+ sc7798_SpiWriteData(0xED);
+ sc7798_SpiWriteData(0xF7);
+ sc7798_SpiWriteData(0xFF);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0x00);
+ sc7798_SpiWriteData(0xC0);
+ sc7798_SpiWriteData(0x0A);
+ sc7798_SpiWriteData(0x80);
+ sc7798_SpiWriteData(0x30);
+ sc7798_SpiWriteData(0xE8);
+ sc7798_SpiWriteData(0x00);
+#endif
+
+ sc7798_SpiWriteCmd(0x11);
+ mdelay(120);
+ sc7798_SpiWriteCmd(0x29);
+}
+
+
+#if 1
+static int32_t sc7798_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+
+ if(is_sleep==1){
+ //Sleep In
+ sc7798_SpiWriteCmd(0x28);
+ mdelay(120);
+ sc7798_SpiWriteCmd(0x10);
+ mdelay(10);
+ }else{
+ //Sleep Out
+ sc7798_SpiWriteCmd(0x11);
+ mdelay(120);
+ sc7798_SpiWriteCmd(0x29);
+ mdelay(10);
+ }
+
+ return 0;
+}
+
+
+
+
+static int32_t sc7798_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ uint32_t *test_data[4] = {0};
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+#if 0
+
+ printk("zxdbg add -hx8363_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
+
+ sc7798_SpiWriteCmd(0x2A00);
+ sc7798_SpiWriteData((left>>8));// set left address
+ sc7798_SpiWriteData((left&0xff));
+ sc7798_SpiWriteData((right>>8));// set right address
+ sc7798_SpiWriteData((right&0xff));
+
+ sc7798_SpiWriteCmd(0x2B00);
+ sc7798_SpiWriteData((top>>8));// set left address
+ sc7798_SpiWriteData((top&0xff));
+ sc7798_SpiWriteData((bottom>>8));// set bottom address
+ sc7798_SpiWriteData((bottom&0xff));
+
+// HX8363_SpiWriteCmd(0x2C00);
+
+ sc7798_SpiWriteCmd(0x2A00);
+ spi_read(test_data);
+ spi_read(test_data+1);
+ sc7798_SpiWriteCmd(0x2B00);
+ spi_read(test_data+2);
+ spi_read(test_data+3);
+#endif
+// printk("zxdbg add -hx8363_read read: %x, %x, %x, %x\n",test_data[0], test_data[1], test_data[2], test_data[3]);
+
+ return 0;
+}
+
+static int32_t sc7798_invalidate(struct panel_spec *self)
+{
+// printk("hx8363_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width - 1, self->height - 1);
+}
+
+
+
+static int32_t sc7798_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+// printk("hx8363_invalidate_rect \n");
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+
+#endif
+
+
+static int32_t sc7798_read_id(struct panel_spec *self)
+{
+#if 0
+ int32_t id = 0x62;
+ spi_send_cmd_t spi_send_cmd = self->info.rgb->bus_info.spi->ops->spi_send_cmd;
+ spi_send_data_t spi_send_data = self->info.rgb->bus_info.spi->ops->spi_send_data;
+ spi_read_t spi_read = self->info.rgb->bus_info.spi->ops->spi_read;
+/*
+ printk("sprdfb hx8363_read_id \n");
+ HX8363_SpiWriteCmd(0xB9); // SET password
+ HX8363_SpiWriteData(0xFF); //
+ HX8363_SpiWriteData(0x83); //
+ HX8363_SpiWriteData(0x63); //
+
+ HX8363_SpiWriteCmd(0xFE); // SET SPI READ INDEX
+ HX8363_SpiWriteData(0xF4); // GETHXID
+ HX8363_SpiWriteCmd(0xFF); // GET SPI READ
+
+ spi_read(&id);
+*/
+ id &= 0xff;
+ printk(" hx8363_read_id kernel id = %x\n",id);
+// return id;
+#endif
+ return 0x7798;
+}
+
+static struct panel_operations lcd_sc7798_rgb_spi_operations = {
+ .panel_init = sc7798_init,
+ .panel_set_window = sc7798_set_window,
+ .panel_invalidate_rect= sc7798_invalidate_rect,
+ .panel_invalidate = sc7798_invalidate,
+ .panel_enter_sleep = sc7798_enter_sleep,
+ .panel_readid = sc7798_read_id
+};
+
+static struct timing_rgb lcd_sc7798_rgb_timing = {
+ .hfp = 90,
+ .hbp = 70,
+ .hsync = 60,
+ .vfp = 8,
+ .vbp = 12,
+ .vsync = 4,
+
+};
+
+static struct spi_info lcd_sc7798_rgb_spi_info = {
+ .ops = NULL,
+};
+
+static struct info_rgb lcd_sc7798_rgb_info = {
+ .cmd_bus_mode = SPRDFB_RGB_BUS_TYPE_SPI,
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_NEG,
+ .v_sync_pol = SPRDFB_POLARITY_NEG,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_sc7798_rgb_timing,
+ .bus_info = {
+ .spi = &lcd_sc7798_rgb_spi_info,
+ }
+};
+
+struct panel_spec lcd_panel_sc7798_rgb_spi_spec = {
+
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_RGB,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .rgb = &lcd_sc7798_rgb_info
+ },
+ .ops = &lcd_sc7798_rgb_spi_operations,
+};
+
+struct panel_cfg lcd_sc7798_rgb_spi_spec = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x7798,
+ .lcd_name = "lcd_sc7798_rgb_spi",
+ .panel = &lcd_panel_sc7798_rgb_spi_spec,
+};
+
+static int __init lcd_sc7798_rgb_spi_init(void)
+{
+ return sprdfb_panel_register(&lcd_sc7798_rgb_spi_spec);
+
+}
+
+subsys_initcall(lcd_sc7798_rgb_spi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi.c b/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi.c
new file mode 100755
index 00000000..e377c3c5
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi.c
@@ -0,0 +1,261 @@
+/* drivers/video/sprdfb/lcd_sc7798d_mipi.c
+ *
+ * Support for sc7798d mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(6), {4, 0, 0xB9, 0xF1, 0x08, 0x00} },
+ /*{LCM_SLEEP(10)},*/
+ {LCM_SEND(10), {8, 0, 0xB1, 0x31, 0x0C, 0x0C, 0xA7, 0x33, 0x01, 0xB7} },
+ {LCM_SEND(6), {4, 0, 0xC6, 0x00, 0x00, 0xFD} },
+ {LCM_SEND(7), {5, 0, 0xE3, 0x03, 0x03, 0x03, 0x03} },
+ {LCM_SEND(5), {3, 0, 0xB8, 0x06, 0x22} },
+ {LCM_SLEEP(10)},
+ {LCM_SEND(21), {19, 0, 0xBA, 0x31, 0x00, 0x44, 0x25, 0x91, 0x0A, 0x00, 0x00, 0xC2, 0x34, 0x00, 0x00, 0x04, 0x02, 0x1D,
+ 0xB9, 0xEE, 0x40} },
+ {LCM_SEND(11), {9, 0, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x25, 0x20} },
+ {LCM_SEND(2), {0xB4, 0x00} },
+ {LCM_SEND(2), {0xCC, 0x0E} },
+ {LCM_SEND(2), {0xBC, 0x67} },
+ {LCM_SEND(2), {0xB2, 0x03} },
+ {LCM_SEND(8), {6, 0, 0xC0, 0x73, 0x50, 0x00, 0x08, 0x70} },
+ {LCM_SEND(54), {52, 0, 0xE9, 0x00, 0x00, 0x06, 0x00, 0x00, 0x6E, 0x29, 0x12, 0x30, 0x00, 0x48, 0x08, 0x6E, 0x29, 0x47,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x89, 0x98, 0x33, 0x11, 0x77, 0x55,
+ 0x13, 0x00, 0x00, 0x89, 0x98, 0x22, 0x00, 0x66, 0x44, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} },
+ {LCM_SEND(39), {37, 0, 0xEA, 0x00, 0x00, 0x98, 0x98, 0x44, 0x66, 0x00, 0x22, 0x20, 0x00, 0x00, 0x98, 0x98, 0x55, 0x77,
+ 0x11, 0x33, 0x31, 0x30, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} },
+ {LCM_SEND(37), {35, 0, 0xE0, 0x01, 0x09, 0x0D, 0x2E, 0x36, 0x3F, 0x10, 0x31, 0x07, 0x0D, 0x11, 0x15, 0x13, 0x16, 0x15,
+ 0x32, 0x38, 0x01, 0x05, 0x05, 0x30, 0x35, 0x3F, 0x0E, 0x30, 0x04, 0x09, 0x0A, 0x0D, 0x12,
+ 0x0D, 0x0F, 0x2C, 0x35} },
+ {LCM_SEND(1), {0x11} },
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29} },
+ {LCM_SLEEP(20)},
+
+};
+
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t sc7798d_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel sc7798d_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t sc7798d_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_sc7798d_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0xF0 == read_data[2]))
+ {
+ printk("lcd_sc7798d_mipi read id success!\n");
+ return 0x55b8f0;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_sc7798d_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t sc7798d_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel sc7798d_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_sc7798d_mipi_operations = {
+ .panel_init = sc7798d_mipi_init,
+ .panel_readid = sc7798d_readid,
+ .panel_enter_sleep = sc7798d_enter_sleep,
+};
+
+static struct timing_rgb lcd_sc7798d_mipi_timing = {
+ .hfp = 145, /* unit: pixel */
+ .hbp = 90,
+ .hsync = 70,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_sc7798d_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_sc7798d_mipi_timing,
+ .ops = NULL,
+};
+struct panel_spec lcd_sc7798d_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_sc7798d_mipi_info
+ },
+ .ops = &lcd_sc7798d_mipi_operations,
+};
+struct panel_cfg lcd_sc7798d_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x55b8f0,
+ .lcd_name = "lcd_sc7798d_mipi",
+ .panel = &lcd_sc7798d_mipi_spec,
+};
+
+//temp code
+static int __init lcd_sc7798d_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_sc7798d_mipi);
+}
+
+subsys_initcall(lcd_sc7798d_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi_sharkls_z3lte.c b/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi_sharkls_z3lte.c
new file mode 100755
index 00000000..e377c3c5
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_sd7798d_mipi_sharkls_z3lte.c
@@ -0,0 +1,261 @@
+/* drivers/video/sprdfb/lcd_sc7798d_mipi.c
+ *
+ * Support for sc7798d mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 150
+
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(6), {4, 0, 0xB9, 0xF1, 0x08, 0x00} },
+ /*{LCM_SLEEP(10)},*/
+ {LCM_SEND(10), {8, 0, 0xB1, 0x31, 0x0C, 0x0C, 0xA7, 0x33, 0x01, 0xB7} },
+ {LCM_SEND(6), {4, 0, 0xC6, 0x00, 0x00, 0xFD} },
+ {LCM_SEND(7), {5, 0, 0xE3, 0x03, 0x03, 0x03, 0x03} },
+ {LCM_SEND(5), {3, 0, 0xB8, 0x06, 0x22} },
+ {LCM_SLEEP(10)},
+ {LCM_SEND(21), {19, 0, 0xBA, 0x31, 0x00, 0x44, 0x25, 0x91, 0x0A, 0x00, 0x00, 0xC2, 0x34, 0x00, 0x00, 0x04, 0x02, 0x1D,
+ 0xB9, 0xEE, 0x40} },
+ {LCM_SEND(11), {9, 0, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x25, 0x20} },
+ {LCM_SEND(2), {0xB4, 0x00} },
+ {LCM_SEND(2), {0xCC, 0x0E} },
+ {LCM_SEND(2), {0xBC, 0x67} },
+ {LCM_SEND(2), {0xB2, 0x03} },
+ {LCM_SEND(8), {6, 0, 0xC0, 0x73, 0x50, 0x00, 0x08, 0x70} },
+ {LCM_SEND(54), {52, 0, 0xE9, 0x00, 0x00, 0x06, 0x00, 0x00, 0x6E, 0x29, 0x12, 0x30, 0x00, 0x48, 0x08, 0x6E, 0x29, 0x47,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x89, 0x98, 0x33, 0x11, 0x77, 0x55,
+ 0x13, 0x00, 0x00, 0x89, 0x98, 0x22, 0x00, 0x66, 0x44, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} },
+ {LCM_SEND(39), {37, 0, 0xEA, 0x00, 0x00, 0x98, 0x98, 0x44, 0x66, 0x00, 0x22, 0x20, 0x00, 0x00, 0x98, 0x98, 0x55, 0x77,
+ 0x11, 0x33, 0x31, 0x30, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} },
+ {LCM_SEND(37), {35, 0, 0xE0, 0x01, 0x09, 0x0D, 0x2E, 0x36, 0x3F, 0x10, 0x31, 0x07, 0x0D, 0x11, 0x15, 0x13, 0x16, 0x15,
+ 0x32, 0x38, 0x01, 0x05, 0x05, 0x30, 0x35, 0x3F, 0x0E, 0x30, 0x04, 0x09, 0x0A, 0x0D, 0x12,
+ 0x0D, 0x0F, 0x2C, 0x35} },
+ {LCM_SEND(1), {0x11} },
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1), {0x29} },
+ {LCM_SLEEP(20)},
+
+};
+
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(1), {0x28}},
+ {LCM_SLEEP(150)}, //>150ms
+ {LCM_SEND(1), {0x10}},
+ {LCM_SLEEP(150)}, //>150ms
+};
+
+static LCM_Init_Code sleep_out[] = {
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},//>120ms
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(20)}, //>20ms
+};
+static int32_t sc7798d_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel sc7798d_mipi_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static uint32_t sc7798d_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ LCD_PRINT("kernel lcd_sc7798d_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+
+ if((0x55 == read_data[0])&&(0xB8 == read_data[1])&&(0xF0 == read_data[2]))
+ {
+ printk("lcd_sc7798d_mipi read id success!\n");
+ return 0x55b8f0;
+ }
+ }
+ mipi_eotp_set(0,0);
+ LCD_PRINT("lcd_sc7798d_mipi read id fail! 0xda,0xdb,0xdc is 0x%x,0x%x,0x%x!\n",read_data[0],read_data[1],read_data[2]);
+ return 0;
+}
+
+
+static int32_t sc7798d_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("kernel sc7798d_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_dcs_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep(sleep_in_out->tag & LCM_TAG_MASK);
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_sc7798d_mipi_operations = {
+ .panel_init = sc7798d_mipi_init,
+ .panel_readid = sc7798d_readid,
+ .panel_enter_sleep = sc7798d_enter_sleep,
+};
+
+static struct timing_rgb lcd_sc7798d_mipi_timing = {
+ .hfp = 145, /* unit: pixel */
+ .hbp = 90,
+ .hsync = 70,
+ .vfp = 10, /*unit: line*/
+ .vbp = 12,
+ .vsync = 4,
+};
+
+
+static struct info_mipi lcd_sc7798d_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq =481*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_sc7798d_mipi_timing,
+ .ops = NULL,
+};
+struct panel_spec lcd_sc7798d_mipi_spec = {
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_sc7798d_mipi_info
+ },
+ .ops = &lcd_sc7798d_mipi_operations,
+};
+struct panel_cfg lcd_sc7798d_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x55b8f0,
+ .lcd_name = "lcd_sc7798d_mipi",
+ .panel = &lcd_sc7798d_mipi_spec,
+};
+
+//temp code
+static int __init lcd_sc7798d_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_sc7798d_mipi);
+}
+
+subsys_initcall(lcd_sc7798d_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_ssd2075_mipi.c b/drivers/video/sprdfb/lcd/lcd_ssd2075_mipi.c
new file mode 100644
index 00000000..b2281be3
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_ssd2075_mipi.c
@@ -0,0 +1,375 @@
+/* drivers/video/sprdfb/lcd_ssd2075_mipi.c
+ *
+ * Support for ssd2075 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+//#define printk printf
+
+#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+ {LCM_SEND(2),{0xE1,0x93}},
+ {LCM_SEND(2),{0xB3,0x00}},
+ //5inchGIP
+ {LCM_SEND(7),{5,0,0xB6,0x16,0x0F,0x00,0x77}}, //0x00
+ {LCM_SEND(11),{9,0,0xB8,0x00,0x06,0x08,0x00,0x07,0x09,0x23,0x04}},
+ {LCM_SEND(9),{7,0,0xB9,0x04,0x08,0x22,0xFF,0xFF,0x0F}},
+ {LCM_SEND(11),{9,0,0xBA,0x0E,0x0E,0x10,0x10,0x0A,0x0A,0x0C,0x0C}},
+ {LCM_SEND(11),{9,0,0xBB,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1}},
+ {LCM_SEND(11),{9,0,0xBC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(11),{9,0,0xBD,0x0F,0x0F,0x11,0x11,0x0B,0x0B,0x0D,0x0D}},
+ {LCM_SEND(11),{9,0,0xBE,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1}},
+ {LCM_SEND(11),{9,0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {LCM_SEND(6),{4,0,0xB1,0x06,0x44,0x10}},
+ {LCM_SEND(8),{6,0,0xE0,0x11,0x02,0x04,0x00,0x01}},
+
+ //Gamma2.2
+ #if 1
+ {LCM_SEND(9),{7,0,0xD0,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xD1,0x1A,0x37,0x29,0x1B,0x08}},
+ {LCM_SEND(9),{7,0,0xD2,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xD3,0x1A,0x37,0x29,0x1B,0x08}},
+ {LCM_SEND(9),{7,0,0xD4,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xD5,0x1A,0x37,0x29,0x1B,0x08}},
+ {LCM_SEND(9),{7,0,0xD6,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xD7,0x1A,0x37,0x29,0x1B,0x08}},
+ {LCM_SEND(9),{7,0,0xD8,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xD9,0x1A,0x37,0x29,0x1B,0x08}},
+ {LCM_SEND(9),{7,0,0xDA,0x00,0x00,0x0E,0x0F,0x14,0x20}},
+ {LCM_SEND(8),{6,0,0xDB,0x1A,0x37,0x29,0x1B,0x08}},
+ #else
+ {LCM_SEND(9),{7,0,0xD0,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xD1,0x2D,0x27,0x1A,0x1B,0x0A}},
+ {LCM_SEND(9),{7,0,0xD2,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xD3,0x2D,0x27,0x1A,0x1B,0x0A}},
+ {LCM_SEND(9),{7,0,0xD4,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xD5,0x26,0x2B,0x23,0x1B,0x0A}},
+ {LCM_SEND(9),{7,0,0xD6,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xD7,0x2D,0x27,0x1A,0x1B,0x0A}},
+ {LCM_SEND(9),{7,0,0xD8,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xD9,0x2D,0x27,0x1A,0x1B,0x0A}},
+ {LCM_SEND(9),{7,0,0xDA,0x00,0x00,0x1E,0x27,0x2D,0x35}},
+ {LCM_SEND(8),{6,0,0xDB,0x2D,0x27,0x1A,0x1B,0x0A}},
+ #endif
+ {LCM_SEND(7),{5,0,0x70,0xD8,0x00,0xFF,0x80}},
+ {LCM_SEND(2),{0xFF,0x01}},
+
+ {LCM_SEND(5),{3,0,0xC6,0xCC,0x33}},//77->CC
+ {LCM_SEND(5),{3,0,0xDE,0x9D,0x30}},
+ {LCM_SEND(2),{0x14,0x00}},
+
+ {LCM_SEND(2),{0xE9,0x07}},
+ {LCM_SEND(5),{3,0,0xED,0x60,0x10}},
+ {LCM_SEND(2),{0xEC,0x12}},
+ {LCM_SEND(7),{5,0,0xCD,0x77,0x7B,0x34,0x08}},
+ {LCM_SEND(10),{8,0,0xC3,0x03,0x0D,0x34,0x05,0x01,0x44,0x54}},
+ {LCM_SEND(8),{6,0,0xC4,0x02,0x03,0x3D,0x3D,0x5A}}, // Vcom
+ {LCM_SEND(6),{4,0,0xCB,0xDF,0x80,0x00}},
+ {LCM_SEND(6),{4,0,0xEA,0x15,0x28,0x00}},
+ {LCM_SEND(7),{5,0,0xF0,0x38,0x00,0x00,0x00}},
+ {LCM_SEND(6),{4,0,0xC9,0x60,0x00,0x82}},
+ {LCM_SEND(11),{9,0,0xB5,0x00,0x05,0x05,0x1E,0x04,0x40,0x20,0xFC}},
+ {LCM_SEND(2),{0x36,0x0B}},//08->0B rotate 180
+ {LCM_SEND(2),{0x3A,0x70}},
+ {LCM_SEND(1),{0x11}},
+ {LCM_SLEEP(120)},
+ {LCM_SEND(1),{0x29}},
+};
+
+//static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+//static LCM_Init_Code sleep_in = {LCM_SEND(1), {0x10}};
+
+//static LCM_Init_Code sleep_out = {LCM_SEND(1), {0x11}};
+static LCM_Init_Code sleep_in[] = {
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(10)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(120)},
+{LCM_SEND(2), {0x4f, 0x01}},
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static int32_t ssd2075_mipi_init(struct panel_spec *self)
+{
+ int32_t i = 0;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_ssd2075_init\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((init->tag & LCM_TAG_MASK));
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t ssd2075_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[10] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_ssd2075_mipi read id!\n");
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x0a;
+ param[1] = 0x00;
+ mipi_force_write(0x37, param, 2);
+ read_rtn = mipi_force_read(0xA1,10,(uint8_t *)read_data);
+ printk("lcd_ssd2075_mipi read id 0xA1 value is 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x!\n", read_data[0], read_data[1], \
+ read_data[2], read_data[3],read_data[4], read_data[5],read_data[6], read_data[7],read_data[8], read_data[9]);
+
+ if((0x20 == read_data[0])&&(0x75 == read_data[1])){
+ printk("lcd_ssd2075_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x2075;
+ }
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static int32_t ssd2075_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i = 0;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "ssd2075_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t ssd2075_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+// pr_debug("lcd_ssd2075_mipi read power mode!\n");
+
+ mipi_eotp_set(0,1);
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0xF5, 3,(uint8_t *)read_data);
+// printk("lcd_ssd2075 mipi read power mode 0xF5 value r[0]=0x%x,r[1]=0x%x,r[2]=0x%x! , read result(%d)\n", read_data[0],read_data[1],read_data[2],read_rtn);
+ if((0x0 == read_data[0]) && (0x0 == read_data[1]) && (0x0 == read_data[2]) && (0 == read_rtn)){
+ mipi_eotp_set(1,1);
+// pr_debug("lcd_ssd2075_mipi read power mode success!\n");
+ return 0xF5;
+ }
+ }
+ mipi_eotp_set(1,1);
+ printk("lcd_ssd2075 ssd2075_readpowermode fail! 0xF5 value r[0]=0x%x,r[1]=0x%x,r[2]=0x%x! , read result(%d)\n", read_data[0],\
+ read_data[1],read_data[2],read_rtn);
+ return 0x0;
+}
+
+static int32_t ssd2075_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+// pr_debug("ssd2075_check_esd!\n");
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = ssd2075_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0xF5){
+// pr_debug("ssd2075_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("ssd2075_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+static struct panel_operations lcd_ssd2075_mipi_operations = {
+ .panel_init = ssd2075_mipi_init,
+ .panel_readid = ssd2075_readid,
+ .panel_enter_sleep = ssd2075_enter_sleep,
+ .panel_esd_check = ssd2075_check_esd,
+};
+
+static struct timing_rgb lcd_ssd2075_mipi_timing = {
+ .hfp =50,
+ .hbp = 36,
+ .hsync =16,
+ .vfp = 12,
+ .vbp = 14,
+ .vsync = 2,
+};
+
+
+static struct info_mipi lcd_ssd2075_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq =500*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_ssd2075_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_ssd2075_mipi_spec = {
+ .width = 720,
+ .height = 1280,
+ .fps = 60,
+ .reset_timing = {20,20,120},
+ .suspend_mode = SEND_SLEEP_CMD,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mipi = &lcd_ssd2075_mipi_info
+ },
+ .ops = &lcd_ssd2075_mipi_operations,
+};
+struct panel_cfg lcd_ssd2075_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x2075,
+ .lcd_name = "lcd_ssd2075_mipi",
+ .panel = &lcd_ssd2075_mipi_spec,
+};
+
+static int __init lcd_ssd2075_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_ssd2075_mipi);
+}
+
+subsys_initcall(lcd_ssd2075_mipi_init);
+
diff --git a/drivers/video/sprdfb/lcd/lcd_st7789v_mcu.c b/drivers/video/sprdfb/lcd/lcd_st7789v_mcu.c
new file mode 100644
index 00000000..f9538e90
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_st7789v_mcu.c
@@ -0,0 +1,336 @@
+/* drivers/video/sprdfb/lcd_st7789v.c
+ *
+ * Support for st7789v LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/delay.h>
+#include "../sprdfb_panel.h"
+
+#define ST7789V_BUS_WIDTH_8BIT // bus_width = 8
+
+static int32_t st7789v_init(struct panel_spec *self)
+ {
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("st7789v_init\n");
+ //Power setting sequence
+ send_cmd(0x11);
+ mdelay(120);
+
+#if defined(ST7789V_BUS_WIDTH_8BIT)
+ send_cmd(0xDF);
+ send_data(0x5A69);
+ send_data(0x0201);
+
+ send_cmd(0x36);
+ send_data(0x0000);
+
+ send_cmd(0x3a);
+ send_data(0x0500);
+
+ send_cmd(0x35);
+ send_data(0x0000);
+
+ send_cmd(0xd2);
+ send_data(0x4c00);
+
+ send_cmd(0xb2);
+ send_data(0x0404);
+ send_data(0x0033);
+ send_data(0x3300);
+
+ send_cmd(0xC6);
+ send_data(0x0A00);
+
+ send_cmd(0xb8);
+ send_data(0x2A2B);
+ send_data(0x0575);
+
+ send_cmd(0xb7);
+ send_data(0x7500);
+
+ send_cmd(0xbb);
+ send_data(0x1B00);
+
+ send_cmd(0xC2);
+ send_data(0x0100);
+
+ send_cmd(0xC3);
+ send_data(0x0b00);
+
+ send_cmd(0xC4);
+ send_data(0x2000);
+
+ send_cmd(0xd0);
+ send_data(0xa4a1);
+
+ send_cmd(0xE8);
+ send_data(0x8300);
+
+ send_cmd(0xE9);
+ send_data(0x0909);
+ send_data(0x0500);
+
+ send_cmd(0xC0);
+ send_data(0x2500);
+
+ send_cmd(0xb0);
+ send_data(0x00d0);
+
+ send_cmd(0xE0);
+ send_data(0xd00E);
+ send_data(0x1810);
+ send_data(0x0E2A);
+ send_data(0x3E54);
+ send_data(0x4C2B);
+ send_data(0x1716);
+ send_data(0x1D21);
+
+ send_cmd(0XE1);
+ send_data(0xd00E);
+ send_data(0x1710);
+ send_data(0x0E29);
+ send_data(0x3C44);
+ send_data(0x4D2C);
+ send_data(0x1615);
+ send_data(0x1E22);
+
+ send_cmd(0x29);
+#else // 16/18/24bit
+ send_cmd(0xB7); send_data(0x35);
+ send_cmd(0xBB); send_data(0x1A);
+ send_cmd(0xC2); send_data(0x01);
+ send_cmd(0xC3); send_data(0x0B);
+ send_cmd(0xC4); send_data(0x20);
+ send_cmd(0xD0); send_data(0xA4);send_data(0xA1);
+ send_cmd(0xE8); send_data(0x83);
+ send_cmd(0xE9); send_data(0x09);send_data(0x09);send_data(0x08);
+
+ //Init setting
+ send_cmd(0x36); send_data(0x00);
+ send_cmd(0x35); send_data(0x00);
+ send_cmd(0x3A); send_data(0x05);//0x06: 262k 0x05:65k
+ send_cmd(0xD2); send_data(0x4C);
+ send_cmd(0xB2);send_data(0x0C);send_data(0x0C);send_data(0x00);send_data(0x33);send_data(0x33);
+ send_cmd(0xC6); send_data(0x09);
+
+ //Gamma setting
+ send_cmd(0xE0);
+ send_data(0xD0);
+ send_data(0x02);
+ send_data(0x11);
+ send_data(0x12);
+ send_data(0x12);
+ send_data(0x2A);
+ send_data(0x3D);
+ send_data(0x44);
+ send_data(0x4C);
+ send_data(0x2B);
+ send_data(0x16);
+ send_data(0x14);
+ send_data(0x1E);
+ send_data(0x21);
+
+ send_cmd(0xE1);
+ send_data(0xD0);
+ send_data(0x02);
+ send_data(0x11);
+ send_data(0x11);
+ send_data(0x12);
+ send_data(0x2A);
+ send_data(0x3B);
+ send_data(0x44);
+ send_data(0x4C);
+ send_data(0x2B);
+ send_data(0x16);
+ send_data(0x15);
+ send_data(0x1E);
+ send_data(0x21);
+
+ send_cmd(0x29); //Display On
+#endif
+ return 0;
+}
+
+
+static int32_t st7789v_set_window(struct panel_spec *self,
+ uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
+{
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ send_data_t send_data = self->info.mcu->ops->send_data;
+
+ pr_debug("st7789v_set_window\n");
+
+#if defined(ST7789V_BUS_WIDTH_8BIT)
+ send_cmd(0x002A); // col
+ send_data(left);
+ send_data(right);
+
+ send_cmd(0x002B); // row
+ send_data(top);
+ send_data(bottom);
+ send_cmd(0x002C);
+#else // 16/18/24bit
+ send_cmd(0x2A); // col
+ send_data((left >> 8));
+ send_data((left & 0xFF));
+ send_data((right >> 8));
+ send_data((right & 0xFF));
+
+ send_cmd(0x2B); // row
+ send_data((top >> 8));
+ send_data((top & 0xFF));
+ send_data((bottom >> 8));
+ send_data((bottom & 0xFF));
+ send_cmd(0x2C);
+#endif
+
+ return 0;
+}
+
+
+static int32_t st7789v_invalidate(struct panel_spec *self)
+{
+ pr_debug("st7789v_invalidate\n");
+
+ return self->ops->panel_set_window(self, 0, 0,
+ self->width-1, self->height-1);
+}
+
+static int32_t st7789v_invalidate_rect(struct panel_spec *self,
+ uint16_t left, uint16_t top,
+ uint16_t right, uint16_t bottom)
+{
+
+ pr_debug("st7789v_invalidate_rect : (%d, %d, %d, %d)\n",left, top, right, bottom);
+
+ return self->ops->panel_set_window(self, left, top,
+ right, bottom);
+}
+
+static int32_t st7789v_set_direction(struct panel_spec *self, uint16_t direction)
+{
+
+ pr_debug("st7789v_set_direction\n");
+ return 0;
+}
+
+static int32_t st7789v_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ //send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+
+ if(is_sleep) {
+ //send_cmd(0x10);
+ mdelay(120);
+ }
+ else {
+ //send_cmd(0x11);
+ mdelay(120);
+ }
+ return 0;
+}
+
+#define LCD_MTP_ID 0x51a0f0
+static uint32_t st7789v_read_id(struct panel_spec *self)
+{
+ int32_t read_value = 0;
+
+ send_data_t send_cmd = self->info.mcu->ops->send_cmd;
+ read_data_t read_data = self->info.mcu->ops->read_data;
+
+ send_cmd(0x04);
+
+#if defined(ST7789V_BUS_WIDTH_8BIT)
+ read_value += (read_data() &0xff)<<16;
+ read_value += read_data();
+#else
+ read_data();
+ read_value += read_data()<< 16;
+ read_value += read_data()<< 8;
+ read_value += read_data();
+#endif
+ pr_debug("st7789v_read_id=%x\n",read_value);
+
+ if(read_value == LCD_MTP_ID)
+ read_value = 0x7789;
+
+ return read_value;
+}
+
+static struct panel_operations lcd_st7789v_operations = {
+ .panel_init = st7789v_init,
+ .panel_set_window = st7789v_set_window,
+ .panel_invalidate = st7789v_invalidate,
+ //.lcd_invalidate_rect = st7789v_invalidate_rect,
+ .panel_set_direction = st7789v_set_direction,
+ .panel_enter_sleep = st7789v_enter_sleep,
+ .panel_readid = st7789v_read_id,
+};
+
+static struct timing_mcu lcd_st7789v_timing[] = {
+ [MCU_LCD_REGISTER_TIMING] = {
+ .rcss = 45,
+ .rlpw = 60,
+ .rhpw = 100,
+ .wcss = 10,
+ .wlpw = 28,
+ .whpw = 28,
+ },
+ [MCU_LCD_GRAM_TIMING] = {
+ .rcss = 25, /* 25 ns */
+ .rlpw = 70,
+ .rhpw = 70,
+ .wcss = 10,
+ .wlpw = 28,
+ .whpw = 28,
+ }
+};
+
+
+static struct info_mcu lcd_st7789v_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 8, //16,
+ .bpp = 16, /*RGB565*/
+ .timing = &lcd_st7789v_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_panel_st7789v = {
+ .width = 240,
+ .height = 320,
+ .fps = 60,
+ .type = LCD_MODE_MCU,
+ .direction = LCD_DIRECT_NORMAL,
+ .info = {
+ .mcu = &lcd_st7789v_info
+ },
+ .ops = &lcd_st7789v_operations,
+};
+
+struct panel_cfg lcd_st7789v = {
+ /* this panel may on both CS0/1 */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x7789,
+ .lcd_name = "lcd_st7789v",
+ .panel = &lcd_panel_st7789v,
+};
+
+static int __init lcd_st7789v_init(void)
+{
+ return sprdfb_panel_register(&lcd_st7789v);
+}
+
+subsys_initcall(lcd_st7789v_init); \ No newline at end of file
diff --git a/drivers/video/sprdfb/lcd/lcd_t8861_mipi.c b/drivers/video/sprdfb/lcd/lcd_t8861_mipi.c
new file mode 100644
index 00000000..51e8a908
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_t8861_mipi.c
@@ -0,0 +1,485 @@
+/* drivers/video/sprdfb/lcd/lcd_t8861_mipi.c
+ *
+ * Support for t8861 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * 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/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+
+//#define LCD_DEBUG
+#ifdef LCD_DEBUG
+#define LCD_PRINT printk
+#else
+#define LCD_PRINT(...)
+#endif
+
+#define MAX_DATA 48
+
+typedef struct LCM_Init_Code_tag {
+ unsigned int tag;
+ unsigned char data[MAX_DATA];
+}LCM_Init_Code;
+
+typedef struct LCM_force_cmd_code_tag{
+ unsigned int datatype;
+ LCM_Init_Code real_cmd_code;
+}LCM_Force_Cmd_Code;
+
+#define LCM_TAG_SHIFT 24
+#define LCM_TAG_MASK ((1 << 24) -1)
+#define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)
+#define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)
+//#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
+
+#define LCM_TAG_SEND (1<< 0)
+#define LCM_TAG_SLEEP (1 << 1)
+
+static LCM_Init_Code init_data[] = {
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+ {LCM_SLEEP(5)},
+
+ {LCM_SEND(2), {0x08,0x10}},
+
+ {LCM_SEND(2), {0x21,0x01}},
+
+ {LCM_SEND(2), {0x30,0x02}},
+ {LCM_SEND(2), {0x31,0x00}}, //0x02
+
+ {LCM_SEND(2), {0x60,0x07}},
+ {LCM_SEND(2), {0x61,0x06}},
+ {LCM_SEND(2), {0x62,0x06}},
+ {LCM_SEND(2), {0x63,0x04}},
+
+ {LCM_SEND(2), {0x40,0x14}},
+ {LCM_SEND(2), {0x41,0x44}},//22
+ {LCM_SEND(2), {0x42,0x01}},
+ {LCM_SEND(2), {0x43,0x89}},
+ {LCM_SEND(2), {0x44,0x89}},
+ {LCM_SEND(2), {0x45,0x1b}},
+ {LCM_SEND(2), {0x46,0x44}},
+ {LCM_SEND(2), {0x47,0x44}},
+
+ {LCM_SEND(2), {0x50,0x85}},
+ {LCM_SEND(2), {0x51,0x85}},
+ {LCM_SEND(2), {0x52,0x00}},
+ {LCM_SEND(2), {0x53,0x64}},//90
+
+ //{LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+
+ {LCM_SEND(2), {0xA0,0x00}},
+ {LCM_SEND(2), {0xA1,0x00}},//01
+ {LCM_SEND(2), {0xA2,0x03}},//08
+ {LCM_SEND(2), {0xA3,0x0e}},//0e
+ {LCM_SEND(2), {0xA4,0x08}},//08
+ {LCM_SEND(2), {0xA5,0x1f}},//19
+ {LCM_SEND(2), {0xA6,0x0f}},//0b
+ {LCM_SEND(2), {0xA7,0x0b}},//0a
+ {LCM_SEND(2), {0xA8,0x03}},//02
+ {LCM_SEND(2), {0xA9,0x06}},//08
+ {LCM_SEND(2), {0xAA,0x05}},//04
+ {LCM_SEND(2), {0xAB,0x02}},//03
+ {LCM_SEND(2), {0xAC,0x0e}},//0a
+ {LCM_SEND(2), {0xAD,0x25}},//2c
+ {LCM_SEND(2), {0xAE,0x1d}},//28
+ {LCM_SEND(2), {0xAF,0x00}},
+
+ {LCM_SEND(2), {0xC0,0x00}},//00
+ {LCM_SEND(2), {0xC1,0x04}},//02
+ {LCM_SEND(2), {0xC2,0x0f}},//09
+ {LCM_SEND(2), {0xC3,0x10}},//0e
+ {LCM_SEND(2), {0xC4,0x0b}},//09
+ {LCM_SEND(2), {0xC5,0x1e}},//19
+ {LCM_SEND(2), {0xC6,0x09}},//0a
+ {LCM_SEND(2), {0xC7,0x0a}},//0a
+ {LCM_SEND(2), {0xC8,0x00}},//02
+ {LCM_SEND(2), {0xC9,0x0a}},//07
+ {LCM_SEND(2), {0xCA,0x01}},//05
+ {LCM_SEND(2), {0xCB,0x06}},//04
+ {LCM_SEND(2), {0xCC,0x09}},//0a
+ {LCM_SEND(2), {0xCD,0x2a}},//2d
+ {LCM_SEND(2), {0xCE,0x28}},//28
+ {LCM_SEND(2), {0xCF,0x00}},//00
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}},
+ {LCM_SEND(2), {0x00,0xa0}},
+ {LCM_SEND(2), {0x01,0x05}},
+ {LCM_SEND(2), {0x02,0x00}},
+ {LCM_SEND(2), {0x03,0x00}},
+ {LCM_SEND(2), {0x04,0x01}},
+ {LCM_SEND(2), {0x05,0x01}},
+ {LCM_SEND(2), {0x06,0x88}},
+ {LCM_SEND(2), {0x07,0x04}},
+ {LCM_SEND(2), {0x08,0x01}},
+ {LCM_SEND(2), {0x09,0x90}},
+ {LCM_SEND(2), {0x0A,0x04}},
+ {LCM_SEND(2), {0x0B,0x01}},
+ {LCM_SEND(2), {0x0C,0x01}},
+ {LCM_SEND(2), {0x0D,0x01}},
+ {LCM_SEND(2), {0x0E,0x00}},
+ {LCM_SEND(2), {0x0F,0x00}},
+
+ {LCM_SEND(2), {0x10,0x55}},
+ {LCM_SEND(2), {0x11,0x50}},
+ {LCM_SEND(2), {0x12,0x01}},
+ {LCM_SEND(2), {0x13,0x85}},
+ {LCM_SEND(2), {0x14,0x85}},
+ {LCM_SEND(2), {0x15,0xc0}},
+ {LCM_SEND(2), {0x16,0x0B}},
+ {LCM_SEND(2), {0x17,0x00}},
+ {LCM_SEND(2), {0x18,0x00}},
+ {LCM_SEND(2), {0x19,0x00}},
+ {LCM_SEND(2), {0x1A,0x00}},
+ {LCM_SEND(2), {0x1B,0x00}},
+ {LCM_SEND(2), {0x1C,0x00}},
+ {LCM_SEND(2), {0x1D,0x00}},
+
+ {LCM_SEND(2), {0x20,0x01}},
+ {LCM_SEND(2), {0x21,0x23}},
+ {LCM_SEND(2), {0x22,0x45}},
+ {LCM_SEND(2), {0x23,0x67}},
+ {LCM_SEND(2), {0x24,0x01}},
+ {LCM_SEND(2), {0x25,0x23}},
+ {LCM_SEND(2), {0x26,0x45}},
+ {LCM_SEND(2), {0x27,0x67}},
+
+ {LCM_SEND(2), {0x30,0x02}},
+ {LCM_SEND(2), {0x31,0x22}},
+ {LCM_SEND(2), {0x32,0x11}},
+ {LCM_SEND(2), {0x33,0xaa}},
+ {LCM_SEND(2), {0x34,0xbb}},
+ {LCM_SEND(2), {0x35,0x66}},
+ {LCM_SEND(2), {0x36,0x00}},
+ {LCM_SEND(2), {0x37,0x22}},
+ {LCM_SEND(2), {0x38,0x22}},
+ {LCM_SEND(2), {0x39,0x22}},
+ {LCM_SEND(2), {0x3A,0x22}},
+ {LCM_SEND(2), {0x3B,0x22}},
+ {LCM_SEND(2), {0x3C,0x22}},
+ {LCM_SEND(2), {0x3D,0x22}},
+ {LCM_SEND(2), {0x3E,0x22}},
+ {LCM_SEND(2), {0x3F,0x22}},
+
+ {LCM_SEND(2), {0x40,0x22}},
+ {LCM_SEND(2), {0x53,0x1a}},
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}},
+ {LCM_SEND(2), {0x18,0x1d}},
+ {LCM_SEND(2), {0x17,0x12}},
+
+ {LCM_SEND(2), {0x02,0x77}},
+
+ {LCM_SEND(2), {0xe1,0x79}},
+
+ {LCM_SEND(2), {0x06,0x13}},
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+
+// {LCM_SEND(2), {0x35,0x00}},
+
+ {LCM_SEND(1), {0x11}},
+ {LCM_SLEEP(120)},
+
+ {LCM_SEND(1), {0x29}},
+ {LCM_SLEEP(1)},
+
+// {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x08}},
+
+};
+
+static LCM_Init_Code disp_on = {LCM_SEND(1), {0x29}};
+
+static LCM_Init_Code sleep_in[] = {
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+ {LCM_SLEEP(1)},
+
+
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},
+ {LCM_SLEEP(1)},
+
+{LCM_SEND(1), {0x28}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x10}},
+{LCM_SLEEP(10)},
+ {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},
+ {LCM_SLEEP(1)},
+
+ {LCM_SEND(2), {0x58,0x91}},
+
+};
+
+static LCM_Init_Code sleep_out[] = {
+{LCM_SEND(1), {0x11}},
+{LCM_SLEEP(120)},
+{LCM_SEND(1), {0x29}},
+{LCM_SLEEP(20)},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code[]={
+ {0x39, {LCM_SEND(8), {0x6, 0, 0xFF, 0xFF, 0x98, 0x06,0x04,0x01}}},
+ {0x37, {LCM_SEND(2), {0x3, 0}}},
+};
+
+static LCM_Force_Cmd_Code rd_prep_code_1[]={
+ {0x37, {LCM_SEND(2), {0x1, 0}}},
+};
+static int32_t t8861_mipi_init(struct panel_spec *self)
+{
+ int32_t i;
+ LCM_Init_Code *init = init_data;
+ unsigned int tag;
+
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug(KERN_DEBUG "t8861_mipi_init\n");
+
+ msleep(2);
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i < ARRAY_SIZE(init_data); i++){
+ tag = (init->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));
+ udelay(20);
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((init->tag & LCM_TAG_MASK) * 1000);
+ msleep(init->tag & LCM_TAG_MASK);
+ }
+ init++;
+ }
+ mipi_eotp_set(1,1);
+
+ return 0;
+}
+
+static uint32_t t8861_readid(struct panel_spec *self)
+{
+ /*Jessica TODO: need read id*/
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;
+ uint8_t read_data[3] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk("lcd_t8861_mipi read id!\n");
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(1,0);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000);
+ }
+ rd_prepare++;
+ }
+ read_rtn = mipi_force_read(0x02, 3,(uint8_t *)read_data);
+ printk("lcd_t8861_mipi read id 0xc5 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);
+
+ if((0x04 == read_data[0])){
+ printk("lcd_t8861_mipi read id success!\n");
+ mipi_eotp_set(1,1);
+ return 0x04;
+ }
+ }
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+static int32_t t8861_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ int32_t i;
+ LCM_Init_Code *sleep_in_out = NULL;
+ unsigned int tag;
+ int32_t size = 0;
+
+ mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ printk(KERN_DEBUG "t8861_enter_sleep, is_sleep = %d\n", is_sleep);
+
+ if(is_sleep){
+ sleep_in_out = sleep_in;
+ size = ARRAY_SIZE(sleep_in);
+ }else{
+ sleep_in_out = sleep_out;
+ size = ARRAY_SIZE(sleep_out);
+ }
+ mipi_eotp_set(1,0);
+
+ for(i = 0; i <size ; i++){
+ tag = (sleep_in_out->tag >>24);
+ if(tag & LCM_TAG_SEND){
+ mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ //udelay((sleep_in_out->tag & LCM_TAG_MASK) * 1000);
+ msleep((sleep_in_out->tag & LCM_TAG_MASK));
+ }
+ sleep_in_out++;
+ }
+ return 0;
+}
+
+static uint32_t t8861_readpowermode(struct panel_spec *self)
+{
+ int32_t i = 0;
+ uint32_t j =0;
+ LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;
+ uint8_t read_data[1] = {0};
+ int32_t read_rtn = 0;
+ unsigned int tag = 0;
+ uint32_t reg_val_1 = 0;
+ uint32_t reg_val_2 = 0;
+
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_debug("lcd_t8861_mipi read power mode!\n");
+ mipi_eotp_set(0,1);
+
+ for(j = 0; j < 4; j++){
+ rd_prepare = rd_prep_code_1;
+ for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){
+ tag = (rd_prepare->real_cmd_code.tag >> 24);
+ if(tag & LCM_TAG_SEND){
+ mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));
+ }else if(tag & LCM_TAG_SLEEP){
+ udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000);
+ }
+ rd_prepare++;
+ }
+
+ read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);
+ //printk("lcd_t8861 mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);
+
+ if((0x9c == read_data[0]) && (0 == read_rtn)){
+ pr_debug("lcd_t8861_mipi read power mode success!\n");
+ mipi_eotp_set(1,1);
+ return 0x9c;
+ }
+ }
+
+ mipi_eotp_set(1,1);
+ return 0x0;
+}
+
+
+static uint32_t t8861_check_esd(struct panel_spec *self)
+{
+ uint32_t power_mode;
+
+ pr_debug("t8861_check_esd!\n");
+ mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;
+ mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;
+
+ mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
+ uint16_t work_mode = self->info.mipi->work_mode;
+
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_lp_mode();
+ }else{
+ mipi_set_data_lp_mode();
+ }
+ power_mode = t8861_readpowermode(self);
+ //power_mode = 0x0;
+ if(SPRDFB_MIPI_MODE_CMD==work_mode){
+ mipi_set_hs_mode();
+ }else{
+ mipi_set_data_hs_mode();
+ }
+ if(power_mode == 0x9c){
+ pr_debug("t8861_check_esd OK!\n");
+ return 1;
+ }else{
+ printk("t8861_check_esd fail!(0x%x)\n", power_mode);
+ return 0;
+ }
+}
+
+
+static struct panel_operations lcd_t8861_mipi_operations = {
+ .panel_init = t8861_mipi_init,
+ .panel_readid = t8861_readid,
+ .panel_enter_sleep = t8861_enter_sleep,
+ .panel_esd_check = t8861_check_esd,
+};
+
+static struct timing_rgb lcd_t8861_mipi_timing = {
+ .hfp = 60, /* unit: pixel */// 100
+ .hbp = 80,//80
+ .hsync = 60,//6
+ .vfp = 20, /*unit: line*/
+ .vbp = 14,
+ .vsync =6, //6,
+};
+
+static struct info_mipi lcd_t8861_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 2,
+ .phy_feq = 500*1000, //500->10MHz,400->8M in lp mode
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_t8861_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_t8861_mipi_spec = {
+ //.cap = PANEL_CAP_NOT_TEAR_SYNC,
+ .width = 480,
+ .height = 800,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .is_clean_lcd = true,
+ .info = {
+ .mipi = &lcd_t8861_mipi_info
+ },
+ .ops = &lcd_t8861_mipi_operations,
+};
+
+struct panel_cfg lcd_t8861_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x04,
+ .lcd_name = "lcd_t8861_mipi",
+ .panel = &lcd_t8861_mipi_spec,
+};
+
+static int __init lcd_t8861_mipi_init(void)
+{
+ return sprdfb_panel_register(&lcd_t8861_mipi);
+}
+
+subsys_initcall(lcd_t8861_mipi_init);
diff --git a/drivers/video/sprdfb/lcd/lcd_vx5b3d_mipi.c b/drivers/video/sprdfb/lcd/lcd_vx5b3d_mipi.c
new file mode 100755
index 00000000..94cc6486
--- /dev/null
+++ b/drivers/video/sprdfb/lcd/lcd_vx5b3d_mipi.c
@@ -0,0 +1,965 @@
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include "../sprdfb_panel.h"
+#include <mach/gpio.h>
+#include <linux/i2c.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <mach/i2c-sprd.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/of_gpio.h>
+#define LCD_DEBUG
+#define pr_info printk
+#define LCD_PRINT printk
+#define MAX_DATA 100
+//#define QUICKLOGIC_DEBUG
+
+struct bridge_data {
+ u16 addr;
+ u32 data;
+}__attribute__ ((packed));
+
+struct vx5b3d_dt_data {
+ int gpio_bridge_en;
+ int gpio_bridge_rst;
+ int gpio_blic_en;
+ int gpio_lcd_3v3_en;
+};
+struct vx5b3d_dt_data *pdata = NULL;
+
+static struct i2c_client *g_client = NULL;
+struct regulator *lvds_1v8;
+struct regulator *lvds_3v3;
+struct panel_spec lcd_vx5b3d_mipi_spec;
+struct panel_spec *self = &lcd_vx5b3d_mipi_spec;
+struct i2c_driver quicklogic_i2c_driver;
+extern uint32_t sprdfb_panel_reset_all(void);
+
+#define QUICKLOGIC_MIPI_VENDOR_ID_1 0x5
+#define QUICKLOGIC_MIPI_VENDOR_ID_2 0x1
+#define QUICKLOGIC_MIPI_COMMAND_CSR_WRITE 0x40
+#define QUICKLOGIC_MIPI_COMMAND_CSR_OFFSET 0x41
+
+#define VX5B3D_I2C_RETRY_CNT (5)
+
+#define DELAY_CMD (0xFFFF)
+
+struct bridge_data vx5b3d_init[] = {
+ {0x700, 0x6C900040},
+ {0x704, 0x0003040A},
+ {0x70C, 0x00004604},
+ {0x710, 0x054D000B},
+ {0x714, 0x00000020},
+ {0x718, 0x00000102},
+ {0x71C, 0x00A8002F},
+ {0x720, 0x00000000},
+
+ {DELAY_CMD, 100}, /* For pll locking */
+ {0x154, 0x00000000},
+ {0x154, 0x80000000},
+ {DELAY_CMD, 100}, /* For pll locking */
+
+ {0x700, 0x6C900840},
+ {0x70C, 0x00005E56},
+ {0x718, 0x00000202},
+
+ {0x154, 0x00000000},
+ {0x154, 0x80000000},
+ {DELAY_CMD, 100}, /* For pll locking */
+
+ {0x37C, 0x00001063},
+ {0x380, 0x82A86030},
+ {0x384, 0x2861408B},
+ {0x388, 0x00130285},
+ {0x38C, 0x10630009},
+ {0x394, 0x400B82A8},
+ {0x600, 0x016CC78C},
+ {0x604, 0x3FFFFFE0},
+ {0x608, 0x00000D8C},
+ {0x154, 0x00000000},
+ {0x154, 0x80000000},
+ {0x120, 0x00000005},
+ {0x124, 0x1892C400},
+ {0x128, 0x00102806},
+ {0x12C, 0x00000062},
+ {0x130, 0x00003C18},
+ {0x134, 0x00000015},
+ {0x138, 0x00FF8000},
+ {0x13C, 0x00000000},
+
+ /*PWM 100 % duty ration*/
+ {0x114, 0x000c6302},
+
+ /*backlight duty ratio control when device is first bring up.*/
+ {0x160, 0x000007F8},
+ {0x164, 0x000002A8},
+ {0x138, 0x3fff0000},
+ {0x15C, 0x00000005},
+
+ {0x140, 0x00010000},
+ /*Add for power consumtion*/
+ {0x174, 0x00000000},
+ /*end*/
+
+ /*
+ slope = 2 / variance = 0x55550022
+ slope register [15,10]
+ */
+ {0x404, 0x55550822},
+
+ /*
+ To minimize the text effect
+ this value from 0xa to 0xf
+ */
+ {0x418, 0x555502ff},
+
+ /*
+ Disable brightnes issue Caused by IBC
+ read 4 bytes from address 0x410 to 0x413
+ 0x15E50300 is read value for 0x410 register
+ 0x5E50300= 0x15E50300 & 0xefffffff
+ */
+ {0x410, 0x05E50300},
+ /*...end*/
+ {0x20C, 0x00000124},
+ {0x21C, 0x00000000},
+ {0x224, 0x00000007},
+ {0x228, 0x00050001},
+ {0x22C, 0x0000FF03},
+ {0x230, 0x00000001},
+ {0x234, 0xCA033E10},
+ {0x238, 0x00000060},
+ {0x23C, 0x82E86030},
+ {0x244, 0x001E0285},
+ {0x258, 0x00060062},
+ /*vee strenght initialization*/
+ {0x400, 0x00000000},
+ {0x158, 0x00000000},
+ {0x158, 0x00000001},
+};
+
+static DEFINE_MUTEX(lock);
+#define QUICKLOGIC_MIPI_VENDOR_ID_1 0x5
+#define QUICKLOGIC_MIPI_VENDOR_ID_2 0x1
+#define QUICKLOGIC_MIPI_COMMAND_CSR_WRITE 0x40
+#define QUICKLOGIC_MIPI_COMMAND_CSR_OFFSET 0x41
+
+#define QUICKLOGIC_IIC_READ_CONTROL 0x0E
+#define QUICKLOGIC_IIC_WRITE_CONTROL 0x0A
+#define QUICKLOGIC_BYTE_I2C_RELEASE (0x0u)
+#define QUICKLOGIC_IIC_RELEASE {\
+ QUICKLOGIC_BYTE_I2C_RELEASE, \
+}
+
+#define QL_MIPI_PANEL_CMD_SIZE 255
+#define QL_VX_LCD_VC 0 /* dcs read/write */
+#define CONTROL_BYTE_DCS (0x08u)
+
+#define DTYPE_DCS_WRITE 0x05 /* short write, 0 parameter */
+#define DTYPE_DCS_WRITE1 0x15 /* short write, 1 parameter */
+#define DTYPE_DCS_READ 0x06 /* read */
+#define DTYPE_DCS_LWRITE 0x39 /* long write *//* generic read/write */
+#define DTYPE_GEN_WRITE 0x03 /* short write, 0 parameter */
+#define DTYPE_GEN_WRITE1 0x13 /* short write, 1 parameter */
+#define DTYPE_GEN_WRITE2 0x23 /* short write, 2 parameter */
+#define DTYPE_GEN_LWRITE 0x29 /* long write */
+#define DTYPE_GEN_READ 0x04 /* long read, 0 parameter */
+#define DTYPE_GEN_READ1 0x14 /* long read, 1 parameter */
+#define DTYPE_GEN_READ2 0x24 /* long read, 2 parameter */
+
+
+#define I2CID_BRIDGE 3
+#define I2C_NT50366_ADDR_WRITE 0x9E /* NT50366C 100_1111 0 */
+#define I2C_NT51017_ADDR_WRITE 0xD0 /* NT51017 110_1000 0 */
+#define I2C_BRIDGE_ADDR_WRITE0 0x58 /* 0101_100 0 ADDR=Low */
+#define I2C_BRIDGE_ADDR_WRITE1 0x5A /* 0101_101 0 ADDR=High */
+#define I2C_BRIDGE_ADDR I2C_BRIDGE_ADDR_WRITE0
+
+#define CONTROL_BYTE_GEN (0x09u)
+/**************************************************
+ * QUICKLOGIC MACRO FOR I2C *
+ ***************************************************/
+#define GEN_QL_CSR_OFFSET_LENGTH {\
+ CONTROL_BYTE_GEN, \
+ 0x29, /* Data ID */\
+ 0x05, /* Vendor Id 1 */\
+ 0x01, /* Vendor Id 2 */\
+ 0x41, /* Vendor Unique Command */\
+ 0x00, /* Address LS */\
+ 0x00, /* Address MS */\
+ 0x00, /* Length LS */\
+ 0x00, /* Length MS */\
+}
+
+#define GEN_QL_CSR_WRITE {\
+ CONTROL_BYTE_GEN, \
+ 0x29, /* Data ID */\
+ 0x05, /* Vendor Id 1 */\
+ 0x01, /* Vendor Id 2 */\
+ 0x40, /* Vendor Unique Command */\
+ 0x00, /* Address LS */\
+ 0x00, /* Address MS */\
+ 0x00, /* data LS */\
+ 0x00, \
+ 0x00, \
+ 0x00, /* data MS */\
+}
+
+
+int Quicklogic_i2c_read32(u16 reg, u32 *pval)
+{
+ int ret;
+ int status;
+ u8 address[3], data[4];
+
+ if (g_client == NULL) /* No global client pointer? */
+ return -EIO;
+
+ mutex_lock(&lock);
+ memset(data, 0, 4);
+ address[0] = (reg >> 8) & 0xff;
+ address[1] = reg & 0xff;
+ address[2] = 0xE;
+
+ ret = i2c_master_send(g_client, address, 3);
+ if (ret < 0) {
+ status = -EIO;
+ }
+ ret = i2c_master_recv(g_client, data, 4);
+ if (ret >= 0) {
+ status = 0;
+ *pval = data[0] | (data[1] << 8) | (data[2] << 16)
+ | (data[3] << 24);
+ } else
+ status = -EIO;
+
+ mutex_unlock(&lock);
+
+ return status;
+}
+EXPORT_SYMBOL(Quicklogic_i2c_read32);
+
+int Quicklogic_i2c_read(u32 addr, u32 *val, u32 data_size)
+{
+ u32 data;
+ char buf[] = GEN_QL_CSR_OFFSET_LENGTH;
+ char rx[10];
+ int ret = -1;
+ int write_size;
+
+ if (g_client == NULL) /* No global client pointer? */
+ return -EIO;
+
+ mutex_lock(&lock);
+
+ buf[5] = addr & 0xff;
+ buf[6] = (addr >> 8) & 0xff;
+ buf[7] = data_size & 0xff;
+ buf[8] = (data_size >> 8) & 0xff;
+
+ write_size = 9;
+
+ if ((ret = i2c_master_send( g_client,
+ (char*)(&buf[0]),
+ write_size )) != write_size) {
+ printk(KERN_ERR
+ "%s: i2c_master_send failed (%d)!\n", __func__, ret);
+ mutex_unlock(&lock);
+
+ return -EIO;
+ }
+
+ /*generic read request 0x24 to send generic read command */
+ write_size = 4;
+
+ buf[0] = CONTROL_BYTE_GEN;
+ buf[1] = 0x24; /* Data ID */
+ buf[2] = 0x05; /* Vendor Id 1 */
+ buf[3] = 0x01; /* Vendor Id 2 */
+
+ if ((ret = i2c_master_send(g_client,
+ (char*)(&buf[0]),
+ write_size )) != write_size) {
+
+ pr_info("i2c_master_send failed (%d)!\n", ret);
+ mutex_unlock(&lock);
+ return -EIO;
+ }
+
+ /*return number of bytes or error*/
+ if ((ret = i2c_master_recv(g_client,
+ (char*)(&rx[0]),
+ data_size )) != data_size) {
+
+ pr_info("i2c_master_recv failed (%d)!\n", ret);
+ mutex_unlock(&lock);
+ return -EIO;
+ }
+
+ data = rx[0];
+ if (data_size > 1)
+ data |= (rx[1] << 8);
+ if (data_size > 2)
+ data |= (rx[2] << 16) | (rx[3] << 24);
+
+ *val = data;
+
+ mutex_unlock(&lock);
+
+ pr_info("QX_read value0x%x=0x%x\n",addr,data);
+
+ return 0;
+
+}
+EXPORT_SYMBOL(Quicklogic_i2c_read);
+
+int Quicklogic_i2c_write32(u16 reg, u32 val)
+{
+ int status = 0;
+ /*int write_size;*/
+ char buf[] = GEN_QL_CSR_WRITE;
+
+ if (g_client == NULL) /* No global client pointer? */
+ return -EIO;
+
+ mutex_lock(&lock);
+
+ buf[5] = (uint8_t)reg; /* Address LS */
+ buf[6] = (uint8_t)(reg >> 8); /* Address MS */
+
+ buf[7] = val & 0xff;
+ buf[8] = (val >> 8) & 0xff;
+ buf[9] = (val >> 16) & 0xff;
+ buf[10] =(val >> 24) & 0xff;
+ status = i2c_master_send(g_client, (char *)(&buf[0]), 11);
+
+ if (status >= 0)
+ status = 0;
+ else {
+ printk("zyun: i2c write 32 single error! [0x%04x] -EIO\n", reg);
+ status = -EIO;
+ }
+
+ udelay(10);
+ mutex_unlock(&lock);
+
+ return status;
+
+}
+EXPORT_SYMBOL(Quicklogic_i2c_write32);
+
+int Quicklogic_i2c_release(void)
+{
+ int write_size;
+ int ret = 0;
+ char buf[] = QUICKLOGIC_IIC_RELEASE;
+
+ if (g_client == NULL) /* No global client pointer? */
+ return -1;
+
+ mutex_lock(&lock);
+
+ write_size = 1;
+
+ if ((ret = i2c_master_send( g_client,
+ (char*)(&buf[0]),
+ write_size )) != write_size)
+ pr_info("i2c_master_send failed (%d)!\n", ret);
+
+ mutex_unlock(&lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(Quicklogic_i2c_release);
+
+int Quicklogic_i2cTomipi_write(int dtype, int vit_com, u8 data_size, u8 *ptr )
+{
+ char buf[QL_MIPI_PANEL_CMD_SIZE];
+ int write_size;
+ int i;
+ int ret = -1;
+ int dtype_int;
+
+
+ if (g_client == NULL) /* No global client pointer? */
+ return -1;
+
+ if (data_size > (QL_MIPI_PANEL_CMD_SIZE - 10)) {
+ printk("data size (%d) too big, adjust the QL_MIPI_PANEL_CMD_SIZE!\n", data_size);
+ return ret;
+ }
+ dtype_int = dtype;
+
+ mutex_lock(&lock);
+
+ switch (dtype) {
+ case DTYPE_GEN_WRITE:
+ case DTYPE_GEN_LWRITE:
+ case DTYPE_GEN_WRITE1:
+ case DTYPE_GEN_WRITE2:
+ buf[0] = CONTROL_BYTE_GEN;
+ dtype_int = (data_size == 1) ? DTYPE_GEN_WRITE1 :
+ (data_size == 2) ? DTYPE_GEN_WRITE2 : DTYPE_GEN_LWRITE;
+ break;
+ case DTYPE_DCS_WRITE:
+ case DTYPE_DCS_LWRITE:
+ case DTYPE_DCS_WRITE1:
+ buf[0] = CONTROL_BYTE_DCS;
+ dtype_int = (data_size == 1) ? DTYPE_DCS_WRITE :
+ (data_size == 2) ? DTYPE_DCS_WRITE1 : DTYPE_DCS_LWRITE;
+ break;
+ default:
+ printk("Error unknown data type (0x%x).\n", dtype);
+ break;
+ }
+
+ buf[1] = ((vit_com & 0x3) << 6) | dtype_int ; /*vc, Data ID *//* Copy data */
+
+ /* Copy data */
+ for(i = 0; i < data_size; i++)
+ buf[2+i] = *ptr++;
+
+ write_size = data_size + 2;
+
+ if ((ret = i2c_master_send(g_client,(char*)(&buf[0]),write_size )) != write_size) {
+ printk("Quicklogic_i2c_write32 failed : %d\n", ret);
+
+ mutex_unlock(&lock);
+
+ return -EIO;
+ }
+
+ mutex_unlock(&lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(Quicklogic_i2cTomipi_write);
+
+int Quicklogic_i2cTomipi_read(int dtype, int vit_com, u8 data_size, u8 reg , u8 *pval)
+{
+ char buf[QL_MIPI_PANEL_CMD_SIZE];
+ char rx[10];
+ int write_size; int ret = -1; int dtype_int;
+
+ if (data_size > (QL_MIPI_PANEL_CMD_SIZE-10)) {
+ printk("data size (%d) too big, adjust the QL_MIPI_PANEL_CMD_SIZE!\n", data_size);
+ return ret;
+ }
+
+ dtype_int = dtype;
+
+ mutex_lock(&lock);
+
+ switch (dtype) {
+
+ case DTYPE_GEN_READ1: /*0x14*/
+ case DTYPE_GEN_READ2: /*0x24*/
+ buf[0] = CONTROL_BYTE_GEN;
+ break;
+
+ case DTYPE_DCS_READ: /*0x6*/
+ buf[0] = CONTROL_BYTE_DCS;
+ break;
+
+ default:
+ printk("Error unknown data type (0x%x).\n", dtype);
+ break;
+ }
+
+ buf[1] = ((vit_com & 0x3) << 6) | dtype_int ; /*vc, Data ID */
+
+ switch (dtype) {
+
+ case DTYPE_GEN_READ2: /* short read, 2 parameter */
+
+ write_size = 4;
+ buf[2] = reg;
+ buf[3] = 0;
+ break;
+
+ default:
+ buf[2] = reg;
+ break;
+ }
+
+ write_size = 3;
+
+ if ((ret = i2c_master_send(g_client,(char*)(&buf[0]),
+ write_size )) != write_size) {
+
+ printk("%s: i2c_master_send failed (%d)!\n", __func__, ret);
+
+ mutex_unlock(&lock);
+ return -EIO;
+ }
+
+ if ((ret = i2c_master_recv(g_client, (char*)(&rx[0]),
+ data_size )) != data_size) {
+
+ printk("%s: i2c_master_recv failed (%d)!\n", __func__, ret);
+
+ mutex_unlock(&lock);
+ return -EIO;
+ }
+
+ if (ret < 0)
+ printk("Quicklogic_i2c_read32 failed : %d\n", ret);
+
+ *pval = rx[0];
+
+ if (data_size > 1)
+ *pval |= (rx[1] << 8);
+ if (data_size > 2)
+ *pval |= (rx[2] << 16) | (rx[3] << 24);
+
+ printk("QuickBridge reg=[0x%x]..return=[0x%x]\n",reg,*pval);
+
+ mutex_unlock(&lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(Quicklogic_i2cTomipi_read);
+
+
+int vx5b3d_mipi_write32(struct panel_spec *self, u16 addr, u32 data)
+{
+ int i;
+ static u8 packet[] = {
+ 0x09, 0x00, /* data length */
+ QUICKLOGIC_MIPI_VENDOR_ID_1,
+ QUICKLOGIC_MIPI_VENDOR_ID_2,
+ QUICKLOGIC_MIPI_COMMAND_CSR_WRITE,
+ 0x0, 0x0, /* address 16bits */
+ 0x0, 0x0, 0x0, 0x0 /* data max 32bits */
+ };
+ mipi_dcs_write_t mipi_gen_write=
+ self->info.mipi->ops->mipi_gen_write;
+
+ for (i = 0; i < 2; i++)
+ packet[5 + i] = (u8)(addr >> (8 * i) & 0xff);
+
+ for (i = 0; i < 4; i++)
+ packet[7 + i] = (u8)((data >> (8 * i)) & 0xff);
+
+#ifdef VX5B3D_DEBUG
+ for (i = 0; i < ARRAY_SIZE(packet); i++)
+ printf("packet[%d] = 0x%02x\n", i, packet[i]);
+#endif
+
+ mipi_gen_write(packet, ARRAY_SIZE(packet));
+
+ udelay(1);
+
+ return 0;
+}
+
+int vx5b3d_mipi_write32_array(struct panel_spec *self,
+ struct bridge_data *b_data, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (b_data[i].addr == DELAY_CMD) {
+ mdelay(b_data[i].data);
+ continue;
+ }
+ vx5b3d_mipi_write32(self, b_data[i].addr, b_data[i].data);
+ }
+
+ return 0;
+}
+
+int vx5b3d_i2c_write32(u16 addr, u32 data)
+{
+ int ret, i;
+ int retry_cnt = VX5B3D_I2C_RETRY_CNT;
+
+ do {
+ ret = Quicklogic_i2c_write32(addr, data);
+ } while (--retry_cnt && ret);
+
+ if (!retry_cnt)
+ printk("zyun: vx5b3d_i2c_write32 failed![%d, addr:0x%04x, data:0x%08x] failed!!\n",
+ i, addr, data);
+
+ return ret;
+}
+
+int vx5b3d_i2c_write32_array(struct bridge_data *b_data, int len)
+{
+ int i, ret;
+
+ for (i = 0; i < len; i++) {
+ if (b_data[i].addr == DELAY_CMD) {
+ mdelay(b_data[i].data);
+ continue;
+ }
+ ret = vx5b3d_i2c_write32(b_data[i].addr, b_data[i].data);
+ }
+
+ return ret;
+}
+
+static u32 vx5b3d_i2c_read32(u16 addr)
+{
+ u32 buf;
+ Quicklogic_i2c_read(addr, &buf, 4);
+
+ return buf;
+}
+
+/*
+static u32 vx5b3d_compare(struct bridge_data *b_data, int len)
+{
+ int i;
+ u32 rd_data;
+
+ for (i = 0; i < len; i++) {
+ if (b_data[i].addr == DELAY_CMD) {
+ continue;
+ }
+ rd_data = vx5b3d_i2c_read32(b_data[i].addr);
+ if (rd_data != b_data[i].data)
+ pr_err("[0x%04x] rd_data:0x%x, data:0x%x - not match!!\n",
+ b_data[i].addr, rd_data, b_data[i].data);
+ }
+}
+*/
+
+static int32_t vx5b3d_power(int on)
+{
+ static int probe = 0;
+ if (!probe) {
+ gpio_request(pdata->gpio_lcd_3v3_en, "LCD_3V3_EN");
+ gpio_direction_output(pdata->gpio_lcd_3v3_en, 0);
+ if (gpio_request(pdata->gpio_bridge_en, "BRIDGE_EN")) {
+ printk("[%s] GPIO%d request failed!\n", "BRIDGE_EN", pdata->gpio_bridge_en);
+ return 0;
+ }
+ gpio_direction_output(pdata->gpio_bridge_en, 1);
+
+ if (gpio_request(pdata->gpio_bridge_rst, "BRIDGE_RST")){
+ printk("[%s] GPIO%d request failed!\n", "BRIDGE_RST", pdata->gpio_bridge_rst);
+ return 0;
+ }
+ gpio_direction_output(pdata->gpio_bridge_rst, 1);
+
+ if (gpio_request(pdata->gpio_blic_en, "BLIC_EN")) {
+ printk("[%s] GPIO%d request failed!\n", "BLIC_EN", pdata->gpio_blic_en);
+ return 0;
+ }
+ gpio_direction_output(pdata->gpio_blic_en, 1);
+
+ lvds_1v8 = regulator_get(NULL,"vddsim1");
+ if (IS_ERR(lvds_1v8)) {
+ lvds_1v8 = NULL;
+ pr_info("%s regulator 1v8 get failed!!\n", "vddsim1");
+ } else {
+ regulator_set_voltage(lvds_1v8, 1800000, 1800000);
+ regulator_enable(lvds_1v8);
+ }
+
+ lvds_3v3 = regulator_get(NULL,"vddwifipa");
+ if (IS_ERR(lvds_3v3)) {
+ lvds_3v3 = NULL;
+ pr_info("%s regulator 3v3 get failed!!\n", "vddwifipa");
+ } else {
+ regulator_set_voltage(lvds_3v3, 3300000, 3300000);
+ regulator_enable(lvds_3v3);
+ }
+ probe = 1;
+ }
+
+ printk("%s, on= %d\n", __func__, on);
+ if (on) {
+ gpio_set_value(pdata->gpio_lcd_3v3_en, 1);
+ gpio_set_value(pdata->gpio_bridge_en, 1);
+ regulator_enable(lvds_1v8);
+ regulator_enable(lvds_3v3);
+ udelay(20);
+ gpio_set_value(pdata->gpio_bridge_rst, 1);
+ udelay(20);
+ gpio_set_value(pdata->gpio_blic_en, 1);
+ } else {
+ gpio_set_value(pdata->gpio_lcd_3v3_en, 0);
+ gpio_set_value(pdata->gpio_bridge_rst, 0);
+ udelay(20);
+ regulator_disable(lvds_3v3);
+ regulator_disable(lvds_1v8);
+ gpio_set_value(pdata->gpio_bridge_en, 0);
+ gpio_set_value(pdata->gpio_blic_en, 0);
+ msleep(350);
+ }
+}
+
+static int32_t vx5b3d_mipi_init(struct panel_spec *self)
+{
+ mipi_set_lp_mode_t mipi_set_lp_mode =
+ self->info.mipi->ops->mipi_set_lp_mode;
+ mipi_set_video_mode_t mipi_set_video_mode =
+ self->info.mipi->ops->mipi_set_video_mode;
+
+ if (!g_client)
+ {
+ pr_info("zyun: g_client is NULL!\n");
+ return 0;
+ }
+ /* step 1 : All DSI into LP11*/
+
+ mipi_set_lp_mode();
+ vx5b3d_power(1);
+
+ /* step 3 : Delay*/
+ mdelay(10);
+#ifdef QUICKLOGIC_DEBUG
+ pr_info("[QUICKLOGIC] : VX5B3D INIT - START\n");
+ pr_info("[QUICKLOGIC] : VX5B3D INIT - Waiting...(10sec)\n");
+ mdelay(10 * 1000);
+
+ pr_info("[QUICKLOGIC] : START VX5B3D INIT - Waiting Done!!\n");
+#else
+// vx5b3d_mipi_write32_array(self, vx5b3d_init, ARRAY_SIZE(vx5b3d_init));
+ vx5b3d_i2c_write32_array(vx5b3d_init, ARRAY_SIZE(vx5b3d_init));
+#endif
+ /* step 5 : Start the DSI video stream */
+ mipi_set_video_mode();
+ mdelay(5);
+
+ printk("zyun: init done! 1 \n");
+ pr_info("[QUICKLOGIC] : VX5B3D INIT - DONE\n");
+ //vx5b3d_compare(vx5b3d_init, ARRAY_SIZE(vx5b3d_init));
+
+ return 0;
+}
+
+static uint32_t vx5b3d_readid(struct panel_spec *self)
+{
+ int32_t j =0;
+ uint8_t read_data[4] = {0};
+ int32_t read_rtn = 0;
+ uint8_t param[2] = {0};
+ mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;
+ mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;
+ mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;
+ mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;
+
+ pr_info("%s\n", __func__);
+
+ mipi_set_cmd_mode();
+ mipi_eotp_set(0,0);
+
+ for(j = 0; j < 4; j++){
+ param[0] = 0x01;
+ param[1] = 0x00;
+ mipi_force_write(0x04, param, 2);
+ read_rtn = mipi_force_read(0xda,1,&read_data[0]);
+ LCD_PRINT("lcd_vx5b3d_mipi read id 0xda value is 0x%x!\n",read_data[0]);
+ read_rtn = mipi_force_read(0xdb,1,&read_data[1]);
+ LCD_PRINT("lcd_vx5b3d_mipi read id 0xdb value is 0x%x!\n",read_data[1]);
+ read_rtn = mipi_force_read(0xdc,1,&read_data[2]);
+ LCD_PRINT("lcd_vx5b3d_mipi read id 0xdc value is 0x%x!\n",read_data[2]);
+
+ // if((0x55 == read_data[0])&&(0xbc == read_data[1])&&(0x90 == read_data[2])){
+ printk("lcd_vx5b3d_mipi read id success!\n");
+ return 0x8282;
+ // }
+ }
+
+ mipi_eotp_set(0,0);
+
+ return 0;
+}
+
+
+static int32_t vx5b3d_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
+{
+ pr_info("%s\n", __func__);
+
+ vx5b3d_power(0);
+
+ return 0;
+}
+
+static struct panel_operations lcd_vx5b3d_mipi_operations = {
+ .panel_init = vx5b3d_mipi_init,
+ .panel_readid = vx5b3d_readid,
+ .panel_enter_sleep = vx5b3d_enter_sleep,
+};
+
+static struct timing_rgb lcd_vx5b3d_mipi_timing = {
+ .hfp = 123,
+ .hbp = 100,
+ .hsync = 120,
+ .vfp = 13,
+ .vbp = 10,
+ .vsync = 10,
+};
+
+
+static struct info_mipi lcd_vx5b3d_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq = 480*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_vx5b3d_mipi_timing,
+ .ops = NULL,
+};
+
+struct panel_spec lcd_vx5b3d_mipi_spec = {
+ .width = 1024,
+ .height = 600,
+ .fps = 60,
+ .type = LCD_MODE_DSI,
+ .direction = LCD_DIRECT_NORMAL,
+ .suspend_mode = SEND_SLEEP_CMD,
+ .info = {
+ .mipi = &lcd_vx5b3d_mipi_info
+ },
+ .ops = &lcd_vx5b3d_mipi_operations,
+};
+struct panel_cfg lcd_vx5b3d_mipi = {
+ /* this panel can only be main lcd */
+ .dev_id = SPRDFB_MAINLCD_ID,
+ .lcd_id = 0x8282,
+ .lcd_name = "lcd_vx5b3d_mipi",
+ .panel = &lcd_vx5b3d_mipi_spec,
+};
+//temp code
+static int __init lcd_vx5b3d_mipi_init(void)
+{
+ printk("zyun: %s\n", __func__);
+ i2c_add_driver(&quicklogic_i2c_driver);
+ return sprdfb_panel_register(&lcd_vx5b3d_mipi);
+}
+subsys_initcall(lcd_vx5b3d_mipi_init);
+
+
+#ifdef CONFIG_OF
+static int vx5b3d_parse_dt(struct vx5b3d_dt_data *data, struct device *dev)
+{
+ struct device_node *dNode = dev->of_node;
+ if (dNode == NULL)
+ return -ENODEV;
+ pdata->gpio_bridge_en = of_get_named_gpio(dNode, "gpio_bridge_en", 0);
+ pdata->gpio_bridge_rst = of_get_named_gpio(dNode, "gpio_bridge_rst", 0);
+ pdata->gpio_blic_en= of_get_named_gpio(dNode, "gpio_backlight_en", 0);
+ pdata->gpio_lcd_3v3_en = of_get_named_gpio(dNode, "gpio_lcd_3v3_en", 0);
+ if(pdata->gpio_bridge_en < 0
+ || pdata->gpio_bridge_rst < 0
+ || pdata->gpio_blic_en < 0
+ || pdata->gpio_lcd_3v3_en < 0){
+ pr_err("[%s] - get gpio error: bridge_en:%d, bridge_rst:%d, blic_en:%d, lcd_3v3_en:%d\n",
+ __func__, pdata->gpio_bridge_en, pdata->gpio_bridge_rst, pdata->gpio_blic_en, pdata->gpio_lcd_3v3_en);
+ return -ENODEV;
+ }
+ return 0;
+}
+#endif
+
+static int __init quicklogic_probe(struct i2c_client *client,
+ const struct i2c_device_id * id)
+{
+ static is_i2c_init=false;
+ /*globle data, defined in this file*/
+ pdata = kzalloc(sizeof(struct vx5b3d_dt_data), GFP_KERNEL);
+ if(pdata == NULL){
+ pr_err("[%s] line %d kzalloc fail!\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+#ifdef CONFIG_OF
+ int ret = vx5b3d_parse_dt(pdata, &client->dev);
+ if(ret != 0){
+ return ret;
+ }
+#endif
+ if(is_i2c_init)
+ return 0;
+ if(client==NULL)
+ {
+ printk("zyun: I2C probe error!\n");
+ return 0;
+ }
+ else
+ {
+ is_i2c_init=true;
+ printk("zyun: i2c client, addr=0x%x, name = %s\n", client->addr, client->name);
+ }
+
+ g_client = client;
+ sprd_i2c_ctl_chg_clk(3, 400000); // up h/w i2c 1 400k
+ vx5b3d_power(1);
+
+ return 0;
+}
+static int __exit quicklogic_remove(struct i2c_client *client)
+{
+ pr_info("%s\n", __func__);
+
+ return 0;
+}
+
+
+#define QUICKLOGIC_DEV_NAME ("bridge")
+static struct i2c_device_id quicklogic_id_table[] = {
+ { QUICKLOGIC_DEV_NAME, 0 },
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, quicklogic_id_table);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static const struct dev_pm_ops quicklogic_pm_ops = {
+};
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id quicklogic_of_match[] = {
+ { .compatible = "quicklogic,i2c", },
+};
+#endif
+
+struct i2c_driver quicklogic_i2c_driver = {
+ .id_table = quicklogic_id_table,
+ .probe = quicklogic_probe,
+ .remove = __exit_p(quicklogic_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = QUICKLOGIC_DEV_NAME,
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ .pm = &quicklogic_pm_ops,
+#endif
+
+#ifdef CONFIG_OF
+ .of_match_table = quicklogic_of_match,
+#endif
+ },
+};
+
+static int __init quicklogic_init(void)
+{
+ pr_info("%s, add quicklogic i2c\n", __func__);
+// return i2c_add_driver(&quicklogic_i2c_driver);
+ return 0;
+}
+
+static void __exit quicklogic_exit(void)
+{
+ pr_info("%s, delete quicklogic i2c\n", __func__);
+ i2c_del_driver(&quicklogic_i2c_driver);
+}
+
+module_init(quicklogic_init);
+module_exit(quicklogic_exit);
+
+MODULE_DESCRIPTION("QuickLogic Bridge Driver");
+MODULE_LICENSE("GPL");