cyttsp5_device_access.c 143 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201
  1. /*
  2. * cyttsp5_device_access.c
  3. * Parade TrueTouch(TM) Standard Product V5 Device Access Module.
  4. * Configuration and Test command/status user interface.
  5. * For use with Parade touchscreen controllers.
  6. * Supported parts include:
  7. * CYTMA5XX
  8. * CYTMA448
  9. * CYTMA445A
  10. * CYTT21XXX
  11. * CYTT31XXX
  12. *
  13. * Copyright (C) 2015 Parade Technologies
  14. * Copyright (C) 2012-2015 Cypress Semiconductor
  15. *
  16. * This program is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU General Public License
  18. * version 2, and only version 2, as published by the
  19. * Free Software Foundation.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * Contact Parade Technologies at www.paradetech.com <ttdrivers@paradetech.com>
  27. *
  28. */
  29. #include "cyttsp5_regs.h"
  30. #include <linux/firmware.h>
  31. #include <linux/timer.h>
  32. #include <linux/timex.h>
  33. #include <linux/rtc.h>
  34. #define CY_CMCP_THRESHOLD_FILE_NAME "cyttsp5_thresholdfile.csv"
  35. #define CMCP_THRESHOLD_FILE_NAME "ttdl_cmcp_thresholdfile.csv"
  36. /* Max test case number */
  37. #define MAX_CASE_NUM (22)
  38. /* ASCII */
  39. #define ASCII_LF (0x0A)
  40. #define ASCII_CR (0x0D)
  41. #define ASCII_COMMA (0x2C)
  42. #define ASCII_ZERO (0x30)
  43. #define ASCII_NINE (0x39)
  44. /* Max characters of test case name */
  45. #define NAME_SIZE_MAX (50)
  46. /* Max sensor and button number */
  47. #define MAX_BUTTONS (HID_SYSINFO_MAX_BTN)
  48. #define MAX_SENSORS (1024)
  49. #define MAX_TX_SENSORS (128)
  50. #define MAX_RX_SENSORS (128)
  51. /* Multiply by 2 for double (min, max) values */
  52. #define TABLE_BUTTON_MAX_SIZE (MAX_BUTTONS * 2)
  53. #define TABLE_SENSOR_MAX_SIZE (MAX_SENSORS * 2)
  54. #define TABLE_TX_MAX_SIZE (MAX_TX_SENSORS*2)
  55. #define TABLE_RX_MAX_SIZE (MAX_RX_SENSORS*2)
  56. #define CM_PANEL_DATA_OFFSET (6)
  57. #define CM_BTN_DATA_OFFSET (6)
  58. #define CP_PANEL_DATA_OFFSET (6)
  59. #define CP_BTN_DATA_OFFSET (6)
  60. #define MAX_BUF_LEN (50000)
  61. /* cmcp csv file information */
  62. struct configuration {
  63. u32 cm_range_limit_row;
  64. u32 cm_range_limit_col;
  65. u32 cm_min_limit_cal;
  66. u32 cm_max_limit_cal;
  67. u32 cm_max_delta_sensor_percent;
  68. u32 cm_max_delta_button_percent;
  69. u32 min_sensor_rx;
  70. u32 max_sensor_rx;
  71. u32 min_sensor_tx;
  72. u32 max_sensor_tx;
  73. u32 min_button;
  74. u32 max_button;
  75. u32 max_delta_sensor;
  76. u32 cp_max_delta_sensor_rx_percent;
  77. u32 cp_max_delta_sensor_tx_percent;
  78. u32 cm_min_max_table_button[TABLE_BUTTON_MAX_SIZE];
  79. u32 cp_min_max_table_button[TABLE_BUTTON_MAX_SIZE];
  80. u32 cm_min_max_table_sensor[TABLE_SENSOR_MAX_SIZE];
  81. u32 cp_min_max_table_rx[TABLE_RX_MAX_SIZE];
  82. u32 cp_min_max_table_tx[TABLE_TX_MAX_SIZE];
  83. u32 cm_min_max_table_button_size;
  84. u32 cp_min_max_table_button_size;
  85. u32 cm_min_max_table_sensor_size;
  86. u32 cp_min_max_table_rx_size;
  87. u32 cp_min_max_table_tx_size;
  88. u32 cp_max_delta_button_percent;
  89. u32 cm_max_table_gradient_cols_percent[TABLE_TX_MAX_SIZE];
  90. u32 cm_max_table_gradient_cols_percent_size;
  91. u32 cm_max_table_gradient_rows_percent[TABLE_RX_MAX_SIZE];
  92. u32 cm_max_table_gradient_rows_percent_size;
  93. u32 cm_excluding_row_edge;
  94. u32 cm_excluding_col_edge;
  95. u32 rx_num;
  96. u32 tx_num;
  97. u32 btn_num;
  98. u32 cm_enabled;
  99. u32 cp_enabled;
  100. u32 is_valid_or_not;
  101. };
  102. /* Test case search definition */
  103. struct test_case_search {
  104. char name[NAME_SIZE_MAX]; /* Test case name */
  105. u32 name_size; /* Test case name size */
  106. u32 offset; /* Test case offset */
  107. };
  108. /* Test case field definition */
  109. struct test_case_field {
  110. char *name; /* Test case name */
  111. u32 name_size; /* Test case name size */
  112. u32 type; /* Test case type */
  113. u32 *bufptr; /* Buffer to store value information */
  114. u32 exist_or_not;/* Test case exist or not */
  115. u32 data_num; /* Buffer data number */
  116. u32 line_num; /* Buffer line number */
  117. };
  118. /* Test case type */
  119. enum test_case_type {
  120. TEST_CASE_TYPE_NO,
  121. TEST_CASE_TYPE_ONE,
  122. TEST_CASE_TYPE_MUL,
  123. TEST_CASE_TYPE_MUL_LINES,
  124. };
  125. /* Test case order in test_case_field_array */
  126. enum case_order {
  127. CM_TEST_INPUTS,
  128. CM_EXCLUDING_COL_EDGE,
  129. CM_EXCLUDING_ROW_EDGE,
  130. CM_GRADIENT_CHECK_COL,
  131. CM_GRADIENT_CHECK_ROW,
  132. CM_RANGE_LIMIT_ROW,
  133. CM_RANGE_LIMIT_COL,
  134. CM_MIN_LIMIT_CAL,
  135. CM_MAX_LIMIT_CAL,
  136. CM_MAX_DELTA_SENSOR_PERCENT,
  137. CM_MAX_DELTA_BUTTON_PERCENT,
  138. PER_ELEMENT_MIN_MAX_TABLE_BUTTON,
  139. PER_ELEMENT_MIN_MAX_TABLE_SENSOR,
  140. CP_TEST_INPUTS,
  141. CP_MAX_DELTA_SENSOR_RX_PERCENT,
  142. CP_MAX_DELTA_SENSOR_TX_PERCENT,
  143. CP_MAX_DELTA_BUTTON_PERCENT,
  144. CP_PER_ELEMENT_MIN_MAX_BUTTON,
  145. MIN_BUTTON,
  146. MAX_BUTTON,
  147. PER_ELEMENT_MIN_MAX_RX,
  148. PER_ELEMENT_MIN_MAX_TX,
  149. CASE_ORDER_MAX,
  150. };
  151. enum cmcp_test_item {
  152. CMCP_FULL = 0,
  153. CMCP_CM_PANEL,
  154. CMCP_CP_PANEL,
  155. CMCP_CM_BTN,
  156. CMCP_CP_BTN,
  157. };
  158. #define CM_ENABLED 0x10
  159. #define CP_ENABLED 0x20
  160. #define CM_PANEL (0x01 | CM_ENABLED)
  161. #define CP_PANEL (0x02 | CP_ENABLED)
  162. #define CM_BTN (0x04 | CM_ENABLED)
  163. #define CP_BTN (0x08 | CP_ENABLED)
  164. #define CMCP_FULL_CASE\
  165. (CM_PANEL | CP_PANEL | CM_BTN | CP_BTN | CM_ENABLED | CP_ENABLED)
  166. #define CYTTSP5_DEVICE_ACCESS_NAME "cyttsp5_device_access"
  167. #define CYTTSP5_INPUT_ELEM_SZ (sizeof("0xHH") + 1)
  168. #define STATUS_SUCCESS 0
  169. #define STATUS_FAIL -1
  170. #define PIP_CMD_MAX_LENGTH ((1 << 16) - 1)
  171. #ifdef TTHE_TUNER_SUPPORT
  172. struct heatmap_param {
  173. bool scan_start;
  174. enum scan_data_type_list data_type; /* raw, base, diff */
  175. int num_element;
  176. };
  177. #endif
  178. #define ABS(x) (((x) < 0) ? -(x) : (x))
  179. #define CY_MAX_CONFIG_BYTES 256
  180. #define CYTTSP5_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME "get_panel_data"
  181. #define TTHE_TUNER_MAX_BUF (CY_MAX_PRBUF_SIZE * 3)
  182. struct cyttsp5_device_access_data {
  183. struct device *dev;
  184. struct cyttsp5_sysinfo *si;
  185. struct mutex sysfs_lock;
  186. u8 status;
  187. u16 response_length;
  188. bool sysfs_nodes_created;
  189. struct kobject mfg_test;
  190. u8 panel_scan_data_id;
  191. u8 get_idac_data_id;
  192. u8 calibrate_sensing_mode;
  193. u8 calibrate_initialize_baselines;
  194. u8 baseline_sensing_mode;
  195. #ifdef TTHE_TUNER_SUPPORT
  196. struct heatmap_param heatmap;
  197. struct dentry *tthe_get_panel_data_debugfs;
  198. struct mutex debugfs_lock;
  199. u8 tthe_get_panel_data_buf[TTHE_TUNER_MAX_BUF];
  200. u8 tthe_get_panel_data_is_open;
  201. #endif
  202. struct dentry *cmcp_results_debugfs;
  203. struct dentry *base_dentry;
  204. struct dentry *mfg_test_dentry;
  205. u8 ic_buf[CY_MAX_PRBUF_SIZE];
  206. u8 response_buf[CY_MAX_PRBUF_SIZE];
  207. struct mutex cmcp_threshold_lock;
  208. u8 *cmcp_threshold_data;
  209. int cmcp_threshold_size;
  210. bool cmcp_threshold_loading;
  211. struct work_struct cmcp_threshold_update;
  212. struct completion builtin_cmcp_threshold_complete;
  213. int builtin_cmcp_threshold_status;
  214. bool is_manual_upgrade_enabled;
  215. struct configuration *configs;
  216. struct cmcp_data *cmcp_info;
  217. struct result *result;
  218. struct test_case_search *test_search_array;
  219. struct test_case_field *test_field_array;
  220. int cmcp_test_items;
  221. int test_executed;
  222. int cmcp_range_check;
  223. int cmcp_force_calibrate;
  224. int cmcp_test_in_progress;
  225. };
  226. struct cmcp_data {
  227. struct gd_sensor *gd_sensor_col;
  228. struct gd_sensor *gd_sensor_row;
  229. int32_t *cm_data_panel;
  230. int32_t *cp_tx_data_panel;
  231. int32_t *cp_rx_data_panel;
  232. int32_t *cp_tx_cal_data_panel;
  233. int32_t *cp_rx_cal_data_panel;
  234. int32_t cp_sensor_rx_delta;
  235. int32_t cp_sensor_tx_delta;
  236. int32_t cp_button_delta;
  237. int32_t *cm_btn_data;
  238. int32_t *cp_btn_data;
  239. int32_t *cm_sensor_column_delta;
  240. int32_t *cm_sensor_row_delta;
  241. int32_t cp_btn_cal;
  242. int32_t cm_btn_cal;
  243. int32_t cp_button_ave;
  244. int32_t cm_ave_data_panel;
  245. int32_t cp_tx_ave_data_panel;
  246. int32_t cp_rx_ave_data_panel;
  247. int32_t cm_cal_data_panel;
  248. int32_t cm_ave_data_btn;
  249. int32_t cm_cal_data_btn;
  250. int32_t cm_delta_data_btn;
  251. int32_t cm_sensor_delta;
  252. int32_t tx_num;
  253. int32_t rx_num;
  254. int32_t btn_num;
  255. };
  256. struct result {
  257. int32_t sensor_assignment;
  258. int32_t config_ver;
  259. int32_t revision_ctrl;
  260. int32_t device_id_high;
  261. int32_t device_id_low;
  262. bool cm_test_run;
  263. bool cp_test_run;
  264. /* Sensor Cm validation */
  265. bool cm_test_pass;
  266. bool cm_sensor_validation_pass;
  267. bool cm_sensor_row_delta_pass;
  268. bool cm_sensor_col_delta_pass;
  269. bool cm_sensor_gd_row_pass;
  270. bool cm_sensor_gd_col_pass;
  271. bool cm_sensor_calibration_pass;
  272. bool cm_sensor_delta_pass;
  273. bool cm_button_validation_pass;
  274. bool cm_button_delta_pass;
  275. int32_t *cm_sensor_raw_data;
  276. int32_t cm_sensor_calibration;
  277. int32_t cm_sensor_delta;
  278. int32_t *cm_button_raw_data;
  279. int32_t cm_button_delta;
  280. /* Sensor Cp validation */
  281. bool cp_test_pass;
  282. bool cp_sensor_delta_pass;
  283. bool cp_sensor_rx_delta_pass;
  284. bool cp_sensor_tx_delta_pass;
  285. bool cp_sensor_average_pass;
  286. bool cp_button_delta_pass;
  287. bool cp_button_average_pass;
  288. bool cp_rx_validation_pass;
  289. bool cp_tx_validation_pass;
  290. bool cp_button_validation_pass;
  291. int32_t *cp_sensor_rx_raw_data;
  292. int32_t *cp_sensor_tx_raw_data;
  293. int32_t cp_sensor_rx_delta;
  294. int32_t cp_sensor_tx_delta;
  295. int32_t cp_sensor_rx_calibration;
  296. int32_t cp_sensor_tx_calibration;
  297. int32_t *cp_button_raw_data;
  298. int32_t cp_button_delta;
  299. /*other validation*/
  300. bool short_test_pass;
  301. bool test_summary;
  302. uint8_t *cm_open_pwc;
  303. };
  304. static struct cyttsp5_core_commands *cmd;
  305. static struct cyttsp5_module device_access_module;
  306. static ssize_t cyttsp5_run_and_get_selftest_result_noprint(struct device *dev,
  307. char *buf, size_t buf_len, u8 test_id, u16 read_length,
  308. bool get_result_on_pass);
  309. static int _cyttsp5_calibrate_idacs_cmd(struct device *dev,
  310. u8 sensing_mode, u8 *status);
  311. static inline struct cyttsp5_device_access_data *cyttsp5_get_device_access_data(
  312. struct device *dev)
  313. {
  314. return cyttsp5_get_module_data(dev, &device_access_module);
  315. }
  316. static ssize_t cyttsp5_status_show(struct device *dev,
  317. struct device_attribute *attr, char *buf)
  318. {
  319. struct cyttsp5_device_access_data *dad
  320. = cyttsp5_get_device_access_data(dev);
  321. u8 val;
  322. mutex_lock(&dad->sysfs_lock);
  323. val = dad->status;
  324. mutex_unlock(&dad->sysfs_lock);
  325. return scnprintf(buf, CY_MAX_PRBUF_SIZE, "%d\n", val);
  326. }
  327. static DEVICE_ATTR(status, S_IRUSR, cyttsp5_status_show, NULL);
  328. static ssize_t cyttsp5_response_show(struct device *dev,
  329. struct device_attribute *attr, char *buf)
  330. {
  331. struct cyttsp5_device_access_data *dad
  332. = cyttsp5_get_device_access_data(dev);
  333. int i;
  334. ssize_t num_read;
  335. int index;
  336. mutex_lock(&dad->sysfs_lock);
  337. index = scnprintf(buf, CY_MAX_PRBUF_SIZE,
  338. "Status %d\n", dad->status);
  339. if (!dad->status)
  340. goto error;
  341. num_read = dad->response_length;
  342. for (i = 0; i < num_read; i++)
  343. index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index,
  344. "0x%02X\n", dad->response_buf[i]);
  345. index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index,
  346. "(%zd bytes)\n", num_read);
  347. error:
  348. mutex_unlock(&dad->sysfs_lock);
  349. return index;
  350. }
  351. static DEVICE_ATTR(response, S_IRUSR, cyttsp5_response_show, NULL);
  352. /*
  353. * Gets user input from sysfs and parse it
  354. * return size of parsed output buffer
  355. */
  356. static int cyttsp5_ic_parse_input(struct device *dev, const char *buf,
  357. size_t buf_size, u8 *ic_buf, size_t ic_buf_size)
  358. {
  359. const char *pbuf = buf;
  360. unsigned long value;
  361. char scan_buf[CYTTSP5_INPUT_ELEM_SZ];
  362. u32 i = 0;
  363. u32 j;
  364. int last = 0;
  365. int ret;
  366. parade_debug(dev, DEBUG_LEVEL_1,
  367. "%s: pbuf=%p buf=%p size=%zu %s=%zu buf=%s\n",
  368. __func__, pbuf, buf, buf_size, "scan buf size",
  369. CYTTSP5_INPUT_ELEM_SZ, buf);
  370. while (pbuf <= (buf + buf_size)) {
  371. if (i >= CY_MAX_CONFIG_BYTES) {
  372. dev_err(dev, "%s: %s size=%d max=%d\n", __func__,
  373. "Max cmd size exceeded", i,
  374. CY_MAX_CONFIG_BYTES);
  375. return -EINVAL;
  376. }
  377. if (i >= ic_buf_size) {
  378. dev_err(dev, "%s: %s size=%d buf_size=%zu\n", __func__,
  379. "Buffer size exceeded", i, ic_buf_size);
  380. return -EINVAL;
  381. }
  382. while (((*pbuf == ' ') || (*pbuf == ','))
  383. && (pbuf < (buf + buf_size))) {
  384. last = *pbuf;
  385. pbuf++;
  386. }
  387. if (pbuf >= (buf + buf_size))
  388. break;
  389. memset(scan_buf, 0, CYTTSP5_INPUT_ELEM_SZ);
  390. if ((last == ',') && (*pbuf == ',')) {
  391. dev_err(dev, "%s: %s \",,\" not allowed.\n", __func__,
  392. "Invalid data format.");
  393. return -EINVAL;
  394. }
  395. for (j = 0; j < (CYTTSP5_INPUT_ELEM_SZ - 1)
  396. && (pbuf < (buf + buf_size))
  397. && (*pbuf != ' ')
  398. && (*pbuf != ','); j++) {
  399. last = *pbuf;
  400. scan_buf[j] = *pbuf++;
  401. }
  402. ret = kstrtoul(scan_buf, 16, &value);
  403. if (ret < 0) {
  404. dev_err(dev, "%s: %s '%s' %s%s i=%d r=%d\n", __func__,
  405. "Invalid data format. ", scan_buf,
  406. "Use \"0xHH,...,0xHH\"", " instead.",
  407. i, ret);
  408. return ret;
  409. }
  410. ic_buf[i] = value;
  411. i++;
  412. }
  413. return i;
  414. }
  415. static ssize_t cyttsp5_command_store(struct device *dev,
  416. struct device_attribute *attr, const char *buf, size_t size)
  417. {
  418. struct cyttsp5_device_access_data *dad
  419. = cyttsp5_get_device_access_data(dev);
  420. ssize_t length;
  421. int rc;
  422. mutex_lock(&dad->sysfs_lock);
  423. dad->status = 0;
  424. dad->response_length = 0;
  425. length = cyttsp5_ic_parse_input(dev, buf, size, dad->ic_buf,
  426. CY_MAX_PRBUF_SIZE);
  427. if (length <= 0) {
  428. dev_err(dev, "%s: %s Group Data store\n", __func__,
  429. "Malformed input for");
  430. goto exit;
  431. }
  432. /* write ic_buf to log */
  433. cyttsp5_pr_buf(dev, dad->ic_buf, length, "ic_buf");
  434. pm_runtime_get_sync(dev);
  435. rc = cmd->nonhid_cmd->user_cmd(dev, 1, CY_MAX_PRBUF_SIZE,
  436. dad->response_buf, length, dad->ic_buf,
  437. &dad->response_length);
  438. pm_runtime_put(dev);
  439. if (rc) {
  440. dad->response_length = 0;
  441. dev_err(dev, "%s: Failed to store command\n", __func__);
  442. } else {
  443. dad->status = 1;
  444. }
  445. exit:
  446. mutex_unlock(&dad->sysfs_lock);
  447. parade_debug(dev, DEBUG_LEVEL_2, "%s: return size=%zu\n",
  448. __func__, size);
  449. return size;
  450. }
  451. static DEVICE_ATTR(command, S_IWUSR, NULL, cyttsp5_command_store);
  452. static int cmcp_check_config_fw_match(struct device *dev,
  453. struct configuration *configuration)
  454. {
  455. struct cyttsp5_device_access_data *dad
  456. = cyttsp5_get_device_access_data(dev);
  457. int32_t tx_num = dad->configs->tx_num;
  458. int32_t rx_num = dad->configs->rx_num;
  459. int32_t button_num = dad->configs->btn_num;
  460. int ret = 0;
  461. if (tx_num != dad->si->sensing_conf_data.tx_num) {
  462. dev_err(dev, "%s: TX number mismatch!\n", __func__);
  463. ret = -EINVAL;
  464. }
  465. if (rx_num != dad->si->sensing_conf_data.rx_num) {
  466. dev_err(dev, "%s: RX number mismatch!\n", __func__);
  467. ret = -EINVAL;
  468. }
  469. if (button_num != dad->si->num_btns) {
  470. dev_err(dev, "%s: Button number mismatch!\n", __func__);
  471. ret = -EINVAL;
  472. }
  473. return ret;
  474. }
  475. static int validate_cm_test_results(struct device *dev,
  476. struct configuration *configuration, struct cmcp_data *cmcp_info,
  477. struct result *result, bool *pass, int test_item)
  478. {
  479. int32_t tx_num = cmcp_info->tx_num;
  480. int32_t rx_num = cmcp_info->rx_num;
  481. int32_t button_num = cmcp_info->btn_num;
  482. uint32_t sensor_num = tx_num * rx_num;
  483. int32_t *cm_sensor_data = cmcp_info->cm_data_panel;
  484. int32_t cm_button_delta;
  485. int32_t cm_sensor_calibration;
  486. int32_t *cm_button_data = cmcp_info->cm_btn_data;
  487. struct gd_sensor *gd_sensor_col = cmcp_info->gd_sensor_col;
  488. struct gd_sensor *gd_sensor_row = cmcp_info->gd_sensor_row;
  489. int32_t *cm_sensor_column_delta = cmcp_info->cm_sensor_column_delta;
  490. int32_t *cm_sensor_row_delta = cmcp_info->cm_sensor_row_delta;
  491. int ret = 0;
  492. int i, j;
  493. parade_debug(dev, DEBUG_LEVEL_2, "%s: start\n", __func__);
  494. if ((test_item & CM_PANEL) == CM_PANEL) {
  495. parade_debug(dev, DEBUG_LEVEL_2, "Check each sensor Cm data for min max value\n ");
  496. /* Check each sensor Cm data for min/max values */
  497. result->cm_sensor_validation_pass = true;
  498. for (i = 0; i < sensor_num; i++) {
  499. int row = i % rx_num;
  500. int col = i / rx_num;
  501. int32_t cm_sensor_min =
  502. configuration->cm_min_max_table_sensor[(row*tx_num+col)*2];
  503. int32_t cm_sensor_max =
  504. configuration->cm_min_max_table_sensor[(row*tx_num+col)*2+1];
  505. if ((cm_sensor_data[i] < cm_sensor_min)
  506. || (cm_sensor_data[i] > cm_sensor_max)) {
  507. dev_err(dev, "%s: Sensor[%d,%d]:%d (%d,%d)\n",
  508. "Cm sensor min/max test",
  509. row, col,
  510. cm_sensor_data[i],
  511. cm_sensor_min, cm_sensor_max);
  512. result->cm_sensor_validation_pass = false;
  513. }
  514. }
  515. /*check cm gradient column data*/
  516. result->cm_sensor_gd_col_pass = true;
  517. for (i = 0;
  518. i < configuration->cm_max_table_gradient_cols_percent_size;
  519. i++) {
  520. if ((gd_sensor_col + i)->gradient_val >
  521. 10 * configuration->cm_max_table_gradient_cols_percent[i]){
  522. dev_err(dev,
  523. "%s: cm_max_table_gradient_cols_percent[%d]:%d, gradient_val:%d\n",
  524. __func__,
  525. i,
  526. configuration->cm_max_table_gradient_cols_percent[i],
  527. (gd_sensor_col + i)->gradient_val);
  528. result->cm_sensor_gd_col_pass = false;
  529. }
  530. }
  531. /*check cm gradient row data*/
  532. result->cm_sensor_gd_row_pass = true;
  533. for (j = 0;
  534. j < configuration->cm_max_table_gradient_rows_percent_size;
  535. j++) {
  536. if ((gd_sensor_row + j)->gradient_val >
  537. 10 * configuration->cm_max_table_gradient_rows_percent[j]) {
  538. dev_err(dev,
  539. "%s: cm_max_table_gradient_rows_percent[%d]:%d, gradient_val:%d\n",
  540. __func__,
  541. j, configuration->cm_max_table_gradient_rows_percent[j],
  542. (gd_sensor_row + j)->gradient_val);
  543. result->cm_sensor_gd_row_pass = false;
  544. }
  545. }
  546. result->cm_sensor_row_delta_pass = true;
  547. result->cm_sensor_col_delta_pass = true;
  548. result->cm_sensor_calibration_pass = true;
  549. result->cm_sensor_delta_pass = true;
  550. /*
  551. * Check each row Cm data
  552. * with neighbor for difference
  553. */
  554. for (i = 0; i < tx_num; i++) {
  555. for (j = 1; j < rx_num; j++) {
  556. int32_t cm_sensor_row_diff =
  557. ABS(cm_sensor_data[i * rx_num + j] -
  558. cm_sensor_data[i * rx_num + j - 1]);
  559. cm_sensor_row_delta[i * rx_num + j - 1] =
  560. cm_sensor_row_diff;
  561. if (cm_sensor_row_diff
  562. > configuration->cm_range_limit_row) {
  563. dev_err(dev,
  564. "%s: Sensor[%d,%d]:%d (%d)\n",
  565. "Cm sensor row range limit test",
  566. j, i,
  567. cm_sensor_row_diff,
  568. configuration->cm_range_limit_row);
  569. result->cm_sensor_row_delta_pass = false;
  570. }
  571. }
  572. }
  573. /*
  574. * Check each column Cm data
  575. * with neighbor for difference
  576. */
  577. for (i = 1; i < tx_num; i++) {
  578. for (j = 0; j < rx_num; j++) {
  579. int32_t cm_sensor_col_diff =
  580. ABS((int)cm_sensor_data[i * rx_num + j] -
  581. (int)cm_sensor_data[(i - 1) * rx_num + j]);
  582. cm_sensor_column_delta[(i - 1) * rx_num + j] =
  583. cm_sensor_col_diff;
  584. if (cm_sensor_col_diff >
  585. configuration->cm_range_limit_col) {
  586. dev_err(dev,
  587. "%s: Sensor[%d,%d]:%d (%d)\n",
  588. "Cm sensor column range limit test",
  589. j, i,
  590. cm_sensor_col_diff,
  591. configuration->cm_range_limit_col);
  592. result->cm_sensor_col_delta_pass = false;
  593. }
  594. }
  595. }
  596. /* Check sensor calculated Cm for min/max values */
  597. cm_sensor_calibration = cmcp_info->cm_cal_data_panel;
  598. if (cm_sensor_calibration <
  599. configuration->cm_min_limit_cal
  600. || cm_sensor_calibration >
  601. configuration->cm_max_limit_cal) {
  602. dev_err(dev, "%s: Cm_cal:%d (%d,%d)\n",
  603. "Cm sensor Cm_cal min/max test",
  604. cm_sensor_calibration,
  605. configuration->cm_min_limit_cal,
  606. configuration->cm_max_limit_cal);
  607. result->cm_sensor_calibration_pass = false;
  608. }
  609. /* Check sensor Cm delta for range limit */
  610. if (cmcp_info->cm_sensor_delta
  611. > 10 * configuration->cm_max_delta_sensor_percent) {
  612. dev_err(dev,
  613. "%s: Cm_sensor_delta:%d (%d)\n",
  614. "Cm sensor delta range limit test",
  615. cmcp_info->cm_sensor_delta,
  616. configuration->cm_max_delta_sensor_percent);
  617. result->cm_sensor_delta_pass = false;
  618. }
  619. result->cm_test_pass = result->cm_sensor_gd_col_pass
  620. && result->cm_sensor_gd_row_pass
  621. && result->cm_sensor_validation_pass
  622. && result->cm_sensor_row_delta_pass
  623. && result->cm_sensor_col_delta_pass
  624. && result->cm_sensor_calibration_pass
  625. && result->cm_sensor_delta_pass;
  626. }
  627. if (((test_item & CM_BTN) == CM_BTN) && (cmcp_info->btn_num)) {
  628. /* Check each button Cm data for min/max values */
  629. result->cm_button_validation_pass = true;
  630. for (i = 0; i < button_num; i++) {
  631. int32_t cm_button_min =
  632. configuration->cm_min_max_table_button[i * 2];
  633. int32_t cm_button_max =
  634. configuration->cm_min_max_table_button[i * 2 + 1];
  635. if ((cm_button_data[i] <= cm_button_min)
  636. || (cm_button_data[i] >= cm_button_max)) {
  637. dev_err(dev,
  638. "%s: Button[%d]:%d (%d,%d)\n",
  639. "Cm button min/max test",
  640. i,
  641. cm_button_data[i],
  642. cm_button_min, cm_button_max);
  643. result->cm_button_validation_pass = false;
  644. }
  645. }
  646. /* Check button Cm delta for range limit */
  647. result->cm_button_delta_pass = true;
  648. cm_button_delta = ABS((cmcp_info->cm_ave_data_btn -
  649. cmcp_info->cm_cal_data_btn) * 100 /
  650. cmcp_info->cm_ave_data_btn);
  651. if (cm_button_delta >
  652. configuration->cm_max_delta_button_percent) {
  653. dev_err(dev,
  654. "%s: Cm_button_delta:%d (%d)\n",
  655. "Cm button delta range limit test",
  656. cm_button_delta,
  657. configuration->cm_max_delta_button_percent);
  658. result->cm_button_delta_pass = false;
  659. }
  660. result->cm_test_pass = result->cm_test_pass
  661. && result->cm_button_validation_pass
  662. && result->cm_button_delta_pass;
  663. }
  664. if (pass)
  665. *pass = result->cm_test_pass;
  666. return ret;
  667. }
  668. static int validate_cp_test_results(struct device *dev,
  669. struct configuration *configuration, struct cmcp_data *cmcp_info,
  670. struct result *result, bool *pass, int test_item)
  671. {
  672. int i = 0;
  673. uint32_t configuration_rx_num;
  674. uint32_t configuration_tx_num;
  675. int32_t *cp_sensor_tx_data = cmcp_info->cp_tx_data_panel;
  676. int32_t *cp_sensor_rx_data = cmcp_info->cp_rx_data_panel;
  677. int32_t cp_button_delta;
  678. int32_t cp_button_average;
  679. result->cp_test_pass = true;
  680. configuration_rx_num = configuration->cp_min_max_table_rx_size/2;
  681. configuration_tx_num = configuration->cp_min_max_table_tx_size/2;
  682. parade_debug(dev, DEBUG_LEVEL_2, "%s start\n", __func__);
  683. if ((test_item & CP_PANEL) == CP_PANEL) {
  684. int32_t cp_sensor_tx_delta;
  685. int32_t cp_sensor_rx_delta;
  686. /* Check Sensor Cp delta for range limit */
  687. result->cp_sensor_delta_pass = true;
  688. /*check cp_sensor_tx_delta */
  689. for (i = 0; i < configuration_tx_num; i++) {
  690. cp_sensor_tx_delta =
  691. ABS((cmcp_info->cp_tx_cal_data_panel[i]-
  692. cmcp_info->cp_tx_data_panel[i]) * 100 /
  693. cmcp_info->cp_tx_data_panel[i]);
  694. if (cp_sensor_tx_delta >
  695. configuration->cp_max_delta_sensor_tx_percent) {
  696. dev_err(dev,
  697. "%s: Cp_sensor_tx_delta:%d (%d)\n",
  698. "Cp sensor delta range limit test",
  699. cp_sensor_tx_delta,
  700. configuration->cp_max_delta_sensor_tx_percent);
  701. result->cp_sensor_delta_pass = false;
  702. }
  703. }
  704. /*check cp_sensor_rx_delta */
  705. for (i = 0; i < configuration_rx_num; i++) {
  706. cp_sensor_rx_delta =
  707. ABS((cmcp_info->cp_rx_cal_data_panel[i] -
  708. cmcp_info->cp_rx_data_panel[i]) * 100 /
  709. cmcp_info->cp_rx_data_panel[i]);
  710. if (cp_sensor_rx_delta >
  711. configuration->cp_max_delta_sensor_rx_percent) {
  712. dev_err(dev,
  713. "%s: Cp_sensor_rx_delta:%d(%d)\n",
  714. "Cp sensor delta range limit test",
  715. cp_sensor_rx_delta,
  716. configuration->cp_max_delta_sensor_rx_percent);
  717. result->cp_sensor_delta_pass = false;
  718. }
  719. }
  720. /* Check sensor Cp rx for min/max values */
  721. result->cp_rx_validation_pass = true;
  722. for (i = 0; i < configuration_rx_num; i++) {
  723. int32_t cp_rx_min =
  724. configuration->cp_min_max_table_rx[i * 2];
  725. int32_t cp_rx_max =
  726. configuration->cp_min_max_table_rx[i * 2 + 1];
  727. if ((cp_sensor_rx_data[i] <= cp_rx_min)
  728. || (cp_sensor_rx_data[i] >= cp_rx_max)) {
  729. dev_err(dev,
  730. "%s: Cp Rx[%d]:%d (%d,%d)\n",
  731. "Cp Rx min/max test",
  732. i,
  733. (int)cp_sensor_rx_data[i],
  734. cp_rx_min, cp_rx_max);
  735. result->cp_rx_validation_pass = false;
  736. }
  737. }
  738. /* Check sensor Cp tx for min/max values */
  739. result->cp_tx_validation_pass = true;
  740. for (i = 0; i < configuration_tx_num; i++) {
  741. int32_t cp_tx_min =
  742. configuration->cp_min_max_table_tx[i * 2];
  743. int32_t cp_tx_max =
  744. configuration->cp_min_max_table_tx[i * 2 + 1];
  745. if ((cp_sensor_tx_data[i] <= cp_tx_min)
  746. || (cp_sensor_tx_data[i] >= cp_tx_max)) {
  747. dev_err(dev,
  748. "%s: Cp Tx[%d]:%d(%d,%d)\n",
  749. "Cp Tx min/max test",
  750. i,
  751. cp_sensor_tx_data[i],
  752. cp_tx_min, cp_tx_max);
  753. result->cp_tx_validation_pass = false;
  754. }
  755. }
  756. result->cp_test_pass = result->cp_test_pass
  757. && result->cp_sensor_delta_pass
  758. && result->cp_rx_validation_pass
  759. && result->cp_tx_validation_pass;
  760. }
  761. if (((test_item & CP_BTN) == CP_BTN) && (cmcp_info->btn_num)) {
  762. result->cp_button_delta_pass = true;
  763. /* Check button Cp delta for range limit */
  764. cp_button_delta = ABS((cmcp_info->cp_btn_cal
  765. - cmcp_info->cp_button_ave) * 100 /
  766. cmcp_info->cp_button_ave);
  767. if (cp_button_delta >
  768. configuration->cp_max_delta_button_percent) {
  769. dev_err(dev,
  770. "%s: Cp_button_delta:%d (%d)\n",
  771. "Cp button delta range limit test",
  772. cp_button_delta,
  773. configuration->cp_max_delta_button_percent);
  774. result->cp_button_delta_pass = false;
  775. }
  776. /* Check button Cp average for min/max values */
  777. result->cp_button_average_pass = true;
  778. cp_button_average = cmcp_info->cp_button_ave;
  779. if (cp_button_average < configuration->min_button
  780. || cp_button_average >
  781. configuration->max_button) {
  782. dev_err(dev,
  783. "%s: Button Cp average fails min/max test\n",
  784. __func__);
  785. dev_err(dev,
  786. "%s: Cp_button_average:%d (%d,%d)\n",
  787. "Cp button average min/max test",
  788. cp_button_average,
  789. configuration->min_button,
  790. configuration->max_button);
  791. result->cp_button_average_pass = false;
  792. }
  793. /* Check each button Cp data for min/max values */
  794. result->cp_button_validation_pass = true;
  795. for (i = 0; i < cmcp_info->btn_num; i++) {
  796. int32_t cp_button_min =
  797. configuration->cp_min_max_table_button[i * 2];
  798. int32_t cp_button_max =
  799. configuration->cp_min_max_table_button[i * 2 + 1];
  800. if ((cmcp_info->cp_btn_data[i] <= cp_button_min)
  801. || (cmcp_info->cp_btn_data[i] >= cp_button_max)) {
  802. dev_err(dev,
  803. "%s: Button[%d]:%d (%d,%d)\n",
  804. "Cp button min/max test",
  805. i,
  806. cmcp_info->cp_btn_data[i],
  807. cp_button_min, cp_button_max);
  808. result->cp_button_validation_pass = false;
  809. }
  810. }
  811. result->cp_test_pass = result->cp_test_pass
  812. && result->cp_button_delta_pass
  813. && result->cp_button_average_pass
  814. && result->cp_button_validation_pass;
  815. }
  816. if (pass)
  817. *pass = result->cp_test_pass;
  818. return 0;
  819. }
  820. static void calculate_gradient_row(struct gd_sensor *gd_sensor_row_head,
  821. uint16_t row_num, int exclude_row_edge, int exclude_col_edge)
  822. {
  823. int i = 0;
  824. uint16_t cm_min_cur = 0;
  825. uint16_t cm_max_cur = 0;
  826. uint16_t cm_ave_cur = 0;
  827. uint16_t cm_ave_next = 0;
  828. uint16_t cm_ave_prev = 0;
  829. struct gd_sensor *p = gd_sensor_row_head;
  830. if (exclude_row_edge) {
  831. for (i = 0; i < row_num; i++) {
  832. if (!exclude_col_edge) {
  833. cm_ave_cur = (p + i)->cm_ave;
  834. cm_min_cur = (p + i)->cm_min;
  835. cm_max_cur = (p + i)->cm_max;
  836. if (i < (row_num-1))
  837. cm_ave_next = (p + i+1)->cm_ave;
  838. if (i > 0)
  839. cm_ave_prev = (p + i-1)->cm_ave;
  840. } else {
  841. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  842. cm_min_cur = (p + i)->cm_min_exclude_edge;
  843. cm_max_cur = (p + i)->cm_max_exclude_edge;
  844. if (i < (row_num-1))
  845. cm_ave_next =
  846. (p + i+1)->cm_ave_exclude_edge;
  847. if (i > 0)
  848. cm_ave_prev =
  849. (p + i-1)->cm_ave_exclude_edge;
  850. }
  851. if (cm_ave_cur == 0)
  852. cm_ave_cur = 1;
  853. /*multiple 1000 to increate accuracy*/
  854. if ((i == 0) || (i == (row_num-1))) {
  855. (p + i)->gradient_val =
  856. (cm_max_cur - cm_min_cur) * 1000 /
  857. cm_ave_cur;
  858. } else if (i == 1) {
  859. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  860. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  861. cm_ave_cur;
  862. } else {
  863. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  864. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  865. cm_ave_cur;
  866. }
  867. }
  868. } else if (!exclude_row_edge) {
  869. for (i = 0; i < row_num; i++) {
  870. if (!exclude_col_edge) {
  871. cm_ave_cur = (p + i)->cm_ave;
  872. cm_min_cur = (p + i)->cm_min;
  873. cm_max_cur = (p + i)->cm_max;
  874. if (i < (row_num-1))
  875. cm_ave_next = (p + i+1)->cm_ave;
  876. if (i > 0)
  877. cm_ave_prev = (p + i-1)->cm_ave;
  878. } else {
  879. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  880. cm_min_cur = (p + i)->cm_min_exclude_edge;
  881. cm_max_cur = (p + i)->cm_max_exclude_edge;
  882. if (i < (row_num-1))
  883. cm_ave_next =
  884. (p + i+1)->cm_ave_exclude_edge;
  885. if (i > 0)
  886. cm_ave_prev =
  887. (p + i-1)->cm_ave_exclude_edge;
  888. }
  889. if (cm_ave_cur == 0)
  890. cm_ave_cur = 1;
  891. /*multiple 1000 to increate accuracy*/
  892. if (i <= 1)
  893. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  894. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  895. cm_ave_cur;
  896. else
  897. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  898. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  899. cm_ave_cur;
  900. }
  901. }
  902. }
  903. static void calculate_gradient_col(struct gd_sensor *gd_sensor_row_head,
  904. uint16_t col_num, int exclude_row_edge, int exclude_col_edge)
  905. {
  906. int i = 0;
  907. int32_t cm_min_cur = 0;
  908. int32_t cm_max_cur = 0;
  909. int32_t cm_ave_cur = 0;
  910. int32_t cm_ave_next = 0;
  911. int32_t cm_ave_prev = 0;
  912. struct gd_sensor *p = gd_sensor_row_head;
  913. if (!exclude_col_edge) {
  914. for (i = 0; i < col_num; i++) {
  915. if (!exclude_row_edge) {
  916. cm_ave_cur = (p + i)->cm_ave;
  917. cm_min_cur = (p + i)->cm_min;
  918. cm_max_cur = (p + i)->cm_max;
  919. if (i < (col_num-1))
  920. cm_ave_next = (p + i+1)->cm_ave;
  921. if (i > 0)
  922. cm_ave_prev = (p + i-1)->cm_ave;
  923. } else {
  924. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  925. cm_min_cur = (p + i)->cm_min_exclude_edge;
  926. cm_max_cur = (p + i)->cm_max_exclude_edge;
  927. if (i < (col_num-1))
  928. cm_ave_next =
  929. (p + i+1)->cm_ave_exclude_edge;
  930. if (i > 0)
  931. cm_ave_prev =
  932. (p + i-1)->cm_ave_exclude_edge;
  933. }
  934. if (cm_ave_cur == 0)
  935. cm_ave_cur = 1;
  936. /*multiple 1000 to increate accuracy*/
  937. if (i <= 1)
  938. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  939. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  940. cm_ave_cur;
  941. else
  942. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  943. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  944. cm_ave_cur;
  945. }
  946. } else if (exclude_col_edge) {
  947. for (i = 0; i < col_num; i++) {
  948. if (!exclude_row_edge) {
  949. cm_ave_cur = (p + i)->cm_ave;
  950. cm_min_cur = (p + i)->cm_min;
  951. cm_max_cur = (p + i)->cm_max;
  952. if (i < (col_num-1))
  953. cm_ave_next = (p + i+1)->cm_ave;
  954. if (i > 0)
  955. cm_ave_prev = (p + i-1)->cm_ave;
  956. } else {
  957. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  958. cm_min_cur = (p + i)->cm_min_exclude_edge;
  959. cm_max_cur = (p + i)->cm_max_exclude_edge;
  960. if (i < (col_num-1))
  961. cm_ave_next =
  962. (p + i+1)->cm_ave_exclude_edge;
  963. if (i > 0)
  964. cm_ave_prev =
  965. (p + i-1)->cm_ave_exclude_edge;
  966. }
  967. if (cm_ave_cur == 0)
  968. cm_ave_cur = 1;
  969. /*multiple 1000 to increate accuracy*/
  970. if ((i == 0) || (i == (col_num - 1)))
  971. (p + i)->gradient_val =
  972. (cm_max_cur - cm_min_cur) * 1000 /
  973. cm_ave_cur;
  974. else if (i == 1)
  975. (p + i)->gradient_val =
  976. (cm_max_cur - cm_min_cur +
  977. ABS(cm_ave_cur - cm_ave_next))
  978. * 1000 / cm_ave_cur;
  979. else
  980. (p + i)->gradient_val =
  981. (cm_max_cur - cm_min_cur +
  982. ABS(cm_ave_cur - cm_ave_prev))
  983. * 1000 / cm_ave_cur;
  984. }
  985. }
  986. }
  987. static void fill_gd_sensor_table(struct gd_sensor *head, int32_t index,
  988. int32_t cm_max, int32_t cm_min, int32_t cm_ave,
  989. int32_t cm_max_exclude_edge, int32_t cm_min_exclude_edge,
  990. int32_t cm_ave_exclude_edge)
  991. {
  992. (head + index)->cm_max = cm_max;
  993. (head + index)->cm_min = cm_min;
  994. (head + index)->cm_ave = cm_ave;
  995. (head + index)->cm_ave_exclude_edge = cm_ave_exclude_edge;
  996. (head + index)->cm_max_exclude_edge = cm_max_exclude_edge;
  997. (head + index)->cm_min_exclude_edge = cm_min_exclude_edge;
  998. }
  999. static void calculate_gd_info(struct gd_sensor *gd_sensor_col,
  1000. struct gd_sensor *gd_sensor_row, int tx_num, int rx_num,
  1001. int32_t *cm_sensor_data, int cm_excluding_row_edge,
  1002. int cm_excluding_col_edge)
  1003. {
  1004. int32_t cm_max;
  1005. int32_t cm_min;
  1006. int32_t cm_ave;
  1007. int32_t cm_max_exclude_edge;
  1008. int32_t cm_min_exclude_edge;
  1009. int32_t cm_ave_exclude_edge;
  1010. int32_t cm_data;
  1011. int i;
  1012. int j;
  1013. /*calculate all the gradient related info for column*/
  1014. for (i = 0; i < tx_num; i++) {
  1015. /*re-initialize for a new col*/
  1016. cm_max = cm_sensor_data[i * rx_num];
  1017. cm_min = cm_max;
  1018. cm_ave = 0;
  1019. cm_max_exclude_edge = cm_sensor_data[i * rx_num + 1];
  1020. cm_min_exclude_edge = cm_max_exclude_edge;
  1021. cm_ave_exclude_edge = 0;
  1022. for (j = 0; j < rx_num; j++) {
  1023. cm_data = cm_sensor_data[i * rx_num + j];
  1024. if (cm_data > cm_max)
  1025. cm_max = cm_data;
  1026. if (cm_data < cm_min)
  1027. cm_min = cm_data;
  1028. cm_ave += cm_data;
  1029. /*calculate exclude edge data*/
  1030. if ((j > 0) && (j < (rx_num-1))) {
  1031. if (cm_data > cm_max_exclude_edge)
  1032. cm_max_exclude_edge = cm_data;
  1033. if (cm_data < cm_min_exclude_edge)
  1034. cm_min_exclude_edge = cm_data;
  1035. cm_ave_exclude_edge += cm_data;
  1036. }
  1037. }
  1038. cm_ave /= rx_num;
  1039. cm_ave_exclude_edge /= (rx_num-2);
  1040. fill_gd_sensor_table(gd_sensor_col, i, cm_max, cm_min, cm_ave,
  1041. cm_max_exclude_edge, cm_min_exclude_edge, cm_ave_exclude_edge);
  1042. }
  1043. calculate_gradient_col(gd_sensor_col, tx_num, cm_excluding_row_edge,
  1044. cm_excluding_col_edge);
  1045. /*calculate all the gradient related info for row*/
  1046. for (j = 0; j < rx_num; j++) {
  1047. /*re-initialize for a new row*/
  1048. cm_max = cm_sensor_data[j];
  1049. cm_min = cm_max;
  1050. cm_ave = 0;
  1051. cm_max_exclude_edge = cm_sensor_data[rx_num + j];
  1052. cm_min_exclude_edge = cm_max_exclude_edge;
  1053. cm_ave_exclude_edge = 0;
  1054. for (i = 0; i < tx_num; i++) {
  1055. cm_data = cm_sensor_data[i * rx_num + j];
  1056. if (cm_data > cm_max)
  1057. cm_max = cm_data;
  1058. if (cm_data < cm_min)
  1059. cm_min = cm_data;
  1060. cm_ave += cm_data;
  1061. /*calculate exclude edge data*/
  1062. if ((i > 0) && (i < (tx_num-1))) {
  1063. if (cm_data > cm_max_exclude_edge)
  1064. cm_max_exclude_edge = cm_data;
  1065. if (cm_data < cm_min_exclude_edge)
  1066. cm_min_exclude_edge = cm_data;
  1067. cm_ave_exclude_edge += cm_data;
  1068. }
  1069. }
  1070. cm_ave /= tx_num;
  1071. cm_ave_exclude_edge /= (tx_num-2);
  1072. fill_gd_sensor_table(gd_sensor_row, j, cm_max, cm_min, cm_ave,
  1073. cm_max_exclude_edge, cm_min_exclude_edge, cm_ave_exclude_edge);
  1074. }
  1075. calculate_gradient_row(gd_sensor_row, rx_num, cm_excluding_row_edge,
  1076. cm_excluding_col_edge);
  1077. }
  1078. static int cyttsp5_get_cmcp_info(struct cyttsp5_device_access_data *dad,
  1079. struct cmcp_data *cmcp_info)
  1080. {
  1081. struct device *dev;
  1082. int32_t *cm_data_panel = cmcp_info->cm_data_panel;
  1083. int32_t *cp_tx_data_panel = cmcp_info->cp_tx_data_panel;
  1084. int32_t *cp_rx_data_panel = cmcp_info->cp_rx_data_panel;
  1085. int32_t *cp_tx_cal_data_panel = cmcp_info->cp_tx_cal_data_panel;
  1086. int32_t *cp_rx_cal_data_panel = cmcp_info->cp_rx_cal_data_panel;
  1087. int32_t *cm_btn_data = cmcp_info->cm_btn_data;
  1088. int32_t *cp_btn_data = cmcp_info->cp_btn_data;
  1089. struct gd_sensor *gd_sensor_col = cmcp_info->gd_sensor_col;
  1090. struct gd_sensor *gd_sensor_row = cmcp_info->gd_sensor_row;
  1091. struct result *result = dad->result;
  1092. int32_t cp_btn_cal = 0;
  1093. int32_t cm_btn_cal = 0;
  1094. int32_t cp_btn_ave = 0;
  1095. int32_t cm_ave_data_panel = 0;
  1096. int32_t cm_ave_data_btn = 0;
  1097. int32_t cm_delta_data_btn = 0;
  1098. int32_t cp_tx_ave_data_panel = 0;
  1099. int32_t cp_rx_ave_data_panel = 0;
  1100. u8 tmp_buf[3];
  1101. int tx_num;
  1102. int rx_num;
  1103. int btn_num;
  1104. int rc = 0;
  1105. int i;
  1106. dev = dad->dev;
  1107. cmcp_info->tx_num = dad->si->sensing_conf_data.tx_num;
  1108. cmcp_info->rx_num = dad->si->sensing_conf_data.rx_num;
  1109. cmcp_info->btn_num = dad->si->num_btns;
  1110. tx_num = cmcp_info->tx_num;
  1111. rx_num = cmcp_info->rx_num;
  1112. btn_num = cmcp_info->btn_num;
  1113. parade_debug(dev, DEBUG_LEVEL_2, "%s tx_num=%d", __func__, tx_num);
  1114. parade_debug(dev, DEBUG_LEVEL_2, "%s rx_num=%d", __func__, rx_num);
  1115. parade_debug(dev, DEBUG_LEVEL_2, "%s btn_num=%d", __func__, btn_num);
  1116. /*short test*/
  1117. result->short_test_pass = true;
  1118. rc = cyttsp5_run_and_get_selftest_result_noprint(
  1119. dev, tmp_buf, sizeof(tmp_buf),
  1120. CY_ST_ID_AUTOSHORTS, PIP_CMD_MAX_LENGTH, false);
  1121. if (rc) {
  1122. dev_err(dev, "short test not supported");
  1123. goto exit;
  1124. }
  1125. if (dad->ic_buf[1] != 0)
  1126. result->short_test_pass = false;
  1127. /*Get cm_panel data*/
  1128. rc = cyttsp5_run_and_get_selftest_result_noprint(
  1129. dev, tmp_buf, sizeof(tmp_buf),
  1130. CY_ST_ID_CM_PANEL, PIP_CMD_MAX_LENGTH, true);
  1131. if (rc) {
  1132. dev_err(dev, "Get CM Panel not supported");
  1133. goto exit;
  1134. }
  1135. if (cm_data_panel != NULL) {
  1136. for (i = 0; i < tx_num * rx_num; i++) {
  1137. cm_data_panel[i] =
  1138. 10*(dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2] + 256
  1139. * dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2+1]);
  1140. parade_debug(dev, DEBUG_LEVEL_2,
  1141. "cm_data_panel[%d]=%d\n",
  1142. i, cm_data_panel[i]);
  1143. cm_ave_data_panel += cm_data_panel[i];
  1144. }
  1145. cm_ave_data_panel /= (tx_num * rx_num);
  1146. cmcp_info->cm_ave_data_panel = cm_ave_data_panel;
  1147. cmcp_info->cm_cal_data_panel =
  1148. 10*(dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2]
  1149. +256 * dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2+1]);
  1150. /*multiple 1000 to increate accuracy*/
  1151. cmcp_info->cm_sensor_delta = ABS((cmcp_info->cm_ave_data_panel -
  1152. cmcp_info->cm_cal_data_panel) * 1000 /
  1153. cmcp_info->cm_ave_data_panel);
  1154. }
  1155. /*calculate gradient panel sensor column/row here*/
  1156. calculate_gd_info(gd_sensor_col, gd_sensor_row, tx_num, rx_num,
  1157. cm_data_panel, 1, 1);
  1158. for (i = 0; i < tx_num; i++) {
  1159. parade_debug(dev, DEBUG_LEVEL_2,
  1160. "i=%d max=%d,min=%d,ave=%d, gradient=%d",
  1161. i, gd_sensor_col[i].cm_max, gd_sensor_col[i].cm_min,
  1162. gd_sensor_col[i].cm_ave, gd_sensor_col[i].gradient_val);
  1163. }
  1164. for (i = 0; i < rx_num; i++) {
  1165. parade_debug(dev, DEBUG_LEVEL_2,
  1166. "i=%d max=%d,min=%d,ave=%d, gradient=%d",
  1167. i, gd_sensor_row[i].cm_max, gd_sensor_row[i].cm_min,
  1168. gd_sensor_row[i].cm_ave, gd_sensor_row[i].gradient_val);
  1169. }
  1170. /*Get cp data*/
  1171. rc = cyttsp5_run_and_get_selftest_result_noprint(
  1172. dev, tmp_buf, sizeof(tmp_buf),
  1173. CY_ST_ID_CP_PANEL, PIP_CMD_MAX_LENGTH, true);
  1174. if (rc) {
  1175. dev_err(dev, "Get CP Panel not supported");
  1176. goto exit;
  1177. }
  1178. /*Get cp_tx_data_panel*/
  1179. if (cp_tx_data_panel != NULL) {
  1180. for (i = 0; i < tx_num; i++) {
  1181. cp_tx_data_panel[i] =
  1182. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+i*2]
  1183. + 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+i*2+1]);
  1184. parade_debug(dev, DEBUG_LEVEL_2,
  1185. "cp_tx_data_panel[%d]=%d\n",
  1186. i, cp_tx_data_panel[i]);
  1187. cp_tx_ave_data_panel += cp_tx_data_panel[i];
  1188. }
  1189. cp_tx_ave_data_panel /= tx_num;
  1190. cmcp_info->cp_tx_ave_data_panel = cp_tx_ave_data_panel;
  1191. }
  1192. /*Get cp_tx_cal_data_panel*/
  1193. if (cp_tx_cal_data_panel != NULL) {
  1194. for (i = 0; i < tx_num; i++) {
  1195. cp_tx_cal_data_panel[i] =
  1196. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*2+i*2]
  1197. + 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*2+i*2+1]);
  1198. parade_debug(dev, DEBUG_LEVEL_2, " cp_tx_cal_data_panel[%d]=%d\n",
  1199. i, cp_tx_cal_data_panel[i]);
  1200. }
  1201. }
  1202. /*get cp_sensor_tx_delta,using the first sensor cal value for temp */
  1203. /*multiple 1000 to increase accuracy*/
  1204. cmcp_info->cp_sensor_tx_delta = ABS((cp_tx_cal_data_panel[0]
  1205. - cp_tx_ave_data_panel) * 1000 / cp_tx_ave_data_panel);
  1206. /*Get cp_rx_data_panel*/
  1207. if (cp_rx_data_panel != NULL) {
  1208. for (i = 0; i < rx_num; i++) {
  1209. cp_rx_data_panel[i] =
  1210. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+i*2] +
  1211. 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+i*2+1]);
  1212. parade_debug(dev, DEBUG_LEVEL_2,
  1213. "cp_rx_data_panel[%d]=%d\n", i,
  1214. cp_rx_data_panel[i]);
  1215. cp_rx_ave_data_panel += cp_rx_data_panel[i];
  1216. }
  1217. cp_rx_ave_data_panel /= rx_num;
  1218. cmcp_info->cp_rx_ave_data_panel = cp_rx_ave_data_panel;
  1219. }
  1220. /*Get cp_rx_cal_data_panel*/
  1221. if (cp_rx_cal_data_panel != NULL) {
  1222. for (i = 0; i < rx_num; i++) {
  1223. cp_rx_cal_data_panel[i] =
  1224. 10 * (dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+rx_num*2+i*2] +
  1225. 256 *
  1226. dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+rx_num*2+i*2+1]);
  1227. parade_debug(dev, DEBUG_LEVEL_2,
  1228. "cp_rx_cal_data_panel[%d]=%d\n", i,
  1229. cp_rx_cal_data_panel[i]);
  1230. }
  1231. }
  1232. /*get cp_sensor_rx_delta,using the first sensor cal value for temp */
  1233. /*multiple 1000 to increase accuracy*/
  1234. cmcp_info->cp_sensor_rx_delta = ABS((cp_rx_cal_data_panel[0]
  1235. - cp_rx_ave_data_panel) * 1000 / cp_rx_ave_data_panel);
  1236. if (btn_num == 0)
  1237. goto skip_button_test;
  1238. /*get cm btn data*/
  1239. rc = cyttsp5_run_and_get_selftest_result_noprint(
  1240. dev, tmp_buf, sizeof(tmp_buf),
  1241. CY_ST_ID_CM_BUTTON, PIP_CMD_MAX_LENGTH, true);
  1242. if (rc) {
  1243. dev_err(dev, "Get CM BTN not supported");
  1244. goto exit;
  1245. }
  1246. if (cm_btn_data != NULL) {
  1247. for (i = 0; i < btn_num; i++) {
  1248. cm_btn_data[i] =
  1249. 10 * (dad->ic_buf[CM_BTN_DATA_OFFSET+i*2] +
  1250. 256 * dad->ic_buf[CM_BTN_DATA_OFFSET+i*2+1]);
  1251. parade_debug(dev, DEBUG_LEVEL_2,
  1252. " cm_btn_data[%d]=%d\n",
  1253. i, cm_btn_data[i]);
  1254. cm_ave_data_btn += cm_btn_data[i];
  1255. }
  1256. cm_ave_data_btn /= btn_num;
  1257. cm_btn_cal = 10*(dad->ic_buf[CM_BTN_DATA_OFFSET+i*2]
  1258. + 256 * dad->ic_buf[CM_BTN_DATA_OFFSET+i*2+1]);
  1259. /*multiple 1000 to increase accuracy*/
  1260. cm_delta_data_btn = ABS((cm_ave_data_btn-cm_btn_cal)
  1261. * 1000 / cm_ave_data_btn);
  1262. parade_debug(dev, DEBUG_LEVEL_2, " cm_btn_cal=%d\n",
  1263. cm_btn_cal);
  1264. cmcp_info->cm_ave_data_btn = cm_ave_data_btn;
  1265. cmcp_info->cm_cal_data_btn = cm_btn_cal;
  1266. cmcp_info->cm_delta_data_btn = cm_delta_data_btn;
  1267. }
  1268. /*get cp btn data*/
  1269. rc = cyttsp5_run_and_get_selftest_result_noprint(
  1270. dev, tmp_buf, sizeof(tmp_buf),
  1271. CY_ST_ID_CP_BUTTON, PIP_CMD_MAX_LENGTH, true);
  1272. if (rc) {
  1273. dev_err(dev, "Get CP BTN not supported");
  1274. goto exit;
  1275. }
  1276. if (cp_btn_data != NULL) {
  1277. for (i = 0; i < btn_num; i++) {
  1278. cp_btn_data[i] =
  1279. 10 * (dad->ic_buf[CP_BTN_DATA_OFFSET+i*2] +
  1280. 256 * dad->ic_buf[CP_BTN_DATA_OFFSET+i*2+1]);
  1281. cp_btn_ave += cp_btn_data[i];
  1282. parade_debug(dev, DEBUG_LEVEL_2,
  1283. "cp_btn_data[%d]=%d\n",
  1284. i, cp_btn_data[i]);
  1285. }
  1286. cp_btn_ave /= btn_num;
  1287. cp_btn_cal = 10*(dad->ic_buf[CP_BTN_DATA_OFFSET+i*2]
  1288. + 256 * dad->ic_buf[CP_BTN_DATA_OFFSET+i*2+1]);
  1289. cmcp_info->cp_button_ave = cp_btn_ave;
  1290. cmcp_info->cp_btn_cal = cp_btn_cal;
  1291. /*multiple 1000 to increase accuracy*/
  1292. cmcp_info->cp_button_delta = ABS((cp_btn_cal
  1293. - cp_btn_ave) * 1000 / cp_btn_ave);
  1294. parade_debug(dev, DEBUG_LEVEL_2, " cp_btn_cal=%d\n",
  1295. cp_btn_cal);
  1296. parade_debug(dev, DEBUG_LEVEL_2, " cp_btn_ave=%d\n",
  1297. cp_btn_ave);
  1298. }
  1299. skip_button_test:
  1300. exit:
  1301. return rc;
  1302. }
  1303. static void cyttsp5_free_cmcp_buf(struct cmcp_data *cmcp_info)
  1304. {
  1305. if (cmcp_info->gd_sensor_col != NULL)
  1306. kfree(cmcp_info->gd_sensor_col);
  1307. if (cmcp_info->gd_sensor_row != NULL)
  1308. kfree(cmcp_info->gd_sensor_row);
  1309. if (cmcp_info->cm_data_panel != NULL)
  1310. kfree(cmcp_info->cm_data_panel);
  1311. if (cmcp_info->cp_tx_data_panel != NULL)
  1312. kfree(cmcp_info->cp_tx_data_panel);
  1313. if (cmcp_info->cp_rx_data_panel != NULL)
  1314. kfree(cmcp_info->cp_rx_data_panel);
  1315. if (cmcp_info->cp_tx_cal_data_panel != NULL)
  1316. kfree(cmcp_info->cp_tx_cal_data_panel);
  1317. if (cmcp_info->cp_rx_cal_data_panel != NULL)
  1318. kfree(cmcp_info->cp_rx_cal_data_panel);
  1319. if (cmcp_info->cm_btn_data != NULL)
  1320. kfree(cmcp_info->cm_btn_data);
  1321. if (cmcp_info->cp_btn_data != NULL)
  1322. kfree(cmcp_info->cp_btn_data);
  1323. if (cmcp_info->cm_sensor_column_delta != NULL)
  1324. kfree(cmcp_info->cm_sensor_column_delta);
  1325. if (cmcp_info->cm_sensor_row_delta != NULL)
  1326. kfree(cmcp_info->cm_sensor_row_delta);
  1327. }
  1328. static int cyttsp5_cmcp_get_test_item(int item_input)
  1329. {
  1330. int test_item = 0;
  1331. switch (item_input) {
  1332. case CMCP_FULL:
  1333. test_item = CMCP_FULL_CASE;
  1334. break;
  1335. case CMCP_CM_PANEL:
  1336. test_item = CM_PANEL;
  1337. break;
  1338. case CMCP_CP_PANEL:
  1339. test_item = CP_PANEL;
  1340. break;
  1341. case CMCP_CM_BTN:
  1342. test_item = CM_BTN;
  1343. break;
  1344. case CMCP_CP_BTN:
  1345. test_item = CP_BTN;
  1346. break;
  1347. }
  1348. return test_item;
  1349. }
  1350. static ssize_t cyttsp5_cmcp_test_show(struct device *dev,
  1351. struct device_attribute *attr, char *buf)
  1352. {
  1353. struct cyttsp5_device_access_data *dad
  1354. = cyttsp5_get_device_access_data(dev);
  1355. struct cmcp_data *cmcp_info = dad->cmcp_info;
  1356. struct result *result = dad->result;
  1357. struct configuration *configuration = dad->configs;
  1358. bool final_pass = true;
  1359. static const char * const cmcp_test_case_array[] = {"Full Cm/Cp test",
  1360. "Cm panel test", "Cp panel test",
  1361. "Cm button test", "Cp button test"};
  1362. int index = 0;
  1363. int test_item = 0;
  1364. int no_builtin_file = 0;
  1365. int rc;
  1366. u8 status;
  1367. int self_test_id_supported = 0;
  1368. dev = dad->dev;
  1369. if ((configuration == NULL) || (cmcp_info == NULL))
  1370. goto exit;
  1371. mutex_lock(&dad->sysfs_lock);
  1372. if (dad->cmcp_test_in_progress) {
  1373. mutex_unlock(&dad->sysfs_lock);
  1374. goto cmcp_not_ready;
  1375. }
  1376. dad->cmcp_test_in_progress = 1;
  1377. dad->test_executed = 0;
  1378. test_item = cyttsp5_cmcp_get_test_item(dad->cmcp_test_items);
  1379. if (dad->builtin_cmcp_threshold_status < 0) {
  1380. dev_err(dev, "%s: No cmcp threshold file.\n", __func__);
  1381. no_builtin_file = 1;
  1382. mutex_unlock(&dad->sysfs_lock);
  1383. goto start_testing;
  1384. }
  1385. if (dad->cmcp_test_items < 0) {
  1386. parade_debug(dev, DEBUG_LEVEL_2,
  1387. "%s: Invalid test item! Should be 0~4!\n", __func__);
  1388. mutex_unlock(&dad->sysfs_lock);
  1389. goto invalid_item;
  1390. }
  1391. parade_debug(dev, DEBUG_LEVEL_2, "%s: Test item is %s, %d\n",
  1392. __func__, cmcp_test_case_array[dad->cmcp_test_items],
  1393. test_item);
  1394. if ((dad->si->num_btns == 0)
  1395. && ((dad->cmcp_test_items == CMCP_CM_BTN)
  1396. || (dad->cmcp_test_items == CMCP_CP_BTN))) {
  1397. parade_debug(dev, DEBUG_LEVEL_2,
  1398. "%s: FW doesn't support button!\n", __func__);
  1399. mutex_unlock(&dad->sysfs_lock);
  1400. goto invalid_item_btn;
  1401. }
  1402. mutex_unlock(&dad->sysfs_lock);
  1403. if (cmcp_check_config_fw_match(dev, configuration))
  1404. goto mismatch;
  1405. start_testing:
  1406. parade_debug(dev, DEBUG_LEVEL_2, "%s: Start Cm/Cp test!\n", __func__);
  1407. result->cm_test_pass = true;
  1408. result->cp_test_pass = true;
  1409. /*stop watchdog*/
  1410. rc = cmd->request_stop_wd(dev);
  1411. if (rc)
  1412. dev_err(dev, "stop watchdog failed");
  1413. /*force single tx*/
  1414. rc = cmd->nonhid_cmd->set_param(dev, 0, 0x1F, 1, 1);
  1415. if (rc)
  1416. dev_err(dev, "force single tx failed");
  1417. /*suspend_scanning */
  1418. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  1419. if (rc)
  1420. dev_err(dev, "suspend_scanning failed");
  1421. /*do calibration*/
  1422. if (!dad->cmcp_force_calibrate) {
  1423. parade_debug(dev, DEBUG_LEVEL_2, "do calibration in single tx mode");
  1424. rc = _cyttsp5_calibrate_idacs_cmd(dev, 0, &status);
  1425. if (rc < 0) {
  1426. dev_err(dev, "%s: Error on calibrate idacs for mutual r=%d\n",
  1427. __func__, rc);
  1428. }
  1429. rc = _cyttsp5_calibrate_idacs_cmd(dev, 1, &status);
  1430. if (rc < 0) {
  1431. dev_err(dev, "%s: Error on calibrate idacs for buttons r=%d\n",
  1432. __func__, rc);
  1433. }
  1434. rc = _cyttsp5_calibrate_idacs_cmd(dev, 2, &status);
  1435. if (rc < 0) {
  1436. dev_err(dev, "%s: Error on calibrate idacs for self r=%d\n",
  1437. __func__, rc);
  1438. }
  1439. }
  1440. /*resume_scanning */
  1441. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  1442. if (rc)
  1443. dev_err(dev, "resume_scanning failed");
  1444. /*get all cmcp data from FW*/
  1445. self_test_id_supported =
  1446. cyttsp5_get_cmcp_info(dad, cmcp_info);
  1447. if (self_test_id_supported)
  1448. dev_err(dev, "cyttsp5_get_cmcp_info failed");
  1449. /*restore to multi tx*/
  1450. rc = cmd->nonhid_cmd->set_param(dev, 0, 0x1F, 0, 1);
  1451. if (rc)
  1452. dev_err(dev, "restore multi tx failed");
  1453. /*suspend_scanning */
  1454. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  1455. if (rc)
  1456. dev_err(dev, "suspend_scanning failed");
  1457. /*do calibration*/
  1458. if (!dad->cmcp_force_calibrate) {
  1459. parade_debug(dev, DEBUG_LEVEL_2, "do calibration in multi tx mode");
  1460. rc = _cyttsp5_calibrate_idacs_cmd(dev, 0, &status);
  1461. if (rc < 0) {
  1462. dev_err(dev, "%s: Error on calibrate idacs for mutual r=%d\n",
  1463. __func__, rc);
  1464. }
  1465. rc = _cyttsp5_calibrate_idacs_cmd(dev, 1, &status);
  1466. if (rc < 0) {
  1467. dev_err(dev, "%s: Error on calibrate idacs for buttons r=%d\n",
  1468. __func__, rc);
  1469. }
  1470. rc = _cyttsp5_calibrate_idacs_cmd(dev, 2, &status);
  1471. if (rc < 0) {
  1472. dev_err(dev, "%s: Error on calibrate idacs for self r=%d\n",
  1473. __func__, rc);
  1474. }
  1475. }
  1476. /*resume_scanning */
  1477. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  1478. if (rc)
  1479. dev_err(dev, "resume_scanning failed");
  1480. /*start watchdog*/
  1481. rc = cmd->request_start_wd(dev);
  1482. if (rc)
  1483. dev_err(dev, "start watchdog failed");
  1484. if (self_test_id_supported)
  1485. goto self_test_id_failed;
  1486. if (no_builtin_file)
  1487. goto no_builtin;
  1488. if (test_item && CM_ENABLED)
  1489. validate_cm_test_results(dev, configuration, cmcp_info,
  1490. result, &final_pass, test_item);
  1491. if (test_item && CP_ENABLED)
  1492. validate_cp_test_results(dev, configuration, cmcp_info,
  1493. result, &final_pass, test_item);
  1494. no_builtin:
  1495. if ((dad->cmcp_test_items == CMCP_FULL)
  1496. && (dad->cmcp_range_check == 0)) {
  1497. /*full test and full check*/
  1498. result->test_summary =
  1499. result->cm_test_pass
  1500. && result->cp_test_pass
  1501. && result->short_test_pass;
  1502. } else if ((dad->cmcp_test_items == CMCP_FULL)
  1503. && (dad->cmcp_range_check == 1)) {
  1504. /*full test and basic check*/
  1505. result->test_summary =
  1506. result->cm_sensor_gd_col_pass
  1507. && result->cm_sensor_gd_row_pass
  1508. && result->cm_sensor_validation_pass
  1509. && result->cp_rx_validation_pass
  1510. && result->cp_tx_validation_pass
  1511. && result->short_test_pass;
  1512. } else if (dad->cmcp_test_items == CMCP_CM_PANEL) {
  1513. /*cm panel test result only*/
  1514. result->test_summary =
  1515. result->cm_sensor_gd_col_pass
  1516. && result->cm_sensor_gd_row_pass
  1517. && result->cm_sensor_validation_pass
  1518. && result->cm_sensor_row_delta_pass
  1519. && result->cm_sensor_col_delta_pass
  1520. && result->cm_sensor_calibration_pass
  1521. && result->cm_sensor_delta_pass;
  1522. } else if (dad->cmcp_test_items == CMCP_CP_PANEL) {
  1523. /*cp panel test result only*/
  1524. result->test_summary =
  1525. result->cp_sensor_delta_pass
  1526. && result->cp_rx_validation_pass
  1527. && result->cp_tx_validation_pass;
  1528. } else if (dad->cmcp_test_items == CMCP_CM_BTN) {
  1529. /*cm button test result only*/
  1530. result->test_summary =
  1531. result->cm_button_validation_pass
  1532. && result->cm_button_delta_pass;
  1533. } else if (dad->cmcp_test_items == CMCP_CP_BTN) {
  1534. /*cp button test result only*/
  1535. result->test_summary =
  1536. result->cp_button_delta_pass
  1537. && result->cp_button_average_pass
  1538. && result->cp_button_validation_pass;
  1539. }
  1540. mutex_lock(&dad->sysfs_lock);
  1541. dad->test_executed = 1;
  1542. mutex_unlock(&dad->sysfs_lock);
  1543. if (result->test_summary) {
  1544. dev_vdbg(dev, "%s: Finish Cm/Cp test! All Test Passed\n",
  1545. __func__);
  1546. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1547. "Status 1\n");
  1548. } else {
  1549. dev_vdbg(dev, "%s: Finish Cm/Cp test! Range Check Failure\n",
  1550. __func__);
  1551. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1552. "Status 6\n");
  1553. }
  1554. goto cmcp_ready;
  1555. mismatch:
  1556. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1557. "Status 2\nInput cmcp threshold file mismatches with FW\n");
  1558. goto cmcp_ready;
  1559. invalid_item_btn:
  1560. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1561. "Status 3\nFW doesn't support button!\n");
  1562. goto cmcp_ready;
  1563. invalid_item:
  1564. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1565. "Status 4\nWrong test item or range check input!\nOnly support below items:\n0 - Cm/Cp Panel & Button with Gradient (Typical)\n1 - Cm Panel with Gradient\n2 - Cp Panel\n3 - Cm Button\n4 - Cp Button\nOnly support below range check:\n0 - Full Range Checking (default)\n1 - Basic Range Checking(TSG5 style)\n");
  1566. goto cmcp_ready;
  1567. self_test_id_failed:
  1568. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1569. "Status 5\nget self test ID not supported!");
  1570. goto cmcp_ready;
  1571. cmcp_not_ready:
  1572. index = snprintf(buf, CY_MAX_PRBUF_SIZE,
  1573. "Status 0\n");
  1574. goto cmcp_ready;
  1575. cmcp_ready:
  1576. mutex_lock(&dad->sysfs_lock);
  1577. dad->cmcp_test_in_progress = 0;
  1578. mutex_unlock(&dad->sysfs_lock);
  1579. exit:
  1580. return index;
  1581. }
  1582. static ssize_t cyttsp5_cmcp_test_store(struct device *dev,
  1583. struct device_attribute *attr, const char *buf, size_t size)
  1584. {
  1585. struct cyttsp5_device_access_data *dad
  1586. = cyttsp5_get_device_access_data(dev);
  1587. u8 test_item = 0;
  1588. u8 range_check = 0;
  1589. u8 force_calibrate = 0;
  1590. int ret;
  1591. static const char * const cmcp_test_case_array[] = {"Full Cm/Cp test",
  1592. "Cm panel test", "Cp panel test",
  1593. "Cm button test", "Cp button test"};
  1594. static const char * const cmcp_test_range_check_array[] = {
  1595. "Full (default)", "Basic"};
  1596. static const char * const cmcp_test_force_cal_array[] = {
  1597. "Calibrate When Testing (default)", "No Calibration"};
  1598. ssize_t length = 0;
  1599. pm_runtime_get_sync(dev);
  1600. mutex_lock(&dad->sysfs_lock);
  1601. length = cyttsp5_ic_parse_input(dev, buf, size, dad->ic_buf,
  1602. CY_MAX_PRBUF_SIZE);
  1603. if (length <= 0 || length > 3) {
  1604. dev_err(dev, "%s: Input format error!\n", __func__);
  1605. dad->cmcp_test_items = -EINVAL;
  1606. ret = -EINVAL;
  1607. goto error;
  1608. }
  1609. /* Get test item */
  1610. test_item = dad->ic_buf[0];
  1611. /* Get range check */
  1612. if (length >= 2)
  1613. range_check = dad->ic_buf[1];
  1614. /* Get force calibration */
  1615. if (length == 3)
  1616. force_calibrate = dad->ic_buf[2];
  1617. /*
  1618. * Test item limitation:
  1619. * 0: Perform all Tests
  1620. * 1: CM Panel with Gradient
  1621. * 2: CP Panel
  1622. * 3: CM Button
  1623. * 4: CP Button
  1624. * Ranage check limitation:
  1625. * 0: full check
  1626. * 1: basic check
  1627. * Force calibrate limitation:
  1628. * 0: do calibration
  1629. * 1: don't do calibration
  1630. */
  1631. if ((test_item < 0) || (test_item > 4) || (range_check > 1)
  1632. || (force_calibrate > 1)) {
  1633. dev_err(dev,
  1634. "%s: Test item should be 0~4; Range check should be 0~1; Force calibrate should be 0~1\n",
  1635. __func__);
  1636. dad->cmcp_test_items = -EINVAL;
  1637. ret = -EINVAL;
  1638. goto error;
  1639. }
  1640. /*
  1641. * If it is not all Test, then range_check should be 0
  1642. * because other test does not has concept of basic check
  1643. */
  1644. if (test_item > 0 && test_item < 5)
  1645. range_check = 0;
  1646. dad->cmcp_test_items = test_item;
  1647. dad->cmcp_range_check = range_check;
  1648. dad->cmcp_force_calibrate = force_calibrate;
  1649. parade_debug(dev, DEBUG_LEVEL_2,
  1650. "%s: Test item is %s; Range check is %s; Force calibrate is %s.\n",
  1651. __func__,
  1652. cmcp_test_case_array[test_item],
  1653. cmcp_test_range_check_array[range_check],
  1654. cmcp_test_force_cal_array[force_calibrate]);
  1655. error:
  1656. mutex_unlock(&dad->sysfs_lock);
  1657. pm_runtime_put(dev);
  1658. if (ret)
  1659. return ret;
  1660. return size;
  1661. }
  1662. static DEVICE_ATTR(cmcp_test, S_IRUSR | S_IWUSR,
  1663. cyttsp5_cmcp_test_show, cyttsp5_cmcp_test_store);
  1664. int prepare_print_string(char *out_buf, char *in_buf, int index)
  1665. {
  1666. if ((out_buf == NULL) || (in_buf == NULL))
  1667. return index;
  1668. index += scnprintf(&out_buf[index], MAX_BUF_LEN - index,
  1669. "%s", in_buf);
  1670. return index;
  1671. }
  1672. int prepare_print_data(char *out_buf, int32_t *in_buf, int index, int data_num)
  1673. {
  1674. int i;
  1675. if ((out_buf == NULL) || (in_buf == NULL))
  1676. return index;
  1677. for (i = 0; i < data_num; i++)
  1678. index += scnprintf(&out_buf[index], MAX_BUF_LEN - index,
  1679. "%d,", in_buf[i]);
  1680. return index;
  1681. }
  1682. int save_header(char *out_buf, int index, struct result *result)
  1683. {
  1684. struct timex txc;
  1685. struct rtc_time tm;
  1686. char time_buf[100] = {0};
  1687. do_gettimeofday(&(txc.time));
  1688. rtc_time_to_tm(txc.time.tv_sec, &tm);
  1689. scnprintf(time_buf, 100, "%d/%d/%d,TIME,%d:%d:%d,", tm.tm_year+1900,
  1690. tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
  1691. index = prepare_print_string(out_buf, ",.header,\n", index);
  1692. index = prepare_print_string(out_buf, ",DATE,", index);
  1693. index = prepare_print_string(out_buf, &time_buf[0], index);
  1694. index = prepare_print_string(out_buf, ",\n", index);
  1695. index = prepare_print_string(out_buf, ",SW_VERSION,", index);
  1696. index = prepare_print_string(out_buf, CY_DRIVER_VERSION, index);
  1697. index = prepare_print_string(out_buf, ",\n", index);
  1698. index = prepare_print_string(out_buf, ",.end,\n", index);
  1699. index = prepare_print_string(out_buf, ",.engineering data,\n", index);
  1700. return index;
  1701. }
  1702. static int print_silicon_id(char *out_buf, char *in_buf, int index)
  1703. {
  1704. index = prepare_print_string(out_buf, ",1,", index);
  1705. index = prepare_print_string(out_buf, &in_buf[0], index);
  1706. return index;
  1707. }
  1708. int save_engineering_data(struct device *dev, char *out_buf, int index,
  1709. struct cmcp_data *cmcp_info, struct configuration *configuration,
  1710. struct result *result, int test_item, int no_builtin_file)
  1711. {
  1712. int i;
  1713. int j;
  1714. int tx_num = cmcp_info->tx_num;
  1715. int rx_num = cmcp_info->rx_num;
  1716. int btn_num = cmcp_info->btn_num;
  1717. int tmp = 0;
  1718. uint32_t fw_revision_control;
  1719. uint32_t fw_config_ver;
  1720. char device_id[20] = {0};
  1721. struct cyttsp5_device_access_data *dad
  1722. = cyttsp5_get_device_access_data(dev);
  1723. fw_revision_control = dad->si->cydata.revctrl;
  1724. fw_config_ver = dad->si->cydata.fw_ver_conf;
  1725. /*calculate silicon id*/
  1726. result->device_id_low = 0;
  1727. result->device_id_high = 0;
  1728. for (i = 0; i < 4; i++)
  1729. result->device_id_low =
  1730. (result->device_id_low << 8) + dad->si->cydata.mfg_id[i];
  1731. for (i = 4; i < 8; i++)
  1732. result->device_id_high =
  1733. (result->device_id_high << 8) + dad->si->cydata.mfg_id[i];
  1734. scnprintf(device_id, 20, "%x%x",
  1735. result->device_id_high, result->device_id_low);
  1736. /*print test summary*/
  1737. index = print_silicon_id(out_buf, &device_id[0], index);
  1738. if (result->test_summary)
  1739. index = prepare_print_string(out_buf, ",PASS,\n", index);
  1740. else
  1741. index = prepare_print_string(out_buf, ",FAIL,\n", index);
  1742. /*revision ctrl number*/
  1743. index = print_silicon_id(out_buf, &device_id[0], index);
  1744. index = prepare_print_string(out_buf, ",FW revision Control,", index);
  1745. index = prepare_print_data(out_buf, &fw_revision_control, index, 1);
  1746. index = prepare_print_string(out_buf, "\n", index);
  1747. /*config version*/
  1748. index = print_silicon_id(out_buf, &device_id[0], index);
  1749. index = prepare_print_string(out_buf, ",CONFIG_VER,", index);
  1750. index = prepare_print_data(out_buf, &fw_config_ver, index, 1);
  1751. index = prepare_print_string(out_buf, "\n", index);
  1752. /*short test*/
  1753. index = print_silicon_id(out_buf, &device_id[0], index);
  1754. if (result->short_test_pass)
  1755. index = prepare_print_string(out_buf, ",Shorts,PASS,\n", index);
  1756. else
  1757. index = prepare_print_string(out_buf, ",Shorts,FAIL,\n", index);
  1758. if ((test_item & CM_ENABLED) == CM_ENABLED) {
  1759. /*print BUTNS_CM_DATA_ROW00*/
  1760. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  1761. index = print_silicon_id(out_buf, &device_id[0], index);
  1762. index = prepare_print_string(out_buf,
  1763. ",Sensor Cm Validation,BUTNS_CM_DATA_ROW00,",
  1764. index);
  1765. index = prepare_print_data(out_buf,
  1766. &cmcp_info->cm_btn_data[0],
  1767. index,
  1768. btn_num);
  1769. index = prepare_print_string(out_buf, "\n", index);
  1770. }
  1771. if ((test_item & CM_PANEL) == CM_PANEL) {
  1772. /*print CM_DATA_ROW*/
  1773. for (i = 0; i < rx_num; i++) {
  1774. index = print_silicon_id(out_buf, &device_id[0],
  1775. index);
  1776. index = prepare_print_string(out_buf,
  1777. ",Sensor Cm Validation,CM_DATA_ROW",
  1778. index);
  1779. index = prepare_print_data(out_buf, &i,
  1780. index, 1);
  1781. for (j = 0; j < tx_num; j++)
  1782. index = prepare_print_data(out_buf,
  1783. &cmcp_info->cm_data_panel[j*rx_num+i],
  1784. index, 1);
  1785. index = prepare_print_string(out_buf,
  1786. "\n", index);
  1787. }
  1788. if (!no_builtin_file) {
  1789. /*print CM_MAX_GRADIENT_COLS_PERCENT*/
  1790. index = print_silicon_id(out_buf,
  1791. &device_id[0], index);
  1792. index = prepare_print_string(out_buf,
  1793. ",Sensor Cm Validation,CM_MAX_GRADIENT_COLS_PERCENT,",
  1794. index);
  1795. for (i = 0; i < tx_num; i++) {
  1796. char tmp_buf[10] = {0};
  1797. scnprintf(tmp_buf, 10, "%d.%d,",
  1798. cmcp_info->gd_sensor_col[i].gradient_val / 10,
  1799. cmcp_info->gd_sensor_col[i].gradient_val % 10);
  1800. index = prepare_print_string(out_buf,
  1801. &tmp_buf[0], index);
  1802. }
  1803. index = prepare_print_string(out_buf,
  1804. "\n", index);
  1805. /*print CM_MAX_GRADIENT_ROWS_PERCENT*/
  1806. index = print_silicon_id(out_buf,
  1807. &device_id[0], index);
  1808. index = prepare_print_string(out_buf,
  1809. ",Sensor Cm Validation,CM_MAX_GRADIENT_ROWS_PERCENT,",
  1810. index);
  1811. for (i = 0; i < rx_num; i++) {
  1812. char tmp_buf[10] = {0};
  1813. scnprintf(tmp_buf, 10, "%d.%d,",
  1814. cmcp_info->gd_sensor_row[i].gradient_val / 10,
  1815. cmcp_info->gd_sensor_row[i].gradient_val % 10);
  1816. index = prepare_print_string(out_buf,
  1817. &tmp_buf[0], index);
  1818. }
  1819. index = prepare_print_string(out_buf,
  1820. "\n", index);
  1821. if (!dad->cmcp_range_check) {
  1822. /*print CM_DELTA_COLUMN*/
  1823. for (i = 0; i < rx_num; i++) {
  1824. index = print_silicon_id(
  1825. out_buf,
  1826. &device_id[0], index);
  1827. index = prepare_print_string(
  1828. out_buf,
  1829. ",Sensor Cm Validation,DELTA_COLUMNS_ROW",
  1830. index);
  1831. index = prepare_print_data(
  1832. out_buf,
  1833. &i, index, 1);
  1834. index = prepare_print_data(
  1835. out_buf,
  1836. &tmp, index, 1);
  1837. for (j = 1; j < tx_num; j++)
  1838. index = prepare_print_data(
  1839. out_buf,
  1840. &cmcp_info->cm_sensor_column_delta[(j-1)*rx_num+i],
  1841. index, 1);
  1842. index = prepare_print_string(
  1843. out_buf,
  1844. "\n", index);
  1845. }
  1846. /*print CM_DELTA_ROW*/
  1847. index = print_silicon_id(out_buf,
  1848. &device_id[0],
  1849. index);
  1850. index = prepare_print_string(out_buf,
  1851. ",Sensor Cm Validation,DELTA_ROWS_ROW",
  1852. index);
  1853. index = prepare_print_data(out_buf,
  1854. &tmp, index, 1);
  1855. for (j = 0; j < tx_num; j++)
  1856. index = prepare_print_data(
  1857. out_buf,
  1858. &tmp, index, 1);
  1859. index = prepare_print_string(out_buf,
  1860. "\n", index);
  1861. for (i = 1; i < rx_num; i++) {
  1862. index = print_silicon_id(
  1863. out_buf,
  1864. &device_id[0],
  1865. index);
  1866. index = prepare_print_string(
  1867. out_buf,
  1868. ",Sensor Cm Validation,DELTA_ROWS_ROW",
  1869. index);
  1870. index = prepare_print_data(
  1871. out_buf, &i,
  1872. index, 1);
  1873. for (j = 0; j < tx_num; j++)
  1874. index = prepare_print_data(
  1875. out_buf,
  1876. &cmcp_info->cm_sensor_row_delta[j*rx_num+i-1],
  1877. index, 1);
  1878. index = prepare_print_string(
  1879. out_buf,
  1880. "\n", index);
  1881. }
  1882. /*print pass/fail Sensor Cm Validation*/
  1883. index = print_silicon_id(out_buf, &device_id[0],
  1884. index);
  1885. if (result->cm_test_pass)
  1886. index = prepare_print_string(out_buf,
  1887. ",Sensor Cm Validation,PASS,\n",
  1888. index);
  1889. else
  1890. index = prepare_print_string(out_buf,
  1891. ",Sensor Cm Validation,FAIL,\n",
  1892. index);
  1893. }
  1894. }
  1895. }
  1896. if (!no_builtin_file) {
  1897. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)
  1898. && (!dad->cmcp_range_check)) {
  1899. char tmp_buf[10] = {0};
  1900. /*print Button Element by Element */
  1901. index = print_silicon_id(out_buf, &device_id[0],
  1902. index);
  1903. if (result->cm_button_validation_pass)
  1904. index = prepare_print_string(out_buf,
  1905. ",Sensor Cm Validation - Button Element by Element,PASS\n",
  1906. index);
  1907. else
  1908. index = prepare_print_string(out_buf,
  1909. ",Sensor Cm Validation - Button Element by Element,FAIL\n",
  1910. index);
  1911. /*
  1912. *print Sensor Cm Validation
  1913. *- Buttons Range Buttons Range
  1914. */
  1915. index = print_silicon_id(out_buf,
  1916. &device_id[0], index);
  1917. index = prepare_print_string(out_buf,
  1918. ",Sensor Cm Validation - Buttons Range,Buttons Range,",
  1919. index);
  1920. scnprintf(tmp_buf, 10, "%d.%d,",
  1921. cmcp_info->cm_delta_data_btn / 10,
  1922. cmcp_info->cm_delta_data_btn % 10);
  1923. index = prepare_print_string(out_buf,
  1924. &tmp_buf[0], index);
  1925. index = prepare_print_string(out_buf,
  1926. "\n", index);
  1927. /*print Sensor Cm Validation
  1928. *-Buttons Range Cm_button_avg
  1929. */
  1930. index = print_silicon_id(out_buf,
  1931. &device_id[0], index);
  1932. index = prepare_print_string(out_buf,
  1933. ",Sensor Cm Validation - Buttons Range,Cm_button_avg,",
  1934. index);
  1935. index = prepare_print_data(out_buf,
  1936. &cmcp_info->cm_ave_data_btn,
  1937. index, 1);
  1938. index = prepare_print_string(out_buf,
  1939. "\n", index);
  1940. /*print Sensor Cm Validation
  1941. * -Buttons Range Cm_button_avg
  1942. */
  1943. index = print_silicon_id(out_buf,
  1944. &device_id[0], index);
  1945. index = prepare_print_string(out_buf,
  1946. ",Sensor Cm Validation - Buttons Range,Cm_button_cal,",
  1947. index);
  1948. index = prepare_print_data(out_buf,
  1949. &cmcp_info->cm_cal_data_btn,
  1950. index, 1);
  1951. index = prepare_print_string(out_buf,
  1952. "\n", index);
  1953. /*print Sensor Cm Validation
  1954. *-Buttons Range pass/fail
  1955. */
  1956. index = print_silicon_id(out_buf,
  1957. &device_id[0], index);
  1958. if (result->cm_button_delta_pass)
  1959. index = prepare_print_string(out_buf,
  1960. ",Sensor Cm Validation - Buttons Range,PASS,LIMITS,",
  1961. index);
  1962. else
  1963. index = prepare_print_string(out_buf,
  1964. ",Sensor Cm Validation - Buttons Range,FAIL,LIMITS,",
  1965. index);
  1966. index = prepare_print_data(out_buf,
  1967. &configuration->cm_max_delta_button_percent,
  1968. index, 1);
  1969. index = prepare_print_string(out_buf,
  1970. "\n", index);
  1971. }
  1972. if ((test_item & CM_PANEL) == CM_PANEL &&
  1973. !dad->cmcp_range_check) {
  1974. char tmp_buf[10] = {0};
  1975. /*print Cm_sensor_cal */
  1976. index = print_silicon_id(out_buf,
  1977. &device_id[0], index);
  1978. index = prepare_print_string(out_buf,
  1979. ",Sensor Cm Validation - Calibration,Cm_sensor_cal,",
  1980. index);
  1981. index = prepare_print_data(out_buf,
  1982. &cmcp_info->cm_cal_data_panel,
  1983. index, 1);
  1984. index = prepare_print_string(out_buf,
  1985. "\n", index);
  1986. /*print Cm_sensor_cal limit*/
  1987. index = print_silicon_id(out_buf,
  1988. &device_id[0], index);
  1989. if (result->cm_sensor_calibration_pass)
  1990. index = prepare_print_string(out_buf,
  1991. ",Sensor Cm Validation - Calibration,PASS,LIMITS,",
  1992. index);
  1993. else
  1994. index = prepare_print_string(out_buf,
  1995. ",Sensor Cm Validation - Calibration,FAIL,LIMITS,",
  1996. index);
  1997. index = prepare_print_data(out_buf,
  1998. &configuration->cm_min_limit_cal,
  1999. index, 1);
  2000. index = prepare_print_data(out_buf,
  2001. &configuration->cm_max_limit_cal,
  2002. index, 1);
  2003. index = prepare_print_string(out_buf,
  2004. "\n", index);
  2005. /*print Columns Delta Matrix*/
  2006. index = print_silicon_id(out_buf,
  2007. &device_id[0], index);
  2008. if (result->cm_sensor_col_delta_pass)
  2009. index = prepare_print_string(out_buf,
  2010. ",Sensor Cm Validation - Columns Delta Matrix,PASS,LIMITS,",
  2011. index);
  2012. else
  2013. index = prepare_print_string(out_buf,
  2014. ",Sensor Cm Validation - Columns Delta Matrix,FAIL,LIMITS,",
  2015. index);
  2016. index = prepare_print_data(out_buf,
  2017. &configuration->cm_range_limit_col,
  2018. index, 1);
  2019. index = prepare_print_string(out_buf,
  2020. "\n", index);
  2021. /*print Cm Validation - Element by Element*/
  2022. index = print_silicon_id(out_buf,
  2023. &device_id[0], index);
  2024. if (result->cm_sensor_validation_pass)
  2025. index = prepare_print_string(out_buf,
  2026. ",Sensor Cm Validation - Element by Element,PASS,",
  2027. index);
  2028. else
  2029. index = prepare_print_string(out_buf,
  2030. ",Sensor Cm Validation - Element by Element,FAIL,",
  2031. index);
  2032. index = prepare_print_string(out_buf,
  2033. "\n", index);
  2034. /*print Cm Validation -Gradient Cols*/
  2035. index = print_silicon_id(out_buf,
  2036. &device_id[0], index);
  2037. if (result->cm_sensor_gd_col_pass)
  2038. index = prepare_print_string(out_buf,
  2039. ",Sensor Cm Validation - Gradient Cols,PASS,",
  2040. index);
  2041. else
  2042. index = prepare_print_string(out_buf,
  2043. ",Sensor Cm Validation - Gradient Cols,FAIL,",
  2044. index);
  2045. index = prepare_print_string(out_buf,
  2046. "\n", index);
  2047. /*print Cm Validation -Gradient Rows*/
  2048. index = print_silicon_id(out_buf,
  2049. &device_id[0], index);
  2050. if (result->cm_sensor_gd_row_pass)
  2051. index = prepare_print_string(out_buf,
  2052. ",Sensor Cm Validation - Gradient Rows,PASS,",
  2053. index);
  2054. else
  2055. index = prepare_print_string(out_buf,
  2056. ",Sensor Cm Validation - Gradient Rows,FAIL,",
  2057. index);
  2058. index = prepare_print_string(out_buf,
  2059. "\n", index);
  2060. /*
  2061. * Print Sensor Cm Validation
  2062. * -Rows Delta Matrix
  2063. */
  2064. index = print_silicon_id(out_buf,
  2065. &device_id[0], index);
  2066. if (result->cm_sensor_row_delta_pass)
  2067. index = prepare_print_string(out_buf,
  2068. ",Sensor Cm Validation - Rows Delta Matrix,PASS,LIMITS,",
  2069. index);
  2070. else
  2071. index = prepare_print_string(out_buf,
  2072. ",Sensor Cm Validation - Rows Delta Matrix,FAIL,LIMITS,",
  2073. index);
  2074. index = prepare_print_data(out_buf,
  2075. &configuration->cm_range_limit_row,
  2076. index, 1);
  2077. index = prepare_print_string(out_buf,
  2078. "\n", index);
  2079. /*print Cm_sensor_avg */
  2080. index = print_silicon_id(out_buf,
  2081. &device_id[0], index);
  2082. index = prepare_print_string(out_buf,
  2083. ",Sensor Cm Validation - Sensor Range,Cm_sensor_avg,",
  2084. index);
  2085. index = prepare_print_data(out_buf,
  2086. &cmcp_info->cm_ave_data_panel,
  2087. index, 1);
  2088. index = prepare_print_string(out_buf,
  2089. "\n", index);
  2090. /*printSensor Cm Validation -
  2091. * Sensor Range, Sensor Range
  2092. */
  2093. index = print_silicon_id(out_buf,
  2094. &device_id[0], index);
  2095. index = prepare_print_string(out_buf,
  2096. ",Sensor Cm Validation - Sensor Range,Sensor Range,",
  2097. index);
  2098. scnprintf(tmp_buf, 10, "%d.%d,",
  2099. cmcp_info->cm_sensor_delta / 10,
  2100. cmcp_info->cm_sensor_delta % 10);
  2101. index = prepare_print_string(out_buf,
  2102. &tmp_buf[0], index);
  2103. index = prepare_print_string(out_buf,
  2104. "\n", index);
  2105. /*print Sensor Cm Validation - Sensor Range*/
  2106. index = print_silicon_id(out_buf,
  2107. &device_id[0], index);
  2108. if (result->cm_sensor_delta_pass)
  2109. index = prepare_print_string(out_buf,
  2110. ",Sensor Cm Validation - Sensor Range,PASS,LIMITS,",
  2111. index);
  2112. else
  2113. index = prepare_print_string(out_buf,
  2114. ",Sensor Cm Validation - Sensor Range,FAIL,LIMITS,",
  2115. index);
  2116. index = prepare_print_data(out_buf,
  2117. &configuration->cm_max_delta_sensor_percent,
  2118. index, 1);
  2119. index = prepare_print_string(out_buf,
  2120. "\n", index);
  2121. }
  2122. }
  2123. }
  2124. if ((test_item & CP_ENABLED) == CP_ENABLED) {
  2125. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2126. /*print BUTNS_CP_DATA_ROW00 */
  2127. index = print_silicon_id(out_buf, &device_id[0], index);
  2128. index = prepare_print_string(out_buf,
  2129. ",Self-cap Calibration Check,BUTNS_CP_DATA_ROW00,",
  2130. index);
  2131. index = prepare_print_data(out_buf,
  2132. &cmcp_info->cp_btn_data[0],
  2133. index, btn_num);
  2134. index = prepare_print_string(out_buf,
  2135. "\n", index);
  2136. if (!no_builtin_file && !dad->cmcp_range_check) {
  2137. /*print Cp Button Element by Element */
  2138. index = print_silicon_id(out_buf, &device_id[0],
  2139. index);
  2140. if (result->cp_button_validation_pass)
  2141. index = prepare_print_string(out_buf,
  2142. ",Self-cap Calibration Check - Button Element by Element,PASS\n",
  2143. index);
  2144. else
  2145. index = prepare_print_string(out_buf,
  2146. ",Self-cap Calibration Check - Button Element by Element,FAIL\n",
  2147. index);
  2148. /*print cp_button_ave */
  2149. index = print_silicon_id(out_buf,
  2150. &device_id[0], index);
  2151. index = prepare_print_string(out_buf,
  2152. ",Self-cap Calibration Check,Cp_button_avg,",
  2153. index);
  2154. index = prepare_print_data(out_buf,
  2155. &cmcp_info->cp_button_ave,
  2156. index, 1);
  2157. index = prepare_print_string(out_buf,
  2158. "\n", index);
  2159. /*print Cp_button_cal */
  2160. index = print_silicon_id(out_buf,
  2161. &device_id[0], index);
  2162. index = prepare_print_string(out_buf,
  2163. ",Self-cap Calibration Check,Cp_button_cal,",
  2164. index);
  2165. index = prepare_print_data(out_buf,
  2166. &cmcp_info->cp_btn_cal,
  2167. index, 1);
  2168. index = prepare_print_string(out_buf,
  2169. "\n", index);
  2170. }
  2171. }
  2172. if ((test_item & CP_PANEL) == CP_PANEL) {
  2173. /*print CP_DATA_RX */
  2174. index = print_silicon_id(out_buf, &device_id[0], index);
  2175. index = prepare_print_string(out_buf,
  2176. ",Self-cap Calibration Check,CP_DATA_RX,", index);
  2177. index = prepare_print_data(out_buf,
  2178. &cmcp_info->cp_rx_data_panel[0], index, rx_num);
  2179. index = prepare_print_string(out_buf, "\n", index);
  2180. /*print CP_DATA_TX */
  2181. index = print_silicon_id(out_buf, &device_id[0], index);
  2182. index = prepare_print_string(out_buf,
  2183. ",Self-cap Calibration Check,CP_DATA_TX,", index);
  2184. index = prepare_print_data(out_buf,
  2185. &cmcp_info->cp_tx_data_panel[0], index, tx_num);
  2186. index = prepare_print_string(out_buf, "\n", index);
  2187. }
  2188. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)
  2189. && !dad->cmcp_range_check) {
  2190. if (!no_builtin_file) {
  2191. char tmp_buf[10] = {0};
  2192. /*print Cp_delta_button */
  2193. index = print_silicon_id(out_buf, &device_id[0],
  2194. index);
  2195. index = prepare_print_string(out_buf,
  2196. ",Self-cap Calibration Check,Cp_delta_button,",
  2197. index);
  2198. scnprintf(tmp_buf, 10, "%d.%d,",
  2199. cmcp_info->cp_button_delta / 10,
  2200. cmcp_info->cp_button_delta % 10);
  2201. index = prepare_print_string(out_buf,
  2202. &tmp_buf[0], index);
  2203. index = prepare_print_string(out_buf, "\n",
  2204. index);
  2205. }
  2206. }
  2207. if ((test_item & CP_PANEL) == CP_PANEL &&
  2208. !dad->cmcp_range_check) {
  2209. if (!no_builtin_file) {
  2210. char tmp_buf[10] = {0};
  2211. /*print Cp_delta_rx */
  2212. index = print_silicon_id(out_buf, &device_id[0],
  2213. index);
  2214. index = prepare_print_string(out_buf,
  2215. ",Self-cap Calibration Check,Cp_delta_rx,",
  2216. index);
  2217. scnprintf(tmp_buf, 10, "%d.%d,",
  2218. cmcp_info->cp_sensor_rx_delta / 10,
  2219. cmcp_info->cp_sensor_rx_delta % 10);
  2220. index = prepare_print_string(out_buf,
  2221. &tmp_buf[0], index);
  2222. index = prepare_print_string(out_buf, "\n",
  2223. index);
  2224. /*print Cp_delta_tx */
  2225. index = print_silicon_id(out_buf, &device_id[0],
  2226. index);
  2227. index = prepare_print_string(out_buf,
  2228. ",Self-cap Calibration Check,Cp_delta_tx,",
  2229. index);
  2230. scnprintf(tmp_buf, 10, "%d.%d,",
  2231. cmcp_info->cp_sensor_tx_delta / 10,
  2232. cmcp_info->cp_sensor_tx_delta % 10);
  2233. index = prepare_print_string(out_buf,
  2234. &tmp_buf[0], index);
  2235. index = prepare_print_string(out_buf, "\n",
  2236. index);
  2237. /*print Cp_sensor_avg_rx */
  2238. index = print_silicon_id(out_buf, &device_id[0],
  2239. index);
  2240. index = prepare_print_string(out_buf,
  2241. ",Self-cap Calibration Check,Cp_sensor_avg_rx,",
  2242. index);
  2243. index = prepare_print_data(out_buf,
  2244. &cmcp_info->cp_rx_ave_data_panel,
  2245. index, 1);
  2246. index = prepare_print_string(out_buf,
  2247. "\n", index);
  2248. /*print Cp_sensor_avg_tx */
  2249. index = print_silicon_id(out_buf,
  2250. &device_id[0], index);
  2251. index = prepare_print_string(out_buf,
  2252. ",Self-cap Calibration Check,Cp_sensor_avg_tx,",
  2253. index);
  2254. index = prepare_print_data(out_buf,
  2255. &cmcp_info->cp_tx_ave_data_panel,
  2256. index, 1);
  2257. index = prepare_print_string(out_buf,
  2258. "\n", index);
  2259. /*print Cp_sensor_cal_rx */
  2260. index = print_silicon_id(out_buf,
  2261. &device_id[0], index);
  2262. index = prepare_print_string(out_buf,
  2263. ",Self-cap Calibration Check,Cp_sensor_cal_rx,",
  2264. index);
  2265. index = prepare_print_data(out_buf,
  2266. &cmcp_info->cp_rx_cal_data_panel[0],
  2267. index, rx_num);
  2268. index = prepare_print_string(out_buf,
  2269. "\n", index);
  2270. /*print Cp_sensor_cal_tx */
  2271. index = print_silicon_id(out_buf,
  2272. &device_id[0], index);
  2273. index = prepare_print_string(out_buf,
  2274. ",Self-cap Calibration Check,Cp_sensor_cal_tx,",
  2275. index);
  2276. index = prepare_print_data(out_buf,
  2277. &cmcp_info->cp_tx_cal_data_panel[0],
  2278. index, tx_num);
  2279. index = prepare_print_string(out_buf,
  2280. "\n", index);
  2281. }
  2282. }
  2283. if (!no_builtin_file && !dad->cmcp_range_check) {
  2284. /*print cp test limits */
  2285. index = print_silicon_id(out_buf, &device_id[0], index);
  2286. if (result->cp_test_pass)
  2287. index = prepare_print_string(out_buf,
  2288. ",Self-cap Calibration Check,PASS, LIMITS,",
  2289. index);
  2290. else
  2291. index = prepare_print_string(out_buf,
  2292. ",Self-cap Calibration Check,FAIL, LIMITS,",
  2293. index);
  2294. index = prepare_print_string(out_buf,
  2295. "CP_MAX_DELTA_SENSOR_RX_PERCENT,", index);
  2296. index = prepare_print_data(out_buf,
  2297. &configuration->cp_max_delta_sensor_rx_percent,
  2298. index, 1);
  2299. index = prepare_print_string(out_buf,
  2300. "CP_MAX_DELTA_SENSOR_TX_PERCENT,", index);
  2301. index = prepare_print_data(out_buf,
  2302. &configuration->cp_max_delta_sensor_tx_percent,
  2303. index, 1);
  2304. index = prepare_print_string(out_buf,
  2305. "CP_MAX_DELTA_BUTTON_PERCENT,", index);
  2306. index = prepare_print_data(out_buf,
  2307. &configuration->cp_max_delta_button_percent,
  2308. index, 1);
  2309. index = prepare_print_string(out_buf, "\n", index);
  2310. }
  2311. }
  2312. if (!no_builtin_file) {
  2313. if ((test_item & CM_ENABLED) == CM_ENABLED) {
  2314. if ((test_item & CM_PANEL) == CM_PANEL) {
  2315. /*print columns gradient limit*/
  2316. index = prepare_print_string(out_buf,
  2317. ",Sensor Cm Validation,MAX_LIMITS,CM_MAX_GRADIENT_COLS_PERCENT,",
  2318. index);
  2319. index = prepare_print_data(out_buf,
  2320. &configuration->cm_max_table_gradient_cols_percent[0],
  2321. index,
  2322. configuration->cm_max_table_gradient_cols_percent_size);
  2323. index = prepare_print_string(out_buf,
  2324. "\n", index);
  2325. /*print rows gradient limit*/
  2326. index = prepare_print_string(out_buf,
  2327. ",Sensor Cm Validation,MAX_LIMITS,CM_MAX_GRADIENT_ROWS_PERCENT,",
  2328. index);
  2329. index = prepare_print_data(out_buf,
  2330. &configuration->cm_max_table_gradient_rows_percent[0],
  2331. index,
  2332. configuration->cm_max_table_gradient_rows_percent_size);
  2333. index = prepare_print_string(out_buf,
  2334. "\n", index);
  2335. /*print cm max limit*/
  2336. for (i = 0; i < rx_num; i++) {
  2337. index = prepare_print_string(out_buf,
  2338. ",Sensor Cm Validation,MAX_LIMITS,CM_DATA_ROW",
  2339. index);
  2340. index = prepare_print_data(out_buf,
  2341. &i, index, 1);
  2342. for (j = 0; j < tx_num; j++)
  2343. index = prepare_print_data(
  2344. out_buf,
  2345. &configuration->cm_min_max_table_sensor[i*tx_num*2+j*2+1],
  2346. index, 1);
  2347. index = prepare_print_string(out_buf,
  2348. "\n", index);
  2349. }
  2350. }
  2351. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  2352. index = prepare_print_string(out_buf,
  2353. ",Sensor Cm Validation,MAX LIMITS,M_BUTNS,",
  2354. index);
  2355. for (j = 0; j < btn_num; j++) {
  2356. index = prepare_print_data(out_buf,
  2357. &configuration->cm_min_max_table_button[2*j+1],
  2358. index, 1);
  2359. }
  2360. index = prepare_print_string(out_buf,
  2361. "\n", index);
  2362. }
  2363. index = prepare_print_string(out_buf,
  2364. ",Sensor Cm Validation MAX LIMITS\n", index);
  2365. if ((test_item & CM_PANEL) == CM_PANEL) {
  2366. /*print cm min limit*/
  2367. for (i = 0; i < rx_num; i++) {
  2368. index = prepare_print_string(out_buf,
  2369. ",Sensor Cm Validation,MIN_LIMITS,CM_DATA_ROW",
  2370. index);
  2371. index = prepare_print_data(out_buf, &i,
  2372. index, 1);
  2373. for (j = 0; j < tx_num; j++)
  2374. index = prepare_print_data(
  2375. out_buf,
  2376. &configuration->cm_min_max_table_sensor[i*tx_num*2 + j*2],
  2377. index, 1);
  2378. index = prepare_print_string(out_buf,
  2379. "\n", index);
  2380. }
  2381. }
  2382. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  2383. index = prepare_print_string(out_buf,
  2384. ",Sensor Cm Validation,MIN LIMITS,M_BUTNS,",
  2385. index);
  2386. for (j = 0; j < btn_num; j++) {
  2387. index = prepare_print_data(out_buf,
  2388. &configuration->cm_min_max_table_button[2*j],
  2389. index, 1);
  2390. }
  2391. index = prepare_print_string(out_buf,
  2392. "\n", index);
  2393. }
  2394. index = prepare_print_string(out_buf,
  2395. ",Sensor Cm Validation MIN LIMITS\n", index);
  2396. }
  2397. if ((test_item & CP_ENABLED) == CP_ENABLED) {
  2398. if ((test_item & CP_PANEL) == CP_PANEL) {
  2399. /*print cp tx max limit*/
  2400. index = prepare_print_string(out_buf,
  2401. ",Self-cap Calibration Check,MAX_LIMITS,TX,",
  2402. index);
  2403. for (i = 0; i < tx_num; i++)
  2404. index = prepare_print_data(out_buf,
  2405. &configuration->cp_min_max_table_tx[i*2+1],
  2406. index, 1);
  2407. index = prepare_print_string(out_buf,
  2408. "\n", index);
  2409. /*print cp rx max limit*/
  2410. index = prepare_print_string(out_buf,
  2411. ",Self-cap Calibration Check,MAX_LIMITS,RX,",
  2412. index);
  2413. for (i = 0; i < rx_num; i++)
  2414. index = prepare_print_data(out_buf,
  2415. &configuration->cp_min_max_table_rx[i*2+1],
  2416. index, 1);
  2417. index = prepare_print_string(out_buf,
  2418. "\n", index);
  2419. }
  2420. /*print cp btn max limit*/
  2421. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2422. index = prepare_print_string(out_buf,
  2423. ",Self-cap Calibration Check,MAX_LIMITS,S_BUTNS,",
  2424. index);
  2425. for (i = 0; i < btn_num; i++)
  2426. index = prepare_print_data(out_buf,
  2427. &configuration->cp_min_max_table_button[i*2+1],
  2428. index, 1);
  2429. index = prepare_print_string(out_buf,
  2430. "\n", index);
  2431. }
  2432. if ((test_item & CP_PANEL) == CP_PANEL) {
  2433. /*print cp tx min limit*/
  2434. index = prepare_print_string(out_buf,
  2435. ",Self-cap Calibration Check,MIN_LIMITS,TX,",
  2436. index);
  2437. for (i = 0; i < tx_num; i++)
  2438. index = prepare_print_data(out_buf,
  2439. &configuration->cp_min_max_table_tx[i*2],
  2440. index, 1);
  2441. index = prepare_print_string(out_buf,
  2442. "\n", index);
  2443. /*print cp rx min limit*/
  2444. index = prepare_print_string(out_buf,
  2445. ",Self-cap Calibration Check,MIN_LIMITS,RX,",
  2446. index);
  2447. for (i = 0; i < rx_num; i++)
  2448. index = prepare_print_data(out_buf,
  2449. &configuration->cp_min_max_table_rx[i*2],
  2450. index, 1);
  2451. index = prepare_print_string(out_buf,
  2452. "\n", index);
  2453. }
  2454. /*print cp btn min limit*/
  2455. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2456. index = prepare_print_string(out_buf,
  2457. ",Self-cap Calibration Check,MIN_LIMITS,S_BUTNS,",
  2458. index);
  2459. for (i = 0; i < btn_num; i++)
  2460. index = prepare_print_data(out_buf,
  2461. &configuration->cp_min_max_table_button[i*2],
  2462. index, 1);
  2463. index = prepare_print_string(out_buf,
  2464. "\n", index);
  2465. }
  2466. }
  2467. }
  2468. return index;
  2469. }
  2470. int result_save(struct device *dev, char *buf,
  2471. struct configuration *configuration, struct result *result,
  2472. struct cmcp_data *cmcp_info, loff_t *ppos, size_t count, int test_item,
  2473. int no_builtin_file)
  2474. {
  2475. u8 *out_buf = NULL;
  2476. int index = 0;
  2477. int byte_left;
  2478. out_buf = kzalloc(MAX_BUF_LEN, GFP_KERNEL);
  2479. if (configuration == NULL)
  2480. dev_err(dev, "config is NULL");
  2481. if (result == NULL)
  2482. dev_err(dev, "result is NULL");
  2483. if (cmcp_info == NULL)
  2484. dev_err(dev, "cmcp_info is NULL");
  2485. index = save_header(out_buf, index, result);
  2486. index = save_engineering_data(dev, out_buf, index,
  2487. cmcp_info, configuration, result,
  2488. test_item, no_builtin_file);
  2489. byte_left = simple_read_from_buffer(buf, count, ppos, out_buf, index);
  2490. kfree(out_buf);
  2491. return byte_left;
  2492. }
  2493. static int cmcp_results_debugfs_open(struct inode *inode,
  2494. struct file *filp)
  2495. {
  2496. filp->private_data = inode->i_private;
  2497. return 0;
  2498. }
  2499. static int cmcp_results_debugfs_close(struct inode *inode,
  2500. struct file *filp)
  2501. {
  2502. filp->private_data = NULL;
  2503. return 0;
  2504. }
  2505. static ssize_t cmcp_results_debugfs_read(struct file *filp,
  2506. char __user *buf, size_t count, loff_t *ppos)
  2507. {
  2508. struct cyttsp5_device_access_data *dad = filp->private_data;
  2509. struct device *dev;
  2510. struct cmcp_data *cmcp_info = dad->cmcp_info;
  2511. struct result *result = dad->result;
  2512. struct configuration *configuration = dad->configs;
  2513. int ret = 0;
  2514. int test_item;
  2515. int no_builtin_file = 0;
  2516. int test_executed = 0;
  2517. dev = dad->dev;
  2518. mutex_lock(&dad->sysfs_lock);
  2519. test_executed = dad->test_executed;
  2520. test_item = cyttsp5_cmcp_get_test_item(dad->cmcp_test_items);
  2521. if (dad->builtin_cmcp_threshold_status < 0) {
  2522. dev_err(dev, "%s: No cmcp threshold file.\n", __func__);
  2523. no_builtin_file = 1;
  2524. }
  2525. mutex_unlock(&dad->sysfs_lock);
  2526. if (test_executed)
  2527. /*save result to buf*/
  2528. ret = result_save(dev, buf, configuration, result, cmcp_info,
  2529. ppos, count, test_item, no_builtin_file);
  2530. else {
  2531. char warning_info[] =
  2532. "No test result available!\n";
  2533. dev_err(dev, "%s: No test result available!\n", __func__);
  2534. return simple_read_from_buffer(buf, count, ppos, warning_info,
  2535. strlen(warning_info));
  2536. }
  2537. return ret;
  2538. }
  2539. static const struct file_operations cmcp_results_debugfs_fops = {
  2540. .open = cmcp_results_debugfs_open,
  2541. .release = cmcp_results_debugfs_close,
  2542. .read = cmcp_results_debugfs_read,
  2543. .write = NULL,
  2544. };
  2545. static ssize_t cyttsp5_cmcp_threshold_loading_show(struct device *dev,
  2546. struct device_attribute *attr, char *buf)
  2547. {
  2548. struct cyttsp5_device_access_data *dad
  2549. = cyttsp5_get_device_access_data(dev);
  2550. bool cmcp_threshold_loading;
  2551. mutex_lock(&dad->cmcp_threshold_lock);
  2552. cmcp_threshold_loading = dad->cmcp_threshold_loading;
  2553. mutex_unlock(&dad->cmcp_threshold_lock);
  2554. return sprintf(buf, "%d\n", cmcp_threshold_loading);
  2555. }
  2556. /* Return the buffer offset of new test case */
  2557. u32 cmcp_return_offset_of_new_case(const char *bufPtr, u32 first_time)
  2558. {
  2559. static u32 offset, first_search;
  2560. if (first_time == 0) {
  2561. first_search = 0;
  2562. offset = 0;
  2563. }
  2564. if (first_search != 0) {
  2565. /* Search one case */
  2566. for (;;) {
  2567. /* Search ASCII_LF */
  2568. while (*bufPtr++ != ASCII_LF)
  2569. offset++;
  2570. offset++;
  2571. /*
  2572. * Single line: end loop
  2573. * Multiple lines: continue loop
  2574. */
  2575. if (*bufPtr != ASCII_COMMA)
  2576. break;
  2577. }
  2578. } else
  2579. first_search = 1;
  2580. return offset;
  2581. }
  2582. /* Get test case information from cmcp threshold file */
  2583. u32 cmcp_get_case_info_from_threshold_file(struct device *dev, const char *buf,
  2584. struct test_case_search *search_array, u32 file_size)
  2585. {
  2586. u32 case_num = 0, buffer_offset = 0, name_count = 0, first_search = 0;
  2587. parade_debug(dev, DEBUG_LEVEL_2, "%s: Search cmcp threshold file\n",
  2588. __func__);
  2589. /* Get all the test cases */
  2590. for (case_num = 0; case_num < MAX_CASE_NUM; case_num++) {
  2591. buffer_offset =
  2592. cmcp_return_offset_of_new_case(&buf[buffer_offset],
  2593. first_search);
  2594. first_search = 1;
  2595. if (buf[buffer_offset] == 0)
  2596. break;
  2597. for (name_count = 0; name_count < NAME_SIZE_MAX; name_count++) {
  2598. /* File end */
  2599. if (buf[buffer_offset + name_count] == ASCII_COMMA)
  2600. break;
  2601. search_array[case_num].name[name_count] =
  2602. buf[buffer_offset + name_count];
  2603. }
  2604. /* Exit when buffer offset is larger than file size */
  2605. if (buffer_offset >= file_size)
  2606. break;
  2607. search_array[case_num].name_size = name_count;
  2608. search_array[case_num].offset = buffer_offset;
  2609. /*
  2610. * parade_debug(dev, DEBUG_LEVEL_2, "Find case %d: Name is %s;
  2611. * Name size is %d; Case offset is %d\n",
  2612. * case_num,
  2613. * search_array[case_num].name,
  2614. * search_array[case_num].name_size,
  2615. * search_array[case_num].offset);
  2616. */
  2617. }
  2618. return case_num;
  2619. }
  2620. /* Compose one value based on data of each bit */
  2621. int cmcp_compose_data(char *buf, u32 count)
  2622. {
  2623. u32 base_array[] = {1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9};
  2624. int value = 0;
  2625. u32 index = 0;
  2626. for (index = 0; index < count; index++)
  2627. value += buf[index] * base_array[count - 1 - index];
  2628. return value;
  2629. }
  2630. /* Return one value */
  2631. int cmcp_return_one_value(struct device *dev,
  2632. const char *buf, u32 *offset, u32 *line_num)
  2633. {
  2634. int value = -1;
  2635. char tmp_buffer[10];
  2636. u32 count = 0;
  2637. u32 tmp_offset = *offset;
  2638. static u32 line_count = 1;
  2639. /* Bypass extra commas */
  2640. while (buf[tmp_offset] == ASCII_COMMA
  2641. && buf[tmp_offset + 1] == ASCII_COMMA)
  2642. tmp_offset++;
  2643. /* Windows and Linux difference at the end of one line */
  2644. if (buf[tmp_offset] == ASCII_COMMA
  2645. && buf[tmp_offset + 1] == ASCII_CR
  2646. && buf[tmp_offset + 2] == ASCII_LF)
  2647. tmp_offset += 2;
  2648. else if (buf[tmp_offset] == ASCII_COMMA
  2649. && buf[tmp_offset + 1] == ASCII_LF)
  2650. tmp_offset += 1;
  2651. else if (buf[tmp_offset] == ASCII_COMMA
  2652. && buf[tmp_offset + 1] == ASCII_CR)
  2653. tmp_offset += 1;
  2654. /* New line for multiple lines */
  2655. if (buf[tmp_offset] == ASCII_LF && buf[tmp_offset + 1] == ASCII_COMMA) {
  2656. tmp_offset++;
  2657. line_count++;
  2658. /*parade_debug(dev, DEBUG_LEVEL_2, "\n");*/
  2659. }
  2660. /* Beginning */
  2661. if (buf[tmp_offset] == ASCII_COMMA) {
  2662. tmp_offset++;
  2663. for (;;) {
  2664. if ((buf[tmp_offset] >= ASCII_ZERO)
  2665. && (buf[tmp_offset] <= ASCII_NINE)) {
  2666. tmp_buffer[count++] =
  2667. buf[tmp_offset] - ASCII_ZERO;
  2668. tmp_offset++;
  2669. } else {
  2670. if (count != 0) {
  2671. value = cmcp_compose_data(tmp_buffer,
  2672. count);
  2673. /*parade_debug(dev, DEBUG_LEVEL_2, */
  2674. /* ",%d", value);*/
  2675. } else {
  2676. /* 0 indicates no data available */
  2677. value = -1;
  2678. }
  2679. break;
  2680. }
  2681. }
  2682. } else {
  2683. /* Multiple line: line count */
  2684. *line_num = line_count;
  2685. /* Reset for next case */
  2686. line_count = 1;
  2687. }
  2688. *offset = tmp_offset;
  2689. return value;
  2690. }
  2691. /* Get configuration information */
  2692. void cmcp_get_configuration_info(struct device *dev,
  2693. const char *buf, struct test_case_search *search_array,
  2694. u32 case_count, struct test_case_field *field_array,
  2695. struct configuration *config)
  2696. {
  2697. u32 count = 0, sub_count = 0;
  2698. u32 exist_or_not = 0;
  2699. u32 value_offset = 0;
  2700. int retval = 0;
  2701. u32 data_num = 0;
  2702. u32 line_num = 1;
  2703. parade_debug(dev, DEBUG_LEVEL_2,
  2704. "%s: Fill configuration struct per cmcp threshold file\n",
  2705. __func__);
  2706. /* Search cases */
  2707. for (count = 0; count < MAX_CASE_NUM; count++) {
  2708. exist_or_not = 0;
  2709. for (sub_count = 0; sub_count < case_count; sub_count++) {
  2710. if (!strncmp(field_array[count].name,
  2711. search_array[sub_count].name,
  2712. field_array[count].name_size)) {
  2713. exist_or_not = 1;
  2714. break;
  2715. }
  2716. }
  2717. field_array[count].exist_or_not = exist_or_not;
  2718. /* Clear data number */
  2719. data_num = 0;
  2720. if (exist_or_not == 1) {
  2721. switch (field_array[count].type) {
  2722. case TEST_CASE_TYPE_NO:
  2723. field_array[count].data_num = 0;
  2724. field_array[count].line_num = 1;
  2725. break;
  2726. case TEST_CASE_TYPE_ONE:
  2727. value_offset = search_array[sub_count].offset
  2728. + search_array[sub_count].name_size;
  2729. *field_array[count].bufptr =
  2730. cmcp_return_one_value(dev, buf,
  2731. &value_offset, 0);
  2732. field_array[count].data_num = 1;
  2733. field_array[count].line_num = 1;
  2734. break;
  2735. case TEST_CASE_TYPE_MUL:
  2736. case TEST_CASE_TYPE_MUL_LINES:
  2737. line_num = 1;
  2738. value_offset = search_array[sub_count].offset
  2739. + search_array[sub_count].name_size;
  2740. for (;;) {
  2741. retval = cmcp_return_one_value(dev,
  2742. buf, &value_offset, &line_num);
  2743. if (retval >= 0) {
  2744. *field_array[count].bufptr++ =
  2745. retval;
  2746. data_num++;
  2747. } else
  2748. break;
  2749. }
  2750. field_array[count].data_num = data_num;
  2751. field_array[count].line_num = line_num;
  2752. break;
  2753. default:
  2754. break;
  2755. }
  2756. parade_debug(dev, DEBUG_LEVEL_2,
  2757. "%s: %s: Data number is %d, line number is %d\n",
  2758. __func__,
  2759. field_array[count].name,
  2760. field_array[count].data_num,
  2761. field_array[count].line_num);
  2762. } else
  2763. parade_debug(dev, DEBUG_LEVEL_2, "%s: !!! %s doesn't exist\n",
  2764. __func__, field_array[count].name);
  2765. }
  2766. }
  2767. /* Get basic information, like tx, rx, button number */
  2768. void cmcp_get_basic_info(struct device *dev,
  2769. struct test_case_field *field_array, struct configuration *config)
  2770. {
  2771. #define CMCP_DEBUG 0
  2772. u32 tx_num = 0;
  2773. #if CMCP_DEBUG
  2774. u32 index = 0;
  2775. #endif
  2776. config->is_valid_or_not = 1; /* Set to valid by default */
  2777. config->cm_enabled = 0;
  2778. config->cp_enabled = 0;
  2779. if (field_array[CM_TEST_INPUTS].exist_or_not)
  2780. config->cm_enabled = 1;
  2781. if (field_array[CP_TEST_INPUTS].exist_or_not)
  2782. config->cp_enabled = 1;
  2783. /* Get basic information only when CM and CP are enabled */
  2784. if (config->cm_enabled && config->cp_enabled) {
  2785. parade_debug(dev, DEBUG_LEVEL_2,
  2786. "%s: Find CM and CP thresholds\n", __func__);
  2787. config->rx_num =
  2788. field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num;
  2789. tx_num =
  2790. (field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num >> 1)
  2791. /field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num;
  2792. config->tx_num = tx_num;
  2793. config->btn_num =
  2794. field_array[PER_ELEMENT_MIN_MAX_TABLE_BUTTON].data_num >> 1;
  2795. config->cm_min_max_table_button_size =
  2796. field_array[PER_ELEMENT_MIN_MAX_TABLE_BUTTON].data_num;
  2797. config->cm_min_max_table_sensor_size =
  2798. field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num;
  2799. config->cp_min_max_table_rx_size =
  2800. field_array[PER_ELEMENT_MIN_MAX_RX].data_num;
  2801. config->cp_min_max_table_tx_size =
  2802. field_array[PER_ELEMENT_MIN_MAX_TX].data_num;
  2803. config->cm_max_table_gradient_cols_percent_size =
  2804. field_array[CM_GRADIENT_CHECK_COL].data_num;
  2805. config->cm_max_table_gradient_rows_percent_size =
  2806. field_array[CM_GRADIENT_CHECK_ROW].data_num;
  2807. config->cp_min_max_table_button_size =
  2808. field_array[CP_PER_ELEMENT_MIN_MAX_BUTTON].data_num;
  2809. #if CMCP_DEBUG
  2810. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2811. config->cm_excluding_col_edge);
  2812. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2813. config->cm_excluding_row_edge);
  2814. for (index = 0;
  2815. index < config->cm_max_table_gradient_cols_percent_size;
  2816. index++)
  2817. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2818. config->cm_max_table_gradient_cols_percent[index]);
  2819. for (index = 0;
  2820. index < config->cm_max_table_gradient_rows_percent_size;
  2821. index++)
  2822. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2823. config->cm_max_table_gradient_rows_percent[index]);
  2824. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2825. config->cm_range_limit_row);
  2826. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2827. config->cm_range_limit_col);
  2828. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2829. config->cm_min_limit_cal);
  2830. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2831. config->cm_max_limit_cal);
  2832. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2833. config->cm_max_delta_sensor_percent);
  2834. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2835. config->cm_max_delta_button_percent);
  2836. for (index = 0;
  2837. index < config->cm_min_max_table_button_size; index++)
  2838. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2839. config->cm_min_max_table_button[index]);
  2840. for (index = 0;
  2841. index < config->cm_min_max_table_sensor_size; index++)
  2842. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2843. config->cm_min_max_table_sensor[index]);
  2844. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2845. config->cp_max_delta_sensor_rx_percent);
  2846. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2847. config->cp_max_delta_sensor_tx_percent);
  2848. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2849. config->cp_max_delta_button_percent);
  2850. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2851. config->min_button);
  2852. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2853. config->max_button);
  2854. for (index = 0;
  2855. index < config->cp_min_max_table_button_size; index++)
  2856. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2857. config->cp_min_max_table_button[index]);
  2858. for (index = 0;
  2859. index < config->cp_min_max_table_rx_size; index++)
  2860. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2861. config->cp_min_max_table_rx[index]);
  2862. for (index = 0;
  2863. index < config->cp_min_max_table_tx_size; index++)
  2864. parade_debug(dev, DEBUG_LEVEL_2, "%d\n",
  2865. config->cp_min_max_table_tx[index]);
  2866. #endif
  2867. /* Invalid mutual data length */
  2868. if ((field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num >>
  2869. 1) % field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num) {
  2870. config->is_valid_or_not = 0;
  2871. parade_debug(dev, DEBUG_LEVEL_2, "Invalid mutual data length\n");
  2872. }
  2873. } else {
  2874. if (!config->cm_enabled)
  2875. parade_debug(dev, DEBUG_LEVEL_2,
  2876. "%s: Miss CM thresholds or CM data format is wrong!\n",
  2877. __func__);
  2878. if (!config->cp_enabled)
  2879. parade_debug(dev, DEBUG_LEVEL_2,
  2880. "%s: Miss CP thresholds or CP data format is wrong!\n",
  2881. __func__);
  2882. config->rx_num = 0;
  2883. config->tx_num = 0;
  2884. config->btn_num = 0;
  2885. config->is_valid_or_not = 0;
  2886. }
  2887. parade_debug(dev, DEBUG_LEVEL_2,
  2888. "%s:\n"
  2889. "Input file is %s!\n"
  2890. "CM test: %s\n"
  2891. "CP test: %s\n"
  2892. "rx_num is %d\n"
  2893. "tx_num is %d\n"
  2894. "btn_num is %d\n",
  2895. __func__,
  2896. config->is_valid_or_not == 1 ? "VALID" : "!!! INVALID !!!",
  2897. config->cm_enabled == 1 ? "Found" : "Not found",
  2898. config->cp_enabled == 1 ? "Found" : "Not found",
  2899. config->rx_num,
  2900. config->tx_num,
  2901. config->btn_num);
  2902. }
  2903. void cmcp_test_case_field_init(struct test_case_field *test_field_array,
  2904. struct configuration *configs)
  2905. {
  2906. struct test_case_field test_case_field_array[MAX_CASE_NUM] = {
  2907. {"CM TEST INPUTS", 14, TEST_CASE_TYPE_NO,
  2908. NULL, 0, 0, 0},
  2909. {"CM_EXCLUDING_COL_EDGE", 21, TEST_CASE_TYPE_ONE,
  2910. &configs->cm_excluding_col_edge, 0, 0, 0},
  2911. {"CM_EXCLUDING_ROW_EDGE", 21, TEST_CASE_TYPE_ONE,
  2912. &configs->cm_excluding_row_edge, 0, 0, 0},
  2913. {"CM_GRADIENT_CHECK_COL", 21, TEST_CASE_TYPE_MUL,
  2914. &configs->cm_max_table_gradient_cols_percent[0],
  2915. 0, 0, 0},
  2916. {"CM_GRADIENT_CHECK_ROW", 21, TEST_CASE_TYPE_MUL,
  2917. &configs->cm_max_table_gradient_rows_percent[0],
  2918. 0, 0, 0},
  2919. {"CM_RANGE_LIMIT_ROW", 18, TEST_CASE_TYPE_ONE,
  2920. &configs->cm_range_limit_row, 0, 0, 0},
  2921. {"CM_RANGE_LIMIT_COL", 18, TEST_CASE_TYPE_ONE,
  2922. &configs->cm_range_limit_col, 0, 0, 0},
  2923. {"CM_MIN_LIMIT_CAL", 16, TEST_CASE_TYPE_ONE,
  2924. &configs->cm_min_limit_cal, 0, 0, 0},
  2925. {"CM_MAX_LIMIT_CAL", 16, TEST_CASE_TYPE_ONE,
  2926. &configs->cm_max_limit_cal, 0, 0, 0},
  2927. {"CM_MAX_DELTA_SENSOR_PERCENT", 27, TEST_CASE_TYPE_ONE,
  2928. &configs->cm_max_delta_sensor_percent, 0, 0, 0},
  2929. {"CM_MAX_DELTA_BUTTON_PERCENT", 27, TEST_CASE_TYPE_ONE,
  2930. &configs->cm_max_delta_button_percent, 0, 0, 0},
  2931. {"PER_ELEMENT_MIN_MAX_TABLE_BUTTON", 32, TEST_CASE_TYPE_MUL,
  2932. &configs->cm_min_max_table_button[0], 0, 0, 0},
  2933. {"PER_ELEMENT_MIN_MAX_TABLE_SENSOR", 32,
  2934. TEST_CASE_TYPE_MUL_LINES,
  2935. &configs->cm_min_max_table_sensor[0], 0, 0, 0},
  2936. {"CP TEST INPUTS", 14, TEST_CASE_TYPE_NO,
  2937. NULL, 0, 0, 0},
  2938. {"CP_PER_ELEMENT_MIN_MAX_BUTTON", 29, TEST_CASE_TYPE_MUL,
  2939. &configs->cp_min_max_table_button[0], 0, 0, 0},
  2940. {"CP_MAX_DELTA_SENSOR_RX_PERCENT", 30, TEST_CASE_TYPE_ONE,
  2941. &configs->cp_max_delta_sensor_rx_percent,
  2942. 0, 0, 0},
  2943. {"CP_MAX_DELTA_SENSOR_TX_PERCENT", 30, TEST_CASE_TYPE_ONE,
  2944. &configs->cp_max_delta_sensor_tx_percent,
  2945. 0, 0, 0},
  2946. {"CP_MAX_DELTA_BUTTON_PERCENT", 27, TEST_CASE_TYPE_ONE,
  2947. &configs->cp_max_delta_button_percent, 0, 0, 0},
  2948. {"MIN_BUTTON", 10, TEST_CASE_TYPE_ONE,
  2949. &configs->min_button, 0, 0, 0},
  2950. {"MAX_BUTTON", 10, TEST_CASE_TYPE_ONE,
  2951. &configs->max_button, 0, 0, 0},
  2952. {"PER_ELEMENT_MIN_MAX_RX", 22, TEST_CASE_TYPE_MUL,
  2953. &configs->cp_min_max_table_rx[0], 0, 0, 0},
  2954. {"PER_ELEMENT_MIN_MAX_TX", 22, TEST_CASE_TYPE_MUL,
  2955. &configs->cp_min_max_table_tx[0], 0, 0, 0},
  2956. };
  2957. memcpy(test_field_array, test_case_field_array,
  2958. sizeof(struct test_case_field) * MAX_CASE_NUM);
  2959. }
  2960. static ssize_t cyttsp5_parse_cmcp_threshold_file_common(
  2961. struct device *dev, const char *buf, u32 file_size)
  2962. {
  2963. struct cyttsp5_device_access_data *dad
  2964. = cyttsp5_get_device_access_data(dev);
  2965. ssize_t rc = 0;
  2966. u32 case_count = 0;
  2967. parade_debug(dev, DEBUG_LEVEL_2,
  2968. "%s: Start parsing cmcp threshold file. File size is %d\n",
  2969. __func__, file_size);
  2970. cmcp_test_case_field_init(dad->test_field_array, dad->configs);
  2971. /* Get all the cases from .csv file */
  2972. case_count = cmcp_get_case_info_from_threshold_file(dev,
  2973. buf, dad->test_search_array, file_size);
  2974. /* Search cases */
  2975. cmcp_get_configuration_info(dev,
  2976. buf,
  2977. dad->test_search_array, case_count, dad->test_field_array,
  2978. dad->configs);
  2979. /* Get basic information */
  2980. cmcp_get_basic_info(dev, dad->test_field_array, dad->configs);
  2981. return rc;
  2982. }
  2983. static ssize_t cyttsp5_cmcp_threshold_loading_store(struct device *dev,
  2984. struct device_attribute *attr, const char *buf, size_t size)
  2985. {
  2986. struct cyttsp5_device_access_data *dad
  2987. = cyttsp5_get_device_access_data(dev);
  2988. long value;
  2989. int rc;
  2990. rc = kstrtol(buf, 10, &value);
  2991. if (rc < 0 || value < -1 || value > 1) {
  2992. dev_err(dev, "%s: Invalid value\n", __func__);
  2993. return size;
  2994. }
  2995. mutex_lock(&dad->cmcp_threshold_lock);
  2996. if (value == 1)
  2997. dad->cmcp_threshold_loading = true;
  2998. else if (value == -1)
  2999. dad->cmcp_threshold_loading = false;
  3000. else if (value == 0 && dad->cmcp_threshold_loading) {
  3001. dad->cmcp_threshold_loading = false;
  3002. if (dad->cmcp_threshold_size == 0) {
  3003. dev_err(dev, "%s: No cmcp threshold data\n", __func__);
  3004. goto exit_free;
  3005. }
  3006. /* Clear test executed flag */
  3007. dad->test_executed = 0;
  3008. cyttsp5_parse_cmcp_threshold_file_common(dev,
  3009. &dad->cmcp_threshold_data[0], dad->cmcp_threshold_size);
  3010. /* Mark valid */
  3011. dad->builtin_cmcp_threshold_status = 0;
  3012. /* Restore test item to default value when new file input */
  3013. dad->cmcp_test_items = 0;
  3014. }
  3015. exit_free:
  3016. kfree(dad->cmcp_threshold_data);
  3017. dad->cmcp_threshold_data = NULL;
  3018. dad->cmcp_threshold_size = 0;
  3019. mutex_unlock(&dad->cmcp_threshold_lock);
  3020. if (rc)
  3021. return rc;
  3022. return size;
  3023. }
  3024. static DEVICE_ATTR(cmcp_threshold_loading, S_IRUSR | S_IWUSR,
  3025. cyttsp5_cmcp_threshold_loading_show,
  3026. cyttsp5_cmcp_threshold_loading_store);
  3027. /*
  3028. * cmcp threshold data write
  3029. */
  3030. static ssize_t cyttsp5_cmcp_threshold_data_write(struct file *filp,
  3031. struct kobject *kobj, struct bin_attribute *bin_attr,
  3032. char *buf, loff_t offset, size_t count)
  3033. {
  3034. struct device *dev = container_of(kobj, struct device, kobj);
  3035. struct cyttsp5_device_access_data *dad
  3036. = cyttsp5_get_device_access_data(dev);
  3037. u8 *p;
  3038. parade_debug(dev, DEBUG_LEVEL_2, "%s: offset:%lld count:%zu\n",
  3039. __func__, offset, count);
  3040. mutex_lock(&dad->cmcp_threshold_lock);
  3041. if (!dad->cmcp_threshold_loading) {
  3042. mutex_unlock(&dad->cmcp_threshold_lock);
  3043. return -ENODEV;
  3044. }
  3045. p = krealloc(dad->cmcp_threshold_data, offset + count, GFP_KERNEL);
  3046. if (!p) {
  3047. kfree(dad->cmcp_threshold_data);
  3048. dad->cmcp_threshold_data = NULL;
  3049. mutex_unlock(&dad->cmcp_threshold_lock);
  3050. return -ENOMEM;
  3051. }
  3052. dad->cmcp_threshold_data = p;
  3053. memcpy(&dad->cmcp_threshold_data[offset], buf, count);
  3054. dad->cmcp_threshold_size += count;
  3055. mutex_unlock(&dad->cmcp_threshold_lock);
  3056. return count;
  3057. }
  3058. static struct bin_attribute bin_attr_cmcp_threshold_data = {
  3059. .attr = {
  3060. .name = "cmcp_threshold_data",
  3061. .mode = S_IWUSR,
  3062. },
  3063. .size = 0,
  3064. .write = cyttsp5_cmcp_threshold_data_write,
  3065. };
  3066. /*
  3067. * Suspend scan command
  3068. */
  3069. static int cyttsp5_suspend_scan_cmd_(struct device *dev)
  3070. {
  3071. int rc;
  3072. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  3073. if (rc < 0)
  3074. dev_err(dev, "%s: Suspend scan failed r=%d\n",
  3075. __func__, rc);
  3076. return rc;
  3077. }
  3078. /*
  3079. * Resume scan command
  3080. */
  3081. static int cyttsp5_resume_scan_cmd_(struct device *dev)
  3082. {
  3083. int rc;
  3084. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  3085. if (rc < 0)
  3086. dev_err(dev, "%s: Resume scan failed r=%d\n",
  3087. __func__, rc);
  3088. return rc;
  3089. }
  3090. /*
  3091. * Execute scan command
  3092. */
  3093. static int cyttsp5_exec_scan_cmd_(struct device *dev)
  3094. {
  3095. int rc;
  3096. rc = cmd->nonhid_cmd->exec_panel_scan(dev, 0);
  3097. if (rc < 0)
  3098. dev_err(dev, "%s: Heatmap start scan failed r=%d\n",
  3099. __func__, rc);
  3100. return rc;
  3101. }
  3102. /*
  3103. * Retrieve panel data command
  3104. */
  3105. static int cyttsp5_ret_scan_data_cmd_(struct device *dev, u16 read_offset,
  3106. u16 read_count, u8 data_id, u8 *response, u8 *config,
  3107. u16 *actual_read_len, u8 *return_buf)
  3108. {
  3109. int rc;
  3110. rc = cmd->nonhid_cmd->retrieve_panel_scan(dev, 0, read_offset,
  3111. read_count, data_id, response, config, actual_read_len,
  3112. return_buf);
  3113. if (rc < 0)
  3114. dev_err(dev, "%s: Retrieve scan data failed r=%d\n",
  3115. __func__, rc);
  3116. return rc;
  3117. }
  3118. /*
  3119. * Get data structure command
  3120. */
  3121. static int cyttsp5_get_data_structure_cmd_(struct device *dev, u16 read_offset,
  3122. u16 read_length, u8 data_id, u8 *status, u8 *data_format,
  3123. u16 *actual_read_len, u8 *data)
  3124. {
  3125. int rc;
  3126. rc = cmd->nonhid_cmd->get_data_structure(dev, 0, read_offset,
  3127. read_length, data_id, status, data_format,
  3128. actual_read_len, data);
  3129. if (rc < 0)
  3130. dev_err(dev, "%s: Get data structure failed r=%d\n",
  3131. __func__, rc);
  3132. return rc;
  3133. }
  3134. /*
  3135. * Run self test command
  3136. */
  3137. static int cyttsp5_run_selftest_cmd_(struct device *dev, u8 test_id,
  3138. u8 write_idacs_to_flash, u8 *status, u8 *summary_result,
  3139. u8 *results_available)
  3140. {
  3141. int rc;
  3142. rc = cmd->nonhid_cmd->run_selftest(dev, 0, test_id,
  3143. write_idacs_to_flash, status, summary_result,
  3144. results_available);
  3145. if (rc < 0)
  3146. dev_err(dev, "%s: Run self test failed r=%d\n",
  3147. __func__, rc);
  3148. return rc;
  3149. }
  3150. /*
  3151. * Get self test result command
  3152. */
  3153. static int cyttsp5_get_selftest_result_cmd_(struct device *dev,
  3154. u16 read_offset, u16 read_length, u8 test_id, u8 *status,
  3155. u16 *actual_read_len, u8 *data)
  3156. {
  3157. int rc;
  3158. rc = cmd->nonhid_cmd->get_selftest_result(dev, 0, read_offset,
  3159. read_length, test_id, status, actual_read_len, data);
  3160. if (rc < 0)
  3161. dev_err(dev, "%s: Get self test result failed r=%d\n",
  3162. __func__, rc);
  3163. return rc;
  3164. }
  3165. /*
  3166. * Calibrate IDACs command
  3167. */
  3168. static int _cyttsp5_calibrate_idacs_cmd(struct device *dev,
  3169. u8 sensing_mode, u8 *status)
  3170. {
  3171. int rc;
  3172. rc = cmd->nonhid_cmd->calibrate_idacs(dev, 0, sensing_mode, status);
  3173. return rc;
  3174. }
  3175. /*
  3176. * Initialize Baselines command
  3177. */
  3178. static int _cyttsp5_initialize_baselines_cmd(struct device *dev,
  3179. u8 sensing_mode, u8 *status)
  3180. {
  3181. int rc;
  3182. rc = cmd->nonhid_cmd->initialize_baselines(dev, 0, sensing_mode,
  3183. status);
  3184. return rc;
  3185. }
  3186. static int prepare_print_buffer(int status, u8 *in_buf, int length,
  3187. u8 *out_buf, size_t out_buf_size)
  3188. {
  3189. int index = 0;
  3190. int i;
  3191. index += scnprintf(out_buf, out_buf_size, "status %d\n", status);
  3192. for (i = 0; i < length; i++) {
  3193. index += scnprintf(&out_buf[index], out_buf_size - index,
  3194. "%02X\n", in_buf[i]);
  3195. }
  3196. return index;
  3197. }
  3198. static ssize_t cyttsp5_run_and_get_selftest_result_noprint(struct device *dev,
  3199. char *buf, size_t buf_len, u8 test_id, u16 read_length,
  3200. bool get_result_on_pass)
  3201. {
  3202. struct cyttsp5_device_access_data *dad
  3203. = cyttsp5_get_device_access_data(dev);
  3204. int status = STATUS_FAIL;
  3205. u8 cmd_status = 0;
  3206. u8 summary_result = 0;
  3207. u16 act_length = 0;
  3208. int length = 0;
  3209. int rc;
  3210. mutex_lock(&dad->sysfs_lock);
  3211. pm_runtime_get_sync(dev);
  3212. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3213. if (rc < 0) {
  3214. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3215. __func__, rc);
  3216. goto put_pm_runtime;
  3217. }
  3218. rc = cyttsp5_suspend_scan_cmd_(dev);
  3219. if (rc < 0) {
  3220. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3221. __func__, rc);
  3222. goto release_exclusive;
  3223. }
  3224. rc = cyttsp5_run_selftest_cmd_(dev, test_id, 0,
  3225. &cmd_status, &summary_result, NULL);
  3226. if (rc < 0) {
  3227. dev_err(dev, "%s: Error on run self test for test_id:%d r=%d\n",
  3228. __func__, test_id, rc);
  3229. goto resume_scan;
  3230. }
  3231. /* Form response buffer */
  3232. dad->ic_buf[0] = cmd_status;
  3233. dad->ic_buf[1] = summary_result;
  3234. length = 2;
  3235. /* Get data if command status is success */
  3236. if (cmd_status != CY_CMD_STATUS_SUCCESS)
  3237. goto status_success;
  3238. /* Get data unless test result is pass */
  3239. if (summary_result == CY_ST_RESULT_PASS && !get_result_on_pass)
  3240. goto status_success;
  3241. rc = cyttsp5_get_selftest_result_cmd_(dev, 0, read_length,
  3242. test_id, &cmd_status, &act_length, &dad->ic_buf[6]);
  3243. if (rc < 0) {
  3244. dev_err(dev, "%s: Error on get self test result r=%d\n",
  3245. __func__, rc);
  3246. goto resume_scan;
  3247. }
  3248. dad->ic_buf[2] = cmd_status;
  3249. dad->ic_buf[3] = test_id;
  3250. dad->ic_buf[4] = LOW_BYTE(act_length);
  3251. dad->ic_buf[5] = HI_BYTE(act_length);
  3252. length = 6 + act_length;
  3253. status_success:
  3254. status = STATUS_SUCCESS;
  3255. resume_scan:
  3256. cyttsp5_resume_scan_cmd_(dev);
  3257. release_exclusive:
  3258. cmd->release_exclusive(dev);
  3259. put_pm_runtime:
  3260. pm_runtime_put(dev);
  3261. mutex_unlock(&dad->sysfs_lock);
  3262. return status;
  3263. }
  3264. static ssize_t cyttsp5_run_and_get_selftest_result(struct device *dev,
  3265. char *buf, size_t buf_len, u8 test_id, u16 read_length,
  3266. bool get_result_on_pass)
  3267. {
  3268. struct cyttsp5_device_access_data *dad
  3269. = cyttsp5_get_device_access_data(dev);
  3270. int status = STATUS_FAIL;
  3271. u8 cmd_status = 0;
  3272. u8 summary_result = 0;
  3273. u16 act_length = 0;
  3274. int length = 0;
  3275. int size;
  3276. int rc;
  3277. mutex_lock(&dad->sysfs_lock);
  3278. pm_runtime_get_sync(dev);
  3279. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3280. if (rc < 0) {
  3281. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3282. __func__, rc);
  3283. goto put_pm_runtime;
  3284. }
  3285. rc = cyttsp5_suspend_scan_cmd_(dev);
  3286. if (rc < 0) {
  3287. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3288. __func__, rc);
  3289. goto release_exclusive;
  3290. }
  3291. rc = cyttsp5_run_selftest_cmd_(dev, test_id, 0,
  3292. &cmd_status, &summary_result, NULL);
  3293. if (rc < 0) {
  3294. dev_err(dev, "%s: Error on run self test for test_id:%d r=%d\n",
  3295. __func__, test_id, rc);
  3296. goto resume_scan;
  3297. }
  3298. /* Form response buffer */
  3299. dad->ic_buf[0] = cmd_status;
  3300. dad->ic_buf[1] = summary_result;
  3301. length = 2;
  3302. /* Get data if command status is success */
  3303. if (cmd_status != CY_CMD_STATUS_SUCCESS)
  3304. goto status_success;
  3305. /* Get data unless test result is pass */
  3306. if (summary_result == CY_ST_RESULT_PASS && !get_result_on_pass)
  3307. goto status_success;
  3308. rc = cyttsp5_get_selftest_result_cmd_(dev, 0, read_length,
  3309. test_id, &cmd_status, &act_length, &dad->ic_buf[6]);
  3310. if (rc < 0) {
  3311. dev_err(dev, "%s: Error on get self test result r=%d\n",
  3312. __func__, rc);
  3313. goto resume_scan;
  3314. }
  3315. dad->ic_buf[2] = cmd_status;
  3316. dad->ic_buf[3] = test_id;
  3317. dad->ic_buf[4] = LOW_BYTE(act_length);
  3318. dad->ic_buf[5] = HI_BYTE(act_length);
  3319. length = 6 + act_length;
  3320. status_success:
  3321. status = STATUS_SUCCESS;
  3322. resume_scan:
  3323. cyttsp5_resume_scan_cmd_(dev);
  3324. release_exclusive:
  3325. cmd->release_exclusive(dev);
  3326. put_pm_runtime:
  3327. pm_runtime_put(dev);
  3328. if (status == STATUS_FAIL)
  3329. length = 0;
  3330. size = prepare_print_buffer(status, dad->ic_buf, length, buf, buf_len);
  3331. mutex_unlock(&dad->sysfs_lock);
  3332. return size;
  3333. }
  3334. struct cyttsp5_device_access_debugfs_data {
  3335. struct cyttsp5_device_access_data *dad;
  3336. ssize_t pr_buf_len;
  3337. u8 pr_buf[3 * CY_MAX_PRBUF_SIZE];
  3338. };
  3339. static int cyttsp5_device_access_debugfs_open(struct inode *inode,
  3340. struct file *filp)
  3341. {
  3342. struct cyttsp5_device_access_data *dad = inode->i_private;
  3343. struct cyttsp5_device_access_debugfs_data *data;
  3344. data = kzalloc(sizeof(*data), GFP_KERNEL);
  3345. if (!data)
  3346. return -ENOMEM;
  3347. data->dad = dad;
  3348. filp->private_data = data;
  3349. return nonseekable_open(inode, filp);
  3350. }
  3351. static int cyttsp5_device_access_debugfs_release(struct inode *inode,
  3352. struct file *filp)
  3353. {
  3354. kfree(filp->private_data);
  3355. return 0;
  3356. }
  3357. #define CY_DEBUGFS_FOPS(_name, _read, _write) \
  3358. static const struct file_operations _name##_debugfs_fops = { \
  3359. .open = cyttsp5_device_access_debugfs_open, \
  3360. .release = cyttsp5_device_access_debugfs_release, \
  3361. .read = _read, \
  3362. .write = _write, \
  3363. }
  3364. static ssize_t panel_scan_debugfs_read(struct file *filp, char __user *buf,
  3365. size_t count, loff_t *ppos)
  3366. {
  3367. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3368. struct cyttsp5_device_access_data *dad = data->dad;
  3369. struct device *dev = dad->dev;
  3370. struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
  3371. int status = STATUS_FAIL;
  3372. u8 config;
  3373. u16 actual_read_len;
  3374. int length = 0;
  3375. u8 element_size = 0;
  3376. u8 *buf_offset;
  3377. int elem_offset = 0;
  3378. int rc;
  3379. if (*ppos)
  3380. goto exit;
  3381. mutex_lock(&dad->sysfs_lock);
  3382. pm_runtime_get_sync(dev);
  3383. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3384. if (rc < 0) {
  3385. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3386. __func__, rc);
  3387. goto put_pm_runtime;
  3388. }
  3389. rc = cyttsp5_suspend_scan_cmd_(dev);
  3390. if (rc < 0) {
  3391. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3392. __func__, rc);
  3393. goto release_exclusive;
  3394. }
  3395. rc = cyttsp5_exec_scan_cmd_(dev);
  3396. if (rc < 0) {
  3397. dev_err(dev, "%s: Error on execute panel scan r=%d\n",
  3398. __func__, rc);
  3399. goto resume_scan;
  3400. }
  3401. /* Set length to max to read all */
  3402. rc = cyttsp5_ret_scan_data_cmd_(dev, 0, 0xFFFF,
  3403. dad->panel_scan_data_id, dad->ic_buf, &config,
  3404. &actual_read_len, NULL);
  3405. if (rc < 0) {
  3406. dev_err(dev, "%s: Error on retrieve panel scan r=%d\n",
  3407. __func__, rc);
  3408. goto resume_scan;
  3409. }
  3410. length = get_unaligned_le16(&dad->ic_buf[0]);
  3411. buf_offset = dad->ic_buf + length;
  3412. element_size = config & 0x07;
  3413. elem_offset = actual_read_len;
  3414. while (actual_read_len > 0) {
  3415. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, 0xFFFF,
  3416. dad->panel_scan_data_id, NULL, &config,
  3417. &actual_read_len, buf_offset);
  3418. if (rc < 0)
  3419. goto resume_scan;
  3420. length += actual_read_len * element_size;
  3421. buf_offset = dad->ic_buf + length;
  3422. elem_offset += actual_read_len;
  3423. }
  3424. /* Reconstruct cmd header */
  3425. put_unaligned_le16(length, &dad->ic_buf[0]);
  3426. put_unaligned_le16(elem_offset, &dad->ic_buf[7]);
  3427. /* Do not print command header */
  3428. length -= 5;
  3429. status = STATUS_SUCCESS;
  3430. resume_scan:
  3431. cyttsp5_resume_scan_cmd_(dev);
  3432. release_exclusive:
  3433. cmd->release_exclusive(dev);
  3434. put_pm_runtime:
  3435. pm_runtime_put(dev);
  3436. if (status == STATUS_FAIL)
  3437. length = 0;
  3438. if (cd->show_timestamp) {
  3439. int index = 0;
  3440. index += scnprintf(data->pr_buf, sizeof(data->pr_buf),
  3441. "[%u] ", jiffies_to_msecs(jiffies));
  3442. data->pr_buf_len = prepare_print_buffer(status,
  3443. &dad->ic_buf[5], length, &data->pr_buf[index],
  3444. sizeof(data->pr_buf)-index);
  3445. } else {
  3446. data->pr_buf_len = prepare_print_buffer(status,
  3447. &dad->ic_buf[5], length, data->pr_buf,
  3448. sizeof(data->pr_buf));
  3449. }
  3450. mutex_unlock(&dad->sysfs_lock);
  3451. exit:
  3452. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3453. data->pr_buf_len);
  3454. }
  3455. static ssize_t panel_scan_debugfs_write(struct file *filp,
  3456. const char __user *buf, size_t count, loff_t *ppos)
  3457. {
  3458. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3459. struct cyttsp5_device_access_data *dad = data->dad;
  3460. ssize_t length;
  3461. int rc = 0;
  3462. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  3463. buf, count);
  3464. if (rc < 0)
  3465. return rc;
  3466. count = rc;
  3467. mutex_lock(&dad->sysfs_lock);
  3468. length = cyttsp5_ic_parse_input(dad->dev, data->pr_buf, count,
  3469. dad->ic_buf, CY_MAX_PRBUF_SIZE);
  3470. if (length != 1) {
  3471. dev_err(dad->dev, "%s: Malformed input\n", __func__);
  3472. rc = -EINVAL;
  3473. goto exit_unlock;
  3474. }
  3475. dad->panel_scan_data_id = dad->ic_buf[0];
  3476. exit_unlock:
  3477. mutex_unlock(&dad->sysfs_lock);
  3478. if (rc)
  3479. return rc;
  3480. return count;
  3481. }
  3482. CY_DEBUGFS_FOPS(panel_scan, panel_scan_debugfs_read, panel_scan_debugfs_write);
  3483. static ssize_t get_idac_debugfs_read(struct file *filp, char __user *buf,
  3484. size_t count, loff_t *ppos)
  3485. {
  3486. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3487. struct cyttsp5_device_access_data *dad = data->dad;
  3488. struct device *dev = dad->dev;
  3489. int status = STATUS_FAIL;
  3490. u8 cmd_status = 0;
  3491. u8 data_format = 0;
  3492. u16 act_length = 0;
  3493. int length = 0;
  3494. int rc;
  3495. if (*ppos)
  3496. goto exit;
  3497. mutex_lock(&dad->sysfs_lock);
  3498. pm_runtime_get_sync(dev);
  3499. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3500. if (rc < 0) {
  3501. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3502. __func__, rc);
  3503. goto put_pm_runtime;
  3504. }
  3505. rc = cyttsp5_suspend_scan_cmd_(dev);
  3506. if (rc < 0) {
  3507. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3508. __func__, rc);
  3509. goto release_exclusive;
  3510. }
  3511. rc = cyttsp5_get_data_structure_cmd_(dev, 0, PIP_CMD_MAX_LENGTH,
  3512. dad->get_idac_data_id, &cmd_status, &data_format,
  3513. &act_length, &dad->ic_buf[5]);
  3514. if (rc < 0) {
  3515. dev_err(dev, "%s: Error on get data structure r=%d\n",
  3516. __func__, rc);
  3517. goto resume_scan;
  3518. }
  3519. dad->ic_buf[0] = cmd_status;
  3520. dad->ic_buf[1] = dad->get_idac_data_id;
  3521. dad->ic_buf[2] = LOW_BYTE(act_length);
  3522. dad->ic_buf[3] = HI_BYTE(act_length);
  3523. dad->ic_buf[4] = data_format;
  3524. length = 5 + act_length;
  3525. status = STATUS_SUCCESS;
  3526. resume_scan:
  3527. cyttsp5_resume_scan_cmd_(dev);
  3528. release_exclusive:
  3529. cmd->release_exclusive(dev);
  3530. put_pm_runtime:
  3531. pm_runtime_put(dev);
  3532. if (status == STATUS_FAIL)
  3533. length = 0;
  3534. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  3535. data->pr_buf, sizeof(data->pr_buf));
  3536. mutex_unlock(&dad->sysfs_lock);
  3537. exit:
  3538. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3539. data->pr_buf_len);
  3540. }
  3541. static ssize_t get_idac_debugfs_write(struct file *filp,
  3542. const char __user *buf, size_t count, loff_t *ppos)
  3543. {
  3544. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3545. struct cyttsp5_device_access_data *dad = data->dad;
  3546. ssize_t length;
  3547. int rc = 0;
  3548. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  3549. buf, count);
  3550. if (rc < 0)
  3551. return rc;
  3552. count = rc;
  3553. mutex_lock(&dad->sysfs_lock);
  3554. length = cyttsp5_ic_parse_input(dad->dev, data->pr_buf, count,
  3555. dad->ic_buf, CY_MAX_PRBUF_SIZE);
  3556. if (length != 1) {
  3557. dev_err(dad->dev, "%s: Malformed input\n", __func__);
  3558. rc = -EINVAL;
  3559. goto exit_unlock;
  3560. }
  3561. dad->get_idac_data_id = dad->ic_buf[0];
  3562. exit_unlock:
  3563. mutex_unlock(&dad->sysfs_lock);
  3564. if (rc)
  3565. return rc;
  3566. return count;
  3567. }
  3568. CY_DEBUGFS_FOPS(get_idac, get_idac_debugfs_read, get_idac_debugfs_write);
  3569. static ssize_t calibrate_debugfs_read(struct file *filp, char __user *buf,
  3570. size_t count, loff_t *ppos)
  3571. {
  3572. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3573. struct cyttsp5_device_access_data *dad = data->dad;
  3574. struct device *dev = dad->dev;
  3575. int status = STATUS_FAIL;
  3576. int length = 0;
  3577. int rc;
  3578. if (*ppos)
  3579. goto exit;
  3580. mutex_lock(&dad->sysfs_lock);
  3581. pm_runtime_get_sync(dev);
  3582. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3583. if (rc < 0) {
  3584. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3585. __func__, rc);
  3586. goto put_pm_runtime;
  3587. }
  3588. rc = cyttsp5_suspend_scan_cmd_(dev);
  3589. if (rc < 0) {
  3590. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3591. __func__, rc);
  3592. goto release_exclusive;
  3593. }
  3594. rc = _cyttsp5_calibrate_idacs_cmd(dev, dad->calibrate_sensing_mode,
  3595. &dad->ic_buf[0]);
  3596. if (rc < 0) {
  3597. dev_err(dev, "%s: Error on calibrate idacs r=%d\n",
  3598. __func__, rc);
  3599. goto resume_scan;
  3600. }
  3601. length = 1;
  3602. /* Check if baseline initialization is requested */
  3603. if (dad->calibrate_initialize_baselines) {
  3604. /* Perform baseline initialization for all modes */
  3605. rc = _cyttsp5_initialize_baselines_cmd(dev, CY_IB_SM_MUTCAP |
  3606. CY_IB_SM_SELFCAP | CY_IB_SM_BUTTON,
  3607. &dad->ic_buf[length]);
  3608. if (rc < 0) {
  3609. dev_err(dev, "%s: Error on initialize baselines r=%d\n",
  3610. __func__, rc);
  3611. goto resume_scan;
  3612. }
  3613. length++;
  3614. }
  3615. status = STATUS_SUCCESS;
  3616. resume_scan:
  3617. cyttsp5_resume_scan_cmd_(dev);
  3618. release_exclusive:
  3619. cmd->release_exclusive(dev);
  3620. put_pm_runtime:
  3621. pm_runtime_put(dev);
  3622. if (status == STATUS_FAIL)
  3623. length = 0;
  3624. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  3625. data->pr_buf, sizeof(data->pr_buf));
  3626. mutex_unlock(&dad->sysfs_lock);
  3627. exit:
  3628. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3629. data->pr_buf_len);
  3630. }
  3631. static ssize_t calibrate_debugfs_write(struct file *filp,
  3632. const char __user *buf, size_t count, loff_t *ppos)
  3633. {
  3634. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3635. struct cyttsp5_device_access_data *dad = data->dad;
  3636. ssize_t length;
  3637. int rc = 0;
  3638. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  3639. buf, count);
  3640. if (rc < 0)
  3641. return rc;
  3642. count = rc;
  3643. mutex_lock(&dad->sysfs_lock);
  3644. length = cyttsp5_ic_parse_input(dad->dev, data->pr_buf, count,
  3645. dad->ic_buf, CY_MAX_PRBUF_SIZE);
  3646. if (length != 2) {
  3647. dev_err(dad->dev, "%s: Malformed input\n", __func__);
  3648. rc = -EINVAL;
  3649. goto exit_unlock;
  3650. }
  3651. dad->calibrate_sensing_mode = dad->ic_buf[0];
  3652. dad->calibrate_initialize_baselines = dad->ic_buf[1];
  3653. exit_unlock:
  3654. mutex_unlock(&dad->sysfs_lock);
  3655. if (rc)
  3656. return rc;
  3657. return count;
  3658. }
  3659. CY_DEBUGFS_FOPS(calibrate, calibrate_debugfs_read, calibrate_debugfs_write);
  3660. static ssize_t baseline_debugfs_read(struct file *filp, char __user *buf,
  3661. size_t count, loff_t *ppos)
  3662. {
  3663. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3664. struct cyttsp5_device_access_data *dad = data->dad;
  3665. struct device *dev = dad->dev;
  3666. int status = STATUS_FAIL;
  3667. int length = 0;
  3668. int rc;
  3669. if (*ppos)
  3670. goto exit;
  3671. mutex_lock(&dad->sysfs_lock);
  3672. pm_runtime_get_sync(dev);
  3673. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3674. if (rc < 0) {
  3675. dev_err(dev, "%s: Error on request exclusive r=%d\n",
  3676. __func__, rc);
  3677. goto put_pm_runtime;
  3678. }
  3679. rc = cyttsp5_suspend_scan_cmd_(dev);
  3680. if (rc < 0) {
  3681. dev_err(dev, "%s: Error on suspend scan r=%d\n",
  3682. __func__, rc);
  3683. goto release_exclusive;
  3684. }
  3685. rc = _cyttsp5_initialize_baselines_cmd(dev, dad->baseline_sensing_mode,
  3686. &dad->ic_buf[0]);
  3687. if (rc < 0) {
  3688. dev_err(dev, "%s: Error on initialize baselines r=%d\n",
  3689. __func__, rc);
  3690. goto resume_scan;
  3691. }
  3692. length = 1;
  3693. status = STATUS_SUCCESS;
  3694. resume_scan:
  3695. cyttsp5_resume_scan_cmd_(dev);
  3696. release_exclusive:
  3697. cmd->release_exclusive(dev);
  3698. put_pm_runtime:
  3699. pm_runtime_put(dev);
  3700. if (status == STATUS_FAIL)
  3701. length = 0;
  3702. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  3703. data->pr_buf, sizeof(data->pr_buf));
  3704. mutex_unlock(&dad->sysfs_lock);
  3705. exit:
  3706. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3707. data->pr_buf_len);
  3708. }
  3709. static ssize_t baseline_debugfs_write(struct file *filp,
  3710. const char __user *buf, size_t count, loff_t *ppos)
  3711. {
  3712. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3713. struct cyttsp5_device_access_data *dad = data->dad;
  3714. ssize_t length;
  3715. int rc = 0;
  3716. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  3717. buf, count);
  3718. if (rc < 0)
  3719. return rc;
  3720. count = rc;
  3721. mutex_lock(&dad->sysfs_lock);
  3722. length = cyttsp5_ic_parse_input(dad->dev, buf, count, dad->ic_buf,
  3723. CY_MAX_PRBUF_SIZE);
  3724. if (length != 1) {
  3725. dev_err(dad->dev, "%s: Malformed input\n", __func__);
  3726. rc = -EINVAL;
  3727. goto exit_unlock;
  3728. }
  3729. dad->baseline_sensing_mode = dad->ic_buf[0];
  3730. exit_unlock:
  3731. mutex_unlock(&dad->sysfs_lock);
  3732. if (rc)
  3733. return rc;
  3734. return count;
  3735. }
  3736. CY_DEBUGFS_FOPS(baseline, baseline_debugfs_read, baseline_debugfs_write);
  3737. static ssize_t auto_shorts_debugfs_read(struct file *filp, char __user *buf,
  3738. size_t count, loff_t *ppos)
  3739. {
  3740. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3741. if (!*ppos)
  3742. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3743. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3744. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3745. CY_ST_ID_AUTOSHORTS, PIP_CMD_MAX_LENGTH, false);
  3746. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3747. data->pr_buf_len);
  3748. }
  3749. CY_DEBUGFS_FOPS(auto_shorts, auto_shorts_debugfs_read, NULL);
  3750. static ssize_t opens_debugfs_read(struct file *filp, char __user *buf,
  3751. size_t count, loff_t *ppos)
  3752. {
  3753. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3754. if (!*ppos)
  3755. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3756. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3757. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3758. CY_ST_ID_OPENS, PIP_CMD_MAX_LENGTH, false);
  3759. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3760. data->pr_buf_len);
  3761. }
  3762. CY_DEBUGFS_FOPS(opens, opens_debugfs_read, NULL);
  3763. static ssize_t cm_panel_debugfs_read(struct file *filp, char __user *buf,
  3764. size_t count, loff_t *ppos)
  3765. {
  3766. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3767. if (!*ppos)
  3768. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3769. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3770. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3771. CY_ST_ID_CM_PANEL, PIP_CMD_MAX_LENGTH, true);
  3772. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3773. data->pr_buf_len);
  3774. }
  3775. CY_DEBUGFS_FOPS(cm_panel, cm_panel_debugfs_read, NULL);
  3776. static ssize_t cp_panel_debugfs_read(struct file *filp, char __user *buf,
  3777. size_t count, loff_t *ppos)
  3778. {
  3779. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3780. if (!*ppos)
  3781. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3782. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3783. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3784. CY_ST_ID_CP_PANEL, PIP_CMD_MAX_LENGTH, true);
  3785. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3786. data->pr_buf_len);
  3787. }
  3788. CY_DEBUGFS_FOPS(cp_panel, cp_panel_debugfs_read, NULL);
  3789. static ssize_t cm_button_debugfs_read(struct file *filp, char __user *buf,
  3790. size_t count, loff_t *ppos)
  3791. {
  3792. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3793. if (!*ppos)
  3794. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3795. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3796. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3797. CY_ST_ID_CM_BUTTON, PIP_CMD_MAX_LENGTH, true);
  3798. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3799. data->pr_buf_len);
  3800. }
  3801. CY_DEBUGFS_FOPS(cm_button, cm_button_debugfs_read, NULL);
  3802. static ssize_t cp_button_debugfs_read(struct file *filp, char __user *buf,
  3803. size_t count, loff_t *ppos)
  3804. {
  3805. struct cyttsp5_device_access_debugfs_data *data = filp->private_data;
  3806. if (!*ppos)
  3807. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  3808. data->pr_buf_len = cyttsp5_run_and_get_selftest_result(
  3809. data->dad->dev, data->pr_buf, sizeof(data->pr_buf),
  3810. CY_ST_ID_CP_BUTTON, PIP_CMD_MAX_LENGTH, true);
  3811. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  3812. data->pr_buf_len);
  3813. }
  3814. CY_DEBUGFS_FOPS(cp_button, cp_button_debugfs_read, NULL);
  3815. #ifdef TTHE_TUNER_SUPPORT
  3816. static ssize_t tthe_get_panel_data_debugfs_read(struct file *filp,
  3817. char __user *buf, size_t count, loff_t *ppos)
  3818. {
  3819. struct cyttsp5_device_access_data *dad = filp->private_data;
  3820. struct device *dev;
  3821. struct cyttsp5_core_data *cd;
  3822. u8 config;
  3823. u16 actual_read_len;
  3824. u16 length = 0;
  3825. u8 element_size = 0;
  3826. u8 *buf_offset;
  3827. u8 *buf_out;
  3828. int elem;
  3829. int elem_offset = 0;
  3830. int print_idx = 0;
  3831. int rc;
  3832. int rc1;
  3833. int i;
  3834. mutex_lock(&dad->debugfs_lock);
  3835. dev = dad->dev;
  3836. cd = dev_get_drvdata(dev);
  3837. buf_out = dad->tthe_get_panel_data_buf;
  3838. if (!buf_out)
  3839. goto release_mutex;
  3840. pm_runtime_get_sync(dev);
  3841. rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
  3842. if (rc < 0)
  3843. goto put_runtime;
  3844. if (dad->heatmap.scan_start) {
  3845. /*
  3846. * To fix CDT206291: avoid multiple scans when
  3847. * return data is larger than 4096 bytes in one cycle
  3848. */
  3849. dad->heatmap.scan_start = 0;
  3850. /* Start scan */
  3851. rc = cyttsp5_exec_scan_cmd_(dev);
  3852. if (rc < 0)
  3853. goto release_exclusive;
  3854. }
  3855. elem = dad->heatmap.num_element;
  3856. #if defined(CY_ENABLE_MAX_ELEN)
  3857. if (elem > CY_MAX_ELEN) {
  3858. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset,
  3859. CY_MAX_ELEN, dad->heatmap.data_type, dad->ic_buf,
  3860. &config, &actual_read_len, NULL);
  3861. } else{
  3862. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, elem,
  3863. dad->heatmap.data_type, dad->ic_buf, &config,
  3864. &actual_read_len, NULL);
  3865. }
  3866. #else
  3867. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, elem,
  3868. dad->heatmap.data_type, dad->ic_buf, &config,
  3869. &actual_read_len, NULL);
  3870. #endif
  3871. if (rc < 0)
  3872. goto release_exclusive;
  3873. length = get_unaligned_le16(&dad->ic_buf[0]);
  3874. buf_offset = dad->ic_buf + length;
  3875. element_size = config & CY_CMD_RET_PANEL_ELMNT_SZ_MASK;
  3876. elem -= actual_read_len;
  3877. elem_offset = actual_read_len;
  3878. while (elem > 0) {
  3879. #ifdef CY_ENABLE_MAX_ELEN
  3880. if (elem > CY_MAX_ELEN) {
  3881. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset,
  3882. CY_MAX_ELEN, dad->heatmap.data_type, NULL, &config,
  3883. &actual_read_len, buf_offset);
  3884. } else{
  3885. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, elem,
  3886. dad->heatmap.data_type, NULL, &config,
  3887. &actual_read_len, buf_offset);
  3888. }
  3889. #else
  3890. rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, elem,
  3891. dad->heatmap.data_type, NULL, &config,
  3892. &actual_read_len, buf_offset);
  3893. #endif
  3894. if (rc < 0)
  3895. goto release_exclusive;
  3896. if (!actual_read_len)
  3897. break;
  3898. length += actual_read_len * element_size;
  3899. buf_offset = dad->ic_buf + length;
  3900. elem -= actual_read_len;
  3901. elem_offset += actual_read_len;
  3902. }
  3903. /* Reconstruct cmd header */
  3904. put_unaligned_le16(length, &dad->ic_buf[0]);
  3905. put_unaligned_le16(elem_offset, &dad->ic_buf[7]);
  3906. release_exclusive:
  3907. rc1 = cmd->release_exclusive(dev);
  3908. put_runtime:
  3909. pm_runtime_put(dev);
  3910. if (rc < 0)
  3911. goto release_mutex;
  3912. if (cd->show_timestamp)
  3913. print_idx += scnprintf(buf_out, TTHE_TUNER_MAX_BUF,
  3914. "[%u] CY_DATA:", jiffies_to_msecs(jiffies));
  3915. else
  3916. print_idx += scnprintf(buf_out, TTHE_TUNER_MAX_BUF,
  3917. "CY_DATA:");
  3918. for (i = 0; i < length; i++)
  3919. print_idx += scnprintf(buf_out + print_idx,
  3920. TTHE_TUNER_MAX_BUF - print_idx,
  3921. "%02X ", dad->ic_buf[i]);
  3922. print_idx += scnprintf(buf_out + print_idx,
  3923. TTHE_TUNER_MAX_BUF - print_idx,
  3924. ":(%d bytes)\n", length);
  3925. rc = simple_read_from_buffer(buf, count, ppos, buf_out, print_idx);
  3926. print_idx = rc;
  3927. release_mutex:
  3928. mutex_unlock(&dad->debugfs_lock);
  3929. return print_idx;
  3930. }
  3931. static ssize_t tthe_get_panel_data_debugfs_write(struct file *filp,
  3932. const char __user *buf, size_t count, loff_t *ppos)
  3933. {
  3934. struct cyttsp5_device_access_data *dad = filp->private_data;
  3935. struct device *dev = dad->dev;
  3936. ssize_t length;
  3937. int max_read;
  3938. u8 *buf_in = dad->tthe_get_panel_data_buf;
  3939. int ret;
  3940. mutex_lock(&dad->debugfs_lock);
  3941. ret = copy_from_user(buf_in + (*ppos), buf, count);
  3942. if (ret)
  3943. goto exit;
  3944. buf_in[count] = 0;
  3945. length = cyttsp5_ic_parse_input(dev, buf_in, count, dad->ic_buf,
  3946. CY_MAX_PRBUF_SIZE);
  3947. if (length <= 0) {
  3948. dev_err(dev, "%s: %s Group Data store\n", __func__,
  3949. "Malformed input for");
  3950. goto exit;
  3951. }
  3952. /* update parameter value */
  3953. dad->heatmap.num_element = get_unaligned_le16(&dad->ic_buf[3]);
  3954. dad->heatmap.data_type = dad->ic_buf[5];
  3955. if (dad->ic_buf[6] > 0)
  3956. dad->heatmap.scan_start = true;
  3957. else
  3958. dad->heatmap.scan_start = false;
  3959. /* elem can not be bigger then buffer size */
  3960. max_read = CY_CMD_RET_PANEL_HDR;
  3961. max_read += dad->heatmap.num_element * CY_CMD_RET_PANEL_ELMNT_SZ_MAX;
  3962. if (max_read >= CY_MAX_PRBUF_SIZE) {
  3963. dad->heatmap.num_element =
  3964. (CY_MAX_PRBUF_SIZE - CY_CMD_RET_PANEL_HDR)
  3965. / CY_CMD_RET_PANEL_ELMNT_SZ_MAX;
  3966. parade_debug(dev, DEBUG_LEVEL_2, "%s: Will get %d element\n",
  3967. __func__, dad->heatmap.num_element);
  3968. }
  3969. exit:
  3970. mutex_unlock(&dad->debugfs_lock);
  3971. parade_debug(dev, DEBUG_LEVEL_2, "%s: return count=%zu\n",
  3972. __func__, count);
  3973. return count;
  3974. }
  3975. static int tthe_get_panel_data_debugfs_open(struct inode *inode,
  3976. struct file *filp)
  3977. {
  3978. struct cyttsp5_device_access_data *dad = inode->i_private;
  3979. mutex_lock(&dad->debugfs_lock);
  3980. if (dad->tthe_get_panel_data_is_open) {
  3981. mutex_unlock(&dad->debugfs_lock);
  3982. return -EBUSY;
  3983. }
  3984. filp->private_data = inode->i_private;
  3985. dad->tthe_get_panel_data_is_open = 1;
  3986. mutex_unlock(&dad->debugfs_lock);
  3987. return 0;
  3988. }
  3989. static int tthe_get_panel_data_debugfs_close(struct inode *inode,
  3990. struct file *filp)
  3991. {
  3992. struct cyttsp5_device_access_data *dad = filp->private_data;
  3993. mutex_lock(&dad->debugfs_lock);
  3994. filp->private_data = NULL;
  3995. dad->tthe_get_panel_data_is_open = 0;
  3996. mutex_unlock(&dad->debugfs_lock);
  3997. return 0;
  3998. }
  3999. static const struct file_operations tthe_get_panel_data_fops = {
  4000. .open = tthe_get_panel_data_debugfs_open,
  4001. .release = tthe_get_panel_data_debugfs_close,
  4002. .read = tthe_get_panel_data_debugfs_read,
  4003. .write = tthe_get_panel_data_debugfs_write,
  4004. };
  4005. #endif
  4006. static int cyttsp5_setup_sysfs(struct device *dev)
  4007. {
  4008. struct cyttsp5_device_access_data *dad
  4009. = cyttsp5_get_device_access_data(dev);
  4010. int rc;
  4011. rc = device_create_file(dev, &dev_attr_command);
  4012. if (rc) {
  4013. dev_err(dev, "%s: Error, could not create command\n",
  4014. __func__);
  4015. goto exit;
  4016. }
  4017. rc = device_create_file(dev, &dev_attr_status);
  4018. if (rc) {
  4019. dev_err(dev, "%s: Error, could not create status\n",
  4020. __func__);
  4021. goto unregister_command;
  4022. }
  4023. rc = device_create_file(dev, &dev_attr_response);
  4024. if (rc) {
  4025. dev_err(dev, "%s: Error, could not create response\n",
  4026. __func__);
  4027. goto unregister_status;
  4028. }
  4029. dad->base_dentry = debugfs_create_dir(dev_name(dev), NULL);
  4030. if (IS_ERR_OR_NULL(dad->base_dentry)) {
  4031. dev_err(dev, "%s: Error, could not create base directory\n",
  4032. __func__);
  4033. goto unregister_response;
  4034. }
  4035. dad->mfg_test_dentry = debugfs_create_dir("mfg_test",
  4036. dad->base_dentry);
  4037. if (IS_ERR_OR_NULL(dad->mfg_test_dentry)) {
  4038. dev_err(dev, "%s: Error, could not create mfg_test directory\n",
  4039. __func__);
  4040. goto unregister_base_dir;
  4041. }
  4042. if (IS_ERR_OR_NULL(debugfs_create_file("panel_scan", 0600,
  4043. dad->mfg_test_dentry, dad,
  4044. &panel_scan_debugfs_fops))) {
  4045. dev_err(dev, "%s: Error, could not create panel_scan\n",
  4046. __func__);
  4047. goto unregister_base_dir;
  4048. }
  4049. if (IS_ERR_OR_NULL(debugfs_create_file("get_idac", 0600,
  4050. dad->mfg_test_dentry, dad, &get_idac_debugfs_fops))) {
  4051. dev_err(dev, "%s: Error, could not create get_idac\n",
  4052. __func__);
  4053. goto unregister_base_dir;
  4054. }
  4055. if (IS_ERR_OR_NULL(debugfs_create_file("auto_shorts", 0400,
  4056. dad->mfg_test_dentry, dad,
  4057. &auto_shorts_debugfs_fops))) {
  4058. dev_err(dev, "%s: Error, could not create auto_shorts\n",
  4059. __func__);
  4060. goto unregister_base_dir;
  4061. }
  4062. if (IS_ERR_OR_NULL(debugfs_create_file("opens", 0400,
  4063. dad->mfg_test_dentry, dad, &opens_debugfs_fops))) {
  4064. dev_err(dev, "%s: Error, could not create opens\n",
  4065. __func__);
  4066. goto unregister_base_dir;
  4067. }
  4068. if (IS_ERR_OR_NULL(debugfs_create_file("calibrate", 0600,
  4069. dad->mfg_test_dentry, dad, &calibrate_debugfs_fops))) {
  4070. dev_err(dev, "%s: Error, could not create calibrate\n",
  4071. __func__);
  4072. goto unregister_base_dir;
  4073. }
  4074. if (IS_ERR_OR_NULL(debugfs_create_file("baseline", 0600,
  4075. dad->mfg_test_dentry, dad, &baseline_debugfs_fops))) {
  4076. dev_err(dev, "%s: Error, could not create baseline\n",
  4077. __func__);
  4078. goto unregister_base_dir;
  4079. }
  4080. if (IS_ERR_OR_NULL(debugfs_create_file("cm_panel", 0400,
  4081. dad->mfg_test_dentry, dad, &cm_panel_debugfs_fops))) {
  4082. dev_err(dev, "%s: Error, could not create cm_panel\n",
  4083. __func__);
  4084. goto unregister_base_dir;
  4085. }
  4086. if (IS_ERR_OR_NULL(debugfs_create_file("cp_panel", 0400,
  4087. dad->mfg_test_dentry, dad, &cp_panel_debugfs_fops))) {
  4088. dev_err(dev, "%s: Error, could not create cp_panel\n",
  4089. __func__);
  4090. goto unregister_base_dir;
  4091. }
  4092. if (IS_ERR_OR_NULL(debugfs_create_file("cm_button", 0400,
  4093. dad->mfg_test_dentry, dad, &cm_button_debugfs_fops))) {
  4094. dev_err(dev, "%s: Error, could not create cm_button\n",
  4095. __func__);
  4096. goto unregister_base_dir;
  4097. }
  4098. if (IS_ERR_OR_NULL(debugfs_create_file("cp_button", 0400,
  4099. dad->mfg_test_dentry, dad, &cp_button_debugfs_fops))) {
  4100. dev_err(dev, "%s: Error, could not create cp_button\n",
  4101. __func__);
  4102. goto unregister_base_dir;
  4103. }
  4104. dad->cmcp_results_debugfs = debugfs_create_file("cmcp_results", 0644,
  4105. dad->mfg_test_dentry, dad, &cmcp_results_debugfs_fops);
  4106. if (IS_ERR_OR_NULL(dad->cmcp_results_debugfs)) {
  4107. dev_err(dev, "%s: Error, could not create cmcp_results\n",
  4108. __func__);
  4109. dad->cmcp_results_debugfs = NULL;
  4110. goto unregister_base_dir;
  4111. }
  4112. #ifdef TTHE_TUNER_SUPPORT
  4113. dad->tthe_get_panel_data_debugfs = debugfs_create_file(
  4114. CYTTSP5_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME,
  4115. 0644, NULL, dad, &tthe_get_panel_data_fops);
  4116. if (IS_ERR_OR_NULL(dad->tthe_get_panel_data_debugfs)) {
  4117. dev_err(dev, "%s: Error, could not create get_panel_data\n",
  4118. __func__);
  4119. dad->tthe_get_panel_data_debugfs = NULL;
  4120. goto unregister_base_dir;
  4121. }
  4122. #endif
  4123. rc = device_create_file(dev, &dev_attr_cmcp_test);
  4124. if (rc) {
  4125. dev_err(dev, "%s: Error, could not create cmcp_test\n",
  4126. __func__);
  4127. goto unregister_base_dir;
  4128. }
  4129. rc = device_create_file(dev, &dev_attr_cmcp_threshold_loading);
  4130. if (rc) {
  4131. dev_err(dev, "%s: Error, could not create cmcp_thresold_loading\n",
  4132. __func__);
  4133. goto unregister_cmcp_test;
  4134. }
  4135. rc = device_create_bin_file(dev, &bin_attr_cmcp_threshold_data);
  4136. if (rc) {
  4137. dev_err(dev, "%s: Error, could not create cmcp_thresold_data\n",
  4138. __func__);
  4139. goto unregister_cmcp_thresold_loading;
  4140. }
  4141. dad->sysfs_nodes_created = true;
  4142. return rc;
  4143. unregister_cmcp_thresold_loading:
  4144. device_remove_file(dev, &dev_attr_cmcp_threshold_loading);
  4145. unregister_cmcp_test:
  4146. device_remove_file(dev, &dev_attr_cmcp_test);
  4147. unregister_base_dir:
  4148. debugfs_remove_recursive(dad->base_dentry);
  4149. unregister_response:
  4150. device_remove_file(dev, &dev_attr_response);
  4151. unregister_status:
  4152. device_remove_file(dev, &dev_attr_status);
  4153. unregister_command:
  4154. device_remove_file(dev, &dev_attr_command);
  4155. exit:
  4156. return rc;
  4157. }
  4158. static int cyttsp5_setup_sysfs_attention(struct device *dev)
  4159. {
  4160. struct cyttsp5_device_access_data *dad
  4161. = cyttsp5_get_device_access_data(dev);
  4162. int rc = 0;
  4163. dad->si = cmd->request_sysinfo(dev);
  4164. if (!dad->si)
  4165. return -EINVAL;
  4166. rc = cyttsp5_setup_sysfs(dev);
  4167. cmd->unsubscribe_attention(dev, CY_ATTEN_STARTUP,
  4168. CYTTSP5_DEVICE_ACCESS_NAME, cyttsp5_setup_sysfs_attention,
  4169. 0);
  4170. return rc;
  4171. }
  4172. #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICE_ACCESS_API
  4173. int cyttsp5_device_access_user_command(const char *core_name, u16 read_len,
  4174. u8 *read_buf, u16 write_len, u8 *write_buf,
  4175. u16 *actual_read_len)
  4176. {
  4177. struct cyttsp5_core_data *cd;
  4178. int rc;
  4179. might_sleep();
  4180. /* Check parameters */
  4181. if (!read_buf || !write_buf || !actual_read_len)
  4182. return -EINVAL;
  4183. if (!core_name)
  4184. core_name = CY_DEFAULT_CORE_ID;
  4185. /* Find device */
  4186. cd = cyttsp5_get_core_data((char *)core_name);
  4187. if (!cd) {
  4188. pr_err("%s: No device.\n", __func__);
  4189. return -ENODEV;
  4190. }
  4191. pm_runtime_get_sync(cd->dev);
  4192. rc = cmd->nonhid_cmd->user_cmd(cd->dev, 1, read_len, read_buf,
  4193. write_len, write_buf, actual_read_len);
  4194. pm_runtime_put(cd->dev);
  4195. return rc;
  4196. }
  4197. EXPORT_SYMBOL_GPL(cyttsp5_device_access_user_command);
  4198. struct command_work {
  4199. struct work_struct work;
  4200. const char *core_name;
  4201. u16 read_len;
  4202. u8 *read_buf;
  4203. u16 write_len;
  4204. u8 *write_buf;
  4205. void (*cont)(const char *core_name, u16 read_len, u8 *read_buf,
  4206. u16 write_len, u8 *write_buf, u16 actual_read_length,
  4207. int rc);
  4208. };
  4209. static void cyttsp5_device_access_user_command_work_func(
  4210. struct work_struct *work)
  4211. {
  4212. struct command_work *cmd_work =
  4213. container_of(work, struct command_work, work);
  4214. u16 actual_read_length;
  4215. int rc;
  4216. rc = cyttsp5_device_access_user_command(cmd_work->core_name,
  4217. cmd_work->read_len, cmd_work->read_buf,
  4218. cmd_work->write_len, cmd_work->write_buf,
  4219. &actual_read_length);
  4220. if (cmd_work->cont)
  4221. cmd_work->cont(cmd_work->core_name,
  4222. cmd_work->read_len, cmd_work->read_buf,
  4223. cmd_work->write_len, cmd_work->write_buf,
  4224. actual_read_length, rc);
  4225. kfree(cmd_work);
  4226. }
  4227. int cyttsp5_device_access_user_command_async(const char *core_name,
  4228. u16 read_len, u8 *read_buf, u16 write_len, u8 *write_buf,
  4229. void (*cont)(const char *core_name, u16 read_len, u8 *read_buf,
  4230. u16 write_len, u8 *write_buf, u16 actual_read_length,
  4231. int rc))
  4232. {
  4233. struct command_work *cmd_work;
  4234. cmd_work = kzalloc(sizeof(*cmd_work), GFP_ATOMIC);
  4235. if (!cmd_work)
  4236. return -ENOMEM;
  4237. cmd_work->core_name = core_name;
  4238. cmd_work->read_len = read_len;
  4239. cmd_work->read_buf = read_buf;
  4240. cmd_work->write_len = write_len;
  4241. cmd_work->write_buf = write_buf;
  4242. cmd_work->cont = cont;
  4243. INIT_WORK(&cmd_work->work,
  4244. cyttsp5_device_access_user_command_work_func);
  4245. schedule_work(&cmd_work->work);
  4246. return 0;
  4247. }
  4248. EXPORT_SYMBOL_GPL(cyttsp5_device_access_user_command_async);
  4249. #endif
  4250. static void cyttsp5_cmcp_parse_threshold_file(const struct firmware *fw,
  4251. void *context)
  4252. {
  4253. struct device *dev = context;
  4254. struct cyttsp5_device_access_data *dad =
  4255. cyttsp5_get_device_access_data(dev);
  4256. if (!fw) {
  4257. dev_info(dev, "%s: No builtin cmcp threshold file\n", __func__);
  4258. goto exit;
  4259. }
  4260. if (!fw->data || !fw->size) {
  4261. dev_err(dev, "%s: Invalid builtin cmcp threshold file\n",
  4262. __func__);
  4263. goto exit;
  4264. }
  4265. parade_debug(dev, DEBUG_LEVEL_1, "%s: Found cmcp threshold file.\n",
  4266. __func__);
  4267. cyttsp5_parse_cmcp_threshold_file_common(dev, &fw->data[0], fw->size);
  4268. dad->builtin_cmcp_threshold_status = 0;
  4269. complete(&dad->builtin_cmcp_threshold_complete);
  4270. return;
  4271. exit:
  4272. release_firmware(fw);
  4273. dad->builtin_cmcp_threshold_status = -EINVAL;
  4274. complete(&dad->builtin_cmcp_threshold_complete);
  4275. }
  4276. static void cyttsp5_parse_cmcp_threshold_builtin(
  4277. struct work_struct *cmcp_threshold_update)
  4278. {
  4279. struct cyttsp5_device_access_data *dad =
  4280. container_of(cmcp_threshold_update,
  4281. struct cyttsp5_device_access_data,
  4282. cmcp_threshold_update);
  4283. struct device *dev = dad->dev;
  4284. int retval;
  4285. dad->si = cmd->request_sysinfo(dev);
  4286. if (!dad->si) {
  4287. dev_err(dev, "%s: Fail get sysinfo pointer from core\n",
  4288. __func__);
  4289. return;
  4290. }
  4291. parade_debug(dev, DEBUG_LEVEL_2,
  4292. "%s: Enabling cmcp threshold class loader built-in\n",
  4293. __func__);
  4294. /* Open threshold file */
  4295. retval = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
  4296. CMCP_THRESHOLD_FILE_NAME, dev, GFP_KERNEL, dev,
  4297. cyttsp5_cmcp_parse_threshold_file);
  4298. if (retval < 0) {
  4299. dev_err(dev, "%s: Failed loading cmcp threshold file, attempting legacy file\n",
  4300. __func__);
  4301. /* Try legacy file name */
  4302. retval = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
  4303. CY_CMCP_THRESHOLD_FILE_NAME, dev, GFP_KERNEL,
  4304. dev, cyttsp5_cmcp_parse_threshold_file);
  4305. if (retval < 0) {
  4306. dev_err(dev, "%s: Fail request cmcp threshold class file load\n",
  4307. __func__);
  4308. goto exit;
  4309. }
  4310. }
  4311. /* wait until cmcp threshold upgrade finishes */
  4312. wait_for_completion(&dad->builtin_cmcp_threshold_complete);
  4313. retval = dad->builtin_cmcp_threshold_status;
  4314. exit:
  4315. return;
  4316. }
  4317. static int cyttsp5_device_access_probe(struct device *dev, void **data)
  4318. {
  4319. struct cyttsp5_device_access_data *dad;
  4320. struct configuration *configurations;
  4321. struct cmcp_data *cmcp_info;
  4322. struct result *result;
  4323. int tx_num = MAX_TX_SENSORS;
  4324. int rx_num = MAX_RX_SENSORS;
  4325. int btn_num = MAX_BUTTONS;
  4326. struct test_case_field *test_case_field_array;
  4327. struct test_case_search *test_case_search_array;
  4328. int rc = 0;
  4329. dad = kzalloc(sizeof(*dad), GFP_KERNEL);
  4330. if (!dad) {
  4331. rc = -ENOMEM;
  4332. goto cyttsp5_device_access_probe_data_failed;
  4333. }
  4334. configurations =
  4335. kzalloc(sizeof(*configurations), GFP_KERNEL);
  4336. if (!configurations) {
  4337. rc = -ENOMEM;
  4338. goto cyttsp5_device_access_probe_configs_failed;
  4339. }
  4340. dad->configs = configurations;
  4341. cmcp_info = kzalloc(sizeof(*cmcp_info), GFP_KERNEL);
  4342. if (!cmcp_info) {
  4343. rc = -ENOMEM;
  4344. goto cyttsp5_device_access_probe_cmcp_info_failed;
  4345. }
  4346. dad->cmcp_info = cmcp_info;
  4347. cmcp_info->tx_num = tx_num;
  4348. cmcp_info->rx_num = rx_num;
  4349. cmcp_info->btn_num = btn_num;
  4350. result = kzalloc(sizeof(*result), GFP_KERNEL);
  4351. if (!result) {
  4352. rc = -ENOMEM;
  4353. goto cyttsp5_device_access_probe_result_failed;
  4354. }
  4355. dad->result = result;
  4356. test_case_field_array =
  4357. kzalloc(sizeof(*test_case_field_array) * MAX_CASE_NUM,
  4358. GFP_KERNEL);
  4359. if (!test_case_field_array) {
  4360. rc = -ENOMEM;
  4361. goto cyttsp5_device_access_probe_field_array_failed;
  4362. }
  4363. test_case_search_array =
  4364. kzalloc(sizeof(*test_case_search_array) * MAX_CASE_NUM,
  4365. GFP_KERNEL);
  4366. if (!test_case_search_array) {
  4367. rc = -ENOMEM;
  4368. goto cyttsp5_device_access_probe_search_array_failed;
  4369. }
  4370. cmcp_info->gd_sensor_col = (struct gd_sensor *)
  4371. kzalloc(tx_num * sizeof(struct gd_sensor), GFP_KERNEL);
  4372. if (cmcp_info->gd_sensor_col == NULL)
  4373. goto cyttsp5_device_access_probe_gd_sensor_col_failed;
  4374. cmcp_info->gd_sensor_row = (struct gd_sensor *)
  4375. kzalloc(rx_num * sizeof(struct gd_sensor), GFP_KERNEL);
  4376. if (cmcp_info->gd_sensor_row == NULL)
  4377. goto cyttsp5_device_access_probe_gd_sensor_row_failed;
  4378. cmcp_info->cm_data_panel =
  4379. kzalloc((tx_num * rx_num + 1) * sizeof(int32_t), GFP_KERNEL);
  4380. if (cmcp_info->cm_data_panel == NULL)
  4381. goto cyttsp5_device_access_probe_cm_data_panel_failed;
  4382. cmcp_info->cp_tx_data_panel =
  4383. kzalloc(tx_num * sizeof(int32_t), GFP_KERNEL);
  4384. if (cmcp_info->cp_tx_data_panel == NULL)
  4385. goto cyttsp5_device_access_probe_cp_tx_data_panel_failed;
  4386. cmcp_info->cp_tx_cal_data_panel =
  4387. kzalloc(tx_num * sizeof(int32_t), GFP_KERNEL);
  4388. if (cmcp_info->cp_tx_cal_data_panel == NULL)
  4389. goto cyttsp5_device_access_probe_cp_tx_cal_data_panel_failed;
  4390. cmcp_info->cp_rx_data_panel =
  4391. kzalloc(rx_num * sizeof(int32_t), GFP_KERNEL);
  4392. if (cmcp_info->cp_rx_data_panel == NULL)
  4393. goto cyttsp5_device_access_probe_cp_rx_data_panel_failed;
  4394. cmcp_info->cp_rx_cal_data_panel =
  4395. kzalloc(rx_num * sizeof(int32_t), GFP_KERNEL);
  4396. if (cmcp_info->cp_rx_cal_data_panel == NULL)
  4397. goto cyttsp5_device_access_probe_cp_rx_cal_data_panel_failed;
  4398. cmcp_info->cm_btn_data = kcalloc(btn_num, sizeof(int32_t), GFP_KERNEL);
  4399. if (cmcp_info->cm_btn_data == NULL)
  4400. goto cyttsp5_device_access_probe_cm_btn_data_failed;
  4401. cmcp_info->cp_btn_data = kcalloc(btn_num, sizeof(int32_t), GFP_KERNEL);
  4402. if (cmcp_info->cp_btn_data == NULL)
  4403. goto cyttsp5_device_access_probe_cp_btn_data_failed;
  4404. cmcp_info->cm_sensor_column_delta =
  4405. kzalloc(rx_num * tx_num * sizeof(int32_t), GFP_KERNEL);
  4406. if (cmcp_info->cm_sensor_column_delta == NULL)
  4407. goto cyttsp5_device_access_probe_cm_sensor_column_delta_failed;
  4408. cmcp_info->cm_sensor_row_delta =
  4409. kzalloc(tx_num * rx_num * sizeof(int32_t), GFP_KERNEL);
  4410. if (cmcp_info->cm_sensor_row_delta == NULL)
  4411. goto cyttsp5_device_access_probe_cm_sensor_row_delta_failed;
  4412. mutex_init(&dad->sysfs_lock);
  4413. mutex_init(&dad->cmcp_threshold_lock);
  4414. dad->dev = dev;
  4415. #ifdef TTHE_TUNER_SUPPORT
  4416. mutex_init(&dad->debugfs_lock);
  4417. dad->heatmap.num_element = 200;
  4418. #endif
  4419. *data = dad;
  4420. dad->test_field_array = test_case_field_array;
  4421. dad->test_search_array = test_case_search_array;
  4422. dad->test_executed = 0;
  4423. init_completion(&dad->builtin_cmcp_threshold_complete);
  4424. /* get sysinfo */
  4425. dad->si = cmd->request_sysinfo(dev);
  4426. if (dad->si) {
  4427. rc = cyttsp5_setup_sysfs(dev);
  4428. if (rc)
  4429. goto cyttsp5_device_access_setup_sysfs_failed;
  4430. } else {
  4431. dev_err(dev, "%s: Fail get sysinfo pointer from core p=%p\n",
  4432. __func__, dad->si);
  4433. cmd->subscribe_attention(dev, CY_ATTEN_STARTUP,
  4434. CYTTSP5_DEVICE_ACCESS_NAME,
  4435. cyttsp5_setup_sysfs_attention, 0);
  4436. }
  4437. INIT_WORK(&dad->cmcp_threshold_update,
  4438. cyttsp5_parse_cmcp_threshold_builtin);
  4439. schedule_work(&dad->cmcp_threshold_update);
  4440. return 0;
  4441. cyttsp5_device_access_setup_sysfs_failed:
  4442. kfree(cmcp_info->cm_sensor_row_delta);
  4443. cyttsp5_device_access_probe_cm_sensor_row_delta_failed:
  4444. kfree(cmcp_info->cm_sensor_column_delta);
  4445. cyttsp5_device_access_probe_cm_sensor_column_delta_failed:
  4446. kfree(cmcp_info->cp_btn_data);
  4447. cyttsp5_device_access_probe_cp_btn_data_failed:
  4448. kfree(cmcp_info->cm_btn_data);
  4449. cyttsp5_device_access_probe_cm_btn_data_failed:
  4450. kfree(cmcp_info->cp_rx_cal_data_panel);
  4451. cyttsp5_device_access_probe_cp_rx_cal_data_panel_failed:
  4452. kfree(cmcp_info->cp_rx_data_panel);
  4453. cyttsp5_device_access_probe_cp_rx_data_panel_failed:
  4454. kfree(cmcp_info->cp_tx_cal_data_panel);
  4455. cyttsp5_device_access_probe_cp_tx_cal_data_panel_failed:
  4456. kfree(cmcp_info->cp_tx_data_panel);
  4457. cyttsp5_device_access_probe_cp_tx_data_panel_failed:
  4458. kfree(cmcp_info->cm_data_panel);
  4459. cyttsp5_device_access_probe_cm_data_panel_failed:
  4460. kfree(cmcp_info->gd_sensor_row);
  4461. cyttsp5_device_access_probe_gd_sensor_row_failed:
  4462. kfree(cmcp_info->gd_sensor_col);
  4463. cyttsp5_device_access_probe_gd_sensor_col_failed:
  4464. kfree(test_case_search_array);
  4465. cyttsp5_device_access_probe_search_array_failed:
  4466. kfree(test_case_field_array);
  4467. cyttsp5_device_access_probe_field_array_failed:
  4468. kfree(result);
  4469. cyttsp5_device_access_probe_result_failed:
  4470. kfree(cmcp_info);
  4471. cyttsp5_device_access_probe_cmcp_info_failed:
  4472. kfree(configurations);
  4473. cyttsp5_device_access_probe_configs_failed:
  4474. kfree(dad);
  4475. cyttsp5_device_access_probe_data_failed:
  4476. dev_err(dev, "%s failed.\n", __func__);
  4477. return rc;
  4478. }
  4479. static void cyttsp5_device_access_release(struct device *dev, void *data)
  4480. {
  4481. struct cyttsp5_device_access_data *dad = data;
  4482. if (dad->sysfs_nodes_created) {
  4483. device_remove_file(dev, &dev_attr_command);
  4484. device_remove_file(dev, &dev_attr_status);
  4485. device_remove_file(dev, &dev_attr_response);
  4486. debugfs_remove(dad->cmcp_results_debugfs);
  4487. debugfs_remove_recursive(dad->base_dentry);
  4488. #ifdef TTHE_TUNER_SUPPORT
  4489. debugfs_remove(dad->tthe_get_panel_data_debugfs);
  4490. #endif
  4491. device_remove_file(dev, &dev_attr_cmcp_test);
  4492. device_remove_file(dev, &dev_attr_cmcp_threshold_loading);
  4493. device_remove_bin_file(dev, &bin_attr_cmcp_threshold_data);
  4494. kfree(dad->cmcp_threshold_data);
  4495. } else {
  4496. cmd->unsubscribe_attention(dev, CY_ATTEN_STARTUP,
  4497. CYTTSP5_DEVICE_ACCESS_NAME,
  4498. cyttsp5_setup_sysfs_attention, 0);
  4499. }
  4500. kfree(dad->test_search_array);
  4501. kfree(dad->test_field_array);
  4502. kfree(dad->configs);
  4503. cyttsp5_free_cmcp_buf(dad->cmcp_info);
  4504. kfree(dad->cmcp_info);
  4505. kfree(dad->result);
  4506. kfree(dad);
  4507. }
  4508. static struct cyttsp5_module device_access_module = {
  4509. .name = CYTTSP5_DEVICE_ACCESS_NAME,
  4510. .probe = cyttsp5_device_access_probe,
  4511. .release = cyttsp5_device_access_release,
  4512. };
  4513. static int __init cyttsp5_device_access_init(void)
  4514. {
  4515. int rc;
  4516. cmd = cyttsp5_get_commands();
  4517. if (!cmd)
  4518. return -EINVAL;
  4519. rc = cyttsp5_register_module(&device_access_module);
  4520. if (rc < 0) {
  4521. pr_err("%s: Error, failed registering module\n",
  4522. __func__);
  4523. return rc;
  4524. }
  4525. pr_info("%s: Parade TTSP Device Access Driver (Built %s) rc=%d\n",
  4526. __func__, CY_DRIVER_VERSION, rc);
  4527. return 0;
  4528. }
  4529. module_init(cyttsp5_device_access_init);
  4530. static void __exit cyttsp5_device_access_exit(void)
  4531. {
  4532. cyttsp5_unregister_module(&device_access_module);
  4533. }
  4534. module_exit(cyttsp5_device_access_exit);
  4535. MODULE_LICENSE("GPL");
  4536. MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product Device Access Driver");
  4537. MODULE_AUTHOR("Parade Technologies <ttdrivers@paradetech.com>");