12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662 |
- From 2474b15f441fc37985fac9a9458c9b5135f20907 Mon Sep 17 00:00:00 2001
- From: Sakari Ailus <sakari.ailus@linux.intel.com>
- Date: Mon, 12 Oct 2020 21:04:11 +0300
- Subject: [PATCH] ipu3-cio2: Use unsigned values where appropriate
- Use unsigned values for width, height, bit shifts and registers,
- effectively for all definitions that are not signed.
- Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/ipu3-cio2.h | 156 +++++++++++------------
- 1 file changed, 78 insertions(+), 78 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- index 146492383aa5..7650d7998a3f 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- @@ -13,20 +13,20 @@
- #define CIO2_PCI_BAR 0
- #define CIO2_DMA_MASK DMA_BIT_MASK(39)
-
- -#define CIO2_IMAGE_MAX_WIDTH 4224
- -#define CIO2_IMAGE_MAX_LENGTH 3136
- +#define CIO2_IMAGE_MAX_WIDTH 4224U
- +#define CIO2_IMAGE_MAX_LENGTH 3136U
-
- /* 32MB = 8xFBPT_entry */
- #define CIO2_MAX_LOPS 8
- #define CIO2_MAX_BUFFERS (PAGE_SIZE / 16 / CIO2_MAX_LOPS)
- #define CIO2_LOP_ENTRIES (PAGE_SIZE / sizeof(u32))
-
- -#define CIO2_PAD_SINK 0
- -#define CIO2_PAD_SOURCE 1
- -#define CIO2_PADS 2
- +#define CIO2_PAD_SINK 0U
- +#define CIO2_PAD_SOURCE 1U
- +#define CIO2_PADS 2U
-
- -#define CIO2_NUM_DMA_CHAN 20
- -#define CIO2_NUM_PORTS 4 /* DPHYs */
- +#define CIO2_NUM_DMA_CHAN 20U
- +#define CIO2_NUM_PORTS 4U /* DPHYs */
-
- /* 1 for each sensor */
- #define CIO2_QUEUES CIO2_NUM_PORTS
- @@ -66,12 +66,12 @@
- #define CIO2_REG_MIPIBE_FORCE_RAW8 (CIO2_REG_MIPIBE_BASE + 0x20)
- #define CIO2_REG_MIPIBE_FORCE_RAW8_ENABLE BIT(0)
- #define CIO2_REG_MIPIBE_FORCE_RAW8_USE_TYPEID BIT(1)
- -#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT 2
- +#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT 2U
-
- #define CIO2_REG_MIPIBE_IRQ_STATUS (CIO2_REG_MIPIBE_BASE + 0x24)
- #define CIO2_REG_MIPIBE_IRQ_CLEAR (CIO2_REG_MIPIBE_BASE + 0x28)
- #define CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD (CIO2_REG_MIPIBE_BASE + 0x68)
- -#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD 1
- +#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD 1U
- #define CIO2_REG_MIPIBE_PKT_STALL_STATUS (CIO2_REG_MIPIBE_BASE + 0x6c)
- #define CIO2_REG_MIPIBE_PARSE_GSP_THROUGH_LP_LUT_REG_IDX \
- (CIO2_REG_MIPIBE_BASE + 0x70)
- @@ -79,10 +79,10 @@
- (CIO2_REG_MIPIBE_BASE + 0x74 + 4 * (vc))
- #define CIO2_REG_MIPIBE_LP_LUT_ENTRY(m) /* m = 0..15 */ \
- (CIO2_REG_MIPIBE_BASE + 0x84 + 4 * (m))
- -#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD 1
- -#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT 1
- -#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT 5
- -#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT 7
- +#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD 1U
- +#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT 1U
- +#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT 5U
- +#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT 7U
-
- /* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_IRQCTRL_BASE */
- /* IRQ registers are 18-bit wide, see cio2_irq_error for bit definitions */
- @@ -113,31 +113,31 @@
- #define CIO2_CGC_ROSC_DCGE BIT(12)
- #define CIO2_CGC_XOSC_DCGE BIT(13)
- #define CIO2_CGC_FLIS_DCGE BIT(14)
- -#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT 20
- -#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT 24
- +#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT 20U
- +#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT 24U
- #define CIO2_REG_D0I3C 0x1408
- #define CIO2_D0I3C_I3 BIT(2) /* Set D0I3 */
- #define CIO2_D0I3C_RR BIT(3) /* Restore? */
- #define CIO2_REG_SWRESET 0x140c
- -#define CIO2_SWRESET_SWRESET 1
- +#define CIO2_SWRESET_SWRESET 1U
- #define CIO2_REG_SENSOR_ACTIVE 0x1410
- #define CIO2_REG_INT_STS 0x1414
- #define CIO2_REG_INT_STS_EXT_OE 0x1418
- -#define CIO2_INT_EXT_OE_DMAOE_SHIFT 0
- +#define CIO2_INT_EXT_OE_DMAOE_SHIFT 0U
- #define CIO2_INT_EXT_OE_DMAOE_MASK 0x7ffff
- -#define CIO2_INT_EXT_OE_OES_SHIFT 24
- +#define CIO2_INT_EXT_OE_OES_SHIFT 24U
- #define CIO2_INT_EXT_OE_OES_MASK (0xf << CIO2_INT_EXT_OE_OES_SHIFT)
- #define CIO2_REG_INT_EN 0x1420
- #define CIO2_REG_INT_EN_IRQ (1 << 24)
- -#define CIO2_REG_INT_EN_IOS(dma) (1 << (((dma) >> 1) + 12))
- +#define CIO2_REG_INT_EN_IOS(dma) (1U << (((dma) >> 1U) + 12U))
- /*
- * Interrupt on completion bit, Eg. DMA 0-3 maps to bit 0-3,
- * DMA4 & DMA5 map to bit 4 ... DMA18 & DMA19 map to bit 11 Et cetera
- */
- -#define CIO2_INT_IOC(dma) (1 << ((dma) < 4 ? (dma) : ((dma) >> 1) + 2))
- +#define CIO2_INT_IOC(dma) (1U << ((dma) < 4U ? (dma) : ((dma) >> 1U) + 2U))
- #define CIO2_INT_IOC_SHIFT 0
- #define CIO2_INT_IOC_MASK (0x7ff << CIO2_INT_IOC_SHIFT)
- -#define CIO2_INT_IOS_IOLN(dma) (1 << (((dma) >> 1) + 12))
- +#define CIO2_INT_IOS_IOLN(dma) (1U << (((dma) >> 1U) + 12U))
- #define CIO2_INT_IOS_IOLN_SHIFT 12
- #define CIO2_INT_IOS_IOLN_MASK (0x3ff << CIO2_INT_IOS_IOLN_SHIFT)
- #define CIO2_INT_IOIE BIT(22)
- @@ -145,32 +145,32 @@
- #define CIO2_INT_IOIRQ BIT(24)
- #define CIO2_REG_INT_EN_EXT_OE 0x1424
- #define CIO2_REG_DMA_DBG 0x1448
- -#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT 0
- +#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT 0U
- #define CIO2_REG_PBM_ARB_CTRL 0x1460
- -#define CIO2_PBM_ARB_CTRL_LANES_DIV 0 /* 4-4-2-2 lanes */
- -#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT 0
- +#define CIO2_PBM_ARB_CTRL_LANES_DIV 0U /* 4-4-2-2 lanes */
- +#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT 0U
- #define CIO2_PBM_ARB_CTRL_LE_EN BIT(7)
- -#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN 2
- -#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT 8
- -#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP 480
- -#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT 16
- +#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN 2U
- +#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT 8U
- +#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP 480U
- +#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT 16U
- #define CIO2_REG_PBM_WMCTRL1 0x1464
- -#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT 0
- -#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT 8
- -#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT 16
- +#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT 0U
- +#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT 8U
- +#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT 16U
- #define CIO2_PBM_WMCTRL1_TS_COUNT_DISABLE BIT(31)
- #define CIO2_PBM_WMCTRL1_MIN_2CK (4 << CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT)
- #define CIO2_PBM_WMCTRL1_MID1_2CK (16 << CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT)
- #define CIO2_PBM_WMCTRL1_MID2_2CK (21 << CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT)
- #define CIO2_REG_PBM_WMCTRL2 0x1468
- -#define CIO2_PBM_WMCTRL2_HWM_2CK 40
- -#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT 0
- -#define CIO2_PBM_WMCTRL2_LWM_2CK 22
- -#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT 8
- -#define CIO2_PBM_WMCTRL2_OBFFWM_2CK 2
- -#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT 16
- -#define CIO2_PBM_WMCTRL2_TRANSDYN 1
- -#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT 24
- +#define CIO2_PBM_WMCTRL2_HWM_2CK 40U
- +#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT 0U
- +#define CIO2_PBM_WMCTRL2_LWM_2CK 22U
- +#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT 8U
- +#define CIO2_PBM_WMCTRL2_OBFFWM_2CK 2U
- +#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT 16U
- +#define CIO2_PBM_WMCTRL2_TRANSDYN 1U
- +#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT 24U
- #define CIO2_PBM_WMCTRL2_DYNWMEN BIT(28)
- #define CIO2_PBM_WMCTRL2_OBFF_MEM_EN BIT(29)
- #define CIO2_PBM_WMCTRL2_OBFF_CPU_EN BIT(30)
- @@ -178,12 +178,12 @@
- #define CIO2_REG_PBM_TS_COUNT 0x146c
- #define CIO2_REG_PBM_FOPN_ABORT 0x1474
- /* below n = 0..3 */
- -#define CIO2_PBM_FOPN_ABORT(n) (0x1 << 8 * (n))
- -#define CIO2_PBM_FOPN_FORCE_ABORT(n) (0x2 << 8 * (n))
- -#define CIO2_PBM_FOPN_FRAMEOPEN(n) (0x8 << 8 * (n))
- +#define CIO2_PBM_FOPN_ABORT(n) (0x1 << 8U * (n))
- +#define CIO2_PBM_FOPN_FORCE_ABORT(n) (0x2 << 8U * (n))
- +#define CIO2_PBM_FOPN_FRAMEOPEN(n) (0x8 << 8U * (n))
- #define CIO2_REG_LTRCTRL 0x1480
- #define CIO2_LTRCTRL_LTRDYNEN BIT(16)
- -#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT 8
- +#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT 8U
- #define CIO2_LTRCTRL_LTRSTABLETIME_MASK 0xff
- #define CIO2_LTRCTRL_LTRSEL1S3 BIT(7)
- #define CIO2_LTRCTRL_LTRSEL1S2 BIT(6)
- @@ -195,28 +195,28 @@
- #define CIO2_LTRCTRL_LTRSEL2S0 BIT(0)
- #define CIO2_REG_LTRVAL23 0x1484
- #define CIO2_REG_LTRVAL01 0x1488
- -#define CIO2_LTRVAL02_VAL_SHIFT 0
- -#define CIO2_LTRVAL02_SCALE_SHIFT 10
- -#define CIO2_LTRVAL13_VAL_SHIFT 16
- -#define CIO2_LTRVAL13_SCALE_SHIFT 26
- +#define CIO2_LTRVAL02_VAL_SHIFT 0U
- +#define CIO2_LTRVAL02_SCALE_SHIFT 10U
- +#define CIO2_LTRVAL13_VAL_SHIFT 16U
- +#define CIO2_LTRVAL13_SCALE_SHIFT 26U
-
- -#define CIO2_LTRVAL0_VAL 175
- +#define CIO2_LTRVAL0_VAL 175U
- /* Value times 1024 ns */
- -#define CIO2_LTRVAL0_SCALE 2
- -#define CIO2_LTRVAL1_VAL 90
- -#define CIO2_LTRVAL1_SCALE 2
- -#define CIO2_LTRVAL2_VAL 90
- -#define CIO2_LTRVAL2_SCALE 2
- -#define CIO2_LTRVAL3_VAL 90
- -#define CIO2_LTRVAL3_SCALE 2
- +#define CIO2_LTRVAL0_SCALE 2U
- +#define CIO2_LTRVAL1_VAL 90U
- +#define CIO2_LTRVAL1_SCALE 2U
- +#define CIO2_LTRVAL2_VAL 90U
- +#define CIO2_LTRVAL2_SCALE 2U
- +#define CIO2_LTRVAL3_VAL 90U
- +#define CIO2_LTRVAL3_SCALE 2U
-
- #define CIO2_REG_CDMABA(n) (0x1500 + 0x10 * (n)) /* n = 0..19 */
- #define CIO2_REG_CDMARI(n) (0x1504 + 0x10 * (n))
- -#define CIO2_CDMARI_FBPT_RP_SHIFT 0
- +#define CIO2_CDMARI_FBPT_RP_SHIFT 0U
- #define CIO2_CDMARI_FBPT_RP_MASK 0xff
- #define CIO2_REG_CDMAC0(n) (0x1508 + 0x10 * (n))
- -#define CIO2_CDMAC0_FBPT_LEN_SHIFT 0
- -#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT 8
- +#define CIO2_CDMAC0_FBPT_LEN_SHIFT 0U
- +#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT 8U
- #define CIO2_CDMAC0_FBPT_NS BIT(25)
- #define CIO2_CDMAC0_DMA_INTR_ON_FS BIT(26)
- #define CIO2_CDMAC0_DMA_INTR_ON_FE BIT(27)
- @@ -225,12 +225,12 @@
- #define CIO2_CDMAC0_DMA_EN BIT(30)
- #define CIO2_CDMAC0_DMA_HALTED BIT(31)
- #define CIO2_REG_CDMAC1(n) (0x150c + 0x10 * (n))
- -#define CIO2_CDMAC1_LINENUMINT_SHIFT 0
- -#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT 16
- +#define CIO2_CDMAC1_LINENUMINT_SHIFT 0U
- +#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT 16U
- /* n = 0..3 */
- #define CIO2_REG_PXM_PXF_FMT_CFG0(n) (0x1700 + 0x30 * (n))
- -#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT 0
- -#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT 16
- +#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT 0U
- +#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT 16U
- #define CIO2_PXM_PXF_FMT_CFG_PCK_64B (0 << 0)
- #define CIO2_PXM_PXF_FMT_CFG_PCK_32B (1 << 0)
- #define CIO2_PXM_PXF_FMT_CFG_BPP_08 (0 << 2)
- @@ -249,27 +249,27 @@
- #define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_BD (1 << 10)
- #define CIO2_REG_INT_STS_EXT_IE 0x17e4
- #define CIO2_REG_INT_EN_EXT_IE 0x17e8
- -#define CIO2_INT_EXT_IE_ECC_RE(n) (0x01 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_DPHY_NR(n) (0x02 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_ECC_NR(n) (0x04 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_CRCERR(n) (0x08 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n) (0x10 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_PKT2SHORT(n) (0x20 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_PKT2LONG(n) (0x40 << (8 * (n)))
- -#define CIO2_INT_EXT_IE_IRQ(n) (0x80 << (8 * (n)))
- +#define CIO2_INT_EXT_IE_ECC_RE(n) (0x01 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_DPHY_NR(n) (0x02 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_ECC_NR(n) (0x04 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_CRCERR(n) (0x08 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n) (0x10 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_PKT2SHORT(n) (0x20 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_PKT2LONG(n) (0x40 << (8U * (n)))
- +#define CIO2_INT_EXT_IE_IRQ(n) (0x80 << (8U * (n)))
- #define CIO2_REG_PXM_FRF_CFG(n) (0x1720 + 0x30 * (n))
- #define CIO2_PXM_FRF_CFG_FNSEL BIT(0)
- #define CIO2_PXM_FRF_CFG_FN_RST BIT(1)
- #define CIO2_PXM_FRF_CFG_ABORT BIT(2)
- -#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT 3
- +#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT 3U
- #define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR BIT(8)
- #define CIO2_PXM_FRF_CFG_MSK_ECC_RE BIT(9)
- #define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE BIT(10)
- -#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT 11
- +#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT 11U
- #define CIO2_PXM_FRF_CFG_MASK_CRC_THRES BIT(13)
- #define CIO2_PXM_FRF_CFG_MASK_CSI_ACCEPT BIT(14)
- #define CIO2_PXM_FRF_CFG_CIOHC_FS_MODE BIT(15)
- -#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT 16
- +#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT 16U
- #define CIO2_REG_PXM_SID2BID0(n) (0x1724 + 0x30 * (n))
- #define CIO2_FB_HPLL_FREQ 0x2
- #define CIO2_ISCLK_RATIO 0xc
- @@ -278,14 +278,14 @@
-
- #define CIO2_INT_EN_EXT_OE_MASK 0x8f0fffff
-
- -#define CIO2_CGC_CLKGATE_HOLDOFF 3
- -#define CIO2_CGC_CSI_CLKGATE_HOLDOFF 5
- +#define CIO2_CGC_CLKGATE_HOLDOFF 3U
- +#define CIO2_CGC_CSI_CLKGATE_HOLDOFF 5U
-
- #define CIO2_PXM_FRF_CFG_CRC_TH 16
-
- #define CIO2_INT_EN_EXT_IE_MASK 0xffffffff
-
- -#define CIO2_DMA_CHAN 0
- +#define CIO2_DMA_CHAN 0U
-
- #define CIO2_CSIRX_DLY_CNT_CLANE_IDX -1
-
- @@ -302,8 +302,8 @@
- #define CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT 0x4
- #define CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT 0x570
-
- -#define CIO2_PMCSR_OFFSET 4
- -#define CIO2_PMCSR_D0D3_SHIFT 2
- +#define CIO2_PMCSR_OFFSET 4U
- +#define CIO2_PMCSR_D0D3_SHIFT 2U
- #define CIO2_PMCSR_D3 0x3
-
- struct cio2_csi2_timing {
- --
- 2.33.0
- From 80cc88e57e3b5b737e093f1a0b42a2f6da577ae6 Mon Sep 17 00:00:00 2001
- From: Sakari Ailus <sakari.ailus@linux.intel.com>
- Date: Mon, 12 Oct 2020 21:04:12 +0300
- Subject: [PATCH] ipu3-cio2: Remove explicit type from frame size checks
- Now that the values are unsigned, we can remove explicit cast to u32.
- Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- index 2fe4a0bd0284..2061d7a50700 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- @@ -1283,9 +1283,8 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
- }
- }
-
- - fmt->format.width = min_t(u32, fmt->format.width, CIO2_IMAGE_MAX_WIDTH);
- - fmt->format.height = min_t(u32, fmt->format.height,
- - CIO2_IMAGE_MAX_LENGTH);
- + fmt->format.width = min(fmt->format.width, CIO2_IMAGE_MAX_WIDTH);
- + fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_LENGTH);
- fmt->format.field = V4L2_FIELD_NONE;
-
- mutex_lock(&q->subdev_lock);
- --
- 2.33.0
- From dc8f0b080a1f793d85e993e1796883614e9ce6cc Mon Sep 17 00:00:00 2001
- From: Sakari Ailus <sakari.ailus@linux.intel.com>
- Date: Mon, 12 Oct 2020 21:04:13 +0300
- Subject: [PATCH] ipu3-cio2: Rename CIO2_IMAGE_MAX_LENGTH as
- CIO2_IMAGE_MAX_HEIGHT
- CIO2_IMAGE_MAX_LENGTH is the maximum width of the image. Rename it as
- "CIO2_IMAGE_MAX_HEIGHT" in order to better describe what it is.
- Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 6 +++---
- drivers/media/pci/intel/ipu3/ipu3-cio2.h | 2 +-
- 2 files changed, 4 insertions(+), 4 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- index 2061d7a50700..a0202166e2b0 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- @@ -1095,8 +1095,8 @@ static int cio2_v4l2_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
- /* Only supports up to 4224x3136 */
- if (mpix->width > CIO2_IMAGE_MAX_WIDTH)
- mpix->width = CIO2_IMAGE_MAX_WIDTH;
- - if (mpix->height > CIO2_IMAGE_MAX_LENGTH)
- - mpix->height = CIO2_IMAGE_MAX_LENGTH;
- + if (mpix->height > CIO2_IMAGE_MAX_HEIGHT)
- + mpix->height = CIO2_IMAGE_MAX_HEIGHT;
-
- mpix->num_planes = 1;
- mpix->pixelformat = fmt->fourcc;
- @@ -1284,7 +1284,7 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
- }
-
- fmt->format.width = min(fmt->format.width, CIO2_IMAGE_MAX_WIDTH);
- - fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_LENGTH);
- + fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT);
- fmt->format.field = V4L2_FIELD_NONE;
-
- mutex_lock(&q->subdev_lock);
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- index 7650d7998a3f..ccf0b85ae36f 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- @@ -14,7 +14,7 @@
- #define CIO2_DMA_MASK DMA_BIT_MASK(39)
-
- #define CIO2_IMAGE_MAX_WIDTH 4224U
- -#define CIO2_IMAGE_MAX_LENGTH 3136U
- +#define CIO2_IMAGE_MAX_HEIGHT 3136U
-
- /* 32MB = 8xFBPT_entry */
- #define CIO2_MAX_LOPS 8
- --
- 2.33.0
- From 60dce090c91b1919a00bc95124dd008d049aa3d4 Mon Sep 17 00:00:00 2001
- From: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
- Date: Tue, 13 Oct 2020 17:25:35 +0300
- Subject: [PATCH] ipu3-cio2: Check receved the size against payload size, not
- buffer size
- Compare the received size of the payload size, not the allocated size of
- the buffer that is page aligned. This way also images that aren't aligned
- to page size are not warned about.
- Also wrap a line over 80 characters.
- Suggested-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
- Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
- Tested-by: Jean-Michel Hautbois <jeanmichel.hautbois@xxxxxxxxx>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- index a0202166e2b0..c0cd4606810c 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
- @@ -561,7 +561,9 @@ static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
-
- b = q->bufs[q->bufs_first];
- if (b) {
- - unsigned int bytes = entry[1].second_entry.num_of_bytes;
- + unsigned int received = entry[1].second_entry.num_of_bytes;
- + unsigned long payload =
- + vb2_get_plane_payload(&b->vbb.vb2_buf, 0);
-
- q->bufs[q->bufs_first] = NULL;
- atomic_dec(&q->bufs_queued);
- @@ -571,10 +573,10 @@ static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
- b->vbb.vb2_buf.timestamp = ns;
- b->vbb.field = V4L2_FIELD_NONE;
- b->vbb.sequence = atomic_read(&q->frame_sequence);
- - if (b->vbb.vb2_buf.planes[0].length != bytes)
- - dev_warn(dev, "buffer length is %d received %d\n",
- - b->vbb.vb2_buf.planes[0].length,
- - bytes);
- + if (payload != received)
- + dev_warn(dev,
- + "payload length is %lu, received %u\n",
- + payload, received);
- vb2_buffer_done(&b->vbb.vb2_buf, VB2_BUF_STATE_DONE);
- }
- atomic_inc(&q->frame_sequence);
- --
- 2.33.0
- From 77c2761d168b618b79be1dc908a649f2f3ba6e00 Mon Sep 17 00:00:00 2001
- From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Date: Wed, 30 Dec 2020 22:44:05 +0200
- Subject: [PATCH] media: ipu3-cio2: Add headers that ipu3-cio2.h is direct user
- of
- Add headers that ipu3-cio2.h is direct user of.
- Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Daniel Scally <djrscally@gmail.com>
- Tested-by: Daniel Scally <djrscally@gmail.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/ipu3-cio2.h | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- index ccf0b85ae36f..62187ab5ae43 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- @@ -4,8 +4,26 @@
- #ifndef __IPU3_CIO2_H
- #define __IPU3_CIO2_H
-
- +#include <linux/bits.h>
- +#include <linux/dma-mapping.h>
- +#include <linux/kernel.h>
- +#include <linux/mutex.h>
- #include <linux/types.h>
-
- +#include <asm/page.h>
- +
- +#include <media/media-device.h>
- +#include <media/media-entity.h>
- +#include <media/v4l2-async.h>
- +#include <media/v4l2-dev.h>
- +#include <media/v4l2-device.h>
- +#include <media/v4l2-subdev.h>
- +#include <media/videobuf2-core.h>
- +#include <media/videobuf2-v4l2.h>
- +
- +struct cio2_fbpt_entry; /* defined here, after the first usage */
- +struct pci_dev;
- +
- #define CIO2_NAME "ipu3-cio2"
- #define CIO2_DEVICE_NAME "Intel IPU3 CIO2"
- #define CIO2_ENTITY_NAME "ipu3-csi2"
- --
- 2.33.0
- From 8baab94b24db7550d05fa3360efc24fb1cad79e9 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 24 Oct 2020 22:42:28 +0100
- Subject: [PATCH] device property: Return true in fwnode_device_is_available
- for NULL ops
- Some types of fwnode_handle do not implement the device_is_available()
- check, such as those created by software_nodes. There isn't really a
- meaningful way to check for the availability of a device that doesn't
- actually exist, so if the check isn't implemented just assume that the
- "device" is present.
- Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/base/property.c | 6 ++++++
- 1 file changed, 6 insertions(+)
- diff --git a/drivers/base/property.c b/drivers/base/property.c
- index 4c43d30145c6..bc9c634df6df 100644
- --- a/drivers/base/property.c
- +++ b/drivers/base/property.c
- @@ -785,9 +785,15 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put);
- /**
- * fwnode_device_is_available - check if a device is available for use
- * @fwnode: Pointer to the fwnode of the device.
- + *
- + * For fwnode node types that don't implement the .device_is_available()
- + * operation, this function returns true.
- */
- bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
- {
- + if (!fwnode_has_op(fwnode, device_is_available))
- + return true;
- +
- return fwnode_call_bool_op(fwnode, device_is_available);
- }
- EXPORT_SYMBOL_GPL(fwnode_device_is_available);
- --
- 2.33.0
- From ea49a99ed515607bdb999f35233be6c651492e4a Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 21 Nov 2020 22:06:38 +0000
- Subject: [PATCH] device property: Call fwnode_graph_get_endpoint_by_id() for
- fwnode->secondary
- This function is used to find fwnode endpoints against a device. In
- some instances those endpoints are software nodes which are children of
- fwnode->secondary. Add support to fwnode_graph_get_endpoint_by_id() to
- find those endpoints by recursively calling itself passing the ptr to
- fwnode->secondary in the event no endpoint is found for the primary.
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/base/property.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
- diff --git a/drivers/base/property.c b/drivers/base/property.c
- index bc9c634df6df..ddba75d90af2 100644
- --- a/drivers/base/property.c
- +++ b/drivers/base/property.c
- @@ -1163,7 +1163,14 @@ fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
- best_ep_id = fwnode_ep.id;
- }
-
- - return best_ep;
- + if (best_ep)
- + return best_ep;
- +
- + if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
- + return fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
- + endpoint, flags);
- +
- + return NULL;
- }
- EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
-
- --
- 2.33.0
- From 87fef2d943894c2b371af910231d00c662179442 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 25 Oct 2020 22:49:08 +0000
- Subject: [PATCH] software_node: Enforce parent before child ordering of nodes
- arrays
- Registering software_nodes with the .parent member set to point to a
- currently unregistered software_node has the potential for problems,
- so enforce parent -> child ordering in arrays passed in to
- software_node_register_nodes().
- Software nodes that are children of another software node should be
- unregistered before their parent. To allow easy unregistering of an array
- of software_nodes ordered parent to child, reverse the order in which
- software_node_unregister_nodes() unregisters software_nodes.
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/base/swnode.c | 42 ++++++++++++++++++++++++++++++------------
- 1 file changed, 30 insertions(+), 12 deletions(-)
- diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
- index 206bd4d7d7e2..eb89bdb9232c 100644
- --- a/drivers/base/swnode.c
- +++ b/drivers/base/swnode.c
- @@ -692,7 +692,11 @@ swnode_register(const struct software_node *node, struct swnode *parent,
- * software_node_register_nodes - Register an array of software nodes
- * @nodes: Zero terminated array of software nodes to be registered
- *
- - * Register multiple software nodes at once.
- + * Register multiple software nodes at once. If any node in the array
- + * has its .parent pointer set (which can only be to another software_node),
- + * then its parent **must** have been registered before it is; either outside
- + * of this function or by ordering the array such that parent comes before
- + * child.
- */
- int software_node_register_nodes(const struct software_node *nodes)
- {
- @@ -700,14 +704,23 @@ int software_node_register_nodes(const struct software_node *nodes)
- int i;
-
- for (i = 0; nodes[i].name; i++) {
- - ret = software_node_register(&nodes[i]);
- - if (ret) {
- - software_node_unregister_nodes(nodes);
- - return ret;
- + const struct software_node *parent = nodes[i].parent;
- +
- + if (parent && !software_node_to_swnode(parent)) {
- + ret = -EINVAL;
- + goto err_unregister_nodes;
- }
- +
- + ret = software_node_register(&nodes[i]);
- + if (ret)
- + goto err_unregister_nodes;
- }
-
- return 0;
- +
- +err_unregister_nodes:
- + software_node_unregister_nodes(nodes);
- + return ret;
- }
- EXPORT_SYMBOL_GPL(software_node_register_nodes);
-
- @@ -715,18 +728,23 @@ EXPORT_SYMBOL_GPL(software_node_register_nodes);
- * software_node_unregister_nodes - Unregister an array of software nodes
- * @nodes: Zero terminated array of software nodes to be unregistered
- *
- - * Unregister multiple software nodes at once.
- + * Unregister multiple software nodes at once. If parent pointers are set up
- + * in any of the software nodes then the array **must** be ordered such that
- + * parents come before their children.
- *
- - * NOTE: Be careful using this call if the nodes had parent pointers set up in
- - * them before registering. If so, it is wiser to remove the nodes
- - * individually, in the correct order (child before parent) instead of relying
- - * on the sequential order of the list of nodes in the array.
- + * NOTE: If you are uncertain whether the array is ordered such that
- + * parents will be unregistered before their children, it is wiser to
- + * remove the nodes individually, in the correct order (child before
- + * parent).
- */
- void software_node_unregister_nodes(const struct software_node *nodes)
- {
- - int i;
- + unsigned int i = 0;
- +
- + while (nodes[i].name)
- + i++;
-
- - for (i = 0; nodes[i].name; i++)
- + while (i--)
- software_node_unregister(&nodes[i]);
- }
- EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
- --
- 2.33.0
- From e32a376cde000010f438c6fa0068e56765ac6eca Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 21 Oct 2020 22:25:03 +0100
- Subject: [PATCH] software_node: unregister software_nodes in reverse order
- To maintain consistency with software_node_unregister_nodes(), reverse
- the order in which the software_node_unregister_node_group() function
- unregisters nodes.
- Reported-by: kernel test robot <lkp@intel.com>
- Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/base/swnode.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
- diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
- index eb89bdb9232c..032b24f60c78 100644
- --- a/drivers/base/swnode.c
- +++ b/drivers/base/swnode.c
- @@ -779,16 +779,23 @@ EXPORT_SYMBOL_GPL(software_node_register_node_group);
- * software_node_unregister_node_group - Unregister a group of software nodes
- * @node_group: NULL terminated array of software node pointers to be unregistered
- *
- - * Unregister multiple software nodes at once.
- + * Unregister multiple software nodes at once. The array will be unwound in
- + * reverse order (i.e. last entry first) and thus if any members of the array are
- + * children of another member then the children must appear later in the list such
- + * that they are unregistered first.
- */
- -void software_node_unregister_node_group(const struct software_node **node_group)
- +void software_node_unregister_node_group(
- + const struct software_node **node_group)
- {
- - unsigned int i;
- + unsigned int i = 0;
-
- if (!node_group)
- return;
-
- - for (i = 0; node_group[i]; i++)
- + while (node_group[i])
- + i++;
- +
- + while (i--)
- software_node_unregister(node_group[i]);
- }
- EXPORT_SYMBOL_GPL(software_node_unregister_node_group);
- --
- 2.33.0
- From 8d589207e02ba1733fc4d9b95eb6529871a8a291 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Tue, 22 Dec 2020 13:09:05 +0000
- Subject: [PATCH] device property: Define format macros for ports and endpoints
- OF, ACPI and software_nodes all implement graphs including nodes for ports
- and endpoints. These are all intended to be named with a common schema,
- as "port@n" and "endpoint@n" where n is an unsigned int representing the
- index of the node. To ensure commonality across the subsystems, provide a
- set of macros to define the format.
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- include/linux/fwnode.h | 7 +++++++
- 1 file changed, 7 insertions(+)
- diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
- index 9506f8ec0974..72d36d46287d 100644
- --- a/include/linux/fwnode.h
- +++ b/include/linux/fwnode.h
- @@ -32,6 +32,13 @@ struct fwnode_endpoint {
- const struct fwnode_handle *local_fwnode;
- };
-
- +/*
- + * ports and endpoints defined as software_nodes should all follow a common
- + * naming scheme; use these macros to ensure commonality.
- + */
- +#define SWNODE_GRAPH_PORT_NAME_FMT "port@%u"
- +#define SWNODE_GRAPH_ENDPOINT_NAME_FMT "endpoint@%u"
- +
- #define NR_FWNODE_REFERENCE_ARGS 8
-
- /**
- --
- 2.33.0
- From b68f8d0583a0da5e4a766953b524016295d5df4b Mon Sep 17 00:00:00 2001
- From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
- Date: Tue, 15 Sep 2020 15:47:46 +0100
- Subject: [PATCH] software_node: Add support for fwnode_graph*() family of
- functions
- This implements the remaining .graph_*() callbacks in the fwnode
- operations structure for the software nodes. That makes the
- fwnode_graph_*() functions available in the drivers also when software
- nodes are used.
- The implementation tries to mimic the "OF graph" as much as possible, but
- there is no support for the "reg" device property. The ports will need to
- have the index in their name which starts with "port@" (for example
- "port@0", "port@1", ...) and endpoints will use the index of the software
- node that is given to them during creation. The port nodes can also be
- grouped under a specially named "ports" subnode, just like in DT, if
- necessary.
- The remote-endpoints are reference properties under the endpoint nodes
- that are named "remote-endpoint".
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
- Co-developed-by: Daniel Scally <djrscally@gmail.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/base/swnode.c | 115 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 114 insertions(+), 1 deletion(-)
- diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
- index 032b24f60c78..7f056c5e0ed3 100644
- --- a/drivers/base/swnode.c
- +++ b/drivers/base/swnode.c
- @@ -540,6 +540,115 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
- return 0;
- }
-
- +static struct fwnode_handle *
- +swnode_graph_find_next_port(const struct fwnode_handle *parent,
- + struct fwnode_handle *port)
- +{
- + struct fwnode_handle *old = port;
- +
- + while ((port = software_node_get_next_child(parent, old))) {
- + /*
- + * fwnode ports have naming style "port@", so we search for any
- + * children that follow that convention.
- + */
- + if (!strncmp(to_swnode(port)->node->name, "port@",
- + strlen("port@")))
- + return port;
- + old = port;
- + }
- +
- + return NULL;
- +}
- +
- +static struct fwnode_handle *
- +software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
- + struct fwnode_handle *endpoint)
- +{
- + struct swnode *swnode = to_swnode(fwnode);
- + struct fwnode_handle *parent;
- + struct fwnode_handle *port;
- +
- + if (!swnode)
- + return NULL;
- +
- + if (endpoint) {
- + port = software_node_get_parent(endpoint);
- + parent = software_node_get_parent(port);
- + } else {
- + parent = software_node_get_named_child_node(fwnode, "ports");
- + if (!parent)
- + parent = software_node_get(&swnode->fwnode);
- +
- + port = swnode_graph_find_next_port(parent, NULL);
- + }
- +
- + for (; port; port = swnode_graph_find_next_port(parent, port)) {
- + endpoint = software_node_get_next_child(port, endpoint);
- + if (endpoint) {
- + fwnode_handle_put(port);
- + break;
- + }
- + }
- +
- + fwnode_handle_put(parent);
- +
- + return endpoint;
- +}
- +
- +static struct fwnode_handle *
- +software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
- +{
- + struct swnode *swnode = to_swnode(fwnode);
- + const struct software_node_ref_args *ref;
- + const struct property_entry *prop;
- +
- + if (!swnode)
- + return NULL;
- +
- + prop = property_entry_get(swnode->node->properties, "remote-endpoint");
- + if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
- + return NULL;
- +
- + ref = prop->pointer;
- +
- + return software_node_get(software_node_fwnode(ref[0].node));
- +}
- +
- +static struct fwnode_handle *
- +software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
- +{
- + struct swnode *swnode = to_swnode(fwnode);
- +
- + swnode = swnode->parent;
- + if (swnode && !strcmp(swnode->node->name, "ports"))
- + swnode = swnode->parent;
- +
- + return swnode ? software_node_get(&swnode->fwnode) : NULL;
- +}
- +
- +static int
- +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
- + struct fwnode_endpoint *endpoint)
- +{
- + struct swnode *swnode = to_swnode(fwnode);
- + const char *parent_name = swnode->parent->node->name;
- + int ret;
- +
- + if (strlen("port@") >= strlen(parent_name) ||
- + strncmp(parent_name, "port@", strlen("port@")))
- + return -EINVAL;
- +
- + /* Ports have naming style "port@n", we need to select the n */
- + ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port);
- + if (ret)
- + return ret;
- +
- + endpoint->id = swnode->id;
- + endpoint->local_fwnode = fwnode;
- +
- + return 0;
- +}
- +
- static const struct fwnode_operations software_node_ops = {
- .get = software_node_get,
- .put = software_node_put,
- @@ -551,7 +660,11 @@ static const struct fwnode_operations software_node_ops = {
- .get_parent = software_node_get_parent,
- .get_next_child_node = software_node_get_next_child,
- .get_named_child_node = software_node_get_named_child_node,
- - .get_reference_args = software_node_get_reference_args
- + .get_reference_args = software_node_get_reference_args,
- + .graph_get_next_endpoint = software_node_graph_get_next_endpoint,
- + .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
- + .graph_get_port_parent = software_node_graph_get_port_parent,
- + .graph_parse_endpoint = software_node_graph_parse_endpoint,
- };
-
- /* -------------------------------------------------------------------------- */
- --
- 2.33.0
- From 2074d259d4e0e363320583ce0eab59821fa2509a Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 10 Oct 2020 23:07:22 +0100
- Subject: [PATCH] lib/test_printf.c: Use helper function to unwind array of
- software_nodes
- Use the software_node_unregister_nodes() helper function to unwind this
- array in a cleaner way.
- Acked-by: Petr Mladek <pmladek@suse.com>
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- lib/test_printf.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
- diff --git a/lib/test_printf.c b/lib/test_printf.c
- index 7ac87f18a10f..7d60f24240a4 100644
- --- a/lib/test_printf.c
- +++ b/lib/test_printf.c
- @@ -644,9 +644,7 @@ static void __init fwnode_pointer(void)
- test(second_name, "%pfwP", software_node_fwnode(&softnodes[1]));
- test(third_name, "%pfwP", software_node_fwnode(&softnodes[2]));
-
- - software_node_unregister(&softnodes[2]);
- - software_node_unregister(&softnodes[1]);
- - software_node_unregister(&softnodes[0]);
- + software_node_unregister_nodes(softnodes);
- }
-
- static void __init
- --
- 2.33.0
- From 8aef347cd8368f0c56d6f26c5d8349d8c2321117 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 10 Oct 2020 23:11:36 +0100
- Subject: [PATCH] ipu3-cio2: Add T: entry to MAINTAINERS
- Development for the ipu3-cio2 driver is taking place in media_tree, but
- there's no T: entry in MAINTAINERS to denote that - rectify that oversight
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- MAINTAINERS | 1 +
- 1 file changed, 1 insertion(+)
- diff --git a/MAINTAINERS b/MAINTAINERS
- index 4fef10dd2975..7ac7d1ae8764 100644
- --- a/MAINTAINERS
- +++ b/MAINTAINERS
- @@ -8938,6 +8938,7 @@ M: Bingbu Cao <bingbu.cao@intel.com>
- R: Tianshu Qiu <tian.shu.qiu@intel.com>
- L: linux-media@vger.kernel.org
- S: Maintained
- +T: git git://linuxtv.org/media_tree.git
- F: Documentation/userspace-api/media/v4l/pixfmt-srggb10-ipu3.rst
- F: drivers/media/pci/intel/ipu3/
-
- --
- 2.33.0
- From bc6f5e14d0a9b9926678e7baf0b75bfd09278ddc Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 10 Oct 2020 22:47:21 +0100
- Subject: [PATCH] ipu3-cio2: Rename ipu3-cio2.c
- ipu3-cio2 driver needs extending with multiple files; rename the main
- source file and specify the renamed file in Makefile to accommodate that.
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/Makefile | 2 ++
- drivers/media/pci/intel/ipu3/{ipu3-cio2.c => ipu3-cio2-main.c} | 0
- 2 files changed, 2 insertions(+)
- rename drivers/media/pci/intel/ipu3/{ipu3-cio2.c => ipu3-cio2-main.c} (100%)
- diff --git a/drivers/media/pci/intel/ipu3/Makefile b/drivers/media/pci/intel/ipu3/Makefile
- index 98ddd5beafe0..429d516452e4 100644
- --- a/drivers/media/pci/intel/ipu3/Makefile
- +++ b/drivers/media/pci/intel/ipu3/Makefile
- @@ -1,2 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0-only
- obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
- +
- +ipu3-cio2-y += ipu3-cio2-main.o
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
- similarity index 100%
- rename from drivers/media/pci/intel/ipu3/ipu3-cio2.c
- rename to drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
- --
- 2.33.0
- From ce657d720915cf99a81a1c66e0331fbe0e1e1c2c Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 21 Oct 2020 21:53:05 +0100
- Subject: [PATCH] media: v4l2-core: v4l2-async: Check sd->fwnode->secondary in
- match_fwnode()
- Where the fwnode graph is comprised of software_nodes, these will be
- assigned as the secondary to dev->fwnode. Check the v4l2_subdev's fwnode
- for a secondary and attempt to match against it during match_fwnode() to
- accommodate that possibility.
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/v4l2-core/v4l2-async.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
- diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
- index 33babe6e8b3a..d23dff76da3d 100644
- --- a/drivers/media/v4l2-core/v4l2-async.c
- +++ b/drivers/media/v4l2-core/v4l2-async.c
- @@ -87,6 +87,14 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
- if (sd->fwnode == asd->match.fwnode)
- return true;
-
- + /*
- + * Check the same situation for any possible secondary assigned to the
- + * subdev's fwnode
- + */
- + if (!IS_ERR_OR_NULL(sd->fwnode->secondary) &&
- + sd->fwnode->secondary == asd->match.fwnode)
- + return true;
- +
- /*
- * Otherwise, check if the sd fwnode and the asd fwnode refer to an
- * endpoint or a device. If they're of the same type, there's no match.
- --
- 2.33.0
- From cbb823597d62725a97cc98633d97b7145e13d6c2 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 15 Nov 2020 08:15:34 +0000
- Subject: [PATCH] ACPI / bus: Add acpi_dev_get_next_match_dev() and helper
- macro
- To ensure we handle situations in which multiple sensors of the same
- model (and therefore _HID) are present in a system, we need to be able
- to iterate over devices matching a known _HID but unknown _UID and _HRV
- - add acpi_dev_get_next_match_dev() to accommodate that possibility and
- change acpi_dev_get_first_match_dev() to simply call the new function
- with a NULL starting point. Add an iterator macro for convenience.
- Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/acpi/utils.c | 30 ++++++++++++++++++++++++++----
- include/acpi/acpi_bus.h | 7 +++++++
- 2 files changed, 33 insertions(+), 4 deletions(-)
- diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
- index d5411a166685..ddca1550cce6 100644
- --- a/drivers/acpi/utils.c
- +++ b/drivers/acpi/utils.c
- @@ -843,12 +843,13 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
- EXPORT_SYMBOL(acpi_dev_present);
-
- /**
- - * acpi_dev_get_first_match_dev - Return the first match of ACPI device
- + * acpi_dev_get_next_match_dev - Return the next match of ACPI device
- + * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv
- * @hid: Hardware ID of the device.
- * @uid: Unique ID of the device, pass NULL to not check _UID
- * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
- *
- - * Return the first match of ACPI device if a matching device was present
- + * Return the next match of ACPI device if another matching device was present
- * at the moment of invocation, or NULL otherwise.
- *
- * The caller is responsible to call put_device() on the returned device.
- @@ -856,8 +857,9 @@ EXPORT_SYMBOL(acpi_dev_present);
- * See additional information in acpi_dev_present() as well.
- */
- struct acpi_device *
- -acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
- +acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv)
- {
- + struct device *start = adev ? &adev->dev : NULL;
- struct acpi_dev_match_info match = {};
- struct device *dev;
-
- @@ -865,9 +867,29 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
- match.uid = uid;
- match.hrv = hrv;
-
- - dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
- + dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb);
- return dev ? to_acpi_device(dev) : NULL;
- }
- +EXPORT_SYMBOL(acpi_dev_get_next_match_dev);
- +
- +/**
- + * acpi_dev_get_first_match_dev - Return the first match of ACPI device
- + * @hid: Hardware ID of the device.
- + * @uid: Unique ID of the device, pass NULL to not check _UID
- + * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
- + *
- + * Return the first match of ACPI device if a matching device was present
- + * at the moment of invocation, or NULL otherwise.
- + *
- + * The caller is responsible to call put_device() on the returned device.
- + *
- + * See additional information in acpi_dev_present() as well.
- + */
- +struct acpi_device *
- +acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
- +{
- + return acpi_dev_get_next_match_dev(NULL, hid, uid, hrv);
- +}
- EXPORT_SYMBOL(acpi_dev_get_first_match_dev);
-
- /*
- diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
- index 6ad3b89a8a2e..7295aa50120a 100644
- --- a/include/acpi/acpi_bus.h
- +++ b/include/acpi/acpi_bus.h
- @@ -684,9 +684,16 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
-
- bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
-
- +struct acpi_device *
- +acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
- struct acpi_device *
- acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
-
- +#define for_each_acpi_dev_match(adev, hid, uid, hrv) \
- + for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \
- + adev; \
- + adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv))
- +
- static inline void acpi_dev_put(struct acpi_device *adev)
- {
- if (adev)
- --
- 2.33.0
- From 4c4ecb2b29db4aebb8a247643cf131b13a15b332 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 19 Dec 2020 23:55:04 +0000
- Subject: [PATCH] media: v4l2-fwnode: Include v4l2_fwnode_bus_type
- V4L2 fwnode bus types are enumerated in v4l2-fwnode.c, meaning they aren't
- available to the rest of the kernel. Move the enum to the corresponding
- header so that I can use the label to refer to those values.
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/v4l2-core/v4l2-fwnode.c | 11 -----------
- include/media/v4l2-fwnode.h | 22 ++++++++++++++++++++++
- 2 files changed, 22 insertions(+), 11 deletions(-)
- diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
- index dfc53d11053f..fe01aeb59fd4 100644
- --- a/drivers/media/v4l2-core/v4l2-fwnode.c
- +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
- @@ -28,17 +28,6 @@
- #include <media/v4l2-fwnode.h>
- #include <media/v4l2-subdev.h>
-
- -enum v4l2_fwnode_bus_type {
- - V4L2_FWNODE_BUS_TYPE_GUESS = 0,
- - V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
- - V4L2_FWNODE_BUS_TYPE_CSI1,
- - V4L2_FWNODE_BUS_TYPE_CCP2,
- - V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
- - V4L2_FWNODE_BUS_TYPE_PARALLEL,
- - V4L2_FWNODE_BUS_TYPE_BT656,
- - NR_OF_V4L2_FWNODE_BUS_TYPE,
- -};
- -
- static const struct v4l2_fwnode_bus_conv {
- enum v4l2_fwnode_bus_type fwnode_bus_type;
- enum v4l2_mbus_type mbus_type;
- diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
- index ed0840f3d5df..6ca337c28b3c 100644
- --- a/include/media/v4l2-fwnode.h
- +++ b/include/media/v4l2-fwnode.h
- @@ -213,6 +213,28 @@ struct v4l2_fwnode_connector {
- } connector;
- };
-
- +/**
- + * enum v4l2_fwnode_bus_type - Video bus types defined by firmware properties
- + * @V4L2_FWNODE_BUS_TYPE_GUESS: Default value if no bus-type fwnode property
- + * @V4L2_FWNODE_BUS_TYPE_CSI2_CPHY: MIPI CSI-2 bus, C-PHY physical layer
- + * @V4L2_FWNODE_BUS_TYPE_CSI1: MIPI CSI-1 bus
- + * @V4L2_FWNODE_BUS_TYPE_CCP2: SMIA Compact Camera Port 2 bus
- + * @V4L2_FWNODE_BUS_TYPE_CSI2_DPHY: MIPI CSI-2 bus, D-PHY physical layer
- + * @V4L2_FWNODE_BUS_TYPE_PARALLEL: Camera Parallel Interface bus
- + * @V4L2_FWNODE_BUS_TYPE_BT656: BT.656 video format bus-type
- + * @NR_OF_V4L2_FWNODE_BUS_TYPE: Number of bus-types
- + */
- +enum v4l2_fwnode_bus_type {
- + V4L2_FWNODE_BUS_TYPE_GUESS = 0,
- + V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
- + V4L2_FWNODE_BUS_TYPE_CSI1,
- + V4L2_FWNODE_BUS_TYPE_CCP2,
- + V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
- + V4L2_FWNODE_BUS_TYPE_PARALLEL,
- + V4L2_FWNODE_BUS_TYPE_BT656,
- + NR_OF_V4L2_FWNODE_BUS_TYPE
- +};
- +
- /**
- * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- --
- 2.33.0
- From 0392fb1e916582a46fe6396ce6db45f1b7b1b2aa Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 21 Oct 2020 21:53:44 +0100
- Subject: [PATCH] ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver
- Currently on platforms designed for Windows, connections between CIO2 and
- sensors are not properly defined in DSDT. This patch extends the ipu3-cio2
- driver to compensate by building software_node connections, parsing the
- connection properties from the sensor's SSDB buffer.
- Suggested-by: Jordan Hand <jorhand@linux.microsoft.com>
- Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
- Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- MAINTAINERS | 1 +
- drivers/media/pci/intel/ipu3/Kconfig | 18 +
- drivers/media/pci/intel/ipu3/Makefile | 1 +
- drivers/media/pci/intel/ipu3/cio2-bridge.c | 311 ++++++++++++++++++
- drivers/media/pci/intel/ipu3/cio2-bridge.h | 125 +++++++
- drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 34 ++
- drivers/media/pci/intel/ipu3/ipu3-cio2.h | 6 +
- 7 files changed, 496 insertions(+)
- create mode 100644 drivers/media/pci/intel/ipu3/cio2-bridge.c
- create mode 100644 drivers/media/pci/intel/ipu3/cio2-bridge.h
- diff --git a/MAINTAINERS b/MAINTAINERS
- index 7ac7d1ae8764..f313ba49c2b8 100644
- --- a/MAINTAINERS
- +++ b/MAINTAINERS
- @@ -8935,6 +8935,7 @@ INTEL IPU3 CSI-2 CIO2 DRIVER
- M: Yong Zhi <yong.zhi@intel.com>
- M: Sakari Ailus <sakari.ailus@linux.intel.com>
- M: Bingbu Cao <bingbu.cao@intel.com>
- +M: Dan Scally <djrscally@gmail.com>
- R: Tianshu Qiu <tian.shu.qiu@intel.com>
- L: linux-media@vger.kernel.org
- S: Maintained
- diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig
- index 7a805201034b..24f4e79fe0cb 100644
- --- a/drivers/media/pci/intel/ipu3/Kconfig
- +++ b/drivers/media/pci/intel/ipu3/Kconfig
- @@ -17,3 +17,21 @@ config VIDEO_IPU3_CIO2
- Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
- connected camera.
- The module will be called ipu3-cio2.
- +
- +config CIO2_BRIDGE
- + bool "IPU3 CIO2 Sensors Bridge"
- + depends on VIDEO_IPU3_CIO2
- + help
- + This extension provides an API for the ipu3-cio2 driver to create
- + connections to cameras that are hidden in the SSDB buffer in ACPI.
- + It can be used to enable support for cameras in detachable / hybrid
- + devices that ship with Windows.
- +
- + Say Y here if your device is a detachable / hybrid laptop that comes
- + with Windows installed by the OEM, for example:
- +
- + - Microsoft Surface models (except Surface Pro 3)
- + - The Lenovo Miix line (for example the 510, 520, 710 and 720)
- + - Dell 7285
- +
- + If in doubt, say N here.
- diff --git a/drivers/media/pci/intel/ipu3/Makefile b/drivers/media/pci/intel/ipu3/Makefile
- index 429d516452e4..933777e6ea8a 100644
- --- a/drivers/media/pci/intel/ipu3/Makefile
- +++ b/drivers/media/pci/intel/ipu3/Makefile
- @@ -2,3 +2,4 @@
- obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
-
- ipu3-cio2-y += ipu3-cio2-main.o
- +ipu3-cio2-$(CONFIG_CIO2_BRIDGE) += cio2-bridge.o
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- new file mode 100644
- index 000000000000..143f3c0f445e
- --- /dev/null
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- @@ -0,0 +1,311 @@
- +// SPDX-License-Identifier: GPL-2.0
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +
- +#include <linux/acpi.h>
- +#include <linux/device.h>
- +#include <linux/pci.h>
- +#include <linux/property.h>
- +#include <media/v4l2-fwnode.h>
- +
- +#include "cio2-bridge.h"
- +
- +/*
- + * Extend this array with ACPI Hardware IDs of devices known to be working
- + * plus the number of link-frequencies expected by their drivers, along with
- + * the frequency values in hertz. This is somewhat opportunistic way of adding
- + * support for this for now in the hopes of a better source for the information
- + * (possibly some encoded value in the SSDB buffer that we're unaware of)
- + * becoming apparent in the future.
- + *
- + * Do not add an entry for a sensor that is not actually supported.
- + */
- +static const struct cio2_sensor_config cio2_supported_sensors[] = {
- + /* Omnivision OV5693 */
- + CIO2_SENSOR_CONFIG("INT33BE", 0),
- + /* Omnivision OV2680 */
- + CIO2_SENSOR_CONFIG("OVTI2680", 0),
- +};
- +
- +static const struct cio2_property_names prop_names = {
- + .clock_frequency = "clock-frequency",
- + .rotation = "rotation",
- + .bus_type = "bus-type",
- + .data_lanes = "data-lanes",
- + .remote_endpoint = "remote-endpoint",
- + .link_frequencies = "link-frequencies",
- +};
- +
- +static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
- + void *data, u32 size)
- +{
- + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- + union acpi_object *obj;
- + acpi_status status;
- + int ret = 0;
- +
- + status = acpi_evaluate_object(adev->handle, id, NULL, &buffer);
- + if (ACPI_FAILURE(status))
- + return -ENODEV;
- +
- + obj = buffer.pointer;
- + if (!obj) {
- + dev_err(&adev->dev, "Couldn't locate ACPI buffer\n");
- + return -ENODEV;
- + }
- +
- + if (obj->type != ACPI_TYPE_BUFFER) {
- + dev_err(&adev->dev, "Not an ACPI buffer\n");
- + ret = -ENODEV;
- + goto out_free_buff;
- + }
- +
- + if (obj->buffer.length > size) {
- + dev_err(&adev->dev, "Given buffer is too small\n");
- + ret = -EINVAL;
- + goto out_free_buff;
- + }
- +
- + memcpy(data, obj->buffer.pointer, obj->buffer.length);
- +
- +out_free_buff:
- + kfree(buffer.pointer);
- + return ret;
- +}
- +
- +static void cio2_bridge_create_fwnode_properties(
- + struct cio2_sensor *sensor,
- + struct cio2_bridge *bridge,
- + const struct cio2_sensor_config *cfg)
- +{
- + sensor->prop_names = prop_names;
- +
- + sensor->local_ref[0].node = &sensor->swnodes[SWNODE_CIO2_ENDPOINT];
- + sensor->remote_ref[0].node = &sensor->swnodes[SWNODE_SENSOR_ENDPOINT];
- +
- + sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
- + sensor->prop_names.clock_frequency,
- + sensor->ssdb.mclkspeed);
- + sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
- + sensor->prop_names.rotation,
- + sensor->ssdb.degree);
- +
- + sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
- + sensor->prop_names.bus_type,
- + V4L2_FWNODE_BUS_TYPE_CSI2_DPHY);
- + sensor->ep_properties[1] = PROPERTY_ENTRY_U32_ARRAY_LEN(
- + sensor->prop_names.data_lanes,
- + bridge->data_lanes,
- + sensor->ssdb.lanes);
- + sensor->ep_properties[2] = PROPERTY_ENTRY_REF_ARRAY(
- + sensor->prop_names.remote_endpoint,
- + sensor->local_ref);
- +
- + if (cfg->nr_link_freqs > 0)
- + sensor->ep_properties[3] = PROPERTY_ENTRY_U64_ARRAY_LEN(
- + sensor->prop_names.link_frequencies,
- + cfg->link_freqs,
- + cfg->nr_link_freqs);
- +
- + sensor->cio2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN(
- + sensor->prop_names.data_lanes,
- + bridge->data_lanes,
- + sensor->ssdb.lanes);
- + sensor->cio2_properties[1] = PROPERTY_ENTRY_REF_ARRAY(
- + sensor->prop_names.remote_endpoint,
- + sensor->remote_ref);
- +}
- +
- +static void cio2_bridge_init_swnode_names(struct cio2_sensor *sensor)
- +{
- + snprintf(sensor->node_names.remote_port,
- + sizeof(sensor->node_names.remote_port),
- + SWNODE_GRAPH_PORT_NAME_FMT, sensor->ssdb.link);
- + snprintf(sensor->node_names.port,
- + sizeof(sensor->node_names.port),
- + SWNODE_GRAPH_PORT_NAME_FMT, 0); /* Always port 0 */
- + snprintf(sensor->node_names.endpoint,
- + sizeof(sensor->node_names.endpoint),
- + SWNODE_GRAPH_ENDPOINT_NAME_FMT, 0); /* And endpoint 0 */
- +}
- +
- +static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
- + struct cio2_sensor *sensor)
- +{
- + struct software_node *nodes = sensor->swnodes;
- +
- + cio2_bridge_init_swnode_names(sensor);
- +
- + nodes[SWNODE_SENSOR_HID] = NODE_SENSOR(sensor->name,
- + sensor->dev_properties);
- + nodes[SWNODE_SENSOR_PORT] = NODE_PORT(sensor->node_names.port,
- + &nodes[SWNODE_SENSOR_HID]);
- + nodes[SWNODE_SENSOR_ENDPOINT] = NODE_ENDPOINT(
- + sensor->node_names.endpoint,
- + &nodes[SWNODE_SENSOR_PORT],
- + sensor->ep_properties);
- + nodes[SWNODE_CIO2_PORT] = NODE_PORT(sensor->node_names.remote_port,
- + &bridge->cio2_hid_node);
- + nodes[SWNODE_CIO2_ENDPOINT] = NODE_ENDPOINT(
- + sensor->node_names.endpoint,
- + &nodes[SWNODE_CIO2_PORT],
- + sensor->cio2_properties);
- +}
- +
- +static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
- +{
- + struct cio2_sensor *sensor;
- + unsigned int i;
- +
- + for (i = 0; i < bridge->n_sensors; i++) {
- + sensor = &bridge->sensors[i];
- + software_node_unregister_nodes(sensor->swnodes);
- + acpi_dev_put(sensor->adev);
- + }
- +}
- +
- +static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
- + struct cio2_bridge *bridge,
- + struct pci_dev *cio2)
- +{
- + struct fwnode_handle *fwnode;
- + struct cio2_sensor *sensor;
- + struct acpi_device *adev;
- + int ret;
- +
- + for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
- + if (!adev->status.enabled)
- + continue;
- +
- + if (bridge->n_sensors >= CIO2_NUM_PORTS) {
- + dev_err(&cio2->dev, "Exceeded available CIO2 ports\n");
- + cio2_bridge_unregister_sensors(bridge);
- + ret = -EINVAL;
- + goto err_out;
- + }
- +
- + sensor = &bridge->sensors[bridge->n_sensors];
- + sensor->adev = adev;
- + strscpy(sensor->name, cfg->hid, sizeof(sensor->name));
- +
- + ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
- + &sensor->ssdb,
- + sizeof(sensor->ssdb));
- + if (ret)
- + goto err_put_adev;
- +
- + if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
- + dev_err(&adev->dev,
- + "Number of lanes in SSDB is invalid\n");
- + ret = -EINVAL;
- + goto err_put_adev;
- + }
- +
- + cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
- + cio2_bridge_create_connection_swnodes(bridge, sensor);
- +
- + ret = software_node_register_nodes(sensor->swnodes);
- + if (ret)
- + goto err_put_adev;
- +
- + fwnode = software_node_fwnode(&sensor->swnodes[SWNODE_SENSOR_HID]);
- + if (!fwnode) {
- + ret = -ENODEV;
- + goto err_free_swnodes;
- + }
- +
- + adev->fwnode.secondary = fwnode;
- +
- + dev_info(&cio2->dev, "Found supported sensor %s\n",
- + acpi_dev_name(adev));
- +
- + bridge->n_sensors++;
- + }
- +
- + return 0;
- +
- +err_free_swnodes:
- + software_node_unregister_nodes(sensor->swnodes);
- +err_put_adev:
- + acpi_dev_put(sensor->adev);
- +err_out:
- + return ret;
- +}
- +
- +static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
- + struct pci_dev *cio2)
- +{
- + unsigned int i;
- + int ret;
- +
- + for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
- + const struct cio2_sensor_config *cfg = &cio2_supported_sensors[i];
- +
- + ret = cio2_bridge_connect_sensor(cfg, bridge, cio2);
- + if (ret)
- + goto err_unregister_sensors;
- + }
- +
- + return 0;
- +
- +err_unregister_sensors:
- + cio2_bridge_unregister_sensors(bridge);
- + return ret;
- +}
- +
- +int cio2_bridge_init(struct pci_dev *cio2)
- +{
- + struct device *dev = &cio2->dev;
- + struct fwnode_handle *fwnode;
- + struct cio2_bridge *bridge;
- + unsigned int i;
- + int ret;
- +
- + bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
- + if (!bridge)
- + return -ENOMEM;
- +
- + strscpy(bridge->cio2_node_name, CIO2_HID, sizeof(bridge->cio2_node_name));
- + bridge->cio2_hid_node.name = bridge->cio2_node_name;
- +
- + ret = software_node_register(&bridge->cio2_hid_node);
- + if (ret < 0) {
- + dev_err(dev, "Failed to register the CIO2 HID node\n");
- + goto err_free_bridge;
- + }
- +
- + /*
- + * Map the lane arrangement, which is fixed for the IPU3 (meaning we
- + * only need one, rather than one per sensor). We include it as a
- + * member of the struct cio2_bridge rather than a global variable so
- + * that it survives if the module is unloaded along with the rest of
- + * the struct.
- + */
- + for (i = 0; i < CIO2_MAX_LANES; i++)
- + bridge->data_lanes[i] = i + 1;
- +
- + ret = cio2_bridge_connect_sensors(bridge, cio2);
- + if (ret || bridge->n_sensors == 0)
- + goto err_unregister_cio2;
- +
- + dev_info(dev, "Connected %d cameras\n", bridge->n_sensors);
- +
- + fwnode = software_node_fwnode(&bridge->cio2_hid_node);
- + if (!fwnode) {
- + dev_err(dev, "Error getting fwnode from cio2 software_node\n");
- + ret = -ENODEV;
- + goto err_unregister_sensors;
- + }
- +
- + set_secondary_fwnode(dev, fwnode);
- +
- + return 0;
- +
- +err_unregister_sensors:
- + cio2_bridge_unregister_sensors(bridge);
- +err_unregister_cio2:
- + software_node_unregister(&bridge->cio2_hid_node);
- +err_free_bridge:
- + kfree(bridge);
- +
- + return ret;
- +}
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- new file mode 100644
- index 000000000000..dd0ffcafa489
- --- /dev/null
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- @@ -0,0 +1,125 @@
- +/* SPDX-License-Identifier: GPL-2.0 */
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +#ifndef __CIO2_BRIDGE_H
- +#define __CIO2_BRIDGE_H
- +
- +#include <linux/property.h>
- +#include <linux/types.h>
- +
- +#include "ipu3-cio2.h"
- +
- +#define CIO2_HID "INT343E"
- +#define CIO2_MAX_LANES 4
- +#define MAX_NUM_LINK_FREQS 3
- +
- +#define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
- + (const struct cio2_sensor_config) { \
- + .hid = _HID, \
- + .nr_link_freqs = _NR, \
- + .link_freqs = { __VA_ARGS__ } \
- + }
- +
- +#define NODE_SENSOR(_HID, _PROPS) \
- + (const struct software_node) { \
- + .name = _HID, \
- + .properties = _PROPS, \
- + }
- +
- +#define NODE_PORT(_PORT, _SENSOR_NODE) \
- + (const struct software_node) { \
- + .name = _PORT, \
- + .parent = _SENSOR_NODE, \
- + }
- +
- +#define NODE_ENDPOINT(_EP, _PORT, _PROPS) \
- + (const struct software_node) { \
- + .name = _EP, \
- + .parent = _PORT, \
- + .properties = _PROPS, \
- + }
- +
- +enum cio2_sensor_swnodes {
- + SWNODE_SENSOR_HID,
- + SWNODE_SENSOR_PORT,
- + SWNODE_SENSOR_ENDPOINT,
- + SWNODE_CIO2_PORT,
- + SWNODE_CIO2_ENDPOINT,
- + SWNODE_COUNT
- +};
- +
- +/* Data representation as it is in ACPI SSDB buffer */
- +struct cio2_sensor_ssdb {
- + u8 version;
- + u8 sku;
- + u8 guid_csi2[16];
- + u8 devfunction;
- + u8 bus;
- + u32 dphylinkenfuses;
- + u32 clockdiv;
- + u8 link;
- + u8 lanes;
- + u32 csiparams[10];
- + u32 maxlanespeed;
- + u8 sensorcalibfileidx;
- + u8 sensorcalibfileidxInMBZ[3];
- + u8 romtype;
- + u8 vcmtype;
- + u8 platforminfo;
- + u8 platformsubinfo;
- + u8 flash;
- + u8 privacyled;
- + u8 degree;
- + u8 mipilinkdefined;
- + u32 mclkspeed;
- + u8 controllogicid;
- + u8 reserved1[3];
- + u8 mclkport;
- + u8 reserved2[13];
- +} __packed;
- +
- +struct cio2_property_names {
- + char clock_frequency[16];
- + char rotation[9];
- + char bus_type[9];
- + char data_lanes[11];
- + char remote_endpoint[16];
- + char link_frequencies[17];
- +};
- +
- +struct cio2_node_names {
- + char port[7];
- + char endpoint[11];
- + char remote_port[7];
- +};
- +
- +struct cio2_sensor_config {
- + const char *hid;
- + const u8 nr_link_freqs;
- + const u64 link_freqs[MAX_NUM_LINK_FREQS];
- +};
- +
- +struct cio2_sensor {
- + char name[ACPI_ID_LEN];
- + struct acpi_device *adev;
- +
- + struct software_node swnodes[6];
- + struct cio2_node_names node_names;
- +
- + struct cio2_sensor_ssdb ssdb;
- + struct cio2_property_names prop_names;
- + struct property_entry ep_properties[5];
- + struct property_entry dev_properties[3];
- + struct property_entry cio2_properties[3];
- + struct software_node_ref_args local_ref[1];
- + struct software_node_ref_args remote_ref[1];
- +};
- +
- +struct cio2_bridge {
- + char cio2_node_name[ACPI_ID_LEN];
- + struct software_node cio2_hid_node;
- + u32 data_lanes[4];
- + unsigned int n_sensors;
- + struct cio2_sensor sensors[CIO2_NUM_PORTS];
- +};
- +
- +#endif
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
- index c0cd4606810c..77cea941fd8d 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
- @@ -1709,11 +1709,28 @@ static void cio2_queues_exit(struct cio2_device *cio2)
- cio2_queue_exit(cio2, &cio2->queue[i]);
- }
-
- +static int cio2_check_fwnode_graph(struct fwnode_handle *fwnode)
- +{
- + struct fwnode_handle *endpoint;
- +
- + if (IS_ERR_OR_NULL(fwnode))
- + return -EINVAL;
- +
- + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
- + if (endpoint) {
- + fwnode_handle_put(endpoint);
- + return 0;
- + }
- +
- + return cio2_check_fwnode_graph(fwnode->secondary);
- +}
- +
- /**************** PCI interface ****************/
-
- static int cio2_pci_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *id)
- {
- + struct fwnode_handle *fwnode = dev_fwnode(&pci_dev->dev);
- struct cio2_device *cio2;
- int r;
-
- @@ -1722,6 +1739,23 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
- return -ENOMEM;
- cio2->pci_dev = pci_dev;
-
- + /*
- + * On some platforms no connections to sensors are defined in firmware,
- + * if the device has no endpoints then we can try to build those as
- + * software_nodes parsed from SSDB.
- + */
- + r = cio2_check_fwnode_graph(fwnode);
- + if (r) {
- + if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) {
- + dev_err(&pci_dev->dev, "fwnode graph has no endpoints connected\n");
- + return -EINVAL;
- + }
- +
- + r = cio2_bridge_init(pci_dev);
- + if (r)
- + return r;
- + }
- +
- r = pcim_enable_device(pci_dev);
- if (r) {
- dev_err(&pci_dev->dev, "failed to enable device (%d)\n", r);
- diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- index 62187ab5ae43..dc3e343a37fb 100644
- --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
- @@ -455,4 +455,10 @@ static inline struct cio2_queue *vb2q_to_cio2_queue(struct vb2_queue *vq)
- return container_of(vq, struct cio2_queue, vbq);
- }
-
- +#if IS_ENABLED(CONFIG_CIO2_BRIDGE)
- +int cio2_bridge_init(struct pci_dev *cio2);
- +#else
- +int cio2_bridge_init(struct pci_dev *cio2) { return 0; }
- +#endif
- +
- #endif
- --
- 2.33.0
- From d870071b5f738817441b184b82b5b919b1515fae Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 2 Dec 2020 12:38:10 +0000
- Subject: [PATCH] acpi: utils: move acpi_lpss_dep() to utils
- I need to be able to identify devices which declare themselves to be
- dependent on other devices through _DEP; add this function to utils.c
- and export it to the rest of the ACPI layer.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/acpi/acpi_lpss.c | 24 ------------------------
- drivers/acpi/internal.h | 1 +
- drivers/acpi/utils.c | 24 ++++++++++++++++++++++++
- 3 files changed, 25 insertions(+), 24 deletions(-)
- diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
- index be73974ce449..70c7d9a3f715 100644
- --- a/drivers/acpi/acpi_lpss.c
- +++ b/drivers/acpi/acpi_lpss.c
- @@ -543,30 +543,6 @@ static struct device *acpi_lpss_find_device(const char *hid, const char *uid)
- return bus_find_device(&pci_bus_type, NULL, &data, match_hid_uid);
- }
-
- -static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
- -{
- - struct acpi_handle_list dep_devices;
- - acpi_status status;
- - int i;
- -
- - if (!acpi_has_method(adev->handle, "_DEP"))
- - return false;
- -
- - status = acpi_evaluate_reference(adev->handle, "_DEP", NULL,
- - &dep_devices);
- - if (ACPI_FAILURE(status)) {
- - dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n");
- - return false;
- - }
- -
- - for (i = 0; i < dep_devices.count; i++) {
- - if (dep_devices.handles[i] == handle)
- - return true;
- - }
- -
- - return false;
- -}
- -
- static void acpi_lpss_link_consumer(struct device *dev1,
- const struct lpss_device_links *link)
- {
- diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
- index a958ad60a339..3901a251c998 100644
- --- a/drivers/acpi/internal.h
- +++ b/drivers/acpi/internal.h
- @@ -81,6 +81,7 @@ static inline void acpi_lpss_init(void) {}
- #endif
-
- void acpi_apd_init(void);
- +bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle);
-
- acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src);
- bool acpi_queue_hotplug_work(struct work_struct *work);
- diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
- index ddca1550cce6..78b38775f18b 100644
- --- a/drivers/acpi/utils.c
- +++ b/drivers/acpi/utils.c
- @@ -807,6 +807,30 @@ static int acpi_dev_match_cb(struct device *dev, const void *data)
- return hrv == match->hrv;
- }
-
- +bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
- +{
- + struct acpi_handle_list dep_devices;
- + acpi_status status;
- + int i;
- +
- + if (!acpi_has_method(adev->handle, "_DEP"))
- + return false;
- +
- + status = acpi_evaluate_reference(adev->handle, "_DEP", NULL,
- + &dep_devices);
- + if (ACPI_FAILURE(status)) {
- + dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n");
- + return false;
- + }
- +
- + for (i = 0; i < dep_devices.count; i++) {
- + if (dep_devices.handles[i] == handle)
- + return true;
- + }
- +
- + return false;
- +}
- +
- /**
- * acpi_dev_present - Detect that a given ACPI device is present
- * @hid: Hardware ID of the device.
- --
- 2.33.0
- From a659546aa2ac175585041d0cea87aa970ec7585c Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 26 Nov 2020 21:12:41 +0000
- Subject: [PATCH] acpi: utils: Add function to fetch dependent acpi_devices
- In some ACPI tables we encounter, devices use the _DEP method to assert
- a dependence on other ACPI devices as opposed to the OpRegions that the
- specification intends. We need to be able to find those devices "from"
- the dependee, so add a function to parse all ACPI Devices and check if
- the include the handle of the dependee device in their _DEP buffer.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/acpi/utils.c | 34 ++++++++++++++++++++++++++++++++++
- include/acpi/acpi_bus.h | 2 ++
- 2 files changed, 36 insertions(+)
- diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
- index 78b38775f18b..ec6a2406a886 100644
- --- a/drivers/acpi/utils.c
- +++ b/drivers/acpi/utils.c
- @@ -831,6 +831,18 @@ bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
- return false;
- }
-
- +static int acpi_dev_match_by_dep(struct device *dev, const void *data)
- +{
- + struct acpi_device *adev = to_acpi_device(dev);
- + const struct acpi_device *dependee = data;
- + acpi_handle handle = dependee->handle;
- +
- + if (acpi_lpss_dep(adev, handle))
- + return 1;
- +
- + return 0;
- +}
- +
- /**
- * acpi_dev_present - Detect that a given ACPI device is present
- * @hid: Hardware ID of the device.
- @@ -866,6 +878,28 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
- }
- EXPORT_SYMBOL(acpi_dev_present);
-
- +/**
- + * acpi_dev_get_next_dep_dev - Return next ACPI device dependent on input dev
- + * @adev: Pointer to the dependee device
- + * @prev: Pointer to the previous dependent device (or NULL for first match)
- + *
- + * Return the next ACPI device which declares itself dependent on @adev in
- + * the _DEP buffer.
- + *
- + * The caller is responsible to call put_device() on the returned device.
- + */
- +struct acpi_device *acpi_dev_get_next_dep_dev(struct acpi_device *adev,
- + struct acpi_device *prev)
- +{
- + struct device *start = prev ? &prev->dev : NULL;
- + struct device *dev;
- +
- + dev = bus_find_device(&acpi_bus_type, start, adev, acpi_dev_match_by_dep);
- +
- + return dev ? to_acpi_device(dev) : NULL;
- +}
- +EXPORT_SYMBOL(acpi_dev_get_next_dep_dev);
- +
- /**
- * acpi_dev_get_next_match_dev - Return the next match of ACPI device
- * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv
- diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
- index 7295aa50120a..58f964471da5 100644
- --- a/include/acpi/acpi_bus.h
- +++ b/include/acpi/acpi_bus.h
- @@ -684,6 +684,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
-
- bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
-
- +struct acpi_device *
- +acpi_dev_get_next_dep_dev(struct acpi_device *adev, struct acpi_device *prev);
- struct acpi_device *
- acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
- struct acpi_device *
- --
- 2.33.0
- From d7f298e244aba7f166774f34339fd5d884fa7114 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 16 Nov 2020 21:38:49 +0000
- Subject: [PATCH] i2c: i2c-core-base: Use format macro in i2c_dev_set_name()
- Some places in the kernel allow users to map resources to a device
- using device name (for example, gpiod_lookup_table). Currently
- this involves waiting for the i2c_client to have been registered so we
- can use dev_name(&client->dev). We want to add a function to allow users
- to refer to an i2c device by name before it has been instantiated, so
- create a macro for the format that's accessible outside the i2c layer
- and use it in i2c_dev_set_name()
- Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/i2c/i2c-core-base.c | 4 ++--
- include/linux/i2c.h | 7 +++++++
- 2 files changed, 9 insertions(+), 2 deletions(-)
- diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
- index bdce6d3e5327..f3ecc78dca4e 100644
- --- a/drivers/i2c/i2c-core-base.c
- +++ b/drivers/i2c/i2c-core-base.c
- @@ -813,12 +813,12 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
- struct acpi_device *adev = ACPI_COMPANION(&client->dev);
-
- if (info && info->dev_name) {
- - dev_set_name(&client->dev, "i2c-%s", info->dev_name);
- + dev_set_name(&client->dev, I2C_DEV_NAME_FORMAT, info->dev_name);
- return;
- }
-
- if (adev) {
- - dev_set_name(&client->dev, "i2c-%s", acpi_dev_name(adev));
- + dev_set_name(&client->dev, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
- return;
- }
-
- diff --git a/include/linux/i2c.h b/include/linux/i2c.h
- index a670ae129f4b..b18172f240af 100644
- --- a/include/linux/i2c.h
- +++ b/include/linux/i2c.h
- @@ -39,6 +39,9 @@ enum i2c_slave_event;
- typedef int (*i2c_slave_cb_t)(struct i2c_client *client,
- enum i2c_slave_event event, u8 *val);
-
- +/* I2C Device Name Format - to maintain consistency outside the i2c layer */
- +#define I2C_DEV_NAME_FORMAT "i2c-%s"
- +
- /* I2C Frequency Modes */
- #define I2C_MAX_STANDARD_MODE_FREQ 100000
- #define I2C_MAX_FAST_MODE_FREQ 400000
- @@ -1013,6 +1016,10 @@ static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
- {
- return ERR_PTR(-ENODEV);
- }
- +static inline char *i2c_acpi_dev_name(struct acpi_device *adev)
- +{
- + return NULL;
- +}
- static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
- {
- return NULL;
- --
- 2.33.0
- From b39615bf56e9af6f6f601c992d48b2001c71f50b Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 2 Dec 2020 16:41:42 +0000
- Subject: [PATCH] i2c: i2c-core-acpi: Add i2c_acpi_dev_name()
- We want to refer to an i2c device by name before it has been
- created by the kernel; add a function that constructs the name
- from the acpi device instead.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/i2c/i2c-core-acpi.c | 16 ++++++++++++++++
- include/linux/i2c.h | 1 +
- 2 files changed, 17 insertions(+)
- diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
- index aed579942436..89751415b69b 100644
- --- a/drivers/i2c/i2c-core-acpi.c
- +++ b/drivers/i2c/i2c-core-acpi.c
- @@ -497,6 +497,22 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
- }
- EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
-
- +/**
- + * i2c_acpi_dev_name - Construct i2c device name for devs sourced from ACPI
- + * @adev: ACPI device to construct the name for
- + *
- + * Constructs the name of an i2c device matching the format used by
- + * i2c_dev_set_name() to allow users to refer to an i2c device by name even
- + * before they have been instantiated.
- + *
- + * The caller is responsible for freeing the returned pointer.
- + */
- +char *i2c_acpi_dev_name(struct acpi_device *adev)
- +{
- + return kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
- +}
- +EXPORT_SYMBOL_GPL(i2c_acpi_dev_name);
- +
- #ifdef CONFIG_ACPI_I2C_OPREGION
- static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
- u8 cmd, u8 *data, u8 data_len)
- diff --git a/include/linux/i2c.h b/include/linux/i2c.h
- index b18172f240af..269a2009080c 100644
- --- a/include/linux/i2c.h
- +++ b/include/linux/i2c.h
- @@ -1000,6 +1000,7 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
- u32 i2c_acpi_find_bus_speed(struct device *dev);
- struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
- struct i2c_board_info *info);
- +char *i2c_acpi_dev_name(struct acpi_device *adev);
- struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
- #else
- static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
- --
- 2.33.0
- From 93e728bae8143ccdc46578ce93feec0c40172d85 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 16 Nov 2020 00:16:56 +0000
- Subject: [PATCH] gpio: gpiolib-acpi: Export acpi_get_gpiod()
- I need to be able to translate GPIO resources in an acpi_device's _CRS
- into gpio_descs. Those are represented in _CRS as a pathname to a GPIO
- device plus the pin's index number: this function is perfect for that
- purpose.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/gpio/gpiolib-acpi.c | 3 ++-
- include/linux/acpi.h | 5 +++++
- 2 files changed, 7 insertions(+), 1 deletion(-)
- diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
- index 6f11714ce023..4ae6fd33b783 100644
- --- a/drivers/gpio/gpiolib-acpi.c
- +++ b/drivers/gpio/gpiolib-acpi.c
- @@ -111,7 +111,7 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
- * controller does not have GPIO chip registered at the moment. This is to
- * support probe deferral.
- */
- -static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
- +struct gpio_desc *acpi_get_gpiod(char *path, int pin)
- {
- struct gpio_chip *chip;
- acpi_handle handle;
- @@ -127,6 +127,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
-
- return gpiochip_get_desc(chip, pin);
- }
- +EXPORT_SYMBOL_GPL(acpi_get_gpiod);
-
- static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
- {
- diff --git a/include/linux/acpi.h b/include/linux/acpi.h
- index fdb1d5262ce8..817f53506cfe 100644
- --- a/include/linux/acpi.h
- +++ b/include/linux/acpi.h
- @@ -1080,6 +1080,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
- bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
- struct acpi_resource_gpio **agpio);
- int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
- +struct gpio_desc *acpi_get_gpiod(char *path, int pin);
- #else
- static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
- struct acpi_resource_gpio **agpio)
- @@ -1091,6 +1092,10 @@ static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
- {
- return -ENXIO;
- }
- +struct gpio_desc *acpi_get_gpiod(char *path, int pin)
- +{
- + return NULL;
- +}
- #endif
-
- static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
- --
- 2.33.0
- From f47c23f06fd6656dcc585ad8bcf6223b73f28e49 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 12 Dec 2020 23:56:59 +0000
- Subject: [PATCH] mfd: Remove tps68470 MFD driver
- This driver only covered one scenario in which ACPI devices with _HID
- INT3472 are found, and its functionality has been taken over by the
- intel-skl-int3472 module, so remove it.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/acpi/pmic/Kconfig | 1 -
- drivers/gpio/Kconfig | 1 -
- drivers/mfd/Kconfig | 18 --------
- drivers/mfd/Makefile | 1 -
- drivers/mfd/tps68470.c | 97 ---------------------------------------
- 5 files changed, 118 deletions(-)
- delete mode 100644 drivers/mfd/tps68470.c
- diff --git a/drivers/acpi/pmic/Kconfig b/drivers/acpi/pmic/Kconfig
- index 56bbcb2ce61b..e27d8ef3a32c 100644
- --- a/drivers/acpi/pmic/Kconfig
- +++ b/drivers/acpi/pmic/Kconfig
- @@ -52,7 +52,6 @@ endif # PMIC_OPREGION
-
- config TPS68470_PMIC_OPREGION
- bool "ACPI operation region support for TPS68470 PMIC"
- - depends on MFD_TPS68470
- help
- This config adds ACPI operation region support for TI TPS68470 PMIC.
- TPS68470 device is an advanced power management unit that powers
- diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
- index d1300fc003ed..923768bf2719 100644
- --- a/drivers/gpio/Kconfig
- +++ b/drivers/gpio/Kconfig
- @@ -1321,7 +1321,6 @@ config GPIO_TPS65912
-
- config GPIO_TPS68470
- bool "TPS68470 GPIO"
- - depends on MFD_TPS68470
- help
- Select this option to enable GPIO driver for the TPS68470
- chip family.
- diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
- index b8847ae04d93..bd655a383cee 100644
- --- a/drivers/mfd/Kconfig
- +++ b/drivers/mfd/Kconfig
- @@ -1534,24 +1534,6 @@ config MFD_TPS65217
- This driver can also be built as a module. If so, the module
- will be called tps65217.
-
- -config MFD_TPS68470
- - bool "TI TPS68470 Power Management / LED chips"
- - depends on ACPI && PCI && I2C=y
- - depends on I2C_DESIGNWARE_PLATFORM=y
- - select MFD_CORE
- - select REGMAP_I2C
- - help
- - If you say yes here you get support for the TPS68470 series of
- - Power Management / LED chips.
- -
- - These include voltage regulators, LEDs and other features
- - that are often used in portable devices.
- -
- - This option is a bool as it provides an ACPI operation
- - region, which must be available before any of the devices
- - using this are probed. This option also configures the
- - designware-i2c driver to be built-in, for the same reason.
- -
- config MFD_TI_LP873X
- tristate "TI LP873X Power Management IC"
- depends on I2C
- diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
- index 1780019d2474..a23f38c4c38a 100644
- --- a/drivers/mfd/Makefile
- +++ b/drivers/mfd/Makefile
- @@ -105,7 +105,6 @@ obj-$(CONFIG_MFD_TPS65910) += tps65910.o
- obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
- obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
- obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
- -obj-$(CONFIG_MFD_TPS68470) += tps68470.o
- obj-$(CONFIG_MFD_TPS80031) += tps80031.o
- obj-$(CONFIG_MENELAUS) += menelaus.o
-
- diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c
- deleted file mode 100644
- index 4a4df4ffd18c..000000000000
- --- a/drivers/mfd/tps68470.c
- +++ /dev/null
- @@ -1,97 +0,0 @@
- -// SPDX-License-Identifier: GPL-2.0
- -/*
- - * TPS68470 chip Parent driver
- - *
- - * Copyright (C) 2017 Intel Corporation
- - *
- - * Authors:
- - * Rajmohan Mani <rajmohan.mani@intel.com>
- - * Tianshu Qiu <tian.shu.qiu@intel.com>
- - * Jian Xu Zheng <jian.xu.zheng@intel.com>
- - * Yuning Pu <yuning.pu@intel.com>
- - */
- -
- -#include <linux/acpi.h>
- -#include <linux/delay.h>
- -#include <linux/i2c.h>
- -#include <linux/init.h>
- -#include <linux/mfd/core.h>
- -#include <linux/mfd/tps68470.h>
- -#include <linux/regmap.h>
- -
- -static const struct mfd_cell tps68470s[] = {
- - { .name = "tps68470-gpio" },
- - { .name = "tps68470_pmic_opregion" },
- -};
- -
- -static const struct regmap_config tps68470_regmap_config = {
- - .reg_bits = 8,
- - .val_bits = 8,
- - .max_register = TPS68470_REG_MAX,
- -};
- -
- -static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
- -{
- - unsigned int version;
- - int ret;
- -
- - /* Force software reset */
- - ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
- - if (ret)
- - return ret;
- -
- - ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
- - if (ret) {
- - dev_err(dev, "Failed to read revision register: %d\n", ret);
- - return ret;
- - }
- -
- - dev_info(dev, "TPS68470 REVID: 0x%x\n", version);
- -
- - return 0;
- -}
- -
- -static int tps68470_probe(struct i2c_client *client)
- -{
- - struct device *dev = &client->dev;
- - struct regmap *regmap;
- - int ret;
- -
- - regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
- - if (IS_ERR(regmap)) {
- - dev_err(dev, "devm_regmap_init_i2c Error %ld\n",
- - PTR_ERR(regmap));
- - return PTR_ERR(regmap);
- - }
- -
- - i2c_set_clientdata(client, regmap);
- -
- - ret = tps68470_chip_init(dev, regmap);
- - if (ret < 0) {
- - dev_err(dev, "TPS68470 Init Error %d\n", ret);
- - return ret;
- - }
- -
- - ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, tps68470s,
- - ARRAY_SIZE(tps68470s), NULL, 0, NULL);
- - if (ret < 0) {
- - dev_err(dev, "devm_mfd_add_devices failed: %d\n", ret);
- - return ret;
- - }
- -
- - return 0;
- -}
- -
- -static const struct acpi_device_id tps68470_acpi_ids[] = {
- - {"INT3472"},
- - {},
- -};
- -
- -static struct i2c_driver tps68470_driver = {
- - .driver = {
- - .name = "tps68470",
- - .acpi_match_table = tps68470_acpi_ids,
- - },
- - .probe_new = tps68470_probe,
- -};
- -builtin_i2c_driver(tps68470_driver);
- --
- 2.33.0
- From 8fe7e113fe28d240202bf5047de448b5cd86a6de Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Fri, 15 Jan 2021 12:37:31 +0000
- Subject: [PATCH] platform: x86: Add intel_skl_int3472 driver
- ACPI devices with _HID INT3472 are currently matched to the tps68470
- driver, however this does not cover all situations in which that _HID
- occurs. We've encountered three possibilities:
- 1. On Chrome OS devices, an ACPI device with _HID INT3472 (representing
- a physical tps68470 device) that requires a GPIO and OpRegion driver
- 2. On devices designed for Windows, an ACPI device with _HID INT3472
- (again representing a physical tps68470 device) which requires GPIO,
- Clock and Regulator drivers.
- 3. On other devices designed for Windows, an ACPI device with _HID
- INT3472 which does NOT represent a physical tps68470, and is instead
- used as a dummy device to group some system GPIO lines which are meant
- to be consumed by the sensor that is dependent on this entry.
- This commit adds a new module, registering a platform driver to deal
- with the 3rd scenario plus an i2c-driver to deal with #1 and #2, by
- querying the CLDB buffer found against INT3472 entries to determine
- which is most appropriate.
- Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- MAINTAINERS | 5 +
- drivers/platform/x86/Kconfig | 25 +
- drivers/platform/x86/Makefile | 5 +
- .../platform/x86/intel_skl_int3472_common.c | 100 ++++
- .../platform/x86/intel_skl_int3472_common.h | 99 ++++
- .../platform/x86/intel_skl_int3472_discrete.c | 489 ++++++++++++++++++
- .../platform/x86/intel_skl_int3472_tps68470.c | 145 ++++++
- 7 files changed, 868 insertions(+)
- create mode 100644 drivers/platform/x86/intel_skl_int3472_common.c
- create mode 100644 drivers/platform/x86/intel_skl_int3472_common.h
- create mode 100644 drivers/platform/x86/intel_skl_int3472_discrete.c
- create mode 100644 drivers/platform/x86/intel_skl_int3472_tps68470.c
- diff --git a/MAINTAINERS b/MAINTAINERS
- index f313ba49c2b8..7bec93adaae5 100644
- --- a/MAINTAINERS
- +++ b/MAINTAINERS
- @@ -9045,6 +9045,11 @@ S: Maintained
- F: arch/x86/include/asm/intel_scu_ipc.h
- F: drivers/platform/x86/intel_scu_*
-
- +INTEL SKL INT3472 ACPI DEVICE DRIVER
- +M: Daniel Scally <djrscally@gmail.com>
- +S: Maintained
- +F: drivers/platform/x86/intel_skl_int3472_*
- +
- INTEL SPEED SELECT TECHNOLOGY
- M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
- L: platform-driver-x86@vger.kernel.org
- diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
- index 533998040530..ab8324034c76 100644
- --- a/drivers/platform/x86/Kconfig
- +++ b/drivers/platform/x86/Kconfig
- @@ -807,6 +807,31 @@ config INTEL_CHT_INT33FE
- device and CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m
- for Type-C device.
-
- +config INTEL_SKL_INT3472
- + tristate "Intel SkyLake ACPI INT3472 Driver"
- + depends on X86 && ACPI
- + select REGMAP_I2C
- + help
- + This driver adds support for the INT3472 ACPI devices found on some
- + Intel SkyLake devices.
- +
- + There are 3 kinds of INT3472 ACPI device possible; two for devices
- + designed for Windows (either with or without a physical tps68470
- + PMIC) and one designed for Chrome OS. This driver handles all three
- + situations by discovering information it needs to discern them at
- + runtime.
- +
- + If your device was designed for Chrome OS, this driver will provide
- + an ACPI operation region, which must be available before any of the
- + devices using this are probed. For this reason, you should select Y
- + if your device was designed for ChromeOS. This option also configures
- + the designware-i2c driver to be built-in, for the same reason.
- +
- + Say Y or M here if you have a SkyLake device designed for use
- + with Windows or ChromeOS. Say N here if you are not sure.
- +
- + The module will be named "intel-skl-int3472"
- +
- config INTEL_HID_EVENT
- tristate "INTEL HID Event"
- depends on ACPI
- diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
- index f552cbfb7914..dd8fc06b224c 100644
- --- a/drivers/platform/x86/Makefile
- +++ b/drivers/platform/x86/Makefile
- @@ -79,6 +79,11 @@ obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
- obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
- obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
- obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
- +obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o
- +intel_skl_int3472-objs := intel_skl_int3472_common.o \
- + intel_skl_int3472_discrete.o \
- + intel_skl_int3472_tps68470.o
- +
- obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
-
- # Microsoft
- diff --git a/drivers/platform/x86/intel_skl_int3472_common.c b/drivers/platform/x86/intel_skl_int3472_common.c
- new file mode 100644
- index 000000000000..08cb9d3c06aa
- --- /dev/null
- +++ b/drivers/platform/x86/intel_skl_int3472_common.c
- @@ -0,0 +1,100 @@
- +// SPDX-License-Identifier: GPL-2.0
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +
- +#include <linux/acpi.h>
- +#include <linux/i2c.h>
- +#include <linux/platform_device.h>
- +
- +#include "intel_skl_int3472_common.h"
- +
- +int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
- + struct int3472_cldb *cldb)
- +{
- + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- + acpi_handle handle = adev->handle;
- + union acpi_object *obj;
- + acpi_status status;
- + int ret = 0;
- +
- + status = acpi_evaluate_object(handle, "CLDB", NULL, &buffer);
- + if (ACPI_FAILURE(status))
- + return -ENODEV;
- +
- + obj = buffer.pointer;
- + if (!obj) {
- + dev_err(&adev->dev, "ACPI device has no CLDB object\n");
- + return -ENODEV;
- + }
- +
- + if (obj->type != ACPI_TYPE_BUFFER) {
- + dev_err(&adev->dev, "CLDB object is not an ACPI buffer\n");
- + ret = -EINVAL;
- + goto out_free_buff;
- + }
- +
- + if (obj->buffer.length > sizeof(*cldb)) {
- + dev_err(&adev->dev, "The CLDB buffer is too large\n");
- + ret = -EINVAL;
- + goto out_free_buff;
- + }
- +
- + memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
- +
- +out_free_buff:
- + kfree(buffer.pointer);
- + return ret;
- +}
- +
- +static const struct acpi_device_id int3472_device_id[] = {
- + { "INT3472", 0 },
- + { },
- +};
- +MODULE_DEVICE_TABLE(acpi, int3472_device_id);
- +
- +static struct platform_driver int3472_discrete = {
- + .driver = {
- + .name = "int3472-discrete",
- + .acpi_match_table = int3472_device_id,
- + },
- + .probe = skl_int3472_discrete_probe,
- + .remove = skl_int3472_discrete_remove,
- +};
- +
- +static struct i2c_driver int3472_tps68470 = {
- + .driver = {
- + .name = "int3472-tps68470",
- + .acpi_match_table = int3472_device_id,
- + },
- + .probe_new = skl_int3472_tps68470_probe,
- +};
- +
- +static int skl_int3472_init(void)
- +{
- + int ret = 0;
- +
- + ret = platform_driver_register(&int3472_discrete);
- + if (ret)
- + return ret;
- +
- + ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
- + if (ret)
- + goto err_unregister_plat_drv;
- +
- + return 0;
- +
- +err_unregister_plat_drv:
- + platform_driver_unregister(&int3472_discrete);
- + return ret;
- +}
- +module_init(skl_int3472_init);
- +
- +static void skl_int3472_exit(void)
- +{
- + platform_driver_unregister(&int3472_discrete);
- + i2c_del_driver(&int3472_tps68470);
- +}
- +module_exit(skl_int3472_exit);
- +
- +MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
- +MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
- +MODULE_LICENSE("GPL v2");
- diff --git a/drivers/platform/x86/intel_skl_int3472_common.h b/drivers/platform/x86/intel_skl_int3472_common.h
- new file mode 100644
- index 000000000000..4ac6bb2b223f
- --- /dev/null
- +++ b/drivers/platform/x86/intel_skl_int3472_common.h
- @@ -0,0 +1,99 @@
- +/* SPDX-License-Identifier: GPL-2.0 */
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +#include <linux/regulator/machine.h>
- +#include <linux/clk-provider.h>
- +#include <linux/gpio/machine.h>
- +#include <linux/regulator/driver.h>
- +#include <linux/types.h>
- +
- +/* PMIC GPIO Types */
- +#define INT3472_GPIO_TYPE_RESET 0x00
- +#define INT3472_GPIO_TYPE_POWERDOWN 0x01
- +#define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c
- +#define INT3472_GPIO_TYPE_POWER_ENABLE 0x0b
- +#define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d
- +#define INT3472_PDEV_MAX_NAME_LEN 23
- +#define INT3472_MAX_SENSOR_GPIOS 3
- +#define GPIO_REGULATOR_NAME_LENGTH 27
- +#define GPIO_REGULATOR_SUPPLY_NAME_LENGTH 9
- +
- +#define INT3472_REGULATOR(_NAME, _SUPPLY, _OPS) \
- + (const struct regulator_desc) { \
- + .name = _NAME, \
- + .supply_name = _SUPPLY, \
- + .id = 0, \
- + .type = REGULATOR_VOLTAGE, \
- + .ops = _OPS, \
- + .owner = THIS_MODULE, \
- + }
- +
- +#define INT3472_GPIO_FUNCTION_REMAP(_PIN, _FUNCTION) \
- + (const struct int3472_gpio_function_remap) { \
- + .documented = _PIN, \
- + .actual = _FUNCTION \
- + }
- +
- +#define to_int3472_clk(hw) \
- + container_of(hw, struct int3472_gpio_clock, clk_hw)
- +
- +struct int3472_cldb {
- + u8 version;
- + /*
- + * control logic type
- + * 0: UNKNOWN
- + * 1: DISCRETE(CRD-D)
- + * 2: PMIC TPS68470
- + * 3: PMIC uP6641
- + */
- + u8 control_logic_type;
- + u8 control_logic_id;
- + u8 sensor_card_sku;
- + u8 reserved[28];
- +};
- +
- +struct int3472_gpio_regulator {
- + char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
- + char supply_name[GPIO_REGULATOR_SUPPLY_NAME_LENGTH];
- + struct gpio_desc *gpio;
- + struct regulator_dev *rdev;
- + struct regulator_desc rdesc;
- +};
- +
- +struct int3472_gpio_clock {
- + struct clk *clk;
- + struct clk_hw clk_hw;
- + struct gpio_desc *gpio;
- +};
- +
- +struct int3472_device {
- + struct acpi_device *adev;
- + struct platform_device *pdev;
- + struct acpi_device *sensor;
- + char *sensor_name;
- +
- + unsigned int n_gpios; /* how many GPIOs have we seen */
- +
- + struct int3472_gpio_regulator regulator;
- + struct int3472_gpio_clock clock;
- +
- + unsigned int n_sensor_gpios; /* how many have we mapped to sensor */
- + bool gpios_mapped;
- + struct gpiod_lookup_table gpios;
- +};
- +
- +struct int3472_gpio_function_remap {
- + char *documented;
- + char *actual;
- +};
- +
- +struct int3472_sensor_config {
- + char *sensor_module_name;
- + struct regulator_consumer_supply supply_map;
- + const struct int3472_gpio_function_remap *function_maps;
- +};
- +
- +int skl_int3472_discrete_probe(struct platform_device *pdev);
- +int skl_int3472_discrete_remove(struct platform_device *pdev);
- +int skl_int3472_tps68470_probe(struct i2c_client *client);
- +int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
- + struct int3472_cldb *cldb);
- diff --git a/drivers/platform/x86/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel_skl_int3472_discrete.c
- new file mode 100644
- index 000000000000..ea7e57f3e3f0
- --- /dev/null
- +++ b/drivers/platform/x86/intel_skl_int3472_discrete.c
- @@ -0,0 +1,489 @@
- +// SPDX-License-Identifier: GPL-2.0
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +
- +#include <linux/acpi.h>
- +#include <linux/clkdev.h>
- +#include <linux/gpio/consumer.h>
- +#include <linux/i2c.h>
- +#include <linux/kernel.h>
- +#include <linux/module.h>
- +#include <linux/platform_device.h>
- +#include <linux/regulator/driver.h>
- +
- +#include "intel_skl_int3472_common.h"
- +
- +/* 79234640-9e10-4fea-a5c1b5aa8b19756f */
- +static const guid_t int3472_gpio_guid =
- + GUID_INIT(0x79234640, 0x9e10, 0x4fea,
- + 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
- +
- +/* 822ace8f-2814-4174-a56b5f029fe079ee */
- +static const guid_t cio2_sensor_module_guid =
- + GUID_INIT(0x822ace8f, 0x2814, 0x4174,
- + 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
- +
- +/*
- + * Here follows platform specific mapping information that we can pass to
- + * the functions mapping resources to the sensors. Where the sensors have
- + * a power enable pin defined in DSDT we need to provide a supply name so
- + * the sensor drivers can find the regulator. Optionally, we can provide a
- + * NULL terminated array of function name mappings to deal with any platform
- + * specific deviations from the documented behaviour of GPIOs.
- + *
- + * Map a GPIO function name to NULL to prevent the driver from mapping that
- + * GPIO at all.
- + */
- +
- +static const struct int3472_gpio_function_remap ov2680_gpio_function_remaps[] = {
- + INT3472_GPIO_FUNCTION_REMAP("reset", NULL),
- + INT3472_GPIO_FUNCTION_REMAP("powerdown", "reset"),
- + { }
- +};
- +
- +static struct int3472_sensor_config int3472_sensor_configs[] = {
- + /* Lenovo Miix 510-12ISK - OV2680, Front */
- + { "GNDF140809R", { 0 }, ov2680_gpio_function_remaps},
- + /* Lenovo Miix 510-12ISK - OV5648, Rear */
- + { "GEFF150023R", REGULATOR_SUPPLY("avdd", "i2c-OVTI5648:00"), NULL},
- + /* Surface Go 1&2 - OV5693, Front */
- + { "YHCU", REGULATOR_SUPPLY("avdd", "i2c-INT33BE:00"), NULL},
- +};
- +
- +/*
- + * The regulators have to have .ops to be valid, but the only ops we actually
- + * support are .enable and .disable which are handled via .ena_gpiod. Pass an
- + * empty struct to clear the check without lying about capabilities.
- + */
- +static const struct regulator_ops int3472_gpio_regulator_ops = { 0 };
- +
- +static int skl_int3472_clk_enable(struct clk_hw *hw)
- +{
- + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
- +
- + gpiod_set_value(clk->gpio, 1);
- +
- + return 0;
- +}
- +
- +static void skl_int3472_clk_disable(struct clk_hw *hw)
- +{
- + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
- +
- + gpiod_set_value(clk->gpio, 0);
- +}
- +
- +static int skl_int3472_clk_prepare(struct clk_hw *hw)
- +{
- + /*
- + * We're just turning a GPIO on to enable, so nothing to do here, but
- + * we want to provide the op so prepare_enable() works.
- + */
- + return 0;
- +}
- +
- +static void skl_int3472_clk_unprepare(struct clk_hw *hw)
- +{
- + /* Likewise, nothing to do here... */
- +}
- +
- +static const struct clk_ops skl_int3472_clock_ops = {
- + .prepare = skl_int3472_clk_prepare,
- + .unprepare = skl_int3472_clk_unprepare,
- + .enable = skl_int3472_clk_enable,
- + .disable = skl_int3472_clk_disable,
- +};
- +
- +static struct int3472_sensor_config *
- +int3472_get_sensor_module_config(struct int3472_device *int3472)
- +{
- + unsigned int i = ARRAY_SIZE(int3472_sensor_configs);
- + struct int3472_sensor_config *ret;
- + union acpi_object *obj;
- +
- + obj = acpi_evaluate_dsm_typed(int3472->sensor->handle,
- + &cio2_sensor_module_guid, 0x00,
- + 0x01, NULL, ACPI_TYPE_STRING);
- +
- + if (!obj) {
- + dev_err(&int3472->pdev->dev,
- + "Failed to get sensor module string from _DSM\n");
- + return ERR_PTR(-ENODEV);
- + }
- +
- + if (obj->string.type != ACPI_TYPE_STRING) {
- + dev_err(&int3472->pdev->dev,
- + "Sensor _DSM returned a non-string value\n");
- + ret = ERR_PTR(-EINVAL);
- + goto out_free_obj;
- + }
- +
- + ret = ERR_PTR(-ENODEV);
- + while (i--) {
- + if (!strcmp(int3472_sensor_configs[i].sensor_module_name,
- + obj->string.pointer)) {
- + ret = &int3472_sensor_configs[i];
- + goto out_free_obj;
- + }
- + }
- +
- +out_free_obj:
- + ACPI_FREE(obj);
- + return ret;
- +}
- +
- +static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
- + struct acpi_resource *ares,
- + char *func, u32 polarity)
- +{
- + char *path = ares->data.gpio.resource_source.string_ptr;
- + struct int3472_sensor_config *sensor_config;
- + struct gpiod_lookup table_entry;
- + struct acpi_device *adev;
- + acpi_handle handle;
- + acpi_status status;
- + int ret;
- +
- + sensor_config = int3472_get_sensor_module_config(int3472);
- + if (!IS_ERR(sensor_config) && sensor_config->function_maps) {
- + unsigned int i = 0;
- +
- + while (sensor_config->function_maps[i].documented) {
- + if (!strcmp(func, sensor_config->function_maps[i].documented)) {
- + func = sensor_config->function_maps[i].actual;
- +
- + break;
- + }
- +
- + i++;
- + }
- + }
- +
- + if (!func)
- + return 0;
- +
- + if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) {
- + dev_warn(&int3472->pdev->dev, "Too many GPIOs mapped\n");
- + return -EINVAL;
- + }
- +
- + status = acpi_get_handle(NULL, path, &handle);
- + if (ACPI_FAILURE(status))
- + return -EINVAL;
- +
- + ret = acpi_bus_get_device(handle, &adev);
- + if (ret)
- + return -ENODEV;
- +
- + table_entry = (struct gpiod_lookup)GPIO_LOOKUP_IDX(acpi_dev_name(adev),
- + ares->data.gpio.pin_table[0],
- + func, 0, polarity);
- +
- + memcpy(&int3472->gpios.table[int3472->n_sensor_gpios], &table_entry,
- + sizeof(table_entry));
- +
- + int3472->n_sensor_gpios++;
- +
- + return 0;
- +}
- +
- +static int int3472_register_clock(struct int3472_device *int3472,
- + struct acpi_resource *ares)
- +{
- + char *path = ares->data.gpio.resource_source.string_ptr;
- + struct clk_init_data init = { };
- + int ret = 0;
- +
- + init.name = kasprintf(GFP_KERNEL, "%s-clk", acpi_dev_name(int3472->adev));
- + init.ops = &skl_int3472_clock_ops;
- +
- + int3472->clock.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
- + if (IS_ERR(int3472->clock.gpio)) {
- + ret = PTR_ERR(int3472->clock.gpio);
- + goto out_free_init_name;
- + }
- +
- + int3472->clock.clk_hw.init = &init;
- + int3472->clock.clk = clk_register(&int3472->adev->dev,
- + &int3472->clock.clk_hw);
- + if (IS_ERR(int3472->clock.clk)) {
- + ret = PTR_ERR(int3472->clock.clk);
- + goto err_put_gpio;
- + }
- +
- + ret = clk_register_clkdev(int3472->clock.clk, "xvclk", int3472->sensor_name);
- + if (ret)
- + goto err_unregister_clk;
- +
- + goto out_free_init_name;
- +
- +err_unregister_clk:
- + clk_unregister(int3472->clock.clk);
- +err_put_gpio:
- + gpiod_put(int3472->clock.gpio);
- +out_free_init_name:
- + kfree(init.name);
- +
- + return ret;
- +}
- +
- +static int int3472_register_regulator(struct int3472_device *int3472,
- + struct acpi_resource *ares)
- +{
- + char *path = ares->data.gpio.resource_source.string_ptr;
- + struct int3472_sensor_config *sensor_config;
- + struct regulator_init_data init_data = { };
- + struct int3472_gpio_regulator *regulator;
- + struct regulator_config cfg = { };
- + int ret;
- +
- + sensor_config = int3472_get_sensor_module_config(int3472);
- + if (IS_ERR_OR_NULL(sensor_config)) {
- + dev_err(&int3472->pdev->dev, "No sensor module config\n");
- + return PTR_ERR(sensor_config);
- + }
- +
- + if (!sensor_config->supply_map.supply) {
- + dev_err(&int3472->pdev->dev, "No supply name defined\n");
- + return -ENODEV;
- + }
- +
- + init_data.supply_regulator = NULL;
- + init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
- + init_data.num_consumer_supplies = 1;
- + init_data.consumer_supplies = &sensor_config->supply_map;
- +
- + snprintf(int3472->regulator.regulator_name, GPIO_REGULATOR_NAME_LENGTH,
- + "int3472-discrete-regulator");
- + snprintf(int3472->regulator.supply_name, GPIO_REGULATOR_SUPPLY_NAME_LENGTH,
- + "supply-0");
- +
- + int3472->regulator.rdesc = INT3472_REGULATOR(int3472->regulator.regulator_name,
- + int3472->regulator.supply_name,
- + &int3472_gpio_regulator_ops);
- +
- + int3472->regulator.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
- + if (IS_ERR(int3472->regulator.gpio)) {
- + ret = PTR_ERR(int3472->regulator.gpio);
- + goto err_free_regulator;
- + }
- +
- + cfg.dev = &int3472->adev->dev;
- + cfg.init_data = &init_data;
- + cfg.ena_gpiod = int3472->regulator.gpio;
- +
- + int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc, &cfg);
- + if (IS_ERR(int3472->regulator.rdev)) {
- + ret = PTR_ERR(int3472->regulator.rdev);
- + goto err_free_gpio;
- + }
- +
- + return 0;
- +
- +err_free_gpio:
- + gpiod_put(regulator->gpio);
- +err_free_regulator:
- + kfree(regulator);
- +
- + return ret;
- +}
- +
- +/**
- + * int3472_handle_gpio_resources: maps PMIC resources to consuming sensor
- + * @ares: A pointer to a &struct acpi_resource
- + * @data: A pointer to a &struct int3472_device
- + *
- + * This function handles GPIO resources that are against an INT3472
- + * ACPI device, by checking the value of the corresponding _DSM entry.
- + * This will return a 32bit int, where the lowest byte represents the
- + * function of the GPIO pin:
- + *
- + * 0x00 Reset
- + * 0x01 Power down
- + * 0x0b Power enable
- + * 0x0c Clock enable
- + * 0x0d Privacy LED
- + *
- + * There are some known platform specific quirks where that does not quite
- + * hold up; for example where a pin with type 0x01 (Power down) is mapped to
- + * a sensor pin that performs a reset function. These will be handled by the
- + * mapping sub-functions.
- + *
- + * GPIOs will either be mapped directly to the sensor device or else used
- + * to create clocks and regulators via the usual frameworks.
- + *
- + * Return:
- + * * 0 - When all resources found are handled properly.
- + * * -EINVAL - If the resource is not a GPIO IO resource
- + * * -ENODEV - If the resource has no corresponding _DSM entry
- + * * -Other - Errors propagated from one of the sub-functions.
- + */
- +static int int3472_handle_gpio_resources(struct acpi_resource *ares,
- + void *data)
- +{
- + struct int3472_device *int3472 = data;
- + union acpi_object *obj;
- + int ret = 0;
- +
- + if (ares->type != ACPI_RESOURCE_TYPE_GPIO ||
- + ares->data.gpio.connection_type != ACPI_RESOURCE_GPIO_TYPE_IO)
- + return EINVAL; /* Deliberately positive so parsing continues */
- +
- + /*
- + * n_gpios + 2 because the index of this _DSM function is 1-based and
- + * the first function is just a count.
- + */
- + obj = acpi_evaluate_dsm_typed(int3472->adev->handle,
- + &int3472_gpio_guid, 0x00,
- + int3472->n_gpios + 2,
- + NULL, ACPI_TYPE_INTEGER);
- +
- + if (!obj) {
- + dev_warn(&int3472->pdev->dev,
- + "No _DSM entry for this GPIO pin\n");
- + return ENODEV;
- + }
- +
- + switch (obj->integer.value & 0xff) {
- + case INT3472_GPIO_TYPE_RESET:
- + ret = int3472_map_gpio_to_sensor(int3472, ares, "reset",
- + GPIO_ACTIVE_LOW);
- + if (ret)
- + dev_err(&int3472->pdev->dev,
- + "Failed to map reset pin to sensor\n");
- +
- + break;
- + case INT3472_GPIO_TYPE_POWERDOWN:
- + ret = int3472_map_gpio_to_sensor(int3472, ares, "powerdown",
- + GPIO_ACTIVE_LOW);
- + if (ret)
- + dev_err(&int3472->pdev->dev,
- + "Failed to map powerdown pin to sensor\n");
- +
- + break;
- + case INT3472_GPIO_TYPE_CLK_ENABLE:
- + ret = int3472_register_clock(int3472, ares);
- + if (ret)
- + dev_err(&int3472->pdev->dev,
- + "Failed to map clock to sensor\n");
- +
- + break;
- + case INT3472_GPIO_TYPE_POWER_ENABLE:
- + ret = int3472_register_regulator(int3472, ares);
- + if (ret) {
- + dev_err(&int3472->pdev->dev,
- + "Failed to map regulator to sensor\n");
- + }
- +
- + break;
- + case INT3472_GPIO_TYPE_PRIVACY_LED:
- + ret = int3472_map_gpio_to_sensor(int3472, ares, "indicator-led",
- + GPIO_ACTIVE_HIGH);
- + if (ret)
- + dev_err(&int3472->pdev->dev,
- + "Failed to map indicator led to sensor\n");
- +
- + break;
- + default:
- + dev_warn(&int3472->pdev->dev,
- + "GPIO type 0x%llx unknown; the sensor may not work\n",
- + (obj->integer.value & 0xff));
- + ret = EINVAL;
- + }
- +
- + int3472->n_gpios++;
- + ACPI_FREE(obj);
- +
- + return ret;
- +}
- +
- +static int int3472_parse_crs(struct int3472_device *int3472)
- +{
- + struct list_head resource_list;
- + int ret = 0;
- +
- + INIT_LIST_HEAD(&resource_list);
- +
- + ret = acpi_dev_get_resources(int3472->adev, &resource_list,
- + int3472_handle_gpio_resources, int3472);
- +
- + if (!ret) {
- + gpiod_add_lookup_table(&int3472->gpios);
- + int3472->gpios_mapped = true;
- + }
- +
- + acpi_dev_free_resource_list(&resource_list);
- +
- + return ret;
- +}
- +
- +int skl_int3472_discrete_probe(struct platform_device *pdev)
- +{
- + struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
- + struct int3472_device *int3472;
- + struct int3472_cldb cldb;
- + int ret = 0;
- +
- + ret = skl_int3472_get_cldb_buffer(adev, &cldb);
- + if (ret || cldb.control_logic_type != 1)
- + return -EINVAL;
- +
- + int3472 = kzalloc(sizeof(*int3472) +
- + ((INT3472_MAX_SENSOR_GPIOS + 1) * sizeof(struct gpiod_lookup)),
- + GFP_KERNEL);
- + if (!int3472)
- + return -ENOMEM;
- +
- + int3472->adev = adev;
- + int3472->pdev = pdev;
- + platform_set_drvdata(pdev, int3472);
- +
- + int3472->sensor = acpi_dev_get_next_dep_dev(adev, NULL);
- + if (!int3472->sensor) {
- + dev_err(&pdev->dev,
- + "This INT3472 entry seems to have no dependents.\n");
- + ret = -ENODEV;
- + goto err_free_int3472;
- + }
- + int3472->sensor_name = i2c_acpi_dev_name(int3472->sensor);
- + int3472->gpios.dev_id = int3472->sensor_name;
- +
- + ret = int3472_parse_crs(int3472);
- + if (ret) {
- + skl_int3472_discrete_remove(pdev);
- + goto err_return_ret;
- + }
- +
- + return 0;
- +
- +err_free_int3472:
- + kfree(int3472);
- +err_return_ret:
- + return ret;
- +}
- +
- +int skl_int3472_discrete_remove(struct platform_device *pdev)
- +{
- + struct int3472_device *int3472;
- +
- + int3472 = platform_get_drvdata(pdev);
- +
- + if (int3472->gpios_mapped)
- + gpiod_remove_lookup_table(&int3472->gpios);
- +
- + if (!IS_ERR_OR_NULL(int3472->regulator.rdev)) {
- + gpiod_put(int3472->regulator.gpio);
- + regulator_unregister(int3472->regulator.rdev);
- + }
- +
- + if (!IS_ERR_OR_NULL(int3472->clock.clk)) {
- + gpiod_put(int3472->clock.gpio);
- + clk_unregister(int3472->clock.clk);
- + }
- +
- + acpi_dev_put(int3472->sensor);
- +
- + kfree(int3472->sensor_name);
- + kfree(int3472);
- +
- + return 0;
- +}
- diff --git a/drivers/platform/x86/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel_skl_int3472_tps68470.c
- new file mode 100644
- index 000000000000..3fe27ec0caff
- --- /dev/null
- +++ b/drivers/platform/x86/intel_skl_int3472_tps68470.c
- @@ -0,0 +1,145 @@
- +// SPDX-License-Identifier: GPL-2.0
- +/* Author: Dan Scally <djrscally@gmail.com> */
- +
- +#include <linux/i2c.h>
- +#include <linux/mfd/tps68470.h>
- +#include <linux/platform_device.h>
- +#include <linux/regmap.h>
- +
- +#include "intel_skl_int3472_common.h"
- +
- +static const struct regmap_config tps68470_regmap_config = {
- + .reg_bits = 8,
- + .val_bits = 8,
- + .max_register = TPS68470_REG_MAX,
- +};
- +
- +static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
- +{
- + unsigned int version;
- + int ret;
- +
- + /* Force software reset */
- + ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
- + if (ret)
- + return ret;
- +
- + ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
- + if (ret) {
- + dev_err(dev, "Failed to read revision register: %d\n", ret);
- + return ret;
- + }
- +
- + dev_info(dev, "TPS68470 REVID: 0x%x\n", version);
- +
- + return 0;
- +}
- +
- +static struct platform_device *
- +skl_int3472_register_pdev(const char *name, struct device *parent)
- +{
- + struct platform_device *pdev;
- + int ret;
- +
- + pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
- + if (IS_ERR_OR_NULL(pdev))
- + return ERR_PTR(-ENOMEM);
- +
- + pdev->dev.parent = parent;
- + pdev->driver_override = kstrndup(pdev->name, INT3472_PDEV_MAX_NAME_LEN,
- + GFP_KERNEL);
- +
- + ret = platform_device_add(pdev);
- + if (ret) {
- + platform_device_put(pdev);
- + return ERR_PTR(ret);
- + }
- +
- + return pdev;
- +}
- +
- +int skl_int3472_tps68470_probe(struct i2c_client *client)
- +{
- + struct acpi_device *adev = ACPI_COMPANION(&client->dev);
- + struct platform_device *regulator_dev;
- + struct platform_device *opregion_dev;
- + struct platform_device *gpio_dev;
- + struct int3472_cldb cldb = { 0 };
- + struct platform_device *clk_dev;
- + bool cldb_present = true;
- + struct regmap *regmap;
- + int ret = 0;
- +
- + regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
- + if (IS_ERR(regmap)) {
- + dev_err(&client->dev, "devm_regmap_init_i2c Error %ld\n",
- + PTR_ERR(regmap));
- + return PTR_ERR(regmap);
- + }
- +
- + i2c_set_clientdata(client, regmap);
- +
- + ret = tps68470_chip_init(&client->dev, regmap);
- + if (ret < 0) {
- + dev_err(&client->dev, "TPS68470 Init Error %d\n", ret);
- + return ret;
- + }
- +
- + /*
- + * Check CLDB buffer against the PMIC's adev. If present, then we check
- + * the value of control_logic_type field and follow one of the following
- + * scenarios:
- + *
- + * 1. No CLDB - likely ACPI tables designed for ChromeOS. We create
- + * platform devices for the GPIOs and OpRegion drivers.
- + *
- + * 2. CLDB, with control_logic_type = 2 - probably ACPI tables made
- + * for Windows 2-in-1 platforms. Register pdevs for GPIO, Clock and
- + * Regulator drivers to bind to.
- + *
- + * 3. Any other value in control_logic_type, we should never have
- + * gotten to this point; crash and burn.
- + */
- + ret = skl_int3472_get_cldb_buffer(adev, &cldb);
- + if (!ret && cldb.control_logic_type != 2)
- + return -EINVAL;
- +
- + if (ret)
- + cldb_present = false;
- +
- + gpio_dev = skl_int3472_register_pdev("tps68470-gpio", &client->dev);
- + if (IS_ERR(gpio_dev))
- + return PTR_ERR(gpio_dev);
- +
- + if (cldb_present) {
- + clk_dev = skl_int3472_register_pdev("tps68470-clk",
- + &client->dev);
- + if (IS_ERR(clk_dev)) {
- + ret = PTR_ERR(clk_dev);
- + goto err_free_gpio;
- + }
- +
- + regulator_dev = skl_int3472_register_pdev("tps68470-regulator",
- + &client->dev);
- + if (IS_ERR(regulator_dev)) {
- + ret = PTR_ERR(regulator_dev);
- + goto err_free_clk;
- + }
- + } else {
- + opregion_dev = skl_int3472_register_pdev("tps68470_pmic_opregion",
- + &client->dev);
- + if (IS_ERR(opregion_dev)) {
- + ret = PTR_ERR(opregion_dev);
- + goto err_free_gpio;
- + }
- + }
- +
- + return 0;
- +
- +err_free_clk:
- + platform_device_put(clk_dev);
- +err_free_gpio:
- + platform_device_put(gpio_dev);
- +
- + return ret;
- +}
- --
- 2.33.0
- From dc854a10270465727e4ec5e9c25a2c88b55539b2 Mon Sep 17 00:00:00 2001
- From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
- Date: Fri, 11 Dec 2020 21:17:35 +0100
- Subject: [PATCH] PCI: ACPI: Fix up ACPI companion lookup for device 0 on the
- root bus
- In some cases acpi_pci_find_companion() returns an incorrect device
- object as the ACPI companion for device 0 on the root bus (bus 0).
- On the affected systems that device is the PCI interface to the
- host bridge and the "ACPI companion" returned for it corresponds
- to a non-PCI device located in the SoC (e.g. a sensor on an I2C
- bus). As a result of this, the ACPI device object "attached"
- to PCI device 00:00.0 cannot be used for enumerating the device
- that is really represented by it which (of course) is problematic.
- Address that issue by preventing acpi_pci_find_companion() from
- returning a device object with a valid _HID (which by the spec
- should not be present uder ACPI device objects corresponding to
- PCI devices) for PCI device 00:00.0.
- Link: https://lore.kernel.org/linux-acpi/1409ba0c-1580-dc09-e6fe-a0c9bcda6462@gmail.com/
- Reported-by: Daniel Scally <djrscally@gmail.com>
- Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
- Patchset: cameras
- ---
- drivers/pci/pci-acpi.c | 20 +++++++++++++++++++-
- 1 file changed, 19 insertions(+), 1 deletion(-)
- diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
- index 745a4e0c4994..87e45a800919 100644
- --- a/drivers/pci/pci-acpi.c
- +++ b/drivers/pci/pci-acpi.c
- @@ -1162,14 +1162,32 @@ void acpi_pci_remove_bus(struct pci_bus *bus)
- static struct acpi_device *acpi_pci_find_companion(struct device *dev)
- {
- struct pci_dev *pci_dev = to_pci_dev(dev);
- + struct acpi_device *adev;
- bool check_children;
- u64 addr;
-
- check_children = pci_is_bridge(pci_dev);
- /* Please ref to ACPI spec for the syntax of _ADR */
- addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
- - return acpi_find_child_device(ACPI_COMPANION(dev->parent), addr,
- + adev = acpi_find_child_device(ACPI_COMPANION(dev->parent), addr,
- check_children);
- + /*
- + * There may be ACPI device objects in the ACPI namespace that are
- + * children of the device object representing the host bridge, but don't
- + * represent PCI devices. Both _HID and _ADR may be present for them,
- + * even though that is against the specification (for example, see
- + * Section 6.1 of ACPI 6.3), but in many cases the _ADR returns 0 which
- + * appears to indicate that they should not be taken into consideration
- + * as potential companions of PCI devices on the root bus.
- + *
- + * To catch this special case, disregard the returned device object if
- + * it has a valid _HID, addr is 0 and the PCI device at hand is on the
- + * root bus.
- + */
- + if (adev && adev->pnp.type.platform_id && !addr && !pci_dev->bus->parent)
- + return NULL;
- +
- + return adev;
- }
-
- /**
- --
- 2.33.0
- From 1e350fd1a4d00b6b9fd895b017daece0db39380a Mon Sep 17 00:00:00 2001
- From: Jake Day <jake@ninebysix.com>
- Date: Fri, 25 Sep 2020 10:24:53 -0400
- Subject: [PATCH] media: i2c: Add support for the OV5693 image sensor
- The OV5693 is a 5 Mpx CMOS image sensor, connected via MIPI CSI-2
- in a one or two lane configuration.
- Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/Kconfig | 11 +
- drivers/media/i2c/Makefile | 1 +
- drivers/media/i2c/ad5823.h | 63 ++
- drivers/media/i2c/ov5693.c | 1788 ++++++++++++++++++++++++++++++++++++
- drivers/media/i2c/ov5693.h | 1430 ++++++++++++++++++++++++++++
- 5 files changed, 3293 insertions(+)
- create mode 100644 drivers/media/i2c/ad5823.h
- create mode 100644 drivers/media/i2c/ov5693.c
- create mode 100644 drivers/media/i2c/ov5693.h
- diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
- index 878f66ef2719..10bbc85d0aba 100644
- --- a/drivers/media/i2c/Kconfig
- +++ b/drivers/media/i2c/Kconfig
- @@ -958,6 +958,17 @@ config VIDEO_OV5675
- To compile this driver as a module, choose M here: the
- module will be called ov5675.
-
- +config VIDEO_OV5693
- + tristate "OmniVision OV5693 sensor support"
- + depends on I2C && VIDEO_V4L2
- + select V4L2_FWNODE
- + help
- + This is a Video4Linux2 sensor driver for the OmniVision
- + OV5693 camera.
- +
- + To compile this driver as a module, choose M here: the
- + module will be called ov5693.
- +
- config VIDEO_OV5695
- tristate "OmniVision OV5695 sensor support"
- depends on I2C && VIDEO_V4L2
- diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
- index f0a77473979d..2bc1dd3e791b 100644
- --- a/drivers/media/i2c/Makefile
- +++ b/drivers/media/i2c/Makefile
- @@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
- obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
- obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
- obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
- +obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
- obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
- obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
- obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
- diff --git a/drivers/media/i2c/ad5823.h b/drivers/media/i2c/ad5823.h
- new file mode 100644
- index 000000000000..f1362cd69f6e
- --- /dev/null
- +++ b/drivers/media/i2c/ad5823.h
- @@ -0,0 +1,63 @@
- +/* SPDX-License-Identifier: GPL-2.0 */
- +/*
- + * Support for AD5823 VCM.
- + *
- + * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License version
- + * 2 as published by the Free Software Foundation.
- + *
- + * 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.
- + *
- + *
- + */
- +
- +#ifndef __AD5823_H__
- +#define __AD5823_H__
- +
- +#include <linux/types.h>
- +
- +#define AD5823_VCM_ADDR 0x0c
- +
- +#define AD5823_REG_RESET 0x01
- +#define AD5823_REG_MODE 0x02
- +#define AD5823_REG_VCM_MOVE_TIME 0x03
- +#define AD5823_REG_VCM_CODE_MSB 0x04
- +#define AD5823_REG_VCM_CODE_LSB 0x05
- +#define AD5823_REG_VCM_THRESHOLD_MSB 0x06
- +#define AD5823_REG_VCM_THRESHOLD_LSB 0x07
- +
- +#define AD5823_REG_LENGTH 0x1
- +
- +#define AD5823_RING_CTRL_ENABLE 0x04
- +#define AD5823_RING_CTRL_DISABLE 0x00
- +
- +#define AD5823_RESONANCE_PERIOD 100000
- +#define AD5823_RESONANCE_COEF 512
- +#define AD5823_HIGH_FREQ_RANGE 0x80
- +
- +#define VCM_CODE_MSB_MASK 0xfc
- +#define AD5823_INIT_FOCUS_POS 350
- +
- +enum ad5823_tok_type {
- + AD5823_8BIT = 0x1,
- + AD5823_16BIT = 0x2,
- +};
- +
- +enum ad5823_vcm_mode {
- + AD5823_ARC_RES0 = 0x0, /* Actuator response control RES1 */
- + AD5823_ARC_RES1 = 0x1, /* Actuator response control RES0.5 */
- + AD5823_ARC_RES2 = 0x2, /* Actuator response control RES2 */
- + AD5823_ESRC = 0x3, /* Enhanced slew rate control */
- + AD5823_DIRECT = 0x4, /* Direct control */
- +};
- +
- +#define AD5823_INVALID_CONFIG 0xffffffff
- +#define AD5823_MAX_FOCUS_POS 1023
- +#define DELAY_PER_STEP_NS 1000000
- +#define DELAY_MAX_PER_STEP_NS (1000000 * 1023)
- +#endif
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- new file mode 100644
- index 000000000000..32485e4ed42b
- --- /dev/null
- +++ b/drivers/media/i2c/ov5693.c
- @@ -0,0 +1,1788 @@
- +// SPDX-License-Identifier: GPL-2.0
- +/*
- + * Support for OmniVision OV5693 1080p HD camera sensor.
- + *
- + * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License version
- + * 2 as published by the Free Software Foundation.
- + *
- + * 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.
- + *
- + *
- + */
- +
- +#include <linux/clk.h>
- +#include <linux/module.h>
- +#include <linux/types.h>
- +#include <linux/kernel.h>
- +#include <linux/mm.h>
- +#include <linux/string.h>
- +#include <linux/errno.h>
- +#include <linux/init.h>
- +#include <linux/kmod.h>
- +#include <linux/device.h>
- +#include <linux/delay.h>
- +#include <linux/slab.h>
- +#include <linux/i2c.h>
- +#include <linux/moduleparam.h>
- +#include <media/v4l2-device.h>
- +#include <linux/io.h>
- +#include <linux/acpi.h>
- +#include <linux/regulator/consumer.h>
- +
- +#include "ov5693.h"
- +#include "ad5823.h"
- +
- +#define __cci_delay(t) \
- + do { \
- + if ((t) < 10) { \
- + usleep_range((t) * 1000, ((t) + 1) * 1000); \
- + } else { \
- + msleep((t)); \
- + } \
- + } while (0)
- +
- +/* Value 30ms reached through experimentation on byt ecs.
- + * The DS specifies a much lower value but when using a smaller value
- + * the I2C bus sometimes locks up permanently when starting the camera.
- + * This issue could not be reproduced on cht, so we can reduce the
- + * delay value to a lower value when insmod.
- + */
- +static uint up_delay = 30;
- +module_param(up_delay, uint, 0644);
- +MODULE_PARM_DESC(up_delay,
- + "Delay prior to the first CCI transaction for ov5693");
- +
- +
- +/* Exposure/gain */
- +
- +#define OV5693_EXPOSURE_CTRL_HH_REG 0x3500
- +#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(18, 16)) >> 16)
- +#define OV5693_EXPOSURE_CTRL_H_REG 0x3501
- +#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
- +#define OV5693_EXPOSURE_CTRL_L_REG 0x3502
- +#define OV5693_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
- +#define OV5693_EXPOSURE_GAIN_MANUAL_REG 0x3509
- +
- +#define OV5693_GAIN_CTRL_H_REG 0x3504
- +#define OV5693_GAIN_CTRL_H(v) (((v) & GENMASK(9, 8)) >> 8)
- +#define OV5693_GAIN_CTRL_L_REG 0x3505
- +#define OV5693_GAIN_CTRL_L(v) ((v) & GENMASK(7, 0))
- +
- +#define OV5693_FORMAT1_REG 0x3820
- +#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
- +#define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
- +#define OV5693_FORMAT2_REG 0x3821
- +#define OV5693_FORMAT2_HSYNC_EN BIT(6)
- +#define OV5693_FORMAT2_FST_VBIN_EN BIT(5)
- +#define OV5693_FORMAT2_FST_HBIN_EN BIT(4)
- +#define OV5693_FORMAT2_ISP_HORZ_VAR2_EN BIT(3)
- +#define OV5693_FORMAT2_FLIP_HORZ_ISP_EN BIT(2)
- +#define OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN BIT(1)
- +#define OV5693_FORMAT2_SYNC_HBIN_EN BIT(0)
- +
- +/* ISP */
- +
- +#define OV5693_ISP_CTRL0_REG 0x5000
- +#define OV5693_ISP_CTRL0_LENC_EN BIT(7)
- +#define OV5693_ISP_CTRL0_WHITE_BALANCE_EN BIT(4)
- +#define OV5693_ISP_CTRL0_DPC_BLACK_EN BIT(2)
- +#define OV5693_ISP_CTRL0_DPC_WHITE_EN BIT(1)
- +#define OV5693_ISP_CTRL1_REG 0x5001
- +#define OV5693_ISP_CTRL1_BLC_EN BIT(0)
- +
- +/* native and active pixel array size. */
- +#define OV5693_NATIVE_WIDTH 2688U
- +#define OV5693_NATIVE_HEIGHT 1984U
- +#define OV5693_PIXEL_ARRAY_LEFT 48U
- +#define OV5693_PIXEL_ARRAY_TOP 20U
- +#define OV5693_PIXEL_ARRAY_WIDTH 2592U
- +#define OV5693_PIXEL_ARRAY_HEIGHT 1944U
- +
- +#define OV5693_PPL_DEFAULT 2800
- +
- +static int vcm_ad_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
- +{
- + int err;
- + struct i2c_msg msg;
- + u8 buf[2];
- +
- + buf[0] = reg;
- + buf[1] = val;
- +
- + msg.addr = VCM_ADDR;
- + msg.flags = 0;
- + msg.len = 2;
- + msg.buf = &buf[0];
- +
- + err = i2c_transfer(client->adapter, &msg, 1);
- + if (err != 1) {
- + dev_err(&client->dev, "%s: vcm i2c fail, err code = %d\n",
- + __func__, err);
- + return -EIO;
- + }
- + return 0;
- +}
- +
- +static int ad5823_i2c_write(struct i2c_client *client, u8 reg, u8 val)
- +{
- + struct i2c_msg msg;
- + u8 buf[2];
- +
- + buf[0] = reg;
- + buf[1] = val;
- + msg.addr = AD5823_VCM_ADDR;
- + msg.flags = 0;
- + msg.len = 0x02;
- + msg.buf = &buf[0];
- +
- + if (i2c_transfer(client->adapter, &msg, 1) != 1)
- + return -EIO;
- + return 0;
- +}
- +
- +static int ad5823_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
- +{
- + struct i2c_msg msg[2];
- + u8 buf[2];
- +
- + buf[0] = reg;
- + buf[1] = 0;
- +
- + msg[0].addr = AD5823_VCM_ADDR;
- + msg[0].flags = 0;
- + msg[0].len = 0x01;
- + msg[0].buf = &buf[0];
- +
- + msg[1].addr = 0x0c;
- + msg[1].flags = I2C_M_RD;
- + msg[1].len = 0x01;
- + msg[1].buf = &buf[1];
- + *val = 0;
- + if (i2c_transfer(client->adapter, msg, 2) != 2)
- + return -EIO;
- + *val = buf[1];
- + return 0;
- +}
- +
- +static const u32 ov5693_embedded_effective_size = 28;
- +
- +/* i2c read/write stuff */
- +static int ov5693_read_reg(struct i2c_client *client,
- + u16 data_length, u16 reg, u16 *val)
- +{
- + int err;
- + struct i2c_msg msg[2];
- + unsigned char data[6];
- +
- + if (!client->adapter) {
- + dev_err(&client->dev, "%s error, no client->adapter\n",
- + __func__);
- + return -ENODEV;
- + }
- +
- + if (data_length != OV5693_8BIT && data_length != OV5693_16BIT
- + && data_length != OV5693_32BIT) {
- + dev_err(&client->dev, "%s error, invalid data length\n",
- + __func__);
- + return -EINVAL;
- + }
- +
- + memset(msg, 0, sizeof(msg));
- +
- + msg[0].addr = client->addr;
- + msg[0].flags = 0;
- + msg[0].len = I2C_MSG_LENGTH;
- + msg[0].buf = data;
- +
- + /* high byte goes out first */
- + data[0] = (u8)(reg >> 8);
- + data[1] = (u8)(reg & 0xff);
- +
- + msg[1].addr = client->addr;
- + msg[1].len = data_length;
- + msg[1].flags = I2C_M_RD;
- + msg[1].buf = data;
- +
- + err = i2c_transfer(client->adapter, msg, 2);
- + if (err != 2) {
- + if (err >= 0)
- + err = -EIO;
- + dev_err(&client->dev,
- + "read from offset 0x%x error %d", reg, err);
- + return err;
- + }
- +
- + *val = 0;
- + /* high byte comes first */
- + if (data_length == OV5693_8BIT)
- + *val = (u8)data[0];
- + else if (data_length == OV5693_16BIT)
- + *val = be16_to_cpu(*(__be16 *)&data[0]);
- + else
- + *val = be32_to_cpu(*(__be32 *)&data[0]);
- +
- + return 0;
- +}
- +
- +static int ov5693_i2c_write(struct i2c_client *client, u16 len, u8 *data)
- +{
- + struct i2c_msg msg;
- + const int num_msg = 1;
- + int ret;
- +
- + msg.addr = client->addr;
- + msg.flags = 0;
- + msg.len = len;
- + msg.buf = data;
- + ret = i2c_transfer(client->adapter, &msg, 1);
- +
- + return ret == num_msg ? 0 : -EIO;
- +}
- +
- +static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
- +{
- + struct i2c_msg msg;
- + const int num_msg = 1;
- + int ret;
- + __be16 val;
- +
- + val = cpu_to_be16(data);
- + msg.addr = VCM_ADDR;
- + msg.flags = 0;
- + msg.len = OV5693_16BIT;
- + msg.buf = (void *)&val;
- +
- + ret = i2c_transfer(client->adapter, &msg, 1);
- +
- + return ret == num_msg ? 0 : -EIO;
- +}
- +
- +/*
- + * Theory: per datasheet, the two VCMs both allow for a 2-byte read.
- + * The DW9714 doesn't actually specify what this does (it has a
- + * two-byte write-only protocol, but specifies the read sequence as
- + * legal), but it returns the same data (zeroes) always, after an
- + * undocumented initial NAK. The AD5823 has a one-byte address
- + * register to which all writes go, and subsequent reads will cycle
- + * through the 8 bytes of registers. Notably, the default values (the
- + * device is always power-cycled affirmatively, so we can rely on
- + * these) in AD5823 are not pairwise repetitions of the same 16 bit
- + * word. So all we have to do is sequentially read two bytes at a
- + * time and see if we detect a difference in any of the first four
- + * pairs.
- + */
- +static int vcm_detect(struct i2c_client *client)
- +{
- + int i, ret;
- + struct i2c_msg msg;
- + u16 data0 = 0, data;
- +
- + for (i = 0; i < 4; i++) {
- + msg.addr = VCM_ADDR;
- + msg.flags = I2C_M_RD;
- + msg.len = sizeof(data);
- + msg.buf = (u8 *)&data;
- + ret = i2c_transfer(client->adapter, &msg, 1);
- +
- + /*
- + * DW9714 always fails the first read and returns
- + * zeroes for subsequent ones
- + */
- + if (i == 0 && ret == -EREMOTEIO) {
- + data0 = 0;
- + continue;
- + }
- +
- + if (i == 0)
- + data0 = data;
- +
- + if (data != data0)
- + return VCM_AD5823;
- + }
- + return ret == 1 ? VCM_DW9714 : ret;
- +}
- +
- +static int ov5693_write_reg(struct i2c_client *client, u16 data_length,
- + u16 reg, u16 val)
- +{
- + int ret;
- + unsigned char data[4] = {0};
- + __be16 *wreg = (void *)data;
- + const u16 len = data_length + sizeof(u16); /* 16-bit address + data */
- +
- + if (data_length != OV5693_8BIT && data_length != OV5693_16BIT) {
- + dev_err(&client->dev,
- + "%s error, invalid data_length\n", __func__);
- + return -EINVAL;
- + }
- +
- + /* high byte goes out first */
- + *wreg = cpu_to_be16(reg);
- +
- + if (data_length == OV5693_8BIT) {
- + data[2] = (u8)(val);
- + } else {
- + /* OV5693_16BIT */
- + __be16 *wdata = (void *)&data[2];
- +
- + *wdata = cpu_to_be16(val);
- + }
- +
- + ret = ov5693_i2c_write(client, len, data);
- + if (ret)
- + dev_err(&client->dev,
- + "write error: wrote 0x%x to offset 0x%x error %d",
- + val, reg, ret);
- +
- + return ret;
- +}
- +
- +/*
- + * ov5693_write_reg_array - Initializes a list of OV5693 registers
- + * @client: i2c driver client structure
- + * @reglist: list of registers to be written
- + *
- + * This function initializes a list of registers. When consecutive addresses
- + * are found in a row on the list, this function creates a buffer and sends
- + * consecutive data in a single i2c_transfer().
- + *
- + * __ov5693_flush_reg_array, __ov5693_buf_reg_array() and
- + * __ov5693_write_reg_is_consecutive() are internal functions to
- + * ov5693_write_reg_array_fast() and should be not used anywhere else.
- + *
- + */
- +
- +static int __ov5693_flush_reg_array(struct i2c_client *client,
- + struct ov5693_write_ctrl *ctrl)
- +{
- + u16 size;
- + __be16 *reg = (void *)&ctrl->buffer.addr;
- +
- + if (ctrl->index == 0)
- + return 0;
- +
- + size = sizeof(u16) + ctrl->index; /* 16-bit address + data */
- +
- + *reg = cpu_to_be16(ctrl->buffer.addr);
- + ctrl->index = 0;
- +
- + return ov5693_i2c_write(client, size, (u8 *)reg);
- +}
- +
- +static int __ov5693_buf_reg_array(struct i2c_client *client,
- + struct ov5693_write_ctrl *ctrl,
- + const struct ov5693_reg *next)
- +{
- + int size;
- + __be16 *data16;
- +
- + switch (next->type) {
- + case OV5693_8BIT:
- + size = 1;
- + ctrl->buffer.data[ctrl->index] = (u8)next->val;
- + break;
- + case OV5693_16BIT:
- + size = 2;
- +
- + data16 = (void *)&ctrl->buffer.data[ctrl->index];
- + *data16 = cpu_to_be16((u16)next->val);
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + /* When first item is added, we need to store its starting address */
- + if (ctrl->index == 0)
- + ctrl->buffer.addr = next->reg;
- +
- + ctrl->index += size;
- +
- + /*
- + * Buffer cannot guarantee free space for u32? Better flush it to avoid
- + * possible lack of memory for next item.
- + */
- + if (ctrl->index + sizeof(u16) >= OV5693_MAX_WRITE_BUF_SIZE)
- + return __ov5693_flush_reg_array(client, ctrl);
- +
- + return 0;
- +}
- +
- +static int __ov5693_write_reg_is_consecutive(struct i2c_client *client,
- + struct ov5693_write_ctrl *ctrl,
- + const struct ov5693_reg *next)
- +{
- + if (ctrl->index == 0)
- + return 1;
- +
- + return ctrl->buffer.addr + ctrl->index == next->reg;
- +}
- +
- +static int ov5693_write_reg_array(struct i2c_client *client,
- + const struct ov5693_reg *reglist)
- +{
- + const struct ov5693_reg *next = reglist;
- + struct ov5693_write_ctrl ctrl;
- + int err;
- +
- + ctrl.index = 0;
- + for (; next->type != OV5693_TOK_TERM; next++) {
- + switch (next->type & OV5693_TOK_MASK) {
- + case OV5693_TOK_DELAY:
- + err = __ov5693_flush_reg_array(client, &ctrl);
- + if (err)
- + return err;
- + msleep(next->val);
- + break;
- + default:
- + /*
- + * If next address is not consecutive, data needs to be
- + * flushed before proceed.
- + */
- + if (!__ov5693_write_reg_is_consecutive(client, &ctrl,
- + next)) {
- + err = __ov5693_flush_reg_array(client, &ctrl);
- + if (err)
- + return err;
- + }
- + err = __ov5693_buf_reg_array(client, &ctrl, next);
- + if (err) {
- + dev_err(&client->dev,
- + "%s: write error, aborted\n",
- + __func__);
- + return err;
- + }
- + break;
- + }
- + }
- +
- + return __ov5693_flush_reg_array(client, &ctrl);
- +}
- +
- +static int ov5693_read_otp_reg_array(struct i2c_client *client, u16 size,
- + u16 addr, u8 *buf)
- +{
- + u16 index;
- + int ret;
- + u16 *pVal = NULL;
- +
- + for (index = 0; index <= size; index++) {
- + pVal = (u16 *)(buf + index);
- + ret =
- + ov5693_read_reg(client, OV5693_8BIT, addr + index,
- + pVal);
- + if (ret)
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + int ret;
- + int i;
- + u8 *b = buf;
- +
- + dev->otp_size = 0;
- + for (i = 1; i < OV5693_OTP_BANK_MAX; i++) {
- + /*set bank NO and OTP read mode. */
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_OTP_BANK_REG,
- + (i | 0xc0)); //[7:6] 2'b11 [5:0] bank no
- + if (ret) {
- + dev_err(&client->dev, "failed to prepare OTP page\n");
- + return ret;
- + }
- + //dev_dbg(&client->dev, "write 0x%x->0x%x\n",OV5693_OTP_BANK_REG,(i|0xc0));
- +
- + /*enable read */
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_OTP_READ_REG,
- + OV5693_OTP_MODE_READ); // enable :1
- + if (ret) {
- + dev_err(&client->dev,
- + "failed to set OTP reading mode page");
- + return ret;
- + }
- + //dev_dbg(&client->dev, "write 0x%x->0x%x\n",
- + // OV5693_OTP_READ_REG,OV5693_OTP_MODE_READ);
- +
- + /* Reading the OTP data array */
- + ret = ov5693_read_otp_reg_array(client, OV5693_OTP_BANK_SIZE,
- + OV5693_OTP_START_ADDR,
- + b);
- + if (ret) {
- + dev_err(&client->dev, "failed to read OTP data\n");
- + return ret;
- + }
- +
- + //dev_dbg(&client->dev,
- + // "BANK[%2d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- + // i, *b, *(b+1), *(b+2), *(b+3), *(b+4), *(b+5), *(b+6), *(b+7),
- + // *(b+8), *(b+9), *(b+10), *(b+11), *(b+12), *(b+13), *(b+14), *(b+15));
- +
- + //Intel OTP map, try to read 320byts first.
- + if (i == 21) {
- + if ((*b) == 0) {
- + dev->otp_size = 320;
- + break;
- + }
- + /* (*b) != 0 */
- + b = buf;
- + continue;
- + } else if (i ==
- + 24) { //if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
- + if ((*b) == 0) {
- + dev->otp_size = 32;
- + break;
- + }
- + /* (*b) != 0 */
- + b = buf;
- + continue;
- + } else if (i ==
- + 27) { //if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
- + if ((*b) == 0) {
- + dev->otp_size = 32;
- + break;
- + }
- + /* (*b) != 0 */
- + dev->otp_size = 0; // no OTP data.
- + break;
- + }
- +
- + b = b + OV5693_OTP_BANK_SIZE;
- + }
- + return 0;
- +}
- +
- +/*
- + * Read otp data and store it into a kmalloced buffer.
- + * The caller must kfree the buffer when no more needed.
- + * @size: set to the size of the returned otp data.
- + */
- +static void *ov5693_otp_read(struct v4l2_subdev *sd)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + u8 *buf;
- + int ret;
- +
- + buf = devm_kzalloc(&client->dev, (OV5693_OTP_DATA_SIZE + 16), GFP_KERNEL);
- + if (!buf)
- + return ERR_PTR(-ENOMEM);
- +
- + //otp valid after mipi on and sw stream on
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_FRAME_OFF_NUM, 0x00);
- +
- + ret = ov5693_write_reg(client, OV5693_8BIT,
- + OV5693_SW_STREAM, OV5693_START_STREAMING);
- +
- + ret = __ov5693_otp_read(sd, buf);
- +
- + //mipi off and sw stream off after otp read
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_FRAME_OFF_NUM, 0x0f);
- +
- + ret = ov5693_write_reg(client, OV5693_8BIT,
- + OV5693_SW_STREAM, OV5693_STOP_STREAMING);
- +
- + /* Driver has failed to find valid data */
- + if (ret) {
- + dev_err(&client->dev, "sensor found no valid OTP data\n");
- + return ERR_PTR(ret);
- + }
- +
- + return buf;
- +}
- +
- +static int ov5693_update_bits(struct ov5693_device *sensor, u16 address,
- + u16 mask, u16 bits)
- +{
- + u16 value = 0;
- + int ret;
- +
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT, address, &value);
- + if (ret)
- + return ret;
- +
- + value &= ~mask;
- + value |= bits;
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT, address, value);
- + if (ret)
- + return ret;
- +
- + return 0;
- +}
- +
- +/* Flip */
- +
- +static int ov5693_flip_vert_configure(struct ov5693_device *sensor, bool enable)
- +{
- + u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
- + OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
- + int ret;
- +
- + ret = ov5693_update_bits(sensor, OV5693_FORMAT1_REG, bits,
- + enable ? bits : 0);
- + if (ret)
- + return ret;
- +
- + return 0;
- +}
- +
- +static int ov5693_flip_horz_configure(struct ov5693_device *sensor, bool enable)
- +{
- + u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
- + OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
- + int ret;
- +
- + ret = ov5693_update_bits(sensor, OV5693_FORMAT2_REG, bits,
- + enable ? bits : 0);
- + if (ret)
- + return ret;
- +
- + return 0;
- +}
- +
- +/*
- + * This returns the exposure time being used. This should only be used
- + * for filling in EXIF data, not for actual image processing.
- + */
- +static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + u16 reg_v, reg_v2;
- + int ret;
- +
- + /* get exposure */
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_EXPOSURE_L,
- + ®_v);
- + if (ret)
- + goto err;
- +
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_EXPOSURE_M,
- + ®_v2);
- + if (ret)
- + goto err;
- +
- + reg_v += reg_v2 << 8;
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_EXPOSURE_H,
- + ®_v2);
- + if (ret)
- + goto err;
- +
- + *value = reg_v + (((u32)reg_v2 << 16));
- +err:
- + return ret;
- +}
- +
- +static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret = -EINVAL;
- + u8 vcm_code;
- +
- + ret = ad5823_i2c_read(client, AD5823_REG_VCM_CODE_MSB, &vcm_code);
- + if (ret)
- + return ret;
- +
- + /* set reg VCM_CODE_MSB Bit[1:0] */
- + vcm_code = (vcm_code & VCM_CODE_MSB_MASK) |
- + ((val >> 8) & ~VCM_CODE_MSB_MASK);
- + ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB, vcm_code);
- + if (ret)
- + return ret;
- +
- + /* set reg VCM_CODE_LSB Bit[7:0] */
- + ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_LSB, (val & 0xff));
- + if (ret)
- + return ret;
- +
- + /* set required vcm move time */
- + vcm_code = AD5823_RESONANCE_PERIOD / AD5823_RESONANCE_COEF
- + - AD5823_HIGH_FREQ_RANGE;
- + ret = ad5823_i2c_write(client, AD5823_REG_VCM_MOVE_TIME, vcm_code);
- +
- + return ret;
- +}
- +
- +static int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- +{
- + value = min(value, AD5823_MAX_FOCUS_POS);
- + return ad5823_t_focus_vcm(sd, value);
- +}
- +
- +static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret = 0;
- +
- + dev_dbg(&client->dev, "%s: FOCUS_POS: 0x%x\n", __func__, value);
- + value = clamp(value, 0, OV5693_VCM_MAX_FOCUS_POS);
- + if (dev->vcm == VCM_DW9714) {
- + if (dev->vcm_update) {
- + ret = vcm_dw_i2c_write(client, VCM_PROTECTION_OFF);
- + if (ret)
- + return ret;
- + ret = vcm_dw_i2c_write(client, DIRECT_VCM);
- + if (ret)
- + return ret;
- + ret = vcm_dw_i2c_write(client, VCM_PROTECTION_ON);
- + if (ret)
- + return ret;
- + dev->vcm_update = false;
- + }
- + ret = vcm_dw_i2c_write(client,
- + vcm_val(value, VCM_DEFAULT_S));
- + } else if (dev->vcm == VCM_AD5823) {
- + ad5823_t_focus_abs(sd, value);
- + }
- + if (ret == 0) {
- + dev->number_of_steps = value - dev->focus;
- + dev->focus = value;
- + dev->timestamp_t_focus_abs = ktime_get();
- + } else
- + dev_err(&client->dev,
- + "%s: i2c failed. ret %d\n", __func__, ret);
- +
- + return ret;
- +}
- +
- +static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- +
- + return ov5693_t_focus_abs(sd, dev->focus + value);
- +}
- +
- +#define DELAY_PER_STEP_NS 1000000
- +#define DELAY_MAX_PER_STEP_NS (1000000 * 1023)
- +
- +/* Exposure */
- +
- +static int ov5693_get_exposure(struct ov5693_device *sensor)
- +{
- + u16 reg_v, reg_v2;
- + int ret = 0;
- +
- + /* get exposure */
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_L,
- + ®_v);
- + if (ret)
- + return ret;
- +
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_M,
- + ®_v2);
- + if (ret)
- + return ret;
- +
- + reg_v += reg_v2 << 8;
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_H,
- + ®_v2);
- + if (ret)
- + return ret;
- +
- + printk("exposure set to: %u\n", reg_v + (((u32)reg_v2 << 16)));
- + return ret;
- +}
- +
- +static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
- +{
- + int ret;
- +
- + ov5693_get_exposure(sensor);
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
- + if (ret)
- + return ret;
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_CTRL_H_REG, OV5693_EXPOSURE_CTRL_H(exposure));
- + if (ret)
- + return ret;
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_EXPOSURE_CTRL_L_REG, OV5693_EXPOSURE_CTRL_L(exposure));
- + if (ret)
- + return ret;
- + ov5693_get_exposure(sensor);
- +
- + return 0;
- +}
- +
- +/* Gain */
- +
- +static int ov5693_get_gain(struct ov5693_device *sensor, u32 *gain)
- +{
- + u16 gain_l, gain_h;
- + int ret = 0;
- +
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_GAIN_CTRL_L_REG,
- + &gain_l);
- + if (ret)
- + return ret;
- +
- + ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_GAIN_CTRL_H_REG,
- + &gain_h);
- + if (ret)
- + return ret;
- +
- + *gain = (u32)(((gain_h >> 8) & 0x03) |
- + (gain_l & 0xff));
- +
- + return ret;
- +}
- +static int ov5693_gain_configure(struct ov5693_device *sensor, u32 gain)
- +{
- + int ret;
- +
- + /* A 1.0 gain is 0x400 */
- + gain = (gain * 1024)/1000;
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + OV5693_MWB_RED_GAIN_H, gain);
- + if (ret) {
- + dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + __func__, OV5693_MWB_RED_GAIN_H);
- + return ret;
- + }
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + OV5693_MWB_GREEN_GAIN_H, gain);
- + if (ret) {
- + dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + __func__, OV5693_MWB_RED_GAIN_H);
- + return ret;
- + }
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + OV5693_MWB_BLUE_GAIN_H, gain);
- + if (ret) {
- + dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + __func__, OV5693_MWB_RED_GAIN_H);
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
- +{
- + int ret;
- +
- + /* Analog gain */
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_AGC_L, gain & 0xff);
- + if (ret) {
- + dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + __func__, OV5693_AGC_L);
- + return ret;
- + }
- +
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_AGC_H, (gain >> 8) & 0xff);
- + if (ret) {
- + dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + __func__, OV5693_AGC_H);
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- +{
- + struct ov5693_device *dev =
- + container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
- + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
- + int ret = 0;
- +
- + switch (ctrl->id) {
- + case V4L2_CID_FOCUS_ABSOLUTE:
- + dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
- + __func__, ctrl->val);
- + ret = ov5693_t_focus_abs(&dev->sd, ctrl->val);
- + break;
- + case V4L2_CID_FOCUS_RELATIVE:
- + dev_dbg(&client->dev, "%s: CID_FOCUS_RELATIVE:%d.\n",
- + __func__, ctrl->val);
- + ret = ov5693_t_focus_rel(&dev->sd, ctrl->val);
- + break;
- + case V4L2_CID_EXPOSURE:
- + dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
- + __func__, ctrl->val);
- + ret = ov5693_exposure_configure(dev, ctrl->val);
- + if (ret)
- + return ret;
- + break;
- + case V4L2_CID_ANALOGUE_GAIN:
- + dev_dbg(&client->dev, "%s: CID_ANALOGUE_GAIN:%d.\n",
- + __func__, ctrl->val);
- + ret = ov5693_analog_gain_configure(dev, ctrl->val);
- + if (ret)
- + return ret;
- + break;
- + case V4L2_CID_DIGITAL_GAIN:
- + dev_dbg(&client->dev, "%s: CID_DIGITAL_GAIN:%d.\n",
- + __func__, ctrl->val);
- + ret = ov5693_gain_configure(dev, ctrl->val);
- + if (ret)
- + return ret;
- + break;
- + case V4L2_CID_HFLIP:
- + return ov5693_flip_horz_configure(dev, !!ctrl->val);
- + case V4L2_CID_VFLIP:
- + return ov5693_flip_vert_configure(dev, !!ctrl->val);
- + default:
- + ret = -EINVAL;
- + }
- + return ret;
- +}
- +
- +static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
- +{
- + struct ov5693_device *dev =
- + container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
- + int ret = 0;
- +
- + switch (ctrl->id) {
- + case V4L2_CID_EXPOSURE_ABSOLUTE:
- + ret = ov5693_q_exposure(&dev->sd, &ctrl->val);
- + break;
- + case V4L2_CID_AUTOGAIN:
- + ret = ov5693_get_gain(dev, &ctrl->val);
- + break;
- + case V4L2_CID_FOCUS_ABSOLUTE:
- + /* NOTE: there was atomisp-specific function ov5693_q_focus_abs() */
- + break;
- + default:
- + ret = -EINVAL;
- + }
- +
- + return ret;
- +}
- +
- +static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
- + .s_ctrl = ov5693_s_ctrl,
- + .g_volatile_ctrl = ov5693_g_volatile_ctrl
- +};
- +
- +static const struct v4l2_ctrl_config ov5693_controls[] = {
- + {
- + .ops = &ov5693_ctrl_ops,
- + .id = V4L2_CID_FOCUS_ABSOLUTE,
- + .type = V4L2_CTRL_TYPE_INTEGER,
- + .name = "focus move absolute",
- + .min = 0,
- + .max = OV5693_VCM_MAX_FOCUS_POS,
- + .step = 1,
- + .def = 0,
- + .flags = 0,
- + },
- + {
- + .ops = &ov5693_ctrl_ops,
- + .id = V4L2_CID_FOCUS_RELATIVE,
- + .type = V4L2_CTRL_TYPE_INTEGER,
- + .name = "focus move relative",
- + .min = OV5693_VCM_MAX_FOCUS_NEG,
- + .max = OV5693_VCM_MAX_FOCUS_POS,
- + .step = 1,
- + .def = 0,
- + .flags = 0,
- + },
- +};
- +
- +static int ov5693_isp_configure(struct ov5693_device *sensor)
- +{
- + int ret;
- +
- + /* Enable lens correction. */
- + ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + OV5693_ISP_CTRL0_REG, 0x86);
- + if (ret)
- + return ret;
- +
- + return 0;
- +}
- +
- +static int ov5693_init(struct v4l2_subdev *sd)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret;
- +
- + if (!dev->has_vcm)
- + return 0;
- +
- + dev_info(&client->dev, "%s\n", __func__);
- + mutex_lock(&dev->input_lock);
- + dev->vcm_update = false;
- +
- + if (dev->vcm == VCM_AD5823) {
- + ret = vcm_ad_i2c_wr8(client, 0x01, 0x01); /* vcm init test */
- + if (ret)
- + dev_err(&client->dev,
- + "vcm reset failed\n");
- + /*change the mode*/
- + ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB,
- + AD5823_RING_CTRL_ENABLE);
- + if (ret)
- + dev_err(&client->dev,
- + "vcm enable ringing failed\n");
- + ret = ad5823_i2c_write(client, AD5823_REG_MODE,
- + AD5823_ARC_RES1);
- + if (ret)
- + dev_err(&client->dev,
- + "vcm change mode failed\n");
- + }
- +
- + /*change initial focus value for ad5823*/
- + if (dev->vcm == VCM_AD5823) {
- + dev->focus = AD5823_INIT_FOCUS_POS;
- + ov5693_t_focus_abs(sd, AD5823_INIT_FOCUS_POS);
- + } else {
- + dev->focus = 0;
- + ov5693_t_focus_abs(sd, 0);
- + }
- +
- + ov5693_isp_configure(dev);
- + mutex_unlock(&dev->input_lock);
- +
- + return 0;
- +}
- +
- +static int __power_up(struct v4l2_subdev *sd)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + struct ov5693_device *sensor = to_ov5693_sensor(sd);
- + int ret;
- +
- + ret = clk_prepare_enable(sensor->clk);
- + if (ret) {
- + dev_err(&client->dev, "Error enabling clock\n");
- + return -EINVAL;
- + }
- +
- + if (sensor->indicator_led)
- + gpiod_set_value_cansleep(sensor->indicator_led, 1);
- +
- + ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES,
- + sensor->supplies);
- + if (ret)
- + goto fail_power;
- +
- + __cci_delay(up_delay);
- +
- + return 0;
- +
- +fail_power:
- + if (sensor->indicator_led)
- + gpiod_set_value_cansleep(sensor->indicator_led, 0);
- + dev_err(&client->dev, "sensor power-up failed\n");
- +
- + return ret;
- +}
- +
- +static int power_down(struct v4l2_subdev *sd)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- +
- + dev->focus = OV5693_INVALID_CONFIG;
- +
- + clk_disable_unprepare(dev->clk);
- +
- + if (dev->indicator_led)
- + gpiod_set_value_cansleep(dev->indicator_led, 0);
- + return regulator_bulk_disable(OV5693_NUM_SUPPLIES, dev->supplies);
- +}
- +
- +static int power_up(struct v4l2_subdev *sd)
- +{
- + static const int retry_count = 4;
- + int i, ret;
- +
- + for (i = 0; i < retry_count; i++) {
- + ret = __power_up(sd);
- + if (!ret)
- + return 0;
- +
- + power_down(sd);
- + }
- + return ret;
- +}
- +
- +static int ov5693_s_power(struct v4l2_subdev *sd, int on)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret;
- +
- + dev_info(&client->dev, "%s: on %d\n", __func__, on);
- +
- + if (on == 0)
- + return power_down(sd);
- +
- + /* on == 1 */
- + ret = power_up(sd);
- + if (!ret) {
- + ret = ov5693_init(sd);
- + /* restore settings */
- + ov5693_res = ov5693_res_video;
- + N_RES = N_RES_VIDEO;
- + }
- +
- + return ret;
- +}
- +
- +/*
- + * distance - calculate the distance
- + * @res: resolution
- + * @w: width
- + * @h: height
- + *
- + * Get the gap between res_w/res_h and w/h.
- + * distance = (res_w/res_h - w/h) / (w/h) * 8192
- + * res->width/height smaller than w/h wouldn't be considered.
- + * The gap of ratio larger than 1/8 wouldn't be considered.
- + * Returns the value of gap or -1 if fail.
- + */
- +#define LARGEST_ALLOWED_RATIO_MISMATCH 1024
- +static int distance(struct ov5693_resolution *res, u32 w, u32 h)
- +{
- + int ratio;
- + int distance;
- +
- + if (w == 0 || h == 0 ||
- + res->width < w || res->height < h)
- + return -1;
- +
- + ratio = res->width << 13;
- + ratio /= w;
- + ratio *= h;
- + ratio /= res->height;
- +
- + distance = abs(ratio - 8192);
- +
- + if (distance > LARGEST_ALLOWED_RATIO_MISMATCH)
- + return -1;
- +
- + return distance;
- +}
- +
- +/* Return the nearest higher resolution index
- + * Firstly try to find the approximate aspect ratio resolution
- + * If we find multiple same AR resolutions, choose the
- + * minimal size.
- + */
- +static int nearest_resolution_index(int w, int h)
- +{
- + int i;
- + int idx = -1;
- + int dist;
- + int min_dist = INT_MAX;
- + int min_res_w = INT_MAX;
- + struct ov5693_resolution *tmp_res = NULL;
- +
- + for (i = 0; i < N_RES; i++) {
- + tmp_res = &ov5693_res[i];
- + dist = distance(tmp_res, w, h);
- + if (dist == -1)
- + continue;
- + if (dist < min_dist) {
- + min_dist = dist;
- + idx = i;
- + min_res_w = ov5693_res[i].width;
- + continue;
- + }
- + if (dist == min_dist && ov5693_res[i].width < min_res_w)
- + idx = i;
- + }
- +
- + return idx;
- +}
- +
- +static int get_resolution_index(int w, int h)
- +{
- + int i;
- +
- + for (i = 0; i < N_RES; i++) {
- + if (w != ov5693_res[i].width)
- + continue;
- + if (h != ov5693_res[i].height)
- + continue;
- +
- + return i;
- + }
- +
- + return -1;
- +}
- +
- +/* TODO: remove it. */
- +static int startup(struct v4l2_subdev *sd)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret = 0;
- +
- + ret = ov5693_write_reg(client, OV5693_8BIT,
- + OV5693_SW_RESET, 0x01);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 reset err.\n");
- + return ret;
- + }
- +
- + ret = ov5693_write_reg_array(client, ov5693_global_setting);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 write register err.\n");
- + return ret;
- + }
- +
- + ret = ov5693_write_reg_array(client, ov5693_res[dev->fmt_idx].regs);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 write register err.\n");
- + return ret;
- + }
- +
- + return ret;
- +}
- +
- +static int ov5693_set_fmt(struct v4l2_subdev *sd,
- + struct v4l2_subdev_pad_config *cfg,
- + struct v4l2_subdev_format *format)
- +{
- + struct v4l2_mbus_framefmt *fmt = &format->format;
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret = 0;
- + int idx;
- + int cnt;
- +
- + if (format->pad)
- + return -EINVAL;
- + if (!fmt)
- + return -EINVAL;
- +
- + mutex_lock(&dev->input_lock);
- + idx = nearest_resolution_index(fmt->width, fmt->height);
- + if (idx == -1) {
- + /* return the largest resolution */
- + fmt->width = ov5693_res[N_RES - 1].width;
- + fmt->height = ov5693_res[N_RES - 1].height;
- + } else {
- + fmt->width = ov5693_res[idx].width;
- + fmt->height = ov5693_res[idx].height;
- + }
- +
- + fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
- + if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- + cfg->try_fmt = *fmt;
- + ret = 0;
- + goto mutex_unlock;
- + }
- +
- + dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- + if (dev->fmt_idx == -1) {
- + dev_err(&client->dev, "get resolution fail\n");
- + ret = -EINVAL;
- + goto mutex_unlock;
- + }
- +
- + for (cnt = 0; cnt < OV5693_POWER_UP_RETRY_NUM; cnt++) {
- + ret = power_up(sd);
- + if (ret) {
- + dev_err(&client->dev, "power up failed\n");
- + continue;
- + }
- +
- + mutex_unlock(&dev->input_lock);
- + ov5693_init(sd);
- + mutex_lock(&dev->input_lock);
- + ret = startup(sd);
- + if (ret)
- + dev_err(&client->dev, " startup() FAILED!\n");
- + else
- + break;
- + }
- + if (cnt == OV5693_POWER_UP_RETRY_NUM) {
- + dev_err(&client->dev, "power up failed, gave up\n");
- + goto mutex_unlock;
- + }
- +
- +
- +
- + /*
- + * After sensor settings are set to HW, sometimes stream is started.
- + * This would cause ISP timeout because ISP is not ready to receive
- + * data yet. So add stop streaming here.
- + */
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
- + OV5693_STOP_STREAMING);
- + if (ret)
- + dev_warn(&client->dev, "ov5693 stream off err\n");
- +
- +mutex_unlock:
- + mutex_unlock(&dev->input_lock);
- + return ret;
- +}
- +
- +static const struct v4l2_rect *
- +__ov5693_get_pad_crop(struct ov5693_device *dev, struct v4l2_subdev_pad_config *cfg,
- + unsigned int pad, enum v4l2_subdev_format_whence which)
- +{
- + switch (which) {
- + case V4L2_SUBDEV_FORMAT_TRY:
- + return v4l2_subdev_get_try_crop(&dev->sd, cfg, pad);
- + case V4L2_SUBDEV_FORMAT_ACTIVE:
- + return &dev->mode->crop;
- + }
- +
- + return NULL;
- +}
- +static int ov5693_get_selection(struct v4l2_subdev *sd,
- + struct v4l2_subdev_pad_config *cfg,
- + struct v4l2_subdev_selection *sel)
- +{
- + switch (sel->target) {
- + case V4L2_SEL_TGT_CROP: {
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- +
- + mutex_lock(&dev->input_lock);
- + sel->r = *__ov5693_get_pad_crop(dev, cfg, sel->pad,
- + sel->which);
- + mutex_unlock(&dev->input_lock);
- +
- + return 0;
- + }
- +
- + case V4L2_SEL_TGT_NATIVE_SIZE:
- + sel->r.top = 0;
- + sel->r.left = 0;
- + sel->r.width = OV5693_NATIVE_WIDTH;
- + sel->r.height = OV5693_NATIVE_HEIGHT;
- +
- + return 0;
- +
- + case V4L2_SEL_TGT_CROP_DEFAULT:
- + sel->r.top = OV5693_PIXEL_ARRAY_TOP;
- + sel->r.left = OV5693_PIXEL_ARRAY_LEFT;
- + sel->r.width = OV5693_PIXEL_ARRAY_WIDTH;
- + sel->r.height = OV5693_PIXEL_ARRAY_HEIGHT;
- +
- + return 0;
- + }
- +
- + return -EINVAL;
- +}
- +
- +static int ov5693_get_fmt(struct v4l2_subdev *sd,
- + struct v4l2_subdev_pad_config *cfg,
- + struct v4l2_subdev_format *format)
- +{
- + struct v4l2_mbus_framefmt *fmt = &format->format;
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- +
- + if (format->pad)
- + return -EINVAL;
- +
- + if (!fmt)
- + return -EINVAL;
- +
- + fmt->width = ov5693_res[dev->fmt_idx].width;
- + fmt->height = ov5693_res[dev->fmt_idx].height;
- + fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
- +
- + return 0;
- +}
- +
- +static int ov5693_detect(struct i2c_client *client)
- +{
- + struct i2c_adapter *adapter = client->adapter;
- + u16 high, low;
- + int ret;
- + u16 id;
- + u8 revision;
- +
- + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
- + return -ENODEV;
- +
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_SC_CMMN_CHIP_ID_H, &high);
- + if (ret) {
- + dev_err(&client->dev, "sensor_id_high = 0x%x\n", high);
- + return -ENODEV;
- + }
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_SC_CMMN_CHIP_ID_L, &low);
- + id = ((((u16)high) << 8) | (u16)low);
- +
- + if (id != OV5693_ID) {
- + dev_err(&client->dev, "sensor ID error 0x%x\n", id);
- + return -ENODEV;
- + }
- +
- + ret = ov5693_read_reg(client, OV5693_8BIT,
- + OV5693_SC_CMMN_SUB_ID, &high);
- + revision = (u8)high & 0x0f;
- +
- + dev_info(&client->dev, "sensor_revision = 0x%x\n", revision);
- + dev_info(&client->dev, "sensor_address = 0x%02x\n", client->addr);
- + dev_info(&client->dev, "detect ov5693 success\n");
- + return 0;
- +}
- +
- +static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret;
- +
- + mutex_lock(&dev->input_lock);
- +
- + /* power_on() here before streaming for regular PCs. */
- + if (enable) {
- + ret = power_up(sd);
- + if (ret) {
- + dev_err(&client->dev, "sensor power-up error\n");
- + goto out;
- + }
- + }
- +
- + ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
- + enable ? OV5693_START_STREAMING :
- + OV5693_STOP_STREAMING);
- +
- + /* power_off() here after streaming for regular PCs. */
- + if (!enable)
- + power_down(sd);
- +
- +out:
- + mutex_unlock(&dev->input_lock);
- +
- + return ret;
- +}
- +
- +static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct i2c_client *client = v4l2_get_subdevdata(sd);
- + int ret = 0;
- +
- + mutex_lock(&dev->input_lock);
- + ret = power_up(sd);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 power-up err.\n");
- + goto fail_power_on;
- + }
- +
- + if (!dev->vcm)
- + dev->vcm = vcm_detect(client);
- +
- + /* config & detect sensor */
- + ret = ov5693_detect(client);
- + if (ret) {
- + dev_err(&client->dev, "ov5693_detect err s_config.\n");
- + goto fail_power_on;
- + }
- +
- + dev->otp_data = ov5693_otp_read(sd);
- +
- + /* turn off sensor, after probed */
- + ret = power_down(sd);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 power-off err.\n");
- + goto fail_power_on;
- + }
- + mutex_unlock(&dev->input_lock);
- +
- + return ret;
- +
- +fail_power_on:
- + power_down(sd);
- + dev_err(&client->dev, "sensor power-gating failed\n");
- + mutex_unlock(&dev->input_lock);
- + return ret;
- +}
- +
- +static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
- + struct v4l2_subdev_frame_interval *interval)
- +{
- + struct ov5693_device *dev = to_ov5693_sensor(sd);
- +
- + interval->interval.numerator = 1;
- + interval->interval.denominator = ov5693_res[dev->fmt_idx].fps;
- +
- + return 0;
- +}
- +
- +static int ov5693_enum_mbus_code(struct v4l2_subdev *sd,
- + struct v4l2_subdev_pad_config *cfg,
- + struct v4l2_subdev_mbus_code_enum *code)
- +{
- + if (code->index >= MAX_FMTS)
- + return -EINVAL;
- +
- + code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
- + return 0;
- +}
- +
- +static int ov5693_enum_frame_size(struct v4l2_subdev *sd,
- + struct v4l2_subdev_pad_config *cfg,
- + struct v4l2_subdev_frame_size_enum *fse)
- +{
- + int index = fse->index;
- +
- + if (index >= N_RES)
- + return -EINVAL;
- +
- + fse->min_width = ov5693_res[index].width;
- + fse->min_height = ov5693_res[index].height;
- + fse->max_width = ov5693_res[index].width;
- + fse->max_height = ov5693_res[index].height;
- +
- + return 0;
- +}
- +
- +static const struct v4l2_subdev_video_ops ov5693_video_ops = {
- + .s_stream = ov5693_s_stream,
- + .g_frame_interval = ov5693_g_frame_interval,
- +};
- +
- +static const struct v4l2_subdev_core_ops ov5693_core_ops = {
- + .s_power = ov5693_s_power,
- +};
- +
- +static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
- + .enum_mbus_code = ov5693_enum_mbus_code,
- + .enum_frame_size = ov5693_enum_frame_size,
- + .get_fmt = ov5693_get_fmt,
- + .set_fmt = ov5693_set_fmt,
- + .get_selection = ov5693_get_selection,
- +};
- +
- +static const struct v4l2_subdev_ops ov5693_ops = {
- + .core = &ov5693_core_ops,
- + .video = &ov5693_video_ops,
- + .pad = &ov5693_pad_ops,
- +};
- +
- +static int ov5693_remove(struct i2c_client *client)
- +{
- + struct v4l2_subdev *sd = i2c_get_clientdata(client);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- + unsigned int i = OV5693_NUM_SUPPLIES;
- +
- + dev_info(&client->dev, "%s...\n", __func__);
- +
- + gpiod_put(ov5693->reset);
- + gpiod_put(ov5693->indicator_led);
- + while (i--)
- + regulator_put(ov5693->supplies[i].consumer);
- +
- + v4l2_async_unregister_subdev(sd);
- +
- + media_entity_cleanup(&ov5693->sd.entity);
- + v4l2_ctrl_handler_free(&ov5693->ctrl_handler);
- + kfree(ov5693);
- +
- + return 0;
- +}
- +
- +static int ov5693_init_controls(struct ov5693_device *ov5693)
- +{
- + struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
- + const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
- + struct v4l2_ctrl *ctrl;
- + unsigned int i;
- + int ret;
- + int hblank;
- +
- + ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
- + ARRAY_SIZE(ov5693_controls));
- + if (ret) {
- + ov5693_remove(client);
- + return ret;
- + }
- +
- + for (i = 0; i < ARRAY_SIZE(ov5693_controls); i++)
- + v4l2_ctrl_new_custom(&ov5693->ctrl_handler,
- + &ov5693_controls[i],
- + NULL);
- +
- + /* link freq */
- + ctrl = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler, NULL,
- + V4L2_CID_LINK_FREQ,
- + 0, 0, link_freq_menu_items);
- + if (ctrl)
- + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- +
- + /* pixel rate */
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
- + 0, OV5693_PIXEL_RATE, 1, OV5693_PIXEL_RATE);
- +
- + if (ov5693->ctrl_handler.error) {
- + ov5693_remove(client);
- + return ov5693->ctrl_handler.error;
- + }
- +
- + /* Exposure */
- +
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
- + 512);
- +
- + /* Gain */
- +
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_ANALOGUE_GAIN, 1, 1023, 1, 128);
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_DIGITAL_GAIN, 1, 3999, 1, 1000);
- +
- + /* Flip */
- +
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
- + v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
- +
- + hblank = OV5693_PPL_DEFAULT - ov5693->mode->width;
- + ov5693->hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_HBLANK, hblank, hblank,
- + 1, hblank);
- + if (ov5693->hblank)
- + ov5693->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- +
- + /* Use same lock for controls as for everything else. */
- + ov5693->ctrl_handler.lock = &ov5693->input_lock;
- + ov5693->sd.ctrl_handler = &ov5693->ctrl_handler;
- +
- + return 0;
- +}
- +
- +static int ov5693_configure_gpios(struct ov5693_device *ov5693)
- +{
- + ov5693->reset = gpiod_get_index(&ov5693->i2c_client->dev, "reset", 0,
- + GPIOD_OUT_HIGH);
- + if (IS_ERR(ov5693->reset)) {
- + dev_err(&ov5693->i2c_client->dev, "Couldn't find reset GPIO\n");
- + return -EINVAL;
- + }
- +
- + ov5693->indicator_led = gpiod_get_index_optional(&ov5693->i2c_client->dev, "indicator-led", 0,
- + GPIOD_OUT_HIGH);
- + if (IS_ERR(ov5693->indicator_led)) {
- + dev_err(&ov5693->i2c_client->dev, "Couldn't find indicator-led GPIO\n");
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static int ov5693_get_regulators(struct ov5693_device *ov5693)
- +{
- + unsigned int i;
- +
- + for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
- + ov5693->supplies[i].supply = ov5693_supply_names[i];
- +
- + return regulator_bulk_get(&ov5693->i2c_client->dev,
- + OV5693_NUM_SUPPLIES,
- + ov5693->supplies);
- +}
- +
- +static int ov5693_probe(struct i2c_client *client)
- +{
- + struct ov5693_device *ov5693;
- + int ret = 0;
- +
- + dev_info(&client->dev, "%s() called", __func__);
- +
- + ov5693 = kzalloc(sizeof(*ov5693), GFP_KERNEL);
- + if (!ov5693)
- + return -ENOMEM;
- +
- + ov5693->i2c_client = client;
- +
- + /* check if VCM device exists */
- + /* TODO: read from SSDB */
- + ov5693->has_vcm = false;
- +
- + mutex_init(&ov5693->input_lock);
- +
- + v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
- +
- + ov5693->clk = devm_clk_get(&client->dev, "xvclk");
- + if (IS_ERR(ov5693->clk)) {
- + dev_err(&client->dev, "Error getting clock\n");
- + return -EINVAL;
- + }
- +
- + ret = ov5693_configure_gpios(ov5693);
- + if (ret)
- + goto out_free;
- +
- + ret = ov5693_get_regulators(ov5693);
- + if (ret)
- + goto out_put_reset;
- +
- + ret = ov5693_s_config(&ov5693->sd, client->irq);
- + if (ret)
- + goto out_put_reset;
- +
- + ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- + ov5693->pad.flags = MEDIA_PAD_FL_SOURCE;
- + ov5693->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
- + ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
- + ov5693->mode = &ov5693_res_video[N_RES_VIDEO-1];
- +
- + ret = ov5693_init_controls(ov5693);
- + if (ret)
- + ov5693_remove(client);
- +
- + ret = media_entity_pads_init(&ov5693->sd.entity, 1, &ov5693->pad);
- + if (ret)
- + ov5693_remove(client);
- +
- + ret = v4l2_async_register_subdev_sensor_common(&ov5693->sd);
- + if (ret) {
- + dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret);
- + goto media_entity_cleanup;
- + }
- +
- + return ret;
- +
- +media_entity_cleanup:
- + media_entity_cleanup(&ov5693->sd.entity);
- +out_put_reset:
- + gpiod_put(ov5693->reset);
- +out_free:
- + v4l2_device_unregister_subdev(&ov5693->sd);
- + kfree(ov5693);
- + return ret;
- +}
- +
- +static const struct acpi_device_id ov5693_acpi_match[] = {
- + {"INT33BE"},
- + {},
- +};
- +MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match);
- +
- +static struct i2c_driver ov5693_driver = {
- + .driver = {
- + .name = "ov5693",
- + .acpi_match_table = ov5693_acpi_match,
- + },
- + .probe_new = ov5693_probe,
- + .remove = ov5693_remove,
- +};
- +module_i2c_driver(ov5693_driver);
- +
- +MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors");
- +MODULE_LICENSE("GPL");
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- new file mode 100644
- index 000000000000..9a508e1f3624
- --- /dev/null
- +++ b/drivers/media/i2c/ov5693.h
- @@ -0,0 +1,1430 @@
- +/* SPDX-License-Identifier: GPL-2.0 */
- +/*
- + * Support for OmniVision OV5693 5M camera sensor.
- + *
- + * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License version
- + * 2 as published by the Free Software Foundation.
- + *
- + * 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.
- + *
- + *
- + */
- +
- +#ifndef __OV5693_H__
- +#define __OV5693_H__
- +#include <linux/kernel.h>
- +#include <linux/types.h>
- +#include <linux/i2c.h>
- +#include <linux/delay.h>
- +#include <linux/videodev2.h>
- +#include <linux/spinlock.h>
- +#include <media/v4l2-subdev.h>
- +#include <media/v4l2-device.h>
- +#include <media/v4l2-ctrls.h>
- +#include <linux/v4l2-mediabus.h>
- +#include <media/media-entity.h>
- +
- +#define OV5693_HID "INT33BE"
- +
- +/*
- + * FIXME: non-preview resolutions are currently broken
- + */
- +#define ENABLE_NON_PREVIEW 1
- +
- +#define OV5693_POWER_UP_RETRY_NUM 5
- +
- +/* Defines for register writes and register array processing */
- +#define I2C_MSG_LENGTH 0x2
- +#define I2C_RETRY_COUNT 5
- +
- +#define OV5693_FOCAL_LENGTH_NUM 334 /*3.34mm*/
- +#define OV5693_FOCAL_LENGTH_DEM 100
- +#define OV5693_F_NUMBER_DEFAULT_NUM 24
- +#define OV5693_F_NUMBER_DEM 10
- +
- +#define MAX_FMTS 1
- +
- +/* sensor_mode_data read_mode adaptation */
- +#define OV5693_READ_MODE_BINNING_ON 0x0400
- +#define OV5693_READ_MODE_BINNING_OFF 0x00
- +#define OV5693_INTEGRATION_TIME_MARGIN 8
- +
- +#define OV5693_MAX_EXPOSURE_VALUE 0xFFF1
- +#define OV5693_MAX_GAIN_VALUE 0xFF
- +
- +/*
- + * focal length bits definition:
- + * bits 31-16: numerator, bits 15-0: denominator
- + */
- +#define OV5693_FOCAL_LENGTH_DEFAULT 0x1B70064
- +
- +/*
- + * current f-number bits definition:
- + * bits 31-16: numerator, bits 15-0: denominator
- + */
- +#define OV5693_F_NUMBER_DEFAULT 0x18000a
- +
- +/*
- + * f-number range bits definition:
- + * bits 31-24: max f-number numerator
- + * bits 23-16: max f-number denominator
- + * bits 15-8: min f-number numerator
- + * bits 7-0: min f-number denominator
- + */
- +#define OV5693_F_NUMBER_RANGE 0x180a180a
- +#define OV5693_ID 0x5690
- +
- +#define OV5693_FINE_INTG_TIME_MIN 0
- +#define OV5693_FINE_INTG_TIME_MAX_MARGIN 0
- +#define OV5693_COARSE_INTG_TIME_MIN 1
- +#define OV5693_COARSE_INTG_TIME_MAX_MARGIN 6
- +
- +#define OV5693_BIN_FACTOR_MAX 4
- +/*
- + * OV5693 System control registers
- + */
- +#define OV5693_SW_SLEEP 0x0100
- +#define OV5693_SW_RESET 0x0103
- +#define OV5693_SW_STREAM 0x0100
- +
- +#define OV5693_SC_CMMN_CHIP_ID_H 0x300A
- +#define OV5693_SC_CMMN_CHIP_ID_L 0x300B
- +#define OV5693_SC_CMMN_SCCB_ID 0x300C
- +#define OV5693_SC_CMMN_SUB_ID 0x302A /* process, version*/
- +/*Bit[7:4] Group control, Bit[3:0] Group ID*/
- +#define OV5693_GROUP_ACCESS 0x3208
- +/*
- +*Bit[3:0] Bit[19:16] of exposure,
- +*remaining 16 bits lies in Reg0x3501&Reg0x3502
- +*/
- +#define OV5693_EXPOSURE_H 0x3500
- +#define OV5693_EXPOSURE_M 0x3501
- +#define OV5693_EXPOSURE_L 0x3502
- +/*Bit[1:0] means Bit[9:8] of gain*/
- +#define OV5693_AGC_H 0x350A
- +#define OV5693_AGC_L 0x350B /*Bit[7:0] of gain*/
- +
- +#define OV5693_HORIZONTAL_START_H 0x3800 /*Bit[11:8]*/
- +#define OV5693_HORIZONTAL_START_L 0x3801 /*Bit[7:0]*/
- +#define OV5693_VERTICAL_START_H 0x3802 /*Bit[11:8]*/
- +#define OV5693_VERTICAL_START_L 0x3803 /*Bit[7:0]*/
- +#define OV5693_HORIZONTAL_END_H 0x3804 /*Bit[11:8]*/
- +#define OV5693_HORIZONTAL_END_L 0x3805 /*Bit[7:0]*/
- +#define OV5693_VERTICAL_END_H 0x3806 /*Bit[11:8]*/
- +#define OV5693_VERTICAL_END_L 0x3807 /*Bit[7:0]*/
- +#define OV5693_HORIZONTAL_OUTPUT_SIZE_H 0x3808 /*Bit[3:0]*/
- +#define OV5693_HORIZONTAL_OUTPUT_SIZE_L 0x3809 /*Bit[7:0]*/
- +#define OV5693_VERTICAL_OUTPUT_SIZE_H 0x380a /*Bit[3:0]*/
- +#define OV5693_VERTICAL_OUTPUT_SIZE_L 0x380b /*Bit[7:0]*/
- +/*High 8-bit, and low 8-bit HTS address is 0x380d*/
- +#define OV5693_TIMING_HTS_H 0x380C
- +/*High 8-bit, and low 8-bit HTS address is 0x380d*/
- +#define OV5693_TIMING_HTS_L 0x380D
- +/*High 8-bit, and low 8-bit HTS address is 0x380f*/
- +#define OV5693_TIMING_VTS_H 0x380e
- +/*High 8-bit, and low 8-bit HTS address is 0x380f*/
- +#define OV5693_TIMING_VTS_L 0x380f
- +
- +#define OV5693_MWB_RED_GAIN_H 0x3400
- +#define OV5693_MWB_GREEN_GAIN_H 0x3402
- +#define OV5693_MWB_BLUE_GAIN_H 0x3404
- +#define OV5693_MWB_GAIN_MAX 0x0fff
- +
- +#define OV5693_START_STREAMING 0x01
- +#define OV5693_STOP_STREAMING 0x00
- +
- +#define VCM_ADDR 0x0c
- +#define VCM_CODE_MSB 0x04
- +
- +#define OV5693_INVALID_CONFIG 0xffffffff
- +
- +#define OV5693_VCM_SLEW_STEP 0x30F0
- +#define OV5693_VCM_SLEW_STEP_MAX 0x7
- +#define OV5693_VCM_SLEW_STEP_MASK 0x7
- +#define OV5693_VCM_CODE 0x30F2
- +#define OV5693_VCM_SLEW_TIME 0x30F4
- +#define OV5693_VCM_SLEW_TIME_MAX 0xffff
- +#define OV5693_VCM_ENABLE 0x8000
- +
- +#define OV5693_VCM_MAX_FOCUS_NEG -1023
- +#define OV5693_VCM_MAX_FOCUS_POS 1023
- +
- +#define DLC_ENABLE 1
- +#define DLC_DISABLE 0
- +#define VCM_PROTECTION_OFF 0xeca3
- +#define VCM_PROTECTION_ON 0xdc51
- +#define VCM_DEFAULT_S 0x0
- +#define vcm_step_s(a) (u8)(a & 0xf)
- +#define vcm_step_mclk(a) (u8)((a >> 4) & 0x3)
- +#define vcm_dlc_mclk(dlc, mclk) (u16)((dlc << 3) | mclk | 0xa104)
- +#define vcm_tsrc(tsrc) (u16)(tsrc << 3 | 0xf200)
- +#define vcm_val(data, s) (u16)(data << 4 | s)
- +#define DIRECT_VCM vcm_dlc_mclk(0, 0)
- +
- +/* Defines for OTP Data Registers */
- +#define OV5693_FRAME_OFF_NUM 0x4202
- +#define OV5693_OTP_BYTE_MAX 32 //change to 32 as needed by otpdata
- +#define OV5693_OTP_SHORT_MAX 16
- +#define OV5693_OTP_START_ADDR 0x3D00
- +#define OV5693_OTP_END_ADDR 0x3D0F
- +#define OV5693_OTP_DATA_SIZE 320
- +#define OV5693_OTP_PROGRAM_REG 0x3D80
- +#define OV5693_OTP_READ_REG 0x3D81 // 1:Enable 0:disable
- +#define OV5693_OTP_BANK_REG 0x3D84 //otp bank and mode
- +#define OV5693_OTP_READY_REG_DONE 1
- +#define OV5693_OTP_BANK_MAX 28
- +#define OV5693_OTP_BANK_SIZE 16 //16 bytes per bank
- +#define OV5693_OTP_READ_ONETIME 16
- +#define OV5693_OTP_MODE_READ 1
- +
- +/* link freq and pixel rate required for IPU3 */
- +#define OV5693_LINK_FREQ_640MHZ 640000000
- +/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
- + * To avoid integer overflow, dividing by bits_per_sample first.
- + */
- +#define OV5693_PIXEL_RATE (OV5693_LINK_FREQ_640MHZ / 10) * 2 * 2
- +static const s64 link_freq_menu_items[] = {
- + OV5693_LINK_FREQ_640MHZ
- +};
- +
- +#define OV5693_NUM_SUPPLIES 2
- +static const char * const ov5693_supply_names[] = {
- + "avdd",
- + "dovdd",
- +};
- +
- +struct regval_list {
- + u16 reg_num;
- + u8 value;
- +};
- +
- +struct ov5693_resolution {
- + u8 *desc;
- + const struct ov5693_reg *regs;
- + int res;
- + int width;
- + int height;
- + int fps;
- + int pix_clk_freq;
- + u16 pixels_per_line;
- + u16 lines_per_frame;
- + u8 bin_factor_x;
- + u8 bin_factor_y;
- + u8 bin_mode;
- + bool used;
- +
- + /* Analog crop rectangle. */
- + struct v4l2_rect crop;
- +};
- +
- +struct ov5693_format {
- + u8 *desc;
- + u32 pixelformat;
- + struct ov5693_reg *regs;
- +};
- +
- +enum vcm_type {
- + VCM_UNKNOWN,
- + VCM_AD5823,
- + VCM_DW9714,
- +};
- +
- +/*
- + * ov5693 device structure.
- + */
- +struct ov5693_device {
- + struct i2c_client *i2c_client;
- + struct v4l2_subdev sd;
- + struct media_pad pad;
- + struct v4l2_mbus_framefmt format;
- + struct mutex input_lock;
- + struct v4l2_ctrl_handler ctrl_handler;
- +
- + struct gpio_desc *reset;
- + struct gpio_desc *indicator_led;
- + struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
- + struct clk *clk;
- +
- + /* Current mode */
- + const struct ov5693_resolution *mode;
- +
- + struct camera_sensor_platform_data *platform_data;
- + ktime_t timestamp_t_focus_abs;
- + int vt_pix_clk_freq_mhz;
- + int fmt_idx;
- + int run_mode;
- + int otp_size;
- + u8 *otp_data;
- + u32 focus;
- + s16 number_of_steps;
- + u8 res;
- + u8 type;
- + bool vcm_update;
- + enum vcm_type vcm;
- +
- + bool has_vcm;
- +
- + struct v4l2_ctrl *hblank;
- +};
- +
- +enum ov5693_tok_type {
- + OV5693_8BIT = 0x0001,
- + OV5693_16BIT = 0x0002,
- + OV5693_32BIT = 0x0004,
- + OV5693_TOK_TERM = 0xf000, /* terminating token for reg list */
- + OV5693_TOK_DELAY = 0xfe00, /* delay token for reg list */
- + OV5693_TOK_MASK = 0xfff0
- +};
- +
- +/**
- + * struct ov5693_reg - MI sensor register format
- + * @type: type of the register
- + * @reg: 16-bit offset to register
- + * @val: 8/16/32-bit register value
- + *
- + * Define a structure for sensor register initialization values
- + */
- +struct ov5693_reg {
- + enum ov5693_tok_type type;
- + u16 reg;
- + u32 val; /* @set value for read/mod/write, @mask */
- +};
- +
- +#define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd)
- +
- +#define OV5693_MAX_WRITE_BUF_SIZE 30
- +
- +struct ov5693_write_buffer {
- + u16 addr;
- + u8 data[OV5693_MAX_WRITE_BUF_SIZE];
- +};
- +
- +struct ov5693_write_ctrl {
- + int index;
- + struct ov5693_write_buffer buffer;
- +};
- +
- +static struct ov5693_reg const ov5693_global_setting[] = {
- + {OV5693_8BIT, 0x0103, 0x01},
- + {OV5693_8BIT, 0x3001, 0x0a},
- + {OV5693_8BIT, 0x3002, 0x80},
- + {OV5693_8BIT, 0x3006, 0x00},
- + {OV5693_8BIT, 0x3011, 0x21},
- + {OV5693_8BIT, 0x3012, 0x09},
- + {OV5693_8BIT, 0x3013, 0x10},
- + {OV5693_8BIT, 0x3014, 0x00},
- + {OV5693_8BIT, 0x3015, 0x08},
- + {OV5693_8BIT, 0x3016, 0xf0},
- + {OV5693_8BIT, 0x3017, 0xf0},
- + {OV5693_8BIT, 0x3018, 0xf0},
- + {OV5693_8BIT, 0x301b, 0xb4},
- + {OV5693_8BIT, 0x301d, 0x02},
- + {OV5693_8BIT, 0x3021, 0x00},
- + {OV5693_8BIT, 0x3022, 0x01},
- + {OV5693_8BIT, 0x3028, 0x44},
- + {OV5693_8BIT, 0x3098, 0x02},
- + {OV5693_8BIT, 0x3099, 0x19},
- + {OV5693_8BIT, 0x309a, 0x02},
- + {OV5693_8BIT, 0x309b, 0x01},
- + {OV5693_8BIT, 0x309c, 0x00},
- + {OV5693_8BIT, 0x30a0, 0xd2},
- + {OV5693_8BIT, 0x30a2, 0x01},
- + {OV5693_8BIT, 0x30b2, 0x00},
- + {OV5693_8BIT, 0x30b3, 0x7d},
- + {OV5693_8BIT, 0x30b4, 0x03},
- + {OV5693_8BIT, 0x30b5, 0x04},
- + {OV5693_8BIT, 0x30b6, 0x01},
- + {OV5693_8BIT, 0x3104, 0x21},
- + {OV5693_8BIT, 0x3106, 0x00},
- + {OV5693_8BIT, 0x3400, 0x04},
- + {OV5693_8BIT, 0x3401, 0x00},
- + {OV5693_8BIT, 0x3402, 0x04},
- + {OV5693_8BIT, 0x3403, 0x00},
- + {OV5693_8BIT, 0x3404, 0x04},
- + {OV5693_8BIT, 0x3405, 0x00},
- + {OV5693_8BIT, 0x3406, 0x01},
- + {OV5693_8BIT, 0x3500, 0x00},
- + {OV5693_8BIT, 0x3503, 0x07},
- + {OV5693_8BIT, 0x3504, 0x00},
- + {OV5693_8BIT, 0x3505, 0x00},
- + {OV5693_8BIT, 0x3506, 0x00},
- + {OV5693_8BIT, 0x3507, 0x02},
- + {OV5693_8BIT, 0x3508, 0x00},
- + {OV5693_8BIT, 0x3509, 0x10},
- + {OV5693_8BIT, 0x350a, 0x00},
- + {OV5693_8BIT, 0x350b, 0x40},
- + {OV5693_8BIT, 0x3601, 0x0a},
- + {OV5693_8BIT, 0x3602, 0x38},
- + {OV5693_8BIT, 0x3612, 0x80},
- + {OV5693_8BIT, 0x3620, 0x54},
- + {OV5693_8BIT, 0x3621, 0xc7},
- + {OV5693_8BIT, 0x3622, 0x0f},
- + {OV5693_8BIT, 0x3625, 0x10},
- + {OV5693_8BIT, 0x3630, 0x55},
- + {OV5693_8BIT, 0x3631, 0xf4},
- + {OV5693_8BIT, 0x3632, 0x00},
- + {OV5693_8BIT, 0x3633, 0x34},
- + {OV5693_8BIT, 0x3634, 0x02},
- + {OV5693_8BIT, 0x364d, 0x0d},
- + {OV5693_8BIT, 0x364f, 0xdd},
- + {OV5693_8BIT, 0x3660, 0x04},
- + {OV5693_8BIT, 0x3662, 0x10},
- + {OV5693_8BIT, 0x3663, 0xf1},
- + {OV5693_8BIT, 0x3665, 0x00},
- + {OV5693_8BIT, 0x3666, 0x20},
- + {OV5693_8BIT, 0x3667, 0x00},
- + {OV5693_8BIT, 0x366a, 0x80},
- + {OV5693_8BIT, 0x3680, 0xe0},
- + {OV5693_8BIT, 0x3681, 0x00},
- + {OV5693_8BIT, 0x3700, 0x42},
- + {OV5693_8BIT, 0x3701, 0x14},
- + {OV5693_8BIT, 0x3702, 0xa0},
- + {OV5693_8BIT, 0x3703, 0xd8},
- + {OV5693_8BIT, 0x3704, 0x78},
- + {OV5693_8BIT, 0x3705, 0x02},
- + {OV5693_8BIT, 0x370a, 0x00},
- + {OV5693_8BIT, 0x370b, 0x20},
- + {OV5693_8BIT, 0x370c, 0x0c},
- + {OV5693_8BIT, 0x370d, 0x11},
- + {OV5693_8BIT, 0x370e, 0x00},
- + {OV5693_8BIT, 0x370f, 0x40},
- + {OV5693_8BIT, 0x3710, 0x00},
- + {OV5693_8BIT, 0x371a, 0x1c},
- + {OV5693_8BIT, 0x371b, 0x05},
- + {OV5693_8BIT, 0x371c, 0x01},
- + {OV5693_8BIT, 0x371e, 0xa1},
- + {OV5693_8BIT, 0x371f, 0x0c},
- + {OV5693_8BIT, 0x3721, 0x00},
- + {OV5693_8BIT, 0x3724, 0x10},
- + {OV5693_8BIT, 0x3726, 0x00},
- + {OV5693_8BIT, 0x372a, 0x01},
- + {OV5693_8BIT, 0x3730, 0x10},
- + {OV5693_8BIT, 0x3738, 0x22},
- + {OV5693_8BIT, 0x3739, 0xe5},
- + {OV5693_8BIT, 0x373a, 0x50},
- + {OV5693_8BIT, 0x373b, 0x02},
- + {OV5693_8BIT, 0x373c, 0x41},
- + {OV5693_8BIT, 0x373f, 0x02},
- + {OV5693_8BIT, 0x3740, 0x42},
- + {OV5693_8BIT, 0x3741, 0x02},
- + {OV5693_8BIT, 0x3742, 0x18},
- + {OV5693_8BIT, 0x3743, 0x01},
- + {OV5693_8BIT, 0x3744, 0x02},
- + {OV5693_8BIT, 0x3747, 0x10},
- + {OV5693_8BIT, 0x374c, 0x04},
- + {OV5693_8BIT, 0x3751, 0xf0},
- + {OV5693_8BIT, 0x3752, 0x00},
- + {OV5693_8BIT, 0x3753, 0x00},
- + {OV5693_8BIT, 0x3754, 0xc0},
- + {OV5693_8BIT, 0x3755, 0x00},
- + {OV5693_8BIT, 0x3756, 0x1a},
- + {OV5693_8BIT, 0x3758, 0x00},
- + {OV5693_8BIT, 0x3759, 0x0f},
- + {OV5693_8BIT, 0x376b, 0x44},
- + {OV5693_8BIT, 0x375c, 0x04},
- + {OV5693_8BIT, 0x3774, 0x10},
- + {OV5693_8BIT, 0x3776, 0x00},
- + {OV5693_8BIT, 0x377f, 0x08},
- + {OV5693_8BIT, 0x3780, 0x22},
- + {OV5693_8BIT, 0x3781, 0x0c},
- + {OV5693_8BIT, 0x3784, 0x2c},
- + {OV5693_8BIT, 0x3785, 0x1e},
- + {OV5693_8BIT, 0x378f, 0xf5},
- + {OV5693_8BIT, 0x3791, 0xb0},
- + {OV5693_8BIT, 0x3795, 0x00},
- + {OV5693_8BIT, 0x3796, 0x64},
- + {OV5693_8BIT, 0x3797, 0x11},
- + {OV5693_8BIT, 0x3798, 0x30},
- + {OV5693_8BIT, 0x3799, 0x41},
- + {OV5693_8BIT, 0x379a, 0x07},
- + {OV5693_8BIT, 0x379b, 0xb0},
- + {OV5693_8BIT, 0x379c, 0x0c},
- + {OV5693_8BIT, 0x37c5, 0x00},
- + {OV5693_8BIT, 0x37c6, 0x00},
- + {OV5693_8BIT, 0x37c7, 0x00},
- + {OV5693_8BIT, 0x37c9, 0x00},
- + {OV5693_8BIT, 0x37ca, 0x00},
- + {OV5693_8BIT, 0x37cb, 0x00},
- + {OV5693_8BIT, 0x37de, 0x00},
- + {OV5693_8BIT, 0x37df, 0x00},
- + {OV5693_8BIT, 0x3800, 0x00},
- + {OV5693_8BIT, 0x3801, 0x00},
- + {OV5693_8BIT, 0x3802, 0x00},
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3810, 0x00},
- + {OV5693_8BIT, 0x3812, 0x00},
- + {OV5693_8BIT, 0x3823, 0x00},
- + {OV5693_8BIT, 0x3824, 0x00},
- + {OV5693_8BIT, 0x3825, 0x00},
- + {OV5693_8BIT, 0x3826, 0x00},
- + {OV5693_8BIT, 0x3827, 0x00},
- + {OV5693_8BIT, 0x382a, 0x04},
- + {OV5693_8BIT, 0x3a04, 0x06},
- + {OV5693_8BIT, 0x3a05, 0x14},
- + {OV5693_8BIT, 0x3a06, 0x00},
- + {OV5693_8BIT, 0x3a07, 0xfe},
- + {OV5693_8BIT, 0x3b00, 0x00},
- + {OV5693_8BIT, 0x3b02, 0x00},
- + {OV5693_8BIT, 0x3b03, 0x00},
- + {OV5693_8BIT, 0x3b04, 0x00},
- + {OV5693_8BIT, 0x3b05, 0x00},
- + {OV5693_8BIT, 0x3e07, 0x20},
- + {OV5693_8BIT, 0x4000, 0x08},
- + {OV5693_8BIT, 0x4001, 0x04},
- + {OV5693_8BIT, 0x4002, 0x45},
- + {OV5693_8BIT, 0x4004, 0x08},
- + {OV5693_8BIT, 0x4005, 0x18},
- + {OV5693_8BIT, 0x4006, 0x20},
- + {OV5693_8BIT, 0x4008, 0x24},
- + {OV5693_8BIT, 0x4009, 0x10},
- + {OV5693_8BIT, 0x400c, 0x00},
- + {OV5693_8BIT, 0x400d, 0x00},
- + {OV5693_8BIT, 0x4058, 0x00},
- + {OV5693_8BIT, 0x404e, 0x37},
- + {OV5693_8BIT, 0x404f, 0x8f},
- + {OV5693_8BIT, 0x4058, 0x00},
- + {OV5693_8BIT, 0x4101, 0xb2},
- + {OV5693_8BIT, 0x4303, 0x00},
- + {OV5693_8BIT, 0x4304, 0x08},
- + {OV5693_8BIT, 0x4307, 0x31},
- + {OV5693_8BIT, 0x4311, 0x04},
- + {OV5693_8BIT, 0x4315, 0x01},
- + {OV5693_8BIT, 0x4511, 0x05},
- + {OV5693_8BIT, 0x4512, 0x01},
- + {OV5693_8BIT, 0x4806, 0x00},
- + {OV5693_8BIT, 0x4816, 0x52},
- + {OV5693_8BIT, 0x481f, 0x30},
- + {OV5693_8BIT, 0x4826, 0x2c},
- + {OV5693_8BIT, 0x4831, 0x64},
- + {OV5693_8BIT, 0x4d00, 0x04},
- + {OV5693_8BIT, 0x4d01, 0x71},
- + {OV5693_8BIT, 0x4d02, 0xfd},
- + {OV5693_8BIT, 0x4d03, 0xf5},
- + {OV5693_8BIT, 0x4d04, 0x0c},
- + {OV5693_8BIT, 0x4d05, 0xcc},
- + {OV5693_8BIT, 0x4837, 0x0a},
- + {OV5693_8BIT, 0x5000, 0x06},
- + {OV5693_8BIT, 0x5001, 0x01},
- + {OV5693_8BIT, 0x5003, 0x20},
- + {OV5693_8BIT, 0x5046, 0x0a},
- + {OV5693_8BIT, 0x5013, 0x00},
- + {OV5693_8BIT, 0x5046, 0x0a},
- + {OV5693_8BIT, 0x5780, 0x1c},
- + {OV5693_8BIT, 0x5786, 0x20},
- + {OV5693_8BIT, 0x5787, 0x10},
- + {OV5693_8BIT, 0x5788, 0x18},
- + {OV5693_8BIT, 0x578a, 0x04},
- + {OV5693_8BIT, 0x578b, 0x02},
- + {OV5693_8BIT, 0x578c, 0x02},
- + {OV5693_8BIT, 0x578e, 0x06},
- + {OV5693_8BIT, 0x578f, 0x02},
- + {OV5693_8BIT, 0x5790, 0x02},
- + {OV5693_8BIT, 0x5791, 0xff},
- + {OV5693_8BIT, 0x5842, 0x01},
- + {OV5693_8BIT, 0x5843, 0x2b},
- + {OV5693_8BIT, 0x5844, 0x01},
- + {OV5693_8BIT, 0x5845, 0x92},
- + {OV5693_8BIT, 0x5846, 0x01},
- + {OV5693_8BIT, 0x5847, 0x8f},
- + {OV5693_8BIT, 0x5848, 0x01},
- + {OV5693_8BIT, 0x5849, 0x0c},
- + {OV5693_8BIT, 0x5e00, 0x00},
- + {OV5693_8BIT, 0x5e10, 0x0c},
- + {OV5693_8BIT, 0x0100, 0x00},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +#if ENABLE_NON_PREVIEW
- +/*
- + * 654x496 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- + */
- +static struct ov5693_reg const ov5693_654x496[] = {
- + {OV5693_8BIT, 0x3501, 0x3d},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe6},
- + {OV5693_8BIT, 0x3709, 0xc7},
- + {OV5693_8BIT, 0x3803, 0x00},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xa3},
- + {OV5693_8BIT, 0x3808, 0x02},
- + {OV5693_8BIT, 0x3809, 0x90},
- + {OV5693_8BIT, 0x380a, 0x01},
- + {OV5693_8BIT, 0x380b, 0xf0},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x08},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x04},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*
- + * 1296x976 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- +*DS from 2592x1952
- +*/
- +static struct ov5693_reg const ov5693_1296x976[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- +
- + {OV5693_8BIT, 0x3800, 0x00},
- + {OV5693_8BIT, 0x3801, 0x00},
- + {OV5693_8BIT, 0x3802, 0x00},
- + {OV5693_8BIT, 0x3803, 0x00},
- +
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xA3},
- +
- + {OV5693_8BIT, 0x3808, 0x05},
- + {OV5693_8BIT, 0x3809, 0x10},
- + {OV5693_8BIT, 0x380a, 0x03},
- + {OV5693_8BIT, 0x380b, 0xD0},
- +
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- +
- + {OV5693_8BIT, 0x3810, 0x00},
- + {OV5693_8BIT, 0x3811, 0x10},
- + {OV5693_8BIT, 0x3812, 0x00},
- + {OV5693_8BIT, 0x3813, 0x02},
- +
- + {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/
- + {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +
- +};
- +
- +/*
- + * 336x256 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- + DS from 2564x1956
- + */
- +static struct ov5693_reg const ov5693_336x256[] = {
- + {OV5693_8BIT, 0x3501, 0x3d},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe6},
- + {OV5693_8BIT, 0x3709, 0xc7},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xa3},
- + {OV5693_8BIT, 0x3808, 0x01},
- + {OV5693_8BIT, 0x3809, 0x50},
- + {OV5693_8BIT, 0x380a, 0x01},
- + {OV5693_8BIT, 0x380b, 0x00},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x1E},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x04},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*
- + * 336x256 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- + DS from 2368x1956
- + */
- +static struct ov5693_reg const ov5693_368x304[] = {
- + {OV5693_8BIT, 0x3501, 0x3d},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe6},
- + {OV5693_8BIT, 0x3709, 0xc7},
- + {OV5693_8BIT, 0x3808, 0x01},
- + {OV5693_8BIT, 0x3809, 0x70},
- + {OV5693_8BIT, 0x380a, 0x01},
- + {OV5693_8BIT, 0x380b, 0x30},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x80},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x04},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*
- + * ov5693_192x160 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- + DS from 2460x1956
- + */
- +static struct ov5693_reg const ov5693_192x160[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x80},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xA3},
- + {OV5693_8BIT, 0x3808, 0x00},
- + {OV5693_8BIT, 0x3809, 0xC0},
- + {OV5693_8BIT, 0x380a, 0x00},
- + {OV5693_8BIT, 0x380b, 0xA0},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x40},
- + {OV5693_8BIT, 0x3813, 0x00},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x04},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +static struct ov5693_reg const ov5693_736x496[] = {
- + {OV5693_8BIT, 0x3501, 0x3d},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe6},
- + {OV5693_8BIT, 0x3709, 0xc7},
- + {OV5693_8BIT, 0x3803, 0x68},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0x3b},
- + {OV5693_8BIT, 0x3808, 0x02},
- + {OV5693_8BIT, 0x3809, 0xe0},
- + {OV5693_8BIT, 0x380a, 0x01},
- + {OV5693_8BIT, 0x380b, 0xf0},
- + {OV5693_8BIT, 0x380c, 0x0a}, /*hts*/
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07}, /*vts*/
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x08},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x04},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +#endif
- +
- +/*
- +static struct ov5693_reg const ov5693_736x496[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe6},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0x00},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xa3},
- + {OV5693_8BIT, 0x3808, 0x02},
- + {OV5693_8BIT, 0x3809, 0xe0},
- + {OV5693_8BIT, 0x380a, 0x01},
- + {OV5693_8BIT, 0x380b, 0xf0},
- + {OV5693_8BIT, 0x380c, 0x0d},
- + {OV5693_8BIT, 0x380d, 0xb0},
- + {OV5693_8BIT, 0x380e, 0x05},
- + {OV5693_8BIT, 0x380f, 0xf2},
- + {OV5693_8BIT, 0x3811, 0x08},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x31},
- + {OV5693_8BIT, 0x3815, 0x31},
- + {OV5693_8BIT, 0x3820, 0x01},
- + {OV5693_8BIT, 0x3821, 0x1f},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +*/
- +/*
- + * 976x556 30fps 8.8ms VBlanking 2lane 10Bit (Scaling)
- + */
- +#if ENABLE_NON_PREVIEW
- +static struct ov5693_reg const ov5693_976x556[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0xf0},
- + {OV5693_8BIT, 0x3806, 0x06},
- + {OV5693_8BIT, 0x3807, 0xa7},
- + {OV5693_8BIT, 0x3808, 0x03},
- + {OV5693_8BIT, 0x3809, 0xd0},
- + {OV5693_8BIT, 0x380a, 0x02},
- + {OV5693_8BIT, 0x380b, 0x2C},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x10},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*DS from 2624x1492*/
- +static struct ov5693_reg const ov5693_1296x736[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- +
- + {OV5693_8BIT, 0x3800, 0x00},
- + {OV5693_8BIT, 0x3801, 0x00},
- + {OV5693_8BIT, 0x3802, 0x00},
- + {OV5693_8BIT, 0x3803, 0x00},
- +
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xA3},
- +
- + {OV5693_8BIT, 0x3808, 0x05},
- + {OV5693_8BIT, 0x3809, 0x10},
- + {OV5693_8BIT, 0x380a, 0x02},
- + {OV5693_8BIT, 0x380b, 0xe0},
- +
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- +
- + {OV5693_8BIT, 0x3813, 0xE8},
- +
- + {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/
- + {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +static struct ov5693_reg const ov5693_1636p_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0xf0},
- + {OV5693_8BIT, 0x3806, 0x06},
- + {OV5693_8BIT, 0x3807, 0xa7},
- + {OV5693_8BIT, 0x3808, 0x06},
- + {OV5693_8BIT, 0x3809, 0x64},
- + {OV5693_8BIT, 0x380a, 0x04},
- + {OV5693_8BIT, 0x380b, 0x48},
- + {OV5693_8BIT, 0x380c, 0x0a}, /*hts*/
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07}, /*vts*/
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x02},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +#endif
- +
- +static struct ov5693_reg const ov5693_1616x1216_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x80},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3800, 0x00}, /*{3800,3801} Array X start*/
- + {OV5693_8BIT, 0x3801, 0x08}, /* 04 //{3800,3801} Array X start*/
- + {OV5693_8BIT, 0x3802, 0x00}, /*{3802,3803} Array Y start*/
- + {OV5693_8BIT, 0x3803, 0x04}, /* 00 //{3802,3803} Array Y start*/
- + {OV5693_8BIT, 0x3804, 0x0a}, /*{3804,3805} Array X end*/
- + {OV5693_8BIT, 0x3805, 0x37}, /* 3b //{3804,3805} Array X end*/
- + {OV5693_8BIT, 0x3806, 0x07}, /*{3806,3807} Array Y end*/
- + {OV5693_8BIT, 0x3807, 0x9f}, /* a3 //{3806,3807} Array Y end*/
- + {OV5693_8BIT, 0x3808, 0x06}, /*{3808,3809} Final output H size*/
- + {OV5693_8BIT, 0x3809, 0x50}, /*{3808,3809} Final output H size*/
- + {OV5693_8BIT, 0x380a, 0x04}, /*{380a,380b} Final output V size*/
- + {OV5693_8BIT, 0x380b, 0xc0}, /*{380a,380b} Final output V size*/
- + {OV5693_8BIT, 0x380c, 0x0a}, /*{380c,380d} HTS*/
- + {OV5693_8BIT, 0x380d, 0x80}, /*{380c,380d} HTS*/
- + {OV5693_8BIT, 0x380e, 0x07}, /*{380e,380f} VTS*/
- + {OV5693_8BIT, 0x380f, 0xc0}, /* bc //{380e,380f} VTS*/
- + {OV5693_8BIT, 0x3810, 0x00}, /*{3810,3811} windowing X offset*/
- + {OV5693_8BIT, 0x3811, 0x10}, /*{3810,3811} windowing X offset*/
- + {OV5693_8BIT, 0x3812, 0x00}, /*{3812,3813} windowing Y offset*/
- + {OV5693_8BIT, 0x3813, 0x06}, /*{3812,3813} windowing Y offset*/
- + {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/
- + {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/
- + {OV5693_8BIT, 0x3820, 0x00}, /*FLIP/Binnning control*/
- + {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x5041, 0x84},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*
- + * 1940x1096 30fps 8.8ms VBlanking 2lane 10bit (Scaling)
- + */
- +#if ENABLE_NON_PREVIEW
- +static struct ov5693_reg const ov5693_1940x1096[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0xf0},
- + {OV5693_8BIT, 0x3806, 0x06},
- + {OV5693_8BIT, 0x3807, 0xa7},
- + {OV5693_8BIT, 0x3808, 0x07},
- + {OV5693_8BIT, 0x3809, 0x94},
- + {OV5693_8BIT, 0x380a, 0x04},
- + {OV5693_8BIT, 0x380b, 0x48},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x02},
- + {OV5693_8BIT, 0x3813, 0x02},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x80},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +static struct ov5693_reg const ov5693_2592x1456_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3800, 0x00},
- + {OV5693_8BIT, 0x3801, 0x00},
- + {OV5693_8BIT, 0x3802, 0x00},
- + {OV5693_8BIT, 0x3803, 0xf0},
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3806, 0x06},
- + {OV5693_8BIT, 0x3807, 0xa4},
- + {OV5693_8BIT, 0x3808, 0x0a},
- + {OV5693_8BIT, 0x3809, 0x20},
- + {OV5693_8BIT, 0x380a, 0x05},
- + {OV5693_8BIT, 0x380b, 0xb0},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x10},
- + {OV5693_8BIT, 0x3813, 0x00},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +#endif
- +
- +static struct ov5693_reg const ov5693_2576x1456_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3800, 0x00},
- + {OV5693_8BIT, 0x3801, 0x00},
- + {OV5693_8BIT, 0x3802, 0x00},
- + {OV5693_8BIT, 0x3803, 0xf0},
- + {OV5693_8BIT, 0x3804, 0x0a},
- + {OV5693_8BIT, 0x3805, 0x3f},
- + {OV5693_8BIT, 0x3806, 0x06},
- + {OV5693_8BIT, 0x3807, 0xa4},
- + {OV5693_8BIT, 0x3808, 0x0a},
- + {OV5693_8BIT, 0x3809, 0x10},
- + {OV5693_8BIT, 0x380a, 0x05},
- + {OV5693_8BIT, 0x380b, 0xb0},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x18},
- + {OV5693_8BIT, 0x3813, 0x00},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +/*
- + * 2592x1944 30fps 0.6ms VBlanking 2lane 10Bit
- + */
- +#if ENABLE_NON_PREVIEW
- +static struct ov5693_reg const ov5693_2592x1944_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0x00},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xa3},
- + {OV5693_8BIT, 0x3808, 0x0a},
- + {OV5693_8BIT, 0x3809, 0x20},
- + {OV5693_8BIT, 0x380a, 0x07},
- + {OV5693_8BIT, 0x380b, 0x98},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x10},
- + {OV5693_8BIT, 0x3813, 0x00},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +#endif
- +
- +/*
- + * 11:9 Full FOV Output, expected FOV Res: 2346x1920
- + * ISP Effect Res: 1408x1152
- + * Sensor out: 1424x1168, DS From: 2380x1952
- + *
- + * WA: Left Offset: 8, Hor scal: 64
- + */
- +#if ENABLE_NON_PREVIEW
- +static struct ov5693_reg const ov5693_1424x1168_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x3b}, /* long exposure[15:8] */
- + {OV5693_8BIT, 0x3502, 0x80}, /* long exposure[7:0] */
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3800, 0x00}, /* TIMING_X_ADDR_START */
- + {OV5693_8BIT, 0x3801, 0x50}, /* 80 */
- + {OV5693_8BIT, 0x3802, 0x00}, /* TIMING_Y_ADDR_START */
- + {OV5693_8BIT, 0x3803, 0x02}, /* 2 */
- + {OV5693_8BIT, 0x3804, 0x09}, /* TIMING_X_ADDR_END */
- + {OV5693_8BIT, 0x3805, 0xdd}, /* 2525 */
- + {OV5693_8BIT, 0x3806, 0x07}, /* TIMING_Y_ADDR_END */
- + {OV5693_8BIT, 0x3807, 0xa1}, /* 1953 */
- + {OV5693_8BIT, 0x3808, 0x05}, /* TIMING_X_OUTPUT_SIZE */
- + {OV5693_8BIT, 0x3809, 0x90}, /* 1424 */
- + {OV5693_8BIT, 0x380a, 0x04}, /* TIMING_Y_OUTPUT_SIZE */
- + {OV5693_8BIT, 0x380b, 0x90}, /* 1168 */
- + {OV5693_8BIT, 0x380c, 0x0a}, /* TIMING_HTS */
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07}, /* TIMING_VTS */
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3810, 0x00}, /* TIMING_ISP_X_WIN */
- + {OV5693_8BIT, 0x3811, 0x02}, /* 2 */
- + {OV5693_8BIT, 0x3812, 0x00}, /* TIMING_ISP_Y_WIN */
- + {OV5693_8BIT, 0x3813, 0x00}, /* 0 */
- + {OV5693_8BIT, 0x3814, 0x11}, /* TIME_X_INC */
- + {OV5693_8BIT, 0x3815, 0x11}, /* TIME_Y_INC */
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +#endif
- +
- +/*
- + * 3:2 Full FOV Output, expected FOV Res: 2560x1706
- + * ISP Effect Res: 720x480
- + * Sensor out: 736x496, DS From 2616x1764
- + */
- +static struct ov5693_reg const ov5693_736x496_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x3b}, /* long exposure[15:8] */
- + {OV5693_8BIT, 0x3502, 0x80}, /* long exposure[7:0] */
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3800, 0x00}, /* TIMING_X_ADDR_START */
- + {OV5693_8BIT, 0x3801, 0x02}, /* 2 */
- + {OV5693_8BIT, 0x3802, 0x00}, /* TIMING_Y_ADDR_START */
- + {OV5693_8BIT, 0x3803, 0x62}, /* 98 */
- + {OV5693_8BIT, 0x3804, 0x0a}, /* TIMING_X_ADDR_END */
- + {OV5693_8BIT, 0x3805, 0x3b}, /* 2619 */
- + {OV5693_8BIT, 0x3806, 0x07}, /* TIMING_Y_ADDR_END */
- + {OV5693_8BIT, 0x3807, 0x43}, /* 1859 */
- + {OV5693_8BIT, 0x3808, 0x02}, /* TIMING_X_OUTPUT_SIZE */
- + {OV5693_8BIT, 0x3809, 0xe0}, /* 736 */
- + {OV5693_8BIT, 0x380a, 0x01}, /* TIMING_Y_OUTPUT_SIZE */
- + {OV5693_8BIT, 0x380b, 0xf0}, /* 496 */
- + {OV5693_8BIT, 0x380c, 0x0a}, /* TIMING_HTS */
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07}, /* TIMING_VTS */
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3810, 0x00}, /* TIMING_ISP_X_WIN */
- + {OV5693_8BIT, 0x3811, 0x02}, /* 2 */
- + {OV5693_8BIT, 0x3812, 0x00}, /* TIMING_ISP_Y_WIN */
- + {OV5693_8BIT, 0x3813, 0x00}, /* 0 */
- + {OV5693_8BIT, 0x3814, 0x11}, /* TIME_X_INC */
- + {OV5693_8BIT, 0x3815, 0x11}, /* TIME_Y_INC */
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +static struct ov5693_reg const ov5693_2576x1936_30fps[] = {
- + {OV5693_8BIT, 0x3501, 0x7b},
- + {OV5693_8BIT, 0x3502, 0x00},
- + {OV5693_8BIT, 0x3708, 0xe2},
- + {OV5693_8BIT, 0x3709, 0xc3},
- + {OV5693_8BIT, 0x3803, 0x00},
- + {OV5693_8BIT, 0x3806, 0x07},
- + {OV5693_8BIT, 0x3807, 0xa3},
- + {OV5693_8BIT, 0x3808, 0x0a},
- + {OV5693_8BIT, 0x3809, 0x10},
- + {OV5693_8BIT, 0x380a, 0x07},
- + {OV5693_8BIT, 0x380b, 0x90},
- + {OV5693_8BIT, 0x380c, 0x0a},
- + {OV5693_8BIT, 0x380d, 0x80},
- + {OV5693_8BIT, 0x380e, 0x07},
- + {OV5693_8BIT, 0x380f, 0xc0},
- + {OV5693_8BIT, 0x3811, 0x18},
- + {OV5693_8BIT, 0x3813, 0x00},
- + {OV5693_8BIT, 0x3814, 0x11},
- + {OV5693_8BIT, 0x3815, 0x11},
- + {OV5693_8BIT, 0x3820, 0x00},
- + {OV5693_8BIT, 0x3821, 0x1e},
- + {OV5693_8BIT, 0x5002, 0x00},
- + {OV5693_8BIT, 0x0100, 0x01},
- + {OV5693_TOK_TERM, 0, 0}
- +};
- +
- +static struct ov5693_resolution ov5693_res_preview[] = {
- + {
- + .desc = "ov5693_736x496_30fps",
- + .width = 736,
- + .height = 496,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_736x496_30fps,
- + },
- + {
- + .desc = "ov5693_1616x1216_30fps",
- + .width = 1616,
- + .height = 1216,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_1616x1216_30fps,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2576,
- + .height = 1456,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2576x1456_30fps,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2576,
- + .height = 1936,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2576x1936_30fps,
- + },
- +};
- +
- +#define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
- +
- +/*
- + * Disable non-preview configurations until the configuration selection is
- + * improved.
- + */
- +#if ENABLE_NON_PREVIEW
- +struct ov5693_resolution ov5693_res_still[] = {
- + {
- + .desc = "ov5693_736x496_30fps",
- + .width = 736,
- + .height = 496,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_736x496_30fps,
- + },
- + {
- + .desc = "ov5693_1424x1168_30fps",
- + .width = 1424,
- + .height = 1168,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_1424x1168_30fps,
- + },
- + {
- + .desc = "ov5693_1616x1216_30fps",
- + .width = 1616,
- + .height = 1216,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_1616x1216_30fps,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2592,
- + .height = 1456,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2592x1456_30fps,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2592,
- + .height = 1944,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2592x1944_30fps,
- + },
- +};
- +
- +#define N_RES_STILL (ARRAY_SIZE(ov5693_res_still))
- +
- +struct ov5693_resolution ov5693_res_video[] = {
- + {
- + .desc = "ov5693_736x496_30fps",
- + .width = 736,
- + .height = 496,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 1,
- + .regs = ov5693_736x496,
- + },
- + {
- + .desc = "ov5693_336x256_30fps",
- + .width = 336,
- + .height = 256,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 1,
- + .regs = ov5693_336x256,
- + },
- + {
- + .desc = "ov5693_368x304_30fps",
- + .width = 368,
- + .height = 304,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 1,
- + .regs = ov5693_368x304,
- + },
- + {
- + .desc = "ov5693_192x160_30fps",
- + .width = 192,
- + .height = 160,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 1,
- + .regs = ov5693_192x160,
- + },
- + {
- + .desc = "ov5693_1296x736_30fps",
- + .width = 1296,
- + .height = 736,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 0,
- + .regs = ov5693_1296x736,
- + },
- + {
- + .desc = "ov5693_1296x976_30fps",
- + .width = 1296,
- + .height = 976,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 2,
- + .bin_factor_y = 2,
- + .bin_mode = 0,
- + .regs = ov5693_1296x976,
- + },
- + {
- + .desc = "ov5693_1636P_30fps",
- + .width = 1636,
- + .height = 1096,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_1636p_30fps,
- + },
- + {
- + .desc = "ov5693_1080P_30fps",
- + .width = 1940,
- + .height = 1096,
- + .fps = 30,
- + .pix_clk_freq = 160,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_1940x1096,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2592,
- + .height = 1456,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2592x1456_30fps,
- + },
- + {
- + .desc = "ov5693_5M_30fps",
- + .width = 2592,
- + .height = 1944,
- + .pix_clk_freq = 160,
- + .fps = 30,
- + .used = 0,
- + .pixels_per_line = 2688,
- + .lines_per_frame = 1984,
- + .bin_factor_x = 1,
- + .bin_factor_y = 1,
- + .bin_mode = 0,
- + .regs = ov5693_2592x1944_30fps,
- + .crop = {
- + .left = 0,
- + .top = 0,
- + .width = 2592,
- + .height = 1944
- + },
- + },
- +};
- +
- +#define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video))
- +#endif
- +
- +static struct ov5693_resolution *ov5693_res = ov5693_res_video;
- +static unsigned long N_RES = N_RES_VIDEO;
- +#endif
- --
- 2.33.0
- From 636227d49ba696aefb0608471380d2d7306fdb8c Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 17 Jan 2021 19:08:18 +0000
- Subject: [PATCH] media: i2c: Add reset pin toggling to ov5693
- The ov5693 has an xshutdown pin which can be present and, if so, needs
- toggling as part of power on sequence.
- Add calls to handle the reset GPIO
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 4 ++++
- 1 file changed, 4 insertions(+)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 32485e4ed42b..f9ced52ad37a 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1085,6 +1085,8 @@ static int __power_up(struct v4l2_subdev *sd)
- if (ret)
- goto fail_power;
-
- + gpiod_set_value_cansleep(sensor->reset, 0);
- +
- __cci_delay(up_delay);
-
- return 0;
- @@ -1103,6 +1105,8 @@ static int power_down(struct v4l2_subdev *sd)
-
- dev->focus = OV5693_INVALID_CONFIG;
-
- + gpiod_set_value_cansleep(sensor->reset, 1);
- +
- clk_disable_unprepare(dev->clk);
-
- if (dev->indicator_led)
- --
- 2.33.0
- From 2dffcd137b3a665ea278785f3c01c0f143e301e8 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 17 Jan 2021 21:39:15 +0000
- Subject: [PATCH] media: i2c: Fix misnamed variable in power_down() for ov5693
- Fix the misnamed variable in gpiod_set_value_cansleep().
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index f9ced52ad37a..9fd44a3d1d85 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1105,7 +1105,7 @@ static int power_down(struct v4l2_subdev *sd)
-
- dev->focus = OV5693_INVALID_CONFIG;
-
- - gpiod_set_value_cansleep(sensor->reset, 1);
- + gpiod_set_value_cansleep(dev->reset, 1);
-
- clk_disable_unprepare(dev->clk);
-
- --
- 2.33.0
- From 238061b3ae97913f96ade9beba6c26947de52d6c Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
- Date: Fri, 22 Jan 2021 20:58:13 +0100
- Subject: [PATCH] cio2-bridge: Parse sensor orientation and rotation
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- The sensor orientation is read from the _PLC ACPI buffer and converted
- to a v4l2 format.
- See https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
- page 351 for a definition of the Panel property.
- The sensor rotation is read from the SSDB ACPI buffer and converted into
- degrees.
- Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/cio2-bridge.c | 45 ++++++++++++++++++++--
- drivers/media/pci/intel/ipu3/cio2-bridge.h | 3 ++
- 2 files changed, 44 insertions(+), 4 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- index 143f3c0f445e..806d4e5fc177 100644
- --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- @@ -29,6 +29,7 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
- static const struct cio2_property_names prop_names = {
- .clock_frequency = "clock-frequency",
- .rotation = "rotation",
- + .orientation = "orientation",
- .bus_type = "bus-type",
- .data_lanes = "data-lanes",
- .remote_endpoint = "remote-endpoint",
- @@ -72,11 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
- return ret;
- }
-
- +static u32 cio2_bridge_parse_rotation(u8 rotation)
- +{
- + if (rotation == 1)
- + return 180;
- + return 0;
- +}
- +
- +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
- +{
- + switch (panel) {
- + case 4:
- + return V4L2_FWNODE_ORIENTATION_FRONT;
- + case 5:
- + return V4L2_FWNODE_ORIENTATION_BACK;
- + default:
- + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
- + }
- +}
- +
- static void cio2_bridge_create_fwnode_properties(
- struct cio2_sensor *sensor,
- struct cio2_bridge *bridge,
- const struct cio2_sensor_config *cfg)
- {
- + u32 rotation;
- + enum v4l2_fwnode_orientation orientation;
- +
- + rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
- + orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
- +
- sensor->prop_names = prop_names;
-
- sensor->local_ref[0].node = &sensor->swnodes[SWNODE_CIO2_ENDPOINT];
- @@ -85,9 +111,12 @@ static void cio2_bridge_create_fwnode_properties(
- sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
- sensor->prop_names.clock_frequency,
- sensor->ssdb.mclkspeed);
- - sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
- + sensor->dev_properties[1] = PROPERTY_ENTRY_U32(
- sensor->prop_names.rotation,
- - sensor->ssdb.degree);
- + rotation);
- + sensor->dev_properties[2] = PROPERTY_ENTRY_U32(
- + sensor->prop_names.orientation,
- + orientation);
-
- sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
- sensor->prop_names.bus_type,
- @@ -159,6 +188,7 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
- for (i = 0; i < bridge->n_sensors; i++) {
- sensor = &bridge->sensors[i];
- software_node_unregister_nodes(sensor->swnodes);
- + ACPI_FREE(sensor->pld);
- acpi_dev_put(sensor->adev);
- }
- }
- @@ -170,6 +200,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
- struct fwnode_handle *fwnode;
- struct cio2_sensor *sensor;
- struct acpi_device *adev;
- + acpi_status status;
- int ret;
-
- for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
- @@ -193,11 +224,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
- if (ret)
- goto err_put_adev;
-
- + status = acpi_get_physical_device_location(adev->handle, &sensor->pld);
- + if (ACPI_FAILURE(status))
- + goto err_put_adev;
- +
- if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
- dev_err(&adev->dev,
- "Number of lanes in SSDB is invalid\n");
- ret = -EINVAL;
- - goto err_put_adev;
- + goto err_free_pld;
- }
-
- cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
- @@ -205,7 +240,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
-
- ret = software_node_register_nodes(sensor->swnodes);
- if (ret)
- - goto err_put_adev;
- + goto err_free_pld;
-
- fwnode = software_node_fwnode(&sensor->swnodes[SWNODE_SENSOR_HID]);
- if (!fwnode) {
- @@ -225,6 +260,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
-
- err_free_swnodes:
- software_node_unregister_nodes(sensor->swnodes);
- +err_free_pld:
- + ACPI_FREE(sensor->pld);
- err_put_adev:
- acpi_dev_put(sensor->adev);
- err_out:
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- index dd0ffcafa489..924d99d20328 100644
- --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- @@ -80,6 +80,7 @@ struct cio2_sensor_ssdb {
- struct cio2_property_names {
- char clock_frequency[16];
- char rotation[9];
- + char orientation[12];
- char bus_type[9];
- char data_lanes[11];
- char remote_endpoint[16];
- @@ -106,6 +107,8 @@ struct cio2_sensor {
- struct cio2_node_names node_names;
-
- struct cio2_sensor_ssdb ssdb;
- + struct acpi_pld_info *pld;
- +
- struct cio2_property_names prop_names;
- struct property_entry ep_properties[5];
- struct property_entry dev_properties[3];
- --
- 2.33.0
- From 0c8bba6d8661cbb5f7a54ba8ccd17678ae58ebc9 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
- Date: Fri, 22 Jan 2021 21:23:47 +0100
- Subject: [PATCH] ov5693: Add orientation and rotation controls
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Parse orientation and rotation from fwnodes and initialize the
- respective controls.
- Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 9fd44a3d1d85..1a85800df7ed 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -31,6 +31,7 @@
- #include <linux/i2c.h>
- #include <linux/moduleparam.h>
- #include <media/v4l2-device.h>
- +#include <media/v4l2-fwnode.h>
- #include <linux/io.h>
- #include <linux/acpi.h>
- #include <linux/regulator/consumer.h>
- @@ -1608,6 +1609,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- {
- struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
- const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
- + struct v4l2_fwnode_device_properties props;
- struct v4l2_ctrl *ctrl;
- unsigned int i;
- int ret;
- @@ -1663,6 +1665,15 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- if (ov5693->hblank)
- ov5693->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- + /* set properties from fwnode (e.g. rotation, orientation) */
- + ret = v4l2_fwnode_device_parse(&client->dev, &props);
- + if (ret)
- + return ret;
- +
- + ret = v4l2_ctrl_new_fwnode_properties(&ov5693->ctrl_handler, ops, &props);
- + if (ret)
- + return ret;
- +
- /* Use same lock for controls as for everything else. */
- ov5693->ctrl_handler.lock = &ov5693->input_lock;
- ov5693->sd.ctrl_handler = &ov5693->ctrl_handler;
- --
- 2.33.0
- From 2e7dcc9a3f803030d102e9cdfba6a995311b5a55 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 23 Jan 2021 00:28:32 +0000
- Subject: [PATCH] platform: x86: Stylistic updates for intel-skl-int3472
- This commit makes a bunch of stylistic updates, minor changes and other
- stuff that's part of the improvements pass I'm doing to the code after
- taking into account feedback from the list.
- It also alters the ACPI buffer fetching code to be more generalisable so
- I can re-use it to fetch the clock frequency.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- .../platform/x86/intel_skl_int3472_common.c | 37 ++++---
- .../platform/x86/intel_skl_int3472_common.h | 7 +-
- .../platform/x86/intel_skl_int3472_discrete.c | 101 +++++++++---------
- .../platform/x86/intel_skl_int3472_tps68470.c | 16 +--
- 4 files changed, 89 insertions(+), 72 deletions(-)
- diff --git a/drivers/platform/x86/intel_skl_int3472_common.c b/drivers/platform/x86/intel_skl_int3472_common.c
- index 08cb9d3c06aa..549d211979e1 100644
- --- a/drivers/platform/x86/intel_skl_int3472_common.c
- +++ b/drivers/platform/x86/intel_skl_int3472_common.c
- @@ -7,41 +7,52 @@
-
- #include "intel_skl_int3472_common.h"
-
- -int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
- - struct int3472_cldb *cldb)
- +union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
- + char *id)
- {
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_handle handle = adev->handle;
- union acpi_object *obj;
- acpi_status status;
- - int ret = 0;
-
- - status = acpi_evaluate_object(handle, "CLDB", NULL, &buffer);
- + status = acpi_evaluate_object(handle, id, NULL, &buffer);
- if (ACPI_FAILURE(status))
- - return -ENODEV;
- + return ERR_PTR(-ENODEV);
-
- obj = buffer.pointer;
- if (!obj) {
- - dev_err(&adev->dev, "ACPI device has no CLDB object\n");
- - return -ENODEV;
- + dev_err(&adev->dev, "ACPI device has no %s object\n", id);
- + return ERR_PTR(-ENODEV);
- }
-
- if (obj->type != ACPI_TYPE_BUFFER) {
- - dev_err(&adev->dev, "CLDB object is not an ACPI buffer\n");
- - ret = -EINVAL;
- - goto out_free_buff;
- + dev_err(&adev->dev, "%s object is not an ACPI buffer\n", id);
- + kfree(obj);
- + return ERR_PTR(-EINVAL);
- }
-
- + return obj;
- +}
- +
- +int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
- +{
- + union acpi_object *obj;
- + int ret = 0;
- +
- + obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
- + if (IS_ERR(obj))
- + return PTR_ERR(obj);
- +
- if (obj->buffer.length > sizeof(*cldb)) {
- dev_err(&adev->dev, "The CLDB buffer is too large\n");
- ret = -EINVAL;
- - goto out_free_buff;
- + goto out_free_obj;
- }
-
- memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
-
- -out_free_buff:
- - kfree(buffer.pointer);
- +out_free_obj:
- + kfree(obj);
- return ret;
- }
-
- diff --git a/drivers/platform/x86/intel_skl_int3472_common.h b/drivers/platform/x86/intel_skl_int3472_common.h
- index 4ac6bb2b223f..e1083bb67dc6 100644
- --- a/drivers/platform/x86/intel_skl_int3472_common.h
- +++ b/drivers/platform/x86/intel_skl_int3472_common.h
- @@ -29,7 +29,7 @@
-
- #define INT3472_GPIO_FUNCTION_REMAP(_PIN, _FUNCTION) \
- (const struct int3472_gpio_function_remap) { \
- - .documented = _PIN, \
- + .documented = _PIN, \
- .actual = _FUNCTION \
- }
-
- @@ -95,5 +95,6 @@ struct int3472_sensor_config {
- int skl_int3472_discrete_probe(struct platform_device *pdev);
- int skl_int3472_discrete_remove(struct platform_device *pdev);
- int skl_int3472_tps68470_probe(struct i2c_client *client);
- -int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
- - struct int3472_cldb *cldb);
- +union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
- + char *id);
- +int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
- diff --git a/drivers/platform/x86/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel_skl_int3472_discrete.c
- index ea7e57f3e3f0..42ae8396eb64 100644
- --- a/drivers/platform/x86/intel_skl_int3472_discrete.c
- +++ b/drivers/platform/x86/intel_skl_int3472_discrete.c
- @@ -12,12 +12,12 @@
-
- #include "intel_skl_int3472_common.h"
-
- -/* 79234640-9e10-4fea-a5c1b5aa8b19756f */
- +/* 79234640-9e10-4fea-a5c1-b5aa8b19756f */
- static const guid_t int3472_gpio_guid =
- GUID_INIT(0x79234640, 0x9e10, 0x4fea,
- 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
-
- -/* 822ace8f-2814-4174-a56b5f029fe079ee */
- +/* 822ace8f-2814-4174-a56b-5f029fe079ee */
- static const guid_t cio2_sensor_module_guid =
- GUID_INIT(0x822ace8f, 0x2814, 0x4174,
- 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
- @@ -94,7 +94,7 @@ static const struct clk_ops skl_int3472_clock_ops = {
- };
-
- static struct int3472_sensor_config *
- -int3472_get_sensor_module_config(struct int3472_device *int3472)
- +skl_int3472_get_sensor_module_config(struct int3472_device *int3472)
- {
- unsigned int i = ARRAY_SIZE(int3472_sensor_configs);
- struct int3472_sensor_config *ret;
- @@ -131,9 +131,9 @@ int3472_get_sensor_module_config(struct int3472_device *int3472)
- return ret;
- }
-
- -static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
- - struct acpi_resource *ares,
- - char *func, u32 polarity)
- +static int skl_int3472_map_gpio_to_sensor(struct int3472_device *int3472,
- + struct acpi_resource *ares,
- + char *func, u32 polarity)
- {
- char *path = ares->data.gpio.resource_source.string_ptr;
- struct int3472_sensor_config *sensor_config;
- @@ -143,7 +143,7 @@ static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
- acpi_status status;
- int ret;
-
- - sensor_config = int3472_get_sensor_module_config(int3472);
- + sensor_config = skl_int3472_get_sensor_module_config(int3472);
- if (!IS_ERR(sensor_config) && sensor_config->function_maps) {
- unsigned int i = 0;
-
- @@ -186,17 +186,19 @@ static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
- return 0;
- }
-
- -static int int3472_register_clock(struct int3472_device *int3472,
- - struct acpi_resource *ares)
- +static int skl_int3472_register_clock(struct int3472_device *int3472,
- + struct acpi_resource *ares)
- {
- char *path = ares->data.gpio.resource_source.string_ptr;
- - struct clk_init_data init = { };
- + struct clk_init_data init = { 0 };
- int ret = 0;
-
- - init.name = kasprintf(GFP_KERNEL, "%s-clk", acpi_dev_name(int3472->adev));
- + init.name = kasprintf(GFP_KERNEL, "%s-clk",
- + acpi_dev_name(int3472->adev));
- init.ops = &skl_int3472_clock_ops;
-
- - int3472->clock.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
- + int3472->clock.gpio = acpi_get_gpiod(path,
- + ares->data.gpio.pin_table[0]);
- if (IS_ERR(int3472->clock.gpio)) {
- ret = PTR_ERR(int3472->clock.gpio);
- goto out_free_init_name;
- @@ -226,17 +228,16 @@ static int int3472_register_clock(struct int3472_device *int3472,
- return ret;
- }
-
- -static int int3472_register_regulator(struct int3472_device *int3472,
- - struct acpi_resource *ares)
- +static int skl_int3472_register_regulator(struct int3472_device *int3472,
- + struct acpi_resource *ares)
- {
- char *path = ares->data.gpio.resource_source.string_ptr;
- struct int3472_sensor_config *sensor_config;
- struct regulator_init_data init_data = { };
- - struct int3472_gpio_regulator *regulator;
- struct regulator_config cfg = { };
- int ret;
-
- - sensor_config = int3472_get_sensor_module_config(int3472);
- + sensor_config = skl_int3472_get_sensor_module_config(int3472);
- if (IS_ERR_OR_NULL(sensor_config)) {
- dev_err(&int3472->pdev->dev, "No sensor module config\n");
- return PTR_ERR(sensor_config);
- @@ -252,26 +253,29 @@ static int int3472_register_regulator(struct int3472_device *int3472,
- init_data.num_consumer_supplies = 1;
- init_data.consumer_supplies = &sensor_config->supply_map;
-
- - snprintf(int3472->regulator.regulator_name, GPIO_REGULATOR_NAME_LENGTH,
- - "int3472-discrete-regulator");
- - snprintf(int3472->regulator.supply_name, GPIO_REGULATOR_SUPPLY_NAME_LENGTH,
- - "supply-0");
- + snprintf(int3472->regulator.regulator_name,
- + GPIO_REGULATOR_NAME_LENGTH, "int3472-discrete-regulator");
- + snprintf(int3472->regulator.supply_name,
- + GPIO_REGULATOR_SUPPLY_NAME_LENGTH, "supply-0");
-
- - int3472->regulator.rdesc = INT3472_REGULATOR(int3472->regulator.regulator_name,
- - int3472->regulator.supply_name,
- - &int3472_gpio_regulator_ops);
- + int3472->regulator.rdesc = INT3472_REGULATOR(
- + int3472->regulator.regulator_name,
- + int3472->regulator.supply_name,
- + &int3472_gpio_regulator_ops);
-
- - int3472->regulator.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
- + int3472->regulator.gpio = acpi_get_gpiod(path,
- + ares->data.gpio.pin_table[0]);
- if (IS_ERR(int3472->regulator.gpio)) {
- - ret = PTR_ERR(int3472->regulator.gpio);
- - goto err_free_regulator;
- + dev_err(&int3472->pdev->dev, "Failed to get GPIO line\n");
- + return PTR_ERR(int3472->regulator.gpio);
- }
-
- cfg.dev = &int3472->adev->dev;
- cfg.init_data = &init_data;
- cfg.ena_gpiod = int3472->regulator.gpio;
-
- - int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc, &cfg);
- + int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
- + &cfg);
- if (IS_ERR(int3472->regulator.rdev)) {
- ret = PTR_ERR(int3472->regulator.rdev);
- goto err_free_gpio;
- @@ -280,15 +284,13 @@ static int int3472_register_regulator(struct int3472_device *int3472,
- return 0;
-
- err_free_gpio:
- - gpiod_put(regulator->gpio);
- -err_free_regulator:
- - kfree(regulator);
- + gpiod_put(int3472->regulator.gpio);
-
- return ret;
- }
-
- /**
- - * int3472_handle_gpio_resources: maps PMIC resources to consuming sensor
- + * skl_int3472_handle_gpio_resources: maps PMIC resources to consuming sensor
- * @ares: A pointer to a &struct acpi_resource
- * @data: A pointer to a &struct int3472_device
- *
- @@ -305,8 +307,9 @@ static int int3472_register_regulator(struct int3472_device *int3472,
- *
- * There are some known platform specific quirks where that does not quite
- * hold up; for example where a pin with type 0x01 (Power down) is mapped to
- - * a sensor pin that performs a reset function. These will be handled by the
- - * mapping sub-functions.
- + * a sensor pin that performs a reset function or entries in _CRS and _DSM that
- + * do not actually correspond to a physical connection. These will be handled by
- + * the mapping sub-functions.
- *
- * GPIOs will either be mapped directly to the sensor device or else used
- * to create clocks and regulators via the usual frameworks.
- @@ -317,8 +320,8 @@ static int int3472_register_regulator(struct int3472_device *int3472,
- * * -ENODEV - If the resource has no corresponding _DSM entry
- * * -Other - Errors propagated from one of the sub-functions.
- */
- -static int int3472_handle_gpio_resources(struct acpi_resource *ares,
- - void *data)
- +static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
- + void *data)
- {
- struct int3472_device *int3472 = data;
- union acpi_object *obj;
- @@ -345,30 +348,30 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
-
- switch (obj->integer.value & 0xff) {
- case INT3472_GPIO_TYPE_RESET:
- - ret = int3472_map_gpio_to_sensor(int3472, ares, "reset",
- - GPIO_ACTIVE_LOW);
- + ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "reset",
- + GPIO_ACTIVE_LOW);
- if (ret)
- dev_err(&int3472->pdev->dev,
- "Failed to map reset pin to sensor\n");
-
- break;
- case INT3472_GPIO_TYPE_POWERDOWN:
- - ret = int3472_map_gpio_to_sensor(int3472, ares, "powerdown",
- - GPIO_ACTIVE_LOW);
- + ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "powerdown",
- + GPIO_ACTIVE_LOW);
- if (ret)
- dev_err(&int3472->pdev->dev,
- "Failed to map powerdown pin to sensor\n");
-
- break;
- case INT3472_GPIO_TYPE_CLK_ENABLE:
- - ret = int3472_register_clock(int3472, ares);
- + ret = skl_int3472_register_clock(int3472, ares);
- if (ret)
- dev_err(&int3472->pdev->dev,
- "Failed to map clock to sensor\n");
-
- break;
- case INT3472_GPIO_TYPE_POWER_ENABLE:
- - ret = int3472_register_regulator(int3472, ares);
- + ret = skl_int3472_register_regulator(int3472, ares);
- if (ret) {
- dev_err(&int3472->pdev->dev,
- "Failed to map regulator to sensor\n");
- @@ -376,8 +379,9 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
-
- break;
- case INT3472_GPIO_TYPE_PRIVACY_LED:
- - ret = int3472_map_gpio_to_sensor(int3472, ares, "indicator-led",
- - GPIO_ACTIVE_HIGH);
- + ret = skl_int3472_map_gpio_to_sensor(int3472, ares,
- + "indicator-led",
- + GPIO_ACTIVE_HIGH);
- if (ret)
- dev_err(&int3472->pdev->dev,
- "Failed to map indicator led to sensor\n");
- @@ -396,7 +400,7 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
- return ret;
- }
-
- -static int int3472_parse_crs(struct int3472_device *int3472)
- +static int skl_int3472_parse_crs(struct int3472_device *int3472)
- {
- struct list_head resource_list;
- int ret = 0;
- @@ -404,7 +408,8 @@ static int int3472_parse_crs(struct int3472_device *int3472)
- INIT_LIST_HEAD(&resource_list);
-
- ret = acpi_dev_get_resources(int3472->adev, &resource_list,
- - int3472_handle_gpio_resources, int3472);
- + skl_int3472_handle_gpio_resources,
- + int3472);
-
- if (!ret) {
- gpiod_add_lookup_table(&int3472->gpios);
- @@ -423,7 +428,7 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
- struct int3472_cldb cldb;
- int ret = 0;
-
- - ret = skl_int3472_get_cldb_buffer(adev, &cldb);
- + ret = skl_int3472_fill_cldb(adev, &cldb);
- if (ret || cldb.control_logic_type != 1)
- return -EINVAL;
-
- @@ -444,10 +449,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
- ret = -ENODEV;
- goto err_free_int3472;
- }
- - int3472->sensor_name = i2c_acpi_dev_name(int3472->sensor);
- + int3472->sensor_name = kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(int3472->sensor));
- int3472->gpios.dev_id = int3472->sensor_name;
-
- - ret = int3472_parse_crs(int3472);
- + ret = skl_int3472_parse_crs(int3472);
- if (ret) {
- skl_int3472_discrete_remove(pdev);
- goto err_return_ret;
- diff --git a/drivers/platform/x86/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel_skl_int3472_tps68470.c
- index 3fe27ec0caff..40629291b339 100644
- --- a/drivers/platform/x86/intel_skl_int3472_tps68470.c
- +++ b/drivers/platform/x86/intel_skl_int3472_tps68470.c
- @@ -87,20 +87,20 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
-
- /*
- * Check CLDB buffer against the PMIC's adev. If present, then we check
- - * the value of control_logic_type field and follow one of the following
- - * scenarios:
- + * the value of control_logic_type field and follow one of the
- + * following scenarios:
- *
- - * 1. No CLDB - likely ACPI tables designed for ChromeOS. We create
- - * platform devices for the GPIOs and OpRegion drivers.
- + * 1. No CLDB - likely ACPI tables designed for ChromeOS. We
- + * create platform devices for the GPIOs and OpRegion drivers.
- *
- - * 2. CLDB, with control_logic_type = 2 - probably ACPI tables made
- - * for Windows 2-in-1 platforms. Register pdevs for GPIO, Clock and
- - * Regulator drivers to bind to.
- + * 2. CLDB, with control_logic_type = 2 - probably ACPI tables
- + * made for Windows 2-in-1 platforms. Register pdevs for GPIO,
- + * Clock and Regulator drivers to bind to.
- *
- * 3. Any other value in control_logic_type, we should never have
- * gotten to this point; crash and burn.
- */
- - ret = skl_int3472_get_cldb_buffer(adev, &cldb);
- + ret = skl_int3472_fill_cldb(adev, &cldb);
- if (!ret && cldb.control_logic_type != 2)
- return -EINVAL;
-
- --
- 2.33.0
- From 44e995a18984d3b9406e53da163ec61619c56d9a Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 23 Jan 2021 00:30:15 +0000
- Subject: [PATCH] platform: x86: Add recalc_rate opp to int3472-discrete clock
- This commit adds the recalc_rate opp to the clock registered by
- int3472-discrete so that sensor drivers calling clk_get_rate() will get a
- valid value returned.
- The value is simply read from the sensor's SSDB buffer, and so we pass
- CLK_GET_RATE_NOCACHE
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- .../platform/x86/intel_skl_int3472_common.h | 6 +++
- .../platform/x86/intel_skl_int3472_discrete.c | 37 ++++++++++++++++++-
- 2 files changed, 41 insertions(+), 2 deletions(-)
- diff --git a/drivers/platform/x86/intel_skl_int3472_common.h b/drivers/platform/x86/intel_skl_int3472_common.h
- index e1083bb67dc6..860c849b7769 100644
- --- a/drivers/platform/x86/intel_skl_int3472_common.h
- +++ b/drivers/platform/x86/intel_skl_int3472_common.h
- @@ -17,6 +17,8 @@
- #define GPIO_REGULATOR_NAME_LENGTH 27
- #define GPIO_REGULATOR_SUPPLY_NAME_LENGTH 9
-
- +#define CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET 86
- +
- #define INT3472_REGULATOR(_NAME, _SUPPLY, _OPS) \
- (const struct regulator_desc) { \
- .name = _NAME, \
- @@ -36,6 +38,9 @@
- #define to_int3472_clk(hw) \
- container_of(hw, struct int3472_gpio_clock, clk_hw)
-
- +#define to_int3472_device(clk) \
- + container_of(clk, struct int3472_device, clock)
- +
- struct int3472_cldb {
- u8 version;
- /*
- @@ -62,6 +67,7 @@ struct int3472_gpio_regulator {
- struct int3472_gpio_clock {
- struct clk *clk;
- struct clk_hw clk_hw;
- + struct clk_lookup *cl;
- struct gpio_desc *gpio;
- };
-
- diff --git a/drivers/platform/x86/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel_skl_int3472_discrete.c
- index 42ae8396eb64..98eb1ec3399e 100644
- --- a/drivers/platform/x86/intel_skl_int3472_discrete.c
- +++ b/drivers/platform/x86/intel_skl_int3472_discrete.c
- @@ -86,11 +86,41 @@ static void skl_int3472_clk_unprepare(struct clk_hw *hw)
- /* Likewise, nothing to do here... */
- }
-
- +static unsigned int skl_int3472_get_clk_frequency(struct int3472_device *int3472)
- +{
- + union acpi_object *obj;
- + unsigned int ret = 0;
- +
- + obj = skl_int3472_get_acpi_buffer(int3472->sensor, "SSDB");
- + if (IS_ERR(obj))
- + goto out_free_buff; /* report rate as 0 on error */
- +
- + if (obj->buffer.length < CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET + sizeof(u32)) {
- + dev_err(&int3472->pdev->dev, "The buffer is too small\n");
- + goto out_free_buff;
- + }
- +
- + ret = *(u32*)(obj->buffer.pointer + CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET);
- +
- +out_free_buff:
- + kfree(obj);
- + return ret;
- +}
- +
- +static unsigned long skl_int3472_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
- +{
- + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
- + struct int3472_device *int3472 = to_int3472_device(clk);
- +
- + return skl_int3472_get_clk_frequency(int3472);
- +}
- +
- static const struct clk_ops skl_int3472_clock_ops = {
- .prepare = skl_int3472_clk_prepare,
- .unprepare = skl_int3472_clk_unprepare,
- .enable = skl_int3472_clk_enable,
- .disable = skl_int3472_clk_disable,
- + .recalc_rate = skl_int3472_clk_recalc_rate,
- };
-
- static struct int3472_sensor_config *
- @@ -196,6 +226,7 @@ static int skl_int3472_register_clock(struct int3472_device *int3472,
- init.name = kasprintf(GFP_KERNEL, "%s-clk",
- acpi_dev_name(int3472->adev));
- init.ops = &skl_int3472_clock_ops;
- + init.flags |= CLK_GET_RATE_NOCACHE;
-
- int3472->clock.gpio = acpi_get_gpiod(path,
- ares->data.gpio.pin_table[0]);
- @@ -212,8 +243,9 @@ static int skl_int3472_register_clock(struct int3472_device *int3472,
- goto err_put_gpio;
- }
-
- - ret = clk_register_clkdev(int3472->clock.clk, "xvclk", int3472->sensor_name);
- - if (ret)
- + int3472->clock.cl = clkdev_create(int3472->clock.clk, "xvclk",
- + int3472->sensor_name);
- + if (IS_ERR_OR_NULL(int3472->clock.cl))
- goto err_unregister_clk;
-
- goto out_free_init_name;
- @@ -483,6 +515,7 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
- if (!IS_ERR_OR_NULL(int3472->clock.clk)) {
- gpiod_put(int3472->clock.gpio);
- clk_unregister(int3472->clock.clk);
- + clkdev_drop(int3472->clock.cl);
- }
-
- acpi_dev_put(int3472->sensor);
- --
- 2.33.0
- From af463fa43654ac271940b47b9f9bd31a6d332750 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
- Date: Sun, 24 Jan 2021 11:07:42 +0100
- Subject: [PATCH] cio2-bridge: Use macros and add warnings
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Use macros for the _PLD panel as defined in the ACPI spec 6.3 and emit
- a warning if we see an unknown value.
- Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
- Patchset: cameras
- ---
- drivers/media/pci/intel/ipu3/cio2-bridge.c | 33 ++++++++++++++++------
- drivers/media/pci/intel/ipu3/cio2-bridge.h | 13 +++++++++
- 2 files changed, 37 insertions(+), 9 deletions(-)
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- index 806d4e5fc177..3c373ad1c0b0 100644
- --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
- @@ -73,21 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
- return ret;
- }
-
- -static u32 cio2_bridge_parse_rotation(u8 rotation)
- +static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
- {
- - if (rotation == 1)
- + switch (sensor->ssdb.degree) {
- + case CIO2_SENSOR_ROTATION_NORMAL:
- + return 0;
- + case CIO2_SENSOR_ROTATION_INVERTED:
- return 180;
- - return 0;
- + default:
- + dev_warn(&sensor->adev->dev,
- + "Unknown rotation %d. Assume 0 degree rotation\n",
- + sensor->ssdb.degree);
- + return 0;
- + }
- }
-
- -static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
- +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_sensor *sensor)
- {
- - switch (panel) {
- - case 4:
- + switch (sensor->pld->panel) {
- + case CIO2_PLD_PANEL_FRONT:
- return V4L2_FWNODE_ORIENTATION_FRONT;
- - case 5:
- + case CIO2_PLD_PANEL_BACK:
- return V4L2_FWNODE_ORIENTATION_BACK;
- + case CIO2_PLD_PANEL_TOP:
- + case CIO2_PLD_PANEL_LEFT:
- + case CIO2_PLD_PANEL_RIGHT:
- + case CIO2_PLD_PANEL_UNKNOWN:
- + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
- default:
- + dev_warn(&sensor->adev->dev, "Unknown _PLD panel value %d\n",
- + sensor->pld->panel);
- return V4L2_FWNODE_ORIENTATION_EXTERNAL;
- }
- }
- @@ -100,8 +115,8 @@ static void cio2_bridge_create_fwnode_properties(
- u32 rotation;
- enum v4l2_fwnode_orientation orientation;
-
- - rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
- - orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
- + rotation = cio2_bridge_parse_rotation(sensor);
- + orientation = cio2_bridge_parse_orientation(sensor);
-
- sensor->prop_names = prop_names;
-
- diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- index 924d99d20328..e1e388cc9f45 100644
- --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
- +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
- @@ -12,6 +12,19 @@
- #define CIO2_MAX_LANES 4
- #define MAX_NUM_LINK_FREQS 3
-
- +/* Values are estimated guesses as we don't have a spec */
- +#define CIO2_SENSOR_ROTATION_NORMAL 0
- +#define CIO2_SENSOR_ROTATION_INVERTED 1
- +
- +/* Panel position defined in _PLD section of ACPI Specification 6.3 */
- +#define CIO2_PLD_PANEL_TOP 0
- +#define CIO2_PLD_PANEL_BOTTOM 1
- +#define CIO2_PLD_PANEL_LEFT 2
- +#define CIO2_PLD_PANEL_RIGHT 3
- +#define CIO2_PLD_PANEL_FRONT 4
- +#define CIO2_PLD_PANEL_BACK 5
- +#define CIO2_PLD_PANEL_UNKNOWN 6
- +
- #define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
- (const struct cio2_sensor_config) { \
- .hid = _HID, \
- --
- 2.33.0
- From 9f5594c8807e188c8f57a84a9574be82446118fb Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 8 Feb 2021 21:44:38 +0000
- Subject: [PATCH] media: i2c: Tidy up ov5693_init_controls()
- The ov5693 driver initialises a bunch of v4l2 controls and throws away
- the pointers. This seems weird, let's not do that.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 46 ++++++++++++++++++++++----------------
- drivers/media/i2c/ov5693.h | 12 +++++++++-
- 2 files changed, 38 insertions(+), 20 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 1a85800df7ed..a9747ab783d7 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1610,7 +1610,6 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
- const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
- struct v4l2_fwnode_device_properties props;
- - struct v4l2_ctrl *ctrl;
- unsigned int i;
- int ret;
- int hblank;
- @@ -1628,15 +1627,17 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- NULL);
-
- /* link freq */
- - ctrl = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler, NULL,
- - V4L2_CID_LINK_FREQ,
- - 0, 0, link_freq_menu_items);
- - if (ctrl)
- - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- + ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler,
- + NULL, V4L2_CID_LINK_FREQ,
- + 0, 0, link_freq_menu_items);
- + if (ov5693->ctrls.link_freq)
- + ov5693->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- /* pixel rate */
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
- - 0, OV5693_PIXEL_RATE, 1, OV5693_PIXEL_RATE);
- + ov5693->ctrls.pixel_rate = v4l2_ctrl_new_std(&ov5693->ctrl_handler, NULL,
- + V4L2_CID_PIXEL_RATE, 0,
- + OV5693_PIXEL_RATE, 1,
- + OV5693_PIXEL_RATE);
-
- if (ov5693->ctrl_handler.error) {
- ov5693_remove(client);
- @@ -1645,25 +1646,32 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
-
- /* Exposure */
-
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
- - 512);
- + ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_EXPOSURE, 16,
- + 1048575, 16, 512);
-
- /* Gain */
-
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_ANALOGUE_GAIN, 1, 1023, 1, 128);
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_DIGITAL_GAIN, 1, 3999, 1, 1000);
- + ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler,
- + ops, V4L2_CID_ANALOGUE_GAIN,
- + 1, 1023, 1, 128);
- + ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_DIGITAL_GAIN, 1,
- + 3999, 1, 1000);
-
- /* Flip */
-
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
- - v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
- + ov5693->ctrls.hflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_HFLIP, 0, 1, 1, 0);
- + ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- hblank = OV5693_PPL_DEFAULT - ov5693->mode->width;
- - ov5693->hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- - V4L2_CID_HBLANK, hblank, hblank,
- - 1, hblank);
- - if (ov5693->hblank)
- - ov5693->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- + ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_HBLANK, hblank, hblank,
- + 1, hblank);
- + if (ov5693->ctrls.hblank)
- + ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- /* set properties from fwnode (e.g. rotation, orientation) */
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 9a508e1f3624..26819cf3f4d2 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -270,7 +270,17 @@ struct ov5693_device {
-
- bool has_vcm;
-
- - struct v4l2_ctrl *hblank;
- + struct ov5693_v4l2_ctrls {
- + struct v4l2_ctrl *link_freq;
- + struct v4l2_ctrl *pixel_rate;
- + struct v4l2_ctrl *exposure;
- + struct v4l2_ctrl *analogue_gain;
- + struct v4l2_ctrl *digital_gain;
- + struct v4l2_ctrl *hflip;
- + struct v4l2_ctrl *vflip;
- + struct v4l2_ctrl *hblank;
- + } ctrls;
- +
- };
-
- enum ov5693_tok_type {
- --
- 2.33.0
- From 5fc8a53c12d4549b0196f9cecac40c4a4f985873 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 8 Feb 2021 21:46:49 +0000
- Subject: [PATCH] media: i2c: Remove OV5693_PPL_DEFAULT
- No need for this macro, the PPL setting is against the mode structs.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index a9747ab783d7..7fb368eec327 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -105,8 +105,6 @@ MODULE_PARM_DESC(up_delay,
- #define OV5693_PIXEL_ARRAY_WIDTH 2592U
- #define OV5693_PIXEL_ARRAY_HEIGHT 1944U
-
- -#define OV5693_PPL_DEFAULT 2800
- -
- static int vcm_ad_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
- {
- int err;
- @@ -1666,7 +1664,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- - hblank = OV5693_PPL_DEFAULT - ov5693->mode->width;
- + hblank = ov5693->mode->pixels_per_line - ov5693->mode->width;
- ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- V4L2_CID_HBLANK, hblank, hblank,
- 1, hblank);
- --
- 2.33.0
- From 9b6b3a7cc2420c4b57591404ed70378e4cc7c237 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 8 Feb 2021 22:53:02 +0000
- Subject: [PATCH] media: i2c: Add vblank control to ov5693 driver
- The latest libcamera requires a V4L2_CID_VBLANK control in each sensor
- driver; add a skeleton one to the ov5693 to fulfill the requirement.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 12 ++++++++++++
- drivers/media/i2c/ov5693.h | 3 +++
- 2 files changed, 15 insertions(+)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 7fb368eec327..1950d7ac2d54 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -946,6 +946,10 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- return ov5693_flip_horz_configure(dev, !!ctrl->val);
- case V4L2_CID_VFLIP:
- return ov5693_flip_vert_configure(dev, !!ctrl->val);
- + case V4L2_CID_VBLANK:
- + ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
- + dev->mode->height + ctrl->val);
- + break;
- default:
- ret = -EINVAL;
- }
- @@ -1611,6 +1615,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- unsigned int i;
- int ret;
- int hblank;
- + int vblank_max, vblank_min, vblank_def;
-
- ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
- ARRAY_SIZE(ov5693_controls));
- @@ -1671,6 +1676,13 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- if (ov5693->ctrls.hblank)
- ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- + vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode->height;
- + vblank_def = ov5693->mode->lines_per_frame - ov5693->mode->height;
- + vblank_min = ov5693->mode->lines_per_frame - ov5693->mode->height;
- + ov5693->ctrls.vblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- + V4L2_CID_VBLANK, vblank_min,
- + vblank_max, 1, vblank_def);
- +
- /* set properties from fwnode (e.g. rotation, orientation) */
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
- if (ret)
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 26819cf3f4d2..9d7eed97963b 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -131,6 +131,8 @@
- /*High 8-bit, and low 8-bit HTS address is 0x380f*/
- #define OV5693_TIMING_VTS_L 0x380f
-
- +#define OV5693_TIMING_MAX_VTS 0xffff
- +
- #define OV5693_MWB_RED_GAIN_H 0x3400
- #define OV5693_MWB_GREEN_GAIN_H 0x3402
- #define OV5693_MWB_BLUE_GAIN_H 0x3404
- @@ -279,6 +281,7 @@ struct ov5693_device {
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- struct v4l2_ctrl *hblank;
- + struct v4l2_ctrl *vblank;
- } ctrls;
-
- };
- --
- 2.33.0
- From 32c9eeba5037cf58eafa718260a6e678efc52089 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 10 Feb 2021 00:36:32 +0000
- Subject: [PATCH] media: i2c: update exposure control for ov5693
- The exposure control for ov5693 currently is in units of 1/16th of a line,
- but I think the framework expects it in units of lines. Set the control to
- work in lines and simply apply the multiplication when configuring the chip
- registers instead.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 23 ++++++++++++++++++++---
- 1 file changed, 20 insertions(+), 3 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 1950d7ac2d54..cea767230aa9 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -801,6 +801,12 @@ static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
- {
- int ret;
-
- + /*
- + * The control for exposure seems to be in units of lines, but the chip
- + * datasheet specifies exposure is in units of 1/16th of a line.
- + */
- + exposure = exposure * 16;
- +
- ov5693_get_exposure(sensor);
- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
- @@ -910,6 +916,16 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
- int ret = 0;
-
- + /* If VBLANK is altered we need to update exposure to compensate */
- + if (ctrl->id == V4L2_CID_VBLANK) {
- + int exposure_max;
- + exposure_max = dev->mode->lines_per_frame - 8;
- + __v4l2_ctrl_modify_range(dev->ctrls.exposure, dev->ctrls.exposure->minimum,
- + exposure_max, dev->ctrls.exposure->step,
- + dev->ctrls.exposure->val < exposure_max ?
- + dev->ctrls.exposure->val : exposure_max);
- + }
- +
- switch (ctrl->id) {
- case V4L2_CID_FOCUS_ABSOLUTE:
- dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
- @@ -1616,6 +1632,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- int ret;
- int hblank;
- int vblank_max, vblank_min, vblank_def;
- + int exposure_max;
-
- ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
- ARRAY_SIZE(ov5693_controls));
- @@ -1648,10 +1665,10 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- }
-
- /* Exposure */
- -
- + exposure_max = ov5693->mode->lines_per_frame - 8;
- ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- - V4L2_CID_EXPOSURE, 16,
- - 1048575, 16, 512);
- + V4L2_CID_EXPOSURE, 1,
- + exposure_max, 1, 123);
-
- /* Gain */
-
- --
- 2.33.0
- From 49678e1440330e97a36563a1f245fb52e7823e04 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 10 Feb 2021 00:39:42 +0000
- Subject: [PATCH] media: i2c: Fix incorrect bit-setting
- The bitmask macros to set the exposure for the ov5693 are not quite right.
- Update them so that they're setting the correct bits in the registers.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index cea767230aa9..f681dbfcec56 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -63,11 +63,11 @@ MODULE_PARM_DESC(up_delay,
- /* Exposure/gain */
-
- #define OV5693_EXPOSURE_CTRL_HH_REG 0x3500
- -#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(18, 16)) >> 16)
- +#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(14, 12)) >> 12)
- #define OV5693_EXPOSURE_CTRL_H_REG 0x3501
- -#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
- +#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(11, 4)) >> 4)
- #define OV5693_EXPOSURE_CTRL_L_REG 0x3502
- -#define OV5693_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
- +#define OV5693_EXPOSURE_CTRL_L(v) (((v) & GENMASK(3, 0)) << 4)
- #define OV5693_EXPOSURE_GAIN_MANUAL_REG 0x3509
-
- #define OV5693_GAIN_CTRL_H_REG 0x3504
- --
- 2.33.0
- From 0397bb78961d71bcf4cd0ff8ede80826d3ddd717 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 10 Feb 2021 16:25:48 +0000
- Subject: [PATCH] media: i2c: Don't set stream on during mode config
- Currently the register lists for the ov5693 include setting stream on.
- That register shouldn't be set until the control is called, so remove
- this setting from all of the modes.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.h | 16 ----------------
- 1 file changed, 16 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 9d7eed97963b..965208078c2b 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -581,7 +581,6 @@ static struct ov5693_reg const ov5693_654x496[] = {
- {OV5693_8BIT, 0x3820, 0x04},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -626,7 +625,6 @@ static struct ov5693_reg const ov5693_1296x976[] = {
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
-
- };
- @@ -656,7 +654,6 @@ static struct ov5693_reg const ov5693_336x256[] = {
- {OV5693_8BIT, 0x3820, 0x04},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -683,7 +680,6 @@ static struct ov5693_reg const ov5693_368x304[] = {
- {OV5693_8BIT, 0x3820, 0x04},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -715,7 +711,6 @@ static struct ov5693_reg const ov5693_192x160[] = {
- {OV5693_8BIT, 0x3820, 0x04},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -742,7 +737,6 @@ static struct ov5693_reg const ov5693_736x496[] = {
- {OV5693_8BIT, 0x3820, 0x04},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
- #endif
- @@ -771,7 +765,6 @@ static struct ov5693_reg const ov5693_736x496[] = {
- {OV5693_8BIT, 0x3820, 0x01},
- {OV5693_8BIT, 0x3821, 0x1f},
- {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
- */
- @@ -802,7 +795,6 @@ static struct ov5693_reg const ov5693_976x556[] = {
- {OV5693_8BIT, 0x3820, 0x00},
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -841,7 +833,6 @@ static struct ov5693_reg const ov5693_1296x736[] = {
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -868,7 +859,6 @@ static struct ov5693_reg const ov5693_1636p_30fps[] = {
- {OV5693_8BIT, 0x3820, 0x00},
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
- #endif
- @@ -904,7 +894,6 @@ static struct ov5693_reg const ov5693_1616x1216_30fps[] = {
- {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/
- {OV5693_8BIT, 0x5002, 0x00},
- {OV5693_8BIT, 0x5041, 0x84},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -935,7 +924,6 @@ static struct ov5693_reg const ov5693_1940x1096[] = {
- {OV5693_8BIT, 0x3820, 0x00},
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -1029,7 +1017,6 @@ static struct ov5693_reg const ov5693_2592x1944_30fps[] = {
- {OV5693_8BIT, 0x3820, 0x00},
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
- #endif
- @@ -1073,7 +1060,6 @@ static struct ov5693_reg const ov5693_1424x1168_30fps[] = {
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
- #endif
- @@ -1114,7 +1100,6 @@ static struct ov5693_reg const ov5693_736x496_30fps[] = {
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- @@ -1141,7 +1126,6 @@ static struct ov5693_reg const ov5693_2576x1936_30fps[] = {
- {OV5693_8BIT, 0x3820, 0x00},
- {OV5693_8BIT, 0x3821, 0x1e},
- {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_8BIT, 0x0100, 0x01},
- {OV5693_TOK_TERM, 0, 0}
- };
-
- --
- 2.33.0
- From 05691584e795bd16965cf2cc3b27ca0133e2ae7e Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 10 Feb 2021 16:35:24 +0000
- Subject: [PATCH] media: i2c: Update gain control for ov5693
- The gain control of the ov5693 driver is setting the wrong bits and
- defining an invalid maximum value; change (and use) the bitshifting
- macros and update the control's ranges.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index f681dbfcec56..51eb3b05d121 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -71,9 +71,9 @@ MODULE_PARM_DESC(up_delay,
- #define OV5693_EXPOSURE_GAIN_MANUAL_REG 0x3509
-
- #define OV5693_GAIN_CTRL_H_REG 0x3504
- -#define OV5693_GAIN_CTRL_H(v) (((v) & GENMASK(9, 8)) >> 8)
- +#define OV5693_GAIN_CTRL_H(v) ((v >> 4) & GENMASK(2, 0))
- #define OV5693_GAIN_CTRL_L_REG 0x3505
- -#define OV5693_GAIN_CTRL_L(v) ((v) & GENMASK(7, 0))
- +#define OV5693_GAIN_CTRL_L(v) ((v << 4) & GENMASK(7, 4))
-
- #define OV5693_FORMAT1_REG 0x3820
- #define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
- @@ -889,9 +889,13 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
- {
- int ret;
-
- - /* Analog gain */
- + /*
- + * As with exposure, the lowest 4 bits are fractional bits. Setting
- + * those is not supported, so we have a tiny bit of bit shifting to
- + * do.
- + */
- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- - OV5693_AGC_L, gain & 0xff);
- + OV5693_AGC_L, OV5693_GAIN_CTRL_L(gain));
- if (ret) {
- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_AGC_L);
- @@ -899,7 +903,7 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
- }
-
- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- - OV5693_AGC_H, (gain >> 8) & 0xff);
- + OV5693_AGC_H, OV5693_GAIN_CTRL_H(gain));
- if (ret) {
- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_AGC_H);
- @@ -1674,10 +1678,10 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
-
- ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler,
- ops, V4L2_CID_ANALOGUE_GAIN,
- - 1, 1023, 1, 128);
- + 1, 127, 1, 8);
- ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
- V4L2_CID_DIGITAL_GAIN, 1,
- - 3999, 1, 1000);
- + 4095, 1, 1024);
-
- /* Flip */
-
- --
- 2.33.0
- From 000757caef6c4e3162b28447cdb832659cf01b88 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Wed, 10 Feb 2021 23:44:39 +0000
- Subject: [PATCH] media: i2c: Fixup gain read
- This function reads the bits from the gain registers poorly. Update
- it to do that properly (although, it probably just needs to be deleted)
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 17 +++++++++++------
- 1 file changed, 11 insertions(+), 6 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 51eb3b05d121..952558c4f33b 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -770,30 +770,35 @@ static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
-
- static int ov5693_get_exposure(struct ov5693_device *sensor)
- {
- - u16 reg_v, reg_v2;
- + u32 exposure = 0;
- + u16 tmp;
- int ret = 0;
-
- /* get exposure */
- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- OV5693_EXPOSURE_L,
- - ®_v);
- + &tmp);
- if (ret)
- return ret;
-
- + exposure |= ((tmp >> 4) & 0b1111);
- +
- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- OV5693_EXPOSURE_M,
- - ®_v2);
- + &tmp);
- if (ret)
- return ret;
-
- - reg_v += reg_v2 << 8;
- + exposure |= (tmp << 4);
- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- OV5693_EXPOSURE_H,
- - ®_v2);
- + &tmp);
- if (ret)
- return ret;
-
- - printk("exposure set to: %u\n", reg_v + (((u32)reg_v2 << 16)));
- + exposure |= (tmp << 12);
- +
- + printk("exposure set to: %u\n", exposure);
- return ret;
- }
-
- --
- 2.33.0
- From e34f12d5d1acd241e7b9eebd15fa0dc4c5ae692e Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 11 Feb 2021 00:40:10 +0000
- Subject: [PATCH] media: i2c: Update controls on stream
- Currently the ov5693 driver throws away control setting by simply loading
- each mode's default registers. Instead, re-set the user defined controls
- during stream with __v4l2_ctrl_handler_setup()
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 6 ++++++
- 1 file changed, 6 insertions(+)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 952558c4f33b..dd31083eeb7b 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1492,6 +1492,12 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
- }
- }
-
- + ret = __v4l2_ctrl_handler_setup(&dev->ctrl_handler);
- + if (ret) {
- + power_down(sd);
- + return ret;
- + }
- +
- ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
- enable ? OV5693_START_STREAMING :
- OV5693_STOP_STREAMING);
- --
- 2.33.0
- From bcf152f00576999a15a184e41818742dd01a0313 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 11 Feb 2021 23:29:15 +0000
- Subject: [PATCH] media: i2c: Correct link frequency value
- The link frequency is given by vts * hts * fps * bits / lanes / 2. In the
- case of the ov5693 driver that works out to 400MHz, not 640Mhz. Correct
- the macro.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.h | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 965208078c2b..7f1d31a82d3d 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -186,13 +186,13 @@
- #define OV5693_OTP_MODE_READ 1
-
- /* link freq and pixel rate required for IPU3 */
- -#define OV5693_LINK_FREQ_640MHZ 640000000
- +#define OV5693_LINK_FREQ_400MHZ 400000000
- /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
- * To avoid integer overflow, dividing by bits_per_sample first.
- */
- -#define OV5693_PIXEL_RATE (OV5693_LINK_FREQ_640MHZ / 10) * 2 * 2
- +#define OV5693_PIXEL_RATE (OV5693_LINK_FREQ_400MHZ / 10) * 2 * 2
- static const s64 link_freq_menu_items[] = {
- - OV5693_LINK_FREQ_640MHZ
- + OV5693_LINK_FREQ_400MHZ
- };
-
- #define OV5693_NUM_SUPPLIES 2
- --
- 2.33.0
- From e1d20f8442fdb17668d029b8726466810e297385 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Mon, 25 Jan 2021 23:12:09 +0000
- Subject: [PATCH] media: i2c: Cleanup ov5693 driver
- This commit performs some cleanup to the ov5693 driver:
- 1. Superfluous words in variable names dropped; "i2c_client" becomes
- "client", "input_lock" becomes "lock"
- 2. ov5693_configure_gpios() is does error handling properly, and uses
- gpiod_get_optional()
- 3. The name of the struct ov5693_device variable in each functions, which
- previously was a mix of dev, sensor or ov5693, is standardised to the
- latter.
- 4. The list of headers is alphabetised (and probably also needs trimming)
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 309 +++++++++++++++++++------------------
- drivers/media/i2c/ov5693.h | 5 +-
- 2 files changed, 165 insertions(+), 149 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index dd31083eeb7b..0643390c872a 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -16,25 +16,25 @@
- *
- */
-
- +#include <linux/acpi.h>
- #include <linux/clk.h>
- -#include <linux/module.h>
- -#include <linux/types.h>
- -#include <linux/kernel.h>
- -#include <linux/mm.h>
- -#include <linux/string.h>
- +#include <linux/delay.h>
- +#include <linux/device.h>
- #include <linux/errno.h>
- +#include <linux/i2c.h>
- #include <linux/init.h>
- +#include <linux/io.h>
- +#include <linux/kernel.h>
- #include <linux/kmod.h>
- -#include <linux/device.h>
- -#include <linux/delay.h>
- -#include <linux/slab.h>
- -#include <linux/i2c.h>
- +#include <linux/module.h>
- #include <linux/moduleparam.h>
- +#include <linux/mm.h>
- +#include <linux/regulator/consumer.h>
- +#include <linux/slab.h>
- +#include <linux/string.h>
- +#include <linux/types.h>
- #include <media/v4l2-device.h>
- #include <media/v4l2-fwnode.h>
- -#include <linux/io.h>
- -#include <linux/acpi.h>
- -#include <linux/regulator/consumer.h>
-
- #include "ov5693.h"
- #include "ad5823.h"
- @@ -485,12 +485,12 @@ static int ov5693_read_otp_reg_array(struct i2c_client *client, u16 size,
- static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
- {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- int ret;
- int i;
- u8 *b = buf;
-
- - dev->otp_size = 0;
- + ov5693->otp_size = 0;
- for (i = 1; i < OV5693_OTP_BANK_MAX; i++) {
- /*set bank NO and OTP read mode. */
- ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_OTP_BANK_REG,
- @@ -529,7 +529,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
- //Intel OTP map, try to read 320byts first.
- if (i == 21) {
- if ((*b) == 0) {
- - dev->otp_size = 320;
- + ov5693->otp_size = 320;
- break;
- }
- /* (*b) != 0 */
- @@ -538,7 +538,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
- } else if (i ==
- 24) { //if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
- if ((*b) == 0) {
- - dev->otp_size = 32;
- + ov5693->otp_size = 32;
- break;
- }
- /* (*b) != 0 */
- @@ -547,11 +547,11 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
- } else if (i ==
- 27) { //if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
- if ((*b) == 0) {
- - dev->otp_size = 32;
- + ov5693->otp_size = 32;
- break;
- }
- /* (*b) != 0 */
- - dev->otp_size = 0; // no OTP data.
- + ov5693->otp_size = 0; // no OTP data.
- break;
- }
-
- @@ -598,20 +598,20 @@ static void *ov5693_otp_read(struct v4l2_subdev *sd)
- return buf;
- }
-
- -static int ov5693_update_bits(struct ov5693_device *sensor, u16 address,
- +static int ov5693_update_bits(struct ov5693_device *ov5693, u16 address,
- u16 mask, u16 bits)
- {
- u16 value = 0;
- int ret;
-
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT, address, &value);
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT, address, &value);
- if (ret)
- return ret;
-
- value &= ~mask;
- value |= bits;
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT, address, value);
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT, address, value);
- if (ret)
- return ret;
-
- @@ -620,13 +620,13 @@ static int ov5693_update_bits(struct ov5693_device *sensor, u16 address,
-
- /* Flip */
-
- -static int ov5693_flip_vert_configure(struct ov5693_device *sensor, bool enable)
- +static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, bool enable)
- {
- u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
- OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
- int ret;
-
- - ret = ov5693_update_bits(sensor, OV5693_FORMAT1_REG, bits,
- + ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG, bits,
- enable ? bits : 0);
- if (ret)
- return ret;
- @@ -634,13 +634,13 @@ static int ov5693_flip_vert_configure(struct ov5693_device *sensor, bool enable)
- return 0;
- }
-
- -static int ov5693_flip_horz_configure(struct ov5693_device *sensor, bool enable)
- +static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, bool enable)
- {
- u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
- OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
- int ret;
-
- - ret = ov5693_update_bits(sensor, OV5693_FORMAT2_REG, bits,
- + ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG, bits,
- enable ? bits : 0);
- if (ret)
- return ret;
- @@ -721,14 +721,14 @@ static int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
-
- static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
-
- dev_dbg(&client->dev, "%s: FOCUS_POS: 0x%x\n", __func__, value);
- value = clamp(value, 0, OV5693_VCM_MAX_FOCUS_POS);
- - if (dev->vcm == VCM_DW9714) {
- - if (dev->vcm_update) {
- + if (ov5693->vcm == VCM_DW9714) {
- + if (ov5693->vcm_update) {
- ret = vcm_dw_i2c_write(client, VCM_PROTECTION_OFF);
- if (ret)
- return ret;
- @@ -738,17 +738,17 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- ret = vcm_dw_i2c_write(client, VCM_PROTECTION_ON);
- if (ret)
- return ret;
- - dev->vcm_update = false;
- + ov5693->vcm_update = false;
- }
- ret = vcm_dw_i2c_write(client,
- vcm_val(value, VCM_DEFAULT_S));
- - } else if (dev->vcm == VCM_AD5823) {
- + } else if (ov5693->vcm == VCM_AD5823) {
- ad5823_t_focus_abs(sd, value);
- }
- if (ret == 0) {
- - dev->number_of_steps = value - dev->focus;
- - dev->focus = value;
- - dev->timestamp_t_focus_abs = ktime_get();
- + ov5693->number_of_steps = value - ov5693->focus;
- + ov5693->focus = value;
- + ov5693->timestamp_t_focus_abs = ktime_get();
- } else
- dev_err(&client->dev,
- "%s: i2c failed. ret %d\n", __func__, ret);
- @@ -758,9 +758,9 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
-
- static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- - return ov5693_t_focus_abs(sd, dev->focus + value);
- + return ov5693_t_focus_abs(sd, ov5693->focus + value);
- }
-
- #define DELAY_PER_STEP_NS 1000000
- @@ -768,14 +768,14 @@ static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
-
- /* Exposure */
-
- -static int ov5693_get_exposure(struct ov5693_device *sensor)
- +static int ov5693_get_exposure(struct ov5693_device *ov5693)
- {
- u32 exposure = 0;
- u16 tmp;
- int ret = 0;
-
- /* get exposure */
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_L,
- &tmp);
- if (ret)
- @@ -783,14 +783,14 @@ static int ov5693_get_exposure(struct ov5693_device *sensor)
-
- exposure |= ((tmp >> 4) & 0b1111);
-
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_M,
- &tmp);
- if (ret)
- return ret;
-
- exposure |= (tmp << 4);
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_H,
- &tmp);
- if (ret)
- @@ -802,7 +802,7 @@ static int ov5693_get_exposure(struct ov5693_device *sensor)
- return ret;
- }
-
- -static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
- +static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
- {
- int ret;
-
- @@ -812,40 +812,40 @@ static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
- */
- exposure = exposure * 16;
-
- - ov5693_get_exposure(sensor);
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ov5693_get_exposure(ov5693);
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
- if (ret)
- return ret;
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_CTRL_H_REG, OV5693_EXPOSURE_CTRL_H(exposure));
- if (ret)
- return ret;
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_CTRL_L_REG, OV5693_EXPOSURE_CTRL_L(exposure));
- if (ret)
- return ret;
- - ov5693_get_exposure(sensor);
- + ov5693_get_exposure(ov5693);
-
- return 0;
- }
-
- /* Gain */
-
- -static int ov5693_get_gain(struct ov5693_device *sensor, u32 *gain)
- +static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain)
- {
- u16 gain_l, gain_h;
- int ret = 0;
-
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- OV5693_GAIN_CTRL_L_REG,
- &gain_l);
- if (ret)
- return ret;
-
- - ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- OV5693_GAIN_CTRL_H_REG,
- &gain_h);
- if (ret)
- @@ -856,33 +856,33 @@ static int ov5693_get_gain(struct ov5693_device *sensor, u32 *gain)
-
- return ret;
- }
- -static int ov5693_gain_configure(struct ov5693_device *sensor, u32 gain)
- +static int ov5693_gain_configure(struct ov5693_device *ov5693, u32 gain)
- {
- int ret;
-
- /* A 1.0 gain is 0x400 */
- gain = (gain * 1024)/1000;
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
- OV5693_MWB_RED_GAIN_H, gain);
- if (ret) {
- - dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_MWB_RED_GAIN_H);
- return ret;
- }
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
- OV5693_MWB_GREEN_GAIN_H, gain);
- if (ret) {
- - dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_MWB_RED_GAIN_H);
- return ret;
- }
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
- OV5693_MWB_BLUE_GAIN_H, gain);
- if (ret) {
- - dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_MWB_RED_GAIN_H);
- return ret;
- }
- @@ -890,7 +890,7 @@ static int ov5693_gain_configure(struct ov5693_device *sensor, u32 gain)
- return 0;
- }
-
- -static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
- +static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain)
- {
- int ret;
-
- @@ -899,18 +899,18 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
- * those is not supported, so we have a tiny bit of bit shifting to
- * do.
- */
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_AGC_L, OV5693_GAIN_CTRL_L(gain));
- if (ret) {
- - dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_AGC_L);
- return ret;
- }
-
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_AGC_H, OV5693_GAIN_CTRL_H(gain));
- if (ret) {
- - dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
- + dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
- __func__, OV5693_AGC_H);
- return ret;
- }
- @@ -920,60 +920,60 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
-
- static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- {
- - struct ov5693_device *dev =
- + struct ov5693_device *ov5693 =
- container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
- - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
- + struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
- int ret = 0;
-
- /* If VBLANK is altered we need to update exposure to compensate */
- if (ctrl->id == V4L2_CID_VBLANK) {
- int exposure_max;
- - exposure_max = dev->mode->lines_per_frame - 8;
- - __v4l2_ctrl_modify_range(dev->ctrls.exposure, dev->ctrls.exposure->minimum,
- - exposure_max, dev->ctrls.exposure->step,
- - dev->ctrls.exposure->val < exposure_max ?
- - dev->ctrls.exposure->val : exposure_max);
- + exposure_max = ov5693->mode->lines_per_frame - 8;
- + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure, ov5693->ctrls.exposure->minimum,
- + exposure_max, ov5693->ctrls.exposure->step,
- + ov5693->ctrls.exposure->val < exposure_max ?
- + ov5693->ctrls.exposure->val : exposure_max);
- }
-
- switch (ctrl->id) {
- case V4L2_CID_FOCUS_ABSOLUTE:
- dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
- __func__, ctrl->val);
- - ret = ov5693_t_focus_abs(&dev->sd, ctrl->val);
- + ret = ov5693_t_focus_abs(&ov5693->sd, ctrl->val);
- break;
- case V4L2_CID_FOCUS_RELATIVE:
- dev_dbg(&client->dev, "%s: CID_FOCUS_RELATIVE:%d.\n",
- __func__, ctrl->val);
- - ret = ov5693_t_focus_rel(&dev->sd, ctrl->val);
- + ret = ov5693_t_focus_rel(&ov5693->sd, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
- __func__, ctrl->val);
- - ret = ov5693_exposure_configure(dev, ctrl->val);
- + ret = ov5693_exposure_configure(ov5693, ctrl->val);
- if (ret)
- return ret;
- break;
- case V4L2_CID_ANALOGUE_GAIN:
- dev_dbg(&client->dev, "%s: CID_ANALOGUE_GAIN:%d.\n",
- __func__, ctrl->val);
- - ret = ov5693_analog_gain_configure(dev, ctrl->val);
- + ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
- if (ret)
- return ret;
- break;
- case V4L2_CID_DIGITAL_GAIN:
- dev_dbg(&client->dev, "%s: CID_DIGITAL_GAIN:%d.\n",
- __func__, ctrl->val);
- - ret = ov5693_gain_configure(dev, ctrl->val);
- + ret = ov5693_gain_configure(ov5693, ctrl->val);
- if (ret)
- return ret;
- break;
- case V4L2_CID_HFLIP:
- - return ov5693_flip_horz_configure(dev, !!ctrl->val);
- + return ov5693_flip_horz_configure(ov5693, !!ctrl->val);
- case V4L2_CID_VFLIP:
- - return ov5693_flip_vert_configure(dev, !!ctrl->val);
- + return ov5693_flip_vert_configure(ov5693, !!ctrl->val);
- case V4L2_CID_VBLANK:
- ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
- - dev->mode->height + ctrl->val);
- + ov5693->mode->height + ctrl->val);
- break;
- default:
- ret = -EINVAL;
- @@ -983,16 +983,16 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
-
- static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
- {
- - struct ov5693_device *dev =
- + struct ov5693_device *ov5693 =
- container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE_ABSOLUTE:
- - ret = ov5693_q_exposure(&dev->sd, &ctrl->val);
- + ret = ov5693_q_exposure(&ov5693->sd, &ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- - ret = ov5693_get_gain(dev, &ctrl->val);
- + ret = ov5693_get_gain(ov5693, &ctrl->val);
- break;
- case V4L2_CID_FOCUS_ABSOLUTE:
- /* NOTE: there was atomisp-specific function ov5693_q_focus_abs() */
- @@ -1034,12 +1034,12 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
- },
- };
-
- -static int ov5693_isp_configure(struct ov5693_device *sensor)
- +static int ov5693_isp_configure(struct ov5693_device *ov5693)
- {
- int ret;
-
- /* Enable lens correction. */
- - ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
- + ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_ISP_CTRL0_REG, 0x86);
- if (ret)
- return ret;
- @@ -1049,18 +1049,18 @@ static int ov5693_isp_configure(struct ov5693_device *sensor)
-
- static int ov5693_init(struct v4l2_subdev *sd)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- - if (!dev->has_vcm)
- + if (!ov5693->has_vcm)
- return 0;
-
- dev_info(&client->dev, "%s\n", __func__);
- - mutex_lock(&dev->input_lock);
- - dev->vcm_update = false;
- + mutex_lock(&ov5693->lock);
- + ov5693->vcm_update = false;
-
- - if (dev->vcm == VCM_AD5823) {
- + if (ov5693->vcm == VCM_AD5823) {
- ret = vcm_ad_i2c_wr8(client, 0x01, 0x01); /* vcm init test */
- if (ret)
- dev_err(&client->dev,
- @@ -1079,16 +1079,16 @@ static int ov5693_init(struct v4l2_subdev *sd)
- }
-
- /*change initial focus value for ad5823*/
- - if (dev->vcm == VCM_AD5823) {
- - dev->focus = AD5823_INIT_FOCUS_POS;
- + if (ov5693->vcm == VCM_AD5823) {
- + ov5693->focus = AD5823_INIT_FOCUS_POS;
- ov5693_t_focus_abs(sd, AD5823_INIT_FOCUS_POS);
- } else {
- - dev->focus = 0;
- + ov5693->focus = 0;
- ov5693_t_focus_abs(sd, 0);
- }
-
- - ov5693_isp_configure(dev);
- - mutex_unlock(&dev->input_lock);
- + ov5693_isp_configure(ov5693);
- + mutex_unlock(&ov5693->lock);
-
- return 0;
- }
- @@ -1096,32 +1096,32 @@ static int ov5693_init(struct v4l2_subdev *sd)
- static int __power_up(struct v4l2_subdev *sd)
- {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- - struct ov5693_device *sensor = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- int ret;
-
- - ret = clk_prepare_enable(sensor->clk);
- + ret = clk_prepare_enable(ov5693->clk);
- if (ret) {
- dev_err(&client->dev, "Error enabling clock\n");
- return -EINVAL;
- }
-
- - if (sensor->indicator_led)
- - gpiod_set_value_cansleep(sensor->indicator_led, 1);
- + if (ov5693->indicator_led)
- + gpiod_set_value_cansleep(ov5693->indicator_led, 1);
-
- ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES,
- - sensor->supplies);
- + ov5693->supplies);
- if (ret)
- goto fail_power;
-
- - gpiod_set_value_cansleep(sensor->reset, 0);
- + gpiod_set_value_cansleep(ov5693->reset, 0);
-
- __cci_delay(up_delay);
-
- return 0;
-
- fail_power:
- - if (sensor->indicator_led)
- - gpiod_set_value_cansleep(sensor->indicator_led, 0);
- + if (ov5693->indicator_led)
- + gpiod_set_value_cansleep(ov5693->indicator_led, 0);
- dev_err(&client->dev, "sensor power-up failed\n");
-
- return ret;
- @@ -1129,17 +1129,17 @@ static int __power_up(struct v4l2_subdev *sd)
-
- static int power_down(struct v4l2_subdev *sd)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- - dev->focus = OV5693_INVALID_CONFIG;
- + ov5693->focus = OV5693_INVALID_CONFIG;
-
- - gpiod_set_value_cansleep(dev->reset, 1);
- + gpiod_set_value_cansleep(ov5693->reset, 1);
-
- - clk_disable_unprepare(dev->clk);
- + clk_disable_unprepare(ov5693->clk);
-
- - if (dev->indicator_led)
- - gpiod_set_value_cansleep(dev->indicator_led, 0);
- - return regulator_bulk_disable(OV5693_NUM_SUPPLIES, dev->supplies);
- + if (ov5693->indicator_led)
- + gpiod_set_value_cansleep(ov5693->indicator_led, 0);
- + return regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
- }
-
- static int power_up(struct v4l2_subdev *sd)
- @@ -1265,7 +1265,7 @@ static int get_resolution_index(int w, int h)
- /* TODO: remove it. */
- static int startup(struct v4l2_subdev *sd)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
-
- @@ -1282,7 +1282,7 @@ static int startup(struct v4l2_subdev *sd)
- return ret;
- }
-
- - ret = ov5693_write_reg_array(client, ov5693_res[dev->fmt_idx].regs);
- + ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
- if (ret) {
- dev_err(&client->dev, "ov5693 write register err.\n");
- return ret;
- @@ -1296,7 +1296,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_format *format)
- {
- struct v4l2_mbus_framefmt *fmt = &format->format;
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
- int idx;
- @@ -1307,7 +1307,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- if (!fmt)
- return -EINVAL;
-
- - mutex_lock(&dev->input_lock);
- + mutex_lock(&ov5693->lock);
- idx = nearest_resolution_index(fmt->width, fmt->height);
- if (idx == -1) {
- /* return the largest resolution */
- @@ -1325,8 +1325,8 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- goto mutex_unlock;
- }
-
- - dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- - if (dev->fmt_idx == -1) {
- + ov5693->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- + if (ov5693->fmt_idx == -1) {
- dev_err(&client->dev, "get resolution fail\n");
- ret = -EINVAL;
- goto mutex_unlock;
- @@ -1339,9 +1339,9 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- continue;
- }
-
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&ov5693->lock);
- ov5693_init(sd);
- - mutex_lock(&dev->input_lock);
- + mutex_lock(&ov5693->lock);
- ret = startup(sd);
- if (ret)
- dev_err(&client->dev, " startup() FAILED!\n");
- @@ -1353,8 +1353,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- goto mutex_unlock;
- }
-
- -
- -
- /*
- * After sensor settings are set to HW, sometimes stream is started.
- * This would cause ISP timeout because ISP is not ready to receive
- @@ -1366,19 +1364,19 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- dev_warn(&client->dev, "ov5693 stream off err\n");
-
- mutex_unlock:
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&ov5693->lock);
- return ret;
- }
-
- static const struct v4l2_rect *
- -__ov5693_get_pad_crop(struct ov5693_device *dev, struct v4l2_subdev_pad_config *cfg,
- +__ov5693_get_pad_crop(struct ov5693_device *ov5693, struct v4l2_subdev_pad_config *cfg,
- unsigned int pad, enum v4l2_subdev_format_whence which)
- {
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- - return v4l2_subdev_get_try_crop(&dev->sd, cfg, pad);
- + return v4l2_subdev_get_try_crop(&ov5693->sd, cfg, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- - return &dev->mode->crop;
- + return &ov5693->mode->crop;
- }
-
- return NULL;
- @@ -1389,12 +1387,12 @@ static int ov5693_get_selection(struct v4l2_subdev *sd,
- {
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP: {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- - mutex_lock(&dev->input_lock);
- - sel->r = *__ov5693_get_pad_crop(dev, cfg, sel->pad,
- + mutex_lock(&ov5693->lock);
- + sel->r = *__ov5693_get_pad_crop(ov5693, cfg, sel->pad,
- sel->which);
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&ov5693->lock);
-
- return 0;
- }
- @@ -1424,7 +1422,7 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_format *format)
- {
- struct v4l2_mbus_framefmt *fmt = &format->format;
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- if (format->pad)
- return -EINVAL;
- @@ -1432,8 +1430,8 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
- if (!fmt)
- return -EINVAL;
-
- - fmt->width = ov5693_res[dev->fmt_idx].width;
- - fmt->height = ov5693_res[dev->fmt_idx].height;
- + fmt->width = ov5693_res[ov5693->fmt_idx].width;
- + fmt->height = ov5693_res[ov5693->fmt_idx].height;
- fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-
- return 0;
- @@ -1481,7 +1479,7 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- - mutex_lock(&dev->input_lock);
- + mutex_lock(&dev->lock);
-
- /* power_on() here before streaming for regular PCs. */
- if (enable) {
- @@ -1507,26 +1505,26 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
- power_down(sd);
-
- out:
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&dev->lock);
-
- return ret;
- }
-
- static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
-
- - mutex_lock(&dev->input_lock);
- + mutex_lock(&ov5693->lock);
- ret = power_up(sd);
- if (ret) {
- dev_err(&client->dev, "ov5693 power-up err.\n");
- goto fail_power_on;
- }
-
- - if (!dev->vcm)
- - dev->vcm = vcm_detect(client);
- + if (!ov5693->vcm)
- + ov5693->vcm = vcm_detect(client);
-
- /* config & detect sensor */
- ret = ov5693_detect(client);
- @@ -1535,7 +1533,7 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- goto fail_power_on;
- }
-
- - dev->otp_data = ov5693_otp_read(sd);
- + ov5693->otp_data = ov5693_otp_read(sd);
-
- /* turn off sensor, after probed */
- ret = power_down(sd);
- @@ -1543,24 +1541,24 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- dev_err(&client->dev, "ov5693 power-off err.\n");
- goto fail_power_on;
- }
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&ov5693->lock);
-
- return ret;
-
- fail_power_on:
- power_down(sd);
- dev_err(&client->dev, "sensor power-gating failed\n");
- - mutex_unlock(&dev->input_lock);
- + mutex_unlock(&ov5693->lock);
- return ret;
- }
-
- static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *interval)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- interval->interval.numerator = 1;
- - interval->interval.denominator = ov5693_res[dev->fmt_idx].fps;
- + interval->interval.denominator = ov5693_res[ov5693->fmt_idx].fps;
-
- return 0;
- }
- @@ -1725,7 +1723,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- return ret;
-
- /* Use same lock for controls as for everything else. */
- - ov5693->ctrl_handler.lock = &ov5693->input_lock;
- + ov5693->ctrl_handler.lock = &ov5693->lock;
- ov5693->sd.ctrl_handler = &ov5693->ctrl_handler;
-
- return 0;
- @@ -1733,21 +1731,38 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
-
- static int ov5693_configure_gpios(struct ov5693_device *ov5693)
- {
- - ov5693->reset = gpiod_get_index(&ov5693->i2c_client->dev, "reset", 0,
- + int ret;
- +
- + ov5693->reset = gpiod_get_optional(&ov5693->client->dev, "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(ov5693->reset)) {
- - dev_err(&ov5693->i2c_client->dev, "Couldn't find reset GPIO\n");
- - return -EINVAL;
- + dev_err(&ov5693->client->dev, "Couldn't find reset GPIO\n");
- + return PTR_ERR(ov5693->reset);
- + }
- +
- + ov5693->powerdown = gpiod_get_optional(&ov5693->client->dev, "powerdown",
- + GPIOD_OUT_HIGH);
- + if (IS_ERR(ov5693->powerdown)) {
- + dev_err(&ov5693->client->dev, "Couldn't find powerdown GPIO\n");
- + ret = PTR_ERR(ov5693->powerdown);
- + goto err_put_reset;
- }
-
- - ov5693->indicator_led = gpiod_get_index_optional(&ov5693->i2c_client->dev, "indicator-led", 0,
- + ov5693->indicator_led = gpiod_get_optional(&ov5693->client->dev, "indicator-led",
- GPIOD_OUT_HIGH);
- if (IS_ERR(ov5693->indicator_led)) {
- - dev_err(&ov5693->i2c_client->dev, "Couldn't find indicator-led GPIO\n");
- - return -EINVAL;
- + dev_err(&ov5693->client->dev, "Couldn't find indicator-led GPIO\n");
- + ret = PTR_ERR(ov5693->indicator_led);
- + goto err_put_powerdown;
- }
-
- return 0;
- +err_put_reset:
- + gpiod_put(ov5693->reset);
- +err_put_powerdown:
- + gpiod_put(ov5693->powerdown);
- +
- + return ret;
- }
-
- static int ov5693_get_regulators(struct ov5693_device *ov5693)
- @@ -1757,7 +1772,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
- for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
- ov5693->supplies[i].supply = ov5693_supply_names[i];
-
- - return regulator_bulk_get(&ov5693->i2c_client->dev,
- + return regulator_bulk_get(&ov5693->client->dev,
- OV5693_NUM_SUPPLIES,
- ov5693->supplies);
- }
- @@ -1773,13 +1788,13 @@ static int ov5693_probe(struct i2c_client *client)
- if (!ov5693)
- return -ENOMEM;
-
- - ov5693->i2c_client = client;
- + ov5693->client = client;
-
- /* check if VCM device exists */
- /* TODO: read from SSDB */
- ov5693->has_vcm = false;
-
- - mutex_init(&ov5693->input_lock);
- + mutex_init(&ov5693->lock);
-
- v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
-
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 7f1d31a82d3d..70ccb3aae4c7 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -241,14 +241,15 @@ enum vcm_type {
- * ov5693 device structure.
- */
- struct ov5693_device {
- - struct i2c_client *i2c_client;
- + struct i2c_client *client;
- struct v4l2_subdev sd;
- struct media_pad pad;
- struct v4l2_mbus_framefmt format;
- - struct mutex input_lock;
- + struct mutex lock;
- struct v4l2_ctrl_handler ctrl_handler;
-
- struct gpio_desc *reset;
- + struct gpio_desc *powerdown;
- struct gpio_desc *indicator_led;
- struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
- struct clk *clk;
- --
- 2.33.0
- From 00545008dfbfb2e4447504e41561beedfb9ccdf0 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 28 Jan 2021 12:04:38 +0000
- Subject: [PATCH] media: i2c: Add pm_runtime support to ov5693 driver
- The ov5693 driver currently uses hacky and horrible power up/down methods
- called directly in s_stream. Add pm_runtime support and use that in
- s_stream instead. Replace all other uses of the power+up/down() calls with
- the single ov5693_sensor_stream() for now.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 183 +++++++++++++++++++++++++++++--------
- drivers/media/i2c/ov5693.h | 1 +
- 2 files changed, 146 insertions(+), 38 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 0643390c872a..f2eaa5f71a31 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -29,6 +29,7 @@
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/mm.h>
- +#include <linux/pm_runtime.h>
- #include <linux/regulator/consumer.h>
- #include <linux/slab.h>
- #include <linux/string.h>
- @@ -935,6 +936,10 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- ov5693->ctrls.exposure->val : exposure_max);
- }
-
- + /* Only apply changes to the controls if the device is powered up */
- + if (!pm_runtime_get_if_in_use(&ov5693->client->dev))
- + return 0;
- +
- switch (ctrl->id) {
- case V4L2_CID_FOCUS_ABSOLUTE:
- dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
- @@ -950,27 +955,23 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
- __func__, ctrl->val);
- ret = ov5693_exposure_configure(ov5693, ctrl->val);
- - if (ret)
- - return ret;
- break;
- case V4L2_CID_ANALOGUE_GAIN:
- dev_dbg(&client->dev, "%s: CID_ANALOGUE_GAIN:%d.\n",
- __func__, ctrl->val);
- ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
- - if (ret)
- - return ret;
- break;
- case V4L2_CID_DIGITAL_GAIN:
- dev_dbg(&client->dev, "%s: CID_DIGITAL_GAIN:%d.\n",
- __func__, ctrl->val);
- ret = ov5693_gain_configure(ov5693, ctrl->val);
- - if (ret)
- - return ret;
- break;
- case V4L2_CID_HFLIP:
- - return ov5693_flip_horz_configure(ov5693, !!ctrl->val);
- + ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val);
- + break;
- case V4L2_CID_VFLIP:
- - return ov5693_flip_vert_configure(ov5693, !!ctrl->val);
- + ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val);
- + break;
- case V4L2_CID_VBLANK:
- ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
- ov5693->mode->height + ctrl->val);
- @@ -978,6 +979,9 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- default:
- ret = -EINVAL;
- }
- +
- + pm_runtime_put(&ov5693->client->dev);
- +
- return ret;
- }
-
- @@ -1093,6 +1097,106 @@ static int ov5693_init(struct v4l2_subdev *sd)
- return 0;
- }
-
- +static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
- +{
- + return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_STREAM,
- + standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING);
- +}
- +
- +static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
- +{
- + gpiod_set_value_cansleep(ov5693->reset, 1);
- + gpiod_set_value_cansleep(ov5693->powerdown, 1);
- +
- + regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
- +
- + clk_disable_unprepare(ov5693->clk);
- + gpiod_set_value_cansleep(ov5693->indicator_led, 0);
- +}
- +
- +
- +static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
- +{
- + int ret = 0;
- +
- + gpiod_set_value_cansleep(ov5693->reset, 1);
- + gpiod_set_value_cansleep(ov5693->powerdown, 1);
- +
- + ret = clk_prepare_enable(ov5693->clk);
- + if (ret) {
- + dev_err(&ov5693->client->dev, "Failed to enable clk\n");
- + goto fail_power;
- + }
- +
- + ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies);
- + if (ret) {
- + dev_err(&ov5693->client->dev, "Failed to enable regulators\n");
- + goto fail_power;
- + }
- +
- + gpiod_set_value_cansleep(ov5693->reset, 0);
- + gpiod_set_value_cansleep(ov5693->powerdown, 0);
- + gpiod_set_value_cansleep(ov5693->indicator_led, 1);
- +
- + usleep_range(20000, 25000);
- +
- + return 0;
- +
- +fail_power:
- + ov5693_sensor_powerdown(ov5693);
- + return ret;
- +}
- +
- +static int __maybe_unused ov5693_sensor_suspend(struct device *dev)
- +{
- + struct i2c_client *client = i2c_verify_client(dev);
- + struct v4l2_subdev *sd = i2c_get_clientdata(client);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- + int ret;
- +
- + mutex_lock(&ov5693->lock);
- +
- + if (ov5693->streaming) {
- + ret = ov5693_sw_standby(ov5693, true);
- + if (ret)
- + goto out_unlock;
- + }
- +
- + ov5693_sensor_powerdown(ov5693);
- +
- +out_unlock:
- + mutex_unlock(&ov5693->lock);
- + return ret;
- +}
- +
- +static int __maybe_unused ov5693_sensor_resume(struct device *dev)
- +{
- + struct i2c_client *client = i2c_verify_client(dev);
- + struct v4l2_subdev *sd = i2c_get_clientdata(client);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- + int ret;
- +
- + mutex_lock(&ov5693->lock);
- +
- + ret = ov5693_sensor_powerup(ov5693);
- + if (ret)
- + goto out_unlock;
- +
- + if (ov5693->streaming) {
- + ret = ov5693_sw_standby(ov5693, false);
- + if (ret)
- + goto err_power;
- + }
- +
- + goto out_unlock;
- +
- +err_power:
- + ov5693_sensor_powerdown(ov5693);
- +out_unlock:
- + mutex_unlock(&ov5693->lock);
- + return ret;
- +}
- +
- static int __power_up(struct v4l2_subdev *sd)
- {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- @@ -1134,6 +1238,7 @@ static int power_down(struct v4l2_subdev *sd)
- ov5693->focus = OV5693_INVALID_CONFIG;
-
- gpiod_set_value_cansleep(ov5693->reset, 1);
- + gpiod_set_value_cansleep(ov5693->powerdown, 1);
-
- clk_disable_unprepare(ov5693->clk);
-
- @@ -1333,7 +1438,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- }
-
- for (cnt = 0; cnt < OV5693_POWER_UP_RETRY_NUM; cnt++) {
- - ret = power_up(sd);
- + ret = ov5693_sensor_powerup(ov5693);
- if (ret) {
- dev_err(&client->dev, "power up failed\n");
- continue;
- @@ -1475,38 +1580,34 @@ static int ov5693_detect(struct i2c_client *client)
-
- static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
- {
- - struct ov5693_device *dev = to_ov5693_sensor(sd);
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- int ret;
-
- - mutex_lock(&dev->lock);
- -
- - /* power_on() here before streaming for regular PCs. */
- if (enable) {
- - ret = power_up(sd);
- - if (ret) {
- - dev_err(&client->dev, "sensor power-up error\n");
- - goto out;
- - }
- + ret = pm_runtime_get_sync(&ov5693->client->dev);
- + if (ret < 0)
- + goto err_power_down;
- }
-
- - ret = __v4l2_ctrl_handler_setup(&dev->ctrl_handler);
- - if (ret) {
- - power_down(sd);
- - return ret;
- - }
- + ret = __v4l2_ctrl_handler_setup(&ov5693->ctrl_handler);
- + if (ret)
- + goto err_power_down;
-
- - ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
- - enable ? OV5693_START_STREAMING :
- - OV5693_STOP_STREAMING);
- + mutex_lock(&ov5693->lock);
- + ret = ov5693_sw_standby(ov5693, !enable);
- + mutex_unlock(&ov5693->lock);
- +
- + if (ret)
- + goto err_power_down;
- + ov5693->streaming = !!enable;
-
- /* power_off() here after streaming for regular PCs. */
- if (!enable)
- - power_down(sd);
- -
- -out:
- - mutex_unlock(&dev->lock);
- + pm_runtime_put(&ov5693->client->dev);
-
- + return 0;
- +err_power_down:
- + pm_runtime_put_noidle(&ov5693->client->dev);
- return ret;
- }
-
- @@ -1517,7 +1618,7 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- int ret = 0;
-
- mutex_lock(&ov5693->lock);
- - ret = power_up(sd);
- + ret = ov5693_sensor_powerup(ov5693);
- if (ret) {
- dev_err(&client->dev, "ov5693 power-up err.\n");
- goto fail_power_on;
- @@ -1536,17 +1637,14 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- ov5693->otp_data = ov5693_otp_read(sd);
-
- /* turn off sensor, after probed */
- - ret = power_down(sd);
- - if (ret) {
- - dev_err(&client->dev, "ov5693 power-off err.\n");
- - goto fail_power_on;
- - }
- + ov5693_sensor_powerdown(ov5693);
- +
- mutex_unlock(&ov5693->lock);
-
- return ret;
-
- fail_power_on:
- - power_down(sd);
- + ov5693_sensor_powerdown(ov5693);
- dev_err(&client->dev, "sensor power-gating failed\n");
- mutex_unlock(&ov5693->lock);
- return ret;
- @@ -1830,6 +1928,9 @@ static int ov5693_probe(struct i2c_client *client)
- if (ret)
- ov5693_remove(client);
-
- + pm_runtime_enable(&client->dev);
- + pm_runtime_set_suspended(&client->dev);
- +
- ret = v4l2_async_register_subdev_sensor_common(&ov5693->sd);
- if (ret) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret);
- @@ -1839,6 +1940,7 @@ static int ov5693_probe(struct i2c_client *client)
- return ret;
-
- media_entity_cleanup:
- + pm_runtime_disable(&client->dev);
- media_entity_cleanup(&ov5693->sd.entity);
- out_put_reset:
- gpiod_put(ov5693->reset);
- @@ -1848,6 +1950,10 @@ static int ov5693_probe(struct i2c_client *client)
- return ret;
- }
-
- +static const struct dev_pm_ops ov5693_pm_ops = {
- + SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL)
- +};
- +
- static const struct acpi_device_id ov5693_acpi_match[] = {
- {"INT33BE"},
- {},
- @@ -1858,6 +1964,7 @@ static struct i2c_driver ov5693_driver = {
- .driver = {
- .name = "ov5693",
- .acpi_match_table = ov5693_acpi_match,
- + .pm = &ov5693_pm_ops,
- },
- .probe_new = ov5693_probe,
- .remove = ov5693_remove,
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 70ccb3aae4c7..b78d3b474a43 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -256,6 +256,7 @@ struct ov5693_device {
-
- /* Current mode */
- const struct ov5693_resolution *mode;
- + bool streaming;
-
- struct camera_sensor_platform_data *platform_data;
- ktime_t timestamp_t_focus_abs;
- --
- 2.33.0
- From 0a057ee3ecd60dd5eb0d8ba418c226cf772cb72b Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 28 Jan 2021 12:07:36 +0000
- Subject: [PATCH] media: i2c: Remove old power methods from ov5693
- Now that we have replaced the power_up/down() methods with a unified
- function and pm_runtime support, we can remove these old methods from the
- driver entirely along with some macros and a header.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 114 -------------------------------------
- 1 file changed, 114 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index f2eaa5f71a31..ce26ce86fbd5 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -27,7 +27,6 @@
- #include <linux/kernel.h>
- #include <linux/kmod.h>
- #include <linux/module.h>
- -#include <linux/moduleparam.h>
- #include <linux/mm.h>
- #include <linux/pm_runtime.h>
- #include <linux/regulator/consumer.h>
- @@ -40,27 +39,6 @@
- #include "ov5693.h"
- #include "ad5823.h"
-
- -#define __cci_delay(t) \
- - do { \
- - if ((t) < 10) { \
- - usleep_range((t) * 1000, ((t) + 1) * 1000); \
- - } else { \
- - msleep((t)); \
- - } \
- - } while (0)
- -
- -/* Value 30ms reached through experimentation on byt ecs.
- - * The DS specifies a much lower value but when using a smaller value
- - * the I2C bus sometimes locks up permanently when starting the camera.
- - * This issue could not be reproduced on cht, so we can reduce the
- - * delay value to a lower value when insmod.
- - */
- -static uint up_delay = 30;
- -module_param(up_delay, uint, 0644);
- -MODULE_PARM_DESC(up_delay,
- - "Delay prior to the first CCI transaction for ov5693");
- -
- -
- /* Exposure/gain */
-
- #define OV5693_EXPOSURE_CTRL_HH_REG 0x3500
- @@ -1197,93 +1175,6 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
- return ret;
- }
-
- -static int __power_up(struct v4l2_subdev *sd)
- -{
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - int ret;
- -
- - ret = clk_prepare_enable(ov5693->clk);
- - if (ret) {
- - dev_err(&client->dev, "Error enabling clock\n");
- - return -EINVAL;
- - }
- -
- - if (ov5693->indicator_led)
- - gpiod_set_value_cansleep(ov5693->indicator_led, 1);
- -
- - ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES,
- - ov5693->supplies);
- - if (ret)
- - goto fail_power;
- -
- - gpiod_set_value_cansleep(ov5693->reset, 0);
- -
- - __cci_delay(up_delay);
- -
- - return 0;
- -
- -fail_power:
- - if (ov5693->indicator_led)
- - gpiod_set_value_cansleep(ov5693->indicator_led, 0);
- - dev_err(&client->dev, "sensor power-up failed\n");
- -
- - return ret;
- -}
- -
- -static int power_down(struct v4l2_subdev *sd)
- -{
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- -
- - ov5693->focus = OV5693_INVALID_CONFIG;
- -
- - gpiod_set_value_cansleep(ov5693->reset, 1);
- - gpiod_set_value_cansleep(ov5693->powerdown, 1);
- -
- - clk_disable_unprepare(ov5693->clk);
- -
- - if (ov5693->indicator_led)
- - gpiod_set_value_cansleep(ov5693->indicator_led, 0);
- - return regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
- -}
- -
- -static int power_up(struct v4l2_subdev *sd)
- -{
- - static const int retry_count = 4;
- - int i, ret;
- -
- - for (i = 0; i < retry_count; i++) {
- - ret = __power_up(sd);
- - if (!ret)
- - return 0;
- -
- - power_down(sd);
- - }
- - return ret;
- -}
- -
- -static int ov5693_s_power(struct v4l2_subdev *sd, int on)
- -{
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - int ret;
- -
- - dev_info(&client->dev, "%s: on %d\n", __func__, on);
- -
- - if (on == 0)
- - return power_down(sd);
- -
- - /* on == 1 */
- - ret = power_up(sd);
- - if (!ret) {
- - ret = ov5693_init(sd);
- - /* restore settings */
- - ov5693_res = ov5693_res_video;
- - N_RES = N_RES_VIDEO;
- - }
- -
- - return ret;
- -}
- -
- /*
- * distance - calculate the distance
- * @res: resolution
- @@ -1694,10 +1585,6 @@ static const struct v4l2_subdev_video_ops ov5693_video_ops = {
- .g_frame_interval = ov5693_g_frame_interval,
- };
-
- -static const struct v4l2_subdev_core_ops ov5693_core_ops = {
- - .s_power = ov5693_s_power,
- -};
- -
- static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
- .enum_mbus_code = ov5693_enum_mbus_code,
- .enum_frame_size = ov5693_enum_frame_size,
- @@ -1707,7 +1594,6 @@ static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
- };
-
- static const struct v4l2_subdev_ops ov5693_ops = {
- - .core = &ov5693_core_ops,
- .video = &ov5693_video_ops,
- .pad = &ov5693_pad_ops,
- };
- --
- 2.33.0
- From 1cce1c2b2913dde59e9c2083bdfb8fac1946df44 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Thu, 28 Jan 2021 12:14:00 +0000
- Subject: [PATCH] media: i2c: Trim unused headers from ov5693
- The ov5693 driver includes a ton of unecessary headers,
- trim the list down.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 8 --------
- 1 file changed, 8 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index ce26ce86fbd5..b3b391a49fdb 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -20,19 +20,11 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/device.h>
- -#include <linux/errno.h>
- #include <linux/i2c.h>
- -#include <linux/init.h>
- -#include <linux/io.h>
- -#include <linux/kernel.h>
- -#include <linux/kmod.h>
- #include <linux/module.h>
- -#include <linux/mm.h>
- #include <linux/pm_runtime.h>
- #include <linux/regulator/consumer.h>
- #include <linux/slab.h>
- -#include <linux/string.h>
- -#include <linux/types.h>
- #include <media/v4l2-device.h>
- #include <media/v4l2-fwnode.h>
-
- --
- 2.33.0
- From 9a9284056a8c43d857e95e9748164a23ecd2597d Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 13 Feb 2021 21:39:35 +0000
- Subject: [PATCH] media: i2c: Remove VCM stuff
- This all needs binning, since we have no idea if it's right. It needs to
- be moved to a driver for the VCM device I guess.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 325 +------------------------------------
- 1 file changed, 1 insertion(+), 324 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index b3b391a49fdb..2c82b6578de9 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -76,72 +76,6 @@
- #define OV5693_PIXEL_ARRAY_WIDTH 2592U
- #define OV5693_PIXEL_ARRAY_HEIGHT 1944U
-
- -static int vcm_ad_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
- -{
- - int err;
- - struct i2c_msg msg;
- - u8 buf[2];
- -
- - buf[0] = reg;
- - buf[1] = val;
- -
- - msg.addr = VCM_ADDR;
- - msg.flags = 0;
- - msg.len = 2;
- - msg.buf = &buf[0];
- -
- - err = i2c_transfer(client->adapter, &msg, 1);
- - if (err != 1) {
- - dev_err(&client->dev, "%s: vcm i2c fail, err code = %d\n",
- - __func__, err);
- - return -EIO;
- - }
- - return 0;
- -}
- -
- -static int ad5823_i2c_write(struct i2c_client *client, u8 reg, u8 val)
- -{
- - struct i2c_msg msg;
- - u8 buf[2];
- -
- - buf[0] = reg;
- - buf[1] = val;
- - msg.addr = AD5823_VCM_ADDR;
- - msg.flags = 0;
- - msg.len = 0x02;
- - msg.buf = &buf[0];
- -
- - if (i2c_transfer(client->adapter, &msg, 1) != 1)
- - return -EIO;
- - return 0;
- -}
- -
- -static int ad5823_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
- -{
- - struct i2c_msg msg[2];
- - u8 buf[2];
- -
- - buf[0] = reg;
- - buf[1] = 0;
- -
- - msg[0].addr = AD5823_VCM_ADDR;
- - msg[0].flags = 0;
- - msg[0].len = 0x01;
- - msg[0].buf = &buf[0];
- -
- - msg[1].addr = 0x0c;
- - msg[1].flags = I2C_M_RD;
- - msg[1].len = 0x01;
- - msg[1].buf = &buf[1];
- - *val = 0;
- - if (i2c_transfer(client->adapter, msg, 2) != 2)
- - return -EIO;
- - *val = buf[1];
- - return 0;
- -}
- -
- -static const u32 ov5693_embedded_effective_size = 28;
- -
- /* i2c read/write stuff */
- static int ov5693_read_reg(struct i2c_client *client,
- u16 data_length, u16 reg, u16 *val)
- @@ -215,69 +149,6 @@ static int ov5693_i2c_write(struct i2c_client *client, u16 len, u8 *data)
- return ret == num_msg ? 0 : -EIO;
- }
-
- -static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
- -{
- - struct i2c_msg msg;
- - const int num_msg = 1;
- - int ret;
- - __be16 val;
- -
- - val = cpu_to_be16(data);
- - msg.addr = VCM_ADDR;
- - msg.flags = 0;
- - msg.len = OV5693_16BIT;
- - msg.buf = (void *)&val;
- -
- - ret = i2c_transfer(client->adapter, &msg, 1);
- -
- - return ret == num_msg ? 0 : -EIO;
- -}
- -
- -/*
- - * Theory: per datasheet, the two VCMs both allow for a 2-byte read.
- - * The DW9714 doesn't actually specify what this does (it has a
- - * two-byte write-only protocol, but specifies the read sequence as
- - * legal), but it returns the same data (zeroes) always, after an
- - * undocumented initial NAK. The AD5823 has a one-byte address
- - * register to which all writes go, and subsequent reads will cycle
- - * through the 8 bytes of registers. Notably, the default values (the
- - * device is always power-cycled affirmatively, so we can rely on
- - * these) in AD5823 are not pairwise repetitions of the same 16 bit
- - * word. So all we have to do is sequentially read two bytes at a
- - * time and see if we detect a difference in any of the first four
- - * pairs.
- - */
- -static int vcm_detect(struct i2c_client *client)
- -{
- - int i, ret;
- - struct i2c_msg msg;
- - u16 data0 = 0, data;
- -
- - for (i = 0; i < 4; i++) {
- - msg.addr = VCM_ADDR;
- - msg.flags = I2C_M_RD;
- - msg.len = sizeof(data);
- - msg.buf = (u8 *)&data;
- - ret = i2c_transfer(client->adapter, &msg, 1);
- -
- - /*
- - * DW9714 always fails the first read and returns
- - * zeroes for subsequent ones
- - */
- - if (i == 0 && ret == -EREMOTEIO) {
- - data0 = 0;
- - continue;
- - }
- -
- - if (i == 0)
- - data0 = data;
- -
- - if (data != data0)
- - return VCM_AD5823;
- - }
- - return ret == 1 ? VCM_DW9714 : ret;
- -}
- -
- static int ov5693_write_reg(struct i2c_client *client, u16 data_length,
- u16 reg, u16 val)
- {
- @@ -654,89 +525,6 @@ static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
- return ret;
- }
-
- -static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val)
- -{
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - int ret = -EINVAL;
- - u8 vcm_code;
- -
- - ret = ad5823_i2c_read(client, AD5823_REG_VCM_CODE_MSB, &vcm_code);
- - if (ret)
- - return ret;
- -
- - /* set reg VCM_CODE_MSB Bit[1:0] */
- - vcm_code = (vcm_code & VCM_CODE_MSB_MASK) |
- - ((val >> 8) & ~VCM_CODE_MSB_MASK);
- - ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB, vcm_code);
- - if (ret)
- - return ret;
- -
- - /* set reg VCM_CODE_LSB Bit[7:0] */
- - ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_LSB, (val & 0xff));
- - if (ret)
- - return ret;
- -
- - /* set required vcm move time */
- - vcm_code = AD5823_RESONANCE_PERIOD / AD5823_RESONANCE_COEF
- - - AD5823_HIGH_FREQ_RANGE;
- - ret = ad5823_i2c_write(client, AD5823_REG_VCM_MOVE_TIME, vcm_code);
- -
- - return ret;
- -}
- -
- -static int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- -{
- - value = min(value, AD5823_MAX_FOCUS_POS);
- - return ad5823_t_focus_vcm(sd, value);
- -}
- -
- -static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
- -{
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - int ret = 0;
- -
- - dev_dbg(&client->dev, "%s: FOCUS_POS: 0x%x\n", __func__, value);
- - value = clamp(value, 0, OV5693_VCM_MAX_FOCUS_POS);
- - if (ov5693->vcm == VCM_DW9714) {
- - if (ov5693->vcm_update) {
- - ret = vcm_dw_i2c_write(client, VCM_PROTECTION_OFF);
- - if (ret)
- - return ret;
- - ret = vcm_dw_i2c_write(client, DIRECT_VCM);
- - if (ret)
- - return ret;
- - ret = vcm_dw_i2c_write(client, VCM_PROTECTION_ON);
- - if (ret)
- - return ret;
- - ov5693->vcm_update = false;
- - }
- - ret = vcm_dw_i2c_write(client,
- - vcm_val(value, VCM_DEFAULT_S));
- - } else if (ov5693->vcm == VCM_AD5823) {
- - ad5823_t_focus_abs(sd, value);
- - }
- - if (ret == 0) {
- - ov5693->number_of_steps = value - ov5693->focus;
- - ov5693->focus = value;
- - ov5693->timestamp_t_focus_abs = ktime_get();
- - } else
- - dev_err(&client->dev,
- - "%s: i2c failed. ret %d\n", __func__, ret);
- -
- - return ret;
- -}
- -
- -static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
- -{
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- -
- - return ov5693_t_focus_abs(sd, ov5693->focus + value);
- -}
- -
- -#define DELAY_PER_STEP_NS 1000000
- -#define DELAY_MAX_PER_STEP_NS (1000000 * 1023)
- -
- /* Exposure */
-
- static int ov5693_get_exposure(struct ov5693_device *ov5693)
- @@ -911,16 +699,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
- return 0;
-
- switch (ctrl->id) {
- - case V4L2_CID_FOCUS_ABSOLUTE:
- - dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
- - __func__, ctrl->val);
- - ret = ov5693_t_focus_abs(&ov5693->sd, ctrl->val);
- - break;
- - case V4L2_CID_FOCUS_RELATIVE:
- - dev_dbg(&client->dev, "%s: CID_FOCUS_RELATIVE:%d.\n",
- - __func__, ctrl->val);
- - ret = ov5693_t_focus_rel(&ov5693->sd, ctrl->val);
- - break;
- case V4L2_CID_EXPOSURE:
- dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
- __func__, ctrl->val);
- @@ -983,90 +761,6 @@ static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
- .g_volatile_ctrl = ov5693_g_volatile_ctrl
- };
-
- -static const struct v4l2_ctrl_config ov5693_controls[] = {
- - {
- - .ops = &ov5693_ctrl_ops,
- - .id = V4L2_CID_FOCUS_ABSOLUTE,
- - .type = V4L2_CTRL_TYPE_INTEGER,
- - .name = "focus move absolute",
- - .min = 0,
- - .max = OV5693_VCM_MAX_FOCUS_POS,
- - .step = 1,
- - .def = 0,
- - .flags = 0,
- - },
- - {
- - .ops = &ov5693_ctrl_ops,
- - .id = V4L2_CID_FOCUS_RELATIVE,
- - .type = V4L2_CTRL_TYPE_INTEGER,
- - .name = "focus move relative",
- - .min = OV5693_VCM_MAX_FOCUS_NEG,
- - .max = OV5693_VCM_MAX_FOCUS_POS,
- - .step = 1,
- - .def = 0,
- - .flags = 0,
- - },
- -};
- -
- -static int ov5693_isp_configure(struct ov5693_device *ov5693)
- -{
- - int ret;
- -
- - /* Enable lens correction. */
- - ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- - OV5693_ISP_CTRL0_REG, 0x86);
- - if (ret)
- - return ret;
- -
- - return 0;
- -}
- -
- -static int ov5693_init(struct v4l2_subdev *sd)
- -{
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - int ret;
- -
- - if (!ov5693->has_vcm)
- - return 0;
- -
- - dev_info(&client->dev, "%s\n", __func__);
- - mutex_lock(&ov5693->lock);
- - ov5693->vcm_update = false;
- -
- - if (ov5693->vcm == VCM_AD5823) {
- - ret = vcm_ad_i2c_wr8(client, 0x01, 0x01); /* vcm init test */
- - if (ret)
- - dev_err(&client->dev,
- - "vcm reset failed\n");
- - /*change the mode*/
- - ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB,
- - AD5823_RING_CTRL_ENABLE);
- - if (ret)
- - dev_err(&client->dev,
- - "vcm enable ringing failed\n");
- - ret = ad5823_i2c_write(client, AD5823_REG_MODE,
- - AD5823_ARC_RES1);
- - if (ret)
- - dev_err(&client->dev,
- - "vcm change mode failed\n");
- - }
- -
- - /*change initial focus value for ad5823*/
- - if (ov5693->vcm == VCM_AD5823) {
- - ov5693->focus = AD5823_INIT_FOCUS_POS;
- - ov5693_t_focus_abs(sd, AD5823_INIT_FOCUS_POS);
- - } else {
- - ov5693->focus = 0;
- - ov5693_t_focus_abs(sd, 0);
- - }
- -
- - ov5693_isp_configure(ov5693);
- - mutex_unlock(&ov5693->lock);
- -
- - return 0;
- -}
- -
- static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
- {
- return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_STREAM,
- @@ -1327,9 +1021,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- continue;
- }
-
- - mutex_unlock(&ov5693->lock);
- - ov5693_init(sd);
- - mutex_lock(&ov5693->lock);
- ret = startup(sd);
- if (ret)
- dev_err(&client->dev, " startup() FAILED!\n");
- @@ -1507,9 +1198,6 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
- goto fail_power_on;
- }
-
- - if (!ov5693->vcm)
- - ov5693->vcm = vcm_detect(client);
- -
- /* config & detect sensor */
- ret = ov5693_detect(client);
- if (ret) {
- @@ -1617,24 +1305,17 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
- struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
- const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
- struct v4l2_fwnode_device_properties props;
- - unsigned int i;
- int ret;
- int hblank;
- int vblank_max, vblank_min, vblank_def;
- int exposure_max;
-
- - ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
- - ARRAY_SIZE(ov5693_controls));
- + ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler, 8);
- if (ret) {
- ov5693_remove(client);
- return ret;
- }
-
- - for (i = 0; i < ARRAY_SIZE(ov5693_controls); i++)
- - v4l2_ctrl_new_custom(&ov5693->ctrl_handler,
- - &ov5693_controls[i],
- - NULL);
- -
- /* link freq */
- ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler,
- NULL, V4L2_CID_LINK_FREQ,
- @@ -1766,10 +1447,6 @@ static int ov5693_probe(struct i2c_client *client)
-
- ov5693->client = client;
-
- - /* check if VCM device exists */
- - /* TODO: read from SSDB */
- - ov5693->has_vcm = false;
- -
- mutex_init(&ov5693->lock);
-
- v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
- --
- 2.33.0
- From b52dadcfd79b26724cf0dee8c22649dffbc766a9 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 13 Feb 2021 22:16:08 +0000
- Subject: [PATCH] media: i2c: Tidy up ov5693 sensor init
- The initialisation of a mode when the sensor is activated is a bit messy,
- so lets tidy that up a bit to bring it in line with other drivers.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 100 ++++++++++++++++---------------------
- 1 file changed, 42 insertions(+), 58 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 2c82b6578de9..313bc9177328 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -767,6 +767,42 @@ static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
- standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING);
- }
-
- +static int ov5693_sw_reset(struct ov5693_device *ov5693)
- +{
- + return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_RESET,
- + 0x01);
- +}
- +
- +static int ov5693_sensor_init(struct ov5693_device *ov5693)
- +{
- + struct i2c_client *client = ov5693->client;
- + int ret = 0;
- +
- + ret = ov5693_sw_reset(ov5693);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 reset err.\n");
- + return ret;
- + }
- +
- + ret = ov5693_write_reg_array(client, ov5693_global_setting);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 write register err.\n");
- + return ret;
- + }
- +
- + ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 write register err.\n");
- + return ret;
- + }
- +
- + ret = ov5693_sw_standby(ov5693, true);
- + if (ret)
- + dev_err(&client->dev, "ov5693 stream off error\n");
- +
- + return ret;
- +}
- +
- static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
- {
- gpiod_set_value_cansleep(ov5693->reset, 1);
- @@ -846,6 +882,12 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
- if (ret)
- goto out_unlock;
-
- + ret = ov5693_sensor_init(ov5693);
- + if (ret) {
- + dev_err(&client->dev, "ov5693 sensor init failure\n");
- + goto err_power;
- + }
- +
- if (ov5693->streaming) {
- ret = ov5693_sw_standby(ov5693, false);
- if (ret)
- @@ -944,35 +986,6 @@ static int get_resolution_index(int w, int h)
- return -1;
- }
-
- -/* TODO: remove it. */
- -static int startup(struct v4l2_subdev *sd)
- -{
- - struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- - int ret = 0;
- -
- - ret = ov5693_write_reg(client, OV5693_8BIT,
- - OV5693_SW_RESET, 0x01);
- - if (ret) {
- - dev_err(&client->dev, "ov5693 reset err.\n");
- - return ret;
- - }
- -
- - ret = ov5693_write_reg_array(client, ov5693_global_setting);
- - if (ret) {
- - dev_err(&client->dev, "ov5693 write register err.\n");
- - return ret;
- - }
- -
- - ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
- - if (ret) {
- - dev_err(&client->dev, "ov5693 write register err.\n");
- - return ret;
- - }
- -
- - return ret;
- -}
- -
- static int ov5693_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *format)
- @@ -982,7 +995,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
- int idx;
- - int cnt;
-
- if (format->pad)
- return -EINVAL;
- @@ -1014,34 +1026,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
- goto mutex_unlock;
- }
-
- - for (cnt = 0; cnt < OV5693_POWER_UP_RETRY_NUM; cnt++) {
- - ret = ov5693_sensor_powerup(ov5693);
- - if (ret) {
- - dev_err(&client->dev, "power up failed\n");
- - continue;
- - }
- -
- - ret = startup(sd);
- - if (ret)
- - dev_err(&client->dev, " startup() FAILED!\n");
- - else
- - break;
- - }
- - if (cnt == OV5693_POWER_UP_RETRY_NUM) {
- - dev_err(&client->dev, "power up failed, gave up\n");
- - goto mutex_unlock;
- - }
- -
- - /*
- - * After sensor settings are set to HW, sometimes stream is started.
- - * This would cause ISP timeout because ISP is not ready to receive
- - * data yet. So add stop streaming here.
- - */
- - ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
- - OV5693_STOP_STREAMING);
- - if (ret)
- - dev_warn(&client->dev, "ov5693 stream off err\n");
- -
- mutex_unlock:
- mutex_unlock(&ov5693->lock);
- return ret;
- --
- 2.33.0
- From b0e47f06039b2b73908b044681c9d311edf1fe5e Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Fri, 12 Feb 2021 16:14:04 +0000
- Subject: [PATCH] media: i2c: cleanup macros in ov5693.h
- Lots of orphaned or duplicated macros in this header file. Clean
- those up a bit so it's less ugly.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.h | 89 +-------------------------------------
- 1 file changed, 2 insertions(+), 87 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index b78d3b474a43..6502777eb5f3 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -37,68 +37,23 @@
- */
- #define ENABLE_NON_PREVIEW 1
-
- -#define OV5693_POWER_UP_RETRY_NUM 5
- -
- /* Defines for register writes and register array processing */
- -#define I2C_MSG_LENGTH 0x2
- -#define I2C_RETRY_COUNT 5
- -
- -#define OV5693_FOCAL_LENGTH_NUM 334 /*3.34mm*/
- -#define OV5693_FOCAL_LENGTH_DEM 100
- -#define OV5693_F_NUMBER_DEFAULT_NUM 24
- -#define OV5693_F_NUMBER_DEM 10
- +#define I2C_MSG_LENGTH 0x2
-
- #define MAX_FMTS 1
-
- -/* sensor_mode_data read_mode adaptation */
- -#define OV5693_READ_MODE_BINNING_ON 0x0400
- -#define OV5693_READ_MODE_BINNING_OFF 0x00
- -#define OV5693_INTEGRATION_TIME_MARGIN 8
- -
- -#define OV5693_MAX_EXPOSURE_VALUE 0xFFF1
- -#define OV5693_MAX_GAIN_VALUE 0xFF
- -
- -/*
- - * focal length bits definition:
- - * bits 31-16: numerator, bits 15-0: denominator
- - */
- -#define OV5693_FOCAL_LENGTH_DEFAULT 0x1B70064
- -
- -/*
- - * current f-number bits definition:
- - * bits 31-16: numerator, bits 15-0: denominator
- - */
- -#define OV5693_F_NUMBER_DEFAULT 0x18000a
- -
- -/*
- - * f-number range bits definition:
- - * bits 31-24: max f-number numerator
- - * bits 23-16: max f-number denominator
- - * bits 15-8: min f-number numerator
- - * bits 7-0: min f-number denominator
- - */
- -#define OV5693_F_NUMBER_RANGE 0x180a180a
- #define OV5693_ID 0x5690
-
- -#define OV5693_FINE_INTG_TIME_MIN 0
- -#define OV5693_FINE_INTG_TIME_MAX_MARGIN 0
- -#define OV5693_COARSE_INTG_TIME_MIN 1
- -#define OV5693_COARSE_INTG_TIME_MAX_MARGIN 6
- -
- -#define OV5693_BIN_FACTOR_MAX 4
- /*
- * OV5693 System control registers
- */
- -#define OV5693_SW_SLEEP 0x0100
- #define OV5693_SW_RESET 0x0103
- #define OV5693_SW_STREAM 0x0100
-
- #define OV5693_SC_CMMN_CHIP_ID_H 0x300A
- #define OV5693_SC_CMMN_CHIP_ID_L 0x300B
- -#define OV5693_SC_CMMN_SCCB_ID 0x300C
- #define OV5693_SC_CMMN_SUB_ID 0x302A /* process, version*/
- -/*Bit[7:4] Group control, Bit[3:0] Group ID*/
- -#define OV5693_GROUP_ACCESS 0x3208
- +
- /*
- *Bit[3:0] Bit[19:16] of exposure,
- *remaining 16 bits lies in Reg0x3501&Reg0x3502
- @@ -110,18 +65,6 @@
- #define OV5693_AGC_H 0x350A
- #define OV5693_AGC_L 0x350B /*Bit[7:0] of gain*/
-
- -#define OV5693_HORIZONTAL_START_H 0x3800 /*Bit[11:8]*/
- -#define OV5693_HORIZONTAL_START_L 0x3801 /*Bit[7:0]*/
- -#define OV5693_VERTICAL_START_H 0x3802 /*Bit[11:8]*/
- -#define OV5693_VERTICAL_START_L 0x3803 /*Bit[7:0]*/
- -#define OV5693_HORIZONTAL_END_H 0x3804 /*Bit[11:8]*/
- -#define OV5693_HORIZONTAL_END_L 0x3805 /*Bit[7:0]*/
- -#define OV5693_VERTICAL_END_H 0x3806 /*Bit[11:8]*/
- -#define OV5693_VERTICAL_END_L 0x3807 /*Bit[7:0]*/
- -#define OV5693_HORIZONTAL_OUTPUT_SIZE_H 0x3808 /*Bit[3:0]*/
- -#define OV5693_HORIZONTAL_OUTPUT_SIZE_L 0x3809 /*Bit[7:0]*/
- -#define OV5693_VERTICAL_OUTPUT_SIZE_H 0x380a /*Bit[3:0]*/
- -#define OV5693_VERTICAL_OUTPUT_SIZE_L 0x380b /*Bit[7:0]*/
- /*High 8-bit, and low 8-bit HTS address is 0x380d*/
- #define OV5693_TIMING_HTS_H 0x380C
- /*High 8-bit, and low 8-bit HTS address is 0x380d*/
- @@ -141,34 +84,6 @@
- #define OV5693_START_STREAMING 0x01
- #define OV5693_STOP_STREAMING 0x00
-
- -#define VCM_ADDR 0x0c
- -#define VCM_CODE_MSB 0x04
- -
- -#define OV5693_INVALID_CONFIG 0xffffffff
- -
- -#define OV5693_VCM_SLEW_STEP 0x30F0
- -#define OV5693_VCM_SLEW_STEP_MAX 0x7
- -#define OV5693_VCM_SLEW_STEP_MASK 0x7
- -#define OV5693_VCM_CODE 0x30F2
- -#define OV5693_VCM_SLEW_TIME 0x30F4
- -#define OV5693_VCM_SLEW_TIME_MAX 0xffff
- -#define OV5693_VCM_ENABLE 0x8000
- -
- -#define OV5693_VCM_MAX_FOCUS_NEG -1023
- -#define OV5693_VCM_MAX_FOCUS_POS 1023
- -
- -#define DLC_ENABLE 1
- -#define DLC_DISABLE 0
- -#define VCM_PROTECTION_OFF 0xeca3
- -#define VCM_PROTECTION_ON 0xdc51
- -#define VCM_DEFAULT_S 0x0
- -#define vcm_step_s(a) (u8)(a & 0xf)
- -#define vcm_step_mclk(a) (u8)((a >> 4) & 0x3)
- -#define vcm_dlc_mclk(dlc, mclk) (u16)((dlc << 3) | mclk | 0xa104)
- -#define vcm_tsrc(tsrc) (u16)(tsrc << 3 | 0xf200)
- -#define vcm_val(data, s) (u16)(data << 4 | s)
- -#define DIRECT_VCM vcm_dlc_mclk(0, 0)
- -
- /* Defines for OTP Data Registers */
- #define OV5693_FRAME_OFF_NUM 0x4202
- #define OV5693_OTP_BYTE_MAX 32 //change to 32 as needed by otpdata
- --
- 2.33.0
- From 07688f98d5cf042a675581a0d50543379b280c18 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Fri, 12 Feb 2021 16:19:09 +0000
- Subject: [PATCH] media: i2c: use devm_kzalloc() to initialise ov5693
- There's a memory leak in probe because we're not using devres; swtich
- so that we are.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 313bc9177328..d092ed698eb3 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1425,7 +1425,7 @@ static int ov5693_probe(struct i2c_client *client)
-
- dev_info(&client->dev, "%s() called", __func__);
-
- - ov5693 = kzalloc(sizeof(*ov5693), GFP_KERNEL);
- + ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
- if (!ov5693)
- return -ENOMEM;
-
- --
- 2.33.0
- From 227f50c100aa3939be34d4cee2b2eaedd8e6eb32 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Fri, 12 Feb 2021 16:26:21 +0000
- Subject: [PATCH] media: i2c: Check for supported clk rate in probe
- The ov5693 driver is configured to support a 19.2MHz external clock only.
- Check that we do indeed have that value and if not, exit with -EINVAL.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 8 ++++++++
- drivers/media/i2c/ov5693.h | 2 ++
- 2 files changed, 10 insertions(+)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index d092ed698eb3..8082d37841da 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1421,6 +1421,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
- static int ov5693_probe(struct i2c_client *client)
- {
- struct ov5693_device *ov5693;
- + u32 clk_rate;
- int ret = 0;
-
- dev_info(&client->dev, "%s() called", __func__);
- @@ -1441,6 +1442,13 @@ static int ov5693_probe(struct i2c_client *client)
- return -EINVAL;
- }
-
- + clk_rate = clk_get_rate(ov5693->clk);
- + if (clk_rate != OV5693_XVCLK_FREQ) {
- + dev_err(&client->dev, "Unsupported clk freq %u, expected %u\n",
- + clk_rate, OV5693_XVCLK_FREQ);
- + return -EINVAL;
- + }
- +
- ret = ov5693_configure_gpios(ov5693);
- if (ret)
- goto out_free;
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 6502777eb5f3..0dfbbe9a0ff2 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -100,6 +100,8 @@
- #define OV5693_OTP_READ_ONETIME 16
- #define OV5693_OTP_MODE_READ 1
-
- +#define OV5693_XVCLK_FREQ 19200000
- +
- /* link freq and pixel rate required for IPU3 */
- #define OV5693_LINK_FREQ_400MHZ 400000000
- /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
- --
- 2.33.0
- From 5a0cbf1fec50b3cbcf2ffdfedb8a28c00f15310a Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 13 Feb 2021 23:17:50 +0000
- Subject: [PATCH] media: i2c: Use devres to fetch gpios
- Use devres; it'll simplify error handling through this function
- and probe.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 22 +++++-----------------
- 1 file changed, 5 insertions(+), 17 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 8082d37841da..c580159079d2 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1270,8 +1270,6 @@ static int ov5693_remove(struct i2c_client *client)
-
- dev_info(&client->dev, "%s...\n", __func__);
-
- - gpiod_put(ov5693->reset);
- - gpiod_put(ov5693->indicator_led);
- while (i--)
- regulator_put(ov5693->supplies[i].consumer);
-
- @@ -1372,38 +1370,28 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
-
- static int ov5693_configure_gpios(struct ov5693_device *ov5693)
- {
- - int ret;
- -
- - ov5693->reset = gpiod_get_optional(&ov5693->client->dev, "reset",
- + ov5693->reset = devm_gpiod_get_optional(&ov5693->client->dev, "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(ov5693->reset)) {
- dev_err(&ov5693->client->dev, "Couldn't find reset GPIO\n");
- return PTR_ERR(ov5693->reset);
- }
-
- - ov5693->powerdown = gpiod_get_optional(&ov5693->client->dev, "powerdown",
- + ov5693->powerdown = devm_gpiod_get_optional(&ov5693->client->dev, "powerdown",
- GPIOD_OUT_HIGH);
- if (IS_ERR(ov5693->powerdown)) {
- dev_err(&ov5693->client->dev, "Couldn't find powerdown GPIO\n");
- - ret = PTR_ERR(ov5693->powerdown);
- - goto err_put_reset;
- + return PTR_ERR(ov5693->powerdown);
- }
-
- - ov5693->indicator_led = gpiod_get_optional(&ov5693->client->dev, "indicator-led",
- + ov5693->indicator_led = devm_gpiod_get_optional(&ov5693->client->dev, "indicator-led",
- GPIOD_OUT_HIGH);
- if (IS_ERR(ov5693->indicator_led)) {
- dev_err(&ov5693->client->dev, "Couldn't find indicator-led GPIO\n");
- - ret = PTR_ERR(ov5693->indicator_led);
- - goto err_put_powerdown;
- + return PTR_ERR(ov5693->indicator_led);
- }
-
- return 0;
- -err_put_reset:
- - gpiod_put(ov5693->reset);
- -err_put_powerdown:
- - gpiod_put(ov5693->powerdown);
- -
- - return ret;
- }
-
- static int ov5693_get_regulators(struct ov5693_device *ov5693)
- --
- 2.33.0
- From fb99f6001c7ffec79ece7a941fbc9b85acd9e180 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sat, 13 Feb 2021 23:20:47 +0000
- Subject: [PATCH] media: i2c: Use devres to fetch regulators
- As before, use devres to simplify error handling and driver removal
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 6 +-----
- 1 file changed, 1 insertion(+), 5 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index c580159079d2..9f61b470f8ba 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -1266,13 +1266,9 @@ static int ov5693_remove(struct i2c_client *client)
- {
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - unsigned int i = OV5693_NUM_SUPPLIES;
-
- dev_info(&client->dev, "%s...\n", __func__);
-
- - while (i--)
- - regulator_put(ov5693->supplies[i].consumer);
- -
- v4l2_async_unregister_subdev(sd);
-
- media_entity_cleanup(&ov5693->sd.entity);
- @@ -1401,7 +1397,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
- for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
- ov5693->supplies[i].supply = ov5693_supply_names[i];
-
- - return regulator_bulk_get(&ov5693->client->dev,
- + return devm_regulator_bulk_get(&ov5693->client->dev,
- OV5693_NUM_SUPPLIES,
- ov5693->supplies);
- }
- --
- 2.33.0
- From 89bcec14cf2e9d0ee4dc3938bda2cb8377007007 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 14 Feb 2021 12:39:14 +0000
- Subject: [PATCH] media: i2c: remove debug print
- The exposure configure function has a debug print. It's working fine,
- so bin it.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 37 -------------------------------------
- 1 file changed, 37 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 9f61b470f8ba..622a7ddf4063 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -526,41 +526,6 @@ static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
- }
-
- /* Exposure */
- -
- -static int ov5693_get_exposure(struct ov5693_device *ov5693)
- -{
- - u32 exposure = 0;
- - u16 tmp;
- - int ret = 0;
- -
- - /* get exposure */
- - ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- - OV5693_EXPOSURE_L,
- - &tmp);
- - if (ret)
- - return ret;
- -
- - exposure |= ((tmp >> 4) & 0b1111);
- -
- - ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- - OV5693_EXPOSURE_M,
- - &tmp);
- - if (ret)
- - return ret;
- -
- - exposure |= (tmp << 4);
- - ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
- - OV5693_EXPOSURE_H,
- - &tmp);
- - if (ret)
- - return ret;
- -
- - exposure |= (tmp << 12);
- -
- - printk("exposure set to: %u\n", exposure);
- - return ret;
- -}
- -
- static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
- {
- int ret;
- @@ -571,7 +536,6 @@ static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
- */
- exposure = exposure * 16;
-
- - ov5693_get_exposure(ov5693);
- ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
- OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
- if (ret)
- @@ -586,7 +550,6 @@ static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
- OV5693_EXPOSURE_CTRL_L_REG, OV5693_EXPOSURE_CTRL_L(exposure));
- if (ret)
- return ret;
- - ov5693_get_exposure(ov5693);
-
- return 0;
- }
- --
- 2.33.0
- From 20db0005a194231baa4b02dde2133631072add3c Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 14 Feb 2021 14:32:50 +0000
- Subject: [PATCH] media: i2c: Remove unused resolutions from ov5693
- The list of resolutions in here is really unmaintanably long. For now just
- bin all of the ones that are not part of ov5693_res_video, which is the
- only array of resolutions in use anyway.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.h | 357 +------------------------------------
- 1 file changed, 1 insertion(+), 356 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 0dfbbe9a0ff2..29e6735112da 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -474,34 +474,7 @@ static struct ov5693_reg const ov5693_global_setting[] = {
- };
-
- #if ENABLE_NON_PREVIEW
- -/*
- - * 654x496 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- - */
- -static struct ov5693_reg const ov5693_654x496[] = {
- - {OV5693_8BIT, 0x3501, 0x3d},
- - {OV5693_8BIT, 0x3502, 0x00},
- - {OV5693_8BIT, 0x3708, 0xe6},
- - {OV5693_8BIT, 0x3709, 0xc7},
- - {OV5693_8BIT, 0x3803, 0x00},
- - {OV5693_8BIT, 0x3806, 0x07},
- - {OV5693_8BIT, 0x3807, 0xa3},
- - {OV5693_8BIT, 0x3808, 0x02},
- - {OV5693_8BIT, 0x3809, 0x90},
- - {OV5693_8BIT, 0x380a, 0x01},
- - {OV5693_8BIT, 0x380b, 0xf0},
- - {OV5693_8BIT, 0x380c, 0x0a},
- - {OV5693_8BIT, 0x380d, 0x80},
- - {OV5693_8BIT, 0x380e, 0x07},
- - {OV5693_8BIT, 0x380f, 0xc0},
- - {OV5693_8BIT, 0x3811, 0x08},
- - {OV5693_8BIT, 0x3813, 0x02},
- - {OV5693_8BIT, 0x3814, 0x31},
- - {OV5693_8BIT, 0x3815, 0x31},
- - {OV5693_8BIT, 0x3820, 0x04},
- - {OV5693_8BIT, 0x3821, 0x1f},
- - {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_TOK_TERM, 0, 0}
- -};
- +
-
- /*
- * 1296x976 30fps 17ms VBlanking 2lane 10Bit (Scaling)
- @@ -660,62 +633,10 @@ static struct ov5693_reg const ov5693_736x496[] = {
- };
- #endif
-
- -/*
- -static struct ov5693_reg const ov5693_736x496[] = {
- - {OV5693_8BIT, 0x3501, 0x7b},
- - {OV5693_8BIT, 0x3502, 0x00},
- - {OV5693_8BIT, 0x3708, 0xe6},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3803, 0x00},
- - {OV5693_8BIT, 0x3806, 0x07},
- - {OV5693_8BIT, 0x3807, 0xa3},
- - {OV5693_8BIT, 0x3808, 0x02},
- - {OV5693_8BIT, 0x3809, 0xe0},
- - {OV5693_8BIT, 0x380a, 0x01},
- - {OV5693_8BIT, 0x380b, 0xf0},
- - {OV5693_8BIT, 0x380c, 0x0d},
- - {OV5693_8BIT, 0x380d, 0xb0},
- - {OV5693_8BIT, 0x380e, 0x05},
- - {OV5693_8BIT, 0x380f, 0xf2},
- - {OV5693_8BIT, 0x3811, 0x08},
- - {OV5693_8BIT, 0x3813, 0x02},
- - {OV5693_8BIT, 0x3814, 0x31},
- - {OV5693_8BIT, 0x3815, 0x31},
- - {OV5693_8BIT, 0x3820, 0x01},
- - {OV5693_8BIT, 0x3821, 0x1f},
- - {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_TOK_TERM, 0, 0}
- -};
- -*/
- /*
- * 976x556 30fps 8.8ms VBlanking 2lane 10Bit (Scaling)
- */
- #if ENABLE_NON_PREVIEW
- -static struct ov5693_reg const ov5693_976x556[] = {
- - {OV5693_8BIT, 0x3501, 0x7b},
- - {OV5693_8BIT, 0x3502, 0x00},
- - {OV5693_8BIT, 0x3708, 0xe2},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3803, 0xf0},
- - {OV5693_8BIT, 0x3806, 0x06},
- - {OV5693_8BIT, 0x3807, 0xa7},
- - {OV5693_8BIT, 0x3808, 0x03},
- - {OV5693_8BIT, 0x3809, 0xd0},
- - {OV5693_8BIT, 0x380a, 0x02},
- - {OV5693_8BIT, 0x380b, 0x2C},
- - {OV5693_8BIT, 0x380c, 0x0a},
- - {OV5693_8BIT, 0x380d, 0x80},
- - {OV5693_8BIT, 0x380e, 0x07},
- - {OV5693_8BIT, 0x380f, 0xc0},
- - {OV5693_8BIT, 0x3811, 0x10},
- - {OV5693_8BIT, 0x3813, 0x02},
- - {OV5693_8BIT, 0x3814, 0x11},
- - {OV5693_8BIT, 0x3815, 0x11},
- - {OV5693_8BIT, 0x3820, 0x00},
- - {OV5693_8BIT, 0x3821, 0x1e},
- - {OV5693_8BIT, 0x5002, 0x80},
- - {OV5693_TOK_TERM, 0, 0}
- -};
-
- /*DS from 2624x1492*/
- static struct ov5693_reg const ov5693_1296x736[] = {
- @@ -782,40 +703,6 @@ static struct ov5693_reg const ov5693_1636p_30fps[] = {
- };
- #endif
-
- -static struct ov5693_reg const ov5693_1616x1216_30fps[] = {
- - {OV5693_8BIT, 0x3501, 0x7b},
- - {OV5693_8BIT, 0x3502, 0x80},
- - {OV5693_8BIT, 0x3708, 0xe2},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3800, 0x00}, /*{3800,3801} Array X start*/
- - {OV5693_8BIT, 0x3801, 0x08}, /* 04 //{3800,3801} Array X start*/
- - {OV5693_8BIT, 0x3802, 0x00}, /*{3802,3803} Array Y start*/
- - {OV5693_8BIT, 0x3803, 0x04}, /* 00 //{3802,3803} Array Y start*/
- - {OV5693_8BIT, 0x3804, 0x0a}, /*{3804,3805} Array X end*/
- - {OV5693_8BIT, 0x3805, 0x37}, /* 3b //{3804,3805} Array X end*/
- - {OV5693_8BIT, 0x3806, 0x07}, /*{3806,3807} Array Y end*/
- - {OV5693_8BIT, 0x3807, 0x9f}, /* a3 //{3806,3807} Array Y end*/
- - {OV5693_8BIT, 0x3808, 0x06}, /*{3808,3809} Final output H size*/
- - {OV5693_8BIT, 0x3809, 0x50}, /*{3808,3809} Final output H size*/
- - {OV5693_8BIT, 0x380a, 0x04}, /*{380a,380b} Final output V size*/
- - {OV5693_8BIT, 0x380b, 0xc0}, /*{380a,380b} Final output V size*/
- - {OV5693_8BIT, 0x380c, 0x0a}, /*{380c,380d} HTS*/
- - {OV5693_8BIT, 0x380d, 0x80}, /*{380c,380d} HTS*/
- - {OV5693_8BIT, 0x380e, 0x07}, /*{380e,380f} VTS*/
- - {OV5693_8BIT, 0x380f, 0xc0}, /* bc //{380e,380f} VTS*/
- - {OV5693_8BIT, 0x3810, 0x00}, /*{3810,3811} windowing X offset*/
- - {OV5693_8BIT, 0x3811, 0x10}, /*{3810,3811} windowing X offset*/
- - {OV5693_8BIT, 0x3812, 0x00}, /*{3812,3813} windowing Y offset*/
- - {OV5693_8BIT, 0x3813, 0x06}, /*{3812,3813} windowing Y offset*/
- - {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/
- - {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/
- - {OV5693_8BIT, 0x3820, 0x00}, /*FLIP/Binnning control*/
- - {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/
- - {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_8BIT, 0x5041, 0x84},
- - {OV5693_TOK_TERM, 0, 0}
- -};
- -
- /*
- * 1940x1096 30fps 8.8ms VBlanking 2lane 10bit (Scaling)
- */
- @@ -878,37 +765,6 @@ static struct ov5693_reg const ov5693_2592x1456_30fps[] = {
- };
- #endif
-
- -static struct ov5693_reg const ov5693_2576x1456_30fps[] = {
- - {OV5693_8BIT, 0x3501, 0x7b},
- - {OV5693_8BIT, 0x3502, 0x00},
- - {OV5693_8BIT, 0x3708, 0xe2},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3800, 0x00},
- - {OV5693_8BIT, 0x3801, 0x00},
- - {OV5693_8BIT, 0x3802, 0x00},
- - {OV5693_8BIT, 0x3803, 0xf0},
- - {OV5693_8BIT, 0x3804, 0x0a},
- - {OV5693_8BIT, 0x3805, 0x3f},
- - {OV5693_8BIT, 0x3806, 0x06},
- - {OV5693_8BIT, 0x3807, 0xa4},
- - {OV5693_8BIT, 0x3808, 0x0a},
- - {OV5693_8BIT, 0x3809, 0x10},
- - {OV5693_8BIT, 0x380a, 0x05},
- - {OV5693_8BIT, 0x380b, 0xb0},
- - {OV5693_8BIT, 0x380c, 0x0a},
- - {OV5693_8BIT, 0x380d, 0x80},
- - {OV5693_8BIT, 0x380e, 0x07},
- - {OV5693_8BIT, 0x380f, 0xc0},
- - {OV5693_8BIT, 0x3811, 0x18},
- - {OV5693_8BIT, 0x3813, 0x00},
- - {OV5693_8BIT, 0x3814, 0x11},
- - {OV5693_8BIT, 0x3815, 0x11},
- - {OV5693_8BIT, 0x3820, 0x00},
- - {OV5693_8BIT, 0x3821, 0x1e},
- - {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_TOK_TERM, 0, 0}
- -};
- -
- /*
- * 2592x1944 30fps 0.6ms VBlanking 2lane 10Bit
- */
- @@ -940,49 +796,6 @@ static struct ov5693_reg const ov5693_2592x1944_30fps[] = {
- };
- #endif
-
- -/*
- - * 11:9 Full FOV Output, expected FOV Res: 2346x1920
- - * ISP Effect Res: 1408x1152
- - * Sensor out: 1424x1168, DS From: 2380x1952
- - *
- - * WA: Left Offset: 8, Hor scal: 64
- - */
- -#if ENABLE_NON_PREVIEW
- -static struct ov5693_reg const ov5693_1424x1168_30fps[] = {
- - {OV5693_8BIT, 0x3501, 0x3b}, /* long exposure[15:8] */
- - {OV5693_8BIT, 0x3502, 0x80}, /* long exposure[7:0] */
- - {OV5693_8BIT, 0x3708, 0xe2},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3800, 0x00}, /* TIMING_X_ADDR_START */
- - {OV5693_8BIT, 0x3801, 0x50}, /* 80 */
- - {OV5693_8BIT, 0x3802, 0x00}, /* TIMING_Y_ADDR_START */
- - {OV5693_8BIT, 0x3803, 0x02}, /* 2 */
- - {OV5693_8BIT, 0x3804, 0x09}, /* TIMING_X_ADDR_END */
- - {OV5693_8BIT, 0x3805, 0xdd}, /* 2525 */
- - {OV5693_8BIT, 0x3806, 0x07}, /* TIMING_Y_ADDR_END */
- - {OV5693_8BIT, 0x3807, 0xa1}, /* 1953 */
- - {OV5693_8BIT, 0x3808, 0x05}, /* TIMING_X_OUTPUT_SIZE */
- - {OV5693_8BIT, 0x3809, 0x90}, /* 1424 */
- - {OV5693_8BIT, 0x380a, 0x04}, /* TIMING_Y_OUTPUT_SIZE */
- - {OV5693_8BIT, 0x380b, 0x90}, /* 1168 */
- - {OV5693_8BIT, 0x380c, 0x0a}, /* TIMING_HTS */
- - {OV5693_8BIT, 0x380d, 0x80},
- - {OV5693_8BIT, 0x380e, 0x07}, /* TIMING_VTS */
- - {OV5693_8BIT, 0x380f, 0xc0},
- - {OV5693_8BIT, 0x3810, 0x00}, /* TIMING_ISP_X_WIN */
- - {OV5693_8BIT, 0x3811, 0x02}, /* 2 */
- - {OV5693_8BIT, 0x3812, 0x00}, /* TIMING_ISP_Y_WIN */
- - {OV5693_8BIT, 0x3813, 0x00}, /* 0 */
- - {OV5693_8BIT, 0x3814, 0x11}, /* TIME_X_INC */
- - {OV5693_8BIT, 0x3815, 0x11}, /* TIME_Y_INC */
- - {OV5693_8BIT, 0x3820, 0x00},
- - {OV5693_8BIT, 0x3821, 0x1e},
- - {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
- - {OV5693_TOK_TERM, 0, 0}
- -};
- -#endif
- -
- /*
- * 3:2 Full FOV Output, expected FOV Res: 2560x1706
- * ISP Effect Res: 720x480
- @@ -1022,173 +835,6 @@ static struct ov5693_reg const ov5693_736x496_30fps[] = {
- {OV5693_TOK_TERM, 0, 0}
- };
-
- -static struct ov5693_reg const ov5693_2576x1936_30fps[] = {
- - {OV5693_8BIT, 0x3501, 0x7b},
- - {OV5693_8BIT, 0x3502, 0x00},
- - {OV5693_8BIT, 0x3708, 0xe2},
- - {OV5693_8BIT, 0x3709, 0xc3},
- - {OV5693_8BIT, 0x3803, 0x00},
- - {OV5693_8BIT, 0x3806, 0x07},
- - {OV5693_8BIT, 0x3807, 0xa3},
- - {OV5693_8BIT, 0x3808, 0x0a},
- - {OV5693_8BIT, 0x3809, 0x10},
- - {OV5693_8BIT, 0x380a, 0x07},
- - {OV5693_8BIT, 0x380b, 0x90},
- - {OV5693_8BIT, 0x380c, 0x0a},
- - {OV5693_8BIT, 0x380d, 0x80},
- - {OV5693_8BIT, 0x380e, 0x07},
- - {OV5693_8BIT, 0x380f, 0xc0},
- - {OV5693_8BIT, 0x3811, 0x18},
- - {OV5693_8BIT, 0x3813, 0x00},
- - {OV5693_8BIT, 0x3814, 0x11},
- - {OV5693_8BIT, 0x3815, 0x11},
- - {OV5693_8BIT, 0x3820, 0x00},
- - {OV5693_8BIT, 0x3821, 0x1e},
- - {OV5693_8BIT, 0x5002, 0x00},
- - {OV5693_TOK_TERM, 0, 0}
- -};
- -
- -static struct ov5693_resolution ov5693_res_preview[] = {
- - {
- - .desc = "ov5693_736x496_30fps",
- - .width = 736,
- - .height = 496,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_736x496_30fps,
- - },
- - {
- - .desc = "ov5693_1616x1216_30fps",
- - .width = 1616,
- - .height = 1216,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_1616x1216_30fps,
- - },
- - {
- - .desc = "ov5693_5M_30fps",
- - .width = 2576,
- - .height = 1456,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_2576x1456_30fps,
- - },
- - {
- - .desc = "ov5693_5M_30fps",
- - .width = 2576,
- - .height = 1936,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_2576x1936_30fps,
- - },
- -};
- -
- -#define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
- -
- -/*
- - * Disable non-preview configurations until the configuration selection is
- - * improved.
- - */
- -#if ENABLE_NON_PREVIEW
- -struct ov5693_resolution ov5693_res_still[] = {
- - {
- - .desc = "ov5693_736x496_30fps",
- - .width = 736,
- - .height = 496,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_736x496_30fps,
- - },
- - {
- - .desc = "ov5693_1424x1168_30fps",
- - .width = 1424,
- - .height = 1168,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_1424x1168_30fps,
- - },
- - {
- - .desc = "ov5693_1616x1216_30fps",
- - .width = 1616,
- - .height = 1216,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_1616x1216_30fps,
- - },
- - {
- - .desc = "ov5693_5M_30fps",
- - .width = 2592,
- - .height = 1456,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_2592x1456_30fps,
- - },
- - {
- - .desc = "ov5693_5M_30fps",
- - .width = 2592,
- - .height = 1944,
- - .pix_clk_freq = 160,
- - .fps = 30,
- - .used = 0,
- - .pixels_per_line = 2688,
- - .lines_per_frame = 1984,
- - .bin_factor_x = 1,
- - .bin_factor_y = 1,
- - .bin_mode = 0,
- - .regs = ov5693_2592x1944_30fps,
- - },
- -};
- -
- -#define N_RES_STILL (ARRAY_SIZE(ov5693_res_still))
- -
- struct ov5693_resolution ov5693_res_video[] = {
- {
- .desc = "ov5693_736x496_30fps",
- @@ -1343,4 +989,3 @@ struct ov5693_resolution ov5693_res_video[] = {
-
- static struct ov5693_resolution *ov5693_res = ov5693_res_video;
- static unsigned long N_RES = N_RES_VIDEO;
- -#endif
- --
- 2.33.0
- From 4ddf83de46c2815e6cf66cc2121558ccba73c432 Mon Sep 17 00:00:00 2001
- From: Daniel Scally <djrscally@gmail.com>
- Date: Sun, 14 Feb 2021 14:45:58 +0000
- Subject: [PATCH] media: i2c: update set_fmt() for ov5693
- The set_fmt() function is a bit messy still, using home grown solutions to
- find the closest supported resolution instead of the v4l2 helpers. It also
- fails to update control ranges to account for the new mode (though this is
- moot currently as they're all the same, but the probably shouldn't be).
- Fix it up a little.
- Signed-off-by: Daniel Scally <djrscally@gmail.com>
- Patchset: cameras
- ---
- drivers/media/i2c/ov5693.c | 148 ++++++++++---------------------------
- drivers/media/i2c/ov5693.h | 5 +-
- 2 files changed, 40 insertions(+), 113 deletions(-)
- diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
- index 622a7ddf4063..09c84006d5c9 100644
- --- a/drivers/media/i2c/ov5693.c
- +++ b/drivers/media/i2c/ov5693.c
- @@ -753,7 +753,7 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693)
- return ret;
- }
-
- - ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
- + ret = ov5693_write_reg_array(client, ov5693->mode->regs);
- if (ret) {
- dev_err(&client->dev, "ov5693 write register err.\n");
- return ret;
- @@ -866,128 +866,56 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
- return ret;
- }
-
- -/*
- - * distance - calculate the distance
- - * @res: resolution
- - * @w: width
- - * @h: height
- - *
- - * Get the gap between res_w/res_h and w/h.
- - * distance = (res_w/res_h - w/h) / (w/h) * 8192
- - * res->width/height smaller than w/h wouldn't be considered.
- - * The gap of ratio larger than 1/8 wouldn't be considered.
- - * Returns the value of gap or -1 if fail.
- - */
- -#define LARGEST_ALLOWED_RATIO_MISMATCH 1024
- -static int distance(struct ov5693_resolution *res, u32 w, u32 h)
- -{
- - int ratio;
- - int distance;
- -
- - if (w == 0 || h == 0 ||
- - res->width < w || res->height < h)
- - return -1;
- -
- - ratio = res->width << 13;
- - ratio /= w;
- - ratio *= h;
- - ratio /= res->height;
- -
- - distance = abs(ratio - 8192);
- -
- - if (distance > LARGEST_ALLOWED_RATIO_MISMATCH)
- - return -1;
- -
- - return distance;
- -}
- -
- -/* Return the nearest higher resolution index
- - * Firstly try to find the approximate aspect ratio resolution
- - * If we find multiple same AR resolutions, choose the
- - * minimal size.
- - */
- -static int nearest_resolution_index(int w, int h)
- -{
- - int i;
- - int idx = -1;
- - int dist;
- - int min_dist = INT_MAX;
- - int min_res_w = INT_MAX;
- - struct ov5693_resolution *tmp_res = NULL;
- -
- - for (i = 0; i < N_RES; i++) {
- - tmp_res = &ov5693_res[i];
- - dist = distance(tmp_res, w, h);
- - if (dist == -1)
- - continue;
- - if (dist < min_dist) {
- - min_dist = dist;
- - idx = i;
- - min_res_w = ov5693_res[i].width;
- - continue;
- - }
- - if (dist == min_dist && ov5693_res[i].width < min_res_w)
- - idx = i;
- - }
- -
- - return idx;
- -}
- -
- -static int get_resolution_index(int w, int h)
- -{
- - int i;
- -
- - for (i = 0; i < N_RES; i++) {
- - if (w != ov5693_res[i].width)
- - continue;
- - if (h != ov5693_res[i].height)
- - continue;
- -
- - return i;
- - }
- -
- - return -1;
- -}
- -
- static int ov5693_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *format)
- {
- - struct v4l2_mbus_framefmt *fmt = &format->format;
- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
- - struct i2c_client *client = v4l2_get_subdevdata(sd);
- + const struct ov5693_resolution *mode;
- + int exposure_max;
- int ret = 0;
- - int idx;
- + int hblank;
-
- if (format->pad)
- return -EINVAL;
- - if (!fmt)
- - return -EINVAL;
-
- mutex_lock(&ov5693->lock);
- - idx = nearest_resolution_index(fmt->width, fmt->height);
- - if (idx == -1) {
- - /* return the largest resolution */
- - fmt->width = ov5693_res[N_RES - 1].width;
- - fmt->height = ov5693_res[N_RES - 1].height;
- - } else {
- - fmt->width = ov5693_res[idx].width;
- - fmt->height = ov5693_res[idx].height;
- - }
-
- - fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
- + mode = v4l2_find_nearest_size(ov5693_res_video, ARRAY_SIZE(ov5693_res_video),
- + width, height, format->format.width,
- + format->format.height);
- +
- + if (!mode)
- + return -EINVAL;
- +
- + format->format.width = mode->width;
- + format->format.height = mode->height;
- + format->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
- +
- if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- - cfg->try_fmt = *fmt;
- - ret = 0;
- + *v4l2_subdev_get_try_format(sd, cfg, format->pad) = format->format;
- goto mutex_unlock;
- }
-
- - ov5693->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- - if (ov5693->fmt_idx == -1) {
- - dev_err(&client->dev, "get resolution fail\n");
- - ret = -EINVAL;
- - goto mutex_unlock;
- - }
- + ov5693->mode = mode;
- +
- + /* Update limits and set FPS to default */
- + __v4l2_ctrl_modify_range(ov5693->ctrls.vblank,
- + mode->lines_per_frame - mode->height,
- + OV5693_TIMING_MAX_VTS - mode->height,
- + 1, mode->lines_per_frame - mode->height);
- + __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank,
- + mode->lines_per_frame - mode->height);
- +
- + hblank = mode->pixels_per_line - mode->width;
- + __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1, hblank);
- +
- + exposure_max = mode->lines_per_frame - 8;
- + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
- + ov5693->ctrls.exposure->minimum, exposure_max,
- + ov5693->ctrls.exposure->step,
- + ov5693->ctrls.exposure->val < exposure_max ?
- + ov5693->ctrls.exposure->val : exposure_max);
-
- mutex_unlock:
- mutex_unlock(&ov5693->lock);
- @@ -1056,8 +984,8 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
- if (!fmt)
- return -EINVAL;
-
- - fmt->width = ov5693_res[ov5693->fmt_idx].width;
- - fmt->height = ov5693_res[ov5693->fmt_idx].height;
- + fmt->width = ov5693->mode->width;
- + fmt->height = ov5693->mode->height;
- fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-
- return 0;
- @@ -1174,7 +1102,7 @@ static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
-
- interval->interval.numerator = 1;
- - interval->interval.denominator = ov5693_res[ov5693->fmt_idx].fps;
- + interval->interval.denominator = ov5693->mode->fps;
-
- return 0;
- }
- diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
- index 29e6735112da..0377853f8b2b 100644
- --- a/drivers/media/i2c/ov5693.h
- +++ b/drivers/media/i2c/ov5693.h
- @@ -127,8 +127,8 @@ struct ov5693_resolution {
- u8 *desc;
- const struct ov5693_reg *regs;
- int res;
- - int width;
- - int height;
- + u32 width;
- + u32 height;
- int fps;
- int pix_clk_freq;
- u16 pixels_per_line;
- @@ -178,7 +178,6 @@ struct ov5693_device {
- struct camera_sensor_platform_data *platform_data;
- ktime_t timestamp_t_focus_abs;
- int vt_pix_clk_freq_mhz;
- - int fmt_idx;
- int run_mode;
- int otp_size;
- u8 *otp_data;
- --
- 2.33.0
|