6db4831e98
Android 14
1478 lines
39 KiB
C
1478 lines
39 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
*/
|
|
|
|
#if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
|
|
#include <linux/string.h>
|
|
#include <linux/wait.h>
|
|
#include <linux/of.h>
|
|
|
|
#include "lcm_define.h"
|
|
#include "lcm_drv.h"
|
|
#include "lcm_common.h"
|
|
#include "lcm_gpio.h"
|
|
#include "lcm_i2c.h"
|
|
#include "lcm_pmic.h"
|
|
#include "lcm_util.h"
|
|
|
|
|
|
/* #define LCM_DEBUG */
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Local Variables */
|
|
/* ------------------------------------------------------------------------- */
|
|
static struct LCM_DTS _LCM_DTS;
|
|
static struct LCM_UTIL_FUNCS lcm_util;
|
|
|
|
#define FRAME_WIDTH _LCM_DTS.params.width
|
|
#define FRAME_HEIGHT _LCM_DTS.params.height
|
|
|
|
#define dsi_set_cmdq(pdata, queue_size, force_update) \
|
|
lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
|
|
#define read_reg_v2(cmd, buffer, buffer_size) \
|
|
lcm_util.dsi_dcs_read_lcm_reg_v2(cmd, buffer, buffer_size)
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* LCM Driver Implementations */
|
|
/* ------------------------------------------------------------------------- */
|
|
void lcm_common_parse_dts(const struct LCM_DTS *DTS, unsigned char force_update)
|
|
{
|
|
struct LCM_PARAMS *dts_params = &_LCM_DTS.params;
|
|
struct LCM_DATA *dts_init = &(_LCM_DTS.init[0]);
|
|
struct LCM_DATA *dts_compare_id = &(_LCM_DTS.compare_id[0]);
|
|
struct LCM_DATA *dts_suspend = &(_LCM_DTS.suspend[0]);
|
|
struct LCM_DATA *dts_backlight = &(_LCM_DTS.backlight[0]);
|
|
struct LCM_DATA *dts_backlight_cmdq = &(_LCM_DTS.backlight_cmdq[0]);
|
|
|
|
|
|
if ((_LCM_DTS.parsing != 0) && (force_update == 0)) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS has been parsed or non-force update: %d, %d\n",
|
|
__func__, __LINE__, _LCM_DTS.parsing, force_update);
|
|
return;
|
|
}
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS parameter set */
|
|
memset(dts_params, 0, sizeof(struct LCM_PARAMS));
|
|
dts_params->type = LCM_TYPE_DSI;
|
|
dts_params->width = 720;
|
|
dts_params->height = 1280;
|
|
dts_params->dbi.te_mode = LCM_DBI_TE_MODE_VSYNC_ONLY;
|
|
dts_params->dbi.te_edge_polarity = LCM_POLARITY_RISING;
|
|
dts_params->dsi.mode = CMD_MODE;
|
|
dts_params->dsi.switch_mode = SYNC_PULSE_VDO_MODE;
|
|
dts_params->dsi.LANE_NUM = LCM_FOUR_LANE;
|
|
dts_params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
|
|
dts_params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
|
|
dts_params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
|
|
dts_params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;
|
|
dts_params->dsi.packet_size = 256;
|
|
dts_params->dsi.PS = LCM_PACKED_PS_24BIT_RGB888;
|
|
dts_params->dsi.PLL_CLOCK = 200;
|
|
dts_params->dsi.clk_lp_per_line_enable = 0;
|
|
dts_params->dsi.esd_check_enable = 0;
|
|
dts_params->dsi.customization_esd_check_enable = 0;
|
|
dts_params->dsi.lcm_esd_check_table[0].cmd = 0x53;
|
|
dts_params->dsi.lcm_esd_check_table[0].count = 0x01;
|
|
dts_params->dsi.lcm_esd_check_table[0].para_list[0] = 0x24;
|
|
#else
|
|
memset(dts_params, 0, sizeof(struct LCM_PARAMS));
|
|
memcpy(dts_params, &(DTS->params), sizeof(struct LCM_PARAMS));
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
if (memcmp((unsigned char *)dts_params,
|
|
(unsigned char *)(&(DTS->params)),
|
|
sizeof(struct LCM_PARAMS)) != 0x0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS compare error\n",
|
|
__func__, __LINE__);
|
|
|
|
pr_debug("[LCM][ERROR] dts_params:\n");
|
|
tmp = (unsigned char *)dts_params;
|
|
tmp2 = (unsigned char *)(&(DTS->params));
|
|
for (i = 0; i < sizeof(struct LCM_PARAMS); i += 8) {
|
|
if (*(tmp + i) != *(tmp2 + i))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i), *(tmp2 + i), i);
|
|
if (*(tmp + i + 1) != *(tmp2 + i + 1))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 1),
|
|
*(tmp2 + i + 1), i + 1);
|
|
if (*(tmp + i + 2) != *(tmp2 + i + 2))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 2),
|
|
*(tmp2 + i + 2), i + 2);
|
|
if (*(tmp + i + 3) != *(tmp2 + i + 3))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 3),
|
|
*(tmp2 + i + 3), i + 3);
|
|
if (*(tmp + i + 4) != *(tmp2 + i + 4))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 4),
|
|
*(tmp2 + i + 4), i + 4);
|
|
if (*(tmp + i + 5) != *(tmp2 + i + 5))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 5),
|
|
*(tmp2 + i + 5), i + 5);
|
|
if (*(tmp + i + 6) != *(tmp2 + i + 6))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 6),
|
|
*(tmp2 + i + 6), i + 6);
|
|
if (*(tmp + i + 7) != *(tmp2 + i + 7))
|
|
pr_debug("data: 0x%x 0x%x, index: %d\n",
|
|
*(tmp + i + 7),
|
|
*(tmp2 + i + 7), i + 7);
|
|
}
|
|
|
|
pr_debug("[LCM][ERROR] DTS->params:\n");
|
|
tmp = (unsigned char *)(&(DTS->params));
|
|
for (i = 0; i < sizeof(struct LCM_PARAMS); i += 8) {
|
|
pr_debug("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
*(tmp + i), *(tmp + i + 1), *(tmp + i + 2),
|
|
*(tmp + i + 3), *(tmp + i + 4),
|
|
*(tmp + i + 5), *(tmp + i + 6),
|
|
*(tmp + i + 7));
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS init data set */
|
|
_LCM_DTS.init_size = 0;
|
|
memset(dts_init, 0, sizeof(struct LCM_DATA) * INIT_SIZE);
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_RESET;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = LCM_UTIL_RESET_HIGH;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_RESET;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = LCM_UTIL_RESET_LOW;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_MDELAY;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = 10;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_RESET;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = LCM_UTIL_RESET_HIGH;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_MDELAY;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = 20;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 2;
|
|
dts_init->data_t3.cmd = 0x11;
|
|
dts_init->data_t3.size = 0;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_MDELAY;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = 120;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 5;
|
|
dts_init->data_t3.cmd = 0xB9;
|
|
dts_init->data_t3.size = 3;
|
|
dts_init->data_t3.data[0] = 0xFF;
|
|
dts_init->data_t3.data[1] = 0x83;
|
|
dts_init->data_t3.data[2] = 0x92;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_UTIL;
|
|
dts_init->type = LCM_UTIL_MDELAY;
|
|
dts_init->size = 1;
|
|
dts_init->data_t1.data = 10;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 4;
|
|
dts_init->data_t3.cmd = 0xB0;
|
|
dts_init->data_t3.size = 2;
|
|
dts_init->data_t3.data[0] = 0x01;
|
|
dts_init->data_t3.data[1] = 0x08;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 19;
|
|
dts_init->data_t3.cmd = 0xBA;
|
|
dts_init->data_t3.size = 17;
|
|
dts_init->data_t3.data[0] = 0x13;
|
|
dts_init->data_t3.data[1] = 0x83;
|
|
dts_init->data_t3.data[2] = 0x00;
|
|
dts_init->data_t3.data[3] = 0xD6;
|
|
dts_init->data_t3.data[4] = 0xC5;
|
|
dts_init->data_t3.data[5] = 0x10;
|
|
dts_init->data_t3.data[6] = 0x09;
|
|
dts_init->data_t3.data[7] = 0xFF;
|
|
dts_init->data_t3.data[8] = 0x0F;
|
|
dts_init->data_t3.data[9] = 0x27;
|
|
dts_init->data_t3.data[10] = 0x03;
|
|
dts_init->data_t3.data[11] = 0x21;
|
|
dts_init->data_t3.data[12] = 0x27;
|
|
dts_init->data_t3.data[13] = 0x25;
|
|
dts_init->data_t3.data[14] = 0x20;
|
|
dts_init->data_t3.data[15] = 0x00;
|
|
dts_init->data_t3.data[16] = 0x10;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 15;
|
|
dts_init->data_t3.cmd = 0xB1;
|
|
dts_init->data_t3.size = 13;
|
|
dts_init->data_t3.data[0] = 0x7C;
|
|
dts_init->data_t3.data[1] = 0x00;
|
|
dts_init->data_t3.data[2] = 0x43;
|
|
dts_init->data_t3.data[3] = 0xBB;
|
|
dts_init->data_t3.data[4] = 0x00;
|
|
dts_init->data_t3.data[5] = 0x1A;
|
|
dts_init->data_t3.data[6] = 0x1A;
|
|
dts_init->data_t3.data[7] = 0x2F;
|
|
dts_init->data_t3.data[8] = 0x36;
|
|
dts_init->data_t3.data[9] = 0x3F;
|
|
dts_init->data_t3.data[10] = 0x3F;
|
|
dts_init->data_t3.data[11] = 0x42;
|
|
dts_init->data_t3.data[12] = 0x7A;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 14;
|
|
dts_init->data_t3.cmd = 0xB2;
|
|
dts_init->data_t3.size = 12;
|
|
dts_init->data_t3.data[0] = 0x08;
|
|
dts_init->data_t3.data[1] = 0xC8;
|
|
dts_init->data_t3.data[2] = 0x06;
|
|
dts_init->data_t3.data[3] = 0x18;
|
|
dts_init->data_t3.data[4] = 0x04;
|
|
dts_init->data_t3.data[5] = 0x84;
|
|
dts_init->data_t3.data[6] = 0x00;
|
|
dts_init->data_t3.data[7] = 0xFF;
|
|
dts_init->data_t3.data[8] = 0x06;
|
|
dts_init->data_t3.data[9] = 0x06;
|
|
dts_init->data_t3.data[10] = 0x04;
|
|
dts_init->data_t3.data[11] = 0x20;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 25;
|
|
dts_init->data_t3.cmd = 0xB4;
|
|
dts_init->data_t3.size = 23;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x00;
|
|
dts_init->data_t3.data[2] = 0x05;
|
|
dts_init->data_t3.data[3] = 0x0A;
|
|
dts_init->data_t3.data[4] = 0x8F;
|
|
dts_init->data_t3.data[5] = 0x06;
|
|
dts_init->data_t3.data[6] = 0x0A;
|
|
dts_init->data_t3.data[7] = 0x95;
|
|
dts_init->data_t3.data[8] = 0x01;
|
|
dts_init->data_t3.data[9] = 0x07;
|
|
dts_init->data_t3.data[10] = 0x06;
|
|
dts_init->data_t3.data[11] = 0x0C;
|
|
dts_init->data_t3.data[12] = 0x02;
|
|
dts_init->data_t3.data[13] = 0x08;
|
|
dts_init->data_t3.data[14] = 0x08;
|
|
dts_init->data_t3.data[15] = 0x21;
|
|
dts_init->data_t3.data[16] = 0x04;
|
|
dts_init->data_t3.data[17] = 0x02;
|
|
dts_init->data_t3.data[18] = 0x08;
|
|
dts_init->data_t3.data[19] = 0x01;
|
|
dts_init->data_t3.data[20] = 0x04;
|
|
dts_init->data_t3.data[21] = 0x1A;
|
|
dts_init->data_t3.data[22] = 0x95;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0x35;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 6;
|
|
dts_init->data_t3.cmd = 0xBF;
|
|
dts_init->data_t3.size = 4;
|
|
dts_init->data_t3.data[0] = 0x05;
|
|
dts_init->data_t3.data[1] = 0x60;
|
|
dts_init->data_t3.data[2] = 0x02;
|
|
dts_init->data_t3.data[3] = 0x00;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0xB6;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x6A;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0x36;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x08;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 4;
|
|
dts_init->data_t3.cmd = 0xC0;
|
|
dts_init->data_t3.size = 2;
|
|
dts_init->data_t3.data[0] = 0x03;
|
|
dts_init->data_t3.data[1] = 0x94;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0xC2;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x08;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 6;
|
|
dts_init->data_t3.cmd = 0xC6;
|
|
dts_init->data_t3.size = 4;
|
|
dts_init->data_t3.data[0] = 0x35;
|
|
dts_init->data_t3.data[1] = 0x00;
|
|
dts_init->data_t3.data[2] = 0x20;
|
|
dts_init->data_t3.data[3] = 0x04;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0xCC;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x09;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0xD4;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 25;
|
|
dts_init->data_t3.cmd = 0xD5;
|
|
dts_init->data_t3.size = 23;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x01;
|
|
dts_init->data_t3.data[2] = 0x04;
|
|
dts_init->data_t3.data[3] = 0x00;
|
|
dts_init->data_t3.data[4] = 0x01;
|
|
dts_init->data_t3.data[5] = 0x67;
|
|
dts_init->data_t3.data[6] = 0x89;
|
|
dts_init->data_t3.data[7] = 0xAB;
|
|
dts_init->data_t3.data[8] = 0x45;
|
|
dts_init->data_t3.data[9] = 0xCC;
|
|
dts_init->data_t3.data[10] = 0xCC;
|
|
dts_init->data_t3.data[11] = 0xCC;
|
|
dts_init->data_t3.data[12] = 0x00;
|
|
dts_init->data_t3.data[13] = 0x10;
|
|
dts_init->data_t3.data[14] = 0x54;
|
|
dts_init->data_t3.data[15] = 0xBA;
|
|
dts_init->data_t3.data[16] = 0x98;
|
|
dts_init->data_t3.data[17] = 0x76;
|
|
dts_init->data_t3.data[18] = 0xCC;
|
|
dts_init->data_t3.data[19] = 0xCC;
|
|
dts_init->data_t3.data[20] = 0xCC;
|
|
dts_init->data_t3.data[21] = 0x00;
|
|
dts_init->data_t3.data[22] = 0x00;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 25;
|
|
dts_init->data_t3.cmd = 0xD8;
|
|
dts_init->data_t3.size = 23;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x00;
|
|
dts_init->data_t3.data[2] = 0x05;
|
|
dts_init->data_t3.data[3] = 0x00;
|
|
dts_init->data_t3.data[4] = 0x9A;
|
|
dts_init->data_t3.data[5] = 0x00;
|
|
dts_init->data_t3.data[6] = 0x02;
|
|
dts_init->data_t3.data[7] = 0x95;
|
|
dts_init->data_t3.data[8] = 0x01;
|
|
dts_init->data_t3.data[9] = 0x07;
|
|
dts_init->data_t3.data[10] = 0x06;
|
|
dts_init->data_t3.data[11] = 0x00;
|
|
dts_init->data_t3.data[12] = 0x08;
|
|
dts_init->data_t3.data[13] = 0x08;
|
|
dts_init->data_t3.data[14] = 0x00;
|
|
dts_init->data_t3.data[15] = 0x1D;
|
|
dts_init->data_t3.data[16] = 0x08;
|
|
dts_init->data_t3.data[17] = 0x08;
|
|
dts_init->data_t3.data[18] = 0x08;
|
|
dts_init->data_t3.data[19] = 0x00;
|
|
dts_init->data_t3.data[20] = 0x00;
|
|
dts_init->data_t3.data[21] = 0x00;
|
|
dts_init->data_t3.data[22] = 0x77;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 36;
|
|
dts_init->data_t3.cmd = 0xE0;
|
|
dts_init->data_t3.size = 34;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x12;
|
|
dts_init->data_t3.data[2] = 0x19;
|
|
dts_init->data_t3.data[3] = 0x33;
|
|
dts_init->data_t3.data[4] = 0x36;
|
|
dts_init->data_t3.data[5] = 0x3F;
|
|
dts_init->data_t3.data[6] = 0x28;
|
|
dts_init->data_t3.data[7] = 0x47;
|
|
dts_init->data_t3.data[8] = 0x06;
|
|
dts_init->data_t3.data[9] = 0x0C;
|
|
dts_init->data_t3.data[10] = 0x0E;
|
|
dts_init->data_t3.data[11] = 0x12;
|
|
dts_init->data_t3.data[12] = 0x14;
|
|
dts_init->data_t3.data[13] = 0x12;
|
|
dts_init->data_t3.data[14] = 0x14;
|
|
dts_init->data_t3.data[15] = 0x12;
|
|
dts_init->data_t3.data[16] = 0x1A;
|
|
dts_init->data_t3.data[17] = 0x00;
|
|
dts_init->data_t3.data[18] = 0x12;
|
|
dts_init->data_t3.data[19] = 0x19;
|
|
dts_init->data_t3.data[20] = 0x33;
|
|
dts_init->data_t3.data[21] = 0x36;
|
|
dts_init->data_t3.data[22] = 0x3F;
|
|
dts_init->data_t3.data[23] = 0x28;
|
|
dts_init->data_t3.data[24] = 0x47;
|
|
dts_init->data_t3.data[25] = 0x06;
|
|
dts_init->data_t3.data[26] = 0x0C;
|
|
dts_init->data_t3.data[27] = 0x0E;
|
|
dts_init->data_t3.data[28] = 0x12;
|
|
dts_init->data_t3.data[29] = 0x14;
|
|
dts_init->data_t3.data[30] = 0x12;
|
|
dts_init->data_t3.data[31] = 0x14;
|
|
dts_init->data_t3.data[32] = 0x12;
|
|
dts_init->data_t3.data[33] = 0x1A;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 36;
|
|
dts_init->data_t3.cmd = 0xE1;
|
|
dts_init->data_t3.size = 34;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x12;
|
|
dts_init->data_t3.data[2] = 0x19;
|
|
dts_init->data_t3.data[3] = 0x33;
|
|
dts_init->data_t3.data[4] = 0x36;
|
|
dts_init->data_t3.data[5] = 0x3F;
|
|
dts_init->data_t3.data[6] = 0x28;
|
|
dts_init->data_t3.data[7] = 0x47;
|
|
dts_init->data_t3.data[8] = 0x06;
|
|
dts_init->data_t3.data[9] = 0x0C;
|
|
dts_init->data_t3.data[10] = 0x0E;
|
|
dts_init->data_t3.data[11] = 0x12;
|
|
dts_init->data_t3.data[12] = 0x14;
|
|
dts_init->data_t3.data[13] = 0x12;
|
|
dts_init->data_t3.data[14] = 0x14;
|
|
dts_init->data_t3.data[15] = 0x12;
|
|
dts_init->data_t3.data[16] = 0x1A;
|
|
dts_init->data_t3.data[17] = 0x00;
|
|
dts_init->data_t3.data[18] = 0x12;
|
|
dts_init->data_t3.data[19] = 0x19;
|
|
dts_init->data_t3.data[20] = 0x33;
|
|
dts_init->data_t3.data[21] = 0x36;
|
|
dts_init->data_t3.data[22] = 0x3F;
|
|
dts_init->data_t3.data[23] = 0x28;
|
|
dts_init->data_t3.data[24] = 0x47;
|
|
dts_init->data_t3.data[25] = 0x06;
|
|
dts_init->data_t3.data[26] = 0x0C;
|
|
dts_init->data_t3.data[27] = 0x0E;
|
|
dts_init->data_t3.data[28] = 0x12;
|
|
dts_init->data_t3.data[29] = 0x14;
|
|
dts_init->data_t3.data[30] = 0x12;
|
|
dts_init->data_t3.data[31] = 0x14;
|
|
dts_init->data_t3.data[32] = 0x12;
|
|
dts_init->data_t3.data[33] = 0x1A;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 36;
|
|
dts_init->data_t3.cmd = 0xE2;
|
|
dts_init->data_t3.size = 34;
|
|
dts_init->data_t3.data[0] = 0x00;
|
|
dts_init->data_t3.data[1] = 0x12;
|
|
dts_init->data_t3.data[2] = 0x19;
|
|
dts_init->data_t3.data[3] = 0x33;
|
|
dts_init->data_t3.data[4] = 0x36;
|
|
dts_init->data_t3.data[5] = 0x3F;
|
|
dts_init->data_t3.data[6] = 0x28;
|
|
dts_init->data_t3.data[7] = 0x47;
|
|
dts_init->data_t3.data[8] = 0x06;
|
|
dts_init->data_t3.data[9] = 0x0C;
|
|
dts_init->data_t3.data[10] = 0x0E;
|
|
dts_init->data_t3.data[11] = 0x12;
|
|
dts_init->data_t3.data[12] = 0x14;
|
|
dts_init->data_t3.data[13] = 0x12;
|
|
dts_init->data_t3.data[14] = 0x14;
|
|
dts_init->data_t3.data[15] = 0x12;
|
|
dts_init->data_t3.data[16] = 0x1A;
|
|
dts_init->data_t3.data[17] = 0x00;
|
|
dts_init->data_t3.data[18] = 0x12;
|
|
dts_init->data_t3.data[19] = 0x19;
|
|
dts_init->data_t3.data[20] = 0x33;
|
|
dts_init->data_t3.data[21] = 0x36;
|
|
dts_init->data_t3.data[22] = 0x3F;
|
|
dts_init->data_t3.data[23] = 0x28;
|
|
dts_init->data_t3.data[24] = 0x47;
|
|
dts_init->data_t3.data[25] = 0x06;
|
|
dts_init->data_t3.data[26] = 0x0C;
|
|
dts_init->data_t3.data[27] = 0x0E;
|
|
dts_init->data_t3.data[28] = 0x12;
|
|
dts_init->data_t3.data[29] = 0x14;
|
|
dts_init->data_t3.data[30] = 0x12;
|
|
dts_init->data_t3.data[31] = 0x14;
|
|
dts_init->data_t3.data[32] = 0x12;
|
|
dts_init->data_t3.data[33] = 0x1A;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 3;
|
|
dts_init->data_t3.cmd = 0x3A;
|
|
dts_init->data_t3.size = 1;
|
|
dts_init->data_t3.data[0] = 0x77;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
|
|
dts_init->func = LCM_FUNC_CMD;
|
|
dts_init->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_init->size = 2;
|
|
dts_init->data_t3.cmd = 0x29;
|
|
dts_init->data_t3.size = 0;
|
|
dts_init = dts_init + 1;
|
|
_LCM_DTS.init_size = _LCM_DTS.init_size + 1;
|
|
#else
|
|
memset(dts_init, 0, sizeof(struct LCM_DATA) * (DTS->init_size));
|
|
memcpy(dts_init, &(DTS->init[0]),
|
|
sizeof(struct LCM_DATA) * (DTS->init_size));
|
|
_LCM_DTS.init_size = DTS->init_size;
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
dts_init = &(_LCM_DTS.init[0]);
|
|
if (memcmp((unsigned char *)dts_init,
|
|
(unsigned char *)(&(DTS->init[0])), sizeof(struct LCM_DATA))
|
|
!= 0x0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS compare error\n",
|
|
__func__, __LINE__);
|
|
|
|
pr_debug("[LCM][ERROR] dts_init:\n");
|
|
tmp = (unsigned char *)dts_init;
|
|
for (i = 0; i < _LCM_DTS.init_size; i++) {
|
|
pr_debug("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
*(tmp), *(tmp + 1), *(tmp + 2), *(tmp + 3),
|
|
*(tmp + 4), *(tmp + 5), *(tmp + 6),
|
|
*(tmp + 7));
|
|
tmp = tmp + sizeof(struct LCM_DATA);
|
|
}
|
|
|
|
pr_debug("[LCM][ERROR] DTS->init:\n");
|
|
tmp = (unsigned char *)(&(DTS->init[0]));
|
|
for (i = 0; i < DTS->init_size; i++) {
|
|
pr_debug("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
*(tmp), *(tmp + 1), *(tmp + 2), *(tmp + 3),
|
|
*(tmp + 4), *(tmp + 5), *(tmp + 6),
|
|
*(tmp + 7));
|
|
tmp = tmp + sizeof(struct LCM_DATA);
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS compare_id data set */
|
|
_LCM_DTS.compare_id_size = 0;
|
|
memset(dts_compare_id, 0, sizeof(struct LCM_DATA) * COMPARE_ID_SIZE);
|
|
dts_compare_id->func = LCM_FUNC_CMD;
|
|
dts_compare_id->type = LCM_UTIL_WRITE_CMD_V1;
|
|
dts_compare_id->size = 5;
|
|
dts_compare_id->data_t5.size = 1;
|
|
dts_compare_id->data_t5.cmd[0] = 0x00;
|
|
dts_compare_id->data_t5.cmd[1] = 0x37;
|
|
dts_compare_id->data_t5.cmd[2] = 0x01;
|
|
dts_compare_id->data_t5.cmd[3] = 0x00;
|
|
dts_compare_id = dts_compare_id + 1;
|
|
_LCM_DTS.compare_id_size = _LCM_DTS.compare_id_size + 1;
|
|
|
|
dts_compare_id->func = LCM_FUNC_CMD;
|
|
dts_compare_id->type = LCM_UTIL_READ_CMD_V2;
|
|
dts_compare_id->size = 3;
|
|
dts_compare_id->data_t4.cmd = 0xF4;
|
|
dts_compare_id->data_t4.location = 1;
|
|
dts_compare_id->data_t4.data = 0x92;
|
|
dts_compare_id = dts_compare_id + 1;
|
|
_LCM_DTS.compare_id_size = _LCM_DTS.compare_id_size + 1;
|
|
#else
|
|
memset(dts_compare_id, 0,
|
|
sizeof(struct LCM_DATA) * (DTS->compare_id_size));
|
|
memcpy(dts_compare_id, &(DTS->compare_id[0]),
|
|
sizeof(struct LCM_DATA) * (DTS->compare_id_size));
|
|
_LCM_DTS.compare_id_size = DTS->compare_id_size;
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS suspend data set */
|
|
_LCM_DTS.suspend_size = 0;
|
|
memset(dts_suspend, 0, sizeof(struct LCM_DATA) * SUSPEND_SIZE);
|
|
dts_suspend->func = LCM_FUNC_CMD;
|
|
dts_suspend->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_suspend->size = 2;
|
|
dts_suspend->data_t3.cmd = 0x10;
|
|
dts_suspend->data_t3.size = 0;
|
|
dts_suspend = dts_suspend + 1;
|
|
_LCM_DTS.suspend_size = _LCM_DTS.suspend_size + 1;
|
|
|
|
dts_suspend->func = LCM_FUNC_UTIL;
|
|
dts_suspend->type = LCM_UTIL_MDELAY;
|
|
dts_suspend->size = 1;
|
|
dts_suspend->data_t1.data = 120;
|
|
dts_suspend = dts_suspend + 1;
|
|
_LCM_DTS.suspend_size = _LCM_DTS.suspend_size + 1;
|
|
#else
|
|
memset(dts_suspend, 0,
|
|
sizeof(struct LCM_DATA) * (DTS->suspend_size));
|
|
memcpy(dts_suspend, &(DTS->suspend[0]),
|
|
sizeof(struct LCM_DATA) * (DTS->suspend_size));
|
|
_LCM_DTS.suspend_size = DTS->suspend_size;
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS backlight data set */
|
|
_LCM_DTS.backlight_size = 0;
|
|
memset(dts_backlight, 0, sizeof(struct LCM_DATA) * BACKLIGHT_SIZE);
|
|
dts_backlight->func = LCM_FUNC_CMD;
|
|
dts_backlight->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_backlight->size = 3;
|
|
dts_backlight->data_t3.cmd = 0x51;
|
|
dts_backlight->data_t3.size = 1;
|
|
dts_backlight->data_t3.data[0] = 0xFF;
|
|
dts_backlight = dts_backlight + 1;
|
|
_LCM_DTS.backlight_size = _LCM_DTS.backlight_size + 1;
|
|
#else
|
|
memset(dts_backlight, 0,
|
|
sizeof(struct LCM_DATA) * (DTS->backlight_size));
|
|
memcpy(dts_backlight, &(DTS->backlight[0]),
|
|
sizeof(struct LCM_DATA) * (DTS->backlight_size));
|
|
_LCM_DTS.backlight_size = DTS->backlight_size;
|
|
#endif
|
|
|
|
#if defined(LCM_DEBUG)
|
|
/* LCM DTS backlight cmdq data set */
|
|
_LCM_DTS.backlight_cmdq_size = 0;
|
|
memset(dts_backlight_cmdq, 0,
|
|
sizeof(struct LCM_DATA) * BACKLIGHT_CMDQ_SIZE);
|
|
dts_backlight_cmdq->func = LCM_FUNC_CMD;
|
|
dts_backlight_cmdq->type = LCM_UTIL_WRITE_CMD_V2;
|
|
dts_backlight_cmdq->size = 3;
|
|
dts_backlight_cmdq->data_t3.cmd = 0x51;
|
|
dts_backlight_cmdq->data_t3.size = 1;
|
|
dts_backlight_cmdq->data_t3.data[0] = 0xFF;
|
|
dts_backlight_cmdq = dts_backlight_cmdq + 1;
|
|
_LCM_DTS.backlight_cmdq_size = _LCM_DTS.backlight_cmdq_size + 1;
|
|
#else
|
|
memset(dts_backlight_cmdq, 0,
|
|
sizeof(struct LCM_DATA) * (DTS->backlight_cmdq_size));
|
|
memcpy(dts_backlight_cmdq, &(DTS->backlight_cmdq[0]),
|
|
sizeof(struct LCM_DATA) * (DTS->backlight_cmdq_size));
|
|
_LCM_DTS.backlight_cmdq_size = DTS->backlight_cmdq_size;
|
|
#endif
|
|
|
|
_LCM_DTS.parsing = 1;
|
|
}
|
|
|
|
|
|
void lcm_common_set_util_funcs(const struct LCM_UTIL_FUNCS *util)
|
|
{
|
|
memcpy(&lcm_util, util, sizeof(struct LCM_UTIL_FUNCS));
|
|
}
|
|
|
|
|
|
void lcm_common_get_params(struct LCM_PARAMS *params)
|
|
{
|
|
if (params == NULL) {
|
|
pr_debug("[LCM][ERROR] %s/%d: NULL parameter\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing != 0) {
|
|
memset(params, 0, sizeof(struct LCM_PARAMS));
|
|
memcpy(params, &(_LCM_DTS.params), sizeof(struct LCM_PARAMS));
|
|
} else {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
void lcm_common_init(void)
|
|
{
|
|
unsigned int i;
|
|
struct LCM_DATA *init;
|
|
|
|
if (_LCM_DTS.init_size > INIT_SIZE) {
|
|
pr_debug("[LCM][ERROR] %s/%d: Init table overflow %d\n",
|
|
__func__, __LINE__, _LCM_DTS.init_size);
|
|
return;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing == 0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < _LCM_DTS.init_size; i++) {
|
|
init = &(_LCM_DTS.init[i]);
|
|
switch (init->func) {
|
|
case LCM_FUNC_GPIO:
|
|
lcm_gpio_set_data(init->type, &init->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_I2C:
|
|
lcm_i2c_set_data(init->type, &init->data_t2);
|
|
break;
|
|
|
|
case LCM_FUNC_UTIL:
|
|
lcm_util_set_data(&lcm_util,
|
|
init->type, &init->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_CMD:
|
|
switch (init->type) {
|
|
case LCM_UTIL_WRITE_CMD_V1:
|
|
lcm_util_set_write_cmd_v1(&lcm_util,
|
|
&init->data_t5, 1);
|
|
break;
|
|
|
|
case LCM_UTIL_WRITE_CMD_V2:
|
|
lcm_util_set_write_cmd_v2(&lcm_util,
|
|
&init->data_t3, 1);
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, init->type);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, init->func);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void lcm_common_suspend(void)
|
|
{
|
|
unsigned int i;
|
|
struct LCM_DATA *suspend;
|
|
|
|
if (_LCM_DTS.suspend_size > SUSPEND_SIZE) {
|
|
pr_debug("[LCM][ERROR] %s/%d: Suspend table overflow %d\n",
|
|
__func__, __LINE__, _LCM_DTS.suspend_size);
|
|
return;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing == 0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < _LCM_DTS.suspend_size; i++) {
|
|
suspend = &(_LCM_DTS.suspend[i]);
|
|
switch (suspend->func) {
|
|
case LCM_FUNC_GPIO:
|
|
lcm_gpio_set_data(suspend->type, &suspend->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_I2C:
|
|
lcm_i2c_set_data(suspend->type, &suspend->data_t2);
|
|
break;
|
|
|
|
case LCM_FUNC_UTIL:
|
|
lcm_util_set_data(&lcm_util, suspend->type,
|
|
&suspend->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_CMD:
|
|
switch (suspend->type) {
|
|
case LCM_UTIL_WRITE_CMD_V1:
|
|
lcm_util_set_write_cmd_v1(&lcm_util,
|
|
&suspend->data_t5, 1);
|
|
break;
|
|
|
|
case LCM_UTIL_WRITE_CMD_V2:
|
|
lcm_util_set_write_cmd_v2(&lcm_util,
|
|
&suspend->data_t3, 1);
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, suspend->type);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, suspend->func);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void lcm_common_resume(void)
|
|
{
|
|
lcm_common_init();
|
|
}
|
|
|
|
void lcm_common_updatebycmdq(unsigned int x, unsigned int y
|
|
, unsigned int width, unsigned int height, void *cmdq)
|
|
{
|
|
unsigned int x0 = x;
|
|
unsigned int y0 = y;
|
|
unsigned int x1 = x0 + width - 1;
|
|
unsigned int y1 = y0 + height - 1;
|
|
|
|
unsigned char x0_MSB = ((x0 >> 8) & 0xFF);
|
|
unsigned char x0_LSB = (x0 & 0xFF);
|
|
unsigned char x1_MSB = ((x1 >> 8) & 0xFF);
|
|
unsigned char x1_LSB = (x1 & 0xFF);
|
|
unsigned char y0_MSB = ((y0 >> 8) & 0xFF);
|
|
unsigned char y0_LSB = (y0 & 0xFF);
|
|
unsigned char y1_MSB = ((y1 >> 8) & 0xFF);
|
|
unsigned char y1_LSB = (y1 & 0xFF);
|
|
|
|
struct LCM_DATA update;
|
|
struct LCM_DATA_T5 *data_t5 = &(update.data_t5);
|
|
struct LCM_PARAMS *dts_params = &_LCM_DTS.params;
|
|
|
|
if (_LCM_DTS.parsing == 0 || dts_params->dsi.mode != CMD_MODE)
|
|
return;
|
|
|
|
data_t5->size = 3;
|
|
data_t5->cmd[0] = 0x02;
|
|
data_t5->cmd[1] = 0x39;
|
|
data_t5->cmd[2] = 0x05;
|
|
data_t5->cmd[3] = 0x00;
|
|
|
|
data_t5->cmd[4] = 0x2a;
|
|
data_t5->cmd[5] = x0_MSB;
|
|
data_t5->cmd[6] = x0_LSB;
|
|
data_t5->cmd[7] = x1_MSB;
|
|
|
|
data_t5->cmd[8] = x1_LSB;
|
|
data_t5->cmd[9] = 0x00;
|
|
data_t5->cmd[10] = 0x00;
|
|
data_t5->cmd[11] = 0x00;
|
|
lcm_util_set_write_cmd_v11(&lcm_util, data_t5, 1, cmdq);
|
|
|
|
data_t5->size = 3;
|
|
data_t5->cmd[0] = 0x02;
|
|
data_t5->cmd[1] = 0x39;
|
|
data_t5->cmd[2] = 0x05;
|
|
data_t5->cmd[3] = 0x00;
|
|
|
|
data_t5->cmd[4] = 0x2b;
|
|
data_t5->cmd[5] = y0_MSB;
|
|
data_t5->cmd[6] = y0_LSB;
|
|
data_t5->cmd[7] = y1_MSB;
|
|
|
|
data_t5->cmd[8] = y1_LSB;
|
|
data_t5->cmd[9] = 0x00;
|
|
data_t5->cmd[10] = 0x00;
|
|
data_t5->cmd[11] = 0x00;
|
|
lcm_util_set_write_cmd_v11(&lcm_util, data_t5, 1, cmdq);
|
|
}
|
|
|
|
|
|
void lcm_common_update(unsigned int x, unsigned int y, unsigned int width,
|
|
unsigned int height)
|
|
{
|
|
unsigned int x0 = x;
|
|
unsigned int y0 = y;
|
|
unsigned int x1 = x0 + width - 1;
|
|
unsigned int y1 = y0 + height - 1;
|
|
|
|
unsigned char x0_MSB = ((x0 >> 8) & 0xFF);
|
|
unsigned char x0_LSB = (x0 & 0xFF);
|
|
unsigned char x1_MSB = ((x1 >> 8) & 0xFF);
|
|
unsigned char x1_LSB = (x1 & 0xFF);
|
|
unsigned char y0_MSB = ((y0 >> 8) & 0xFF);
|
|
unsigned char y0_LSB = (y0 & 0xFF);
|
|
unsigned char y1_MSB = ((y1 >> 8) & 0xFF);
|
|
unsigned char y1_LSB = (y1 & 0xFF);
|
|
|
|
struct LCM_DATA update;
|
|
struct LCM_DATA_T5 *data_t5 = &(update.data_t5);
|
|
struct LCM_PARAMS *dts_params = &_LCM_DTS.params;
|
|
|
|
if (_LCM_DTS.parsing == 0 || dts_params->dsi.mode != CMD_MODE)
|
|
return;
|
|
|
|
data_t5->size = 3;
|
|
data_t5->cmd[0] = 0x02;
|
|
data_t5->cmd[1] = 0x39;
|
|
data_t5->cmd[2] = 0x05;
|
|
data_t5->cmd[3] = 0x00;
|
|
|
|
data_t5->cmd[4] = 0x2a;
|
|
data_t5->cmd[5] = x0_MSB;
|
|
data_t5->cmd[6] = x0_LSB;
|
|
data_t5->cmd[7] = x1_MSB;
|
|
|
|
data_t5->cmd[8] = x1_LSB;
|
|
data_t5->cmd[9] = 0x00;
|
|
data_t5->cmd[10] = 0x00;
|
|
data_t5->cmd[11] = 0x00;
|
|
lcm_util_set_write_cmd_v1(&lcm_util, data_t5, 1);
|
|
|
|
data_t5->size = 3;
|
|
data_t5->cmd[0] = 0x02;
|
|
data_t5->cmd[1] = 0x39;
|
|
data_t5->cmd[2] = 0x05;
|
|
data_t5->cmd[3] = 0x00;
|
|
|
|
data_t5->cmd[4] = 0x2b;
|
|
data_t5->cmd[5] = y0_MSB;
|
|
data_t5->cmd[6] = y0_LSB;
|
|
data_t5->cmd[7] = y1_MSB;
|
|
|
|
data_t5->cmd[8] = y1_LSB;
|
|
data_t5->cmd[9] = 0x00;
|
|
data_t5->cmd[10] = 0x00;
|
|
data_t5->cmd[11] = 0x00;
|
|
lcm_util_set_write_cmd_v1(&lcm_util, data_t5, 1);
|
|
|
|
data_t5->size = 1;
|
|
data_t5->cmd[0] = 0x09;
|
|
data_t5->cmd[1] = 0x39;
|
|
data_t5->cmd[2] = 0x2c;
|
|
data_t5->cmd[3] = 0x00;
|
|
lcm_util_set_write_cmd_v1(&lcm_util, data_t5, 0);
|
|
}
|
|
|
|
|
|
void lcm_common_setbacklight(unsigned int level)
|
|
{
|
|
unsigned int default_level = 145;
|
|
unsigned int mapped_level = 0;
|
|
unsigned int i;
|
|
struct LCM_DATA *backlight;
|
|
struct LCM_DATA_T3 *backlight_data_t3;
|
|
|
|
/* for LGE backlight IC mapping table */
|
|
if (level > 255)
|
|
level = 255;
|
|
|
|
if (level > 0)
|
|
mapped_level = default_level +
|
|
(level) * (255 - default_level) / (255);
|
|
else
|
|
mapped_level = 0;
|
|
|
|
if (_LCM_DTS.backlight_size > BACKLIGHT_SIZE) {
|
|
pr_debug("[LCM][ERROR] %s/%d: Backlight table overflow %d\n",
|
|
__func__, __LINE__, _LCM_DTS.backlight_size);
|
|
return;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing == 0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < _LCM_DTS.backlight_size; i++) {
|
|
if (i == (_LCM_DTS.backlight_size - 1)) {
|
|
backlight = &(_LCM_DTS.backlight[i]);
|
|
backlight_data_t3 = &(backlight->data_t3);
|
|
backlight_data_t3->data[i] = mapped_level;
|
|
} else
|
|
backlight = &(_LCM_DTS.backlight[i]);
|
|
|
|
switch (backlight->func) {
|
|
case LCM_FUNC_GPIO:
|
|
lcm_gpio_set_data(backlight->type, &backlight->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_I2C:
|
|
lcm_i2c_set_data(backlight->type, &backlight->data_t2);
|
|
break;
|
|
|
|
case LCM_FUNC_UTIL:
|
|
lcm_util_set_data(&lcm_util, backlight->type,
|
|
&backlight->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_CMD:
|
|
switch (backlight->type) {
|
|
case LCM_UTIL_WRITE_CMD_V1:
|
|
lcm_util_set_write_cmd_v1(&lcm_util,
|
|
&backlight->data_t5, 1);
|
|
break;
|
|
|
|
case LCM_UTIL_WRITE_CMD_V2:
|
|
lcm_util_set_write_cmd_v2(&lcm_util,
|
|
&backlight->data_t3, 1);
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__,
|
|
(unsigned int)backlight->type);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__,
|
|
(unsigned int)backlight->func);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
unsigned int lcm_common_compare_id(void)
|
|
{
|
|
/* default: skip compare id */
|
|
unsigned int compare = 1;
|
|
unsigned int i;
|
|
struct LCM_DATA *compare_id;
|
|
|
|
if (_LCM_DTS.compare_id_size > COMPARE_ID_SIZE) {
|
|
pr_debug("[LCM][ERROR] %s/%d: Compare table overflow %d\n",
|
|
__func__, __LINE__, _LCM_DTS.compare_id_size);
|
|
return 0;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing == 0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < _LCM_DTS.compare_id_size; i++) {
|
|
compare_id = &(_LCM_DTS.compare_id[i]);
|
|
switch (compare_id->func) {
|
|
case LCM_FUNC_GPIO:
|
|
lcm_gpio_set_data(compare_id->type,
|
|
&compare_id->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_I2C:
|
|
lcm_i2c_set_data(compare_id->type,
|
|
&compare_id->data_t2);
|
|
break;
|
|
|
|
case LCM_FUNC_UTIL:
|
|
lcm_util_set_data(&lcm_util, compare_id->type,
|
|
&compare_id->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_CMD:
|
|
switch (compare_id->type) {
|
|
case LCM_UTIL_WRITE_CMD_V1:
|
|
lcm_util_set_write_cmd_v1(&lcm_util,
|
|
&compare_id->data_t5, 1);
|
|
break;
|
|
|
|
case LCM_UTIL_WRITE_CMD_V2:
|
|
lcm_util_set_write_cmd_v2(&lcm_util,
|
|
&compare_id->data_t3, 1);
|
|
break;
|
|
|
|
case LCM_UTIL_READ_CMD_V2:
|
|
lcm_util_set_read_cmd_v2(&lcm_util,
|
|
&compare_id->data_t4, &compare);
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, compare_id->type);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__, compare_id->func);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return compare;
|
|
}
|
|
|
|
|
|
unsigned int lcm_common_ata_check(unsigned char *buffer)
|
|
{
|
|
#ifndef BUILD_LK
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
|
|
void lcm_common_setbacklight_cmdq(void *handle, unsigned int level)
|
|
{
|
|
unsigned int i;
|
|
struct LCM_DATA *backlight_cmdq;
|
|
struct LCM_DATA_T3 *backlight_cmdq_data_t3;
|
|
|
|
if (_LCM_DTS.backlight_cmdq_size > BACKLIGHT_CMDQ_SIZE) {
|
|
pr_debug("[LCM][ERROR] %s/%d: Backlight cmdq table overflow %d\n",
|
|
__func__, __LINE__, _LCM_DTS.backlight_cmdq_size);
|
|
return;
|
|
}
|
|
|
|
if (_LCM_DTS.parsing == 0) {
|
|
pr_debug("[LCM][ERROR] %s/%d: DTS is not parsed\n",
|
|
__func__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < _LCM_DTS.backlight_cmdq_size; i++) {
|
|
if (i == (_LCM_DTS.backlight_cmdq_size - 1)) {
|
|
backlight_cmdq = &(_LCM_DTS.backlight_cmdq[i]);
|
|
backlight_cmdq_data_t3 = &(backlight_cmdq->data_t3);
|
|
backlight_cmdq_data_t3->data[i] = level;
|
|
} else
|
|
backlight_cmdq = &(_LCM_DTS.backlight_cmdq[i]);
|
|
|
|
switch (backlight_cmdq->func) {
|
|
case LCM_FUNC_GPIO:
|
|
lcm_gpio_set_data(backlight_cmdq->type,
|
|
&backlight_cmdq->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_I2C:
|
|
lcm_i2c_set_data(backlight_cmdq->type,
|
|
&backlight_cmdq->data_t2);
|
|
break;
|
|
|
|
case LCM_FUNC_UTIL:
|
|
lcm_util_set_data(&lcm_util, backlight_cmdq->type,
|
|
&backlight_cmdq->data_t1);
|
|
break;
|
|
|
|
case LCM_FUNC_CMD:
|
|
switch (backlight_cmdq->type) {
|
|
case LCM_UTIL_WRITE_CMD_V23:
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&backlight_cmdq->data_t3, 1);
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__,
|
|
(unsigned int)backlight_cmdq->type);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
pr_debug("[LCM][ERROR] %s/%d: %d\n",
|
|
__func__, __LINE__,
|
|
(unsigned int)backlight_cmdq->func);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined(R63419_WQHD_TRULY_PHANTOM_2K_CMD_OK)
|
|
void lcm_common_setroi(int x, int y, int width, int height, void *handle)
|
|
{
|
|
lcm_common_updatebycmdq(2*x, 2*y, 2*width, 2*height, handle);
|
|
}
|
|
|
|
|
|
void lcm_common_scale(void *handle, enum LCM_SCALE_TYPE scale)
|
|
{
|
|
struct LCM_DATA_T3 cmd;
|
|
|
|
if (scale == LCM_Hx2_Vx2)
|
|
lcm_common_updatebycmdq(0, 0, 1440, 2560, handle);
|
|
else if (scale == LCM_Hx1_Vx1)
|
|
lcm_common_updatebycmdq(0, 0, 720, 1280, handle);
|
|
|
|
if (scale == LCM_Hx2_Vx2) {
|
|
|
|
cmd.cmd = 0xB0;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x00;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0xB6;
|
|
cmd.size = 2;
|
|
cmd.data[0] = 0x39;
|
|
cmd.data[1] = 0x93;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0xC5;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x03;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
cmd.cmd = 0xB0;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x03;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
} else if (scale == LCM_Hx1_Vx1) {
|
|
|
|
cmd.cmd = 0x10;
|
|
cmd.size = 0;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0x11;
|
|
cmd.size = 0;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0xB0;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x00;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0xB6;
|
|
cmd.size = 2;
|
|
cmd.data[0] = 0x3A;
|
|
cmd.data[1] = 0xD3;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
|
|
cmd.cmd = 0xC5;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x00;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
cmd.cmd = 0xB0;
|
|
cmd.size = 1;
|
|
cmd.data[0] = 0x03;
|
|
lcm_util_set_write_cmd_v23(&lcm_util, handle,
|
|
&cmd, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define PARTIAL_WIDTH_ALIGN_LINE
|
|
static inline int align_to(int value, int n, int lower_align)
|
|
{
|
|
int x = value;
|
|
|
|
value = (((x) + ((n) - 1)) & ~((n) - 1));
|
|
|
|
if (lower_align) {
|
|
|
|
if (value > x)
|
|
value -= n;
|
|
} else {
|
|
#ifndef PARTIAL_WIDTH_ALIGN_LINE
|
|
if (value <= x)
|
|
value += n;
|
|
#else
|
|
if (value < x)
|
|
value += n;
|
|
#endif
|
|
}
|
|
return value;
|
|
}
|
|
|
|
static void r63419_lcm_validate_roi(int *x, int *y, int *width, int *height)
|
|
{
|
|
int x1 = *x;
|
|
int x2 = *width + x1 - 1;
|
|
int y1 = *y;
|
|
int y2 = *height + y1 - 1;
|
|
int w = *width;
|
|
int h = *height;
|
|
int lcm_w = _LCM_DTS.params.dsi.horizontal_active_pixel;
|
|
|
|
/* comfine SP & EP value */
|
|
#ifndef PARTIAL_WIDTH_ALIGN_LINE
|
|
x1 = 0;
|
|
y1 = align_to(y1, 2, 1);
|
|
y2 = align_to(y2, 2, 0) - 1;
|
|
w = lcm_w;
|
|
#else
|
|
int ya_align = align_to(y2, 2, 0);
|
|
int lcm_half = lcm_w >> 1;
|
|
int roi_half = 0;
|
|
|
|
if (w == 0 || w == lcm_w) {
|
|
w = lcm_w;
|
|
} else {
|
|
y1 = align_to(y1, 2, 1);
|
|
|
|
if (ya_align == y2)
|
|
ya_align += 1;
|
|
else
|
|
ya_align -= 1;
|
|
y2 = ya_align;
|
|
|
|
if (lcm_half >= x2) {
|
|
roi_half = lcm_half - x1;
|
|
} else if (x1 >= lcm_half) {
|
|
roi_half = x2 - lcm_half;
|
|
} else {
|
|
int left = lcm_half - x1;
|
|
int right = x2 - lcm_half;
|
|
|
|
roi_half = left > right ? left : right;
|
|
}
|
|
if (roi_half < 16)
|
|
roi_half = 16;
|
|
|
|
roi_half = align_to(roi_half, 16, 0);
|
|
roi_half += 16;
|
|
if (roi_half > lcm_half)
|
|
roi_half = lcm_half;
|
|
|
|
x1 = lcm_half - roi_half;
|
|
|
|
w = roi_half << 1;
|
|
}
|
|
#endif
|
|
|
|
if (h == 0) {
|
|
h = 6;
|
|
} else {
|
|
if (y2 - y1 < 6) {
|
|
if (y1 > 6)
|
|
y1 -= 6;
|
|
else
|
|
y2 += 6;
|
|
}
|
|
h = y2 - y1 + 1;
|
|
}
|
|
/* pr_debug("roi(%d,%d,%d,%d) to (%d,%d,%d,%d)\n",*/
|
|
/* *x, *y, *width, *height, x1, y1, w, h); */
|
|
*x = x1;
|
|
*y = y1;
|
|
*width = w;
|
|
*height = h;
|
|
}
|
|
#endif
|
|
|
|
struct LCM_DRIVER lcm_common_drv = {
|
|
.name = NULL,
|
|
.set_util_funcs = lcm_common_set_util_funcs,
|
|
.get_params = lcm_common_get_params,
|
|
.init = lcm_common_init,
|
|
.suspend = lcm_common_suspend,
|
|
.resume = lcm_common_resume,
|
|
.compare_id = lcm_common_compare_id,
|
|
.set_backlight = lcm_common_setbacklight,
|
|
.update = lcm_common_update,
|
|
.ata_check = lcm_common_ata_check,
|
|
.set_backlight_cmdq = lcm_common_setbacklight_cmdq,
|
|
.parse_dts = lcm_common_parse_dts,
|
|
#if defined(R63419_WQHD_TRULY_PHANTOM_2K_CMD_OK)
|
|
.validate_roi = r63419_lcm_validate_roi,
|
|
.scale = lcm_common_scale,
|
|
.setroi = lcm_common_setroi,
|
|
#endif
|
|
};
|
|
#endif
|