kernel_samsung_a34x-permissive/drivers/misc/mediatek/lcm/lcm_common.c
2024-04-28 15:51:13 +02:00

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