xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/elan/elan_update.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * ELAN HID-I2C TouchScreen driver.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2014 Elan Microelectronics Corporation.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Chuming Zhang <chuming.zhang@elanic.com.cn>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "elan_ts.h"
11*4882a593Smuzhiyun #include <asm/unaligned.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun //define private data
14*4882a593Smuzhiyun //#define IAP_PORTION
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun uint8_t active_pen_fw[]= {
18*4882a593Smuzhiyun 	#include "MA50_HIDoverI2C_570B.cfg"
19*4882a593Smuzhiyun };
20*4882a593Smuzhiyun uint8_t passive_pen_fw[]= {
21*4882a593Smuzhiyun 	//  #include "passive_pen.i"
22*4882a593Smuzhiyun };
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun const struct vendor_map g_vendor_map[]=
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	{0x2ae2, "fw_data", active_pen_fw, sizeof(active_pen_fw), 0x271F},
27*4882a593Smuzhiyun 	{0x2ae1, "passive_pen", passive_pen_fw, sizeof(passive_pen_fw), 0x271F},
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun //#define ELAN_FW_PAGESIZE	(132)
31*4882a593Smuzhiyun 
get_hid_iap_ack(struct elan_ts_data * ts,uint8_t * cmd,int len,uint8_t * buf,int rlen)32*4882a593Smuzhiyun static int get_hid_iap_ack(struct elan_ts_data *ts, uint8_t *cmd, int len,uint8_t *buf, int rlen)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	int err = 0;
35*4882a593Smuzhiyun 	const uint8_t ack_ok[2] = {0xaa,0xaa};
36*4882a593Smuzhiyun 	const uint8_t ack_rewrite[2] = {0x55,0x55};
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	err = ts->ops->send(cmd,len);
39*4882a593Smuzhiyun 	if (err != len) {
40*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] write page finish command fauled\n");
41*4882a593Smuzhiyun 		return err;
42*4882a593Smuzhiyun 	}
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	err = ts->ops->poll();
45*4882a593Smuzhiyun 	if (err) {
46*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] wait for int failed\n");
47*4882a593Smuzhiyun 		return err;
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	err = ts->ops->recv(buf,rlen);
51*4882a593Smuzhiyun 	dev_info(&ts->client->dev, "[elan]%s buf[4]:buf[5]= %x:%x\n",__func__, buf[4],buf[5]);
52*4882a593Smuzhiyun 	if ( err == rlen) {
53*4882a593Smuzhiyun 		if (memcmp(buf+4,ack_ok,sizeof(ack_ok)) == 0) {
54*4882a593Smuzhiyun 			dev_info(&ts->client->dev,"[elan] iap write page response ok\n");
55*4882a593Smuzhiyun 			return 0;
56*4882a593Smuzhiyun 		} else if (memcmp(buf+4, ack_rewrite, sizeof(ack_rewrite))) {
57*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "[elan] iap rewrite page response\n");
58*4882a593Smuzhiyun 			return 1;
59*4882a593Smuzhiyun 		} else {
60*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "[elan] iap ack  error\n");
61*4882a593Smuzhiyun 			return -1;
62*4882a593Smuzhiyun 		}
63*4882a593Smuzhiyun 	} else {
64*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] recv ack return value error\n");
65*4882a593Smuzhiyun 		return err;
66*4882a593Smuzhiyun 	}
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	return 0;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
query_remark_id(struct elan_ts_data * ts)71*4882a593Smuzhiyun static int query_remark_id(struct elan_ts_data *ts)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	int len = 0;
74*4882a593Smuzhiyun 	uint8_t remarkid[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x00,0x06,0x96,0x80,0x1F,0x00,0x00,0x21};
75*4882a593Smuzhiyun 	uint8_t buf[67] = {0};
76*4882a593Smuzhiyun 	u16 remark_id = 0;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	len = ts->ops->send(remarkid,sizeof(remarkid));
79*4882a593Smuzhiyun 	if ( len != sizeof(remarkid) ) {
80*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan]Send query remark id cmd failed!! len=%d",len);
81*4882a593Smuzhiyun 		return -EINVAL;
82*4882a593Smuzhiyun 	} else
83*4882a593Smuzhiyun 		dev_err(&ts->client->dev,"[elan]Remark id write successfully!");
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	msleep(5);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	len = ts->ops->recv(buf, sizeof(buf));
88*4882a593Smuzhiyun 	if (len != sizeof(buf)) {
89*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan]Send Check Address Read Data error. len=%d", len);
90*4882a593Smuzhiyun 		return -EINVAL;
91*4882a593Smuzhiyun 	} else {
92*4882a593Smuzhiyun 		remark_id = (buf[7] << 8) | buf[8];
93*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan]Get Remark id = 0x%4x",remark_id);
94*4882a593Smuzhiyun 		return remark_id;
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 
hid_fw_upgrade_init(struct elan_ts_data * ts)99*4882a593Smuzhiyun static int hid_fw_upgrade_init(struct elan_ts_data *ts)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	int err = 0;
102*4882a593Smuzhiyun 	u16 remark_id;
103*4882a593Smuzhiyun 	const uint8_t flash_key[HID_CMD_LEN]  = {0x04,0x00,0x23,0x00,0x03,0x00,0x04,0x54,0xc0,0xe1,0x5a};
104*4882a593Smuzhiyun 	const uint8_t check_addr[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x00,0x01,0x10};
105*4882a593Smuzhiyun 	const uint8_t isp_cmd[HID_CMD_LEN]    = {0x04,0x00,0x23,0x00,0x03,0x00,0x04,0x54,0x00,0x12,0x34};
106*4882a593Smuzhiyun 	uint8_t buf[67] = {0};
107*4882a593Smuzhiyun 	uint8_t response_addr = 0x20;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	elan_ts_hw_reset(&ts->hw_info);
110*4882a593Smuzhiyun 	mdelay(300);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	err = elan_ic_status(ts->client);
113*4882a593Smuzhiyun 	if (err == FORCED_UPGRADE)
114*4882a593Smuzhiyun 		ts->recover = FORCED_UPGRADE;
115*4882a593Smuzhiyun 	else if (err == COMPARE_UPGRADE)
116*4882a593Smuzhiyun 		ts->recover = COMPARE_UPGRADE;
117*4882a593Smuzhiyun 	else
118*4882a593Smuzhiyun 		ts->recover = UNKNOW_TYPE;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	if (err != UNKNOW_TYPE) {
121*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] %s bcl = 0x%02x\n", __func__,ts->fw_info.fw_bcl);
122*4882a593Smuzhiyun 		if (ts->fw_info.fw_bcl >= 0x60) {
123*4882a593Smuzhiyun 			remark_id = query_remark_id(ts);
124*4882a593Smuzhiyun 			if ( remark_id != ts->update_info.remark_id) {
125*4882a593Smuzhiyun 				dev_err(&ts->client->dev, "[elan]Remark id failed,exit update");
126*4882a593Smuzhiyun 				return err;
127*4882a593Smuzhiyun 			}
128*4882a593Smuzhiyun 		}
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	dev_err(&ts->client->dev, "[elan] %s get ic status = %d\n", __func__, err);
132*4882a593Smuzhiyun 	err = ts->ops->send(flash_key,sizeof(flash_key));
133*4882a593Smuzhiyun 	if ( err != sizeof(flash_key)) {
134*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan]send flash key failed ,exit update\n");
135*4882a593Smuzhiyun 		return err;
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	mdelay(20);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	if (ts->recover == COMPARE_UPGRADE) {//normal mode
141*4882a593Smuzhiyun 		err = ts->ops->send(isp_cmd, sizeof(isp_cmd));
142*4882a593Smuzhiyun 		if ( err != sizeof(isp_cmd)) {
143*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "[elan] send isp cmd failed, exit update\n");
144*4882a593Smuzhiyun 			return err;
145*4882a593Smuzhiyun 		}
146*4882a593Smuzhiyun 	}
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	mdelay(20);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	err = ts->ops->send(check_addr, sizeof(check_addr));
151*4882a593Smuzhiyun 	if ( err != sizeof(check_addr)) {
152*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] send check addr failed, exit update\n");
153*4882a593Smuzhiyun 		return err;
154*4882a593Smuzhiyun 	}
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun //	mdelay(20);
157*4882a593Smuzhiyun 	ts->ops->poll();
158*4882a593Smuzhiyun 	err = ts->ops->recv(buf, sizeof(buf));
159*4882a593Smuzhiyun 	if ( err != sizeof(buf)) {
160*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] recv check addr response failed\n");
161*4882a593Smuzhiyun 		return err;
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	dev_err(&ts->client->dev, "[elan] %s response_addr = 0x%02x, buf=0x%2x\n",__func__, response_addr, buf[4]);
165*4882a593Smuzhiyun 	if (memcmp(&buf[4], &response_addr, 1)) {
166*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] response addr check failed,exit update\n");
167*4882a593Smuzhiyun 		return err;
168*4882a593Smuzhiyun 	} else {
169*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] update init success\n");
170*4882a593Smuzhiyun 		err = 0;
171*4882a593Smuzhiyun 	}
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	return  err;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 
hid_fw_upgrade_finshed(struct elan_ts_data * ts)177*4882a593Smuzhiyun static int hid_fw_upgrade_finshed(struct elan_ts_data *ts)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	int ret = 0;
180*4882a593Smuzhiyun 	uint8_t upgrade_end[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x1A};
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	ret = ts->ops->send(upgrade_end, sizeof(upgrade_end));
183*4882a593Smuzhiyun 	if (ret != sizeof(upgrade_end))
184*4882a593Smuzhiyun 		ret = -1;
185*4882a593Smuzhiyun 	else
186*4882a593Smuzhiyun 		ret = 0;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	return ret;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun 
Hid_Fw_Update(struct i2c_client * client)191*4882a593Smuzhiyun static int Hid_Fw_Update(struct i2c_client *client)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
194*4882a593Smuzhiyun 	struct elan_update_fw_info *update = &ts->update_info;
195*4882a593Smuzhiyun 	int wRemainLen = 0;
196*4882a593Smuzhiyun 	int wCopyLen = 0;
197*4882a593Smuzhiyun 	int wFwSize = update->FwSize;
198*4882a593Smuzhiyun 	int wCount = 0;
199*4882a593Smuzhiyun 	int wPayLoadLen = 0;
200*4882a593Smuzhiyun 	int qOffset = 0;
201*4882a593Smuzhiyun 	int qCmdLen = 9;
202*4882a593Smuzhiyun 	int err = 0;
203*4882a593Smuzhiyun 	int retry = 3;
204*4882a593Smuzhiyun 	uint8_t ack_buf[67] = {0x00};
205*4882a593Smuzhiyun 	uint8_t qIapPagefinishcmd[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x22};
206*4882a593Smuzhiyun 	uint8_t qIapWriteCmd[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x21,0x00,0x00,0x1c};
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun update_retry:
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	err = hid_fw_upgrade_init(ts);
211*4882a593Smuzhiyun 	if ( err ) {
212*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] upgrade init failed\n");
213*4882a593Smuzhiyun 		if ((retry-- > 0))
214*4882a593Smuzhiyun 			goto update_retry;
215*4882a593Smuzhiyun 		else
216*4882a593Smuzhiyun 			return -1;
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	msleep(50);
220*4882a593Smuzhiyun 	dev_err(&ts->client->dev, "[elan]%s fw size = %d\n", __func__,wFwSize);
221*4882a593Smuzhiyun 	while(wFwSize) {
222*4882a593Smuzhiyun 		wRemainLen = MIN((update->FwSize - wCount),( IAP_FLASH_SIZE  -( qOffset % IAP_FLASH_SIZE )));
223*4882a593Smuzhiyun 		wCopyLen = MIN(wRemainLen, HID_CMD_LEN - qCmdLen);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 		//dev_info(&ts->client->dev,"[elan]%s wRemainLen:wCopyLen = %d:%d\n", __func__,wRemainLen, wCopyLen);
226*4882a593Smuzhiyun 		memcpy(qIapWriteCmd+ IAP_CMD_HEADER_LEN, update->FwData + wCount, wCopyLen);
227*4882a593Smuzhiyun 		qCmdLen += wCopyLen;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 		wPayLoadLen = wCopyLen;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 		qIapWriteCmd[6] = qOffset >> 8;
232*4882a593Smuzhiyun 		qIapWriteCmd[7] = qOffset & 0xff;
233*4882a593Smuzhiyun 		qIapWriteCmd[8] = wPayLoadLen;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		err = ts->ops->send(qIapWriteCmd, sizeof(qIapWriteCmd));
236*4882a593Smuzhiyun 		if ( err != sizeof(qIapWriteCmd)) {
237*4882a593Smuzhiyun 			dev_err(&ts->client->dev,"[elan]write %dbytes  failed\n", wCopyLen);
238*4882a593Smuzhiyun 			if ( (retry--) > 0) {
239*4882a593Smuzhiyun 				qOffset = 0;
240*4882a593Smuzhiyun 				wFwSize = update->FwSize;
241*4882a593Smuzhiyun 				wCount = 0;
242*4882a593Smuzhiyun 				qCmdLen = IAP_CMD_HEADER_LEN;
243*4882a593Smuzhiyun 				goto update_retry;
244*4882a593Smuzhiyun 			} else
245*4882a593Smuzhiyun 				return -1;
246*4882a593Smuzhiyun 		}
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 		qCmdLen = IAP_CMD_HEADER_LEN;
249*4882a593Smuzhiyun 		qOffset += wPayLoadLen;
250*4882a593Smuzhiyun 		wCount += wPayLoadLen;
251*4882a593Smuzhiyun 		wFwSize -= wPayLoadLen;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 		if( (qOffset % (IAP_FLASH_SIZE) == 0) ||( wCount == update->FwSize)) {
254*4882a593Smuzhiyun 			err = get_hid_iap_ack(ts,qIapPagefinishcmd,sizeof(qIapPagefinishcmd),ack_buf, sizeof(ack_buf));
255*4882a593Smuzhiyun 			if (err) {
256*4882a593Smuzhiyun 				dev_err(&ts->client->dev, "get iap ack failed\n");
257*4882a593Smuzhiyun 				if ( (retry--) > 0) {
258*4882a593Smuzhiyun 					wFwSize = update->FwSize;
259*4882a593Smuzhiyun 					wCount = 0;
260*4882a593Smuzhiyun 					qCmdLen = IAP_CMD_HEADER_LEN;
261*4882a593Smuzhiyun 					qOffset = 0;
262*4882a593Smuzhiyun 					goto update_retry;
263*4882a593Smuzhiyun 				} else
264*4882a593Smuzhiyun 					return -1;
265*4882a593Smuzhiyun 			} else
266*4882a593Smuzhiyun 				qOffset = 0;
267*4882a593Smuzhiyun 		}
268*4882a593Smuzhiyun 	}
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	err = hid_fw_upgrade_finshed(ts);
271*4882a593Smuzhiyun 	if (err) {
272*4882a593Smuzhiyun 		dev_err(&ts->client->dev,"[elan] fw upgrade finshed failed!!!\n");
273*4882a593Smuzhiyun 		return -1;
274*4882a593Smuzhiyun 	}
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	dev_err(&ts->client->dev,"[elan] fw upgrade success!!!\n");
277*4882a593Smuzhiyun 	return 0;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
elan_fw_write_page(struct i2c_client * client,const void * page)281*4882a593Smuzhiyun static int elan_fw_write_page(struct i2c_client *client,
282*4882a593Smuzhiyun 		const void *page)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
285*4882a593Smuzhiyun 	const uint8_t ack_ok[] = { 0xaa, 0xaa };
286*4882a593Smuzhiyun 	uint8_t buf[2] = {0x00};
287*4882a593Smuzhiyun 	int retry;
288*4882a593Smuzhiyun 	int error;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	for (retry = 0; retry < 5; retry++) {
292*4882a593Smuzhiyun 		error = ts->ops->send(page, FW_PAGE_SIZE);
293*4882a593Smuzhiyun 		if (error != FW_PAGE_SIZE) {
294*4882a593Smuzhiyun 			dev_err(&client->dev,
295*4882a593Smuzhiyun 					"IAP Write Page failed: %d\n", error);
296*4882a593Smuzhiyun 			continue;
297*4882a593Smuzhiyun 		}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		error = ts->ops->recv(buf, sizeof(buf));
300*4882a593Smuzhiyun 		if (error != sizeof(buf)) {
301*4882a593Smuzhiyun 			dev_err(&client->dev,
302*4882a593Smuzhiyun 					"IAP Ack read failed: %d\n", error);
303*4882a593Smuzhiyun 			return error;
304*4882a593Smuzhiyun 		}
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 		if (!memcmp(buf, ack_ok, sizeof(ack_ok)))
307*4882a593Smuzhiyun 			return 0;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 		error = -EIO;
310*4882a593Smuzhiyun 		dev_err(&client->dev,
311*4882a593Smuzhiyun 				"IAP Get Ack Error [%02x:%02x]\n",
312*4882a593Smuzhiyun 				buf[0], buf[1]);
313*4882a593Smuzhiyun 	}
314*4882a593Smuzhiyun 	return error;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 
Normal_Fw_Update(struct i2c_client * client)318*4882a593Smuzhiyun static int Normal_Fw_Update(struct i2c_client *client)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
321*4882a593Smuzhiyun 	struct elan_update_fw_info *update = &ts->update_info;
322*4882a593Smuzhiyun 	const uint8_t enter_iap[] = { 0x45, 0x49, 0x41, 0x50 };
323*4882a593Smuzhiyun //	const uint8_t enter_isp[] = { 0x54, 0x00, 0x12, 0x34 };
324*4882a593Smuzhiyun 	const uint8_t iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc };
325*4882a593Smuzhiyun 	uint8_t buf[4] = {0x00};
326*4882a593Smuzhiyun 	int page = 0;
327*4882a593Smuzhiyun 	int error;
328*4882a593Smuzhiyun 	uint8_t send_id;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	elan_ts_hw_reset(&ts->hw_info);
332*4882a593Smuzhiyun 	msleep(20);
333*4882a593Smuzhiyun 	error =  ts->ops->send(enter_iap, sizeof(enter_iap));
334*4882a593Smuzhiyun 	if (error != sizeof(enter_iap)) {
335*4882a593Smuzhiyun 		dev_err(&client->dev, "failed to enter IAP mode: %d\n", error);
336*4882a593Smuzhiyun 		return error;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	msleep(20);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	/* check IAP state */
342*4882a593Smuzhiyun 	error = ts->ops->recv(buf, sizeof(buf));
343*4882a593Smuzhiyun 	if (error != sizeof(buf)) {
344*4882a593Smuzhiyun 		dev_err(&client->dev,
345*4882a593Smuzhiyun 				"failed to read IAP acknowledgement: %d\n",
346*4882a593Smuzhiyun 				error);
347*4882a593Smuzhiyun 		return error;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	if (memcmp(buf, iap_ack, sizeof(iap_ack))) {
351*4882a593Smuzhiyun 		dev_err(&client->dev,
352*4882a593Smuzhiyun 				"failed to enter IAP: %*ph (expected %*ph)\n",
353*4882a593Smuzhiyun 				(int)sizeof(buf), buf, (int)sizeof(iap_ack), iap_ack);
354*4882a593Smuzhiyun 		return -EIO;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	dev_info(&client->dev, "successfully entered IAP mode");
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	/* send dummy byte */
360*4882a593Smuzhiyun 	send_id = client->addr;
361*4882a593Smuzhiyun 	error = ts->ops->send(&send_id, 1);
362*4882a593Smuzhiyun 	if (error != 1) {
363*4882a593Smuzhiyun 		dev_err(&client->dev, "sending dummy byte failed: %d\n",
364*4882a593Smuzhiyun 				error);
365*4882a593Smuzhiyun 		return error;
366*4882a593Smuzhiyun 	}
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	/*write page*/
369*4882a593Smuzhiyun 	for (page = 0; page < update->PageNum; page++) {
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 		error = elan_fw_write_page(client,
372*4882a593Smuzhiyun 				update->FwData + page * FW_PAGE_SIZE);
373*4882a593Smuzhiyun 		if (error) {
374*4882a593Smuzhiyun 			dev_err(&client->dev,
375*4882a593Smuzhiyun 					"failed to write FW page %d: %d\n",
376*4882a593Smuzhiyun 					page, error);
377*4882a593Smuzhiyun 			return error;
378*4882a593Smuzhiyun 		}
379*4882a593Smuzhiyun 	}
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	msleep(300);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	dev_info(&client->dev, "firmware update completed\n");
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	return 0;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun 
elan_FW_Update(struct i2c_client * client)389*4882a593Smuzhiyun int elan_FW_Update(struct i2c_client *client)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	int err = 0;
392*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	if (ts->chip_type == HID_TYPE_PROTOCOL){
396*4882a593Smuzhiyun 		err = Hid_Fw_Update(client);
397*4882a593Smuzhiyun 		if (!err)
398*4882a593Smuzhiyun 			ts->recover = COMPARE_UPGRADE;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	}
401*4882a593Smuzhiyun 	else if(ts->chip_type == NORMAL_TYPE_PROTOCOL)
402*4882a593Smuzhiyun 		err  = Normal_Fw_Update(client);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	return err;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 
elan_ts_hid_calibrate(struct i2c_client * client)408*4882a593Smuzhiyun static int elan_ts_hid_calibrate(struct i2c_client *client)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	uint8_t flash_key[HID_CMD_LEN] = {0x04,0x00,0x23,0x00,0x03,0x00,0x04,CMD_W_PKT,0xc0,0xe1,0x5a};
411*4882a593Smuzhiyun 	uint8_t cal_cmd[HID_CMD_LEN] =	{0x04,0x00,0x23,0x00,0x03,0x00,0x04,CMD_W_PKT,0x29,0x00,0x01};
412*4882a593Smuzhiyun 	int  err = 0;
413*4882a593Smuzhiyun 	uint8_t resp[67] = {0x00};
414*4882a593Smuzhiyun 	uint8_t rek_resp[4] = {0x66,0x66,0x66,0x66};
415*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	dev_info(&client->dev, "[elan] %s: Flash Key cmd\n", __func__);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	err = ts->ops->send(flash_key, sizeof(flash_key));
420*4882a593Smuzhiyun 	if (err != sizeof(flash_key)) {
421*4882a593Smuzhiyun 		dev_err(&client->dev,
422*4882a593Smuzhiyun 				"[elan] %s: i2c_master_send failed\n",__func__);
423*4882a593Smuzhiyun 		return err;
424*4882a593Smuzhiyun 	}
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	err = ts->ops->send(cal_cmd, sizeof(cal_cmd));
427*4882a593Smuzhiyun 	if ( err != sizeof(cal_cmd)) {
428*4882a593Smuzhiyun 		dev_err(&client->dev, "[elan] %s: i2c_master_send failed\n",__func__);
429*4882a593Smuzhiyun 		return err;
430*4882a593Smuzhiyun 	}
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	err = ts->ops->poll();
433*4882a593Smuzhiyun 	if (err) {
434*4882a593Smuzhiyun 		dev_err(&client->dev,
435*4882a593Smuzhiyun 				"[elan] %s: wait for int low failed %d\n", __func__, err);
436*4882a593Smuzhiyun 		return err;
437*4882a593Smuzhiyun 	} else {
438*4882a593Smuzhiyun 		err = ts->ops->recv(resp,sizeof(resp));
439*4882a593Smuzhiyun 		if ( err == sizeof(resp)) {
440*4882a593Smuzhiyun 			if (memcmp(rek_resp, resp + 4, sizeof(rek_resp))) {
441*4882a593Smuzhiyun 				dev_err(&client->dev, "%s:%d calibrate failed\n", __func__,__LINE__);
442*4882a593Smuzhiyun 				return -EINVAL;
443*4882a593Smuzhiyun 			} else {
444*4882a593Smuzhiyun 				dev_info(&client->dev,"calibrate success\n");
445*4882a593Smuzhiyun 				return 0;
446*4882a593Smuzhiyun 			}
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 		} else {
449*4882a593Smuzhiyun 			dev_err(&client->dev, "%s:%d recv calibrate data failed\n",__func__,__LINE__);
450*4882a593Smuzhiyun 			return -EINVAL;
451*4882a593Smuzhiyun 		}
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
elan_ts_normal_calibrate(struct i2c_client * client)455*4882a593Smuzhiyun static int elan_ts_normal_calibrate(struct i2c_client *client)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
458*4882a593Smuzhiyun 	uint8_t flash_key[] = {CMD_W_PKT, 0xc0, 0xe1, 0x5a};
459*4882a593Smuzhiyun 	uint8_t cal_cmd[] = {CMD_W_PKT, 0x29, 0x00, 0x01};
460*4882a593Smuzhiyun 	uint8_t rek_resp[4] = {0x66,0x66,0x66,0x66};
461*4882a593Smuzhiyun 	uint8_t resp[4] = {0x00};
462*4882a593Smuzhiyun 	int err = 0;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	dev_info(&client->dev, "[elan] %s: Flash Key cmd\n", __func__);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	err = ts->ops->send(flash_key, sizeof(flash_key));
467*4882a593Smuzhiyun 	if (err != sizeof(flash_key)) {
468*4882a593Smuzhiyun 		dev_err(&client->dev,
469*4882a593Smuzhiyun 				"[elan] %s: i2c_master_send failed\n",__func__);
470*4882a593Smuzhiyun 		return err;
471*4882a593Smuzhiyun 	}
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	err = ts->ops->send(cal_cmd, sizeof(cal_cmd));
474*4882a593Smuzhiyun 	if ( err != sizeof(cal_cmd) ) {
475*4882a593Smuzhiyun 		dev_err(&client->dev,
476*4882a593Smuzhiyun 				"[elan] %s: i2c_master_send failed\n",__func__);
477*4882a593Smuzhiyun 		return err;
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	err = ts->ops->poll();
481*4882a593Smuzhiyun 	if ( err ) {
482*4882a593Smuzhiyun 	} else {
483*4882a593Smuzhiyun 		err = ts->ops->recv(resp,sizeof(resp));
484*4882a593Smuzhiyun 		if ( err == sizeof(resp) ) {
485*4882a593Smuzhiyun 			if (memcmp(rek_resp, resp, sizeof(rek_resp))) {
486*4882a593Smuzhiyun 				dev_err(&client->dev, "%s:%d calibrate failed", __func__,__LINE__);
487*4882a593Smuzhiyun 				return -EINVAL;
488*4882a593Smuzhiyun 			} else {
489*4882a593Smuzhiyun 				dev_info(&client->dev,"calibrate success");
490*4882a593Smuzhiyun 				return 0;
491*4882a593Smuzhiyun 			}
492*4882a593Smuzhiyun 		} else {
493*4882a593Smuzhiyun 			dev_err(&client->dev, "%s:%d recv calibrate data failed",__func__,__LINE__);
494*4882a593Smuzhiyun 			return -EINVAL;
495*4882a593Smuzhiyun 		}
496*4882a593Smuzhiyun 	}
497*4882a593Smuzhiyun 	return 0;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
elan_ts_calibrate(struct i2c_client * client)500*4882a593Smuzhiyun int elan_ts_calibrate(struct i2c_client *client)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
503*4882a593Smuzhiyun 	int err = 0;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	if (ts->chip_type == HID_TYPE_PROTOCOL)
506*4882a593Smuzhiyun 		err = elan_ts_hid_calibrate(client);
507*4882a593Smuzhiyun 	else if(ts->chip_type == NORMAL_TYPE_PROTOCOL)
508*4882a593Smuzhiyun 		err  = elan_ts_normal_calibrate(client);
509*4882a593Smuzhiyun 	return err;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun 
check_cal_status(struct i2c_client * client)512*4882a593Smuzhiyun static int check_cal_status(struct i2c_client *client)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
515*4882a593Smuzhiyun 	const uint8_t check_rek_cmd[HID_CMD_LEN] = {0x04, 0x00, 0x23, 0x00, 0x03, 0x00, 0x04, 0x53, 0xD0, 0x00, 0x01};
516*4882a593Smuzhiyun 	const uint8_t rek_count[2] = {0xFF,0xFF};
517*4882a593Smuzhiyun 	uint8_t resp[67] = {0};
518*4882a593Smuzhiyun 	int err = 0;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	err = ts->ops->send(check_rek_cmd, sizeof(check_rek_cmd));
521*4882a593Smuzhiyun 	if (err != sizeof(check_rek_cmd)) {
522*4882a593Smuzhiyun 		dev_err(&client->dev, "[elan] %s send check rek command failed\n", __func__);
523*4882a593Smuzhiyun 		return err;
524*4882a593Smuzhiyun 	}
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	err = ts->ops->poll();
527*4882a593Smuzhiyun 	if (err) {
528*4882a593Smuzhiyun 		dev_err(&client->dev, "[elan] %s wait int failed\n", __func__);
529*4882a593Smuzhiyun 		return err;
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	err = ts->ops->recv(resp, sizeof(resp));
533*4882a593Smuzhiyun 	if (err != sizeof(resp)){
534*4882a593Smuzhiyun 		dev_err(&client->dev, "[elan] %s recv check rek failed\n", __func__);
535*4882a593Smuzhiyun 		return err;
536*4882a593Smuzhiyun 	} else {
537*4882a593Smuzhiyun 		dev_info(&client->dev, "[elan] %s check rek resp 0x%2x:0x%2x:0x%2x:0x%2x\n",__func__,\
538*4882a593Smuzhiyun 								resp[6],resp[7],resp[8],resp[9]);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 		if (memcmp(resp+6, rek_count,2)) {
541*4882a593Smuzhiyun 			dev_info(&client->dev, "[elan] %s check ok!!\n",__func__);
542*4882a593Smuzhiyun 			return 0;
543*4882a593Smuzhiyun 		}
544*4882a593Smuzhiyun 		else {
545*4882a593Smuzhiyun 			dev_info(&client->dev, "[elan] %s check failed!!\n",__func__);
546*4882a593Smuzhiyun 			return -1;
547*4882a593Smuzhiyun 		}
548*4882a593Smuzhiyun 	}
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
elan_ts_check_calibrate(struct i2c_client * client)552*4882a593Smuzhiyun int elan_ts_check_calibrate(struct i2c_client *client)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	int err = 0;
555*4882a593Smuzhiyun 	struct elan_ts_data *ts = i2c_get_clientdata(client);
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	if (ts->chip_type == HID_TYPE_PROTOCOL)
558*4882a593Smuzhiyun 		err = check_cal_status(client);
559*4882a593Smuzhiyun 	else
560*4882a593Smuzhiyun 		dev_info(&client->dev, "[elan] ok");
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	return err;
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 
elan_read_fw_from_sdcard(struct elan_ts_data * ts)566*4882a593Smuzhiyun static int elan_read_fw_from_sdcard(struct elan_ts_data *ts)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun 	dev_err(&ts->client->dev, "[elan] can not pass Google GKI, return\n");
569*4882a593Smuzhiyun 	return -1;
570*4882a593Smuzhiyun /*
571*4882a593Smuzhiyun  *	struct elan_update_fw_info *update = &ts->update_info;
572*4882a593Smuzhiyun  *	mm_segment_t oldfs;
573*4882a593Smuzhiyun  *	struct file *firmware_fp;
574*4882a593Smuzhiyun  *	int ret = 0;
575*4882a593Smuzhiyun  *	int retry = 0;
576*4882a593Smuzhiyun  *	int file_len;
577*4882a593Smuzhiyun  *	static uint8_t *fw_data_user;
578*4882a593Smuzhiyun  *
579*4882a593Smuzhiyun  *	if ( fw_data_user != NULL)
580*4882a593Smuzhiyun  *		kfree(fw_data_user);
581*4882a593Smuzhiyun  *
582*4882a593Smuzhiyun  *	oldfs = get_fs();
583*4882a593Smuzhiyun  *	set_fs(KERNEL_DS);
584*4882a593Smuzhiyun  *
585*4882a593Smuzhiyun  *	for (retry = 0; retry < 5; retry++) {
586*4882a593Smuzhiyun  *		firmware_fp = filp_open(update->fw_local_path, O_RDONLY, 0);
587*4882a593Smuzhiyun  *		if ( IS_ERR(firmware_fp) ) {
588*4882a593Smuzhiyun  *			dev_err(&ts->client->dev, "[elan] retry to open user ekt file\n");
589*4882a593Smuzhiyun  *			mdelay(100);
590*4882a593Smuzhiyun  *		} else
591*4882a593Smuzhiyun  *			break;
592*4882a593Smuzhiyun  *	}
593*4882a593Smuzhiyun  *
594*4882a593Smuzhiyun  *	if ( retry >= 5 ) {
595*4882a593Smuzhiyun  *		dev_err(&ts->client->dev,
596*4882a593Smuzhiyun  *				"[elan] open %s file error!!\n",update->fw_local_path);
597*4882a593Smuzhiyun  *		ret = -1;
598*4882a593Smuzhiyun  *		goto out_read_fw_from_user2;
599*4882a593Smuzhiyun  *	} else
600*4882a593Smuzhiyun  *		dev_dbg(&ts->client->dev,
601*4882a593Smuzhiyun  *				"[elan] open %s file sucess!!\n",update->fw_local_path);
602*4882a593Smuzhiyun  *
603*4882a593Smuzhiyun  *	file_len = firmware_fp->f_path.dentry->d_inode->i_size;
604*4882a593Smuzhiyun  *	if (file_len == 0) {
605*4882a593Smuzhiyun  *		dev_dbg(&ts->client->dev,
606*4882a593Smuzhiyun  *				"[elan] Get File len err!!!!");
607*4882a593Smuzhiyun  *		ret = -2;
608*4882a593Smuzhiyun  *		goto out_read_fw_from_user1;
609*4882a593Smuzhiyun  *	}
610*4882a593Smuzhiyun  *
611*4882a593Smuzhiyun  *	fw_data_user = kzalloc(file_len, GFP_KERNEL);
612*4882a593Smuzhiyun  *	if (fw_data_user == NULL) {
613*4882a593Smuzhiyun  *		dev_err(&ts->client->dev,
614*4882a593Smuzhiyun  *				"[elan] malloc fw_data err\n");
615*4882a593Smuzhiyun  *		ret = -3;
616*4882a593Smuzhiyun  *		goto out_read_fw_from_user1;
617*4882a593Smuzhiyun  *	}
618*4882a593Smuzhiyun  *
619*4882a593Smuzhiyun  *	ret = firmware_fp->f_op->read(firmware_fp, fw_data_user,
620*4882a593Smuzhiyun  *			             file_len, &firmware_fp->f_pos);
621*4882a593Smuzhiyun  *	if ( ret != file_len ) {
622*4882a593Smuzhiyun  *		dev_err(&ts->client->dev,
623*4882a593Smuzhiyun  *				"[elan] read EKT file size err, ret=%d!\n",ret);
624*4882a593Smuzhiyun  *		ret = -4;
625*4882a593Smuzhiyun  *		goto out_read_fw_from_user0;
626*4882a593Smuzhiyun  *	} else {
627*4882a593Smuzhiyun  *		update->FwData = fw_data_user;
628*4882a593Smuzhiyun  *		update->FwSize = file_len;
629*4882a593Smuzhiyun  *		update->PageNum = update->FwSize/132;
630*4882a593Smuzhiyun  *		ret = 0;
631*4882a593Smuzhiyun  *	}
632*4882a593Smuzhiyun  *out_read_fw_from_user0:
633*4882a593Smuzhiyun  *out_read_fw_from_user1:
634*4882a593Smuzhiyun  *	filp_close(firmware_fp, NULL);
635*4882a593Smuzhiyun  *out_read_fw_from_user2:
636*4882a593Smuzhiyun  *	set_fs(oldfs);
637*4882a593Smuzhiyun  *
638*4882a593Smuzhiyun  *	return ret;
639*4882a593Smuzhiyun  */
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun 
get_driver_fw(struct elan_ts_data * ts)642*4882a593Smuzhiyun static int get_driver_fw(struct elan_ts_data *ts)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	int i,vendor_num = 0, lcm_id;
645*4882a593Smuzhiyun 	struct elan_update_fw_info *update_info = &ts->update_info;
646*4882a593Smuzhiyun 	vendor_num = sizeof(g_vendor_map)/sizeof(g_vendor_map[0]);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	/*if there are more than one display product, ODM should provid lcmid*/
649*4882a593Smuzhiyun 	lcm_id = 0x2ae2;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	/*if there are more than one tp panle, ELAN should provide fwid*/
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	for (i = 0; i < vendor_num; i++) {
654*4882a593Smuzhiyun 		dev_err(&ts->client->dev,
655*4882a593Smuzhiyun 				"[elan] vendor name = %s, lcm_id = 0x%04x, vendor_id = 0x%04x\n",\
656*4882a593Smuzhiyun 				g_vendor_map[i].vendor_name,lcm_id, g_vendor_map[i].vendor_id);
657*4882a593Smuzhiyun 		if (lcm_id == g_vendor_map[i].vendor_id) {
658*4882a593Smuzhiyun 			update_info->FwData = g_vendor_map[i].fw_array;
659*4882a593Smuzhiyun 			update_info->FwSize  = g_vendor_map[i].fw_size;
660*4882a593Smuzhiyun 			update_info->PageNum = g_vendor_map[i].fw_size/132;
661*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "fwSize = %d, pagenum = %d\n", update_info->FwSize,update_info->PageNum );
662*4882a593Smuzhiyun 			return 0;
663*4882a593Smuzhiyun 		}
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	dev_err(&ts->client->dev,"[elan] ID is error, not support!!\n");
667*4882a593Smuzhiyun 	return -1;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 
elan_get_vendor_fw(struct elan_ts_data * ts,int type)671*4882a593Smuzhiyun int elan_get_vendor_fw(struct elan_ts_data *ts, int type)
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun 	int err = 0;
674*4882a593Smuzhiyun 	struct elan_update_fw_info *update_info = &ts->update_info;
675*4882a593Smuzhiyun 	const struct firmware *p_fw_entry;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	if ( type == FROM_SYS_ETC_FIRMWARE) {
678*4882a593Smuzhiyun 		update_info->FwName = kasprintf(GFP_KERNEL, "elants_i2c.ekt");
679*4882a593Smuzhiyun 		if (!update_info->FwName)
680*4882a593Smuzhiyun 			return -ENOMEM;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 		err = request_firmware(&p_fw_entry, update_info->FwName, &ts->client->dev);
683*4882a593Smuzhiyun 		if ( err ) {
684*4882a593Smuzhiyun 			dev_err(&ts->client->dev,
685*4882a593Smuzhiyun 					"request_firmware fail err=%d\n",err);
686*4882a593Smuzhiyun 			return -1;
687*4882a593Smuzhiyun 		} else {
688*4882a593Smuzhiyun 			dev_dbg(&ts->client->dev, "Firmware Size=%zu",p_fw_entry->size);
689*4882a593Smuzhiyun 			update_info->FwData = p_fw_entry->data;
690*4882a593Smuzhiyun 			update_info->FwSize = p_fw_entry->size;
691*4882a593Smuzhiyun 			update_info->PageNum = update_info->FwSize/132;
692*4882a593Smuzhiyun 			dev_info(&ts->client->dev, "[elan] %d: FwSize %d, PageNum %d\n", __LINE__,
693*4882a593Smuzhiyun 				update_info->FwSize, update_info->PageNum );
694*4882a593Smuzhiyun 		}
695*4882a593Smuzhiyun 	} else if ( type == FROM_SDCARD_FIRMWARE ) {
696*4882a593Smuzhiyun 		update_info->FwName = kasprintf(GFP_KERNEL, "elants_i2c.ekt");
697*4882a593Smuzhiyun 		sprintf(update_info->fw_local_path, "%s%s", "/data/local/tmp", update_info->FwName);
698*4882a593Smuzhiyun 		dev_info(&ts->client->dev, "[elan] Update Firmware from %s\n", update_info->fw_local_path);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 		err = elan_read_fw_from_sdcard(ts);
701*4882a593Smuzhiyun 		if ( err ) {
702*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "Get FW Data From %s failed\n",update_info->fw_local_path);
703*4882a593Smuzhiyun 			return -1;
704*4882a593Smuzhiyun 		}
705*4882a593Smuzhiyun 	} else if ( type == FROM_DRIVER_FIRMWARE ) {
706*4882a593Smuzhiyun 		err = get_driver_fw(ts);
707*4882a593Smuzhiyun 		if ( err ) {
708*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "Get FW Data From driver failed\n");
709*4882a593Smuzhiyun 			return -1;
710*4882a593Smuzhiyun 		}
711*4882a593Smuzhiyun 	}
712*4882a593Smuzhiyun 	update_info->remark_id =  get_unaligned_le16(&update_info->FwData[update_info->FwSize - 4]);
713*4882a593Smuzhiyun 	return err;
714*4882a593Smuzhiyun }
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 
elan_check_update_flage(struct elan_ts_data * ts)717*4882a593Smuzhiyun void elan_check_update_flage(struct elan_ts_data *ts)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	int New_FW_VERSION = 0;
720*4882a593Smuzhiyun 	int New_FW_ID = 0;
721*4882a593Smuzhiyun 	int err = 0;
722*4882a593Smuzhiyun 	int retry = 0;
723*4882a593Smuzhiyun 	struct elan_update_fw_info *update_info = &ts->update_info;
724*4882a593Smuzhiyun 	struct elan_fw_info *fw_info = &ts->fw_info;
725*4882a593Smuzhiyun 	int try = 30;
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun 	/*
728*4882a593Smuzhiyun 	** support three methods to get fwdata.
729*4882a593Smuzhiyun 	 * FROM_SYS_ETC_FIRMWARE :/system/firmware/elants_i2c.ekt
730*4882a593Smuzhiyun 	 * FROM_SDCARD_FIRMWARE: /data/local/tmp/elants_i2c.ekt
731*4882a593Smuzhiyun 	 * FROM_DRIVER_FIRMWARE: in driver code directory *.i
732*4882a593Smuzhiyun 	 */
733*4882a593Smuzhiyun RETRY:
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 	err = elan_get_vendor_fw(ts,ts->fw_store_type);
736*4882a593Smuzhiyun 	if (err) {
737*4882a593Smuzhiyun 		if (try--) {
738*4882a593Smuzhiyun 			msleep(100);
739*4882a593Smuzhiyun 			goto RETRY;
740*4882a593Smuzhiyun 		}
741*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] ***counld not get fw,exit update flow!!***\n");
742*4882a593Smuzhiyun 		goto exit_fw_upgrade;
743*4882a593Smuzhiyun 	} else {
744*4882a593Smuzhiyun 		dev_err(&ts->client->dev,
745*4882a593Smuzhiyun 			"[elan]%d ***get fw success,enter update flow!! try count %d***\n",
746*4882a593Smuzhiyun 			__LINE__, 30-try);
747*4882a593Smuzhiyun 	}
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 	if ( ts->recover == FORCED_UPGRADE ) {
750*4882a593Smuzhiyun 		dev_err(&ts->client->dev, "[elan] *** fw is miss, force update fw!! ***\n");
751*4882a593Smuzhiyun 		goto fw_upgrade;
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	/*
755*4882a593Smuzhiyun 	** id and version index maybe change.
756*4882a593Smuzhiyun 	*/
757*4882a593Smuzhiyun 	New_FW_ID = update_info->FwData[0xD5ED] << 8 | update_info->FwData[0XD5EC];
758*4882a593Smuzhiyun 	New_FW_VERSION = update_info->FwData[0x9F] << 8 | update_info->FwData[0x9E];
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun 	dev_info(&ts->client->dev, "[elan] FW_ID=0x%4x,New_FW_ID=0x%4x\n",fw_info->fw_id,New_FW_ID);
761*4882a593Smuzhiyun 	dev_info(&ts->client->dev, "[elan] FW_VERSION=0x%4x,New_FW_VERSION=0x%4x\n",fw_info->fw_ver,New_FW_VERSION);
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 	if ((fw_info->fw_id&0xff) != (New_FW_ID&0xff)) {
764*4882a593Smuzhiyun 		dev_err(&ts->client->dev,"[elan] fw id is different, can not update!");
765*4882a593Smuzhiyun 		goto exit_fw_upgrade;
766*4882a593Smuzhiyun 	}
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	if ((fw_info->fw_ver&0xff) >= (New_FW_VERSION&0xff)) {
769*4882a593Smuzhiyun 		dev_info(&ts->client->dev,"[elan] fw version is newest!!\n");
770*4882a593Smuzhiyun 		goto exit_fw_upgrade;
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun fw_upgrade:
774*4882a593Smuzhiyun 	/*start update fw*/
775*4882a593Smuzhiyun 	elan_FW_Update(ts->client);
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	elan_ts_hw_reset(&ts->hw_info);
778*4882a593Smuzhiyun 	mdelay(300);
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun 	/*get fw msg*/
781*4882a593Smuzhiyun 	for (; retry < 3; retry++) {
782*4882a593Smuzhiyun 		 err = elan__fw_packet_handler(ts->client);
783*4882a593Smuzhiyun 		 if (err)
784*4882a593Smuzhiyun 			 dev_err(&ts->client->dev, "[elan] After update fw get fw msg failed, retry=%d\n",retry);
785*4882a593Smuzhiyun 		 else
786*4882a593Smuzhiyun 			 break;
787*4882a593Smuzhiyun 	}
788*4882a593Smuzhiyun 	mdelay(200);
789*4882a593Smuzhiyun 	/*calibration*/
790*4882a593Smuzhiyun 	for (retry = 0; retry < 3; retry++) {
791*4882a593Smuzhiyun 		err = elan_ts_calibrate(ts->client);
792*4882a593Smuzhiyun 		if (err)
793*4882a593Smuzhiyun 			dev_err(&ts->client->dev, "[elan] After update fw calibrate failed, retry=%d\n",retry);
794*4882a593Smuzhiyun 		else {
795*4882a593Smuzhiyun 			err = elan_ts_check_calibrate(ts->client); /*ic reponse rek count,count != 0xff? "ok":"failed" */
796*4882a593Smuzhiyun 			if (err)
797*4882a593Smuzhiyun 				dev_err(&ts->client->dev, "[elan] After update fw check rek failed, retry=%d\n",retry);
798*4882a593Smuzhiyun 			else
799*4882a593Smuzhiyun 				break;
800*4882a593Smuzhiyun 		}
801*4882a593Smuzhiyun 	}
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun exit_fw_upgrade:
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	return;
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun 
808