/*********************************
* Put these codes on the lcm driver file
* And use LCM_DEBUG_MAIN func to activty yours debug function.
* Use adb command to push your edit configer file in the system: adb push lcm_init /data/
* You can edit config file as following syntax
* register config
reg:size=0x1,data=0x00290500,delay=0x5;
* timming config
timming:hs_trail=0x4,hs_zero=0x6,hs_prpr=0x4,lpx=0x3,ta_sack=0x1,ta_get=0xf,ta_sure=0x4,ta_go=0xc,clk_trail=0x3,clk_zero=0xc,lpx_wait=0x1,cont_det=0x0,clk_hs_prpr=0x3,pll_div1=0x1A,pll_div2=0x1;
**********************************/
--------skip----------
// need some include files
#if ENHANCMENT_DEBUG_LCM
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#endif
--------skip----------
#if ENHANCMENT_DEBUG_LCM
/*******************************************************
Function:
Open file function.
Input:
path:the file path.
old_fs_p:old fs point.
Output:
File point.
*********************************************************/
static struct file * lcm_debug_file_open(u8 * path, mm_segment_t * old_fs_p)
{
s32 errno = -1;
struct file *filp = NULL;
*old_fs_p = get_fs();
set_fs(KERNEL_DS);
filp = filp_open(path, O_RDONLY, 0644);
if(!filp || IS_ERR(filp))
{
if(!filp)
errno = -ENOENT;
else
errno = PTR_ERR(filp);
printk("[JX] %s Open file error. errno is:%d\n",__func__,errno);
return NULL;
}
filp->f_op->llseek(filp,0,0);
return filp ;
}
/*******************************************************
Function:
Close file function.
Input:
filp:the file point.
old_fs_p:old fs point.
Output:
None.
*********************************************************/
static void lcm_debug_file_close(struct file * filp, mm_segment_t old_fs)
{
set_fs(old_fs);
if(filp)
filp_close(filp, NULL);
}
/*******************************************************
Function:
Get file length function.
Input:
path:the file path.
Output:
File length.
*********************************************************/
static int lcm_debug_get_file_length(char * path)
{
struct file * file_ck = NULL;
mm_segment_t old_fs;
s32 length ;
file_ck = lcm_debug_file_open(path, &old_fs);
if(file_ck == NULL)
return 0;
length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);
if(length < 0)
length = 0;
lcm_debug_file_close(file_ck, old_fs);
return length;
}
/*******************************************************
Function:
lcm hard reset. Maybe need to modify this function.
Input:
NULL
Output:
NULL
*********************************************************/
static void lcm_debug_reset(void)
{
SET_RESET_PIN(0);
MDELAY(5);
SET_RESET_PIN(1);
MDELAY(120);
}
/*******************************************************
Function:
DeCreat proc entry function.
Input:
NULL
Output:
NULL
*********************************************************/
static u32 lcm_debug_size_of_str(char * s)
{
u32 temp=0;
for (; *s != '\0'; ++s)
temp++;
return temp;
}
static int lcm_debug_count_buffer_len(u8 *start, u8 *end)
{
u8 *temp_s,*temp_e;
int ret=0;
temp_s=start;
temp_e=end;
if(temp_s>temp_e) return -1;
for(ret=1;temp_s<temp_e;ret++,temp_s++) {
// printk("[JX] %s temp_s:0x%x \n",__func__,temp_s);
}
return ret;
}
static u8 * lcm_debug_get_param(char * str,int char_end, u8 *pstart,unsigned int *data)
{
u8 * pend=NULL;
u8 * cp=NULL;
u8 * param_ptr;
int buffer_len;
int str_len;
cp = pstart;
if(cp==NULL) return NULL;
//printk("[JX] %s str:%s pstart:%s\n",__func__,str,pstart);
str_len = lcm_debug_size_of_str(str);
if (strncmp(cp, str, str_len) == 0) {
cp+=str_len;
if((pend = strchr(cp, char_end))!=NULL) {
buffer_len = lcm_debug_count_buffer_len(cp,pend);
param_ptr = (u8*)vmalloc(buffer_len);
if(!param_ptr) {
vfree(param_ptr);
printk("[JX] ERROR can not malloc buffer.\n");
return NULL;
}
memset(param_ptr,0,buffer_len);
memcpy(param_ptr,cp,buffer_len);
*data = simple_strtoul(param_ptr,NULL,16);
memset(param_ptr,0,buffer_len);
vfree(param_ptr);
}else{
printk("[JX] ERROR can not found';'\n");
return NULL;
}
}else {
printk("[JX] ERROR not found %s\n",str);
return NULL;
}
return pend+1;
}
static s32 lcm_debug_parse_segment(u8 * data,LCM_DEBUG_SEGMENT_TYPE_E type)
{
u8 * cp;
int i;
if(data==NULL) {
printk("[JX] %s ERROR NULL of data",__func__);
return -1;
}
cp = data;
//printk("[JX] %s type:%d data:%s \n",__func__,type,cp);
switch(type) {
case LCM_DEBUG_SEGMENT_TYPE_REG:
do {
if (strncmp(cp, "size=", 5) == 0) {
if(!(cp=lcm_debug_get_param("size=",',',cp,&lcm_debug_reg_info[lcm_debug_reg_info_num].queue_size)))
break;
}
if (strncmp(cp, "data=", 5) == 0) {
if(lcm_debug_reg_info[lcm_debug_reg_info_num].queue_size!=0) {
for(i=0;i<lcm_debug_reg_info[lcm_debug_reg_info_num].queue_size;i++) {
if(!(cp=lcm_debug_get_param("data=",',',cp,&lcm_debug_reg_info[lcm_debug_reg_info_num].pdata[i]))) {
printk("[JX] %s ERROR reg%d data out of size\n",__func__,lcm_debug_reg_info_num);
return -1;
}
}
}
}
if (strncmp(cp, "delay=", 6) == 0) {
if(!(cp=lcm_debug_get_param("delay=",';',cp,&lcm_debug_reg_info[lcm_debug_reg_info_num].delay_ms)))
break;
}
cp++;
}while(*cp != '\0');
break;
case LCM_DEBUG_SEGMENT_TYPE_TIMMING:
do {
if(!(cp=lcm_debug_get_param("hs_trail=",',',cp,&lcm_debug_timming.HS_TRAIL)))
break;
if(!(cp = lcm_debug_get_param("hs_zero=",',',cp,&lcm_debug_timming.HS_ZERO)))
break;
if(!(cp = lcm_debug_get_param("hs_prpr=",',',cp,&lcm_debug_timming.HS_PRPR)))
break;
if(!(cp = lcm_debug_get_param("lpx=",',',cp,&lcm_debug_timming.LPX)))
break;
if(!(cp = lcm_debug_get_param("ta_sack=",',',cp,&lcm_debug_timming.TA_SACK)))
break;
if(!(cp = lcm_debug_get_param("ta_get=",',',cp,&lcm_debug_timming.TA_GET)))
break;
if(!(cp = lcm_debug_get_param("ta_sure=",',',cp,&lcm_debug_timming.TA_SURE)))
break;
if(!(cp = lcm_debug_get_param("ta_go=",',',cp,&lcm_debug_timming.TA_GO)))
break;
if(!(cp = lcm_debug_get_param("clk_trail=",',',cp,&lcm_debug_timming.CLK_TRAIL)))
break;
if(!(cp = lcm_debug_get_param("clk_zero=",',',cp,&lcm_debug_timming.CLK_ZERO)))
break;
if(!(cp = lcm_debug_get_param("lpx_wait=",',',cp,&lcm_debug_timming.LPX_WAIT)))
break;
if(!(cp = lcm_debug_get_param("cont_det=",',',cp,&lcm_debug_timming.CONT_DET)))
break;
if(!(cp = lcm_debug_get_param("clk_hs_prpr=",',',cp,&lcm_debug_timming.CLK_HS_PRPR)))
break;
if(!(cp = lcm_debug_get_param("pll_div1=",',',cp,&lcm_debug_timming.pll_div1)))
break;
if(!(cp = lcm_debug_get_param("pll_div2=",';',cp,&lcm_debug_timming.pll_div2)))
break;
cp++;
}while(*cp != '\0');
break;
default:
break;
}
}
static u8 * lcm_debug_get_segment(char * str, int char_end, u8 *pstart,LCM_DEBUG_SEGMENT_TYPE_E type)
{
u8 * pend=NULL;
u8 * cp=NULL;
u8 * param_ptr;
int buffer_len;
int str_len;
cp = pstart;
if(cp==NULL) return NULL;
str_len = lcm_debug_size_of_str(str);
cp+=str_len;
if((pend = strchr(cp, char_end))!=NULL) {
buffer_len = lcm_debug_count_buffer_len(cp,pend);
param_ptr = (u8*)vmalloc(buffer_len);
if(!param_ptr) {
vfree(param_ptr);
printk("[JX] ERROR can not malloc buffer.\n");
return NULL;
}
memset(param_ptr,0,buffer_len);
memcpy(param_ptr,cp,buffer_len);
lcm_debug_parse_segment(param_ptr,type);
memset(param_ptr,0,buffer_len);
vfree(param_ptr);
}else{
printk("[JX] ERROR can not found';'\n");
return NULL;
}
return pend+1;
}
static s32 lcm_debug_parse_cmd_2(u8 *data,u32 file_len )
{
u8 *cp;
int i,j;
cp = data;
lcm_debug_reg_info_num = 0;
for(;cp<(data+file_len);cp++) {
//printk("[JX] cp:0x%x str:%s\n",cp,cp);
if(strncmp("reg:",cp,4)==0) {
if(!(cp = lcm_debug_get_segment("reg:",';',cp,LCM_DEBUG_SEGMENT_TYPE_REG))) {
printk("[JX] ERROR NULL of cp");
break;
}
lcm_debug_reg_info_num++;
}
if(strncmp("timming:",cp,8)==0) {
if(!(cp = lcm_debug_get_segment("timming:",';',cp,LCM_DEBUG_SEGMENT_TYPE_TIMMING))) {
printk("[JX] ERROR NULL of cp");
break;
}
}
}
/*
//log out lcm_debug_reg_info
for(i=0;i<lcm_debug_reg_info_num;i++)
{
printk("[JX] reg_%d=0x%x\n",i,lcm_debug_reg_info[i].queue_size);
for(j=0;j<lcm_debug_reg_info[i].queue_size;j++)
{
printk("data:0x%x\n",lcm_debug_reg_info[i].pdata[j]);
}
printk("delay:0x%x\n",lcm_debug_reg_info[i].delay_ms);
}
//log out lcm_debug_timming
printk("[JX] timming:0x%x\n",lcm_debug_timming.HS_TRAIL);
printk("[JX] timming:0x%x\n",lcm_debug_timming.HS_ZERO);
printk("[JX] timming:0x%x\n",lcm_debug_timming.HS_PRPR);
printk("[JX] timming:0x%x\n",lcm_debug_timming.LPX);
printk("[JX] timming:0x%x\n",lcm_debug_timming.TA_SACK);
printk("[JX] timming:0x%x\n",lcm_debug_timming.TA_GET);
printk("[JX] timming:0x%x\n",lcm_debug_timming.TA_SURE);
printk("[JX] timming:0x%x\n",lcm_debug_timming.TA_GO);
printk("[JX] timming:0x%x\n",lcm_debug_timming.CLK_TRAIL);
printk("[JX] timming:0x%x\n",lcm_debug_timming.CLK_ZERO);
printk("[JX] timming:0x%x\n",lcm_debug_timming.LPX_WAIT);
printk("[JX] timming:0x%x\n",lcm_debug_timming.CONT_DET);
printk("[JX] timming:0x%x\n",lcm_debug_timming.CLK_HS_PRPR);
printk("[JX] timming:0x%x\n",lcm_debug_timming.pll_div1);
printk("[JX] timming:0x%x\n",lcm_debug_timming.pll_div2);
*/
// then write to lcm
if(lcm_debug_timming.HS_TRAIL!=0) {
lcm_params->dsi.HS_TRAIL = lcm_debug_timming.HS_TRAIL;
lcm_params->dsi.HS_ZERO = lcm_debug_timming.HS_ZERO;
lcm_params->dsi.HS_PRPR = lcm_debug_timming.HS_PRPR;
lcm_params->dsi.LPX = lcm_debug_timming.LPX;
lcm_params->dsi.TA_SACK = lcm_debug_timming.TA_SACK;
lcm_params->dsi.TA_GET = lcm_debug_timming.TA_GET;
lcm_params->dsi.TA_SURE = lcm_debug_timming.TA_SURE;
lcm_params->dsi.TA_GO = lcm_debug_timming.TA_GO;
lcm_params->dsi.CLK_TRAIL = lcm_debug_timming.CLK_TRAIL;
lcm_params->dsi.CLK_ZERO = lcm_debug_timming.CLK_ZERO;
lcm_params->dsi.LPX_WAIT = lcm_debug_timming.LPX_WAIT;
lcm_params->dsi.CONT_DET = lcm_debug_timming.CONT_DET;
lcm_params->dsi.CLK_HS_PRPR = lcm_debug_timming.CLK_HS_PRPR;
lcm_params->dsi.pll_div1 = lcm_debug_timming.pll_div1;
lcm_params->dsi.pll_div2 = lcm_debug_timming.pll_div2;
DSI_PHY_TIMCONFIG(lcm_params);
}
lcm_debug_reset();
//lcm_debug_read_reg();
for(i=0;i<lcm_debug_reg_info_num;i++) {
dsi_set_cmdq(&(lcm_debug_reg_info[i].pdata), lcm_debug_reg_info[i].queue_size, 1);
MDELAY(lcm_debug_reg_info[i].delay_ms);
}
printk("[JX] %s, send cmd done. \n",__func__);
return 0;
}
/*******************************************************
Function:
main of the lem debug function.
Input:
NULL
Output:
Error Report.
*********************************************************/
static int lcm_debug_main(void)
{
struct file *file_data = NULL;
mm_segment_t old_fs;
static s8* fw_path = "/data/lcm_init";
u32 file_len = 0;
u8 *file_ptr = NULL;
s32 ret = -1;
printk("[JX] %s.\n",__func__);
file_data = lcm_debug_file_open(fw_path, &old_fs);
if(file_data == NULL)
{
printk("[JX] Cannot open update file,Exit update.\n");
goto Done;
}
file_len = lcm_debug_get_file_length(fw_path);
printk("[JX] Update file length:%d.\n", file_len);
file_ptr = (u8*)vmalloc(file_len);
if(file_ptr==NULL)
{
printk("[JX] Cannot malloc memory,Exit update.\n");
goto FreeDone;
}
ret = file_data->f_op->read(file_data, file_ptr, file_len, &file_data->f_pos);
if(ret <= 0)
{
printk("[JX] Read file data failed,Exit update.\n");
goto FreeDone;
}
lcm_debug_file_close(file_data, old_fs);
// ret = lcm_debug_parse_cmd(file_ptr, file_len);
ret = lcm_debug_parse_cmd_2(file_ptr, file_len);
if(ret < 0)
{
printk("[JX] Update failed!Exit.\n");
goto Free;
}
vfree(file_ptr);
return 0;
Done:
lcm_debug_file_close(file_data, old_fs);
return 0;
FreeDone:
vfree(file_ptr);
lcm_debug_file_close(file_data, old_fs);
return 0;
Free:
vfree(file_ptr);
return 0;
}
#endif