pt_device_access.c 197 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746
  1. /*
  2. * pt_device_access.c
  3. * Parade TrueTouch(TM) Standard Product Device Access Module.
  4. * Configuration and Test command/status user interface.
  5. * For use with Parade touchscreen controllers.
  6. * Supported parts include:
  7. * TMA5XX
  8. * TMA448
  9. * TMA445A
  10. * TT21XXX
  11. * TT31XXX
  12. * TT4XXXX
  13. * TT7XXX
  14. * TC3XXX
  15. *
  16. * Copyright (C) 2015-2020 Parade Technologies
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License
  20. * version 2, and only version 2, as published by the
  21. * Free Software Foundation.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details.
  27. *
  28. * Contact Parade Technologies at www.paradetech.com <[email protected]>
  29. */
  30. #include "pt_regs.h"
  31. #include <linux/firmware.h>
  32. #include <linux/timer.h>
  33. #include <linux/timex.h>
  34. #include <linux/rtc.h>
  35. #define PT_CMCP_THRESHOLD_FILE_NAME "pt_thresholdfile.csv"
  36. #define CMCP_THRESHOLD_FILE_NAME "ttdl_cmcp_thresholdfile.csv"
  37. /* Max test case number */
  38. #define MAX_CASE_NUM (22)
  39. /* ASCII */
  40. #define ASCII_LF (0x0A)
  41. #define ASCII_CR (0x0D)
  42. #define ASCII_COMMA (0x2C)
  43. #define ASCII_ZERO (0x30)
  44. #define ASCII_NINE (0x39)
  45. /* Max characters of test case name */
  46. #define NAME_SIZE_MAX (50)
  47. /* Max sensor and button number */
  48. #define MAX_BUTTONS (PIP1_SYSINFO_MAX_BTN)
  49. #define MAX_SENSORS (5120)
  50. #define MAX_TX_SENSORS (128)
  51. #define MAX_RX_SENSORS (128)
  52. /* Multiply by 2 for double (min, max) values */
  53. #define TABLE_BUTTON_MAX_SIZE (MAX_BUTTONS * 2)
  54. #define TABLE_SENSOR_MAX_SIZE (MAX_SENSORS * 2)
  55. #define TABLE_TX_MAX_SIZE (MAX_TX_SENSORS*2)
  56. #define TABLE_RX_MAX_SIZE (MAX_RX_SENSORS*2)
  57. #define CM_PANEL_DATA_OFFSET (6)
  58. #define CM_BTN_DATA_OFFSET (6)
  59. #define CP_PANEL_DATA_OFFSET (6)
  60. #define CP_BTN_DATA_OFFSET (6)
  61. #define MAX_BUF_LEN (100000)
  62. #define RETRIEVE_PANEL_SCAN_HDR (10)
  63. enum print_buffer_format {
  64. PT_PR_FORMAT_DEFAULT = 0,
  65. PT_PR_FORMAT_U8_SPACE = 1,
  66. PT_PR_FORMAT_U16_SPACE = 2,
  67. PT_PR_FORMAT_U8_NO_SPACE = 3,
  68. PT_PR_FORMAT_U32_SPACE = 4,
  69. PT_PR_FORMAT_UNDEFINE
  70. };
  71. /* cmcp csv file information */
  72. struct configuration {
  73. u32 cm_range_limit_row;
  74. u32 cm_range_limit_col;
  75. u32 cm_min_limit_cal;
  76. u32 cm_max_limit_cal;
  77. u32 cm_max_delta_sensor_percent;
  78. u32 cm_max_delta_button_percent;
  79. u32 min_button;
  80. u32 max_button;
  81. u32 cp_max_delta_sensor_rx_percent;
  82. u32 cp_max_delta_sensor_tx_percent;
  83. u32 cm_min_max_table_btn[TABLE_BUTTON_MAX_SIZE];
  84. u32 cp_min_max_table_btn[TABLE_BUTTON_MAX_SIZE];
  85. u32 cm_min_max_table_sensor[TABLE_SENSOR_MAX_SIZE];
  86. u32 cp_min_max_table_rx[TABLE_RX_MAX_SIZE];
  87. u32 cp_min_max_table_tx[TABLE_TX_MAX_SIZE];
  88. u32 cm_min_max_table_btn_size;
  89. u32 cp_min_max_table_btn_size;
  90. u32 cm_min_max_table_sensor_size;
  91. u32 cp_min_max_table_rx_size;
  92. u32 cp_min_max_table_tx_size;
  93. u32 cp_max_delta_button_percent;
  94. u32 cm_max_table_gradient_cols_percent[TABLE_TX_MAX_SIZE];
  95. u32 cm_max_table_gradient_cols_percent_size;
  96. u32 cm_max_table_gradient_rows_percent[TABLE_RX_MAX_SIZE];
  97. u32 cm_max_table_gradient_rows_percent_size;
  98. u32 cm_excluding_row_edge;
  99. u32 cm_excluding_col_edge;
  100. u32 rx_num;
  101. u32 tx_num;
  102. u32 btn_num;
  103. u32 cm_enabled;
  104. u32 cp_enabled;
  105. u32 is_valid_or_not;
  106. };
  107. /* Test case search definition */
  108. struct test_case_search {
  109. char name[NAME_SIZE_MAX]; /* Test case name */
  110. u32 name_size; /* Test case name size */
  111. u32 offset; /* Test case offset */
  112. };
  113. /* Test case field definition */
  114. struct test_case_field {
  115. char *name; /* Test case name */
  116. u32 name_size; /* Test case name size */
  117. u32 type; /* Test case type */
  118. u32 *bufptr; /* Buffer to store value information */
  119. u32 exist_or_not;/* Test case exist or not */
  120. u32 data_num; /* Buffer data number */
  121. u32 line_num; /* Buffer line number */
  122. };
  123. /* Test case type */
  124. enum test_case_type {
  125. TEST_CASE_TYPE_NO,
  126. TEST_CASE_TYPE_ONE,
  127. TEST_CASE_TYPE_MUL,
  128. TEST_CASE_TYPE_MUL_LINES,
  129. };
  130. /* Test case order in test_case_field_array */
  131. enum case_order {
  132. CM_TEST_INPUTS,
  133. CM_EXCLUDING_COL_EDGE,
  134. CM_EXCLUDING_ROW_EDGE,
  135. CM_GRADIENT_CHECK_COL,
  136. CM_GRADIENT_CHECK_ROW,
  137. CM_RANGE_LIMIT_ROW,
  138. CM_RANGE_LIMIT_COL,
  139. CM_MIN_LIMIT_CAL,
  140. CM_MAX_LIMIT_CAL,
  141. CM_MAX_DELTA_SENSOR_PERCENT,
  142. CM_MAX_DELTA_BUTTON_PERCENT,
  143. PER_ELEMENT_MIN_MAX_TABLE_BUTTON,
  144. PER_ELEMENT_MIN_MAX_TABLE_SENSOR,
  145. CP_TEST_INPUTS,
  146. CP_MAX_DELTA_SENSOR_RX_PERCENT,
  147. CP_MAX_DELTA_SENSOR_TX_PERCENT,
  148. CP_MAX_DELTA_BUTTON_PERCENT,
  149. CP_PER_ELEMENT_MIN_MAX_BUTTON,
  150. MIN_BUTTON,
  151. MAX_BUTTON,
  152. PER_ELEMENT_MIN_MAX_RX,
  153. PER_ELEMENT_MIN_MAX_TX,
  154. CASE_ORDER_MAX,
  155. };
  156. enum cmcp_test_item {
  157. CMCP_FULL = 0,
  158. CMCP_CM_PANEL,
  159. CMCP_CP_PANEL,
  160. CMCP_CM_BTN,
  161. CMCP_CP_BTN,
  162. };
  163. #define CM_ENABLED 0x10
  164. #define CP_ENABLED 0x20
  165. #define CM_PANEL (0x01 | CM_ENABLED)
  166. #define CP_PANEL (0x02 | CP_ENABLED)
  167. #define CM_BTN (0x04 | CM_ENABLED)
  168. #define CP_BTN (0x08 | CP_ENABLED)
  169. #define CMCP_FULL_CASE\
  170. (CM_PANEL | CP_PANEL | CM_BTN | CP_BTN | CM_ENABLED | CP_ENABLED)
  171. #define PT_DEVICE_ACCESS_NAME "pt_device_access"
  172. #define PT_INPUT_ELEM_SZ (sizeof("0xHH") + 1)
  173. #define PIP_CMD_MAX_LENGTH ((1 << 16) - 1)
  174. #ifdef TTHE_TUNER_SUPPORT
  175. struct heatmap_param {
  176. bool scan_start;
  177. enum scan_data_type_list data_type; /* raw, base, diff */
  178. int num_element;
  179. };
  180. #endif
  181. #define ABS(x) (((x) < 0) ? -(x) : (x))
  182. #ifndef MIN
  183. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  184. #endif
  185. #define PT_MAX_CONFIG_BYTES 256
  186. #define PT_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME "get_panel_data"
  187. #define TTHE_TUNER_MAX_BUF (PT_MAX_PRBUF_SIZE * 8)
  188. struct pt_device_access_data {
  189. struct device *dev;
  190. struct pt_sysinfo *si;
  191. struct mutex sysfs_lock;
  192. bool sysfs_nodes_created;
  193. struct kobject mfg_test;
  194. u8 panel_scan_retrieve_id;
  195. u8 panel_scan_type_id;
  196. u8 get_idac_data_id;
  197. u8 calibrate_sensing_mode;
  198. u8 calibrate_initialize_baselines;
  199. u8 baseline_sensing_mode;
  200. u8 fw_self_test_id;
  201. u8 fw_self_test_format;
  202. u16 fw_self_test_param_len;
  203. u8 fw_self_test_param[PT_FW_SELF_TEST_MAX_PARM];
  204. struct pt_cal_ext_data cal_ext_data;
  205. struct dentry *panel_scan_debugfs;
  206. int panel_scan_size;
  207. u8 panel_scan_data_buf[TTHE_TUNER_MAX_BUF];
  208. struct mutex debugfs_lock;
  209. #ifdef TTHE_TUNER_SUPPORT
  210. struct heatmap_param heatmap;
  211. struct dentry *tthe_get_panel_data_debugfs;
  212. u8 tthe_get_panel_data_is_open;
  213. #endif
  214. struct dentry *cmcp_results_debugfs;
  215. struct dentry *base_dentry;
  216. struct dentry *mfg_test_dentry;
  217. u8 ic_buf[PT_MAX_PRBUF_SIZE];
  218. u8 response_buf[PT_MAX_PRBUF_SIZE];
  219. struct mutex cmcp_threshold_lock;
  220. u8 *cmcp_threshold_data;
  221. int cmcp_threshold_size;
  222. bool cmcp_threshold_loading;
  223. struct work_struct cmcp_threshold_update;
  224. int builtin_cmcp_threshold_status;
  225. bool is_manual_upgrade_enabled;
  226. struct configuration *configs;
  227. struct cmcp_data *cmcp_info;
  228. struct result *result;
  229. struct test_case_search *test_search_array;
  230. struct test_case_field *test_field_array;
  231. int cmcp_test_items;
  232. int test_executed;
  233. int cmcp_range_check;
  234. int cmcp_force_calibrate;
  235. int cmcp_test_in_progress;
  236. };
  237. struct cmcp_data {
  238. struct gd_sensor *gd_sensor_col;
  239. struct gd_sensor *gd_sensor_row;
  240. int32_t *cm_data_panel;
  241. int32_t *cp_tx_data_panel;
  242. int32_t *cp_rx_data_panel;
  243. int32_t *cp_tx_cal_data_panel;
  244. int32_t *cp_rx_cal_data_panel;
  245. int32_t cp_sensor_rx_delta;
  246. int32_t cp_sensor_tx_delta;
  247. int32_t cp_button_delta;
  248. int32_t *cm_btn_data;
  249. int32_t *cp_btn_data;
  250. int32_t *cm_sensor_column_delta;
  251. int32_t *cm_sensor_row_delta;
  252. int32_t cp_btn_cal;
  253. int32_t cm_btn_cal;
  254. int32_t cp_button_ave;
  255. int32_t cm_ave_data_panel;
  256. int32_t cp_tx_ave_data_panel;
  257. int32_t cp_rx_ave_data_panel;
  258. int32_t cm_cal_data_panel;
  259. int32_t cm_ave_data_btn;
  260. int32_t cm_cal_data_btn;
  261. int32_t cm_delta_data_btn;
  262. int32_t cm_sensor_delta;
  263. int32_t tx_num;
  264. int32_t rx_num;
  265. int32_t btn_num;
  266. };
  267. struct result {
  268. int32_t config_ver;
  269. int32_t revision_ctrl;
  270. int32_t device_id_high;
  271. int32_t device_id_low;
  272. /* Sensor Cm validation */
  273. bool cm_test_pass;
  274. bool cm_sensor_validation_pass;
  275. bool cm_sensor_row_delta_pass;
  276. bool cm_sensor_col_delta_pass;
  277. bool cm_sensor_gd_row_pass;
  278. bool cm_sensor_gd_col_pass;
  279. bool cm_sensor_calibration_pass;
  280. bool cm_sensor_delta_pass;
  281. bool cm_button_validation_pass;
  282. bool cm_button_delta_pass;
  283. int32_t *cm_sensor_raw_data;
  284. int32_t cm_sensor_calibration;
  285. int32_t cm_sensor_delta;
  286. int32_t *cm_button_raw_data;
  287. int32_t cm_button_delta;
  288. /* Sensor Cp validation */
  289. bool cp_test_pass;
  290. bool cp_sensor_delta_pass;
  291. bool cp_sensor_rx_delta_pass;
  292. bool cp_sensor_tx_delta_pass;
  293. bool cp_sensor_average_pass;
  294. bool cp_button_delta_pass;
  295. bool cp_button_average_pass;
  296. bool cp_rx_validation_pass;
  297. bool cp_tx_validation_pass;
  298. bool cp_button_validation_pass;
  299. int32_t *cp_sensor_rx_raw_data;
  300. int32_t *cp_sensor_tx_raw_data;
  301. int32_t cp_sensor_rx_delta;
  302. int32_t cp_sensor_tx_delta;
  303. int32_t cp_sensor_rx_calibration;
  304. int32_t cp_sensor_tx_calibration;
  305. int32_t *cp_button_raw_data;
  306. int32_t cp_button_delta;
  307. /*other validation*/
  308. bool short_test_pass;
  309. bool test_summary;
  310. };
  311. static struct pt_core_commands *cmd;
  312. static struct pt_module device_access_module;
  313. static ssize_t pt_run_and_get_selftest_result(struct device *dev,
  314. int protect, char *buf, size_t buf_len, u8 test_id,
  315. u16 read_length, bool get_result_on_pass,
  316. bool print_results, u8 print_format);
  317. static int _pt_calibrate_idacs_cmd(struct device *dev,
  318. u8 sensing_mode, u8 *status);
  319. static int pt_perform_calibration(struct device *dev);
  320. /*******************************************************************************
  321. * FUNCTION: pt_get_device_access_data
  322. *
  323. * SUMMARY: Inline function to get pt_device_access_data.
  324. *
  325. * RETURN:
  326. * pointer to pt_device_access_data structure
  327. *
  328. * PARAMETERS:
  329. * *dev - pointer to device structure
  330. ******************************************************************************/
  331. static inline struct pt_device_access_data *pt_get_device_access_data(
  332. struct device *dev)
  333. {
  334. return pt_get_module_data(dev, &device_access_module);
  335. }
  336. /*******************************************************************************
  337. * FUNCTION: cmcp_check_config_fw_match
  338. *
  339. * SUMMARY: Checks if tx,rx and btn num of firmware match with configuration.
  340. *
  341. * RETURN:
  342. * 0 = match
  343. * !0 = doesn't match
  344. *
  345. * PARAMETERS:
  346. * *dev - pointer to device structure
  347. * *configuration - pointer to configuration structure
  348. ******************************************************************************/
  349. static int cmcp_check_config_fw_match(struct device *dev,
  350. struct configuration *configuration)
  351. {
  352. struct pt_device_access_data *dad
  353. = pt_get_device_access_data(dev);
  354. int32_t tx_num = dad->configs->tx_num;
  355. int32_t rx_num = dad->configs->rx_num;
  356. int32_t button_num = dad->configs->btn_num;
  357. int ret = 0;
  358. if (tx_num != dad->si->sensing_conf_data.tx_num) {
  359. pt_debug(dev, DL_ERROR,
  360. "%s: TX number mismatch! CSV=%d DUT=%d\n",
  361. __func__, tx_num, dad->si->sensing_conf_data.tx_num);
  362. ret = -EINVAL;
  363. }
  364. if (rx_num != dad->si->sensing_conf_data.rx_num) {
  365. pt_debug(dev, DL_ERROR,
  366. "%s: RX number mismatch! CSV=%d DUT=%d\n",
  367. __func__, rx_num, dad->si->sensing_conf_data.rx_num);
  368. ret = -EINVAL;
  369. }
  370. if (button_num != dad->si->num_btns) {
  371. pt_debug(dev, DL_ERROR,
  372. "%s: Button number mismatch! CSV=%d DUT=%d\n",
  373. __func__, button_num, dad->si->num_btns);
  374. ret = -EINVAL;
  375. }
  376. return ret;
  377. }
  378. /*******************************************************************************
  379. * FUNCTION: validate_cm_test_results
  380. *
  381. * SUMMARY: Checks cm test results and outputs each test and a summary result
  382. *
  383. * RETURN:
  384. * 0 = success
  385. * !0 = failure
  386. *
  387. * PARAMETERS:
  388. * *dev - pointer to device structure
  389. * *configuration - pointer to configuration structure
  390. * *cmcp_info - pointer to cmcp_data structure to store cmcp data from fw
  391. * *result - pointer to result structure
  392. * *pass - pointer to bool value
  393. * test_item - flag to store all test item are requested
  394. ******************************************************************************/
  395. static int validate_cm_test_results(struct device *dev,
  396. struct configuration *configuration, struct cmcp_data *cmcp_info,
  397. struct result *result, bool *pass, int test_item)
  398. {
  399. int32_t tx_num = cmcp_info->tx_num;
  400. int32_t rx_num = cmcp_info->rx_num;
  401. int32_t button_num = cmcp_info->btn_num;
  402. uint32_t sensor_num = tx_num * rx_num;
  403. int32_t *cm_sensor_data = cmcp_info->cm_data_panel;
  404. int32_t cm_button_delta;
  405. int32_t cm_sensor_calibration;
  406. int32_t *cm_button_data = cmcp_info->cm_btn_data;
  407. struct gd_sensor *gd_sensor_col = cmcp_info->gd_sensor_col;
  408. struct gd_sensor *gd_sensor_row = cmcp_info->gd_sensor_row;
  409. int32_t *cm_sensor_column_delta = cmcp_info->cm_sensor_column_delta;
  410. int32_t *cm_sensor_row_delta = cmcp_info->cm_sensor_row_delta;
  411. int ret = 0;
  412. int i, j;
  413. pt_debug(dev, DL_INFO, "%s: start\n", __func__);
  414. if ((test_item & CM_PANEL) == CM_PANEL) {
  415. pt_debug(dev, DL_INFO,
  416. "Check each sensor Cm data for min max value\n ");
  417. /* Check each sensor Cm data for min/max values */
  418. result->cm_sensor_validation_pass = true;
  419. for (i = 0; i < sensor_num; i++) {
  420. int row = i % rx_num;
  421. int col = i / rx_num;
  422. int32_t cm_sensor_min =
  423. configuration->cm_min_max_table_sensor[(row*tx_num+col)*2];
  424. int32_t cm_sensor_max =
  425. configuration->cm_min_max_table_sensor[(row*tx_num+col)*2+1];
  426. if ((cm_sensor_data[i] < cm_sensor_min) ||
  427. (cm_sensor_data[i] > cm_sensor_max)) {
  428. pt_debug(dev, DL_WARN,
  429. "%s: Sensor[%d,%d]:%d (%d,%d)\n",
  430. "Cm sensor min/max test",
  431. row, col,
  432. cm_sensor_data[i],
  433. cm_sensor_min, cm_sensor_max);
  434. result->cm_sensor_validation_pass = false;
  435. }
  436. }
  437. /*check cm gradient column data*/
  438. result->cm_sensor_gd_col_pass = true;
  439. for (i = 0; i < configuration->cm_max_table_gradient_cols_percent_size;
  440. i++) {
  441. if ((gd_sensor_col + i)->gradient_val >
  442. 10 * configuration->cm_max_table_gradient_cols_percent[i]) {
  443. pt_debug(dev, DL_WARN,
  444. "%s: cm_max_table_gradient_cols_percent[%d]:%d, gradient_val:%d\n",
  445. __func__, i,
  446. configuration->cm_max_table_gradient_cols_percent[i],
  447. (gd_sensor_col + i)->gradient_val);
  448. result->cm_sensor_gd_col_pass = false;
  449. }
  450. }
  451. /*check cm gradient row data*/
  452. result->cm_sensor_gd_row_pass = true;
  453. for (j = 0; j < configuration->cm_max_table_gradient_rows_percent_size;
  454. j++) {
  455. if ((gd_sensor_row + j)->gradient_val >
  456. 10 * configuration->cm_max_table_gradient_rows_percent[j]) {
  457. pt_debug(dev, DL_WARN,
  458. "%s: cm_max_table_gradient_rows_percent[%d]:%d, gradient_val:%d\n",
  459. __func__, j,
  460. configuration->cm_max_table_gradient_rows_percent[j],
  461. (gd_sensor_row + j)->gradient_val);
  462. result->cm_sensor_gd_row_pass = false;
  463. }
  464. }
  465. result->cm_sensor_row_delta_pass = true;
  466. result->cm_sensor_col_delta_pass = true;
  467. result->cm_sensor_calibration_pass = true;
  468. result->cm_sensor_delta_pass = true;
  469. /* Check each row Cm data with neighbor for difference */
  470. for (i = 0; i < tx_num; i++) {
  471. for (j = 1; j < rx_num; j++) {
  472. int32_t cm_sensor_row_diff =
  473. ABS(cm_sensor_data[i * rx_num + j] -
  474. cm_sensor_data[i * rx_num + j - 1]);
  475. cm_sensor_row_delta[i * rx_num + j - 1] =
  476. cm_sensor_row_diff;
  477. if (cm_sensor_row_diff >
  478. configuration->cm_range_limit_row) {
  479. pt_debug(dev, DL_DEBUG,
  480. "%s: Sensor[%d,%d]:%d (%d)\n",
  481. "Cm sensor row range limit test",
  482. j, i, cm_sensor_row_diff,
  483. configuration->cm_range_limit_row);
  484. result->cm_sensor_row_delta_pass = false;
  485. }
  486. }
  487. }
  488. /* Check each column Cm data with neighbor for difference */
  489. for (i = 1; i < tx_num; i++) {
  490. for (j = 0; j < rx_num; j++) {
  491. int32_t cm_sensor_col_diff =
  492. ABS((int)cm_sensor_data[i * rx_num + j] -
  493. (int)cm_sensor_data[(i - 1) * rx_num + j]);
  494. cm_sensor_column_delta[(i - 1) * rx_num + j] =
  495. cm_sensor_col_diff;
  496. if (cm_sensor_col_diff >
  497. configuration->cm_range_limit_col) {
  498. pt_debug(dev, DL_DEBUG,
  499. "%s: Sensor[%d,%d]:%d (%d)\n",
  500. "Cm sensor column range limit test",
  501. j, i, cm_sensor_col_diff,
  502. configuration->cm_range_limit_col);
  503. result->cm_sensor_col_delta_pass = false;
  504. }
  505. }
  506. }
  507. /* Check sensor calculated Cm for min/max values */
  508. cm_sensor_calibration = cmcp_info->cm_cal_data_panel;
  509. if (cm_sensor_calibration <
  510. configuration->cm_min_limit_cal ||
  511. cm_sensor_calibration > configuration->cm_max_limit_cal) {
  512. pt_debug(dev, DL_DEBUG, "%s: Cm_cal:%d (%d,%d)\n",
  513. "Cm sensor Cm_cal min/max test",
  514. cm_sensor_calibration,
  515. configuration->cm_min_limit_cal,
  516. configuration->cm_max_limit_cal);
  517. result->cm_sensor_calibration_pass = false;
  518. }
  519. /* Check sensor Cm delta for range limit */
  520. if (cmcp_info->cm_sensor_delta >
  521. (10 * configuration->cm_max_delta_sensor_percent)) {
  522. pt_debug(dev, DL_DEBUG,
  523. "%s: Cm_sensor_delta:%d (%d)\n",
  524. "Cm sensor delta range limit test",
  525. cmcp_info->cm_sensor_delta,
  526. configuration->cm_max_delta_sensor_percent);
  527. result->cm_sensor_delta_pass = false;
  528. }
  529. result->cm_test_pass = result->cm_sensor_gd_col_pass
  530. && result->cm_sensor_gd_row_pass
  531. && result->cm_sensor_validation_pass
  532. && result->cm_sensor_row_delta_pass
  533. && result->cm_sensor_col_delta_pass
  534. && result->cm_sensor_calibration_pass
  535. && result->cm_sensor_delta_pass;
  536. }
  537. if (((test_item & CM_BTN) == CM_BTN) && (cmcp_info->btn_num)) {
  538. /* Check each button Cm data for min/max values */
  539. result->cm_button_validation_pass = true;
  540. for (i = 0; i < button_num; i++) {
  541. int32_t cm_button_min =
  542. configuration->cm_min_max_table_btn[i * 2];
  543. int32_t cm_button_max =
  544. configuration->cm_min_max_table_btn[i * 2 + 1];
  545. if ((cm_button_data[i] <= cm_button_min) ||
  546. (cm_button_data[i] >= cm_button_max)) {
  547. pt_debug(dev, DL_DEBUG,
  548. "%s: Button[%d]:%d (%d,%d)\n",
  549. "Cm button min/max test",
  550. i, cm_button_data[i],
  551. cm_button_min, cm_button_max);
  552. result->cm_button_validation_pass = false;
  553. }
  554. }
  555. /* Check button Cm delta for range limit */
  556. result->cm_button_delta_pass = true;
  557. cm_button_delta = ABS((cmcp_info->cm_ave_data_btn -
  558. cmcp_info->cm_cal_data_btn) * 100 /
  559. cmcp_info->cm_ave_data_btn);
  560. if (cm_button_delta >
  561. configuration->cm_max_delta_button_percent) {
  562. pt_debug(dev, DL_INFO,
  563. "%s: Cm_button_delta:%d (%d)\n",
  564. "Cm button delta range limit test",
  565. cm_button_delta,
  566. configuration->cm_max_delta_button_percent);
  567. result->cm_button_delta_pass = false;
  568. }
  569. result->cm_test_pass = result->cm_test_pass &&
  570. result->cm_button_validation_pass &&
  571. result->cm_button_delta_pass;
  572. }
  573. if (pass)
  574. *pass = result->cm_test_pass;
  575. return ret;
  576. }
  577. /*******************************************************************************
  578. * FUNCTION: validate_cp_test_results
  579. *
  580. * SUMMARY: Checks cp test results and outputs each test and a summary result.
  581. *
  582. * RETURN:
  583. * 0 = success
  584. * !0 = failure
  585. *
  586. * PARAMETERS:
  587. * *dev - pointer to device structure
  588. * *configuration - pointer to configuration structure
  589. * *cmcp_info - pointer to cmcp_data structure to store cmcp data from fw
  590. * *result - pointer to result structure
  591. * *pass - pointer to bool value
  592. * test_item - flag to store all test item are requested
  593. ******************************************************************************/
  594. static int validate_cp_test_results(struct device *dev,
  595. struct configuration *configuration, struct cmcp_data *cmcp_info,
  596. struct result *result, bool *pass, int test_item)
  597. {
  598. int i = 0;
  599. uint32_t configuration_rx_num;
  600. uint32_t configuration_tx_num;
  601. int32_t *cp_sensor_tx_data = cmcp_info->cp_tx_data_panel;
  602. int32_t *cp_sensor_rx_data = cmcp_info->cp_rx_data_panel;
  603. int32_t cp_button_delta;
  604. int32_t cp_button_average;
  605. result->cp_test_pass = true;
  606. configuration_rx_num = configuration->cp_min_max_table_rx_size/2;
  607. configuration_tx_num = configuration->cp_min_max_table_tx_size/2;
  608. pt_debug(dev, DL_INFO, "%s start\n", __func__);
  609. if ((test_item & CP_PANEL) == CP_PANEL) {
  610. int32_t cp_sensor_tx_delta;
  611. int32_t cp_sensor_rx_delta;
  612. /* Check Sensor Cp delta for range limit */
  613. result->cp_sensor_delta_pass = true;
  614. /*check cp_sensor_tx_delta */
  615. for (i = 0; i < configuration_tx_num; i++) {
  616. cp_sensor_tx_delta =
  617. ABS((cmcp_info->cp_tx_cal_data_panel[i]-
  618. cmcp_info->cp_tx_data_panel[i]) * 100 /
  619. cmcp_info->cp_tx_data_panel[i]);
  620. if (cp_sensor_tx_delta >
  621. configuration->cp_max_delta_sensor_tx_percent) {
  622. pt_debug(dev, DL_DEBUG,
  623. "%s: Cp_sensor_tx_delta:%d (%d)\n",
  624. "Cp sensor delta range limit test",
  625. cp_sensor_tx_delta,
  626. configuration->cp_max_delta_sensor_tx_percent);
  627. result->cp_sensor_delta_pass = false;
  628. }
  629. }
  630. /*check cp_sensor_rx_delta */
  631. for (i = 0; i < configuration_rx_num; i++) {
  632. cp_sensor_rx_delta =
  633. ABS((cmcp_info->cp_rx_cal_data_panel[i] -
  634. cmcp_info->cp_rx_data_panel[i]) * 100 /
  635. cmcp_info->cp_rx_data_panel[i]);
  636. if (cp_sensor_rx_delta >
  637. configuration->cp_max_delta_sensor_rx_percent) {
  638. pt_debug(dev, DL_DEBUG,
  639. "%s: Cp_sensor_rx_delta:%d(%d)\n",
  640. "Cp sensor delta range limit test",
  641. cp_sensor_rx_delta,
  642. configuration->cp_max_delta_sensor_rx_percent);
  643. result->cp_sensor_delta_pass = false;
  644. }
  645. }
  646. /* Check sensor Cp rx for min/max values */
  647. result->cp_rx_validation_pass = true;
  648. for (i = 0; i < configuration_rx_num; i++) {
  649. int32_t cp_rx_min =
  650. configuration->cp_min_max_table_rx[i * 2];
  651. int32_t cp_rx_max =
  652. configuration->cp_min_max_table_rx[i * 2 + 1];
  653. if ((cp_sensor_rx_data[i] <= cp_rx_min) ||
  654. (cp_sensor_rx_data[i] >= cp_rx_max)) {
  655. pt_debug(dev, DL_DEBUG,
  656. "%s: Cp Rx[%d]:%d (%d,%d)\n",
  657. "Cp Rx min/max test",
  658. i, (int)cp_sensor_rx_data[i],
  659. cp_rx_min, cp_rx_max);
  660. result->cp_rx_validation_pass = false;
  661. }
  662. }
  663. /* Check sensor Cp tx for min/max values */
  664. result->cp_tx_validation_pass = true;
  665. for (i = 0; i < configuration_tx_num; i++) {
  666. int32_t cp_tx_min =
  667. configuration->cp_min_max_table_tx[i * 2];
  668. int32_t cp_tx_max =
  669. configuration->cp_min_max_table_tx[i * 2 + 1];
  670. if ((cp_sensor_tx_data[i] <= cp_tx_min) ||
  671. (cp_sensor_tx_data[i] >= cp_tx_max)) {
  672. pt_debug(dev, DL_DEBUG,
  673. "%s: Cp Tx[%d]:%d(%d,%d)\n",
  674. "Cp Tx min/max test",
  675. i, cp_sensor_tx_data[i],
  676. cp_tx_min, cp_tx_max);
  677. result->cp_tx_validation_pass = false;
  678. }
  679. }
  680. result->cp_test_pass = result->cp_test_pass
  681. && result->cp_sensor_delta_pass
  682. && result->cp_rx_validation_pass
  683. && result->cp_tx_validation_pass;
  684. }
  685. if (((test_item & CP_BTN) == CP_BTN) && (cmcp_info->btn_num)) {
  686. result->cp_button_delta_pass = true;
  687. /* Check button Cp delta for range limit */
  688. cp_button_delta = ABS((cmcp_info->cp_btn_cal
  689. - cmcp_info->cp_button_ave) * 100 /
  690. cmcp_info->cp_button_ave);
  691. if (cp_button_delta >
  692. configuration->cp_max_delta_button_percent) {
  693. pt_debug(dev, DL_INFO,
  694. "%s: Cp_button_delta:%d (%d)\n",
  695. "Cp button delta range limit test",
  696. cp_button_delta,
  697. configuration->cp_max_delta_button_percent);
  698. result->cp_button_delta_pass = false;
  699. }
  700. /* Check button Cp average for min/max values */
  701. result->cp_button_average_pass = true;
  702. cp_button_average = cmcp_info->cp_button_ave;
  703. if (cp_button_average < configuration->min_button ||
  704. cp_button_average > configuration->max_button) {
  705. pt_debug(dev, DL_INFO,
  706. "%s: Button Cp average fails min/max test\n",
  707. __func__);
  708. pt_debug(dev, DL_INFO,
  709. "%s: Cp_button_average:%d (%d,%d)\n",
  710. "Cp button average min/max test",
  711. cp_button_average,
  712. configuration->min_button,
  713. configuration->max_button);
  714. result->cp_button_average_pass = false;
  715. }
  716. /* Check each button Cp data for min/max values */
  717. result->cp_button_validation_pass = true;
  718. for (i = 0; i < cmcp_info->btn_num; i++) {
  719. int32_t cp_button_min =
  720. configuration->cp_min_max_table_btn[i * 2];
  721. int32_t cp_button_max =
  722. configuration->cp_min_max_table_btn[i * 2 + 1];
  723. if ((cmcp_info->cp_btn_data[i] <= cp_button_min) ||
  724. (cmcp_info->cp_btn_data[i] >= cp_button_max)) {
  725. pt_debug(dev, DL_DEBUG,
  726. "%s: Button[%d]:%d (%d,%d)\n",
  727. "Cp button min/max test",
  728. i, cmcp_info->cp_btn_data[i],
  729. cp_button_min, cp_button_max);
  730. result->cp_button_validation_pass = false;
  731. }
  732. }
  733. result->cp_test_pass = result->cp_test_pass
  734. && result->cp_button_delta_pass
  735. && result->cp_button_average_pass
  736. && result->cp_button_validation_pass;
  737. }
  738. if (pass)
  739. *pass = result->cp_test_pass;
  740. return 0;
  741. }
  742. /*******************************************************************************
  743. * FUNCTION: calculate_gradient_row
  744. *
  745. * SUMMARY: Calculates gradient value for rows.
  746. *
  747. * PARAMETERS:
  748. * *gd_sensor_row_head - pointer to gd_sensor structure
  749. * row_num - number of row
  750. * exclude_row_edge - flag to exclude row edge(1:exclude; 0:include)
  751. * exclude_col_edge - flag to exclude column edge(1:exclude; 0:include)
  752. ******************************************************************************/
  753. static void calculate_gradient_row(struct gd_sensor *gd_sensor_row_head,
  754. uint16_t row_num, int exclude_row_edge, int exclude_col_edge)
  755. {
  756. int i = 0;
  757. uint16_t cm_min_cur = 0;
  758. uint16_t cm_max_cur = 0;
  759. uint16_t cm_ave_cur = 0;
  760. uint16_t cm_ave_next = 0;
  761. uint16_t cm_ave_prev = 0;
  762. struct gd_sensor *p = gd_sensor_row_head;
  763. if (exclude_row_edge) {
  764. for (i = 0; i < row_num; i++) {
  765. if (!exclude_col_edge) {
  766. cm_ave_cur = (p + i)->cm_ave;
  767. cm_min_cur = (p + i)->cm_min;
  768. cm_max_cur = (p + i)->cm_max;
  769. if (i < (row_num-1))
  770. cm_ave_next = (p + i+1)->cm_ave;
  771. if (i > 0)
  772. cm_ave_prev = (p + i-1)->cm_ave;
  773. } else {
  774. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  775. cm_min_cur = (p + i)->cm_min_exclude_edge;
  776. cm_max_cur = (p + i)->cm_max_exclude_edge;
  777. if (i < (row_num-1))
  778. cm_ave_next =
  779. (p + i+1)->cm_ave_exclude_edge;
  780. if (i > 0)
  781. cm_ave_prev =
  782. (p + i-1)->cm_ave_exclude_edge;
  783. }
  784. if (cm_ave_cur == 0)
  785. cm_ave_cur = 1;
  786. /*multiple 1000 to increate accuracy*/
  787. if ((i == 0) || (i == (row_num-1))) {
  788. (p + i)->gradient_val =
  789. (cm_max_cur - cm_min_cur) * 1000 /
  790. cm_ave_cur;
  791. } else if (i == 1) {
  792. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  793. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  794. cm_ave_cur;
  795. } else {
  796. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  797. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  798. cm_ave_cur;
  799. }
  800. }
  801. } else if (!exclude_row_edge) {
  802. for (i = 0; i < row_num; i++) {
  803. if (!exclude_col_edge) {
  804. cm_ave_cur = (p + i)->cm_ave;
  805. cm_min_cur = (p + i)->cm_min;
  806. cm_max_cur = (p + i)->cm_max;
  807. if (i < (row_num-1))
  808. cm_ave_next = (p + i+1)->cm_ave;
  809. if (i > 0)
  810. cm_ave_prev = (p + i-1)->cm_ave;
  811. } else {
  812. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  813. cm_min_cur = (p + i)->cm_min_exclude_edge;
  814. cm_max_cur = (p + i)->cm_max_exclude_edge;
  815. if (i < (row_num-1))
  816. cm_ave_next =
  817. (p + i+1)->cm_ave_exclude_edge;
  818. if (i > 0)
  819. cm_ave_prev =
  820. (p + i-1)->cm_ave_exclude_edge;
  821. }
  822. if (cm_ave_cur == 0)
  823. cm_ave_cur = 1;
  824. /*multiple 1000 to increate accuracy*/
  825. if (i <= 1)
  826. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  827. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  828. cm_ave_cur;
  829. else
  830. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  831. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  832. cm_ave_cur;
  833. }
  834. }
  835. }
  836. /*******************************************************************************
  837. * FUNCTION: calculate_gradient_col
  838. *
  839. * SUMMARY: Calculates gradient value for columns.
  840. *
  841. * PARAMETERS:
  842. * *gd_sensor_row_head - pointer to gd_sensor structure
  843. * col_num - number of column
  844. * exclude_row_edge - flag to exclude row edge(1:exclude; 0:include)
  845. * exclude_col_edge - flag to exclude column edge(1:exclude; 0:include)
  846. ******************************************************************************/
  847. static void calculate_gradient_col(struct gd_sensor *gd_sensor_row_head,
  848. uint16_t col_num, int exclude_row_edge, int exclude_col_edge)
  849. {
  850. int i = 0;
  851. int32_t cm_min_cur = 0;
  852. int32_t cm_max_cur = 0;
  853. int32_t cm_ave_cur = 0;
  854. int32_t cm_ave_next = 0;
  855. int32_t cm_ave_prev = 0;
  856. struct gd_sensor *p = gd_sensor_row_head;
  857. if (!exclude_col_edge) {
  858. for (i = 0; i < col_num; i++) {
  859. if (!exclude_row_edge) {
  860. cm_ave_cur = (p + i)->cm_ave;
  861. cm_min_cur = (p + i)->cm_min;
  862. cm_max_cur = (p + i)->cm_max;
  863. if (i < (col_num-1))
  864. cm_ave_next = (p + i+1)->cm_ave;
  865. if (i > 0)
  866. cm_ave_prev = (p + i-1)->cm_ave;
  867. } else {
  868. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  869. cm_min_cur = (p + i)->cm_min_exclude_edge;
  870. cm_max_cur = (p + i)->cm_max_exclude_edge;
  871. if (i < (col_num-1))
  872. cm_ave_next =
  873. (p + i+1)->cm_ave_exclude_edge;
  874. if (i > 0)
  875. cm_ave_prev =
  876. (p + i-1)->cm_ave_exclude_edge;
  877. }
  878. if (cm_ave_cur == 0)
  879. cm_ave_cur = 1;
  880. /*multiple 1000 to increate accuracy*/
  881. if (i <= 1)
  882. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  883. + ABS(cm_ave_cur - cm_ave_next)) * 1000 /
  884. cm_ave_cur;
  885. else
  886. (p + i)->gradient_val = (cm_max_cur - cm_min_cur
  887. + ABS(cm_ave_cur - cm_ave_prev)) * 1000 /
  888. cm_ave_cur;
  889. }
  890. } else if (exclude_col_edge) {
  891. for (i = 0; i < col_num; i++) {
  892. if (!exclude_row_edge) {
  893. cm_ave_cur = (p + i)->cm_ave;
  894. cm_min_cur = (p + i)->cm_min;
  895. cm_max_cur = (p + i)->cm_max;
  896. if (i < (col_num-1))
  897. cm_ave_next = (p + i+1)->cm_ave;
  898. if (i > 0)
  899. cm_ave_prev = (p + i-1)->cm_ave;
  900. } else {
  901. cm_ave_cur = (p + i)->cm_ave_exclude_edge;
  902. cm_min_cur = (p + i)->cm_min_exclude_edge;
  903. cm_max_cur = (p + i)->cm_max_exclude_edge;
  904. if (i < (col_num-1))
  905. cm_ave_next =
  906. (p + i+1)->cm_ave_exclude_edge;
  907. if (i > 0)
  908. cm_ave_prev =
  909. (p + i-1)->cm_ave_exclude_edge;
  910. }
  911. if (cm_ave_cur == 0)
  912. cm_ave_cur = 1;
  913. /*multiple 1000 to increate accuracy*/
  914. if ((i == 0) || (i == (col_num - 1)))
  915. (p + i)->gradient_val =
  916. (cm_max_cur - cm_min_cur) * 1000 /
  917. cm_ave_cur;
  918. else if (i == 1)
  919. (p + i)->gradient_val =
  920. (cm_max_cur - cm_min_cur +
  921. ABS(cm_ave_cur - cm_ave_next))
  922. * 1000 / cm_ave_cur;
  923. else
  924. (p + i)->gradient_val =
  925. (cm_max_cur - cm_min_cur +
  926. ABS(cm_ave_cur - cm_ave_prev))
  927. * 1000 / cm_ave_cur;
  928. }
  929. }
  930. }
  931. /*******************************************************************************
  932. * FUNCTION: fill_gd_sensor_table
  933. *
  934. * SUMMARY: Fills cm calculation result and exclude parameter to gd_sensor
  935. * structure.
  936. *
  937. * PARAMETERS:
  938. * *head - pointer to gd_sensor structure
  939. * index - index of row or column
  940. * cm_max - maximum of cm
  941. * cm_min - minmum of cm
  942. * cm_ave - average of cm
  943. * cm_max_exclude_edge - maximum of cm without edge data
  944. * cm_min_exclude_edge - minmum of cm without edge data
  945. * cm_ave_exclude_edge - average of cm without edge data
  946. ******************************************************************************/
  947. static void fill_gd_sensor_table(struct gd_sensor *head, int32_t index,
  948. int32_t cm_max, int32_t cm_min, int32_t cm_ave,
  949. int32_t cm_max_exclude_edge, int32_t cm_min_exclude_edge,
  950. int32_t cm_ave_exclude_edge)
  951. {
  952. (head + index)->cm_max = cm_max;
  953. (head + index)->cm_min = cm_min;
  954. (head + index)->cm_ave = cm_ave;
  955. (head + index)->cm_ave_exclude_edge = cm_ave_exclude_edge;
  956. (head + index)->cm_max_exclude_edge = cm_max_exclude_edge;
  957. (head + index)->cm_min_exclude_edge = cm_min_exclude_edge;
  958. }
  959. /*******************************************************************************
  960. * FUNCTION: calculate_gd_info
  961. *
  962. * SUMMARY: Calculates gradient panel sensor column and row by calling
  963. * function calculate_gradient_col() & calculate_gradient_row().
  964. *
  965. * PARAMETERS:
  966. * *head - pointer to gd_sensor structure
  967. * index - index of row or column
  968. * cm_max - maximum of cm
  969. * cm_min - minmum of cm
  970. * cm_ave - average of cm
  971. * cm_max_exclude_edge - maximum of cm without edge data
  972. * cm_min_exclude_edge - minmum of cm without edge data
  973. * cm_ave_exclude_edge - average of cm without edge data
  974. ******************************************************************************/
  975. static void calculate_gd_info(struct gd_sensor *gd_sensor_col,
  976. struct gd_sensor *gd_sensor_row, int tx_num, int rx_num,
  977. int32_t *cm_sensor_data, int cm_excluding_row_edge,
  978. int cm_excluding_col_edge)
  979. {
  980. int32_t cm_max;
  981. int32_t cm_min;
  982. int32_t cm_ave;
  983. int32_t cm_max_exclude_edge;
  984. int32_t cm_min_exclude_edge;
  985. int32_t cm_ave_exclude_edge;
  986. int32_t cm_data;
  987. int i;
  988. int j;
  989. /*calculate all the gradient related info for column*/
  990. for (i = 0; i < tx_num; i++) {
  991. /*re-initialize for a new col*/
  992. cm_max = cm_sensor_data[i * rx_num];
  993. cm_min = cm_max;
  994. cm_ave = 0;
  995. cm_max_exclude_edge = cm_sensor_data[i * rx_num + 1];
  996. cm_min_exclude_edge = cm_max_exclude_edge;
  997. cm_ave_exclude_edge = 0;
  998. for (j = 0; j < rx_num; j++) {
  999. cm_data = cm_sensor_data[i * rx_num + j];
  1000. if (cm_data > cm_max)
  1001. cm_max = cm_data;
  1002. if (cm_data < cm_min)
  1003. cm_min = cm_data;
  1004. cm_ave += cm_data;
  1005. /*calculate exclude edge data*/
  1006. if ((j > 0) && (j < (rx_num-1))) {
  1007. if (cm_data > cm_max_exclude_edge)
  1008. cm_max_exclude_edge = cm_data;
  1009. if (cm_data < cm_min_exclude_edge)
  1010. cm_min_exclude_edge = cm_data;
  1011. cm_ave_exclude_edge += cm_data;
  1012. }
  1013. }
  1014. cm_ave /= rx_num;
  1015. cm_ave_exclude_edge /= (rx_num-2);
  1016. fill_gd_sensor_table(gd_sensor_col, i, cm_max, cm_min, cm_ave,
  1017. cm_max_exclude_edge, cm_min_exclude_edge, cm_ave_exclude_edge);
  1018. }
  1019. calculate_gradient_col(gd_sensor_col, tx_num, cm_excluding_row_edge,
  1020. cm_excluding_col_edge);
  1021. /*calculate all the gradient related info for row*/
  1022. for (j = 0; j < rx_num; j++) {
  1023. /*re-initialize for a new row*/
  1024. cm_max = cm_sensor_data[j];
  1025. cm_min = cm_max;
  1026. cm_ave = 0;
  1027. cm_max_exclude_edge = cm_sensor_data[rx_num + j];
  1028. cm_min_exclude_edge = cm_max_exclude_edge;
  1029. cm_ave_exclude_edge = 0;
  1030. for (i = 0; i < tx_num; i++) {
  1031. cm_data = cm_sensor_data[i * rx_num + j];
  1032. if (cm_data > cm_max)
  1033. cm_max = cm_data;
  1034. if (cm_data < cm_min)
  1035. cm_min = cm_data;
  1036. cm_ave += cm_data;
  1037. /*calculate exclude edge data*/
  1038. if ((i > 0) && (i < (tx_num-1))) {
  1039. if (cm_data > cm_max_exclude_edge)
  1040. cm_max_exclude_edge = cm_data;
  1041. if (cm_data < cm_min_exclude_edge)
  1042. cm_min_exclude_edge = cm_data;
  1043. cm_ave_exclude_edge += cm_data;
  1044. }
  1045. }
  1046. cm_ave /= tx_num;
  1047. cm_ave_exclude_edge /= (tx_num-2);
  1048. fill_gd_sensor_table(gd_sensor_row, j, cm_max, cm_min, cm_ave,
  1049. cm_max_exclude_edge, cm_min_exclude_edge, cm_ave_exclude_edge);
  1050. }
  1051. calculate_gradient_row(gd_sensor_row, rx_num, cm_excluding_row_edge,
  1052. cm_excluding_col_edge);
  1053. }
  1054. /*******************************************************************************
  1055. * FUNCTION: pt_get_cmcp_info
  1056. *
  1057. * SUMMARY: Function to include following work:
  1058. * 1) run short test and get result
  1059. * 2) run selftest to get cm_panel data, cm_cal_data_panel data, calculate
  1060. * cm_ave_data_panel, cm_sensor_delta and gradient by column and row.
  1061. * 3) run selftest to get cp_panel data, cp_cal_data_panel data, cacluate
  1062. * cp_ave_data_panel, cp_sensor_delta for tx and rx.
  1063. * 4) run selftest to get cm_btn data, cm_cal_data_btn data, cacluate
  1064. * cm_delta_data_btn data, cm_ave_data_btn data.
  1065. * 5) run selftest to get cp_btn data, cp_btn_cal data, cacluate
  1066. * cp_button_delta data, cp_button_ave data.
  1067. *
  1068. * RETURN:
  1069. * 0 = success
  1070. * !0 = failure
  1071. *
  1072. * PARAMETERS:
  1073. * *dad - pointer to pt_device_access_data structure
  1074. * *cmcp_info - pointer to cmcp_data structure
  1075. ******************************************************************************/
  1076. static int pt_get_cmcp_info(struct pt_device_access_data *dad,
  1077. struct cmcp_data *cmcp_info)
  1078. {
  1079. struct device *dev;
  1080. int32_t *cm_data_panel = cmcp_info->cm_data_panel;
  1081. int32_t *cp_tx_data_panel = cmcp_info->cp_tx_data_panel;
  1082. int32_t *cp_rx_data_panel = cmcp_info->cp_rx_data_panel;
  1083. int32_t *cp_tx_cal_data_panel = cmcp_info->cp_tx_cal_data_panel;
  1084. int32_t *cp_rx_cal_data_panel = cmcp_info->cp_rx_cal_data_panel;
  1085. int32_t *cm_btn_data = cmcp_info->cm_btn_data;
  1086. int32_t *cp_btn_data = cmcp_info->cp_btn_data;
  1087. struct gd_sensor *gd_sensor_col = cmcp_info->gd_sensor_col;
  1088. struct gd_sensor *gd_sensor_row = cmcp_info->gd_sensor_row;
  1089. struct result *result = dad->result;
  1090. int32_t cp_btn_cal = 0;
  1091. int32_t cp_btn_ave = 0;
  1092. int32_t cm_ave_data_panel = 0;
  1093. int32_t cm_ave_data_btn = 0;
  1094. int32_t cp_tx_ave_data_panel = 0;
  1095. int32_t cp_rx_ave_data_panel = 0;
  1096. u8 tmp_buf[3];
  1097. int tx_num;
  1098. int rx_num;
  1099. int btn_num;
  1100. int rc = 0;
  1101. int i;
  1102. dev = dad->dev;
  1103. cmcp_info->tx_num = dad->si->sensing_conf_data.tx_num;
  1104. cmcp_info->rx_num = dad->si->sensing_conf_data.rx_num;
  1105. cmcp_info->btn_num = dad->si->num_btns;
  1106. tx_num = cmcp_info->tx_num;
  1107. rx_num = cmcp_info->rx_num;
  1108. btn_num = cmcp_info->btn_num;
  1109. pt_debug(dev, DL_INFO, "%s tx_num=%d", __func__, tx_num);
  1110. pt_debug(dev, DL_INFO, "%s rx_num=%d", __func__, rx_num);
  1111. pt_debug(dev, DL_INFO, "%s btn_num=%d", __func__, btn_num);
  1112. /*short test*/
  1113. result->short_test_pass = true;
  1114. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1115. tmp_buf, sizeof(tmp_buf),
  1116. PT_ST_ID_AUTOSHORTS, PIP_CMD_MAX_LENGTH,
  1117. PT_ST_DONT_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1118. if (rc) {
  1119. pt_debug(dev, DL_ERROR, "short test not supported");
  1120. goto exit;
  1121. }
  1122. if (dad->ic_buf[1] != 0)
  1123. result->short_test_pass = false;
  1124. /*Get cm_panel data*/
  1125. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1126. tmp_buf, sizeof(tmp_buf),
  1127. PT_ST_ID_CM_PANEL, PIP_CMD_MAX_LENGTH,
  1128. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1129. if (rc) {
  1130. pt_debug(dev, DL_ERROR, "Get CM Panel not supported");
  1131. goto exit;
  1132. }
  1133. if (cm_data_panel != NULL) {
  1134. for (i = 0; i < tx_num * rx_num; i++) {
  1135. cm_data_panel[i] =
  1136. 10*(dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2] + 256
  1137. * dad->ic_buf[CM_PANEL_DATA_OFFSET+i*2+1]);
  1138. pt_debug(dev, DL_DEBUG,
  1139. "cm_data_panel[%d]=%d\n",
  1140. i, cm_data_panel[i]);
  1141. cm_ave_data_panel += cm_data_panel[i];
  1142. }
  1143. cm_ave_data_panel /= (tx_num * rx_num);
  1144. cmcp_info->cm_ave_data_panel = cm_ave_data_panel;
  1145. /* Calculate gradient panel sensor column/row here */
  1146. calculate_gd_info(gd_sensor_col, gd_sensor_row, tx_num, rx_num,
  1147. cm_data_panel, 1, 1);
  1148. for (i = 0; i < tx_num; i++) {
  1149. pt_debug(dev, DL_DEBUG,
  1150. "i=%d max=%d,min=%d,ave=%d, gradient=%d", i,
  1151. gd_sensor_col[i].cm_max,
  1152. gd_sensor_col[i].cm_min,
  1153. gd_sensor_col[i].cm_ave,
  1154. gd_sensor_col[i].gradient_val);
  1155. }
  1156. for (i = 0; i < rx_num; i++) {
  1157. pt_debug(dev, DL_DEBUG,
  1158. "i=%d max=%d,min=%d,ave=%d, gradient=%d", i,
  1159. gd_sensor_row[i].cm_max,
  1160. gd_sensor_row[i].cm_min,
  1161. gd_sensor_row[i].cm_ave,
  1162. gd_sensor_row[i].gradient_val);
  1163. }
  1164. }
  1165. /*Get cp data*/
  1166. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1167. tmp_buf, sizeof(tmp_buf),
  1168. PT_ST_ID_CP_PANEL, PIP_CMD_MAX_LENGTH,
  1169. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1170. if (rc) {
  1171. pt_debug(dev, DL_ERROR, "Get CP Panel not supported");
  1172. goto exit;
  1173. }
  1174. /*Get cp_tx_data_panel*/
  1175. if (cp_tx_data_panel != NULL) {
  1176. for (i = 0; i < tx_num; i++) {
  1177. cp_tx_data_panel[i] =
  1178. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+i*2]
  1179. + 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+i*2+1]);
  1180. pt_debug(dev, DL_DEBUG,
  1181. "cp_tx_data_panel[%d]=%d\n",
  1182. i, cp_tx_data_panel[i]);
  1183. cp_tx_ave_data_panel += cp_tx_data_panel[i];
  1184. }
  1185. cp_tx_ave_data_panel /= tx_num;
  1186. cmcp_info->cp_tx_ave_data_panel = cp_tx_ave_data_panel;
  1187. }
  1188. /*Get cp_tx_cal_data_panel*/
  1189. if (cp_tx_cal_data_panel != NULL) {
  1190. for (i = 0; i < tx_num; i++) {
  1191. cp_tx_cal_data_panel[i] =
  1192. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*2+i*2]
  1193. + 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*2+i*2+1]);
  1194. pt_debug(dev, DL_DEBUG, "cp_tx_cal_data_panel[%d]=%d\n",
  1195. i, cp_tx_cal_data_panel[i]);
  1196. }
  1197. /*get cp_sensor_tx_delta,using the first sensor cal value for temp */
  1198. /*multiple 1000 to increase accuracy*/
  1199. cmcp_info->cp_sensor_tx_delta = ABS((cp_tx_cal_data_panel[0]
  1200. - cp_tx_ave_data_panel) * 1000 / cp_tx_ave_data_panel);
  1201. }
  1202. /*Get cp_rx_data_panel*/
  1203. if (cp_rx_data_panel != NULL) {
  1204. for (i = 0; i < rx_num; i++) {
  1205. cp_rx_data_panel[i] =
  1206. 10*(dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+i*2] +
  1207. 256 * dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+i*2+1]);
  1208. pt_debug(dev, DL_DEBUG,
  1209. "cp_rx_data_panel[%d]=%d\n", i,
  1210. cp_rx_data_panel[i]);
  1211. cp_rx_ave_data_panel += cp_rx_data_panel[i];
  1212. }
  1213. cp_rx_ave_data_panel /= rx_num;
  1214. cmcp_info->cp_rx_ave_data_panel = cp_rx_ave_data_panel;
  1215. }
  1216. /*Get cp_rx_cal_data_panel*/
  1217. if (cp_rx_cal_data_panel != NULL) {
  1218. for (i = 0; i < rx_num; i++) {
  1219. cp_rx_cal_data_panel[i] =
  1220. 10 * (dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+rx_num*2+i*2] +
  1221. 256 *
  1222. dad->ic_buf[CP_PANEL_DATA_OFFSET+tx_num*4+rx_num*2+i*2+1]);
  1223. pt_debug(dev, DL_DEBUG,
  1224. "cp_rx_cal_data_panel[%d]=%d\n", i,
  1225. cp_rx_cal_data_panel[i]);
  1226. }
  1227. /*get cp_sensor_rx_delta,using the first sensor cal value for temp */
  1228. /*multiple 1000 to increase accuracy*/
  1229. cmcp_info->cp_sensor_rx_delta = ABS((cp_rx_cal_data_panel[0]
  1230. - cp_rx_ave_data_panel) * 1000 / cp_rx_ave_data_panel);
  1231. }
  1232. if (btn_num == 0) {
  1233. pt_debug(dev, DL_INFO, "%s: Skip Button Test\n", __func__);
  1234. goto skip_button_test;
  1235. }
  1236. /*get cm btn data*/
  1237. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1238. tmp_buf, sizeof(tmp_buf),
  1239. PT_ST_ID_CM_BUTTON, PIP_CMD_MAX_LENGTH,
  1240. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1241. if (rc) {
  1242. pt_debug(dev, DL_ERROR, "Get CM BTN not supported");
  1243. goto exit;
  1244. }
  1245. if (cm_btn_data != NULL) {
  1246. for (i = 0; i < btn_num; i++) {
  1247. cm_btn_data[i] =
  1248. 10 * (dad->ic_buf[CM_BTN_DATA_OFFSET+i*2] +
  1249. 256 * dad->ic_buf[CM_BTN_DATA_OFFSET+i*2+1]);
  1250. pt_debug(dev, DL_DEBUG,
  1251. " cm_btn_data[%d]=%d\n",
  1252. i, cm_btn_data[i]);
  1253. cm_ave_data_btn += cm_btn_data[i];
  1254. }
  1255. cm_ave_data_btn /= btn_num;
  1256. cmcp_info->cm_ave_data_btn = cm_ave_data_btn;
  1257. }
  1258. /*get cp btn data*/
  1259. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1260. tmp_buf, sizeof(tmp_buf),
  1261. PT_ST_ID_CP_BUTTON, PIP_CMD_MAX_LENGTH,
  1262. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1263. if (rc) {
  1264. pt_debug(dev, DL_ERROR, "Get CP BTN not supported");
  1265. goto exit;
  1266. }
  1267. if (cp_btn_data != NULL) {
  1268. for (i = 0; i < btn_num; i++) {
  1269. cp_btn_data[i] =
  1270. 10 * (dad->ic_buf[CP_BTN_DATA_OFFSET+i*2] +
  1271. 256 * dad->ic_buf[CP_BTN_DATA_OFFSET+i*2+1]);
  1272. cp_btn_ave += cp_btn_data[i];
  1273. pt_debug(dev, DL_DEBUG,
  1274. "cp_btn_data[%d]=%d\n",
  1275. i, cp_btn_data[i]);
  1276. }
  1277. cp_btn_ave /= btn_num;
  1278. cp_btn_cal = 10*(dad->ic_buf[CP_BTN_DATA_OFFSET+i*2]
  1279. + 256 * dad->ic_buf[CP_BTN_DATA_OFFSET+i*2+1]);
  1280. cmcp_info->cp_button_ave = cp_btn_ave;
  1281. cmcp_info->cp_btn_cal = cp_btn_cal;
  1282. /*multiple 1000 to increase accuracy*/
  1283. cmcp_info->cp_button_delta = ABS((cp_btn_cal
  1284. - cp_btn_ave) * 1000 / cp_btn_ave);
  1285. pt_debug(dev, DL_INFO, " cp_btn_cal=%d\n",
  1286. cp_btn_cal);
  1287. pt_debug(dev, DL_INFO, " cp_btn_ave=%d\n",
  1288. cp_btn_ave);
  1289. }
  1290. skip_button_test:
  1291. exit:
  1292. return rc;
  1293. }
  1294. /*******************************************************************************
  1295. * FUNCTION: pt_get_cm_cal
  1296. *
  1297. * SUMMARY: Function to include following work:
  1298. * 1) run selftest to get cm_cal_data_panel, cm_sensor_delta
  1299. * 2) run selftest to get cm_cal_data_btn, cm_delta_data_btn
  1300. *
  1301. * NOTE:
  1302. * This function depends on the calculation result of pt_get_cmcp_info()
  1303. *
  1304. * RETURN:
  1305. * 0 = success
  1306. * !0 = failure
  1307. *
  1308. * PARAMETERS:
  1309. * *dad - pointer to pt_device_access_data structure
  1310. * *cmcp_info - pointer to cmcp_data structure
  1311. ******************************************************************************/
  1312. static int pt_get_cm_cal(struct pt_device_access_data *dad,
  1313. struct cmcp_data *cmcp_info)
  1314. {
  1315. struct device *dev;
  1316. int32_t *cm_data_panel = cmcp_info->cm_data_panel;
  1317. int32_t *cm_btn_data = cmcp_info->cm_btn_data;
  1318. u8 tmp_buf[3];
  1319. int rc = 0;
  1320. int i;
  1321. dev = dad->dev;
  1322. /*Get cm_cal data*/
  1323. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1324. tmp_buf, sizeof(tmp_buf),
  1325. PT_ST_ID_CM_PANEL, PIP_CMD_MAX_LENGTH,
  1326. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1327. if (rc) {
  1328. pt_debug(dev, DL_ERROR, "Get CM Panel not supported");
  1329. goto exit;
  1330. }
  1331. if (cm_data_panel != NULL) {
  1332. i = cmcp_info->tx_num * cmcp_info->rx_num;
  1333. cmcp_info->cm_cal_data_panel =
  1334. 10 * (dad->ic_buf[CM_PANEL_DATA_OFFSET + i * 2] +
  1335. 256 * dad->ic_buf[CM_PANEL_DATA_OFFSET + i * 2 + 1]);
  1336. /*multiple 1000 to increase accuracy*/
  1337. cmcp_info->cm_sensor_delta =
  1338. ABS((cmcp_info->cm_ave_data_panel -
  1339. cmcp_info->cm_cal_data_panel) *
  1340. 1000 / cmcp_info->cm_ave_data_panel);
  1341. }
  1342. if (cmcp_info->btn_num == 0) {
  1343. pt_debug(dev, DL_INFO, "%s: Skip Button Test\n", __func__);
  1344. goto skip_button_test;
  1345. }
  1346. /*get cm_btn_cal data*/
  1347. rc = pt_run_and_get_selftest_result(dev, PT_CORE_CMD_UNPROTECTED,
  1348. tmp_buf, sizeof(tmp_buf),
  1349. PT_ST_ID_CM_BUTTON, PIP_CMD_MAX_LENGTH,
  1350. PT_ST_GET_RESULTS, PT_ST_NOPRINT, PT_PR_FORMAT_DEFAULT);
  1351. if (rc) {
  1352. pt_debug(dev, DL_ERROR, "Get CM BTN not supported");
  1353. goto exit;
  1354. }
  1355. if (cm_btn_data != NULL) {
  1356. i = cmcp_info->btn_num;
  1357. cmcp_info->cm_cal_data_btn =
  1358. 10 * (dad->ic_buf[CM_BTN_DATA_OFFSET + i * 2] +
  1359. 256 * dad->ic_buf[CM_BTN_DATA_OFFSET + i * 2 + 1]);
  1360. /*multiple 1000 to increase accuracy*/
  1361. cmcp_info->cm_delta_data_btn = ABS(
  1362. (cmcp_info->cm_ave_data_btn - cmcp_info->cm_cal_data_btn) *
  1363. 1000 / cmcp_info->cm_ave_data_btn);
  1364. pt_debug(dev, DL_INFO, " cm_btn_cal=%d\n",
  1365. cmcp_info->cm_cal_data_btn);
  1366. }
  1367. skip_button_test:
  1368. exit:
  1369. return rc;
  1370. }
  1371. /*******************************************************************************
  1372. * FUNCTION: pt_free_cmcp_buf
  1373. *
  1374. * SUMMARY: Free pointers in cmcp_data structure
  1375. *
  1376. * PARAMETERS:
  1377. * *cmcp_info - pointer to cmcp_data structure
  1378. ******************************************************************************/
  1379. static void pt_free_cmcp_buf(struct cmcp_data *cmcp_info)
  1380. {
  1381. if (cmcp_info->gd_sensor_col != NULL)
  1382. kfree(cmcp_info->gd_sensor_col);
  1383. if (cmcp_info->gd_sensor_row != NULL)
  1384. kfree(cmcp_info->gd_sensor_row);
  1385. if (cmcp_info->cm_data_panel != NULL)
  1386. kfree(cmcp_info->cm_data_panel);
  1387. if (cmcp_info->cp_tx_data_panel != NULL)
  1388. kfree(cmcp_info->cp_tx_data_panel);
  1389. if (cmcp_info->cp_rx_data_panel != NULL)
  1390. kfree(cmcp_info->cp_rx_data_panel);
  1391. if (cmcp_info->cp_tx_cal_data_panel != NULL)
  1392. kfree(cmcp_info->cp_tx_cal_data_panel);
  1393. if (cmcp_info->cp_rx_cal_data_panel != NULL)
  1394. kfree(cmcp_info->cp_rx_cal_data_panel);
  1395. if (cmcp_info->cm_btn_data != NULL)
  1396. kfree(cmcp_info->cm_btn_data);
  1397. if (cmcp_info->cp_btn_data != NULL)
  1398. kfree(cmcp_info->cp_btn_data);
  1399. if (cmcp_info->cm_sensor_column_delta != NULL)
  1400. kfree(cmcp_info->cm_sensor_column_delta);
  1401. if (cmcp_info->cm_sensor_row_delta != NULL)
  1402. kfree(cmcp_info->cm_sensor_row_delta);
  1403. }
  1404. /*******************************************************************************
  1405. * FUNCTION: pt_cmcp_get_test_item
  1406. *
  1407. * SUMMARY: Parses enum cmcp_test_item to integer value test_item as bitwise
  1408. * type.
  1409. *
  1410. * RETURN: integer value to indidate available test item with bitwise type
  1411. *
  1412. * PARAMETERS:
  1413. * item_input - enum cmcp_test_item
  1414. ******************************************************************************/
  1415. static int pt_cmcp_get_test_item(int item_input)
  1416. {
  1417. int test_item = 0;
  1418. switch (item_input) {
  1419. case CMCP_FULL:
  1420. test_item = CMCP_FULL_CASE;
  1421. break;
  1422. case CMCP_CM_PANEL:
  1423. test_item = CM_PANEL;
  1424. break;
  1425. case CMCP_CP_PANEL:
  1426. test_item = CP_PANEL;
  1427. break;
  1428. case CMCP_CM_BTN:
  1429. test_item = CM_BTN;
  1430. break;
  1431. case CMCP_CP_BTN:
  1432. test_item = CP_BTN;
  1433. break;
  1434. }
  1435. return test_item;
  1436. }
  1437. /*******************************************************************************
  1438. * FUNCTION: pt_cmcp_test_show
  1439. *
  1440. * SUMMARY: Show method for cmcp_test sysfs node. Allows to perform cmcp test
  1441. * with following steps:
  1442. * 1) Get cmcp test items which from threhold file
  1443. * 2) Check whether cmcp test items match with firmware
  1444. * 3) Set parameter to force single TX
  1445. * 4) Do calibration if requested
  1446. * 5) Get all cmcp data from FW and do calculation
  1447. * 6) Set parameter to restore to multi tx
  1448. * 7) Do calibration if requested
  1449. * 8) Check scan state,try to fix if it is not right
  1450. * 9) Start watchdog
  1451. * 10) Validate cm and cp test results if requested
  1452. * 11) Fill the test result
  1453. *
  1454. * RETURN:
  1455. * 0 = success
  1456. * !0 = failure
  1457. *
  1458. * PARAMETERS:
  1459. * *dev - pointer to device structure
  1460. * *attr - pointer to device attributes
  1461. * *buf - pointer to output buffer
  1462. ******************************************************************************/
  1463. static ssize_t pt_cmcp_test_show(struct device *dev,
  1464. struct device_attribute *attr, char *buf)
  1465. {
  1466. struct pt_device_access_data *dad
  1467. = pt_get_device_access_data(dev);
  1468. struct cmcp_data *cmcp_info = dad->cmcp_info;
  1469. struct result *result = dad->result;
  1470. struct configuration *configuration = dad->configs;
  1471. bool final_pass = true;
  1472. static const char * const cmcp_test_case_array[] = {"Full Cm/Cp test",
  1473. "Cm panel test", "Cp panel test",
  1474. "Cm button test", "Cp button test"};
  1475. int index = 0;
  1476. int test_item = 0;
  1477. int no_builtin_file = 0;
  1478. int rc = 0;
  1479. int self_test_result_1 = 0;
  1480. int self_test_result_2 = 0;
  1481. u8 sys_mode = FW_SYS_MODE_UNDEFINED;
  1482. u8 retry = 3;
  1483. dev = dad->dev;
  1484. if ((configuration == NULL) || (cmcp_info == NULL))
  1485. goto exit;
  1486. mutex_lock(&dad->sysfs_lock);
  1487. if (dad->cmcp_test_in_progress) {
  1488. mutex_unlock(&dad->sysfs_lock);
  1489. goto cmcp_not_ready;
  1490. }
  1491. dad->cmcp_test_in_progress = 1;
  1492. dad->test_executed = 0;
  1493. test_item = pt_cmcp_get_test_item(dad->cmcp_test_items);
  1494. if (dad->builtin_cmcp_threshold_status < 0) {
  1495. pt_debug(dev, DL_WARN, "%s: No cmcp threshold file.\n",
  1496. __func__);
  1497. no_builtin_file = 1;
  1498. mutex_unlock(&dad->sysfs_lock);
  1499. goto start_testing;
  1500. }
  1501. if (dad->cmcp_test_items < 0) {
  1502. pt_debug(dev, DL_ERROR,
  1503. "%s: Invalid test item! Should be 0~4!\n", __func__);
  1504. mutex_unlock(&dad->sysfs_lock);
  1505. goto invalid_item;
  1506. }
  1507. pt_debug(dev, DL_INFO, "%s: Test item is %s, %d\n",
  1508. __func__, cmcp_test_case_array[dad->cmcp_test_items],
  1509. test_item);
  1510. if ((dad->si->num_btns == 0)
  1511. && ((dad->cmcp_test_items == CMCP_CM_BTN)
  1512. || (dad->cmcp_test_items == CMCP_CP_BTN))) {
  1513. pt_debug(dev, DL_WARN,
  1514. "%s: FW doesn't support button!\n", __func__);
  1515. mutex_unlock(&dad->sysfs_lock);
  1516. goto invalid_item_btn;
  1517. }
  1518. mutex_unlock(&dad->sysfs_lock);
  1519. if (cmcp_check_config_fw_match(dev, configuration))
  1520. goto mismatch;
  1521. start_testing:
  1522. pt_debug(dev, DL_INFO, "%s: Start Cm/Cp test!\n", __func__);
  1523. result->cm_test_pass = true;
  1524. result->cp_test_pass = true;
  1525. /*stop watchdog*/
  1526. rc = cmd->request_stop_wd(dev);
  1527. if (rc)
  1528. pt_debug(dev, DL_ERROR, "stop watchdog failed");
  1529. /* Make sure the device is awake */
  1530. pm_runtime_get_sync(dev);
  1531. /* Resource protect */
  1532. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  1533. if (rc) {
  1534. pt_debug(dev, DL_ERROR,
  1535. "%s: Error on request exclusive rc = %d\n",
  1536. __func__, rc);
  1537. }
  1538. /*force single tx*/
  1539. rc = cmd->nonhid_cmd->set_param(dev,
  1540. PT_CORE_CMD_UNPROTECTED, 0x1F, 1, 1);
  1541. if (rc)
  1542. pt_debug(dev, DL_ERROR, "force single tx failed");
  1543. /*suspend_scanning */
  1544. rc = cmd->nonhid_cmd->suspend_scanning(dev, PT_CORE_CMD_UNPROTECTED);
  1545. if (rc)
  1546. pt_debug(dev, DL_ERROR, "suspend_scanning failed");
  1547. /* Do calibration if requested */
  1548. if (!dad->cmcp_force_calibrate) {
  1549. pt_debug(dev, DL_INFO, "do calibration in single tx mode");
  1550. rc = pt_perform_calibration(dev);
  1551. if (rc)
  1552. pt_debug(dev, DL_ERROR, "calibration failed");
  1553. }
  1554. /*resume_scanning */
  1555. rc = cmd->nonhid_cmd->resume_scanning(dev, PT_CORE_CMD_UNPROTECTED);
  1556. if (rc)
  1557. pt_debug(dev, DL_ERROR, "resume_scanning failed");
  1558. /*get all cmcp data from FW*/
  1559. self_test_result_1 = pt_get_cmcp_info(dad, cmcp_info);
  1560. if (self_test_result_1)
  1561. pt_debug(dev, DL_ERROR, "pt_get_cmcp_info failed");
  1562. /*restore to multi tx*/
  1563. rc = cmd->nonhid_cmd->set_param(dev,
  1564. PT_CORE_CMD_UNPROTECTED, 0x1F, 0, 1);
  1565. if (rc)
  1566. pt_debug(dev, DL_ERROR, "restore multi tx failed");
  1567. /*suspend_scanning */
  1568. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  1569. if (rc)
  1570. pt_debug(dev, DL_ERROR, "suspend_scanning failed");
  1571. /* Do calibration if requested */
  1572. if (!dad->cmcp_force_calibrate) {
  1573. pt_debug(dev, DL_INFO, "do calibration in multi tx mode");
  1574. rc = pt_perform_calibration(dev);
  1575. if (rc)
  1576. pt_debug(dev, DL_ERROR, "calibration failed");
  1577. }
  1578. /*resume_scanning */
  1579. rc = cmd->nonhid_cmd->resume_scanning(dev, PT_CORE_CMD_UNPROTECTED);
  1580. if (rc)
  1581. pt_debug(dev, DL_ERROR, "resume_scanning failed");
  1582. /*get cm cal data from FW*/
  1583. self_test_result_2 = pt_get_cm_cal(dad, cmcp_info);
  1584. if (self_test_result_2)
  1585. pt_debug(dev, DL_ERROR, "pt_get_cm_cal failed");
  1586. /* check scan state,try to fix if it is not right*/
  1587. while (retry--) {
  1588. rc = cmd->request_get_fw_mode(dev, PT_CORE_CMD_UNPROTECTED,
  1589. &sys_mode, NULL);
  1590. if (sys_mode != FW_SYS_MODE_SCANNING) {
  1591. pt_debug(dev, DL_ERROR,
  1592. "%s: fw mode: %d, retry: %d, rc = %d\n",
  1593. __func__, sys_mode, retry, rc);
  1594. rc = cmd->nonhid_cmd->resume_scanning(dev,
  1595. PT_CORE_CMD_UNPROTECTED);
  1596. }
  1597. }
  1598. rc = cmd->release_exclusive(dev);
  1599. if (rc) {
  1600. pt_debug(dev, DL_ERROR,
  1601. "%s: Error on release exclusive rc = %d\n",
  1602. __func__, rc);
  1603. }
  1604. pm_runtime_put(dev);
  1605. /*start watchdog*/
  1606. rc = cmd->request_start_wd(dev);
  1607. if (rc)
  1608. pt_debug(dev, DL_ERROR, "start watchdog failed");
  1609. if (self_test_result_1 || self_test_result_2)
  1610. goto self_test_failed;
  1611. /* The tests are finished without failure */
  1612. mutex_lock(&dad->sysfs_lock);
  1613. dad->test_executed = 1;
  1614. mutex_unlock(&dad->sysfs_lock);
  1615. if (no_builtin_file)
  1616. goto no_builtin;
  1617. if ((test_item) & (CM_ENABLED))
  1618. validate_cm_test_results(dev, configuration, cmcp_info,
  1619. result, &final_pass, test_item);
  1620. if ((test_item) & (CP_ENABLED))
  1621. validate_cp_test_results(dev, configuration, cmcp_info,
  1622. result, &final_pass, test_item);
  1623. if ((dad->cmcp_test_items == CMCP_FULL)
  1624. && (dad->cmcp_range_check == 0)) {
  1625. /*full test and full check*/
  1626. result->test_summary = result->cm_test_pass
  1627. && result->cp_test_pass
  1628. && result->short_test_pass;
  1629. } else if ((dad->cmcp_test_items == CMCP_FULL)
  1630. && (dad->cmcp_range_check == 1)) {
  1631. /*full test and basic check*/
  1632. result->test_summary = result->cm_sensor_gd_col_pass
  1633. && result->cm_sensor_gd_row_pass
  1634. && result->cm_sensor_validation_pass
  1635. && result->cp_rx_validation_pass
  1636. && result->cp_tx_validation_pass
  1637. && result->short_test_pass;
  1638. } else if (dad->cmcp_test_items == CMCP_CM_PANEL) {
  1639. /*cm panel test result only*/
  1640. result->test_summary = result->cm_sensor_gd_col_pass
  1641. && result->cm_sensor_gd_row_pass
  1642. && result->cm_sensor_validation_pass
  1643. && result->cm_sensor_row_delta_pass
  1644. && result->cm_sensor_col_delta_pass
  1645. && result->cm_sensor_calibration_pass
  1646. && result->cm_sensor_delta_pass;
  1647. } else if (dad->cmcp_test_items == CMCP_CP_PANEL) {
  1648. /*cp panel test result only*/
  1649. result->test_summary = result->cp_sensor_delta_pass
  1650. && result->cp_rx_validation_pass
  1651. && result->cp_tx_validation_pass;
  1652. } else if (dad->cmcp_test_items == CMCP_CM_BTN) {
  1653. /*cm button test result only*/
  1654. result->test_summary = result->cm_button_validation_pass
  1655. && result->cm_button_delta_pass;
  1656. } else if (dad->cmcp_test_items == CMCP_CP_BTN) {
  1657. /*cp button test result only*/
  1658. result->test_summary = result->cp_button_delta_pass
  1659. && result->cp_button_average_pass
  1660. && result->cp_button_validation_pass;
  1661. }
  1662. if (result->test_summary) {
  1663. pt_debug(dev, DL_INFO,
  1664. "%s: Finish Cm/Cp test! All Test Passed\n", __func__);
  1665. index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 1\n");
  1666. } else {
  1667. pt_debug(dev, DL_INFO,
  1668. "%s: Finish Cm/Cp test! Range Check Failure\n",
  1669. __func__);
  1670. index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 6\n");
  1671. }
  1672. goto cmcp_ready;
  1673. mismatch:
  1674. index = scnprintf(buf, PT_MAX_PRBUF_SIZE,
  1675. "Status: 2\nInput cmcp threshold file mismatches with FW\n");
  1676. goto cmcp_ready;
  1677. invalid_item_btn:
  1678. index = scnprintf(buf, PT_MAX_PRBUF_SIZE,
  1679. "Status: 3\nFW doesn't support button!\n");
  1680. goto cmcp_ready;
  1681. invalid_item:
  1682. index = scnprintf(buf, PT_MAX_PRBUF_SIZE,
  1683. "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");
  1684. goto cmcp_ready;
  1685. self_test_failed:
  1686. index = scnprintf(buf, PT_MAX_PRBUF_SIZE,
  1687. "Status: 5\nget self test ID not supported!\n");
  1688. goto cmcp_ready;
  1689. cmcp_not_ready:
  1690. index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 0\n");
  1691. goto cmcp_ready;
  1692. no_builtin:
  1693. index = scnprintf(buf, PT_MAX_PRBUF_SIZE,
  1694. "Status: 7\nNo cmcp threshold file!\n");
  1695. cmcp_ready:
  1696. mutex_lock(&dad->sysfs_lock);
  1697. dad->cmcp_test_in_progress = 0;
  1698. mutex_unlock(&dad->sysfs_lock);
  1699. exit:
  1700. return index;
  1701. }
  1702. /*******************************************************************************
  1703. * FUNCTION: pt_cmcp_test_store
  1704. *
  1705. * SUMMARY: The store method for cmcp_test sysfs node.Allows the user to
  1706. * configure which cm/cp tests will be executed on the "cat" of this node.
  1707. *
  1708. * RETURN: Size of passed in buffer
  1709. *
  1710. * PARAMETERS:
  1711. * *dev - pointer to device structure
  1712. * *attr - pointer to device attributes
  1713. * *buf - pointer to buffer that hold the command parameters
  1714. * size - size of buf
  1715. ******************************************************************************/
  1716. static ssize_t pt_cmcp_test_store(struct device *dev,
  1717. struct device_attribute *attr, const char *buf, size_t size)
  1718. {
  1719. struct pt_device_access_data *dad
  1720. = pt_get_device_access_data(dev);
  1721. u8 test_item = 0;
  1722. u8 range_check = 0;
  1723. u8 force_calibrate = 0;
  1724. u32 input_data[4];
  1725. int ret = 0;
  1726. static const char * const cmcp_test_case_array[] = {"Full Cm/Cp test",
  1727. "Cm panel test", "Cp panel test",
  1728. "Cm button test", "Cp button test"};
  1729. static const char * const cmcp_test_range_check_array[] = {
  1730. "Full (default)", "Basic"};
  1731. static const char * const cmcp_test_force_cal_array[] = {
  1732. "Calibrate When Testing (default)", "No Calibration"};
  1733. ssize_t length = 0;
  1734. pm_runtime_get_sync(dev);
  1735. mutex_lock(&dad->sysfs_lock);
  1736. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  1737. ARRAY_SIZE(input_data));
  1738. if (length <= 0 || length > 3) {
  1739. pt_debug(dev, DL_ERROR, "%s: Input format error!\n",
  1740. __func__);
  1741. dad->cmcp_test_items = -EINVAL;
  1742. ret = -EINVAL;
  1743. goto error;
  1744. }
  1745. /* Get test item */
  1746. test_item = input_data[0];
  1747. /* Get range check */
  1748. if (length >= 2)
  1749. range_check = input_data[1];
  1750. /* Get force calibration */
  1751. if (length == 3)
  1752. force_calibrate = input_data[2];
  1753. /*
  1754. * Test item limitation:
  1755. * 0: Perform all Tests
  1756. * 1: CM Panel with Gradient
  1757. * 2: CP Panel
  1758. * 3: CM Button
  1759. * 4: CP Button
  1760. * Ranage check limitation:
  1761. * 0: full check
  1762. * 1: basic check
  1763. * Force calibrate limitation:
  1764. * 0: do calibration
  1765. * 1: don't do calibration
  1766. */
  1767. if ((test_item < 0) || (test_item > 4) || (range_check > 1)
  1768. || (force_calibrate > 1)) {
  1769. pt_debug(dev, DL_ERROR,
  1770. "%s: Test item should be 0~4; Range check should be 0~1; Force calibrate should be 0~1\n",
  1771. __func__);
  1772. dad->cmcp_test_items = -EINVAL;
  1773. ret = -EINVAL;
  1774. goto error;
  1775. }
  1776. /*
  1777. * If it is not all Test, then range_check should be 0
  1778. * because other test does not has concept of basic check
  1779. */
  1780. if (test_item > 0 && test_item < 5)
  1781. range_check = 0;
  1782. dad->cmcp_test_items = test_item;
  1783. dad->cmcp_range_check = range_check;
  1784. dad->cmcp_force_calibrate = force_calibrate;
  1785. pt_debug(dev, DL_INFO,
  1786. "%s: Test item=%s; Range check=%s; Force cal=%s.\n",
  1787. __func__,
  1788. cmcp_test_case_array[test_item],
  1789. cmcp_test_range_check_array[range_check],
  1790. cmcp_test_force_cal_array[force_calibrate]);
  1791. error:
  1792. mutex_unlock(&dad->sysfs_lock);
  1793. pm_runtime_put(dev);
  1794. if (ret)
  1795. return ret;
  1796. return size;
  1797. }
  1798. static DEVICE_ATTR(cmcp_test, 0600,
  1799. pt_cmcp_test_show, pt_cmcp_test_store);
  1800. /*******************************************************************************
  1801. * FUNCTION: prepare_print_string
  1802. *
  1803. * SUMMARY: Formats input buffer to out buffer with string type,and increases
  1804. * the index by size of formated data.
  1805. *
  1806. * RETURN:
  1807. * index plus with size of formated data
  1808. *
  1809. * PARAMETERS:
  1810. * *out_buf - output buffer to store formated data
  1811. * *in_buf - input buffer to be formated
  1812. * index - index in output buffer for appending content
  1813. ******************************************************************************/
  1814. int prepare_print_string(char *out_buf, char *in_buf, int index)
  1815. {
  1816. if ((out_buf == NULL) || (in_buf == NULL))
  1817. return index;
  1818. index += scnprintf(&out_buf[index], MAX_BUF_LEN - index,
  1819. "%s", in_buf);
  1820. return index;
  1821. }
  1822. /*******************************************************************************
  1823. * FUNCTION: prepare_print_string
  1824. *
  1825. * SUMMARY: Formats input buffer to out buffer with decimal base,and increases
  1826. * the index by size of formated data.
  1827. *
  1828. * RETURN:
  1829. * index plus with size of formated data
  1830. *
  1831. * PARAMETERS:
  1832. * *out_buf - output buffer to store formated data
  1833. * *in_buf - input buffer to be formated
  1834. * index - index in output buffer for appending content
  1835. * data_num - data number in input buffer
  1836. ******************************************************************************/
  1837. int prepare_print_data(char *out_buf, int32_t *in_buf, int index, int data_num)
  1838. {
  1839. int i;
  1840. if ((out_buf == NULL) || (in_buf == NULL))
  1841. return index;
  1842. for (i = 0; i < data_num; i++)
  1843. index += scnprintf(&out_buf[index], MAX_BUF_LEN - index,
  1844. "%d,", in_buf[i]);
  1845. return index;
  1846. }
  1847. /*******************************************************************************
  1848. * FUNCTION: save_header
  1849. *
  1850. * SUMMARY: Appends "header" for cmcp test result to output buffer.
  1851. *
  1852. * RETURN:
  1853. * index plus with size of formated data
  1854. *
  1855. * PARAMETERS:
  1856. * *out_buf - output buffer to store formated data
  1857. * index - index in output buffer for appending content
  1858. * *result - pointer to result structure
  1859. ******************************************************************************/
  1860. static int save_header(char *out_buf, int index, struct result *result)
  1861. {
  1862. struct rtc_time tm;
  1863. char time_buf[100] = {0};
  1864. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
  1865. struct timespec64 ts;
  1866. ktime_get_real_ts64(&ts);
  1867. rtc_time64_to_tm(ts.tv_sec, &tm);
  1868. #else
  1869. struct timex txc;
  1870. do_gettimeofday(&(txc.time));
  1871. rtc_time_to_tm(txc.time.tv_sec, &tm);
  1872. #endif
  1873. scnprintf(time_buf, 100, "%d/%d/%d,TIME,%d:%d:%d,", tm.tm_year+1900,
  1874. tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
  1875. index = prepare_print_string(out_buf, ",.header,\n", index);
  1876. index = prepare_print_string(out_buf, ",DATE,", index);
  1877. index = prepare_print_string(out_buf, &time_buf[0], index);
  1878. index = prepare_print_string(out_buf, ",\n", index);
  1879. index = prepare_print_string(out_buf, ",SW_VERSION,", index);
  1880. index = prepare_print_string(out_buf, PT_DRIVER_VERSION, index);
  1881. index = prepare_print_string(out_buf, ",\n", index);
  1882. index = prepare_print_string(out_buf, ",.end,\n", index);
  1883. index = prepare_print_string(out_buf, ",.engineering data,\n", index);
  1884. return index;
  1885. }
  1886. /*******************************************************************************
  1887. * FUNCTION: print_silicon_id
  1888. *
  1889. * SUMMARY: Formats input buffer(silicon id) to out buffer with
  1890. * string type,and increases the index by size of formated data.
  1891. *
  1892. * RETURN:
  1893. * index plus with size of formated data
  1894. *
  1895. * PARAMETERS:
  1896. * *out_buf - output buffer to store formated data
  1897. * *in_buf - input buffer to be formated
  1898. * index - index in output buffer for appending content
  1899. ******************************************************************************/
  1900. static int print_silicon_id(char *out_buf, char *in_buf, int index)
  1901. {
  1902. index = prepare_print_string(out_buf, ",1,", index);
  1903. index = prepare_print_string(out_buf, &in_buf[0], index);
  1904. return index;
  1905. }
  1906. /*******************************************************************************
  1907. * FUNCTION: save_engineering_data
  1908. *
  1909. * SUMMARY: Generates cmcp test result with *.csv format to output buffer, but
  1910. * it doesn't include the header.
  1911. *
  1912. * RETURN:
  1913. * index plus with size of formated data
  1914. *
  1915. * PARAMETERS:
  1916. * *dev - pointer to device structure
  1917. * *out_buf - output buffer to store formated data
  1918. * index - index in output buffer for appending content
  1919. * *cmcp_info - pointer to cmcp_data structure
  1920. * *configuration - pointer to configuration structure
  1921. * *result - pointer to result structure
  1922. * test_item - test control in bitwise
  1923. * no_builtin_file - flag to determin if builtin-file exist
  1924. ******************************************************************************/
  1925. int save_engineering_data(struct device *dev, char *out_buf, int index,
  1926. struct cmcp_data *cmcp_info, struct configuration *configuration,
  1927. struct result *result, int test_item, int no_builtin_file)
  1928. {
  1929. int i;
  1930. int j;
  1931. int tx_num = 0;
  1932. int rx_num = 0;
  1933. int btn_num = 0;
  1934. int tmp = 0;
  1935. uint32_t fw_revision_control;
  1936. uint32_t fw_config_ver;
  1937. char device_id[20] = {0};
  1938. struct pt_device_access_data *dad
  1939. = pt_get_device_access_data(dev);
  1940. if ((result == NULL) || (cmcp_info == NULL))
  1941. return -EINVAL;
  1942. tx_num = cmcp_info->tx_num;
  1943. rx_num = cmcp_info->rx_num;
  1944. btn_num = cmcp_info->btn_num;
  1945. fw_revision_control = dad->si->ttdata.revctrl;
  1946. fw_config_ver = dad->si->ttdata.fw_ver_conf;
  1947. /*calculate silicon id*/
  1948. result->device_id_low = 0;
  1949. result->device_id_high = 0;
  1950. for (i = 0; i < 4; i++)
  1951. result->device_id_low =
  1952. (result->device_id_low << 8) + dad->si->ttdata.mfg_id[i];
  1953. for (i = 4; i < 8; i++)
  1954. result->device_id_high =
  1955. (result->device_id_high << 8) + dad->si->ttdata.mfg_id[i];
  1956. scnprintf(device_id, 20, "%x%x",
  1957. result->device_id_high, result->device_id_low);
  1958. /*print test summary*/
  1959. index = print_silicon_id(out_buf, &device_id[0], index);
  1960. if (result->test_summary)
  1961. index = prepare_print_string(out_buf, ",PASS,\n", index);
  1962. else
  1963. index = prepare_print_string(out_buf, ",FAIL,\n", index);
  1964. /*revision ctrl number*/
  1965. index = print_silicon_id(out_buf, &device_id[0], index);
  1966. index = prepare_print_string(out_buf, ",FW revision Control,", index);
  1967. index = prepare_print_data(out_buf, &fw_revision_control, index, 1);
  1968. index = prepare_print_string(out_buf, "\n", index);
  1969. /*config version*/
  1970. index = print_silicon_id(out_buf, &device_id[0], index);
  1971. index = prepare_print_string(out_buf, ",CONFIG_VER,", index);
  1972. index = prepare_print_data(out_buf, &fw_config_ver, index, 1);
  1973. index = prepare_print_string(out_buf, "\n", index);
  1974. /* Shorts test */
  1975. index = print_silicon_id(out_buf, &device_id[0], index);
  1976. if (result->short_test_pass)
  1977. index = prepare_print_string(out_buf, ",Shorts,PASS,\n", index);
  1978. else
  1979. index = prepare_print_string(out_buf, ",Shorts,FAIL,\n", index);
  1980. if ((test_item & CM_ENABLED) == CM_ENABLED) {
  1981. /*print BUTNS_CM_DATA_ROW00*/
  1982. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  1983. index = print_silicon_id(out_buf, &device_id[0], index);
  1984. index = prepare_print_string(out_buf,
  1985. ",Sensor Cm Validation,BUTNS_CM_DATA_ROW00,",
  1986. index);
  1987. index = prepare_print_data(out_buf,
  1988. &cmcp_info->cm_btn_data[0],
  1989. index,
  1990. btn_num);
  1991. index = prepare_print_string(out_buf, "\n", index);
  1992. }
  1993. if ((test_item & CM_PANEL) == CM_PANEL) {
  1994. /*print CM_DATA_ROW*/
  1995. for (i = 0; i < rx_num; i++) {
  1996. index = print_silicon_id(out_buf, &device_id[0],
  1997. index);
  1998. index = prepare_print_string(out_buf,
  1999. ",Sensor Cm Validation,CM_DATA_ROW",
  2000. index);
  2001. index = prepare_print_data(out_buf, &i,
  2002. index, 1);
  2003. for (j = 0; j < tx_num; j++)
  2004. index = prepare_print_data(out_buf,
  2005. &cmcp_info->cm_data_panel[j*rx_num+i],
  2006. index, 1);
  2007. index = prepare_print_string(out_buf,
  2008. "\n", index);
  2009. }
  2010. if (!no_builtin_file) {
  2011. /*print CM_MAX_GRADIENT_COLS_PERCENT*/
  2012. index = print_silicon_id(out_buf,
  2013. &device_id[0], index);
  2014. index = prepare_print_string(out_buf,
  2015. ",Sensor Cm Validation,CM_MAX_GRADIENT_COLS_PERCENT,",
  2016. index);
  2017. for (i = 0; i < tx_num; i++) {
  2018. char tmp_buf[10] = {0};
  2019. scnprintf(tmp_buf, 10, "%d.%d,",
  2020. cmcp_info->gd_sensor_col[i].gradient_val / 10,
  2021. cmcp_info->gd_sensor_col[i].gradient_val % 10);
  2022. index = prepare_print_string(out_buf,
  2023. &tmp_buf[0], index);
  2024. }
  2025. index = prepare_print_string(out_buf,
  2026. "\n", index);
  2027. /*print CM_MAX_GRADIENT_ROWS_PERCENT*/
  2028. index = print_silicon_id(out_buf,
  2029. &device_id[0], index);
  2030. index = prepare_print_string(out_buf,
  2031. ",Sensor Cm Validation,CM_MAX_GRADIENT_ROWS_PERCENT,",
  2032. index);
  2033. for (i = 0; i < rx_num; i++) {
  2034. char tmp_buf[10] = {0};
  2035. scnprintf(tmp_buf, 10, "%d.%d,",
  2036. cmcp_info->gd_sensor_row[i].gradient_val / 10,
  2037. cmcp_info->gd_sensor_row[i].gradient_val % 10);
  2038. index = prepare_print_string(out_buf,
  2039. &tmp_buf[0], index);
  2040. }
  2041. index = prepare_print_string(out_buf,
  2042. "\n", index);
  2043. if (!dad->cmcp_range_check) {
  2044. /*print CM_DELTA_COLUMN*/
  2045. for (i = 0; i < rx_num; i++) {
  2046. index = print_silicon_id(
  2047. out_buf,
  2048. &device_id[0], index);
  2049. index = prepare_print_string(
  2050. out_buf,
  2051. ",Sensor Cm Validation,DELTA_COLUMNS_ROW",
  2052. index);
  2053. index = prepare_print_data(
  2054. out_buf,
  2055. &i, index, 1);
  2056. index = prepare_print_data(
  2057. out_buf,
  2058. &tmp, index, 1);
  2059. for (j = 1; j < tx_num; j++)
  2060. index = prepare_print_data(
  2061. out_buf,
  2062. &cmcp_info->cm_sensor_column_delta[(j-1)*rx_num+i],
  2063. index, 1);
  2064. index = prepare_print_string(
  2065. out_buf,
  2066. "\n", index);
  2067. }
  2068. /*print CM_DELTA_ROW*/
  2069. index = print_silicon_id(out_buf,
  2070. &device_id[0],
  2071. index);
  2072. index = prepare_print_string(out_buf,
  2073. ",Sensor Cm Validation,DELTA_ROWS_ROW",
  2074. index);
  2075. index = prepare_print_data(out_buf,
  2076. &tmp, index, 1);
  2077. for (j = 0; j < tx_num; j++)
  2078. index = prepare_print_data(
  2079. out_buf,
  2080. &tmp, index, 1);
  2081. index = prepare_print_string(out_buf,
  2082. "\n", index);
  2083. for (i = 1; i < rx_num; i++) {
  2084. index = print_silicon_id(
  2085. out_buf,
  2086. &device_id[0],
  2087. index);
  2088. index = prepare_print_string(
  2089. out_buf,
  2090. ",Sensor Cm Validation,DELTA_ROWS_ROW",
  2091. index);
  2092. index = prepare_print_data(
  2093. out_buf, &i,
  2094. index, 1);
  2095. for (j = 0; j < tx_num; j++)
  2096. index = prepare_print_data(
  2097. out_buf,
  2098. &cmcp_info->cm_sensor_row_delta[j*rx_num+i-1],
  2099. index, 1);
  2100. index = prepare_print_string(
  2101. out_buf,
  2102. "\n", index);
  2103. }
  2104. /*print pass/fail Sensor Cm Validation*/
  2105. index = print_silicon_id(out_buf, &device_id[0],
  2106. index);
  2107. if (result->cm_test_pass)
  2108. index = prepare_print_string(out_buf,
  2109. ",Sensor Cm Validation,PASS,\n",
  2110. index);
  2111. else
  2112. index = prepare_print_string(out_buf,
  2113. ",Sensor Cm Validation,FAIL,\n",
  2114. index);
  2115. }
  2116. }
  2117. }
  2118. if (!no_builtin_file) {
  2119. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)
  2120. && (!dad->cmcp_range_check)) {
  2121. char tmp_buf[10] = {0};
  2122. /*print Button Element by Element */
  2123. index = print_silicon_id(out_buf, &device_id[0],
  2124. index);
  2125. if (result->cm_button_validation_pass)
  2126. index = prepare_print_string(out_buf,
  2127. ",Sensor Cm Validation - Button Element by Element,PASS\n",
  2128. index);
  2129. else
  2130. index = prepare_print_string(out_buf,
  2131. ",Sensor Cm Validation - Button Element by Element,FAIL\n",
  2132. index);
  2133. /*
  2134. *print Sensor Cm Validation
  2135. *- Buttons Range Buttons Range
  2136. */
  2137. index = print_silicon_id(out_buf,
  2138. &device_id[0], index);
  2139. index = prepare_print_string(out_buf,
  2140. ",Sensor Cm Validation - Buttons Range,Buttons Range,",
  2141. index);
  2142. scnprintf(tmp_buf, 10, "%d.%d,",
  2143. cmcp_info->cm_delta_data_btn / 10,
  2144. cmcp_info->cm_delta_data_btn % 10);
  2145. index = prepare_print_string(out_buf,
  2146. &tmp_buf[0], index);
  2147. index = prepare_print_string(out_buf,
  2148. "\n", index);
  2149. /*print Sensor Cm Validation
  2150. *-Buttons Range Cm_button_avg
  2151. */
  2152. index = print_silicon_id(out_buf,
  2153. &device_id[0], index);
  2154. index = prepare_print_string(out_buf,
  2155. ",Sensor Cm Validation - Buttons Range,Cm_button_avg,",
  2156. index);
  2157. index = prepare_print_data(out_buf,
  2158. &cmcp_info->cm_ave_data_btn,
  2159. index, 1);
  2160. index = prepare_print_string(out_buf,
  2161. "\n", index);
  2162. /*print Sensor Cm Validation
  2163. * -Buttons Range Cm_button_avg
  2164. */
  2165. index = print_silicon_id(out_buf,
  2166. &device_id[0], index);
  2167. index = prepare_print_string(out_buf,
  2168. ",Sensor Cm Validation - Buttons Range,Cm_button_cal,",
  2169. index);
  2170. index = prepare_print_data(out_buf,
  2171. &cmcp_info->cm_cal_data_btn,
  2172. index, 1);
  2173. index = prepare_print_string(out_buf,
  2174. "\n", index);
  2175. /*print Sensor Cm Validation
  2176. *-Buttons Range pass/fail
  2177. */
  2178. index = print_silicon_id(out_buf,
  2179. &device_id[0], index);
  2180. if (result->cm_button_delta_pass)
  2181. index = prepare_print_string(out_buf,
  2182. ",Sensor Cm Validation - Buttons Range,PASS,LIMITS,",
  2183. index);
  2184. else
  2185. index = prepare_print_string(out_buf,
  2186. ",Sensor Cm Validation - Buttons Range,FAIL,LIMITS,",
  2187. index);
  2188. index = prepare_print_data(out_buf,
  2189. &configuration->cm_max_delta_button_percent,
  2190. index, 1);
  2191. index = prepare_print_string(out_buf,
  2192. "\n", index);
  2193. }
  2194. if ((test_item & CM_PANEL) == CM_PANEL &&
  2195. !dad->cmcp_range_check) {
  2196. char tmp_buf[10] = {0};
  2197. /*print Cm_sensor_cal */
  2198. index = print_silicon_id(out_buf,
  2199. &device_id[0], index);
  2200. index = prepare_print_string(out_buf,
  2201. ",Sensor Cm Validation - Calibration,Cm_sensor_cal,",
  2202. index);
  2203. index = prepare_print_data(out_buf,
  2204. &cmcp_info->cm_cal_data_panel,
  2205. index, 1);
  2206. index = prepare_print_string(out_buf,
  2207. "\n", index);
  2208. /*print Cm_sensor_cal limit*/
  2209. index = print_silicon_id(out_buf,
  2210. &device_id[0], index);
  2211. if (result->cm_sensor_calibration_pass)
  2212. index = prepare_print_string(out_buf,
  2213. ",Sensor Cm Validation - Calibration,PASS,LIMITS,",
  2214. index);
  2215. else
  2216. index = prepare_print_string(out_buf,
  2217. ",Sensor Cm Validation - Calibration,FAIL,LIMITS,",
  2218. index);
  2219. index = prepare_print_data(out_buf,
  2220. &configuration->cm_min_limit_cal,
  2221. index, 1);
  2222. index = prepare_print_data(out_buf,
  2223. &configuration->cm_max_limit_cal,
  2224. index, 1);
  2225. index = prepare_print_string(out_buf,
  2226. "\n", index);
  2227. /*print Columns Delta Matrix*/
  2228. index = print_silicon_id(out_buf,
  2229. &device_id[0], index);
  2230. if (result->cm_sensor_col_delta_pass)
  2231. index = prepare_print_string(out_buf,
  2232. ",Sensor Cm Validation - Columns Delta Matrix,PASS,LIMITS,",
  2233. index);
  2234. else
  2235. index = prepare_print_string(out_buf,
  2236. ",Sensor Cm Validation - Columns Delta Matrix,FAIL,LIMITS,",
  2237. index);
  2238. index = prepare_print_data(out_buf,
  2239. &configuration->cm_range_limit_col,
  2240. index, 1);
  2241. index = prepare_print_string(out_buf,
  2242. "\n", index);
  2243. /*print Cm Validation - Element by Element*/
  2244. index = print_silicon_id(out_buf,
  2245. &device_id[0], index);
  2246. if (result->cm_sensor_validation_pass)
  2247. index = prepare_print_string(out_buf,
  2248. ",Sensor Cm Validation - Element by Element,PASS,",
  2249. index);
  2250. else
  2251. index = prepare_print_string(out_buf,
  2252. ",Sensor Cm Validation - Element by Element,FAIL,",
  2253. index);
  2254. index = prepare_print_string(out_buf,
  2255. "\n", index);
  2256. /*print Cm Validation -Gradient Cols*/
  2257. index = print_silicon_id(out_buf,
  2258. &device_id[0], index);
  2259. if (result->cm_sensor_gd_col_pass)
  2260. index = prepare_print_string(out_buf,
  2261. ",Sensor Cm Validation - Gradient Cols,PASS,",
  2262. index);
  2263. else
  2264. index = prepare_print_string(out_buf,
  2265. ",Sensor Cm Validation - Gradient Cols,FAIL,",
  2266. index);
  2267. index = prepare_print_string(out_buf,
  2268. "\n", index);
  2269. /*print Cm Validation -Gradient Rows*/
  2270. index = print_silicon_id(out_buf,
  2271. &device_id[0], index);
  2272. if (result->cm_sensor_gd_row_pass)
  2273. index = prepare_print_string(out_buf,
  2274. ",Sensor Cm Validation - Gradient Rows,PASS,",
  2275. index);
  2276. else
  2277. index = prepare_print_string(out_buf,
  2278. ",Sensor Cm Validation - Gradient Rows,FAIL,",
  2279. index);
  2280. index = prepare_print_string(out_buf,
  2281. "\n", index);
  2282. /*
  2283. * Print Sensor Cm Validation
  2284. * -Rows Delta Matrix
  2285. */
  2286. index = print_silicon_id(out_buf,
  2287. &device_id[0], index);
  2288. if (result->cm_sensor_row_delta_pass)
  2289. index = prepare_print_string(out_buf,
  2290. ",Sensor Cm Validation - Rows Delta Matrix,PASS,LIMITS,",
  2291. index);
  2292. else
  2293. index = prepare_print_string(out_buf,
  2294. ",Sensor Cm Validation - Rows Delta Matrix,FAIL,LIMITS,",
  2295. index);
  2296. index = prepare_print_data(out_buf,
  2297. &configuration->cm_range_limit_row,
  2298. index, 1);
  2299. index = prepare_print_string(out_buf,
  2300. "\n", index);
  2301. /*print Cm_sensor_avg */
  2302. index = print_silicon_id(out_buf,
  2303. &device_id[0], index);
  2304. index = prepare_print_string(out_buf,
  2305. ",Sensor Cm Validation - Sensor Range,Cm_sensor_avg,",
  2306. index);
  2307. index = prepare_print_data(out_buf,
  2308. &cmcp_info->cm_ave_data_panel,
  2309. index, 1);
  2310. index = prepare_print_string(out_buf,
  2311. "\n", index);
  2312. /*printSensor Cm Validation -
  2313. * Sensor Range, Sensor Range
  2314. */
  2315. index = print_silicon_id(out_buf,
  2316. &device_id[0], index);
  2317. index = prepare_print_string(out_buf,
  2318. ",Sensor Cm Validation - Sensor Range,Sensor Range,",
  2319. index);
  2320. scnprintf(tmp_buf, 10, "%d.%d,",
  2321. cmcp_info->cm_sensor_delta / 10,
  2322. cmcp_info->cm_sensor_delta % 10);
  2323. index = prepare_print_string(out_buf,
  2324. &tmp_buf[0], index);
  2325. index = prepare_print_string(out_buf,
  2326. "\n", index);
  2327. /*print Sensor Cm Validation - Sensor Range*/
  2328. index = print_silicon_id(out_buf,
  2329. &device_id[0], index);
  2330. if (result->cm_sensor_delta_pass)
  2331. index = prepare_print_string(out_buf,
  2332. ",Sensor Cm Validation - Sensor Range,PASS,LIMITS,",
  2333. index);
  2334. else
  2335. index = prepare_print_string(out_buf,
  2336. ",Sensor Cm Validation - Sensor Range,FAIL,LIMITS,",
  2337. index);
  2338. index = prepare_print_data(out_buf,
  2339. &configuration->cm_max_delta_sensor_percent,
  2340. index, 1);
  2341. index = prepare_print_string(out_buf,
  2342. "\n", index);
  2343. }
  2344. }
  2345. }
  2346. if ((test_item & CP_ENABLED) == CP_ENABLED) {
  2347. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2348. /*print BUTNS_CP_DATA_ROW00 */
  2349. index = print_silicon_id(out_buf, &device_id[0], index);
  2350. index = prepare_print_string(out_buf,
  2351. ",Self-cap Calibration Check,BUTNS_CP_DATA_ROW00,",
  2352. index);
  2353. index = prepare_print_data(out_buf,
  2354. &cmcp_info->cp_btn_data[0],
  2355. index, btn_num);
  2356. index = prepare_print_string(out_buf,
  2357. "\n", index);
  2358. if (!no_builtin_file && !dad->cmcp_range_check) {
  2359. /*print Cp Button Element by Element */
  2360. index = print_silicon_id(out_buf, &device_id[0],
  2361. index);
  2362. if (result->cp_button_validation_pass)
  2363. index = prepare_print_string(out_buf,
  2364. ",Self-cap Calibration Check - Button Element by Element,PASS\n",
  2365. index);
  2366. else
  2367. index = prepare_print_string(out_buf,
  2368. ",Self-cap Calibration Check - Button Element by Element,FAIL\n",
  2369. index);
  2370. /*print cp_button_ave */
  2371. index = print_silicon_id(out_buf,
  2372. &device_id[0], index);
  2373. index = prepare_print_string(out_buf,
  2374. ",Self-cap Calibration Check,Cp_button_avg,",
  2375. index);
  2376. index = prepare_print_data(out_buf,
  2377. &cmcp_info->cp_button_ave,
  2378. index, 1);
  2379. index = prepare_print_string(out_buf,
  2380. "\n", index);
  2381. /*print Cp_button_cal */
  2382. index = print_silicon_id(out_buf,
  2383. &device_id[0], index);
  2384. index = prepare_print_string(out_buf,
  2385. ",Self-cap Calibration Check,Cp_button_cal,",
  2386. index);
  2387. index = prepare_print_data(out_buf,
  2388. &cmcp_info->cp_btn_cal,
  2389. index, 1);
  2390. index = prepare_print_string(out_buf,
  2391. "\n", index);
  2392. }
  2393. }
  2394. if ((test_item & CP_PANEL) == CP_PANEL) {
  2395. /*print CP_DATA_RX */
  2396. index = print_silicon_id(out_buf, &device_id[0], index);
  2397. index = prepare_print_string(out_buf,
  2398. ",Self-cap Calibration Check,CP_DATA_RX,", index);
  2399. index = prepare_print_data(out_buf,
  2400. &cmcp_info->cp_rx_data_panel[0], index, rx_num);
  2401. index = prepare_print_string(out_buf, "\n", index);
  2402. /*print CP_DATA_TX */
  2403. index = print_silicon_id(out_buf, &device_id[0], index);
  2404. index = prepare_print_string(out_buf,
  2405. ",Self-cap Calibration Check,CP_DATA_TX,", index);
  2406. index = prepare_print_data(out_buf,
  2407. &cmcp_info->cp_tx_data_panel[0], index, tx_num);
  2408. index = prepare_print_string(out_buf, "\n", index);
  2409. }
  2410. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)
  2411. && !dad->cmcp_range_check) {
  2412. if (!no_builtin_file) {
  2413. char tmp_buf[10] = {0};
  2414. /*print Cp_delta_button */
  2415. index = print_silicon_id(out_buf, &device_id[0],
  2416. index);
  2417. index = prepare_print_string(out_buf,
  2418. ",Self-cap Calibration Check,Cp_delta_button,",
  2419. index);
  2420. scnprintf(tmp_buf, 10, "%d.%d,",
  2421. cmcp_info->cp_button_delta / 10,
  2422. cmcp_info->cp_button_delta % 10);
  2423. index = prepare_print_string(out_buf,
  2424. &tmp_buf[0], index);
  2425. index = prepare_print_string(out_buf, "\n",
  2426. index);
  2427. }
  2428. }
  2429. if ((test_item & CP_PANEL) == CP_PANEL &&
  2430. !dad->cmcp_range_check) {
  2431. if (!no_builtin_file) {
  2432. char tmp_buf[10] = {0};
  2433. /*print Cp_delta_rx */
  2434. index = print_silicon_id(out_buf, &device_id[0],
  2435. index);
  2436. index = prepare_print_string(out_buf,
  2437. ",Self-cap Calibration Check,Cp_delta_rx,",
  2438. index);
  2439. scnprintf(tmp_buf, 10, "%d.%d,",
  2440. cmcp_info->cp_sensor_rx_delta / 10,
  2441. cmcp_info->cp_sensor_rx_delta % 10);
  2442. index = prepare_print_string(out_buf,
  2443. &tmp_buf[0], index);
  2444. index = prepare_print_string(out_buf, "\n",
  2445. index);
  2446. /*print Cp_delta_tx */
  2447. index = print_silicon_id(out_buf, &device_id[0],
  2448. index);
  2449. index = prepare_print_string(out_buf,
  2450. ",Self-cap Calibration Check,Cp_delta_tx,",
  2451. index);
  2452. scnprintf(tmp_buf, 10, "%d.%d,",
  2453. cmcp_info->cp_sensor_tx_delta / 10,
  2454. cmcp_info->cp_sensor_tx_delta % 10);
  2455. index = prepare_print_string(out_buf,
  2456. &tmp_buf[0], index);
  2457. index = prepare_print_string(out_buf, "\n",
  2458. index);
  2459. /*print Cp_sensor_avg_rx */
  2460. index = print_silicon_id(out_buf, &device_id[0],
  2461. index);
  2462. index = prepare_print_string(out_buf,
  2463. ",Self-cap Calibration Check,Cp_sensor_avg_rx,",
  2464. index);
  2465. index = prepare_print_data(out_buf,
  2466. &cmcp_info->cp_rx_ave_data_panel,
  2467. index, 1);
  2468. index = prepare_print_string(out_buf,
  2469. "\n", index);
  2470. /*print Cp_sensor_avg_tx */
  2471. index = print_silicon_id(out_buf,
  2472. &device_id[0], index);
  2473. index = prepare_print_string(out_buf,
  2474. ",Self-cap Calibration Check,Cp_sensor_avg_tx,",
  2475. index);
  2476. index = prepare_print_data(out_buf,
  2477. &cmcp_info->cp_tx_ave_data_panel,
  2478. index, 1);
  2479. index = prepare_print_string(out_buf,
  2480. "\n", index);
  2481. /*print Cp_sensor_cal_rx */
  2482. index = print_silicon_id(out_buf,
  2483. &device_id[0], index);
  2484. index = prepare_print_string(out_buf,
  2485. ",Self-cap Calibration Check,Cp_sensor_cal_rx,",
  2486. index);
  2487. index = prepare_print_data(out_buf,
  2488. &cmcp_info->cp_rx_cal_data_panel[0],
  2489. index, rx_num);
  2490. index = prepare_print_string(out_buf,
  2491. "\n", index);
  2492. /*print Cp_sensor_cal_tx */
  2493. index = print_silicon_id(out_buf,
  2494. &device_id[0], index);
  2495. index = prepare_print_string(out_buf,
  2496. ",Self-cap Calibration Check,Cp_sensor_cal_tx,",
  2497. index);
  2498. index = prepare_print_data(out_buf,
  2499. &cmcp_info->cp_tx_cal_data_panel[0],
  2500. index, tx_num);
  2501. index = prepare_print_string(out_buf,
  2502. "\n", index);
  2503. }
  2504. }
  2505. if (!no_builtin_file && !dad->cmcp_range_check) {
  2506. /*print cp test limits */
  2507. index = print_silicon_id(out_buf, &device_id[0], index);
  2508. if (result->cp_test_pass)
  2509. index = prepare_print_string(out_buf,
  2510. ",Self-cap Calibration Check,PASS, LIMITS,",
  2511. index);
  2512. else
  2513. index = prepare_print_string(out_buf,
  2514. ",Self-cap Calibration Check,FAIL, LIMITS,",
  2515. index);
  2516. index = prepare_print_string(out_buf,
  2517. "CP_MAX_DELTA_SENSOR_RX_PERCENT,", index);
  2518. index = prepare_print_data(out_buf,
  2519. &configuration->cp_max_delta_sensor_rx_percent,
  2520. index, 1);
  2521. index = prepare_print_string(out_buf,
  2522. "CP_MAX_DELTA_SENSOR_TX_PERCENT,", index);
  2523. index = prepare_print_data(out_buf,
  2524. &configuration->cp_max_delta_sensor_tx_percent,
  2525. index, 1);
  2526. index = prepare_print_string(out_buf,
  2527. "CP_MAX_DELTA_BUTTON_PERCENT,", index);
  2528. index = prepare_print_data(out_buf,
  2529. &configuration->cp_max_delta_button_percent,
  2530. index, 1);
  2531. index = prepare_print_string(out_buf, "\n", index);
  2532. }
  2533. }
  2534. if (!no_builtin_file) {
  2535. if ((test_item & CM_ENABLED) == CM_ENABLED) {
  2536. if ((test_item & CM_PANEL) == CM_PANEL) {
  2537. /*print columns gradient limit*/
  2538. index = prepare_print_string(out_buf,
  2539. ",Sensor Cm Validation,MAX_LIMITS,CM_MAX_GRADIENT_COLS_PERCENT,",
  2540. index);
  2541. index = prepare_print_data(out_buf,
  2542. &configuration->cm_max_table_gradient_cols_percent[0],
  2543. index,
  2544. configuration->cm_max_table_gradient_cols_percent_size);
  2545. index = prepare_print_string(out_buf,
  2546. "\n", index);
  2547. /*print rows gradient limit*/
  2548. index = prepare_print_string(out_buf,
  2549. ",Sensor Cm Validation,MAX_LIMITS,CM_MAX_GRADIENT_ROWS_PERCENT,",
  2550. index);
  2551. index = prepare_print_data(out_buf,
  2552. &configuration->cm_max_table_gradient_rows_percent[0],
  2553. index,
  2554. configuration->cm_max_table_gradient_rows_percent_size);
  2555. index = prepare_print_string(out_buf,
  2556. "\n", index);
  2557. /*print cm max limit*/
  2558. for (i = 0; i < rx_num; i++) {
  2559. index = prepare_print_string(out_buf,
  2560. ",Sensor Cm Validation,MAX_LIMITS,CM_DATA_ROW",
  2561. index);
  2562. index = prepare_print_data(out_buf,
  2563. &i, index, 1);
  2564. for (j = 0; j < tx_num; j++)
  2565. index = prepare_print_data(
  2566. out_buf,
  2567. &configuration->cm_min_max_table_sensor[i*tx_num*2+j*2+1],
  2568. index, 1);
  2569. index = prepare_print_string(out_buf,
  2570. "\n", index);
  2571. }
  2572. }
  2573. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  2574. index = prepare_print_string(out_buf,
  2575. ",Sensor Cm Validation,MAX LIMITS,M_BUTNS,",
  2576. index);
  2577. for (j = 0; j < btn_num; j++) {
  2578. index = prepare_print_data(out_buf,
  2579. &configuration->cm_min_max_table_btn[2*j+1],
  2580. index, 1);
  2581. }
  2582. index = prepare_print_string(out_buf,
  2583. "\n", index);
  2584. }
  2585. index = prepare_print_string(out_buf,
  2586. ",Sensor Cm Validation MAX LIMITS\n", index);
  2587. if ((test_item & CM_PANEL) == CM_PANEL) {
  2588. /*print cm min limit*/
  2589. for (i = 0; i < rx_num; i++) {
  2590. index = prepare_print_string(out_buf,
  2591. ",Sensor Cm Validation,MIN_LIMITS,CM_DATA_ROW",
  2592. index);
  2593. index = prepare_print_data(out_buf, &i,
  2594. index, 1);
  2595. for (j = 0; j < tx_num; j++)
  2596. index = prepare_print_data(
  2597. out_buf,
  2598. &configuration->cm_min_max_table_sensor[i*tx_num*2 + j*2],
  2599. index, 1);
  2600. index = prepare_print_string(out_buf,
  2601. "\n", index);
  2602. }
  2603. }
  2604. if (((test_item & CM_BTN) == CM_BTN) && (btn_num > 0)) {
  2605. index = prepare_print_string(out_buf,
  2606. ",Sensor Cm Validation,MIN LIMITS,M_BUTNS,",
  2607. index);
  2608. for (j = 0; j < btn_num; j++) {
  2609. index = prepare_print_data(out_buf,
  2610. &configuration->cm_min_max_table_btn[2*j],
  2611. index, 1);
  2612. }
  2613. index = prepare_print_string(out_buf,
  2614. "\n", index);
  2615. }
  2616. index = prepare_print_string(out_buf,
  2617. ",Sensor Cm Validation MIN LIMITS\n", index);
  2618. }
  2619. if ((test_item & CP_ENABLED) == CP_ENABLED) {
  2620. if ((test_item & CP_PANEL) == CP_PANEL) {
  2621. /*print cp tx max limit*/
  2622. index = prepare_print_string(out_buf,
  2623. ",Self-cap Calibration Check,MAX_LIMITS,TX,",
  2624. index);
  2625. for (i = 0; i < tx_num; i++)
  2626. index = prepare_print_data(out_buf,
  2627. &configuration->cp_min_max_table_tx[i*2+1],
  2628. index, 1);
  2629. index = prepare_print_string(out_buf,
  2630. "\n", index);
  2631. /*print cp rx max limit*/
  2632. index = prepare_print_string(out_buf,
  2633. ",Self-cap Calibration Check,MAX_LIMITS,RX,",
  2634. index);
  2635. for (i = 0; i < rx_num; i++)
  2636. index = prepare_print_data(out_buf,
  2637. &configuration->cp_min_max_table_rx[i*2+1],
  2638. index, 1);
  2639. index = prepare_print_string(out_buf,
  2640. "\n", index);
  2641. }
  2642. /*print cp btn max limit*/
  2643. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2644. index = prepare_print_string(out_buf,
  2645. ",Self-cap Calibration Check,MAX_LIMITS,S_BUTNS,",
  2646. index);
  2647. for (i = 0; i < btn_num; i++)
  2648. index = prepare_print_data(out_buf,
  2649. &configuration->cp_min_max_table_btn[i*2+1],
  2650. index, 1);
  2651. index = prepare_print_string(out_buf,
  2652. "\n", index);
  2653. }
  2654. if ((test_item & CP_PANEL) == CP_PANEL) {
  2655. /*print cp tx min limit*/
  2656. index = prepare_print_string(out_buf,
  2657. ",Self-cap Calibration Check,MIN_LIMITS,TX,",
  2658. index);
  2659. for (i = 0; i < tx_num; i++)
  2660. index = prepare_print_data(out_buf,
  2661. &configuration->cp_min_max_table_tx[i*2],
  2662. index, 1);
  2663. index = prepare_print_string(out_buf,
  2664. "\n", index);
  2665. /*print cp rx min limit*/
  2666. index = prepare_print_string(out_buf,
  2667. ",Self-cap Calibration Check,MIN_LIMITS,RX,",
  2668. index);
  2669. for (i = 0; i < rx_num; i++)
  2670. index = prepare_print_data(out_buf,
  2671. &configuration->cp_min_max_table_rx[i*2],
  2672. index, 1);
  2673. index = prepare_print_string(out_buf,
  2674. "\n", index);
  2675. }
  2676. /*print cp btn min limit*/
  2677. if (((test_item & CP_BTN) == CP_BTN) && (btn_num > 0)) {
  2678. index = prepare_print_string(out_buf,
  2679. ",Self-cap Calibration Check,MIN_LIMITS,S_BUTNS,",
  2680. index);
  2681. for (i = 0; i < btn_num; i++)
  2682. index = prepare_print_data(out_buf,
  2683. &configuration->cp_min_max_table_btn[i*2],
  2684. index, 1);
  2685. index = prepare_print_string(out_buf,
  2686. "\n", index);
  2687. }
  2688. }
  2689. }
  2690. return index;
  2691. }
  2692. /*******************************************************************************
  2693. * FUNCTION: result_save
  2694. *
  2695. * SUMMARY: Malloc memory for output buffer and populate with the cmcp test
  2696. * header and results in the csv file format.
  2697. *
  2698. * NOTE: It supports simple_read_from_buffer() to read data multiple times to
  2699. * the buffer.
  2700. *
  2701. * RETURN:
  2702. * Size of data printed to "buf"
  2703. *
  2704. * PARAMETERS:
  2705. * *dev - pointer to device structure
  2706. * *buf - the user space buffer to read to
  2707. * *configuration - pointer to configuration structure
  2708. * *result - pointer to result structure
  2709. * *cmcp_info - pointer to cmcp_data structure
  2710. * *ppos - the current position in the buffer
  2711. * count - the maximum number of bytes to read
  2712. * test_item - test control in bitwise
  2713. * no_builtin_file - flag to determine if builtin-file exist
  2714. ******************************************************************************/
  2715. int result_save(struct device *dev, char *buf,
  2716. struct configuration *configuration, struct result *result,
  2717. struct cmcp_data *cmcp_info, loff_t *ppos, size_t count, int test_item,
  2718. int no_builtin_file)
  2719. {
  2720. u8 *out_buf = NULL;
  2721. int index = 0;
  2722. int byte_left;
  2723. out_buf = kzalloc(MAX_BUF_LEN, GFP_KERNEL);
  2724. if (configuration == NULL) {
  2725. pt_debug(dev, DL_WARN, "config is NULL");
  2726. return -ENOMEM;
  2727. }
  2728. if (result == NULL) {
  2729. pt_debug(dev, DL_WARN, "result is NULL");
  2730. return -ENOMEM;
  2731. }
  2732. if (cmcp_info == NULL) {
  2733. pt_debug(dev, DL_WARN, "cmcp_info is NULL");
  2734. return -ENOMEM;
  2735. }
  2736. index = save_header(out_buf, index, result);
  2737. index = save_engineering_data(dev, out_buf, index,
  2738. cmcp_info, configuration, result,
  2739. test_item, no_builtin_file);
  2740. byte_left = simple_read_from_buffer(buf, count, ppos, out_buf, index);
  2741. kfree(out_buf);
  2742. return byte_left;
  2743. }
  2744. /*******************************************************************************
  2745. * FUNCTION: cmcp_results_debugfs_open
  2746. *
  2747. * SUMMARY: Open method for cmcp_results debugfs node.
  2748. *
  2749. * RETURN: 0 = success
  2750. *
  2751. * PARAMETERS:
  2752. * *inode - file inode number
  2753. * *filp - file pointer to debugfs file
  2754. ******************************************************************************/
  2755. static int cmcp_results_debugfs_open(struct inode *inode,
  2756. struct file *filp)
  2757. {
  2758. filp->private_data = inode->i_private;
  2759. return 0;
  2760. }
  2761. /*******************************************************************************
  2762. * FUNCTION: cmcp_results_debugfs_close
  2763. *
  2764. * SUMMARY: Close method for cmcp_results debugfs node.
  2765. *
  2766. * RETURN: 0 = success
  2767. *
  2768. * PARAMETERS:
  2769. * *inode - file inode number
  2770. * *filp - file pointer to debugfs file
  2771. ******************************************************************************/
  2772. static int cmcp_results_debugfs_close(struct inode *inode,
  2773. struct file *filp)
  2774. {
  2775. filp->private_data = NULL;
  2776. return 0;
  2777. }
  2778. /*******************************************************************************
  2779. * FUNCTION: cmcp_results_debugfs_read
  2780. *
  2781. * SUMMARY: Read method for cmcp_results debugfs node. This function prints
  2782. * cmcp test results to user buffer.
  2783. *
  2784. * RETURN: Size of debugfs data print
  2785. *
  2786. * PARAMETERS:
  2787. * *filp - file pointer to debugfs file
  2788. * *buf - the user space buffer to read to
  2789. * count - the maximum number of bytes to read
  2790. * *ppos - the current position in the buffer
  2791. ******************************************************************************/
  2792. static ssize_t cmcp_results_debugfs_read(struct file *filp,
  2793. char __user *buf, size_t count, loff_t *ppos)
  2794. {
  2795. struct pt_device_access_data *dad = filp->private_data;
  2796. struct device *dev;
  2797. struct cmcp_data *cmcp_info = dad->cmcp_info;
  2798. struct result *result = dad->result;
  2799. struct configuration *configuration = dad->configs;
  2800. int ret = 0;
  2801. int test_item;
  2802. int no_builtin_file = 0;
  2803. int test_executed = 0;
  2804. dev = dad->dev;
  2805. mutex_lock(&dad->sysfs_lock);
  2806. test_executed = dad->test_executed;
  2807. test_item = pt_cmcp_get_test_item(dad->cmcp_test_items);
  2808. if (dad->builtin_cmcp_threshold_status < 0) {
  2809. pt_debug(dev, DL_WARN,
  2810. "%s: No cmcp threshold file.\n", __func__);
  2811. no_builtin_file = 1;
  2812. }
  2813. mutex_unlock(&dad->sysfs_lock);
  2814. if (test_executed)
  2815. /*save result to buf*/
  2816. ret = result_save(dev, buf, configuration, result, cmcp_info,
  2817. ppos, count, test_item, no_builtin_file);
  2818. else {
  2819. char warning_info[] =
  2820. "No test result available!\n";
  2821. pt_debug(dev, DL_ERROR,
  2822. "%s: No test result available!\n", __func__);
  2823. return simple_read_from_buffer(buf, count, ppos, warning_info,
  2824. strlen(warning_info));
  2825. }
  2826. return ret;
  2827. }
  2828. static const struct file_operations cmcp_results_debugfs_fops = {
  2829. .open = cmcp_results_debugfs_open,
  2830. .release = cmcp_results_debugfs_close,
  2831. .read = cmcp_results_debugfs_read,
  2832. .write = NULL,
  2833. };
  2834. /*******************************************************************************
  2835. * FUNCTION: cmcp_return_offset_of_new_case
  2836. *
  2837. * SUMMARY: Returns the buffer offset of new test case
  2838. *
  2839. * NOTE: There are two static variable inside this function.
  2840. *
  2841. * RETURN: offset index for new case
  2842. *
  2843. * PARAMETERS:
  2844. * *bufPtr - pointer to input buffer
  2845. * first_time - flag to initialize some static variable
  2846. * (0:init; 1:don't init)
  2847. * *pFileEnd - pointer to the end of file for safe check
  2848. ******************************************************************************/
  2849. u32 cmcp_return_offset_of_new_case(const char *bufPtr, u32 first_time,
  2850. const char *pFileEnd)
  2851. {
  2852. static u32 offset, first_search;
  2853. if (first_time == 0) {
  2854. first_search = 0;
  2855. offset = 0;
  2856. }
  2857. if (first_search != 0) {
  2858. /* Search one case */
  2859. for (;;) {
  2860. /* Search ASCII_LF */
  2861. while (bufPtr < pFileEnd) {
  2862. if (*bufPtr++ != ASCII_LF)
  2863. offset++;
  2864. else
  2865. break;
  2866. }
  2867. if (bufPtr >= pFileEnd)
  2868. break;
  2869. offset++;
  2870. /*
  2871. * Single line: end loop
  2872. * Multiple lines: continue loop
  2873. */
  2874. if (*bufPtr != ASCII_COMMA)
  2875. break;
  2876. }
  2877. } else
  2878. first_search = 1;
  2879. return offset;
  2880. }
  2881. /*******************************************************************************
  2882. * FUNCTION: cmcp_get_case_info_from_threshold_file
  2883. *
  2884. * SUMMARY: Gets test case information from cmcp threshold file
  2885. *
  2886. * RETURN:
  2887. * Number of test cases
  2888. *
  2889. * PARAMETERS:
  2890. * *dev - pointer to Device structure
  2891. * *buf - pointer to input file
  2892. * *search_array - pointer to test_case_search structure
  2893. * file_size - size of input file for safe check
  2894. ******************************************************************************/
  2895. u32 cmcp_get_case_info_from_threshold_file(struct device *dev, const char *buf,
  2896. struct test_case_search *search_array, u32 file_size)
  2897. {
  2898. u32 case_num = 0, buffer_offset = 0, name_count = 0, first_search = 0;
  2899. const char *pFileEnd = buf + file_size;
  2900. pt_debug(dev, DL_INFO, "%s: Search cmcp threshold file\n",
  2901. __func__);
  2902. /* Get all the test cases */
  2903. for (case_num = 0; case_num < MAX_CASE_NUM; case_num++) {
  2904. buffer_offset =
  2905. cmcp_return_offset_of_new_case(&buf[buffer_offset],
  2906. first_search, pFileEnd);
  2907. first_search = 1;
  2908. if (buf[buffer_offset] == 0)
  2909. break;
  2910. for (name_count = 0; name_count < NAME_SIZE_MAX; name_count++) {
  2911. /* File end */
  2912. if (buf[buffer_offset + name_count] == ASCII_COMMA)
  2913. break;
  2914. search_array[case_num].name[name_count] =
  2915. buf[buffer_offset + name_count];
  2916. }
  2917. /* Exit when buffer offset is larger than file size */
  2918. if (buffer_offset >= file_size)
  2919. break;
  2920. search_array[case_num].name_size = name_count;
  2921. search_array[case_num].offset = buffer_offset;
  2922. /*
  2923. * pt_debug(dev, DL_INFO, "Find case %d: Name is %s;
  2924. * Name size is %d; Case offset is %d\n",
  2925. * case_num,
  2926. * search_array[case_num].name,
  2927. * search_array[case_num].name_size,
  2928. * search_array[case_num].offset);
  2929. */
  2930. }
  2931. return case_num;
  2932. }
  2933. /*******************************************************************************
  2934. * FUNCTION: cmcp_compose_data
  2935. *
  2936. * SUMMARY: Composes one value based on data of each bit
  2937. *
  2938. * RETURN:
  2939. * Value that composed from buffer
  2940. *
  2941. * PARAMETERS:
  2942. * *buf - pointer to input file
  2943. * count - number of data elements in *buf in decimal
  2944. ******************************************************************************/
  2945. int cmcp_compose_data(char *buf, u32 count)
  2946. {
  2947. u32 base_array[] = {1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9};
  2948. int value = 0;
  2949. u32 index = 0;
  2950. for (index = 0; index < count; index++)
  2951. value += buf[index] * base_array[count - 1 - index];
  2952. return value;
  2953. }
  2954. /*******************************************************************************
  2955. * FUNCTION: cmcp_return_one_value
  2956. *
  2957. * SUMMARY: Parses csv file at a given row and offset and combines multiple
  2958. * "bits' as a single value. Handles data over multiple lines and various
  2959. * end-of-line characters.
  2960. *
  2961. * NOTE: There is a static value to calculate line count inside this function.
  2962. *
  2963. * RETURN:
  2964. * Value that parsed from buffer
  2965. *
  2966. * PARAMETERS:
  2967. * *dev - pointer to devices structure
  2968. * *buf - pointer to input buffer
  2969. * *offset - offset index of input buffer
  2970. * *line_num - store line count
  2971. * pFileEnd - pointer to the end of threshold file
  2972. ******************************************************************************/
  2973. int cmcp_return_one_value(struct device *dev, const char *buf, u32 *offset,
  2974. u32 *line_num, const char *pFileEnd)
  2975. {
  2976. int value = -1;
  2977. char tmp_buffer[10];
  2978. u32 count = 0;
  2979. u32 tmp_offset = *offset;
  2980. static u32 line_count = 1;
  2981. /* Bypass extra commas */
  2982. while (((buf + tmp_offset + 1) < pFileEnd)
  2983. && buf[tmp_offset] == ASCII_COMMA
  2984. && buf[tmp_offset + 1] == ASCII_COMMA)
  2985. tmp_offset++;
  2986. if ((buf + tmp_offset + 1) >= pFileEnd)
  2987. goto exit;
  2988. /* Windows and Linux difference at the end of one line */
  2989. if (buf[tmp_offset] == ASCII_COMMA && buf[tmp_offset + 1] == ASCII_CR) {
  2990. if ((buf + tmp_offset + 2) < pFileEnd) {
  2991. if (buf[tmp_offset + 2] == ASCII_LF)
  2992. tmp_offset += 2;
  2993. } else
  2994. goto exit;
  2995. } else if (buf[tmp_offset] == ASCII_COMMA &&
  2996. buf[tmp_offset + 1] == ASCII_LF)
  2997. tmp_offset += 1;
  2998. else if (buf[tmp_offset] == ASCII_COMMA
  2999. && buf[tmp_offset + 1] == ASCII_CR)
  3000. tmp_offset += 1;
  3001. if ((buf + tmp_offset + 1) >= pFileEnd)
  3002. goto exit;
  3003. /* New line for multiple lines */
  3004. if ((buf[tmp_offset] == ASCII_LF || buf[tmp_offset] == ASCII_CR) &&
  3005. buf[tmp_offset + 1] == ASCII_COMMA) {
  3006. tmp_offset++;
  3007. line_count++;
  3008. pt_debug(dev, DL_DEBUG, "%s: Line Count = %d\n",
  3009. __func__, line_count);
  3010. }
  3011. /* Beginning */
  3012. if (buf[tmp_offset] == ASCII_COMMA) {
  3013. tmp_offset++;
  3014. for (;;) {
  3015. if ((buf + tmp_offset) >= pFileEnd)
  3016. break;
  3017. if ((buf[tmp_offset] >= ASCII_ZERO)
  3018. && (buf[tmp_offset] <= ASCII_NINE)) {
  3019. tmp_buffer[count++] =
  3020. buf[tmp_offset] - ASCII_ZERO;
  3021. tmp_offset++;
  3022. } else {
  3023. if (count != 0) {
  3024. value = cmcp_compose_data(tmp_buffer,
  3025. count);
  3026. /*pt_debug(dev, DL_DEBUG, */
  3027. /* ",%d", value);*/
  3028. } else {
  3029. /* 0 indicates no data available */
  3030. value = -1;
  3031. }
  3032. break;
  3033. }
  3034. }
  3035. } else {
  3036. /* Multiple line: line count */
  3037. if (line_num)
  3038. *line_num = line_count;
  3039. /* Reset for next case */
  3040. line_count = 1;
  3041. }
  3042. exit:
  3043. *offset = tmp_offset;
  3044. return value;
  3045. }
  3046. /*******************************************************************************
  3047. * FUNCTION: cmcp_get_configuration_info
  3048. *
  3049. * SUMMARY: Gets cmcp configuration information.
  3050. *
  3051. * PARAMETERS:
  3052. * *dev - pointer to devices structure
  3053. * *buf - pointer to input buffer
  3054. * *search_array - pointer to test_case_search structure
  3055. * case_count - number of test cases
  3056. * *field_array - pointer to test_case_field structure
  3057. * *config - pointer to configuration structure
  3058. * file_size - file size of threshold file
  3059. ******************************************************************************/
  3060. void cmcp_get_configuration_info(struct device *dev,
  3061. const char *buf, struct test_case_search *search_array,
  3062. u32 case_count, struct test_case_field *field_array,
  3063. struct configuration *config, u32 file_size)
  3064. {
  3065. u32 count = 0, sub_count = 0;
  3066. u32 exist_or_not = 0;
  3067. u32 value_offset = 0;
  3068. int retval = 0;
  3069. u32 data_num = 0;
  3070. u32 line_num = 1;
  3071. const char *pFileEnd = buf + file_size;
  3072. pt_debug(dev, DL_INFO,
  3073. "%s: Fill configuration struct per cmcp threshold file\n",
  3074. __func__);
  3075. /* Search cases */
  3076. for (count = 0; count < MAX_CASE_NUM; count++) {
  3077. exist_or_not = 0;
  3078. for (sub_count = 0; sub_count < case_count; sub_count++) {
  3079. if (!strncmp(field_array[count].name,
  3080. search_array[sub_count].name,
  3081. field_array[count].name_size)) {
  3082. exist_or_not = 1;
  3083. break;
  3084. }
  3085. }
  3086. field_array[count].exist_or_not = exist_or_not;
  3087. pt_debug(dev, DL_DEBUG,
  3088. "%s: Field Array[%d] exists: %d, type: %d\n",
  3089. __func__, count, exist_or_not, field_array[count].type);
  3090. /* Clear data number */
  3091. data_num = 0;
  3092. if (exist_or_not == 1) {
  3093. switch (field_array[count].type) {
  3094. case TEST_CASE_TYPE_NO:
  3095. field_array[count].data_num = 0;
  3096. field_array[count].line_num = 1;
  3097. break;
  3098. case TEST_CASE_TYPE_ONE:
  3099. value_offset = search_array[sub_count].offset
  3100. + search_array[sub_count].name_size;
  3101. *field_array[count].bufptr =
  3102. cmcp_return_one_value(dev, buf,
  3103. &value_offset, 0, pFileEnd);
  3104. field_array[count].data_num = 1;
  3105. field_array[count].line_num = 1;
  3106. break;
  3107. case TEST_CASE_TYPE_MUL:
  3108. case TEST_CASE_TYPE_MUL_LINES:
  3109. line_num = 1;
  3110. value_offset = search_array[sub_count].offset
  3111. + search_array[sub_count].name_size;
  3112. for (;;) {
  3113. retval = cmcp_return_one_value(
  3114. dev, buf, &value_offset, &line_num,
  3115. pFileEnd);
  3116. if (retval >= 0) {
  3117. *field_array[count].bufptr++ =
  3118. retval;
  3119. data_num++;
  3120. } else
  3121. break;
  3122. }
  3123. field_array[count].data_num = data_num;
  3124. field_array[count].line_num = line_num;
  3125. break;
  3126. default:
  3127. break;
  3128. }
  3129. pt_debug(dev, DL_DEBUG,
  3130. "%s: %s: Data count is %d, line number is %d\n",
  3131. __func__,
  3132. field_array[count].name,
  3133. field_array[count].data_num,
  3134. field_array[count].line_num);
  3135. } else
  3136. pt_debug(dev, DL_ERROR, "%s: !!! %s doesn't exist\n",
  3137. __func__, field_array[count].name);
  3138. }
  3139. }
  3140. /*******************************************************************************
  3141. * FUNCTION: cmcp_get_basic_info
  3142. *
  3143. * SUMMARY: Gets basic information for cmcp test, such as available test item,
  3144. * number of tx, rx, button.
  3145. *
  3146. * PARAMETERS:
  3147. * *dev - pointer to devices structure
  3148. * *field_array - pointer to test_case_field structure
  3149. * *config - pointer to configuration structure
  3150. ******************************************************************************/
  3151. void cmcp_get_basic_info(struct device *dev,
  3152. struct test_case_field *field_array, struct configuration *config)
  3153. {
  3154. u32 tx_num = 0;
  3155. u32 index = 0;
  3156. config->is_valid_or_not = 1; /* Set to valid by default */
  3157. config->cm_enabled = 0;
  3158. config->cp_enabled = 0;
  3159. if (field_array[CM_TEST_INPUTS].exist_or_not)
  3160. config->cm_enabled = 1;
  3161. if (field_array[CP_TEST_INPUTS].exist_or_not)
  3162. config->cp_enabled = 1;
  3163. /* Get basic information only when CM and CP are enabled */
  3164. if (config->cm_enabled && config->cp_enabled) {
  3165. pt_debug(dev, DL_INFO,
  3166. "%s: Find CM and CP thresholds\n", __func__);
  3167. config->rx_num =
  3168. field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num;
  3169. tx_num =
  3170. (field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num >> 1)
  3171. /field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num;
  3172. config->tx_num = tx_num;
  3173. config->btn_num =
  3174. field_array[PER_ELEMENT_MIN_MAX_TABLE_BUTTON].data_num >> 1;
  3175. config->cm_min_max_table_btn_size =
  3176. field_array[PER_ELEMENT_MIN_MAX_TABLE_BUTTON].data_num;
  3177. config->cm_min_max_table_sensor_size =
  3178. field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num;
  3179. config->cp_min_max_table_rx_size =
  3180. field_array[PER_ELEMENT_MIN_MAX_RX].data_num;
  3181. config->cp_min_max_table_tx_size =
  3182. field_array[PER_ELEMENT_MIN_MAX_TX].data_num;
  3183. config->cm_max_table_gradient_cols_percent_size =
  3184. field_array[CM_GRADIENT_CHECK_COL].data_num;
  3185. config->cm_max_table_gradient_rows_percent_size =
  3186. field_array[CM_GRADIENT_CHECK_ROW].data_num;
  3187. config->cp_min_max_table_btn_size =
  3188. field_array[CP_PER_ELEMENT_MIN_MAX_BUTTON].data_num;
  3189. /* *** Detailed Debug Information *** */
  3190. pt_debug(dev, DL_DEBUG, "%d\n",
  3191. config->cm_excluding_col_edge);
  3192. pt_debug(dev, DL_DEBUG, "%d\n",
  3193. config->cm_excluding_row_edge);
  3194. for (index = 0;
  3195. index < config->cm_max_table_gradient_cols_percent_size;
  3196. index++)
  3197. pt_debug(dev, DL_DEBUG, "%d\n",
  3198. config->cm_max_table_gradient_cols_percent[index]);
  3199. for (index = 0;
  3200. index < config->cm_max_table_gradient_rows_percent_size;
  3201. index++)
  3202. pt_debug(dev, DL_DEBUG, "%d\n",
  3203. config->cm_max_table_gradient_rows_percent[index]);
  3204. pt_debug(dev, DL_DEBUG, "%d\n",
  3205. config->cm_range_limit_row);
  3206. pt_debug(dev, DL_DEBUG, "%d\n",
  3207. config->cm_range_limit_col);
  3208. pt_debug(dev, DL_DEBUG, "%d\n",
  3209. config->cm_min_limit_cal);
  3210. pt_debug(dev, DL_DEBUG, "%d\n",
  3211. config->cm_max_limit_cal);
  3212. pt_debug(dev, DL_DEBUG, "%d\n",
  3213. config->cm_max_delta_sensor_percent);
  3214. pt_debug(dev, DL_DEBUG, "%d\n",
  3215. config->cm_max_delta_button_percent);
  3216. for (index = 0;
  3217. index < config->cm_min_max_table_btn_size; index++)
  3218. pt_debug(dev, DL_DEBUG, "%d\n",
  3219. config->cm_min_max_table_btn[index]);
  3220. for (index = 0;
  3221. index < config->cm_min_max_table_sensor_size; index++)
  3222. pt_debug(dev, DL_DEBUG, "%d\n",
  3223. config->cm_min_max_table_sensor[index]);
  3224. pt_debug(dev, DL_DEBUG, "%d\n",
  3225. config->cp_max_delta_sensor_rx_percent);
  3226. pt_debug(dev, DL_DEBUG, "%d\n",
  3227. config->cp_max_delta_sensor_tx_percent);
  3228. pt_debug(dev, DL_DEBUG, "%d\n",
  3229. config->cp_max_delta_button_percent);
  3230. pt_debug(dev, DL_DEBUG, "%d\n",
  3231. config->min_button);
  3232. pt_debug(dev, DL_DEBUG, "%d\n",
  3233. config->max_button);
  3234. for (index = 0;
  3235. index < config->cp_min_max_table_btn_size; index++)
  3236. pt_debug(dev, DL_DEBUG, "%d\n",
  3237. config->cp_min_max_table_btn[index]);
  3238. for (index = 0;
  3239. index < config->cp_min_max_table_rx_size; index++)
  3240. pt_debug(dev, DL_DEBUG, "%d\n",
  3241. config->cp_min_max_table_rx[index]);
  3242. for (index = 0;
  3243. index < config->cp_min_max_table_tx_size; index++)
  3244. pt_debug(dev, DL_DEBUG, "%d\n",
  3245. config->cp_min_max_table_tx[index]);
  3246. /* *** End of Detailed Debug Information *** */
  3247. /* Invalid mutual data length */
  3248. if ((field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].data_num >>
  3249. 1) % field_array[PER_ELEMENT_MIN_MAX_TABLE_SENSOR].line_num) {
  3250. config->is_valid_or_not = 0;
  3251. pt_debug(dev, DL_ERROR, "Invalid mutual data length\n");
  3252. }
  3253. } else {
  3254. if (!config->cm_enabled)
  3255. pt_debug(dev, DL_ERROR,
  3256. "%s: Miss CM thresholds or CM data format is wrong!\n",
  3257. __func__);
  3258. if (!config->cp_enabled)
  3259. pt_debug(dev, DL_ERROR,
  3260. "%s: Miss CP thresholds or CP data format is wrong!\n",
  3261. __func__);
  3262. config->rx_num = 0;
  3263. config->tx_num = 0;
  3264. config->btn_num = 0;
  3265. config->is_valid_or_not = 0;
  3266. }
  3267. pt_debug(dev, DL_DEBUG,
  3268. "%s:\n"
  3269. "Input file is %s!\n"
  3270. "CM test: %s\n"
  3271. "CP test: %s\n"
  3272. "rx_num is %d\n"
  3273. "tx_num is %d\n"
  3274. "btn_num is %d\n",
  3275. __func__,
  3276. config->is_valid_or_not == 1 ? "VALID" : "!!! INVALID !!!",
  3277. config->cm_enabled == 1 ? "Found" : "Not found",
  3278. config->cp_enabled == 1 ? "Found" : "Not found",
  3279. config->rx_num,
  3280. config->tx_num,
  3281. config->btn_num);
  3282. }
  3283. /*******************************************************************************
  3284. * FUNCTION: cmcp_test_case_field_init
  3285. *
  3286. * SUMMARY: Initialize the structure test_field_array.
  3287. *
  3288. * PARAMETERS:
  3289. * *test_field_array - pointer to test_case_field structure
  3290. * *configuration - pointer to configuration structure
  3291. ******************************************************************************/
  3292. void cmcp_test_case_field_init(struct test_case_field *test_field_array,
  3293. struct configuration *configs)
  3294. {
  3295. struct test_case_field test_case_field_array[MAX_CASE_NUM] = {
  3296. {"CM TEST INPUTS", 14, TEST_CASE_TYPE_NO,
  3297. NULL, 0, 0, 0},
  3298. {"CM_EXCLUDING_COL_EDGE", 21, TEST_CASE_TYPE_ONE,
  3299. &configs->cm_excluding_col_edge, 0, 0, 0},
  3300. {"CM_EXCLUDING_ROW_EDGE", 21, TEST_CASE_TYPE_ONE,
  3301. &configs->cm_excluding_row_edge, 0, 0, 0},
  3302. {"CM_GRADIENT_CHECK_COL", 21, TEST_CASE_TYPE_MUL,
  3303. &configs->cm_max_table_gradient_cols_percent[0],
  3304. 0, 0, 0},
  3305. {"CM_GRADIENT_CHECK_ROW", 21, TEST_CASE_TYPE_MUL,
  3306. &configs->cm_max_table_gradient_rows_percent[0],
  3307. 0, 0, 0},
  3308. {"CM_RANGE_LIMIT_ROW", 18, TEST_CASE_TYPE_ONE,
  3309. &configs->cm_range_limit_row, 0, 0, 0},
  3310. {"CM_RANGE_LIMIT_COL", 18, TEST_CASE_TYPE_ONE,
  3311. &configs->cm_range_limit_col, 0, 0, 0},
  3312. {"CM_MIN_LIMIT_CAL", 16, TEST_CASE_TYPE_ONE,
  3313. &configs->cm_min_limit_cal, 0, 0, 0},
  3314. {"CM_MAX_LIMIT_CAL", 16, TEST_CASE_TYPE_ONE,
  3315. &configs->cm_max_limit_cal, 0, 0, 0},
  3316. {"CM_MAX_DELTA_SENSOR_PERCENT", 27, TEST_CASE_TYPE_ONE,
  3317. &configs->cm_max_delta_sensor_percent, 0, 0, 0},
  3318. {"CM_MAX_DELTA_BUTTON_PERCENT", 27, TEST_CASE_TYPE_ONE,
  3319. &configs->cm_max_delta_button_percent, 0, 0, 0},
  3320. {"PER_ELEMENT_MIN_MAX_TABLE_BUTTON", 32, TEST_CASE_TYPE_MUL,
  3321. &configs->cm_min_max_table_btn[0], 0, 0, 0},
  3322. {"PER_ELEMENT_MIN_MAX_TABLE_SENSOR", 32,
  3323. TEST_CASE_TYPE_MUL_LINES,
  3324. &configs->cm_min_max_table_sensor[0], 0, 0, 0},
  3325. {"CP TEST INPUTS", 14, TEST_CASE_TYPE_NO,
  3326. NULL, 0, 0, 0},
  3327. {"CP_PER_ELEMENT_MIN_MAX_BUTTON", 29, TEST_CASE_TYPE_MUL,
  3328. &configs->cp_min_max_table_btn[0], 0, 0, 0},
  3329. {"CP_MAX_DELTA_SENSOR_RX_PERCENT", 30, TEST_CASE_TYPE_ONE,
  3330. &configs->cp_max_delta_sensor_rx_percent,
  3331. 0, 0, 0},
  3332. {"CP_MAX_DELTA_SENSOR_TX_PERCENT", 30, TEST_CASE_TYPE_ONE,
  3333. &configs->cp_max_delta_sensor_tx_percent,
  3334. 0, 0, 0},
  3335. {"CP_MAX_DELTA_BUTTON_PERCENT", 27, TEST_CASE_TYPE_ONE,
  3336. &configs->cp_max_delta_button_percent, 0, 0, 0},
  3337. {"MIN_BUTTON", 10, TEST_CASE_TYPE_ONE,
  3338. &configs->min_button, 0, 0, 0},
  3339. {"MAX_BUTTON", 10, TEST_CASE_TYPE_ONE,
  3340. &configs->max_button, 0, 0, 0},
  3341. {"PER_ELEMENT_MIN_MAX_RX", 22, TEST_CASE_TYPE_MUL,
  3342. &configs->cp_min_max_table_rx[0], 0, 0, 0},
  3343. {"PER_ELEMENT_MIN_MAX_TX", 22, TEST_CASE_TYPE_MUL,
  3344. &configs->cp_min_max_table_tx[0], 0, 0, 0},
  3345. };
  3346. memcpy(test_field_array, test_case_field_array,
  3347. sizeof(struct test_case_field) * MAX_CASE_NUM);
  3348. }
  3349. /*******************************************************************************
  3350. * FUNCTION: pt_parse_cmcp_threshold_file_common
  3351. *
  3352. * SUMMARY: Parses cmcp threshold file and stores to the data structure.
  3353. *
  3354. * PARAMETERS:
  3355. * *dev - pointer to devices structure
  3356. * *buf - pointer to input buffer
  3357. * file_size - file size
  3358. ******************************************************************************/
  3359. static ssize_t pt_parse_cmcp_threshold_file_common(
  3360. struct device *dev, const char *buf, u32 file_size)
  3361. {
  3362. struct pt_device_access_data *dad
  3363. = pt_get_device_access_data(dev);
  3364. ssize_t rc = 0;
  3365. u32 case_count = 0;
  3366. pt_debug(dev, DL_INFO,
  3367. "%s: Start parsing cmcp threshold file. File size is %d\n",
  3368. __func__, file_size);
  3369. cmcp_test_case_field_init(dad->test_field_array, dad->configs);
  3370. /* Get all the cases from .csv file */
  3371. case_count = cmcp_get_case_info_from_threshold_file(dev,
  3372. buf, dad->test_search_array, file_size);
  3373. pt_debug(dev, DL_INFO,
  3374. "%s: Number of cases found in CSV file: %d\n",
  3375. __func__, case_count);
  3376. /* Search cases */
  3377. cmcp_get_configuration_info(dev,
  3378. buf,
  3379. dad->test_search_array, case_count, dad->test_field_array,
  3380. dad->configs, file_size);
  3381. /* Get basic information */
  3382. cmcp_get_basic_info(dev, dad->test_field_array, dad->configs);
  3383. return rc;
  3384. }
  3385. /*******************************************************************************
  3386. * FUNCTION: pt_cmcp_threshold_loading_store
  3387. *
  3388. * SUMMARY: The store method for the cmcp_threshold_loading sysfs node. The
  3389. * passed in value controls if threshold loading is performed.
  3390. *
  3391. * RETURN: Size of passed in buffer is success
  3392. *
  3393. * PARAMETERS:
  3394. * *dev - pointer to device structure
  3395. * *attr - pointer to device attributes
  3396. * *buf - pointer to buffer that hold the command parameters
  3397. * size - size of buf
  3398. ******************************************************************************/
  3399. static ssize_t pt_cmcp_threshold_loading_store(struct device *dev,
  3400. struct device_attribute *attr, const char *buf, size_t size)
  3401. {
  3402. struct pt_device_access_data *dad = pt_get_device_access_data(dev);
  3403. ssize_t length;
  3404. u32 input_data[3];
  3405. int rc = 0;
  3406. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  3407. ARRAY_SIZE(input_data));
  3408. if (length != 1) {
  3409. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  3410. __func__);
  3411. rc = -EINVAL;
  3412. goto exit;
  3413. }
  3414. mutex_lock(&dad->cmcp_threshold_lock);
  3415. if (input_data[0] == 1)
  3416. dad->cmcp_threshold_loading = true;
  3417. else if (input_data[0] == -1)
  3418. dad->cmcp_threshold_loading = false;
  3419. else if (input_data[0] == 0 && dad->cmcp_threshold_loading) {
  3420. dad->cmcp_threshold_loading = false;
  3421. if (dad->cmcp_threshold_size == 0) {
  3422. pt_debug(dev, DL_ERROR, "%s: No cmcp threshold data\n",
  3423. __func__);
  3424. goto exit_free;
  3425. }
  3426. /* Clear test executed flag */
  3427. dad->test_executed = 0;
  3428. pt_parse_cmcp_threshold_file_common(dev,
  3429. &dad->cmcp_threshold_data[0], dad->cmcp_threshold_size);
  3430. /* Mark valid */
  3431. dad->builtin_cmcp_threshold_status = 0;
  3432. /* Restore test item to default value when new file input */
  3433. dad->cmcp_test_items = 0;
  3434. } else {
  3435. pt_debug(dev, DL_WARN, "%s: Invalid value\n", __func__);
  3436. rc = -EINVAL;
  3437. mutex_unlock(&dad->cmcp_threshold_lock);
  3438. goto exit;
  3439. }
  3440. exit_free:
  3441. kfree(dad->cmcp_threshold_data);
  3442. dad->cmcp_threshold_data = NULL;
  3443. dad->cmcp_threshold_size = 0;
  3444. mutex_unlock(&dad->cmcp_threshold_lock);
  3445. exit:
  3446. if (rc)
  3447. return rc;
  3448. return size;
  3449. }
  3450. static DEVICE_ATTR(cmcp_threshold_loading, 0200,
  3451. NULL, pt_cmcp_threshold_loading_store);
  3452. /*******************************************************************************
  3453. * FUNCTION: pt_cmcp_threshold_data_write
  3454. *
  3455. * SUMMARY: The write method for the cmcp_threshold_data_sysfs node. The passed
  3456. * in data (threshold file) is written to the threshold buffer.
  3457. *
  3458. * RETURN: Size of passed in buffer is success
  3459. *
  3460. * PARAMETERS:
  3461. * *filp - pointer to file structure
  3462. * *kobj - pointer to kobject structure
  3463. * *bin_attr - pointer to bin_attribute structure
  3464. * buf - pointer to cmd input buffer
  3465. * offset - offset index to store input buffer
  3466. * count - size of data in buffer
  3467. ******************************************************************************/
  3468. static ssize_t pt_cmcp_threshold_data_write(struct file *filp,
  3469. struct kobject *kobj, struct bin_attribute *bin_attr,
  3470. char *buf, loff_t offset, size_t count)
  3471. {
  3472. struct device *dev = container_of(kobj, struct device, kobj);
  3473. struct pt_device_access_data *dad
  3474. = pt_get_device_access_data(dev);
  3475. u8 *p;
  3476. pt_debug(dev, DL_INFO, "%s: offset:%lld count:%zu\n",
  3477. __func__, offset, count);
  3478. mutex_lock(&dad->cmcp_threshold_lock);
  3479. if (!dad->cmcp_threshold_loading) {
  3480. mutex_unlock(&dad->cmcp_threshold_lock);
  3481. return -ENODEV;
  3482. }
  3483. p = krealloc(dad->cmcp_threshold_data, offset + count, GFP_KERNEL);
  3484. if (!p) {
  3485. kfree(dad->cmcp_threshold_data);
  3486. dad->cmcp_threshold_data = NULL;
  3487. mutex_unlock(&dad->cmcp_threshold_lock);
  3488. return -ENOMEM;
  3489. }
  3490. dad->cmcp_threshold_data = p;
  3491. memcpy(&dad->cmcp_threshold_data[offset], buf, count);
  3492. dad->cmcp_threshold_size += count;
  3493. mutex_unlock(&dad->cmcp_threshold_lock);
  3494. return count;
  3495. }
  3496. static struct bin_attribute bin_attr_cmcp_threshold_data = {
  3497. .attr = {
  3498. .name = "cmcp_threshold_data",
  3499. .mode = 0200,
  3500. },
  3501. .size = 0,
  3502. .write = pt_cmcp_threshold_data_write,
  3503. };
  3504. /*******************************************************************************
  3505. * FUNCTION: pt_suspend_scan_cmd_
  3506. *
  3507. * SUMMARY: Non-protected wrapper function for suspend scan command
  3508. *
  3509. * RETURN:
  3510. * 0 = success
  3511. * !0 = failure
  3512. *
  3513. * PARAMETERS:
  3514. * *dev - pointer to devices structure
  3515. ******************************************************************************/
  3516. static int pt_suspend_scan_cmd_(struct device *dev)
  3517. {
  3518. int rc;
  3519. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  3520. if (rc)
  3521. pt_debug(dev, DL_ERROR, "%s: Suspend scan failed rc = %d\n",
  3522. __func__, rc);
  3523. return rc;
  3524. }
  3525. /*******************************************************************************
  3526. * FUNCTION: pt_resume_scan_cmd_
  3527. *
  3528. * SUMMARY: Non-protected wrapper function for resume scan command
  3529. *
  3530. * RETURN:
  3531. * 0 = success
  3532. * !0 = failure
  3533. *
  3534. * PARAMETERS:
  3535. * *dev - pointer to devices structure
  3536. ******************************************************************************/
  3537. static int pt_resume_scan_cmd_(struct device *dev)
  3538. {
  3539. int rc;
  3540. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  3541. if (rc)
  3542. pt_debug(dev, DL_ERROR, "%s: Resume scan failed rc = %d\n",
  3543. __func__, rc);
  3544. return rc;
  3545. }
  3546. /*******************************************************************************
  3547. * FUNCTION: pt_exec_scan_cmd_
  3548. *
  3549. * SUMMARY: Non-protected wrapper function for execute scan command
  3550. *
  3551. * RETURN:
  3552. * 0 = success
  3553. * !0 = failure
  3554. *
  3555. * PARAMETERS:
  3556. * *dev - pointer to devices structure
  3557. * scan_type - type of panel scan to perform (PIP2 only)
  3558. ******************************************************************************/
  3559. static int pt_exec_scan_cmd_(struct device *dev, u8 scan_type)
  3560. {
  3561. int rc;
  3562. rc = cmd->nonhid_cmd->exec_panel_scan(dev, PT_CORE_CMD_UNPROTECTED,
  3563. scan_type);
  3564. if (rc)
  3565. pt_debug(dev, DL_ERROR,
  3566. "%s: Heatmap start scan failed rc = %d\n",
  3567. __func__, rc);
  3568. return rc;
  3569. }
  3570. /*******************************************************************************
  3571. * FUNCTION: pt_ret_scan_data_cmd_
  3572. *
  3573. * SUMMARY: Non-protected wrapper function for retrieve panel data command
  3574. *
  3575. * RETURN:
  3576. * 0 = success
  3577. * !0 = failure
  3578. *
  3579. * PARAMETERS:
  3580. * *dev - pointer to device structure
  3581. * read_offset - read pointer offset
  3582. * read_count - length of data to read
  3583. * data_id - enumerated test ID to read selftest results from
  3584. * *response - pointer to store the read response status
  3585. * *config - pointer to store config data
  3586. * *actual_read_len - pointer to store data length actually read
  3587. * *return_buf - pointer to the read buffer
  3588. ******************************************************************************/
  3589. static int pt_ret_scan_data_cmd_(struct device *dev, u16 read_offset,
  3590. u16 read_count, u8 data_id, u8 *response, u8 *config,
  3591. u16 *actual_read_len, u8 *return_buf)
  3592. {
  3593. int rc;
  3594. rc = cmd->nonhid_cmd->retrieve_panel_scan(dev, 0, read_offset,
  3595. read_count, data_id, response, config, actual_read_len,
  3596. return_buf);
  3597. if (rc)
  3598. pt_debug(dev, DL_ERROR,
  3599. "%s: Retrieve scan data failed rc = %d\n",
  3600. __func__, rc);
  3601. return rc;
  3602. }
  3603. /*******************************************************************************
  3604. * FUNCTION: pt_get_data_structure_cmd_
  3605. *
  3606. * SUMMARY: Non-protected wrapper function for get data structure command
  3607. *
  3608. * RETURN:
  3609. * 0 = success
  3610. * !0 = failure
  3611. *
  3612. * PARAMETERS:
  3613. * *dev - pointer to device structure
  3614. * read_offset - read pointer offset
  3615. * read_length - length of data to read
  3616. * data_id - data ID to read
  3617. * *status - pointer to store the read response status
  3618. * *data_format - pointer to store format of data read
  3619. * *actual_read_len - pointer to store data length actually read
  3620. * *data - pointer to store data read
  3621. ******************************************************************************/
  3622. static int pt_get_data_structure_cmd_(struct device *dev, u16 read_offset,
  3623. u16 read_length, u8 data_id, u8 *status, u8 *data_format,
  3624. u16 *actual_read_len, u8 *data)
  3625. {
  3626. int rc;
  3627. rc = cmd->nonhid_cmd->get_data_structure(dev, 0, read_offset,
  3628. read_length, data_id, status, data_format,
  3629. actual_read_len, data);
  3630. if (rc)
  3631. pt_debug(dev, DL_ERROR,
  3632. "%s: Get data structure failed rc = %d\n",
  3633. __func__, rc);
  3634. return rc;
  3635. }
  3636. /*******************************************************************************
  3637. * FUNCTION: pt_run_selftest_cmd_
  3638. *
  3639. * SUMMARY: Non-protected wrapper function for run self test command
  3640. *
  3641. * RETURN:
  3642. * 0 = success
  3643. * !0 = failure
  3644. *
  3645. * PARAMETERS:
  3646. * *dev - pointer to device structure
  3647. * test_id - enumerated test ID to run
  3648. * write_idacs_to_flash - flag whether to write new IDACS to flash
  3649. * *status - pointer to store the read response status
  3650. * *summary_results - pointer to store the results summary
  3651. * *results_available - pointer to store if results are available
  3652. ******************************************************************************/
  3653. static int pt_run_selftest_cmd_(struct device *dev, u8 test_id,
  3654. u8 write_idacs_to_flash, u8 *status, u8 *summary_result,
  3655. u8 *results_available)
  3656. {
  3657. int rc;
  3658. rc = cmd->nonhid_cmd->run_selftest(dev, 0, test_id,
  3659. write_idacs_to_flash, status, summary_result,
  3660. results_available);
  3661. if (rc)
  3662. pt_debug(dev, DL_ERROR, "%s: Run self test failed rc = %d\n",
  3663. __func__, rc);
  3664. return rc;
  3665. }
  3666. /*******************************************************************************
  3667. * FUNCTION: pt_get_selftest_result_cmd_
  3668. *
  3669. * SUMMARY: Non-protected wrapper function for get self test result command
  3670. *
  3671. * RETURN:
  3672. * 0 = success
  3673. * !0 = failure
  3674. *
  3675. * PARAMETERS:
  3676. * *dev - pointer to device structure
  3677. * read_offset - read pointer offset
  3678. * read_length - length of data to read
  3679. * test_id - enumerated test ID to read selftest results from
  3680. * *status - pointer to store the read response status
  3681. * *actual_read_len - pointer to store data length actually read
  3682. * *data - pointer to where the data read is stored
  3683. ******************************************************************************/
  3684. static int pt_get_selftest_result_cmd_(struct device *dev,
  3685. u16 read_offset, u16 read_length, u8 test_id, u8 *status,
  3686. u16 *actual_read_len, u8 *data)
  3687. {
  3688. int rc;
  3689. rc = cmd->nonhid_cmd->get_selftest_result(dev, 0, read_offset,
  3690. read_length, test_id, status, actual_read_len, data);
  3691. if (rc)
  3692. pt_debug(dev, DL_ERROR,
  3693. "%s: Get self test result failed rc = %d\n",
  3694. __func__, rc);
  3695. return rc;
  3696. }
  3697. /*******************************************************************************
  3698. * FUNCTION: _pt_calibrate_ext_cmd
  3699. *
  3700. * SUMMARY: Wrapper function to function calibrate_ext() in pt_core_commands
  3701. * structure
  3702. *
  3703. * RETURN:
  3704. * 0 = success
  3705. * !0 = failure
  3706. *
  3707. * PARAMETERS:
  3708. * *dev - pointer to device structure
  3709. * *cal_data - pointer to extended calibration data structure
  3710. * *status - pointer to where the command response status is stored
  3711. ******************************************************************************/
  3712. static int _pt_calibrate_ext_cmd(struct device *dev,
  3713. struct pt_cal_ext_data *cal_data, u8 *status)
  3714. {
  3715. int rc;
  3716. rc = cmd->nonhid_cmd->calibrate_ext(dev,
  3717. PT_CORE_CMD_UNPROTECTED, cal_data, status);
  3718. return rc;
  3719. }
  3720. /*******************************************************************************
  3721. * FUNCTION: _pt_calibrate_idacs_cmd
  3722. *
  3723. * SUMMARY: Wrapper function to function calibrate_idacs() in pt_core_commands
  3724. * structure
  3725. *
  3726. * RETURN:
  3727. * 0 = success
  3728. * !0 = failure
  3729. *
  3730. * PARAMETERS:
  3731. * *dev - pointer to device structure
  3732. * sensing_mode - sense mode to calibrate (0-5)
  3733. * *status - pointer to where the command response status is stored
  3734. ******************************************************************************/
  3735. static int _pt_calibrate_idacs_cmd(struct device *dev,
  3736. u8 sensing_mode, u8 *status)
  3737. {
  3738. int rc;
  3739. rc = cmd->nonhid_cmd->calibrate_idacs(dev, 0, sensing_mode, status);
  3740. return rc;
  3741. }
  3742. /*******************************************************************************
  3743. * FUNCTION: _pt_initialize_baselines_cmd
  3744. *
  3745. * SUMMARY: Wrapper function to call initialize_baselines() in pt_core_commands
  3746. * structure
  3747. *
  3748. * RETURN:
  3749. * 0 = success
  3750. * !0 = failure
  3751. *
  3752. * PARAMETERS:
  3753. * *dev - pointer to device structure
  3754. * sensing_mode - enumerated ID against which to initialize the baseline
  3755. * *status - pointer to where the command response statas is stored
  3756. ******************************************************************************/
  3757. static int _pt_initialize_baselines_cmd(struct device *dev,
  3758. u8 sensing_mode, u8 *status)
  3759. {
  3760. int rc;
  3761. rc = cmd->nonhid_cmd->initialize_baselines(dev, 0, sensing_mode,
  3762. status);
  3763. return rc;
  3764. }
  3765. /*******************************************************************************
  3766. * FUNCTION: pt_perform_calibration
  3767. *
  3768. * SUMMARY: For Gen5/6, Send the PIP1 Calibrate IDACs command (0x28). For TT/TC,
  3769. * send PIP1 Extended Calibrate command (0x30).
  3770. *
  3771. * NOTE: Panel scan must be suspended prior to calling this function.
  3772. *
  3773. * RETURN:
  3774. * 0 = success
  3775. * !0 = failure
  3776. *
  3777. * PARAMETERS:
  3778. * *dev - pointer to device structure
  3779. ******************************************************************************/
  3780. static int pt_perform_calibration(struct device *dev)
  3781. {
  3782. struct pt_cal_ext_data cal_data = {0};
  3783. u8 dut_gen = cmd->request_dut_generation(dev);
  3784. u8 mode;
  3785. u8 status;
  3786. int rc;
  3787. if (dut_gen == DUT_PIP1_ONLY) {
  3788. for (mode = 0; mode < 3; mode++) {
  3789. rc = _pt_calibrate_idacs_cmd(dev, mode, &status);
  3790. if (rc < 0) {
  3791. pt_debug(dev, DL_ERROR,
  3792. "%s: calibrate idac error, mode= %d, rc = %d\n",
  3793. __func__, mode, rc);
  3794. break;
  3795. }
  3796. }
  3797. } else {
  3798. memset(&cal_data, 0, sizeof(struct pt_cal_ext_data));
  3799. rc = _pt_calibrate_ext_cmd(dev, &cal_data, &status);
  3800. if (rc < 0)
  3801. pt_debug(dev, DL_ERROR,
  3802. "%s: extended calibrate error, rc = %d\n",
  3803. __func__, rc);
  3804. }
  3805. return rc;
  3806. }
  3807. /*******************************************************************************
  3808. * FUNCTION: prepare_print_buffer
  3809. *
  3810. * SUMMARY: Format input buffer to out buffer with Hex base,and format "status"
  3811. * to decimal base.
  3812. *
  3813. * RETURN:
  3814. * size of formated data in output buffer
  3815. *
  3816. * PARAMETERS:
  3817. * status - Indicate test result:0(STATUS_SUCCESS),-1(STATUS_FAIL)
  3818. * *in_buf - input buffer to be formated
  3819. * length - length of input buffer
  3820. * *out_buf - output buffer to store formated data
  3821. * out_buf_size - length of output buffer
  3822. * out_format - format of output data (5 supported formats):
  3823. * PT_PR_FORMAT_DEFAULT : format all data as a column
  3824. * PT_PR_FORMAT_U8_SPACE : sort status bytes and self test results,
  3825. * and format the results as a row, each element include 1 byte
  3826. * PT_PR_FORMAT_U16_SPACE : sort status bytes and self test results,
  3827. * and format the results as a row, each element include 2 byte
  3828. * PT_PR_FORMAT_U8_NO_SPACE : sort status bytes and self test results,
  3829. * and format the results as a row, no space between the elements
  3830. * PT_PR_FORMAT_U32_SPACE : sort status bytes and self test results,
  3831. * and format the results as a row, each element include 4 byte
  3832. ******************************************************************************/
  3833. static int prepare_print_buffer(int status, u8 *in_buf, int length,
  3834. u8 *out_buf, size_t out_buf_size, u8 out_format)
  3835. {
  3836. int index = 0;
  3837. int data_length;
  3838. int i;
  3839. index += scnprintf(out_buf, out_buf_size, "Status: %d\n", status);
  3840. if (out_format == PT_PR_FORMAT_DEFAULT) {
  3841. for (i = 0; i < length; i++)
  3842. index += scnprintf(&out_buf[index],
  3843. out_buf_size - index,
  3844. "%02X\n", in_buf[i]);
  3845. } else {
  3846. index += scnprintf(&out_buf[index],
  3847. out_buf_size - index,
  3848. "Response Status[1-%d]: ", MIN(length, 3));
  3849. for (i = 0; i < MIN(length, 3); i++)
  3850. index += scnprintf(&out_buf[index],
  3851. out_buf_size - index,
  3852. "%02X ", in_buf[i]);
  3853. index += scnprintf(&out_buf[index], out_buf_size - index, "\n");
  3854. if (length <= 6) {
  3855. goto exit;
  3856. } else {
  3857. data_length = get_unaligned_le16(&in_buf[4]);
  3858. index += scnprintf(&out_buf[index],
  3859. out_buf_size - index, "RAW_DATA: ");
  3860. }
  3861. if (out_format == PT_PR_FORMAT_U8_SPACE) {
  3862. for (i = 6; i < length; i++)
  3863. index += scnprintf(&out_buf[index],
  3864. out_buf_size - index,
  3865. "%02X ", in_buf[i]);
  3866. index += scnprintf(&out_buf[index],
  3867. out_buf_size - index,
  3868. ":(%d bytes)\n", data_length);
  3869. } else if (out_format == PT_PR_FORMAT_U16_SPACE) {
  3870. for (i = 6; (i + 1) < length; i += 2)
  3871. index += scnprintf(&out_buf[index],
  3872. out_buf_size - index, "%04X ",
  3873. get_unaligned_le16(&in_buf[i]));
  3874. index += scnprintf(&out_buf[index],
  3875. out_buf_size - index,
  3876. ":(%d words)\n", (length-6)/2);
  3877. } else if (out_format == PT_PR_FORMAT_U8_NO_SPACE) {
  3878. for (i = 6; i < length; i++)
  3879. index += scnprintf(&out_buf[index],
  3880. out_buf_size - index,
  3881. "%02X", in_buf[i]);
  3882. index += scnprintf(&out_buf[index],
  3883. out_buf_size - index,
  3884. ":(%d bytes)\n", data_length);
  3885. } else if (out_format == PT_PR_FORMAT_U32_SPACE) {
  3886. for (i = 6; (i + 1) < length; i += 4)
  3887. index += scnprintf(&out_buf[index],
  3888. out_buf_size - index, "%08X ",
  3889. get_unaligned_le32(&in_buf[i]));
  3890. index += scnprintf(&out_buf[index],
  3891. out_buf_size - index,
  3892. ":(%d 32bit values)\n", (length-6)/4);
  3893. }
  3894. }
  3895. exit:
  3896. return index;
  3897. }
  3898. /*******************************************************************************
  3899. * FUNCTION: pt_run_and_get_selftest_result
  3900. *
  3901. * SUMMARY: Run the selftest and store the test result in the
  3902. * pt_device_access_data struct.
  3903. *
  3904. * RETURN:
  3905. * >0 : Size of debugfs data to print
  3906. * <0 : failure
  3907. * 0 : success
  3908. *
  3909. * NOTE: "Status: x" - x will contain the first error code if any
  3910. *
  3911. * PARAMETERS:
  3912. * *dev - pointer to device structure
  3913. * protect - flag to call protected or non-protected
  3914. * *buf - pointer to print buf of return data
  3915. * buf_len - length of print buf of return data
  3916. * test_id - selftest id
  3917. * read_length - max length to stor return data
  3918. * get_result_on_pass - indicate whether to get result when finish test
  3919. * print_results - print results to log
  3920. * (true:get result;false:don't get result )
  3921. * print_format - format of print results
  3922. ******************************************************************************/
  3923. static ssize_t pt_run_and_get_selftest_result(struct device *dev,
  3924. int protect, char *buf, size_t buf_len, u8 test_id,
  3925. u16 read_length, bool get_result_on_pass, bool print_results,
  3926. u8 print_format)
  3927. {
  3928. struct pt_device_access_data *dad = pt_get_device_access_data(dev);
  3929. int status = STATUS_SUCCESS;
  3930. u8 cmd_status = STATUS_SUCCESS;
  3931. u8 summary_result = 0;
  3932. u8 sys_mode = FW_SYS_MODE_UNDEFINED;
  3933. u16 act_length = 0;
  3934. int length = 0;
  3935. int size = 0;
  3936. int rc;
  3937. mutex_lock(&dad->sysfs_lock);
  3938. pm_runtime_get_sync(dev);
  3939. if (protect == PT_CORE_CMD_PROTECTED) {
  3940. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  3941. if (rc) {
  3942. pt_debug(dev, DL_ERROR,
  3943. "%s: Error on request exclusive rc = %d\n",
  3944. __func__, rc);
  3945. status = -EPERM;
  3946. goto put_pm_runtime;
  3947. }
  3948. }
  3949. /* Get the current scan state so we restore to the same at the end */
  3950. rc = cmd->request_get_fw_mode(dev, PT_CORE_CMD_UNPROTECTED, &sys_mode,
  3951. NULL);
  3952. if (rc) {
  3953. status = rc;
  3954. goto release_exclusive;
  3955. }
  3956. if (sys_mode != FW_SYS_MODE_TEST) {
  3957. rc = pt_suspend_scan_cmd_(dev);
  3958. if (rc) {
  3959. pt_debug(dev, DL_ERROR,
  3960. "%s: Error on suspend scan rc = %d\n",
  3961. __func__, rc);
  3962. status = -EPERM;
  3963. goto release_exclusive;
  3964. }
  3965. }
  3966. /* Sleep for 20ms to allow the last scan to be available in FW */
  3967. msleep(20);
  3968. rc = pt_run_selftest_cmd_(dev, test_id, 0,
  3969. &cmd_status, &summary_result, NULL);
  3970. if (rc) {
  3971. /* Error sending self test */
  3972. pt_debug(dev, DL_ERROR,
  3973. "%s: Error on run self test for test_id:%d rc = %d\n",
  3974. __func__, test_id, rc);
  3975. status = rc;
  3976. goto resume_scan;
  3977. }
  3978. if (cmd_status) {
  3979. /* Self test response status failure */
  3980. pt_debug(dev, DL_WARN,
  3981. "%s: Test ID: 0x%02X resulted in status: 0x%02X\n",
  3982. __func__, test_id, cmd_status);
  3983. status = cmd_status;
  3984. }
  3985. dad->si = cmd->request_sysinfo(dad->dev);
  3986. if (!dad->si) {
  3987. pt_debug(dad->dev, DL_ERROR,
  3988. "%s: Fail get sysinfo pointer from core\n", __func__);
  3989. if (status == STATUS_SUCCESS)
  3990. status = -EINVAL;
  3991. goto resume_scan;
  3992. }
  3993. if (IS_PIP_VER_GE(dad->si, 1, 11)) {
  3994. /* PIP1.11+ does not report the summary_result in byte 6 */
  3995. summary_result = cmd_status;
  3996. }
  3997. /* Form response buffer */
  3998. dad->ic_buf[0] = cmd_status;
  3999. dad->ic_buf[1] = summary_result;
  4000. pt_debug(dev, DL_INFO, "%s: Run Self Test cmd status = %d\n",
  4001. __func__, cmd_status);
  4002. pt_debug(dev, DL_INFO, "%s: Run Self Test result summary = %d\n",
  4003. __func__, summary_result);
  4004. length = 2;
  4005. /*
  4006. * Get data if requested and the cmd status indicates that the test
  4007. * completed with either a pass or a fail. All other status codes
  4008. * indicate the test itself was not run so there is no data to retrieve
  4009. */
  4010. if ((cmd_status == PT_ST_RESULT_PASS ||
  4011. cmd_status == PT_ST_RESULT_FAIL) && get_result_on_pass) {
  4012. rc = pt_get_selftest_result_cmd_(dev, 0, read_length,
  4013. test_id, &cmd_status, &act_length, &dad->ic_buf[6]);
  4014. if (rc) {
  4015. pt_debug(dev, DL_ERROR,
  4016. "%s: Error on get self test result rc = %d\n",
  4017. __func__, rc);
  4018. if (status == STATUS_SUCCESS)
  4019. status = rc;
  4020. goto resume_scan;
  4021. }
  4022. pt_debug(dev, DL_INFO, "%s: Get Self Test result status = %d\n",
  4023. __func__, cmd_status);
  4024. /* Only store new status if no error on running self test */
  4025. if (status == STATUS_SUCCESS)
  4026. status = cmd_status;
  4027. dad->ic_buf[2] = cmd_status;
  4028. dad->ic_buf[3] = test_id;
  4029. dad->ic_buf[4] = LOW_BYTE(act_length);
  4030. dad->ic_buf[5] = HI_BYTE(act_length);
  4031. length = 6 + act_length;
  4032. }
  4033. resume_scan:
  4034. /* Only resume scanning if we suspended it */
  4035. if (sys_mode == FW_SYS_MODE_SCANNING)
  4036. pt_resume_scan_cmd_(dev);
  4037. release_exclusive:
  4038. if (protect == PT_CORE_CMD_PROTECTED)
  4039. cmd->release_exclusive(dev);
  4040. put_pm_runtime:
  4041. pm_runtime_put(dev);
  4042. /* Communication error */
  4043. if (status < 0)
  4044. length = 0;
  4045. if (print_results) {
  4046. size = prepare_print_buffer(status, dad->ic_buf, length,
  4047. buf, buf_len, print_format);
  4048. rc = size;
  4049. }
  4050. mutex_unlock(&dad->sysfs_lock);
  4051. return rc;
  4052. }
  4053. struct pt_device_access_debugfs_data {
  4054. struct pt_device_access_data *dad;
  4055. ssize_t pr_buf_len;
  4056. u8 pr_buf[10 * PT_MAX_PRBUF_SIZE];
  4057. };
  4058. /*******************************************************************************
  4059. * FUNCTION: pt_device_access_debugfs_open
  4060. *
  4061. * SUMMARY: Open the device_access debugfs node to initialize.
  4062. *
  4063. * RETURN:
  4064. * 0 = success
  4065. * !0 = failure
  4066. *
  4067. * PARAMETERS:
  4068. * *inode - pointer to inode structure
  4069. * *filp - pointer to file structure
  4070. ******************************************************************************/
  4071. static int pt_device_access_debugfs_open(struct inode *inode,
  4072. struct file *filp)
  4073. {
  4074. struct pt_device_access_data *dad = inode->i_private;
  4075. struct pt_device_access_debugfs_data *data;
  4076. data = kzalloc(sizeof(*data), GFP_KERNEL);
  4077. if (!data)
  4078. return -ENOMEM;
  4079. data->dad = dad;
  4080. filp->private_data = data;
  4081. return nonseekable_open(inode, filp);
  4082. }
  4083. /*******************************************************************************
  4084. * FUNCTION: pt_device_access_debugfs_release
  4085. *
  4086. * SUMMARY: Close the device_access debugfs node to free pointer.
  4087. *
  4088. * RETURN:
  4089. * 0 = success
  4090. * !0 = failure
  4091. *
  4092. * PARAMETERS:
  4093. * *inode - pointer to inode structure
  4094. * *filp - pointer to file structure
  4095. ******************************************************************************/
  4096. static int pt_device_access_debugfs_release(struct inode *inode,
  4097. struct file *filp)
  4098. {
  4099. kfree(filp->private_data);
  4100. return 0;
  4101. }
  4102. #define PT_DEBUGFS_FOPS(_name, _read, _write) \
  4103. static const struct file_operations _name##_debugfs_fops = { \
  4104. .open = pt_device_access_debugfs_open, \
  4105. .release = pt_device_access_debugfs_release, \
  4106. .read = _read, \
  4107. .write = _write, \
  4108. }
  4109. /*******************************************************************************
  4110. * FUNCTION: panel_scan_debugfs_read
  4111. *
  4112. * SUMMARY: This function retrieves a full panel scan by sending the following
  4113. * PIP commands:
  4114. * 1) Suspend Scanning
  4115. * 2) Execute Panel Scan
  4116. * 3) Retrieve Panel Scan (n times to retrieve full scan)
  4117. * 4) Resume Scanning
  4118. *
  4119. * RETURN: Size of debugfs data print
  4120. *
  4121. * PARAMETERS:
  4122. * *filp - file pointer to debugfs file
  4123. * *buf - the user space buffer to read to
  4124. * count - the maximum number of bytes to read
  4125. * *ppos - the current position in the buffer
  4126. ******************************************************************************/
  4127. static ssize_t panel_scan_debugfs_read(struct file *filp, char __user *buf,
  4128. size_t count, loff_t *ppos)
  4129. {
  4130. struct pt_device_access_debugfs_data *data = filp->private_data;
  4131. struct pt_device_access_data *dad = data->dad;
  4132. struct device *dev = dad->dev;
  4133. struct pt_core_data *cd = dev_get_drvdata(dev);
  4134. int status = STATUS_FAIL;
  4135. u8 config;
  4136. u16 num_elem_read;
  4137. int length = 0;
  4138. u8 element_size = 0;
  4139. u8 *buf_out;
  4140. u8 *buf_offset;
  4141. u8 sys_mode = FW_SYS_MODE_UNDEFINED;
  4142. int elem_offset = 0;
  4143. int rc;
  4144. int print_idx = 0;
  4145. int i;
  4146. mutex_lock(&dad->debugfs_lock);
  4147. buf_out = dad->panel_scan_data_buf;
  4148. if (!buf_out)
  4149. goto release_mutex;
  4150. pm_runtime_get_sync(dev);
  4151. /*
  4152. * This function will re-enter if the panel_scan_size is greater than
  4153. * count (count is the kernel page size which is typically 4096), on
  4154. * re-entry, *ppos will retain how far the last copy to user space
  4155. * completed
  4156. */
  4157. if (*ppos) {
  4158. if (*ppos >= dad->panel_scan_size)
  4159. goto release_mutex;
  4160. print_idx = simple_read_from_buffer(buf, count, ppos,
  4161. buf_out, dad->panel_scan_size);
  4162. pt_debug(dev, DL_DEBUG, "%s: Sent %d bytes to user space\n",
  4163. __func__, print_idx);
  4164. goto release_mutex;
  4165. }
  4166. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  4167. if (rc) {
  4168. pt_debug(dev, DL_ERROR,
  4169. "%s: Error on request exclusive rc = %d\n",
  4170. __func__, rc);
  4171. goto put_pm_runtime;
  4172. }
  4173. /* Get the current scan state so we restore to the same at the end */
  4174. rc = cmd->request_get_fw_mode(dev, PT_CORE_CMD_UNPROTECTED, &sys_mode,
  4175. NULL);
  4176. if (rc) {
  4177. status = rc;
  4178. goto release_exclusive;
  4179. }
  4180. if (sys_mode != FW_SYS_MODE_TEST) {
  4181. rc = pt_suspend_scan_cmd_(dev);
  4182. if (rc) {
  4183. pt_debug(dev, DL_ERROR,
  4184. "%s: Error on suspend scan rc = %d\n",
  4185. __func__, rc);
  4186. goto release_exclusive;
  4187. }
  4188. }
  4189. rc = pt_exec_scan_cmd_(dev, dad->panel_scan_type_id);
  4190. if (rc) {
  4191. pt_debug(dev, DL_ERROR,
  4192. "%s: Error on execute panel scan rc = %d\n",
  4193. __func__, rc);
  4194. goto resume_scan;
  4195. }
  4196. /* Set length to max to read all */
  4197. rc = pt_ret_scan_data_cmd_(dev, 0, 0xFFFF,
  4198. dad->panel_scan_retrieve_id, dad->ic_buf, &config,
  4199. &num_elem_read, NULL);
  4200. if (rc) {
  4201. pt_debug(dev, DL_ERROR,
  4202. "%s: Error on retrieve panel scan rc = %d\n",
  4203. __func__, rc);
  4204. goto resume_scan;
  4205. }
  4206. length = get_unaligned_le16(&dad->ic_buf[0]);
  4207. buf_offset = dad->ic_buf + length;
  4208. element_size = config & 0x07;
  4209. elem_offset = num_elem_read;
  4210. while (num_elem_read > 0) {
  4211. rc = pt_ret_scan_data_cmd_(dev, elem_offset, 0xFFFF,
  4212. dad->panel_scan_retrieve_id, NULL, &config,
  4213. &num_elem_read, buf_offset);
  4214. if (rc)
  4215. goto resume_scan;
  4216. length += num_elem_read * element_size;
  4217. buf_offset = dad->ic_buf + length;
  4218. elem_offset += num_elem_read;
  4219. if (num_elem_read < 0x7A)
  4220. break;
  4221. }
  4222. /* Reconstruct cmd header */
  4223. put_unaligned_le16(length, &dad->ic_buf[0]);
  4224. put_unaligned_le16(elem_offset, &dad->ic_buf[7]);
  4225. status = STATUS_SUCCESS;
  4226. resume_scan:
  4227. /* Only resume scanning if we suspended it */
  4228. if (sys_mode == FW_SYS_MODE_SCANNING)
  4229. pt_resume_scan_cmd_(dev);
  4230. release_exclusive:
  4231. cmd->release_exclusive(dev);
  4232. put_pm_runtime:
  4233. pm_runtime_put(dev);
  4234. if (status == STATUS_FAIL)
  4235. length = 0;
  4236. if (cd->show_timestamp)
  4237. print_idx += scnprintf(buf_out + print_idx, TTHE_TUNER_MAX_BUF,
  4238. "[%u] SCAN_DATA:", pt_get_time_stamp());
  4239. else
  4240. print_idx += scnprintf(buf_out + print_idx, TTHE_TUNER_MAX_BUF,
  4241. "SCAN_DATA:");
  4242. for (i = 0; i < length; i++)
  4243. print_idx += scnprintf(buf_out + print_idx,
  4244. TTHE_TUNER_MAX_BUF - print_idx,
  4245. "%02X ", dad->ic_buf[i]);
  4246. print_idx += scnprintf(buf_out + print_idx,
  4247. TTHE_TUNER_MAX_BUF - print_idx,
  4248. ":(%d bytes)\n", length);
  4249. /*
  4250. * Save the size of the full scan which this function uses on re-entry
  4251. * to send the data back to user space in 'count' size chuncks
  4252. */
  4253. dad->panel_scan_size = print_idx;
  4254. print_idx = simple_read_from_buffer(buf, count, ppos, buf_out,
  4255. print_idx);
  4256. pt_debug(dev, DL_DEBUG, "%s: Sent %d bytes to user space\n",
  4257. __func__, print_idx);
  4258. release_mutex:
  4259. mutex_unlock(&dad->debugfs_lock);
  4260. return print_idx;
  4261. }
  4262. /*******************************************************************************
  4263. * FUNCTION: panel_scan_debugfs_write
  4264. *
  4265. * SUMMARY: Store the type of panel scan the read method will perform.
  4266. *
  4267. * RETURN: Size of debugfs data write
  4268. *
  4269. * PARAMETERS:
  4270. * *filp - file pointer to debugfs file
  4271. * *buf - the user space buffer to write to
  4272. * count - the maximum number of bytes to write
  4273. * *ppos - the current position in the buffer
  4274. ******************************************************************************/
  4275. static ssize_t panel_scan_debugfs_write(struct file *filp,
  4276. const char __user *buf, size_t count, loff_t *ppos)
  4277. {
  4278. struct pt_device_access_debugfs_data *data = filp->private_data;
  4279. struct pt_device_access_data *dad = data->dad;
  4280. ssize_t length;
  4281. u32 input_data[3];
  4282. int rc = 0;
  4283. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  4284. buf, count);
  4285. if (rc < 0)
  4286. return rc;
  4287. count = rc;
  4288. mutex_lock(&dad->debugfs_lock);
  4289. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  4290. input_data, ARRAY_SIZE(input_data));
  4291. switch (length) {
  4292. case 1:
  4293. dad->panel_scan_retrieve_id = input_data[0];
  4294. dad->panel_scan_type_id = 0;
  4295. break;
  4296. case 2:
  4297. dad->panel_scan_retrieve_id = input_data[0];
  4298. dad->panel_scan_type_id = input_data[1];
  4299. break;
  4300. default:
  4301. pt_debug(dad->dev, DL_ERROR,
  4302. "%s: Malformed input\n", __func__);
  4303. rc = -EINVAL;
  4304. }
  4305. mutex_unlock(&dad->debugfs_lock);
  4306. if (rc)
  4307. return rc;
  4308. return count;
  4309. }
  4310. /*******************************************************************************
  4311. * FUNCTION: panel_scan_debugfs_open
  4312. *
  4313. * SUMMARY: Open the panel_scan debugfs node to initialize.
  4314. *
  4315. * RETURN: 0 = success
  4316. * !0 = failure
  4317. *
  4318. * PARAMETERS:
  4319. * *inode - file inode number
  4320. * *filp - file pointer to debugfs file
  4321. ******************************************************************************/
  4322. static int panel_scan_debugfs_open(struct inode *inode,
  4323. struct file *filp)
  4324. {
  4325. struct pt_device_access_data *dad = inode->i_private;
  4326. struct pt_device_access_debugfs_data *data;
  4327. data = kzalloc(sizeof(*data), GFP_KERNEL);
  4328. if (!data)
  4329. return -ENOMEM;
  4330. data->dad = dad;
  4331. data->pr_buf_len = 4 * PT_MAX_PRBUF_SIZE;
  4332. filp->private_data = data;
  4333. return nonseekable_open(inode, filp);
  4334. }
  4335. /*******************************************************************************
  4336. * FUNCTION: panel_scan_debugfs_close
  4337. *
  4338. * SUMMARY: Close the panel_scan debugfs node to free pointer.
  4339. *
  4340. * RETURN: 0 = success
  4341. *
  4342. * PARAMETERS:
  4343. * *inode - file inode number
  4344. * *filp - file pointer to debugfs file
  4345. ******************************************************************************/
  4346. static int panel_scan_debugfs_close(struct inode *inode,
  4347. struct file *filp)
  4348. {
  4349. kfree(filp->private_data);
  4350. filp->private_data = NULL;
  4351. return 0;
  4352. }
  4353. static const struct file_operations panel_scan_fops = {
  4354. .open = panel_scan_debugfs_open,
  4355. .release = panel_scan_debugfs_close,
  4356. .read = panel_scan_debugfs_read,
  4357. .write = panel_scan_debugfs_write,
  4358. };
  4359. /*******************************************************************************
  4360. * FUNCTION: get_idac_debugfs_read
  4361. *
  4362. * SUMMARY: Retrieve data structure with idac data id by sending the following
  4363. * PIP commands:
  4364. * 1) Suspend Scanning
  4365. * 2) Retrieve data structure
  4366. * 3) Resume Scanning
  4367. * The "Status: n" this node prints, 'n' will be:
  4368. * - zero for a full pass
  4369. * - negative for TTDL communication errors
  4370. * - positive for any FW status errors
  4371. *
  4372. * RETURN: Size of debugfs data print
  4373. *
  4374. * PARAMETERS:
  4375. * *filp - file pointer to debugfs file
  4376. * *buf - the user space buffer to read to
  4377. * count - the maximum number of bytes to read
  4378. * *ppos - the current position in the buffer
  4379. ******************************************************************************/
  4380. static ssize_t get_idac_debugfs_read(struct file *filp, char __user *buf,
  4381. size_t count, loff_t *ppos)
  4382. {
  4383. struct pt_device_access_debugfs_data *data = filp->private_data;
  4384. struct pt_device_access_data *dad = data->dad;
  4385. struct device *dev = dad->dev;
  4386. int status = STATUS_FAIL;
  4387. u8 cmd_status = 0;
  4388. u8 data_format = 0;
  4389. u16 act_length = 0;
  4390. int length = 0;
  4391. int rc;
  4392. if (*ppos)
  4393. goto exit;
  4394. mutex_lock(&dad->sysfs_lock);
  4395. pm_runtime_get_sync(dev);
  4396. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  4397. if (rc) {
  4398. status = rc;
  4399. pt_debug(dev, DL_ERROR,
  4400. "%s: Error on request exclusive rc = %d\n",
  4401. __func__, rc);
  4402. goto put_pm_runtime;
  4403. }
  4404. rc = pt_suspend_scan_cmd_(dev);
  4405. if (rc) {
  4406. status = rc;
  4407. pt_debug(dev, DL_ERROR, "%s: Error on suspend scan rc = %d\n",
  4408. __func__, rc);
  4409. goto release_exclusive;
  4410. }
  4411. rc = pt_get_data_structure_cmd_(dev, 0, PIP_CMD_MAX_LENGTH,
  4412. dad->get_idac_data_id, &cmd_status, &data_format,
  4413. &act_length, &dad->ic_buf[5]);
  4414. if (rc) {
  4415. status = rc;
  4416. pt_debug(dev, DL_ERROR,
  4417. "%s: Error on get data structure rc = %d\n",
  4418. __func__, rc);
  4419. goto resume_scan;
  4420. }
  4421. dad->ic_buf[0] = cmd_status;
  4422. dad->ic_buf[1] = dad->get_idac_data_id;
  4423. dad->ic_buf[2] = LOW_BYTE(act_length);
  4424. dad->ic_buf[3] = HI_BYTE(act_length);
  4425. dad->ic_buf[4] = data_format;
  4426. length = 5 + act_length;
  4427. status = cmd_status;
  4428. resume_scan:
  4429. pt_resume_scan_cmd_(dev);
  4430. release_exclusive:
  4431. cmd->release_exclusive(dev);
  4432. put_pm_runtime:
  4433. pm_runtime_put(dev);
  4434. if (status == STATUS_FAIL)
  4435. length = 0;
  4436. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  4437. data->pr_buf, sizeof(data->pr_buf), PT_PR_FORMAT_DEFAULT);
  4438. mutex_unlock(&dad->sysfs_lock);
  4439. exit:
  4440. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4441. data->pr_buf_len);
  4442. }
  4443. /*******************************************************************************
  4444. * FUNCTION: get_idac_debugfs_write
  4445. *
  4446. * SUMMARY: Store the data id of idac,the read method will perform.
  4447. *
  4448. * RETURN: Size of debugfs data write
  4449. *
  4450. * PARAMETERS:
  4451. * *filp - file pointer to debugfs file
  4452. * *buf - the user space buffer to write to
  4453. * count - the maximum number of bytes to write
  4454. * *ppos - the current position in the buffer
  4455. ******************************************************************************/
  4456. static ssize_t get_idac_debugfs_write(struct file *filp,
  4457. const char __user *buf, size_t count, loff_t *ppos)
  4458. {
  4459. struct pt_device_access_debugfs_data *data = filp->private_data;
  4460. struct pt_device_access_data *dad = data->dad;
  4461. ssize_t length;
  4462. u32 input_data[2];
  4463. int rc = 0;
  4464. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  4465. buf, count);
  4466. if (rc < 0)
  4467. return rc;
  4468. count = rc;
  4469. mutex_lock(&dad->sysfs_lock);
  4470. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  4471. input_data, ARRAY_SIZE(input_data));
  4472. if (length != 1) {
  4473. pt_debug(dad->dev, DL_ERROR,
  4474. "%s: Malformed input\n", __func__);
  4475. rc = -EINVAL;
  4476. goto exit_unlock;
  4477. }
  4478. dad->get_idac_data_id = input_data[0];
  4479. exit_unlock:
  4480. mutex_unlock(&dad->sysfs_lock);
  4481. if (rc)
  4482. return rc;
  4483. return count;
  4484. }
  4485. PT_DEBUGFS_FOPS(get_idac, get_idac_debugfs_read, get_idac_debugfs_write);
  4486. /*******************************************************************************
  4487. * FUNCTION: calibrate_ext_debugfs_read
  4488. *
  4489. * SUMMARY: Perform extended calibration command(0x30) which is flexible to
  4490. * calibrate each individual feature by adding extra parameter for calibration
  4491. * mode.
  4492. *
  4493. * NOTE:
  4494. * - This calibrate command requires the DUT to support PIP version >= 1.10
  4495. * - The "Status:" included in the printout will be one of the following:
  4496. * <0 - Linux error code (PIP transmission error)
  4497. * 0 - Full pass
  4498. * >0 - PIP error status
  4499. *
  4500. * RETURN: Size of debugfs data print
  4501. *
  4502. * PARAMETERS:
  4503. * *filp - file pointer to debugfs file
  4504. * *buf - the user space buffer to read to
  4505. * count - the maximum number of bytes to read
  4506. * *ppos - the current position in the buffer
  4507. ******************************************************************************/
  4508. static ssize_t calibrate_ext_debugfs_read(struct file *filp, char __user *buf,
  4509. size_t count, loff_t *ppos)
  4510. {
  4511. struct pt_device_access_debugfs_data *data = filp->private_data;
  4512. struct pt_device_access_data *dad = data->dad;
  4513. struct device *dev = dad->dev;
  4514. int status = STATUS_FAIL;
  4515. int length = 0;
  4516. int rc;
  4517. if (*ppos)
  4518. goto exit;
  4519. dad->si = cmd->request_sysinfo(dad->dev);
  4520. if (!dad->si) {
  4521. pt_debug(dad->dev, DL_ERROR,
  4522. "%s: Fail get sysinfo pointer from core\n",
  4523. __func__);
  4524. status = -EIO;
  4525. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, 0,
  4526. data->pr_buf, sizeof(data->pr_buf),
  4527. PT_PR_FORMAT_DEFAULT);
  4528. goto exit;
  4529. }
  4530. if (!IS_PIP_VER_GE(dad->si, 1, 10)) {
  4531. pt_debug(dad->dev, DL_ERROR,
  4532. "%s: extended calibration command is not supported\n",
  4533. __func__);
  4534. status = -EPROTONOSUPPORT;
  4535. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, 0,
  4536. data->pr_buf, sizeof(data->pr_buf),
  4537. PT_PR_FORMAT_DEFAULT);
  4538. goto exit;
  4539. }
  4540. if (dad->cal_ext_data.mode == PT_CAL_EXT_MODE_UNDEFINED) {
  4541. pt_debug(dad->dev, DL_ERROR,
  4542. "%s: No parameters provided for calibration command\n",
  4543. __func__);
  4544. status = -EINVAL;
  4545. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, 0,
  4546. data->pr_buf, sizeof(data->pr_buf),
  4547. PT_PR_FORMAT_DEFAULT);
  4548. goto exit;
  4549. }
  4550. mutex_lock(&dad->sysfs_lock);
  4551. pm_runtime_get_sync(dev);
  4552. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  4553. if (rc) {
  4554. status = rc;
  4555. pt_debug(dev, DL_ERROR,
  4556. "%s: Error on request exclusive rc = %d\n",
  4557. __func__, rc);
  4558. goto put_pm_runtime;
  4559. }
  4560. rc = pt_suspend_scan_cmd_(dev);
  4561. if (rc) {
  4562. status = rc;
  4563. pt_debug(dev, DL_ERROR, "%s: Error on suspend scan rc = %d\n",
  4564. __func__, rc);
  4565. goto release_exclusive;
  4566. }
  4567. rc = _pt_calibrate_ext_cmd(dev, &dad->cal_ext_data, &dad->ic_buf[0]);
  4568. if (rc) {
  4569. status = rc;
  4570. pt_debug(dev, DL_ERROR,
  4571. "%s: Error on calibrate_ext rc = %d\n",
  4572. __func__, rc);
  4573. goto resume_scan;
  4574. }
  4575. /*
  4576. * Include PIP errors as positive status codes and report the data.
  4577. * No PIP error "0x00" in the response indicates full success
  4578. */
  4579. length = 1;
  4580. status = dad->ic_buf[0];
  4581. resume_scan:
  4582. pt_resume_scan_cmd_(dev);
  4583. release_exclusive:
  4584. cmd->release_exclusive(dev);
  4585. put_pm_runtime:
  4586. pm_runtime_put(dev);
  4587. /* Negative status codes are bus transmission errors and have no data */
  4588. if (status < 0)
  4589. length = 0;
  4590. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  4591. data->pr_buf, sizeof(data->pr_buf), PT_PR_FORMAT_DEFAULT);
  4592. mutex_unlock(&dad->sysfs_lock);
  4593. exit:
  4594. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4595. data->pr_buf_len);
  4596. }
  4597. /*******************************************************************************
  4598. * FUNCTION: calibrate_ext_debugfs_write
  4599. *
  4600. * SUMMARY: Stores the calibration mode and up to three parameters to perform
  4601. * individual features.
  4602. *
  4603. * RETURN: Size of debugfs data write
  4604. *
  4605. * PARAMETERS:
  4606. * *filp - file pointer to debugfs file
  4607. * *buf - the user space buffer to write to
  4608. * count - the maximum number of bytes to write
  4609. * *ppos - the current position in the buffer
  4610. ******************************************************************************/
  4611. static ssize_t calibrate_ext_debugfs_write(struct file *filp,
  4612. const char __user *buf, size_t count, loff_t *ppos)
  4613. {
  4614. struct pt_device_access_debugfs_data *data = filp->private_data;
  4615. struct pt_device_access_data *dad = data->dad;
  4616. ssize_t length;
  4617. u32 input_data[5];
  4618. int rc = 0;
  4619. int i = 0;
  4620. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  4621. buf, count);
  4622. if (rc < 0)
  4623. return rc;
  4624. count = rc;
  4625. mutex_lock(&dad->sysfs_lock);
  4626. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  4627. input_data, ARRAY_SIZE(input_data));
  4628. if ((length <= 4) && (length > 0)) {
  4629. for (i = length; i < 4; i++)
  4630. input_data[i] = 0;
  4631. dad->cal_ext_data.mode = (u8)input_data[0];
  4632. dad->cal_ext_data.data0 = (u8)input_data[1];
  4633. dad->cal_ext_data.data1 = (u8)input_data[2];
  4634. dad->cal_ext_data.data2 = (u8)input_data[3];
  4635. #ifdef TTDL_DIAGNOSTICS
  4636. pt_debug(dad->dev, DL_INFO,
  4637. "%s: calibration mode=%d, data[0..2]=0x%02X %02X %02X\n",
  4638. __func__,
  4639. dad->cal_ext_data.mode, dad->cal_ext_data.data0,
  4640. dad->cal_ext_data.data1, dad->cal_ext_data.data2);
  4641. #endif
  4642. } else {
  4643. pt_debug(dad->dev, DL_ERROR,
  4644. "%s: Malformed input\n", __func__);
  4645. rc = -EINVAL;
  4646. goto exit_unlock;
  4647. }
  4648. exit_unlock:
  4649. mutex_unlock(&dad->sysfs_lock);
  4650. if (rc)
  4651. return rc;
  4652. return count;
  4653. }
  4654. PT_DEBUGFS_FOPS(calibrate_ext,
  4655. calibrate_ext_debugfs_read, calibrate_ext_debugfs_write);
  4656. /*******************************************************************************
  4657. * FUNCTION: calibrate_debugfs_read
  4658. *
  4659. * SUMMARY: Perform calibration by sending the following PIP commands:
  4660. * 1) Suspend Scanning
  4661. * 2) Execute calibrate
  4662. * 3) Initialize baseline conditionally
  4663. * 4) Resume Scanning
  4664. *
  4665. * RETURN: Size of debugfs data print
  4666. *
  4667. * PARAMETERS:
  4668. * *filp - file pointer to debugfs file
  4669. * *buf - the user space buffer to read to
  4670. * count - the maximum number of bytes to read
  4671. * *ppos - the current position in the buffer
  4672. ******************************************************************************/
  4673. static ssize_t calibrate_debugfs_read(struct file *filp, char __user *buf,
  4674. size_t count, loff_t *ppos)
  4675. {
  4676. struct pt_device_access_debugfs_data *data = filp->private_data;
  4677. struct pt_device_access_data *dad = data->dad;
  4678. struct device *dev = dad->dev;
  4679. int status = STATUS_FAIL;
  4680. int length = 0;
  4681. int rc;
  4682. if (*ppos)
  4683. goto exit;
  4684. mutex_lock(&dad->sysfs_lock);
  4685. pm_runtime_get_sync(dev);
  4686. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  4687. if (rc) {
  4688. status = rc;
  4689. pt_debug(dev, DL_ERROR,
  4690. "%s: Error on request exclusive rc = %d\n",
  4691. __func__, rc);
  4692. goto put_pm_runtime;
  4693. }
  4694. rc = pt_suspend_scan_cmd_(dev);
  4695. if (rc) {
  4696. status = rc;
  4697. pt_debug(dev, DL_ERROR, "%s: Error on suspend scan rc = %d\n",
  4698. __func__, rc);
  4699. goto release_exclusive;
  4700. }
  4701. rc = _pt_calibrate_idacs_cmd(dev, dad->calibrate_sensing_mode,
  4702. &dad->ic_buf[0]);
  4703. if (rc) {
  4704. status = rc;
  4705. pt_debug(dev, DL_ERROR,
  4706. "%s: Error on calibrate idacs rc = %d\n",
  4707. __func__, rc);
  4708. goto resume_scan;
  4709. }
  4710. length = 1;
  4711. /* Check if baseline initialization is requested */
  4712. if (dad->calibrate_initialize_baselines) {
  4713. /* Perform baseline initialization for all modes */
  4714. rc = _pt_initialize_baselines_cmd(dev, PT_IB_SM_MUTCAP |
  4715. PT_IB_SM_SELFCAP | PT_IB_SM_BUTTON,
  4716. &dad->ic_buf[length]);
  4717. if (rc) {
  4718. status = rc;
  4719. pt_debug(dev, DL_ERROR,
  4720. "%s: Error on initialize baselines rc = %d\n",
  4721. __func__, rc);
  4722. goto resume_scan;
  4723. }
  4724. length++;
  4725. }
  4726. status = STATUS_SUCCESS;
  4727. resume_scan:
  4728. pt_resume_scan_cmd_(dev);
  4729. release_exclusive:
  4730. cmd->release_exclusive(dev);
  4731. put_pm_runtime:
  4732. pm_runtime_put(dev);
  4733. if (status == STATUS_FAIL)
  4734. length = 0;
  4735. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  4736. data->pr_buf, sizeof(data->pr_buf), PT_PR_FORMAT_DEFAULT);
  4737. mutex_unlock(&dad->sysfs_lock);
  4738. exit:
  4739. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4740. data->pr_buf_len);
  4741. }
  4742. /*******************************************************************************
  4743. * FUNCTION: calibrate_debugfs_write
  4744. *
  4745. * SUMMARY: Stores the calibration sense mode and a flag to control if the
  4746. * baseline will be initialized for the read method of this node.
  4747. *
  4748. * RETURN: Size of debugfs data write
  4749. *
  4750. * PARAMETERS:
  4751. * *filp - file pointer to debugfs file
  4752. * *buf - the user space buffer to write to
  4753. * count - the maximum number of bytes to write
  4754. * *ppos - the current position in the buffer
  4755. ******************************************************************************/
  4756. static ssize_t calibrate_debugfs_write(struct file *filp,
  4757. const char __user *buf, size_t count, loff_t *ppos)
  4758. {
  4759. struct pt_device_access_debugfs_data *data = filp->private_data;
  4760. struct pt_device_access_data *dad = data->dad;
  4761. ssize_t length;
  4762. u32 input_data[3];
  4763. int rc = 0;
  4764. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  4765. buf, count);
  4766. if (rc < 0)
  4767. return rc;
  4768. count = rc;
  4769. mutex_lock(&dad->sysfs_lock);
  4770. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  4771. input_data, ARRAY_SIZE(input_data));
  4772. if (length != 2) {
  4773. pt_debug(dad->dev, DL_ERROR,
  4774. "%s: Malformed input\n", __func__);
  4775. rc = -EINVAL;
  4776. goto exit_unlock;
  4777. }
  4778. dad->calibrate_sensing_mode = input_data[0];
  4779. dad->calibrate_initialize_baselines = input_data[1];
  4780. exit_unlock:
  4781. mutex_unlock(&dad->sysfs_lock);
  4782. if (rc)
  4783. return rc;
  4784. return count;
  4785. }
  4786. PT_DEBUGFS_FOPS(calibrate, calibrate_debugfs_read, calibrate_debugfs_write);
  4787. /*******************************************************************************
  4788. * FUNCTION: baseline_debugfs_read
  4789. *
  4790. * SUMMARY: Perform baseline initialization by sending the following PIP
  4791. * commands:
  4792. * 1) Suspend Scanning
  4793. * 2) Execute initialize baseline
  4794. * 3) Resume Scanning
  4795. *
  4796. * RETURN: Size of debugfs data print
  4797. *
  4798. * PARAMETERS:
  4799. * *filp - file pointer to debugfs file
  4800. * *buf - the user space buffer to read to
  4801. * count - the maximum number of bytes to read
  4802. * *ppos - the current position in the buffer
  4803. ******************************************************************************/
  4804. static ssize_t baseline_debugfs_read(struct file *filp, char __user *buf,
  4805. size_t count, loff_t *ppos)
  4806. {
  4807. struct pt_device_access_debugfs_data *data = filp->private_data;
  4808. struct pt_device_access_data *dad = data->dad;
  4809. struct device *dev = dad->dev;
  4810. int status = STATUS_FAIL;
  4811. int length = 0;
  4812. int rc;
  4813. if (*ppos)
  4814. goto exit;
  4815. mutex_lock(&dad->sysfs_lock);
  4816. pm_runtime_get_sync(dev);
  4817. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  4818. if (rc) {
  4819. status = rc;
  4820. pt_debug(dev, DL_ERROR,
  4821. "%s: Error on request exclusive rc = %d\n",
  4822. __func__, rc);
  4823. goto put_pm_runtime;
  4824. }
  4825. rc = pt_suspend_scan_cmd_(dev);
  4826. if (rc) {
  4827. status = rc;
  4828. pt_debug(dev, DL_ERROR, "%s: Error on suspend scan rc = %d\n",
  4829. __func__, rc);
  4830. goto release_exclusive;
  4831. }
  4832. rc = _pt_initialize_baselines_cmd(dev, dad->baseline_sensing_mode,
  4833. &dad->ic_buf[0]);
  4834. if (rc) {
  4835. status = rc;
  4836. pt_debug(dev, DL_ERROR,
  4837. "%s: Error on initialize baselines rc = %d\n",
  4838. __func__, rc);
  4839. goto resume_scan;
  4840. }
  4841. length = 1;
  4842. status = STATUS_SUCCESS;
  4843. resume_scan:
  4844. pt_resume_scan_cmd_(dev);
  4845. release_exclusive:
  4846. cmd->release_exclusive(dev);
  4847. put_pm_runtime:
  4848. pm_runtime_put(dev);
  4849. if (status == STATUS_FAIL)
  4850. length = 0;
  4851. data->pr_buf_len = prepare_print_buffer(status, dad->ic_buf, length,
  4852. data->pr_buf, sizeof(data->pr_buf), PT_PR_FORMAT_DEFAULT);
  4853. mutex_unlock(&dad->sysfs_lock);
  4854. exit:
  4855. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4856. data->pr_buf_len);
  4857. }
  4858. /*******************************************************************************
  4859. * FUNCTION: baseline_debugfs_write
  4860. *
  4861. * SUMMARY: Store the sense mode of base initialization, the read method will
  4862. * perform.
  4863. *
  4864. * RETURN: Size of debugfs data write
  4865. *
  4866. * PARAMETERS:
  4867. * *filp - file pointer to debugfs file
  4868. * *buf - the user space buffer to write to
  4869. * count - the maximum number of bytes to write
  4870. * *ppos - the current position in the buffer
  4871. ******************************************************************************/
  4872. static ssize_t baseline_debugfs_write(struct file *filp,
  4873. const char __user *buf, size_t count, loff_t *ppos)
  4874. {
  4875. struct pt_device_access_debugfs_data *data = filp->private_data;
  4876. struct pt_device_access_data *dad = data->dad;
  4877. ssize_t length;
  4878. u32 input_data[2];
  4879. int rc = 0;
  4880. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  4881. buf, count);
  4882. if (rc < 0)
  4883. return rc;
  4884. count = rc;
  4885. mutex_lock(&dad->sysfs_lock);
  4886. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  4887. input_data, ARRAY_SIZE(input_data));
  4888. if (length != 1) {
  4889. pt_debug(dad->dev, DL_ERROR,
  4890. "%s: Malformed input\n", __func__);
  4891. rc = -EINVAL;
  4892. goto exit_unlock;
  4893. }
  4894. dad->baseline_sensing_mode = input_data[0];
  4895. exit_unlock:
  4896. mutex_unlock(&dad->sysfs_lock);
  4897. if (rc)
  4898. return rc;
  4899. return count;
  4900. }
  4901. PT_DEBUGFS_FOPS(baseline, baseline_debugfs_read, baseline_debugfs_write);
  4902. /*******************************************************************************
  4903. * FUNCTION: auto_shorts_debugfs_read
  4904. *
  4905. * SUMMARY: Performs the "auto shorts" test and prints the result to the output
  4906. * buffer.
  4907. *
  4908. * RETURN: Size of debugfs data print
  4909. *
  4910. * PARAMETERS:
  4911. * *filp - file pointer to debugfs file
  4912. * *buf - the user space buffer to read to
  4913. * count - the maximum number of bytes to read
  4914. * *ppos - the current position in the buffer
  4915. ******************************************************************************/
  4916. static ssize_t auto_shorts_debugfs_read(struct file *filp, char __user *buf,
  4917. size_t count, loff_t *ppos)
  4918. {
  4919. struct pt_device_access_debugfs_data *data = filp->private_data;
  4920. if (!*ppos)
  4921. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  4922. data->pr_buf_len = pt_run_and_get_selftest_result(
  4923. data->dad->dev, PT_CORE_CMD_PROTECTED,
  4924. data->pr_buf, sizeof(data->pr_buf),
  4925. PT_ST_ID_AUTOSHORTS, PIP_CMD_MAX_LENGTH,
  4926. PT_ST_DONT_GET_RESULTS, PT_ST_PRINT_RESULTS,
  4927. PT_PR_FORMAT_DEFAULT);
  4928. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4929. data->pr_buf_len);
  4930. }
  4931. PT_DEBUGFS_FOPS(auto_shorts, auto_shorts_debugfs_read, NULL);
  4932. /*******************************************************************************
  4933. * FUNCTION: opens_debugfs_read
  4934. *
  4935. * SUMMARY: Performs the "opens" test and prints the results to the output
  4936. * buffer.
  4937. *
  4938. * RETURN: Size of debugfs data print
  4939. *
  4940. * PARAMETERS:
  4941. * *filp - file pointer to debugfs file
  4942. * *buf - the user space buffer to read to
  4943. * count - the maximum number of bytes to read
  4944. * *ppos - the current position in the buffer
  4945. ******************************************************************************/
  4946. static ssize_t opens_debugfs_read(struct file *filp, char __user *buf,
  4947. size_t count, loff_t *ppos)
  4948. {
  4949. struct pt_device_access_debugfs_data *data = filp->private_data;
  4950. if (!*ppos)
  4951. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  4952. data->pr_buf_len = pt_run_and_get_selftest_result(
  4953. data->dad->dev, PT_CORE_CMD_PROTECTED,
  4954. data->pr_buf, sizeof(data->pr_buf),
  4955. PT_ST_ID_OPENS, PIP_CMD_MAX_LENGTH,
  4956. PT_ST_DONT_GET_RESULTS, PT_ST_PRINT_RESULTS,
  4957. PT_PR_FORMAT_DEFAULT);
  4958. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4959. data->pr_buf_len);
  4960. }
  4961. PT_DEBUGFS_FOPS(opens, opens_debugfs_read, NULL);
  4962. /*******************************************************************************
  4963. * FUNCTION: cm_panel_debugfs_read
  4964. *
  4965. * SUMMARY: Performs the "CM panel" test and prints the result to the output
  4966. * buffer.
  4967. *
  4968. * RETURN: Size of debugfs data print
  4969. *
  4970. * PARAMETERS:
  4971. * *filp - file pointer to debugfs file
  4972. * *buf - the user space buffer to read to
  4973. * count - the maximum number of bytes to read
  4974. * *ppos - the current position in the buffer
  4975. ******************************************************************************/
  4976. static ssize_t cm_panel_debugfs_read(struct file *filp, char __user *buf,
  4977. size_t count, loff_t *ppos)
  4978. {
  4979. struct pt_device_access_debugfs_data *data = filp->private_data;
  4980. if (!*ppos)
  4981. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  4982. data->pr_buf_len = pt_run_and_get_selftest_result(
  4983. data->dad->dev, PT_CORE_CMD_PROTECTED,
  4984. data->pr_buf, sizeof(data->pr_buf),
  4985. PT_ST_ID_CM_PANEL, PIP_CMD_MAX_LENGTH,
  4986. PT_ST_GET_RESULTS, PT_ST_PRINT_RESULTS,
  4987. PT_PR_FORMAT_DEFAULT);
  4988. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  4989. data->pr_buf_len);
  4990. }
  4991. PT_DEBUGFS_FOPS(cm_panel, cm_panel_debugfs_read, NULL);
  4992. /*******************************************************************************
  4993. * FUNCTION: cp_panel_debugfs_read
  4994. *
  4995. * SUMMARY: Performs the "CP panel" test and prints the result to the output
  4996. * buffer.
  4997. *
  4998. * RETURN: Size of debugfs data print
  4999. *
  5000. * PARAMETERS:
  5001. * *filp - file pointer to debugfs file
  5002. * *buf - the user space buffer to read to
  5003. * count - the maximum number of bytes to read
  5004. * *ppos - the current position in the buffer
  5005. ******************************************************************************/
  5006. static ssize_t cp_panel_debugfs_read(struct file *filp, char __user *buf,
  5007. size_t count, loff_t *ppos)
  5008. {
  5009. struct pt_device_access_debugfs_data *data = filp->private_data;
  5010. if (!*ppos)
  5011. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  5012. data->pr_buf_len = pt_run_and_get_selftest_result(
  5013. data->dad->dev, PT_CORE_CMD_PROTECTED,
  5014. data->pr_buf, sizeof(data->pr_buf),
  5015. PT_ST_ID_CP_PANEL, PIP_CMD_MAX_LENGTH,
  5016. PT_ST_GET_RESULTS, PT_ST_PRINT_RESULTS,
  5017. PT_PR_FORMAT_DEFAULT);
  5018. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  5019. data->pr_buf_len);
  5020. }
  5021. PT_DEBUGFS_FOPS(cp_panel, cp_panel_debugfs_read, NULL);
  5022. /*******************************************************************************
  5023. * FUNCTION: cm_button_debugfs_read
  5024. *
  5025. * SUMMARY: Performs the "CM buttons" test and prints the result to the output
  5026. * buffer.
  5027. *
  5028. * RETURN: Size of debugfs data print
  5029. *
  5030. * PARAMETERS:
  5031. * *filp - file pointer to debugfs file
  5032. * *buf - the user space buffer to read to
  5033. * count - the maximum number of bytes to read
  5034. * *ppos - the current position in the buffer
  5035. ******************************************************************************/
  5036. static ssize_t cm_button_debugfs_read(struct file *filp, char __user *buf,
  5037. size_t count, loff_t *ppos)
  5038. {
  5039. struct pt_device_access_debugfs_data *data = filp->private_data;
  5040. if (!*ppos)
  5041. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  5042. data->pr_buf_len = pt_run_and_get_selftest_result(
  5043. data->dad->dev, PT_CORE_CMD_PROTECTED,
  5044. data->pr_buf, sizeof(data->pr_buf),
  5045. PT_ST_ID_CM_BUTTON, PIP_CMD_MAX_LENGTH,
  5046. PT_ST_GET_RESULTS, PT_ST_PRINT_RESULTS,
  5047. PT_PR_FORMAT_DEFAULT);
  5048. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  5049. data->pr_buf_len);
  5050. }
  5051. PT_DEBUGFS_FOPS(cm_button, cm_button_debugfs_read, NULL);
  5052. /*******************************************************************************
  5053. * FUNCTION: cp_button_debugfs_read
  5054. *
  5055. * SUMMARY: Performs the "CP buttons" test and prints the result to the output
  5056. * buffer.
  5057. *
  5058. * RETURN: Size of debugfs data print
  5059. *
  5060. * PARAMETERS:
  5061. * *filp - file pointer to debugfs file
  5062. * *buf - the user space buffer to read to
  5063. * count - the maximum number of bytes to read
  5064. * *ppos - the current position in the buffer
  5065. ******************************************************************************/
  5066. static ssize_t cp_button_debugfs_read(struct file *filp, char __user *buf,
  5067. size_t count, loff_t *ppos)
  5068. {
  5069. struct pt_device_access_debugfs_data *data = filp->private_data;
  5070. if (!*ppos)
  5071. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  5072. data->pr_buf_len = pt_run_and_get_selftest_result(
  5073. data->dad->dev, PT_CORE_CMD_PROTECTED,
  5074. data->pr_buf, sizeof(data->pr_buf),
  5075. PT_ST_ID_CP_BUTTON, PIP_CMD_MAX_LENGTH,
  5076. PT_ST_GET_RESULTS, PT_ST_PRINT_RESULTS,
  5077. PT_PR_FORMAT_DEFAULT);
  5078. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  5079. data->pr_buf_len);
  5080. }
  5081. PT_DEBUGFS_FOPS(cp_button, cp_button_debugfs_read, NULL);
  5082. /*******************************************************************************
  5083. * FUNCTION: fw_self_test_debugfs_read
  5084. *
  5085. * SUMMARY: Performs the self test by firmware and prints the results to the
  5086. * output buffer.
  5087. *
  5088. * RETURN: Size of debugfs data print
  5089. *
  5090. * PARAMETERS:
  5091. * *filp - file pointer to debugfs file
  5092. * *buf - the user space buffer to read to
  5093. * count - the maximum number of bytes to read
  5094. * *ppos - the current position in the buffer
  5095. ******************************************************************************/
  5096. static ssize_t fw_self_test_debugfs_read(struct file *filp, char __user *buf,
  5097. size_t count, loff_t *ppos)
  5098. {
  5099. u8 ret_status;
  5100. u8 ret_self_test_id;
  5101. u8 sys_mode = FW_SYS_MODE_UNDEFINED;
  5102. u16 ret_act_load_len;
  5103. int rc;
  5104. struct pt_device_access_debugfs_data *data = filp->private_data;
  5105. struct pt_device_access_data *dad = data->dad;
  5106. if (!*ppos) {
  5107. if (dad->fw_self_test_id == PT_ST_ID_INVALID ||
  5108. dad->fw_self_test_format >= PT_PR_FORMAT_UNDEFINE) {
  5109. data->pr_buf_len = scnprintf(data->pr_buf,
  5110. sizeof(data->pr_buf), "Status: %d\n", -EINVAL);
  5111. pt_debug(dad->dev, DL_ERROR,
  5112. "%s: Malformed input\n", __func__);
  5113. goto exit;
  5114. }
  5115. /* only send the load parameters cmd if param data exists */
  5116. if (dad->fw_self_test_param_len > 0) {
  5117. rc = cmd->request_get_fw_mode(dad->dev,
  5118. PT_CORE_CMD_UNPROTECTED, &sys_mode, NULL);
  5119. if (rc) {
  5120. pt_debug(dad->dev, DL_ERROR,
  5121. "%s: ERR on request mode rc=%d\n",
  5122. __func__, rc);
  5123. data->pr_buf_len = scnprintf(
  5124. data->pr_buf,
  5125. sizeof(data->pr_buf),
  5126. "Status: %d\n", rc);
  5127. goto exit;
  5128. }
  5129. if (sys_mode != FW_SYS_MODE_TEST) {
  5130. rc = pt_suspend_scan_cmd_(dad->dev);
  5131. if (rc) {
  5132. pt_debug(dad->dev, DL_ERROR,
  5133. "%s: ERR on sus scan rc=%d\n",
  5134. __func__, rc);
  5135. data->pr_buf_len = scnprintf(
  5136. data->pr_buf,
  5137. sizeof(data->pr_buf),
  5138. "Status: %d\n", rc);
  5139. goto exit;
  5140. }
  5141. }
  5142. cmd->nonhid_cmd->load_self_test_param(dad->dev,
  5143. PT_CORE_CMD_PROTECTED,
  5144. dad->fw_self_test_id, 0,
  5145. dad->fw_self_test_param_len,
  5146. dad->fw_self_test_param, &ret_status,
  5147. &ret_self_test_id, &ret_act_load_len);
  5148. if (ret_status) {
  5149. data->pr_buf_len = scnprintf(data->pr_buf,
  5150. sizeof(data->pr_buf),
  5151. "Status: %d\n", -EINVAL);
  5152. pt_debug(dad->dev, DL_ERROR,
  5153. "%s: Load Param Malformed input\n",
  5154. __func__);
  5155. goto resume_scan;
  5156. }
  5157. }
  5158. /* Set length to PIP_CMD_MAX_LENGTH to read all */
  5159. data->pr_buf_len = pt_run_and_get_selftest_result(
  5160. dad->dev, PT_CORE_CMD_PROTECTED,
  5161. data->pr_buf, sizeof(data->pr_buf),
  5162. dad->fw_self_test_id, PIP_CMD_MAX_LENGTH,
  5163. PT_ST_GET_RESULTS, PT_ST_PRINT_RESULTS,
  5164. dad->fw_self_test_format);
  5165. /* Clear the parameters so next test won't use them */
  5166. if (dad->fw_self_test_param_len > 0) {
  5167. cmd->nonhid_cmd->load_self_test_param(dad->dev,
  5168. PT_CORE_CMD_PROTECTED,
  5169. dad->fw_self_test_id, 0, 0, NULL,
  5170. &ret_status, &ret_self_test_id,
  5171. &ret_act_load_len);
  5172. }
  5173. dad->fw_self_test_id = PT_ST_ID_INVALID;
  5174. dad->fw_self_test_format = PT_PR_FORMAT_UNDEFINE;
  5175. dad->fw_self_test_param_len = 0;
  5176. resume_scan:
  5177. /* Only resume scanning if we suspended it */
  5178. if (sys_mode == FW_SYS_MODE_SCANNING)
  5179. pt_resume_scan_cmd_(dad->dev);
  5180. }
  5181. exit:
  5182. return simple_read_from_buffer(buf, count, ppos, data->pr_buf,
  5183. data->pr_buf_len);
  5184. }
  5185. /*******************************************************************************
  5186. * FUNCTION: fw_self_test_debugfs_write
  5187. *
  5188. * SUMMARY: Store the self test ID and ouptut format, the read method will
  5189. * perform.
  5190. *
  5191. * RETURN: Size of debugfs data write
  5192. *
  5193. * PARAMETERS:
  5194. * *filp - file pointer to debugfs file
  5195. * *buf - the user space buffer to write to
  5196. * count - the maximum number of bytes to write
  5197. * *ppos - the current position in the buffer
  5198. ******************************************************************************/
  5199. static ssize_t fw_self_test_debugfs_write(struct file *filp,
  5200. const char __user *buf, size_t count, loff_t *ppos)
  5201. {
  5202. struct pt_device_access_debugfs_data *data = filp->private_data;
  5203. struct pt_device_access_data *dad = data->dad;
  5204. ssize_t length;
  5205. u32 input_data[PT_FW_SELF_TEST_MAX_PARM + 1];
  5206. int rc = 0;
  5207. int i;
  5208. rc = simple_write_to_buffer(data->pr_buf, sizeof(data->pr_buf), ppos,
  5209. buf, count);
  5210. if (rc < 0)
  5211. return rc;
  5212. count = rc;
  5213. mutex_lock(&dad->sysfs_lock);
  5214. length = cmd->parse_sysfs_input(dad->dev, data->pr_buf, count,
  5215. input_data, PT_FW_SELF_TEST_MAX_PARM + 1);
  5216. if (length == 1) {
  5217. dad->fw_self_test_id = input_data[0];
  5218. dad->fw_self_test_format = PT_PR_FORMAT_DEFAULT;
  5219. dad->fw_self_test_param_len = 0;
  5220. } else if (length == 2) {
  5221. dad->fw_self_test_id = input_data[0];
  5222. dad->fw_self_test_format = input_data[1];
  5223. dad->fw_self_test_param_len = 0;
  5224. } else if (length > 2 && (length <= PT_FW_SELF_TEST_MAX_PARM)) {
  5225. dad->fw_self_test_id = input_data[0];
  5226. dad->fw_self_test_format = input_data[1];
  5227. dad->fw_self_test_param_len = length - 2;
  5228. pt_debug(dad->dev, DL_INFO,
  5229. "%s: test_id=%d, format=%d, param_len=%d",
  5230. __func__, dad->fw_self_test_id,
  5231. dad->fw_self_test_format, dad->fw_self_test_param_len);
  5232. for (i = 0; i < dad->fw_self_test_param_len; i++)
  5233. dad->fw_self_test_param[i] = input_data[i + 2];
  5234. } else {
  5235. pt_debug(dad->dev, DL_ERROR,
  5236. "%s: Malformed input\n", __func__);
  5237. rc = -EINVAL;
  5238. goto exit_unlock;
  5239. }
  5240. exit_unlock:
  5241. mutex_unlock(&dad->sysfs_lock);
  5242. if (rc)
  5243. return rc;
  5244. return count;
  5245. }
  5246. PT_DEBUGFS_FOPS(fw_self_test,
  5247. fw_self_test_debugfs_read, fw_self_test_debugfs_write);
  5248. #ifdef TTHE_TUNER_SUPPORT
  5249. /*******************************************************************************
  5250. * FUNCTION: tthe_get_panel_data_debugfs_read
  5251. *
  5252. * SUMMARY: Performs a panel scan and prints the panel data into the output
  5253. * buffer.
  5254. *
  5255. * RETURN: Size of debugfs data print
  5256. *
  5257. * PARAMETERS:
  5258. * *filp - file pointer to debugfs file
  5259. * *buf - the user space buffer to read to
  5260. * count - the maximum number of bytes to read
  5261. * *ppos - the current position in the buffer
  5262. ******************************************************************************/
  5263. static ssize_t tthe_get_panel_data_debugfs_read(struct file *filp,
  5264. char __user *buf, size_t count, loff_t *ppos)
  5265. {
  5266. struct pt_device_access_data *dad = filp->private_data;
  5267. struct device *dev;
  5268. struct pt_core_data *cd;
  5269. u8 config;
  5270. u16 actual_read_len;
  5271. u16 length = 0;
  5272. u8 element_size = 0;
  5273. u8 *buf_offset;
  5274. u8 *buf_out;
  5275. int elem;
  5276. int elem_offset = 0;
  5277. int print_idx = 0;
  5278. int rc;
  5279. int rc1;
  5280. int i;
  5281. mutex_lock(&dad->debugfs_lock);
  5282. dev = dad->dev;
  5283. cd = dev_get_drvdata(dev);
  5284. buf_out = dad->panel_scan_data_buf;
  5285. if (!buf_out)
  5286. goto release_mutex;
  5287. pm_runtime_get_sync(dev);
  5288. rc = cmd->request_exclusive(dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
  5289. if (rc)
  5290. goto put_runtime;
  5291. if (dad->heatmap.scan_start) {
  5292. /*
  5293. * To fix CDT206291: avoid multiple scans when
  5294. * return data is larger than 4096 bytes in one cycle
  5295. */
  5296. dad->heatmap.scan_start = 0;
  5297. /* Start scan */
  5298. rc = pt_exec_scan_cmd_(dev, 0);
  5299. if (rc)
  5300. goto release_exclusive;
  5301. }
  5302. elem = dad->heatmap.num_element;
  5303. #if defined(PT_ENABLE_MAX_ELEN)
  5304. if (elem > PT_MAX_ELEN) {
  5305. rc = pt_ret_scan_data_cmd_(dev, elem_offset,
  5306. PT_MAX_ELEN, dad->heatmap.data_type, dad->ic_buf,
  5307. &config, &actual_read_len, NULL);
  5308. } else {
  5309. rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem,
  5310. dad->heatmap.data_type, dad->ic_buf, &config,
  5311. &actual_read_len, NULL);
  5312. }
  5313. #else
  5314. rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem,
  5315. dad->heatmap.data_type, dad->ic_buf, &config,
  5316. &actual_read_len, NULL);
  5317. #endif
  5318. if (rc)
  5319. goto release_exclusive;
  5320. length = get_unaligned_le16(&dad->ic_buf[0]);
  5321. buf_offset = dad->ic_buf + length;
  5322. element_size = config & PT_CMD_RET_PANEL_ELMNT_SZ_MASK;
  5323. elem -= actual_read_len;
  5324. elem_offset = actual_read_len;
  5325. while (elem > 0) {
  5326. #ifdef PT_ENABLE_MAX_ELEN
  5327. if (elem > PT_MAX_ELEN) {
  5328. rc = pt_ret_scan_data_cmd_(dev, elem_offset,
  5329. PT_MAX_ELEN, dad->heatmap.data_type, NULL, &config,
  5330. &actual_read_len, buf_offset);
  5331. } else {
  5332. rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem,
  5333. dad->heatmap.data_type, NULL, &config,
  5334. &actual_read_len, buf_offset);
  5335. }
  5336. #else
  5337. rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem,
  5338. dad->heatmap.data_type, NULL, &config,
  5339. &actual_read_len, buf_offset);
  5340. #endif
  5341. if (rc)
  5342. goto release_exclusive;
  5343. if (!actual_read_len)
  5344. break;
  5345. length += actual_read_len * element_size;
  5346. buf_offset = dad->ic_buf + length;
  5347. elem -= actual_read_len;
  5348. elem_offset += actual_read_len;
  5349. }
  5350. /* Reconstruct cmd header */
  5351. put_unaligned_le16(length, &dad->ic_buf[0]);
  5352. put_unaligned_le16(elem_offset, &dad->ic_buf[7]);
  5353. release_exclusive:
  5354. rc1 = cmd->release_exclusive(dev);
  5355. put_runtime:
  5356. pm_runtime_put(dev);
  5357. if (rc)
  5358. goto release_mutex;
  5359. if (cd->show_timestamp)
  5360. print_idx += scnprintf(buf_out, TTHE_TUNER_MAX_BUF,
  5361. "[%u] PT_DATA:", pt_get_time_stamp());
  5362. else
  5363. print_idx += scnprintf(buf_out, TTHE_TUNER_MAX_BUF,
  5364. "PT_DATA:");
  5365. for (i = 0; i < length; i++)
  5366. print_idx += scnprintf(buf_out + print_idx,
  5367. TTHE_TUNER_MAX_BUF - print_idx,
  5368. "%02X ", dad->ic_buf[i]);
  5369. print_idx += scnprintf(buf_out + print_idx,
  5370. TTHE_TUNER_MAX_BUF - print_idx,
  5371. ":(%d bytes)\n", length);
  5372. rc = simple_read_from_buffer(buf, count, ppos, buf_out, print_idx);
  5373. print_idx = rc;
  5374. release_mutex:
  5375. mutex_unlock(&dad->debugfs_lock);
  5376. return print_idx;
  5377. }
  5378. /*******************************************************************************
  5379. * FUNCTION: tthe_get_panel_data_debugfs_write
  5380. *
  5381. * SUMMARY: Store the panel data type to retrieve and size of panel data, the
  5382. * read method will perform.
  5383. *
  5384. * RETURN: Size of debugfs data write
  5385. *
  5386. * PARAMETERS:
  5387. * *filp - file pointer to debugfs file
  5388. * *buf - the user space buffer to write to
  5389. * count - the maximum number of bytes to write
  5390. * *ppos - the current position in the buffer
  5391. ******************************************************************************/
  5392. static ssize_t tthe_get_panel_data_debugfs_write(struct file *filp,
  5393. const char __user *buf, size_t count, loff_t *ppos)
  5394. {
  5395. struct pt_device_access_data *dad = filp->private_data;
  5396. struct device *dev = dad->dev;
  5397. ssize_t length;
  5398. int max_read;
  5399. u32 input_data[8];
  5400. u8 *buf_in = dad->panel_scan_data_buf;
  5401. int ret;
  5402. mutex_lock(&dad->debugfs_lock);
  5403. ret = copy_from_user(buf_in + (*ppos), buf, count);
  5404. if (ret)
  5405. goto exit;
  5406. buf_in[count] = 0;
  5407. length = cmd->parse_sysfs_input(dev, buf_in, count, input_data,
  5408. ARRAY_SIZE(input_data));
  5409. if (length <= 0) {
  5410. pt_debug(dev, DL_ERROR,
  5411. "%s: %s Group Data store\n",
  5412. __func__, "Malformed input for");
  5413. goto exit;
  5414. }
  5415. /* update parameter value */
  5416. dad->heatmap.num_element = input_data[3] + (input_data[4] << 8);
  5417. dad->heatmap.data_type = input_data[5];
  5418. if (input_data[6] > 0)
  5419. dad->heatmap.scan_start = true;
  5420. else
  5421. dad->heatmap.scan_start = false;
  5422. /* elem can not be bigger then buffer size */
  5423. max_read = PT_CMD_RET_PANEL_HDR;
  5424. max_read += dad->heatmap.num_element * PT_CMD_RET_PANEL_ELMNT_SZ_MAX;
  5425. if (max_read >= PT_MAX_PRBUF_SIZE) {
  5426. dad->heatmap.num_element =
  5427. (PT_MAX_PRBUF_SIZE - PT_CMD_RET_PANEL_HDR)
  5428. / PT_CMD_RET_PANEL_ELMNT_SZ_MAX;
  5429. pt_debug(dev, DL_INFO, "%s: Will get %d element\n",
  5430. __func__, dad->heatmap.num_element);
  5431. }
  5432. exit:
  5433. mutex_unlock(&dad->debugfs_lock);
  5434. pt_debug(dev, DL_INFO, "%s: return count=%zu\n",
  5435. __func__, count);
  5436. return count;
  5437. }
  5438. /*******************************************************************************
  5439. * FUNCTION: tthe_get_panel_data_debugfs_open
  5440. *
  5441. * SUMMARY: Open the get_panel_data debugfs node to initialize.
  5442. *
  5443. * RETURN:
  5444. * 0 = success
  5445. * !0 = failure
  5446. *
  5447. * PARAMETERS:
  5448. * *inode - pointer to inode structure
  5449. * *filp - pointer to file structure
  5450. ******************************************************************************/
  5451. static int tthe_get_panel_data_debugfs_open(struct inode *inode,
  5452. struct file *filp)
  5453. {
  5454. struct pt_device_access_data *dad = inode->i_private;
  5455. mutex_lock(&dad->debugfs_lock);
  5456. if (dad->tthe_get_panel_data_is_open) {
  5457. mutex_unlock(&dad->debugfs_lock);
  5458. return -EBUSY;
  5459. }
  5460. filp->private_data = inode->i_private;
  5461. dad->tthe_get_panel_data_is_open = 1;
  5462. mutex_unlock(&dad->debugfs_lock);
  5463. return 0;
  5464. }
  5465. /*******************************************************************************
  5466. * FUNCTION: tthe_get_panel_data_debugfs_close
  5467. *
  5468. * SUMMARY: Close the get_panel_data debugfs node to free pointer.
  5469. *
  5470. * RETURN:
  5471. * 0 = success
  5472. * !0 = failure
  5473. *
  5474. * PARAMETERS:
  5475. * *inode - pointer to inode structure
  5476. * *filp - pointer to file structure
  5477. ******************************************************************************/
  5478. static int tthe_get_panel_data_debugfs_close(struct inode *inode,
  5479. struct file *filp)
  5480. {
  5481. struct pt_device_access_data *dad = filp->private_data;
  5482. mutex_lock(&dad->debugfs_lock);
  5483. filp->private_data = NULL;
  5484. dad->tthe_get_panel_data_is_open = 0;
  5485. mutex_unlock(&dad->debugfs_lock);
  5486. return 0;
  5487. }
  5488. static const struct file_operations tthe_get_panel_data_fops = {
  5489. .open = tthe_get_panel_data_debugfs_open,
  5490. .release = tthe_get_panel_data_debugfs_close,
  5491. .read = tthe_get_panel_data_debugfs_read,
  5492. .write = tthe_get_panel_data_debugfs_write,
  5493. };
  5494. #endif
  5495. /*******************************************************************************
  5496. * FUNCTION: pt_setup_sysfs
  5497. *
  5498. * SUMMARY: Creates all device test dependent sysfs nodes owned by the
  5499. * device access file.
  5500. *
  5501. * RETURN:
  5502. * 0 = success
  5503. * !0 = failure
  5504. *
  5505. * PARAMETERS:
  5506. * *dev - pointer to device structure
  5507. ******************************************************************************/
  5508. static int pt_setup_sysfs(struct device *dev)
  5509. {
  5510. struct pt_device_access_data *dad
  5511. = pt_get_device_access_data(dev);
  5512. int rc = 0;
  5513. pt_debug(dev, DL_INFO, "Entering %s\n", __func__);
  5514. dad->base_dentry = debugfs_create_dir(dev_name(dev), NULL);
  5515. if (IS_ERR_OR_NULL(dad->base_dentry)) {
  5516. pt_debug(dev, DL_ERROR,
  5517. "%s: Error, could not create base directory\n",
  5518. __func__);
  5519. goto exit;
  5520. }
  5521. dad->mfg_test_dentry = debugfs_create_dir("mfg_test",
  5522. dad->base_dentry);
  5523. if (IS_ERR_OR_NULL(dad->mfg_test_dentry)) {
  5524. pt_debug(dev, DL_ERROR,
  5525. "%s: Error, could not create mfg_test directory\n",
  5526. __func__);
  5527. goto unregister_base_dir;
  5528. }
  5529. dad->panel_scan_debugfs = debugfs_create_file(
  5530. "panel_scan", 0644, dad->mfg_test_dentry, dad,
  5531. &panel_scan_fops);
  5532. if (IS_ERR_OR_NULL(dad->panel_scan_debugfs)) {
  5533. pt_debug(dev, DL_ERROR,
  5534. "%s: Error, could not create panel_scan\n",
  5535. __func__);
  5536. goto unregister_base_dir;
  5537. }
  5538. if (IS_ERR_OR_NULL(debugfs_create_file("get_idac", 0600,
  5539. dad->mfg_test_dentry, dad, &get_idac_debugfs_fops))) {
  5540. pt_debug(dev, DL_ERROR,
  5541. "%s: Error, could not create get_idac\n",
  5542. __func__);
  5543. goto unregister_base_dir;
  5544. }
  5545. if (IS_ERR_OR_NULL(debugfs_create_file("auto_shorts", 0400,
  5546. dad->mfg_test_dentry, dad,
  5547. &auto_shorts_debugfs_fops))) {
  5548. pt_debug(dev, DL_ERROR,
  5549. "%s: Error, could not create auto_shorts\n",
  5550. __func__);
  5551. goto unregister_base_dir;
  5552. }
  5553. if (IS_ERR_OR_NULL(debugfs_create_file("opens", 0400,
  5554. dad->mfg_test_dentry, dad, &opens_debugfs_fops))) {
  5555. pt_debug(dev, DL_ERROR,
  5556. "%s: Error, could not create opens\n",
  5557. __func__);
  5558. goto unregister_base_dir;
  5559. }
  5560. if (IS_ERR_OR_NULL(debugfs_create_file("calibrate_ext",
  5561. 0600, dad->mfg_test_dentry,
  5562. dad, &calibrate_ext_debugfs_fops))) {
  5563. pt_debug(dev, DL_ERROR,
  5564. "%s: Error, could not create calibrate_ext\n",
  5565. __func__);
  5566. goto unregister_base_dir;
  5567. }
  5568. if (IS_ERR_OR_NULL(debugfs_create_file("calibrate", 0600,
  5569. dad->mfg_test_dentry, dad, &calibrate_debugfs_fops))) {
  5570. pt_debug(dev, DL_ERROR,
  5571. "%s: Error, could not create calibrate\n",
  5572. __func__);
  5573. goto unregister_base_dir;
  5574. }
  5575. if (IS_ERR_OR_NULL(debugfs_create_file("baseline", 0600,
  5576. dad->mfg_test_dentry, dad, &baseline_debugfs_fops))) {
  5577. pt_debug(dev, DL_ERROR,
  5578. "%s: Error, could not create baseline\n",
  5579. __func__);
  5580. goto unregister_base_dir;
  5581. }
  5582. if (IS_ERR_OR_NULL(debugfs_create_file("cm_panel", 0400,
  5583. dad->mfg_test_dentry, dad, &cm_panel_debugfs_fops))) {
  5584. pt_debug(dev, DL_ERROR,
  5585. "%s: Error, could not create cm_panel\n",
  5586. __func__);
  5587. goto unregister_base_dir;
  5588. }
  5589. if (IS_ERR_OR_NULL(debugfs_create_file("cp_panel", 0400,
  5590. dad->mfg_test_dentry, dad, &cp_panel_debugfs_fops))) {
  5591. pt_debug(dev, DL_ERROR,
  5592. "%s: Error, could not create cp_panel\n",
  5593. __func__);
  5594. goto unregister_base_dir;
  5595. }
  5596. if (IS_ERR_OR_NULL(debugfs_create_file("cm_button", 0400,
  5597. dad->mfg_test_dentry, dad, &cm_button_debugfs_fops))) {
  5598. pt_debug(dev, DL_ERROR,
  5599. "%s: Error, could not create cm_button\n",
  5600. __func__);
  5601. goto unregister_base_dir;
  5602. }
  5603. if (IS_ERR_OR_NULL(debugfs_create_file("cp_button", 0400,
  5604. dad->mfg_test_dentry, dad, &cp_button_debugfs_fops))) {
  5605. pt_debug(dev, DL_ERROR,
  5606. "%s: Error, could not create cp_button\n",
  5607. __func__);
  5608. goto unregister_base_dir;
  5609. }
  5610. if (IS_ERR_OR_NULL(debugfs_create_file("fw_self_test", 0600,
  5611. dad->mfg_test_dentry, dad, &fw_self_test_debugfs_fops))) {
  5612. pt_debug(dev, DL_ERROR,
  5613. "%s: Error, could not create fw_self_test\n",
  5614. __func__);
  5615. goto unregister_base_dir;
  5616. }
  5617. dad->cmcp_results_debugfs = debugfs_create_file("cmcp_results", 0644,
  5618. dad->mfg_test_dentry, dad, &cmcp_results_debugfs_fops);
  5619. if (IS_ERR_OR_NULL(dad->cmcp_results_debugfs)) {
  5620. pt_debug(dev, DL_ERROR,
  5621. "%s: Error, could not create cmcp_results\n",
  5622. __func__);
  5623. dad->cmcp_results_debugfs = NULL;
  5624. goto unregister_base_dir;
  5625. }
  5626. #ifdef TTHE_TUNER_SUPPORT
  5627. dad->tthe_get_panel_data_debugfs = debugfs_create_file(
  5628. PT_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME,
  5629. 0644, NULL, dad, &tthe_get_panel_data_fops);
  5630. if (IS_ERR_OR_NULL(dad->tthe_get_panel_data_debugfs)) {
  5631. pt_debug(dev, DL_ERROR,
  5632. "%s: Error, could not create get_panel_data\n",
  5633. __func__);
  5634. dad->tthe_get_panel_data_debugfs = NULL;
  5635. goto unregister_base_dir;
  5636. }
  5637. #endif
  5638. rc = device_create_file(dev, &dev_attr_cmcp_test);
  5639. if (rc) {
  5640. pt_debug(dev, DL_ERROR,
  5641. "%s: Error, could not create cmcp_test\n",
  5642. __func__);
  5643. goto unregister_base_dir;
  5644. }
  5645. rc = device_create_file(dev, &dev_attr_cmcp_threshold_loading);
  5646. if (rc) {
  5647. pt_debug(dev, DL_ERROR,
  5648. "%s: Error, could not create cmcp_threshold_loading\n",
  5649. __func__);
  5650. goto unregister_cmcp_test;
  5651. }
  5652. rc = device_create_bin_file(dev, &bin_attr_cmcp_threshold_data);
  5653. if (rc) {
  5654. pt_debug(dev, DL_ERROR,
  5655. "%s: Error, could not create cmcp_threshold_data\n",
  5656. __func__);
  5657. goto unregister_cmcp_thresold_loading;
  5658. }
  5659. dad->sysfs_nodes_created = true;
  5660. return rc;
  5661. unregister_cmcp_thresold_loading:
  5662. device_remove_file(dev, &dev_attr_cmcp_threshold_loading);
  5663. unregister_cmcp_test:
  5664. device_remove_file(dev, &dev_attr_cmcp_test);
  5665. unregister_base_dir:
  5666. debugfs_remove_recursive(dad->base_dentry);
  5667. exit:
  5668. return rc;
  5669. }
  5670. /*******************************************************************************
  5671. * FUNCTION: pt_setup_cmcp_attention
  5672. *
  5673. * SUMMARY: Function to be registered to TTDL attention list to setup sysfs and
  5674. * parse threshold file for device test.
  5675. *
  5676. * RETURN:
  5677. * 0 = success
  5678. * !0 = failure
  5679. *
  5680. * PARAMETERS:
  5681. * *dev - pointer to device structure
  5682. ******************************************************************************/
  5683. static int pt_setup_cmcp_attention(struct device *dev)
  5684. {
  5685. struct pt_device_access_data *dad
  5686. = pt_get_device_access_data(dev);
  5687. int rc = 0;
  5688. dad->si = cmd->request_sysinfo(dev);
  5689. if (!dad->si)
  5690. return -EINVAL;
  5691. rc = pt_setup_sysfs(dev);
  5692. schedule_work(&dad->cmcp_threshold_update);
  5693. cmd->unsubscribe_attention(dev, PT_ATTEN_STARTUP,
  5694. PT_DEVICE_ACCESS_NAME, pt_setup_cmcp_attention,
  5695. 0);
  5696. return rc;
  5697. }
  5698. /*******************************************************************************
  5699. * FUNCTION: pt_cmcp_parse_threshold_file
  5700. *
  5701. * SUMMARY: Parse cmcp threshold file and store it to the structure.
  5702. *
  5703. * PARAMETERS:
  5704. * *fw - pointer to firmware structure
  5705. * *context - expected read length of the response
  5706. ******************************************************************************/
  5707. static void pt_cmcp_parse_threshold_file(const struct firmware *fw,
  5708. void *context)
  5709. {
  5710. struct device *dev = context;
  5711. struct pt_device_access_data *dad =
  5712. pt_get_device_access_data(dev);
  5713. if (!fw) {
  5714. pt_debug(dev, DL_WARN,
  5715. "%s: No builtin cmcp threshold file\n",
  5716. __func__);
  5717. goto exit;
  5718. }
  5719. if (!fw->data || !fw->size) {
  5720. pt_debug(dev, DL_ERROR,
  5721. "%s: Invalid builtin cmcp threshold file\n",
  5722. __func__);
  5723. goto exit;
  5724. }
  5725. pt_debug(dev, DL_WARN, "%s: Found cmcp threshold file.\n",
  5726. __func__);
  5727. pt_parse_cmcp_threshold_file_common(dev, &fw->data[0], fw->size);
  5728. dad->builtin_cmcp_threshold_status = 0;
  5729. release_firmware(fw);
  5730. return;
  5731. exit:
  5732. if (fw)
  5733. release_firmware(fw);
  5734. dad->builtin_cmcp_threshold_status = -EINVAL;
  5735. }
  5736. /*******************************************************************************
  5737. * FUNCTION: pt_device_access_user_command
  5738. *
  5739. * SUMMARY: Wrapper function to call pt_cmcp_parse_threshold_file() by firmware
  5740. * class function.
  5741. *
  5742. * PARAMETERS:
  5743. * *cmcp_threshold_update - pointer to work_struct structure
  5744. ******************************************************************************/
  5745. static void pt_parse_cmcp_threshold_builtin(
  5746. struct work_struct *cmcp_threshold_update)
  5747. {
  5748. struct pt_device_access_data *dad =
  5749. container_of(cmcp_threshold_update,
  5750. struct pt_device_access_data,
  5751. cmcp_threshold_update);
  5752. struct device *dev = dad->dev;
  5753. struct pt_core_data *cd = dev_get_drvdata(dev);
  5754. const struct firmware *fw_entry = NULL;
  5755. int retval;
  5756. dad->si = cmd->request_sysinfo(dev);
  5757. if (!dad->si) {
  5758. pt_debug(dev, DL_ERROR,
  5759. "%s: Fail get sysinfo pointer from core\n",
  5760. __func__);
  5761. return;
  5762. }
  5763. pt_debug(dev, DL_INFO,
  5764. "%s: Enabling cmcp threshold class loader built-in\n",
  5765. __func__);
  5766. /* Open threshold file */
  5767. mutex_lock(&cd->firmware_class_lock);
  5768. #if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE)
  5769. retval = request_firmware(&fw_entry, CMCP_THRESHOLD_FILE_NAME, dev);
  5770. #else
  5771. retval = request_firmware_direct(&fw_entry,
  5772. CMCP_THRESHOLD_FILE_NAME, dev);
  5773. #endif
  5774. if (retval < 0) {
  5775. pt_debug(dev, DL_WARN,
  5776. "%s: Failed loading cmcp threshold file, attempting legacy file\n",
  5777. __func__);
  5778. /* Try legacy file name */
  5779. #if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE)
  5780. retval = request_firmware(&fw_entry,
  5781. PT_CMCP_THRESHOLD_FILE_NAME, dev);
  5782. #else
  5783. retval = request_firmware_direct(&fw_entry,
  5784. PT_CMCP_THRESHOLD_FILE_NAME, dev);
  5785. #endif
  5786. if (retval < 0) {
  5787. mutex_unlock(&cd->firmware_class_lock);
  5788. dad->builtin_cmcp_threshold_status = -EINVAL;
  5789. pt_debug(dev, DL_WARN,
  5790. "%s: Fail request cmcp threshold class file load\n",
  5791. __func__);
  5792. goto exit;
  5793. }
  5794. }
  5795. pt_cmcp_parse_threshold_file(fw_entry, dev);
  5796. mutex_unlock(&cd->firmware_class_lock);
  5797. exit:
  5798. return;
  5799. }
  5800. /*******************************************************************************
  5801. * FUNCTION: pt_device_access_probe
  5802. *
  5803. * SUMMARY: The probe function for the device access
  5804. *
  5805. * PARAMETERS:
  5806. * *dev - pointer to device structure
  5807. * **data - double pointer to pt_device_access_data data to be created here
  5808. ******************************************************************************/
  5809. static int pt_device_access_probe(struct device *dev, void **data)
  5810. {
  5811. struct pt_device_access_data *dad;
  5812. struct configuration *configurations;
  5813. struct cmcp_data *cmcp_info;
  5814. struct result *result;
  5815. int tx_num = MAX_TX_SENSORS;
  5816. int rx_num = MAX_RX_SENSORS;
  5817. int btn_num = MAX_BUTTONS;
  5818. struct test_case_field *test_case_field_array;
  5819. struct test_case_search *test_case_search_array;
  5820. int rc = 0;
  5821. dad = kzalloc(sizeof(*dad), GFP_KERNEL);
  5822. if (!dad) {
  5823. rc = -ENOMEM;
  5824. goto pt_device_access_probe_data_failed;
  5825. }
  5826. configurations =
  5827. kzalloc(sizeof(*configurations), GFP_KERNEL);
  5828. if (!configurations) {
  5829. rc = -ENOMEM;
  5830. goto pt_device_access_probe_configs_failed;
  5831. }
  5832. dad->configs = configurations;
  5833. cmcp_info = kzalloc(sizeof(*cmcp_info), GFP_KERNEL);
  5834. if (!cmcp_info) {
  5835. rc = -ENOMEM;
  5836. goto pt_device_access_probe_cmcp_info_failed;
  5837. }
  5838. dad->cmcp_info = cmcp_info;
  5839. cmcp_info->tx_num = tx_num;
  5840. cmcp_info->rx_num = rx_num;
  5841. cmcp_info->btn_num = btn_num;
  5842. result = kzalloc(sizeof(*result), GFP_KERNEL);
  5843. if (!result) {
  5844. rc = -ENOMEM;
  5845. goto pt_device_access_probe_result_failed;
  5846. }
  5847. dad->result = result;
  5848. test_case_field_array =
  5849. kzalloc(sizeof(*test_case_field_array) * MAX_CASE_NUM,
  5850. GFP_KERNEL);
  5851. if (!test_case_field_array) {
  5852. rc = -ENOMEM;
  5853. goto pt_device_access_probe_field_array_failed;
  5854. }
  5855. test_case_search_array =
  5856. kzalloc(sizeof(*test_case_search_array) * MAX_CASE_NUM,
  5857. GFP_KERNEL);
  5858. if (!test_case_search_array) {
  5859. rc = -ENOMEM;
  5860. goto pt_device_access_probe_search_array_failed;
  5861. }
  5862. cmcp_info->gd_sensor_col = (struct gd_sensor *)
  5863. kzalloc(tx_num * sizeof(struct gd_sensor), GFP_KERNEL);
  5864. if (cmcp_info->gd_sensor_col == NULL)
  5865. goto pt_device_access_probe_gd_sensor_col_failed;
  5866. cmcp_info->gd_sensor_row = (struct gd_sensor *)
  5867. kzalloc(rx_num * sizeof(struct gd_sensor), GFP_KERNEL);
  5868. if (cmcp_info->gd_sensor_row == NULL)
  5869. goto pt_device_access_probe_gd_sensor_row_failed;
  5870. cmcp_info->cm_data_panel =
  5871. kzalloc((tx_num * rx_num + 1) * sizeof(int32_t), GFP_KERNEL);
  5872. if (cmcp_info->cm_data_panel == NULL)
  5873. goto pt_device_access_probe_cm_data_panel_failed;
  5874. cmcp_info->cp_tx_data_panel =
  5875. kzalloc(tx_num * sizeof(int32_t), GFP_KERNEL);
  5876. if (cmcp_info->cp_tx_data_panel == NULL)
  5877. goto pt_device_access_probe_cp_tx_data_panel_failed;
  5878. cmcp_info->cp_tx_cal_data_panel =
  5879. kzalloc(tx_num * sizeof(int32_t), GFP_KERNEL);
  5880. if (cmcp_info->cp_tx_cal_data_panel == NULL)
  5881. goto pt_device_access_probe_cp_tx_cal_data_panel_failed;
  5882. cmcp_info->cp_rx_data_panel =
  5883. kzalloc(rx_num * sizeof(int32_t), GFP_KERNEL);
  5884. if (cmcp_info->cp_rx_data_panel == NULL)
  5885. goto pt_device_access_probe_cp_rx_data_panel_failed;
  5886. cmcp_info->cp_rx_cal_data_panel =
  5887. kzalloc(rx_num * sizeof(int32_t), GFP_KERNEL);
  5888. if (cmcp_info->cp_rx_cal_data_panel == NULL)
  5889. goto pt_device_access_probe_cp_rx_cal_data_panel_failed;
  5890. cmcp_info->cm_btn_data = kcalloc(btn_num, sizeof(int32_t), GFP_KERNEL);
  5891. if (cmcp_info->cm_btn_data == NULL)
  5892. goto pt_device_access_probe_cm_btn_data_failed;
  5893. cmcp_info->cp_btn_data = kcalloc(btn_num, sizeof(int32_t), GFP_KERNEL);
  5894. if (cmcp_info->cp_btn_data == NULL)
  5895. goto pt_device_access_probe_cp_btn_data_failed;
  5896. cmcp_info->cm_sensor_column_delta =
  5897. kzalloc(rx_num * tx_num * sizeof(int32_t), GFP_KERNEL);
  5898. if (cmcp_info->cm_sensor_column_delta == NULL)
  5899. goto pt_device_access_probe_cm_sensor_column_delta_failed;
  5900. cmcp_info->cm_sensor_row_delta =
  5901. kzalloc(tx_num * rx_num * sizeof(int32_t), GFP_KERNEL);
  5902. if (cmcp_info->cm_sensor_row_delta == NULL)
  5903. goto pt_device_access_probe_cm_sensor_row_delta_failed;
  5904. mutex_init(&dad->sysfs_lock);
  5905. mutex_init(&dad->cmcp_threshold_lock);
  5906. dad->dev = dev;
  5907. #ifdef TTHE_TUNER_SUPPORT
  5908. mutex_init(&dad->debugfs_lock);
  5909. dad->heatmap.num_element = 200;
  5910. #endif
  5911. *data = dad;
  5912. dad->test_field_array = test_case_field_array;
  5913. dad->test_search_array = test_case_search_array;
  5914. dad->test_executed = 0;
  5915. dad->cal_ext_data.mode = PT_CAL_EXT_MODE_UNDEFINED;
  5916. dad->panel_scan_retrieve_id = 0;
  5917. dad->panel_scan_type_id = 0;
  5918. INIT_WORK(&dad->cmcp_threshold_update, pt_parse_cmcp_threshold_builtin);
  5919. /* get sysinfo */
  5920. dad->si = cmd->request_sysinfo(dev);
  5921. if (dad->si) {
  5922. rc = pt_setup_sysfs(dev);
  5923. if (rc)
  5924. goto pt_device_access_setup_sysfs_failed;
  5925. } else {
  5926. pt_debug(dev, DL_ERROR,
  5927. "%s: Fail get sysinfo pointer from core p=%p\n",
  5928. __func__, dad->si);
  5929. cmd->subscribe_attention(dev, PT_ATTEN_STARTUP,
  5930. PT_DEVICE_ACCESS_NAME,
  5931. pt_setup_cmcp_attention, 0);
  5932. }
  5933. schedule_work(&dad->cmcp_threshold_update);
  5934. return 0;
  5935. pt_device_access_setup_sysfs_failed:
  5936. kfree(cmcp_info->cm_sensor_row_delta);
  5937. pt_device_access_probe_cm_sensor_row_delta_failed:
  5938. kfree(cmcp_info->cm_sensor_column_delta);
  5939. pt_device_access_probe_cm_sensor_column_delta_failed:
  5940. kfree(cmcp_info->cp_btn_data);
  5941. pt_device_access_probe_cp_btn_data_failed:
  5942. kfree(cmcp_info->cm_btn_data);
  5943. pt_device_access_probe_cm_btn_data_failed:
  5944. kfree(cmcp_info->cp_rx_cal_data_panel);
  5945. pt_device_access_probe_cp_rx_cal_data_panel_failed:
  5946. kfree(cmcp_info->cp_rx_data_panel);
  5947. pt_device_access_probe_cp_rx_data_panel_failed:
  5948. kfree(cmcp_info->cp_tx_cal_data_panel);
  5949. pt_device_access_probe_cp_tx_cal_data_panel_failed:
  5950. kfree(cmcp_info->cp_tx_data_panel);
  5951. pt_device_access_probe_cp_tx_data_panel_failed:
  5952. kfree(cmcp_info->cm_data_panel);
  5953. pt_device_access_probe_cm_data_panel_failed:
  5954. kfree(cmcp_info->gd_sensor_row);
  5955. pt_device_access_probe_gd_sensor_row_failed:
  5956. kfree(cmcp_info->gd_sensor_col);
  5957. pt_device_access_probe_gd_sensor_col_failed:
  5958. kfree(test_case_search_array);
  5959. pt_device_access_probe_search_array_failed:
  5960. kfree(test_case_field_array);
  5961. pt_device_access_probe_field_array_failed:
  5962. kfree(result);
  5963. pt_device_access_probe_result_failed:
  5964. kfree(cmcp_info);
  5965. pt_device_access_probe_cmcp_info_failed:
  5966. kfree(configurations);
  5967. pt_device_access_probe_configs_failed:
  5968. kfree(dad);
  5969. pt_device_access_probe_data_failed:
  5970. pt_debug(dev, DL_ERROR, "%s failed.\n", __func__);
  5971. return rc;
  5972. }
  5973. /*******************************************************************************
  5974. * FUNCTION: pt_device_access_release
  5975. *
  5976. * SUMMARY: Remove function for device_access module that does following
  5977. * cleanup:
  5978. * - Unsubscibe all registered attention tasks
  5979. * - Removes all created sysfs nodes
  5980. * - Frees all pointers
  5981. *
  5982. * PARAMETERS:
  5983. * *dev - pointer to device structure
  5984. * *data - pointer to the device_access data
  5985. ******************************************************************************/
  5986. static void pt_device_access_release(struct device *dev, void *data)
  5987. {
  5988. struct pt_device_access_data *dad = data;
  5989. if (dad->sysfs_nodes_created) {
  5990. debugfs_remove(dad->cmcp_results_debugfs);
  5991. debugfs_remove_recursive(dad->base_dentry);
  5992. #ifdef TTHE_TUNER_SUPPORT
  5993. debugfs_remove(dad->tthe_get_panel_data_debugfs);
  5994. #endif
  5995. device_remove_file(dev, &dev_attr_cmcp_test);
  5996. device_remove_file(dev, &dev_attr_cmcp_threshold_loading);
  5997. device_remove_bin_file(dev, &bin_attr_cmcp_threshold_data);
  5998. kfree(dad->cmcp_threshold_data);
  5999. } else {
  6000. cmd->unsubscribe_attention(dev, PT_ATTEN_STARTUP,
  6001. PT_DEVICE_ACCESS_NAME,
  6002. pt_setup_cmcp_attention, 0);
  6003. }
  6004. kfree(dad->test_search_array);
  6005. kfree(dad->test_field_array);
  6006. kfree(dad->configs);
  6007. pt_free_cmcp_buf(dad->cmcp_info);
  6008. kfree(dad->cmcp_info);
  6009. kfree(dad->result);
  6010. kfree(dad);
  6011. }
  6012. static struct pt_module device_access_module = {
  6013. .name = PT_DEVICE_ACCESS_NAME,
  6014. .probe = pt_device_access_probe,
  6015. .release = pt_device_access_release,
  6016. };
  6017. /*******************************************************************************
  6018. * FUNCTION: pt_device_access_init
  6019. *
  6020. * SUMMARY: Initialize function for device access module which to register
  6021. * device_access_module into TTDL module list.
  6022. *
  6023. * RETURN:
  6024. * 0 = success
  6025. * !0 = failure
  6026. ******************************************************************************/
  6027. static int __init pt_device_access_init(void)
  6028. {
  6029. int rc;
  6030. cmd = pt_get_commands();
  6031. if (!cmd)
  6032. return -EINVAL;
  6033. rc = pt_register_module(&device_access_module);
  6034. if (rc) {
  6035. pr_err("%s: Error, failed registering module\n",
  6036. __func__);
  6037. return rc;
  6038. }
  6039. pr_info("%s: Parade TTSP Device Access Driver (Built %s) rc = %d\n",
  6040. __func__, PT_DRIVER_VERSION, rc);
  6041. return 0;
  6042. }
  6043. module_init(pt_device_access_init);
  6044. /*******************************************************************************
  6045. * FUNCTION: pt_device_access_exit
  6046. *
  6047. * SUMMARY: Exit function for device access module which to unregister
  6048. * device_access_module from TTDL module list.
  6049. *
  6050. ******************************************************************************/
  6051. static void __exit pt_device_access_exit(void)
  6052. {
  6053. pt_unregister_module(&device_access_module);
  6054. }
  6055. module_exit(pt_device_access_exit);
  6056. MODULE_LICENSE("GPL");
  6057. MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product Device Access Driver");
  6058. MODULE_AUTHOR("Parade Technologies <[email protected]>");