1 /* drivers/video/sprdfb/lcd_nt51017_mipi_lvds.c
3 * Support for nt51017 lvds LCD device
5 * Copyright (C) 2013 Spreadtrum
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 #include <asm/arch/sprd_lcd.h>
17 //#include <asm/arch/sprd_i2c.h>
18 #include <asm/arch/sci_types.h>
19 #include "sp8830_i2c.h"
20 //#include "sc8830_i2c_cfg.h"
22 #include "../sprdfb.h"
28 #define LCD_PRINT printk
30 #define LCD_PRINT(...)
33 /***************** Important Macro! *****************/
34 /* For TI! ONLY ONE of the flowing marco can be defined! */
35 //#define LINES_ALL_RIGHT_TI
36 #define LINES_ONLY_CLK_RIGHT_TI
38 /* For CHIPONE! ONLY ONE of the flowing marco can be defined! */
39 //#ifdef CONFIG_SHARK_PAD_HW_V102 // 5735A-2 v1.0.2 & 5735C-1 v1.0.0
41 #define LINES_ALL_WRONG_C1
42 #else // 5735A-2 v1.0.1
43 #define LINES_ALL_RIGHT_C1
45 /***************** Important Macro! *****************/
48 int32_t (*init)(struct panel_spec *self);
51 static struct bridge_ops b_ops = {
55 #define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
57 #define I2CID_BRIDGE 2
58 #define I2C_NT50366_ADDR_WRITE 0x9E /* NT50366C 100_1111 0 */
59 #define I2C_NT51017_ADDR_WRITE 0xD0 /* NT51017 110_1000 0 */
60 #define I2C_BRIDGE_ADDR_WRITE0 0x58 /* 0101_100 0 ADDR=Low */
61 #define I2C_BRIDGE_ADDR_WRITE1 0x5A /* 0101_101 0 ADDR=High */
62 #define I2C_BRIDGE_ADDR I2C_BRIDGE_ADDR_WRITE0
64 #define GPIOID_BRIDGE_EN 231
65 #define GPIOID_VDDPWR 232
66 #define GPIOID_ADDR 234 /* should modify pinmap */
67 #define GPIOID_LCDPWR 235
69 extern int sprd_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value);
70 extern int sprd_gpio_request(struct gpio_chip *chip, unsigned offset);
72 typedef struct I2C_Init_Code_tag {
77 static I2C_DEV i2c_dev_bridge = {
81 .slave_addr = I2C_BRIDGE_ADDR,
87 const static I2C_Init_Code lvds_init_data_ti[] = {
96 #ifdef LINES_ALL_RIGHT_TI
97 {0x18, 0x18},/* all the line is right */
98 #elif defined LINES_ONLY_CLK_RIGHT_TI
99 {0x18, 0xF8},/* only clock line is right */
101 {0x19, 0x0C},/* 0x00 */
116 {0x2C, 0x04},/*0x04*/
120 {0x30, 0x04},/*0x04*/
136 const static I2C_Init_Code lvds_init_data_c1[] = {
146 {0x28, 0x04},/*0x02*/
155 {0x69, 0x1C},/*0x1F*/
159 #ifdef LINES_ALL_RIGHT_C1
161 #elif defined LINES_ONLY_CLK_RIGHT_C1
163 #elif defined LINES_ALL_WRONG_C1
167 /*{0x2A, 0x31},modify*/
176 static int32_t sn65dsi83_init(struct panel_spec *self)
182 uint8 ti_pll_en = lvds_init_data_ti[3].val | 0x01; /* (CSR 0x0D.0) */
183 uint8 ti_soft_reset = lvds_init_data_ti[0].val | 0x01; /* (CSR 0x09.0) */
185 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 */
186 mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
187 mipi_set_video_mode_t mipi_set_video_mode = self->info.mipi->ops->mipi_set_video_mode;
189 LCD_PRINT("sn65dsi83_init\n");
191 /* step 1 : All DSI into LP11*/
195 sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
196 sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 0);
198 sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
204 handle = I2C_HAL_Open(&i2c_dev_bridge);
206 /* step 4 : init CSR reg*/
207 for(i=0; i<ARRAY_SIZE(lvds_init_data_ti); i++){
208 err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[i].addr, &lvds_init_data_ti[i].val, 1);
209 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[i].addr, lvds_init_data_ti[i].val,err_code);
212 /* step 5 : Start the DSI video stream */
214 mipi_set_video_mode();
217 /* step 6 : Set the PLL_EN bit(CSR 0x0D.0) */
218 err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[3].addr, &ti_pll_en, 1);
219 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[3].addr, ti_pll_en,err_code);
221 /* step 7 : Wait for the PLL_LOCK bit to be set(CSR 0x0A.7) */
224 /* step 8 : Set the SOFT_RESET bit (CSR 0x09.0) */
225 err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[0].addr, &ti_soft_reset, 1);
226 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[0].addr, ti_soft_reset, err_code);
229 I2C_HAL_Close(handle);
234 static int32_t chipone_init(struct panel_spec *self)
240 sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
241 sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
245 handle = I2C_HAL_Open(&i2c_dev_bridge);
248 for(i=0; i<ARRAY_SIZE(lvds_init_data_c1); i++){
249 err_code = I2C_HAL_Write(handle, &lvds_init_data_c1[i].addr, &lvds_init_data_c1[i].val, 1);
250 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_c1[i].addr, lvds_init_data_c1[i].val,err_code);
254 I2C_HAL_Close(handle);
259 static int32_t get_bridge_info(struct panel_spec *self)
266 sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
267 sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 0);
269 sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
272 sprd_gpio_request(NULL, GPIOID_ADDR);
273 sprd_gpio_direction_output(NULL, GPIOID_ADDR, 0);//drive ADDR to low
277 handle = I2C_HAL_Open(&i2c_dev_bridge);
279 err_code = I2C_HAL_Read(handle, ®, &flag, 1);
281 printf("I2C Read Error! err_code=%d\n", err_code);
285 if (0x35 == flag){//TI
286 b_ops.init = sn65dsi83_init;
287 printf("sprdfb: MIPI to LVDS bridge is TI SN65DSI83!\n");
288 } else if (0xC1 == flag) {//ChipOne
289 b_ops.init = chipone_init;
290 printf("sprdfb: MIPI to LVDS bridge is ChpOne!\n");
292 printf("sprdfb: Unknown bridge! flag=0x%x\n",flag);
293 I2C_HAL_Close(handle);
298 I2C_HAL_Close(handle);
303 static int32_t nt51017_mipi_lvds_init(struct panel_spec *self)
305 LCD_PRINT("lcd_nt51017_mipi_lvds_init\n");
311 sprd_gpio_request(NULL, GPIOID_VDDPWR);
312 sprd_gpio_direction_output(NULL, GPIOID_VDDPWR, 1);
315 sprd_gpio_request(NULL, GPIOID_LCDPWR);
316 sprd_gpio_direction_output(NULL, GPIOID_LCDPWR, 1);
322 static uint32_t nt51017_mipi_lvds_readid(struct panel_spec *self)
324 LCD_PRINT("nt51017_mipi_lvds_readid\n");
326 if(get_bridge_info(self)){
327 printk("u-boot get bridge info fail!\n");
331 return 0xC749;/*51017*/
334 static struct panel_operations lcd_nt51017_mipi_lvds_operations = {
335 .panel_init = nt51017_mipi_lvds_init,
336 .panel_readid = nt51017_mipi_lvds_readid,
339 static struct timing_rgb lcd_nt51017_mipi_lvds_timing = {
340 .hfp = 110, /* unit: pixel */
343 .vfp = 18, /*unit: line*/
348 static struct info_mipi lcd_nt51017_mipi_lvds_info = {
349 .work_mode = SPRDFB_MIPI_MODE_VIDEO,
350 .video_bus_width = 24, /*18,16*/
352 .phy_feq = 512*1000,/*494*/
353 .h_sync_pol = SPRDFB_POLARITY_POS,
354 .v_sync_pol = SPRDFB_POLARITY_POS,
355 .de_pol = SPRDFB_POLARITY_POS,
356 .te_pol = SPRDFB_POLARITY_POS,
357 .color_mode_pol = SPRDFB_POLARITY_NEG,
358 .shut_down_pol = SPRDFB_POLARITY_NEG,
359 .timing = &lcd_nt51017_mipi_lvds_timing,
363 struct panel_spec lcd_nt51017_mipi_lvds_spec = {
364 //.cap = PANEL_CAP_NOT_TEAR_SYNC,
368 .type = LCD_MODE_DSI,
369 .direction = LCD_DIRECT_NORMAL,
371 .mipi = &lcd_nt51017_mipi_lvds_info
373 .ops = &lcd_nt51017_mipi_lvds_operations,