123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (C) 2016-2019, STMicroelectronics Limited.
- * Authors: AMG(Analog Mems Group)
- *
- * [email protected]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- #include <linux/device.h>
- #include <linux/irq.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/input.h>
- #include <linux/input/mt.h>
- #include <linux/interrupt.h>
- #include <linux/hrtimer.h>
- #include <linux/delay.h>
- #include <linux/firmware.h>
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
- #include <linux/completion.h>
- /*#include <linux/wakelock.h>*/
- #include <linux/pm_wakeup.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <linux/of_irq.h>
- #include <linux/gpio.h>
- #include <linux/of_gpio.h>
- #include <linux/regulator/consumer.h>
- #if defined(CONFIG_FB_MSM)
- #include <linux/notifier.h>
- #include <linux/fb.h>
- #else
- #include <drm/drm_panel.h>
- #include <linux/soc/qcom/panel_event_notifier.h>
- #endif
- #ifdef KERNEL_ABOVE_2_6_38
- #include <linux/input/mt.h>
- #endif
- #include "fts.h"
- #include "fts_lib/ftsCompensation.h"
- #include "fts_lib/ftsIO.h"
- #include "fts_lib/ftsError.h"
- #include "fts_lib/ftsFlash.h"
- #include "fts_lib/ftsFrame.h"
- #include "fts_lib/ftsGesture.h"
- #include "fts_lib/ftsTest.h"
- #include "fts_lib/ftsTime.h"
- #include "fts_lib/ftsTool.h"
- #include "linux/moduleparam.h"
- #if defined(CONFIG_ST_TRUSTED_TOUCH)
- #include <linux/atomic.h>
- #include <linux/clk.h>
- #include <linux/pm_runtime.h>
- #include <linux/debugfs.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <linux/kobject.h>
- #include <linux/sysfs.h>
- #include "linux/gunyah/gh_irq_lend.h"
- #include "linux/gunyah/gh_msgq.h"
- #include "linux/gunyah/gh_mem_notifier.h"
- #include "linux/gunyah/gh_rm_drv.h"
- #include <linux/sort.h>
- #endif
- #define LINK_KOBJ_NAME "tp"
- #define FTS_DVDD_VOL_MIN 1800000
- #define FTS_DVDD_VOL_MAX 1800000
- #define FTS_DVDD_LOAD 20000
- #define FTS_AVDD_VOL_MIN 3000000
- #define FTS_AVDD_VOL_MAX 3300000
- #define FTS_AVDD_LOAD 20000
- /*
- * Uncomment to use polling mode instead of interrupt mode.
- *
- */
- // #define FTS_USE_POLLING_MODE
- /*
- * Event installer helpers
- */
- #define event_id(_e) EVENTID_##_e
- #define handler_name(_h) fts_##_h##_event_handler
- #define install_handler(_i, _evt, _hnd) \
- (_i->event_dispatch_table[event_id(_evt)].handler = handler_name(_hnd))
- /*
- * Asyncronouns command helper
- */
- #define WAIT_WITH_TIMEOUT(_info, _timeout, _command) \
- do { \
- if (wait_for_completion_timeout(&_info->cmd_done, _timeout) == 0) { \
- dev_warn(_info->dev, "Waiting for %s command: timeout\n", \
- #_command); \
- } \
- } while (0)
- #ifdef KERNEL_ABOVE_2_6_38
- #define TYPE_B_PROTOCOL
- #endif
- #if defined(SCRIPTLESS) || defined(DRIVER_TEST)
- static struct class *fts_cmd_class;
- #endif
- static void fts_interrupt_disable(struct fts_ts_info *info);
- static void fts_interrupt_enable(struct fts_ts_info *info);
- static irqreturn_t fts_interrupt_handler(int irq, void *handle);
- static int fts_probe_delayed(struct fts_ts_info *info);
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- static struct gh_acl_desc *fts_vm_get_acl(enum gh_vm_names vm_name)
- {
- struct gh_acl_desc *acl_desc;
- gh_vmid_t vmid;
- gh_rm_get_vmid(vm_name, &vmid);
- acl_desc = kzalloc(offsetof(struct gh_acl_desc, acl_entries[1]),
- GFP_KERNEL);
- if (!acl_desc)
- return ERR_PTR(ENOMEM);
- acl_desc->n_acl_entries = 1;
- acl_desc->acl_entries[0].vmid = vmid;
- acl_desc->acl_entries[0].perms = GH_RM_ACL_R | GH_RM_ACL_W;
- return acl_desc;
- }
- static struct gh_sgl_desc *fts_vm_get_sgl(struct trusted_touch_vm_info *vm_info)
- {
- struct gh_sgl_desc *sgl_desc;
- int i;
- sgl_desc = kzalloc(offsetof(struct gh_sgl_desc,
- sgl_entries[vm_info->iomem_list_size]), GFP_KERNEL);
- if (!sgl_desc)
- return ERR_PTR(ENOMEM);
- sgl_desc->n_sgl_entries = vm_info->iomem_list_size;
- for (i = 0; i < vm_info->iomem_list_size; i++) {
- sgl_desc->sgl_entries[i].ipa_base = vm_info->iomem_bases[i];
- sgl_desc->sgl_entries[i].size = vm_info->iomem_sizes[i];
- }
- return sgl_desc;
- }
- static int fts_populate_vm_info(struct fts_ts_info *info)
- {
- int rc = 0;
- struct trusted_touch_vm_info *vm_info;
- struct device_node *np = info->client->dev.of_node;
- int num_regs, num_sizes = 0;
- vm_info = kzalloc(sizeof(struct trusted_touch_vm_info), GFP_KERNEL);
- if (!vm_info) {
- rc = -ENOMEM;
- goto error;
- }
- info->vm_info = vm_info;
- vm_info->irq_label = GH_IRQ_LABEL_TRUSTED_TOUCH;
- vm_info->vm_name = GH_TRUSTED_VM;
- rc = of_property_read_u32(np, "st,trusted-touch-spi-irq",
- &vm_info->hw_irq);
- if (rc) {
- pr_err("Failed to read trusted touch SPI irq:%d\n", rc);
- goto vm_error;
- }
- num_regs = of_property_count_u32_elems(np,
- "st,trusted-touch-io-bases");
- if (num_regs < 0) {
- pr_err("Invalid number of IO regions specified\n");
- rc = -EINVAL;
- goto vm_error;
- }
- num_sizes = of_property_count_u32_elems(np,
- "st,trusted-touch-io-sizes");
- if (num_sizes < 0) {
- pr_err("Invalid number of IO regions specified\n");
- rc = -EINVAL;
- goto vm_error;
- }
- if (num_regs != num_sizes) {
- pr_err("IO bases and sizes doe not match\n");
- rc = -EINVAL;
- goto vm_error;
- }
- vm_info->iomem_list_size = num_regs;
- vm_info->iomem_bases = kcalloc(num_regs, sizeof(*vm_info->iomem_bases),
- GFP_KERNEL);
- if (!vm_info->iomem_bases) {
- rc = -ENOMEM;
- goto vm_error;
- }
- rc = of_property_read_u32_array(np, "st,trusted-touch-io-bases",
- vm_info->iomem_bases, vm_info->iomem_list_size);
- if (rc) {
- pr_err("Failed to read trusted touch io bases:%d\n", rc);
- goto io_bases_error;
- }
- vm_info->iomem_sizes = kzalloc(
- sizeof(*vm_info->iomem_sizes) * num_sizes, GFP_KERNEL);
- if (!vm_info->iomem_sizes) {
- rc = -ENOMEM;
- goto io_bases_error;
- }
- rc = of_property_read_u32_array(np, "st,trusted-touch-io-sizes",
- vm_info->iomem_sizes, vm_info->iomem_list_size);
- if (rc) {
- pr_err("Failed to read trusted touch io sizes:%d\n", rc);
- goto io_sizes_error;
- }
- return rc;
- io_sizes_error:
- kfree(vm_info->iomem_sizes);
- io_bases_error:
- kfree(vm_info->iomem_bases);
- vm_error:
- kfree(vm_info);
- error:
- return rc;
- }
- static void fts_destroy_vm_info(struct fts_ts_info *info)
- {
- kfree(info->vm_info->iomem_sizes);
- kfree(info->vm_info->iomem_bases);
- kfree(info->vm_info);
- }
- static void fts_vm_deinit(struct fts_ts_info *info)
- {
- if (info->vm_info->mem_cookie)
- gh_mem_notifier_unregister(info->vm_info->mem_cookie);
- fts_destroy_vm_info(info);
- }
- #ifdef CONFIG_ARCH_QTI_VM
- static int fts_vm_mem_release(struct fts_ts_info *info);
- static void fts_trusted_touch_vm_mode_disable(struct fts_ts_info *info);
- static int fts_sgl_cmp(const void *a, const void *b)
- {
- struct gh_sgl_entry *left = (struct gh_sgl_entry *)a;
- struct gh_sgl_entry *right = (struct gh_sgl_entry *)b;
- return (left->ipa_base - right->ipa_base);
- }
- static int fts_vm_compare_sgl_desc(struct gh_sgl_desc *expected,
- struct gh_sgl_desc *received)
- {
- int idx;
- if (expected->n_sgl_entries != received->n_sgl_entries)
- return -E2BIG;
- sort(received->sgl_entries, received->n_sgl_entries,
- sizeof(received->sgl_entries[0]), fts_sgl_cmp, NULL);
- sort(expected->sgl_entries, expected->n_sgl_entries,
- sizeof(expected->sgl_entries[0]), fts_sgl_cmp, NULL);
- for (idx = 0; idx < expected->n_sgl_entries; idx++) {
- struct gh_sgl_entry *left = &expected->sgl_entries[idx];
- struct gh_sgl_entry *right = &received->sgl_entries[idx];
- if ((left->ipa_base != right->ipa_base) ||
- (left->size != right->size)) {
- pr_err("sgl mismatch: left_base:%d right base:%d left size:%d right size:%d\n",
- left->ipa_base, right->ipa_base,
- left->size, right->size);
- return -EINVAL;
- }
- }
- return 0;
- }
- static int fts_vm_handle_vm_hardware(struct fts_ts_info *info)
- {
- int rc = 0;
- if (atomic_read(&info->delayed_vm_probe_pending)) {
- rc = fts_probe_delayed(info);
- if (rc) {
- pr_err(" Delayed probe failure on VM!\n");
- return rc;
- }
- atomic_set(&info->delayed_vm_probe_pending, 0);
- return rc;
- }
- queue_delayed_work(info->fwu_workqueue, &info->fwu_work,
- msecs_to_jiffies(EXP_FN_WORK_DELAY_MS));
- fts_interrupt_enable(info);
- return rc;
- }
- static void fts_vm_irq_on_lend_callback(void *data,
- unsigned long notif_type,
- enum gh_irq_label label)
- {
- struct fts_ts_info *info = data;
- struct irq_data *irq_data;
- int irq = 0;
- int const resource_timeout = msecs_to_jiffies(2000);
- int rc = 0;
- irq = gh_irq_accept(info->vm_info->irq_label, -1, IRQ_TYPE_LEVEL_HIGH);
- if (irq < 0) {
- pr_err("failed to accept irq\n");
- goto irq_fail;
- }
- atomic_set(&info->vm_info->tvm_owns_irq, 1);
- irq_data = irq_get_irq_data(irq);
- if (!irq_data) {
- pr_err("Invalid irq data for trusted touch\n");
- goto irq_fail;
- }
- if (!irq_data->hwirq) {
- pr_err("Invalid irq in irq data\n");
- goto irq_fail;
- }
- if (irq_data->hwirq != info->vm_info->hw_irq) {
- pr_err("Invalid irq lent\n");
- goto irq_fail;
- }
- pr_debug("irq:returned from accept:%d\n", irq);
- info->client->irq = irq;
- if (!wait_for_completion_timeout(&info->resource_checkpoint,
- resource_timeout)) {
- pr_err("Resources not acquired in TVM\n");
- goto irq_fail;
- }
- rc = fts_vm_handle_vm_hardware(info);
- if (rc) {
- pr_err(" Delayed probe failure on VM!\n");
- goto irq_fail;
- }
- atomic_set(&info->trusted_touch_enabled, 1);
- return;
- irq_fail:
- fts_trusted_touch_vm_mode_disable(info);
- }
- static void fts_vm_mem_on_lend_handler(enum gh_mem_notifier_tag tag,
- unsigned long notif_type, void *entry_data, void *notif_msg)
- {
- struct gh_rm_notif_mem_shared_payload *payload;
- struct gh_sgl_desc *sgl_desc, *expected_sgl_desc;
- struct gh_acl_desc *acl_desc;
- struct trusted_touch_vm_info *vm_info;
- struct fts_ts_info *info;
- int rc = 0;
- if (notif_type != GH_RM_NOTIF_MEM_SHARED ||
- tag != GH_MEM_NOTIFIER_TAG_TOUCH) {
- pr_err("Invalid command passed from rm\n");
- return;
- }
- if (!entry_data || !notif_msg) {
- pr_err("Invalid entry data passed from rm\n");
- return;
- }
- info = (struct fts_ts_info *)entry_data;
- vm_info = info->vm_info;
- if (!vm_info) {
- pr_err("Invalid vm_info\n");
- return;
- }
- payload = (struct gh_rm_notif_mem_shared_payload *)notif_msg;
- if (payload->trans_type != GH_RM_TRANS_TYPE_LEND ||
- payload->label != TRUSTED_TOUCH_MEM_LABEL) {
- pr_err("Invalid label or transaction type\n");
- goto onlend_fail;
- }
- acl_desc = fts_vm_get_acl(GH_TRUSTED_VM);
- if (IS_ERR(acl_desc)) {
- pr_err("failed to populated acl data:rc=%d\n",
- PTR_ERR(acl_desc));
- goto onlend_fail;
- }
- sgl_desc = gh_rm_mem_accept(payload->mem_handle, GH_RM_MEM_TYPE_IO,
- GH_RM_TRANS_TYPE_LEND,
- GH_RM_MEM_ACCEPT_VALIDATE_ACL_ATTRS |
- GH_RM_MEM_ACCEPT_VALIDATE_LABEL |
- GH_RM_MEM_ACCEPT_DONE, payload->label, acl_desc,
- NULL, NULL, 0);
- if (IS_ERR_OR_NULL(sgl_desc)) {
- pr_err("failed to do mem accept :rc=%d\n",
- PTR_ERR(sgl_desc));
- goto acl_fail;
- }
- atomic_set(&vm_info->tvm_owns_iomem, 1);
- /* Initiate i2c session on tvm */
- rc = pm_runtime_get_sync(info->client->adapter->dev.parent);
- if (rc < 0) {
- pr_err("failed to get sync rc:%d\n", rc);
- (void)fts_vm_mem_release(info);
- atomic_set(&info->vm_info->tvm_owns_iomem, 0);
- goto acl_fail;
- }
- complete(&info->resource_checkpoint);
- expected_sgl_desc = fts_vm_get_sgl(vm_info);
- if (fts_vm_compare_sgl_desc(expected_sgl_desc, sgl_desc)) {
- pr_err("IO sg list does not match\n");
- goto sgl_cmp_fail;
- }
- vm_info->vm_mem_handle = payload->mem_handle;
- kfree(expected_sgl_desc);
- kfree(acl_desc);
- return;
- sgl_cmp_fail:
- kfree(expected_sgl_desc);
- acl_fail:
- kfree(acl_desc);
- onlend_fail:
- fts_trusted_touch_vm_mode_disable(info);
- }
- static int fts_vm_mem_release(struct fts_ts_info *info)
- {
- int rc = 0;
- rc = gh_rm_mem_release(info->vm_info->vm_mem_handle, 0);
- if (rc)
- pr_err("VM mem release failed: rc=%d\n", rc);
- rc = gh_rm_mem_notify(info->vm_info->vm_mem_handle,
- GH_RM_MEM_NOTIFY_OWNER_RELEASED,
- GH_MEM_NOTIFIER_TAG_TOUCH, 0);
- if (rc)
- pr_err("Failed to notify mem release to PVM: rc=%d\n");
- info->vm_info->vm_mem_handle = 0;
- return rc;
- }
- static void fts_trusted_touch_vm_mode_disable(struct fts_ts_info *info)
- {
- int rc = 0;
- if (atomic_read(&info->vm_info->tvm_owns_iomem) &&
- atomic_read(&info->vm_info->tvm_owns_irq))
- fts_interrupt_disable(info);
- if (atomic_read(&info->vm_info->tvm_owns_iomem)) {
- flushFIFO();
- release_all_touches(info);
- rc = fts_vm_mem_release(info);
- if (rc)
- pr_err("Failed to release mem rc:%d\n", rc);
- else
- atomic_set(&info->vm_info->tvm_owns_iomem, 0);
- pm_runtime_put_sync(info->client->adapter->dev.parent);
- }
- if (atomic_read(&info->vm_info->tvm_owns_irq)) {
- rc = gh_irq_release(info->vm_info->irq_label);
- if (rc)
- pr_err("Failed to release irq rc:%d\n", rc);
- else
- atomic_set(&info->vm_info->tvm_owns_irq, 0);
- rc = gh_irq_release_notify(info->vm_info->irq_label);
- if (rc)
- pr_err("Failed to notify release irq rc:%d\n", rc);
- }
- atomic_set(&info->trusted_touch_enabled, 0);
- reinit_completion(&info->resource_checkpoint);
- pr_debug("trusted touch disabled\n");
- }
- static int fts_handle_trusted_touch_tvm(struct fts_ts_info *info, int value)
- {
- int err = 0;
- switch (value) {
- case 0:
- if (atomic_read(&info->trusted_touch_enabled) == 0) {
- pr_err("Trusted touch is already disabled\n");
- break;
- }
- if (atomic_read(&info->trusted_touch_mode) ==
- TRUSTED_TOUCH_VM_MODE) {
- fts_trusted_touch_vm_mode_disable(info);
- } else {
- pr_err("Unsupported trusted touch mode\n");
- }
- break;
- case 1:
- if (atomic_read(&info->trusted_touch_enabled)) {
- pr_err("Trusted touch usecase underway\n");
- err = -EBUSY;
- break;
- }
- if (atomic_read(&info->trusted_touch_mode) ==
- TRUSTED_TOUCH_VM_MODE) {
- pr_err("Cannot turnon trusted touch(vm mode) in VM\n");
- } else {
- pr_err("Unsupported trusted touch mode\n");
- }
- break;
- default:
- dev_err(&info->client->dev, "unsupported value: %lu\n", value);
- err = -EINVAL;
- break;
- }
- return err;
- }
- #else
- static int fts_clk_prepare_enable(struct fts_ts_info *info)
- {
- int ret;
- ret = clk_prepare_enable(info->iface_clk);
- if (ret) {
- dev_err(&info->client->dev,
- "error on clk_prepare_enable(iface_clk):%d\n", ret);
- return ret;
- }
- ret = clk_prepare_enable(info->core_clk);
- if (ret) {
- clk_disable_unprepare(info->iface_clk);
- dev_err(&info->client->dev,
- "error clk_prepare_enable(core_clk):%d\n", ret);
- }
- return ret;
- }
- static void fts_clk_disable_unprepare(struct fts_ts_info *info)
- {
- clk_disable_unprepare(info->core_clk);
- clk_disable_unprepare(info->iface_clk);
- }
- static int fts_bus_get(struct fts_ts_info *info)
- {
- int rc = 0;
- mutex_lock(&info->fts_clk_io_ctrl_mutex);
- rc = pm_runtime_get_sync(info->client->adapter->dev.parent);
- if (rc >= 0 && info->core_clk != NULL && info->iface_clk != NULL) {
- rc = fts_clk_prepare_enable(info);
- if (rc)
- pm_runtime_put_sync(info->client->adapter->dev.parent);
- }
- mutex_unlock(&info->fts_clk_io_ctrl_mutex);
- return rc;
- }
- static void fts_bus_put(struct fts_ts_info *info)
- {
- mutex_lock(&info->fts_clk_io_ctrl_mutex);
- if (info->core_clk != NULL && info->iface_clk != NULL)
- fts_clk_disable_unprepare(info);
- pm_runtime_put_sync(info->client->adapter->dev.parent);
- mutex_unlock(&info->fts_clk_io_ctrl_mutex);
- }
- static struct gh_notify_vmid_desc *fts_vm_get_vmid(gh_vmid_t vmid)
- {
- struct gh_notify_vmid_desc *vmid_desc;
- vmid_desc = kzalloc(offsetof(struct gh_notify_vmid_desc,
- vmid_entries[1]), GFP_KERNEL);
- if (!vmid_desc)
- return ERR_PTR(ENOMEM);
- vmid_desc->n_vmid_entries = 1;
- vmid_desc->vmid_entries[0].vmid = vmid;
- return vmid_desc;
- }
- static void fts_trusted_touch_complete(struct fts_ts_info *info)
- {
- if (atomic_read(&info->vm_info->pvm_owns_iomem) &&
- atomic_read(&info->vm_info->pvm_owns_irq)) {
- fts_interrupt_enable(info);
- fts_bus_put(info);
- complete(&info->trusted_touch_powerdown);
- atomic_set(&info->trusted_touch_enabled, 0);
- pr_debug("reenabled interrupts on PVM\n");
- } else {
- pr_err("PVM does not own irq and IOMEM\n");
- }
- }
- static void fts_vm_irq_on_release_callback(void *data,
- unsigned long notif_type,
- enum gh_irq_label label)
- {
- struct fts_ts_info *info = data;
- int rc = 0;
- rc = gh_irq_reclaim(info->vm_info->irq_label);
- if (rc)
- pr_err("failed to reclaim irq on pvm rc:%d\n", rc);
- else
- atomic_set(&info->vm_info->pvm_owns_irq, 1);
- }
- static void fts_vm_mem_on_release_handler(enum gh_mem_notifier_tag tag,
- unsigned long notif_type, void *entry_data, void *notif_msg)
- {
- struct gh_rm_notif_mem_released_payload *payload;
- struct trusted_touch_vm_info *vm_info;
- struct fts_ts_info *info;
- int rc = 0;
- if (notif_type != GH_RM_NOTIF_MEM_RELEASED ||
- tag != GH_MEM_NOTIFIER_TAG_TOUCH) {
- pr_err(" Invalid tag or command passed\n");
- return;
- }
- if (!entry_data || !notif_msg) {
- pr_err(" Invalid data or notification message\n");
- return;
- }
- payload = (struct gh_rm_notif_mem_released_payload *)notif_msg;
- info = (struct fts_ts_info *)entry_data;
- vm_info = info->vm_info;
- if (!vm_info) {
- pr_err(" Invalid vm_info\n");
- return;
- }
- if (payload->mem_handle != vm_info->vm_mem_handle) {
- pr_err("Invalid mem handle detected\n");
- return;
- }
- rc = gh_rm_mem_reclaim(payload->mem_handle, 0);
- if (rc) {
- pr_err("Trusted touch VM mem release failed rc:%d\n", rc);
- return;
- }
- atomic_set(&vm_info->pvm_owns_iomem, 1);
- vm_info->vm_mem_handle = 0;
- }
- static int fts_vm_mem_lend(struct fts_ts_info *info)
- {
- struct gh_acl_desc *acl_desc;
- struct gh_sgl_desc *sgl_desc;
- struct gh_notify_vmid_desc *vmid_desc;
- gh_memparcel_handle_t mem_handle;
- gh_vmid_t trusted_vmid;
- int rc = 0;
- acl_desc = fts_vm_get_acl(GH_TRUSTED_VM);
- if (IS_ERR(acl_desc)) {
- pr_err("Failed to get acl of IO memories for Trusted touch\n");
- PTR_ERR(acl_desc);
- return -EINVAL;
- }
- sgl_desc = fts_vm_get_sgl(info->vm_info);
- if (IS_ERR(sgl_desc)) {
- pr_err("Failed to get sgl of IO memories for Trusted touch\n");
- PTR_ERR(sgl_desc);
- rc = -EINVAL;
- goto sgl_error;
- }
- rc = gh_rm_mem_lend(GH_RM_MEM_TYPE_IO, 0, TRUSTED_TOUCH_MEM_LABEL,
- acl_desc, sgl_desc, NULL, &mem_handle);
- if (rc) {
- pr_err("Failed to lend IO memories for Trusted touch rc:%d\n",
- rc);
- goto error;
- }
- gh_rm_get_vmid(GH_TRUSTED_VM, &trusted_vmid);
- vmid_desc = fts_vm_get_vmid(trusted_vmid);
- rc = gh_rm_mem_notify(mem_handle, GH_RM_MEM_NOTIFY_RECIPIENT_SHARED,
- GH_MEM_NOTIFIER_TAG_TOUCH, vmid_desc);
- if (rc) {
- pr_err("Failed to notify mem lend to hypervisor rc:%d\n", rc);
- goto vmid_error;
- }
- info->vm_info->vm_mem_handle = mem_handle;
- vmid_error:
- kfree(vmid_desc);
- error:
- kfree(sgl_desc);
- sgl_error:
- kfree(acl_desc);
- return rc;
- }
- static int fts_trusted_touch_vm_mode_enable(struct fts_ts_info *info)
- {
- int rc = 0;
- struct trusted_touch_vm_info *vm_info = info->vm_info;
- /* i2c session start and resource acquire */
- if (fts_bus_get(info) < 0) {
- dev_err(&info->client->dev, "fts_bus_get failed\n");
- rc = -EIO;
- return rc;
- }
- /* flush pending interurpts from FIFO */
- fts_interrupt_disable(info);
- flushFIFO();
- release_all_touches(info);
- rc = fts_vm_mem_lend(info);
- if (rc) {
- pr_err("Failed to lend memory\n");
- return -EINVAL;
- }
- atomic_set(&vm_info->pvm_owns_iomem, 0);
- rc = gh_irq_lend_v2(vm_info->irq_label, vm_info->vm_name,
- info->client->irq, &fts_vm_irq_on_release_callback, info);
- if (rc) {
- pr_err("Failed to lend irq\n");
- return -EINVAL;
- }
- atomic_set(&vm_info->pvm_owns_irq, 0);
- rc = gh_irq_lend_notify(vm_info->irq_label);
- if (rc) {
- pr_err("Failed to notify irq\n");
- return -EINVAL;
- }
- reinit_completion(&info->trusted_touch_powerdown);
- atomic_set(&info->trusted_touch_enabled, 1);
- pr_debug("trusted touch enabled\n");
- return rc;
- }
- static int fts_handle_trusted_touch_pvm(struct fts_ts_info *info, int value)
- {
- int err = 0;
- switch (value) {
- case 0:
- if (atomic_read(&info->trusted_touch_enabled) == 0) {
- pr_err("Trusted touch is already disabled\n");
- break;
- }
- if (atomic_read(&info->trusted_touch_mode) ==
- TRUSTED_TOUCH_VM_MODE) {
- fts_trusted_touch_complete(info);
- } else {
- pr_err("Unsupported trusted touch mode\n");
- }
- break;
- case 1:
- if (atomic_read(&info->trusted_touch_enabled)) {
- pr_err("Trusted touch usecase underway\n");
- err = -EBUSY;
- break;
- }
- if (atomic_read(&info->trusted_touch_mode) ==
- TRUSTED_TOUCH_VM_MODE) {
- err = fts_trusted_touch_vm_mode_enable(info);
- } else {
- pr_err("Unsupported trusted touch mode\n");
- }
- break;
- default:
- dev_err(&info->client->dev, "unsupported value: %lu\n", value);
- err = -EINVAL;
- break;
- }
- return err;
- }
- #endif
- static int fts_vm_init(struct fts_ts_info *info)
- {
- int rc = 0;
- struct trusted_touch_vm_info *vm_info;
- void *mem_cookie;
- rc = fts_populate_vm_info(info);
- if (rc) {
- pr_err("Cannot setup vm pipeline\n");
- rc = -EINVAL;
- goto fail;
- }
- vm_info = info->vm_info;
- #ifdef CONFIG_ARCH_QTI_VM
- mem_cookie = gh_mem_notifier_register(GH_MEM_NOTIFIER_TAG_TOUCH,
- fts_vm_mem_on_lend_handler, info);
- if (!mem_cookie) {
- pr_err("Failed to register on lend mem notifier\n");
- rc = -EINVAL;
- goto init_fail;
- }
- vm_info->mem_cookie = mem_cookie;
- rc = gh_irq_wait_for_lend_v2(vm_info->irq_label, GH_PRIMARY_VM,
- &fts_vm_irq_on_lend_callback, info);
- atomic_set(&vm_info->tvm_owns_irq, 0);
- atomic_set(&vm_info->tvm_owns_iomem, 0);
- init_completion(&info->resource_checkpoint);
- #else
- mem_cookie = gh_mem_notifier_register(GH_MEM_NOTIFIER_TAG_TOUCH,
- fts_vm_mem_on_release_handler, info);
- if (!mem_cookie) {
- pr_err("Failed to register on release mem notifier\n");
- rc = -EINVAL;
- goto init_fail;
- }
- vm_info->mem_cookie = mem_cookie;
- atomic_set(&vm_info->pvm_owns_irq, 1);
- atomic_set(&vm_info->pvm_owns_iomem, 1);
- #endif
- return rc;
- init_fail:
- fts_vm_deinit(info);
- fail:
- return rc;
- }
- static void fts_dt_parse_trusted_touch_info(struct fts_ts_info *info)
- {
- struct device_node *np = info->client->dev.of_node;
- int rc = 0;
- const char *selection;
- const char *environment;
- rc = of_property_read_string(np, "st,trusted-touch-mode",
- &selection);
- if (rc) {
- dev_warn(&info->client->dev,
- "%s: No trusted touch mode selection made\n", __func__);
- }
- if (!strcmp(selection, "vm_mode")) {
- atomic_set(&info->trusted_touch_mode, TRUSTED_TOUCH_VM_MODE);
- pr_err("Selected trusted touch mode to VM mode\n");
- } else {
- atomic_set(&info->trusted_touch_mode, TRUSTED_TOUCH_MODE_NONE);
- pr_err("Invalid trusted_touch mode\n");
- }
- rc = of_property_read_string(np, "st,touch-environment",
- &environment);
- if (rc) {
- dev_warn(&info->client->dev,
- "%s: No trusted touch mode environment\n", __func__);
- }
- info->touch_environment = environment;
- pr_err("Trusted touch environment:%s\n",
- info->touch_environment);
- }
- static void fts_trusted_touch_init(struct fts_ts_info *info)
- {
- int rc = 0;
- atomic_set(&info->trusted_touch_initialized, 0);
- init_completion(&info->trusted_touch_powerdown);
- fts_dt_parse_trusted_touch_info(info);
- /* Get clocks */
- info->core_clk = devm_clk_get(info->client->dev.parent,
- "m-ahb");
- if (IS_ERR(info->core_clk)) {
- info->core_clk = NULL;
- dev_warn(&info->client->dev,
- "%s: core_clk is not defined\n", __func__);
- }
- info->iface_clk = devm_clk_get(info->client->dev.parent,
- "se-clk");
- if (IS_ERR(info->iface_clk)) {
- info->iface_clk = NULL;
- dev_warn(&info->client->dev,
- "%s: iface_clk is not defined\n", __func__);
- }
- if (atomic_read(&info->trusted_touch_mode) == TRUSTED_TOUCH_VM_MODE) {
- rc = fts_vm_init(info);
- if (rc)
- pr_err("Failed to init VM\n");
- }
- atomic_set(&info->trusted_touch_initialized, 1);
- }
- static ssize_t fts_trusted_touch_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info;
- if (!client)
- return scnprintf(buf, PAGE_SIZE, "client is null\n");
- info = i2c_get_clientdata(client);
- if (!info) {
- logError(0, "info is null\n");
- return scnprintf(buf, PAGE_SIZE, "info is null\n");
- }
- return scnprintf(buf, PAGE_SIZE, "%d",
- atomic_read(&info->trusted_touch_enabled));
- }
- static ssize_t fts_trusted_touch_enable_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info;
- unsigned long value;
- int err = 0;
- if (!client)
- return -EIO;
- info = i2c_get_clientdata(client);
- if (!info) {
- logError(0, "info is null\n");
- return -EIO;
- }
- if (count > 2)
- return -EINVAL;
- err = kstrtoul(buf, 10, &value);
- if (err != 0)
- return err;
- if (!atomic_read(&info->trusted_touch_initialized))
- return -EIO;
- #ifdef CONFIG_ARCH_QTI_VM
- err = fts_handle_trusted_touch_tvm(info, value);
- if (err) {
- pr_err("Failed to handle trusted touch in tvm\n");
- return -EINVAL;
- }
- #else
- err = fts_handle_trusted_touch_pvm(info, value);
- if (err) {
- pr_err("Failed to handle trusted touch in pvm\n");
- return -EINVAL;
- }
- #endif
- err = count;
- return err;
- }
- #endif
- //struct chipInfo ftsInfo;
- /**
- * #ifdef PHONE_GESTURE
- * extern struct mutex gestureMask_mutex;
- * #endif
- */
- static char tag[8] = "[ FTS ]\0";
- static char fts_ts_phys[64];
- static u32 typeOfComand[CMD_STR_LEN] = {0};
- static int numberParameters;
- #ifdef USE_ONE_FILE_NODE
- static int feature_feasibility = ERROR_OP_NOT_ALLOW;
- #endif
- #ifdef PHONE_GESTURE
- static u8 mask[GESTURE_MASK_SIZE + 2];
- //extern u16 gesture_coordinates_x[GESTURE_COORDS_REPORT_MAX];
- //extern u16 gesture_coordinates_y[GESTURE_COORDS_REPORT_MAX];
- //extern int gesture_coords_reported;
- //extern struct mutex gestureMask_mutex;
- #ifdef USE_CUSTOM_GESTURES
- static int custom_gesture_res;
- #endif
- #endif
- #ifdef USE_NOISE_PARAM
- static u8 noise_params[NOISE_PARAMETERS_SIZE] = {0};
- #endif
- static void fts_interrupt_enable(struct fts_ts_info *info);
- static int fts_init_afterProbe(struct fts_ts_info *info);
- static int fts_mode_handler(struct fts_ts_info *info, int force);
- static int fts_command(struct fts_ts_info *info, unsigned char cmd);
- static int fts_chip_initialization(struct fts_ts_info *info);
- static int fts_enable_reg(struct fts_ts_info *info, bool enable);
- static struct drm_panel *active_panel;
- #if defined(CONFIG_DRM)
- static void st_ts_panel_notifier_callback(enum panel_event_notifier_tag tag,
- struct panel_event_notification *notification, void *client_data)
- {
- struct fts_ts_info *info = client_data;
- if (!notification) {
- pr_err("Invalid notification\n");
- return;
- }
- logError(0, "%s %s Notification type:%d, early_trigger:%d, sensor_sleep:%d", tag, __func__,
- notification->notif_type,
- notification->notif_data.early_trigger,
- info->sensor_sleep);
- switch (notification->notif_type) {
- case DRM_PANEL_EVENT_UNBLANK:
- if (!notification->notif_data.early_trigger) {
- logError(0, "%s %s: DRM_PANEL_EVENT_UNBLANK\n", tag, __func__);
- queue_work(info->event_wq, &info->resume_work);
- }
- break;
- case DRM_PANEL_EVENT_BLANK:
- if (!notification->notif_data.early_trigger) {
- logError(0, "%s %s: DRM_PANEL_EVENT_BLANK\n", tag, __func__);
- queue_work(info->event_wq, &info->suspend_work);
- }
- break;
- case DRM_PANEL_EVENT_BLANK_LP:
- logError(0, "%s %s:received lp event\n", tag, __func__);
- break;
- case DRM_PANEL_EVENT_FPS_CHANGE:
- logError(0, "%s %s: Received fps change old fps:%d new fps:%d\n",
- tag, __func__,
- notification->notif_data.old_fps,
- notification->notif_data.new_fps);
- break;
- default:
- logError(0, "%s %s:notification serviced :%d\n",
- tag, __func__, notification->notif_type);
- break;
- }
- }
- static int st_register_for_panel_events(struct device_node *dp,
- struct fts_ts_info *info)
- {
- void *cookie;
- cookie = panel_event_notifier_register(PANEL_EVENT_NOTIFICATION_PRIMARY,
- PANEL_EVENT_NOTIFIER_CLIENT_PRIMARY_TOUCH, active_panel,
- &st_ts_panel_notifier_callback, info);
- if (!cookie) {
- pr_err("Failed to register for panel events\n");
- return -1;
- }
- logError(0, "%s %s registered for panel notifications panel: 0x%x\n",
- tag, __func__, active_panel);
- info->notifier_cookie = cookie;
- return 0;
- }
- #endif
- void touch_callback(unsigned int status)
- {
- /* Empty */
- }
- unsigned int le_to_uint(const unsigned char *ptr)
- {
- return (unsigned int) ptr[0] + (unsigned int) ptr[1] * 0x100;
- }
- unsigned int be_to_uint(const unsigned char *ptr)
- {
- return (unsigned int) ptr[1] + (unsigned int) ptr[0] * 0x100;
- }
- void release_all_touches(struct fts_ts_info *info)
- {
- unsigned int type = MT_TOOL_FINGER;
- int i;
- for (i = 0; i < TOUCH_ID_MAX; i++) {
- #ifdef STYLUS_MODE
- if (test_bit(i, &info->stylus_id))
- type = MT_TOOL_PEN;
- #endif
- input_mt_slot(info->input_dev, i);
- input_mt_report_slot_state(info->input_dev, type, 0);
- input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1);
- }
- input_sync(info->input_dev);
- info->touch_id = 0;
- #ifdef STYLUS_MODE
- info->stylus_id = 0;
- #endif
- }
- /************************* FW UPGGRADE *********************************/
- /* update firmware*/
- /**
- * echo 01/00 > fwupdate perform a fw update taking the FW to burn always
- * from a bin file stored in /system/etc/firmware, 01= force the FW update
- * whicheve fw_version and config_id; 00=perform a fw update only if the fw
- * in the file has a greater fw_version or config_id
- */
- /**
- * cat fwupdate to show the result of the burning procedure
- * (example output in the terminal = "AA00000001BB" if the switch is enabled)
- */
- /**
- * echo 01/00 > fwupdate; cat fwupdate to perform both operation stated before
- * in just one call
- */
- static ssize_t fts_fwupdate_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int ret, mode;
- /*const struct firmware *fw = NULL;*/
- /*char *firmware_name = "st_fts.bin";*/
- struct Firmware fwD;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- int orig_size;
- u8 *orig_data;
- /* reading out firmware upgrade mode */
- ret = kstrtoint(buf, 10, &mode);
- if (ret != 0) {
- pr_err("%s: ret = %d\n", __func__, ret);
- return -EINVAL;
- }
- fwD.data = NULL;
- ret = getFWdata_nocheck(PATH_FILE_FW, &orig_data, &orig_size, 0);
- if (ret < OK) {
- logError(1, "%s %s: impossible retrieve FW... ERROR %08X\n",
- tag, __func__, ERROR_MEMH_READ);
- ret = (ret | ERROR_MEMH_READ);
- goto END;
- }
- ret = parseBinFile(orig_data, orig_size, &fwD, !mode);
- if (ret < OK) {
- logError(1, "%s %s: impossible parse ERROR %08X\n",
- tag, __func__, ERROR_MEMH_READ);
- ret = (ret | ERROR_MEMH_READ);
- goto END;
- }
- logError(0, "%s Starting flashing procedure...\n", tag);
- ret = flash_burn(&fwD, mode, !mode);
- if (ret < OK && ret != (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED))
- logError(0, "%s flashProcedure: ERROR %02X\n",
- tag, ERROR_FLASH_PROCEDURE);
- logError(0, "%s flashing procedure Finished!\n", tag);
- END:
- kfree(fwD.data);
- info->fwupdate_stat = ret;
- if (ret < OK)
- logError(1, "%s %s Unable to upgrade firmware! ERROR %08X\n",
- tag, __func__, ret);
- return count;
- }
- static ssize_t fts_fwupdate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- //fwupdate_stat: ERROR code Returned by flashProcedure.
- return snprintf(buf, PAGE_SIZE, "AA%08XBB\n", info->fwupdate_stat);
- }
- /****UTILITIES (current fw_ver/conf_id, active mode, file fw_ver/conf_id)****/
- /**
- * cat appid show on the terminal fw_version.config_id of
- * the FW running in the IC
- */
- static ssize_t fts_appid_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int error;
- error = snprintf(buf, PAGE_SIZE, "%x.%x\n", ftsInfo.u16_fwVer,
- ftsInfo.u16_cfgId);
- return error;
- }
- /**
- * cat mode_active to show the bitmask of which indicate the modes/features
- * which are running on the IC in a specific istant oftime (example output in
- * the terminal = "AA10000000BB" only senseOn performed)
- */
- static ssize_t fts_mode_active_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(1, "%s Current mode active = %08X\n", tag, info->mode);
- //return sprintf(buf, "AA%08XBB\n", info->mode);
- return snprintf(buf, PAGE_SIZE, "AA%08XBB\n", info->mode);
- }
- /**
- * cat fw_file_test show on the terminal fw_version and config_id of the FW
- * stored in the fw file/header file
- */
- static ssize_t fts_fw_test_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct Firmware fw;
- int ret;
- fw.data = NULL;
- ret = readFwFile(PATH_FILE_FW, &fw, 0);
- if (ret < OK)
- logError(1, "%s Error during reading FW file! ERROR %08X\n",
- tag, ret);
- else {
- logError(1, "%s fw_version = %04X, config_version = %04X, ",
- tag, fw.fw_ver, fw.config_id);
- logError(1, "size = %dbytes\n", fw.data_size);
- }
- kfree(fw.data);
- return 0;
- }
- /**
- * cat lockdown_info to show the lockdown info on the terminal
- * (example output in the terminal = "AA00000000X1X2..X10BB" )
- * where first 4 bytes correspond t
- */
- static ssize_t fts_lockdown_info_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- u8 data[LOCKDOWN_CODE_SIZE] = {0};
- int ret, size = 100;
- char buff[CMD_STR_LEN] = {0};
- char all_strbuff[100] = {0};
- ret = fts_disableInterrupt();
- if (ret < OK)
- goto END;
- ret = lockDownInfo((u8 *)data, LOCKDOWN_CODE_SIZE);
- if (ret < OK)
- goto END;
- END:
- ret |= fts_enableInterrupt();
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", ret);
- strlcat(all_strbuff, buff, size);
- if (ret >= OK) {
- for (ret = 0; ret < LOCKDOWN_CODE_SIZE; ret++) {
- snprintf(buff, sizeof(buff), "%02X", data[ret]);
- strlcat(all_strbuff, buff, size);
- }
- } else {
- logError(1, "%s Error while reading lockdown info = %08X\n",
- tag, ret);
- }
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- return snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- }
- /**
- * cat strength_frame to obtain strength data
- * the string returned in the shell is made up as follow:
- * AA = start byte
- * X1X2X3X4 = 4 bytes in HEX format which represent an
- * error code (00000000 no error)
- *
- * if error code is all 0s
- * FF = 1 byte in HEX format number of rows
- * SS = 1 byte in HEX format number of columns
- * N1, ... = the decimal value of each node separated by a coma
- *
- * BB = end byte
- */
- static ssize_t fts_strength_frame_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- /*unsigned int temp;*/
- /*int res;*/
- /*struct i2c_client *client = to_i2c_client(dev); */
- /*struct fts_ts_info *info = i2c_get_clientdata(client); */
- if (sscanf(p, "%x ", &typeOfComand[0]) != 1)
- return -EINVAL;
- logError(1, "%s %s: Type of Strength Frame selected: %d\n", tag,
- __func__, typeOfComand[0]);
- return count;
- }
- static ssize_t fts_strength_frame_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct MutualSenseFrame frame;
- int res = ERROR_OP_NOT_ALLOW, j, size = 6*2;
- int count = 0;
- u16 type = 0;
- char *all_strbuff = NULL;
- char buff[CMD_STR_LEN] = {0};
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- frame.node_data = NULL;
- res = fts_disableInterrupt();
- if (res < OK)
- goto END;
- res = senseOn();
- #ifdef PHONE_KEY
- res = keyOn();
- #endif
- if (res < OK) {
- logError(1, "%s %s: could not start scanning! ERROR %08X\n",
- tag, __func__, res);
- goto END;
- }
- msleep(WAIT_FOR_FRESH_FRAMES);
- res = senseOff();
- #ifdef PHONE_KEY
- res = keyOff();
- #endif
- if (res < OK) {
- logError(1, "%s %s: could not finish scanning! ERROR %08X\n",
- tag, __func__, res);
- goto END;
- }
- /* mdelay(WAIT_AFTER_SENSEOFF); */
- msleep(WAIT_AFTER_SENSEOFF);
- flushFIFO();
- switch (typeOfComand[0]) {
- case 1:
- type = ADDR_NORM_TOUCH;
- break;
- #ifdef PHONE_KEY
- case 2:
- type = ADDR_NORM_MS_KEY;
- break;
- #endif
- default:
- logError(1, "%s %s: Strength type %d not valid! ERROR %08X\n",
- tag, __func__, typeOfComand[0], ERROR_OP_NOT_ALLOW);
- res = ERROR_OP_NOT_ALLOW;
- goto END;
- }
- res = getMSFrame(type, &frame, 0);
- if (res < OK) {
- logError(1, "%s %s: could not get the frame! ERROR %08X\n",
- tag, __func__, res);
- goto END;
- } else {
- size += (res * 6);
- logError(0, "%s The frame size is %d words\n", tag, res);
- res = OK;
- print_frame_short("MS Strength frame =",
- array1dTo2d_short(frame.node_data,
- frame.node_data_size,
- frame.header.sense_node),
- frame.header.force_node,
- frame.header.sense_node);
- }
- END:
- flushFIFO();
- release_all_touches(info);
- fts_mode_handler(info, 1);
- all_strbuff = kmalloc_array(size, sizeof(char), GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", res);
- strlcat(all_strbuff, buff, size);
- if (res >= OK) {
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frame.header.force_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frame.header.sense_node);
- strlcat(all_strbuff, buff, size);
- for (j = 0; j < frame.node_data_size; j++) {
- snprintf(buff, sizeof(buff), "%d,",
- frame.node_data[j]);
- strlcat(all_strbuff, buff, size);
- }
- kfree(frame.node_data);
- }
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1, "%s %s: Unable toallocate all_strbuff!ERROR %08X\n",
- tag, ERROR_ALLOC);
- }
- fts_enableInterrupt();
- return count;
- }
- /********** FEATURES *********************/
- /**
- * TODO: edit this function according to the features policy to
- * allow during the screen on/off, following is shown an example
- * but check always with ST for more details
- */
- int check_feature_feasibility(struct fts_ts_info *info, unsigned int feature)
- {
- int res = OK;
- /**
- * Example based on the status of the screen and
- * on the feature that is trying to enable
- */
- /*Example based only on the feature that is going to be activated*/
- switch (feature) {
- case FEAT_GESTURE:
- if (info->cover_enabled == 1) {
- res = ERROR_OP_NOT_ALLOW;
- logError(1, "%s %s:Feature not allowed when in Cover ",
- tag, __func__);
- logError(1, "mode %08X\n", res);
- /**
- * for example here can be place a code for
- * disabling the cover mode when gesture is
- * activated
- */
- }
- break;
- case FEAT_COVER:
- if (info->gesture_enabled == 1) {
- res = ERROR_OP_NOT_ALLOW;
- /*logError(1,"Feature not allowed*/
- /*when Gestures enabled!");*/
- logError(1, "s %s: Feature not allowed when Gestures ",
- tag, __func__);
- logError(1, "enabled%08X\n", res);
- /**
- * for example here can be place a code for
- * disabling the gesture mode when cover is
- * activated (that means that cover mode has
- * an higher priority on gesture mode)
- */
- }
- break;
- default:
- logError(1, "%s %s: Feature Allowed!\n", tag, __func__);
- }
- return res;
- }
- #ifdef USE_ONE_FILE_NODE
- /**
- * echo XXXX 00/01 > feature_enable
- * set the feature to disable/enable.
- * XXXX = 4 bytes which identify the feature
- *
- * cat feature_enable
- * set the enabled mode/features in the IC
- * and return an error code
- *
- * echo XXXX 00/01 > feature_enable;
- * cat feature_enable to perform both action stated
- * before in just one call
- */
- static ssize_t fts_feature_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- char *p = (char *)buf;
- unsigned int temp;
- int res = OK;
- if ((count - 8 + 1) / 3 != 1) {
- logError(1, "%s fts_feature_enable: ", tag);
- logError(1, "Number of parameter wrong! %d > %d\n",
- (count - 8 + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%08X ", &temp) != 1)
- return -EINVAL;
- p += 9;
- res = check_feature_feasibility(info, temp);
- if (res < OK)
- return -EINVAL;
- switch (temp) {
- #ifdef PHONE_GESTURE
- case FEAT_GESTURE:
- if (sscanf(p, "%02X ", &info->gesture_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: Gesture Enabled = %d\n",
- tag, info->gesture_enabled);
- break;
- #endif
- #ifdef GLOVE_MODE
- case FEAT_GLOVE:
- if (sscanf(p, "%02X ", &info->glove_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: Glove Enabled = %d\n",
- tag, info->glove_enabled);
- break;
- #endif
- #ifdef STYLUS_MODE
- case FEAT_STYLUS:
- if (sscanf(p, "%02X ", &info->stylus_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: Stylus Enabled = %d\n",
- tag, info->stylus_enabled);
- break;
- #endif
- #ifdef COVER_MODE
- case FEAT_COVER:
- if (sscanf(p, "%02X ", &info->cover_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: Cover Enabled = %d\n",
- tag, info->cover_enabled);
- break;
- #endif
- #ifdef CHARGER_MODE
- case FEAT_CHARGER:
- if (sscanf(p, "%02X ", &info->charger_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: Charger Enabled= %d\n",
- tag, info->charger_enabled);
- break;
- #endif
- #ifdef VR_MODE
- case FEAT_VR:
- if (sscanf(p, "%02X ", &info->vr_enabled) != 1)
- return -EINVAL;
- logError(1, "%s fts_feature_enable: VR Enabled = %d\n",
- tag, info->vr_enabled);
- break;
- #endif
- #ifdef EDGE_REJ
- case FEAT_EDGE_REJECTION:
- if (sscanf(p, "%02X ", &info->edge_rej_enabled) != 1)
- return -EINVAL;
- logError(1, "%s %s: Edge Rejection Enabled= %d\n",
- tag, __func__, info->edge_rej_enabled);
- break;
- #endif
- #ifdef CORNER_REJ
- case FEAT_CORNER_REJECTION:
- if (sscanf(p, "%02X ", &info->corner_rej_enabled) != 1)
- return -EINVAL;
- logError(1, "%s %s: Corner Rejection Enabled= %d\n",
- tag, __func__, info->corner_rej_enabled);
- break;
- #endif
- #ifdef EDGE_PALM_REJ
- case FEAT_EDGE_PALM_REJECTION:
- if (sscanf(p, "%02X", &info->edge_palm_rej_enabled) != 1)
- return -EINVAL;
- logError(1, "%s %s:Edge Palm RejectionEnabled= %d\n",
- tag, __func__, info->edge_palm_rej_enabled);
- break;
- #endif
- default:
- logError(1, "%s %s: Feature %08X not valid! ERROR %08X\n",
- tag, __func__, temp, ERROR_OP_NOT_ALLOW);
- res = ERROR_OP_NOT_ALLOW;
- }
- feature_feasibility = res;
- if (feature_feasibility >= OK)
- feature_feasibility = fts_mode_handler(info, 1);
- else {
- logError(1, "%s %s: Call echo XXXX 00/01 > feature_enable ",
- tag, __func__);
- logError(1, "with a correct feature! ERROR %08X\n", res);
- }
- return count;
- }
- static ssize_t fts_feature_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- if (feature_feasibility < OK) {
- logError(1,
- "%s %s:Call before echo 00/01 > feature_enable %08X\n",
- tag, __func__, feature_feasibility);
- }
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", feature_feasibility);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s: Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- feature_feasibility = ERROR_OP_NOT_ALLOW;
- return count;
- }
- #else
- #ifdef EDGE_REJ
- /**
- * echo 01/00 > edge_rej to enable/disable edge rejection
- * cat edge_rej to show the status of the edge_rej_enabled
- * switch (example output in the terminal = "AA00000001BB"
- * if the switch is enabled)
- *
- * echo 01/00 > edge_rej; cat edge_rej to enable/disable
- * edge rejection and see the switch status in just one call
- */
- static ssize_t fts_edge_rej_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: edge_rej_enabled = %d\n",
- tag, __func__, info->edge_rej_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->edge_rej_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else
- logError(1,
- "%s %s: Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- return count;
- }
- static ssize_t fts_edge_rej_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code
- */
- if ((count + 1) / 3 != 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong!%d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be always
- * used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- *
- * second step: call fts_mode_handler to actually enable it
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_EDGE_REJECTION);
- if (res < OK && temp != FEAT_DISABLE)
- return -EINVAL;
- info->edge_rej_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1,
- "%s %s: Error during fts_mode_handler! ERROR %08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #ifdef CORNER_REJ
- /**
- * echo 01/00 > corner_rej to enable/disable corner rejection
- * cat corner_rej to show the status of the
- * corner_rej_enabled switch (example output in the terminal
- * = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > corner_rej; cat corner_rej to enable/disable
- * corner rejection and see the switch status in just one call
- */
- static ssize_t fts_corner_rej_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: corner_rej_enabled = %d\n",
- tag, __func__, info->corner_rej_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->corner_rej_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1, "%s%s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_corner_rej_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code according
- * to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong!%d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- /*sscanf(p, "%02X ", &temp);*/
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be always
- * used when a feature is enabled!
- *
- * first step : check if the wanted feature
- * can be enabled
- *
- * second step: call fts_mode_handler to
- * actually enable it
- *
- * NOTE: Disabling a feature is always
- * allowed by default
- */
- res = check_feature_feasibility(info, FEAT_CORNER_REJECTION);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->corner_rej_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1,
- "%s %s: During fts_mode_handler!ERROR %08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #ifdef EDGE_PALM_REJ
- /**
- * echo 01/00 > edge_palm_rej
- * to enable/disable edge palm rejection
- *
- * cat edge_palm_rej to show the status of the
- * edge_palm_rej_enabled switch (example output
- * in the terminal = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > edge_palm_rej; cat edge_palm_rej
- * to enable/disable edge palm rejection and see
- * the switch status in just one call
- */
- static ssize_t fts_edge_palm_rej_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: edge_palm_rej_enabled = %d\n",
- tag, __func__, info->edge_palm_rej_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X",
- info->edge_palm_rej_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n",
- all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1, "%s%s:Unable to allocate all_strbuff! %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_edge_palm_rej_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code according
- * to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1,
- "%s%s:Number bytes of parameter wrong! %d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- /*sscanf(p, "%02X ", &temp);*/
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be
- * always used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- *
- * second step: call fts_mode_handler to actually enable it
- *
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_EDGE_PALM_REJECTION);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->edge_palm_rej_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1, "%s%s:Error in fts_mode_handler!%08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #ifdef CHARGER_MODE
- /**
- * echo 01/00 > charger_mode to enable/disable charger mode
- *
- * cat charger_mode to show the status of
- * the charger_enabled switch (example output in the terminal
- * = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > charger_mode; cat charger_mode
- * to enable/disable charger mode and see the
- * switch status in just one call
- */
- static ssize_t fts_charger_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s:charger_enabled = %d\n",
- tag, __func__, info->charger_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->charger_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1, "%s %s:Unable to allocate all_strbuff! %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_charger_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code
- * according to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1, "%s %s:Size of parameter wrong! %d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- /*sscanf(p, "%02X ", &temp);*/
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be always
- * used when a feature is enabled!
- *
- * first step : check if the wanted feature
- * can be enabled
- * second step: call fts_mode_handler to
- * actually enable it
- *
- * NOTE: Disabling a feature is always
- * allowed by default
- */
- res = check_feature_feasibility(info, FEAT_CHARGER);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->charger_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1, "%s %s: Error during fts_mode_handler! ",
- tag, __func__);
- logError(1, "ERROR %08X\n", res);
- }
- }
- return count;
- }
- #endif
- #ifdef GLOVE_MODE
- /**
- * echo 01/00 > glove_mode
- * to enable/disable glove mode
- *
- * cat glove_mode to show the status of
- * the glove_enabled switch (example output in the
- * terminal = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > glove_mode; cat glove_mode
- * to enable/disable glove mode and see the
- * switch status in just one call
- */
- static ssize_t fts_glove_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s:glove_enabled = %d\n",
- tag, __func__, info->glove_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->glove_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1, "%s %s:Unable to allocate all_strbuff! %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_glove_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code
- * according to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1, "%s %s:Size of parameter wrong! %d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be
- * always used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- *
- * second step: call fts_mode_handler to actually enable it
- *
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_GLOVE);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->glove_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1, "%s %s: Error during fts_mode_handler! ",
- tag, __func__);
- logError(1, "ERROR %08X\n", res);
- }
- }
- return count;
- }
- #endif
- #ifdef VR_MODE
- /**
- * echo 01/00 > vr_mode to enable/disable vr mode
- *
- * cat vr_mode to show the status of
- * the vr_enabled switch (example output in the
- * terminal = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > vr_mode; cat vr_mode to enable/disable
- * vr mode and see the switch status in just one call
- */
- static ssize_t fts_vr_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: vr_enabled = %d\n",
- tag, __func__, info->vr_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->vr_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s: Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_vr_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code
- * according to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong!%d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be always
- * used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- * second step: call fts_mode_handler to actually enable it
- *
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_VR);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->vr_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1, "%s %s: Error in fts_mode_handler!%08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #ifdef COVER_MODE
- /**
- * echo 01/00 > cover_mode to enable/disable cover mode
- * cat cover_mode to show the status of the
- * cover_enabled switch (example output in the
- * terminal = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > cover_mode; cat cover_mode to
- * enable/disable cover mode and see the switch
- * status in just one call
- *
- * NOTE: the cover can be handled also using a notifier,
- * in this case the body of these functions
- * should be copied in the notifier callback
- */
- static ssize_t fts_cover_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: cover_enabled = %d\n",
- tag, __func__, info->cover_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->cover_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_cover_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code according
- * to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong!%d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be
- * always used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- * second step: call fts_mode_handler to actually enable it
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_COVER);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->cover_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1, "%s%s:Error in fts_mode_handler!%08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #ifdef STYLUS_MODE
- /**
- * echo 01/00 > stylus_mode to enable/disable stylus mode
- * cat stylus_mode to show the status of
- * the stylus_enabled switch (example output in the
- * terminal = "AA00000001BB" if the switch is enabled)
- *
- * echo 01/00 > stylus_mode; cat stylus_mode to
- * enable/disable stylus mode and see the
- * switch status in just one call
- */
- static ssize_t fts_stylus_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: stylus_enabled = %d\n",
- tag, __func__, info->stylus_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->stylus_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s: Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_stylus_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- /**
- * in case of a different elaboration of the input,
- * just modify this initial part of the code
- * according to customer needs
- */
- if ((count + 1) / 3 != 1) {
- logError(1, "%s %s:Size of parameter wrong! %d != %d byte\n",
- tag, __func__, (count + 1) / 3, 1);
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- /**
- * this is a standard code that should be
- * always used when a feature is enabled!
- *
- * first step : check if the wanted feature can be enabled
- * second step: call fts_mode_handler to actually enable it
- * NOTE: Disabling a feature is always allowed by default
- */
- res = check_feature_feasibility(info, FEAT_STYLUS);
- if (res >= OK || temp == FEAT_DISABLE) {
- info->stylus_enabled = temp;
- res = fts_mode_handler(info, 1);
- if (res < OK) {
- logError(1,
- "%s %s:Error during fts_mode_handler! %08X\n",
- tag, __func__, res);
- }
- }
- return count;
- }
- #endif
- #endif
- /************** GESTURES *************/
- #ifdef PHONE_GESTURE
- #ifdef USE_GESTURE_MASK
- /**
- * if this define is used, a gesture bit mask
- * is used as method to select the gestures
- * to enable/disable
- */
- /**
- * echo EE X1 X2 ... X8 > gesture_mask set
- * the gesture mask to disable/enable;
- * EE = 00(disable) or 01(enable);
- * X1 ... X8 = gesture mask (example 06 00 ... 00
- * this gesture mask represent the gestures with ID = 1 and 2)
- * can be specified from 1 to 8 bytes, if less than 8 bytes
- * are specified the remaining bytes are kept as previous settings
- *
- * cat gesture_mask enable/disable the given mask,
- * if one or more gestures is enabled the driver will
- * automatically enable the gesture mode.
- * If all the gestures are disabled the driver
- * automatically will disable the gesture mode.
- * At the end an error code will be printed
- * (example output in the terminal = "AA00000000BB"
- * if there are no errors)
- *
- * echo EE X1 X2 ... X8 > gesture_mask;
- * cat gesture_mask perform in one
- * command both actions stated before
- */
- static ssize_t fts_gesture_mask_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0, res, temp;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- if (mask[0] == 0) {
- res = ERROR_OP_NOT_ALLOW;
- logError(1, "%s %s:Call before echo enable/disable xx xx >",
- tag, __func__);
- logError(1, "%s %s: gesture_mask with a correct number of ",
- tag, __func__);
- logError(1, "parameters! ERROR %08X\n", res);
- return -EINVAL;
- }
- if (mask[1] == FEAT_ENABLE || mask[1] == FEAT_DISABLE)
- res = updateGestureMask(&mask[2], mask[0], mask[1]);
- else
- res = ERROR_OP_NOT_ALLOW;
- if (res < OK) {
- logError(1, "%s fts_gesture_mask_store: ERROR %08X\n",
- tag, res);
- }
- res |= check_feature_feasibility(info, FEAT_GESTURE);
- temp = isAnyGestureActive();
- if (res >= OK || temp == FEAT_DISABLE)
- info->gesture_enabled = temp;
- logError(1, "%s fts_gesture_mask_store:Gesture Enabled = %d\n",
- tag, info->gesture_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", res);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- mask[0] = 0;
- return count;
- }
- static ssize_t fts_gesture_mask_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- int n;
- unsigned int temp;
- if ((count + 1) / 3 > GESTURE_MASK_SIZE + 1) {
- logError(1, "%s %s: Number of bytes of parameter wrong! ", tag,
- __func__);
- logError(1, "%d > (enable/disable + %d )\n", (count + 1) / 3,
- GESTURE_MASK_SIZE);
- mask[0] = 0;
- return -EINVAL;
- }
- mask[0] = ((count + 1) / 3) - 1;
- for (n = 1; n <= (count + 1) / 3; n++) {
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- mask[n] = (u8)temp;
- logError(1, "%s mask[%d] = %02X\n", tag, n, mask[n]);
- }
- return count;
- }
- #else
- /**
- * if this define is not used,
- * to select the gestures to enable/disable
- * are used the IDs of the gestures
- *
- * echo EE X1 X2 ... > gesture_mask set
- * the gesture to disable/enable; EE = 00(disable)
- * or 01(enable); X1 ... = gesture IDs
- * (example 01 02 05... represent the gestures with
- * ID = 1, 2 and 5) there is no limit of the parameters
- * that can be passed, but of course the gesture IDs
- * should be valid (all the valid IDs are listed
- * in ftsGesture.h)
- *
- * cat gesture_mask enable/disable the
- * given gestures, if one or more gestures is enabled
- * the driver will automatically enable the gesture mode.
- * If all the gestures are disabled the driver automatically
- * will disable the gesture mode. At the end an error code
- * will be printed (example output in the terminal =
- * "AA00000000BB" if there are no errors)
- *
- * echo EE X1 X2 ... > gesture_mask; cat gesture_mask
- * perform in one command both actions stated before
- */
- static ssize_t fts_gesture_mask_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- logError(0, "%s %s: gesture_enabled = %d\n", tag, __func__,
- info->gesture_enabled);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", info->gesture_enabled);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s: Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_gesture_mask_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- int n;
- unsigned int temp;
- int res;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- if ((count + 1) / 3 < 2 || (count + 1) / 3 > GESTURE_MASK_SIZE + 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong! %d %d bytes)\n",
- tag, __func__, (count + 1) / 3, GESTURE_MASK_SIZE);
- mask[0] = 0;
- return -EINVAL;
- }
- memset(mask, 0, GESTURE_MASK_SIZE + 2);
- mask[0] = ((count + 1) / 3) - 1;
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- mask[1] = (u8)temp;
- for (n = 1; n < (count + 1) / 3; n++) {
- /*sscanf(p, "%02X ", &temp);*/
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- gestureIDtoGestureMask((u8)temp, &mask[2]);
- }
- for (n = 0; n < GESTURE_MASK_SIZE + 2; n++)
- logError(1, "%s mask[%d] = %02X\n", tag, n, mask[n]);
- if (mask[0] == 0) {
- res = ERROR_OP_NOT_ALLOW;
- logError(1, "%s %s: Call before echo enable/disable xx xx ....",
- tag, __func__);
- logError(1, " > gesture_mask with parameters! ERROR %08X\n",
- res);
- } else {
- if (mask[1] == FEAT_ENABLE || mask[1] == FEAT_DISABLE)
- res = updateGestureMask(&mask[2], mask[0], mask[1]);
- else
- res = ERROR_OP_NOT_ALLOW;
- if (res < OK)
- logError(1, "%s %s: ERROR %08X\n", tag, __func__, res);
- }
- res = check_feature_feasibility(info, FEAT_GESTURE);
- temp = isAnyGestureActive();
- if (res >= OK || temp == FEAT_DISABLE)
- info->gesture_enabled = temp;
- res = fts_mode_handler(info, 0);
- return count;
- }
- #endif
- #ifdef USE_CUSTOM_GESTURES
- /**
- * allow to use user defined gestures
- *
- * echo ID X1 Y1 X2 Y2 ... X30 Y30 >
- * add_custom_gesture add a custom gesture;
- * ID = 1 byte that represent the gesture ID of
- * the custom gesture (can be chosen only between
- * the custom IDs defined in ftsGesture.h);
- * X1 Y1 ... = a series of 30 points (x,y) which
- * represent the gesture template.
- * The loaded gesture is enabled automatically
- *
- * cat add_custom_gesture/remove_custom_gesture
- * Print the error code of the last operation
- * performed with the custom gestures
- * (example output in the terminal = "AA00000000BB"
- * if there are no errors)
- *
- * echo ID X1 Y1 X2 Y2 ... X30 Y30 >
- * add_custom_gesture; cat add_custom_gesture
- * perform in one command both actions stated before
- */
- static ssize_t fts_add_custom_gesture_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- logError(0, "%s %s:Last Operation Result = %08X\n",
- tag, __func__, custom_gesture_res);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", custom_gesture_res);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_add_custom_gesture_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- int n;
- unsigned int temp;
- u8 gestureID;
- u8 gestMask[GESTURE_MASK_SIZE] = {0};
- u8 template[GESTURE_CUSTOM_POINTS];
- int res;
- /*struct i2c_client *client = to_i2c_client(dev);*/
- /*struct fts_ts_info *info = i2c_get_clientdata(client);*/
- if ((count + 1) / 3 != GESTURE_CUSTOM_POINTS + 1) {
- logError(1,
- "%s %s: Number bytes of parameter wrong! %d != %d\n",
- tag, __func__, (count + 1) / 3,
- GESTURE_CUSTOM_POINTS + 1);
- res = ERROR_OP_NOT_ALLOW;
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- gestureID = (u8)temp;
- for (n = 1; n < (count + 1) / 3; n++) {
- /*sscanf(p, "%02X ", &temp);*/
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- template[n-1] = (u8)temp;
- logError(1, "%s template[%d] = %02X\n",
- tag, n-1, template[n-1]);
- }
- res = fts_disableInterrupt();
- if (res >= OK) {
- logError(1, "%s %s: Adding custom gesture ID = %02X\n",
- tag, __func__, gestureID);
- res = addCustomGesture(template,
- GESTURE_CUSTOM_POINTS, gestureID);
- if (res < OK) {
- logError(1,
- "%s %s:error during add custom gesture ",
- tag, __func__);
- logError(1, "ERROR %08X\n", res);
- } else {
- logError(1,
- "%s %s:Enabling in the gesture mask...\n",
- tag, __func__);
- gestureIDtoGestureMask(gestureID, gestMask);
- res = enableGesture(gestMask, GESTURE_MASK_SIZE);
- if (res < OK) {
- logError(1, "%s %s:error during enable gesture",
- tag, __func__);
- logError(1, " mask: ERROR %08X\n", res);
- } else {
- /*if (check_feature_feasibility(info,*/
- /*FEAT_GESTURE)==OK)*/
- /*info->gesture_enabled =*/
- /*isAnyGestureActive();*/
- /*uncomment if you want to activate*/
- /* automatically*/
- /*the gesture mode when a custom gesture*/
- /*is loaded*/
- logError(1, "%s %s:Custom Gesture enabled!\n",
- tag, __func__, res);
- }
- }
- }
- res |= fts_enableInterrupt();
- custom_gesture_res = res;
- return count;
- }
- /**
- * echo ID > remove_custom_gesture
- * remove a custom gesture;
- * ID = 1 byte that represent the gesture ID
- * of the custom gesture (can be chosen only
- * between the custom IDs defined in ftsGesture.h);
- * the same gesture is disabled automatically
- */
- static ssize_t fts_remove_custom_gesture_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- int count = 0;
- logError(0, "%s %s:Last Operation Result = %08X\n",
- tag, __func__, custom_gesture_res);
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", custom_gesture_res);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, __func__, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_remove_custom_gesture_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- char *p = (char *)buf;
- unsigned int temp;
- int res;
- u8 gestureID;
- u8 gestMask[GESTURE_MASK_SIZE] = {0};
- /*struct i2c_client *client = to_i2c_client(dev);*/
- /*struct fts_ts_info *info = i2c_get_clientdata(client);*/
- if ((count + 1) / 3 < 1) {
- logError(1,
- "%s %s:Number bytes of parameter wrong! %d != %d\n",
- tag, __func__, (count + 1) / 3, 1);
- res = ERROR_OP_NOT_ALLOW;
- return -EINVAL;
- }
- if (sscanf(p, "%02X ", &temp) != 1)
- return -EINVAL;
- p += 3;
- gestureID = (u8)temp;
- res = fts_disableInterrupt();
- if (res >= OK) {
- logError(1,
- "%s %s: Removing custom gesture ID = %02X\n",
- tag, __func__, gestureID);
- res = removeCustomGesture(gestureID);
- if (res < OK) {
- logError(1,
- "%s %s:error in custom gesture:%08X\n",
- tag, __func__, res);
- } else {
- logError(1, "%s %s: Enabling in the gesture mask...\n",
- tag, __func__);
- gestureIDtoGestureMask(gestureID, gestMask);
- res = disableGesture(gestMask, GESTURE_MASK_SIZE);
- if (res < OK) {
- logError(1,
- "%s %s:error in enable gesture mask:%08X\n",
- tag, __func__, res);
- } else {
- /*if (check_feature_feasibility*/
- /*(info,FEAT_GESTURE)==OK)*/
- /*info->gesture_enabled = */
- /*isAnyGestureActive();*/
- /**
- * uncomment if you want to disable
- * automatically
- * the gesture mode when a custom gesture is
- * removed and no other gestures were enabled
- */
- logError(1, "%s %s: Custom Gesture disabled!\n",
- tag, __func__, res);
- }
- }
- }
- res |= fts_enableInterrupt();
- custom_gesture_res = res;
- return count;
- }
- #endif
- /**
- * cat gesture_coordinates to obtain the gesture coordinates
- * the string returned in the shell follow this up as follow:
- * AA = start byte
- * X1X2X3X4 = 4 bytes in HEX format
- * which represent an error code (00000000 no error)
- */
- /**** if error code is all 0s ****/
- /**
- * CC = 1 byte in HEX format number of coords
- * (pair of x,y) returned
- *
- * X1X2 Y1Y2 ... = X1X2 2 bytes in HEX format for
- * x[i] and Y1Y2 2 bytes in HEX format for y[i] (MSB first)
- */
- /********************************/
- /* BB = end byte*/
- static ssize_t fts_gesture_coordinates_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int size = 6 * 2;
- //u8 coords_num;
- u8 *all_strbuff = NULL;
- int count = 0, res, i = 0;
- logError(0, "%s %s: Getting gestures coordinates...\n", tag, __func__);
- if (gesture_coords_reported < OK) {
- logError(1, "%s %s:invalid coordinates! ERROR %08X\n",
- tag, __func__, gesture_coords_reported);
- res = gesture_coords_reported;
- } else {
- /*coords are pairs of x,y (*2) where each coord*/
- /*is a short(2bytes=4char)(*4) + 1 byte(2char) num*/
- /*of coords (+2)*/
- size += gesture_coords_reported * 2 * 4 + 2;
- /*coords_num = res;*/
- res = OK;
- /*set error code to OK*/
- }
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (all_strbuff != NULL) {
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", res);
- strlcat(all_strbuff, buff, size);
- if (res >= OK) {
- snprintf(buff, sizeof(buff), "%02X",
- gesture_coords_reported);
- strlcat(all_strbuff, buff, size);
- for (i = 0; i < gesture_coords_reported; i++) {
- snprintf(buff, sizeof(buff), "%04X",
- gesture_coordinates_x[i]);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%04X",
- gesture_coordinates_y[i]);
- strlcat(all_strbuff, buff, size);
- }
- }
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- kfree(all_strbuff);
- } else {
- logError(1,
- "%s %s:Unable to allocate all_strbuff! ERROR %08X\n",
- tag, ERROR_ALLOC);
- }
- return count;
- }
- static ssize_t fts_gesture_coordinates_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- return 0;
- }
- #endif
- /***************** PRODUCTION TEST ****************/
- static ssize_t fts_stm_cmd_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int n;
- char *p = (char *) buf;
- memset(typeOfComand, 0, CMD_STR_LEN * sizeof(u32));
- logError(1, "%s\n", tag);
- for (n = 0; n < (count + 1) / 3; n++) {
- if (sscanf(p, "%02X ", &typeOfComand[n]) != 1)
- return -EINVAL;
- p += 3;
- logError(1, "%s typeOfComand[%d] = %02X\n",
- tag, n, typeOfComand[n]);
- }
- numberParameters = n;
- logError(1, "%s Number of Parameters = %d\n", tag, numberParameters);
- return count;
- }
- static ssize_t fts_stm_cmd_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- char buff[CMD_STR_LEN] = {0};
- int res, j, doClean = 0, count;
- int size = 6 * 2;
- u8 *all_strbuff = NULL;
- struct i2c_client *client = to_i2c_client(dev);
- struct fts_ts_info *info = i2c_get_clientdata(client);
- struct MutualSenseData compData = {0};
- struct SelfSenseData comData = {0};
- struct MutualSenseFrame frameMS = {0};
- struct SelfSenseFrame frameSS = {0};
- /**
- * struct used for defining which test
- * perform during the production test
- */
- struct TestToDo todoDefault;
- todoDefault.MutualRaw = 1;
- todoDefault.MutualRawGap = 1;
- todoDefault.MutualCx1 = 0;
- todoDefault.MutualCx2 = 1;
- todoDefault.MutualCx2Adj = 1;
- todoDefault.MutualCxTotal = 0;
- todoDefault.MutualCxTotalAdj = 0;
- todoDefault.MutualKeyRaw = 0;
- todoDefault.MutualKeyCx1 = 0;
- todoDefault.MutualKeyCx2 = 0;
- todoDefault.MutualKeyCxTotal = 0;
- todoDefault.SelfForceRaw = 1;
- todoDefault.SelfForceRawGap = 0;
- todoDefault.SelfForceIx1 = 0;
- todoDefault.SelfForceIx2 = 0;
- todoDefault.SelfForceIx2Adj = 0;
- todoDefault.SelfForceIxTotal = 1;
- todoDefault.SelfForceIxTotalAdj = 0;
- todoDefault.SelfForceCx1 = 0;
- todoDefault.SelfForceCx2 = 0;
- todoDefault.SelfForceCx2Adj = 0;
- todoDefault.SelfForceCxTotal = 0;
- todoDefault.SelfForceCxTotalAdj = 0;
- todoDefault.SelfSenseRaw = 1;
- todoDefault.SelfSenseRawGap = 0;
- todoDefault.SelfSenseIx1 = 0;
- todoDefault.SelfSenseIx2 = 0;
- todoDefault.SelfSenseIx2Adj = 0;
- todoDefault.SelfSenseIxTotal = 1;
- todoDefault.SelfSenseIxTotalAdj = 0;
- todoDefault.SelfSenseCx1 = 0;
- todoDefault.SelfSenseCx2 = 0;
- todoDefault.SelfSenseCx2Adj = 0;
- todoDefault.SelfSenseCxTotal = 0;
- todoDefault.SelfSenseCxTotalAdj = 0;
- if (numberParameters >= 1) {
- res = fts_disableInterrupt();
- if (res < 0) {
- logError(0, "%s fts_disableInterrupt: ERROR %08X\n",
- tag, res);
- res = (res | ERROR_DISABLE_INTER);
- goto END;
- }
- #if defined(CONFIG_FB_MSM)
- res = fb_unregister_client(&info->notifier);
- #else
- if (active_panel && info->notifier_cookie)
- panel_event_notifier_unregister(info->notifier_cookie);
- #endif
- if (res < 0) {
- logError(1, "%s ERROR: unregister notifier failed!\n",
- tag);
- goto END;
- }
- switch (typeOfComand[0]) {
- /*ITO TEST*/
- case 0x01:
- res = production_test_ito();
- break;
- /*PRODUCTION TEST*/
- case 0x00:
- if (ftsInfo.u32_mpPassFlag != INIT_MP) {
- logError(0, "%s MP Flag not set!\n", tag, res);
- res = production_test_main(LIMITS_FILE, 1, 1,
- &todoDefault, INIT_MP);
- } else {
- logError(0, "%s MP Flag set!\n", tag, res);
- res = production_test_main(LIMITS_FILE, 1, 0,
- &todoDefault, INIT_MP);
- }
- break;
- /*read mutual raw*/
- case 0x13:
- logError(0, "%s Get 1 MS Frame\n", tag);
- //res = getMSFrame(ADDR_RAW_TOUCH, &frame, 0);
- res = getMSFrame2(MS_TOUCH_ACTIVE, &frameMS);
- if (res < 0) {
- logError(0,
- "%s Error in taking MS frame.%02X\n",
- tag, res);
- } else {
- logError(0, "%s The frame size is %d words\n",
- tag, res);
- size = (res * sizeof(short) + 8) * 2;
- /* set res to OK because if getMSFrame is*/
- /* successful res = number of words read*/
- res = OK;
- print_frame_short("MS frame =",
- array1dTo2d_short(frameMS.node_data,
- frameMS.node_data_size,
- frameMS.header.sense_node),
- frameMS.header.force_node,
- frameMS.header.sense_node);
- }
- break;
- /*read self raw*/
- case 0x15:
- logError(0, "%s Get 1 SS Frame\n", tag);
- res = getSSFrame2(SS_TOUCH, &frameSS);
- if (res < OK) {
- logError(0,
- "%s Error while taking the SS frame%02X\n",
- tag, res);
- } else {
- logError(0, "%s The frame size is %d words\n",
- tag, res);
- size = (res * sizeof(short) + 8) * 2 + 1;
- /**
- * set res to OK because if getMSFrame is
- * successful res = number of words read
- */
- res = OK;
- print_frame_short("SS force frame =",
- array1dTo2d_short(frameSS.force_data,
- frameSS.header.force_node, 1),
- frameSS.header.force_node, 1);
- print_frame_short("SS sense frame =",
- array1dTo2d_short(frameSS.sense_data,
- frameSS.header.sense_node,
- frameSS.header.sense_node),
- 1,
- frameSS.header.sense_node);
- }
- break;
- /*read mutual comp data*/
- case 0x14:
- logError(0, "%s Get MS Compensation Data\n", tag);
- res = readMutualSenseCompensationData(MS_TOUCH_ACTIVE,
- &compData);
- if (res < 0) {
- logError(0,
- "%s Error MS compensation data%02X\n",
- tag, res);
- } else {
- logError(0,
- "%s MS Data Reading Finished!\n",
- tag);
- size = ((compData.node_data_size + 9) *
- sizeof(u8)) * 2;
- print_frame_u8("MS Data (Cx2) =",
- array1dTo2d_u8(compData.node_data,
- compData.node_data_size,
- compData.header.sense_node),
- compData.header.force_node,
- compData.header.sense_node);
- }
- break;
- /*read self comp data*/
- case 0x16:
- logError(0, "%s Get SS Compensation Data...\n", tag);
- res = readSelfSenseCompensationData(SS_TOUCH, &comData);
- if (res < 0) {
- logError(0, "%s Error reading SS data%02X\n",
- tag, res);
- } else {
- logError(0, "%s SS Data Reading Finished!\n",
- tag);
- size = ((comData.header.force_node
- + comData.header.sense_node) * 2 + 12);
- size *= sizeof(u8) * 2;
- print_frame_u8("SS Data Ix2_fm = ",
- array1dTo2d_u8(comData.ix2_fm,
- comData.header.force_node, 1),
- comData.header.force_node,
- 1);
- print_frame_u8("SS Data Cx2_fm = ",
- array1dTo2d_u8(comData.cx2_fm,
- comData.header.force_node, 1),
- comData.header.force_node,
- 1);
- print_frame_u8("SS Data Ix2_sn = ",
- array1dTo2d_u8(comData.ix2_sn,
- comData.header.sense_node,
- comData.header.sense_node),
- 1,
- comData.header.sense_node);
- print_frame_u8("SS Data Cx2_sn = ",
- array1dTo2d_u8(comData.cx2_sn,
- comData.header.sense_node,
- comData.header.sense_node),
- 1,
- comData.header.sense_node);
- }
- break;
- /* MS Raw DATA TEST */
- case 0x03:
- res = fts_system_reset();
- if (res >= OK)
- res = production_test_ms_raw(LIMITS_FILE,
- 1, &todoDefault);
- break;
- /* MS CX DATA TEST */
- case 0x04:
- res = fts_system_reset();
- if (res >= OK)
- res = production_test_ms_cx(LIMITS_FILE,
- 1, &todoDefault);
- break;
- /* SS RAW DATA TEST */
- case 0x05:
- res = fts_system_reset();
- if (res >= OK)
- res = production_test_ss_raw(LIMITS_FILE,
- 1, &todoDefault);
- break;
- /* SS IX CX DATA TEST */
- case 0x06:
- res = fts_system_reset();
- if (res >= OK)
- res = production_test_ss_ix_cx(LIMITS_FILE,
- 1, &todoDefault);
- break;
- case 0xF0:
- /* TOUCH ENABLE/DISABLE */
- case 0xF1:
- doClean = (int) (typeOfComand[0] & 0x01);
- res = cleanUp(doClean);
- break;
- default:
- logError(1,
- "%s COMMAND NOT VALID!! Insert a proper value\n",
- tag);
- res = ERROR_OP_NOT_ALLOW;
- break;
- }
- doClean = fts_enableInterrupt();
- if (doClean < 0) {
- logError(0, "%s fts_enableInterrupt: ERROR %08X\n",
- tag, (doClean|ERROR_ENABLE_INTER));
- }
- } else {
- logError(1, "%s NO COMMAND SPECIFIED!!!\n", tag);
- res = ERROR_OP_NOT_ALLOW;
- }
- #if defined(CONFIG_FB_MSM)
- if (fb_register_client(&info->notifier) < 0)
- logError(1, "%s ERROR: register notifier failed!\n", tag);
- #else
- if (active_panel)
- st_register_for_panel_events(info->dev->of_node, info);
- #endif
- END:
- /*here start the reporting phase,*/
- /* assembling the data to send in the file node */
- all_strbuff = kmalloc(size, GFP_KERNEL);
- if (!all_strbuff)
- return 0;
- memset(all_strbuff, 0, size);
- snprintf(buff, sizeof(buff), "%02X", 0xAA);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%08X", res);
- strlcat(all_strbuff, buff, size);
- if (res >= OK) {
- /*all the other cases are already fine printing only the res.*/
- switch (typeOfComand[0]) {
- case 0x13:
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frameMS.header.force_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frameMS.header.sense_node);
- strlcat(all_strbuff, buff, size);
- for (j = 0; j < frameMS.node_data_size; j++) {
- snprintf(buff, sizeof(buff), "%04X",
- frameMS.node_data[j]);
- strlcat(all_strbuff, buff, size);
- }
- kfree(frameMS.node_data);
- break;
- case 0x15:
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frameSS.header.force_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X",
- (u8) frameSS.header.sense_node);
- strlcat(all_strbuff, buff, size);
- /* Copying self raw data Force */
- for (j = 0; j < frameSS.header.force_node; j++) {
- snprintf(buff, sizeof(buff), "%04X",
- frameSS.force_data[j]);
- strlcat(all_strbuff, buff, size);
- }
- /* Copying self raw data Sense */
- for (j = 0; j < frameSS.header.sense_node; j++) {
- snprintf(buff, sizeof(buff), "%04X",
- frameSS.sense_data[j]);
- strlcat(all_strbuff, buff, size);
- }
- kfree(frameSS.force_data);
- kfree(frameSS.sense_data);
- break;
- case 0x14:
- snprintf(buff, sizeof(buff), "%02X",
- (u8) compData.header.force_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X",
- (u8) compData.header.sense_node);
- strlcat(all_strbuff, buff, size);
- /* Cpying CX1 value */
- snprintf(buff, sizeof(buff), "%02X", compData.cx1);
- strlcat(all_strbuff, buff, size);
- /* Copying CX2 values */
- for (j = 0; j < compData.node_data_size; j++) {
- snprintf(buff, sizeof(buff), "%02X",
- *(compData.node_data + j));
- strlcat(all_strbuff, buff, size);
- }
- kfree(compData.node_data);
- break;
- case 0x16:
- snprintf(buff, sizeof(buff), "%02X",
- comData.header.force_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X",
- comData.header.sense_node);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", comData.f_ix1);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", comData.s_ix1);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", comData.f_cx1);
- strlcat(all_strbuff, buff, size);
- snprintf(buff, sizeof(buff), "%02X", comData.s_cx1);
- strlcat(all_strbuff, buff, size);
- /* Copying IX2 Force */
- for (j = 0; j < comData.header.force_node; j++) {
- snprintf(buff, sizeof(buff), "%02X",
- comData.ix2_fm[j]);
- strlcat(all_strbuff, buff, size);
- }
- /* Copying IX2 Sense */
- for (j = 0; j < comData.header.sense_node; j++) {
- snprintf(buff, sizeof(buff), "%02X",
- comData.ix2_sn[j]);
- strlcat(all_strbuff, buff, size);
- }
- /* Copying CX2 Force */
- for (j = 0; j < comData.header.force_node; j++) {
- snprintf(buff, sizeof(buff), "%02X",
- comData.cx2_fm[j]);
- strlcat(all_strbuff, buff, size);
- }
- /* Copying CX2 Sense */
- for (j = 0; j < comData.header.sense_node; j++) {
- snprintf(buff, sizeof(buff), "%02X",
- comData.cx2_sn[j]);
- strlcat(all_strbuff, buff, size);
- }
- kfree(comData.ix2_fm);
- kfree(comData.ix2_sn);
- kfree(comData.cx2_fm);
- kfree(comData.cx2_sn);
- break;
- default:
- break;
- }
- }
- snprintf(buff, sizeof(buff), "%02X", 0xBB);
- strlcat(all_strbuff, buff, size);
- count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
- /**
- * need to reset the number of parameters
- * in order to wait the next command,
- * comment if you want to repeat
- * the last command sent just doing a cat
- */
- numberParameters = 0;
- /* logError(0,"%s numberParameters = %d\n",tag, numberParameters);*/
- kfree(all_strbuff);
- return count;
- }
- static DEVICE_ATTR_RW(fts_fwupdate);
- static DEVICE_ATTR_RO(fts_appid);
- static DEVICE_ATTR_RO(fts_mode_active);
- static DEVICE_ATTR_RO(fts_lockdown_info);
- static DEVICE_ATTR_RW(fts_strength_frame);
- static DEVICE_ATTR_RO(fts_fw_test);
- static DEVICE_ATTR_RW(fts_stm_cmd);
- #ifdef USE_ONE_FILE_NODE
- static DEVICE_ATTR_RW(fts_feature_enable);
- #else
- #ifdef EDGE_REJ
- static DEVICE_ATTR_RW(fts_edge_rej);
- #endif
- #ifdef CORNER_REJ
- static DEVICE_ATTR_RW(fts_corner_rej);
- #endif
- #ifdef EDGE_PALM_REJ
- static DEVICE_ATTR_RW(fts_edge_palm_rej);
- #endif
- #ifdef CHARGER_MODE
- static DEVICE_ATTR_RW(fts_charger_mode);
- #endif
- #ifdef GLOVE_MODE
- static DEVICE_ATTR_RW(fts_glove_mode);
- #endif
- #ifdef VR_MODE
- static DEVICE_ATTR_RW(fts_vr_mode);
- #endif
- #ifdef COVER_MODE
- static DEVICE_ATTR_RW(fts_cover_mode);
- #endif
- #ifdef STYLUS_MODE
- static DEVICE_ATTR_RW(fts_stylus_mode);
- #endif
- #endif
- #ifdef PHONE_GESTURE
- static DEVICE_ATTR_RW(fts_gesture_mask);
- static DEVICE_ATTR_RW(fts_gesture_coordinates);
- #ifdef USE_CUSTOM_GESTURES
- static DEVICE_ATTR_RW(fts_add_custom_gesture);
- static DEVICE_ATTR_RW(fts_remove_custom_gesture);
- #endif
- #endif
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- static DEVICE_ATTR(trusted_touch_enable,
- 0664,
- fts_trusted_touch_enable_show,
- fts_trusted_touch_enable_store);
- #endif
- /* /sys/devices/soc.0/f9928000.i2c/i2c-6/6-0049 */
- static struct attribute *fts_attr_group[] = {
- &dev_attr_fts_fwupdate.attr,
- &dev_attr_fts_appid.attr,
- &dev_attr_fts_mode_active.attr,
- &dev_attr_fts_lockdown_info.attr,
- &dev_attr_fts_strength_frame.attr,
- &dev_attr_fts_fw_test.attr,
- &dev_attr_fts_stm_cmd.attr,
- #ifdef USE_ONE_FILE_NODE
- &dev_attr_fts_feature_enable.attr,
- #else
- #ifdef EDGE_REJ
- &dev_attr_fts_edge_rej.attr,
- #endif
- #ifdef CORNER_REJ
- &dev_attr_fts_corner_rej.attr,
- #endif
- #ifdef EDGE_PALM_REJ
- &dev_attr_fts_edge_palm_rej.attr,
- #endif
- #ifdef CHARGER_MODE
- &dev_attr_fts_charger_mode.attr,
- #endif
- #ifdef GLOVE_MODE
- &dev_attr_fts_glove_mode.attr,
- #endif
- #ifdef VR_MODE
- &dev_attr_fts_vr_mode.attr,
- #endif
- #ifdef COVER_MODE
- &dev_attr_fts_cover_mode.attr,
- #endif
- #ifdef STYLUS_MODE
- &dev_attr_fts_stylus_mode.attr,
- #endif
- #endif
- #ifdef PHONE_GESTURE
- &dev_attr_fts_gesture_mask.attr,
- &dev_attr_fts_gesture_coordinates.attr,
- #ifdef USE_CUSTOM_GESTURES
- &dev_attr_fts_add_custom_gesture.attr,
- &dev_attr_fts_remove_custom_gesture.attr,
- #endif
- #endif
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- &dev_attr_trusted_touch_enable.attr,
- #endif
- NULL,
- };
- static int fts_command(struct fts_ts_info *info, unsigned char cmd)
- {
- unsigned char regAdd;
- int ret;
- regAdd = cmd;
- ret = fts_writeCmd(®Add, sizeof(regAdd)); /* 0 = ok */
- logError(0, "%s Issued command 0x%02x, return value %08X\n", cmd, ret);
- return ret;
- }
- void fts_input_report_key(struct fts_ts_info *info, int key_code)
- {
- mutex_lock(&info->input_report_mutex);
- input_report_key(info->input_dev, key_code, 1);
- input_sync(info->input_dev);
- input_report_key(info->input_dev, key_code, 0);
- input_sync(info->input_dev);
- mutex_unlock(&info->input_report_mutex);
- }
- /*
- * New Interrupt handle implementation
- */
- static inline unsigned char *fts_next_event(unsigned char *evt)
- {
- /* Nothing to do with this event, moving to the next one */
- evt += FIFO_EVENT_SIZE;
- /* the previous one was the last event ? */
- return (evt[-1] & 0x1F) ? evt : NULL;
- }
- /* EventId : 0x00 */
- static void fts_nop_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- /**
- * logError(1,
- * "%s %s Doing nothing for event =
- * %02X %02X %02X %02X %02X %02X %02X %02X\n",
- * tag, __func__, event[0], event[1], event[2],
- * event[3], event[4], event[5], event[6], event[7]);
- */
- /* return fts_next_event(event); */
- }
- /* EventId : 0x03 */
- static void fts_enter_pointer_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- unsigned char touchId, touchcount;
- int x, y;
- int minor;
- int major, distance = 0;
- u8 touchsize;
- if (!info->resume_bit && !info->aoi_notify_enabled)
- return;
- touchId = event[1] & 0x0F;
- touchcount = (event[1] & 0xF0) >> 4;
- touchsize = (event[5] & 0xC0) >> 6;
- major = (event[5] & 0x1F); // bit0-bit4: major
- minor = event[6]; // event6:minor
- __set_bit(touchId, &info->touch_id);
- x = (event[2] << 4) | (event[4] & 0xF0) >> 4;
- y = (event[3] << 4) | (event[4] & 0x0F);
- if (info->bdata->x_flip)
- x = X_AXIS_MAX - x;
- if (info->bdata->y_flip)
- y = Y_AXIS_MAX - y;
- if (x == X_AXIS_MAX)
- x--;
- if (y == Y_AXIS_MAX)
- y--;
- if (info->sensor_sleep && info->aoi_notify_enabled)
- if ((x < info->aoi_left || x > info->aoi_right)
- || (y < info->aoi_top || y > info->aoi_bottom)) {
- x = -x;
- y = -y;
- }
- input_mt_slot(info->input_dev, touchId);
- input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1);
- if (touchcount == 1) {
- input_report_key(info->input_dev, BTN_TOUCH, 1);
- input_report_key(info->input_dev, BTN_TOOL_FINGER, 1);
- }
- input_report_abs(info->input_dev, ABS_MT_POSITION_X, x);
- input_report_abs(info->input_dev, ABS_MT_POSITION_Y, y);
- input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, major);
- input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, minor);
- input_report_abs(info->input_dev, ABS_MT_DISTANCE, distance);
- return;
- }
- /* EventId : 0x04 */
- static void fts_leave_pointer_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- unsigned char touchId, touchcount;
- u8 touchsize;
- touchId = event[1] & 0x0F;
- touchcount = (event[1] & 0xF0) >> 4;
- touchsize = (event[5] & 0xC0) >> 6;
- input_mt_slot(info->input_dev, touchId);
- __clear_bit(touchId, &info->touch_id);
- input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 0);
- if (touchcount == 0) {
- input_report_key(info->input_dev, BTN_TOUCH, 0);
- input_report_key(info->input_dev, BTN_TOOL_FINGER, 0);
- }
- input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1);
- }
- /* EventId : 0x05 */
- #define fts_motion_pointer_event_handler fts_enter_pointer_event_handler
- #ifdef PHONE_KEY
- /* EventId : 0x0E */
- static void fts_key_status_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- int value;
- logError(0,
- "%s %sReceived event %02X %02X %02X %02X %02X %02X %02X %02X\n",
- tag, __func__, event[0], event[1], event[2], event[3],
- event[4], event[5], event[6], event[7]);
- /*
- * TODO: the customer should handle the events coming
- * from the keys according his needs (this is an example
- * that report only the single pressure of one key at time)
- */
- /* event[2] contain the bitmask of the keys that are actually pressed */
- if (event[2] != 0) {
- switch (event[2]) {
- case KEY1:
- value = KEY_HOMEPAGE;
- logError(0, "%s %s: Button HOME!\n", tag, __func__);
- break;
- case KEY2:
- value = KEY_BACK;
- logError(0, "%s %s: Button Back !\n", tag, __func__);
- break;
- case KEY3:
- value = KEY_MENU;
- logError(0, "%s %s: Button Menu !\n", tag, __func__);
- break;
- default:
- logError(0,
- "%s %s:No valid Button ID or more than one key pressed!\n",
- tag, __func__);
- return;
- }
- fts_input_report_key(info, value);
- } else {
- logError(0, "%s %s: All buttons released!\n", tag, __func__);
- }
- }
- #endif
- /* EventId : 0x0F */
- static void fts_error_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- int error = 0;
- logError(0,
- "%s %sReceived event:%02X %02X %02X %02X %02X %02X %02X %02X\n",
- tag, __func__, event[0], event[1], event[2], event[3],
- event[4], event[5], event[6], event[7]);
- switch (event[1]) {
- case EVENT_TYPE_ESD_ERROR: /* esd */
- /* before reset clear all slot */
- release_all_touches(info);
- fts_chip_powercycle(info);
- error = fts_system_reset();
- error |= fts_mode_handler(info, 0);
- error |= fts_enableInterrupt();
- if (error < OK) {
- logError(1,
- "%s %s Cannot restore the device ERROR %08X\n",
- tag, __func__, error);
- }
- break;
- case EVENT_TYPE_WATCHDOG_ERROR: /* watch dog timer */
- /* if (event[2] == 0) { */
- dumpErrorInfo();
- /* before reset clear all slot */
- release_all_touches(info);
- error = fts_system_reset();
- error |= fts_mode_handler(info, 0);
- error |= fts_enableInterrupt();
- if (error < OK) {
- logError(1,
- "%s %s Cannot reset the device ERROR %08X\n",
- tag, __func__, error);
- }
- /* } */
- break;
- }
- /* return fts_next_event(event); */
- }
- /* EventId : 0x10 */
- static void fts_controller_ready_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- int error;
- logError(0, "%s %s Received event 0x%02x\n", tag, __func__, event[0]);
- release_all_touches(info);
- setSystemResettedUp(1);
- setSystemResettedDown(1);
- error = fts_mode_handler(info, 0);
- if (error < OK) {
- logError(1,
- "%s %s Cannot restore the device status ERROR %08X\n",
- tag, __func__, error);
- }
- /* return fts_next_event(event); */
- }
- /* EventId : 0x16 */
- static void fts_status_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- /* logError(1, "%s Received event 0x%02x\n", tag, event[0]); */
- switch (event[1]) {
- case EVENT_TYPE_MS_TUNING_CMPL:
- case EVENT_TYPE_SS_TUNING_CMPL:
- case FTS_FORCE_CAL_SELF_MUTUAL:
- case FTS_FLASH_WRITE_CONFIG:
- case FTS_FLASH_WRITE_COMP_MEMORY:
- case FTS_FORCE_CAL_SELF:
- case FTS_WATER_MODE_ON:
- case FTS_WATER_MODE_OFF:
- default:
- logError(0, "%s %s Received unhandled status event = ",
- tag, __func__);
- logError(0, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
- event[0], event[1], event[2], event[3], event[4],
- event[5], event[6], event[7]);
- break;
- }
- /* return fts_next_event(event); */
- }
- #ifdef PHONE_GESTURE
- /**
- * TODO: Customer should implement their own action
- * in respons of a gesture event.
- * This is an example that simply print the gesture received
- */
- static void fts_gesture_event_handler(struct fts_ts_info *info,
- unsigned char *event)
- {
- unsigned char touchId;
- int value;
- int needCoords = 0;
- logError(0,
- "%s gesture event: %02X %02X %02X %02X %02X %02X %02X %02X\n",
- tag, event[0], event[1], event[2], event[3],
- event[4], event[5], event[6], event[7]);
- if (event[1] == 0x03) {
- logError(1, "%s %s: Gesture ID %02X enable_status = %02X\n",
- tag, __func__, event[2], event[3]);
- }
- if (event[1] == EVENT_TYPE_ENB && event[2] == 0x00) {
- switch (event[3]) {
- case GESTURE_ENABLE:
- logError(1, "%s %s: Gesture Enabled! res = %02X\n",
- tag, __func__, event[4]);
- break;
- case GESTURE_DISABLE:
- logError(1, "%s %s: Gesture Disabled! res = %02X\n",
- tag, __func__, event[4]);
- break;
- default:
- logError(1, "%s %s: Event not Valid!\n", tag, __func__);
- }
- }
- if (event[0] == EVENTID_GESTURE && (event[1] == EVENT_TYPE_GESTURE_DTC1
- || event[1] == EVENT_TYPE_GESTURE_DTC2)) {
- /* always use touchId zero */
- touchId = 0;
- __set_bit(touchId, &info->touch_id);
- /* by default read the coordinates*/
- /* for all gestures excluding double tap */
- needCoords = 1;
- switch (event[2]) {
- case GES_ID_DBLTAP:
- value = KEY_WAKEUP;
- logError(0, "%s %s: double tap!\n", tag, __func__);
- needCoords = 0;
- break;
- case GES_ID_AT:
- value = KEY_WWW;
- logError(0, "%s %s: @!\n", tag, __func__);
- break;
- case GES_ID_C:
- value = KEY_C;
- logError(0, "%s %s: C !\n", tag, __func__);
- break;
- case GES_ID_E:
- value = KEY_E;
- logError(0, "%s %s: e !\n", tag, __func__);
- break;
- case GES_ID_F:
- value = KEY_F;
- logError(0, "%s %s: F !\n", tag, __func__);
- break;
- case GES_ID_L:
- value = KEY_L;
- logError(0, "%s %s: L !\n", tag, __func__);
- break;
- case GES_ID_M:
- value = KEY_M;
- logError(0, "%s %s: M !\n", tag, __func__);
- break;
- case GES_ID_O:
- value = KEY_O;
- logError(0, "%s %s: O !\n", tag, __func__);
- break;
- case GES_ID_S:
- value = KEY_S;
- logError(0, "%s %s: S !\n", tag, __func__);
- break;
- case GES_ID_V:
- value = KEY_V;
- logError(0, "%s %s: V !\n", tag, __func__);
- break;
- case GES_ID_W:
- value = KEY_W;
- logError(0, "%s %s: W !\n", tag, __func__);
- break;
- case GES_ID_Z:
- value = KEY_Z;
- logError(0, "%s %s: Z !\n", tag, __func__);
- break;
- case GES_ID_HFLIP_L2R:
- value = KEY_RIGHT;
- logError(0, "%s %s: -> !\n", tag, __func__);
- break;
- case GES_ID_HFLIP_R2L:
- value = KEY_LEFT;
- logError(0, "%s %s: <- !\n", tag, __func__);
- break;
- case GES_ID_VFLIP_D2T:
- value = KEY_UP;
- logError(0, "%s %s: UP !\n", tag, __func__);
- break;
- case GES_ID_VFLIP_T2D:
- value = KEY_DOWN;
- logError(0, "%s %s: DOWN !\n", tag, __func__);
- break;
- case GES_ID_CUST1:
- value = KEY_F1;
- logError(0, "%s %s: F1 !\n", tag, __func__);
- break;
- case GES_ID_CUST2:
- value = KEY_F1;
- logError(0, "%s %s: F2 !\n", tag, __func__);
- break;
- case GES_ID_CUST3:
- value = KEY_F3;
- logError(0, "%s %s: F3 !\n", tag, __func__);
- break;
- case GES_ID_CUST4:
- value = KEY_F1;
- logError(0, "%s %s: F4 !\n", tag, __func__);
- break;
- case GES_ID_CUST5:
- value = KEY_F1;
- logError(0, "%s %s: F5 !\n", tag, __func__);
- break;
- case GES_ID_LEFTBRACE:
- value = KEY_LEFTBRACE;
- logError(0, "%s %s: < !\n", tag, __func__);
- break;
- case GES_ID_RIGHTBRACE:
- value = KEY_RIGHTBRACE;
- logError(0, "%s %s: > !\n", tag, __func__);
- break;
- default:
- logError(0, "%s %s: No valid GestureID!\n",
- tag, __func__);
- goto gesture_done;
- }
- /* no coordinates for gestures reported by FW */
- if (event[1] == EVENT_TYPE_GESTURE_DTC1)
- needCoords = 0;
- if (needCoords == 1)
- readGestureCoords(event);
- fts_input_report_key(info, value);
- gesture_done:
- /* Done with gesture event, clear bit. */
- __clear_bit(touchId, &info->touch_id);
- }
- /* return fts_next_event(event); */
- }
- #endif
- /* EventId : 0x05 */
- #define fts_motion_pointer_event_handler fts_enter_pointer_event_handler
- /*
- * This handler is called each time there is at least
- * one new event in the FIFO
- */
- static void fts_event_handler(struct work_struct *work)
- {
- struct fts_ts_info *info;
- int error = 0, count = 0;
- unsigned char regAdd;
- unsigned char data[FIFO_EVENT_SIZE] = {0};
- unsigned char eventId;
- struct event_dispatch_handler_t event_handler;
- info = container_of(work, struct fts_ts_info, work);
- /*
- * read all the FIFO and parsing events
- */
- __pm_wakeup_event(info->wakeup_source, HZ);
- regAdd = FIFO_CMD_READONE;
- for (count = 0; count < FIFO_DEPTH; count++) {
- error = fts_readCmd(®Add, sizeof(regAdd), data,
- FIFO_EVENT_SIZE);
- if (error == OK && data[0] != EVENTID_NO_EVENT)
- eventId = data[0];
- else
- break;
- if (eventId < EVENTID_LAST) {
- event_handler = info->event_dispatch_table[eventId];
- event_handler.handler(info, (data));
- }
- }
- input_sync(info->input_dev);
- fts_interrupt_enable(info);
- }
- static void fts_fw_update_auto(struct work_struct *work)
- {
- u8 cmd[4] = { FTS_CMD_HW_REG_W, 0x00, 0x00, SYSTEM_RESET_VALUE };
- int event_to_search[2] = {(int)EVENTID_ERROR_EVENT,
- (int)EVENT_TYPE_CHECKSUM_ERROR};
- u8 readData[FIFO_EVENT_SIZE] = {0};
- int flag_init = 0;
- int retval = 0;
- int retval1 = 0;
- int ret;
- struct fts_ts_info *info;
- struct delayed_work *fwu_work = container_of(work,
- struct delayed_work, work);
- int crc_status = 0;
- int error = 0;
- struct Firmware fwD;
- int orig_size;
- u8 *orig_data;
- info = container_of(fwu_work, struct fts_ts_info, fwu_work);
- logError(0, "%s Fw Auto Update is starting...\n", tag);
- ret = getFWdata(PATH_FILE_FW, &orig_data, &orig_size, 0);
- if (ret < OK) {
- logError(0, "%s %s: impossible retrieve FW... ERROR %08X\n",
- tag, __func__, ERROR_MEMH_READ);
- ret = (ret | ERROR_MEMH_READ);
- goto NO_FIRMWARE_UPDATE;
- }
- ret = parseBinFile(orig_data, orig_size, &fwD, 1);
- if (ret < OK) {
- logError(1, "%s %s: impossible parse ERROR %08X\n",
- tag, __func__, ERROR_MEMH_READ);
- ret = (ret | ERROR_MEMH_READ);
- kfree(fwD.data);
- goto NO_FIRMWARE_UPDATE;
- }
- fts_chip_powercycle(info);
- retval = flash_burn(&fwD, crc_status, 1);
- if ((retval & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
- logError(1, "%s %s:firmware update retry! ERROR %08X\n",
- tag, __func__, retval);
- fts_chip_powercycle(info);
- retval1 = flash_burn(&fwD, crc_status, 1);
- if ((retval1 & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
- logError(1, "%s %s: update failed again! ERROR %08X\n",
- tag, __func__, retval1);
- logError(1, "%s Fw Auto Update Failed!\n", tag);
- }
- }
- kfree(fwD.data);
- u16ToU8_be(SYSTEM_RESET_ADDRESS, &cmd[1]);
- ret = fts_writeCmd(cmd, 4);
- if (ret < OK) {
- logError(1, "%s %s Can't send reset command! ERROR %08X\n",
- tag, __func__, ret);
- } else {
- setSystemResettedDown(1);
- setSystemResettedUp(1);
- ret = pollForEvent(event_to_search, 2, readData,
- GENERAL_TIMEOUT);
- if (ret < OK) {
- logError(0, "%s %s: No CX CRC Found!\n", tag, __func__);
- } else {
- if (readData[2] == CRC_CX_MEMORY) {
- logError(1, "%s %s: CRC Error! ERROR:%02X\n\n",
- tag, __func__, readData[2]);
- flag_init = 1;
- }
- }
- }
- if (ftsInfo.u8_msScrConfigTuneVer != ftsInfo.u8_msScrCxmemTuneVer ||
- ftsInfo.u8_ssTchConfigTuneVer != ftsInfo.u8_ssTchCxmemTuneVer)
- ret = ERROR_GET_INIT_STATUS;
- else if (((ftsInfo.u32_mpPassFlag != INIT_MP)
- && (ftsInfo.u32_mpPassFlag != INIT_FIELD)) || flag_init == 1)
- ret = ERROR_GET_INIT_STATUS;
- else
- ret = OK;
- if (ret == ERROR_GET_INIT_STATUS) {
- error = fts_chip_initialization(info);
- if (error < OK)
- logError(1, "%s %s Can't initialize chip! ERROR %08X",
- tag, __func__, error);
- }
- NO_FIRMWARE_UPDATE:
- error = fts_init_afterProbe(info);
- if (error < OK)
- logError(1, "%s Can't initialize hardware device ERROR %08X\n",
- tag, error);
- logError(0, "%s Fw Auto Update Finished!\n", tag);
- }
- static int fts_chip_initialization(struct fts_ts_info *info)
- {
- int ret2 = 0;
- int retry;
- int initretrycnt = 0;
- struct TestToDo todoDefault;
- todoDefault.MutualRaw = 1;
- todoDefault.MutualRawGap = 1;
- todoDefault.MutualCx1 = 0;
- todoDefault.MutualCx2 = 0;
- todoDefault.MutualCx2Adj = 0;
- todoDefault.MutualCxTotal = 0;
- todoDefault.MutualCxTotalAdj = 0;
- todoDefault.MutualKeyRaw = 0;
- todoDefault.MutualKeyCx1 = 0;
- todoDefault.MutualKeyCx2 = 0;
- todoDefault.MutualKeyCxTotal = 0;
- todoDefault.SelfForceRaw = 0;
- todoDefault.SelfForceRawGap = 0;
- todoDefault.SelfForceIx1 = 0;
- todoDefault.SelfForceIx2 = 0;
- todoDefault.SelfForceIx2Adj = 0;
- todoDefault.SelfForceIxTotal = 0;
- todoDefault.SelfForceIxTotalAdj = 0;
- todoDefault.SelfForceCx1 = 0;
- todoDefault.SelfForceCx2 = 0;
- todoDefault.SelfForceCx2Adj = 0;
- todoDefault.SelfForceCxTotal = 0;
- todoDefault.SelfForceCxTotalAdj = 0;
- todoDefault.SelfSenseRaw = 1;
- todoDefault.SelfSenseRawGap = 0;
- todoDefault.SelfSenseIx1 = 0;
- todoDefault.SelfSenseIx2 = 0;
- todoDefault.SelfSenseIx2Adj = 0;
- todoDefault.SelfSenseIxTotal = 0;
- todoDefault.SelfSenseIxTotalAdj = 0;
- todoDefault.SelfSenseCx1 = 0;
- todoDefault.SelfSenseCx2 = 0;
- todoDefault.SelfSenseCx2Adj = 0;
- todoDefault.SelfSenseCxTotal = 0;
- todoDefault.SelfSenseCxTotalAdj = 0;
- for (retry = 0; retry <= INIT_FLAG_CNT; retry++) {
- ret2 = production_test_main(LIMITS_FILE, 1, 1, &todoDefault,
- INIT_FIELD);
- if (ret2 == OK)
- break;
- initretrycnt++;
- logError(1, "%s %s: cycle count = %04d - ERROR %08X\n",
- tag, __func__, initretrycnt, ret2);
- fts_chip_powercycle(info);
- }
- if (ret2 < OK)
- logError(1, "%s failed to initializate 3 times\n", tag);
- return ret2;
- }
- #ifdef FTS_USE_POLLING_MODE
- static enum hrtimer_restart fts_timer_func(struct hrtimer *timer)
- {
- struct fts_ts_info *info =
- container_of(timer, struct fts_ts_info, timer);
- queue_work(info->event_wq, &info->work);
- return HRTIMER_NORESTART;
- }
- #else
- static irqreturn_t fts_interrupt_handler(int irq, void *handle)
- {
- struct fts_ts_info *info = handle;
- if (!info) {
- pr_err("%s: Invalid info\n", __func__);
- return IRQ_HANDLED;
- }
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- #ifndef CONFIG_ARCH_QTI_VM
- if (atomic_read(&info->vm_info->pvm_owns_iomem) &&
- atomic_read(&info->vm_info->pvm_owns_irq) &&
- atomic_read(&info->trusted_touch_enabled)) {
- pr_err("%s: Cannot service interrupts in PVM while trusted touch is enabled\n",
- __func__);
- return IRQ_HANDLED;
- }
- #endif
- #endif
- disable_irq_nosync(info->client->irq);
- queue_work(info->event_wq, &info->work);
- return IRQ_HANDLED;
- }
- #endif
- static int fts_interrupt_install(struct fts_ts_info *info)
- {
- int i, error = 0;
- size_t len;
- len = sizeof(struct event_dispatch_handler_t) * EVENTID_LAST;
- info->event_dispatch_table = kzalloc(len, GFP_KERNEL);
- if (!info->event_dispatch_table) {
- logError(1, "%s OOM allocating event dispatch table\n", tag);
- return -ENOMEM;
- }
- for (i = 0; i < EVENTID_LAST; i++)
- info->event_dispatch_table[i].handler = fts_nop_event_handler;
- install_handler(info, ENTER_POINTER, enter_pointer);
- install_handler(info, LEAVE_POINTER, leave_pointer);
- install_handler(info, MOTION_POINTER, motion_pointer);
- install_handler(info, ERROR_EVENT, error);
- install_handler(info, CONTROL_READY, controller_ready);
- install_handler(info, STATUS_UPDATE, status);
- #ifdef PHONE_GESTURE
- install_handler(info, GESTURE, gesture);
- #endif
- #ifdef PHONE_KEY
- install_handler(info, KEY_STATUS, key_status);
- #endif
- /* disable interrupts in any case */
- error = fts_disableInterrupt();
- #ifdef FTS_USE_POLLING_MODE
- logError(0, "%s Polling Mode\n");
- hrtimer_init(&info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- info->timer.function = fts_timer_func;
- hrtimer_start(&info->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
- #else
- #ifdef CONFIG_ARCH_QTI_VM
- logError(0, "%s Interrupt Mode\n", tag);
- if (request_threaded_irq(info->client->irq, NULL, fts_interrupt_handler,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, info->client->name, info)) {
- logError(1, "%s Request irq failed\n", tag);
- kfree(info->event_dispatch_table);
- error = -EBUSY;
- }
- #else
- logError(0, "%s Interrupt Mode\n", tag);
- if (request_threaded_irq(info->client->irq, NULL, fts_interrupt_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT, info->client->name, info)) {
- logError(1, "%s Request irq failed\n", tag);
- kfree(info->event_dispatch_table);
- error = -EBUSY;
- }
- #endif
- #endif
- return error;
- }
- static void fts_interrupt_uninstall(struct fts_ts_info *info)
- {
- fts_disableInterrupt();
- kfree(info->event_dispatch_table);
- #ifdef FTS_USE_POLLING_MODE
- hrtimer_cancel(&info->timer);
- #else
- free_irq(info->client->irq, info);
- #endif
- }
- static void fts_interrupt_enable(struct fts_ts_info *info)
- {
- #ifdef FTS_USE_POLLING_MODE
- hrtimer_start(&info->timer, ktime_set(0, 10000000), HRTIMER_MODE_REL);
- #else
- enable_irq(info->client->irq);
- #endif
- /* enable the touch IC irq */
- fts_enableInterrupt();
- }
- static void fts_interrupt_disable(struct fts_ts_info *info)
- {
- /* disable the touch IC irq */
- fts_disableInterrupt();
- #ifdef FTS_USE_POLLING_MODE
- hrtimer_cancel(&info->timer);
- #else
- disable_irq(info->client->irq);
- #endif
- }
- static int fts_init(struct fts_ts_info *info)
- {
- int error;
- error = fts_system_reset();
- if (error < OK && error != (ERROR_TIMEOUT | ERROR_SYSTEM_RESET_FAIL)) {
- logError(1, "%s Cannot reset the device! ERROR %08X\n",
- tag, error);
- return error;
- }
- if (error == (ERROR_TIMEOUT | ERROR_SYSTEM_RESET_FAIL)) {
- logError(1, "%s Setting default Chip INFO!\n", tag);
- defaultChipInfo(0);
- } else {
- error = readChipInfo(0);
- if (error < OK) {
- logError(1, "%s Cannot read Chip Info!ERROR:%08X\n",
- tag, error);
- }
- }
- error = fts_interrupt_install(info);
- if (error != OK)
- logError(1, "%s Init (1) error (ERROR = %08X)\n", tag, error);
- return error;
- }
- int fts_chip_powercycle(struct fts_ts_info *info)
- {
- int error = 0;
- logError(0, "%s %s: Power Cycle Starting...\n", tag, __func__);
- /*
- * if IRQ pin is short with DVDD a call to
- * the ISR will triggered when the regulator is turned off
- */
- logError(0, "%s %s: Disabling IRQ...\n", tag, __func__);
- disable_irq_nosync(info->client->irq);
- if (info->pwr_reg) {
- error = regulator_disable(info->pwr_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to disable DVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bus_reg) {
- error = regulator_disable(info->bus_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to disable AVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bdata->reset_gpio != GPIO_NOT_DEFINED)
- gpio_set_value(info->bdata->reset_gpio, 0);
- else
- msleep(300);
- if (info->pwr_reg) {
- error = regulator_enable(info->bus_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to enable AVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bus_reg) {
- error = regulator_enable(info->pwr_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to enable DVDD regulator\n",
- tag, __func__);
- }
- }
- /* time needed by the regulators for reaching the regime values */
- msleep(20);
- if (info->bdata->reset_gpio != GPIO_NOT_DEFINED) {
- /* time to wait before bring up the reset */
- /* gpio after the power up of the regulators */
- msleep(20);
- gpio_set_value(info->bdata->reset_gpio, 1);
- /* mdelay(300); */
- }
- release_all_touches(info);
- logError(0, "%s %s: Enabling IRQ...\n", tag, __func__);
- enable_irq(info->client->irq);
- logError(0, "%s %s: Power Cycle Finished! ERROR CODE = %08x\n",
- tag, __func__, error);
- setSystemResettedUp(1);
- setSystemResettedDown(1);
- return error;
- }
- int fts_chip_powercycle2(struct fts_ts_info *info, unsigned long sleep)
- {
- int error = 0;
- logError(0, "%s %s: Power Cycle Starting...\n", tag, __func__);
- if (info->pwr_reg) {
- error = regulator_disable(info->pwr_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to disable DVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bus_reg) {
- error = regulator_disable(info->bus_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to disable AVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bdata->reset_gpio != GPIO_NOT_DEFINED)
- gpio_set_value(info->bdata->reset_gpio, 0);
- msleep(sleep);
- if (info->pwr_reg) {
- error = regulator_enable(info->bus_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to enable AVDD regulator\n",
- tag, __func__);
- }
- }
- if (info->bus_reg) {
- error = regulator_enable(info->pwr_reg);
- if (error < 0) {
- logError(1, "%s %s: Failed to enable DVDD regulator\n",
- tag, __func__);
- }
- }
- /* time needed by the regulators for reaching the regime values */
- msleep(500);
- if (info->bdata->reset_gpio != GPIO_NOT_DEFINED) {
- /*
- * time to wait before bring up the reset
- * gpio after the power up of the regulators
- */
- msleep(20);
- gpio_set_value(info->bdata->reset_gpio, 1);
- /* msleep(300); */
- }
- /* before reset clear all slot */
- release_all_touches(info);
- logError(0, "%s %s: Power Cycle Finished! ERROR CODE = %08x\n",
- tag, __func__, error);
- setSystemResettedUp(1);
- setSystemResettedDown(1);
- return error;
- }
- static int fts_init_afterProbe(struct fts_ts_info *info)
- {
- int error = 0;
- /* system reset */
- error = cleanUp(0);
- /* enable the features and the sensing */
- error |= fts_mode_handler(info, 0);
- /* enable the interrupt */
- error |= fts_enableInterrupt();
- #if defined(CONFIG_FB_MSM)
- error |= fb_register_client(&info->notifier);
- #else
- if (active_panel)
- st_register_for_panel_events(info->dev->of_node, info);
- #endif
- if (error < OK)
- logError(1, "%s %s Init after Probe error (ERROR = %08X)\n",
- tag, __func__, error);
- return error;
- }
- /*
- * TODO: change this function according with the needs
- * of customer in terms of feature to enable/disable
- */
- static int fts_mode_handler(struct fts_ts_info *info, int force)
- {
- int res = OK;
- int ret = OK;
- /* initialize the mode to Nothing in order */
- /* to be updated depending on the features enabled */
- info->mode = MODE_NOTHING;
- logError(0, "%s %s: Mode Handler starting...\n", tag, __func__);
- switch (info->resume_bit) {
- case 0:
- /* screen down */
- logError(0, "%s %s: Screen OFF...\n", tag, __func__);
- /*
- * do sense off in order to avoid the flooding
- * of the fifo with touch events if someone is
- * touching the panel during suspend
- */
- logError(0, "%s %s: Sense OFF!\n", tag, __func__);
- /*
- *we need to use fts_command for speed reason
- * (no need to check echo in this case and interrupt
- * can be enabled)
- */
- res |= fts_command(info, FTS_CMD_MS_MT_SENSE_OFF);
- #ifdef PHONE_KEY
- logError(0, "%s %s: Key OFF!\n", tag, __func__);
- res |= fts_command(info, FTS_CMD_MS_KEY_OFF);
- #endif
- #ifdef PHONE_GESTURE
- if (info->gesture_enabled == 1) {
- logError(0, "%s %s: enter in gesture mode!\n",
- tag, __func__);
- ret = enterGestureMode(isSystemResettedDown());
- if (ret >= OK) {
- info->mode |= FEAT_GESTURE;
- } else {
- logError(1,
- "%s %s:enterGestureMode failed!%08X recovery in senseOff\n",
- tag, __func__, ret);
- }
- res |= ret;
- }
- #endif
- if (info->mode != (FEAT_GESTURE|MODE_NOTHING)
- || info->gesture_enabled == 0)
- info->mode |= MODE_SENSEOFF;
- setSystemResettedDown(0);
- break;
- case 1:
- /* screen up */
- logError(0, "%s %s: Screen ON...\n", tag, __func__);
- #ifdef FEAT_GLOVE
- if ((info->glove_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Glove Mode setting...\n",
- tag, __func__);
- ret = featureEnableDisable(info->glove_enabled,
- FEAT_GLOVE);
- if (ret < OK) {
- logError(1,
- "%s %s:error in setting GLOVE_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->glove_enabled == FEAT_ENABLE) {
- info->mode |= FEAT_GLOVE;
- logError(1, "%s %s: GLOVE_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1, "%s %s: GLOVE_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_STYLUS
- if ((info->stylus_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Stylus Mode setting...\n",
- tag, __func__);
- ret = featureEnableDisable(info->stylus_enabled,
- FEAT_STYLUS);
- if (ret < OK) {
- logError(1,
- "%s %s:error in set STYLUS_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->stylus_enabled == FEAT_ENABLE) {
- info->mode |= FEAT_STYLUS;
- logError(1, "%s %s: STYLUS_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1, "%s %s: STYLUS_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_COVER
- if ((info->cover_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Cover Mode setting...\n",
- tag, __func__);
- ret = featureEnableDisable(info->cover_enabled,
- FEAT_COVER);
- if (ret < OK) {
- logError(1,
- "%s %s:error setting COVER_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->cover_enabled == FEAT_ENABLE) {
- info->mode |= FEAT_COVER;
- logError(1, "%s %s: COVER_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1, "%s %s: COVER_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_CHARGER
- if ((info->charger_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Charger Mode setting...\n",
- tag, __func__);
- ret = featureEnableDisable(info->charger_enabled,
- FEAT_CHARGER);
- if (ret < OK) {
- logError(1,
- "%s %s:error set CHARGER_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->charger_enabled == FEAT_ENABLE) {
- info->mode |= FEAT_CHARGER;
- logError(1, "%s %s: CHARGER_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1, "%s %s: CHARGER_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_VR
- if ((info->vr_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Vr Mode setting\n", tag, __func__);
- ret = featureEnableDisable(info->vr_enabled, FEAT_VR);
- if (ret < OK) {
- logError(1,
- "%s %s:error setting VR_MODE!:%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->vr_enabled == FEAT_ENABLE) {
- info->mode |= FEAT_VR;
- logError(1, "%s %s: VR_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1, "%s %s: VR_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_EDGE_REJECTION
- if ((info->edge_rej_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Edge Rejection Mode setting\n",
- tag, __func__);
- ret = featureEnableDisable(info->edge_rej_enabled,
- FEAT_EDGE_REJECTION);
- if (ret < OK) {
- logError(1,
- "%s %s:err set EDGE_REJECTION_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->edge_rej_enabled ==
- FEAT_ENABLE) {
- info->mode |= FEAT_EDGE_REJECTION;
- logError(1,
- "%s %s:EDGE_REJECTION_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1,
- "%s %s:EDGE_REJECTION_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_CORNER_REJECTION
- if ((info->corner_rej_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s: Corner rejection Mode setting\n",
- tag, __func__);
- ret = featureEnableDisable(info->corner_rej_enabled,
- FEAT_CORNER_REJECTION);
- if (ret < OK) {
- logError(1,
- "%s%s:err CORNER_REJECTION_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->corner_rej_enabled ==
- FEAT_ENABLE) {
- info->mode |= FEAT_CORNER_REJECTION;
- logError(1,
- "%s%s:CORNER_REJECTION_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1,
- "%s%s:CORNER_REJECTION_MODE Disabled\n",
- tag, __func__);
- }
- }
- #endif
- #ifdef FEAT_EDGE_PALM_REJECTION
- if ((info->edge_palm_rej_enabled == FEAT_ENABLE &&
- isSystemResettedUp()) || force == 1) {
- logError(0, "%s %s:Edge Palm rejection Mode setting\n",
- tag, __func__);
- ret = featureEnableDisable(info->edge_palm_rej_enabled,
- FEAT_EDGE_PALM_REJECTION);
- if (ret < OK) {
- logError(1,
- "%s %s:err EDGE_PALM_REJECTION_MODE!%08X\n",
- tag, __func__, ret);
- }
- res |= ret;
- if (ret >= OK && info->edge_palm_rej_enabled ==
- FEAT_ENABLE) {
- info->mode |= FEAT_EDGE_PALM_REJECTION;
- logError(1,
- "%s %s:EDGE_PALM_REJECTION_MODE Enabled!\n",
- tag, __func__);
- } else {
- logError(1,
- "%s %s:EDGE_PALM_REJECTION_MODE Disabled!\n",
- tag, __func__);
- }
- }
- #endif
- logError(0, "%s %s: Sense ON!\n", tag, __func__);
- res |= fts_command(info, FTS_CMD_MS_MT_SENSE_ON);
- info->mode |= MODE_SENSEON;
- #ifdef PHONE_KEY
- logError(0, "%s %s: Key ON!\n", tag, __func__);
- res |= fts_command(info, FTS_CMD_MS_KEY_ON);
- #endif
- setSystemResettedUp(0);
- break;
- default:
- logError(1,
- "%s %s: invalid resume_bit value = %d! ERROR %08X\n",
- tag, __func__, info->resume_bit, ERROR_OP_NOT_ALLOW);
- res = ERROR_OP_NOT_ALLOW;
- }
- logError(0, "%s %s: Mode Handler finished! res = %08X\n", tag, __func__,
- res);
- return res;
- }
- static int fts_chip_power_switch(struct fts_ts_info *info, bool on)
- {
- int error = -1;
- if (info->bdata->pwr_on_suspend) {
- if (!info->ts_pinctrl)
- return 0;
- if (on) {
- error = pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_active);
- if (error < 0)
- logError(1, "%s: Failed to select %s\n",
- __func__, PINCTRL_STATE_ACTIVE);
- } else {
- error = pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_suspend);
- if (error < 0)
- logError(1, "%s: Failed to select %s\n",
- __func__, PINCTRL_STATE_SUSPEND);
- }
- return 0;
- }
- if (on) {
- if (info->bus_reg) {
- error = regulator_enable(info->bus_reg);
- if (error < 0)
- logError(1, "%s %s: Failed to enable AVDD\n",
- tag, __func__);
- }
- if (info->pwr_reg) {
- error = regulator_enable(info->pwr_reg);
- if (error < 0)
- logError(1, "%s %s: Failed to enable DVDD\n",
- tag, __func__);
- }
- if (info->ts_pinctrl) {
- if (pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_active) < 0) {
- logError(1, "%s: Failed to select %s\n",
- __func__, PINCTRL_STATE_ACTIVE);
- }
- }
- } else {
- if (info->bdata->reset_gpio != GPIO_NOT_DEFINED)
- gpio_set_value(info->bdata->reset_gpio, 0);
- else
- msleep(300);
- if (info->ts_pinctrl) {
- if (pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_suspend) < 0) {
- logError(1, "%s: Failed to select %s\n",
- __func__, PINCTRL_STATE_SUSPEND);
- }
- }
- if (info->pwr_reg) {
- error = regulator_disable(info->pwr_reg);
- if (error < 0)
- logError(1, "%s %s: Failed to disable DVDD\n",
- tag, __func__);
- }
- if (info->bus_reg) {
- error = regulator_disable(info->bus_reg);
- if (error < 0)
- logError(1, "%s %s: Failed to disable AVDD\n",
- tag, __func__);
- }
- }
- return error;
- }
- static void fts_resume_work(struct work_struct *work)
- {
- struct fts_ts_info *info;
- info = container_of(work, struct fts_ts_info, resume_work);
- __pm_wakeup_event(info->wakeup_source, HZ);
- fts_chip_power_switch(info, true);
- info->resume_bit = 1;
- fts_system_reset();
- #ifdef USE_NOISE_PARAM
- readNoiseParameters(noise_params);
- #endif
- #ifdef USE_NOISE_PARAM
- writeNoiseParameters(noise_params);
- #endif
- release_all_touches(info);
- fts_mode_handler(info, 0);
- info->sensor_sleep = false;
- fts_interrupt_enable(info);
- }
- static void fts_suspend_work(struct work_struct *work)
- {
- struct fts_ts_info *info;
- info = container_of(work, struct fts_ts_info, suspend_work);
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- if (atomic_read(&info->trusted_touch_enabled))
- wait_for_completion_interruptible(
- &info->trusted_touch_powerdown);
- #endif
- __pm_wakeup_event(info->wakeup_source, HZ);
- info->resume_bit = 0;
- fts_mode_handler(info, 0);
- fts_interrupt_disable(info);
- release_all_touches(info);
- info->sensor_sleep = true;
- fts_chip_power_switch(info, false);
- }
- #if defined(CONFIG_FB_MSM)
- static int fts_fb_state_chg_callback(struct notifier_block *nb,
- unsigned long val, void *data)
- {
- struct fts_ts_info *info = container_of(nb,
- struct fts_ts_info, notifier);
- struct fb_event *evdata = data;
- unsigned int blank;
- if (!evdata || (evdata->id != 0))
- return 0;
- if (val != FB_EVENT_BLANK)
- return 0;
- logError(0, "%s %s: fts notifier begin!\n", tag, __func__);
- if (evdata->data && val == FB_EVENT_BLANK && info) {
- blank = *(int *) (evdata->data);
- switch (blank) {
- case FB_BLANK_POWERDOWN:
- if (info->sensor_sleep)
- break;
- logError(0, "%s %s: FB_BLANK_POWERDOWN\n",
- tag, __func__);
- queue_work(info->event_wq, &info->suspend_work);
- break;
- case FB_BLANK_UNBLANK:
- if (!info->sensor_sleep)
- break;
- logError(0, "%s %s: FB_BLANK_UNBLANK\n",
- tag, __func__);
- queue_work(info->event_wq, &info->resume_work);
- break;
- default:
- break;
- }
- }
- return NOTIFY_OK;
- }
- static struct notifier_block fts_noti_block = {
- .notifier_call = fts_fb_state_chg_callback,
- };
- #endif
- static int fts_pinctrl_init(struct fts_ts_info *info)
- {
- int retval;
- /* Get pinctrl if target uses pinctrl */
- info->ts_pinctrl = devm_pinctrl_get(info->dev);
- if (IS_ERR_OR_NULL(info->ts_pinctrl)) {
- retval = PTR_ERR(info->ts_pinctrl);
- logError(1, "Target does not use pinctrl %d\n", retval);
- goto err_pinctrl_get;
- }
- info->pinctrl_state_active
- = pinctrl_lookup_state(info->ts_pinctrl, PINCTRL_STATE_ACTIVE);
- if (IS_ERR_OR_NULL(info->pinctrl_state_active)) {
- retval = PTR_ERR(info->pinctrl_state_active);
- logError(1, "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_ACTIVE, retval);
- goto err_pinctrl_lookup;
- }
- info->pinctrl_state_suspend
- = pinctrl_lookup_state(info->ts_pinctrl, PINCTRL_STATE_SUSPEND);
- if (IS_ERR_OR_NULL(info->pinctrl_state_suspend)) {
- retval = PTR_ERR(info->pinctrl_state_suspend);
- logError(1, "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_SUSPEND, retval);
- goto err_pinctrl_lookup;
- }
- info->pinctrl_state_release
- = pinctrl_lookup_state(info->ts_pinctrl, PINCTRL_STATE_RELEASE);
- if (IS_ERR_OR_NULL(info->pinctrl_state_release)) {
- retval = PTR_ERR(info->pinctrl_state_release);
- logError(1, "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_RELEASE, retval);
- }
- return 0;
- err_pinctrl_lookup:
- devm_pinctrl_put(info->ts_pinctrl);
- err_pinctrl_get:
- info->ts_pinctrl = NULL;
- return retval;
- }
- static int fts_get_reg(struct fts_ts_info *info, bool get)
- {
- int retval;
- const struct fts_i2c_platform_data *bdata = info->bdata;
- if (!get) {
- retval = 0;
- goto regulator_put;
- }
- if ((bdata->pwr_reg_name != NULL) && (*bdata->pwr_reg_name != 0)) {
- info->pwr_reg = regulator_get(info->dev,
- bdata->pwr_reg_name);
- if (IS_ERR(info->pwr_reg)) {
- logError(1, "%s %s: Failed to get power regulator\n",
- tag, __func__);
- retval = PTR_ERR(info->pwr_reg);
- goto regulator_put;
- }
- retval = regulator_set_load(info->pwr_reg, FTS_DVDD_LOAD);
- if (retval < 0) {
- logError(1, "%s %s: Failed to set power load\n",
- tag, __func__);
- goto regulator_put;
- }
- retval = regulator_set_voltage(info->pwr_reg,
- FTS_DVDD_VOL_MIN, FTS_DVDD_VOL_MAX);
- if (retval < 0) {
- logError(1, "%s %s: Failed to set power voltage\n",
- tag, __func__);
- goto regulator_put;
- }
- }
- if ((bdata->bus_reg_name != NULL) && (*bdata->bus_reg_name != 0)) {
- info->bus_reg = regulator_get(info->dev,
- bdata->bus_reg_name);
- if (IS_ERR(info->bus_reg)) {
- logError(1,
- "%s %s:Failed to get bus pullup regulator\n",
- tag, __func__);
- retval = PTR_ERR(info->bus_reg);
- goto regulator_put;
- }
- retval = regulator_set_load(info->bus_reg, FTS_AVDD_LOAD);
- if (retval < 0) {
- logError(1, "%s %s: Failed to set power load\n",
- tag, __func__);
- goto regulator_put;
- }
- retval = regulator_set_voltage(info->bus_reg,
- FTS_AVDD_VOL_MIN, FTS_AVDD_VOL_MAX);
- if (retval < 0) {
- logError(1, "%s %s: Failed to set power voltage\n",
- tag, __func__);
- goto regulator_put;
- }
- }
- return 0;
- regulator_put:
- if (info->pwr_reg) {
- regulator_put(info->pwr_reg);
- info->pwr_reg = NULL;
- }
- if (info->bus_reg) {
- regulator_put(info->bus_reg);
- info->bus_reg = NULL;
- }
- return retval;
- }
- static int fts_enable_reg(struct fts_ts_info *info,
- bool enable)
- {
- int retval;
- if (!enable) {
- retval = 0;
- goto disable_pwr_reg;
- }
- if (info->bus_reg) {
- retval = regulator_enable(info->bus_reg);
- if (retval < 0) {
- logError(1, "%s %s: Failed to enable bus regulator\n",
- tag, __func__);
- goto exit;
- }
- }
- if (info->pwr_reg) {
- retval = regulator_enable(info->pwr_reg);
- if (retval < 0) {
- logError(1, "%s %s: Failed to enable power regulator\n",
- tag, __func__);
- goto disable_bus_reg;
- }
- }
- return OK;
- disable_pwr_reg:
- if (info->pwr_reg)
- regulator_disable(info->pwr_reg);
- disable_bus_reg:
- if (info->bus_reg)
- regulator_disable(info->bus_reg);
- exit:
- return retval;
- }
- static int fts_gpio_setup(int gpio, bool config, int dir, int state)
- {
- int retval = 0;
- unsigned char buf[16];
- if (config) {
- snprintf(buf, 16, "fts_gpio_%u\n", gpio);
- retval = gpio_request(gpio, buf);
- if (retval) {
- logError(1, "%s %s: Failed to get gpio %d (code: %d)",
- tag, __func__, gpio, retval);
- return retval;
- }
- if (dir == 0)
- retval = gpio_direction_input(gpio);
- else
- retval = gpio_direction_output(gpio, state);
- if (retval) {
- logError(1, "%s %s: Failed to set gpio %d direction",
- tag, __func__, gpio);
- return retval;
- }
- } else {
- gpio_free(gpio);
- }
- return retval;
- }
- static int fts_set_gpio(struct fts_ts_info *info)
- {
- int retval;
- const struct fts_i2c_platform_data *bdata =
- info->bdata;
- retval = fts_gpio_setup(bdata->irq_gpio, true, 0, 0);
- if (retval < 0) {
- logError(1, "%s %s: Failed to configure irq GPIO\n",
- tag, __func__);
- goto err_gpio_irq;
- }
- if (bdata->reset_gpio >= 0) {
- retval = fts_gpio_setup(bdata->reset_gpio, true, 1, 0);
- if (retval < 0) {
- logError(1, "%s %s: Failed to configure reset GPIO\n",
- tag, __func__);
- goto err_gpio_reset;
- }
- }
- if (bdata->reset_gpio >= 0) {
- gpio_set_value(bdata->reset_gpio, 0);
- msleep(20);
- gpio_set_value(bdata->reset_gpio, 1);
- }
- setResetGpio(bdata->reset_gpio);
- return OK;
- err_gpio_reset:
- fts_gpio_setup(bdata->irq_gpio, false, 0, 0);
- setResetGpio(GPIO_NOT_DEFINED);
- err_gpio_irq:
- return retval;
- }
- static int parse_dt(struct device *dev,
- struct fts_i2c_platform_data *bdata)
- {
- int retval;
- const char *name;
- struct device_node *np = dev->of_node;
- bdata->irq_gpio = of_get_named_gpio_flags(np,
- "st,irq-gpio", 0, NULL);
- logError(0, "%s irq_gpio = %d\n", tag, bdata->irq_gpio);
- bdata->pwr_on_suspend =
- of_property_read_bool(np, "st,power_on_suspend");
- retval = of_property_read_string(np, "st,regulator_dvdd", &name);
- if (retval == -EINVAL)
- bdata->pwr_reg_name = NULL;
- else if (retval < 0)
- return retval;
- bdata->pwr_reg_name = name;
- logError(0, "%s pwr_reg_name = %s\n", tag, name);
- retval = of_property_read_string(np, "st,regulator_avdd", &name);
- if (retval == -EINVAL)
- bdata->bus_reg_name = NULL;
- else if (retval < 0)
- return retval;
- bdata->bus_reg_name = name;
- logError(0, "%s bus_reg_name = %s\n", tag, name);
- if (of_property_read_bool(np, "st,reset-gpio")) {
- bdata->reset_gpio = of_get_named_gpio_flags(np,
- "st,reset-gpio", 0, NULL);
- logError(0, "%s reset_gpio =%d\n", tag, bdata->reset_gpio);
- } else {
- bdata->reset_gpio = GPIO_NOT_DEFINED;
- }
- bdata->x_flip = of_property_read_bool(np, "st,x-flip");
- bdata->y_flip = of_property_read_bool(np, "st,y-flip");
- return OK;
- }
- static int check_dt(struct device_node *np)
- {
- int i;
- int count;
- struct device_node *node;
- struct drm_panel *panel;
- count = of_count_phandle_with_args(np, "panel", NULL);
- if (count <= 0)
- return OK;
- for (i = 0; i < count; i++) {
- node = of_parse_phandle(np, "panel", i);
- panel = of_drm_find_panel(node);
- of_node_put(node);
- if (!IS_ERR(panel)) {
- active_panel = panel;
- return OK;
- }
- }
- return PTR_ERR(panel);
- }
- static int check_default_tp(struct device_node *dt, const char *prop)
- {
- const char *active_tp;
- const char *compatible;
- char *start;
- int ret;
- ret = of_property_read_string(dt->parent, prop, &active_tp);
- if (ret) {
- pr_err(" %s:fail to read %s %d\n", __func__, prop, ret);
- return -ENODEV;
- }
- ret = of_property_read_string(dt, "compatible", &compatible);
- if (ret < 0) {
- pr_err(" %s:fail to read %s %d\n", __func__, "compatible", ret);
- return -ENODEV;
- }
- start = strnstr(active_tp, compatible, strlen(active_tp));
- if (start == NULL) {
- pr_err(" %s:no match compatible, %s, %s\n",
- __func__, compatible, active_tp);
- ret = -ENODEV;
- }
- return ret;
- }
- static int fts_probe_delayed(struct fts_ts_info *info)
- {
- int error = 0;
- int retval = 0;
- /* Avoid setting up hardware for TVM during probe */
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- #ifdef CONFIG_ARCH_QTI_VM
- if (!atomic_read(&info->delayed_vm_probe_pending)) {
- atomic_set(&info->delayed_vm_probe_pending, 1);
- return 0;
- }
- goto tvm_setup;
- #endif
- #endif
- logError(0, "%s SET Regulators:\n", tag);
- retval = fts_get_reg(info, true);
- if (retval < 0) {
- logError(1, "%s ERROR: %s: Failed to get regulators\n",
- tag, __func__);
- goto Exit_1;
- }
- retval = fts_enable_reg(info, true);
- if (retval < 0) {
- logError(1,
- "%s %s: ERROR Failed to enable regulators\n",
- tag, __func__);
- goto Exit_2;
- }
- logError(0, "%s SET GPIOS:\n", tag);
- retval = fts_set_gpio(info);
- if (retval < 0) {
- logError(1, "%s %s: ERROR Failed to set up GPIO's\n",
- tag, __func__);
- goto Exit_2;
- }
- info->client->irq = gpio_to_irq(info->bdata->irq_gpio);
- retval = fts_pinctrl_init(info);
- if (!retval && info->ts_pinctrl) {
- /*
- * Pinctrl handle is optional. If pinctrl handle is
- * found let pins to be configured in active state.
- * If not found continue further without error.
- */
- retval = pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_active);
- if (retval < 0) {
- logError(1,
- "%s: Failed to select %s pinstate %d\n",
- __func__, PINCTRL_STATE_ACTIVE, retval);
- }
- }
- #ifdef CONFIG_ARCH_QTI_VM
- tvm_setup:
- #endif
- /* init hardware device */
- logError(0, "%s Device Initialization:\n", tag);
- error = fts_init(info);
- if (error < OK) {
- logError(1, "%s Cannot initialize the device ERROR %08X\n",
- tag, error);
- error = -ENODEV;
- #ifdef CONFIG_ARCH_QTI_VM
- return error;
- #endif
- goto Exit_3;
- }
- queue_delayed_work(info->fwu_workqueue, &info->fwu_work,
- msecs_to_jiffies(EXP_FN_WORK_DELAY_MS));
- return error;
- Exit_3:
- if (info->ts_pinctrl) {
- if (IS_ERR_OR_NULL(info->pinctrl_state_release)) {
- devm_pinctrl_put(info->ts_pinctrl);
- info->ts_pinctrl = NULL;
- } else {
- if (pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_release))
- logError(1, "%s:Failed to select %s pinstate\n",
- __func__, PINCTRL_STATE_RELEASE);
- }
- }
- fts_enable_reg(info, false);
- fts_gpio_setup(info->bdata->irq_gpio, false, 0, 0);
- fts_gpio_setup(info->bdata->reset_gpio, false, 0, 0);
- Exit_2:
- fts_get_reg(info, false);
- Exit_1:
- return error;
- }
- static int fts_probe_internal(struct i2c_client *client,
- const struct i2c_device_id *idp)
- {
- struct fts_ts_info *info = NULL;
- int error = 0;
- struct device_node *dp = client->dev.of_node;
- int skip_5_1 = 0;
- logError(0, "%s %s: driver probe begin!\n", tag, __func__);
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- logError(1, "%s Unsupported I2C functionality\n", tag);
- error = -EIO;
- goto ProbeErrorExit_0;
- }
- openChannel(client);
- info = kzalloc(sizeof(struct fts_ts_info), GFP_KERNEL);
- if (!info) {
- logError(1,
- "%s can't allocate struct info!\n",
- tag);
- error = -ENOMEM;
- goto ProbeErrorExit_0;
- }
- info->client = client;
- i2c_set_clientdata(client, info);
- info->i2c_data = kmalloc(I2C_DATA_MAX_LEN, GFP_KERNEL);
- if (info->i2c_data == NULL) {
- error = -ENOMEM;
- goto ProbeErrorExit_0P1;
- }
- info->i2c_data_len = I2C_DATA_MAX_LEN;
- logError(0, "%s i2c address: %x\n", tag, client->addr);
- info->dev = &info->client->dev;
- if (dp) {
- info->bdata = devm_kzalloc(&client->dev,
- sizeof(struct fts_i2c_platform_data),
- GFP_KERNEL);
- if (!info->bdata) {
- logError(1, "%s ERROR:info.bdata kzalloc failed\n",
- tag);
- goto ProbeErrorExit_1;
- }
- parse_dt(&client->dev, info->bdata);
- }
- logError(0, "%s SET Auto Fw Update:\n", tag);
- info->fwu_workqueue = alloc_workqueue("fts-fwu-queue",
- WQ_UNBOUND|WQ_HIGHPRI|WQ_CPU_INTENSIVE, 1);
- if (!info->fwu_workqueue) {
- logError(1, "%s ERROR: Cannot create fwu work thread\n", tag);
- goto ProbeErrorExit_1;
- }
- INIT_DELAYED_WORK(&info->fwu_work, fts_fw_update_auto);
- logError(0, "%s SET Event Handler:\n", tag);
- info->wakeup_source = wakeup_source_register(&client->dev,
- dev_name(&client->dev));
- info->event_wq = alloc_workqueue("fts-event-queue",
- WQ_UNBOUND|WQ_HIGHPRI|WQ_CPU_INTENSIVE, 1);
- if (!info->event_wq) {
- logError(1, "%s ERROR: Cannot create work thread\n", tag);
- error = -ENOMEM;
- goto ProbeErrorExit_4;
- }
- INIT_WORK(&info->work, fts_event_handler);
- INIT_WORK(&info->resume_work, fts_resume_work);
- INIT_WORK(&info->suspend_work, fts_suspend_work);
- logError(0, "%s SET Input Device Property:\n", tag);
- /* info->dev = &info->client->dev; */
- info->input_dev = input_allocate_device();
- if (!info->input_dev) {
- logError(1, "%s ERROR: No such input device defined!\n",
- tag);
- error = -ENODEV;
- goto ProbeErrorExit_5;
- }
- info->input_dev->dev.parent = &client->dev;
- info->input_dev->name = FTS_TS_DRV_NAME;
- snprintf(fts_ts_phys, sizeof(fts_ts_phys), "%s/input0",
- info->input_dev->name);
- info->input_dev->phys = fts_ts_phys;
- info->input_dev->id.bustype = BUS_I2C;
- info->input_dev->id.vendor = 0x0001;
- info->input_dev->id.product = 0x0002;
- info->input_dev->id.version = 0x0100;
- __set_bit(EV_SYN, info->input_dev->evbit);
- __set_bit(EV_KEY, info->input_dev->evbit);
- __set_bit(EV_ABS, info->input_dev->evbit);
- __set_bit(BTN_TOUCH, info->input_dev->keybit);
- __set_bit(BTN_TOOL_FINGER, info->input_dev->keybit);
- input_mt_init_slots(info->input_dev, TOUCH_ID_MAX, INPUT_MT_DIRECT);
- input_set_abs_params(info->input_dev, ABS_MT_POSITION_X,
- X_AXIS_MIN, X_AXIS_MAX, 0, 0);
- input_set_abs_params(info->input_dev, ABS_MT_POSITION_Y,
- Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
- input_set_abs_params(info->input_dev, ABS_MT_TOUCH_MAJOR,
- AREA_MIN, AREA_MAX, 0, 0);
- input_set_abs_params(info->input_dev, ABS_MT_TOUCH_MINOR,
- AREA_MIN, AREA_MAX, 0, 0);
- #ifdef PHONE_GESTURE
- input_set_capability(info->input_dev, EV_KEY, KEY_WAKEUP);
- input_set_capability(info->input_dev, EV_KEY, KEY_M);
- input_set_capability(info->input_dev, EV_KEY, KEY_O);
- input_set_capability(info->input_dev, EV_KEY, KEY_E);
- input_set_capability(info->input_dev, EV_KEY, KEY_W);
- input_set_capability(info->input_dev, EV_KEY, KEY_C);
- input_set_capability(info->input_dev, EV_KEY, KEY_L);
- input_set_capability(info->input_dev, EV_KEY, KEY_F);
- input_set_capability(info->input_dev, EV_KEY, KEY_V);
- input_set_capability(info->input_dev, EV_KEY, KEY_S);
- input_set_capability(info->input_dev, EV_KEY, KEY_Z);
- input_set_capability(info->input_dev, EV_KEY, KEY_WWW);
- input_set_capability(info->input_dev, EV_KEY, KEY_LEFT);
- input_set_capability(info->input_dev, EV_KEY, KEY_RIGHT);
- input_set_capability(info->input_dev, EV_KEY, KEY_UP);
- input_set_capability(info->input_dev, EV_KEY, KEY_DOWN);
- input_set_capability(info->input_dev, EV_KEY, KEY_F1);
- input_set_capability(info->input_dev, EV_KEY, KEY_F2);
- input_set_capability(info->input_dev, EV_KEY, KEY_F3);
- input_set_capability(info->input_dev, EV_KEY, KEY_F4);
- input_set_capability(info->input_dev, EV_KEY, KEY_F5);
- input_set_capability(info->input_dev, EV_KEY, KEY_LEFTBRACE);
- input_set_capability(info->input_dev, EV_KEY, KEY_RIGHTBRACE);
- #endif
- #ifdef PHONE_KEY
- /* KEY associated to the touch screen buttons */
- input_set_capability(info->input_dev, EV_KEY, KEY_HOMEPAGE);
- input_set_capability(info->input_dev, EV_KEY, KEY_BACK);
- input_set_capability(info->input_dev, EV_KEY, KEY_MENU);
- #endif
- mutex_init(&(info->input_report_mutex));
- #ifdef PHONE_GESTURE
- mutex_init(&gestureMask_mutex);
- #endif
- /* register the multi-touch input device */
- error = input_register_device(info->input_dev);
- if (error) {
- logError(1, "%s ERROR: No such input device\n", tag);
- error = -ENODEV;
- goto ProbeErrorExit_5_1;
- }
- skip_5_1 = 1;
- /* track slots */
- info->touch_id = 0;
- #ifdef STYLUS_MODE
- info->stylus_id = 0;
- #endif
- /*
- * init feature switches (by default all the features
- * are disable, if one feature want to be enabled from
- * the start, set the corresponding value to 1)
- */
- info->gesture_enabled = 0;
- info->glove_enabled = 0;
- info->charger_enabled = 0;
- info->stylus_enabled = 0;
- info->vr_enabled = 0;
- info->cover_enabled = 0;
- info->edge_rej_enabled = 0;
- info->corner_rej_enabled = 0;
- info->edge_palm_rej_enabled = 0;
- info->resume_bit = 1;
- #if defined(CONFIG_FB_MSM)
- info->notifier = fts_noti_block;
- #endif
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- fts_trusted_touch_init(info);
- mutex_init(&(info->fts_clk_io_ctrl_mutex));
- #endif
- logError(0, "%s SET Device File Nodes:\n", tag);
- /* sysfs stuff */
- info->attrs.attrs = fts_attr_group;
- error = sysfs_create_group(&client->dev.kobj, &info->attrs);
- if (error) {
- logError(1, "%s ERROR: Cannot create sysfs structure!\n", tag);
- error = -ENODEV;
- goto ProbeErrorExit_7;
- }
- /* I2C cmd */
- fts_cmd_class = class_create(THIS_MODULE, FTS_TS_DRV_NAME);
- #ifdef SCRIPTLESS
- info->i2c_cmd_dev = device_create(fts_cmd_class,
- NULL, DCHIP_ID_0, info, "fts_i2c");
- if (IS_ERR(info->i2c_cmd_dev)) {
- logError(1,
- "%s ERROR: Failed to create device for the sysfs!\n",
- tag);
- goto ProbeErrorExit_8;
- }
- dev_set_drvdata(info->i2c_cmd_dev, info);
- error = sysfs_create_group(&info->i2c_cmd_dev->kobj,
- &i2c_cmd_attr_group);
- if (error) {
- logError(1, "%s ERROR: Failed to create sysfs group!\n", tag);
- goto ProbeErrorExit_9;
- }
- #endif
- #ifdef DRIVER_TEST
- info->test_cmd_dev = device_create(fts_cmd_class,
- NULL, DCHIP_ID_0, info, "fts_driver_test");
- if (IS_ERR(info->test_cmd_dev)) {
- logError(1,
- "%s ERROR: Failed to create device for the sysfs!\n",
- tag);
- goto ProbeErrorExit_10;
- }
- dev_set_drvdata(info->test_cmd_dev, info);
- error = sysfs_create_group(&info->test_cmd_dev->kobj,
- &test_cmd_attr_group);
- if (error) {
- logError(1, "%s ERROR: Failed to create sysfs group!\n", tag);
- goto ProbeErrorExit_11;
- }
- #endif
- info->aoi_cmd_dev = device_create(fts_cmd_class,
- NULL, DCHIP_ID_0, info, "touch_aoi");
- if (IS_ERR(info->aoi_cmd_dev)) {
- logError(1,
- "%s ERROR: Failed to create device for the sysfs\n",
- tag);
- goto ProbeErrorExit_10;
- }
- dev_set_drvdata(info->aoi_cmd_dev, info);
- error = sysfs_create_group(&info->aoi_cmd_dev->kobj,
- &aoi_cmd_attr_group);
- if (error) {
- logError(1, "%s ERROR: Failed to create sysfs group\n", tag);
- goto ProbeErrorExit_11;
- }
- info->aoi_class = class_create(THIS_MODULE, "android_touch");
- if (info->aoi_class) {
- info->aoi_dev = device_create(info->aoi_class,
- NULL, DCHIP_ID_0, info, "touch");
- if (!IS_ERR(info->aoi_dev)) {
- dev_set_drvdata(info->aoi_dev, info);
- error = sysfs_create_group(&info->aoi_dev->kobj,
- &aoi_enable_attr_group);
- }
- }
- error = fts_probe_delayed(info);
- if (error) {
- logError(1, "%s ERROR: Failed to enable resources\n",
- tag);
- goto ProbeErrorExit_11;
- }
- logError(1, "%s Probe Finished!\n", tag);
- return OK;
- /* error exit path */
- #ifdef DRIVER_TEST
- ProbeErrorExit_11:
- #ifndef SCRIPTLESS
- device_destroy(fts_cmd_class, DCHIP_ID_0);
- #endif
- ProbeErrorExit_10:
- #ifndef SCRIPTLESS
- sysfs_remove_group(&client->dev.kobj, &info->attrs);
- #endif
- #endif
- #ifdef SCRIPTLESS
- ProbeErrorExit_9:
- device_destroy(fts_cmd_class, DCHIP_ID_0);
- ProbeErrorExit_8:
- sysfs_remove_group(&client->dev.kobj, &info->attrs);
- #endif
- ProbeErrorExit_7:
- #ifdef CONFIG_ST_TRUSTED_TOUCH
- fts_vm_deinit(info);
- #endif
- /* fb_unregister_client(&info->notifier); */
- input_unregister_device(info->input_dev);
- ProbeErrorExit_5_1:
- if (skip_5_1 != 1)
- input_free_device(info->input_dev);
- ProbeErrorExit_5:
- destroy_workqueue(info->event_wq);
- ProbeErrorExit_4:
- destroy_workqueue(info->fwu_workqueue);
- wakeup_source_unregister(info->wakeup_source);
- ProbeErrorExit_1:
- kfree(info->i2c_data);
- ProbeErrorExit_0P1:
- kfree(info);
- ProbeErrorExit_0:
- logError(1, "%s Probe Failed!\n", tag);
- return error;
- }
- static int fts_probe(struct i2c_client *client, const struct i2c_device_id *idp)
- {
- int error = 0;
- struct device_node *dp = client->dev.of_node;
- error = check_dt(dp);
- if (error == -EPROBE_DEFER)
- return error;
- if (error) {
- if (!check_default_tp(dp, "qcom,i2c-touch-active"))
- error = -EPROBE_DEFER;
- else
- error = -ENODEV;
- return error;
- }
- device_init_wakeup(&client->dev, true);
- return fts_probe_internal(client, idp);
- }
- static int fts_remove(struct i2c_client *client)
- {
- struct fts_ts_info *info = i2c_get_clientdata(client);
- if (info->aoi_dev) {
- sysfs_remove_group(&info->aoi_dev->kobj,
- &aoi_enable_attr_group);
- info->aoi_dev = NULL;
- }
- if (info->aoi_class) {
- device_destroy(info->aoi_class, DCHIP_ID_0);
- info->aoi_class = NULL;
- }
- #ifdef DRIVER_TEST
- sysfs_remove_group(&info->test_cmd_dev->kobj,
- &test_cmd_attr_group);
- #endif
- #ifdef SCRIPTLESS
- /* I2C cmd */
- sysfs_remove_group(&info->i2c_cmd_dev->kobj, &i2c_cmd_attr_group);
- #endif
- #if defined(SCRIPTLESS) || defined(DRIVER_TEST)
- device_destroy(fts_cmd_class, DCHIP_ID_0);
- #endif
- /* sysfs stuff */
- sysfs_remove_group(&client->dev.kobj, &info->attrs);
- /* remove interrupt and event handlers */
- fts_interrupt_uninstall(info);
- #if defined(CONFIG_FB_MSM)
- fb_unregister_client(&info->notifier);
- #else
- if (active_panel && info->notifier_cookie)
- panel_event_notifier_unregister(info->notifier_cookie);
- #endif
- /* unregister the device */
- input_unregister_device(info->input_dev);
- /* input_free_device(info->input_dev ); */
- /* Empty the FIFO buffer */
- fts_command(info, FIFO_CMD_FLUSH);
- /* flushFIFO(); */
- /* Remove the work thread */
- destroy_workqueue(info->event_wq);
- /* wake_lock_destroy(&info->wakelock); */
- wakeup_source_unregister(info->wakeup_source);
- destroy_workqueue(info->fwu_workqueue);
- if (info->ts_pinctrl) {
- if (IS_ERR_OR_NULL(info->pinctrl_state_release)) {
- devm_pinctrl_put(info->ts_pinctrl);
- info->ts_pinctrl = NULL;
- } else {
- pinctrl_select_state(info->ts_pinctrl,
- info->pinctrl_state_release);
- }
- }
- fts_enable_reg(info, false);
- fts_gpio_setup(info->bdata->irq_gpio, false, 0, 0);
- fts_gpio_setup(info->bdata->reset_gpio, false, 0, 0);
- fts_get_reg(info, false);
- /* free all */
- kfree(info->i2c_data);
- kfree(info);
- device_init_wakeup(&client->dev, false);
- return OK;
- }
- static const struct of_device_id fts_of_match_table[] = {
- {
- .compatible = "st,fts",
- },
- {},
- };
- static const struct i2c_device_id fts_device_id[] = {
- {FTS_TS_DRV_NAME, 0},
- {}
- };
- static struct i2c_driver fts_i2c_driver = {
- .driver = {
- .name = FTS_TS_DRV_NAME,
- .of_match_table = fts_of_match_table,
- },
- .probe = fts_probe,
- .remove = fts_remove,
- .id_table = fts_device_id,
- };
- static int __init fts_driver_init(void)
- {
- return i2c_add_driver(&fts_i2c_driver);
- }
- static void __exit fts_driver_exit(void)
- {
- i2c_del_driver(&fts_i2c_driver);
- }
- module_init(fts_driver_init);
- module_exit(fts_driver_exit);
- MODULE_DESCRIPTION("STMicroelectronics MultiTouch IC Driver");
- MODULE_LICENSE("GPL v2");
|