Files
2026-08-24 10:03:24 +08:00

3250 lines
146 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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;
}