mxts_patch.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652
  1. #if TSP_PATCH
  2. /*
  3. Header
  4. */
  5. #define MXT_PATCH_LOCK_CHECK 1
  6. #define MXT_PATCH_SUPP_CHECK 1
  7. #define MXT_PATCH_STAGE_RESET 1
  8. #define TIME_WRAP_AROUND(x, y) (((y)>(x)) ? (y)-(x) : (0-(x))+(y))
  9. #define MXT_PATCH_MAGIC 0x52296416
  10. #define MXT_PATCH_VERSION 1
  11. #define MXT_PATCH_MAX_STAGE 255
  12. #define MXT_PATCH_MAX_TLINE 255
  13. #define MXT_PATCH_MAX_TRIG 255
  14. #define MXT_PATCH_MAX_ITEM 255
  15. #define MXT_PATCH_MAX_TYPE 255
  16. #define MXT_PATCH_MAX_CON 255
  17. #define MXT_PATCH_MAX_EVENT 255
  18. #define MXT_PATCH_MAX_MSG_SIZE 10
  19. #define MXT_XML_CON_NONE "0" //0
  20. #define MXT_XML_CON_EQUAL "=" //1
  21. #define MXT_XML_CON_BELOW "<" //2
  22. #define MXT_XML_CON_ABOVE ">" //3
  23. #define MXT_XML_CON_PLUS "+" //4
  24. #define MXT_XML_CON_MINUS "-" //5
  25. #define MXT_XML_CON_MUL "*" //6
  26. #define MXT_XML_CON_DIV "/" //7
  27. #define MXT_XML_CON_MASK "&" //8
  28. #define MXT_XML_SRC_NONE "0" //0
  29. #define MXT_XML_SRC_CHRG "TA" //1
  30. #define MXT_XML_SRC_FCNT "FCNT" //2
  31. #define MXT_XML_SRC_AREA "AREA" //3
  32. #define MXT_XML_SRC_AMP "AMP" //4
  33. #define MXT_XML_SRC_SUM "SUM" //5
  34. #define MXT_XML_SRC_TCH "TCH" //6
  35. #define MXT_XML_SRC_ATCH "ATCH" //7
  36. #define MXT_XML_SRC_KCNT "KCNT" //8
  37. #define MXT_XML_SRC_KVAL "KVAL" //9
  38. #define MXT_XML_ACT_NONE "0" //0
  39. #define MXT_XML_ACT_CAL "CAL" //1
  40. #define MXT_XML_ACT_EXTMR "EXTMR" //2
  41. enum{
  42. MXT_PATCH_CON_NONE = 0,
  43. MXT_PATCH_CON_EQUAL, //1
  44. MXT_PATCH_CON_BELOW, //2
  45. MXT_PATCH_CON_ABOVE, //3
  46. MXT_PATCH_CON_PLUS, //4
  47. MXT_PATCH_CON_MINUS, //5
  48. MXT_PATCH_CON_MUL, //6
  49. MXT_PATCH_CON_DIV, //7
  50. MXT_PATCH_CON_MASK, //8
  51. //...
  52. MXT_PATCH_CON_END
  53. };
  54. enum {
  55. MXT_PATCH_ITEM_NONE = 0,
  56. MXT_PATCH_ITEM_CHARG, //1
  57. MXT_PATCH_ITEM_FCNT, //2
  58. MXT_PATCH_ITEM_AREA, //3
  59. MXT_PATCH_ITEM_AMP, //4
  60. MXT_PATCH_ITEM_SUM, //5
  61. MXT_PATCH_ITEM_TCH, //6
  62. MXT_PATCH_ITEM_ATCH, //7
  63. MXT_PATCH_ITEM_KCNT, //8
  64. MXT_PATCH_ITEM_KVAL, //9
  65. //...
  66. MXT_PATCH_ITEM_END
  67. };
  68. enum {
  69. MXT_PATCH_ACTION_NONE = 0,
  70. MXT_PATCH_ACTION_CAL,
  71. MXT_PATCH_ACTION_EXTEND_TIMER,
  72. MXT_PATCH_ACTION_GOTO_STAGE,
  73. //...
  74. MXT_PATCH_ACTION_END
  75. };
  76. struct patch_header{ // 32b
  77. u32 magic;
  78. u32 size;
  79. u32 date;
  80. u16 version;
  81. u8 option;
  82. u8 debug;
  83. u8 timer_id;
  84. u8 stage_cnt;
  85. u8 trigger_cnt;
  86. u8 event_cnt;
  87. u8 reserved[12];
  88. };
  89. struct stage_def{ // 8b
  90. u8 stage_id;
  91. u8 option;
  92. u16 stage_period;
  93. u8 cfg_cnt;
  94. u8 test_cnt;
  95. #if MXT_PATCH_STAGE_RESET
  96. u16 reset_period;
  97. #endif
  98. };
  99. struct stage_cfg{ // 4b
  100. u8 obj_type;
  101. u8 option;
  102. u8 offset;
  103. u8 val;
  104. };
  105. struct test_line{ // 12b
  106. u8 test_id;
  107. u8 item_cnt;
  108. u8 cfg_cnt;
  109. u8 act_id;
  110. u16 act_val;
  111. u16 option;
  112. u16 check_cnt;
  113. u8 reserved[2];
  114. };
  115. struct action_cfg{ // 4b
  116. u8 obj_type;
  117. u8 option;
  118. u8 offset;
  119. u8 val;
  120. };
  121. struct item_val{ // 4b
  122. u8 val_id;
  123. u8 val_eq;
  124. u16 val;
  125. };
  126. struct test_item{ // 8b
  127. u8 src_id;
  128. u8 cond;
  129. u8 reserved[2];
  130. struct item_val ival;
  131. };
  132. // Message Trigger
  133. struct trigger{ // 12b
  134. u8 tid;
  135. u8 option;
  136. u8 object;
  137. u8 index;
  138. u8 match_cnt;
  139. u8 cfg_cnt;
  140. u8 reserved[3];
  141. u8 act_id;
  142. u16 act_val;
  143. };
  144. struct match{ //8b
  145. u8 offset;
  146. u8 cond;
  147. u16 mask;
  148. u8 reserved[2];
  149. u16 val;
  150. };
  151. struct trigger_cfg{ // 4b
  152. u8 obj_type;
  153. u8 reserved;
  154. u8 offset;
  155. u8 val;
  156. };
  157. // Event
  158. struct user_event{ // 8b
  159. u8 eid;
  160. u8 option;
  161. u8 cfg_cnt;
  162. u8 reserved[5];
  163. };
  164. struct event_cfg{ // 4b
  165. u8 obj_type;
  166. u8 reserved;
  167. u8 offset;
  168. u8 val;
  169. };
  170. /*
  171. Source
  172. */
  173. struct test_src{
  174. int charger;
  175. int finger_cnt;
  176. int area;
  177. int amp;
  178. int sum_size;
  179. int tch_ch;
  180. int atch_ch;
  181. int key_cnt;
  182. int key_val;
  183. };
  184. #if MXT_PATCH_LOCK_CHECK
  185. struct touch_pos{
  186. u8 tcount[MXT_MAX_FINGER];
  187. u16 initx[MXT_MAX_FINGER];
  188. u16 inity[MXT_MAX_FINGER];
  189. u16 oldx[MXT_MAX_FINGER];
  190. u16 oldy[MXT_MAX_FINGER];
  191. u8 locked_id;
  192. u8 moved_cnt;
  193. u8 option;
  194. u8 cal_enable;
  195. u8 reset_cnt;
  196. u8 distance;
  197. u8 maxdiff;
  198. u8 locked_cnt;
  199. u8 jitter;
  200. };
  201. #endif
  202. #ifndef __mxt_patch_debug
  203. #define __mxt_patch_debug(_data, ...) if(data->patch.debug) \
  204. dev_info(&(_data)->client->dev, __VA_ARGS__);
  205. #endif
  206. #ifndef __mxt_patch_ddebug
  207. #define __mxt_patch_ddebug(_data, ...) if(data->patch.debug>1) \
  208. dev_info(&(_data)->client->dev, __VA_ARGS__);
  209. #endif
  210. /* Function Define */
  211. static void mxt_patch_dump_source(struct mxt_data *data,
  212. bool do_action);
  213. static int mxt_patch_run_stage(struct mxt_data *data);
  214. /* Porting */
  215. static void mxt_patch_calibration(struct mxt_data *data)
  216. {
  217. mxt_write_object(data, MXT_GEN_COMMANDPROCESSOR_T6,
  218. MXT_COMMAND_CALIBRATE, 1);
  219. }
  220. static int mxt_patch_start_timer(struct mxt_data *data, u16 period)
  221. {
  222. struct mxt_object* object;
  223. int ret = 0;
  224. u8 t61_reg[5] = {3, 1, 0, 0, 0};
  225. object = mxt_get_object(data, MXT_SPT_TIMER_T61);
  226. t61_reg[3] = period & 0xFF;
  227. t61_reg[4] = (period >> 8) & 0xFF;
  228. ret = mxt_write_mem(data, object->start_address+
  229. 5*data->patch.timer_id, 5, t61_reg);
  230. if (!ret) {
  231. __mxt_patch_debug(data, "START STAGE: %d TIMER[%d] %dms\n",
  232. data->patch.cur_stage, data->patch.timer_id, period);
  233. }
  234. return ret;
  235. }
  236. static int mxt_patch_stop_timer(struct mxt_data *data)
  237. {
  238. struct mxt_object* object;
  239. int ret = 0;
  240. u8 t61_reg[5] = {3, 2, 0, 0, 0}; //20120807
  241. object = mxt_get_object(data, MXT_SPT_TIMER_T61);
  242. ret = mxt_write_mem(data, object->start_address+
  243. 5*data->patch.timer_id, 5, t61_reg);
  244. if (!ret) {
  245. __mxt_patch_debug(data, "STOP TIMER[%d]\n",
  246. data->patch.timer_id);
  247. }
  248. return ret;
  249. }
  250. /*
  251. OPT= 0:ALL, 2:BATT ONLY, 3:TA ONLY
  252. */
  253. static int mxt_patch_check_tacfg(struct mxt_data *data,
  254. u8 option, u8 ta_mode)
  255. {
  256. if(option&0x02){
  257. if(ta_mode){//TA
  258. if((option&0x01)==0){
  259. __mxt_patch_ddebug(data, "|- SCFG BATT SKIP");
  260. return 1;
  261. }
  262. }
  263. else{// BATT
  264. if((option&0x01)==1){
  265. __mxt_patch_ddebug(data, "|- SCFG TA SKIP");
  266. return 1;
  267. }
  268. }
  269. }
  270. if(option&0x04){
  271. if(data->setdata){
  272. __mxt_patch_ddebug(data, "|- SCFG RF");
  273. return 0;
  274. }
  275. else{
  276. __mxt_patch_ddebug(data, "|- SCFG RF SKIP");
  277. return 1;
  278. }
  279. }
  280. return 0;
  281. }
  282. static int mxt_patch_write_stage_cfg(struct mxt_data *data,
  283. struct stage_cfg* pscfg, bool do_action)
  284. {
  285. if(do_action){
  286. #if TSP_INFORM_CHARGER
  287. if(mxt_patch_check_tacfg(data, pscfg->option,
  288. data->charging_mode)){
  289. return 0;
  290. }
  291. #endif
  292. __mxt_patch_debug(data, "|- SCFG_WRITE: OBJECT_TYPE:%d"
  293. " OFFSET:%d VAL:%d OPT:%d\n",
  294. pscfg->obj_type, pscfg->offset,
  295. pscfg->val, pscfg->option);
  296. mxt_write_object(data, pscfg->obj_type,
  297. pscfg->offset, pscfg->val);
  298. }
  299. return 0;
  300. }
  301. static int mxt_patch_write_action_cfg(struct mxt_data *data,
  302. struct action_cfg* pacfg, bool do_action)
  303. {
  304. if(do_action){
  305. #if TSP_INFORM_CHARGER
  306. if(mxt_patch_check_tacfg(data, pacfg->option,
  307. data->charging_mode)){
  308. return 0;
  309. }
  310. #endif
  311. __mxt_patch_debug(data, "|-- ACFG_WRITE: OBJECT_TYPE:%d"
  312. " OFFSET:%d VAL:%d OPT:%d\n",
  313. pacfg->obj_type, pacfg->offset,
  314. pacfg->val, pacfg->option);
  315. mxt_write_object(data, pacfg->obj_type,
  316. pacfg->offset, pacfg->val);
  317. }
  318. return 0;
  319. }
  320. static int mxt_patch_write_trigger_cfg(struct mxt_data *data,
  321. struct trigger_cfg* ptcfg, bool do_action)
  322. {
  323. if(do_action){
  324. __mxt_patch_debug(data, "|-- TCFG_WRITE: OBJECT_TYPE:%d"
  325. " OFFSET:%d VAL:%d\n",
  326. ptcfg->obj_type, ptcfg->offset, ptcfg->val);
  327. mxt_write_object(data, ptcfg->obj_type,
  328. ptcfg->offset, ptcfg->val);
  329. }
  330. return 0;
  331. }
  332. static int mxt_patch_write_event_cfg(struct mxt_data *data,
  333. struct event_cfg* pecfg, bool do_action)
  334. {
  335. if(do_action){
  336. __mxt_patch_debug(data, "|-- ECFG_WRITE: OBJECT_TYPE:%d"
  337. " OFFSET:%d VAL:%d\n",
  338. pecfg->obj_type, pecfg->offset, pecfg->val);
  339. mxt_write_object(data, pecfg->obj_type,
  340. pecfg->offset, pecfg->val);
  341. }
  342. return 0;
  343. }
  344. static int mxt_patch_predefined_action(struct mxt_data *data,
  345. u8 action_id, u16 action_val, bool do_action)
  346. {
  347. if(do_action){
  348. switch(action_id){
  349. case MXT_PATCH_ACTION_NONE:
  350. __mxt_patch_debug(data, "|-- ACTION NONE\n");
  351. break;
  352. case MXT_PATCH_ACTION_CAL:
  353. __mxt_patch_debug(data, "|-- ACTION CALIBRATE: %d\n",
  354. action_val);
  355. mxt_patch_calibration(data);
  356. data->patch.start = false; // Wait Restart
  357. data->patch.start_stage = action_val;
  358. break;
  359. case MXT_PATCH_ACTION_EXTEND_TIMER:
  360. __mxt_patch_debug(data, "|-- ACTION EXTEND TIMER: %d\n",
  361. action_val);
  362. mxt_patch_start_timer(data, action_val);
  363. break;
  364. case MXT_PATCH_ACTION_GOTO_STAGE:
  365. __mxt_patch_debug(data, "|-- ACTION GOTO STAGE: %d\n",
  366. action_val);
  367. data->patch.skip_test = 1;
  368. data->patch.cur_stage = action_val;
  369. data->patch.run_stage = false;
  370. break;
  371. default:
  372. __mxt_patch_debug(data, "@@ INVALID ACTION ID=%d !!\n",
  373. action_id);
  374. return -1;
  375. }
  376. }
  377. return 0;
  378. }
  379. #if MXT_PATCH_LOCK_CHECK
  380. #define MXT_PATCH_T71_PTN_OPT 1
  381. #define MXT_PATCH_T71_PTN_CAL 2
  382. struct touch_pos tpos_data;
  383. static void mxt_patch_init_tpos(struct mxt_data *data,
  384. struct touch_pos* tpos)
  385. {
  386. int i;
  387. for(i=0;i<MXT_MAX_FINGER;i++){
  388. tpos->tcount[i] = 0;
  389. tpos->initx[i] = 0;
  390. tpos->inity[i] = 0;
  391. tpos->oldx[i] = 0;
  392. tpos->oldy[i] = 0;
  393. }
  394. tpos->locked_id = 0xff;
  395. tpos->moved_cnt = 0;
  396. }
  397. static bool mxt_patch_check_locked(struct mxt_data *data,
  398. struct touch_pos* tpos, u8 tid, u16 x, u16 y)
  399. {
  400. s16 diffx, diffy;
  401. u32 distance;
  402. //OLD DIFF
  403. diffx = x - tpos->oldx[tid];
  404. diffy = y - tpos->oldy[tid];
  405. distance = abs(diffx) + abs(diffy);
  406. // INIT DIFF
  407. if((tpos->initx[tid] != 0)&&(tpos->inity[tid] != 0)){
  408. diffx = x - tpos->initx[tid];
  409. diffy = y - tpos->inity[tid];
  410. __mxt_patch_ddebug(data,
  411. "[TPOS] INITDIFF[%d] ABS X=%d, ABS Y=%d\n",
  412. tid, (int)abs(diffx), (int)abs(diffy));
  413. }
  414. if((tpos->initx[tid] == 0)&&(tpos->inity[tid] == 0)){
  415. __mxt_patch_ddebug(data,
  416. "[TPOS] INITSET[%d] X=%d, Y=%d\n", tid, x, y);
  417. tpos->initx[tid] = x;
  418. tpos->inity[tid] = y;
  419. tpos->moved_cnt = 0;
  420. }else{
  421. // OLD DIFF vs INIT DIFF
  422. if((distance < tpos->jitter)&&
  423. ((abs(diffx) > tpos->maxdiff)||
  424. (abs(diffy) > tpos->maxdiff))){
  425. tpos->moved_cnt++;
  426. }
  427. }
  428. if(tpos->moved_cnt > tpos->reset_cnt){
  429. __mxt_patch_ddebug(data,
  430. "[TPOS] RESET[%d] X=%d, Y=%d\n", tid, x, y);
  431. tpos->initx[tid] = x;
  432. tpos->inity[tid] = y;
  433. tpos->moved_cnt = 0;
  434. }
  435. //__mxt_patch_ddebug(data, "[TPOS] %d, %d, %d, %d, DISTANCE %d\n",
  436. // x, y, tpos->oldx[tid], tpos->oldy[tid], distance);
  437. if((distance < tpos->distance)&&
  438. (abs(diffx) < tpos->maxdiff)&&
  439. (abs(diffy) < tpos->maxdiff)){
  440. return true;
  441. }
  442. else
  443. return false;
  444. return false;
  445. }
  446. static void mxt_patch_check_pattern(struct mxt_data *data,
  447. struct touch_pos* tpos, u8 tid, u16 x, u16 y, u8 finger_cnt)
  448. {
  449. bool cal_condition=false;
  450. if(!finger_cnt){
  451. return;
  452. }
  453. if(mxt_patch_check_locked(data, tpos, tid, x, y)){
  454. tpos->tcount[tid] = tpos->tcount[tid]+1;
  455. //__mxt_patch_debug(data, "[TPOS] INC TCOUNT[%d]=%d\n",
  456. // tid, tpos->tcount[tid]);
  457. }else{
  458. tpos->tcount[tid] = 0;
  459. //__mxt_patch_debug(data, "[TPOS] CLEAR TCOUNT[%d]=%d\n",
  460. // tid, tpos->tcount[tid]);
  461. }
  462. tpos->oldx[tid] = x;
  463. tpos->oldy[tid] = y;
  464. if(finger_cnt == 1){
  465. if(tpos->tcount[tid] > tpos->locked_cnt){
  466. __mxt_patch_debug(data, "[TPOS] ONE TOUCH LOCKED\n");
  467. mxt_patch_init_tpos(data, tpos);
  468. cal_condition = true;
  469. }
  470. }else{
  471. if((tpos->tcount[tid] > tpos->locked_cnt) &&
  472. tpos->locked_id != tid && tpos->locked_id != 0xff){
  473. __mxt_patch_debug(data, "[TPOS] TWO TOUCH LOCKED [%d, %d]\n",
  474. tid, tpos->locked_id);
  475. mxt_patch_init_tpos(data, tpos);
  476. cal_condition = true;
  477. }
  478. if(tpos->tcount[tid] > tpos->locked_cnt){
  479. //__mxt_patch_debug(data, "[TSP] LOCKED FOUND %d\n",
  480. // tpos->locked_id);
  481. tpos->locked_id = tid;
  482. if(tpos->tcount[tid] > 200){
  483. __mxt_patch_debug(data, "[TPOS] OVER LOCKED\n");
  484. cal_condition = true;
  485. }
  486. }
  487. }
  488. if(cal_condition){
  489. int error = mxt_read_object(data,
  490. MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71,
  491. MXT_PATCH_T71_PTN_CAL, &tpos->cal_enable);
  492. if (error) {
  493. dev_err(&data->client->dev, "%s: Error read T71 [%d]\n",
  494. __func__, error);
  495. } else {
  496. if(tpos->cal_enable){
  497. __mxt_patch_debug(data, "[TPOS] CAL\n");
  498. mxt_patch_calibration(data);
  499. error = mxt_read_object(data,
  500. MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71,
  501. MXT_PATCH_T71_PTN_OPT, &tpos->option);
  502. if(!error){
  503. if(tpos->option&0x01){ // Onetime
  504. mxt_write_object(data,
  505. MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71,
  506. MXT_PATCH_T71_PTN_CAL, 0);
  507. __mxt_patch_debug(data, "[TPOS] DISABLE T71[2]\n");
  508. }
  509. }
  510. }
  511. else{
  512. __mxt_patch_debug(data, "[TPOS] SKIP CAL T71[2]=0\n");
  513. }
  514. }
  515. }
  516. }
  517. #endif
  518. #if MXT_PATCH_SUPP_CHECK
  519. struct touch_supp{
  520. u32 old_time;
  521. u8 repeat_cnt;
  522. u8 time_gap;
  523. u8 repeat_max;
  524. };
  525. struct touch_supp tsupp_data;
  526. static void mxt_patch_init_supp(struct mxt_data *data,
  527. struct touch_supp* tsup)
  528. {
  529. tsup->old_time = jiffies_to_msecs(jiffies);
  530. tsup->repeat_cnt = 0;
  531. }
  532. static void mxt_patch_check_supp(struct mxt_data *data, struct touch_supp* tsup)
  533. {
  534. u32 curr_time = jiffies_to_msecs(jiffies);
  535. u32 time_diff;
  536. time_diff = TIME_WRAP_AROUND(tsup->old_time, curr_time);
  537. if(time_diff < tsup->time_gap*100){
  538. __mxt_patch_debug(data, "[TSUP] Abnormal suppress %d\n",
  539. tsup->repeat_cnt);
  540. if(tsup->repeat_cnt++ > tsup->repeat_max){
  541. __mxt_patch_debug(data, "[TSUP] Abnormal suppress detected\n");
  542. mxt_patch_calibration(data);
  543. }
  544. }
  545. else{
  546. tsup->repeat_cnt = 0;
  547. __mxt_patch_debug(data, "[TSUP] Normal suppress\n");
  548. }
  549. tsup->old_time = curr_time;
  550. mxt_patch_dump_source(data, true);
  551. }
  552. #endif
  553. #define MXT_PATCH_T71_DATA_MAX 10
  554. static void mxt_patch_load_t71data(struct mxt_data *data)
  555. {
  556. struct mxt_object *obj;
  557. u8 buf[MXT_PATCH_T71_DATA_MAX];
  558. int error;
  559. obj = mxt_get_object(data,
  560. MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71);
  561. if(obj){
  562. error = mxt_read_mem(data, obj->start_address,
  563. MXT_PATCH_T71_DATA_MAX, buf);
  564. if(!error){
  565. #if MXT_PATCH_LOCK_CHECK
  566. struct touch_pos* tpos = &tpos_data;
  567. tpos->option = buf[MXT_PATCH_T71_PTN_OPT]; //1
  568. tpos->cal_enable = buf[MXT_PATCH_T71_PTN_CAL]; //1
  569. tpos->reset_cnt = buf[3]; //5
  570. tpos->distance = buf[4]; //10
  571. tpos->maxdiff = buf[5]; //10
  572. tpos->locked_cnt = buf[6]; //40
  573. tpos->jitter = buf[7]; //1
  574. __mxt_patch_debug(data,
  575. "PTN CAL %d RST %d DST %d DIF %d CNT %d JIT %d\n",
  576. tpos->cal_enable, tpos->reset_cnt,
  577. tpos->distance, tpos->maxdiff,
  578. tpos->locked_cnt, tpos->jitter);
  579. #endif
  580. #if MXT_PATCH_SUPP_CHECK
  581. tsupp_data.time_gap = buf[8]; //10
  582. tsupp_data.repeat_max = buf[9]; //2
  583. __mxt_patch_debug(data,
  584. "SUPP GAP %d*100ms CNT %d\n",
  585. tsupp_data.time_gap, tsupp_data.repeat_max);
  586. #endif
  587. }
  588. }
  589. }
  590. /* Patch */
  591. const char* mxt_patch_src_item_name(u8 src_id)
  592. {
  593. const char* src_item_name[MXT_PATCH_MAX_TYPE]={
  594. MXT_XML_SRC_NONE, //MXT_PATCH_ITEM_NONE 0
  595. MXT_XML_SRC_CHRG, //MXT_PATCH_ITEM_CHARGER 1
  596. MXT_XML_SRC_FCNT, //MXT_PATCH_ITEM_FINGER_CNT 2
  597. MXT_XML_SRC_AREA, //MXT_PATCH_ITEM_T9_AREA 3
  598. MXT_XML_SRC_AMP, //MXT_PATCH_ITEM_T9_AMP 4
  599. MXT_XML_SRC_SUM, //MXT_PATCH_ITEM_T57_SUM 5
  600. MXT_XML_SRC_TCH, //MXT_PATCH_ITEM_T57_TCH 6
  601. MXT_XML_SRC_ATCH, //MXT_PATCH_ITEM_T57_ATCH 7
  602. MXT_XML_SRC_KCNT, //MXT_PATCH_ITEM_KCNT 8
  603. MXT_XML_SRC_KVAL, //MXT_PATCH_ITEM_KVAL 9
  604. };
  605. if(MXT_PATCH_ITEM_NONE <= src_id &&
  606. src_id < MXT_PATCH_ITEM_END){
  607. return src_item_name[src_id];
  608. }
  609. return "ERR";
  610. }
  611. const char* mxt_patch_cond_name(u8 con_id)
  612. {
  613. const char* cond_name[MXT_PATCH_MAX_CON]={
  614. MXT_XML_CON_NONE, //MXT_PATCH_CON_NONE 0
  615. MXT_XML_CON_EQUAL, //MXT_PATCH_CON_EQUAL 1
  616. MXT_XML_CON_BELOW, //MXT_PATCH_CON_BELOW 2
  617. MXT_XML_CON_ABOVE, //MXT_PATCH_CON_ABOVE 3
  618. MXT_XML_CON_PLUS, //MXT_PATCH_CON_PLUS 4
  619. MXT_XML_CON_MINUS, //MXT_PATCH_CON_MINUS 5
  620. MXT_XML_CON_MUL, //MXT_PATCH_CON_MUL 6
  621. MXT_XML_CON_DIV, //MXT_PATCH_CON_DIV 7
  622. MXT_XML_CON_MASK, //MXT_PATCH_CON_MASK 8
  623. };
  624. if(MXT_PATCH_CON_NONE <= con_id &&
  625. con_id < MXT_PATCH_CON_END){
  626. return cond_name[con_id];
  627. }
  628. return "ERR";
  629. }
  630. static int mxt_patch_item_lval(struct mxt_data *data,
  631. u16* psrc_item, u8 src_id)
  632. {
  633. if(psrc_item != NULL){
  634. if(MXT_PATCH_ITEM_NONE <= src_id &&
  635. src_id < MXT_PATCH_ITEM_END){
  636. return psrc_item[src_id];
  637. }
  638. else{
  639. __mxt_patch_debug(data, "@@ INVALID ITEM ID=%d !!\n", src_id);
  640. }
  641. }
  642. return 0;
  643. }
  644. static int mxt_patch_item_rval(struct mxt_data *data,
  645. u16* psrc_item, struct item_val ival)
  646. {
  647. int lval = mxt_patch_item_lval(data, psrc_item, ival.val_id);
  648. int rval = ival.val;
  649. switch(ival.val_eq){
  650. case MXT_PATCH_CON_NONE:
  651. return lval ? lval : rval;
  652. case MXT_PATCH_CON_PLUS:
  653. lval += rval;
  654. break;
  655. case MXT_PATCH_CON_MINUS:
  656. lval -= rval;
  657. break;
  658. case MXT_PATCH_CON_MUL:
  659. lval *= rval;
  660. break;
  661. case MXT_PATCH_CON_DIV:
  662. lval /= rval;
  663. break;
  664. default:
  665. if(psrc_item){
  666. __mxt_patch_debug(data, "@@ INVALID VAL_EQ=%d"
  667. " (LVAL=%d) => RVAL=%d !!\n",
  668. ival.val_eq, lval, rval);
  669. }
  670. return rval;
  671. }
  672. return lval;
  673. }
  674. static int mxt_patch_item_check(struct mxt_data *data,
  675. u16* psrc_item, struct test_item* ptitem, bool do_action)
  676. {
  677. int lval = mxt_patch_item_lval(data, psrc_item, ptitem->src_id);
  678. int rval = mxt_patch_item_rval(data, psrc_item, ptitem->ival);
  679. if(!do_action){
  680. __mxt_patch_debug(data, "|-- ITEM SRC_ID:%s COND:%s"
  681. " VAL_ID:%s EQ:%s VAL:%d\n",
  682. mxt_patch_src_item_name(ptitem->src_id),
  683. mxt_patch_cond_name(ptitem->cond),
  684. mxt_patch_src_item_name(ptitem->ival.val_id),
  685. mxt_patch_cond_name(ptitem->ival.val_eq),
  686. ptitem->ival.val);
  687. }
  688. if(psrc_item){
  689. switch(ptitem->cond){
  690. case MXT_PATCH_CON_EQUAL:
  691. __mxt_patch_ddebug(data, "|--- IF %s: %d == %d = %d\n",
  692. mxt_patch_src_item_name(ptitem->src_id),
  693. lval, rval, lval == rval ? 1 : 0);
  694. return lval == rval ? 1 : 0;
  695. case MXT_PATCH_CON_BELOW:
  696. __mxt_patch_ddebug(data, "|--- IF %s: %d < %d = %d\n",
  697. mxt_patch_src_item_name(ptitem->src_id),
  698. lval, rval, lval < rval ? 1 : 0);
  699. return lval < rval ? 1 : 0;
  700. case MXT_PATCH_CON_ABOVE:
  701. __mxt_patch_ddebug(data, "|--- IF %s: %d > %d = %d\n",
  702. mxt_patch_src_item_name(ptitem->src_id),
  703. lval, rval, lval > rval ? 1 : 0);
  704. return lval > rval ? 1 : 0;
  705. case MXT_PATCH_CON_MASK:
  706. __mxt_patch_ddebug(data, "|--- IF %s: %d & %d = %d\n",
  707. mxt_patch_src_item_name(ptitem->src_id),
  708. lval, rval, lval & rval ? 1 : 0);
  709. return lval & rval ? 1 : 0;
  710. default:
  711. __mxt_patch_debug(data, "@@ INVALID TEST COND=%d !!\n",
  712. ptitem->cond);
  713. return -1;
  714. }
  715. }
  716. return -1;
  717. }
  718. static int mxt_patch_stage_timer(struct mxt_data *data,
  719. u16 period, bool do_action)
  720. {
  721. if(do_action){
  722. int ret = 0;
  723. u32 time = period * 10;
  724. //__mxt_patch_debug(data, "STAGE[%d] TIMER: %dx10ms\n",
  725. // data->patch.cur_stage, period);
  726. ret = mxt_patch_start_timer(data, time);
  727. if (!ret) {
  728. data->patch.period = period;
  729. }
  730. }
  731. return 0;
  732. }
  733. static void mxt_patch_dump_source(struct mxt_data *data,
  734. bool do_action)
  735. {
  736. if(do_action){
  737. __mxt_patch_debug(data, "TA:%d FCNT:%d AREA:%d AMP:%d"
  738. " SUM:%d TCH:%d ATCH:%d KCNT:%d KVAL:%d\n",
  739. data->patch.src_item[1], data->patch.src_item[2],
  740. data->patch.src_item[3], data->patch.src_item[4],
  741. data->patch.src_item[5], data->patch.src_item[6],
  742. data->patch.src_item[7], data->patch.src_item[8],
  743. data->patch.src_item[9]);
  744. }
  745. }
  746. static int mxt_patch_parse_test_line(struct mxt_data *data,
  747. u8* ppatch, u16* psrc_item, u16* check_cnt, bool do_action)
  748. {
  749. struct test_line* ptline;
  750. struct test_item* ptitem;
  751. struct action_cfg* pacfg;
  752. u32 i=0, ulpos=0;
  753. u8 test_result=0;
  754. bool test_action=false;
  755. ptline = (struct test_line*)ppatch;
  756. if(!do_action){
  757. __mxt_patch_debug(data, "|- TEST_LINE:%X OPT:%d CHK_CNT:%d"
  758. " ITEM_CNT:%d CFG_CNT:%d ACTION:%d VAL:%d \n",
  759. ptline->test_id, ptline->option, ptline->check_cnt,
  760. ptline->item_cnt, ptline->cfg_cnt, ptline->act_id,
  761. ptline->act_val);
  762. }
  763. ulpos += sizeof(struct test_line);
  764. test_result = 0;
  765. test_action = false;
  766. for(i=0; i < ptline->item_cnt; i++){ /* Test Item Parsing */
  767. ptitem = (struct test_item*)(ppatch+ulpos);
  768. if(mxt_patch_item_check(data, psrc_item,
  769. ptitem, do_action) > 0){
  770. test_result++;
  771. if(test_result == ptline->item_cnt){
  772. if(check_cnt != NULL){
  773. *check_cnt = *check_cnt+1;
  774. if(*check_cnt == ptline->check_cnt){
  775. test_action = true;
  776. __mxt_patch_debug(data, "STAGE:%d TEST %d MATCHED",
  777. data->patch.cur_stage, ptline->test_id);
  778. mxt_patch_dump_source(data, test_action);
  779. if(ptline->option&0x01){
  780. *check_cnt=0;
  781. __mxt_patch_ddebug(data, "CHEK CNT CLEAR\n");
  782. }
  783. }
  784. }
  785. }
  786. }
  787. else{
  788. if(data->patch.option&0x04){
  789. if(do_action&&psrc_item){// Skip if any item was failed
  790. __mxt_patch_ddebug(data, "SKIP REMAINED ITEMS %d\n", i);
  791. return 0;
  792. }
  793. }
  794. }
  795. ulpos += sizeof(struct test_item);
  796. }
  797. for(i=0; i <ptline->cfg_cnt; i++){ /* Test Line Action config */
  798. pacfg = (struct action_cfg*)(ppatch+ulpos);
  799. if(!do_action){
  800. __mxt_patch_debug(data, "|-- ACTION_CFG: OBJ:%d"
  801. " OFFSET:%d VAL:%d OPT:%d\n",
  802. pacfg->obj_type, pacfg->offset,
  803. pacfg->val, pacfg->option);
  804. }
  805. mxt_patch_write_action_cfg(data, pacfg, test_action);
  806. ulpos += sizeof(struct action_cfg);
  807. }
  808. mxt_patch_predefined_action(data, ptline->act_id,
  809. ptline->act_val, test_action);
  810. return ulpos;
  811. }
  812. static int mxt_patch_parse_stage(struct mxt_data *data,
  813. u8* ppatch, u16* ptline_addr, u8* ptline_cnt, bool do_action)
  814. {
  815. struct stage_def* psdef;
  816. struct stage_cfg* pscfg;
  817. u32 i=0, ulpos=0;
  818. psdef = (struct stage_def*)ppatch;
  819. if(!do_action){
  820. __mxt_patch_debug(data,
  821. "STAGE_ID:%d OPT:%d PERIOD:%d CFG_CNT:%d TST_CNT:%d RESET:%d\n",
  822. psdef->stage_id, psdef->option, psdef->stage_period,
  823. psdef->cfg_cnt, psdef->test_cnt, psdef->reset_period);//MXT_PATCH_STAGE_RESET
  824. }
  825. mxt_patch_stage_timer(data, psdef->stage_period, do_action);
  826. ulpos += sizeof(struct stage_def);
  827. for(i=0; i < psdef->cfg_cnt; i++){ /* Stage Config Parsing */
  828. pscfg = (struct stage_cfg*)(ppatch+ulpos);
  829. if(!do_action){
  830. __mxt_patch_debug(data,
  831. "|- STAGE_CFG: OBJ:%d OFFSET:%d VAL:%d OPT:%d\n",
  832. pscfg->obj_type, pscfg->offset,
  833. pscfg->val, pscfg->option);
  834. }
  835. mxt_patch_write_stage_cfg(data, pscfg, do_action);
  836. ulpos += sizeof(struct stage_cfg);
  837. }
  838. for(i=0; i < psdef->test_cnt; i++){ /* Test Line Parsing */
  839. if(ptline_addr != NULL){
  840. ptline_addr[i] = (u16)ulpos;
  841. //__mxt_patch_debug(data, "|- TEST LINE_ADDR: %d\n", ulpos);
  842. }
  843. ulpos += mxt_patch_parse_test_line(data,
  844. ppatch+ulpos, NULL, NULL, do_action);
  845. }
  846. if(ptline_cnt != NULL)
  847. *ptline_cnt = psdef->test_cnt;
  848. return ulpos;
  849. }
  850. static u16 mxt_patch_match_lval(struct mxt_data *data,
  851. u8* pmsg, u8 offset, u16 mask)
  852. {
  853. u16 lval=0;
  854. u8 msg[MXT_PATCH_MAX_MSG_SIZE+1];
  855. memset(msg, 0, MXT_PATCH_MAX_MSG_SIZE+1);
  856. if(pmsg){
  857. memcpy(msg, pmsg, MXT_PATCH_MAX_MSG_SIZE);
  858. if(0 <= offset && offset < MXT_PATCH_MAX_MSG_SIZE){
  859. lval = msg[offset] | (msg[offset+1] << 8);
  860. return mask ? lval & mask : lval;
  861. }
  862. else{
  863. __mxt_patch_debug(data, "@@ INVALID OFFSET=%d !!\n",
  864. offset);
  865. }
  866. }
  867. return 0;
  868. }
  869. static int mxt_patch_match_check(struct mxt_data *data,
  870. u8* pmsg, struct match* pmatch, bool do_action)
  871. {
  872. u16 lval = mxt_patch_match_lval(data, pmsg,
  873. pmatch->offset, pmatch->mask);
  874. u16 rval = pmatch->val;
  875. if(pmsg){
  876. switch(pmatch->cond){
  877. case MXT_PATCH_CON_EQUAL:
  878. __mxt_patch_ddebug(data, "|--- IF %d == %d = %d\n",
  879. lval, rval, lval == rval ? 1 : 0);
  880. return lval == rval ? 1 : 0;
  881. case MXT_PATCH_CON_BELOW:
  882. __mxt_patch_ddebug(data, "|--- IF %d < %d = %d\n",
  883. lval, rval, lval < rval ? 1 : 0);
  884. return lval < rval ? 1 : 0;
  885. case MXT_PATCH_CON_ABOVE:
  886. __mxt_patch_ddebug(data, "|--- IF %d > %d = %d\n",
  887. lval, rval, lval > rval ? 1 : 0);
  888. return lval > rval ? 1 : 0;
  889. default:
  890. __mxt_patch_debug(data, "@@ INVALID MATCH COND=%d !!\n",
  891. pmatch->cond);
  892. return -1;
  893. }
  894. }
  895. return -1;
  896. }
  897. static int mxt_patch_trigger_check(struct mxt_data *data,
  898. u8 object, u8 index, u8* pmsg)
  899. {
  900. u8 reportid= pmsg[0];
  901. u8 type, id;
  902. type = data->reportids[reportid].type;
  903. id = data->reportids[reportid].index;
  904. if((type == object)&&(id == index))
  905. return 0;
  906. return 1;
  907. }
  908. static int mxt_patch_parse_trigger(struct mxt_data *data,
  909. u8* ppatch, u8* pmsg, bool do_action, u8 option)
  910. {
  911. struct trigger* ptrgg;
  912. struct match* pmatch;
  913. struct trigger_cfg* ptcfg;
  914. u32 i=0, ulpos=0;
  915. u8 match_result=0;
  916. u8 trigger_action=0;
  917. ptrgg = (struct trigger*)ppatch;
  918. if(!do_action){
  919. __mxt_patch_debug(data, "TRIGGER ID:%d OPT:%d OBJ:%d IDX:%d "
  920. "MATCH:%d CFG:%d ACT:%d VAL:%d\n",
  921. ptrgg->tid, ptrgg->option, ptrgg->object,
  922. ptrgg->index, ptrgg->match_cnt, ptrgg->cfg_cnt,
  923. ptrgg->act_id, ptrgg->act_val);
  924. }
  925. ulpos += sizeof(struct trigger);
  926. // Message Filter
  927. if(do_action){
  928. if(mxt_patch_trigger_check(data,
  929. ptrgg->object, ptrgg->index, pmsg))
  930. return 1;
  931. }
  932. // Match Parsing
  933. match_result=0;
  934. trigger_action=false;
  935. for(i=0; i < ptrgg->match_cnt; i++){
  936. pmatch = (struct match*)(ppatch+ulpos);
  937. if(!do_action){
  938. __mxt_patch_debug(data, "|- MATCH:%d OFFSET:%d MASK:%d"
  939. " COND:%s VAL:%d\n", i,
  940. pmatch->offset, pmatch->mask,
  941. mxt_patch_cond_name(pmatch->cond), pmatch->val);
  942. }
  943. if(mxt_patch_match_check(data, pmsg, pmatch, do_action) > 0){
  944. match_result++;
  945. if(match_result == ptrgg->match_cnt){
  946. if(option == ptrgg->option)
  947. trigger_action = true;
  948. }
  949. }
  950. ulpos += sizeof(struct match);
  951. }
  952. // Trigger Config Parsing
  953. for(i=0; i < ptrgg->cfg_cnt; i++){
  954. ptcfg = (struct trigger_cfg*)(ppatch+ulpos);
  955. if(!do_action){
  956. __mxt_patch_debug(data, "|- TRIGGER_CFG: OBJECT_TYPE:%d"
  957. " OFFSET:%d VAL:%d\n",
  958. ptcfg->obj_type, ptcfg->offset, ptcfg->val);
  959. }
  960. mxt_patch_write_trigger_cfg(data, ptcfg, trigger_action);
  961. ulpos += sizeof(struct trigger_cfg);
  962. }
  963. // Predefined Action
  964. mxt_patch_predefined_action(data, ptrgg->act_id,
  965. ptrgg->act_val, trigger_action);
  966. return ulpos;
  967. }
  968. int mxt_patch_parse_event(struct mxt_data *data,
  969. u8* ppatch, bool do_action)
  970. {
  971. struct user_event* pevent;
  972. struct event_cfg* pecfg;
  973. u32 i=0, ulpos=0;
  974. pevent = (struct user_event*)ppatch;
  975. if(!do_action){
  976. __mxt_patch_debug(data, "EVENT ID:%d OPT:%d CFG:%d\n",
  977. pevent->eid, pevent->option, pevent->cfg_cnt);
  978. }
  979. ulpos += sizeof(struct user_event);
  980. // Event Config Parsing
  981. for(i=0; i < pevent->cfg_cnt; i++){
  982. pecfg = (struct event_cfg*)(ppatch+ulpos);
  983. if(!do_action){
  984. __mxt_patch_debug(data, "|- EVENT_CFG: "
  985. "OBJECT_TYPE:%d OFFSET:%d VAL:%d\n",
  986. pecfg->obj_type, pecfg->offset, pecfg->val);
  987. }
  988. mxt_patch_write_event_cfg(data, pecfg, do_action);
  989. ulpos += sizeof(struct event_cfg);
  990. }
  991. return ulpos;
  992. }
  993. static int mxt_patch_parse_header(struct mxt_data *data,
  994. u8* ppatch, u16* pstage_addr, u16* ptrigger_addr,
  995. u16* pevent_addr)
  996. {
  997. struct patch_header* ppheader;
  998. u32 i=0, ulpos=0;
  999. ppheader = (struct patch_header*)ppatch;
  1000. dev_info(&data->client->dev, "PATCH MAGIC:%X SIZE:%d DATE:%d"
  1001. " VER:%d OPT:%d DBG:%d TMR:%d STG:%d TRG:%d EVT:%d\n",
  1002. ppheader->magic, ppheader->size, ppheader->date,
  1003. ppheader->version, ppheader->option, ppheader->debug,
  1004. ppheader->timer_id, ppheader->stage_cnt, ppheader->trigger_cnt,
  1005. ppheader->event_cnt);
  1006. if(ppheader->version != MXT_PATCH_VERSION){
  1007. dev_err(&data->client->dev, "MXT_PATCH_VERSION ERR\n");
  1008. }
  1009. ulpos = sizeof(struct patch_header);
  1010. for(i=0; i < ppheader->stage_cnt; i++){ /* Stage Def Parsing */
  1011. if(pstage_addr != NULL){
  1012. pstage_addr[i] = (u16)ulpos;
  1013. //__mxt_patch_debug(data, "STAGE_ADDR: %d\n", ulpos);
  1014. }
  1015. ulpos += mxt_patch_parse_stage(data, ppatch+ulpos,
  1016. NULL, NULL, false);
  1017. }
  1018. for(i=0; i < ppheader->trigger_cnt; i++){ /* Trigger Parsing */
  1019. if(ptrigger_addr != NULL){
  1020. ptrigger_addr[i] = (u16)ulpos;
  1021. //__mxt_patch_debug(data, "TRIGGER_ADDR: %d\n", ulpos);
  1022. }
  1023. ulpos += mxt_patch_parse_trigger(data, ppatch+ulpos,
  1024. NULL, false, 0);
  1025. }
  1026. for(i=0; i < ppheader->event_cnt; i++){ /* Event */
  1027. if(pevent_addr != NULL){
  1028. pevent_addr[i] = (u16)ulpos;
  1029. //__mxt_patch_debug(data, "EVENT_ADDR: %d\n", ulpos);
  1030. }
  1031. ulpos += mxt_patch_parse_event(data, ppatch+ulpos, false);
  1032. }
  1033. if(ppheader->size != ulpos){ /* Patch Size Check */
  1034. __mxt_patch_debug(data, "PATCH SIZE ERROR %d != %d\n\n",
  1035. ppheader->size, ulpos);
  1036. return 0;
  1037. }
  1038. else{
  1039. __mxt_patch_debug(data, "PATCH SIZE OK= %d\n\n", ulpos);
  1040. }
  1041. return ulpos;
  1042. }
  1043. static int mxt_patch_run_stage(struct mxt_data *data)
  1044. {
  1045. struct stage_def* psdef=NULL;
  1046. u8* ppatch = data->patch.patch;
  1047. u16* pstage_addr = data->patch.stage_addr;
  1048. u16 tline_addr[MXT_PATCH_MAX_TLINE];
  1049. u8 tline_cnt;
  1050. u8 cur_stage = data->patch.cur_stage;
  1051. //__mxt_patch_debug(data, "RUN STAGE:%d\n", cur_stage);
  1052. if(!ppatch || !pstage_addr){
  1053. dev_err(&data->client->dev, "%s pstage_addr is null\n", __func__);
  1054. return 1;
  1055. }
  1056. psdef = (struct stage_def*)(ppatch+pstage_addr[cur_stage]);
  1057. data->patch.cur_stage_opt = psdef->option;
  1058. mxt_patch_parse_stage(data, (u8*)psdef, tline_addr, &tline_cnt, true);
  1059. if(!data->patch.tline_addr){
  1060. kfree(data->patch.tline_addr);
  1061. }
  1062. if(!data->patch.check_cnt){
  1063. kfree(data->patch.check_cnt);
  1064. }
  1065. data->patch.tline_addr = kzalloc(tline_cnt*sizeof(u16), GFP_KERNEL);
  1066. data->patch.check_cnt = kzalloc(tline_cnt*sizeof(u16), GFP_KERNEL);
  1067. if (!data->patch.tline_addr || !data->patch.check_cnt){
  1068. dev_err(&data->client->dev, "tline_addr alloc error\n");
  1069. return 1;
  1070. }
  1071. memcpy(data->patch.tline_addr, tline_addr, tline_cnt*sizeof(u16));
  1072. memset(data->patch.check_cnt, 0, tline_cnt*sizeof(u16));
  1073. data->patch.tline_cnt = tline_cnt;
  1074. data->patch.run_stage = 1;
  1075. data->patch.skip_test = 0;
  1076. #if MXT_PATCH_STAGE_RESET
  1077. data->patch.stage_timestamp = jiffies_to_msecs(jiffies);
  1078. __mxt_patch_ddebug(data, "Stage[%d] %d\n",
  1079. cur_stage, data->patch.stage_timestamp);
  1080. #endif
  1081. return 0;
  1082. }
  1083. static int mxt_patch_test_source(struct mxt_data *data, u16* psrc_item)
  1084. {
  1085. int i;
  1086. u8* ppatch = data->patch.patch;
  1087. u16* pstage_addr = data->patch.stage_addr;
  1088. u8 cur_stage = data->patch.cur_stage;
  1089. #if MXT_PATCH_STAGE_RESET
  1090. u32 curr_time = jiffies_to_msecs(jiffies);
  1091. u32 time_diff = TIME_WRAP_AROUND(data->patch.stage_timestamp, curr_time);
  1092. struct stage_def* psdef=NULL;
  1093. #endif
  1094. if(!ppatch || !pstage_addr){
  1095. dev_err(&data->client->dev, "%s pstage_addr is null\n", __func__);
  1096. return 1;
  1097. }
  1098. if(!data->patch.run_stage){
  1099. mxt_patch_run_stage(data);
  1100. }
  1101. if(data->patch.run_stage){
  1102. for(i=0; i< data->patch.tline_cnt; i++){
  1103. u16* ptline_addr = data->patch.tline_addr;
  1104. u16* pcheck_cnt = data->patch.check_cnt;
  1105. if(!ptline_addr || !pcheck_cnt){
  1106. dev_err(&data->client->dev, "ptline_addr is null\n");
  1107. return 1;
  1108. }
  1109. __mxt_patch_ddebug(data, "STAGE:%d, TEST:%d\n", cur_stage, i);
  1110. mxt_patch_parse_test_line(data,
  1111. ppatch+pstage_addr[cur_stage]+ptline_addr[i],
  1112. psrc_item, &pcheck_cnt[i], true);
  1113. #if MXT_PATCH_STAGE_RESET
  1114. psdef = (struct stage_def*)(ppatch+pstage_addr[cur_stage]);
  1115. if(psdef->reset_period){
  1116. if(time_diff > psdef->reset_period*10){
  1117. pcheck_cnt[i] = 0;
  1118. __mxt_patch_ddebug(data,
  1119. "RESET CNT STAGE:%d, TEST:%d RESET:%d DIF:%d\n",
  1120. cur_stage, i,
  1121. psdef->reset_period, time_diff);
  1122. data->patch.stage_timestamp = jiffies_to_msecs(jiffies);
  1123. }
  1124. }
  1125. #endif
  1126. if(data->patch.skip_test){
  1127. __mxt_patch_debug(data, "REMAINED TEST SKIP\n");
  1128. return 0;
  1129. }
  1130. }
  1131. }
  1132. return 0;
  1133. }
  1134. static void mxt_patch_init_tsrc(struct test_src* tsrc)
  1135. {
  1136. tsrc->charger=-1;
  1137. tsrc->finger_cnt=-1;
  1138. tsrc->area=-1;
  1139. tsrc->amp=-1;
  1140. tsrc->sum_size=-1;
  1141. tsrc->tch_ch=-1;
  1142. tsrc->atch_ch=-1;
  1143. tsrc->key_cnt=-1;
  1144. tsrc->key_val=-1;
  1145. }
  1146. static int mxt_patch_make_source(struct mxt_data *data,
  1147. struct test_src* tsrc)
  1148. {
  1149. if(tsrc->charger >= 0)
  1150. data->patch.src_item[MXT_PATCH_ITEM_CHARG]= tsrc->charger;
  1151. if(tsrc->finger_cnt >= 0)
  1152. data->patch.src_item[MXT_PATCH_ITEM_FCNT]= tsrc->finger_cnt;
  1153. if(tsrc->area >= 0)
  1154. data->patch.src_item[MXT_PATCH_ITEM_AREA]= tsrc->area;
  1155. if(tsrc->amp >= 0)
  1156. data->patch.src_item[MXT_PATCH_ITEM_AMP]= tsrc->amp;
  1157. if(tsrc->sum_size >= 0)
  1158. data->patch.src_item[MXT_PATCH_ITEM_SUM]= tsrc->sum_size;
  1159. if(tsrc->tch_ch >= 0)
  1160. data->patch.src_item[MXT_PATCH_ITEM_TCH]= tsrc->tch_ch;
  1161. if(tsrc->atch_ch >= 0)
  1162. data->patch.src_item[MXT_PATCH_ITEM_ATCH]= tsrc->atch_ch;
  1163. if(tsrc->key_cnt >= 0)
  1164. data->patch.src_item[MXT_PATCH_ITEM_KCNT]= tsrc->key_cnt;
  1165. if(tsrc->key_val >= 0)
  1166. data->patch.src_item[MXT_PATCH_ITEM_KVAL]= tsrc->key_val;
  1167. //mxt_patch_dump_source(data, true);
  1168. return 0;
  1169. }
  1170. static int mxt_patch_start_stage(struct mxt_data *data)
  1171. {
  1172. if(data->patch.patch){
  1173. mxt_patch_stop_timer(data);
  1174. data->patch.start = true;
  1175. data->patch.cur_stage = 0;
  1176. data->patch.run_stage = false;
  1177. if(data->patch.start_stage){
  1178. data->patch.cur_stage = data->patch.start_stage;
  1179. }
  1180. __mxt_patch_debug(data, "PATCH: START STAGE %d\n",
  1181. data->patch.cur_stage);
  1182. #if MXT_PATCH_LOCK_CHECK
  1183. mxt_patch_init_tpos(data, &tpos_data);
  1184. #endif
  1185. #if MXT_PATCH_SUPP_CHECK
  1186. mxt_patch_init_supp(data, &tsupp_data);
  1187. #endif
  1188. return 0;
  1189. }
  1190. return 1;
  1191. }
  1192. static int mxt_patch_test_trigger(struct mxt_data *data,
  1193. struct mxt_message *message, u8 option)
  1194. {
  1195. int i;
  1196. u8* ppatch = data->patch.patch;
  1197. u16* ptrigger_addr = data->patch.trigger_addr;
  1198. u8 trigger_cnt = data->patch.trigger_cnt;
  1199. u8 tmsg[MXT_PATCH_MAX_MSG_SIZE];
  1200. if(!ppatch || !ptrigger_addr){
  1201. dev_err(&data->client->dev, "%s ptrigger_addr is null\n",
  1202. __func__);
  1203. return 1;
  1204. }
  1205. memset(tmsg, 0, MXT_PATCH_MAX_MSG_SIZE);
  1206. tmsg[0] = message->reportid;
  1207. memcpy(&tmsg[1], message->message, 8);
  1208. for(i=0; i< trigger_cnt; i++){
  1209. //__mxt_patch_debug(data, "TRIGGER:%d\n", i);
  1210. mxt_patch_parse_trigger(data, ppatch+ptrigger_addr[i],
  1211. tmsg, true, option);
  1212. }
  1213. return 0;
  1214. }
  1215. static int mxt_patch_test_event(struct mxt_data *data,
  1216. u8 event_id)
  1217. {
  1218. u8* ppatch = data->patch.patch;
  1219. u16* pevent_addr = data->patch.event_addr;
  1220. if(!ppatch || !pevent_addr){
  1221. dev_err(&data->client->dev, "%s pevent_addr is null\n",
  1222. __func__);
  1223. return 1;
  1224. }
  1225. if(event_id < data->patch.event_cnt){
  1226. mxt_patch_parse_event(data, ppatch+pevent_addr[event_id],
  1227. true);
  1228. }
  1229. return 0;
  1230. }
  1231. static void mxt_patch_T6_object(struct mxt_data *data,
  1232. struct mxt_message *message)
  1233. {
  1234. /* Normal mode */
  1235. if (message->message[0] == 0x00) {
  1236. //__mxt_patch_debug(data, "PATCH: NORMAL\n");
  1237. #if 0 //Event Test
  1238. if(data->patch.event_cnt)
  1239. mxt_patch_test_event(data, 0);
  1240. #endif
  1241. }
  1242. /* Calibration */
  1243. if (message->message[0] & 0x10){
  1244. __mxt_patch_debug(data, "PATCH: CAL\n");
  1245. mxt_patch_start_stage(data);
  1246. }
  1247. /* Reset */
  1248. if (message->message[0] & 0x80) {
  1249. __mxt_patch_debug(data, "PATCH: RESET\n");
  1250. data->patch.start_stage = 0;
  1251. mxt_patch_start_stage(data);
  1252. }
  1253. }
  1254. static void mxt_patch_T9_object(struct mxt_data *data,
  1255. struct mxt_message *message)
  1256. {
  1257. int id;
  1258. u8 *msg = message->message;
  1259. struct test_src tsrc;
  1260. id = data->reportids[message->reportid].index;
  1261. mxt_patch_init_tsrc(&tsrc);
  1262. tsrc.area = msg[4];
  1263. tsrc.amp = msg[5];
  1264. if(data->patch.start){
  1265. mxt_patch_make_source(data, &tsrc);
  1266. #if MXT_PATCH_SUPP_CHECK
  1267. if(data->patch.cur_stage_opt&0x02){
  1268. if((msg[0] & MXT_DETECT_MSG_MASK) != MXT_DETECT_MSG_MASK){
  1269. if (msg[0] & MXT_SUPPRESS_MSG_MASK){
  1270. mxt_patch_check_supp(data, &tsupp_data);
  1271. }
  1272. }
  1273. }
  1274. #endif
  1275. }
  1276. }
  1277. static void mxt_patch_T15_object(struct mxt_data *data,
  1278. struct mxt_message *message)
  1279. {
  1280. struct test_src tsrc;
  1281. unsigned long keystates = message->message[MXT_MSG_T15_KEYSTATE];
  1282. u8 key_cnt=0;
  1283. int i;
  1284. for(i=0; i < 8; i++){
  1285. if(test_bit(i, &keystates)){
  1286. key_cnt++;
  1287. }
  1288. }
  1289. mxt_patch_init_tsrc(&tsrc);
  1290. tsrc.key_cnt = key_cnt;
  1291. tsrc.key_val = keystates;
  1292. if(data->patch.start){
  1293. mxt_patch_make_source(data, &tsrc);
  1294. if(data->patch.option&0x02) //0905#2
  1295. mxt_patch_test_source(data, data->patch.src_item);
  1296. }
  1297. }
  1298. static void mxt_patch_T57_object(struct mxt_data *data,
  1299. struct mxt_message *message)
  1300. {
  1301. struct test_src tsrc;
  1302. u8 *msg = message->message;
  1303. u8 finger_cnt = 0;
  1304. int i;
  1305. mxt_patch_init_tsrc(&tsrc);
  1306. for (i = 0; i < MXT_MAX_FINGER; i++) {
  1307. if ((data->fingers[i].state != MXT_STATE_INACTIVE) &&
  1308. (data->fingers[i].state != MXT_STATE_RELEASE))
  1309. finger_cnt++;
  1310. }
  1311. #if TSP_INFORM_CHARGER
  1312. tsrc.charger = data->charging_mode;
  1313. #endif
  1314. tsrc.finger_cnt = finger_cnt;
  1315. tsrc.sum_size = msg[0] | (msg[1] << 8);
  1316. tsrc.tch_ch = msg[2] | (msg[3] << 8);
  1317. tsrc.atch_ch = msg[4] | (msg[5] << 8);
  1318. if(data->patch.start){
  1319. if((data->patch.option & 0x01)== 0x01 && !finger_cnt)
  1320. return;
  1321. mxt_patch_make_source(data, &tsrc);
  1322. mxt_patch_test_source(data, data->patch.src_item);
  1323. }
  1324. #if MXT_PATCH_LOCK_CHECK
  1325. if(data->patch.cur_stage_opt&0x01){
  1326. if(finger_cnt){
  1327. for (i = 0; i < MXT_MAX_FINGER; i++) {
  1328. if ((data->fingers[i].state != MXT_STATE_INACTIVE) &&
  1329. (data->fingers[i].state != MXT_STATE_RELEASE)){
  1330. mxt_patch_check_pattern(data, &tpos_data, i,
  1331. data->fingers[i].x, data->fingers[i].y, finger_cnt);
  1332. }
  1333. }
  1334. }
  1335. else{
  1336. mxt_patch_init_tpos(data, &tpos_data);
  1337. }
  1338. }
  1339. #endif
  1340. }
  1341. static void mxt_patch_T61_object(struct mxt_data *data,
  1342. struct mxt_message *message)
  1343. {
  1344. int id;
  1345. u8 *msg = message->message;
  1346. id = data->reportids[message->reportid].index;
  1347. if ((id != data->patch.timer_id) || ((msg[0] & 0xa0) != 0xa0))
  1348. return;
  1349. __mxt_patch_debug(data, "END STAGE %d TIMER\n",
  1350. data->patch.cur_stage);
  1351. if((data->patch.cur_stage+1) == data->patch.stage_cnt){
  1352. if(data->patch.period == 0){
  1353. __mxt_patch_debug(data, "EX-STAGE\n");
  1354. }
  1355. else{
  1356. data->patch.start = false;
  1357. __mxt_patch_debug(data, "END ALL STAGE\n");
  1358. }
  1359. }
  1360. else{
  1361. data->patch.cur_stage++;
  1362. data->patch.run_stage = false;
  1363. }
  1364. if(!data->patch.run_stage){
  1365. mxt_patch_run_stage(data);
  1366. }
  1367. }
  1368. static void mxt_patch_message(struct mxt_data *data,
  1369. struct mxt_message *message)
  1370. {
  1371. u8 reportid, type;
  1372. reportid = message->reportid;
  1373. if (reportid > data->max_reportid)
  1374. return;
  1375. type = data->reportids[reportid].type;
  1376. switch (type) {
  1377. case MXT_GEN_COMMANDPROCESSOR_T6:
  1378. mxt_patch_T6_object(data, message);
  1379. break;
  1380. case MXT_TOUCH_MULTITOUCHSCREEN_T9:
  1381. mxt_patch_T9_object(data, message);
  1382. break;
  1383. case MXT_TOUCH_KEYARRAY_T15:
  1384. mxt_patch_T15_object(data, message);
  1385. break;
  1386. case MXT_PROCI_EXTRATOUCHSCREENDATA_T57:
  1387. mxt_patch_T57_object(data, message);
  1388. break;
  1389. case MXT_SPT_TIMER_T61:
  1390. mxt_patch_T61_object(data, message);
  1391. break;
  1392. }
  1393. if(data->patch.trigger_cnt && type){
  1394. u8 option=0;
  1395. #if TSP_INFORM_CHARGER
  1396. option = data->charging_mode;
  1397. #endif
  1398. mxt_patch_test_trigger(data, message, option);
  1399. }
  1400. }
  1401. static int mxt_patch_init(struct mxt_data *data, u8* ppatch)
  1402. {
  1403. struct mxt_patch* patch_info= &data->patch;
  1404. struct patch_header* ppheader;
  1405. u16 stage_addr[32];
  1406. u16 trigger_addr[32];
  1407. u16 event_addr[32];
  1408. u32 patch_size=0;
  1409. if(!ppatch){
  1410. dev_info(&data->client->dev, "%s patch file error\n", __func__);
  1411. return 1;
  1412. }
  1413. patch_size = mxt_patch_parse_header(data,
  1414. ppatch, stage_addr, trigger_addr, event_addr);
  1415. if(!patch_size){
  1416. dev_info(&data->client->dev, "%s patch_size error\n", __func__);
  1417. return 1;
  1418. }
  1419. ppheader = (struct patch_header*)ppatch;
  1420. patch_info->timer_id = ppheader->timer_id;
  1421. patch_info->option = ppheader->option;
  1422. patch_info->debug = ppheader->debug;
  1423. patch_info->stage_cnt = ppheader->stage_cnt;
  1424. patch_info->trigger_cnt = ppheader->trigger_cnt;
  1425. patch_info->event_cnt = ppheader->event_cnt;
  1426. if(!data->patch.src_item){
  1427. kfree(data->patch.src_item);
  1428. }
  1429. patch_info->src_item = kzalloc(MXT_PATCH_ITEM_END*sizeof(u16),
  1430. GFP_KERNEL);
  1431. if(patch_info->stage_cnt){
  1432. if(!patch_info->stage_addr){
  1433. kfree(patch_info->stage_addr);
  1434. }
  1435. patch_info->stage_addr =
  1436. kzalloc(patch_info->stage_cnt*sizeof(u16), GFP_KERNEL);
  1437. if (!patch_info->stage_addr) {
  1438. dev_err(&data->client->dev, "stage_addr alloc error\n");
  1439. return 1;
  1440. }
  1441. memcpy(patch_info->stage_addr, stage_addr,
  1442. patch_info->stage_cnt*sizeof(u16));
  1443. }
  1444. if(patch_info->trigger_cnt){
  1445. if(!patch_info->trigger_addr){
  1446. kfree(patch_info->trigger_addr);
  1447. }
  1448. patch_info->trigger_addr =
  1449. kzalloc(patch_info->trigger_cnt*sizeof(u16), GFP_KERNEL);
  1450. if (!patch_info->trigger_addr) {
  1451. dev_err(&data->client->dev, "trigger_addr alloc error\n");
  1452. return 1;
  1453. }
  1454. memcpy(patch_info->trigger_addr, trigger_addr,
  1455. patch_info->trigger_cnt*sizeof(u16));
  1456. }
  1457. if(patch_info->event_cnt){
  1458. if(!patch_info->event_addr){
  1459. kfree(patch_info->event_addr);
  1460. }
  1461. patch_info->event_addr =
  1462. kzalloc(patch_info->event_cnt*sizeof(u16), GFP_KERNEL);
  1463. if (!patch_info->event_addr) {
  1464. dev_err(&data->client->dev, "event_addr alloc error\n");
  1465. return 1;
  1466. }
  1467. memcpy(patch_info->event_addr, event_addr,
  1468. patch_info->event_cnt*sizeof(u16));
  1469. }
  1470. mxt_patch_load_t71data(data);
  1471. return 0;
  1472. }
  1473. #endif