1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797 |
- /*
- * Synaptics DSX touchscreen driver
- *
- * Copyright (C) 2012-2016 Synaptics Incorporated. All rights reserved.
- *
- * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (C) 2012 Alexandra Chin <[email protected]>
- * Copyright (C) 2012 Scott Lin <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
- * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
- * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
- * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
- * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
- * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
- * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
- * DOLLARS.
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <linux/input.h>
- #include <linux/firmware.h>
- #include <linux/platform_device.h>
- #include <linux/input/synaptics_dsx.h>
- #include "synaptics_dsx_core.h"
- #define FW_IHEX_NAME "synaptics/startup_fw_update.bin"
- #define FW_IMAGE_NAME "synaptics/startup_fw_update.img"
- #define ENABLE_SYS_REFLASH false
- #define FORCE_UPDATE false
- #define DO_LOCKDOWN false
- #define MAX_IMAGE_NAME_LEN 256
- #define MAX_FIRMWARE_ID_LEN 10
- #define IMAGE_HEADER_VERSION_05 0x05
- #define IMAGE_HEADER_VERSION_06 0x06
- #define IMAGE_HEADER_VERSION_10 0x10
- #define IMAGE_AREA_OFFSET 0x100
- #define LOCKDOWN_SIZE 0x50
- #define MAX_UTILITY_PARAMS 20
- #define V5V6_BOOTLOADER_ID_OFFSET 0
- #define V5V6_CONFIG_ID_SIZE 4
- #define V5_PROPERTIES_OFFSET 2
- #define V5_BLOCK_SIZE_OFFSET 3
- #define V5_BLOCK_COUNT_OFFSET 5
- #define V5_BLOCK_NUMBER_OFFSET 0
- #define V5_BLOCK_DATA_OFFSET 2
- #define V6_PROPERTIES_OFFSET 1
- #define V6_BLOCK_SIZE_OFFSET 2
- #define V6_BLOCK_COUNT_OFFSET 3
- #define V6_PROPERTIES_2_OFFSET 4
- #define V6_GUEST_CODE_BLOCK_COUNT_OFFSET 5
- #define V6_BLOCK_NUMBER_OFFSET 0
- #define V6_BLOCK_DATA_OFFSET 1
- #define V6_FLASH_COMMAND_OFFSET 2
- #define V6_FLASH_STATUS_OFFSET 3
- #define V7_CONFIG_ID_SIZE 32
- #define V7_FLASH_STATUS_OFFSET 0
- #define V7_PARTITION_ID_OFFSET 1
- #define V7_BLOCK_NUMBER_OFFSET 2
- #define V7_TRANSFER_LENGTH_OFFSET 3
- #define V7_COMMAND_OFFSET 4
- #define V7_PAYLOAD_OFFSET 5
- #define V7_PARTITION_SUPPORT_BYTES 4
- #define F35_ERROR_CODE_OFFSET 0
- #define F35_FLASH_STATUS_OFFSET 5
- #define F35_CHUNK_NUM_LSB_OFFSET 0
- #define F35_CHUNK_NUM_MSB_OFFSET 1
- #define F35_CHUNK_DATA_OFFSET 2
- #define F35_CHUNK_COMMAND_OFFSET 18
- #define F35_CHUNK_SIZE 16
- #define F35_ERASE_ALL_WAIT_MS 5000
- #define F35_RESET_WAIT_MS 250
- #define SLEEP_MODE_NORMAL (0x00)
- #define SLEEP_MODE_SENSOR_SLEEP (0x01)
- #define SLEEP_MODE_RESERVED0 (0x02)
- #define SLEEP_MODE_RESERVED1 (0x03)
- #define ENABLE_WAIT_MS (1 * 1000)
- #define WRITE_WAIT_MS (3 * 1000)
- #define ERASE_WAIT_MS (5 * 1000)
- #define MIN_SLEEP_TIME_US 50
- #define MAX_SLEEP_TIME_US 100
- #define INT_DISABLE_WAIT_MS 20
- #define ENTER_FLASH_PROG_WAIT_MS 20
- #define READ_CONFIG_WAIT_MS 20
- static int fwu_do_reflash(void);
- static int fwu_recovery_check_status(void);
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static ssize_t fwu_sysfs_show_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
- static ssize_t fwu_sysfs_store_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
- static ssize_t fwu_sysfs_do_recovery_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_write_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_read_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_config_area_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_image_name_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_image_size_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_block_size_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_utility_parameter_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_guest_code_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- #ifdef SYNA_TDDI
- static ssize_t fwu_sysfs_write_lockdown_code_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- static ssize_t fwu_sysfs_read_lockdown_code_show(struct device *dev,
- struct device_attribute *attr, char *buf);
- #endif
- #endif
- enum f34_version {
- F34_V0 = 0,
- F34_V1,
- F34_V2,
- };
- enum bl_version {
- BL_V5 = 5,
- BL_V6 = 6,
- BL_V7 = 7,
- BL_V8 = 8,
- };
- enum flash_area {
- NONE = 0,
- UI_FIRMWARE,
- UI_CONFIG,
- };
- enum update_mode {
- NORMAL = 1,
- FORCE = 2,
- LOCKDOWN = 8,
- };
- enum config_area {
- UI_CONFIG_AREA = 0,
- PM_CONFIG_AREA,
- BL_CONFIG_AREA,
- DP_CONFIG_AREA,
- FLASH_CONFIG_AREA,
- #ifdef SYNA_TDDI
- TDDI_FORCE_CONFIG_AREA,
- TDDI_LCM_DATA_AREA,
- TDDI_OEM_DATA_AREA,
- #endif
- UPP_AREA,
- };
- enum v7_status {
- SUCCESS = 0x00,
- DEVICE_NOT_IN_BOOTLOADER_MODE,
- INVALID_PARTITION,
- INVALID_COMMAND,
- INVALID_BLOCK_OFFSET,
- INVALID_TRANSFER,
- NOT_ERASED,
- FLASH_PROGRAMMING_KEY_INCORRECT,
- BAD_PARTITION_TABLE,
- CHECKSUM_FAILED,
- FLASH_HARDWARE_FAILURE = 0x1f,
- };
- enum v7_partition_id {
- BOOTLOADER_PARTITION = 0x01,
- DEVICE_CONFIG_PARTITION,
- FLASH_CONFIG_PARTITION,
- MANUFACTURING_BLOCK_PARTITION,
- GUEST_SERIALIZATION_PARTITION,
- GLOBAL_PARAMETERS_PARTITION,
- CORE_CODE_PARTITION,
- CORE_CONFIG_PARTITION,
- GUEST_CODE_PARTITION,
- DISPLAY_CONFIG_PARTITION,
- EXTERNAL_TOUCH_AFE_CONFIG_PARTITION,
- UTILITY_PARAMETER_PARTITION,
- };
- enum v7_flash_command {
- CMD_V7_IDLE = 0x00,
- CMD_V7_ENTER_BL,
- CMD_V7_READ,
- CMD_V7_WRITE,
- CMD_V7_ERASE,
- CMD_V7_ERASE_AP,
- CMD_V7_SENSOR_ID,
- };
- enum v5v6_flash_command {
- CMD_V5V6_IDLE = 0x0,
- CMD_V5V6_WRITE_FW = 0x2,
- CMD_V5V6_ERASE_ALL = 0x3,
- CMD_V5V6_WRITE_LOCKDOWN = 0x4,
- CMD_V5V6_READ_CONFIG = 0x5,
- CMD_V5V6_WRITE_CONFIG = 0x6,
- CMD_V5V6_ERASE_UI_CONFIG = 0x7,
- CMD_V5V6_ERASE_BL_CONFIG = 0x9,
- CMD_V5V6_ERASE_DISP_CONFIG = 0xa,
- CMD_V5V6_ERASE_GUEST_CODE = 0xb,
- CMD_V5V6_WRITE_GUEST_CODE = 0xc,
- CMD_V5V6_ERASE_CHIP = 0x0d,
- CMD_V5V6_ENABLE_FLASH_PROG = 0xf,
- #ifdef SYNA_TDDI
- CMD_V5V6_ERASE_FORCE_CONFIG = 0x11,
- CMD_V5V6_READ_FORCE_CONFIG = 0x12,
- CMD_V5V6_WRITE_FORCE_CONFIG = 0x13,
- CMD_V5V6_ERASE_LOCKDOWN_DATA = 0x1a,
- CMD_V5V6_READ_LOCKDOWN_DATA = 0x1b,
- CMD_V5V6_WRITE_LOCKDOWN_DATA = 0x1c,
- CMD_V5V6_ERASE_LCM_DATA = 0x1d,
- CMD_V5V6_ERASE_OEM_DATA = 0x1e,
- #endif
- };
- enum flash_command {
- CMD_IDLE = 0,
- CMD_WRITE_FW,
- CMD_WRITE_CONFIG,
- CMD_WRITE_LOCKDOWN,
- CMD_WRITE_GUEST_CODE,
- CMD_WRITE_BOOTLOADER,
- CMD_WRITE_UTILITY_PARAM,
- CMD_READ_CONFIG,
- CMD_ERASE_ALL,
- CMD_ERASE_UI_FIRMWARE,
- CMD_ERASE_UI_CONFIG,
- CMD_ERASE_BL_CONFIG,
- CMD_ERASE_DISP_CONFIG,
- CMD_ERASE_FLASH_CONFIG,
- CMD_ERASE_GUEST_CODE,
- CMD_ERASE_BOOTLOADER,
- CMD_ERASE_UTILITY_PARAMETER,
- CMD_ENABLE_FLASH_PROG,
- #ifdef SYNA_TDDI
- CMD_ERASE_CHIP,
- CMD_ERASE_FORCE_CONFIG,
- CMD_READ_FORCE_CONFIG,
- CMD_WRITE_FORCE_CONFIG,
- CMD_ERASE_LOCKDOWN_DATA,
- CMD_READ_LOCKDOWN_DATA,
- CMD_WRITE_LOCKDOWN_DATA,
- CMD_ERASE_LCM_DATA,
- CMD_READ_LCM_DATA,
- CMD_WRITE_LCM_DATA,
- CMD_ERASE_OEM_DATA,
- CMD_READ_OEM_DATA,
- CMD_WRITE_OEM_DATA,
- #endif
- };
- enum f35_flash_command {
- CMD_F35_IDLE = 0x0,
- CMD_F35_RESERVED = 0x1,
- CMD_F35_WRITE_CHUNK = 0x2,
- CMD_F35_ERASE_ALL = 0x3,
- CMD_F35_RESET = 0x10,
- };
- enum container_id {
- TOP_LEVEL_CONTAINER = 0,
- UI_CONTAINER,
- UI_CONFIG_CONTAINER,
- BL_CONTAINER,
- BL_IMAGE_CONTAINER,
- BL_CONFIG_CONTAINER,
- BL_LOCKDOWN_INFO_CONTAINER,
- PERMANENT_CONFIG_CONTAINER,
- GUEST_CODE_CONTAINER,
- BL_PROTOCOL_DESCRIPTOR_CONTAINER,
- UI_PROTOCOL_DESCRIPTOR_CONTAINER,
- RMI_SELF_DISCOVERY_CONTAINER,
- RMI_PAGE_CONTENT_CONTAINER,
- GENERAL_INFORMATION_CONTAINER,
- DEVICE_CONFIG_CONTAINER,
- FLASH_CONFIG_CONTAINER,
- GUEST_SERIALIZATION_CONTAINER,
- GLOBAL_PARAMETERS_CONTAINER,
- CORE_CODE_CONTAINER,
- CORE_CONFIG_CONTAINER,
- DISPLAY_CONFIG_CONTAINER,
- EXTERNAL_TOUCH_AFE_CONFIG_CONTAINER,
- UTILITY_CONTAINER,
- UTILITY_PARAMETER_CONTAINER,
- };
- enum utility_parameter_id {
- UNUSED = 0,
- FORCE_PARAMETER,
- ANTI_BENDING_PARAMETER,
- };
- struct pdt_properties {
- union {
- struct {
- unsigned char reserved_1:6;
- unsigned char has_bsr:1;
- unsigned char reserved_2:1;
- } __packed;
- unsigned char data[1];
- };
- };
- struct partition_table {
- unsigned char partition_id:5;
- unsigned char byte_0_reserved:3;
- unsigned char byte_1_reserved;
- unsigned char partition_length_7_0;
- unsigned char partition_length_15_8;
- unsigned char start_physical_address_7_0;
- unsigned char start_physical_address_15_8;
- unsigned char partition_properties_7_0;
- unsigned char partition_properties_15_8;
- } __packed;
- struct f01_device_control {
- union {
- struct {
- unsigned char sleep_mode:2;
- unsigned char nosleep:1;
- unsigned char reserved:2;
- unsigned char charger_connected:1;
- unsigned char report_rate:1;
- unsigned char configured:1;
- } __packed;
- unsigned char data[1];
- };
- };
- struct f34_v7_query_0 {
- union {
- struct {
- unsigned char subpacket_1_size:3;
- unsigned char has_config_id:1;
- unsigned char f34_query0_b4:1;
- unsigned char has_thqa:1;
- unsigned char f34_query0_b6__7:2;
- } __packed;
- unsigned char data[1];
- };
- };
- struct f34_v7_query_1_7 {
- union {
- struct {
- /* query 1 */
- unsigned char bl_minor_revision;
- unsigned char bl_major_revision;
- /* query 2 */
- unsigned char bl_fw_id_7_0;
- unsigned char bl_fw_id_15_8;
- unsigned char bl_fw_id_23_16;
- unsigned char bl_fw_id_31_24;
- /* query 3 */
- unsigned char minimum_write_size;
- unsigned char block_size_7_0;
- unsigned char block_size_15_8;
- unsigned char flash_page_size_7_0;
- unsigned char flash_page_size_15_8;
- /* query 4 */
- unsigned char adjustable_partition_area_size_7_0;
- unsigned char adjustable_partition_area_size_15_8;
- /* query 5 */
- unsigned char flash_config_length_7_0;
- unsigned char flash_config_length_15_8;
- /* query 6 */
- unsigned char payload_length_7_0;
- unsigned char payload_length_15_8;
- /* query 7 */
- unsigned char f34_query7_b0:1;
- unsigned char has_bootloader:1;
- unsigned char has_device_config:1;
- unsigned char has_flash_config:1;
- unsigned char has_manufacturing_block:1;
- unsigned char has_guest_serialization:1;
- unsigned char has_global_parameters:1;
- unsigned char has_core_code:1;
- unsigned char has_core_config:1;
- unsigned char has_guest_code:1;
- unsigned char has_display_config:1;
- unsigned char f34_query7_b11__15:5;
- unsigned char f34_query7_b16__23;
- unsigned char f34_query7_b24__31;
- } __packed;
- unsigned char data[21];
- };
- };
- struct f34_v7_data0 {
- union {
- struct {
- unsigned char operation_status:5;
- unsigned char device_cfg_status:2;
- unsigned char bl_mode:1;
- } __packed;
- unsigned char data[1];
- };
- };
- struct f34_v7_data_1_5 {
- union {
- struct {
- unsigned char partition_id:5;
- unsigned char f34_data1_b5__7:3;
- unsigned char block_offset_7_0;
- unsigned char block_offset_15_8;
- unsigned char transfer_length_7_0;
- unsigned char transfer_length_15_8;
- unsigned char command;
- unsigned char payload_0;
- unsigned char payload_1;
- } __packed;
- unsigned char data[8];
- };
- };
- struct f34_v5v6_flash_properties {
- union {
- struct {
- unsigned char reg_map:1;
- unsigned char unlocked:1;
- unsigned char has_config_id:1;
- unsigned char has_pm_config:1;
- unsigned char has_bl_config:1;
- unsigned char has_disp_config:1;
- unsigned char has_ctrl1:1;
- unsigned char has_query4:1;
- } __packed;
- unsigned char data[1];
- };
- };
- struct f34_v5v6_flash_properties_2 {
- union {
- struct {
- unsigned char has_guest_code:1;
- unsigned char f34_query4_b1:1;
- unsigned char has_gesture_config:1;
- unsigned char has_force_config:1;
- unsigned char has_lockdown_data:1;
- unsigned char has_lcm_data:1;
- unsigned char has_oem_data:1;
- unsigned char f34_query4_b7:1;
- } __packed;
- unsigned char data[1];
- };
- };
- struct register_offset {
- unsigned char properties;
- unsigned char properties_2;
- unsigned char block_size;
- unsigned char block_count;
- unsigned char gc_block_count;
- unsigned char flash_status;
- unsigned char partition_id;
- unsigned char block_number;
- unsigned char transfer_length;
- unsigned char flash_cmd;
- unsigned char payload;
- };
- struct block_count {
- unsigned short ui_firmware;
- unsigned short ui_config;
- unsigned short dp_config;
- unsigned short pm_config;
- unsigned short fl_config;
- unsigned short bl_image;
- unsigned short bl_config;
- unsigned short utility_param;
- unsigned short lockdown;
- unsigned short guest_code;
- #ifdef SYNA_TDDI
- unsigned short tddi_force_config;
- unsigned short tddi_lockdown_data;
- unsigned short tddi_lcm_data;
- unsigned short tddi_oem_data;
- #endif
- unsigned short total_count;
- };
- struct physical_address {
- unsigned short ui_firmware;
- unsigned short ui_config;
- unsigned short dp_config;
- unsigned short pm_config;
- unsigned short fl_config;
- unsigned short bl_image;
- unsigned short bl_config;
- unsigned short utility_param;
- unsigned short lockdown;
- unsigned short guest_code;
- };
- struct container_descriptor {
- unsigned char content_checksum[4];
- unsigned char container_id[2];
- unsigned char minor_version;
- unsigned char major_version;
- unsigned char reserved_08;
- unsigned char reserved_09;
- unsigned char reserved_0a;
- unsigned char reserved_0b;
- unsigned char container_option_flags[4];
- unsigned char content_options_length[4];
- unsigned char content_options_address[4];
- unsigned char content_length[4];
- unsigned char content_address[4];
- };
- struct image_header_10 {
- unsigned char checksum[4];
- unsigned char reserved_04;
- unsigned char reserved_05;
- unsigned char minor_header_version;
- unsigned char major_header_version;
- unsigned char reserved_08;
- unsigned char reserved_09;
- unsigned char reserved_0a;
- unsigned char reserved_0b;
- unsigned char top_level_container_start_addr[4];
- };
- struct image_header_05_06 {
- /* 0x00 - 0x0f */
- unsigned char checksum[4];
- unsigned char reserved_04;
- unsigned char reserved_05;
- unsigned char options_firmware_id:1;
- unsigned char options_bootloader:1;
- unsigned char options_guest_code:1;
- unsigned char options_tddi:1;
- unsigned char options_reserved:4;
- unsigned char header_version;
- unsigned char firmware_size[4];
- unsigned char config_size[4];
- /* 0x10 - 0x1f */
- unsigned char product_id[PRODUCT_ID_SIZE];
- unsigned char package_id[2];
- unsigned char package_id_revision[2];
- unsigned char product_info[PRODUCT_INFO_SIZE];
- /* 0x20 - 0x2f */
- unsigned char bootloader_addr[4];
- unsigned char bootloader_size[4];
- unsigned char ui_addr[4];
- unsigned char ui_size[4];
- /* 0x30 - 0x3f */
- unsigned char ds_id[16];
- /* 0x40 - 0x4f */
- union {
- struct {
- unsigned char cstmr_product_id[PRODUCT_ID_SIZE];
- unsigned char reserved_4a_4f[6];
- };
- struct {
- unsigned char dsp_cfg_addr[4];
- unsigned char dsp_cfg_size[4];
- unsigned char reserved_48_4f[8];
- };
- };
- /* 0x50 - 0x53 */
- unsigned char firmware_id[4];
- };
- struct block_data {
- unsigned int size;
- const unsigned char *data;
- };
- struct image_metadata {
- bool contains_firmware_id;
- bool contains_bootloader;
- bool contains_guest_code;
- bool contains_disp_config;
- bool contains_perm_config;
- bool contains_flash_config;
- bool contains_utility_param;
- unsigned int firmware_id;
- unsigned int checksum;
- unsigned int bootloader_size;
- unsigned int disp_config_offset;
- unsigned char bl_version;
- unsigned char product_id[PRODUCT_ID_SIZE + 1];
- unsigned char cstmr_product_id[PRODUCT_ID_SIZE + 1];
- unsigned char utility_param_id[MAX_UTILITY_PARAMS];
- struct block_data bootloader;
- struct block_data utility;
- struct block_data ui_firmware;
- struct block_data ui_config;
- struct block_data dp_config;
- struct block_data pm_config;
- struct block_data fl_config;
- struct block_data bl_image;
- struct block_data bl_config;
- struct block_data utility_param[MAX_UTILITY_PARAMS];
- struct block_data lockdown;
- struct block_data guest_code;
- struct block_count blkcount;
- struct physical_address phyaddr;
- };
- struct synaptics_rmi4_fwu_handle {
- enum bl_version bl_version;
- bool initialized;
- bool in_bl_mode;
- bool in_ub_mode;
- bool bl_mode_device;
- bool force_update;
- bool do_lockdown;
- bool has_guest_code;
- #ifdef SYNA_TDDI
- bool has_force_config;
- bool has_lockdown_data;
- bool has_lcm_data;
- bool has_oem_data;
- #endif
- bool has_utility_param;
- bool new_partition_table;
- bool incompatible_partition_tables;
- bool write_bootloader;
- unsigned int data_pos;
- unsigned char *ext_data_source;
- unsigned char *read_config_buf;
- unsigned char intr_mask;
- unsigned char command;
- unsigned char bootloader_id[2];
- unsigned char config_id[32];
- unsigned char flash_status;
- unsigned char partitions;
- #ifdef F51_DISCRETE_FORCE
- unsigned char *cal_data;
- unsigned short cal_data_off;
- unsigned short cal_data_size;
- unsigned short cal_data_buf_size;
- unsigned short cal_packet_data_size;
- #endif
- unsigned short block_size;
- unsigned short config_size;
- unsigned short config_area;
- unsigned short config_block_count;
- unsigned short flash_config_length;
- unsigned short payload_length;
- unsigned short partition_table_bytes;
- unsigned short read_config_buf_size;
- const unsigned char *config_data;
- const unsigned char *image;
- unsigned char *image_name;
- unsigned int image_size;
- struct image_metadata img;
- struct register_offset off;
- struct block_count blkcount;
- struct physical_address phyaddr;
- struct f34_v5v6_flash_properties flash_properties;
- struct synaptics_rmi4_fn_desc f34_fd;
- struct synaptics_rmi4_fn_desc f35_fd;
- struct synaptics_rmi4_data *rmi4_data;
- struct workqueue_struct *fwu_workqueue;
- struct work_struct fwu_work;
- };
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static struct bin_attribute dev_attr_data = {
- .attr = {
- .name = "data",
- .mode = 0664,
- },
- .size = 0,
- .read = fwu_sysfs_show_image,
- .write = fwu_sysfs_store_image,
- };
- #endif
- static struct device_attribute attrs[] = {
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- __ATTR(dorecovery, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_do_recovery_store),
- __ATTR(doreflash, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_do_reflash_store),
- __ATTR(writeconfig, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_write_config_store),
- __ATTR(readconfig, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_read_config_store),
- __ATTR(configarea, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_config_area_store),
- __ATTR(imagename, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_image_name_store),
- __ATTR(imagesize, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_image_size_store),
- __ATTR(blocksize, 0444,
- fwu_sysfs_block_size_show,
- synaptics_rmi4_store_error),
- __ATTR(fwblockcount, 0444,
- fwu_sysfs_firmware_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(configblockcount, 0444,
- fwu_sysfs_configuration_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(dispconfigblockcount, 0444,
- fwu_sysfs_disp_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(permconfigblockcount, 0444,
- fwu_sysfs_perm_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(blconfigblockcount, 0444,
- fwu_sysfs_bl_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(uppblockcount, 0444,
- fwu_sysfs_utility_parameter_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(guestcodeblockcount, 0444,
- fwu_sysfs_guest_code_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(writeguestcode, 0220,
- synaptics_rmi4_show_error,
- fwu_sysfs_write_guest_code_store),
- #ifdef SYNA_TDDI
- __ATTR(lockdowncode, 0664,
- fwu_sysfs_read_lockdown_code_show,
- fwu_sysfs_write_lockdown_code_store),
- #endif
- #endif
- };
- static struct synaptics_rmi4_fwu_handle *fwu;
- DECLARE_COMPLETION(fwu_remove_complete);
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- DEFINE_MUTEX(fwu_sysfs_mutex);
- #endif
- static void calculate_checksum(unsigned short *data, unsigned long len,
- unsigned long *result)
- {
- unsigned long temp;
- unsigned long sum1 = 0xffff;
- unsigned long sum2 = 0xffff;
- *result = 0xffffffff;
- while (len--) {
- temp = *data;
- sum1 += temp;
- sum2 += sum1;
- sum1 = (sum1 & 0xffff) + (sum1 >> 16);
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- data++;
- }
- *result = sum2 << 16 | sum1;
- }
- static void convert_to_little_endian(unsigned char *dest, unsigned long src)
- {
- dest[0] = (unsigned char)(src & 0xff);
- dest[1] = (unsigned char)((src >> 8) & 0xff);
- dest[2] = (unsigned char)((src >> 16) & 0xff);
- dest[3] = (unsigned char)((src >> 24) & 0xff);
- }
- static unsigned int le_to_uint(const unsigned char *ptr)
- {
- return (unsigned int)ptr[0] +
- (unsigned int)ptr[1] * 0x100 +
- (unsigned int)ptr[2] * 0x10000 +
- (unsigned int)ptr[3] * 0x1000000;
- }
- #ifdef F51_DISCRETE_FORCE
- static int fwu_f51_force_data_init(void)
- {
- int retval;
- unsigned char query_count;
- unsigned char packet_info;
- unsigned char offset[2];
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- rmi4_data->f51_query_base_addr + 7,
- offset,
- sizeof(offset));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read force data offset\n",
- __func__);
- return retval;
- }
- fwu->cal_data_off = offset[0] | offset[1] << 8;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- rmi4_data->f51_query_base_addr,
- &query_count,
- sizeof(query_count));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read number of F51 query registers\n",
- __func__);
- return retval;
- }
- if (query_count >= 10) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- rmi4_data->f51_query_base_addr + 9,
- &packet_info,
- sizeof(packet_info));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read F51 packet register info\n",
- __func__);
- return retval;
- }
- if (packet_info & MASK_1BIT) {
- fwu->cal_packet_data_size = packet_info >> 1;
- fwu->cal_packet_data_size *= 2;
- } else {
- fwu->cal_packet_data_size = 0;
- }
- } else {
- fwu->cal_packet_data_size = 0;
- }
- fwu->cal_data_size = CAL_DATA_SIZE + fwu->cal_packet_data_size;
- if (fwu->cal_data_size > fwu->cal_data_buf_size) {
- kfree(fwu->cal_data);
- fwu->cal_data_buf_size = fwu->cal_data_size;
- fwu->cal_data = kmalloc(fwu->cal_data_buf_size, GFP_KERNEL);
- if (!fwu->cal_data) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for fwu->cal_data\n",
- __func__);
- fwu->cal_data_buf_size = 0;
- return -ENOMEM;
- }
- }
- return 0;
- }
- #endif
- static int fwu_allocate_read_config_buf(unsigned int count)
- {
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (count > fwu->read_config_buf_size) {
- kfree(fwu->read_config_buf);
- fwu->read_config_buf = kzalloc(count, GFP_KERNEL);
- if (!fwu->read_config_buf) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for fwu->read_config_buf\n",
- __func__);
- fwu->read_config_buf_size = 0;
- return -ENOMEM;
- }
- fwu->read_config_buf_size = count;
- }
- return 0;
- }
- static void fwu_compare_partition_tables(void)
- {
- fwu->incompatible_partition_tables = false;
- if (fwu->phyaddr.bl_image != fwu->img.phyaddr.bl_image)
- fwu->incompatible_partition_tables = true;
- else if (fwu->phyaddr.lockdown != fwu->img.phyaddr.lockdown)
- fwu->incompatible_partition_tables = true;
- else if (fwu->phyaddr.bl_config != fwu->img.phyaddr.bl_config)
- fwu->incompatible_partition_tables = true;
- else if (fwu->phyaddr.utility_param != fwu->img.phyaddr.utility_param)
- fwu->incompatible_partition_tables = true;
- if (fwu->bl_version == BL_V7) {
- if (fwu->phyaddr.fl_config != fwu->img.phyaddr.fl_config)
- fwu->incompatible_partition_tables = true;
- }
- fwu->new_partition_table = false;
- if (fwu->phyaddr.ui_firmware != fwu->img.phyaddr.ui_firmware)
- fwu->new_partition_table = true;
- else if (fwu->phyaddr.ui_config != fwu->img.phyaddr.ui_config)
- fwu->new_partition_table = true;
- if (fwu->flash_properties.has_disp_config) {
- if (fwu->phyaddr.dp_config != fwu->img.phyaddr.dp_config)
- fwu->new_partition_table = true;
- }
- if (fwu->has_guest_code) {
- if (fwu->phyaddr.guest_code != fwu->img.phyaddr.guest_code)
- fwu->new_partition_table = true;
- }
- }
- static void fwu_parse_partition_table(const unsigned char *partition_table,
- struct block_count *blkcount, struct physical_address *phyaddr)
- {
- unsigned char ii;
- unsigned char index;
- unsigned char offset;
- unsigned short partition_length;
- unsigned short physical_address;
- struct partition_table *ptable;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- for (ii = 0; ii < fwu->partitions; ii++) {
- index = ii * 8 + 2;
- ptable = (struct partition_table *)&partition_table[index];
- partition_length = ptable->partition_length_15_8 << 8 |
- ptable->partition_length_7_0;
- physical_address = ptable->start_physical_address_15_8 << 8 |
- ptable->start_physical_address_7_0;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Partition entry %d:\n",
- __func__, ii);
- for (offset = 0; offset < 8; offset++) {
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: 0x%02x\n",
- __func__,
- partition_table[index + offset]);
- }
- switch (ptable->partition_id) {
- case CORE_CODE_PARTITION:
- blkcount->ui_firmware = partition_length;
- phyaddr->ui_firmware = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Core code block count: %d\n",
- __func__, blkcount->ui_firmware);
- blkcount->total_count += partition_length;
- break;
- case CORE_CONFIG_PARTITION:
- blkcount->ui_config = partition_length;
- phyaddr->ui_config = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Core config block count: %d\n",
- __func__, blkcount->ui_config);
- blkcount->total_count += partition_length;
- break;
- case BOOTLOADER_PARTITION:
- blkcount->bl_image = partition_length;
- phyaddr->bl_image = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Bootloader block count: %d\n",
- __func__, blkcount->bl_image);
- blkcount->total_count += partition_length;
- break;
- case UTILITY_PARAMETER_PARTITION:
- blkcount->utility_param = partition_length;
- phyaddr->utility_param = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Utility parameter block count: %d\n",
- __func__, blkcount->utility_param);
- blkcount->total_count += partition_length;
- break;
- case DISPLAY_CONFIG_PARTITION:
- blkcount->dp_config = partition_length;
- phyaddr->dp_config = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Display config block count: %d\n",
- __func__, blkcount->dp_config);
- blkcount->total_count += partition_length;
- break;
- case FLASH_CONFIG_PARTITION:
- blkcount->fl_config = partition_length;
- phyaddr->fl_config = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Flash config block count: %d\n",
- __func__, blkcount->fl_config);
- blkcount->total_count += partition_length;
- break;
- case GUEST_CODE_PARTITION:
- blkcount->guest_code = partition_length;
- phyaddr->guest_code = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Guest code block count: %d\n",
- __func__, blkcount->guest_code);
- blkcount->total_count += partition_length;
- break;
- case GUEST_SERIALIZATION_PARTITION:
- blkcount->pm_config = partition_length;
- phyaddr->pm_config = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Guest serialization block count: %d\n",
- __func__, blkcount->pm_config);
- blkcount->total_count += partition_length;
- break;
- case GLOBAL_PARAMETERS_PARTITION:
- blkcount->bl_config = partition_length;
- phyaddr->bl_config = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Global parameters block count: %d\n",
- __func__, blkcount->bl_config);
- blkcount->total_count += partition_length;
- break;
- case DEVICE_CONFIG_PARTITION:
- blkcount->lockdown = partition_length;
- phyaddr->lockdown = physical_address;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Device config block count: %d\n",
- __func__, blkcount->lockdown);
- blkcount->total_count += partition_length;
- break;
- };
- }
- }
- static void fwu_parse_image_header_10_utility(const unsigned char *image)
- {
- unsigned char ii;
- unsigned char num_of_containers;
- unsigned int addr;
- unsigned int container_id;
- unsigned int length;
- const unsigned char *content;
- struct container_descriptor *descriptor;
- num_of_containers = fwu->img.utility.size / 4;
- for (ii = 0; ii < num_of_containers; ii++) {
- if (ii >= MAX_UTILITY_PARAMS)
- continue;
- addr = le_to_uint(fwu->img.utility.data + (ii * 4));
- descriptor = (struct container_descriptor *)(image + addr);
- container_id = descriptor->container_id[0] |
- descriptor->container_id[1] << 8;
- content = image + le_to_uint(descriptor->content_address);
- length = le_to_uint(descriptor->content_length);
- switch (container_id) {
- case UTILITY_PARAMETER_CONTAINER:
- fwu->img.utility_param[ii].data = content;
- fwu->img.utility_param[ii].size = length;
- fwu->img.utility_param_id[ii] = content[0];
- break;
- default:
- break;
- };
- }
- }
- static void fwu_parse_image_header_10_bootloader(const unsigned char *image)
- {
- unsigned char ii;
- unsigned char num_of_containers;
- unsigned int addr;
- unsigned int container_id;
- unsigned int length;
- const unsigned char *content;
- struct container_descriptor *descriptor;
- num_of_containers = (fwu->img.bootloader.size - 4) / 4;
- for (ii = 1; ii <= num_of_containers; ii++) {
- addr = le_to_uint(fwu->img.bootloader.data + (ii * 4));
- descriptor = (struct container_descriptor *)(image + addr);
- container_id = descriptor->container_id[0] |
- descriptor->container_id[1] << 8;
- content = image + le_to_uint(descriptor->content_address);
- length = le_to_uint(descriptor->content_length);
- switch (container_id) {
- case BL_IMAGE_CONTAINER:
- fwu->img.bl_image.data = content;
- fwu->img.bl_image.size = length;
- break;
- case BL_CONFIG_CONTAINER:
- case GLOBAL_PARAMETERS_CONTAINER:
- fwu->img.bl_config.data = content;
- fwu->img.bl_config.size = length;
- break;
- case BL_LOCKDOWN_INFO_CONTAINER:
- case DEVICE_CONFIG_CONTAINER:
- fwu->img.lockdown.data = content;
- fwu->img.lockdown.size = length;
- break;
- default:
- break;
- };
- }
- }
- static void fwu_parse_image_header_10(void)
- {
- unsigned char ii;
- unsigned char num_of_containers;
- unsigned int addr;
- unsigned int offset;
- unsigned int container_id;
- unsigned int length;
- const unsigned char *image;
- const unsigned char *content;
- struct container_descriptor *descriptor;
- struct image_header_10 *header;
- image = fwu->image;
- header = (struct image_header_10 *)image;
- fwu->img.checksum = le_to_uint(header->checksum);
- /* address of top level container */
- offset = le_to_uint(header->top_level_container_start_addr);
- descriptor = (struct container_descriptor *)(image + offset);
- /* address of top level container content */
- offset = le_to_uint(descriptor->content_address);
- num_of_containers = le_to_uint(descriptor->content_length) / 4;
- for (ii = 0; ii < num_of_containers; ii++) {
- addr = le_to_uint(image + offset);
- offset += 4;
- descriptor = (struct container_descriptor *)(image + addr);
- container_id = descriptor->container_id[0] |
- descriptor->container_id[1] << 8;
- content = image + le_to_uint(descriptor->content_address);
- length = le_to_uint(descriptor->content_length);
- switch (container_id) {
- case UI_CONTAINER:
- case CORE_CODE_CONTAINER:
- fwu->img.ui_firmware.data = content;
- fwu->img.ui_firmware.size = length;
- break;
- case UI_CONFIG_CONTAINER:
- case CORE_CONFIG_CONTAINER:
- fwu->img.ui_config.data = content;
- fwu->img.ui_config.size = length;
- break;
- case BL_CONTAINER:
- fwu->img.bl_version = *content;
- fwu->img.bootloader.data = content;
- fwu->img.bootloader.size = length;
- fwu_parse_image_header_10_bootloader(image);
- break;
- case UTILITY_CONTAINER:
- fwu->img.utility.data = content;
- fwu->img.utility.size = length;
- fwu_parse_image_header_10_utility(image);
- break;
- case GUEST_CODE_CONTAINER:
- fwu->img.contains_guest_code = true;
- fwu->img.guest_code.data = content;
- fwu->img.guest_code.size = length;
- break;
- case DISPLAY_CONFIG_CONTAINER:
- fwu->img.contains_disp_config = true;
- fwu->img.dp_config.data = content;
- fwu->img.dp_config.size = length;
- break;
- case PERMANENT_CONFIG_CONTAINER:
- case GUEST_SERIALIZATION_CONTAINER:
- fwu->img.contains_perm_config = true;
- fwu->img.pm_config.data = content;
- fwu->img.pm_config.size = length;
- break;
- case FLASH_CONFIG_CONTAINER:
- fwu->img.contains_flash_config = true;
- fwu->img.fl_config.data = content;
- fwu->img.fl_config.size = length;
- break;
- case GENERAL_INFORMATION_CONTAINER:
- fwu->img.contains_firmware_id = true;
- fwu->img.firmware_id = le_to_uint(content + 4);
- break;
- default:
- break;
- }
- }
- }
- static void fwu_parse_image_header_05_06(void)
- {
- int retval;
- const unsigned char *image;
- struct image_header_05_06 *header;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- image = fwu->image;
- header = (struct image_header_05_06 *)image;
- fwu->img.checksum = le_to_uint(header->checksum);
- fwu->img.bl_version = header->header_version;
- fwu->img.contains_bootloader = header->options_bootloader;
- if (fwu->img.contains_bootloader)
- fwu->img.bootloader_size = le_to_uint(header->bootloader_size);
- fwu->img.ui_firmware.size = le_to_uint(header->firmware_size);
- if (fwu->img.ui_firmware.size) {
- fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET;
- if (fwu->img.contains_bootloader)
- fwu->img.ui_firmware.data += fwu->img.bootloader_size;
- }
- if ((fwu->img.bl_version == BL_V6) && header->options_tddi)
- fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET;
- fwu->img.ui_config.size = le_to_uint(header->config_size);
- if (fwu->img.ui_config.size) {
- fwu->img.ui_config.data = fwu->img.ui_firmware.data +
- fwu->img.ui_firmware.size;
- }
- if (fwu->img.contains_bootloader || header->options_tddi)
- fwu->img.contains_disp_config = true;
- else
- fwu->img.contains_disp_config = false;
- if (fwu->img.contains_disp_config) {
- fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr);
- fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size);
- fwu->img.dp_config.data = image + fwu->img.disp_config_offset;
- } else {
- retval = secure_memcpy(fwu->img.cstmr_product_id,
- sizeof(fwu->img.cstmr_product_id),
- header->cstmr_product_id,
- sizeof(header->cstmr_product_id),
- PRODUCT_ID_SIZE);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy custom product ID string\n",
- __func__);
- }
- fwu->img.cstmr_product_id[PRODUCT_ID_SIZE] = 0;
- }
- fwu->img.contains_firmware_id = header->options_firmware_id;
- if (fwu->img.contains_firmware_id)
- fwu->img.firmware_id = le_to_uint(header->firmware_id);
- retval = secure_memcpy(fwu->img.product_id,
- sizeof(fwu->img.product_id),
- header->product_id,
- sizeof(header->product_id),
- PRODUCT_ID_SIZE);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy product ID string\n",
- __func__);
- }
- fwu->img.product_id[PRODUCT_ID_SIZE] = 0;
- fwu->img.lockdown.size = LOCKDOWN_SIZE;
- fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE;
- }
- static int fwu_parse_image_info(void)
- {
- struct image_header_10 *header;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- header = (struct image_header_10 *)fwu->image;
- memset(&fwu->img, 0x00, sizeof(fwu->img));
- switch (header->major_header_version) {
- case IMAGE_HEADER_VERSION_10:
- fwu_parse_image_header_10();
- break;
- case IMAGE_HEADER_VERSION_05:
- case IMAGE_HEADER_VERSION_06:
- fwu_parse_image_header_05_06();
- break;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Unsupported image file format (0x%02x)\n",
- __func__, header->major_header_version);
- return -EINVAL;
- }
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) {
- if (!fwu->img.contains_flash_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: No flash config found in firmware image\n",
- __func__);
- return -EINVAL;
- }
- fwu_parse_partition_table(fwu->img.fl_config.data,
- &fwu->img.blkcount, &fwu->img.phyaddr);
- if (fwu->img.blkcount.utility_param)
- fwu->img.contains_utility_param = true;
- fwu_compare_partition_tables();
- } else {
- fwu->new_partition_table = false;
- fwu->incompatible_partition_tables = false;
- }
- return 0;
- }
- static int fwu_read_flash_status(void)
- {
- int retval;
- unsigned char status;
- unsigned char command;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f34_fd.data_base_addr + fwu->off.flash_status,
- &status,
- sizeof(status));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash status\n",
- __func__);
- return retval;
- }
- fwu->in_bl_mode = status >> 7;
- if (fwu->bl_version == BL_V5)
- fwu->flash_status = (status >> 4) & MASK_3BIT;
- else if (fwu->bl_version == BL_V6)
- fwu->flash_status = status & MASK_3BIT;
- else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- fwu->flash_status = status & MASK_5BIT;
- if (fwu->write_bootloader)
- fwu->flash_status = 0x00;
- if (fwu->flash_status != 0x00) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Flash status = %d, command = 0x%02x\n",
- __func__, fwu->flash_status, fwu->command);
- }
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) {
- if (fwu->flash_status == 0x08)
- fwu->flash_status = 0x00;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f34_fd.data_base_addr + fwu->off.flash_cmd,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash command\n",
- __func__);
- return retval;
- }
- if (fwu->bl_version == BL_V5)
- fwu->command = command & MASK_4BIT;
- else if (fwu->bl_version == BL_V6)
- fwu->command = command & MASK_6BIT;
- else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- fwu->command = command;
- if (fwu->write_bootloader)
- fwu->command = 0x00;
- return 0;
- }
- static int fwu_wait_for_idle(int timeout_ms, bool poll)
- {
- int count = 0;
- int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- do {
- usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);
- count++;
- if (poll || (count == timeout_count))
- fwu_read_flash_status();
- if ((fwu->command == CMD_IDLE) && (fwu->flash_status == 0x00))
- return 0;
- } while (count < timeout_count);
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Timed out waiting for idle status\n",
- __func__);
- return -ETIMEDOUT;
- }
- static int fwu_write_f34_v7_command_single_transaction(unsigned char cmd)
- {
- int retval;
- unsigned char data_base;
- struct f34_v7_data_1_5 data_1_5;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- memset(data_1_5.data, 0x00, sizeof(data_1_5.data));
- switch (cmd) {
- case CMD_ERASE_ALL:
- data_1_5.partition_id = CORE_CODE_PARTITION;
- data_1_5.command = CMD_V7_ERASE_AP;
- break;
- case CMD_ERASE_UI_FIRMWARE:
- data_1_5.partition_id = CORE_CODE_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_BL_CONFIG:
- data_1_5.partition_id = GLOBAL_PARAMETERS_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_UI_CONFIG:
- data_1_5.partition_id = CORE_CONFIG_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_DISP_CONFIG:
- data_1_5.partition_id = DISPLAY_CONFIG_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_FLASH_CONFIG:
- data_1_5.partition_id = FLASH_CONFIG_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_GUEST_CODE:
- data_1_5.partition_id = GUEST_CODE_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_BOOTLOADER:
- data_1_5.partition_id = BOOTLOADER_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ERASE_UTILITY_PARAMETER:
- data_1_5.partition_id = UTILITY_PARAMETER_PARTITION;
- data_1_5.command = CMD_V7_ERASE;
- break;
- case CMD_ENABLE_FLASH_PROG:
- data_1_5.partition_id = BOOTLOADER_PARTITION;
- data_1_5.command = CMD_V7_ENTER_BL;
- break;
- };
- data_1_5.payload_0 = fwu->bootloader_id[0];
- data_1_5.payload_1 = fwu->bootloader_id[1];
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.partition_id,
- data_1_5.data,
- sizeof(data_1_5.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write single transaction command\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_write_f34_v7_command(unsigned char cmd)
- {
- int retval;
- unsigned char data_base;
- unsigned char command;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- switch (cmd) {
- case CMD_WRITE_FW:
- case CMD_WRITE_CONFIG:
- case CMD_WRITE_LOCKDOWN:
- case CMD_WRITE_GUEST_CODE:
- case CMD_WRITE_BOOTLOADER:
- case CMD_WRITE_UTILITY_PARAM:
- command = CMD_V7_WRITE;
- break;
- case CMD_READ_CONFIG:
- command = CMD_V7_READ;
- break;
- case CMD_ERASE_ALL:
- command = CMD_V7_ERASE_AP;
- break;
- case CMD_ERASE_UI_FIRMWARE:
- case CMD_ERASE_BL_CONFIG:
- case CMD_ERASE_UI_CONFIG:
- case CMD_ERASE_DISP_CONFIG:
- case CMD_ERASE_FLASH_CONFIG:
- case CMD_ERASE_GUEST_CODE:
- case CMD_ERASE_BOOTLOADER:
- case CMD_ERASE_UTILITY_PARAMETER:
- command = CMD_V7_ERASE;
- break;
- case CMD_ENABLE_FLASH_PROG:
- command = CMD_V7_ENTER_BL;
- break;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid command 0x%02x\n",
- __func__, cmd);
- return -EINVAL;
- };
- fwu->command = command;
- switch (cmd) {
- case CMD_ERASE_ALL:
- case CMD_ERASE_UI_FIRMWARE:
- case CMD_ERASE_BL_CONFIG:
- case CMD_ERASE_UI_CONFIG:
- case CMD_ERASE_DISP_CONFIG:
- case CMD_ERASE_FLASH_CONFIG:
- case CMD_ERASE_GUEST_CODE:
- case CMD_ERASE_BOOTLOADER:
- case CMD_ERASE_UTILITY_PARAMETER:
- case CMD_ENABLE_FLASH_PROG:
- retval = fwu_write_f34_v7_command_single_transaction(cmd);
- if (retval < 0)
- return retval;
- else
- return 0;
- default:
- break;
- };
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.flash_cmd,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write flash command\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_write_f34_v5v6_command(unsigned char cmd)
- {
- int retval;
- unsigned char data_base;
- unsigned char command;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- switch (cmd) {
- case CMD_IDLE:
- command = CMD_V5V6_IDLE;
- break;
- case CMD_WRITE_FW:
- command = CMD_V5V6_WRITE_FW;
- break;
- case CMD_WRITE_CONFIG:
- command = CMD_V5V6_WRITE_CONFIG;
- break;
- case CMD_WRITE_LOCKDOWN:
- command = CMD_V5V6_WRITE_LOCKDOWN;
- break;
- case CMD_WRITE_GUEST_CODE:
- command = CMD_V5V6_WRITE_GUEST_CODE;
- break;
- case CMD_READ_CONFIG:
- command = CMD_V5V6_READ_CONFIG;
- break;
- case CMD_ERASE_ALL:
- command = CMD_V5V6_ERASE_ALL;
- break;
- case CMD_ERASE_UI_CONFIG:
- command = CMD_V5V6_ERASE_UI_CONFIG;
- break;
- case CMD_ERASE_DISP_CONFIG:
- command = CMD_V5V6_ERASE_DISP_CONFIG;
- break;
- case CMD_ERASE_GUEST_CODE:
- command = CMD_V5V6_ERASE_GUEST_CODE;
- break;
- case CMD_ENABLE_FLASH_PROG:
- command = CMD_V5V6_ENABLE_FLASH_PROG;
- break;
- #ifdef SYNA_TDDI
- case CMD_ERASE_CHIP:
- command = CMD_V5V6_ERASE_CHIP;
- break;
- case CMD_ERASE_FORCE_CONFIG:
- command = CMD_V5V6_ERASE_FORCE_CONFIG;
- break;
- case CMD_READ_FORCE_CONFIG:
- command = CMD_V5V6_READ_FORCE_CONFIG;
- break;
- case CMD_WRITE_FORCE_CONFIG:
- command = CMD_V5V6_WRITE_CONFIG;
- break;
- case CMD_ERASE_LOCKDOWN_DATA:
- command = CMD_V5V6_ERASE_LOCKDOWN_DATA;
- break;
- case CMD_READ_LOCKDOWN_DATA:
- command = CMD_V5V6_READ_LOCKDOWN_DATA;
- break;
- case CMD_WRITE_LOCKDOWN_DATA:
- command = CMD_V5V6_WRITE_LOCKDOWN_DATA;
- break;
- case CMD_ERASE_LCM_DATA:
- command = CMD_V5V6_ERASE_LCM_DATA;
- break;
- case CMD_ERASE_OEM_DATA:
- command = CMD_V5V6_ERASE_OEM_DATA;
- break;
- #endif
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid command 0x%02x\n",
- __func__, cmd);
- return -EINVAL;
- }
- switch (cmd) {
- case CMD_ERASE_ALL:
- case CMD_ERASE_UI_CONFIG:
- case CMD_ERASE_DISP_CONFIG:
- case CMD_ERASE_GUEST_CODE:
- #ifdef SYNA_TDDI
- case CMD_ERASE_CHIP:
- case CMD_ERASE_FORCE_CONFIG:
- case CMD_ERASE_LOCKDOWN_DATA:
- case CMD_ERASE_LCM_DATA:
- case CMD_ERASE_OEM_DATA:
- #endif
- case CMD_ENABLE_FLASH_PROG:
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.payload,
- fwu->bootloader_id,
- sizeof(fwu->bootloader_id));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write bootloader ID\n",
- __func__);
- return retval;
- }
- break;
- default:
- break;
- };
- fwu->command = command;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.flash_cmd,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write command 0x%02x\n",
- __func__, command);
- return retval;
- }
- return 0;
- }
- static int fwu_write_f34_command(unsigned char cmd)
- {
- int retval;
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- retval = fwu_write_f34_v7_command(cmd);
- else
- retval = fwu_write_f34_v5v6_command(cmd);
- return retval;
- }
- static int fwu_write_f34_v7_partition_id(unsigned char cmd)
- {
- int retval;
- unsigned char data_base;
- unsigned char partition;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- switch (cmd) {
- case CMD_WRITE_FW:
- partition = CORE_CODE_PARTITION;
- break;
- case CMD_WRITE_CONFIG:
- case CMD_READ_CONFIG:
- if (fwu->config_area == UI_CONFIG_AREA)
- partition = CORE_CONFIG_PARTITION;
- else if (fwu->config_area == DP_CONFIG_AREA)
- partition = DISPLAY_CONFIG_PARTITION;
- else if (fwu->config_area == PM_CONFIG_AREA)
- partition = GUEST_SERIALIZATION_PARTITION;
- else if (fwu->config_area == BL_CONFIG_AREA)
- partition = GLOBAL_PARAMETERS_PARTITION;
- else if (fwu->config_area == FLASH_CONFIG_AREA)
- partition = FLASH_CONFIG_PARTITION;
- else if (fwu->config_area == UPP_AREA)
- partition = UTILITY_PARAMETER_PARTITION;
- break;
- case CMD_WRITE_LOCKDOWN:
- partition = DEVICE_CONFIG_PARTITION;
- break;
- case CMD_WRITE_GUEST_CODE:
- partition = GUEST_CODE_PARTITION;
- break;
- case CMD_WRITE_BOOTLOADER:
- partition = BOOTLOADER_PARTITION;
- break;
- case CMD_WRITE_UTILITY_PARAM:
- partition = UTILITY_PARAMETER_PARTITION;
- break;
- case CMD_ERASE_ALL:
- partition = CORE_CODE_PARTITION;
- break;
- case CMD_ERASE_BL_CONFIG:
- partition = GLOBAL_PARAMETERS_PARTITION;
- break;
- case CMD_ERASE_UI_CONFIG:
- partition = CORE_CONFIG_PARTITION;
- break;
- case CMD_ERASE_DISP_CONFIG:
- partition = DISPLAY_CONFIG_PARTITION;
- break;
- case CMD_ERASE_FLASH_CONFIG:
- partition = FLASH_CONFIG_PARTITION;
- break;
- case CMD_ERASE_GUEST_CODE:
- partition = GUEST_CODE_PARTITION;
- break;
- case CMD_ERASE_BOOTLOADER:
- partition = BOOTLOADER_PARTITION;
- break;
- case CMD_ENABLE_FLASH_PROG:
- partition = BOOTLOADER_PARTITION;
- break;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid command 0x%02x\n",
- __func__, cmd);
- return -EINVAL;
- };
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.partition_id,
- &partition,
- sizeof(partition));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write partition ID\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_write_f34_partition_id(unsigned char cmd)
- {
- int retval;
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- retval = fwu_write_f34_v7_partition_id(cmd);
- else
- retval = 0;
- return retval;
- }
- static int fwu_read_f34_v7_partition_table(unsigned char *partition_table)
- {
- int retval;
- unsigned char data_base;
- unsigned char length[2];
- unsigned short block_number = 0;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- fwu->config_area = FLASH_CONFIG_AREA;
- retval = fwu_write_f34_partition_id(CMD_READ_CONFIG);
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.block_number,
- (unsigned char *)&block_number,
- sizeof(block_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block number\n",
- __func__);
- return retval;
- }
- length[0] = (unsigned char)(fwu->flash_config_length & MASK_8BIT);
- length[1] = (unsigned char)(fwu->flash_config_length >> 8);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.transfer_length,
- length,
- sizeof(length));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write transfer length\n",
- __func__);
- return retval;
- }
- retval = fwu_write_f34_command(CMD_READ_CONFIG);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write command\n",
- __func__);
- return retval;
- }
- msleep(READ_CONFIG_WAIT_MS);
- retval = fwu_wait_for_idle(WRITE_WAIT_MS, true);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to wait for idle status\n",
- __func__);
- return retval;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- data_base + fwu->off.payload,
- partition_table,
- fwu->partition_table_bytes);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read block data\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_read_f34_v7_queries(void)
- {
- int retval;
- unsigned char ii;
- unsigned char query_base;
- unsigned char index;
- unsigned char offset;
- unsigned char *ptable;
- struct f34_v7_query_0 query_0;
- struct f34_v7_query_1_7 query_1_7;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- query_base = fwu->f34_fd.query_base_addr;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- query_base,
- query_0.data,
- sizeof(query_0.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read query 0\n",
- __func__);
- return retval;
- }
- offset = query_0.subpacket_1_size + 1;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- query_base + offset,
- query_1_7.data,
- sizeof(query_1_7.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read queries 1 to 7\n",
- __func__);
- return retval;
- }
- fwu->bootloader_id[0] = query_1_7.bl_minor_revision;
- fwu->bootloader_id[1] = query_1_7.bl_major_revision;
- if (fwu->bootloader_id[1] == BL_V8)
- fwu->bl_version = BL_V8;
- fwu->block_size = query_1_7.block_size_15_8 << 8 |
- query_1_7.block_size_7_0;
- fwu->flash_config_length = query_1_7.flash_config_length_15_8 << 8 |
- query_1_7.flash_config_length_7_0;
- fwu->payload_length = query_1_7.payload_length_15_8 << 8 |
- query_1_7.payload_length_7_0;
- fwu->off.flash_status = V7_FLASH_STATUS_OFFSET;
- fwu->off.partition_id = V7_PARTITION_ID_OFFSET;
- fwu->off.block_number = V7_BLOCK_NUMBER_OFFSET;
- fwu->off.transfer_length = V7_TRANSFER_LENGTH_OFFSET;
- fwu->off.flash_cmd = V7_COMMAND_OFFSET;
- fwu->off.payload = V7_PAYLOAD_OFFSET;
- index = sizeof(query_1_7.data) - V7_PARTITION_SUPPORT_BYTES;
- fwu->partitions = 0;
- for (offset = 0; offset < V7_PARTITION_SUPPORT_BYTES; offset++) {
- for (ii = 0; ii < 8; ii++) {
- if (query_1_7.data[index + offset] & (1 << ii))
- fwu->partitions++;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Supported partitions: 0x%02x\n",
- __func__, query_1_7.data[index + offset]);
- }
- fwu->partition_table_bytes = fwu->partitions * 8 + 2;
- ptable = kzalloc(fwu->partition_table_bytes, GFP_KERNEL);
- if (!ptable) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for partition table\n",
- __func__);
- return -ENOMEM;
- }
- retval = fwu_read_f34_v7_partition_table(ptable);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read partition table\n",
- __func__);
- kfree(ptable);
- return retval;
- }
- fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr);
- if (fwu->blkcount.dp_config)
- fwu->flash_properties.has_disp_config = 1;
- else
- fwu->flash_properties.has_disp_config = 0;
- if (fwu->blkcount.pm_config)
- fwu->flash_properties.has_pm_config = 1;
- else
- fwu->flash_properties.has_pm_config = 0;
- if (fwu->blkcount.bl_config)
- fwu->flash_properties.has_bl_config = 1;
- else
- fwu->flash_properties.has_bl_config = 0;
- if (fwu->blkcount.guest_code)
- fwu->has_guest_code = 1;
- else
- fwu->has_guest_code = 0;
- if (fwu->blkcount.utility_param)
- fwu->has_utility_param = 1;
- else
- fwu->has_utility_param = 0;
- kfree(ptable);
- return 0;
- }
- static int fwu_read_f34_v5v6_queries(void)
- {
- int retval;
- unsigned char count;
- unsigned char base;
- unsigned char offset;
- unsigned char buf[10];
- struct f34_v5v6_flash_properties_2 properties_2;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- base = fwu->f34_fd.query_base_addr;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + V5V6_BOOTLOADER_ID_OFFSET,
- fwu->bootloader_id,
- sizeof(fwu->bootloader_id));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read bootloader ID\n",
- __func__);
- return retval;
- }
- if (fwu->bl_version == BL_V5) {
- fwu->off.properties = V5_PROPERTIES_OFFSET;
- fwu->off.block_size = V5_BLOCK_SIZE_OFFSET;
- fwu->off.block_count = V5_BLOCK_COUNT_OFFSET;
- fwu->off.block_number = V5_BLOCK_NUMBER_OFFSET;
- fwu->off.payload = V5_BLOCK_DATA_OFFSET;
- } else if (fwu->bl_version == BL_V6) {
- fwu->off.properties = V6_PROPERTIES_OFFSET;
- fwu->off.properties_2 = V6_PROPERTIES_2_OFFSET;
- fwu->off.block_size = V6_BLOCK_SIZE_OFFSET;
- fwu->off.block_count = V6_BLOCK_COUNT_OFFSET;
- fwu->off.gc_block_count = V6_GUEST_CODE_BLOCK_COUNT_OFFSET;
- fwu->off.block_number = V6_BLOCK_NUMBER_OFFSET;
- fwu->off.payload = V6_BLOCK_DATA_OFFSET;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + fwu->off.block_size,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read block size info\n",
- __func__);
- return retval;
- }
- batohs(&fwu->block_size, &(buf[0]));
- if (fwu->bl_version == BL_V5) {
- fwu->off.flash_cmd = fwu->off.payload + fwu->block_size;
- fwu->off.flash_status = fwu->off.flash_cmd;
- } else if (fwu->bl_version == BL_V6) {
- fwu->off.flash_cmd = V6_FLASH_COMMAND_OFFSET;
- fwu->off.flash_status = V6_FLASH_STATUS_OFFSET;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + fwu->off.properties,
- fwu->flash_properties.data,
- sizeof(fwu->flash_properties.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash properties\n",
- __func__);
- return retval;
- }
- count = 4;
- if (fwu->flash_properties.has_pm_config)
- count += 2;
- if (fwu->flash_properties.has_bl_config)
- count += 2;
- if (fwu->flash_properties.has_disp_config)
- count += 2;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + fwu->off.block_count,
- buf,
- count);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read block count info\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.ui_firmware, &(buf[0]));
- batohs(&fwu->blkcount.ui_config, &(buf[2]));
- count = 4;
- if (fwu->flash_properties.has_pm_config) {
- batohs(&fwu->blkcount.pm_config, &(buf[count]));
- count += 2;
- }
- if (fwu->flash_properties.has_bl_config) {
- batohs(&fwu->blkcount.bl_config, &(buf[count]));
- count += 2;
- }
- if (fwu->flash_properties.has_disp_config)
- batohs(&fwu->blkcount.dp_config, &(buf[count]));
- fwu->has_guest_code = false;
- #ifdef SYNA_TDDI
- fwu->has_force_config = false;
- fwu->has_lockdown_data = false;
- fwu->has_lcm_data = false;
- fwu->has_oem_data = false;
- #endif
- if (fwu->flash_properties.has_query4) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + fwu->off.properties_2,
- properties_2.data,
- sizeof(properties_2.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash properties 2\n",
- __func__);
- return retval;
- }
- offset = fwu->off.properties_2 + 1;
- count = 0;
- if (properties_2.has_guest_code) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + offset + count,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read guest code block count\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.guest_code, &(buf[0]));
- count++;
- fwu->has_guest_code = true;
- }
- #ifdef SYNA_TDDI
- if (properties_2.has_force_config) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + offset + count,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read tddi force block count\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.tddi_force_config, &(buf[0]));
- count++;
- fwu->has_force_config = true;
- }
- if (properties_2.has_lockdown_data) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + offset + count,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read tddi lockdown block count\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.tddi_lockdown_data, &(buf[0]));
- count++;
- fwu->has_lockdown_data = true;
- }
- if (properties_2.has_lcm_data) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + offset + count,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read tddi lcm block count\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.tddi_lcm_data, &(buf[0]));
- count++;
- fwu->has_lcm_data = true;
- }
- if (properties_2.has_oem_data) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- base + offset + count,
- buf,
- 2);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read tddi oem block count\n",
- __func__);
- return retval;
- }
- batohs(&fwu->blkcount.tddi_oem_data, &(buf[0]));
- fwu->has_oem_data = true;
- }
- #endif
- }
- fwu->has_utility_param = false;
- return 0;
- }
- static int fwu_read_f34_queries(void)
- {
- int retval;
- memset(&fwu->blkcount, 0x00, sizeof(fwu->blkcount));
- memset(&fwu->phyaddr, 0x00, sizeof(fwu->phyaddr));
- if (fwu->bl_version == BL_V7)
- retval = fwu_read_f34_v7_queries();
- else
- retval = fwu_read_f34_v5v6_queries();
- return retval;
- }
- static int fwu_write_f34_v7_blocks(unsigned char *block_ptr,
- unsigned short block_cnt, unsigned char command)
- {
- int retval;
- unsigned char data_base;
- unsigned char length[2];
- unsigned short transfer;
- unsigned short remaining = block_cnt;
- unsigned short block_number = 0;
- unsigned short left_bytes;
- unsigned short write_size;
- unsigned short max_write_size;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- retval = fwu_write_f34_partition_id(command);
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.block_number,
- (unsigned char *)&block_number,
- sizeof(block_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block number\n",
- __func__);
- return retval;
- }
- do {
- if (remaining / fwu->payload_length)
- transfer = fwu->payload_length;
- else
- transfer = remaining;
- length[0] = (unsigned char)(transfer & MASK_8BIT);
- length[1] = (unsigned char)(transfer >> 8);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.transfer_length,
- length,
- sizeof(length));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write transfer length (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- retval = fwu_write_f34_command(command);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write command (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- #ifdef MAX_WRITE_SIZE
- max_write_size = MAX_WRITE_SIZE;
- if (max_write_size >= transfer * fwu->block_size)
- max_write_size = transfer * fwu->block_size;
- else if (max_write_size > fwu->block_size)
- max_write_size -= max_write_size % fwu->block_size;
- else
- max_write_size = fwu->block_size;
- #else
- max_write_size = transfer * fwu->block_size;
- #endif
- left_bytes = transfer * fwu->block_size;
- do {
- if (left_bytes / max_write_size)
- write_size = max_write_size;
- else
- write_size = left_bytes;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.payload,
- block_ptr,
- write_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block data (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- block_ptr += write_size;
- left_bytes -= write_size;
- } while (left_bytes);
- retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to wait for idle status (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- remaining -= transfer;
- } while (remaining);
- return 0;
- }
- static int fwu_write_f34_v5v6_blocks(unsigned char *block_ptr,
- unsigned short block_cnt, unsigned char command)
- {
- int retval;
- unsigned char data_base;
- unsigned char block_number[] = {0, 0};
- unsigned short blk;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- block_number[1] |= (fwu->config_area << 5);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.block_number,
- block_number,
- sizeof(block_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block number\n",
- __func__);
- return retval;
- }
- for (blk = 0; blk < block_cnt; blk++) {
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.payload,
- block_ptr,
- fwu->block_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block data (block %d)\n",
- __func__, blk);
- return retval;
- }
- retval = fwu_write_f34_command(command);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write command for block %d\n",
- __func__, blk);
- return retval;
- }
- retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to wait for idle status (block %d)\n",
- __func__, blk);
- return retval;
- }
- block_ptr += fwu->block_size;
- }
- return 0;
- }
- static int fwu_write_f34_blocks(unsigned char *block_ptr,
- unsigned short block_cnt, unsigned char cmd)
- {
- int retval;
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- retval = fwu_write_f34_v7_blocks(block_ptr, block_cnt, cmd);
- else
- retval = fwu_write_f34_v5v6_blocks(block_ptr, block_cnt, cmd);
- return retval;
- }
- static int fwu_read_f34_v7_blocks(unsigned short block_cnt,
- unsigned char command)
- {
- int retval;
- unsigned char data_base;
- unsigned char length[2];
- unsigned short transfer;
- unsigned short remaining = block_cnt;
- unsigned short block_number = 0;
- unsigned short index = 0;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- retval = fwu_write_f34_partition_id(command);
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.block_number,
- (unsigned char *)&block_number,
- sizeof(block_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block number\n",
- __func__);
- return retval;
- }
- do {
- if (remaining / fwu->payload_length)
- transfer = fwu->payload_length;
- else
- transfer = remaining;
- length[0] = (unsigned char)(transfer & MASK_8BIT);
- length[1] = (unsigned char)(transfer >> 8);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.transfer_length,
- length,
- sizeof(length));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write transfer length (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- retval = fwu_write_f34_command(command);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write command (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to wait for idle status (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- data_base + fwu->off.payload,
- &fwu->read_config_buf[index],
- transfer * fwu->block_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read block data (remaining = %d)\n",
- __func__, remaining);
- return retval;
- }
- index += (transfer * fwu->block_size);
- remaining -= transfer;
- } while (remaining);
- return 0;
- }
- static int fwu_read_f34_v5v6_blocks(unsigned short block_cnt,
- unsigned char command)
- {
- int retval;
- unsigned char data_base;
- unsigned char block_number[] = {0, 0};
- unsigned short blk;
- unsigned short index = 0;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f34_fd.data_base_addr;
- block_number[1] |= (fwu->config_area << 5);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- data_base + fwu->off.block_number,
- block_number,
- sizeof(block_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write block number\n",
- __func__);
- return retval;
- }
- for (blk = 0; blk < block_cnt; blk++) {
- retval = fwu_write_f34_command(command);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write read config command\n",
- __func__);
- return retval;
- }
- retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to wait for idle status\n",
- __func__);
- return retval;
- }
- retval = synaptics_rmi4_reg_read(rmi4_data,
- data_base + fwu->off.payload,
- &fwu->read_config_buf[index],
- fwu->block_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read block data (block %d)\n",
- __func__, blk);
- return retval;
- }
- index += fwu->block_size;
- }
- return 0;
- }
- static int fwu_read_f34_blocks(unsigned short block_cnt, unsigned char cmd)
- {
- int retval;
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- retval = fwu_read_f34_v7_blocks(block_cnt, cmd);
- else
- retval = fwu_read_f34_v5v6_blocks(block_cnt, cmd);
- return retval;
- }
- static int fwu_get_image_firmware_id(unsigned int *fw_id)
- {
- int retval;
- unsigned char index = 0;
- char *strptr;
- char *firmware_id;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (fwu->img.contains_firmware_id) {
- *fw_id = fwu->img.firmware_id;
- } else {
- strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN);
- if (!strptr) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: No valid PR number (PRxxxxxxx) found in image file name (%s)\n",
- __func__, fwu->image_name);
- return -EINVAL;
- }
- strptr += 2;
- firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL);
- if (!firmware_id) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for firmware_id\n",
- __func__);
- return -ENOMEM;
- }
- while (strptr[index] >= '0' && strptr[index] <= '9') {
- firmware_id[index] = strptr[index];
- index++;
- if (index == MAX_FIRMWARE_ID_LEN - 1)
- break;
- }
- retval = sstrtoul(firmware_id, 10, (unsigned long *)fw_id);
- kfree(firmware_id);
- if (retval) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to obtain image firmware ID\n",
- __func__);
- return -EINVAL;
- }
- }
- return 0;
- }
- static int fwu_get_device_config_id(void)
- {
- int retval;
- unsigned char config_id_size;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- config_id_size = V7_CONFIG_ID_SIZE;
- else
- config_id_size = V5V6_CONFIG_ID_SIZE;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f34_fd.ctrl_base_addr,
- fwu->config_id,
- config_id_size);
- if (retval < 0)
- return retval;
- return 0;
- }
- static enum flash_area fwu_go_nogo(void)
- {
- int retval;
- enum flash_area flash_area = NONE;
- unsigned char ii;
- unsigned char config_id_size;
- unsigned int device_fw_id;
- unsigned int image_fw_id;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (fwu->force_update) {
- flash_area = UI_FIRMWARE;
- goto exit;
- }
- /* Update both UI and config if device is in bootloader mode */
- if (fwu->bl_mode_device) {
- flash_area = UI_FIRMWARE;
- goto exit;
- }
- /* Get device firmware ID */
- device_fw_id = rmi4_data->firmware_id;
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device firmware ID = %d\n",
- __func__, device_fw_id);
- /* Get image firmware ID */
- retval = fwu_get_image_firmware_id(&image_fw_id);
- if (retval < 0) {
- flash_area = NONE;
- goto exit;
- }
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Image firmware ID = %d\n",
- __func__, image_fw_id);
- if (image_fw_id > device_fw_id) {
- flash_area = UI_FIRMWARE;
- goto exit;
- } else if (image_fw_id < device_fw_id) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Image firmware ID older than device firmware ID\n",
- __func__);
- flash_area = NONE;
- goto exit;
- }
- /* Get device config ID */
- retval = fwu_get_device_config_id();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read device config ID\n",
- __func__);
- flash_area = NONE;
- goto exit;
- }
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- config_id_size = V7_CONFIG_ID_SIZE;
- else
- config_id_size = V5V6_CONFIG_ID_SIZE;
- for (ii = 0; ii < config_id_size; ii++) {
- if (fwu->img.ui_config.data[ii] > fwu->config_id[ii]) {
- flash_area = UI_CONFIG;
- goto exit;
- } else if (fwu->img.ui_config.data[ii] < fwu->config_id[ii]) {
- flash_area = NONE;
- goto exit;
- }
- }
- flash_area = NONE;
- exit:
- if (flash_area == NONE) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: No need to do reflash\n",
- __func__);
- } else {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Updating %s\n",
- __func__,
- flash_area == UI_FIRMWARE ?
- "UI firmware and config" :
- "UI config only");
- }
- return flash_area;
- }
- static int fwu_scan_pdt(void)
- {
- int retval;
- unsigned char ii;
- unsigned char intr_count = 0;
- unsigned char intr_off;
- unsigned char intr_src;
- unsigned short addr;
- bool f01found = false;
- bool f34found = false;
- bool f35found = false;
- struct synaptics_rmi4_fn_desc rmi_fd;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- fwu->in_ub_mode = false;
- for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- addr,
- (unsigned char *)&rmi_fd,
- sizeof(rmi_fd));
- if (retval < 0)
- return retval;
- if (rmi_fd.fn_number) {
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Found F%02x\n",
- __func__, rmi_fd.fn_number);
- switch (rmi_fd.fn_number) {
- case SYNAPTICS_RMI4_F01:
- f01found = true;
- rmi4_data->f01_query_base_addr =
- rmi_fd.query_base_addr;
- rmi4_data->f01_ctrl_base_addr =
- rmi_fd.ctrl_base_addr;
- rmi4_data->f01_data_base_addr =
- rmi_fd.data_base_addr;
- rmi4_data->f01_cmd_base_addr =
- rmi_fd.cmd_base_addr;
- break;
- case SYNAPTICS_RMI4_F34:
- f34found = true;
- fwu->f34_fd.query_base_addr =
- rmi_fd.query_base_addr;
- fwu->f34_fd.ctrl_base_addr =
- rmi_fd.ctrl_base_addr;
- fwu->f34_fd.data_base_addr =
- rmi_fd.data_base_addr;
- switch (rmi_fd.fn_version) {
- case F34_V0:
- fwu->bl_version = BL_V5;
- break;
- case F34_V1:
- fwu->bl_version = BL_V6;
- break;
- case F34_V2:
- fwu->bl_version = BL_V7;
- break;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Unrecognized F34 version\n",
- __func__);
- return -EINVAL;
- }
- fwu->intr_mask = 0;
- intr_src = rmi_fd.intr_src_count;
- intr_off = intr_count % 8;
- for (ii = intr_off;
- ii < (intr_src + intr_off);
- ii++) {
- fwu->intr_mask |= 1 << ii;
- }
- break;
- case SYNAPTICS_RMI4_F35:
- f35found = true;
- fwu->f35_fd.query_base_addr =
- rmi_fd.query_base_addr;
- fwu->f35_fd.ctrl_base_addr =
- rmi_fd.ctrl_base_addr;
- fwu->f35_fd.data_base_addr =
- rmi_fd.data_base_addr;
- fwu->f35_fd.cmd_base_addr =
- rmi_fd.cmd_base_addr;
- break;
- }
- } else {
- break;
- }
- intr_count += rmi_fd.intr_src_count;
- }
- if (!f01found || !f34found) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to find both F01 and F34\n",
- __func__);
- if (!f35found) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to find F35\n",
- __func__);
- return -EINVAL;
- } else {
- fwu->in_ub_mode = true;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: In microbootloader mode\n",
- __func__);
- fwu_recovery_check_status();
- return 0;
- }
- }
- rmi4_data->intr_mask[0] |= fwu->intr_mask;
- addr = rmi4_data->f01_ctrl_base_addr + 1;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- addr,
- &(rmi4_data->intr_mask[0]),
- sizeof(rmi4_data->intr_mask[0]));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to set interrupt enable bit\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_enter_flash_prog(void)
- {
- int retval;
- struct f01_device_control f01_device_control;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_read_flash_status();
- if (retval < 0)
- return retval;
- if (fwu->in_bl_mode)
- return 0;
- retval = rmi4_data->irq_enable(rmi4_data, false, true);
- if (retval < 0)
- return retval;
- msleep(INT_DISABLE_WAIT_MS);
- retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
- if (retval < 0)
- return retval;
- retval = fwu_wait_for_idle(ENABLE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- if (!fwu->in_bl_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: BL mode not entered\n",
- __func__);
- return -EINVAL;
- }
- if (rmi4_data->hw_if->bl_hw_init) {
- retval = rmi4_data->hw_if->bl_hw_init(rmi4_data);
- if (retval < 0)
- return retval;
- }
- retval = fwu_scan_pdt();
- if (retval < 0)
- return retval;
- retval = fwu_read_f34_queries();
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- f01_device_control.data,
- sizeof(f01_device_control.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read F01 device control\n",
- __func__);
- return retval;
- }
- f01_device_control.nosleep = true;
- f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- f01_device_control.data,
- sizeof(f01_device_control.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write F01 device control\n",
- __func__);
- return retval;
- }
- msleep(ENTER_FLASH_PROG_WAIT_MS);
- return retval;
- }
- static int fwu_check_ui_firmware_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.ui_firmware.size / fwu->block_size;
- if (block_count != fwu->blkcount.ui_firmware) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: UI firmware size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- static int fwu_check_ui_configuration_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.ui_config.size / fwu->block_size;
- if (block_count != fwu->blkcount.ui_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: UI configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- static int fwu_check_dp_configuration_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.dp_config.size / fwu->block_size;
- if (block_count != fwu->blkcount.dp_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Display configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static int fwu_check_pm_configuration_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.pm_config.size / fwu->block_size;
- if (block_count != fwu->blkcount.pm_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Permanent configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- #endif
- static int fwu_check_bl_configuration_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.bl_config.size / fwu->block_size;
- if (block_count != fwu->blkcount.bl_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Bootloader configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- static int fwu_check_guest_code_size(void)
- {
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->img.guest_code.size / fwu->block_size;
- if (block_count != fwu->blkcount.guest_code) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Guest code size mismatch\n",
- __func__);
- return -EINVAL;
- }
- return 0;
- }
- static int fwu_erase_configuration(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_UI_CONFIG);
- if (retval < 0)
- return retval;
- break;
- case DP_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
- if (retval < 0)
- return retval;
- break;
- case BL_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
- if (retval < 0)
- return retval;
- break;
- case FLASH_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_FLASH_CONFIG);
- if (retval < 0)
- return retval;
- break;
- case UPP_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_UTILITY_PARAMETER);
- if (retval < 0)
- return retval;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid config area\n",
- __func__);
- return -EINVAL;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase command written\n",
- __func__);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- return retval;
- }
- static int fwu_erase_bootloader(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_write_f34_command(CMD_ERASE_BOOTLOADER);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase command written\n",
- __func__);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- return 0;
- }
- #ifdef SYNA_TDDI
- static int fwu_erase_lockdown_data(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_write_f34_command(CMD_ERASE_LOCKDOWN_DATA);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase command written\n",
- __func__);
- msleep(100);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- return 0;
- }
- #endif
- static int fwu_erase_guest_code(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_write_f34_command(CMD_ERASE_GUEST_CODE);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase command written\n",
- __func__);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- return 0;
- }
- static int fwu_erase_all(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (fwu->bl_version == BL_V7) {
- retval = fwu_write_f34_command(CMD_ERASE_UI_FIRMWARE);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase command written\n",
- __func__);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- fwu->config_area = UI_CONFIG_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- } else {
- retval = fwu_write_f34_command(CMD_ERASE_ALL);
- if (retval < 0)
- return retval;
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Erase all command written\n",
- __func__);
- retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
- if (!(fwu->bl_version == BL_V8 &&
- fwu->flash_status == BAD_PARTITION_TABLE)) {
- if (retval < 0)
- return retval;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Idle status detected\n",
- __func__);
- if (fwu->bl_version == BL_V8)
- return 0;
- }
- if (fwu->flash_properties.has_disp_config) {
- fwu->config_area = DP_CONFIG_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- }
- if (fwu->has_guest_code) {
- retval = fwu_erase_guest_code();
- if (retval < 0)
- return retval;
- }
- return 0;
- }
- static int fwu_write_firmware(void)
- {
- unsigned short firmware_block_count;
- firmware_block_count = fwu->img.ui_firmware.size / fwu->block_size;
- return fwu_write_f34_blocks((unsigned char *)fwu->img.ui_firmware.data,
- firmware_block_count, CMD_WRITE_FW);
- }
- static int fwu_write_bootloader(void)
- {
- int retval;
- unsigned short bootloader_block_count;
- bootloader_block_count = fwu->img.bl_image.size / fwu->block_size;
- fwu->write_bootloader = true;
- retval = fwu_write_f34_blocks((unsigned char *)fwu->img.bl_image.data,
- bootloader_block_count, CMD_WRITE_BOOTLOADER);
- fwu->write_bootloader = false;
- return retval;
- }
- static int fwu_write_utility_parameter(void)
- {
- int retval;
- unsigned char ii;
- unsigned char checksum_array[4];
- unsigned char *pbuf;
- unsigned short remaining_size;
- unsigned short utility_param_size;
- unsigned long checksum;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- utility_param_size = fwu->blkcount.utility_param * fwu->block_size;
- retval = fwu_allocate_read_config_buf(utility_param_size);
- if (retval < 0)
- return retval;
- memset(fwu->read_config_buf, 0x00, utility_param_size);
- pbuf = fwu->read_config_buf;
- remaining_size = utility_param_size - 4;
- for (ii = 0; ii < MAX_UTILITY_PARAMS; ii++) {
- if (fwu->img.utility_param_id[ii] == UNUSED)
- continue;
- #ifdef F51_DISCRETE_FORCE
- if (fwu->img.utility_param_id[ii] == FORCE_PARAMETER) {
- if (fwu->bl_mode_device) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device in bootloader mode, skipping calibration data restoration\n",
- __func__);
- goto image_param;
- }
- retval = secure_memcpy(&(pbuf[4]),
- remaining_size - 4,
- fwu->cal_data,
- fwu->cal_data_buf_size,
- fwu->cal_data_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy force calibration data\n",
- __func__);
- return retval;
- }
- pbuf[0] = FORCE_PARAMETER;
- pbuf[1] = 0x00;
- pbuf[2] = (4 + fwu->cal_data_size) / 2;
- pbuf += (fwu->cal_data_size + 4);
- remaining_size -= (fwu->cal_data_size + 4);
- continue;
- }
- image_param:
- #endif
- retval = secure_memcpy(pbuf,
- remaining_size,
- fwu->img.utility_param[ii].data,
- fwu->img.utility_param[ii].size,
- fwu->img.utility_param[ii].size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy utility parameter data\n",
- __func__);
- return retval;
- }
- pbuf += fwu->img.utility_param[ii].size;
- remaining_size -= fwu->img.utility_param[ii].size;
- }
- calculate_checksum((unsigned short *)fwu->read_config_buf,
- ((utility_param_size - 4) / 2),
- &checksum);
- convert_to_little_endian(checksum_array, checksum);
- fwu->read_config_buf[utility_param_size - 4] = checksum_array[0];
- fwu->read_config_buf[utility_param_size - 3] = checksum_array[1];
- fwu->read_config_buf[utility_param_size - 2] = checksum_array[2];
- fwu->read_config_buf[utility_param_size - 1] = checksum_array[3];
- retval = fwu_write_f34_blocks((unsigned char *)fwu->read_config_buf,
- fwu->blkcount.utility_param, CMD_WRITE_UTILITY_PARAM);
- if (retval < 0)
- return retval;
- return 0;
- }
- static int fwu_write_configuration(void)
- {
- return fwu_write_f34_blocks((unsigned char *)fwu->config_data,
- fwu->config_block_count, CMD_WRITE_CONFIG);
- }
- static int fwu_write_ui_configuration(void)
- {
- fwu->config_area = UI_CONFIG_AREA;
- fwu->config_data = fwu->img.ui_config.data;
- fwu->config_size = fwu->img.ui_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- return fwu_write_configuration();
- }
- static int fwu_write_dp_configuration(void)
- {
- fwu->config_area = DP_CONFIG_AREA;
- fwu->config_data = fwu->img.dp_config.data;
- fwu->config_size = fwu->img.dp_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- return fwu_write_configuration();
- }
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static int fwu_write_pm_configuration(void)
- {
- fwu->config_area = PM_CONFIG_AREA;
- fwu->config_data = fwu->img.pm_config.data;
- fwu->config_size = fwu->img.pm_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- return fwu_write_configuration();
- }
- #ifdef SYNA_TDDI
- static int fwu_write_tddi_lockdown_data(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_write_f34_blocks(fwu->read_config_buf,
- fwu->blkcount.tddi_lockdown_data,
- CMD_WRITE_LOCKDOWN_DATA);
- if (retval < 0)
- return retval;
- rmi4_data->reset_device(rmi4_data, false);
- return 0;
- }
- #endif
- #endif
- static int fwu_write_flash_configuration(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- fwu->config_area = FLASH_CONFIG_AREA;
- fwu->config_data = fwu->img.fl_config.data;
- fwu->config_size = fwu->img.fl_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- if (fwu->config_block_count != fwu->blkcount.fl_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Flash configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- rmi4_data->reset_device(rmi4_data, false);
- return 0;
- }
- static int fwu_write_guest_code(void)
- {
- int retval;
- unsigned short guest_code_block_count;
- guest_code_block_count = fwu->img.guest_code.size / fwu->block_size;
- retval = fwu_write_f34_blocks((unsigned char *)fwu->img.guest_code.data,
- guest_code_block_count, CMD_WRITE_GUEST_CODE);
- if (retval < 0)
- return retval;
- return 0;
- }
- static int fwu_write_lockdown(void)
- {
- unsigned short lockdown_block_count;
- lockdown_block_count = fwu->img.lockdown.size / fwu->block_size;
- return fwu_write_f34_blocks((unsigned char *)fwu->img.lockdown.data,
- lockdown_block_count, CMD_WRITE_LOCKDOWN);
- }
- static int fwu_write_partition_table_v8(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- fwu->config_area = FLASH_CONFIG_AREA;
- fwu->config_data = fwu->img.fl_config.data;
- fwu->config_size = fwu->img.fl_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- if (fwu->config_block_count != fwu->blkcount.fl_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Flash configuration size mismatch\n",
- __func__);
- return -EINVAL;
- }
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- rmi4_data->reset_device(rmi4_data, false);
- return 0;
- }
- static int fwu_write_partition_table_v7(void)
- {
- int retval;
- unsigned short block_count;
- block_count = fwu->blkcount.bl_config;
- fwu->config_area = BL_CONFIG_AREA;
- fwu->config_size = fwu->block_size * block_count;
- retval = fwu_allocate_read_config_buf(fwu->config_size);
- if (retval < 0)
- return retval;
- retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG);
- if (retval < 0)
- return retval;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- retval = fwu_write_flash_configuration();
- if (retval < 0)
- return retval;
- fwu->config_area = BL_CONFIG_AREA;
- fwu->config_data = fwu->read_config_buf;
- fwu->config_size = fwu->img.bl_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- return 0;
- }
- static int fwu_write_bl_area_v7(void)
- {
- int retval;
- bool has_utility_param;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- has_utility_param = fwu->has_utility_param;
- if (fwu->has_utility_param) {
- fwu->config_area = UPP_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- }
- fwu->config_area = BL_CONFIG_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- fwu->config_area = FLASH_CONFIG_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- retval = fwu_erase_bootloader();
- if (retval < 0)
- return retval;
- retval = fwu_write_bootloader();
- if (retval < 0)
- return retval;
- msleep(rmi4_data->hw_if->board_data->reset_delay_ms);
- rmi4_data->reset_device(rmi4_data, false);
- fwu->config_area = FLASH_CONFIG_AREA;
- fwu->config_data = fwu->img.fl_config.data;
- fwu->config_size = fwu->img.fl_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- rmi4_data->reset_device(rmi4_data, false);
- fwu->config_area = BL_CONFIG_AREA;
- fwu->config_data = fwu->img.bl_config.data;
- fwu->config_size = fwu->img.bl_config.size;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- if (fwu->img.contains_utility_param) {
- retval = fwu_write_utility_parameter();
- if (retval < 0)
- return retval;
- }
- return 0;
- }
- static int fwu_do_reflash(void)
- {
- int retval;
- bool do_bl_update = false;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!fwu->new_partition_table) {
- retval = fwu_check_ui_firmware_size();
- if (retval < 0)
- return retval;
- retval = fwu_check_ui_configuration_size();
- if (retval < 0)
- return retval;
- if (fwu->flash_properties.has_disp_config &&
- fwu->img.contains_disp_config) {
- retval = fwu_check_dp_configuration_size();
- if (retval < 0)
- return retval;
- }
- if (fwu->has_guest_code && fwu->img.contains_guest_code) {
- retval = fwu_check_guest_code_size();
- if (retval < 0)
- return retval;
- }
- } else if (fwu->bl_version == BL_V7) {
- retval = fwu_check_bl_configuration_size();
- if (retval < 0)
- return retval;
- }
- if (!fwu->has_utility_param && fwu->img.contains_utility_param) {
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- do_bl_update = true;
- }
- if (fwu->has_utility_param && !fwu->img.contains_utility_param) {
- if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
- do_bl_update = true;
- }
- if (!do_bl_update && fwu->incompatible_partition_tables) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Incompatible partition tables\n",
- __func__);
- return -EINVAL;
- } else if (!do_bl_update && fwu->new_partition_table) {
- if (!fwu->force_update) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Partition table mismatch\n",
- __func__);
- return -EINVAL;
- }
- }
- retval = fwu_erase_all();
- if (retval < 0)
- return retval;
- if (do_bl_update) {
- retval = fwu_write_bl_area_v7();
- if (retval < 0)
- return retval;
- pr_notice("%s: Bootloader area programmed\n", __func__);
- } else if (fwu->bl_version == BL_V7 && fwu->new_partition_table) {
- retval = fwu_write_partition_table_v7();
- if (retval < 0)
- return retval;
- pr_notice("%s: Partition table programmed\n", __func__);
- } else if (fwu->bl_version == BL_V8) {
- retval = fwu_write_partition_table_v8();
- if (retval < 0)
- return retval;
- pr_notice("%s: Partition table programmed\n", __func__);
- }
- fwu->config_area = UI_CONFIG_AREA;
- if (fwu->flash_properties.has_disp_config &&
- fwu->img.contains_disp_config) {
- retval = fwu_write_dp_configuration();
- if (retval < 0)
- return retval;
- pr_notice("%s: Display configuration programmed\n", __func__);
- }
- retval = fwu_write_ui_configuration();
- if (retval < 0)
- return retval;
- pr_notice("%s: Configuration programmed\n", __func__);
- if (fwu->has_guest_code && fwu->img.contains_guest_code) {
- retval = fwu_write_guest_code();
- if (retval < 0)
- return retval;
- pr_notice("%s: Guest code programmed\n", __func__);
- }
- retval = fwu_write_firmware();
- if (retval < 0)
- return retval;
- pr_notice("%s: Firmware programmed\n", __func__);
- return retval;
- }
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static int fwu_do_read_config(void)
- {
- int retval;
- unsigned short block_count;
- unsigned short config_area;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- block_count = fwu->blkcount.ui_config;
- break;
- case DP_CONFIG_AREA:
- if (!fwu->flash_properties.has_disp_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Display configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.dp_config;
- break;
- case PM_CONFIG_AREA:
- if (!fwu->flash_properties.has_pm_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Permanent configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.pm_config;
- break;
- case BL_CONFIG_AREA:
- if (!fwu->flash_properties.has_bl_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Bootloader configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.bl_config;
- break;
- case UPP_AREA:
- if (!fwu->has_utility_param) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Utility parameter not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.utility_param;
- break;
- #ifdef SYNA_TDDI
- case TDDI_FORCE_CONFIG_AREA:
- if (!fwu->has_force_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: force configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.tddi_force_config;
- break;
- case TDDI_OEM_DATA_AREA:
- if (!fwu->has_oem_data) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: oem data not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.tddi_oem_data;
- break;
- case TDDI_LCM_DATA_AREA:
- if (!fwu->has_lcm_data) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: lcm data not supported\n",
- __func__);
- return -EINVAL;
- }
- block_count = fwu->blkcount.tddi_lcm_data;
- break;
- #endif
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid config area\n",
- __func__);
- return -EINVAL;
- }
- if (block_count == 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Invalid block count\n",
- __func__);
- return -EINVAL;
- }
- mutex_lock(&rmi4_data->rmi4_exp_init_mutex);
- if (fwu->bl_version == BL_V5 || fwu->bl_version == BL_V6) {
- config_area = fwu->config_area;
- retval = fwu_enter_flash_prog();
- fwu->config_area = config_area;
- if (retval < 0)
- goto exit;
- }
- fwu->config_size = fwu->block_size * block_count;
- retval = fwu_allocate_read_config_buf(fwu->config_size);
- if (retval < 0)
- goto exit;
- retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG);
- exit:
- if (fwu->bl_version == BL_V5 || fwu->bl_version == BL_V6)
- rmi4_data->reset_device(rmi4_data, false);
- mutex_unlock(&rmi4_data->rmi4_exp_init_mutex);
- return retval;
- }
- #ifdef SYNA_TDDI
- static int fwu_do_read_tddi_lockdown_data(void)
- {
- int retval = -EINVAL;
- unsigned short block_count;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->blkcount.tddi_lockdown_data;
- fwu->config_size = fwu->block_size * block_count;
- if (fwu->bl_version != BL_V6) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not support lockdown data in bl v.%d\n",
- __func__,
- fwu->bl_version);
- goto exit;
- } else if (!fwu->has_lockdown_data) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not support lockdown data\n", __func__);
- goto exit;
- }
- kfree(fwu->read_config_buf);
- fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
- if (!fwu->read_config_buf) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for fwu->read_config_buf\n",
- __func__);
- fwu->read_config_buf_size = 0;
- retval = -ENOMEM;
- goto exit;
- }
- fwu->read_config_buf_size = fwu->config_size;
- retval = fwu_read_f34_blocks(block_count, CMD_READ_LOCKDOWN_DATA);
- exit:
- return retval;
- }
- int get_tddi_lockdown_data(unsigned char *lockdown_data, unsigned short leng)
- {
- int retval;
- retval = fwu_do_read_tddi_lockdown_data();
- if (retval < 0)
- return retval;
- memcpy(lockdown_data, fwu->read_config_buf, leng);
- return retval;
- }
- int set_tddi_lockdown_data(unsigned char *lockdown_data, unsigned short leng)
- {
- int retval = -EINVAL;
- unsigned long checksum;
- unsigned char checksum_array[4];
- unsigned short blk_cnt;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (fwu->bl_version != BL_V6) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not support lockdown data in bl v.%d\n",
- __func__,
- fwu->bl_version);
- goto exit;
- } else if (!fwu->has_lockdown_data) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not support lockdown data\n", __func__);
- goto exit;
- }
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- goto exit;
- retval = fwu_erase_lockdown_data();
- if (retval < 0)
- goto exit;
- blk_cnt = fwu->blkcount.tddi_lockdown_data;
- fwu->config_size = fwu->blkcount.tddi_lockdown_data * fwu->block_size;
- retval = fwu_allocate_read_config_buf(fwu->config_size);
- if (retval < 0)
- goto exit;
- memset(fwu->read_config_buf, 0x00, fwu->config_size);
- retval = secure_memcpy(fwu->read_config_buf, fwu->config_size,
- lockdown_data, leng, leng);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy tddi lockdwon data\n",
- __func__);
- goto exit;
- }
- calculate_checksum((unsigned short *)fwu->read_config_buf,
- ((fwu->config_size - 4) / 2),
- &checksum);
- convert_to_little_endian(checksum_array, checksum);
- fwu->read_config_buf[blk_cnt * fwu->block_size - 4] = checksum_array[0];
- fwu->read_config_buf[blk_cnt * fwu->block_size - 3] = checksum_array[1];
- fwu->read_config_buf[blk_cnt * fwu->block_size - 2] = checksum_array[2];
- fwu->read_config_buf[blk_cnt * fwu->block_size - 1] = checksum_array[3];
- retval = fwu_write_tddi_lockdown_data();
- exit:
- return retval;
- }
- #endif
- #endif
- static int fwu_do_lockdown_v7(void)
- {
- int retval;
- struct f34_v7_data0 status;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f34_fd.data_base_addr + fwu->off.flash_status,
- status.data,
- sizeof(status.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash status\n",
- __func__);
- return retval;
- }
- if (status.device_cfg_status == 2) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device already locked down\n",
- __func__);
- return 0;
- }
- retval = fwu_write_lockdown();
- if (retval < 0)
- return retval;
- pr_notice("%s: Lockdown programmed\n", __func__);
- return retval;
- }
- static int fwu_do_lockdown_v5v6(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- #ifdef SYNA_TDDI
- unsigned char *img_ld;
- img_ld = (unsigned char *)fwu->img.lockdown.data;
- if (fwu->has_lockdown_data) {
- retval = set_tddi_lockdown_data(img_ld,
- LOCKDOWN_SIZE);
- if (retval < 0)
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write lockdown data\n",
- __func__);
- return retval;
- }
- #endif
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- return retval;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f34_fd.query_base_addr + fwu->off.properties,
- fwu->flash_properties.data,
- sizeof(fwu->flash_properties.data));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash properties\n",
- __func__);
- return retval;
- }
- if (fwu->flash_properties.unlocked == 0) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device already locked down\n",
- __func__);
- return 0;
- }
- retval = fwu_write_lockdown();
- if (retval < 0)
- return retval;
- pr_notice("%s: Lockdown programmed\n", __func__);
- return retval;
- }
- #ifdef F51_DISCRETE_FORCE
- static int fwu_do_restore_f51_cal_data(void)
- {
- int retval;
- unsigned char checksum_array[4];
- unsigned short block_count;
- unsigned long checksum;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- block_count = fwu->blkcount.ui_config;
- fwu->config_size = fwu->block_size * block_count;
- fwu->config_area = UI_CONFIG_AREA;
- retval = fwu_allocate_read_config_buf(fwu->config_size);
- if (retval < 0)
- return retval;
- retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG);
- if (retval < 0)
- return retval;
- retval = secure_memcpy(&fwu->read_config_buf[fwu->cal_data_off],
- fwu->cal_data_size, fwu->cal_data,
- fwu->cal_data_buf_size, fwu->cal_data_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to restore calibration data\n",
- __func__);
- return retval;
- }
- calculate_checksum((unsigned short *)fwu->read_config_buf,
- ((fwu->config_size - 4) / 2),
- &checksum);
- convert_to_little_endian(checksum_array, checksum);
- fwu->read_config_buf[fwu->config_size - 4] = checksum_array[0];
- fwu->read_config_buf[fwu->config_size - 3] = checksum_array[1];
- fwu->read_config_buf[fwu->config_size - 2] = checksum_array[2];
- fwu->read_config_buf[fwu->config_size - 1] = checksum_array[3];
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- return retval;
- fwu->config_area = UI_CONFIG_AREA;
- fwu->config_data = fwu->read_config_buf;
- fwu->config_block_count = fwu->config_size / fwu->block_size;
- retval = fwu_erase_configuration();
- if (retval < 0)
- return retval;
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- return 0;
- }
- #endif
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static int fwu_start_write_guest_code(void)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_parse_image_info();
- if (retval < 0)
- return -EINVAL;
- if (!fwu->has_guest_code) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Guest code not supported\n",
- __func__);
- return -EINVAL;
- }
- if (!fwu->img.contains_guest_code) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: No guest code in firmware image\n",
- __func__);
- return -EINVAL;
- }
- if (rmi4_data->sensor_sleep) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Sensor sleeping\n",
- __func__);
- return -ENODEV;
- }
- rmi4_data->stay_awake = true;
- mutex_lock(&rmi4_data->rmi4_exp_init_mutex);
- pr_notice("%s: Start of write guest code process\n", __func__);
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- goto exit;
- retval = fwu_check_guest_code_size();
- if (retval < 0)
- goto exit;
- retval = fwu_erase_guest_code();
- if (retval < 0)
- goto exit;
- retval = fwu_write_guest_code();
- if (retval < 0)
- goto exit;
- pr_notice("%s: Guest code programmed\n", __func__);
- exit:
- rmi4_data->reset_device(rmi4_data, false);
- pr_notice("%s: End of write guest code process\n", __func__);
- mutex_unlock(&rmi4_data->rmi4_exp_init_mutex);
- rmi4_data->stay_awake = false;
- return retval;
- }
- static int fwu_start_write_config(void)
- {
- int retval;
- unsigned short config_area;
- unsigned int device_fw_id;
- unsigned int image_fw_id;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = fwu_parse_image_info();
- if (retval < 0)
- return -EINVAL;
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- device_fw_id = rmi4_data->firmware_id;
- retval = fwu_get_image_firmware_id(&image_fw_id);
- if (retval < 0)
- return retval;
- if (device_fw_id != image_fw_id) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Device and image firmware IDs don't match\n",
- __func__);
- return -EINVAL;
- }
- retval = fwu_check_ui_configuration_size();
- if (retval < 0)
- return retval;
- break;
- case DP_CONFIG_AREA:
- if (!fwu->flash_properties.has_disp_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Display configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- if (!fwu->img.contains_disp_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: No display configuration in firmware image\n",
- __func__);
- return -EINVAL;
- }
- retval = fwu_check_dp_configuration_size();
- if (retval < 0)
- return retval;
- break;
- case PM_CONFIG_AREA:
- if (!fwu->flash_properties.has_pm_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Permanent configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- if (!fwu->img.contains_perm_config) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: No permanent configuration in firmware image\n",
- __func__);
- return -EINVAL;
- }
- retval = fwu_check_pm_configuration_size();
- if (retval < 0)
- return retval;
- break;
- default:
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Configuration not supported\n",
- __func__);
- return -EINVAL;
- }
- if (rmi4_data->sensor_sleep) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Sensor sleeping\n",
- __func__);
- return -ENODEV;
- }
- rmi4_data->stay_awake = true;
- mutex_lock(&rmi4_data->rmi4_exp_init_mutex);
- pr_notice("%s: Start of write config process\n", __func__);
- config_area = fwu->config_area;
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- goto exit;
- fwu->config_area = config_area;
- if (fwu->config_area != PM_CONFIG_AREA) {
- retval = fwu_erase_configuration();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to erase config\n",
- __func__);
- goto exit;
- }
- }
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- retval = fwu_write_ui_configuration();
- if (retval < 0)
- goto exit;
- break;
- case DP_CONFIG_AREA:
- retval = fwu_write_dp_configuration();
- if (retval < 0)
- goto exit;
- break;
- case PM_CONFIG_AREA:
- retval = fwu_write_pm_configuration();
- if (retval < 0)
- goto exit;
- break;
- }
- pr_notice("%s: Config written\n", __func__);
- exit:
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- rmi4_data->reset_device(rmi4_data, true);
- break;
- case DP_CONFIG_AREA:
- case PM_CONFIG_AREA:
- rmi4_data->reset_device(rmi4_data, false);
- break;
- }
- pr_notice("%s: End of write config process\n", __func__);
- mutex_unlock(&rmi4_data->rmi4_exp_init_mutex);
- rmi4_data->stay_awake = false;
- return retval;
- }
- #endif
- static int fwu_start_reflash(void)
- {
- int retval = 0;
- enum flash_area flash_area;
- bool do_rebuild = false;
- const struct firmware *fw_entry = NULL;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (rmi4_data->sensor_sleep) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Sensor sleeping\n",
- __func__);
- return -ENODEV;
- }
- rmi4_data->stay_awake = true;
- mutex_lock(&rmi4_data->rmi4_exp_init_mutex);
- pr_notice("%s: Start of reflash process\n", __func__);
- if (fwu->image == NULL) {
- retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
- FW_IMAGE_NAME, sizeof(FW_IMAGE_NAME),
- sizeof(FW_IMAGE_NAME));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy image file name\n",
- __func__);
- goto exit;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Requesting firmware image %s\n",
- __func__, fwu->image_name);
- retval = request_firmware(&fw_entry, fwu->image_name,
- rmi4_data->pdev->dev.parent);
- if (retval != 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Firmware image %s not available\n",
- __func__, fwu->image_name);
- retval = -EINVAL;
- goto exit;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Firmware image size = %d\n",
- __func__, (unsigned int)fw_entry->size);
- fwu->image = fw_entry->data;
- }
- retval = fwu_parse_image_info();
- if (retval < 0)
- goto exit;
- if (fwu->blkcount.total_count != fwu->img.blkcount.total_count) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Flash size mismatch\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- if (fwu->bl_version != fwu->img.bl_version) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Bootloader version mismatch\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- retval = fwu_read_flash_status();
- if (retval < 0)
- goto exit;
- if (fwu->in_bl_mode) {
- fwu->bl_mode_device = true;
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device in bootloader mode\n",
- __func__);
- } else {
- fwu->bl_mode_device = false;
- }
- flash_area = fwu_go_nogo();
- if (flash_area != NONE) {
- retval = fwu_enter_flash_prog();
- if (retval < 0) {
- rmi4_data->reset_device(rmi4_data, false);
- goto exit;
- }
- }
- #ifdef F51_DISCRETE_FORCE
- if (flash_area != NONE && !fwu->bl_mode_device) {
- fwu->config_size = fwu->block_size * fwu->blkcount.ui_config;
- fwu->config_area = UI_CONFIG_AREA;
- retval = fwu_allocate_read_config_buf(fwu->config_size);
- if (retval < 0) {
- rmi4_data->reset_device(rmi4_data, false);
- goto exit;
- }
- retval = fwu_read_f34_blocks(fwu->blkcount.ui_config,
- CMD_READ_CONFIG);
- if (retval < 0) {
- rmi4_data->reset_device(rmi4_data, false);
- goto exit;
- }
- retval = secure_memcpy(fwu->cal_data, fwu->cal_data_buf_size,
- &fwu->read_config_buf[fwu->cal_data_off],
- fwu->cal_data_size, fwu->cal_data_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to save calibration data\n",
- __func__);
- rmi4_data->reset_device(rmi4_data, false);
- goto exit;
- }
- }
- #endif
- switch (flash_area) {
- case UI_FIRMWARE:
- do_rebuild = true;
- retval = fwu_do_reflash();
- #ifdef F51_DISCRETE_FORCE
- if (retval < 0)
- break;
- if (fwu->has_utility_param || fwu->img.contains_utility_param)
- break;
- rmi4_data->reset_device(rmi4_data, false);
- if (fwu->bl_mode_device || fwu->in_bl_mode) {
- dev_info(rmi4_data->pdev->dev.parent,
- "%s: Device in bootloader mode, skipping calibration data restoration\n",
- __func__);
- break;
- }
- retval = fwu_do_restore_f51_cal_data();
- #endif
- break;
- case UI_CONFIG:
- do_rebuild = true;
- retval = fwu_check_ui_configuration_size();
- if (retval < 0)
- break;
- fwu->config_area = UI_CONFIG_AREA;
- retval = fwu_erase_configuration();
- if (retval < 0)
- break;
- retval = fwu_write_ui_configuration();
- #ifdef F51_DISCRETE_FORCE
- if (retval < 0)
- break;
- if (fwu->has_utility_param)
- break;
- retval = fwu_do_restore_f51_cal_data();
- #endif
- break;
- case NONE:
- default:
- break;
- }
- if (retval < 0) {
- do_rebuild = false;
- rmi4_data->reset_device(rmi4_data, false);
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do reflash\n",
- __func__);
- goto exit;
- }
- if (fwu->do_lockdown && (fwu->img.lockdown.data != NULL)) {
- switch (fwu->bl_version) {
- case BL_V5:
- case BL_V6:
- retval = fwu_do_lockdown_v5v6();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do lockdown\n",
- __func__);
- }
- rmi4_data->reset_device(rmi4_data, false);
- break;
- case BL_V7:
- case BL_V8:
- retval = fwu_do_lockdown_v7();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do lockdown\n",
- __func__);
- }
- rmi4_data->reset_device(rmi4_data, false);
- break;
- default:
- break;
- }
- }
- exit:
- if (fw_entry)
- release_firmware(fw_entry);
- if (do_rebuild)
- rmi4_data->reset_device(rmi4_data, true);
- pr_notice("%s: End of reflash process\n", __func__);
- mutex_unlock(&rmi4_data->rmi4_exp_init_mutex);
- rmi4_data->stay_awake = false;
- return retval;
- }
- static int fwu_recovery_check_status(void)
- {
- int retval;
- unsigned char data_base;
- unsigned char status;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f35_fd.data_base_addr;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- data_base + F35_ERROR_CODE_OFFSET,
- &status,
- 1);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read status\n",
- __func__);
- return retval;
- }
- status = status & MASK_5BIT;
- if (status != 0x00) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Recovery mode status = %d\n",
- __func__, status);
- return -EINVAL;
- }
- return 0;
- }
- static int fwu_recovery_erase_completion(void)
- {
- int retval;
- unsigned char data_base;
- unsigned char command;
- unsigned char status;
- unsigned int timeout = F35_ERASE_ALL_WAIT_MS / 20;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- data_base = fwu->f35_fd.data_base_addr;
- do {
- command = 0x01;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- fwu->f35_fd.cmd_base_addr,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to issue command\n",
- __func__);
- return retval;
- }
- do {
- retval = synaptics_rmi4_reg_read(rmi4_data,
- fwu->f35_fd.cmd_base_addr,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read command status\n",
- __func__);
- return retval;
- }
- if ((command & 0x01) == 0x00)
- break;
- msleep(20);
- timeout--;
- } while (timeout > 0);
- if (timeout == 0)
- goto exit;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- data_base + F35_FLASH_STATUS_OFFSET,
- &status,
- sizeof(status));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read flash status\n",
- __func__);
- return retval;
- }
- if ((status & 0x01) == 0x00)
- break;
- msleep(20);
- timeout--;
- } while (timeout > 0);
- exit:
- if (timeout == 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Timed out waiting for flash erase completion\n",
- __func__);
- return -ETIMEDOUT;
- }
- return 0;
- }
- static int fwu_recovery_erase_all(void)
- {
- int retval;
- unsigned char ctrl_base;
- unsigned char command = CMD_F35_ERASE_ALL;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- ctrl_base = fwu->f35_fd.ctrl_base_addr;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- ctrl_base + F35_CHUNK_COMMAND_OFFSET,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to issue erase all command\n",
- __func__);
- return retval;
- }
- if (fwu->f35_fd.cmd_base_addr) {
- retval = fwu_recovery_erase_completion();
- if (retval < 0)
- return retval;
- } else {
- msleep(F35_ERASE_ALL_WAIT_MS);
- }
- retval = fwu_recovery_check_status();
- if (retval < 0)
- return retval;
- return 0;
- }
- static int fwu_recovery_write_chunk(void)
- {
- int retval;
- unsigned char ctrl_base;
- unsigned char chunk_number[] = {0, 0};
- unsigned char chunk_spare;
- unsigned char chunk_size;
- unsigned char buf[F35_CHUNK_SIZE + 1];
- unsigned short chunk;
- unsigned short chunk_total;
- unsigned short bytes_written = 0;
- unsigned char *chunk_ptr = (unsigned char *)fwu->image;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- ctrl_base = fwu->f35_fd.ctrl_base_addr;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- ctrl_base + F35_CHUNK_NUM_LSB_OFFSET,
- chunk_number,
- sizeof(chunk_number));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write chunk number\n",
- __func__);
- return retval;
- }
- buf[sizeof(buf) - 1] = CMD_F35_WRITE_CHUNK;
- chunk_total = fwu->image_size / F35_CHUNK_SIZE;
- chunk_spare = fwu->image_size % F35_CHUNK_SIZE;
- if (chunk_spare)
- chunk_total++;
- for (chunk = 0; chunk < chunk_total; chunk++) {
- if (chunk_spare && chunk == chunk_total - 1)
- chunk_size = chunk_spare;
- else
- chunk_size = F35_CHUNK_SIZE;
- memset(buf, 0x00, F35_CHUNK_SIZE);
- secure_memcpy(buf, sizeof(buf), chunk_ptr,
- fwu->image_size - bytes_written,
- chunk_size);
- retval = synaptics_rmi4_reg_write(rmi4_data,
- ctrl_base + F35_CHUNK_DATA_OFFSET,
- buf,
- sizeof(buf));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write chunk data (chunk %d)\n",
- __func__, chunk);
- return retval;
- }
- chunk_ptr += chunk_size;
- bytes_written += chunk_size;
- }
- retval = fwu_recovery_check_status();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write chunk data\n",
- __func__);
- return retval;
- }
- return 0;
- }
- static int fwu_recovery_reset(void)
- {
- int retval;
- unsigned char ctrl_base;
- unsigned char command = CMD_F35_RESET;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- ctrl_base = fwu->f35_fd.ctrl_base_addr;
- retval = synaptics_rmi4_reg_write(rmi4_data,
- ctrl_base + F35_CHUNK_COMMAND_OFFSET,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to issue reset command\n",
- __func__);
- return retval;
- }
- msleep(F35_RESET_WAIT_MS);
- return 0;
- }
- static int fwu_start_recovery(void)
- {
- int retval;
- const struct firmware *fw_entry = NULL;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (rmi4_data->sensor_sleep) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Sensor sleeping\n",
- __func__);
- return -ENODEV;
- }
- rmi4_data->stay_awake = true;
- mutex_lock(&rmi4_data->rmi4_exp_init_mutex);
- pr_notice("%s: Start of recovery process\n", __func__);
- if (fwu->image == NULL) {
- retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
- FW_IHEX_NAME, sizeof(FW_IHEX_NAME),
- sizeof(FW_IHEX_NAME));
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy ihex file name\n",
- __func__);
- goto exit;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Requesting firmware ihex %s\n",
- __func__, fwu->image_name);
- retval = request_firmware(&fw_entry, fwu->image_name,
- rmi4_data->pdev->dev.parent);
- if (retval != 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Firmware ihex %s not available\n",
- __func__, fwu->image_name);
- retval = -EINVAL;
- goto exit;
- }
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Firmware image size = %d\n",
- __func__, (unsigned int)fw_entry->size);
- fwu->image = fw_entry->data;
- fwu->image_size = fw_entry->size;
- }
- retval = rmi4_data->irq_enable(rmi4_data, false, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to disable interrupt\n",
- __func__);
- goto exit;
- }
- retval = fwu_recovery_erase_all();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do erase all in recovery mode\n",
- __func__);
- goto exit;
- }
- pr_notice("%s: External flash erased\n", __func__);
- retval = fwu_recovery_write_chunk();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write chunk data in recovery mode\n",
- __func__);
- goto exit;
- }
- pr_notice("%s: Chunk data programmed\n", __func__);
- retval = fwu_recovery_reset();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to reset device in recovery mode\n",
- __func__);
- goto exit;
- }
- pr_notice("%s: Recovery mode reset issued\n", __func__);
- rmi4_data->reset_device(rmi4_data, true);
- retval = 0;
- exit:
- if (fw_entry)
- release_firmware(fw_entry);
- pr_notice("%s: End of recovery process\n", __func__);
- mutex_unlock(&rmi4_data->rmi4_exp_init_mutex);
- rmi4_data->stay_awake = false;
- return retval;
- }
- int synaptics_fw_updater(const unsigned char *fw_data)
- {
- int retval;
- if (!fwu)
- return -ENODEV;
- if (!fwu->initialized)
- return -ENODEV;
- if (fwu->in_ub_mode) {
- fwu->image = NULL;
- retval = fwu_start_recovery();
- if (retval < 0)
- return retval;
- }
- fwu->image = fw_data;
- retval = fwu_start_reflash();
- fwu->image = NULL;
- return retval;
- }
- EXPORT_SYMBOL(synaptics_fw_updater);
- #ifdef DO_STARTUP_FW_UPDATE
- static void fwu_startup_fw_update_work(struct work_struct *work)
- {
- static unsigned char do_once = 1;
- #ifdef WAIT_FOR_FB_READY
- unsigned int timeout;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- #endif
- if (!do_once)
- return;
- do_once = 0;
- #ifdef WAIT_FOR_FB_READY
- timeout = FB_READY_TIMEOUT_S * 1000 / FB_READY_WAIT_MS + 1;
- while (!rmi4_data->fb_ready) {
- msleep(FB_READY_WAIT_MS);
- timeout--;
- if (timeout == 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Timed out waiting for FB ready\n",
- __func__);
- return;
- }
- }
- #endif
- synaptics_fw_updater(NULL);
- }
- #endif
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- static ssize_t fwu_sysfs_show_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (count < fwu->config_size) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not enough space (%d bytes) in buffer\n",
- __func__, (unsigned int)count);
- retval = -EINVAL;
- goto exit;
- }
- retval = secure_memcpy(buf, count, fwu->read_config_buf,
- fwu->read_config_buf_size, fwu->config_size);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy config data\n",
- __func__);
- goto exit;
- } else {
- retval = fwu->config_size;
- }
- exit:
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_store_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = secure_memcpy(&fwu->ext_data_source[fwu->data_pos],
- fwu->image_size - fwu->data_pos, buf, count, count);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy image data\n",
- __func__);
- goto exit;
- } else {
- retval = count;
- }
- fwu->data_pos += count;
- exit:
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_do_recovery_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (kstrtouint(buf, 10, &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (!fwu->in_ub_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Not in microbootloader mode\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- if (!fwu->ext_data_source) {
- retval = -EINVAL;
- goto exit;
- } else {
- fwu->image = fwu->ext_data_source;
- }
- retval = fwu_start_recovery();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do recovery\n",
- __func__);
- goto exit;
- }
- retval = count;
- exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- fwu->image = NULL;
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (kstrtouint(buf, 10, &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (fwu->in_ub_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: In microbootloader mode\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- if (!fwu->ext_data_source) {
- retval = -EINVAL;
- goto exit;
- } else {
- fwu->image = fwu->ext_data_source;
- }
- if (input & LOCKDOWN) {
- fwu->do_lockdown = true;
- input &= ~LOCKDOWN;
- }
- if ((input != NORMAL) && (input != FORCE)) {
- retval = -EINVAL;
- goto exit;
- }
- if (input == FORCE)
- fwu->force_update = true;
- retval = synaptics_fw_updater(fwu->image);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to do reflash\n",
- __func__);
- goto exit;
- }
- retval = count;
- exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- fwu->image = NULL;
- fwu->force_update = FORCE_UPDATE;
- fwu->do_lockdown = DO_LOCKDOWN;
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_write_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (kstrtouint(buf, 10, &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (input != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (fwu->in_ub_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: In microbootloader mode\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- if (!fwu->ext_data_source) {
- retval = -EINVAL;
- goto exit;
- } else {
- fwu->image = fwu->ext_data_source;
- }
- retval = fwu_start_write_config();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write config\n",
- __func__);
- goto exit;
- }
- retval = count;
- exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- fwu->image = NULL;
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_read_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (kstrtouint(buf, 10, &input) != 1)
- return -EINVAL;
- if (input != 1)
- return -EINVAL;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (fwu->in_ub_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: In microbootloader mode\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- retval = fwu_do_read_config();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read config\n",
- __func__);
- goto exit;
- }
- retval = count;
- exit:
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_config_area_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned long config_area;
- retval = sstrtoul(buf, 10, &config_area);
- if (retval)
- return retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- fwu->config_area = config_area;
- mutex_unlock(&fwu_sysfs_mutex);
- return count;
- }
- static ssize_t fwu_sysfs_image_name_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
- buf, count, count);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to copy image file name\n",
- __func__);
- } else {
- retval = count;
- }
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_image_size_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned long size;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- retval = sstrtoul(buf, 10, &size);
- if (retval)
- return retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- fwu->image_size = size;
- fwu->data_pos = 0;
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
- if (!fwu->ext_data_source) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for image data\n",
- __func__);
- retval = -ENOMEM;
- }
- retval = count;
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_block_size_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.ui_firmware);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.ui_config);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.dp_config);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.pm_config);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.bl_config);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_utility_parameter_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.utility_param);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_guest_code_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- int retval;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- retval = snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.guest_code);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (kstrtouint(buf, 10, &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (input != 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (fwu->in_ub_mode) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: In microbootloader mode\n",
- __func__);
- retval = -EINVAL;
- goto exit;
- }
- if (!fwu->ext_data_source) {
- retval = -EINVAL;
- goto exit;
- } else {
- fwu->image = fwu->ext_data_source;
- }
- retval = fwu_start_write_guest_code();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to write guest code\n",
- __func__);
- goto exit;
- }
- retval = count;
- exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- fwu->image = NULL;
- mutex_unlock(&fwu_sysfs_mutex);
- return retval;
- }
- #ifdef SYNA_TDDI
- static ssize_t fwu_sysfs_read_lockdown_code_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- unsigned short lockdown_data_size;
- unsigned char *lockdown_data;
- char ld_val[2];
- int retval = 0;
- int i = 0;
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- lockdown_data_size = fwu->blkcount.tddi_lockdown_data * fwu->block_size;
- lockdown_data = kzalloc(lockdown_data_size, GFP_KERNEL);
- if (!lockdown_data) {
- mutex_unlock(&fwu_sysfs_mutex);
- return -ENOMEM;
- }
- if (get_tddi_lockdown_data(lockdown_data, lockdown_data_size) < 0) {
- kfree(lockdown_data);
- mutex_unlock(&fwu_sysfs_mutex);
- return -EINVAL;
- }
- for (i = 0; i < lockdown_data_size; i++) {
- retval += snprintf(ld_val, PAGE_SIZE, "%02x",
- *(lockdown_data + i));
- strlcat(buf, ld_val, lockdown_data_size);
- }
- *(buf + retval) = '\n';
- kfree(lockdown_data);
- mutex_unlock(&fwu_sysfs_mutex);
- return retval + 1;
- }
- static ssize_t fwu_sysfs_write_lockdown_code_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- unsigned short lockdown_data_size = (count - 1) / 2;
- unsigned char *lockdown_data;
- unsigned char temp[2];
- int ld_val;
- int i = 0;
- for (i = 0; i < (count - 1); i++) {
- if (((*buf >= '0') && (*buf <= '9')) ||
- (('a' < *buf) && (*buf > 'f')) ||
- (('A' < *buf) && (*buf > 'F')))
- continue;
- else
- return -EINVAL;
- }
- if (count % 2 != 1)
- return -EINVAL;
- lockdown_data = kzalloc(lockdown_data_size, GFP_KERNEL);
- if (!lockdown_data)
- return -ENOMEM;
- for (i = 0; i < lockdown_data_size; i++) {
- memcpy(temp, (buf + 2 * i), sizeof(temp));
- if (kstrtoint(temp, 16, &ld_val) == 1)
- *(lockdown_data + i) = ld_val & 0xff;
- }
- if (!mutex_trylock(&fwu_sysfs_mutex))
- return -EBUSY;
- if (set_tddi_lockdown_data(lockdown_data, lockdown_data_size) < 0) {
- kfree(lockdown_data);
- mutex_unlock(&fwu_sysfs_mutex);
- return -EINVAL;
- }
- kfree(lockdown_data);
- mutex_unlock(&fwu_sysfs_mutex);
- return count;
- }
- #endif
- #endif
- static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
- unsigned char intr_mask)
- {
- if (!fwu)
- return;
- if (fwu->intr_mask & intr_mask)
- fwu_read_flash_status();
- return;
- }
- static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
- {
- int retval;
- unsigned char attr_count;
- struct pdt_properties pdt_props;
- if (fwu) {
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Handle already exists\n",
- __func__);
- return 0;
- }
- fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
- if (!fwu) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for fwu\n",
- __func__);
- retval = -ENOMEM;
- goto exit;
- }
- fwu->image_name = kzalloc(MAX_IMAGE_NAME_LEN, GFP_KERNEL);
- if (!fwu->image_name) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to alloc mem for image name\n",
- __func__);
- retval = -ENOMEM;
- goto exit_free_fwu;
- }
- fwu->rmi4_data = rmi4_data;
- retval = synaptics_rmi4_reg_read(rmi4_data,
- PDT_PROPS,
- pdt_props.data,
- sizeof(pdt_props.data));
- if (retval < 0) {
- dev_dbg(rmi4_data->pdev->dev.parent,
- "%s: Failed to read PDT properties, assuming 0x00\n",
- __func__);
- } else if (pdt_props.has_bsr) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Reflash for LTS not currently supported\n",
- __func__);
- retval = -ENODEV;
- goto exit_free_mem;
- }
- retval = fwu_scan_pdt();
- if (retval < 0)
- goto exit_free_mem;
- if (!fwu->in_ub_mode) {
- retval = fwu_read_f34_queries();
- if (retval < 0)
- goto exit_free_mem;
- retval = fwu_get_device_config_id();
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to read device config ID\n",
- __func__);
- goto exit_free_mem;
- }
- }
- fwu->force_update = FORCE_UPDATE;
- fwu->do_lockdown = DO_LOCKDOWN;
- fwu->initialized = true;
- #ifdef DO_STARTUP_FW_UPDATE
- fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
- INIT_WORK(&fwu->fwu_work, fwu_startup_fw_update_work);
- queue_work(fwu->fwu_workqueue,
- &fwu->fwu_work);
- #endif
- #ifdef F51_DISCRETE_FORCE
- fwu_read_flash_status();
- if (!fwu->in_bl_mode) {
- retval = fwu_f51_force_data_init();
- if (retval < 0)
- goto exit_free_mem;
- }
- #endif
- if (ENABLE_SYS_REFLASH == false)
- return 0;
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
- &dev_attr_data);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to create sysfs bin file\n",
- __func__);
- goto exit_free_mem;
- }
- #endif
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to create sysfs attributes\n",
- __func__);
- retval = -ENODEV;
- goto exit_remove_attrs;
- }
- }
- return 0;
- exit_remove_attrs:
- for (attr_count--; attr_count >= 0; attr_count--) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
- #endif
- exit_free_mem:
- kfree(fwu->image_name);
- exit_free_fwu:
- kfree(fwu);
- fwu = NULL;
- exit:
- return retval;
- }
- static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
- {
- unsigned char attr_count;
- if (!fwu)
- goto exit;
- #ifdef DO_STARTUP_FW_UPDATE
- cancel_work_sync(&fwu->fwu_work);
- flush_workqueue(fwu->fwu_workqueue);
- destroy_workqueue(fwu->fwu_workqueue);
- #endif
- #ifdef F51_DISCRETE_FORCE
- kfree(fwu->cal_data);
- #endif
- kfree(fwu->read_config_buf);
- kfree(fwu->image_name);
- kfree(fwu);
- fwu = NULL;
- if (ENABLE_SYS_REFLASH == false)
- goto exit;
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
- #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
- sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
- #endif
- exit:
- complete(&fwu_remove_complete);
- }
- static void synaptics_rmi4_fwu_reset(struct synaptics_rmi4_data *rmi4_data)
- {
- int retval;
- if (!fwu) {
- synaptics_rmi4_fwu_init(rmi4_data);
- return;
- }
- retval = fwu_scan_pdt();
- if (retval < 0)
- return;
- if (!fwu->in_ub_mode)
- fwu_read_f34_queries();
- #ifdef F51_DISCRETE_FORCE
- fwu_read_flash_status();
- if (!fwu->in_bl_mode)
- fwu_f51_force_data_init();
- #endif
- return;
- }
- static struct synaptics_rmi4_exp_fn fwu_module = {
- .fn_type = RMI_FW_UPDATER,
- .init = synaptics_rmi4_fwu_init,
- .remove = synaptics_rmi4_fwu_remove,
- .reset = synaptics_rmi4_fwu_reset,
- .reinit = NULL,
- .early_suspend = NULL,
- .suspend = NULL,
- .resume = NULL,
- .late_resume = NULL,
- .attn = synaptics_rmi4_fwu_attn,
- };
- static int __init rmi4_fw_update_module_init(void)
- {
- synaptics_rmi4_new_function(&fwu_module, true);
- return 0;
- }
- static void __exit rmi4_fw_update_module_exit(void)
- {
- synaptics_rmi4_new_function(&fwu_module, false);
- wait_for_completion(&fwu_remove_complete);
- }
- module_init(rmi4_fw_update_module_init);
- module_exit(rmi4_fw_update_module_exit);
- MODULE_AUTHOR("Synaptics, Inc.");
- MODULE_DESCRIPTION("Synaptics DSX FW Update Module");
- MODULE_LICENSE("GPL v2");
|