/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2008
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
* ���ʵIJ���
*****************************************************************************/
#ifndef BUILD_LK
#include <linux/string.h>
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#endif
#ifdef BUILD_LK
//#include <platform/gpio_const.h>
#include <platform/mt_gpio.h>
#include <platform/mt_pmic.h>
#include <platform/mt_i2c.h>
#include <platform/upmu_common.h>
//#include "ddp_hal.h"
#else
#include <mach/mt_gpio.h>
#include <mach/mt_pm_ldo.h>
#include <mach/upmu_hw.h>
#include <mach/upmu_common.h>
//#include "ddp_hal.h"
#endif
#include "lcm_drv.h"
// ---------------------------------------------------------------------------
// Local Constants
// ---------------------------------------------------------------------------
#define FRAME_WIDTH (800)
#define FRAME_HEIGHT (1280)
extern u32 lcm_pwr_pin;
//#define GPIO_LCD_STB_EN GPIO68
//#define GPIO_LCD_RST_EN GPIO_LCM_RST
#define GPIO_LCD_PWR_EN GPIO58
//static unsigned long gpio_lcd_pwr_en = 0;//GPIO92 AK22 GPIo80 AK26 GPIO96 AF21
#define LCM_DSI_CMD_MODE 0
#define REGFLAG_DELAY 0XFE
#define REGFLAG_END_OF_TABLE 0xFF // END OF REGISTERS MARKER
// ---------------------------------------------------------------------------
// Local Variables
// ---------------------------------------------------------------------------
static LCM_UTIL_FUNCS lcm_util = {
.set_gpio_out = NULL,
};
#define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
#define UDELAY(n) (lcm_util.udelay(n))
#define MDELAY(n) (lcm_util.mdelay(n))
#define GPIO_LCM_RST_906 (GPIO114 | 0x80000000) //906 916 118
#define GPIO_LCM_RST_916 (GPIO118 | 0x80000000) //906 916 118
extern void mt6325_upmu_set_rg_vgp1_en(kal_uint32 val);
extern void mt6325_upmu_set_rg_vgp3_vosel(kal_uint32 val);
extern void mt6325_upmu_set_rg_vgp3_en(kal_uint32 val);
#define MT6350_VGP1_EN "VGP3"
// ---------------------------------------------------------------------------
// Local Functions
// ---------------------------------------------------------------------------
#define dsi_set_cmdq_V3(ppara, size, force_update) lcm_util.dsi_set_cmdq_V3(ppara, size, force_update)
#define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update)
#define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
#define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd)
#define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums)
#define read_reg lcm_util.dsi_read_reg()
#define read_reg_v2(cmd, buffer, buffer_size) lcm_util.dsi_dcs_read_lcm_reg_v2(cmd, buffer, buffer_size)
static struct LCM_setting_table {
unsigned cmd;
unsigned char count;
unsigned char para_list[64];
};
static struct LCM_setting_table lcm_initialization_setting[] = {
{0xee,1,{0x50}}, // page 1
{0xea,2,{0x85,0x55}}, //
{0x20,1,{0x00}}, //
{0x30,1,{0x00}}, // bist
{0x24,1,{0xa0}}, // rgb TE
{0x79,1,{0x05}}, // zigzag
{0x7a,1,{0x20}}, //
{0x7d,1,{0x00}}, //
{0x80,1,{0x10}}, // te v width
{0x90,2,{0x25,0x40}}, // ss_tp
{0x93,1,{0xf8}}, //
{0x95,1,{0x74}}, //inv
{0x97,1,{0x08}}, // smart gip
{0x99,1,{0x10}}, // ss_delay
{0xee,1,{0x60}}, // page 2
{0x21,1,{0x00}},
{0x27,1,{0x62}}, // vddd
{0x2c,1,{0xf9}},
{0x29,1,{0x8a}},
{0x30,1,{0x01}},
{0x31,1,{0x0F}},
{0x32,1,{0xd9}}, // vrs_tldo
{0x33,1,{0xC0}}, // dsi_rts<1:0>=10
{0x34,1,{0x1f}},
{0x35,1,{0x10}},
{0x36,1,{0x00}},
{0x37,1,{0x00}},
{0x3a,1,{0x24}}, // gas off
{0x3b,1,{0x00}}, // gip_s3s
{0x3C,1,{0x29}}, // VCOM -0.911V
{0x3d,2,{0x11,0x93}}, // VGH=16.05V VGL=-10.39V
{0x42,2,{0x5f,0x5f}},
{0x86,1,{0x20}},
{0x89,1,{0x00}},
{0x8a,1,{0xAA}},
{0x91,1,{0x44}},
{0x92,1,{0x33}},
{0x93,1,{0x9B}}, // vcsw1=1 vcsw2=0
{0x9a,1,{0x00}}, // 800
{0x9b,2,{0x02,0x80}}, // 1280
//gamma2.5--2022/12/02
{0x47,5,{0x00,0x05,0x1a,0x2a,0x29}}, //gamma P0.4.8.12.20
{0x5a,5,{0x00,0x05,0x1a,0x2a,0x29}}, //gamma n 0.4.8.12.20
{0x4c,5,{0x3a,0x30,0x42,0x20,0x1f}}, //28.44.64.96.128.
{0x5f,5,{0x3a,0x30,0x42,0x20,0x1f}}, //28.44.64.96.128.
{0x51,5,{0x1d,0x01,0x13,0x0c,0x18}}, //159.191.211.227.235
{0x64,5,{0x1d,0x01,0x13,0x0c,0x18}}, //159.191.211.227.235
{0x56,4,{0x17,0x29,0x35,0x7f}}, //243.247.251.255
{0x69,4,{0x17,0x29,0x35,0x7f}}, //243.247.251.255
//gamma2.2--2022/12/02
//{0x47,0x00,0x05,0x1a,0x2a,0x29}}, //gamma P0.4.8.12.20
//{0x5a,0x00,0x05,0x1a,0x2a,0x29}}, //gamma n 0.4.8.12.20
//{0x4c,0x3f,0x35,0x48,0x26,0x25}}, //28.44.64.96.128.
//{0x5f,0x3f,0x35,0x48,0x26,0x25}}, //28.44.64.96.128.
//{0x51,0x22,0x05,0x17,0x0f,0x1d}}, //159.191.211.227.235
//{0x64,0x22,0x05,0x17,0x0f,0x1d}}, //159.191.211.227.235
//{0x56,0x1d,0x2b,0x35,0x7f}}, //243.247.251.255
//{0x69,0x1d,0x2b,0x35,0x7f}}, //243.247.251.255
{0xee,1,{0x70}},
//STV0 stv1 stv2
{0x00,4,{0x01,0x07,0x00,0x01}},
{0x04,4,{0x05,0x0b,0x55,0x01}},
{0x08,4,{0x08,0x0c,0x55,0x01}},
{0x0c,2,{0x02,0x02}},//0202
// CYC0 cyc1
{0x10,5,{0x03,0x07,0x00,0x00,0x00}},
{0x15,4,{0x00,0x15,0x0d,0x08}},
{0x29,2,{0x02,0x02}},//d9 02 d0
//gip0-gip21=gipL1-gipL22 (forward scan)
{0x60,5,{0x3c,0x3c,0x08,0x05,0x04}},
{0x65,5,{0x17,0x16,0x15,0x14,0x13}},
{0x6a,5,{0x12,0x11,0x10,0x00,0x01}},
{0x6f,5,{0x3c,0x3c,0x3c,0x3c,0x3c}},
{0x74,2,{0x3c,0x3c}},
//gip22-gip43=gipR1-gipR22 (forward scan)
{0x80,5,{0x3c,0x3c,0x08,0x05,0x04}},
{0x85,5,{0x17,0x16,0x15,0x14,0x13}},
{0x8a,5,{0x12,0x11,0x10,0x00,0x01}},
{0x8f,5,{0x3c,0x3c,0x3c,0x3c,0x3c}},
{0x94,2,{0x3c,0x3c}},
{0xea,2,{0x00,0x00}}, // write enable
{0xee,1,{0x00}}, // ENTER PAGE0
// Sleep Out
{0x11, 0, {0x00}},
{REGFLAG_DELAY, 120, {}},
// Display ON
{0x29, 0, {0x00}},
{REGFLAG_DELAY, 100, {}},
{REGFLAG_END_OF_TABLE, 0x00, {}}
};
static struct LCM_setting_table lcm_set_window[] = {
{0x2A, 4, {0x00, 0x00, (FRAME_WIDTH>>8), (FRAME_WIDTH&0xFF)}},
{0x2B, 4, {0x00, 0x00, (FRAME_HEIGHT>>8), (FRAME_HEIGHT&0xFF)}},
{REGFLAG_END_OF_TABLE, 0x00, {}}
};
static struct LCM_setting_table lcm_sleep_out_setting[] = {
// Sleep Out
{0x11, 0, {0x00}},
{REGFLAG_DELAY, 120, {}},
// Display ON
{0x29, 0, {0x00}},
{REGFLAG_DELAY, 10, {}},
{REGFLAG_END_OF_TABLE, 0x00, {}}
};
static struct LCM_setting_table lcm_sleep_in_setting[] = {
// Display off sequence
{0x28, 0, {0x00}},
// Sleep Mode On
{0x10, 0, {0x00}},
{REGFLAG_END_OF_TABLE, 0x00, {}}
};
static void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update)
{
unsigned int i;
for(i = 0; i < count; i++) {
unsigned cmd;
cmd = table[i].cmd;
switch (cmd) {
case REGFLAG_DELAY :
MDELAY(table[i].count);
break;
case REGFLAG_END_OF_TABLE :
break;
default:
dsi_set_cmdq_V2(cmd, table[i].count, table[i].para_list, force_update);
}
}
}
static void avdd_enable(unsigned char enabled)
{
// gpio_lcd_pwr_en = (lcm_pwr_pin | 0x80000000);
if(enabled)
{
mt_set_gpio_mode(GPIO_LCD_PWR_EN, GPIO_MODE_00);
mt_set_gpio_dir(GPIO_LCD_PWR_EN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_LCD_PWR_EN, GPIO_OUT_ONE);
}
else
{
mt_set_gpio_mode(GPIO_LCD_PWR_EN, GPIO_MODE_00);
mt_set_gpio_dir(GPIO_LCD_PWR_EN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_LCD_PWR_EN, GPIO_OUT_ZERO);
}
}
// ---------------------------------------------------------------------------
// LCM Driver Implementations
// ---------------------------------------------------------------------------
static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util)
{
memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS));
}
extern void DSI_clk_HS_mode(unsigned char enter);
static void lcm_get_params(LCM_PARAMS *params)
{
memset(params, 0, sizeof(LCM_PARAMS));
params->type = LCM_TYPE_DSI;
params->width = FRAME_WIDTH;
params->height = FRAME_HEIGHT;
#if (LCM_DSI_CMD_MODE)
params->dsi.mode = CMD_MODE;
#else
params->dsi.mode = SYNC_PULSE_VDO_MODE; //;//BURST_VDO_MODE; BURST_VDO_MODE
#endif
// DSI
/* Command mode setting */
params->dsi.LANE_NUM = LCM_FOUR_LANE;//; LCM_FOUR_LANE LCM_THREE_LANE
//The following defined the fomat for data coming from LCD engine.
params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;
// Highly depends on LCD driver capability.
// Not support in MT6573
params->dsi.packet_size=256;
// Video mode setting
params->dsi.intermediat_buffer_num = 0; //because DSI/DPI HW design change, this parameters should be 0 when video mode in MT658X; or memory leakage
params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888;
//params->dsi.word_count=FRAME_WIDTH*3;
#if 1 //tongyong
params->dsi.vertical_sync_active = 8;//4
params->dsi.vertical_backporch = 8; //4
params->dsi.vertical_frontporch = 20;//8;
params->dsi.vertical_active_line = FRAME_HEIGHT;
params->dsi.horizontal_sync_active = 20;//16;
params->dsi.horizontal_backporch = 20;//48;
params->dsi.horizontal_frontporch = 80;//16;
params->dsi.horizontal_active_pixel = FRAME_WIDTH;
params->dsi.PLL_CLOCK=220;//200;//240;//300;//270;//246; //
#else //8.5daixian
params->dsi.vertical_sync_active = 4;
params->dsi.vertical_backporch = 12;
params->dsi.vertical_frontporch = 20;//20;
params->dsi.vertical_active_line = FRAME_HEIGHT;
params->dsi.horizontal_sync_active = 20;//18;
params->dsi.horizontal_backporch = 20;//18;
params->dsi.horizontal_frontporch = 30;//18;//20
params->dsi.horizontal_active_pixel = FRAME_WIDTH;
params->dsi.PLL_CLOCK=215;//200;//240;//300;//270;//246; //
#endif
}
static void lcd_power_en(unsigned char enabled)
{
if (enabled)
{
#ifdef BUILD_LK
/* VGP2_PMU 3V */
//pmic_config_interface(DIGLDO_CON29, 0x6, PMIC_RG_VGP2_VOSEL_MASK, PMIC_RG_VGP2_VOSEL_SHIFT);
//pmic_config_interface(DIGLDO_CON8, 0x1, PMIC_RG_VGP2_EN_MASK, PMIC_RG_VGP2_EN_SHIFT);
/* VGP1_PMU 3.3V */
pmic_config_interface(DIGLDO_CON28, 0x7, PMIC_RG_VGP1_VOSEL_MASK, PMIC_RG_VGP1_VOSEL_SHIFT);
pmic_config_interface(DIGLDO_CON7, 0x1, PMIC_RG_VGP1_EN_MASK, PMIC_RG_VGP1_EN_SHIFT);
#else
upmu_set_rg_vgp1_vosel(0x7);
upmu_set_rg_vgp1_en(0x1);
#endif
}
else
{
#ifdef BUILD_LK
/* VGP2_PMU 3V */
//pmic_config_interface(DIGLDO_CON8, 0x0, PMIC_RG_VGP2_EN_MASK, PMIC_RG_VGP2_EN_SHIFT);
//pmic_config_interface(DIGLDO_CON29, 0x0, PMIC_RG_VGP2_VOSEL_MASK, PMIC_RG_VGP2_VOSEL_SHIFT);
/* VGP1_PMU 3.3V */
pmic_config_interface(DIGLDO_CON28, 0x0, PMIC_RG_VGP1_VOSEL_MASK, PMIC_RG_VGP1_VOSEL_SHIFT);
pmic_config_interface(DIGLDO_CON7, 0x0, PMIC_RG_VGP1_EN_MASK, PMIC_RG_VGP1_EN_SHIFT);
#else
upmu_set_rg_vgp1_en(0x0);
upmu_set_rg_vgp1_vosel(0x0);
#endif
}
}
static void lcm_init(void)
{
#ifdef BUILD_LK
printf("[Elink_LCM_Drv Nicholas..] %s, LK \n", __func__);
#else
printk("[Elink_LCM_Drv Nicholas..] %s, kernel", __func__);
#endif
lcd_power_en(1);
//lcd_power_en(1);
//MDELAY(20);
avdd_enable(1);
MDELAY(20);
mt_set_gpio_mode(GPIO_LCD_PWR_EN, GPIO_MODE_00);
mt_set_gpio_dir(GPIO_LCD_PWR_EN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_LCD_PWR_EN, GPIO_OUT_ONE);
MDELAY(50);
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ONE);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ONE);
MDELAY(50);
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ZERO);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ZERO);
MDELAY(50);
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ONE);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ONE);
MDELAY(150);
#if defined(BUILD_LK)
printf("hx8394_init\n");
#else
printk("hx8394_init\n");
#endif
push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1);
}
static void lcm_suspend(void)
{
unsigned int data_array[16];
#ifdef BUILD_LK
printf("[Elink_LCM_Drv Nicholas] %s, LK \n", __func__);
#else
printk("[Elink_LCM_Drv Nicholas] %s, kernel", __func__);
#endif
data_array[0]=0x00280500; // Display Off
dsi_set_cmdq(&data_array, 1, 1);
MDELAY(20);
data_array[0] = 0x00100500; // Sleep In
dsi_set_cmdq(&data_array, 1, 1);
MDELAY(120);
lcd_power_en(0);
avdd_enable(0);
MDELAY(50);
}
static void lcm_resume(void)
{
#ifdef BUILD_LK
printf("%s, LK \n", __func__);
#else
printk("%s, kernel", __func__);
#endif
lcm_init();
}
static unsigned int lcm_compare_id(void)
{
unsigned int id=0;
unsigned char buffer[4];
unsigned int array[16];
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ONE);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ONE);
MDELAY(10);
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ZERO);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ZERO);
MDELAY(10);
mt_set_gpio_out(GPIO_LCM_RST_906, GPIO_OUT_ONE);
mt_set_gpio_out(GPIO_LCM_RST_916, GPIO_OUT_ONE);
MDELAY(120);
lcm_init();
//array[0]=0x00043902;
//array[1]=0x8983FFB9;// page enable
//dsi_set_cmdq(&array, 2, 1);
//MDELAY(10);
array[0] = 0x00033700;// read id return 5 byte
dsi_set_cmdq(array, 1, 1);
MDELAY(5);
//array[0] = 0x04B02300;// unlock for reading ID
//dsi_set_cmdq(array, 1, 1);
//MDELAY(50);
read_reg_v2(0x04, buffer, 4);
MDELAY(5);
id = buffer[0];
#if defined(BUILD_UBOOT)
printf("%s, id = 0x%08x\n", __func__, id);///83940f
#endif
//return (0x83 == id )?1:0;
#ifdef BUILD_LK
printf("jd9366 new params id=0x%x\n", id);
printf("jd9366 lcm_compare_id buffer[0] buffer[1] buffer[2] buffer[3] buffer[4] = 0x%x,0x%x,0x%x,0x%x,0x%x\r\n",buffer[0],buffer[1], buffer[2],buffer[3],buffer[4]);
#else
printk("jd9366 new params id=0x%x\n", id);
printk("jd9366 lcm_compare_id buffer[0] buffer[1] buffer[2] buffer[3] buffer[4]= 0x%x,0x%x,0x%x,0x%x,0x%x\r\n",buffer[0],buffer[1], buffer[2],buffer[3],buffer[4]);
#endif
return ( 0x93 == buffer[0] && 0x65 == buffer[1] )?1:0;
}
LCM_DRIVER gh8555_ivo_ips_dsi_vdo_boe_lcm_drv =
{
.name = "gh8555_ivo_ips_dsi_vdo_boe",
.set_util_funcs = lcm_set_util_funcs,
.get_params = lcm_get_params,
.init = lcm_init,
.suspend = lcm_suspend,
.resume = lcm_resume,
.compare_id = lcm_compare_id,
};