This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DS90UB947-Q1: Init fail of 947

Part Number: DS90UB947-Q1

Hi team,

customer refer to the example code of 947 to init, but it report below information

TI947 Deserializer Detected retry:1
TI947 Error: Serializer is not in Normal state count:20

and the display is black.

I attached customer code(ds947_1) and schematic, the name of init f() is static void ti947948_tplcd_reset_init_new(void)

could you help to check it. thanks.

more information, before, customer didn't add TI example code, the display can be light but need about 2.7s time. I also attached customer's code without TI init reg setting. the file name is ds947-customer.

ds947_1.txt
//modify by hkh 2020325  add ti947948 hot plug
#include <linux/module.h>
#include <drm/drm_encoder_slave.h>
#include <linux/kthread.h>
#include <linux/of_gpio.h>

#if 1   //////////////////////modify by hkh
#define hkh_printk(format, args...) pr_emerg(format,##args)
#else
#define hkh_printk(format, args...) do {} while (0)	
#endif

struct ti947_i2c {
	struct class *cls;
	struct device *dev;
	struct i2c_client *client;
};
struct ti947_i2c *ti947_dev;


static int ds947_pwdn_gpio=-1;
//static int ds948_pwen_gpio=-1;
static struct i2c_client *ti947client=NULL;
static struct i2c_client *ti948client=NULL;

#define ti947_dbg(client, format, ...) do {				\
		if (drm_debug & DRM_UT_KMS)				\
			dev_printk(KERN_DEBUG, &client->dev,		\
				   "%s: " format, __func__, ## __VA_ARGS__); \
	} while (0)
#define ti947_info(client, format, ...)		\
	printk(format, __VA_ARGS__)
#define ti947_err(client, format, ...)			\
	printk(format, __VA_ARGS__)

#define TI947_I2C_ADDR_SLAVE			0xc
#define TI948_I2C_ADDR_SLAVE			0x2c

#if  defined(CONFIG_HONGJING_S61EV_PROJECT)||defined(CONFIG_HONGJING_S61_PROJECT)||defined(CONFIG_HONGJING_S61_T02_PROJECT)||defined(CONFIG_HONGJING_T19_PROJECT)
//// CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP6 
#define TP_I2c_ADDR_SLAVE			(0x24<<1)//0x48	//8bit CYTTSP6
#elif defined( CONFIG_HONGJING_S61_T01_PROJECT)
#define TP_I2c_ADDR_SLAVE			(0x5d<<1)       //8bit GOODIX
#else
#define TP_I2c_ADDR_SLAVE			(0x24<<1)//0x48	//8bit CYTTSP6
#endif

#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)
#define MCU_LCDTP_I2c_ADDR_SLAVE	(0x3c<<1)   //78    //8bit MCU_LCDTP
#define TI947_SLAVE_ID_2			0x71
#define TI947_SLAVE_ALIAS_2			0x78
#endif

/* 947 HW register definitions */
#define TI947_GENERAL_CONF		0x3
#define TI947_SLAVE_ID			0x7
#define TI947_SLAVE_ALIAS		0x8
#define TI947_GPIO0_CONF		0xd
#define TI947_GPIO2_CONF		0xe
#define TI947_GPIO3_CONF		0xf
#define TI947_BRIDGE_CTL		0x4f
#define TI947_SLAVE_ID_1			0x70
#define TI947_SLAVE_ALIAS_1			0x77
#define TI947948_ID_1				0xf3
#define TI947948_ID_2				0xf4
#define TI947948_ID_3				0xf5

/* 948 HW register definitions */
#define TI948_GPIO0_CONF		0x1d
#define TI948_GPIO2_CONF		0x1e
#define TI948_GPIO3_CONF		0x1f

static int ti947_i2c_read_u8(struct i2c_client *client,
			   u8 reg, u8 *buf, int len)
{
	struct i2c_msg msgs[2];
	int ret;

	msgs[0].flags = 0;
	msgs[0].addr  = client->addr;
	msgs[0].len   = 1;
	msgs[0].buf   = &reg;

	msgs[1].flags = I2C_M_RD;
	msgs[1].addr  = client->addr;
	msgs[1].len   = len;
	msgs[1].buf   = buf;
	
	ret = i2c_transfer(client->adapter, msgs, 2);

	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
}

static int ti947_i2c_write_u8(struct i2c_client *client, u8 reg, u8 buf)
{
	u8 *addr_buf;
	struct i2c_msg msg;
	int ret;

	addr_buf = kmalloc(2, GFP_KERNEL);
	if (!addr_buf)
		return -ENOMEM;

	addr_buf[0] = reg;
	memcpy(&addr_buf[1], &buf, 1);

	msg.flags = 0;
	msg.addr = client->addr;
	msg.buf = addr_buf;
	msg.len = 2;

	ret = i2c_transfer(client->adapter, &msg, 1);
	kfree(addr_buf);
	return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
}
/////////////////////////////////////////////////////////////////modify by hkh
static int detect_device(struct i2c_client *client)
{
	u8 ti947_id1;
//	u8 ti947_id1_1;
	u8 ti947_id2;
	u8 ti947_id3;
	ti947_i2c_read_u8(client, TI947948_ID_1, &ti947_id1, sizeof(ti947_id1));
	msleep(1);
//	ti947_i2c_read_u8(client, TI947948_ID_1, &ti947_id1_1, sizeof(ti947_id1_1));
	//msleep(20);
	ti947_i2c_read_u8(client, TI947948_ID_2, &ti947_id2, sizeof(ti947_id2));
	msleep(1);
	ti947_i2c_read_u8(client, TI947948_ID_3, &ti947_id3, sizeof(ti947_id3));
	msleep(1);
	//printk("id1,id1_1,id2,id3: 0x%x,0x%x,0x%x,0x%x\n", ti947_id1, ti947_id1_1, ti947_id2, ti947_id3);
	if ((ti947_id1 != 0x39) || ti947_id2 != 0x34 || (ti947_id3 != 0x37 && ti947_id3 != 0x38)) {
		printk("%s Unknown device %c%c%c\n",
			   __func__, ti947_id1, ti947_id2, ti947_id3);
		return -ENODEV;
	}
	printk("%s Detected device %c%c%c\n", __func__, ti947_id1, ti947_id2, ti947_id3);
	return 1;
}

///////////////////////////////////////////////////////////////////////////////////////
#if defined( CONFIG_HONGJING_T19_PROJECT)
static int ds948_pwen_gpio=-1;
extern int MCU_TPLCD_startup(void);

static void ti947948_tplcd_reset(void)
{
	if(gpio_is_valid(ds947_pwdn_gpio)&&gpio_is_valid(ds948_pwen_gpio))
	{
		pr_emerg("--------> %s\n",__func__);
		gpio_direction_output(ds947_pwdn_gpio, 1);
		//gpio_direction_output(ds948_pwen_gpio, 0);
		//pr_emerg("ds947_pwdn_gpio[%d]=1\n",ds947_pwdn_gpio);
		msleep(100);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		//gpio_direction_output(ds948_pwen_gpio, 1);
		//pr_emerg("ds947_pwdn_gpio[%d]=0\n",ds947_pwdn_gpio);
		msleep(500);
	}
}


int ti947948_Init_tplcd_1st(void)
{
	int i;
	u8  data;
	int ret ;
	//////   ti947   //////
	u8  ti947_reg[] = {0x17,0x4f,0x5b,0xc6,0x0d,0x0e,0x0f,0x1e,0x0f,0x1e,0x4f};
	u8  ti947_dat[] = {0x9e,0xc0,0x20,0x21,0x03,0x33,0x03,0x02,0x03,0x01,0x00};
	
	//////   ti948   //////
	u8 ti948_reg[] = {0x49,0x1d,0x1e,0x1f,0x34,0x1f,0x34,0x41};
	u8 ti948_dat[] = {0xe0,0x05,0x55,0x03,0x02,0x03,0x01,0x1f};

	pr_emerg("---start ti947948_Init--\r\n");
	//hkh_printk("=====%s=====\n",__func__);
	
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti947client)!=1)
	{
		//pr_emerg("%s:ti947 is not detected!\r\n",__func__);
		return 0;
	}
	
	//947 write
//	hkh_printk("=====947 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti947_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti947client,  ti947_reg[i], ti947_dat[i]);
		if(ret != 0)
			pr_emerg("===ti947 write reg:0x%x val:0x%x ret:%d fail===\n", ti947_reg[i], ti947_dat[i],ret);
		msleep(1);
	}

///////////////////////////////////////////////
//check station
	ret = ti947_i2c_read_u8(ti947client, 0x00, &data, sizeof(data));
//	hkh_printk("===947 read reg :0x00: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x18)
	{
		hkh_printk("===ti947 read reg :0x00!=0x18\n");
		return 0;
	}
	ret = ti947_i2c_read_u8(ti947client, 0x06, &data, sizeof(data));
	
	if(data!=0x58)
	{
		hkh_printk("===ti947 read reg :0x06!=0x58\n");
		return 0;
	}
	
////////
	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti948client)!=1)
	{
		//pr_emerg("%s: ti948 is not detected!\r\n",__func__);
		return 0;
	}
//
	ret = ti947_i2c_read_u8(ti948client, 0x06, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x00)
	{
		hkh_printk("===ti948 read reg :0x06!=0x00\n");
		return 0;
	}
	ret = ti947_i2c_read_u8(ti948client, 0x00, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		hkh_printk("===ti948 read reg :0x00!=0x58\n");
		return 0;
	}
	for(i=0;i<10;i++)
	{
		ret = ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
	//	hkh_printk("===948 read reg :0x1c: val:0x%x ret:%d i:%d===\n",data,ret,i);
		if((data&0x0f) != 0x03)  //lock
		{
			hkh_printk("ti948 not locked! i:%d\n",i);
			return 0;
		}
		msleep(10);
	}
////////////////////////////////////////////////
	
	//948 write
//	hkh_printk("=====948 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti948_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti948client, ti948_reg[i], ti948_dat[i]);
		if(ret != 0)
			hkh_printk("===948 write reg:0x%x val:0x%x ret:%d fail===\n", ti948_reg[i], ti948_dat[i],ret);
		msleep(1);
	}
////////////////////////////////////////////////	
	return 1;
}

int ti947948_Init_tplcd_2nd(void)
{
	int i;
	u8  data;
	int ret ;	
//////   ti947   //////
	u8  ti947_reg[] = {0x17,0x4f,0x5b,0xc6,0x0d,0x0e,0x0f,0x1e,0x0f,0x1e,0x4f};
	u8  ti947_dat[] = {0x9e,0xc0,0x20,0x21,0x05,0x33,0x05,0x02,0x03,0x01,0x00};
	
//////   ti948   //////
	u8 ti948_reg[] = {0x49,0x1d,0x1e,0x1f,0x34,0x1f,0x34,0x41};
	u8 ti948_dat[] = {0xe0,0x05,0x55,0x03,0x02,0x05,0x01,0x1f};

	//pr_emerg("---start ti947948_Init--\r\n");
	//hkh_printk("=====%s=====\n",__func__);
/*	
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti947client)!=1)
	{
		pr_emerg("%s:ti947 is not detected!\r\n",__func__);
		return 0;
	}
*/
	//947 write
//	hkh_printk("=====947 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti947_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti947client,  ti947_reg[i], ti947_dat[i]);
		if(ret != 0)
			hkh_printk("===947 write reg:0x%x val:0x%x ret:%d fail===\n", ti947_reg[i], ti947_dat[i],ret);
		msleep(1);
	}

///////////////////////////////////////////////
//check station
/*	ret = ti947_i2c_read_u8(ti947client, 0x00, &data, sizeof(data));
	hkh_printk("===947 read reg :0x00: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x18)
	{
		return 0;
	}
	ret = ti947_i2c_read_u8(ti947client, 0x06, &data, sizeof(data));
	hkh_printk("===947 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		return 0;
	}
	*/
////////
/*	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti948client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return 0;
	}
//
	ret = ti947_i2c_read_u8(ti948client, 0x06, &data, sizeof(data));
	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x00)
	{
		return 0;
	}
	ret = ti947_i2c_read_u8(ti948client, 0x00, &data, sizeof(data));
	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		return 0;
	}*/
	ret = ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x1c: val:0x%x ret:%d===\n",data,ret);
	if((data&0x0f) != 0x03)  //lock
	{
		hkh_printk("ti948 not locked! i:%d\n",i);
		return 0;
	}
	else
	{
		hkh_printk("ti948 lock! i:%d\n",i);
	}
	
////////////////////////////////////////////////
	
	//948 write
//	hkh_printk("=====948 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti948_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti948client, ti948_reg[i], ti948_dat[i]);
		if(ret != 0)
			hkh_printk("===948 write reg:0x%x val:0x%x ret:%d fail===\n", ti948_reg[i], ti948_dat[i],ret);
		msleep(1);	
	}
////////////////////////////////////////////////	
	return 1;	
}

static void ti947948_tplcd_reset_init(void)
{
	int count_num=0;
	int ret=0;
	while(ret==0)
	{
		ret=ti947948_Init_tplcd_1st();
		printk("%s count_num:%d ret:%d\n", __func__,count_num,ret);
		if(ret)
			break;
		msleep(100);
		count_num++;
		if(count_num>=10)
		{
			ti947948_tplcd_reset();
			count_num=0;
			msleep(100);
		}
		//ret=ti947948_Init_tplcd_1st();
	}
	for(count_num=0;count_num<10;count_num++)
	{
		ret=ti947948_Init_tplcd_2nd();
		if(ret)
		{
			printk("%s2 ok count_num:%d ret:%d\n", __func__,count_num,ret);
			break;
		}
		else
		{
			msleep(100);
			printk("%s2 fail count_num:%d ret:%d\n", __func__,count_num,ret);
		}

	}
#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)	
	MCU_TPLCD_startup();
#endif
}

static int pollstate(void)
{
	int ret = 0, count = 0;
	u8 state = 0;
	ret = ti947_i2c_write_u8(ti947client,  0x23, 0x80);
	ret = ti947_i2c_write_u8(ti947client,  0x24, 0x80);
	ti947_i2c_read_u8(ti947client, 0x24, &state, sizeof(state));
	while((state & 0x1f) != 27){
		msleep(10);
		ti947_i2c_read_u8(ti947client, 0x24, &state, sizeof(state));
		count++;
		if(count == 20){
			printk("TI947 Error: Serializer is not in Normal state count:%d\n", count);
			return(1);
		}
	}
	ret = ti947_i2c_write_u8(ti947client,  0x23, 0x0);
	ret = ti947_i2c_write_u8(ti947client,  0x24, 0x0);
	return 0;
}
static void ti947948_tplcd_reset_init_new(void)
{
	int ret = 0, retry = 0, linked = 0, i = 0;
	u8 reg_947 = 0;
//	int Hhigh = 0, Hlow = 0, Vhigh = 0, Vlow = 0;
	u8  ti947_reg[] = {0x40,0x41,0x42,0x41,0x42,0x41,0x42,0x42,0x40,0x41,0x42,0x41,0x42,0x41,0x42,0x42,0x40,0x41,0x42,0x41,0x42,0x42,0x42,0x42,0x41,0x42};
	u8  ti947_dat[] = {0x10,0x4A,0x3F,0x4B,0x89,0x49,0x10,0x00,0x14,0x4A,0x3F,0x4B,0x89,0x49,0x10,0x00,0x10,0x49,0x16,0x47,0x20,0xA0,0x20,0x00,0x49,0x00};

	ret = ti947_i2c_write_u8(ti947client,  0x03, 0xDA);//Set I2C passthrough

	while(!linked){
		ret = ti947_i2c_read_u8(ti947client, 0x5A, &reg_947, sizeof(reg_947));
		if((reg_947 & 0x80) != 0){
            linked = 1;
            printk("TI947 Deserializer Detected retry:%d\n",retry);
		}
		else
		{
			hkh_printk("TI947 read reg:0x5A val:0x%x ret:%d retry:%d\n", reg_947, ret, retry);
			msleep(100);
			retry++;
			if(retry == 10){
				printk("TI947 Error: No Deserializer Detected\n");
			}
		}
	}
	ret = ti947_i2c_write_u8(ti948client,  0x4A, 0x01);//Disable OLDI outputs on 948 to prevent screen glitches from appearing during the init process
	ret = ti947_i2c_write_u8(ti947client,  0x5B, 0x03);//Force dual FPD-Link, disable reset on PLL frequency change
	ret = ti947_i2c_write_u8(ti947client,  0x16, 0x02);//Adjust BCC watchdog timer to minimum
	ret = ti947_i2c_write_u8(ti947client,  0x04, 0x90);//Prevent AVMUTE for non-HDCP systems

	ret = pollstate();//Poll 947 state machine prior to applying init B errata
	if(ret  == 1){
		printk("TI947 Error: Poll 947 state machine\n");
	}

	for (i = 0; i < ARRAY_SIZE( ti947_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti947client,  ti947_reg[i], ti947_dat[i]);
		if(ret != 0)
			hkh_printk("===947 write reg:0x%x val:0x%x ret:%d fail===\n", ti947_reg[i], ti947_dat[i],ret);
		//msleep(1);
	}
	msleep(10);
	retry = 0;
/*
	while(retry < 3){
		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x08);//Enable PATGEN BIST
		msleep(10);//Critical time delay - do not adjust to a shorter value 
		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x19);//H active High monitor
		ret = ti947_i2c_read_u8(ti948client, 0x69, &Hhigh, sizeof(Hhigh));
		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x09);//H active Low monitor
		ret = ti947_i2c_read_u8(ti948client, 0x69, &Hlow, sizeof(Hlow));

		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x39);//V active High monitor
		ret = ti947_i2c_read_u8(ti948client, 0x69, &Vhigh, sizeof(Vhigh));
		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x29);//V active Low monitor
		ret = ti947_i2c_read_u8(ti948client, 0x69, &Vlow, sizeof(Vlow));
		ret = ti947_i2c_write_u8(ti948client,  0x68, 0x00);//Disable PATGEN BIST
	}
*/
	printk("TI947: Initialization Complete\n");
	ret = ti947_i2c_write_u8(ti948client,  0x01, 0x01);//Digital reset to restart AEQ
	msleep(100);//Allow time for 948 to relock
	ret = ti947_i2c_write_u8(ti948client,  0x4A, 0x00);//Enable OLDI outputs on 948

#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)	
	MCU_TPLCD_startup();
#endif
	while(1){
		printk("TI947: enter loop\n");
		msleep(1000);
	}
}
static void ti947_tplcd_check_process(void)
{
	u8 reg_947 = 0;
	if(ti947client!=NULL)
	{
		ti947_i2c_read_u8(ti947client, 0x17, &reg_947, sizeof(reg_947));
		if(reg_947==0x9e)
		{
			ti947_i2c_read_u8(ti947client, 0x0e, &reg_947, sizeof(reg_947));
			if(reg_947==0x33)
			{
				ti947_i2c_read_u8(ti947client, 0xc6, &reg_947, sizeof(reg_947));
				if(reg_947!=0x21)
				{
					pr_emerg("--------> %s 3\n",__func__);
					ti947948_tplcd_reset_init();
				}
			}
			else
			{
				pr_emerg("--------> %s 2\n",__func__);
				ti947948_tplcd_reset_init();
			}
		}
		else
		{
			pr_emerg("--------> %s 1\n",__func__);
			ti947948_tplcd_reset_init();
		}
	}
}
#else

void ti947_Init(void)
{
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return;
	}
	if(detect_device(ti947client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return;
	}
	ti947_i2c_write_u8(ti947client, TI947_GENERAL_CONF , 0xda);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID , TI948_I2C_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS , TI948_I2C_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID_1 , TP_I2c_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS_1 , TP_I2c_ADDR_SLAVE);
	msleep(20);
//#if defined( CONFIG_HONGJING_S61_T01_PROJECT)||defined( CONFIG_HONGJING_S61_T02_PROJECT)||defined( CONFIG_HONGJING_T19_PROJECT)
#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID_2 , MCU_LCDTP_I2c_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS_2 , MCU_LCDTP_I2c_ADDR_SLAVE);
	msleep(20);
#endif
	ti947_i2c_write_u8(ti947client, TI947_GPIO0_CONF , 0x3);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_GPIO2_CONF , 0x30);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_GPIO3_CONF , 0x3);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_BRIDGE_CTL , 0x0);
}

void ti948_Init(void)
{
	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return;
	}
	if(detect_device(ti948client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return;
	}
	ti947_i2c_write_u8(ti948client, TI948_GPIO0_CONF , 0x5);
	msleep(20);
	ti947_i2c_write_u8(ti948client, TI948_GPIO2_CONF , 0x50);
	msleep(20);
	ti947_i2c_write_u8(ti948client, TI948_GPIO3_CONF , 0x5);
}

static void ti947948_reset(void)
{
	if(gpio_is_valid(ds947_pwdn_gpio))
	{
		pr_emerg("--------> %s\n",__func__);
		gpio_direction_output(ds947_pwdn_gpio, 1);
		//pr_emerg("ds947_pwdn_gpio[%d]=1\n",ds947_pwdn_gpio);
		msleep(100);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		//pr_emerg("ds947_pwdn_gpio[%d]=0\n",ds947_pwdn_gpio);
		msleep(20);
		ti947_Init();
	}
}

static void ti947_check_process(void)
{
	u8 reg_947 = 0;
	if(ti947client!=NULL)
	{
		ti947_i2c_read_u8(ti947client, TI947_GENERAL_CONF, &reg_947, sizeof(reg_947));
		if(reg_947==0xda)
		{
			ti947_i2c_read_u8(ti947client, TI947_SLAVE_ID, &reg_947, sizeof(reg_947));
			if(reg_947==TI948_I2C_ADDR_SLAVE)
			{
				ti947_i2c_read_u8(ti947client, TI947_SLAVE_ALIAS, &reg_947, sizeof(reg_947));
				if(reg_947!=TI948_I2C_ADDR_SLAVE)
				{
					pr_emerg("--------> %s 3\n",__func__);
					ti947948_reset();
				}
			}
			else
			{
				pr_emerg("--------> %s 2\n",__func__);
				ti947948_reset();
			}
		}
		else
		{
			pr_emerg("--------> %s 1\n",__func__);
			ti947948_reset();
		}
	}
}

extern int cyttsp6_restartup(void);
void ti9x7_reInit(void)
{
	int i;
	u8 data;
	int ret ;
	hkh_printk("---%s--\r\n",__func__);

	if(ti947client==NULL || ti948client==NULL)
	{
		pr_emerg("%s:ti947client==NULL || ti948client==NULL\r\n",__func__);
		return;
	}

	for(i=0;i<10;i++)
	{
		data=0;
		ret=ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
		hkh_printk("%s :0x1c: 0x%x\n",__func__,data);
		if(data == 0x23)
		{
			pr_emerg("948 already lock\n");
			break;
		}else if(ret < 0)
		{
			pr_emerg("read 948 error\n");
			if(i >= 9)
			{
				return;
			}
		}
		msleep(1);
	}
	ti947_Init();
	ti948_Init();
	cyttsp6_restartup();
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////
#if defined( CONFIG_HONGJING_T19_PROJECT)
int thread_func_init(void *arg) 
{
	u8 status_948 = 0;
	int count_num=0;
	int ret=0;
//	pr_emerg("=====%s: ti9x7_Init() start=====\n",__func__);
	ti947948_tplcd_reset_init_new();
//	ti947948_tplcd_reset_init();
//	pr_emerg("=====%s: ti9x7_Init() end=====\n",__func__);
	while(1) {
		if(ti947client!=NULL&&ti948client!=NULL)
		{
			ti947_tplcd_check_process();
		
			status_948=0;
			ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
	//		hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
			if (((status_948&0x0f) != 0x03)||( ret < 0))
			{
	//			pr_emerg("%s:status_948= 0x%x, ret=%d\n",__func__, status_948,ret);
				for (count_num=0;count_num<10;count_num++)
				{
					msleep(100);
					status_948=0;
					ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
	//				hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
					if (((status_948&0x0f) == 0x03))
					{
						break;
					}
					else
					{
						pr_emerg("%s:status_948= 0x%x, ret=%d not lock!\n",__func__, status_948,ret);
					}
				}
				if(count_num>=10)
				{
	//				pr_emerg("-------->%s:status_948= 0x%x, ret=%d\n",__func__, status_948, ret);
					pr_emerg("--------> %s: 947,948 not lock reinit!\n",__func__);
					ti947948_tplcd_reset_init();
	//				pr_emerg("--------> %s: 947,948 lock\n",__func__);
				}
			}
			else
			{
			}
		}
		msleep(1000);
	}
	return 0;
}
#else
int is_927928_lock=0;
int thread_func_init(void *arg) 
{
	u8 status_948 = 0;
	u8 status_948_1F = 0;
	int count_num=0;
	int ret ;
	ti947948_reset();
	ti948_Init();
	hkh_printk("=====%s: ti9x7_Init() end=====\n",__func__);
	while(1) {
		if(ti947client!=NULL&&ti948client!=NULL)
		{
			ti947_check_process();
		
			status_948=status_948_1F=0;
			ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
			hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
			ret=ti947_i2c_read_u8(ti948client, 0x1f, &status_948_1F, sizeof(status_948_1F));
			hkh_printk("%s:status_948_1F= 0x%x,   ret=%d\n",__func__, status_948_1F,ret);
			if(((status_948&0x0f) == 0x03) && (!is_927928_lock) /*&& (status_948_1F != 0x05)*/)
			{
				ti9x7_reInit();
				is_927928_lock = 1;
				pr_emerg(" %s:947,948 already lock\n",__func__);
			}
			else if (((status_948&0x0f) != 0x03)||( ret < 0)||(status_948_1F != 0x05))
			{
				pr_emerg("%s:status_948= 0x%x,status_948_1F= 0x%x,   ret=%d\n",__func__, status_948, status_948_1F,ret);
				for (count_num=0;count_num<10;count_num++)
				{
					msleep(100);
					status_948=status_948_1F=0;
					ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
					hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
					ret=ti947_i2c_read_u8(ti948client, 0x1f, &status_948_1F, sizeof(status_948_1F));
					hkh_printk("%s:status_948_1F= 0x%x,   ret=%d\n",__func__, status_948_1F,ret);
					if (((status_948&0x0f) == 0x03)&&(status_948_1F == 0x05))
					{
						break;
					}
				}
				if(count_num>=10)
				{
					pr_emerg("-------->%s:status_948= 0x%x,status_948_1F= 0x%x,   ret=%d\n",__func__, status_948, status_948_1F,ret);
					pr_emerg("--------> %s: 947,948 not lock\n",__func__);
					is_927928_lock = 0;
					ti947948_reset();
				}
			}
			else
			{
			}
		}
		msleep(1000);
	}
	return 0;
}
#endif
//////////////////////////////////////////////////////////////modify by hkh

static int
ti947_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct task_struct* my_thread = NULL;
	int rc = 0;
	struct device_node *np;
	
	ti947_dev = kzalloc(sizeof(*ti947_dev), GFP_KERNEL);
	if (!ti947_dev)
		return -ENOMEM;

	printk("%s\n", __func__);
	np = client->dev.of_node;
	ti947_dev->client = client;

	if (client->addr == 0xc) {
		ti947client = client;
		ds947_pwdn_gpio= of_get_named_gpio(np, "pwdn-gpios", 0);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		pr_emerg("ds947_pwdn_gpio= %d\n",ds947_pwdn_gpio);
	}
	if (client->addr == 0x2c) {
		ti948client = client;

//#if defined( CONFIG_HONGJING_T19_PROJECT)
	//	ds948_pwen_gpio=of_get_named_gpio(np,"pwen-gpios", 0);
	//	pr_emerg("ds948_pwen_gpio= %d\n",ds948_pwen_gpio);
	//	gpio_direction_output(ds948_pwen_gpio, 0);
//#endif		
		my_thread = kthread_run(thread_func_init,NULL,"947948init_thread");
		if (IS_ERR(my_thread))
		{
			rc = PTR_ERR(my_thread);
			pr_emerg("error %d create thread_name \n",rc);
		}
	}
	return 0;
}

static int
ti947_remove(struct i2c_client *client)
{
	if (gpio_is_valid(ds947_pwdn_gpio))
		gpio_free(ds947_pwdn_gpio);
#if defined( CONFIG_HONGJING_T19_PROJECT)	
	if (gpio_is_valid(ds948_pwen_gpio))
		gpio_free(ds948_pwen_gpio);
#endif	
	kfree(ti947_dev);
	return 0;
}

static struct i2c_device_id ti947_ids[] = {
	{ "ti947", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ti947_ids);

static const struct of_device_id ti947_of_match[] = {
	{ .compatible = "ti,ds947948" },
	{ }
};
MODULE_DEVICE_TABLE(of, ti947_of_match);

static struct i2c_driver ti947_driver = {
	.probe = ti947_probe,
	.remove = ti947_remove,
	.driver = {
		.name = "ti947",
		.of_match_table = of_match_ptr(ti947_of_match),
	},
	.id_table = ti947_ids,
};

module_i2c_driver(ti947_driver);

MODULE_AUTHOR("wimin.zhong");
MODULE_DESCRIPTION("TI-947 driver");
MODULE_LICENSE("GPL v2");

ds947-customer.txt
//modify by hkh 2020325  add ti947948 hot plug
#include <linux/module.h>
#include <drm/drm_encoder_slave.h>
#include <linux/kthread.h>
#include <linux/of_gpio.h>

#if 1   //////////////////////modify by hkh
#define hkh_printk(format, args...) pr_emerg(format,##args)
#else
#define hkh_printk(format, args...) do {} while (0)	
#endif

struct ti947_i2c {
	struct class *cls;
	struct device *dev;
	struct i2c_client *client;
};
struct ti947_i2c *ti947_dev;


static int ds947_pwdn_gpio=-1;
//static int ds948_pwen_gpio=-1;
static struct i2c_client *ti947client=NULL;
static struct i2c_client *ti948client=NULL;

#define ti947_dbg(client, format, ...) do {				\
		if (drm_debug & DRM_UT_KMS)				\
			dev_printk(KERN_DEBUG, &client->dev,		\
				   "%s: " format, __func__, ## __VA_ARGS__); \
	} while (0)
#define ti947_info(client, format, ...)		\
	printk(format, __VA_ARGS__)
#define ti947_err(client, format, ...)			\
	printk(format, __VA_ARGS__)

#define TI947_I2C_ADDR_SLAVE			0xc
#define TI948_I2C_ADDR_SLAVE			0x2c

#if  defined(CONFIG_HONGJING_S61EV_PROJECT)||defined(CONFIG_HONGJING_S61_PROJECT)||defined(CONFIG_HONGJING_S61_T02_PROJECT)||defined(CONFIG_HONGJING_T19_PROJECT)
//// CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP6 
#define TP_I2c_ADDR_SLAVE			(0x24<<1)//0x48	//8bit CYTTSP6
#elif defined( CONFIG_HONGJING_S61_T01_PROJECT)
#define TP_I2c_ADDR_SLAVE			(0x5d<<1)       //8bit GOODIX
#else
#define TP_I2c_ADDR_SLAVE			(0x24<<1)//0x48	//8bit CYTTSP6
#endif

#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)
#define MCU_LCDTP_I2c_ADDR_SLAVE	(0x3c<<1)   //78    //8bit MCU_LCDTP
#define TI947_SLAVE_ID_2			0x71
#define TI947_SLAVE_ALIAS_2			0x78
#endif

/* 947 HW register definitions */
#define TI947_GENERAL_CONF		0x3
#define TI947_SLAVE_ID			0x7
#define TI947_SLAVE_ALIAS		0x8
#define TI947_GPIO0_CONF		0xd
#define TI947_GPIO2_CONF		0xe
#define TI947_GPIO3_CONF		0xf
#define TI947_BRIDGE_CTL		0x4f
#define TI947_SLAVE_ID_1			0x70
#define TI947_SLAVE_ALIAS_1			0x77
#define TI947948_ID_1				0xf3
#define TI947948_ID_2				0xf4
#define TI947948_ID_3				0xf5

/* 948 HW register definitions */
#define TI948_GPIO0_CONF		0x1d
#define TI948_GPIO2_CONF		0x1e
#define TI948_GPIO3_CONF		0x1f

static int ti947_i2c_read_u8(struct i2c_client *client,
			   u8 reg, u8 *buf, int len)
{
	struct i2c_msg msgs[2];
	int ret;

	msgs[0].flags = 0;
	msgs[0].addr  = client->addr;
	msgs[0].len   = 1;
	msgs[0].buf   = &reg;

	msgs[1].flags = I2C_M_RD;
	msgs[1].addr  = client->addr;
	msgs[1].len   = len;
	msgs[1].buf   = buf;
	
	ret = i2c_transfer(client->adapter, msgs, 2);

	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
}

static int ti947_i2c_write_u8(struct i2c_client *client, u8 reg, u8 buf)
{
	u8 *addr_buf;
	struct i2c_msg msg;
	int ret;

	addr_buf = kmalloc(2, GFP_KERNEL);
	if (!addr_buf)
		return -ENOMEM;

	addr_buf[0] = reg;
	memcpy(&addr_buf[1], &buf, 1);

	msg.flags = 0;
	msg.addr = client->addr;
	msg.buf = addr_buf;
	msg.len = 2;

	ret = i2c_transfer(client->adapter, &msg, 1);
	kfree(addr_buf);
	return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
}
/////////////////////////////////////////////////////////////////modify by hkh
static int detect_device(struct i2c_client *client)
{
	u8 ti947_id1;
//	u8 ti947_id1_1;
	u8 ti947_id2;
	u8 ti947_id3;
	ti947_i2c_read_u8(client, TI947948_ID_1, &ti947_id1, sizeof(ti947_id1));
	msleep(1);
//	ti947_i2c_read_u8(client, TI947948_ID_1, &ti947_id1_1, sizeof(ti947_id1_1));
	//msleep(20);
	ti947_i2c_read_u8(client, TI947948_ID_2, &ti947_id2, sizeof(ti947_id2));
	msleep(1);
	ti947_i2c_read_u8(client, TI947948_ID_3, &ti947_id3, sizeof(ti947_id3));
	msleep(1);
	//printk("id1,id1_1,id2,id3: 0x%x,0x%x,0x%x,0x%x\n", ti947_id1, ti947_id1_1, ti947_id2, ti947_id3);
	if ((ti947_id1 != 0x39) || ti947_id2 != 0x34 || (ti947_id3 != 0x37 && ti947_id3 != 0x38)) {
		printk("%s Unknown device %c%c%c\n",
			   __func__, ti947_id1, ti947_id2, ti947_id3);
		return -ENODEV;
	}
	printk("%s Detected device %c%c%c\n", __func__, ti947_id1, ti947_id2, ti947_id3);
	return 1;
}

///////////////////////////////////////////////////////////////////////////////////////
#if defined( CONFIG_HONGJING_T19_PROJECT)
static int ds948_pwen_gpio=-1;
extern int MCU_TPLCD_startup(void);

static void ti947948_tplcd_reset(void)
{
	if(gpio_is_valid(ds947_pwdn_gpio)&&gpio_is_valid(ds948_pwen_gpio))
	{
		pr_emerg("--------> %s\n",__func__);
		gpio_direction_output(ds947_pwdn_gpio, 1);
		//gpio_direction_output(ds948_pwen_gpio, 0);
		//pr_emerg("ds947_pwdn_gpio[%d]=1\n",ds947_pwdn_gpio);
		msleep(100);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		//gpio_direction_output(ds948_pwen_gpio, 1);
		//pr_emerg("ds947_pwdn_gpio[%d]=0\n",ds947_pwdn_gpio);
		msleep(500);
	}
}


int ti947948_Init_tplcd_1st(void)
{
	int i;
	u8  data;
	int ret ;
	//////   ti947   //////
	u8  ti947_reg[] = {0x17,0x4f,0x5b,0xc6,0x0d,0x0e,0x0f,0x1e,0x0f,0x1e,0x4f};
	u8  ti947_dat[] = {0x9e,0xc0,0x20,0x21,0x03,0x33,0x03,0x02,0x03,0x01,0x00};
	
	//////   ti948   //////
	u8 ti948_reg[] = {0x49,0x1d,0x1e,0x1f,0x34,0x1f,0x34,0x41};
	u8 ti948_dat[] = {0xe0,0x05,0x55,0x03,0x02,0x03,0x01,0x1f};

	pr_emerg("---start ti947948_Init--\r\n");
	//hkh_printk("=====%s=====\n",__func__);
	
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti947client)!=1)
	{
		//pr_emerg("%s:ti947 is not detected!\r\n",__func__);
		return 0;
	}
	
	//947 write
//	hkh_printk("=====947 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti947_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti947client,  ti947_reg[i], ti947_dat[i]);
		if(ret != 0)
			pr_emerg("===ti947 write reg:0x%x val:0x%x ret:%d fail===\n", ti947_reg[i], ti947_dat[i],ret);
		msleep(1);
	}

///////////////////////////////////////////////
//check station
	ret = ti947_i2c_read_u8(ti947client, 0x00, &data, sizeof(data));
//	hkh_printk("===947 read reg :0x00: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x18)
	{
		hkh_printk("===ti947 read reg :0x00!=0x18\n");
		return 0;
	}
	ret = ti947_i2c_read_u8(ti947client, 0x06, &data, sizeof(data));
	
	if(data!=0x58)
	{
		hkh_printk("===ti947 read reg :0x06!=0x58\n");
		return 0;
	}
	
////////
	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti948client)!=1)
	{
		//pr_emerg("%s: ti948 is not detected!\r\n",__func__);
		return 0;
	}
//
	ret = ti947_i2c_read_u8(ti948client, 0x06, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x00)
	{
		hkh_printk("===ti948 read reg :0x06!=0x00\n");
		return 0;
	}
	ret = ti947_i2c_read_u8(ti948client, 0x00, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		hkh_printk("===ti948 read reg :0x00!=0x58\n");
		return 0;
	}
	for(i=0;i<10;i++)
	{
		ret = ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
	//	hkh_printk("===948 read reg :0x1c: val:0x%x ret:%d i:%d===\n",data,ret,i);
		if((data&0x0f) != 0x03)  //lock
		{
			hkh_printk("ti948 not locked! i:%d\n",i);
			return 0;
		}
		msleep(10);
	}
////////////////////////////////////////////////
	
	//948 write
//	hkh_printk("=====948 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti948_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti948client, ti948_reg[i], ti948_dat[i]);
		if(ret != 0)
			hkh_printk("===948 write reg:0x%x val:0x%x ret:%d fail===\n", ti948_reg[i], ti948_dat[i],ret);
		msleep(1);
	}
////////////////////////////////////////////////	
	return 1;
}

int ti947948_Init_tplcd_2nd(void)
{
	int i;
	u8  data;
	int ret ;	
//////   ti947   //////
	u8  ti947_reg[] = {0x17,0x4f,0x5b,0xc6,0x0d,0x0e,0x0f,0x1e,0x0f,0x1e,0x4f};
	u8  ti947_dat[] = {0x9e,0xc0,0x20,0x21,0x05,0x33,0x05,0x02,0x03,0x01,0x00};
	
//////   ti948   //////
	u8 ti948_reg[] = {0x49,0x1d,0x1e,0x1f,0x34,0x1f,0x34,0x41};
	u8 ti948_dat[] = {0xe0,0x05,0x55,0x03,0x02,0x05,0x01,0x1f};

	//pr_emerg("---start ti947948_Init--\r\n");
	//hkh_printk("=====%s=====\n",__func__);
/*	
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti947client)!=1)
	{
		pr_emerg("%s:ti947 is not detected!\r\n",__func__);
		return 0;
	}
*/
	//947 write
//	hkh_printk("=====947 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti947_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti947client,  ti947_reg[i], ti947_dat[i]);
		if(ret != 0)
			hkh_printk("===947 write reg:0x%x val:0x%x ret:%d fail===\n", ti947_reg[i], ti947_dat[i],ret);
		msleep(1);
	}

///////////////////////////////////////////////
//check station
/*	ret = ti947_i2c_read_u8(ti947client, 0x00, &data, sizeof(data));
	hkh_printk("===947 read reg :0x00: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x18)
	{
		return 0;
	}
	ret = ti947_i2c_read_u8(ti947client, 0x06, &data, sizeof(data));
	hkh_printk("===947 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		return 0;
	}
	*/
////////
/*	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return 0;
	}
	if(detect_device(ti948client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return 0;
	}
//
	ret = ti947_i2c_read_u8(ti948client, 0x06, &data, sizeof(data));
	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x00)
	{
		return 0;
	}
	ret = ti947_i2c_read_u8(ti948client, 0x00, &data, sizeof(data));
	hkh_printk("===948 read reg :0x06: val:0x%x ret:%d===\n",data,ret);
	if(data!=0x58)
	{
		return 0;
	}*/
	ret = ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
//	hkh_printk("===948 read reg :0x1c: val:0x%x ret:%d===\n",data,ret);
	if((data&0x0f) != 0x03)  //lock
	{
		hkh_printk("ti948 not locked! i:%d\n",i);
		return 0;
	}
	else
	{
		hkh_printk("ti948 lock! i:%d\n",i);
	}
	
////////////////////////////////////////////////
	
	//948 write
//	hkh_printk("=====948 write ======\n");
	for (i = 0; i < ARRAY_SIZE( ti948_reg); i++)
	{
		ret = ti947_i2c_write_u8(ti948client, ti948_reg[i], ti948_dat[i]);
		if(ret != 0)
			hkh_printk("===948 write reg:0x%x val:0x%x ret:%d fail===\n", ti948_reg[i], ti948_dat[i],ret);
		msleep(1);	
	}
////////////////////////////////////////////////	
	return 1;	
}

static void ti947948_tplcd_reset_init(void)
{
	int count_num=0;
	int ret=0;
	while(ret==0)
	{
		ret=ti947948_Init_tplcd_1st();
		printk("%s count_num:%d ret:%d\n", __func__,count_num,ret);
		if(ret)
			break;
		msleep(100);
		count_num++;
		if(count_num>=10)
		{
			ti947948_tplcd_reset();
			count_num=0;
			msleep(100);
		}
		//ret=ti947948_Init_tplcd_1st();
	}
	for(count_num=0;count_num<10;count_num++)
	{
		ret=ti947948_Init_tplcd_2nd();
		if(ret)
		{
			printk("%s2 ok count_num:%d ret:%d\n", __func__,count_num,ret);
			break;
		}
		else
		{
			msleep(100);
			printk("%s2 fail count_num:%d ret:%d\n", __func__,count_num,ret);
		}

	}
#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)	
	MCU_TPLCD_startup();
#endif
}


static void ti947_tplcd_check_process(void)
{
	u8 reg_947 = 0;
	if(ti947client!=NULL)
	{
		ti947_i2c_read_u8(ti947client, 0x17, &reg_947, sizeof(reg_947));
		if(reg_947==0x9e)
		{
			ti947_i2c_read_u8(ti947client, 0x0e, &reg_947, sizeof(reg_947));
			if(reg_947==0x33)
			{
				ti947_i2c_read_u8(ti947client, 0xc6, &reg_947, sizeof(reg_947));
				if(reg_947!=0x21)
				{
					pr_emerg("--------> %s 3\n",__func__);
					ti947948_tplcd_reset_init();
				}
			}
			else
			{
				pr_emerg("--------> %s 2\n",__func__);
				ti947948_tplcd_reset_init();
			}
		}
		else
		{
			pr_emerg("--------> %s 1\n",__func__);
			ti947948_tplcd_reset_init();
		}
	}
}
#else

void ti947_Init(void)
{
	if(ti947client==NULL)
	{
		pr_emerg("%s:ti947client=NULL\r\n",__func__);
		return;
	}
	if(detect_device(ti947client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return;
	}
	ti947_i2c_write_u8(ti947client, TI947_GENERAL_CONF , 0xda);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID , TI948_I2C_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS , TI948_I2C_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID_1 , TP_I2c_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS_1 , TP_I2c_ADDR_SLAVE);
	msleep(20);
//#if defined( CONFIG_HONGJING_S61_T01_PROJECT)||defined( CONFIG_HONGJING_S61_T02_PROJECT)||defined( CONFIG_HONGJING_T19_PROJECT)
#if defined( CONFIG_HONGJING_MCU_TPLCD_SUPPORT)
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ID_2 , MCU_LCDTP_I2c_ADDR_SLAVE);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_SLAVE_ALIAS_2 , MCU_LCDTP_I2c_ADDR_SLAVE);
	msleep(20);
#endif
	ti947_i2c_write_u8(ti947client, TI947_GPIO0_CONF , 0x3);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_GPIO2_CONF , 0x30);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_GPIO3_CONF , 0x3);
	msleep(20);
	ti947_i2c_write_u8(ti947client, TI947_BRIDGE_CTL , 0x0);
}

void ti948_Init(void)
{
	if(ti948client==NULL)
	{
		pr_emerg("%s:ti948client=NULL\r\n",__func__);
		return;
	}
	if(detect_device(ti948client)!=1)
	{
		pr_emerg("%s:Unknown device\r\n",__func__);
		return;
	}
	ti947_i2c_write_u8(ti948client, TI948_GPIO0_CONF , 0x5);
	msleep(20);
	ti947_i2c_write_u8(ti948client, TI948_GPIO2_CONF , 0x50);
	msleep(20);
	ti947_i2c_write_u8(ti948client, TI948_GPIO3_CONF , 0x5);
}

static void ti947948_reset(void)
{
	if(gpio_is_valid(ds947_pwdn_gpio))
	{
		pr_emerg("--------> %s\n",__func__);
		gpio_direction_output(ds947_pwdn_gpio, 1);
		//pr_emerg("ds947_pwdn_gpio[%d]=1\n",ds947_pwdn_gpio);
		msleep(100);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		//pr_emerg("ds947_pwdn_gpio[%d]=0\n",ds947_pwdn_gpio);
		msleep(20);
		ti947_Init();
	}
}

static void ti947_check_process(void)
{
	u8 reg_947 = 0;
	if(ti947client!=NULL)
	{
		ti947_i2c_read_u8(ti947client, TI947_GENERAL_CONF, &reg_947, sizeof(reg_947));
		if(reg_947==0xda)
		{
			ti947_i2c_read_u8(ti947client, TI947_SLAVE_ID, &reg_947, sizeof(reg_947));
			if(reg_947==TI948_I2C_ADDR_SLAVE)
			{
				ti947_i2c_read_u8(ti947client, TI947_SLAVE_ALIAS, &reg_947, sizeof(reg_947));
				if(reg_947!=TI948_I2C_ADDR_SLAVE)
				{
					pr_emerg("--------> %s 3\n",__func__);
					ti947948_reset();
				}
			}
			else
			{
				pr_emerg("--------> %s 2\n",__func__);
				ti947948_reset();
			}
		}
		else
		{
			pr_emerg("--------> %s 1\n",__func__);
			ti947948_reset();
		}
	}
}

extern int cyttsp6_restartup(void);
void ti9x7_reInit(void)
{
	int i;
	u8 data;
	int ret ;
	hkh_printk("---%s--\r\n",__func__);

	if(ti947client==NULL || ti948client==NULL)
	{
		pr_emerg("%s:ti947client==NULL || ti948client==NULL\r\n",__func__);
		return;
	}

	for(i=0;i<10;i++)
	{
		data=0;
		ret=ti947_i2c_read_u8(ti948client, 0x1c, &data, sizeof(data));
		hkh_printk("%s :0x1c: 0x%x\n",__func__,data);
		if(data == 0x23)
		{
			pr_emerg("948 already lock\n");
			break;
		}else if(ret < 0)
		{
			pr_emerg("read 948 error\n");
			if(i >= 9)
			{
				return;
			}
		}
		msleep(1);
	}
	ti947_Init();
	ti948_Init();
	cyttsp6_restartup();
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////
#if defined( CONFIG_HONGJING_T19_PROJECT)
int thread_func_init(void *arg) 
{
	u8 status_948 = 0;
	int count_num=0;
	int ret=0;
//	pr_emerg("=====%s: ti9x7_Init() start=====\n",__func__);
	ti947948_tplcd_reset_init();
//	pr_emerg("=====%s: ti9x7_Init() end=====\n",__func__);
	while(1) {
		if(ti947client!=NULL&&ti948client!=NULL)
		{
			ti947_tplcd_check_process();
		
			status_948=0;
			ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
	//		hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
			if (((status_948&0x0f) != 0x03)||( ret < 0))
			{
	//			pr_emerg("%s:status_948= 0x%x, ret=%d\n",__func__, status_948,ret);
				for (count_num=0;count_num<10;count_num++)
				{
					msleep(100);
					status_948=0;
					ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
	//				hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
					if (((status_948&0x0f) == 0x03))
					{
						break;
					}
					else
					{
						pr_emerg("%s:status_948= 0x%x, ret=%d not lock!\n",__func__, status_948,ret);
					}
				}
				if(count_num>=10)
				{
	//				pr_emerg("-------->%s:status_948= 0x%x, ret=%d\n",__func__, status_948, ret);
					pr_emerg("--------> %s: 947,948 not lock reinit!\n",__func__);
					ti947948_tplcd_reset_init();
	//				pr_emerg("--------> %s: 947,948 lock\n",__func__);
				}
			}
			else
			{
			}
		}
		msleep(1000);
	}
	return 0;
}
#else
int is_927928_lock=0;
int thread_func_init(void *arg) 
{
	u8 status_948 = 0;
	u8 status_948_1F = 0;
	int count_num=0;
	int ret ;
	ti947948_reset();
	ti948_Init();
	hkh_printk("=====%s: ti9x7_Init() end=====\n",__func__);
	while(1) {
		if(ti947client!=NULL&&ti948client!=NULL)
		{
			ti947_check_process();
		
			status_948=status_948_1F=0;
			ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
			hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
			ret=ti947_i2c_read_u8(ti948client, 0x1f, &status_948_1F, sizeof(status_948_1F));
			hkh_printk("%s:status_948_1F= 0x%x,   ret=%d\n",__func__, status_948_1F,ret);
			if(((status_948&0x0f) == 0x03) && (!is_927928_lock) /*&& (status_948_1F != 0x05)*/)
			{
				ti9x7_reInit();
				is_927928_lock = 1;
				pr_emerg(" %s:947,948 already lock\n",__func__);
			}
			else if (((status_948&0x0f) != 0x03)||( ret < 0)||(status_948_1F != 0x05))
			{
				pr_emerg("%s:status_948= 0x%x,status_948_1F= 0x%x,   ret=%d\n",__func__, status_948, status_948_1F,ret);
				for (count_num=0;count_num<10;count_num++)
				{
					msleep(100);
					status_948=status_948_1F=0;
					ret=ti947_i2c_read_u8(ti948client, 0x1c, &status_948, sizeof(status_948));
					hkh_printk("%s:status_948= 0x%x,   ret=%d\n",__func__, status_948,ret);
					ret=ti947_i2c_read_u8(ti948client, 0x1f, &status_948_1F, sizeof(status_948_1F));
					hkh_printk("%s:status_948_1F= 0x%x,   ret=%d\n",__func__, status_948_1F,ret);
					if (((status_948&0x0f) == 0x03)&&(status_948_1F == 0x05))
					{
						break;
					}
				}
				if(count_num>=10)
				{
					pr_emerg("-------->%s:status_948= 0x%x,status_948_1F= 0x%x,   ret=%d\n",__func__, status_948, status_948_1F,ret);
					pr_emerg("--------> %s: 947,948 not lock\n",__func__);
					is_927928_lock = 0;
					ti947948_reset();
				}
			}
			else
			{
			}
		}
		msleep(1000);
	}
	return 0;
}
#endif
//////////////////////////////////////////////////////////////modify by hkh

static int
ti947_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct task_struct* my_thread = NULL;
	int rc = 0;
	struct device_node *np;
	
	ti947_dev = kzalloc(sizeof(*ti947_dev), GFP_KERNEL);
	if (!ti947_dev)
		return -ENOMEM;

	printk("%s\n", __func__);
	np = client->dev.of_node;
	ti947_dev->client = client;

	if (client->addr == 0xc) {
		ti947client = client;
		ds947_pwdn_gpio= of_get_named_gpio(np, "pwdn-gpios", 0);
		gpio_direction_output(ds947_pwdn_gpio, 0);
		pr_emerg("ds947_pwdn_gpio= %d\n",ds947_pwdn_gpio);
	}
	if (client->addr == 0x2c) {
		ti948client = client;

//#if defined( CONFIG_HONGJING_T19_PROJECT)
	//	ds948_pwen_gpio=of_get_named_gpio(np,"pwen-gpios", 0);
	//	pr_emerg("ds948_pwen_gpio= %d\n",ds948_pwen_gpio);
	//	gpio_direction_output(ds948_pwen_gpio, 0);
//#endif		
		my_thread = kthread_run(thread_func_init,NULL,"947948init_thread");
		if (IS_ERR(my_thread))
		{
			rc = PTR_ERR(my_thread);
			pr_emerg("error %d create thread_name \n",rc);
		}
	}
	return 0;
}

static int
ti947_remove(struct i2c_client *client)
{
	if (gpio_is_valid(ds947_pwdn_gpio))
		gpio_free(ds947_pwdn_gpio);
#if defined( CONFIG_HONGJING_T19_PROJECT)	
	if (gpio_is_valid(ds948_pwen_gpio))
		gpio_free(ds948_pwen_gpio);
#endif	
	kfree(ti947_dev);
	return 0;
}

static struct i2c_device_id ti947_ids[] = {
	{ "ti947", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ti947_ids);

static const struct of_device_id ti947_of_match[] = {
	{ .compatible = "ti,ds947948" },
	{ }
};
MODULE_DEVICE_TABLE(of, ti947_of_match);

static struct i2c_driver ti947_driver = {
	.probe = ti947_probe,
	.remove = ti947_remove,
	.driver = {
		.name = "ti947",
		.of_match_table = of_match_ptr(ti947_of_match),
	},
	.id_table = ti947_ids,
};

module_i2c_driver(ti947_driver);

MODULE_AUTHOR("wimin.zhong");
MODULE_DESCRIPTION("TI-947 driver");
MODULE_LICENSE("GPL v2");