/* 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 #include #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);