Files

3250 lines
146 KiB
C++
Raw Permalink Normal View History

2026-08-13 11:28:40 +08:00
/*
* Copyright (c) 2014 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in the
* file 'LICENSE' which is part of this source code package.
*
* Description: c++ file
*/
#define LOG_NDEBUG 0
#define LOG_MODULE_TAG "TV"
#define LOG_CLASS_TAG "CTvPanel"
#include <CTvLog.h>
#include <stdlib.h>
#include <string.h>
#include <tvutils.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include "CTvPanel.h"
#include <sys/ioctl.h>
#include <cstdio>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
#include <cstdint>
#include "tvutils.h"
static struct tcon_pgamma_config_s tcon_pgamma_config;
static struct tcon_demura_config_s *tcon_demura_config;
int lcd_debug_print_flag = 0;
static struct tcon_demura_config_s tcon_demura_config_CHOT = {
.setting_offset = 0x0,
.setting_len = 0x200,
.data_offset = 0x200,
.data_len = 0x9019e,
.data_crc_offset = 0x99,
.data_crc_len = 2,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_CHOT,
.demura_setting = demura_setting_CHOT,
.demura_data_trans = demura_data_trans_CHOT,
};
static struct tcon_demura_config_s tcon_demura_config_CSOT = {
.setting_offset = 0x0,
.setting_len = 0x110,
.data_offset = 0x110,
.data_len = 0x9b9d0,
.data_crc_offset = 0x3c,
.data_crc_len = 2,
.crc_endian_type = CC_ENDIAN_TYPE_LITTLE,
.panel_crc_check = panel_crc_check_CSOT,
.demura_setting = demura_setting_CSOT,
.demura_data_trans = demura_data_trans_CSOT,
};
static struct tcon_demura_config_s tcon_demura_config_HKC = {
.setting_offset = 0x1000,
.setting_len = 0x42,
.data_offset = 0x1042,
.data_len = 0x8f360,
.data_crc_offset = 0x1040,
.data_crc_len = 2,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_HKC,
.demura_setting = demura_setting_HKC,
.demura_data_trans = demura_data_trans_HKC,
};
static struct tcon_demura_config_s tcon_demura_config_AUO = {
.setting_offset = 0x10000,
.setting_len = 0x70,
.data_offset = 0x20002,
.data_len = 0x17ee60,
.data_crc_offset = 0x20000,
.data_crc_len = 2,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_AUO,
.demura_setting = demura_setting_AUO,
.demura_data_trans = demura_data_trans_AUO,
};
static struct tcon_demura_config_s tcon_demura_config_INX = {
.setting_offset = 0,
.setting_len = 0x80,
.data_offset = 0,
.data_len = 0,
.data_crc_offset = 0x2a,
.data_crc_len = 1,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_INX,
.demura_setting = demura_setting_INX,
.demura_data_trans = demura_data_trans_INX,
};
static struct tcon_demura_config_s tcon_demura_config_BOE = {
.setting_offset = 0,
.setting_len = 0x70,
.data_offset = 0x70,
.data_len = 0x8ee90,
.data_crc_offset = 0x3c,
.data_crc_len = 4,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_BOE,
.demura_setting = demura_setting_BOE,
.demura_data_trans = demura_data_trans_BOE,
};
static struct tcon_demura_config_s tcon_demura_config_LG = {
.setting_offset = 0x685e4,
.setting_len = 0xc,
.data_offset = 0x60000,
.data_len = 0x85f1,
.data_crc_offset = 0x685f0,
.data_crc_len = 0x1,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_LG,
.demura_setting = demura_setting_LG,
.demura_data_trans = demura_data_trans_LG,
};
static struct tcon_demura_config_s tcon_demura_config_SDP = {
.setting_offset = 0x63000,
.setting_len = 0x220,
.data_offset = 0x63220,
.data_len = 0x60114,
.data_crc_offset = 0x6300c,
.data_crc_len = 0x4,
.crc_endian_type = CC_ENDIAN_TYPE_BIG,
.panel_crc_check = panel_crc_check_SDP,
.demura_setting = demura_setting_SDP,
.demura_data_trans = demura_data_trans_SDP,
};
CTvPanel *CTvPanel::mInstance;
CTvPanel *CTvPanel::getInstance()
{
if (NULL == mInstance) mInstance = new CTvPanel();
return mInstance;
}
CTvPanel::CTvPanel()
{
}
CTvPanel::~CTvPanel()
{
}
int CTvPanel::PANEL_File_Read(const char *filename, long offset, unsigned char *buffer, unsigned int length) {
FILE *file = fopen(filename, "rb");
if (NULL == file) {
LOGE("%s, file %s open failed.\n", __FUNCTION__, filename);
return -1;
}
// 移动到文件的指定位置
if (fseek(file, offset, SEEK_SET) != 0) {
LOGE("%s, failed to seek to the offset %ld in file %s.\n", __FUNCTION__, offset, filename);
fclose(file);
return -1;
}
// 读取数据,并检查返回值
size_t bytesRead = fread(buffer, sizeof(char), length, file);
if (bytesRead < length || ferror(file)) {
LOGE("%s, failed to read %u bytes from file %s. Bytes read: %zu.\n", __FUNCTION__, length, filename, bytesRead);
fclose(file);
return -1;
}
// 关闭文件
fclose(file);
return 0;
}
int CTvPanel::PANEL_File_Write(const char *filename, long offset,unsigned char *buffer, unsigned int length) {
FILE *file = fopen(filename, "w+b");
if (file == NULL) {
LOGE("%s, Error opening file %s\n", __FUNCTION__, filename);
return -1;
}
if (fseek(file, offset, SEEK_SET) != 0) {
LOGE("Error seeking in file\n");
fclose(file);
return -1;
}
if (fwrite(buffer, sizeof(char), length, file) != length) {
LOGE("Error writing to file\n");
fclose(file);
return -1;
}
fclose(file);
return 0;
}
int CTvPanel::PANEL_SPI_Read(unsigned int offset, unsigned int ulength, unsigned char *pubuf) {
//return tvSpiRead(offset, ulength, pubuf);
int err = -1;
int fd = open(SPI_DEVICE, O_RDWR);
if (fd < 0) {
LOGE("%s:spi device[%s] is not!\n", __FUNCTION__, SPI_DEVICE);
return -1;
}
if (NULL == pubuf) {
LOGE("%s:pbuf is NULL!\n", __FUNCTION__);
close(fd);
return -1;
}
if (offset != (unsigned int)lseek (fd, offset, SEEK_SET)) {
LOGE("%s lseek error(%s)!\n", __FUNCTION__, strerror(errno));
close(fd);
return -1;
}
err = read (fd, pubuf, ulength);
if (err < 0) {
LOGE("%s read error(%s)!\n", __FUNCTION__, strerror(errno));
close(fd);
return -1;
}
LOGD("%s:read success!\n", __FUNCTION__);
close(fd);
return err;
}
/*
* get the value of the I2C register in batches
*/
int I2C_Read(unsigned int i2c_no, unsigned char dev_addr, unsigned char* slave_addr_buf,
unsigned int slave_addr_count, unsigned char *data_buf, unsigned int data_len) {
LOGD("%s, enter...", __FUNCTION__);
int aml_ret = -1;
int i2c_file = -1;
unsigned char msg_buf[52];
unsigned char outbuf[52];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
unsigned int i, size;
char slave_addr[64] = { '\0' };
if ((i2c_no > 4) || (slave_addr_buf == NULL) || (slave_addr_count <= 0) || (data_buf == NULL) || (data_len <= 0)) {
LOGE("%s, illegal parameter\n", __FUNCTION__);
return -1;
}
size = 0;
memset(slave_addr, 0, sizeof(slave_addr));
for (i = 0; i < slave_addr_count; i++) {
size += sprintf(slave_addr + size, "%02x", slave_addr_buf[i]);
}
LOGE("%s, i2c_num = %d, dev_addr = %#x, reg_addr = %s, reg_addr_count = %d, data_len = %d,"
,__FUNCTION__, i2c_no, dev_addr,slave_addr, slave_addr_count, data_len);
if (i2c_no == 0) {
i2c_file = open(DEV_I2C_0_PATH, O_RDWR);
} else if (i2c_no == 1) {
i2c_file = open(DEV_I2C_1_PATH, O_RDWR);
} else if (i2c_no == 2) {
i2c_file = open(DEV_I2C_2_PATH, O_RDWR);
} else if (i2c_no == 3) {
i2c_file = open(DEV_I2C_3_PATH, O_RDWR);
} else {
i2c_file = open(DEV_I2C_4_PATH, O_RDWR);
}
if (i2c_file < 0) {
LOGE("%s, unable to open i2c control file\n", __FUNCTION__);
return -1;
}
memset((void *)outbuf, 0, 52);
memset((void *)msg_buf, 0, 52);
/*
* In order to read a register, we first do a "dummy write" by writing
* 0 bytes to the register we want to read from. This is similar to
* the packet in aml_set_i2c_register, except it's 1 byte rather than 2.
*/
memcpy((void *)&outbuf[0], slave_addr_buf, slave_addr_count);
messages[0].addr = dev_addr;
messages[0].flags = 0; //write
messages[0].len = slave_addr_count;
messages[0].buf = outbuf;
/* The data will get returned in this structure */
messages[1].addr = dev_addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/; //read
messages[1].len = data_len;
messages[1].buf = data_buf;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
aml_ret = ioctl(i2c_file, I2C_RDWR, &packets);
//usleep(10 * 1000);
if (i2c_file >= 0) {
close(i2c_file);
i2c_file = -1;
}
if (aml_ret < 0) {
LOGE("%s, unable to send data", __FUNCTION__);
return -1;
} else {
return 0;
}
}
#define EPPROM_I2C_NUM 2
#define EEPPROM_DEVICE_ADDRESS 0x50
int CTvPanel::PANEL_I2C_Read(unsigned int offset, unsigned int ulength, unsigned char *pubuf) {
unsigned char slave_addr_buf[2] = {0x0};
unsigned int i = 0;
slave_addr_buf[0]=offset>>8;
slave_addr_buf[1]=offset&0xff;
if (0 > I2C_Read(EPPROM_I2C_NUM, EEPPROM_DEVICE_ADDRESS, slave_addr_buf, 2, pubuf, ulength)) {
LOGE("%s, Read pgamma lut in flash failed.", __FUNCTION__);
return -1;
}
while (i < ulength) {
LOGD("%s, Read pgamma lut 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.", __FUNCTION__,i, pubuf[i], pubuf[i+1], pubuf[i+2], pubuf[i+3], pubuf[i+4], pubuf[i+5], pubuf[i+6], pubuf[i+7]);
i += 8;
}
return 0;
}
int CTvPanel::PANEL_GrepStr(const char *partition_name, const char *str) {
FILE *fp;
int file_ofset;
char *startAddress;
char command[128] = {0};
char output[128] = {0};
sprintf(command, "grep -abo '%s' %s",str, partition_name);
fp = popen(command, "r");
if (fp == NULL) {
LOGE("Failed to execute grep command.\n");
return -1;
}
// Read the first line of the output
if (fgets(output, sizeof(output), fp) == NULL) {
LOGE("Failed to read output from grep command.\n");
pclose(fp);
return -1;
}
startAddress = strtok(output, ":"); // Extract the start address from the output
if (startAddress != NULL) {
file_ofset = atoi(startAddress);
//LOGD("Start address: %s 0x%x \n", startAddress, file_ofset);
} else {
file_ofset = 0;
LOGE("%s, %s not found in %s\n", __FUNCTION__, str, partition_name);
}
pclose(fp);
return file_ofset;
}
int CTvPanel::PANEL_File_Read_bin(const char *filename, unsigned char *buffer) {
size_t bytesRead = 0;
long fileSize = 0;
FILE *file = fopen(filename, "rb");
if (NULL == file) {
LOGE("%s, file %s open failed.\n", __FUNCTION__, filename);
return -1;
}
if (fseek(file, 0, SEEK_END) != 0) {
LOGE("%s, failed to seek file to position .\n", __FUNCTION__);
fclose(file);
return -1;
}
fileSize = ftell(file);
if (fileSize < 0 || fileSize > 0xff) {
LOGE("%s, File length %d error , maximum length is 0xff.\n", __FUNCTION__, fileSize);
fclose(file);
return -1;
}
if (fseek(file, 0, SEEK_SET) != 0) {
LOGE("%s, failed to seek file to position .\n", __FUNCTION__);
fclose(file);
return -1;
}
bytesRead = fread(buffer, sizeof(char), fileSize, file);
if (bytesRead != (unsigned int)fileSize) {
LOGE("%s, failed to read %u bytes from file. Only read 0x%x bytes.\n", __FUNCTION__, fileSize, bytesRead);
fclose(file);
return 0;
}
fclose(file);
return (int)fileSize;
}
unsigned int CTvPanel::PANEL_Get_flash_ByteToInt(unsigned int flash_addr, unsigned int len, unsigned int endian_type) {
unsigned char temp_buf[4] = {0};
unsigned int temp_num = 0, i = 0, j =0;
if (len > 4 || len < 1)
return 0;
// coverity[tainted_data_argument]
if (-1 == PANEL_SPI_Read(flash_addr, len, temp_buf)) {
LOGE("%s, Read demura lut in flash failed.\n", __FUNCTION__);
return 0;
}
if (endian_type == CC_ENDIAN_TYPE_LITTLE) {
for (i = 0; i < len; i++) {
temp_num |= ((unsigned int)(temp_buf[i] & 0xff)) << (8 * i); // 按照小端字节顺序组合flash 的值
}
} else {
for (i = 0, j = len - 1; i < len ; i++, j--) {
temp_num |= ((unsigned int)(temp_buf[j] & 0xff)) << (8 * i); // 按照大端字节顺序组合flash 的值
}
}
return temp_num;
}
int CTvPanel::PANEL_Demura_File_crc_check(unsigned char *buf, unsigned int len) {
unsigned int buf_crc = 0, file_crc = 0;
unsigned int data_size = 0;
data_size = (buf[8] & 0xff) | ((buf[9] & 0xff) << 8) | ((buf[10] & 0xff) << 16) | ((buf[11] & 0xff) << 24);
if (data_size > len || data_size == 0) {
LOGE("%s: data_size 0x%x invalid, bin_size 0x%x\n", __func__, data_size, (unsigned int)len);
return -1;
}
buf_crc = PANEL_DemuraFormatCrc(0, (buf + 4), (data_size - 4));
file_crc = (buf[0] & 0xff) | ((buf[1] & 0xff) << 8) | ((buf[2] & 0xff) << 16) | ((buf[3] & 0xff) << 24);
if (buf_crc != file_crc) {
LOGE("%s, Crc check fialed, buf_crc 0x%x, file_crc is 0x%x. \n", __FUNCTION__, buf_crc, file_crc);
return -1;
}
return 0;
}
const char *CTvPanel::PANEL_READ_Env(const char *name) {
return GetUenv(name);
}
int CTvPanel::AM_PANEL_Init()
{
LOGD("%s, AM_PANEL_Init entering\n",__FUNCTION__);
const char *temp_buf = PANEL_READ_Env("lcd_debug_print");
if (temp_buf && *temp_buf) {
char *endptr = NULL;
lcd_debug_print_flag = (unsigned int)strtoul(temp_buf, &endptr, 0);
if (endptr == temp_buf) {
LOGE("Invalid lcd_debug_print value: %s\n", temp_buf);
lcd_debug_print_flag = 0;
}
} else {
lcd_debug_print_flag = 0;
}
LOGD("%s, lcd_debug_print_flag 0x%x \n",__FUNCTION__, lcd_debug_print_flag);
PANEL_TconlessTypeChose();
LOGD("%s, InitTconlessBin entering\n",__FUNCTION__);
InitTconlessBin();
return 0;
}
int CTvPanel::PANEL_TconlessTypeChose() {
unsigned int demura_offset = 0, demura_size = 0, demura_param_0 = 0, demura_param_1 = 0, demura_param_2 = 0, demura_param_3 = 0, demura_param_4 = 0, demura_param_5 = 0;
unsigned int pgamma_offset = 0, pgamma_size = 0, pgamma_param_0 = 0, pgamma_param_1 = 0, pgamma_param_2 = 0, pgamma_param_3 = 0, pgamma_param_4 = 0, pgamma_param_5 = 0;
unsigned int auto_acc_size = 0, auto_acc_param_1, auto_acc_param_0, DLG_flag;
unsigned char key_data[1024] = {0};
int pgmma_type = 0;
if (0 > readUKeyData(CS_PANEL_INI_SPI_INFO_NAME, key_data, 1024)) {
LOGE("%s, ReadUKeyData failed!\n", __FUNCTION__);
return -1;
}
demura_offset = (int) ((key_data[19]<<24)+(key_data[18]<<16)+(key_data[17]<<8)+key_data[16]);
demura_size = (int) ((key_data[23]<<24)+(key_data[22]<<16)+(key_data[21]<<8)+key_data[20]);
demura_param_0 = (int) ((key_data[27]<<24)+(key_data[26]<<16)+(key_data[25]<<8)+key_data[24]);
demura_param_1 = (int) ((key_data[31]<<24)+(key_data[30]<<16)+(key_data[29]<<8)+key_data[28]);
demura_param_2 = (int) ((key_data[35]<<24)+(key_data[34]<<16)+(key_data[33]<<8)+key_data[32]);
demura_param_3 = (int) ((key_data[39]<<24)+(key_data[38]<<16)+(key_data[37]<<8)+key_data[36]);
demura_param_4 = (int) ((key_data[43]<<24)+(key_data[42]<<16)+(key_data[41]<<8)+key_data[40]);
demura_param_5 = (int) ((key_data[47]<<24)+(key_data[46]<<16)+(key_data[45]<<8)+key_data[44]);
pgamma_offset = (int) ((key_data[51]<<24)+(key_data[50]<<16)+(key_data[49]<<8)+key_data[48]);
pgamma_size = (int) ((key_data[55]<<24)+(key_data[54]<<16)+(key_data[53]<<8)+key_data[52]);
pgamma_param_0 = (int) ((key_data[59]<<24)+(key_data[58]<<16)+(key_data[57]<<8)+key_data[56]);
pgamma_param_1 = (int) ((key_data[63]<<24)+(key_data[62]<<16)+(key_data[61]<<8)+key_data[60]);
pgamma_param_2 = (int) ((key_data[67]<<24)+(key_data[66]<<16)+(key_data[65]<<8)+key_data[64]);
pgamma_param_3 = (int) ((key_data[71]<<24)+(key_data[70]<<16)+(key_data[69]<<8)+key_data[68]);
pgamma_param_4 = (int) ((key_data[75]<<24)+(key_data[74]<<16)+(key_data[73]<<8)+key_data[72]);
pgamma_param_5 = (int) ((key_data[79]<<24)+(key_data[78]<<16)+(key_data[77]<<8)+key_data[76]);
auto_acc_size = (int) ((key_data[87]<<24)+(key_data[86]<<16)+(key_data[85]<<8)+key_data[84]);
auto_acc_param_0 = (int) ((key_data[91]<<24)+(key_data[90]<<16)+(key_data[89]<<8)+key_data[88]);
auto_acc_param_1 = (int) ((key_data[95]<<24)+(key_data[94]<<16)+(key_data[93]<<8)+key_data[92]);
DLG_flag = (int) ((key_data[99]<<24)+(key_data[98]<<16)+(key_data[97]<<8)+key_data[96]);
LOGD("%s, Demura offset = 0x%x, size = 0x%x, attr_0 = 0x%x, attr_1 = 0x%x, attr_2 = 0x%x, attr_3 = 0x%x, attr_4 = 0x%x, attr_5 = 0x%x.\n", __FUNCTION__,
demura_offset, demura_size, demura_param_0, demura_param_1, demura_param_2, demura_param_3, demura_param_4, demura_param_5);
LOGD("%s, Auto pgamma offset = 0x%x size = 0x%x, attr_0 = 0x%x, attr_1 = 0x%x attr_2 = 0x%x, attr_3 = 0x%x, attr_4 = 0x%x, attr_5 = 0x%x.\n", __FUNCTION__,
pgamma_offset, pgamma_size, pgamma_param_0, pgamma_param_1, pgamma_param_2, pgamma_param_3, pgamma_param_4, pgamma_param_5);
LOGD("%s, Auto Acc size = 0x%x, attr_0 = 0x%x, attr_1 = 0x%x, DLG_flag = 0x%x.\n", __FUNCTION__,
auto_acc_size, auto_acc_param_0, auto_acc_param_1, DLG_flag);
/*
demura_lut_offset=0 #demura data lut offset
demura_lut_size=0 #demura data lut len
block0_param_0=0 #[7:0]demura Type [8]mix_demura
block0_param_1=0 #[7:0]demura setting bypass
block0_param_2=0 #demura setting offset
block0_param_3=0 #demura setting len
block0_param_4=0 #demura data_crc offset
block0_param_5=0 #demura data_crc len
*/
if (demura_size != 0) {
tcon_demura_config = NULL;
switch (demura_param_0 & 0xff) {
case 0:
break;
case TCON_DEMURA_CHOT:
LOGD("%s, Do demura type %d tcon_demura_CHOT\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_CHOT;
break;
case TCON_DEMURA_CSOT:
LOGD("%s, Do demura type %d tcon_demura_CSOT\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_CSOT;
break;
case TCON_DEMURA_HKC:
LOGD("%s, Do demura type %d tcon_demura_HKC\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_HKC;
break;
case TCON_DEMURA_AUO:
LOGD("%s, Do demura type %d tcon_demura_AUO\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_AUO;
break;
case TCON_DEMURA_INX:
LOGD("%s, Do demura type %d tcon_demura_INX\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_INX;
break;
case TCON_DEMURA_BOE:
LOGD("%s, Do demura type %d tcon_demura_BOE\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_BOE;
break;
case TCON_DEMURA_LG:
LOGD("%s, Do demura type %d tcon_demura_LG\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_LG;
break;
case TCON_DEMURA_SDP:
LOGD("%s, Do demura type %d tcon_demura_SDP\n", __FUNCTION__, demura_param_0);
tcon_demura_config = &tcon_demura_config_SDP;
break;
default:
break;
};
if (tcon_demura_config != NULL) {
if (demura_param_0 == TCON_DEMURA_INX) {
tcon_demura_config->data_offset = PANEL_Get_flash_ByteToInt(0x2c, 0x4, CC_ENDIAN_TYPE_BIG);
tcon_demura_config->data_len = PANEL_Get_flash_ByteToInt(0x30, 0x4, CC_ENDIAN_TYPE_BIG);
LOGD("%s, inx data_offset = 0x%x data_len = 0x%x\n", __FUNCTION__, tcon_demura_config->data_offset, tcon_demura_config->data_len);
} else {
tcon_demura_config->setting_offset = demura_param_2;
tcon_demura_config->setting_len = demura_param_3;
tcon_demura_config->data_offset = demura_offset;
tcon_demura_config->data_len = demura_size;
tcon_demura_config->data_crc_offset = demura_param_4;
tcon_demura_config->data_crc_len = demura_param_5;
tcon_demura_config->setting_bypass_flag = demura_param_1 & 0xff;
tcon_demura_config->mix_demura_flag = (demura_param_0 & 0x100) >> 8;
}
if (-1 == PANEL_Demura()) {
LOGE("%s, Do demura type%d fail.\n", __FUNCTION__, demura_param_0);
PANEL_RemoveTconlessBinFile(PANLE_DEMURA_REMOVE_FLAG);
}
} else {
LOGE("%s, No demura TYPE %d .\n", __FUNCTION__, demura_param_0);
PANEL_RemoveTconlessBinFile(PANLE_DEMURA_REMOVE_FLAG);
}
LOGD("%s, Finish Demura function.\n", __FUNCTION__);
} else {
LOGE("%s, No demura function.\n", __FUNCTION__);
PANEL_RemoveTconlessBinFile(PANLE_DEMURA_REMOVE_FLAG);
}
/*
p_gamma_offset=0xfe000 #pgamma flash data offset
p_gamma_size=0x2a #pgamma flash data len
block1_param_0=0 #bit[7~0] flash ic type
block1_param_1=0 #bit[7~0] gamma ic type #bit[15~8] default user mapping
block1_param_2=0 #bit[3~0]DLG_type 0:normal 1:DLG #bit[7~4]read_type 0:spi 1:i2c
block1_param_3=0 #Reserved/hkc_vref*1000
block1_param_4=0 #Reserved/hkc_vcom_max*1000
block1_param_5=0 #Reserved/hkc_vcom_min*1000
*/
if (pgamma_size != 0) {
tcon_pgamma_config.flash_data_offset = pgamma_offset;
tcon_pgamma_config.flash_data_len = pgamma_size;
tcon_pgamma_config.flash_vol_info.gam_ic_id = pgamma_param_0;
tcon_pgamma_config.bin_vol_info.gam_ic_id = pgamma_param_1;
tcon_pgamma_config.data_read_type = (pgamma_param_2 & 0xf0) >> 4;
pgmma_type = pgamma_param_2 & 0xf;
if (pgamma_param_0 == GAMMA_IC_LP6298_HKC || pgamma_param_0 == GAMMA_IC_PT650GS03_1) {
if (pgamma_param_3 == 0 || pgamma_param_4 == 0 || pgamma_param_5 == 0) {
LOGE("%s, HKC pgamma needs to configure vref and vcom_max vcom_min ini.\n", __FUNCTION__);
return -1;
}
tcon_pgamma_config.flash_vol_info.verf = (float)pgamma_param_3 / 1000;
tcon_pgamma_config.flash_vol_info.vcom_max = (float)pgamma_param_4 / 1000;
tcon_pgamma_config.flash_vol_info.vcom_min = (float)pgamma_param_5 / 1000;
}
if (pgmma_type == TCON_GAMMA_DLG_60 || pgmma_type == TCON_GAMMA_DLG_120) {
if (PANEL_Pgamma(TCON_GAMMA_DLG_60) == -1) {
LOGE("%s, Do Pgamma DLG 60 fail.\n", __FUNCTION__);
PANEL_RemoveTconlessBinFile(PANLE_PGAMMA_REMOVE_FLAG);
}
if (PANEL_Pgamma(TCON_GAMMA_DLG_120) == -1) {
LOGE("%s, Do Pgamma DLG 120 fail.\n", __FUNCTION__);
PANEL_RemoveTconlessBinFile(PANLE_PGAMMA_REMOVE_FLAG);
}
} else {
if (PANEL_Pgamma(TCON_GAMMA_NORMAL) == -1) {
LOGE("%s, Do Pgamma fail.\n", __FUNCTION__);
PANEL_RemoveTconlessBinFile(PANLE_PGAMMA_REMOVE_FLAG);
}
}
LOGD("%s, Finish Auto pgamma function.\n", __FUNCTION__);
} else {
LOGE("%s, No corresponding Auto pgamma data type.\n", __FUNCTION__);
PANEL_RemoveTconlessBinFile(PANLE_PGAMMA_REMOVE_FLAG);
}
return 0;
}
int CTvPanel::PANEL_RemoveTconlessBinFile(int config) {
if (config & 0x1)
(void) remove(PANLE_DEMURA_FILE_PATH);
if (config & 0x2) {
(void) remove(PANLE_PGAMMA_FILE_PATH);
(void) remove(PANLE_PGAMMA_FILE_PATH_60);
(void) remove(PANLE_PGAMMA_FILE_PATH_120);
(void) remove(PANLE_PGAMMA_CMD_FILE_PATH);
}
if (config & 0x4)
(void) remove(PANLE_ACC_FILE_PATH);
return 0;
}
int CTvPanel::PANEL_DemuraFileCheck(unsigned int crc_flash) {
unsigned int crc_file = 0;
unsigned char buf_file[4] = {0x0};
if (0 == access(PANLE_DEMURA_FILE_PATH, F_OK)) {
//LOGE("%s, do demura file check.\n", __FUNCTION__);
if (0 > PANEL_File_Read(PANLE_DEMURA_FILE_PATH, 0x4, buf_file, 0x4)) {
LOGE("%s, read crc in file failed, skip file check.", __FUNCTION__);
return PANEL_DEMURA_FILE_CHECK_FAIL;
}
} else {
LOGE("%s, demura file does not exist.\n", __FUNCTION__);
return PANEL_DEMURA_FILE_CHECK_FAIL;
}
crc_file = (unsigned int)((buf_file[3] << 24) | (buf_file[2] << 16) | (buf_file[1] << 8) | (buf_file[0]));
if (crc_file == crc_flash) {
LOGD("%s, file and flash data is same.\n", __FUNCTION__);
return PANEL_DEMURA_FILE_CHECK_PASS;
} else {
LOGE("%s, file and flash data is different, crc in file is 0x%x, crc in flash is 0x%x.\n",
__FUNCTION__, crc_file, crc_flash);
return PANEL_DEMURA_FILE_CHECK_FAIL;
}
return PANEL_DEMURA_FILE_CHECK_FAIL;
}
int CTvPanel::PANEL_DemuraFormat(int flash_crc, unsigned char *buffer_lut, int len_lut, tcon_demura_bin_info_s *demura_bin_info) {
int i = 0, ret = -1;
int file_num, header_num = 0, body_num = 0;
unsigned int temp = 0;
unsigned char *buffer_file = NULL;
unsigned char *buffer_fil_header = NULL;
unsigned char *buffer_fil_body = NULL;
int body_len = 0x1000 + len_lut;
BodyInfo bodies[60];
buffer_fil_header = (unsigned char *)malloc(sizeof(unsigned char) * 0x200);
if (buffer_fil_header == NULL)
return -1;
memset(buffer_fil_header, 0x0, sizeof(unsigned char) * 0x200);
buffer_fil_body = (unsigned char *)malloc(sizeof(unsigned char) * body_len);
if (buffer_fil_body == NULL) {
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
return -1;
}
memset(buffer_fil_body, 0x0, sizeof(unsigned char) * body_len);
buffer_file = (unsigned char *)malloc(sizeof(unsigned char) * (body_len + 0x200));
if (buffer_file == NULL) {
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
if (buffer_fil_body != NULL) {
free(buffer_fil_body);
buffer_fil_body = NULL;
}
return -1;
}
memset(buffer_file, 0x0, sizeof(unsigned char) * (body_len + 0x200));
/*********************************header*********************************/
/*00_data_check*/
header_num =4;
/*01_raw_data_check*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, flash_crc);
/*02_block_size*/
header_num += 4;
/*03_header_size*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x40);
/*04_ext_header_size*/
//WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0xa0);
header_num += 2;
/*05_block_type*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x2);
/*06_block_ctrl*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x0);
/*07_block_flag*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0x2);
/*08_init_priority*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0);
/*09_chip_id*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 1);
/*10_name*/
temp = 36 - 1;
strncpy((char *)(&buffer_fil_header[header_num]), "tcon_demura_lut", temp);
header_num += temp + 1;
/*******************************ext_header*******************************/
/*00_part_cnt*/
header_num += 2;
/*01_part_mapping_size*/
WRITE_TO_1_BUFFER(buffer_fil_header, header_num, 0x4);
/*02_reserved*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_1_BUFFER(buffer_fil_header, header_num, 0);
/*03_part_position_array*/
/*********************************body0*********************************/
file_num = 0;
/*00_ext_header body_offset*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, file_num);
/*00_part_name*/
temp = 48 - 1;
strncpy((char *)(&buffer_fil_body[file_num]), "demura_lut_data", temp);
file_num = file_num + temp + 1;
/*01_part_id*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, 0);
/*02_tuning_flag*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, 0x10);
/*03_part_type*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, 0xdd);
/*04_axi_buf_id*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, 0x1);
/*05_data_byte*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, 0x1);
/*06_data_cnt*/
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, len_lut);
/*07_data_array*/
for (i = 0; i < len_lut; i++) {
buffer_fil_body[file_num] = buffer_lut[i];
file_num++;
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_RGBMODE) == 0) {
bodies[body_num++] = (BodyInfo){"mono_mode", 0x11, 0xb0, 0x2, 0x4, 0x190, 0x10000000, ((demura_bin_info->mono_mode & 0x1) << 28)};
} else {
LOGD("%s, The setting in the demura bin does not include the mono_mode.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_RGBMODE) == 0) {
bodies[body_num++] = (BodyInfo){"layer_num", 0x11, 0xb0, 0x2, 0x4, 0x191, 0xf000000, ((demura_bin_info->layer_num & 0xf) << 24)};
} else {
LOGD("%s, The setting in the demura bin does not include the layer_num.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_OTHER) == 0) {
bodies[body_num++] = (BodyInfo){"table_bitwidth", 0x11, 0xb0, 0x2, 0x4, 0x191, 0x30000000, ((demura_bin_info->table_bitwidth & 0x3) << 28)};
bodies[body_num++] = (BodyInfo){"v_lut_num", 0x11, 0xb0, 0x2, 0x4, 0x197, 0xffc00000, ((demura_bin_info->v_lut_num & 0x3ff) << 22)};
bodies[body_num++] = (BodyInfo){"h_lut_num", 0x11, 0xb0, 0x2, 0x4, 0x197, 0x3ff000, ((demura_bin_info->h_lut_num & 0x3ff) << 12)};
bodies[body_num++] = (BodyInfo){"rd_cmd_len", 0x11, 0xb0, 0x2, 0x4, 0x1a4, 0xfffff, (demura_bin_info->rd_cmd_len & 0xfffff)};
} else {
LOGD("%s, The setting in the demura bin does not include the table_bitwidth v_lut_num h_lut_num rd_cmd_len.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_LIMIT) == 0) {
bodies[body_num++] = (BodyInfo){"white_limit_r", 0x11, 0xb0, 0x2, 0x4, 0x198, 0xfff000, ((demura_bin_info->white_limit_r & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"white_limit_g", 0x11, 0xb0, 0x2, 0x4, 0x1a5, 0xfff000, ((demura_bin_info->white_limit_g & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"white_limit_b", 0x11, 0xb0, 0x2, 0x4, 0x1a6, 0xfff000, ((demura_bin_info->white_limit_b & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"black_limit_r", 0x11, 0xb0, 0x2, 0x4, 0x198, 0xfff, (demura_bin_info->black_limit_r & 0xfff)};
bodies[body_num++] = (BodyInfo){"black_limit_g", 0x11, 0xb0, 0x2, 0x4, 0x1a5, 0xfff, (demura_bin_info->black_limit_g & 0xfff)};
bodies[body_num++] = (BodyInfo){"black_limit_b", 0x11, 0xb0, 0x2, 0x4, 0x1a6, 0xfff, (demura_bin_info->black_limit_b & 0xfff)};
} else {
LOGD("%s, The setting in the demura bin does not include the white_limit black_limit.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_LEVEL) == 0) {
bodies[body_num++] = (BodyInfo){"luma_level_0", 0x11, 0xb0, 0x2, 0x4, 0x190, 0xfff, (demura_bin_info->luma_level[0] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_1", 0x11, 0xb0, 0x2, 0x4, 0x190, 0xfff000, ((demura_bin_info->luma_level[1] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_2", 0x11, 0xb0, 0x2, 0x4, 0x191, 0xfff, (demura_bin_info->luma_level[2] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_3", 0x11, 0xb0, 0x2, 0x4, 0x191, 0xfff000, ((demura_bin_info->luma_level[3] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_4", 0x11, 0xb0, 0x2, 0x4, 0x192, 0xfff, (demura_bin_info->luma_level[4] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_5", 0x11, 0xb0, 0x2, 0x4, 0x192, 0xfff000, ((demura_bin_info->luma_level[5] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_6", 0x11, 0xb0, 0x2, 0x4, 0x193, 0xfff, (demura_bin_info->luma_level[6] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_7", 0x11, 0xb0, 0x2, 0x4, 0x193, 0xfff000, ((demura_bin_info->luma_level[7] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_8", 0x11, 0xb0, 0x2, 0x4, 0x194, 0xfff, (demura_bin_info->luma_level[8] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_9", 0x11, 0xb0, 0x2, 0x4, 0x194, 0xfff000, ((demura_bin_info->luma_level[9] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_10", 0x11, 0xb0, 0x2, 0x4, 0x195, 0xfff, (demura_bin_info->luma_level[10] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_11", 0x11, 0xb0, 0x2, 0x4, 0x195, 0xfff000, ((demura_bin_info->luma_level[11] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_12", 0x11, 0xb0, 0x2, 0x4, 0x196, 0xfff, (demura_bin_info->luma_level[12] & 0xfff)};
bodies[body_num++] = (BodyInfo){"luma_level_13", 0x11, 0xb0, 0x2, 0x4, 0x196, 0xfff000, ((demura_bin_info->luma_level[13] & 0xfff) << 12)};
bodies[body_num++] = (BodyInfo){"luma_level_14", 0x11, 0xb0, 0x2, 0x4, 0x197, 0xfff, (demura_bin_info->luma_level[14] & 0xfff)};
} else {
LOGD("%s, The setting in the demura bin does not include the luma_level.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_SLOPE) == 0) {
bodies[body_num++] = (BodyInfo){"plane_slope_0", 0x11, 0xb0, 0x2, 0x4, 0x199, 0xffff0000, ((demura_bin_info->plane_slope[0] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_1", 0x11, 0xb0, 0x2, 0x4, 0x199, 0xffff, (demura_bin_info->plane_slope[1] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_2", 0x11, 0xb0, 0x2, 0x4, 0x19a, 0xffff0000, ((demura_bin_info->plane_slope[2] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_3", 0x11, 0xb0, 0x2, 0x4, 0x19a, 0xffff, (demura_bin_info->plane_slope[3] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_4", 0x11, 0xb0, 0x2, 0x4, 0x19b, 0xffff0000, ((demura_bin_info->plane_slope[4] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_5", 0x11, 0xb0, 0x2, 0x4, 0x19b, 0xffff, (demura_bin_info->plane_slope[5] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_6", 0x11, 0xb0, 0x2, 0x4, 0x19c, 0xffff0000, ((demura_bin_info->plane_slope[6] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_7", 0x11, 0xb0, 0x2, 0x4, 0x19c, 0xffff, (demura_bin_info->plane_slope[7] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_8", 0x11, 0xb0, 0x2, 0x4, 0x19d, 0xffff0000, ((demura_bin_info->plane_slope[8] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_9", 0x11, 0xb0, 0x2, 0x4, 0x19d, 0xffff, (demura_bin_info->plane_slope[9] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_10", 0x11, 0xb0, 0x2, 0x4, 0x19e, 0xffff0000, ((demura_bin_info->plane_slope[10] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_11", 0x11, 0xb0, 0x2, 0x4, 0x19e, 0xffff, (demura_bin_info->plane_slope[11] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_12", 0x11, 0xb0, 0x2, 0x4, 0x19f, 0xffff0000, ((demura_bin_info->plane_slope[12] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_13", 0x11, 0xb0, 0x2, 0x4, 0x19f, 0xffff, (demura_bin_info->plane_slope[13] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_14", 0x11, 0xb0, 0x2, 0x4, 0x1a0, 0xffff0000, ((demura_bin_info->plane_slope[14] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_15", 0x11, 0xb0, 0x2, 0x4, 0x1a0, 0xffff, (demura_bin_info->plane_slope[15] & 0xffff)};
bodies[body_num++] = (BodyInfo){"plane_slope_16", 0x11, 0xb0, 0x2, 0x4, 0x1a1, 0xffff0000, ((demura_bin_info->plane_slope[16] & 0xffff) << 16)};
bodies[body_num++] = (BodyInfo){"plane_slope_17", 0x11, 0xb0, 0x2, 0x4, 0x1a1, 0xffff, (demura_bin_info->plane_slope[17] & 0xffff)};
} else {
LOGD("%s, The setting in the demura bin does not include the plane_slope.\n", __FUNCTION__);
}
if ((tcon_demura_config->setting_bypass_flag & DEMURA_SETTING_BYPASS_DDR_IF) == 0) {
bodies[body_num++] = (BodyInfo){"demura_ddrif_en", 0x11, 0xb0, 0x2, 0x4, 0x1a3, 0x80000000, 0x80000000};
bodies[body_num++] = (BodyInfo){"demura_en", 0x11, 0xb0, 0x2, 0x4, 0x190, 0x80000000, 0x80000000};
bodies[body_num++] = (BodyInfo){"dalay_2frames", 0x12, 0xfd, 50000, 0, 0, 0, 0};
} else {
LOGD("%s, The setting in the demura bin does not include the demura_ddrif_en .\n", __FUNCTION__);
}
bodies[body_num++] = (BodyInfo){"demura_bypass_off",0x11, 0xb0, 0x2, 0x4, 0x202, 0x40000000, 0};
bodies[body_num++] = (BodyInfo){"demura_demo_off", 0x11, 0xb0, 0x2, 0x4, 0x190, 0x40000000, 0};
bodies[body_num++] = (BodyInfo){"demura_dither_en", 0x11, 0xb0, 0x2, 0x4, 0x1ab, 0x200, 0x200};
if (lcd_debug_print_flag) {
LOGD("%s, mono_mode %d.\n", __FUNCTION__,demura_bin_info->mono_mode);
LOGD("%s, layer_num %d.\n", __FUNCTION__,demura_bin_info->layer_num);
LOGD("%s, table_bitwidth %d.\n", __FUNCTION__,demura_bin_info->table_bitwidth);
LOGD("%s, v_lut_num %d.\n", __FUNCTION__,demura_bin_info->v_lut_num);
LOGD("%s, h_lut_num %d.\n", __FUNCTION__,demura_bin_info->h_lut_num);
LOGD("%s, rd_cmd_len %d.\n", __FUNCTION__,demura_bin_info->rd_cmd_len);
LOGD("%s, white_limit_r %d.\n", __FUNCTION__,demura_bin_info->white_limit_r);
LOGD("%s, white_limit_g %d.\n", __FUNCTION__,demura_bin_info->white_limit_g);
LOGD("%s, white_limit_b %d.\n", __FUNCTION__,demura_bin_info->white_limit_b);
LOGD("%s, black_limit_r %d.\n", __FUNCTION__,demura_bin_info->black_limit_r);
LOGD("%s, black_limit_g %d.\n", __FUNCTION__,demura_bin_info->black_limit_g);
LOGD("%s, black_limit_b %d.\n", __FUNCTION__,demura_bin_info->black_limit_b);
for (i=0; i< 15; i++)
LOGD("%s, luma_level[%d] %d.\n", __FUNCTION__, i, demura_bin_info->luma_level[i]);
for (i=0; i< 18; i++)
LOGD("%s, plane_slope[%d] %d.\n", __FUNCTION__, i, demura_bin_info->plane_slope[i]);
}
for (i = 0; i < body_num; i++) {
const BodyInfo *body = &bodies[i];
/*00_ext_header body_offset*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, file_num);
/*00_part_name*/
temp = 48 - 1;
strncpy((char *)(&buffer_fil_body[file_num]), body->name, temp);
file_num = file_num + temp + 1;
/*01_part_id*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, i + 1);
/*02_tuning_flag*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->tuning_flag);
/*03_part_type*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->part_type);
if (body->part_type == 0xfd) {
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->reg_addr_byte_width);
} else {
/*04_reg_addr_byte_width*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->reg_addr_byte_width);
/*05_reg_data_byte_width*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->reg_data_byte_width);
/*06_reg_addr*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, body->reg_addr);
/*07_data_mask*/
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->data_mask);
/*08_data_value*/
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->data_value);
}
}
/*********************************header*********************************/
/*00_ext_header_size*/
temp = 0xe;
WRITE_TO_2_BUFFER(buffer_fil_header, temp, header_num - 0x40);
/*01_ext_header body_num*/
temp = 0x40;
WRITE_TO_2_BUFFER(buffer_fil_header, temp, body_num + 1);
/*02_header file_num*/
temp = 8;
WRITE_TO_4_BUFFER(buffer_fil_header, temp, header_num + file_num);
/*********************************buffer cat*********************************/
memcpy(buffer_file, buffer_fil_header, header_num);
memcpy(buffer_file + header_num, buffer_fil_body, file_num);
/*********************************file crc*********************************/
temp = 0;
WRITE_TO_4_BUFFER(buffer_file, temp, PANEL_DemuraFormatCrc(0, (buffer_file + 4), header_num + file_num - 4));
/*******************************write file********************************/
if (-1 == PANEL_File_Write(PANLE_DEMURA_FILE_PATH, 0x0, buffer_file, header_num + file_num)) {
LOGE("%s, write demura bin file failed.\n", __FUNCTION__);
ret = -1;
} else {
ret = 0;
}
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
if (buffer_fil_body != NULL) {
free(buffer_fil_body);
buffer_fil_body = NULL;
}
if (buffer_file != NULL) {
free(buffer_file);
buffer_file = NULL;
}
return ret;
}
void CTvPanel::PANEL_Demura_lut_Synthesize(unsigned int** buf_plane, unsigned char *buf_res, unsigned int layer_num, unsigned int buf_lut_offset, unsigned int demura_lut_num_H, unsigned int demura_lut_num_V) {
unsigned int i = 0, j = 0, k = 0;
unsigned int num_plane1 =0, num_plane2 =0,num_p1 = 0, num_p2 = 0, num_p = 0;
unsigned int num_res = buf_lut_offset;
for (i = 0; i < (demura_lut_num_V / 2); i++) {
for (k = 0; k < layer_num * 2; k += 2) {
num_plane1 = k;
num_plane2 = k + 1;
num_p1 = num_p;
num_p2 = num_p;
if (k > layer_num - 1) {
num_plane1 = k - layer_num;
num_plane2 = k - layer_num + 1;
num_p1 = num_p + demura_lut_num_H;
num_p2 = num_p + demura_lut_num_H;
}
if (num_plane1 == layer_num - 1) {
num_plane2 = 0;
num_p2 = num_p + demura_lut_num_H;
}
for (j = 0; j < (demura_lut_num_H / 2); j++) {
buf_res[num_res ] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1][num_p1 + 1] << 4) & 0xf0) | ((buf_plane[num_plane1][num_p1] >> 8) & 0xf));
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane1][num_p1 + 1] & 0xff0) >> 4);
num_res += 3;
num_p1 = num_p1 + 2;
}
buf_res[num_res] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane2][num_p2] << 4) & 0xf0) | ((buf_plane[num_plane1][num_p1] >> 8) & 0xf));
num_p1++;
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane2][num_p2] & 0xff0) >> 4);
num_p2++;
num_res += 3;
for (j = 0; j < (demura_lut_num_H / 2); j++) {
buf_res[num_res] = (unsigned char)(buf_plane[num_plane2][num_p2] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane2][num_p2 + 1] << 4) & 0xf0) | ((buf_plane[num_plane2][num_p2] >> 8) & 0xf));
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane2][num_p2 + 1] & 0xff0) >> 4);
num_res += 3;
num_p2 = num_p2 + 2;
}
}
num_p += demura_lut_num_H * 2;
}
if ( demura_lut_num_V % 2 == 1) {
for (i = 0; i <= layer_num / 2; i += 2) {
num_plane1 = i;
num_p1 = num_p;
num_p2 = num_p;
for (j = 0; j < (demura_lut_num_H / 2); j++) {
buf_res[num_res ] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1][num_p1 + 1] << 4) & 0xf0) | ((buf_plane[num_plane1][num_p1] >> 8) & 0xf));
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane1][num_p1 + 1] & 0xff0) >> 4);
num_res += 3;
num_p1 = num_p1 + 2;
}
buf_res[num_res] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1 + 1][num_p2] << 4) & 0xf0) | ((buf_plane[num_plane1][num_p1] >> 8) & 0xf));
num_p1++;
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane1 + 1][num_p2] & 0xff0) >> 4);
num_p2++;
num_res += 3;
for (j = 0; j < (demura_lut_num_H / 2); j++) {
buf_res[num_res] = (unsigned char)(buf_plane[num_plane1 + 1][num_p2] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1 + 1][num_p2 + 1] << 4) & 0xf0) | ((buf_plane[num_plane1 + 1][num_p2] >> 8) & 0xf));
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane1 + 1][num_p2 + 1] & 0xff0) >> 4);
num_res += 3;
num_p2 = num_p2 + 2;
}
}
if (layer_num % 2 == 1) {
num_plane1 = layer_num -1;
num_p1 = num_p;
for (j = 0; j < (demura_lut_num_H / 2); j++) {
buf_res[num_res ] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1][num_p1 + 1] << 4) & 0xf0) | ((buf_plane[num_plane1][num_p1] >> 8) & 0xf));
buf_res[num_res + 2] = (unsigned char)((buf_plane[num_plane1][num_p1 + 1] & 0xff0) >> 4);
num_res += 3;
num_p1 = num_p1 + 2;
}
buf_res[num_res] = (unsigned char)(buf_plane[num_plane1][num_p1] & 0xff);
buf_res[num_res + 1] = (unsigned char)(((buf_plane[num_plane1][num_p1 + 1] & 0xf) << 4));
num_res += 2;
}
}
//LOGD("%s, num_p =%d num_res = %d\n", __FUNCTION__, num_p1, num_res - buf_lut_offset);
}
void CTvPanel::Demura_lut_multipartite(unsigned int** buf_plane, unsigned char *buf_lut,unsigned int layer_num,unsigned int buf_lut_offset) {
unsigned int i = 0, j = 0, k = 0;
unsigned int num_plane1 = 0, num_plane2 = 0,num_p1 = 0, num_p2 = 0, num_p = 0, num_lut = 0;
num_lut = buf_lut_offset;
for (i=0 ; i< 135 ; i++) {
for (k = 0;k < layer_num * 2; k+=2) {
num_plane1 = k;
num_plane2 = k + 1;
num_p1 = num_p;
num_p2 = num_p;
if (k > layer_num) {
num_plane1 = k - layer_num;
num_p1 = num_p + 481;
num_p2 = num_p + 481;
}
if (num_plane1 == layer_num - 1)
num_plane2 = 0;
for (j=0 ; j< 240; j++) {
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ));
num_p1++;
num_lut += 3;
}
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
buf_plane[num_plane2][num_p2] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ));
num_p2++;
num_lut += 3;
for (j=0 ; j< 240; j++) {
buf_plane[num_plane2][num_p2] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p2++;
buf_plane[num_plane2][num_p2] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ));
num_p2++;
num_lut += 3;
}
}
num_p += 481 * 2;
}
for (i = 0;i < layer_num / 2; i+=2) {
num_plane1 = i;
num_p1 = num_p;
num_p2 = num_p;
for (j=0 ; j< 240; j++) {
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ) );
num_p1++;
num_lut += 3;
}
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
buf_plane[num_plane1+1][num_p2] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ) );
num_p2++;
num_lut += 3;
for (j=0 ; j< 240; j++) {
buf_plane[num_plane1+1][num_p2] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p2++;
buf_plane[num_plane1+1][num_p2] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ) );
num_p2++;
num_lut += 3;
}
}
if (layer_num % 2 == 1) {
num_plane1 = layer_num -1;
num_p1 = num_p;
for (j=0 ; j< 240; j++) {
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 2] & 0xff) << 4) | ((buf_lut[num_lut + 1] & 0xf0) >> 4 ) );
num_p1++;
num_lut += 3;
}
buf_plane[num_plane1][num_p1] = (unsigned int)(((buf_lut[num_lut + 1] & 0x0f) << 8) | (buf_lut[num_lut + 0] & 0xff));
num_p1++;
}
LOGD("%s, num_p =%d num_lut = %d\n", __FUNCTION__, num_p1, num_lut - buf_lut_offset);
}
unsigned int CTvPanel::PANEL_DemuraFormatCrc(unsigned int crc, const unsigned char *ptr, int buf_len) {
static const unsigned int s_crc32[16] = {
0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
unsigned int crcu32 = crc;
unsigned char b;
if (buf_len <= 0) {
return 0;
}
if (!ptr) {
return 0;
}
crcu32 = ~crcu32;
while (buf_len--) {
b = *ptr++;
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
}
return ~crcu32;
}
int CTvPanel::PANEL_Demura() {
tcon_demura_bin_info_s demura_bin_info = {0};
int ret = -1;
unsigned int i = 0, j = 0;
unsigned int **panel_buf_plane = NULL;
unsigned char *buf_res;
unsigned char *buf_flash_data = NULL;
unsigned char *buf_flash_setting = NULL;
unsigned int crc_flash = 0, crc_cal = 0;
unsigned int panel_num = 0, res_buffer_size = 0;
if (tcon_demura_config == NULL) {
LOGE("%s,tcon_demura_config is NULL.\n", __FUNCTION__);
return -1;
}
/*********************************file check********************************/
crc_flash = PANEL_Get_flash_ByteToInt(tcon_demura_config->data_crc_offset, tcon_demura_config->data_crc_len, tcon_demura_config->crc_endian_type);
if (0 == crc_flash) {
LOGE("%s, Read demura lut in flash failed.\n", __FUNCTION__);
return -1;
}
if (PANEL_DEMURA_FILE_CHECK_PASS == PANEL_DemuraFileCheck(crc_flash)) {
LOGD("%s, Demura file exists, no need rebuilt.\n", __FUNCTION__);
return 0;
}
/*********************************read data********************************/
buf_flash_data = (unsigned char *)malloc(sizeof(unsigned char) * tcon_demura_config->data_len);
if (buf_flash_data == NULL) {
LOGE("%s, malloc buf_flash failed.\n", __FUNCTION__);
return -1;
}
memset(buf_flash_data, 0x0, sizeof(unsigned char) * tcon_demura_config->data_len);
if (0 > PANEL_SPI_Read(tcon_demura_config->data_offset, tcon_demura_config->data_len, buf_flash_data)) {
LOGE("%s, Read demura lut in flash failed.", __FUNCTION__);
goto PANEL_Demura_err0;
}
/*********************************crc part**********************************/
crc_cal = tcon_demura_config->panel_crc_check(0, buf_flash_data, tcon_demura_config->data_len);
if (crc_flash != crc_cal) {
LOGE("%s, crc check failed.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, crc_flash, crc_cal);
goto PANEL_Demura_err0;
} else {
LOGD("%s, crc check ok.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, crc_flash, crc_cal);
}
/*********************************demura setting**********************************/
buf_flash_setting = (unsigned char *)malloc(sizeof(unsigned char) * tcon_demura_config->setting_len);
if (buf_flash_setting == NULL) {
LOGE("%s, malloc buf_flash_setting failed.\n", __FUNCTION__);
goto PANEL_Demura_err1;
}
memset(buf_flash_setting, 0x0, sizeof(unsigned char) * tcon_demura_config->setting_len);
if (0 > PANEL_SPI_Read(tcon_demura_config->setting_offset, tcon_demura_config->setting_len, buf_flash_setting)) {
LOGE("%s, Read demura lut in flash failed.\n", __FUNCTION__);
goto PANEL_Demura_err1;
}
if ( -1 == tcon_demura_config->demura_setting(buf_flash_setting, &demura_bin_info)) {
LOGE("%s, Read demura setting failed.\n", __FUNCTION__);
goto PANEL_Demura_err1;
}
/*******************************data Rearrange******************************/
if (demura_bin_info.layer_num == 0 || demura_bin_info.h_lut_num == 0 || demura_bin_info.v_lut_num == 0)
goto PANEL_Demura_err1;
if (demura_bin_info.mono_mode == 1)
panel_num = 3 * demura_bin_info.layer_num;
else
panel_num = demura_bin_info.layer_num;
panel_buf_plane = (unsigned int**)malloc(panel_num * sizeof(unsigned int*));
if (panel_buf_plane == NULL) {
LOGE("%s, malloc panel_buf_plane failed.\n", __FUNCTION__);
goto PANEL_Demura_err1;
}
for (i = 0; i < panel_num; i++) {
panel_buf_plane[i] = (unsigned int *)malloc(sizeof(unsigned int) * demura_bin_info.h_lut_num * demura_bin_info.v_lut_num);
if (panel_buf_plane[i] == NULL) {
for (j = 0; j < i; j++) {
free(panel_buf_plane[j]);
}
free(panel_buf_plane);
panel_buf_plane = NULL;
goto PANEL_Demura_err1;
}
memset(panel_buf_plane[i], 0x0, sizeof(unsigned int) * demura_bin_info.h_lut_num * demura_bin_info.v_lut_num);
}
tcon_demura_config->demura_data_trans(buf_flash_data, buf_flash_setting, panel_buf_plane, &demura_bin_info);
res_buffer_size = demura_bin_info.h_lut_num * demura_bin_info.v_lut_num * panel_num * 12 / 8 + 1;
if (res_buffer_size == 1)
goto PANEL_Demura_err2;
buf_res = (unsigned char *)malloc(sizeof(unsigned char) * res_buffer_size);
if (buf_res == NULL) {
LOGE("%s, malloc buf_res failed.\n", __FUNCTION__);
goto PANEL_Demura_err2;
}
memset(buf_res, 0x0, sizeof(unsigned char) * res_buffer_size);
PANEL_Demura_lut_Synthesize(panel_buf_plane, buf_res, panel_num, 0, demura_bin_info.h_lut_num, demura_bin_info.v_lut_num);
if (0 > PANEL_DemuraFormat((int)crc_flash, buf_res, res_buffer_size, &demura_bin_info)) {
LOGE("%s, Do demura format failed.\n", __FUNCTION__);
goto PANEL_Demura_err3;
} else {
LOGD("%s, Do demura format secuss.\n", __FUNCTION__);
}
ret = 0;
if (tcon_demura_config->mix_demura_flag == 1) {
if (PANEL_MixDemura("./bl_demura.bin","./mix_demura.bin", crc_flash, demura_bin_info, panel_buf_plane) == 0) {
LOGD("%s, Do mix demura secuss.\n", __FUNCTION__);
} else {
LOGE("%s, Do mix demura failed.\n", __FUNCTION__);
}
}
PANEL_Demura_err3:
if (buf_res != NULL) {
free(buf_res);
buf_res = NULL;
}
PANEL_Demura_err2:
if (panel_buf_plane != NULL) {
for (i = 0; i < panel_num; i++) {
free(panel_buf_plane[i]);
}
free(panel_buf_plane);
panel_buf_plane = NULL;
}
PANEL_Demura_err1:
if (buf_flash_setting != NULL) {
free(buf_flash_setting);
buf_flash_setting = NULL;
}
PANEL_Demura_err0:
if (buf_flash_data != NULL) {
free(buf_flash_data);
buf_flash_data = NULL;
}
return ret;
}
int CTvPanel::PANEL_MixDemura(const char * BackLight_demura_file, const char * output_bin_path, int crc_flash, const tcon_demura_bin_info_s& panel_demura_bin_info, unsigned int** panel_buf_plane) {
unsigned int ret = -1, i = 0, j = 0;
long bl_file_size = 0;
unsigned int bl_lut_offset = 0, bl_layer_num_offset = 0;
unsigned int lut_len_bl = 0, res_buffer_size = 0, bl_layer_num = 0;
FILE* fp_bl;
tcon_demura_bin_info_s mix_demura_bin_info;
unsigned char *buf_lut_bl = NULL;
unsigned int** bl_buf_plane = NULL;
unsigned char *buf_res;
size_t read_len = 0;
/*read file*/
if (0 == access(output_bin_path, 0)) {
LOGE("%s, %s file exists, no need rebuilt \n", __FUNCTION__, output_bin_path);
return -1;
}
fp_bl = fopen(BackLight_demura_file, "rb");
if (fp_bl == NULL) {
LOGE("%s, BackLight_demura_file not exist \n", __FUNCTION__);
return -1;
}
fseek(fp_bl,0,SEEK_END);
bl_file_size = ftell(fp_bl);
if (bl_file_size < 0) {
LOGE("%s, BackLight_demura_file size error \n", __FUNCTION__);
goto MixDemura_err1;
}
buf_lut_bl = (unsigned char *)malloc(sizeof(unsigned char) * bl_file_size);
if (NULL == buf_lut_bl) {
LOGE("%s, Malloc buf_res failed \n", __FUNCTION__);
goto MixDemura_err1;
}
rewind(fp_bl); // 将文件指针重置到文件开头
if ((read_len = fread(buf_lut_bl,sizeof(char), bl_file_size, fp_bl)) != (size_t)bl_file_size) {
LOGE("%s, fread BackLight_demura_file failed fread, read 0x%x expect bl_file_size 0x%x \n", __FUNCTION__, read_len, (unsigned int)bl_file_size);
goto MixDemura_err1;
}
memcpy(&mix_demura_bin_info, &panel_demura_bin_info, sizeof(tcon_demura_bin_info_s));
if (PANEL_Demura_File_crc_check(buf_lut_bl, bl_file_size) != 0) {
LOGE("%s, BL demura file crc check fail\n", __FUNCTION__);
goto MixDemura_err1;
}
bl_lut_offset = PANEL_GrepStr(BackLight_demura_file, "demura_lut_data");
bl_layer_num_offset = PANEL_GrepStr(BackLight_demura_file, "layer_num");
if ( bl_layer_num_offset != 0 ) {
LOGD("%s,bl_demura layer num buf_lut_bl[0x%x] = 0x%x \n", __FUNCTION__, bl_layer_num_offset + 63, buf_lut_bl[bl_layer_num_offset + 63]);
bl_layer_num = (int)buf_lut_bl[bl_layer_num_offset + 63];
} else {
bl_layer_num = panel_demura_bin_info.layer_num + 1;
}
// TODO: need to check bl_layer_num max size
if (bl_layer_num < 1 || bl_layer_num > 15) {
LOGE("%s, bl_layer_num error, bl_layer_num = %d \n", __FUNCTION__, bl_layer_num);
goto MixDemura_err1;
}
mix_demura_bin_info.layer_num = bl_layer_num;
lut_len_bl = (int)((buf_lut_bl[bl_lut_offset + 56] & 0xff) | ((buf_lut_bl[bl_lut_offset + 57] & 0xff) << 8) | ((buf_lut_bl[bl_lut_offset + 58] & 0xff) << 16) | ((buf_lut_bl[bl_lut_offset + 59] & 0xff) << 24));
LOGD("%s, bl_lut_offset = 0x%x bl_layer_num_offset = 0x%x bl_layer_num = 0x%x lut_len_bl = 0x%x\n", __FUNCTION__, bl_lut_offset, bl_layer_num_offset, bl_layer_num, lut_len_bl);
if (mix_demura_bin_info.v_lut_num != lut_len_bl*8/12/bl_layer_num/mix_demura_bin_info.h_lut_num) {
LOGE("%s, buf err, Please recheck backlight Demura bin bl_layer_num = 0x%x lut_len_bl = %d \n", __FUNCTION__, bl_layer_num, lut_len_bl);
goto MixDemura_err1;
}
/*read panel*/
bl_buf_plane = (unsigned int**)malloc(bl_layer_num * sizeof(unsigned int*));
if (bl_buf_plane == NULL) {
LOGE("%s, Malloc bl_buf_plane failed \n", __FUNCTION__);
goto MixDemura_err1;
}
for (i = 0; i < bl_layer_num; i++) {
bl_buf_plane[i] = (unsigned int*)malloc(mix_demura_bin_info.h_lut_num * mix_demura_bin_info.v_lut_num * sizeof(unsigned int));
if (bl_buf_plane[i] == NULL) {
for (j = 0; j < i; j++) {
free(bl_buf_plane[j]);
}
free(bl_buf_plane);
goto MixDemura_err1;
}
}
Demura_lut_multipartite(bl_buf_plane, buf_lut_bl, bl_layer_num, bl_lut_offset + 60);
/*add demura lut*/
for (i =0; i < panel_demura_bin_info.layer_num; i++) {
for ( j = 0; j < mix_demura_bin_info.h_lut_num * mix_demura_bin_info.v_lut_num; j++ ) {
if ((bl_buf_plane[i][j] <= 2047) && (panel_buf_plane[i][j] <= 2047)) {
bl_buf_plane[i][j] += panel_buf_plane[i][j];
bl_buf_plane[i][j] = bl_buf_plane[i][j] & 0xfff;
if (bl_buf_plane[i][j] > 2047) {
bl_buf_plane[i][j] = 2047;
}
} else if ((bl_buf_plane[i][j] > 2047) && (panel_buf_plane[i][j] > 2047)) {
bl_buf_plane[i][j] += panel_buf_plane[i][j] ;
bl_buf_plane[i][j] = bl_buf_plane[i][j] & 0xfff;
if (bl_buf_plane[i][j] <= 2047) {
bl_buf_plane[i][j] = 2048;
}
} else {
bl_buf_plane[i][j] += panel_buf_plane[i][j];
bl_buf_plane[i][j] = bl_buf_plane[i][j] & 0xfff;
}
}
}
//mix demura setting trans
mix_demura_bin_info.white_limit_r = 0xFFF;
mix_demura_bin_info.white_limit_g = 0xFFF;
mix_demura_bin_info.white_limit_b = 0xFFF;
mix_demura_bin_info.luma_level[bl_layer_num - 1] = mix_demura_bin_info.white_limit_r - 0x10;
mix_demura_bin_info.plane_slope[bl_layer_num - 1] = 0xFFFF / (mix_demura_bin_info.luma_level[bl_layer_num-1] - mix_demura_bin_info.luma_level[bl_layer_num-2]);
mix_demura_bin_info.plane_slope[bl_layer_num] = 0xFFFF / (mix_demura_bin_info.white_limit_r - mix_demura_bin_info.luma_level[bl_layer_num - 1]);
mix_demura_bin_info.rd_cmd_len = mix_demura_bin_info.h_lut_num * mix_demura_bin_info.v_lut_num * mix_demura_bin_info.layer_num * 12 / 512 + 2;
//out lut
res_buffer_size = mix_demura_bin_info.h_lut_num * mix_demura_bin_info.v_lut_num * mix_demura_bin_info.layer_num * 12 / 8 + 1;
buf_res = (unsigned char *)malloc(sizeof(unsigned char) * res_buffer_size);
if (buf_res == NULL) {
goto MixDemura_err2;
}
memset(buf_res, 0x0, sizeof(unsigned char) * res_buffer_size);
PANEL_Demura_lut_Synthesize(bl_buf_plane, buf_res, bl_layer_num, 0, mix_demura_bin_info.h_lut_num, mix_demura_bin_info.v_lut_num);
if (0 > PANEL_DemuraFormat((int)crc_flash, buf_res, res_buffer_size, &mix_demura_bin_info)) {
LOGE("%s, Do demura format failed.\n", __FUNCTION__);
goto MixDemura_err3;
} else {
LOGD("%s, Do demura format secuss.\n", __FUNCTION__);
}
ret = 0;
MixDemura_err3:
if (buf_res != NULL) {
free(buf_res);
buf_res = NULL;
}
MixDemura_err2:
if (bl_buf_plane != NULL) {
for (i = 0; i < bl_layer_num; i++) {
free(bl_buf_plane[i]);
}
free(bl_buf_plane);
}
bl_buf_plane = NULL;
MixDemura_err1:
if (buf_lut_bl != NULL)
free(buf_lut_bl);
buf_lut_bl = NULL;
fclose(fp_bl);
return ret;
}
unsigned int panel_crc_check_CHOT(unsigned int crc, const unsigned char *buffer, int buf_len) {
int i = 0;
for (i = 0; i < buf_len; i+=2) {
crc += (buffer[i] & 0xff) * 256 + (buffer[i + 1] & 0xff);
}
return crc & 0xffff;
}
int demura_setting_CHOT(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
demura_bin_info->h_lut_num = 481;
demura_bin_info->v_lut_num = 271;
demura_bin_info->mono_mode = 0;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->layer_num = 3;
demura_bin_info->black_limit_b = (unsigned int)((((unsigned int)setting_buffer[0x60] << 4) & 0xff0) | (setting_buffer[0x61] & 0xf));
demura_bin_info->black_limit_g = (unsigned int)((((unsigned int)setting_buffer[0x60] << 4) & 0xff0) | (setting_buffer[0x61] & 0xf));
demura_bin_info->black_limit_r = (unsigned int)((((unsigned int)setting_buffer[0x60] << 4) & 0xff0) | (setting_buffer[0x61] & 0xf));
demura_bin_info->white_limit_b = (unsigned int)((((unsigned int)setting_buffer[0x66] << 4) & 0xff0) | (setting_buffer[0x67] & 0xf));
demura_bin_info->white_limit_g = (unsigned int)((((unsigned int)setting_buffer[0x66] << 4) & 0xff0) | (setting_buffer[0x67] & 0xf));
demura_bin_info->white_limit_r = (unsigned int)((((unsigned int)setting_buffer[0x66] << 4) & 0xff0) | (setting_buffer[0x67] & 0xf));
demura_bin_info->luma_level[0] = (unsigned int)((((unsigned int)setting_buffer[0x3e] << 8) & 0xf00) | setting_buffer[0x35]);
demura_bin_info->luma_level[1] = (unsigned int)((((unsigned int)setting_buffer[0x3e] << 4) & 0xf00) | setting_buffer[0x36]);
demura_bin_info->luma_level[2] = (unsigned int)((((unsigned int)setting_buffer[0x3f] << 8) & 0xf00) | setting_buffer[0x37]);
demura_bin_info->luma_level[3] = (unsigned int)((((unsigned int)setting_buffer[0x3f] << 4) & 0xf00) | setting_buffer[0x38]);
demura_bin_info->luma_level[4] = (unsigned int)((((unsigned int)setting_buffer[0x40] << 8) & 0xf00) | setting_buffer[0x39]);
demura_bin_info->luma_level[5] = (unsigned int)((((unsigned int)setting_buffer[0x40] << 4) & 0xf00) | setting_buffer[0x3a]);
demura_bin_info->luma_level[6] = (unsigned int)((((unsigned int)setting_buffer[0x41] << 8) & 0xf00) | setting_buffer[0x3b]);
demura_bin_info->luma_level[7] = (unsigned int)((((unsigned int)setting_buffer[0x41] << 4) & 0xf00) | setting_buffer[0x3c]);
demura_bin_info->luma_level[8] = (unsigned int)((((unsigned int)setting_buffer[0x42] << 8) & 0xf00) | setting_buffer[0x3d]);
demura_bin_info->luma_level[9] = (unsigned int)((((unsigned int)setting_buffer[0xb3] << 8) & 0xf00) | setting_buffer[0xb0]);
demura_bin_info->luma_level[10] = (unsigned int)((((unsigned int)setting_buffer[0xb3] << 4) & 0xf00) | setting_buffer[0xb1]);
demura_bin_info->luma_level[11] = (unsigned int)((((unsigned int)setting_buffer[0xb4] << 8) & 0xf00) | setting_buffer[0xb2]);
unsigned int i = 1;
while (i <= 12) {
if (demura_bin_info->luma_level[i] == demura_bin_info->luma_level[i - 1]) {
demura_bin_info->layer_num = i ; //真实panel数量
break;
}
i++;
}
if (demura_bin_info->layer_num == 0) {
demura_bin_info->layer_num = 1;
}
for (i = 0; i <= demura_bin_info->layer_num ; i++) {
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else if (i == demura_bin_info->layer_num)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
}
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
return 0;
}
int demura_data_trans_CHOT(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0, num_lut = 0, num_p = 0;
for (i = 0, num_lut = 0, num_p = 0; i < 271; i++) {
for (k = 0; k < demura_bin_info->layer_num; k++) {
for (j = 0;j < 480; j+=2) {
panel_buf_plane[k][num_p + j] = (unsigned int)(buf_flash_data[num_lut] | ((buf_flash_data[num_lut + 1] & 0x0f) << 8)) - 2048;
panel_buf_plane[k][num_p + j + 1] = (unsigned int)((((buf_flash_data[num_lut + 1]) & 0xf0) >> 4) | (buf_flash_data[num_lut + 2] << 4)) - 2048;
num_lut += 3;
}
panel_buf_plane[k][num_p + 480] = (unsigned int)(buf_flash_data[num_lut] | ((buf_flash_data[num_lut + 1] & 0x0f) << 8)) - 2048;
num_lut += 6;
}
num_p += 481;
}
LOGD("%s, num_p %d num_lut 0x%x.\n", __FUNCTION__, num_p, num_lut);
return 0;
}
unsigned int panel_crc_check_CSOT(unsigned int crc, const unsigned char *buffer, int buf_len) {
unsigned char dat;
unsigned int offset = 0;
unsigned short crcData = 0;
const unsigned short CRC16_TABLE[256] = {
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
};
while (buf_len--) {
dat = (unsigned char)(crcData >> 8);
crcData <<= 8;
crcData ^= CRC16_TABLE[dat^buffer[offset++]];
}
crc = (unsigned short)crcData & 0xffff;
return crc;
}
int demura_setting_CSOT(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0;
if (tcon_demura_config->setting_len < 0x110) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
demura_bin_info->h_lut_num = (unsigned int)(setting_buffer[0x44] | (setting_buffer[0x45] << 8));
demura_bin_info->v_lut_num = (unsigned int)(setting_buffer[0x46] | (setting_buffer[0x47] << 8));
demura_bin_info->layer_num = setting_buffer[0x41];
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
if (demura_bin_info->h_lut_num == 0 || demura_bin_info->v_lut_num == 0 || demura_bin_info->layer_num == 0)
return -1;
demura_bin_info->mono_mode = setting_buffer[0x40];
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->black_limit_r = (unsigned int)((setting_buffer[0x5c] | (setting_buffer[0x5d] << 8))) << 2;
demura_bin_info->black_limit_g = (unsigned int)((setting_buffer[0x5e] | (setting_buffer[0x5f] << 8))) << 2;
demura_bin_info->black_limit_b = (unsigned int)((setting_buffer[0x60] | (setting_buffer[0x61] << 8))) << 2;
demura_bin_info->white_limit_r = (unsigned int)((setting_buffer[0x64] | (setting_buffer[0x65] << 8))) << 2;
demura_bin_info->white_limit_g = (unsigned int)((setting_buffer[0x66] | (setting_buffer[0x67] << 8))) << 2;
demura_bin_info->white_limit_b = (unsigned int)((setting_buffer[0x68] | (setting_buffer[0x69] << 8))) << 2;
for (i = 0; i < demura_bin_info->layer_num ; i++) {
demura_bin_info->luma_level[i] = (unsigned int)((setting_buffer[0x6d + i + i] << 8) | setting_buffer[0x6c + i + i]) << 2;
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
}
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
return 0;
}
int demura_data_trans_CSOT(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0, num_lut = 0, num_p = 0;
for (i = 0, num_lut = 0, num_p = 0; i < 271; i++) {
for (k = 0; k < demura_bin_info->layer_num; k++) {
for (j = 0;j < 480; j+=2) {
panel_buf_plane[k][num_p + j] = (unsigned int)(buf_flash_data[num_lut] | ((buf_flash_data[num_lut + 1] & 0x0f) << 8));
panel_buf_plane[k][num_p + j + 1] = (unsigned int)((((buf_flash_data[num_lut + 1]) & 0xf0) >> 4) | (buf_flash_data[num_lut + 2] << 4));
num_lut += 3;
if (j % 10 == 8)
num_lut++;
}
panel_buf_plane[k][num_p + 480] = (unsigned int)(buf_flash_data[num_lut] | ((buf_flash_data[num_lut + 1] & 0x0f) << 8));
num_lut += 16;
}
num_p += 481;
}
LOGD("%s, num_p %d num_lut 0x%x.\n", __FUNCTION__, num_p, num_lut);
return 0;
}
unsigned int panel_crc_check_HKC(unsigned int crc, const unsigned char *buffer, int buf_len) {
unsigned int i, j;
unsigned short crc_temp_1, crc_temp_2, crc_temp_3;
unsigned char data_buffer;
unsigned int length;
unsigned int checksum = 0;
i = 0;
length = buf_len;
while (length--) {
data_buffer = buffer[i++];
checksum += data_buffer;
crc_temp_1 = 0;
crc_temp_2 = 0;
crc_temp_3 = 0;
for (j = 0; j < 8; j++) {
crc_temp_1 = ((crc >> 15) ^ data_buffer) & 0x0001;
crc_temp_2 = ((crc >> 1) ^ crc_temp_1) & 0x0001;
crc_temp_3 = ((crc >> 14) ^ crc_temp_1) & 0x0001;
crc = crc << 1;
crc &= 0x7ffa;
crc |= crc_temp_1;
crc |= (crc_temp_2 << 2);
crc |= (crc_temp_3 << 15);
data_buffer >>= 1;
}
}
return crc;
}
int demura_setting_HKC(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0;
if (tcon_demura_config->setting_len < 0x40) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
demura_bin_info->h_lut_num = (unsigned int)((setting_buffer[0x8] << 8) | setting_buffer[0x9]);
demura_bin_info->v_lut_num = (unsigned int)((setting_buffer[0xa] << 8) | setting_buffer[0xb]);
demura_bin_info->layer_num = setting_buffer[0x7];
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
if (demura_bin_info->h_lut_num == 0 || demura_bin_info->v_lut_num == 0 || demura_bin_info->layer_num == 0)
return -1;
demura_bin_info->mono_mode = 0;
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->black_limit_b = (unsigned int)((setting_buffer[0x18] << 8) | setting_buffer[0x19]) << 2;
demura_bin_info->black_limit_g = (unsigned int)((setting_buffer[0x18] << 8) | setting_buffer[0x19]) << 2;
demura_bin_info->black_limit_r = (unsigned int)((setting_buffer[0x18] << 8) | setting_buffer[0x19]) << 2;
demura_bin_info->white_limit_b = (unsigned int)((setting_buffer[0x1a] << 8) | setting_buffer[0x1b]) << 2;
demura_bin_info->white_limit_g = (unsigned int)((setting_buffer[0x1a] << 8) | setting_buffer[0x1b]) << 2;
demura_bin_info->white_limit_r = (unsigned int)((setting_buffer[0x1a] << 8) | setting_buffer[0x1b]) << 2;
for (i = 0; i < demura_bin_info->layer_num ; i++) {
demura_bin_info->luma_level[i] = (unsigned int)((setting_buffer[0x28 + i + i] << 8) | setting_buffer[0x29 + i + i]) << 2;
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
}
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
return 0;
}
int demura_data_trans_HKC(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, num_lut = 0;
//demura_bin_info->h_lut_num * demura_bin_info->v_lut_num / 2 * 2 取偶数
//demura_bin_info->layer_num 为偶数未测试,没有遇到过
if (demura_bin_info->layer_num % 2 == 1) {
for (i = 0; i < demura_bin_info->h_lut_num * demura_bin_info->v_lut_num / 2 * 2; i+=2) {
for (j = 0; j < demura_bin_info->layer_num - 1; j+=2) {
panel_buf_plane[j][i] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
panel_buf_plane[j + 1][i] = (unsigned int)((buf_flash_data[num_lut + 1] & 0xf) << 8) | buf_flash_data[num_lut + 2];
num_lut += 3;
}
panel_buf_plane[demura_bin_info->layer_num - 1][i] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
panel_buf_plane[0][i + 1] = (unsigned int)((buf_flash_data[num_lut + 1] & 0xf) << 8) | buf_flash_data[num_lut + 2];
num_lut += 3;
for (j = 1; j < demura_bin_info->layer_num; j+=2) {
panel_buf_plane[j][i + 1] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
panel_buf_plane[j + 1][i + 1] = (unsigned int)((buf_flash_data[num_lut + 1] & 0xf) << 8) | buf_flash_data[num_lut + 2];
num_lut += 3;
}
}
if (demura_bin_info->h_lut_num * demura_bin_info->v_lut_num % 2 == 1) {
for (j = 0; j < demura_bin_info->layer_num - 1; j+=2) {
panel_buf_plane[j][i] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
panel_buf_plane[j + 1][i] = (unsigned int)((buf_flash_data[num_lut + 1] & 0xf) << 8) | buf_flash_data[num_lut + 2];
num_lut += 3;
}
panel_buf_plane[demura_bin_info->layer_num - 1][i] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
num_lut +=2;
}
} else if (demura_bin_info->layer_num % 2 == 0) {
for (i = 0; i < demura_bin_info->h_lut_num * demura_bin_info->v_lut_num; i++) {
for (j = 0; j < demura_bin_info->layer_num; j+=2) {
panel_buf_plane[j][i] = (unsigned int)(buf_flash_data[num_lut] << 4) | ((buf_flash_data[num_lut + 1] & 0xf0) >> 4);
panel_buf_plane[j + 1][i] = (unsigned int)((buf_flash_data[num_lut + 1] & 0xf) << 8) | buf_flash_data[num_lut + 2];
num_lut += 3;
}
}
}
LOGD("%s,num_p %d num_lut 0x%x.\n", __FUNCTION__, i, num_lut);
return 0;
}
unsigned int panel_crc_check_AUO(unsigned int crc, const unsigned char *buffer, int buf_len) {
unsigned int checksum = 0;
int i = 0;
for (i = 0; i < buf_len; i++) {
checksum += buffer[i];
}
return checksum % 65536;
}
int demura_setting_AUO(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0;
unsigned int rgb_mode = 1;
unsigned int setting_crc_flash = 0, setting_crc = 0;
if (tcon_demura_config->setting_len < 0x70) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
setting_crc_flash = (unsigned int)(setting_buffer[0x1] | (setting_buffer[0x0] << 8));
setting_crc = panel_crc_check_AUO(0, (setting_buffer + 2), 0x70 -2);
if (setting_crc_flash != setting_crc || setting_crc_flash == 0 || setting_crc_flash == 0xffff) {
LOGE("%s, crc check failed.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, setting_crc_flash, setting_crc);
return -1;
}
demura_bin_info->layer_num = (setting_buffer[2] & 0x0f);
demura_bin_info->h_lut_num = (setting_buffer[4] << 4) | ((setting_buffer[5] & 0xf0) >> 4);
demura_bin_info->v_lut_num = ((setting_buffer[5] & 0xf) << 8) | setting_buffer[6];
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
if (demura_bin_info->h_lut_num == 0 || demura_bin_info->v_lut_num == 0 || demura_bin_info->layer_num < 2)
return -1;
//color demura
demura_bin_info->mono_mode = 1;
if (demura_bin_info->mono_mode == 1)
rgb_mode = 3;
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * rgb_mode * 12 / 512 + 2;
demura_bin_info->table_bitwidth = 0;
//The RGB level of AUO is the same
demura_bin_info->black_limit_b = (unsigned int)((setting_buffer[0x9] << 8) | setting_buffer[0xa]);
demura_bin_info->black_limit_g = (unsigned int)((setting_buffer[0x9] << 8) | setting_buffer[0xa]);
demura_bin_info->black_limit_r = (unsigned int)((setting_buffer[0x9] << 8) | setting_buffer[0xa]);
demura_bin_info->white_limit_b = (unsigned int)((setting_buffer[0x1b] << 8) | setting_buffer[0x1c]);
demura_bin_info->white_limit_g = (unsigned int)((setting_buffer[0x1b] << 8) | setting_buffer[0x1c]);
demura_bin_info->white_limit_r = (unsigned int)((setting_buffer[0x1b] << 8) | setting_buffer[0x1c]);
for (i = 0; i < demura_bin_info->layer_num; i++) {
demura_bin_info->luma_level[i] = (unsigned int)((setting_buffer[0xb + i + i] << 8) | setting_buffer[0xc + i + i]);
demura_bin_info->luma_level[i + 5] = (unsigned int)((setting_buffer[0xb + i + i] << 8) | setting_buffer[0xc + i + i]);
demura_bin_info->luma_level[i + 10] = (unsigned int)((setting_buffer[0xb + i + i] << 8) | setting_buffer[0xc + i + i]);
if (demura_bin_info->luma_level[i] < demura_bin_info->black_limit_b || demura_bin_info->luma_level[i] > demura_bin_info->white_limit_b) {
LOGE("%s,There is an issue with the demura level, luma_level[%d] = %d black_limit = %d white_limit = %d.\n", __FUNCTION__,
i, demura_bin_info->luma_level[i], demura_bin_info->black_limit_b, demura_bin_info->white_limit_b);
return -1;
}
if (i == 0) {
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
demura_bin_info->plane_slope[i + 6] = 65535 / (demura_bin_info->luma_level[i + 5] - demura_bin_info->black_limit_g);
demura_bin_info->plane_slope[i + 12] = 65535 / (demura_bin_info->luma_level[i + 10] - demura_bin_info->black_limit_b);
} else {
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
demura_bin_info->plane_slope[i + 6] = 65535 / (demura_bin_info->luma_level[i + 5] - demura_bin_info->luma_level[i + 4]);
demura_bin_info->plane_slope[i + 12] = 65535 / (demura_bin_info->luma_level[i + 10] - demura_bin_info->luma_level[i + 9]);
}
}
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
demura_bin_info->plane_slope[i + 6] = 65535 / (demura_bin_info->white_limit_g - demura_bin_info->luma_level[i + 4]);
demura_bin_info->plane_slope[i + 12] = 65535 / (demura_bin_info->white_limit_b - demura_bin_info->luma_level[i + 9]);
demura_bin_info->plane_slope[5] = demura_bin_info->plane_slope[i];
demura_bin_info->plane_slope[11] = demura_bin_info->plane_slope[i + 6];
demura_bin_info->plane_slope[17] = demura_bin_info->plane_slope[i + 12];
if (lcd_debug_print_flag) {
LOGD("%s, R black_limit %d white_limit %d.\n", __FUNCTION__, demura_bin_info->black_limit_b, demura_bin_info->white_limit_b);
LOGD("%s, G black_limit %d white_limit %d.\n", __FUNCTION__, demura_bin_info->black_limit_g, demura_bin_info->white_limit_g);
LOGD("%s, B black_limit %d white_limit %d.\n", __FUNCTION__, demura_bin_info->black_limit_r, demura_bin_info->white_limit_r);
LOGD("%s, luma_level R 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->luma_level[0], demura_bin_info->luma_level[1], demura_bin_info->luma_level[2], demura_bin_info->luma_level[3], demura_bin_info->luma_level[4]);
LOGD("%s, luma_level G 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->luma_level[5], demura_bin_info->luma_level[6], demura_bin_info->luma_level[7], demura_bin_info->luma_level[8], demura_bin_info->luma_level[9]);
LOGD("%s, luma_level B 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->luma_level[10], demura_bin_info->luma_level[11], demura_bin_info->luma_level[12], demura_bin_info->luma_level[13], demura_bin_info->luma_level[14]);
LOGD("%s, plane_slope R 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->plane_slope[0], demura_bin_info->plane_slope[1], demura_bin_info->plane_slope[2], demura_bin_info->plane_slope[3], demura_bin_info->plane_slope[4], demura_bin_info->plane_slope[5]);
LOGD("%s, plane_slope G 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->plane_slope[6], demura_bin_info->plane_slope[7], demura_bin_info->plane_slope[8], demura_bin_info->plane_slope[9], demura_bin_info->plane_slope[10], demura_bin_info->plane_slope[11]);
LOGD("%s, plane_slope B 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, demura_bin_info->plane_slope[12], demura_bin_info->plane_slope[13], demura_bin_info->plane_slope[14], demura_bin_info->plane_slope[15], demura_bin_info->plane_slope[16], demura_bin_info->plane_slope[17]);
}
return 0;
}
unsigned char auo_data_mag_trans(unsigned char flash_data) {
switch (flash_data) {
case 0:
return 2;
case 1:
return 3;
case 2:
return 4;
case 6:
return 0;
case 7:
return 1;
default:
return -1;
}
}
int demura_data_trans_AUO(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0, num_lut = 0;
unsigned int auo_data_mag[24] = {0};
unsigned int auo_data_offset[24] = {0};
for (i = 0, j = 0; i < 24; i+=2, j++) {
auo_data_mag[i] = auo_data_mag_trans(((buf_flash_setting[0x2f + j] >> 4) & 0x7));
auo_data_mag[i + 1] = auo_data_mag_trans((buf_flash_setting[0x2f + j] & 0x7));
auo_data_offset[i] = ((buf_flash_setting[0x3b + j * 4] & 0x3f) << 8) | buf_flash_setting[0x3c + j * 4];
auo_data_offset[i + 1] = ((buf_flash_setting[0x3d + j * 4] & 0x3f) << 8) | buf_flash_setting[0x3e + j * 4];
}
if (lcd_debug_print_flag) {
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
LOGD("%s, auo_data_mag R 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_mag[0], auo_data_mag[1], auo_data_mag[2], auo_data_mag[3], auo_data_mag[4], auo_data_mag[5]);
LOGD("%s, auo_data_mag G 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_mag[8], auo_data_mag[9], auo_data_mag[10], auo_data_mag[11], auo_data_mag[12], auo_data_mag[13]);
LOGD("%s, auo_data_mag B 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_mag[16], auo_data_mag[17], auo_data_mag[18], auo_data_mag[19], auo_data_mag[20], auo_data_mag[21]);
LOGD("%s, auo_data_offset R 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_offset[0], auo_data_offset[1], auo_data_offset[2], auo_data_offset[3], auo_data_offset[4], auo_data_offset[5]);
LOGD("%s, auo_data_offset G 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_offset[8], auo_data_offset[9], auo_data_offset[10], auo_data_offset[11], auo_data_offset[12], auo_data_offset[13]);
LOGD("%s, auo_data_offset B 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x.\n", __FUNCTION__, auo_data_offset[16], auo_data_offset[17], auo_data_offset[18], auo_data_offset[19], auo_data_offset[20], auo_data_offset[21]);
}
for (j = 0,num_lut = 0; j < demura_bin_info->layer_num; j+=3) {
for (i = 0; i < demura_bin_info->h_lut_num * demura_bin_info->v_lut_num; i++) {
for (k = 0; k < 3 ; k++) {
//auo_data_mag[i * 8 + j /3] i => RGB, j => layer_num auo_data_mag_panel_0[R = 0 G= 8 B = 16] auo_data_mag_panel_0[R = 1 G= 9 B = 17]
if (((buf_flash_data[num_lut] >> 7) & 0x01) == 1)
panel_buf_plane[j + k][i] = (((((unsigned int)(buf_flash_data[num_lut]) << auo_data_mag[k * 8 + j / 3]) | ((0x3fff >> (auo_data_mag[k * 8 + j / 3] + 8)) << (auo_data_mag[k * 8 + j / 3] + 8)) ) + auo_data_offset[k * 8 + j / 3]) >> 2) & 0xfff;
else
panel_buf_plane[j + k][i] = ((((unsigned int)(buf_flash_data[num_lut]) << auo_data_mag[k * 8 + j / 3]) + auo_data_offset[k * 8 + j /3]) >> 2) & 0xfff;
num_lut++;
}
}
}
return 0;
}
unsigned int panel_crc_check_INX(unsigned int crc, const unsigned char *buffer, int buf_len) {
unsigned char coef[8] = {1, 2, 4, 8, 16, 32, 64, 128};
unsigned char shift[9];
unsigned char crc_buf[9];
unsigned char din[9];
unsigned int crcStart = 0, crc_out = 0xff, i = 0, index = 0;
for (index = crcStart; index < crcStart + buf_len; index += 1)
{
for (i = 0; i < 8; i += 1) {
if ((crc_out & coef[i]) != 0)
crc_buf[i] = 1;
else
crc_buf[i] = 0;
if ((buffer[index] & coef[i]) != 0)
din[i] = 1;
else
din[i] = 0;
}
shift[1] = (unsigned char)(din[7] ^ crc_buf[7]);
shift[2] = (unsigned char)(din[6] ^ crc_buf[6]);
shift[3] = (unsigned char)(din[5] ^ crc_buf[5]);
shift[4] = (unsigned char)(din[4] ^ crc_buf[4]);
shift[5] = (unsigned char)(din[3] ^ crc_buf[3] ^ shift[1]);
shift[6] = (unsigned char)(din[2] ^ crc_buf[2] ^ shift[1] ^ shift[2]);
shift[7] = (unsigned char)(din[1] ^ crc_buf[1] ^ shift[1] ^ shift[2] ^ shift[3]);
shift[8] = (unsigned char)(din[0] ^ crc_buf[0] ^ shift[2] ^ shift[3] ^ shift[4]);
crc_buf[7] = (unsigned char)(shift[1] ^ shift[3] ^ shift[4] ^ shift[5]);
crc_buf[6] = (unsigned char)(shift[2] ^ shift[4] ^ shift[5] ^ shift[6]);
crc_buf[5] = (unsigned char)(shift[3] ^ shift[5] ^ shift[6] ^ shift[7]);
crc_buf[4] = (unsigned char)(shift[4] ^ shift[6] ^ shift[7] ^ shift[8]);
crc_buf[3] = (unsigned char)(shift[5] ^ shift[7] ^ shift[8]);
crc_buf[2] = (unsigned char)(shift[6] ^ shift[8]);
crc_buf[1] = (unsigned char)(shift[7]);
crc_buf[0] = (unsigned char)(shift[8]);
crc_out = 0;
for (i = 0; i < 8; i += 1)
crc_out += (unsigned char)(crc_buf[i] * coef[i]);
}
return crc_out;
}
int demura_setting_INX(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
int i = 0;
unsigned int setting_crc_flash = 0, setting_crc = 0;
if (tcon_demura_config->setting_len < 0x80) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
setting_crc_flash = (unsigned int)(setting_buffer[0x7f] | (setting_buffer[0x7e] << 8));
//check sum,The CRC algorithm used in the settings section is different from the data section
setting_crc = panel_crc_check_AUO(0, (setting_buffer + 0x0), 0x80 - 2);
if (setting_crc_flash != setting_crc || setting_crc_flash == 0 || setting_crc_flash == 0xffff) {
LOGE("%s, crc check failed.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, setting_crc_flash, setting_crc);
return -1;
}
demura_bin_info->h_lut_num = 481;
demura_bin_info->v_lut_num = 271;
demura_bin_info->mono_mode = 0;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->layer_num = 5;
demura_bin_info->black_limit_b = (unsigned int)((setting_buffer[0x70] << 4));
demura_bin_info->black_limit_g = (unsigned int)((setting_buffer[0x70] << 4));
demura_bin_info->black_limit_r = (unsigned int)((setting_buffer[0x70] << 4));
demura_bin_info->white_limit_b = (unsigned int)((setting_buffer[0x71] << 4));
demura_bin_info->white_limit_g = (unsigned int)((setting_buffer[0x71] << 4));
demura_bin_info->white_limit_r = (unsigned int)((setting_buffer[0x71] << 4));
if (lcd_debug_print_flag)
LOGD("%s,black_limit = 0x%x white_limit = 0x%x.\n", __FUNCTION__, demura_bin_info->black_limit_b, demura_bin_info->white_limit_b);
for (i = 0; i < 5; i++) {
demura_bin_info->luma_level[i] = (unsigned int)((setting_buffer[0x72 + i] << 4));
//LOGE("%s, luma_level[%d] 0x%x.\n", __FUNCTION__, i, demura_bin_info->luma_level[i]);
if (demura_bin_info->luma_level[i] < demura_bin_info->black_limit_b || demura_bin_info->luma_level[i] > demura_bin_info->white_limit_b) {
LOGE("%s,There is an issue with the demura level, luma_level[%d] = %d black_limit = %d white_limit = %d.\n", __FUNCTION__,
i, demura_bin_info->luma_level[i], demura_bin_info->black_limit_b, demura_bin_info->white_limit_b);
return -1;
}
}
i = 4;
while (i >= 0) {
if (demura_bin_info->luma_level[i] != demura_bin_info->luma_level[4]) {
demura_bin_info->layer_num = i + 2;
break;
}
i--;
}
if (demura_bin_info->luma_level[4] == demura_bin_info->white_limit_b) {
demura_bin_info->layer_num -= 1;
}
if (lcd_debug_print_flag)
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
if (demura_bin_info->h_lut_num == 0 || demura_bin_info->v_lut_num == 0 || demura_bin_info->layer_num == 0)
return -1;
for (i = 0; i < (int)demura_bin_info->layer_num ; i++) {
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
//LOGE("%s, plane_slope[%d] 0x%x.\n", __FUNCTION__, i, demura_bin_info->plane_slope[i]);
}
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
//LOGE("%s, plane_slope[%d] 0x%x.\n", __FUNCTION__, i, demura_bin_info->plane_slope[i]);
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
return 0;
}
int INX_Data_Decode(unsigned int *Code, unsigned int *Mode,
int range, int min, unsigned int *DeLut) {
double Min = (double)(min);
double Range = (double)(range);
double M, N, Q;
double subRange1 = (int)((Range * 1 / 4) + Min + 0.5);
double subRange2 = (int)((Range * 2 / 4) + Min + 0.5);
double subRange3 = (int)((Range * 3 / 4) + Min + 0.5);
int mode;
int m,i;
for (i = 0;i < 4;i++) {
mode = Mode[i];
switch (mode) {
case 0:
M = Min+Range;
N = Min;
break;
case 1:
M = subRange3;
N = Min;
break;
case 2:
M = subRange2;
N = Min;
break;
case 3:
M = subRange1;
N = Min;
break;
case 4:
M = Min + Range;
N = subRange1;
break;
case 5:
M = Min + Range;
N = subRange2;
break;
case 6:
M = Min + Range;
N = subRange3;
break;
case 7:
M = subRange3;
N = subRange1;
break;
default:
M = Min + Range;
N = Min;
break;
}
Q = M - N;
for (m = 0;m < 4;m++) {
if (Q != 0) {
DeLut[m+i*4] = (int)((((double)(Code[m+i*4])) * 546 / 8192) * Q + N + 0.5);
DeLut[m+i*4] = DeLut[m+i*4] - 64;
} else {
DeLut[m+i*4] = (int)(N - 64);
}
}
}
return 0;
}
unsigned int INX_Data_Decode_trans(unsigned int *res_buffer, unsigned char *all_buffer) {
unsigned int i, j, m, q;
unsigned long long temp = 0;
unsigned int all_num = 0, res_num = 0, block_num = 0, bit_move_num = 0;
unsigned int range[2] = {0};
unsigned int ts_buffer[16] = {0x0};
unsigned int data_buffer[16] = {0x0};
unsigned int mode[4] = {0x0};
for (i = 0;i < 271;i++) {
temp = (unsigned long long)((all_buffer[all_num + 3] << 24) |
(all_buffer[all_num + 2] << 16) |
(all_buffer[all_num + 1] << 8) |
all_buffer[all_num]);
all_num += 4;
bit_move_num = 0; // 重置移位计数器
for (j = 0, block_num = 0;j < 39;j++) {
//first of four (per 45 byte)
for (m = 0; m < 4; m++) {
if (block_num == 155) {
//不做动作
} else {
// data_buffer 16个 每个有4个bit
for (q = 0; q < 16; q++) {
data_buffer[q] = (temp & 0x0000000F); // 取低4位
temp >>= 4; // 右移4位
bit_move_num += 4; // 更新移位计数
if (bit_move_num >= 8 && all_num < tcon_demura_config->data_len) { // 如果移位计数达到8
temp |= (long long)all_buffer[all_num++] << (32 - bit_move_num); // 左移24位,与新的all_buffer数据或起来
bit_move_num -= 8;
}
}
// mode 4个 每个有3个bit
for (q = 0; q < 4; q++) {
mode[q] = (temp & 0x00000007); // 取低3位
temp >>= 3; // 右移3位
bit_move_num += 3; // 更新移位计数
if (bit_move_num >= 8 && all_num < tcon_demura_config->data_len) {
temp |= (long long)all_buffer[all_num++] << (32 - bit_move_num);
bit_move_num -= 8;
}
}
// range 2个 每个有7个bit
for (q = 0; q < 2; q++) {
range[q] = (temp & 0x0000007F); // 取低7位
temp >>= 7; // 右移7位
bit_move_num += 7; // 更新移位计数S
if (bit_move_num >= 8 && all_num < tcon_demura_config->data_len) {
temp |= (long long)all_buffer[all_num++] << (32 - bit_move_num);
bit_move_num -= 8;
}
}
INX_Data_Decode(data_buffer, mode, range[0], range[1], ts_buffer);
if (block_num >= 150) {
res_buffer[res_num] = ts_buffer[0];
res_num++;
} else {
for (q = 0;q < 16;q++) {
res_buffer[res_num] = ts_buffer[q];
res_num++;
}
}
block_num++;
}
}
}
all_num = all_num + 17 - 4;
}
return all_num;
}
int demura_data_trans_INX(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int *decode_out_buf;
unsigned int i, j, k, m;
int lut_num = 0, res_num = 0;
//decode 解析出来就是5 panel大小的数据
decode_out_buf = (unsigned int *)malloc(sizeof(unsigned int) * demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * 5);
if (decode_out_buf == NULL) {
LOGE("%s, malloc decode_out_buf failed.\n", __FUNCTION__);
return -1;
}
memset(decode_out_buf, 0x0, sizeof(unsigned int) * demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * 5);
//解压inx数据
if (tcon_demura_config->data_len != INX_Data_Decode_trans(decode_out_buf, buf_flash_data)) {
LOGE("%s, inx data decode failed.\n", __FUNCTION__);
if (decode_out_buf != NULL) {
free(decode_out_buf);
//decode_out_buf = NULL;
}
return -1;
}
for (i = 0;i< 271;i++) {
for (j = 0;j < 31;j++) {
if (j != 30) {
//只将实际layer_num 数量的数据存放,多余数据直接跳过
for (m = 0; m < demura_bin_info->layer_num; m++) {
for (k = 0;k < 16; k++) {
panel_buf_plane[m][lut_num + k] = (decode_out_buf[res_num++] << 2) & 0xfff;
}
}
for (; m < 5; m++)
res_num += 16;
lut_num += 16;
} else {
//第481个数据的处理
for (m = 0; m < demura_bin_info->layer_num; m++)
panel_buf_plane[m][lut_num] = (decode_out_buf[res_num++] << 2) & 0xfff;
for (; m < 5; m++)
res_num++;
lut_num++;
}
}
}
if (decode_out_buf != NULL) {
free(decode_out_buf);
//decode_out_buf = NULL;
}
return 0;
}
unsigned int panel_crc_check_BOE(unsigned int crcData, const unsigned char *buffer, int buf_len) {
int i;
for (i = 0; i < buf_len / 4; i++) {
crcData += buffer[3] | (buffer[2] << 8) | (buffer[1] << 16) | (buffer[0] << 24);
buffer +=4;
}
return crcData;
}
int demura_setting_BOE(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0;
unsigned int setting_crc_flash = 0, setting_crc = 0;
if (tcon_demura_config->setting_len < 0x70) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
setting_crc_flash = (unsigned int)((setting_buffer[0x2c] << 24) | (setting_buffer[0x2d] << 16) | (setting_buffer[0x2e] << 8) | setting_buffer[0x2f]);
setting_crc = panel_crc_check_BOE(0, (setting_buffer + 0x40), 0x30);
if (setting_crc_flash != setting_crc || setting_crc_flash == 0 || setting_crc_flash == 0xffff) {
LOGE("%s, crc check failed.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, setting_crc_flash, setting_crc);
return -1;
}
demura_bin_info->h_lut_num = (unsigned int)((setting_buffer[0x44] << 8) | setting_buffer[0x45]);
demura_bin_info->v_lut_num = (unsigned int)((setting_buffer[0x46] << 8) | setting_buffer[0x47]);
demura_bin_info->layer_num = setting_buffer[0x41];
if (lcd_debug_print_flag)
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
if (demura_bin_info->h_lut_num == 0 || demura_bin_info->v_lut_num == 0 || demura_bin_info->layer_num == 0)
return -1;
demura_bin_info->mono_mode = setting_buffer[0x40];
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->black_limit_r = (unsigned int)(((setting_buffer[0x4c] << 8) | setting_buffer[0x4d])) << 2;
demura_bin_info->black_limit_g = (unsigned int)(((setting_buffer[0x4c] << 8) | setting_buffer[0x4d])) << 2;
demura_bin_info->black_limit_b = (unsigned int)(((setting_buffer[0x4c] << 8) | setting_buffer[0x4d])) << 2;
demura_bin_info->white_limit_r = (unsigned int)(((setting_buffer[0x4e] << 8) | setting_buffer[0x4f])) << 2;
demura_bin_info->white_limit_g = (unsigned int)(((setting_buffer[0x4e] << 8) | setting_buffer[0x4f])) << 2;
demura_bin_info->white_limit_b = (unsigned int)(((setting_buffer[0x4e] << 8) | setting_buffer[0x4f])) << 2;
for (i = 0; i < demura_bin_info->layer_num ; i++) {
demura_bin_info->luma_level[i] = (unsigned int)((setting_buffer[0x50 + i + i] << 8) | setting_buffer[0x51 + i + i]) << 2;
if (demura_bin_info->luma_level[i] < demura_bin_info->black_limit_b || demura_bin_info->luma_level[i] > demura_bin_info->white_limit_b) {
LOGE("%s,There is an issue with the demura level, luma_level[%d] = %d black_limit = %d white_limit = %d.\n", __FUNCTION__,
i, demura_bin_info->luma_level[i], demura_bin_info->black_limit_b, demura_bin_info->white_limit_b);
return -1;
}
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
}
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
return 0;
}
/*
* @brief This function get segment information for demura data.
* @param rgbMod [in] demura rgb mode, 0:mono;1 :RGB
* @param LayerNum [in] demura layer number
* @param uilutHNum [in] demura horizontal blocks number
* @param uiLutVNum [in] demura vertical blocks number
* @param uiSgmtSize [out] blocks number in one sgement
* @param uiSgmtSum [out] segment number in one line
* @param uiSgmtAlignSize [out] uiSgmtSize align with 128bit, save by byte
*/
void BOE_Getsegmentino (unsigned int rgbMod, unsigned int LayerNum, unsigned int uilutHnum, unsigned int uilutVnum, unsigned int *uiSgmtSize, unsigned int *uiSgmtSum, unsigned int *uiSgmtAlignSize) {
unsigned int rgbActor = rgbMod == 1 ? 3 : 1;
unsigned int uiTotalLayer = LayerNum * rgbActor;
unsigned int uiBlockNumPerLine = uilutVnum * uiTotalLayer;
unsigned int u8DecPnum = uiTotalLayer > 4 ? 4 : uiTotalLayer;
unsigned int uiSgmtMinSize =(uilutHnum * uiTotalLayer - 1)/((((1 << 13) - 1)/ uilutVnum) - 1);
unsigned int uiSgmtSizeMulti = (uiSgmtMinSize + (uiTotalLayer * u8DecPnum - 1))/ (uiTotalLayer * u8DecPnum);
*uiSgmtSize = uiTotalLayer * u8DecPnum * uiSgmtSizeMulti; //blocks num per segment
if ((*uiSgmtSize * 10 + 127) / 128 == 17) {
uiSgmtSizeMulti++;
*uiSgmtSize = uiTotalLayer * u8DecPnum * uiSgmtSizeMulti;
}
*uiSgmtSum =(uiBlockNumPerLine + *uiSgmtSize -1) / *uiSgmtSize;
*uiSgmtAlignSize=(((*uiSgmtSize * 10 + 127) >> 7)<<(7 - 3));
}
int demura_data_trans_BOE(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0;
unsigned int num_lut = 0, num_point = 0, block_num = 0, temp_num = 0, bit_move_num = 0;
uint64_t extractedData[20] = {0};
uint64_t temp = 0;
uint32_t temp_buf[64] = {0};
unsigned int uiSgmtSize = 0, uiSgmtSum = 0, uiSgmtAlignSize = 0;
//uiSgmtSize 54 uiSgmtSum 27 uiSgmtAlignSize 80
BOE_Getsegmentino(demura_bin_info->mono_mode, demura_bin_info->layer_num, demura_bin_info->v_lut_num, demura_bin_info->h_lut_num, &uiSgmtSize, &uiSgmtSum, &uiSgmtAlignSize);
if (lcd_debug_print_flag)
LOGD("%s, uiSgmtSize %d uiSgmtSum %d uiSgmtAlignSiz %d\n", __FUNCTION__, uiSgmtSize, uiSgmtSum, uiSgmtAlignSize);
//3panel,27个分段 每个分段54个数据
for (i = 0, num_lut = 0, num_point = 0; i < demura_bin_info->v_lut_num; i++) {
for (j = 0; j < uiSgmtSum; j++) {
temp_num = 0;
for (k = 0; k < uiSgmtAlignSize; k += 4)
//flash mapping 中说明 每8byte一个block,反转,再转换成大端
//化简理解 每4个byte 大端排列 32byte之间是小端排列
extractedData[k / 4] = (uint32_t)((buf_flash_data[num_lut + k + 0] << 24) | (buf_flash_data[num_lut + k + 1] << 16) | (buf_flash_data[num_lut + k + 2] << 8) | (buf_flash_data[num_lut + k + 3] << 0));
//每80byte 一个block, 有效数据为17个32bit数据, 54个10bit数据
num_lut += uiSgmtAlignSize;
temp = (extractedData[0] & 0xffffffff) | (extractedData[1] << 32);
bit_move_num = 0;
if (j == uiSgmtSum - 1)// 26
block_num = uiSgmtSize - (uiSgmtSize * uiSgmtSum - demura_bin_info->h_lut_num * demura_bin_info->layer_num); //39 = 54 - (54*27 - 481*3)
else
block_num = uiSgmtSize; //54
for (k = 0,temp_num = 2; k < block_num; k++) {
temp_buf[k] = (temp & 0x3ff); // 取低10位
temp = temp >> 10; // 右移10位
bit_move_num += 10; // 更新移位计数
if (bit_move_num >= 32 && temp_num < uiSgmtAlignSize / 4) { // 如果移位计数达到32
temp |= ((extractedData[temp_num++] & 0xffffffff) << (64 - bit_move_num)); // 左移32位,与新的all_buffer数据或起来
bit_move_num -= 32;
}
}
//对54个数据进行排列,panel0_point0、panel1_point0、panel2_point0、panel0_point1、panel1_point1、panel2_point1
for (k = 0; k < block_num; k++) //block_num = 54\39
panel_buf_plane[k % demura_bin_info->layer_num][num_point + k / demura_bin_info->layer_num] = ((temp_buf[k] - 0x200) << 2) & 0xfff;
//num_point += k /3;
num_point += k / demura_bin_info->layer_num;
}
}
return num_point * demura_bin_info->layer_num;
}
unsigned int panel_crc_check_LG(unsigned int crc, const unsigned char *buffer, int buf_len) {
unsigned int checksum = 0;
for (int i = 0; i < buf_len; i++) {
checksum += buffer[i];
}
//The current LG demura check sum verification method is limited, but it will be modified when configuring the LG screen in the future
return buffer[buf_len - 1];
}
int demura_setting_LG(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
//LG demura table 241 * 136 12bit block 16X16
//demura_gain 2048
demura_bin_info->h_lut_num = 241;
demura_bin_info->v_lut_num = 136;
demura_bin_info->layer_num = 4;
demura_bin_info->mono_mode = 0;
demura_bin_info->rd_cmd_len = 3074;
demura_bin_info->table_bitwidth = 0;
if (lcd_debug_print_flag)
LOGD("%s, panel_layer_num %d demura_lut_num_H %d demura_lut_num_V %d.\n", __FUNCTION__, demura_bin_info->layer_num, demura_bin_info->h_lut_num, demura_bin_info->v_lut_num);
demura_bin_info->black_limit_b = 20;
demura_bin_info->black_limit_g = 20;
demura_bin_info->black_limit_r = 20;
demura_bin_info->white_limit_b = 3800;
demura_bin_info->white_limit_g = 3800;
demura_bin_info->white_limit_r = 3800;
demura_bin_info->luma_level[0] = 512;
demura_bin_info->luma_level[1] = 1024;
demura_bin_info->luma_level[2] = 2048;
demura_bin_info->luma_level[3] = 3072;
demura_bin_info->luma_level[4] = 0;
demura_bin_info->luma_level[5] = 0;
demura_bin_info->luma_level[6] = 0;
demura_bin_info->luma_level[7] = 0;
demura_bin_info->plane_slope[0] = 138;
demura_bin_info->plane_slope[1] = 138;
demura_bin_info->plane_slope[2] = 128;
demura_bin_info->plane_slope[3] = 64;
demura_bin_info->plane_slope[4] = 64;
demura_bin_info->plane_slope[5] = 0;
demura_bin_info->plane_slope[6] = 0;
demura_bin_info->plane_slope[7] = 0;
demura_bin_info->plane_slope[8] = 0;
demura_bin_info->plane_slope[15] = 64;
return 0;
}
int demura_data_trans_LG(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0, m = 0, num_lut = 0, num_point = 0;
int demura_gain[4] = {0};
char offset[4] = {0};
unsigned char temp_panel_data = 0;
demura_gain[0] = (int)buf_flash_setting[2];
demura_gain[1] = (int)buf_flash_setting[1];
demura_gain[2] = (int)buf_flash_setting[0];
demura_gain[3] = (int)buf_flash_setting[7];
if (lcd_debug_print_flag)
LOGD("%s, demura_gain %d %d %d %d\n", __FUNCTION__, demura_gain[0], demura_gain[1], demura_gain[2], demura_gain[3]);
offset[0] = (char)buf_flash_setting[4];
offset[1] = (char)buf_flash_setting[11];
offset[2] = (char)buf_flash_setting[10];
offset[3] = (char)buf_flash_setting[9];
if (lcd_debug_print_flag)
LOGD("%s, offset %d %d %d %d\n", __FUNCTION__, offset[0], offset[1], offset[2], offset[3]);
num_lut = 4;
num_point = 0;
for (i = 0; i < 136; i++) {
for (j = 0;j < 60; j++) {
for (m = 0; m < 4; m++) {
temp_panel_data = buf_flash_data[num_lut + 3 - m];
for (k = 0; k < 4; k++) {
panel_buf_plane[k][num_point + m] = (unsigned int)((((int)(temp_panel_data & 0x7f)) * ((temp_panel_data & 0x80) ? -1 : 1) * demura_gain[k] / 64 + offset[k]) & 0xfff);
}
}
num_lut += 4;
num_point += 4;
}
temp_panel_data = buf_flash_data[num_lut + 3];
for (k = 0; k < 4; k++)
panel_buf_plane[k][num_point] = (unsigned int)((((int)(temp_panel_data & 0x7f)) * ((temp_panel_data & 0x80) ? -1 : 1) * demura_gain[k] / 64 + offset[k]) & 0xfff);
num_lut += 12;
num_point++;
}
return num_lut;
}
unsigned int panel_crc_check_SDP(unsigned int crc, const unsigned char *buffer, int buf_len) {
int i;
long sum = 0;
for (i = 0; i < buf_len / 2 ; i++) {
sum+= (unsigned int )(buffer[i * 2] << 8) + (unsigned int )buffer[i * 2 +1];
}
return sum % 65536;
}
int demura_setting_SDP(unsigned char *setting_buffer, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0;
unsigned int setting_crc_flash = 0, setting_crc = 0;
if (tcon_demura_config->setting_len < 0x220) {
LOGE("%s, setting_buffer len error.\n", __FUNCTION__);
return -1;
}
setting_crc_flash = (unsigned int)((setting_buffer[0x4] << 24) | (setting_buffer[0x5] << 16) | (setting_buffer[0x6] << 8) | (setting_buffer[0x7]));
setting_crc = panel_crc_check_SDP(0, (setting_buffer + 0x10), 0x220 - 0x10);
if (setting_crc_flash != setting_crc || setting_crc_flash == 0 || setting_crc_flash == 0xffff) {
LOGE("%s, crc check failed.crc in flash is 0x%x, crc in cal is 0x%x.\n", __FUNCTION__, setting_crc_flash, setting_crc);
return -1;
}
demura_bin_info->h_lut_num = 481;
demura_bin_info->v_lut_num = 271;
demura_bin_info->layer_num = setting_buffer[0x65];
demura_bin_info->mono_mode = 0;
demura_bin_info->rd_cmd_len = demura_bin_info->h_lut_num * demura_bin_info->v_lut_num * demura_bin_info->layer_num * 12 / 512 + 2;
demura_bin_info->table_bitwidth = 0;
demura_bin_info->black_limit_b = (unsigned int)((setting_buffer[0x6A] << 8) | setting_buffer[0x6B]) << 2;
demura_bin_info->black_limit_g = (unsigned int)((setting_buffer[0x6A] << 8) | setting_buffer[0x6B]) << 2;
demura_bin_info->black_limit_r = (unsigned int)((setting_buffer[0x6A] << 8) | setting_buffer[0x6B]) << 2;
demura_bin_info->white_limit_b = (unsigned int)((setting_buffer[0x9C] << 8) | setting_buffer[0x9D]) << 2;
demura_bin_info->white_limit_g = (unsigned int)((setting_buffer[0x9C] << 8) | setting_buffer[0x9D]) << 2;
demura_bin_info->white_limit_r = (unsigned int)((setting_buffer[0x9C] << 8) | setting_buffer[0x9D]) << 2;
demura_bin_info->luma_level[0] = (unsigned int)((setting_buffer[0x6C] << 8) | setting_buffer[0x6D]) << 2;
demura_bin_info->luma_level[1] = (unsigned int)((setting_buffer[0x72] << 8) | setting_buffer[0x73]) << 2;
demura_bin_info->luma_level[2] = (unsigned int)((setting_buffer[0x70] << 8) | setting_buffer[0x71]) << 2;
demura_bin_info->luma_level[3] = (unsigned int)((setting_buffer[0x76] << 8) | setting_buffer[0x77]) << 2;
demura_bin_info->luma_level[4] = (unsigned int)((setting_buffer[0x74] << 8) | setting_buffer[0x75]) << 2;
demura_bin_info->luma_level[5] = (unsigned int)((setting_buffer[0x7A] << 8) | setting_buffer[0x7B]) << 2;
demura_bin_info->luma_level[6] = (unsigned int)((setting_buffer[0x78] << 8) | setting_buffer[0x79]) << 2;
demura_bin_info->luma_level[7] = (unsigned int)((setting_buffer[0x7E] << 8) | setting_buffer[0x7F]) << 2;
for (i = 0; i <= demura_bin_info->layer_num ; i++) {
if (i == 0)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->black_limit_r);
else if (i == demura_bin_info->layer_num)
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->white_limit_r - demura_bin_info->luma_level[i - 1]);
else
demura_bin_info->plane_slope[i] = 65535 / (demura_bin_info->luma_level[i] - demura_bin_info->luma_level[i - 1]);
}
demura_bin_info->plane_slope[15] = demura_bin_info->plane_slope[i];
return 0;
}
int demura_data_trans_SDP(unsigned char *buf_flash_data, unsigned char *buf_flash_setting, unsigned int** panel_buf_plane, tcon_demura_bin_info_s *demura_bin_info) {
unsigned int i = 0, j = 0, k = 0, num_lut = 0;
unsigned int num_p = 0, num_p_temp = 0;
for (i = 0, num_lut = 0, num_p =0; i < 271; i++) {
for (k = 0; k < demura_bin_info->layer_num; k++) {
for (j = 0, num_p_temp = num_p; j < 120; j++) {
panel_buf_plane[k][num_p_temp++] = (unsigned int)(buf_flash_data[num_lut + 3] << 4);
panel_buf_plane[k][num_p_temp++] = (unsigned int)(buf_flash_data[num_lut + 2] << 4);
panel_buf_plane[k][num_p_temp++] = (unsigned int)(buf_flash_data[num_lut + 1] << 4);
panel_buf_plane[k][num_p_temp++] = (unsigned int)(buf_flash_data[num_lut + 0] << 4);
num_lut += 4;
}
panel_buf_plane[k][num_p_temp++] = (unsigned int)(buf_flash_data[num_lut + 3]);
num_lut += 4;
}
num_p += 481;
}
return 0;
}
int CTvPanel::PANEL_Pgamma (int pgmma_type) {
unsigned char res_buf[256] = {0};
unsigned char check_buf[256] = {0};
const char *pgamma_default_bin_path;
char pgamma_default_bin_path_kernel[128] = {'\0'};
char pgamma_uboot_env[128] = {'\0'};
char out_pgamma_bin_path[128] = {'\0'};
PGammaVolInfo *flash_vol_info = &tcon_pgamma_config.flash_vol_info;
PGammaVolInfo *bin_vol_info = &tcon_pgamma_config.bin_vol_info;
if (bin_vol_info->gam_ic_id == 0 || flash_vol_info->gam_ic_id == 0 || ((bin_vol_info->gam_ic_id & 0xff) >= GAMMA_IC_MAX) || ((flash_vol_info->gam_ic_id & 0xff) >= GAMMA_IC_MAX)) {
LOGE("%s, Gamma IC is not supported .\n", __FUNCTION__);
return -1;
}
if (pgmma_type == TCON_GAMMA_DLG_120) {
strcpy(out_pgamma_bin_path, PANLE_PGAMMA_FILE_PATH_120);
strcpy(pgamma_uboot_env, PANLE_PGAMMA_DEFLATE_BIN_ENV_DLG_120);
} else if(pgmma_type == TCON_GAMMA_DLG_60){
strcpy(out_pgamma_bin_path, PANLE_PGAMMA_FILE_PATH_60);
strcpy(pgamma_uboot_env, PANLE_PGAMMA_DEFLATE_BIN_ENV_DLG_60);
} else {
strcpy(out_pgamma_bin_path, PANLE_PGAMMA_FILE_PATH);
strcpy(pgamma_uboot_env, PANLE_PGAMMA_DEFLATE_BIN_ENV);
}
/*********************************flash read********************************/
if (tcon_pgamma_config.data_read_type == TCON_GAMMA_I2C) {
if (0 > PANEL_I2C_Read(tcon_pgamma_config.flash_data_offset, tcon_pgamma_config.flash_data_len, flash_vol_info->data_buf)) {
LOGE("%s,i2c Read pgmma lut in flash failed.", __FUNCTION__);
return -1;
}
} else {
if (0 > PANEL_SPI_Read(tcon_pgamma_config.flash_data_offset, tcon_pgamma_config.flash_data_len, flash_vol_info->data_buf)) {
LOGE("%s,spi Read pgmma lut in flash failed.", __FUNCTION__);
return -1;
}
}
if (-1 == PANEL_pgamma_flash_crc_check(flash_vol_info->data_buf, tcon_pgamma_config.flash_data_len)) {
LOGE("%s, Crc check failed.\n", __FUNCTION__);
return -1;
}
/*********************************file read********************************/
if ((pgamma_default_bin_path = PANEL_READ_Env(pgamma_uboot_env)) == NULL) {
LOGE("%s,Read tcon_p_gamma.bin path %s in env failed.\n", __FUNCTION__, pgamma_default_bin_path);
return -1;
}
snprintf(pgamma_default_bin_path_kernel, sizeof(pgamma_default_bin_path_kernel), "/mnt/vendor%s", pgamma_default_bin_path);
if (access((const char*)pgamma_default_bin_path_kernel, F_OK) == 0) {
tcon_pgamma_config.deflate_bin_len = PANEL_File_Read_bin((const char*)pgamma_default_bin_path_kernel, bin_vol_info->data_buf);
if (0 == tcon_pgamma_config.deflate_bin_len || 0xffffffff == tcon_pgamma_config.deflate_bin_len) {
LOGE("%s,Failed to read default pgamma bin %s.\n", __FUNCTION__, pgamma_default_bin_path_kernel);
return -1;
} else {
LOGD("%s,read default pgamma %s data_len 0x%x.\n", __FUNCTION__, pgamma_default_bin_path_kernel, tcon_pgamma_config.deflate_bin_len);
}
} else {
LOGE("%s,Tcon_p_gamma.bin path: %s does not exist.\n", __FUNCTION__, pgamma_default_bin_path_kernel);
return -1;
}
/*********************************data Rearrange********************************/
memcpy(res_buf, bin_vol_info->data_buf, tcon_pgamma_config.deflate_bin_len);
if (-1 == PANEL_pgamma_trans_vol_data(flash_vol_info, bin_vol_info, res_buf)) {
LOGE("%s, pgamma trans fail.\n", __FUNCTION__);
return -1;
}
/********************************write file*********************************/
if (access(out_pgamma_bin_path, F_OK) == 0) {
if (0 == PANEL_File_Read_bin(out_pgamma_bin_path, check_buf)) {
if (memcmp(check_buf, res_buf, tcon_pgamma_config.deflate_bin_len) == 0) {
LOGD("%s, Tcon_pgamma.bin is exist, no need to rebuilt.\n", __FUNCTION__);
return 0;
}
}
}
if (-1 == PANEL_File_Write(out_pgamma_bin_path, 0x0, res_buf, tcon_pgamma_config.deflate_bin_len)) {
LOGE("%s, write pgamma bin file failed.\n", __FUNCTION__);
return -1;
} else {
LOGD("%s, write pgamma bin secuss.\n", __FUNCTION__);
}
return 0;
}
int CTvPanel::PANEL_CMD_Auto_gamma_Format(const char * output_bin_path, unsigned int *temp_gamma_buf) {
unsigned int i = 0, ret = -1;
unsigned int file_num = 0, header_num = 0, body_num = 0;
unsigned int temp = 0;
unsigned char *buffer_file = NULL;
unsigned char *buffer_fil_header = NULL;
unsigned char *buffer_fil_body = NULL;
int body_len = 0x1000;
buffer_fil_header = (unsigned char *)malloc(sizeof(unsigned char) * 0x200);
if (buffer_fil_header == NULL)
return -1;
memset(buffer_fil_header, 0x0, sizeof(unsigned char) * 0x200);
buffer_fil_body = (unsigned char *)malloc(sizeof(unsigned char) * body_len);
if (buffer_fil_body == NULL) {
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
return -1;
}
memset(buffer_fil_body, 0x0, sizeof(unsigned char) * body_len);
buffer_file = (unsigned char *)malloc(sizeof(unsigned char) * (body_len + 0x200));
if (buffer_file == NULL) {
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
if (buffer_fil_body != NULL) {
free(buffer_fil_body);
buffer_fil_body = NULL;
}
return -1;
}
memset(buffer_file, 0x0, sizeof(unsigned char) * (body_len + 0x200));
/*********************************header*********************************/
/*00_data_check*/
header_num =4;
/*01_raw_data_check*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
/*02_block_size*/
header_num += 4;
/*03_header_size*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x40);
/*04_ext_header_size*/
//WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0xa0);
header_num += 2;
/*05_block_type*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x2);
/*06_block_ctrl*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0x0);
/*07_block_flag*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0x2);
/*08_init_priority*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 0);
/*09_chip_id*/
WRITE_TO_2_BUFFER(buffer_fil_header, header_num, 1);
/*10_name*/
temp = 36 - 1;
strncpy((char *)(&buffer_fil_header[header_num]), "tcon_auto_gamma", temp);
header_num += temp + 1;
/*******************************ext_header*******************************/
/*00_part_cnt*/
header_num += 2;
/*01_part_mapping_size*/
WRITE_TO_1_BUFFER(buffer_fil_header, header_num, 0x4);
/*02_reserved*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, 0);
WRITE_TO_1_BUFFER(buffer_fil_header, header_num, 0);
/*03_part_position_array*/
/*********************************bodies*********************************/
BodyInfo bodies[] = {
{"auto_gam2", 0x11, 0xb0, 0x2, 0x4, 0x47b, 0xff00, ((temp_gamma_buf[0] & 0xff) << 8)},
{"auto_gam3", 0x11, 0xb0, 0x2, 0x4, 0x47b, 0xff0000, ((temp_gamma_buf[1] & 0xff) << 16)},
{"auto_gam4", 0x11, 0xb0, 0x2, 0x4, 0x47c, 0xff, (temp_gamma_buf[2] & 0xff)},
{"auto_gam5", 0x11, 0xb0, 0x2, 0x4, 0x47c, 0xff00, ((temp_gamma_buf[3] & 0xff) << 8)},
{"auto_gam6", 0x11, 0xb0, 0x2, 0x4, 0x47c, 0xff0000, ((temp_gamma_buf[4] & 0xff) << 16)},
{"auto_gam7", 0x11, 0xb0, 0x2, 0x4, 0x47d, 0xff, (temp_gamma_buf[5] & 0xff)},
{"auto_gam8", 0x11, 0xb0, 0x2, 0x4, 0x47d, 0xff00, ((temp_gamma_buf[6] & 0xff) << 8)},
{"auto_gam11", 0x11, 0xb0, 0x2, 0x4, 0x47e, 0xff00, ((temp_gamma_buf[7] & 0xff) << 8)},
{"auto_gam12", 0x11, 0xb0, 0x2, 0x4, 0x47e, 0xff0000, ((temp_gamma_buf[8] & 0xff) << 16)},
{"auto_gam13", 0x11, 0xb0, 0x2, 0x4, 0x47f, 0xff, (temp_gamma_buf[9] & 0xff)},
{"auto_gam14", 0x11, 0xb0, 0x2, 0x4, 0x47f, 0xff00, ((temp_gamma_buf[10] & 0xff) << 8)},
{"auto_gam15", 0x11, 0xb0, 0x2, 0x4, 0x47f, 0xff0000, ((temp_gamma_buf[11] & 0xff) << 16)},
{"auto_gam16", 0x11, 0xb0, 0x2, 0x4, 0x480, 0xff, (temp_gamma_buf[12] & 0xff)},
{"auto_gam17", 0x11, 0xb0, 0x2, 0x4, 0x480, 0xff00, ((temp_gamma_buf[13] & 0xff) << 8)},
};
body_num = sizeof(bodies) / sizeof(bodies[0]);
for (i = 0; i < body_num; i++) {
const BodyInfo *body = &bodies[i];
/*00_ext_header body_offset*/
WRITE_TO_4_BUFFER(buffer_fil_header, header_num, file_num);
/*00_part_name*/
temp = 48 - 1;
strncpy((char *)(&buffer_fil_body[file_num]), body->name, temp);
file_num = file_num + temp + 1;
/*01_part_id*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, i + 1);
/*02_tuning_flag*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->tuning_flag);
/*03_part_type*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->part_type);
if (body->part_type == 0xfd) {
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->reg_addr_byte_width);
} else {
/*04_reg_addr_byte_width*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->reg_addr_byte_width);
/*05_reg_data_byte_width*/
WRITE_TO_1_BUFFER(buffer_fil_body, file_num, body->reg_data_byte_width);
/*06_reg_addr*/
WRITE_TO_2_BUFFER(buffer_fil_body, file_num, body->reg_addr);
/*07_data_mask*/
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->data_mask);
/*08_data_value*/
WRITE_TO_4_BUFFER(buffer_fil_body, file_num, body->data_value);
}
}
/*********************************buffer cat*********************************/
memcpy(buffer_file, buffer_fil_header, header_num);
memcpy(buffer_file + header_num, buffer_fil_body, file_num);
/*********************************file crc*********************************/
temp = 0;
WRITE_TO_4_BUFFER(buffer_file, temp, PANEL_DemuraFormatCrc(0, (buffer_file + 4), header_num + file_num - 4));
/*******************************write file********************************/
if (-1 == PANEL_File_Write(output_bin_path, 0x0, buffer_file, header_num + file_num)) {
LOGE("%s, write demura bin file failed.\n", __FUNCTION__);
ret = -1;
} else {
ret = 0;
}
if (buffer_fil_header != NULL) {
free(buffer_fil_header);
buffer_fil_header = NULL;
}
if (buffer_fil_body != NULL) {
free(buffer_fil_body);
buffer_fil_body = NULL;
}
if (buffer_file != NULL) {
free(buffer_file);
buffer_file = NULL;
}
return ret;
}
int CTvPanel::PANEL_pgamma_flash_crc_check(const unsigned char * flash_data_buf, int buf_len) {
unsigned int crc_cal = 0, crc_flash = 0;
switch (tcon_pgamma_config.flash_vol_info.gam_ic_id) {
case GAMMA_IC_CS602:
case GAMMA_IC_CS601:
crc_cal = panel_crc_check_CSOT(0, flash_data_buf, (buf_len - 2));
crc_flash = (unsigned short)((flash_data_buf[buf_len - 2] << 8) | flash_data_buf[buf_len - 1]);
break;
case GAMMA_IC_LP6298_HKC:
crc_cal = panel_crc_check_HKC(0, (flash_data_buf + 2), buf_len - 2);
crc_flash = (unsigned int)((flash_data_buf[0] << 8) | flash_data_buf[1]);
break;
case GAMMA_IC_PT650GS03_1:
//ckeck sum
crc_cal = panel_crc_check_AUO(0 , flash_data_buf, (buf_len -2)) & 0xff;
crc_flash = (unsigned short)(flash_data_buf[buf_len-1]);
break;
default:
LOGE("%s, No crc in flash.\n", __FUNCTION__);
return 0;
break;
}
if (crc_cal != crc_flash || crc_cal == 0 || crc_flash == 0) {
LOGE("%s, Crc check failed, crc in flash is 0x%x, crc after calculate is 0x%x.\n",
__FUNCTION__, crc_flash, crc_cal);
return -1;
}
return 0;
}
int CTvPanel::PANEL_pgamma_trans_vol_data( PGammaVolInfo *flash_vol_info, PGammaVolInfo *bin_vol_info, unsigned char *res_buf) {
unsigned int i, ret;
if ((flash_vol_info->data_buf[0] == 0x0 && flash_vol_info->data_buf[1] == 0x0 &&
flash_vol_info->data_buf[2] == 0x0 && flash_vol_info->data_buf[3] == 0x0) ||
(flash_vol_info->data_buf[0] == 0xff && flash_vol_info->data_buf[1] == 0xff &&
flash_vol_info->data_buf[2] == 0xff && flash_vol_info->data_buf[3] == 0xff)) {
LOGE("%s, No data in flash.\n", __FUNCTION__);
return -1;
}
if ((bin_vol_info->data_buf[0] == 0x0 && bin_vol_info->data_buf[1] == 0x0 &&
bin_vol_info->data_buf[2] == 0x0 && bin_vol_info->data_buf[3] == 0x0) ||
(bin_vol_info->data_buf[0] == 0xff && bin_vol_info->data_buf[1] == 0xff &&
bin_vol_info->data_buf[2] == 0xff && bin_vol_info->data_buf[3] == 0xff)) {
LOGE("%s, No data in default bin.\n", __FUNCTION__);
return -1;
}
switch (flash_vol_info->gam_ic_id & 0xff) {
case GAMMA_IC_CS602:
LOGD("%s: GAMMA_IC_CS602 flash2gamma\n", __FUNCTION__);
ret = buf2gamma_CS602(flash_vol_info);
break;
case GAMMA_IC_LP6298_HKC:
LOGD("%s: GAMMA_IC_LP6298_HKC flash2gamma\n", __FUNCTION__);
ret = buf2gamma_LP6298_HKC(flash_vol_info);
break;
case GAMMA_IC_PT650GS03_1:
LOGD("%s: HKC_PT650GS03_1 flash2gamma\n", __FUNCTION__);
ret = buf2gamma_HKC_PT650GS03_1(flash_vol_info);
break;
case GAMMA_IC_CS601:
LOGD("%s: GAMMA_IC_CS601 flash2gamma\n", __FUNCTION__);
ret = buf2gamma_CS601(flash_vol_info);
break;
default:
LOGE("%s, No gamma ic function.\n", __FUNCTION__);
return -1;
break;
}
for (i=0;i < 14; i++) {
bin_vol_info->gam_vol[i] = flash_vol_info->gam_vol[i];
if (lcd_debug_print_flag)
LOGD("%s: GAMMA%d = %f V \n", __FUNCTION__, i+1, bin_vol_info->gam_vol[i]);
}
bin_vol_info->vcom_vol[0] = flash_vol_info->vcom_vol[0];
bin_vol_info->vcom_vol[1] = flash_vol_info->vcom_vol[1];
if (lcd_debug_print_flag) {
LOGD("%s:vcom %d = %f V \n", __FUNCTION__, 0, bin_vol_info->vcom_vol[0]);
LOGD("%s:vcom %d = %f V \n", __FUNCTION__, 1, bin_vol_info->vcom_vol[1]);
}
switch (bin_vol_info->gam_ic_id & 0xff) {
case GAMMA_IC_LP6281:
LOGD("%s: GAMMA_IC_LP6281 gamma2bin\n", __FUNCTION__);
ret |= gamma2buf_LP6281(bin_vol_info, res_buf);
break;
case GAMMA_IC_CS602:
LOGD("%s: GAMMA_IC_CS602 gamma2bin\n", __FUNCTION__);
ret |= gamma2buf_CS602(bin_vol_info, res_buf);
break;
case GAMMA_IC_PT650GS03_1:
LOGD("%s: HKC_PT650GS03_1 gamma2bin\n", __FUNCTION__);
ret |= gamma2buf_LP6281_HKC_PT650GS03_1(bin_vol_info, res_buf);
break;
case GAMMA_IC_LP6298:
LOGD("%s: GAMMA_IC_LP6298 gamma2bin\n", __FUNCTION__);
ret |= gamma2buf_LP6298(bin_vol_info, res_buf);
break;
case GAMMA_IC_G2732P:
LOGD("%s: GAMMA_IC_LP6298 gamma2bin\n", __FUNCTION__);
ret |= gamma2buf_G2732P(bin_vol_info, res_buf);
break;
default:
LOGE("%s,No gamma ic function .\n", __FUNCTION__);
return -1;
break;
}
return ret;
}
int CTvPanel::buf2gamma_CS602(PGammaVolInfo *cs602_info) {
int i,j;
float cs602_GLDO;
cs602_GLDO =13 + (cs602_info->data_buf[0xa] & 0x1F)*0.2;
for (i = 0, j = 0; i < 14; i+=2, j += 3) {
cs602_info->gam_vol[i] = cs602_GLDO / 1024 * (float)(((cs602_info->data_buf[j+16] << 4) | ((cs602_info->data_buf[j+16 + 1] & 0xf0) >> 4)) + 1);
cs602_info->gam_vol[i+1] = cs602_GLDO / 1024 * (float)((((cs602_info->data_buf[j+16+1] & 0x0f) << 8) | cs602_info->data_buf[j+16 +2]) + 1);
}
cs602_info->vcom_vol[0] = cs602_GLDO / 1024 * (float)(((cs602_info->data_buf[37]<< 4) | ((cs602_info->data_buf[38] & 0xf0) >> 4)) + 1);
cs602_info->vcom_vol[1] = cs602_GLDO / 1024 * (float)((((cs602_info->data_buf[38] & 0x0f)<< 8) | (cs602_info->data_buf[39])) +1);
return 0;
}
int CTvPanel::buf2gamma_CS601(PGammaVolInfo *cs601_info) {
int i,j;
float avdd;
avdd = 13 + (cs601_info->data_buf[0x9] & 0x1F)*0.2;
for (i = 0, j = 0; i < 14; i++, j += 2) {
cs601_info->gam_vol[i] = avdd / 1024 * (float)(((cs601_info->data_buf[j + 0xe] & 0x3) << 8) | (cs601_info->data_buf[j + 0xf] & 0xff));
}
cs601_info->vcom_vol[0] = avdd / 1024 * (float)((((cs601_info->data_buf[0x2a] & 0x1) << 8) | (cs601_info->data_buf[0x2b] & 0xff)) + 250);
cs601_info->vcom_vol[1] = avdd / 1024 * (float)((((cs601_info->data_buf[0x2c] & 0x1) << 8) | (cs601_info->data_buf[0x2d] & 0xff)) + 250);
return 0;
}
int CTvPanel::buf2gamma_HKC_PT650GS03_1(PGammaVolInfo *lp6298_info) {
int i = 0;
unsigned char gam_data_buf[0x128];
if (lcd_debug_print_flag)
LOGD("%s, lp6298_info verf=%3f vcom_max=%3f vcom_min=%3f \n", __FUNCTION__, lp6298_info->verf/1000, lp6298_info->vcom_max/1000, lp6298_info->vcom_min/1000);
if (PANEL_SPI_Read(0x1000, 0xf, gam_data_buf) < 0) {
LOGE("%s, PANEL_SPI_Read fail\n", __FUNCTION__);
}
for (i = 0; i < 14 ; i++) {
lp6298_info->gam_vol[i] = (float)gam_data_buf[i];
if (lcd_debug_print_flag)
LOGD("%s,PT650GS03_1 gamma[%d] = 0x%x \n", __FUNCTION__, i, (unsigned int)lp6298_info->gam_vol[i]);
}
lp6298_info->vcom_vol[0] = ((lp6298_info->vcom_max/1000) - (lp6298_info->vcom_min/1000)) / 127 * ((float)(lp6298_info->data_buf[1] >> 1)) + (lp6298_info->vcom_min/1000);
if (lcd_debug_print_flag)
LOGD("%s, vcom_vol[0]= %3f \n", __FUNCTION__, lp6298_info->vcom_vol[0]);
return 0;
}
int CTvPanel::buf2gamma_LP6298_HKC(PGammaVolInfo *lp6298_info){
int i,j;
if (lcd_debug_print_flag)
LOGD("%s, lp6298_info verf=%3f vcom_max=%3f vcom_min=%3f \n", __FUNCTION__, lp6298_info->verf, lp6298_info->vcom_max, lp6298_info->vcom_min);
for (i = 0, j = 0; i < 14; i++, j += 2) {
lp6298_info->gam_vol[i] = ((float)((lp6298_info->data_buf[j + 3] << 8) | (lp6298_info->data_buf[j + 4] ))) * (lp6298_info->verf) / 1023;
//printf("%s, flash_code 0x%x gamma_vol[%d]= %f\n", __FUNCTION__,((lp6298_info->data_buf[j+3] << 8) | (lp6298_info->data_buf[j+3 + 1] )) , i,lp6298_info->gam_vol[i]);
}
lp6298_info->vcom_vol[0] = ((lp6298_info->vcom_max) - (lp6298_info->vcom_min)) / 127 * (float)(lp6298_info->data_buf[2]) + (lp6298_info->vcom_min);
if (lp6298_info->vcom_vol[0] > lp6298_info->vcom_max)
lp6298_info->vcom_vol[0] = lp6298_info->vcom_max;
//printf("%s, vcom_vol[0]= %f \n", __FUNCTION__, lp6298_info->vcom_vol[0]);
return 0;
}
int CTvPanel::gamma2buf_CS602(PGammaVolInfo *cs602_info, unsigned char *res_buf) {
int i,j;
float cs602_GLDO;
unsigned int temp_code[2] = {0};
unsigned int crc = 0;
cs602_GLDO =13 + (cs602_info->data_buf[0xa] & 0x1F)*0.2;
for (i = 0, j = 0; i < 14; i+=2, j += 3) {
temp_code[0] = (unsigned int)(cs602_info->gam_vol[i] / cs602_GLDO * 1024) - 1;
temp_code[1] = (unsigned int)(cs602_info->gam_vol[i + 1] / cs602_GLDO * 1024) - 1;
res_buf[j + 0x10] = (unsigned char)(temp_code[0] >> 4 & 0xff);
res_buf[j + 0x11] = (unsigned char)((temp_code[0] << 4) & 0xf0) | ((temp_code[1] >> 8) & 0xf);
res_buf[j + 0x12] = (unsigned char)(temp_code[1] & 0xff);
}
temp_code[0] = (unsigned int)(cs602_info->vcom_vol[0] / cs602_GLDO * 1024) -1;
temp_code[1] = (unsigned int)(cs602_info->vcom_vol[1] / cs602_GLDO * 1024) -1 ;
if (((cs602_info->gam_ic_id & 0xff00) >> 8) == 0x1) {
//use vcom3 0x2a + 0x2b, no crc
if (tcon_pgamma_config.deflate_bin_len != 0x2c)
LOGE("%s: use vcom3, deflate bin len 0x%x != 0x2c, need check deflate bin .\n", __FUNCTION__, tcon_pgamma_config.deflate_bin_len);
res_buf[0x2a] = (temp_code[0] >> 8 & 0xf);
res_buf[0x2b] = temp_code[0] & 0xff;
} else if (((cs602_info->gam_ic_id & 0xff00) >> 8) == 0x2) {
//only use vcom1
res_buf[0x25] = (temp_code[0] >> 4 & 0xff0);
res_buf[0x26] = ((temp_code[0] << 4) & 0xf0) | ((cs602_info->data_buf[26] & 0xf));
res_buf[0x27] = cs602_info->data_buf[27];
crc = panel_crc_check_CSOT(0, res_buf, (tcon_pgamma_config.deflate_bin_len - 2));
res_buf[0x28] = (crc & 0xff00) >> 8;
res_buf[0x29] = crc & 0xff;
} else {
res_buf[0x25] = (temp_code[0] & 0xff0) >> 4;
res_buf[0x26] = ((temp_code[0] << 4) & 0xf0) | ((temp_code[1] & 0xf00) >> 8);
res_buf[0x27] = (temp_code[1] & 0xff);
crc = panel_crc_check_CSOT(0, res_buf, (tcon_pgamma_config.deflate_bin_len - 2));
res_buf[0x28] = (crc & 0xff00) >> 8;
res_buf[0x29] = crc & 0xff;
}
return 0;
}
int CTvPanel::gamma2buf_LP6281(PGammaVolInfo *LP6281_info, unsigned char * res_buf) {
int i,j;
float avdd,res1,res2,res3;
unsigned char temp_gamma_buf[256] = {0};
unsigned char temp_vcom_buf[2] = {0};
float vcom_max,vcom_min;
avdd = 13.5 + (LP6281_info->data_buf[0] & 0x3f)*0.1;
res1 = avdd/1024;
res3 = avdd/128;
vcom_max = res3 * (LP6281_info->data_buf[10] + 1);
vcom_min = res3 * LP6281_info->data_buf[11];
res2 = (vcom_max - vcom_min)/127;
if (lcd_debug_print_flag)
LOGD("%s, avdd = %f vcom_max = %f vcom_min =%f \n", __FUNCTION__, avdd, vcom_max, vcom_min);
for (i = 0, j = 0;i < 14; i+=1, j += 2) {
temp_gamma_buf[j] = (unsigned char)(((unsigned int)(LP6281_info->gam_vol[i] /res1) >> 8) & 0x03);
temp_gamma_buf[j + 1] = (unsigned char)((unsigned int)(LP6281_info->gam_vol[i] /res1) & 0xff);
}
temp_vcom_buf[0] = (unsigned char)((unsigned int)((LP6281_info->vcom_vol[0] - vcom_min)/res2)) << 1;
res_buf[8] = (LP6281_info->data_buf[8] & 0x1) | (temp_vcom_buf[0] & 0xfe);
memmove(res_buf +12, temp_gamma_buf, 28);
return 0;
}
int CTvPanel::gamma2buf_LP6281_HKC_PT650GS03_1(PGammaVolInfo *LP6281_info, unsigned char * res_buf) {
float avdd,res2,res3;
unsigned int temp_gamma_buf[256] = {0};
unsigned char temp_vcom_buf[2] = {0};
float vcom_max,vcom_min;
avdd = 13.5 + (LP6281_info->data_buf[0] & 0x3f)*0.1;
res3 = avdd/128;
vcom_max = res3 * (LP6281_info->data_buf[10] + 1);
vcom_min = res3 * LP6281_info->data_buf[11];
res2 = (vcom_max - vcom_min)/127;
if (lcd_debug_print_flag)
LOGD("%s, avdd = %f vcom_max = %f vcom_min =%f \n", __FUNCTION__, avdd, vcom_max, vcom_min);
temp_gamma_buf[0] = (unsigned int)LP6281_info->gam_vol[0];
temp_gamma_buf[1] = (unsigned int)LP6281_info->gam_vol[1];
temp_gamma_buf[2] = (unsigned int)LP6281_info->gam_vol[2];
temp_gamma_buf[3] = (unsigned int)LP6281_info->gam_vol[3];
temp_gamma_buf[4] = (unsigned int)LP6281_info->gam_vol[4];
temp_gamma_buf[5] = (unsigned int)LP6281_info->gam_vol[5];
temp_gamma_buf[6] = (unsigned int)LP6281_info->gam_vol[6];
temp_gamma_buf[7] = (unsigned int)LP6281_info->gam_vol[7];
temp_gamma_buf[8] = (unsigned int)LP6281_info->gam_vol[8];
temp_gamma_buf[9] = (unsigned int)LP6281_info->gam_vol[9];
temp_gamma_buf[10] = (unsigned int)LP6281_info->gam_vol[10];
temp_gamma_buf[11] = (unsigned int)LP6281_info->gam_vol[11];
temp_gamma_buf[12] = (unsigned int)LP6281_info->gam_vol[12];
temp_gamma_buf[13] = (unsigned int)LP6281_info->gam_vol[13];
temp_vcom_buf[0] = (char)((unsigned int)((LP6281_info->vcom_vol[0] - vcom_min)/res2)) << 1;
PANEL_CMD_Auto_gamma_Format(PANLE_PGAMMA_CMD_FILE_PATH, temp_gamma_buf);
memmove(res_buf, LP6281_info->data_buf, 49);
res_buf[8] = (LP6281_info->data_buf[8] & 0x1) | (temp_vcom_buf[0] & 0xfe);
return 0;
}
int CTvPanel::gamma2buf_LP6298(PGammaVolInfo *LP6298_info, unsigned char * res_buf) {
int i,j;
float avdd,res1,res2,res3;
unsigned char temp_gamma_buf[128] = {0};
unsigned char temp_vcom_buf[2] = {0};
float vcom_max,vcom_min;
avdd = 6 + ((float)(LP6298_info->data_buf[2] & 0xff) / 255) * 11.8;
res1 = avdd/1024;
res3 = avdd/128;
vcom_max = 0.6 * res3 * (float)(LP6298_info->data_buf[3]& 0x7f);
vcom_min = 0.6 * res3 * (float)(LP6298_info->data_buf[4]& 0x7f);
res2 = (vcom_max - vcom_min)/127;
if (lcd_debug_print_flag)
LOGD("%s, avdd = %f vcom_max = %f vcom_min =%f \n", __FUNCTION__, avdd, vcom_max, vcom_min);
for (i = 0, j = 0;i < 14; i += 2, j += 3) {
temp_gamma_buf[j] = (unsigned char)(((unsigned int)(LP6298_info->gam_vol[i] /res1) >> 4) & 0x3f);
temp_gamma_buf[j + 1] = (unsigned char)(((unsigned int)(LP6298_info->gam_vol[i] /res1) & 0xf) << 4) | (unsigned char)(((unsigned int)(LP6298_info->gam_vol[i + 1] /res1) >> 8) & 0x3);
temp_gamma_buf[j + 2] = (unsigned char)((unsigned int)(LP6298_info->gam_vol[i + 1] /res1) & 0xff);
}
temp_vcom_buf[0] = (unsigned char)((unsigned int)((LP6298_info->vcom_vol[0] - vcom_min)/res2)) << 1;
res_buf[0x1] = (LP6298_info->data_buf[0x1] & 0x1) | (temp_vcom_buf[0] & 0xfe);
memmove(res_buf +5, temp_gamma_buf, 21);
return 0;
}
int CTvPanel::gamma2buf_G2732P(PGammaVolInfo *G2732P_info, unsigned char * res_buf) {
int i,j;
float avdd,res1,res2,res3;
unsigned char temp_gamma_buf[128] = {0};
unsigned char temp_vcom_buf[2] = {0};
float vcom_max,vcom_min;
avdd = (float)(G2732P_info->data_buf[0] & 0x3f) * 0.1 + 13.5;
res1 = avdd/1024;
res3 = avdd/128;
vcom_max = res3 * (float)(G2732P_info->data_buf[0xa]& 0x7f);
vcom_min = res3 * (float)(G2732P_info->data_buf[0xb]& 0x7f);
res2 = (vcom_max - vcom_min)/127;
LOGD("%s, avdd = %f vcom_max = %f vcom_min =%f \n", __FUNCTION__, avdd, vcom_max, vcom_min);
for (i = 0, j = 0;i < 14; i++, j+=2) {
temp_gamma_buf[j] = (unsigned char)(((unsigned int)(G2732P_info->gam_vol[i] /res1) >> 8) & 0x3);
temp_gamma_buf[j + 1] = (unsigned char)((unsigned int)(G2732P_info->gam_vol[i] /res1) & 0xff);
}
temp_vcom_buf[0] = (unsigned char)((unsigned int)((G2732P_info->vcom_vol[0] - vcom_min)/res2)) << 1;
res_buf[0x8] = (G2732P_info->data_buf[0x9] & 0x1) | (temp_vcom_buf[0] & 0xfe);
memmove(res_buf +0xc, temp_gamma_buf, 28);
return 0;
}