0009-cameras.patch 176 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713
  1. From 2a96c94a25ca756a6056d6c89e492cc2b671bbd4 Mon Sep 17 00:00:00 2001
  2. From: Daniel Scally <djrscally@gmail.com>
  3. Date: Thu, 3 Jun 2021 23:40:02 +0100
  4. Subject: [PATCH] ACPI: scan: Extend acpi_walk_dep_device_list()
  5. The acpi_walk_dep_device_list() function is not as generic as its
  6. name implies, serving only to decrement the dependency count for each
  7. dependent device of the input.
  8. Extend it to accept a callback which can be applied to all the
  9. dependencies in acpi_dep_list.
  10. Replace all existing calls to the function with calls to a wrapper,
  11. passing a callback that applies the same dependency reduction.
  12. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  13. Acked-by: Maximilian Luz <luzmaximilian@gmail.com> # for platform/surface parts
  14. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  15. [ rjw: Changelog edits ]
  16. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  17. Patchset: cameras
  18. ---
  19. drivers/acpi/ec.c | 2 +-
  20. drivers/acpi/pmic/intel_pmic_chtdc_ti.c | 2 +-
  21. drivers/acpi/scan.c | 69 ++++++++++++++-----
  22. drivers/gpio/gpiolib-acpi.c | 10 +--
  23. drivers/i2c/i2c-core-acpi.c | 8 +--
  24. drivers/platform/surface/aggregator/core.c | 6 +-
  25. drivers/platform/surface/surface3_power.c | 22 +++---
  26. .../platform/surface/surface_acpi_notify.c | 7 +-
  27. include/acpi/acpi_bus.h | 7 ++
  28. include/linux/acpi.h | 4 +-
  29. 10 files changed, 90 insertions(+), 47 deletions(-)
  30. diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
  31. index 87c3b4a099b9..e629e891d1bb 100644
  32. --- a/drivers/acpi/ec.c
  33. +++ b/drivers/acpi/ec.c
  34. @@ -1629,7 +1629,7 @@ static int acpi_ec_add(struct acpi_device *device)
  35. WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
  36. /* Reprobe devices depending on the EC */
  37. - acpi_walk_dep_device_list(ec->handle);
  38. + acpi_dev_clear_dependencies(device);
  39. acpi_handle_debug(ec->handle, "enumerated.\n");
  40. return 0;
  41. diff --git a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c
  42. index a5101b07611a..fef7831d0d63 100644
  43. --- a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c
  44. +++ b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c
  45. @@ -117,7 +117,7 @@ static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev)
  46. return err;
  47. /* Re-enumerate devices depending on PMIC */
  48. - acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent));
  49. + acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent));
  50. return 0;
  51. }
  52. diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
  53. index 438df8da6d12..607aeea9a210 100644
  54. --- a/drivers/acpi/scan.c
  55. +++ b/drivers/acpi/scan.c
  56. @@ -47,12 +47,6 @@ static DEFINE_MUTEX(acpi_hp_context_lock);
  57. */
  58. static u64 spcr_uart_addr;
  59. -struct acpi_dep_data {
  60. - struct list_head node;
  61. - acpi_handle supplier;
  62. - acpi_handle consumer;
  63. -};
  64. -
  65. void acpi_scan_lock_acquire(void)
  66. {
  67. mutex_lock(&acpi_scan_lock);
  68. @@ -2107,30 +2101,69 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
  69. device->handler->hotplug.notify_online(device);
  70. }
  71. -void acpi_walk_dep_device_list(acpi_handle handle)
  72. +static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
  73. {
  74. - struct acpi_dep_data *dep, *tmp;
  75. struct acpi_device *adev;
  76. + acpi_bus_get_device(dep->consumer, &adev);
  77. +
  78. + if (adev) {
  79. + adev->dep_unmet--;
  80. + if (!adev->dep_unmet)
  81. + acpi_bus_attach(adev, true);
  82. + }
  83. +
  84. + list_del(&dep->node);
  85. + kfree(dep);
  86. +
  87. + return 0;
  88. +}
  89. +
  90. +/**
  91. + * acpi_walk_dep_device_list - Apply a callback to every entry in acpi_dep_list
  92. + * @handle: The ACPI handle of the supplier device
  93. + * @callback: Pointer to the callback function to apply
  94. + * @data: Pointer to some data to pass to the callback
  95. + *
  96. + * The return value of the callback determines this function's behaviour. If 0
  97. + * is returned we continue to iterate over acpi_dep_list. If a positive value
  98. + * is returned then the loop is broken but this function returns 0. If a
  99. + * negative value is returned by the callback then the loop is broken and that
  100. + * value is returned as the final error.
  101. + */
  102. +int acpi_walk_dep_device_list(acpi_handle handle,
  103. + int (*callback)(struct acpi_dep_data *, void *),
  104. + void *data)
  105. +{
  106. + struct acpi_dep_data *dep, *tmp;
  107. + int ret;
  108. +
  109. mutex_lock(&acpi_dep_list_lock);
  110. list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
  111. if (dep->supplier == handle) {
  112. - acpi_bus_get_device(dep->consumer, &adev);
  113. -
  114. - if (adev) {
  115. - adev->dep_unmet--;
  116. - if (!adev->dep_unmet)
  117. - acpi_bus_attach(adev, true);
  118. - }
  119. -
  120. - list_del(&dep->node);
  121. - kfree(dep);
  122. + ret = callback(dep, data);
  123. + if (ret)
  124. + break;
  125. }
  126. }
  127. mutex_unlock(&acpi_dep_list_lock);
  128. +
  129. + return ret > 0 ? 0 : ret;
  130. }
  131. EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);
  132. +/**
  133. + * acpi_dev_clear_dependencies - Inform consumers that the device is now active
  134. + * @supplier: Pointer to the supplier &struct acpi_device
  135. + *
  136. + * Clear dependencies on the given device.
  137. + */
  138. +void acpi_dev_clear_dependencies(struct acpi_device *supplier)
  139. +{
  140. + acpi_walk_dep_device_list(supplier->handle, acpi_scan_clear_dep, NULL);
  141. +}
  142. +EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
  143. +
  144. /**
  145. * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
  146. * @handle: Root of the namespace scope to scan.
  147. diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
  148. index 3ef22a3c104d..5b4111e4be3f 100644
  149. --- a/drivers/gpio/gpiolib-acpi.c
  150. +++ b/drivers/gpio/gpiolib-acpi.c
  151. @@ -1233,14 +1233,14 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip)
  152. void acpi_gpiochip_add(struct gpio_chip *chip)
  153. {
  154. struct acpi_gpio_chip *acpi_gpio;
  155. - acpi_handle handle;
  156. + struct acpi_device *adev;
  157. acpi_status status;
  158. if (!chip || !chip->parent)
  159. return;
  160. - handle = ACPI_HANDLE(chip->parent);
  161. - if (!handle)
  162. + adev = ACPI_COMPANION(chip->parent);
  163. + if (!adev)
  164. return;
  165. acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
  166. @@ -1254,7 +1254,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
  167. INIT_LIST_HEAD(&acpi_gpio->events);
  168. INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry);
  169. - status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
  170. + status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio);
  171. if (ACPI_FAILURE(status)) {
  172. dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n");
  173. kfree(acpi_gpio);
  174. @@ -1263,7 +1263,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
  175. acpi_gpiochip_request_regions(acpi_gpio);
  176. acpi_gpiochip_scan_gpios(acpi_gpio);
  177. - acpi_walk_dep_device_list(handle);
  178. + acpi_dev_clear_dependencies(adev);
  179. }
  180. void acpi_gpiochip_remove(struct gpio_chip *chip)
  181. diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
  182. index deceed0d76c6..13eb5ac82729 100644
  183. --- a/drivers/i2c/i2c-core-acpi.c
  184. +++ b/drivers/i2c/i2c-core-acpi.c
  185. @@ -259,8 +259,8 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
  186. */
  187. void i2c_acpi_register_devices(struct i2c_adapter *adap)
  188. {
  189. + struct acpi_device *adev;
  190. acpi_status status;
  191. - acpi_handle handle;
  192. if (!has_acpi_companion(&adap->dev))
  193. return;
  194. @@ -275,11 +275,11 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
  195. if (!adap->dev.parent)
  196. return;
  197. - handle = ACPI_HANDLE(adap->dev.parent);
  198. - if (!handle)
  199. + adev = ACPI_COMPANION(adap->dev.parent);
  200. + if (!adev)
  201. return;
  202. - acpi_walk_dep_device_list(handle);
  203. + acpi_dev_clear_dependencies(adev);
  204. }
  205. static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
  206. diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c
  207. index 5d780e55f4a1..279d9df19c01 100644
  208. --- a/drivers/platform/surface/aggregator/core.c
  209. +++ b/drivers/platform/surface/aggregator/core.c
  210. @@ -621,8 +621,8 @@ static const struct acpi_gpio_mapping ssam_acpi_gpios[] = {
  211. static int ssam_serial_hub_probe(struct serdev_device *serdev)
  212. {
  213. + struct acpi_device *ssh = ACPI_COMPANION(&serdev->dev);
  214. struct ssam_controller *ctrl;
  215. - acpi_handle *ssh = ACPI_HANDLE(&serdev->dev);
  216. acpi_status astatus;
  217. int status;
  218. @@ -652,7 +652,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
  219. if (status)
  220. goto err_devopen;
  221. - astatus = ssam_serdev_setup_via_acpi(ssh, serdev);
  222. + astatus = ssam_serdev_setup_via_acpi(ssh->handle, serdev);
  223. if (ACPI_FAILURE(astatus)) {
  224. status = -ENXIO;
  225. goto err_devinit;
  226. @@ -706,7 +706,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
  227. * For now let's thus default power/wakeup to false.
  228. */
  229. device_set_wakeup_capable(&serdev->dev, true);
  230. - acpi_walk_dep_device_list(ssh);
  231. + acpi_dev_clear_dependencies(ssh);
  232. return 0;
  233. diff --git a/drivers/platform/surface/surface3_power.c b/drivers/platform/surface/surface3_power.c
  234. index cc4f9cba6856..dea82aa1abd4 100644
  235. --- a/drivers/platform/surface/surface3_power.c
  236. +++ b/drivers/platform/surface/surface3_power.c
  237. @@ -446,12 +446,12 @@ mshw0011_space_handler(u32 function, acpi_physical_address command,
  238. static int mshw0011_install_space_handler(struct i2c_client *client)
  239. {
  240. - acpi_handle handle;
  241. + struct acpi_device *adev;
  242. struct mshw0011_handler_data *data;
  243. acpi_status status;
  244. - handle = ACPI_HANDLE(&client->dev);
  245. - if (!handle)
  246. + adev = ACPI_COMPANION(&client->dev);
  247. + if (!adev)
  248. return -ENODEV;
  249. data = kzalloc(sizeof(struct mshw0011_handler_data),
  250. @@ -460,25 +460,25 @@ static int mshw0011_install_space_handler(struct i2c_client *client)
  251. return -ENOMEM;
  252. data->client = client;
  253. - status = acpi_bus_attach_private_data(handle, (void *)data);
  254. + status = acpi_bus_attach_private_data(adev->handle, (void *)data);
  255. if (ACPI_FAILURE(status)) {
  256. kfree(data);
  257. return -ENOMEM;
  258. }
  259. - status = acpi_install_address_space_handler(handle,
  260. - ACPI_ADR_SPACE_GSBUS,
  261. - &mshw0011_space_handler,
  262. - NULL,
  263. - data);
  264. + status = acpi_install_address_space_handler(adev->handle,
  265. + ACPI_ADR_SPACE_GSBUS,
  266. + &mshw0011_space_handler,
  267. + NULL,
  268. + data);
  269. if (ACPI_FAILURE(status)) {
  270. dev_err(&client->dev, "Error installing i2c space handler\n");
  271. - acpi_bus_detach_private_data(handle);
  272. + acpi_bus_detach_private_data(adev->handle);
  273. kfree(data);
  274. return -ENOMEM;
  275. }
  276. - acpi_walk_dep_device_list(handle);
  277. + acpi_dev_clear_dependencies(adev);
  278. return 0;
  279. }
  280. diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c
  281. index ef9c1f8e8336..8339988d95c1 100644
  282. --- a/drivers/platform/surface/surface_acpi_notify.c
  283. +++ b/drivers/platform/surface/surface_acpi_notify.c
  284. @@ -798,7 +798,7 @@ static int san_consumer_links_setup(struct platform_device *pdev)
  285. static int san_probe(struct platform_device *pdev)
  286. {
  287. - acpi_handle san = ACPI_HANDLE(&pdev->dev);
  288. + struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
  289. struct ssam_controller *ctrl;
  290. struct san_data *data;
  291. acpi_status astatus;
  292. @@ -821,7 +821,8 @@ static int san_probe(struct platform_device *pdev)
  293. platform_set_drvdata(pdev, data);
  294. - astatus = acpi_install_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
  295. + astatus = acpi_install_address_space_handler(san->handle,
  296. + ACPI_ADR_SPACE_GSBUS,
  297. &san_opreg_handler, NULL,
  298. &data->info);
  299. if (ACPI_FAILURE(astatus))
  300. @@ -835,7 +836,7 @@ static int san_probe(struct platform_device *pdev)
  301. if (status)
  302. goto err_install_dev;
  303. - acpi_walk_dep_device_list(san);
  304. + acpi_dev_clear_dependencies(san);
  305. return 0;
  306. err_install_dev:
  307. diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
  308. index 394eb42d0ec1..b934c77b735f 100644
  309. --- a/include/acpi/acpi_bus.h
  310. +++ b/include/acpi/acpi_bus.h
  311. @@ -280,6 +280,12 @@ struct acpi_device_power {
  312. struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
  313. };
  314. +struct acpi_dep_data {
  315. + struct list_head node;
  316. + acpi_handle supplier;
  317. + acpi_handle consumer;
  318. +};
  319. +
  320. /* Performance Management */
  321. struct acpi_device_perf_flags {
  322. @@ -685,6 +691,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
  323. bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
  324. +void acpi_dev_clear_dependencies(struct acpi_device *supplier);
  325. struct acpi_device *
  326. acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
  327. struct acpi_device *
  328. diff --git a/include/linux/acpi.h b/include/linux/acpi.h
  329. index c60745f657e9..170b9bebdb2b 100644
  330. --- a/include/linux/acpi.h
  331. +++ b/include/linux/acpi.h
  332. @@ -666,7 +666,9 @@ extern bool acpi_driver_match_device(struct device *dev,
  333. const struct device_driver *drv);
  334. int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
  335. int acpi_device_modalias(struct device *, char *, int);
  336. -void acpi_walk_dep_device_list(acpi_handle handle);
  337. +int acpi_walk_dep_device_list(acpi_handle handle,
  338. + int (*callback)(struct acpi_dep_data *, void *),
  339. + void *data);
  340. struct platform_device *acpi_create_platform_device(struct acpi_device *,
  341. struct property_entry *);
  342. --
  343. 2.33.0
  344. From 49022760499bae8d2971805281842cf844271b05 Mon Sep 17 00:00:00 2001
  345. From: Daniel Scally <djrscally@gmail.com>
  346. Date: Thu, 3 Jun 2021 23:40:03 +0100
  347. Subject: [PATCH] ACPI: scan: Add function to fetch dependent of ACPI device
  348. In some ACPI tables we encounter, devices use the _DEP method to assert
  349. a dependence on other ACPI devices as opposed to the OpRegions that the
  350. specification intends.
  351. We need to be able to find those devices "from" the dependee, so add
  352. a callback and a wrapper to walk over the acpi_dep_list and return
  353. the dependent ACPI device.
  354. Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
  355. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  356. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  357. Patchset: cameras
  358. ---
  359. drivers/acpi/scan.c | 35 +++++++++++++++++++++++++++++++++++
  360. include/acpi/acpi_bus.h | 1 +
  361. 2 files changed, 36 insertions(+)
  362. diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
  363. index 607aeea9a210..7f36295579ce 100644
  364. --- a/drivers/acpi/scan.c
  365. +++ b/drivers/acpi/scan.c
  366. @@ -2101,6 +2101,20 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
  367. device->handler->hotplug.notify_online(device);
  368. }
  369. +static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
  370. +{
  371. + struct acpi_device *adev;
  372. +
  373. + adev = acpi_bus_get_acpi_device(dep->consumer);
  374. + if (!adev)
  375. + /* If we don't find an adev then we want to continue parsing */
  376. + return 0;
  377. +
  378. + *(struct acpi_device **)data = adev;
  379. +
  380. + return 1;
  381. +}
  382. +
  383. static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
  384. {
  385. struct acpi_device *adev;
  386. @@ -2164,6 +2178,27 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier)
  387. }
  388. EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
  389. +/**
  390. + * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
  391. + * @supplier: Pointer to the dependee device
  392. + *
  393. + * Returns the first &struct acpi_device which declares itself dependent on
  394. + * @supplier via the _DEP buffer, parsed from the acpi_dep_list.
  395. + *
  396. + * The caller is responsible for putting the reference to adev when it is no
  397. + * longer needed.
  398. + */
  399. +struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
  400. +{
  401. + struct acpi_device *adev = NULL;
  402. +
  403. + acpi_walk_dep_device_list(supplier->handle,
  404. + acpi_dev_get_first_consumer_dev_cb, &adev);
  405. +
  406. + return adev;
  407. +}
  408. +EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
  409. +
  410. /**
  411. * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
  412. * @handle: Root of the namespace scope to scan.
  413. diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
  414. index b934c77b735f..db20595b24d1 100644
  415. --- a/include/acpi/acpi_bus.h
  416. +++ b/include/acpi/acpi_bus.h
  417. @@ -692,6 +692,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
  418. bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
  419. void acpi_dev_clear_dependencies(struct acpi_device *supplier);
  420. +struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
  421. struct acpi_device *
  422. acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
  423. struct acpi_device *
  424. --
  425. 2.33.0
  426. From b59579c09cf15ff8c78c50d3f4a457bb198d7906 Mon Sep 17 00:00:00 2001
  427. From: Daniel Scally <djrscally@gmail.com>
  428. Date: Thu, 3 Jun 2021 23:40:04 +0100
  429. Subject: [PATCH] gpiolib: acpi: Introduce acpi_get_and_request_gpiod() helper
  430. We need to be able to translate GPIO resources in an ACPI device's _CRS
  431. into GPIO descriptor array. Those are represented in _CRS as a pathname
  432. to a GPIO device plus the pin's index number: the acpi_get_gpiod()
  433. function is perfect for that purpose.
  434. As it's currently only used internally within the GPIO layer, provide and
  435. export a wrapper function that additionally holds a reference to the GPIO
  436. device.
  437. Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
  438. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  439. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  440. Patchset: cameras
  441. ---
  442. drivers/gpio/gpiolib-acpi.c | 28 ++++++++++++++++++++++++++++
  443. include/linux/gpio/consumer.h | 2 ++
  444. 2 files changed, 30 insertions(+)
  445. diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
  446. index 5b4111e4be3f..b5acb2c50836 100644
  447. --- a/drivers/gpio/gpiolib-acpi.c
  448. +++ b/drivers/gpio/gpiolib-acpi.c
  449. @@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
  450. return gpiochip_get_desc(chip, pin);
  451. }
  452. +/**
  453. + * acpi_get_and_request_gpiod - Translate ACPI GPIO pin to GPIO descriptor and
  454. + * hold a refcount to the GPIO device.
  455. + * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
  456. + * @pin: ACPI GPIO pin number (0-based, controller-relative)
  457. + * @label: Label to pass to gpiod_request()
  458. + *
  459. + * This function is a simple pass-through to acpi_get_gpiod(), except that
  460. + * as it is intended for use outside of the GPIO layer (in a similar fashion to
  461. + * gpiod_get_index() for example) it also holds a reference to the GPIO device.
  462. + */
  463. +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label)
  464. +{
  465. + struct gpio_desc *gpio;
  466. + int ret;
  467. +
  468. + gpio = acpi_get_gpiod(path, pin);
  469. + if (IS_ERR(gpio))
  470. + return gpio;
  471. +
  472. + ret = gpiod_request(gpio, label);
  473. + if (ret)
  474. + return ERR_PTR(ret);
  475. +
  476. + return gpio;
  477. +}
  478. +EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod);
  479. +
  480. static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
  481. {
  482. struct acpi_gpio_event *event = data;
  483. diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
  484. index c73b25bc9213..566feb56601f 100644
  485. --- a/include/linux/gpio/consumer.h
  486. +++ b/include/linux/gpio/consumer.h
  487. @@ -692,6 +692,8 @@ int devm_acpi_dev_add_driver_gpios(struct device *dev,
  488. const struct acpi_gpio_mapping *gpios);
  489. void devm_acpi_dev_remove_driver_gpios(struct device *dev);
  490. +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label);
  491. +
  492. #else /* CONFIG_GPIOLIB && CONFIG_ACPI */
  493. struct acpi_device;
  494. --
  495. 2.33.0
  496. From 6e23f9976c758315c57f0b8a52d002507d087d88 Mon Sep 17 00:00:00 2001
  497. From: Daniel Scally <djrscally@gmail.com>
  498. Date: Thu, 3 Jun 2021 23:40:05 +0100
  499. Subject: [PATCH] gpiolib: acpi: Add acpi_gpio_get_io_resource()
  500. Add a function to verify that a given ACPI resource represents a GpioIo()
  501. type of resource, and return it if so.
  502. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  503. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  504. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  505. Patchset: cameras
  506. ---
  507. drivers/gpio/gpiolib-acpi.c | 23 +++++++++++++++++++++++
  508. include/linux/acpi.h | 7 +++++++
  509. 2 files changed, 30 insertions(+)
  510. diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
  511. index b5acb2c50836..411525ac4cc4 100644
  512. --- a/drivers/gpio/gpiolib-acpi.c
  513. +++ b/drivers/gpio/gpiolib-acpi.c
  514. @@ -196,6 +196,29 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
  515. }
  516. EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);
  517. +/**
  518. + * acpi_gpio_get_io_resource - Fetch details of an ACPI resource if it is a GPIO
  519. + * I/O resource or return False if not.
  520. + * @ares: Pointer to the ACPI resource to fetch
  521. + * @agpio: Pointer to a &struct acpi_resource_gpio to store the output pointer
  522. + */
  523. +bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
  524. + struct acpi_resource_gpio **agpio)
  525. +{
  526. + struct acpi_resource_gpio *gpio;
  527. +
  528. + if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
  529. + return false;
  530. +
  531. + gpio = &ares->data.gpio;
  532. + if (gpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_IO)
  533. + return false;
  534. +
  535. + *agpio = gpio;
  536. + return true;
  537. +}
  538. +EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource);
  539. +
  540. static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
  541. struct acpi_gpio_event *event)
  542. {
  543. diff --git a/include/linux/acpi.h b/include/linux/acpi.h
  544. index 170b9bebdb2b..e8ba7063c000 100644
  545. --- a/include/linux/acpi.h
  546. +++ b/include/linux/acpi.h
  547. @@ -1098,6 +1098,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
  548. #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
  549. bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
  550. struct acpi_resource_gpio **agpio);
  551. +bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
  552. + struct acpi_resource_gpio **agpio);
  553. int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
  554. #else
  555. static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
  556. @@ -1105,6 +1107,11 @@ static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
  557. {
  558. return false;
  559. }
  560. +static inline bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
  561. + struct acpi_resource_gpio **agpio)
  562. +{
  563. + return false;
  564. +}
  565. static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
  566. const char *name, int index)
  567. {
  568. --
  569. 2.33.0
  570. From e5553a8ae0cb56f7a447e369eced872c6cb9e4d2 Mon Sep 17 00:00:00 2001
  571. From: Daniel Scally <djrscally@gmail.com>
  572. Date: Thu, 3 Jun 2021 23:40:06 +0100
  573. Subject: [PATCH] platform/x86: Add intel_skl_int3472 driver
  574. ACPI devices with _HID INT3472 are currently matched to the tps68470
  575. driver, however this does not cover all situations in which that _HID
  576. occurs. We've encountered three possibilities:
  577. 1. On Chrome OS devices, an ACPI device with _HID INT3472 (representing
  578. a physical TPS68470 device) that requires a GPIO and OpRegion driver
  579. 2. On devices designed for Windows, an ACPI device with _HID INT3472
  580. (again representing a physical TPS68470 device) which requires GPIO,
  581. Clock and Regulator drivers.
  582. 3. On other devices designed for Windows, an ACPI device with _HID
  583. INT3472 which does **not** represent a physical TPS68470, and is instead
  584. used as a dummy device to group some system GPIO lines which are meant
  585. to be consumed by the sensor that is dependent on this entry.
  586. This commit adds a new module, registering a platform driver to deal
  587. with the 3rd scenario plus an i2c driver to deal with #1 and #2, by
  588. querying the CLDB buffer found against INT3472 entries to determine
  589. which is most appropriate.
  590. Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  591. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  592. Link: https://lore.kernel.org/r/20210603224007.120560-6-djrscally@gmail.com
  593. [hdegoede@redhat.com Make skl_int3472_tps68470_calc_type() static]
  594. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  595. Patchset: cameras
  596. ---
  597. MAINTAINERS | 5 +
  598. drivers/platform/x86/Kconfig | 2 +
  599. drivers/platform/x86/Makefile | 1 +
  600. drivers/platform/x86/intel-int3472/Kconfig | 30 ++
  601. drivers/platform/x86/intel-int3472/Makefile | 5 +
  602. .../intel_skl_int3472_clk_and_regulator.c | 196 ++++++++
  603. .../intel-int3472/intel_skl_int3472_common.c | 106 +++++
  604. .../intel-int3472/intel_skl_int3472_common.h | 118 +++++
  605. .../intel_skl_int3472_discrete.c | 417 ++++++++++++++++++
  606. .../intel_skl_int3472_tps68470.c | 137 ++++++
  607. 10 files changed, 1017 insertions(+)
  608. create mode 100644 drivers/platform/x86/intel-int3472/Kconfig
  609. create mode 100644 drivers/platform/x86/intel-int3472/Makefile
  610. create mode 100644 drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  611. create mode 100644 drivers/platform/x86/intel-int3472/intel_skl_int3472_common.c
  612. create mode 100644 drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  613. create mode 100644 drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  614. create mode 100644 drivers/platform/x86/intel-int3472/intel_skl_int3472_tps68470.c
  615. diff --git a/MAINTAINERS b/MAINTAINERS
  616. index 0cce91cd5624..1db7311d78a6 100644
  617. --- a/MAINTAINERS
  618. +++ b/MAINTAINERS
  619. @@ -9386,6 +9386,11 @@ S: Maintained
  620. F: arch/x86/include/asm/intel_scu_ipc.h
  621. F: drivers/platform/x86/intel_scu_*
  622. +INTEL SKYLAKE INT3472 ACPI DEVICE DRIVER
  623. +M: Daniel Scally <djrscally@gmail.com>
  624. +S: Maintained
  625. +F: drivers/platform/x86/intel-int3472/
  626. +
  627. INTEL SPEED SELECT TECHNOLOGY
  628. M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
  629. L: platform-driver-x86@vger.kernel.org
  630. diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
  631. index 60592fb88e7a..88134aaacefc 100644
  632. --- a/drivers/platform/x86/Kconfig
  633. +++ b/drivers/platform/x86/Kconfig
  634. @@ -697,6 +697,8 @@ config INTEL_CHT_INT33FE
  635. device and CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m
  636. for Type-C device.
  637. +source "drivers/platform/x86/intel-int3472/Kconfig"
  638. +
  639. config INTEL_HID_EVENT
  640. tristate "INTEL HID Event"
  641. depends on ACPI
  642. diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
  643. index dcc8cdb95b4d..c0612c02d037 100644
  644. --- a/drivers/platform/x86/Makefile
  645. +++ b/drivers/platform/x86/Makefile
  646. @@ -76,6 +76,7 @@ obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
  647. obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
  648. obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
  649. obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
  650. +obj-$(CONFIG_INTEL_SKL_INT3472) += intel-int3472/
  651. obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
  652. # MSI
  653. diff --git a/drivers/platform/x86/intel-int3472/Kconfig b/drivers/platform/x86/intel-int3472/Kconfig
  654. new file mode 100644
  655. index 000000000000..c112878e833b
  656. --- /dev/null
  657. +++ b/drivers/platform/x86/intel-int3472/Kconfig
  658. @@ -0,0 +1,30 @@
  659. +config INTEL_SKL_INT3472
  660. + tristate "Intel SkyLake ACPI INT3472 Driver"
  661. + depends on ACPI
  662. + depends on COMMON_CLK && CLKDEV_LOOKUP
  663. + depends on I2C
  664. + depends on GPIOLIB
  665. + depends on REGULATOR
  666. + select MFD_CORE
  667. + select REGMAP_I2C
  668. + help
  669. + This driver adds power controller support for the Intel SkyCam
  670. + devices found on the Intel SkyLake platforms.
  671. +
  672. + The INT3472 is a camera power controller, a logical device found on
  673. + Intel Skylake-based systems that can map to different hardware
  674. + devices depending on the platform. On machines designed for Chrome OS
  675. + it maps to a TPS68470 camera PMIC. On machines designed for Windows,
  676. + it maps to either a TP68470 camera PMIC, a uP6641Q sensor PMIC, or a
  677. + set of discrete GPIOs and power gates.
  678. +
  679. + If your device was designed for Chrome OS, this driver will provide
  680. + an ACPI OpRegion, which must be available before any of the devices
  681. + using it are probed. For this reason, you should select Y if your
  682. + device was designed for ChromeOS. For the same reason the
  683. + I2C_DESIGNWARE_PLATFORM option must be set to Y too.
  684. +
  685. + Say Y or M here if you have a SkyLake device designed for use
  686. + with Windows or ChromeOS. Say N here if you are not sure.
  687. +
  688. + The module will be named "intel-skl-int3472".
  689. diff --git a/drivers/platform/x86/intel-int3472/Makefile b/drivers/platform/x86/intel-int3472/Makefile
  690. new file mode 100644
  691. index 000000000000..48bd97f0a04e
  692. --- /dev/null
  693. +++ b/drivers/platform/x86/intel-int3472/Makefile
  694. @@ -0,0 +1,5 @@
  695. +obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o
  696. +intel_skl_int3472-objs := intel_skl_int3472_common.o \
  697. + intel_skl_int3472_discrete.o \
  698. + intel_skl_int3472_tps68470.o \
  699. + intel_skl_int3472_clk_and_regulator.o
  700. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  701. new file mode 100644
  702. index 000000000000..ceee860e2c07
  703. --- /dev/null
  704. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  705. @@ -0,0 +1,196 @@
  706. +// SPDX-License-Identifier: GPL-2.0
  707. +/* Author: Dan Scally <djrscally@gmail.com> */
  708. +
  709. +#include <linux/acpi.h>
  710. +#include <linux/clkdev.h>
  711. +#include <linux/clk-provider.h>
  712. +#include <linux/device.h>
  713. +#include <linux/gpio/consumer.h>
  714. +#include <linux/regulator/driver.h>
  715. +#include <linux/slab.h>
  716. +
  717. +#include "intel_skl_int3472_common.h"
  718. +
  719. +/*
  720. + * The regulators have to have .ops to be valid, but the only ops we actually
  721. + * support are .enable and .disable which are handled via .ena_gpiod. Pass an
  722. + * empty struct to clear the check without lying about capabilities.
  723. + */
  724. +static const struct regulator_ops int3472_gpio_regulator_ops;
  725. +
  726. +static int skl_int3472_clk_prepare(struct clk_hw *hw)
  727. +{
  728. + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
  729. +
  730. + gpiod_set_value_cansleep(clk->ena_gpio, 1);
  731. + gpiod_set_value_cansleep(clk->led_gpio, 1);
  732. +
  733. + return 0;
  734. +}
  735. +
  736. +static void skl_int3472_clk_unprepare(struct clk_hw *hw)
  737. +{
  738. + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
  739. +
  740. + gpiod_set_value_cansleep(clk->ena_gpio, 0);
  741. + gpiod_set_value_cansleep(clk->led_gpio, 0);
  742. +}
  743. +
  744. +static int skl_int3472_clk_enable(struct clk_hw *hw)
  745. +{
  746. + /*
  747. + * We're just turning a GPIO on to enable the clock, which operation
  748. + * has the potential to sleep. Given .enable() cannot sleep, but
  749. + * .prepare() can, we toggle the GPIO in .prepare() instead. Thus,
  750. + * nothing to do here.
  751. + */
  752. + return 0;
  753. +}
  754. +
  755. +static void skl_int3472_clk_disable(struct clk_hw *hw)
  756. +{
  757. + /* Likewise, nothing to do here... */
  758. +}
  759. +
  760. +static unsigned int skl_int3472_get_clk_frequency(struct int3472_discrete_device *int3472)
  761. +{
  762. + union acpi_object *obj;
  763. + unsigned int freq;
  764. +
  765. + obj = skl_int3472_get_acpi_buffer(int3472->sensor, "SSDB");
  766. + if (IS_ERR(obj))
  767. + return 0; /* report rate as 0 on error */
  768. +
  769. + if (obj->buffer.length < CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET + sizeof(u32)) {
  770. + dev_err(int3472->dev, "The buffer is too small\n");
  771. + kfree(obj);
  772. + return 0;
  773. + }
  774. +
  775. + freq = *(u32 *)(obj->buffer.pointer + CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET);
  776. +
  777. + kfree(obj);
  778. + return freq;
  779. +}
  780. +
  781. +static unsigned long skl_int3472_clk_recalc_rate(struct clk_hw *hw,
  782. + unsigned long parent_rate)
  783. +{
  784. + struct int3472_gpio_clock *clk = to_int3472_clk(hw);
  785. +
  786. + return clk->frequency;
  787. +}
  788. +
  789. +static const struct clk_ops skl_int3472_clock_ops = {
  790. + .prepare = skl_int3472_clk_prepare,
  791. + .unprepare = skl_int3472_clk_unprepare,
  792. + .enable = skl_int3472_clk_enable,
  793. + .disable = skl_int3472_clk_disable,
  794. + .recalc_rate = skl_int3472_clk_recalc_rate,
  795. +};
  796. +
  797. +int skl_int3472_register_clock(struct int3472_discrete_device *int3472)
  798. +{
  799. + struct clk_init_data init = {
  800. + .ops = &skl_int3472_clock_ops,
  801. + .flags = CLK_GET_RATE_NOCACHE,
  802. + };
  803. + int ret;
  804. +
  805. + init.name = kasprintf(GFP_KERNEL, "%s-clk",
  806. + acpi_dev_name(int3472->adev));
  807. + if (!init.name)
  808. + return -ENOMEM;
  809. +
  810. + int3472->clock.frequency = skl_int3472_get_clk_frequency(int3472);
  811. +
  812. + int3472->clock.clk_hw.init = &init;
  813. + int3472->clock.clk = clk_register(&int3472->adev->dev,
  814. + &int3472->clock.clk_hw);
  815. + if (IS_ERR(int3472->clock.clk)) {
  816. + ret = PTR_ERR(int3472->clock.clk);
  817. + goto out_free_init_name;
  818. + }
  819. +
  820. + int3472->clock.cl = clkdev_create(int3472->clock.clk, NULL,
  821. + int3472->sensor_name);
  822. + if (!int3472->clock.cl) {
  823. + ret = -ENOMEM;
  824. + goto err_unregister_clk;
  825. + }
  826. +
  827. + kfree(init.name);
  828. + return 0;
  829. +
  830. +err_unregister_clk:
  831. + clk_unregister(int3472->clock.clk);
  832. +out_free_init_name:
  833. + kfree(init.name);
  834. +
  835. + return ret;
  836. +}
  837. +
  838. +int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  839. + struct acpi_resource *ares)
  840. +{
  841. + char *path = ares->data.gpio.resource_source.string_ptr;
  842. + const struct int3472_sensor_config *sensor_config;
  843. + struct regulator_consumer_supply supply_map;
  844. + struct regulator_init_data init_data = { };
  845. + struct regulator_config cfg = { };
  846. + int ret;
  847. +
  848. + sensor_config = int3472->sensor_config;
  849. + if (IS_ERR(sensor_config)) {
  850. + dev_err(int3472->dev, "No sensor module config\n");
  851. + return PTR_ERR(sensor_config);
  852. + }
  853. +
  854. + if (!sensor_config->supply_map.supply) {
  855. + dev_err(int3472->dev, "No supply name defined\n");
  856. + return -ENODEV;
  857. + }
  858. +
  859. + init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
  860. + init_data.num_consumer_supplies = 1;
  861. + supply_map = sensor_config->supply_map;
  862. + supply_map.dev_name = int3472->sensor_name;
  863. + init_data.consumer_supplies = &supply_map;
  864. +
  865. + snprintf(int3472->regulator.regulator_name,
  866. + sizeof(int3472->regulator.regulator_name), "%s-regulator",
  867. + acpi_dev_name(int3472->adev));
  868. + snprintf(int3472->regulator.supply_name,
  869. + GPIO_REGULATOR_SUPPLY_NAME_LENGTH, "supply-0");
  870. +
  871. + int3472->regulator.rdesc = INT3472_REGULATOR(
  872. + int3472->regulator.regulator_name,
  873. + int3472->regulator.supply_name,
  874. + &int3472_gpio_regulator_ops);
  875. +
  876. + int3472->regulator.gpio = acpi_get_and_request_gpiod(path,
  877. + ares->data.gpio.pin_table[0],
  878. + "int3472,regulator");
  879. + if (IS_ERR(int3472->regulator.gpio)) {
  880. + dev_err(int3472->dev, "Failed to get regulator GPIO line\n");
  881. + return PTR_ERR(int3472->regulator.gpio);
  882. + }
  883. +
  884. + cfg.dev = &int3472->adev->dev;
  885. + cfg.init_data = &init_data;
  886. + cfg.ena_gpiod = int3472->regulator.gpio;
  887. +
  888. + int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
  889. + &cfg);
  890. + if (IS_ERR(int3472->regulator.rdev)) {
  891. + ret = PTR_ERR(int3472->regulator.rdev);
  892. + goto err_free_gpio;
  893. + }
  894. +
  895. + return 0;
  896. +
  897. +err_free_gpio:
  898. + gpiod_put(int3472->regulator.gpio);
  899. +
  900. + return ret;
  901. +}
  902. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.c
  903. new file mode 100644
  904. index 000000000000..497e74fba75f
  905. --- /dev/null
  906. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.c
  907. @@ -0,0 +1,106 @@
  908. +// SPDX-License-Identifier: GPL-2.0
  909. +/* Author: Dan Scally <djrscally@gmail.com> */
  910. +
  911. +#include <linux/acpi.h>
  912. +#include <linux/i2c.h>
  913. +#include <linux/platform_device.h>
  914. +#include <linux/slab.h>
  915. +
  916. +#include "intel_skl_int3472_common.h"
  917. +
  918. +union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
  919. +{
  920. + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  921. + acpi_handle handle = adev->handle;
  922. + union acpi_object *obj;
  923. + acpi_status status;
  924. +
  925. + status = acpi_evaluate_object(handle, id, NULL, &buffer);
  926. + if (ACPI_FAILURE(status))
  927. + return ERR_PTR(-ENODEV);
  928. +
  929. + obj = buffer.pointer;
  930. + if (!obj)
  931. + return ERR_PTR(-ENODEV);
  932. +
  933. + if (obj->type != ACPI_TYPE_BUFFER) {
  934. + acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
  935. + kfree(obj);
  936. + return ERR_PTR(-EINVAL);
  937. + }
  938. +
  939. + return obj;
  940. +}
  941. +
  942. +int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
  943. +{
  944. + union acpi_object *obj;
  945. + int ret;
  946. +
  947. + obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
  948. + if (IS_ERR(obj))
  949. + return PTR_ERR(obj);
  950. +
  951. + if (obj->buffer.length > sizeof(*cldb)) {
  952. + acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
  953. + ret = -EINVAL;
  954. + goto out_free_obj;
  955. + }
  956. +
  957. + memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
  958. + ret = 0;
  959. +
  960. +out_free_obj:
  961. + kfree(obj);
  962. + return ret;
  963. +}
  964. +
  965. +static const struct acpi_device_id int3472_device_id[] = {
  966. + { "INT3472", 0 },
  967. + { }
  968. +};
  969. +MODULE_DEVICE_TABLE(acpi, int3472_device_id);
  970. +
  971. +static struct platform_driver int3472_discrete = {
  972. + .driver = {
  973. + .name = "int3472-discrete",
  974. + .acpi_match_table = int3472_device_id,
  975. + },
  976. + .probe = skl_int3472_discrete_probe,
  977. + .remove = skl_int3472_discrete_remove,
  978. +};
  979. +
  980. +static struct i2c_driver int3472_tps68470 = {
  981. + .driver = {
  982. + .name = "int3472-tps68470",
  983. + .acpi_match_table = int3472_device_id,
  984. + },
  985. + .probe_new = skl_int3472_tps68470_probe,
  986. +};
  987. +
  988. +static int skl_int3472_init(void)
  989. +{
  990. + int ret;
  991. +
  992. + ret = platform_driver_register(&int3472_discrete);
  993. + if (ret)
  994. + return ret;
  995. +
  996. + ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
  997. + if (ret)
  998. + platform_driver_unregister(&int3472_discrete);
  999. +
  1000. + return ret;
  1001. +}
  1002. +module_init(skl_int3472_init);
  1003. +
  1004. +static void skl_int3472_exit(void)
  1005. +{
  1006. + platform_driver_unregister(&int3472_discrete);
  1007. + i2c_del_driver(&int3472_tps68470);
  1008. +}
  1009. +module_exit(skl_int3472_exit);
  1010. +
  1011. +MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
  1012. +MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
  1013. +MODULE_LICENSE("GPL v2");
  1014. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  1015. new file mode 100644
  1016. index 000000000000..6fdf78584219
  1017. --- /dev/null
  1018. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  1019. @@ -0,0 +1,118 @@
  1020. +/* SPDX-License-Identifier: GPL-2.0 */
  1021. +/* Author: Dan Scally <djrscally@gmail.com> */
  1022. +
  1023. +#ifndef _INTEL_SKL_INT3472_H
  1024. +#define _INTEL_SKL_INT3472_H
  1025. +
  1026. +#include <linux/clk-provider.h>
  1027. +#include <linux/gpio/machine.h>
  1028. +#include <linux/regulator/driver.h>
  1029. +#include <linux/regulator/machine.h>
  1030. +#include <linux/types.h>
  1031. +
  1032. +/* FIXME drop this once the I2C_DEV_NAME_FORMAT macro has been added to include/linux/i2c.h */
  1033. +#ifndef I2C_DEV_NAME_FORMAT
  1034. +#define I2C_DEV_NAME_FORMAT "i2c-%s"
  1035. +#endif
  1036. +
  1037. +/* PMIC GPIO Types */
  1038. +#define INT3472_GPIO_TYPE_RESET 0x00
  1039. +#define INT3472_GPIO_TYPE_POWERDOWN 0x01
  1040. +#define INT3472_GPIO_TYPE_POWER_ENABLE 0x0b
  1041. +#define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c
  1042. +#define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d
  1043. +
  1044. +#define INT3472_PDEV_MAX_NAME_LEN 23
  1045. +#define INT3472_MAX_SENSOR_GPIOS 3
  1046. +
  1047. +#define GPIO_REGULATOR_NAME_LENGTH 21
  1048. +#define GPIO_REGULATOR_SUPPLY_NAME_LENGTH 9
  1049. +
  1050. +#define CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET 86
  1051. +
  1052. +#define INT3472_REGULATOR(_name, _supply, _ops) \
  1053. + (const struct regulator_desc) { \
  1054. + .name = _name, \
  1055. + .supply_name = _supply, \
  1056. + .type = REGULATOR_VOLTAGE, \
  1057. + .ops = _ops, \
  1058. + .owner = THIS_MODULE, \
  1059. + }
  1060. +
  1061. +#define to_int3472_clk(hw) \
  1062. + container_of(hw, struct int3472_gpio_clock, clk_hw)
  1063. +
  1064. +#define to_int3472_device(clk) \
  1065. + container_of(clk, struct int3472_discrete_device, clock)
  1066. +
  1067. +struct acpi_device;
  1068. +struct i2c_client;
  1069. +struct platform_device;
  1070. +
  1071. +struct int3472_cldb {
  1072. + u8 version;
  1073. + /*
  1074. + * control logic type
  1075. + * 0: UNKNOWN
  1076. + * 1: DISCRETE(CRD-D)
  1077. + * 2: PMIC TPS68470
  1078. + * 3: PMIC uP6641
  1079. + */
  1080. + u8 control_logic_type;
  1081. + u8 control_logic_id;
  1082. + u8 sensor_card_sku;
  1083. + u8 reserved[28];
  1084. +};
  1085. +
  1086. +struct int3472_gpio_function_remap {
  1087. + const char *documented;
  1088. + const char *actual;
  1089. +};
  1090. +
  1091. +struct int3472_sensor_config {
  1092. + const char *sensor_module_name;
  1093. + struct regulator_consumer_supply supply_map;
  1094. + const struct int3472_gpio_function_remap *function_maps;
  1095. +};
  1096. +
  1097. +struct int3472_discrete_device {
  1098. + struct acpi_device *adev;
  1099. + struct device *dev;
  1100. + struct acpi_device *sensor;
  1101. + const char *sensor_name;
  1102. +
  1103. + const struct int3472_sensor_config *sensor_config;
  1104. +
  1105. + struct int3472_gpio_regulator {
  1106. + char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
  1107. + char supply_name[GPIO_REGULATOR_SUPPLY_NAME_LENGTH];
  1108. + struct gpio_desc *gpio;
  1109. + struct regulator_dev *rdev;
  1110. + struct regulator_desc rdesc;
  1111. + } regulator;
  1112. +
  1113. + struct int3472_gpio_clock {
  1114. + struct clk *clk;
  1115. + struct clk_hw clk_hw;
  1116. + struct clk_lookup *cl;
  1117. + struct gpio_desc *ena_gpio;
  1118. + struct gpio_desc *led_gpio;
  1119. + u32 frequency;
  1120. + } clock;
  1121. +
  1122. + unsigned int ngpios; /* how many GPIOs have we seen */
  1123. + unsigned int n_sensor_gpios; /* how many have we mapped to sensor */
  1124. + struct gpiod_lookup_table gpios;
  1125. +};
  1126. +
  1127. +int skl_int3472_discrete_probe(struct platform_device *pdev);
  1128. +int skl_int3472_discrete_remove(struct platform_device *pdev);
  1129. +int skl_int3472_tps68470_probe(struct i2c_client *client);
  1130. +union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
  1131. + char *id);
  1132. +int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
  1133. +int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
  1134. +int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  1135. + struct acpi_resource *ares);
  1136. +
  1137. +#endif
  1138. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  1139. new file mode 100644
  1140. index 000000000000..8c18dbff1c43
  1141. --- /dev/null
  1142. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  1143. @@ -0,0 +1,417 @@
  1144. +// SPDX-License-Identifier: GPL-2.0
  1145. +/* Author: Dan Scally <djrscally@gmail.com> */
  1146. +
  1147. +#include <linux/acpi.h>
  1148. +#include <linux/clkdev.h>
  1149. +#include <linux/clk-provider.h>
  1150. +#include <linux/device.h>
  1151. +#include <linux/gpio/consumer.h>
  1152. +#include <linux/gpio/machine.h>
  1153. +#include <linux/i2c.h>
  1154. +#include <linux/kernel.h>
  1155. +#include <linux/module.h>
  1156. +#include <linux/overflow.h>
  1157. +#include <linux/platform_device.h>
  1158. +#include <linux/uuid.h>
  1159. +
  1160. +#include "intel_skl_int3472_common.h"
  1161. +
  1162. +/*
  1163. + * 79234640-9e10-4fea-a5c1-b5aa8b19756f
  1164. + * This _DSM GUID returns information about the GPIO lines mapped to a
  1165. + * discrete INT3472 device. Function number 1 returns a count of the GPIO
  1166. + * lines that are mapped. Subsequent functions return 32 bit ints encoding
  1167. + * information about the GPIO line, including its purpose.
  1168. + */
  1169. +static const guid_t int3472_gpio_guid =
  1170. + GUID_INIT(0x79234640, 0x9e10, 0x4fea,
  1171. + 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
  1172. +
  1173. +/*
  1174. + * 822ace8f-2814-4174-a56b-5f029fe079ee
  1175. + * This _DSM GUID returns a string from the sensor device, which acts as a
  1176. + * module identifier.
  1177. + */
  1178. +static const guid_t cio2_sensor_module_guid =
  1179. + GUID_INIT(0x822ace8f, 0x2814, 0x4174,
  1180. + 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
  1181. +
  1182. +/*
  1183. + * Here follows platform specific mapping information that we can pass to
  1184. + * the functions mapping resources to the sensors. Where the sensors have
  1185. + * a power enable pin defined in DSDT we need to provide a supply name so
  1186. + * the sensor drivers can find the regulator. The device name will be derived
  1187. + * from the sensor's ACPI device within the code. Optionally, we can provide a
  1188. + * NULL terminated array of function name mappings to deal with any platform
  1189. + * specific deviations from the documented behaviour of GPIOs.
  1190. + *
  1191. + * Map a GPIO function name to NULL to prevent the driver from mapping that
  1192. + * GPIO at all.
  1193. + */
  1194. +
  1195. +static const struct int3472_gpio_function_remap ov2680_gpio_function_remaps[] = {
  1196. + { "reset", NULL },
  1197. + { "powerdown", "reset" },
  1198. + { }
  1199. +};
  1200. +
  1201. +static const struct int3472_sensor_config int3472_sensor_configs[] = {
  1202. + /* Lenovo Miix 510-12ISK - OV2680, Front */
  1203. + { "GNDF140809R", { 0 }, ov2680_gpio_function_remaps },
  1204. + /* Lenovo Miix 510-12ISK - OV5648, Rear */
  1205. + { "GEFF150023R", REGULATOR_SUPPLY("avdd", NULL), NULL },
  1206. + /* Surface Go 1&2 - OV5693, Front */
  1207. + { "YHCU", REGULATOR_SUPPLY("avdd", NULL), NULL },
  1208. +};
  1209. +
  1210. +static const struct int3472_sensor_config *
  1211. +skl_int3472_get_sensor_module_config(struct int3472_discrete_device *int3472)
  1212. +{
  1213. + union acpi_object *obj;
  1214. + unsigned int i;
  1215. +
  1216. + obj = acpi_evaluate_dsm_typed(int3472->sensor->handle,
  1217. + &cio2_sensor_module_guid, 0x00,
  1218. + 0x01, NULL, ACPI_TYPE_STRING);
  1219. +
  1220. + if (!obj) {
  1221. + dev_err(int3472->dev,
  1222. + "Failed to get sensor module string from _DSM\n");
  1223. + return ERR_PTR(-ENODEV);
  1224. + }
  1225. +
  1226. + if (obj->string.type != ACPI_TYPE_STRING) {
  1227. + dev_err(int3472->dev,
  1228. + "Sensor _DSM returned a non-string value\n");
  1229. +
  1230. + ACPI_FREE(obj);
  1231. + return ERR_PTR(-EINVAL);
  1232. + }
  1233. +
  1234. + for (i = 0; i < ARRAY_SIZE(int3472_sensor_configs); i++) {
  1235. + if (!strcmp(int3472_sensor_configs[i].sensor_module_name,
  1236. + obj->string.pointer))
  1237. + break;
  1238. + }
  1239. +
  1240. + ACPI_FREE(obj);
  1241. +
  1242. + if (i >= ARRAY_SIZE(int3472_sensor_configs))
  1243. + return ERR_PTR(-EINVAL);
  1244. +
  1245. + return &int3472_sensor_configs[i];
  1246. +}
  1247. +
  1248. +static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472,
  1249. + struct acpi_resource *ares,
  1250. + const char *func, u32 polarity)
  1251. +{
  1252. + char *path = ares->data.gpio.resource_source.string_ptr;
  1253. + const struct int3472_sensor_config *sensor_config;
  1254. + struct gpiod_lookup *table_entry;
  1255. + struct acpi_device *adev;
  1256. + acpi_handle handle;
  1257. + acpi_status status;
  1258. + int ret;
  1259. +
  1260. + if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) {
  1261. + dev_warn(int3472->dev, "Too many GPIOs mapped\n");
  1262. + return -EINVAL;
  1263. + }
  1264. +
  1265. + sensor_config = int3472->sensor_config;
  1266. + if (!IS_ERR(sensor_config) && sensor_config->function_maps) {
  1267. + const struct int3472_gpio_function_remap *remap;
  1268. +
  1269. + for (remap = sensor_config->function_maps; remap->documented; remap++) {
  1270. + if (!strcmp(func, remap->documented)) {
  1271. + func = remap->actual;
  1272. + break;
  1273. + }
  1274. + }
  1275. + }
  1276. +
  1277. + /* Functions mapped to NULL should not be mapped to the sensor */
  1278. + if (!func)
  1279. + return 0;
  1280. +
  1281. + status = acpi_get_handle(NULL, path, &handle);
  1282. + if (ACPI_FAILURE(status))
  1283. + return -EINVAL;
  1284. +
  1285. + ret = acpi_bus_get_device(handle, &adev);
  1286. + if (ret)
  1287. + return -ENODEV;
  1288. +
  1289. + table_entry = &int3472->gpios.table[int3472->n_sensor_gpios];
  1290. + table_entry->key = acpi_dev_name(adev);
  1291. + table_entry->chip_hwnum = ares->data.gpio.pin_table[0];
  1292. + table_entry->con_id = func;
  1293. + table_entry->idx = 0;
  1294. + table_entry->flags = polarity;
  1295. +
  1296. + int3472->n_sensor_gpios++;
  1297. +
  1298. + return 0;
  1299. +}
  1300. +
  1301. +static int skl_int3472_map_gpio_to_clk(struct int3472_discrete_device *int3472,
  1302. + struct acpi_resource *ares, u8 type)
  1303. +{
  1304. + char *path = ares->data.gpio.resource_source.string_ptr;
  1305. + struct gpio_desc *gpio;
  1306. +
  1307. + switch (type) {
  1308. + case INT3472_GPIO_TYPE_CLK_ENABLE:
  1309. + gpio = acpi_get_and_request_gpiod(path, ares->data.gpio.pin_table[0],
  1310. + "int3472,clk-enable");
  1311. + if (IS_ERR(gpio))
  1312. + return (PTR_ERR(gpio));
  1313. +
  1314. + int3472->clock.ena_gpio = gpio;
  1315. + break;
  1316. + case INT3472_GPIO_TYPE_PRIVACY_LED:
  1317. + gpio = acpi_get_and_request_gpiod(path, ares->data.gpio.pin_table[0],
  1318. + "int3472,privacy-led");
  1319. + if (IS_ERR(gpio))
  1320. + return (PTR_ERR(gpio));
  1321. +
  1322. + int3472->clock.led_gpio = gpio;
  1323. + break;
  1324. + default:
  1325. + dev_err(int3472->dev, "Invalid GPIO type 0x%02x for clock\n", type);
  1326. + break;
  1327. + }
  1328. +
  1329. + return 0;
  1330. +}
  1331. +
  1332. +/**
  1333. + * skl_int3472_handle_gpio_resources: Map PMIC resources to consuming sensor
  1334. + * @ares: A pointer to a &struct acpi_resource
  1335. + * @data: A pointer to a &struct int3472_discrete_device
  1336. + *
  1337. + * This function handles GPIO resources that are against an INT3472
  1338. + * ACPI device, by checking the value of the corresponding _DSM entry.
  1339. + * This will return a 32bit int, where the lowest byte represents the
  1340. + * function of the GPIO pin:
  1341. + *
  1342. + * 0x00 Reset
  1343. + * 0x01 Power down
  1344. + * 0x0b Power enable
  1345. + * 0x0c Clock enable
  1346. + * 0x0d Privacy LED
  1347. + *
  1348. + * There are some known platform specific quirks where that does not quite
  1349. + * hold up; for example where a pin with type 0x01 (Power down) is mapped to
  1350. + * a sensor pin that performs a reset function or entries in _CRS and _DSM that
  1351. + * do not actually correspond to a physical connection. These will be handled
  1352. + * by the mapping sub-functions.
  1353. + *
  1354. + * GPIOs will either be mapped directly to the sensor device or else used
  1355. + * to create clocks and regulators via the usual frameworks.
  1356. + *
  1357. + * Return:
  1358. + * * 1 - To continue the loop
  1359. + * * 0 - When all resources found are handled properly.
  1360. + * * -EINVAL - If the resource is not a GPIO IO resource
  1361. + * * -ENODEV - If the resource has no corresponding _DSM entry
  1362. + * * -Other - Errors propagated from one of the sub-functions.
  1363. + */
  1364. +static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
  1365. + void *data)
  1366. +{
  1367. + struct int3472_discrete_device *int3472 = data;
  1368. + struct acpi_resource_gpio *agpio;
  1369. + union acpi_object *obj;
  1370. + const char *err_msg;
  1371. + int ret;
  1372. + u8 type;
  1373. +
  1374. + if (!acpi_gpio_get_io_resource(ares, &agpio))
  1375. + return 1;
  1376. +
  1377. + /*
  1378. + * ngpios + 2 because the index of this _DSM function is 1-based and
  1379. + * the first function is just a count.
  1380. + */
  1381. + obj = acpi_evaluate_dsm_typed(int3472->adev->handle,
  1382. + &int3472_gpio_guid, 0x00,
  1383. + int3472->ngpios + 2,
  1384. + NULL, ACPI_TYPE_INTEGER);
  1385. +
  1386. + if (!obj) {
  1387. + dev_warn(int3472->dev, "No _DSM entry for GPIO pin %u\n",
  1388. + ares->data.gpio.pin_table[0]);
  1389. + return 1;
  1390. + }
  1391. +
  1392. + type = obj->integer.value & 0xff;
  1393. +
  1394. + switch (type) {
  1395. + case INT3472_GPIO_TYPE_RESET:
  1396. + ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "reset",
  1397. + GPIO_ACTIVE_LOW);
  1398. + if (ret)
  1399. + err_msg = "Failed to map reset pin to sensor\n";
  1400. +
  1401. + break;
  1402. + case INT3472_GPIO_TYPE_POWERDOWN:
  1403. + ret = skl_int3472_map_gpio_to_sensor(int3472, ares,
  1404. + "powerdown",
  1405. + GPIO_ACTIVE_LOW);
  1406. + if (ret)
  1407. + err_msg = "Failed to map powerdown pin to sensor\n";
  1408. +
  1409. + break;
  1410. + case INT3472_GPIO_TYPE_CLK_ENABLE:
  1411. + case INT3472_GPIO_TYPE_PRIVACY_LED:
  1412. + ret = skl_int3472_map_gpio_to_clk(int3472, ares, type);
  1413. + if (ret)
  1414. + err_msg = "Failed to map GPIO to clock\n";
  1415. +
  1416. + break;
  1417. + case INT3472_GPIO_TYPE_POWER_ENABLE:
  1418. + ret = skl_int3472_register_regulator(int3472, ares);
  1419. + if (ret)
  1420. + err_msg = "Failed to map regulator to sensor\n";
  1421. +
  1422. + break;
  1423. + default:
  1424. + dev_warn(int3472->dev,
  1425. + "GPIO type 0x%02x unknown; the sensor may not work\n",
  1426. + type);
  1427. + ret = 1;
  1428. + break;
  1429. + }
  1430. +
  1431. + int3472->ngpios++;
  1432. + ACPI_FREE(obj);
  1433. +
  1434. + if (ret)
  1435. + return dev_err_probe(int3472->dev, ret, err_msg);
  1436. +
  1437. + return 0;
  1438. +}
  1439. +
  1440. +static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
  1441. +{
  1442. + LIST_HEAD(resource_list);
  1443. + int ret;
  1444. +
  1445. + /*
  1446. + * No error check, because not having a sensor config is not necessarily
  1447. + * a failure mode.
  1448. + */
  1449. + int3472->sensor_config = skl_int3472_get_sensor_module_config(int3472);
  1450. +
  1451. + ret = acpi_dev_get_resources(int3472->adev, &resource_list,
  1452. + skl_int3472_handle_gpio_resources,
  1453. + int3472);
  1454. + if (ret)
  1455. + goto out_free_res_list;
  1456. +
  1457. + /*
  1458. + * If we find no clock enable GPIO pin then the privacy LED won't work.
  1459. + * We've never seen that situation, but it's possible. Warn the user so
  1460. + * it's clear what's happened.
  1461. + */
  1462. + if (int3472->clock.ena_gpio) {
  1463. + ret = skl_int3472_register_clock(int3472);
  1464. + if (ret)
  1465. + goto out_free_res_list;
  1466. + } else {
  1467. + if (int3472->clock.led_gpio)
  1468. + dev_warn(int3472->dev,
  1469. + "No clk GPIO. The privacy LED won't work\n");
  1470. + }
  1471. +
  1472. + int3472->gpios.dev_id = int3472->sensor_name;
  1473. + gpiod_add_lookup_table(&int3472->gpios);
  1474. +
  1475. +out_free_res_list:
  1476. + acpi_dev_free_resource_list(&resource_list);
  1477. +
  1478. + return ret;
  1479. +}
  1480. +
  1481. +int skl_int3472_discrete_probe(struct platform_device *pdev)
  1482. +{
  1483. + struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
  1484. + struct int3472_discrete_device *int3472;
  1485. + struct int3472_cldb cldb;
  1486. + int ret;
  1487. +
  1488. + ret = skl_int3472_fill_cldb(adev, &cldb);
  1489. + if (ret) {
  1490. + dev_err(&pdev->dev, "Couldn't fill CLDB structure\n");
  1491. + return ret;
  1492. + }
  1493. +
  1494. + if (cldb.control_logic_type != 1) {
  1495. + dev_err(&pdev->dev, "Unsupported control logic type %u\n",
  1496. + cldb.control_logic_type);
  1497. + return -EINVAL;
  1498. + }
  1499. +
  1500. + /* Max num GPIOs we've seen plus a terminator */
  1501. + int3472 = devm_kzalloc(&pdev->dev, struct_size(int3472, gpios.table,
  1502. + INT3472_MAX_SENSOR_GPIOS + 1), GFP_KERNEL);
  1503. + if (!int3472)
  1504. + return -ENOMEM;
  1505. +
  1506. + int3472->adev = adev;
  1507. + int3472->dev = &pdev->dev;
  1508. + platform_set_drvdata(pdev, int3472);
  1509. +
  1510. + int3472->sensor = acpi_dev_get_first_consumer_dev(adev);
  1511. + if (!int3472->sensor) {
  1512. + dev_err(&pdev->dev, "INT3472 seems to have no dependents.\n");
  1513. + return -ENODEV;
  1514. + }
  1515. +
  1516. + int3472->sensor_name = devm_kasprintf(int3472->dev, GFP_KERNEL,
  1517. + I2C_DEV_NAME_FORMAT,
  1518. + acpi_dev_name(int3472->sensor));
  1519. + if (!int3472->sensor_name) {
  1520. + ret = -ENOMEM;
  1521. + goto err_put_sensor;
  1522. + }
  1523. +
  1524. + /*
  1525. + * Initialising this list means we can call gpiod_remove_lookup_table()
  1526. + * in failure paths without issue.
  1527. + */
  1528. + INIT_LIST_HEAD(&int3472->gpios.list);
  1529. +
  1530. + ret = skl_int3472_parse_crs(int3472);
  1531. + if (ret) {
  1532. + skl_int3472_discrete_remove(pdev);
  1533. + return ret;
  1534. + }
  1535. +
  1536. + return 0;
  1537. +
  1538. +err_put_sensor:
  1539. + acpi_dev_put(int3472->sensor);
  1540. +
  1541. + return ret;
  1542. +}
  1543. +
  1544. +int skl_int3472_discrete_remove(struct platform_device *pdev)
  1545. +{
  1546. + struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
  1547. +
  1548. + gpiod_remove_lookup_table(&int3472->gpios);
  1549. + regulator_unregister(int3472->regulator.rdev);
  1550. + clk_unregister(int3472->clock.clk);
  1551. +
  1552. + if (int3472->clock.cl)
  1553. + clkdev_drop(int3472->clock.cl);
  1554. +
  1555. + gpiod_put(int3472->regulator.gpio);
  1556. + gpiod_put(int3472->clock.ena_gpio);
  1557. + gpiod_put(int3472->clock.led_gpio);
  1558. +
  1559. + return 0;
  1560. +}
  1561. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_tps68470.c
  1562. new file mode 100644
  1563. index 000000000000..c05b4cf502fe
  1564. --- /dev/null
  1565. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_tps68470.c
  1566. @@ -0,0 +1,137 @@
  1567. +// SPDX-License-Identifier: GPL-2.0
  1568. +/* Author: Dan Scally <djrscally@gmail.com> */
  1569. +
  1570. +#include <linux/i2c.h>
  1571. +#include <linux/mfd/core.h>
  1572. +#include <linux/mfd/tps68470.h>
  1573. +#include <linux/platform_device.h>
  1574. +#include <linux/regmap.h>
  1575. +
  1576. +#include "intel_skl_int3472_common.h"
  1577. +
  1578. +#define DESIGNED_FOR_CHROMEOS 1
  1579. +#define DESIGNED_FOR_WINDOWS 2
  1580. +
  1581. +static const struct mfd_cell tps68470_cros[] = {
  1582. + { .name = "tps68470-gpio" },
  1583. + { .name = "tps68470_pmic_opregion" },
  1584. +};
  1585. +
  1586. +static const struct mfd_cell tps68470_win[] = {
  1587. + { .name = "tps68470-gpio" },
  1588. + { .name = "tps68470-clk" },
  1589. + { .name = "tps68470-regulator" },
  1590. +};
  1591. +
  1592. +static const struct regmap_config tps68470_regmap_config = {
  1593. + .reg_bits = 8,
  1594. + .val_bits = 8,
  1595. + .max_register = TPS68470_REG_MAX,
  1596. +};
  1597. +
  1598. +static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
  1599. +{
  1600. + unsigned int version;
  1601. + int ret;
  1602. +
  1603. + /* Force software reset */
  1604. + ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
  1605. + if (ret)
  1606. + return ret;
  1607. +
  1608. + ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
  1609. + if (ret) {
  1610. + dev_err(dev, "Failed to read revision register: %d\n", ret);
  1611. + return ret;
  1612. + }
  1613. +
  1614. + dev_info(dev, "TPS68470 REVID: 0x%02x\n", version);
  1615. +
  1616. + return 0;
  1617. +}
  1618. +
  1619. +/** skl_int3472_tps68470_calc_type: Check what platform a device is designed for
  1620. + * @adev: A pointer to a &struct acpi_device
  1621. + *
  1622. + * Check CLDB buffer against the PMIC's adev. If present, then we check
  1623. + * the value of control_logic_type field and follow one of the
  1624. + * following scenarios:
  1625. + *
  1626. + * 1. No CLDB - likely ACPI tables designed for ChromeOS. We
  1627. + * create platform devices for the GPIOs and OpRegion drivers.
  1628. + *
  1629. + * 2. CLDB, with control_logic_type = 2 - probably ACPI tables
  1630. + * made for Windows 2-in-1 platforms. Register pdevs for GPIO,
  1631. + * Clock and Regulator drivers to bind to.
  1632. + *
  1633. + * 3. Any other value in control_logic_type, we should never have
  1634. + * gotten to this point; fail probe and return.
  1635. + *
  1636. + * Return:
  1637. + * * 1 Device intended for ChromeOS
  1638. + * * 2 Device intended for Windows
  1639. + * * -EINVAL Where @adev has an object named CLDB but it does not conform to
  1640. + * our expectations
  1641. + */
  1642. +static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
  1643. +{
  1644. + struct int3472_cldb cldb = { 0 };
  1645. + int ret;
  1646. +
  1647. + /*
  1648. + * A CLDB buffer that exists, but which does not match our expectations
  1649. + * should trigger an error so we don't blindly continue.
  1650. + */
  1651. + ret = skl_int3472_fill_cldb(adev, &cldb);
  1652. + if (ret && ret != -ENODEV)
  1653. + return ret;
  1654. +
  1655. + if (ret)
  1656. + return DESIGNED_FOR_CHROMEOS;
  1657. +
  1658. + if (cldb.control_logic_type != 2)
  1659. + return -EINVAL;
  1660. +
  1661. + return DESIGNED_FOR_WINDOWS;
  1662. +}
  1663. +
  1664. +int skl_int3472_tps68470_probe(struct i2c_client *client)
  1665. +{
  1666. + struct acpi_device *adev = ACPI_COMPANION(&client->dev);
  1667. + struct regmap *regmap;
  1668. + int device_type;
  1669. + int ret;
  1670. +
  1671. + regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
  1672. + if (IS_ERR(regmap)) {
  1673. + dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
  1674. + return PTR_ERR(regmap);
  1675. + }
  1676. +
  1677. + i2c_set_clientdata(client, regmap);
  1678. +
  1679. + ret = tps68470_chip_init(&client->dev, regmap);
  1680. + if (ret < 0) {
  1681. + dev_err(&client->dev, "TPS68470 init error %d\n", ret);
  1682. + return ret;
  1683. + }
  1684. +
  1685. + device_type = skl_int3472_tps68470_calc_type(adev);
  1686. + switch (device_type) {
  1687. + case DESIGNED_FOR_WINDOWS:
  1688. + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
  1689. + tps68470_win, ARRAY_SIZE(tps68470_win),
  1690. + NULL, 0, NULL);
  1691. + break;
  1692. + case DESIGNED_FOR_CHROMEOS:
  1693. + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
  1694. + tps68470_cros, ARRAY_SIZE(tps68470_cros),
  1695. + NULL, 0, NULL);
  1696. + break;
  1697. + default:
  1698. + dev_err(&client->dev, "Failed to add MFD devices\n");
  1699. + return device_type;
  1700. + }
  1701. +
  1702. + return ret;
  1703. +}
  1704. --
  1705. 2.33.0
  1706. From 06899d0ea5e8fa1e6d3ab17c3b59e9d9bdea4980 Mon Sep 17 00:00:00 2001
  1707. From: Daniel Scally <djrscally@gmail.com>
  1708. Date: Thu, 3 Jun 2021 23:40:07 +0100
  1709. Subject: [PATCH] mfd: tps68470: Remove tps68470 MFD driver
  1710. This driver only covered one scenario in which ACPI devices with _HID
  1711. INT3472 are found, and its functionality has been taken over by the
  1712. intel-skl-int3472 module, so remove it.
  1713. Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
  1714. Acked-by: Lee Jones <lee.jones@linaro.org>
  1715. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  1716. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  1717. Link: https://lore.kernel.org/r/20210603224007.120560-7-djrscally@gmail.com
  1718. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  1719. Patchset: cameras
  1720. ---
  1721. drivers/acpi/pmic/Kconfig | 2 +-
  1722. drivers/gpio/Kconfig | 2 +-
  1723. drivers/mfd/Kconfig | 18 --------
  1724. drivers/mfd/Makefile | 1 -
  1725. drivers/mfd/tps68470.c | 97 ---------------------------------------
  1726. 5 files changed, 2 insertions(+), 118 deletions(-)
  1727. delete mode 100644 drivers/mfd/tps68470.c
  1728. diff --git a/drivers/acpi/pmic/Kconfig b/drivers/acpi/pmic/Kconfig
  1729. index 56bbcb2ce61b..f84b8f6038dc 100644
  1730. --- a/drivers/acpi/pmic/Kconfig
  1731. +++ b/drivers/acpi/pmic/Kconfig
  1732. @@ -52,7 +52,7 @@ endif # PMIC_OPREGION
  1733. config TPS68470_PMIC_OPREGION
  1734. bool "ACPI operation region support for TPS68470 PMIC"
  1735. - depends on MFD_TPS68470
  1736. + depends on INTEL_SKL_INT3472
  1737. help
  1738. This config adds ACPI operation region support for TI TPS68470 PMIC.
  1739. TPS68470 device is an advanced power management unit that powers
  1740. diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
  1741. index 3c69b785cb79..63b84ba161dc 100644
  1742. --- a/drivers/gpio/Kconfig
  1743. +++ b/drivers/gpio/Kconfig
  1744. @@ -1367,7 +1367,7 @@ config GPIO_TPS65912
  1745. config GPIO_TPS68470
  1746. bool "TPS68470 GPIO"
  1747. - depends on MFD_TPS68470
  1748. + depends on INTEL_SKL_INT3472
  1749. help
  1750. Select this option to enable GPIO driver for the TPS68470
  1751. chip family.
  1752. diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
  1753. index 5c408c1dc58c..ace0d1b8f55c 100644
  1754. --- a/drivers/mfd/Kconfig
  1755. +++ b/drivers/mfd/Kconfig
  1756. @@ -1500,24 +1500,6 @@ config MFD_TPS65217
  1757. This driver can also be built as a module. If so, the module
  1758. will be called tps65217.
  1759. -config MFD_TPS68470
  1760. - bool "TI TPS68470 Power Management / LED chips"
  1761. - depends on ACPI && PCI && I2C=y
  1762. - depends on I2C_DESIGNWARE_PLATFORM=y
  1763. - select MFD_CORE
  1764. - select REGMAP_I2C
  1765. - help
  1766. - If you say yes here you get support for the TPS68470 series of
  1767. - Power Management / LED chips.
  1768. -
  1769. - These include voltage regulators, LEDs and other features
  1770. - that are often used in portable devices.
  1771. -
  1772. - This option is a bool as it provides an ACPI operation
  1773. - region, which must be available before any of the devices
  1774. - using this are probed. This option also configures the
  1775. - designware-i2c driver to be built-in, for the same reason.
  1776. -
  1777. config MFD_TI_LP873X
  1778. tristate "TI LP873X Power Management IC"
  1779. depends on I2C
  1780. diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
  1781. index 4f6d2b8a5f76..8b322d89a0c5 100644
  1782. --- a/drivers/mfd/Makefile
  1783. +++ b/drivers/mfd/Makefile
  1784. @@ -105,7 +105,6 @@ obj-$(CONFIG_MFD_TPS65910) += tps65910.o
  1785. obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
  1786. obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
  1787. obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
  1788. -obj-$(CONFIG_MFD_TPS68470) += tps68470.o
  1789. obj-$(CONFIG_MFD_TPS80031) += tps80031.o
  1790. obj-$(CONFIG_MENELAUS) += menelaus.o
  1791. diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c
  1792. deleted file mode 100644
  1793. index 4a4df4ffd18c..000000000000
  1794. --- a/drivers/mfd/tps68470.c
  1795. +++ /dev/null
  1796. @@ -1,97 +0,0 @@
  1797. -// SPDX-License-Identifier: GPL-2.0
  1798. -/*
  1799. - * TPS68470 chip Parent driver
  1800. - *
  1801. - * Copyright (C) 2017 Intel Corporation
  1802. - *
  1803. - * Authors:
  1804. - * Rajmohan Mani <rajmohan.mani@intel.com>
  1805. - * Tianshu Qiu <tian.shu.qiu@intel.com>
  1806. - * Jian Xu Zheng <jian.xu.zheng@intel.com>
  1807. - * Yuning Pu <yuning.pu@intel.com>
  1808. - */
  1809. -
  1810. -#include <linux/acpi.h>
  1811. -#include <linux/delay.h>
  1812. -#include <linux/i2c.h>
  1813. -#include <linux/init.h>
  1814. -#include <linux/mfd/core.h>
  1815. -#include <linux/mfd/tps68470.h>
  1816. -#include <linux/regmap.h>
  1817. -
  1818. -static const struct mfd_cell tps68470s[] = {
  1819. - { .name = "tps68470-gpio" },
  1820. - { .name = "tps68470_pmic_opregion" },
  1821. -};
  1822. -
  1823. -static const struct regmap_config tps68470_regmap_config = {
  1824. - .reg_bits = 8,
  1825. - .val_bits = 8,
  1826. - .max_register = TPS68470_REG_MAX,
  1827. -};
  1828. -
  1829. -static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
  1830. -{
  1831. - unsigned int version;
  1832. - int ret;
  1833. -
  1834. - /* Force software reset */
  1835. - ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
  1836. - if (ret)
  1837. - return ret;
  1838. -
  1839. - ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
  1840. - if (ret) {
  1841. - dev_err(dev, "Failed to read revision register: %d\n", ret);
  1842. - return ret;
  1843. - }
  1844. -
  1845. - dev_info(dev, "TPS68470 REVID: 0x%x\n", version);
  1846. -
  1847. - return 0;
  1848. -}
  1849. -
  1850. -static int tps68470_probe(struct i2c_client *client)
  1851. -{
  1852. - struct device *dev = &client->dev;
  1853. - struct regmap *regmap;
  1854. - int ret;
  1855. -
  1856. - regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
  1857. - if (IS_ERR(regmap)) {
  1858. - dev_err(dev, "devm_regmap_init_i2c Error %ld\n",
  1859. - PTR_ERR(regmap));
  1860. - return PTR_ERR(regmap);
  1861. - }
  1862. -
  1863. - i2c_set_clientdata(client, regmap);
  1864. -
  1865. - ret = tps68470_chip_init(dev, regmap);
  1866. - if (ret < 0) {
  1867. - dev_err(dev, "TPS68470 Init Error %d\n", ret);
  1868. - return ret;
  1869. - }
  1870. -
  1871. - ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, tps68470s,
  1872. - ARRAY_SIZE(tps68470s), NULL, 0, NULL);
  1873. - if (ret < 0) {
  1874. - dev_err(dev, "devm_mfd_add_devices failed: %d\n", ret);
  1875. - return ret;
  1876. - }
  1877. -
  1878. - return 0;
  1879. -}
  1880. -
  1881. -static const struct acpi_device_id tps68470_acpi_ids[] = {
  1882. - {"INT3472"},
  1883. - {},
  1884. -};
  1885. -
  1886. -static struct i2c_driver tps68470_driver = {
  1887. - .driver = {
  1888. - .name = "tps68470",
  1889. - .acpi_match_table = tps68470_acpi_ids,
  1890. - },
  1891. - .probe_new = tps68470_probe,
  1892. -};
  1893. -builtin_i2c_driver(tps68470_driver);
  1894. --
  1895. 2.33.0
  1896. From 375118c70ce1ecc24b7729f0f48c487fa24418aa Mon Sep 17 00:00:00 2001
  1897. From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1898. Date: Fri, 18 Jun 2021 15:55:10 +0300
  1899. Subject: [PATCH] platform/x86: intel_skl_int3472: Free ACPI device resources
  1900. after use
  1901. We may free ACPI device resources immediately after use.
  1902. Refactor skl_int3472_parse_crs() accordingly.
  1903. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1904. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  1905. Tested-by: Daniel Scally <djrscally@gmail.com>
  1906. Link: https://lore.kernel.org/r/20210618125516.53510-2-andriy.shevchenko@linux.intel.com
  1907. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  1908. Patchset: cameras
  1909. ---
  1910. .../x86/intel-int3472/intel_skl_int3472_discrete.c | 13 ++++++-------
  1911. 1 file changed, 6 insertions(+), 7 deletions(-)
  1912. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  1913. index 8c18dbff1c43..48a00a1f4fb6 100644
  1914. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  1915. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  1916. @@ -308,8 +308,10 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
  1917. ret = acpi_dev_get_resources(int3472->adev, &resource_list,
  1918. skl_int3472_handle_gpio_resources,
  1919. int3472);
  1920. - if (ret)
  1921. - goto out_free_res_list;
  1922. + if (ret < 0)
  1923. + return ret;
  1924. +
  1925. + acpi_dev_free_resource_list(&resource_list);
  1926. /*
  1927. * If we find no clock enable GPIO pin then the privacy LED won't work.
  1928. @@ -319,7 +321,7 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
  1929. if (int3472->clock.ena_gpio) {
  1930. ret = skl_int3472_register_clock(int3472);
  1931. if (ret)
  1932. - goto out_free_res_list;
  1933. + return ret;
  1934. } else {
  1935. if (int3472->clock.led_gpio)
  1936. dev_warn(int3472->dev,
  1937. @@ -329,10 +331,7 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
  1938. int3472->gpios.dev_id = int3472->sensor_name;
  1939. gpiod_add_lookup_table(&int3472->gpios);
  1940. -out_free_res_list:
  1941. - acpi_dev_free_resource_list(&resource_list);
  1942. -
  1943. - return ret;
  1944. + return 0;
  1945. }
  1946. int skl_int3472_discrete_probe(struct platform_device *pdev)
  1947. --
  1948. 2.33.0
  1949. From a15fa9ed6d6509ad6e11721f34bfb79f8e292128 Mon Sep 17 00:00:00 2001
  1950. From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1951. Date: Fri, 18 Jun 2021 15:55:11 +0300
  1952. Subject: [PATCH] platform/x86: intel_skl_int3472: Fix dependencies (drop
  1953. CLKDEV_LOOKUP)
  1954. Besides the fact that COMMON_CLK selects CLKDEV_LOOKUP, the latter
  1955. is going to be removed from clock framework.
  1956. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  1957. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1958. Link: https://lore.kernel.org/r/20210618125516.53510-3-andriy.shevchenko@linux.intel.com
  1959. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  1960. Patchset: cameras
  1961. ---
  1962. drivers/platform/x86/intel-int3472/Kconfig | 2 +-
  1963. 1 file changed, 1 insertion(+), 1 deletion(-)
  1964. diff --git a/drivers/platform/x86/intel-int3472/Kconfig b/drivers/platform/x86/intel-int3472/Kconfig
  1965. index c112878e833b..62e5d4cf9ee5 100644
  1966. --- a/drivers/platform/x86/intel-int3472/Kconfig
  1967. +++ b/drivers/platform/x86/intel-int3472/Kconfig
  1968. @@ -1,7 +1,7 @@
  1969. config INTEL_SKL_INT3472
  1970. tristate "Intel SkyLake ACPI INT3472 Driver"
  1971. depends on ACPI
  1972. - depends on COMMON_CLK && CLKDEV_LOOKUP
  1973. + depends on COMMON_CLK
  1974. depends on I2C
  1975. depends on GPIOLIB
  1976. depends on REGULATOR
  1977. --
  1978. 2.33.0
  1979. From 687cd00f086741323a81dfb1290a3723b9485ce2 Mon Sep 17 00:00:00 2001
  1980. From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1981. Date: Fri, 18 Jun 2021 15:55:12 +0300
  1982. Subject: [PATCH] platform/x86: intel_skl_int3472: Use ACPI GPIO resource
  1983. directly
  1984. When we call acpi_gpio_get_io_resource(), the output will be
  1985. the pointer to the ACPI GPIO resource. Use it directly instead of
  1986. dereferencing the generic resource.
  1987. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  1988. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  1989. Tested-by: Daniel Scally <djrscally@gmail.com>
  1990. Link: https://lore.kernel.org/r/20210618125516.53510-4-andriy.shevchenko@linux.intel.com
  1991. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  1992. Patchset: cameras
  1993. ---
  1994. .../intel_skl_int3472_clk_and_regulator.c | 7 ++---
  1995. .../intel-int3472/intel_skl_int3472_common.h | 2 +-
  1996. .../intel_skl_int3472_discrete.c | 28 +++++++++----------
  1997. 3 files changed, 17 insertions(+), 20 deletions(-)
  1998. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  1999. index ceee860e2c07..49ea1e86c193 100644
  2000. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2001. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2002. @@ -131,10 +131,10 @@ int skl_int3472_register_clock(struct int3472_discrete_device *int3472)
  2003. }
  2004. int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2005. - struct acpi_resource *ares)
  2006. + struct acpi_resource_gpio *agpio)
  2007. {
  2008. - char *path = ares->data.gpio.resource_source.string_ptr;
  2009. const struct int3472_sensor_config *sensor_config;
  2010. + char *path = agpio->resource_source.string_ptr;
  2011. struct regulator_consumer_supply supply_map;
  2012. struct regulator_init_data init_data = { };
  2013. struct regulator_config cfg = { };
  2014. @@ -168,8 +168,7 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2015. int3472->regulator.supply_name,
  2016. &int3472_gpio_regulator_ops);
  2017. - int3472->regulator.gpio = acpi_get_and_request_gpiod(path,
  2018. - ares->data.gpio.pin_table[0],
  2019. + int3472->regulator.gpio = acpi_get_and_request_gpiod(path, agpio->pin_table[0],
  2020. "int3472,regulator");
  2021. if (IS_ERR(int3472->regulator.gpio)) {
  2022. dev_err(int3472->dev, "Failed to get regulator GPIO line\n");
  2023. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2024. index 6fdf78584219..765e01ec1604 100644
  2025. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2026. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2027. @@ -113,6 +113,6 @@ union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
  2028. int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
  2029. int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
  2030. int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2031. - struct acpi_resource *ares);
  2032. + struct acpi_resource_gpio *agpio);
  2033. #endif
  2034. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2035. index 48a00a1f4fb6..fd681d2a73fe 100644
  2036. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2037. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2038. @@ -103,11 +103,11 @@ skl_int3472_get_sensor_module_config(struct int3472_discrete_device *int3472)
  2039. }
  2040. static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472,
  2041. - struct acpi_resource *ares,
  2042. + struct acpi_resource_gpio *agpio,
  2043. const char *func, u32 polarity)
  2044. {
  2045. - char *path = ares->data.gpio.resource_source.string_ptr;
  2046. const struct int3472_sensor_config *sensor_config;
  2047. + char *path = agpio->resource_source.string_ptr;
  2048. struct gpiod_lookup *table_entry;
  2049. struct acpi_device *adev;
  2050. acpi_handle handle;
  2051. @@ -145,7 +145,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
  2052. table_entry = &int3472->gpios.table[int3472->n_sensor_gpios];
  2053. table_entry->key = acpi_dev_name(adev);
  2054. - table_entry->chip_hwnum = ares->data.gpio.pin_table[0];
  2055. + table_entry->chip_hwnum = agpio->pin_table[0];
  2056. table_entry->con_id = func;
  2057. table_entry->idx = 0;
  2058. table_entry->flags = polarity;
  2059. @@ -156,23 +156,22 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
  2060. }
  2061. static int skl_int3472_map_gpio_to_clk(struct int3472_discrete_device *int3472,
  2062. - struct acpi_resource *ares, u8 type)
  2063. + struct acpi_resource_gpio *agpio, u8 type)
  2064. {
  2065. - char *path = ares->data.gpio.resource_source.string_ptr;
  2066. + char *path = agpio->resource_source.string_ptr;
  2067. + u16 pin = agpio->pin_table[0];
  2068. struct gpio_desc *gpio;
  2069. switch (type) {
  2070. case INT3472_GPIO_TYPE_CLK_ENABLE:
  2071. - gpio = acpi_get_and_request_gpiod(path, ares->data.gpio.pin_table[0],
  2072. - "int3472,clk-enable");
  2073. + gpio = acpi_get_and_request_gpiod(path, pin, "int3472,clk-enable");
  2074. if (IS_ERR(gpio))
  2075. return (PTR_ERR(gpio));
  2076. int3472->clock.ena_gpio = gpio;
  2077. break;
  2078. case INT3472_GPIO_TYPE_PRIVACY_LED:
  2079. - gpio = acpi_get_and_request_gpiod(path, ares->data.gpio.pin_table[0],
  2080. - "int3472,privacy-led");
  2081. + gpio = acpi_get_and_request_gpiod(path, pin, "int3472,privacy-led");
  2082. if (IS_ERR(gpio))
  2083. return (PTR_ERR(gpio));
  2084. @@ -242,7 +241,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
  2085. if (!obj) {
  2086. dev_warn(int3472->dev, "No _DSM entry for GPIO pin %u\n",
  2087. - ares->data.gpio.pin_table[0]);
  2088. + agpio->pin_table[0]);
  2089. return 1;
  2090. }
  2091. @@ -250,15 +249,14 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
  2092. switch (type) {
  2093. case INT3472_GPIO_TYPE_RESET:
  2094. - ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "reset",
  2095. + ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "reset",
  2096. GPIO_ACTIVE_LOW);
  2097. if (ret)
  2098. err_msg = "Failed to map reset pin to sensor\n";
  2099. break;
  2100. case INT3472_GPIO_TYPE_POWERDOWN:
  2101. - ret = skl_int3472_map_gpio_to_sensor(int3472, ares,
  2102. - "powerdown",
  2103. + ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "powerdown",
  2104. GPIO_ACTIVE_LOW);
  2105. if (ret)
  2106. err_msg = "Failed to map powerdown pin to sensor\n";
  2107. @@ -266,13 +264,13 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
  2108. break;
  2109. case INT3472_GPIO_TYPE_CLK_ENABLE:
  2110. case INT3472_GPIO_TYPE_PRIVACY_LED:
  2111. - ret = skl_int3472_map_gpio_to_clk(int3472, ares, type);
  2112. + ret = skl_int3472_map_gpio_to_clk(int3472, agpio, type);
  2113. if (ret)
  2114. err_msg = "Failed to map GPIO to clock\n";
  2115. break;
  2116. case INT3472_GPIO_TYPE_POWER_ENABLE:
  2117. - ret = skl_int3472_register_regulator(int3472, ares);
  2118. + ret = skl_int3472_register_regulator(int3472, agpio);
  2119. if (ret)
  2120. err_msg = "Failed to map regulator to sensor\n";
  2121. --
  2122. 2.33.0
  2123. From 110d7885979dad5b0d6beb81369d93c3cc38d0d8 Mon Sep 17 00:00:00 2001
  2124. From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  2125. Date: Fri, 18 Jun 2021 15:55:13 +0300
  2126. Subject: [PATCH] platform/x86: intel_skl_int3472: Provide
  2127. skl_int3472_unregister_regulator()
  2128. For the sake of APIs to be properly layered provide
  2129. skl_int3472_unregister_regulator().
  2130. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  2131. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  2132. Tested-by: Daniel Scally <djrscally@gmail.com>
  2133. Link: https://lore.kernel.org/r/20210618125516.53510-5-andriy.shevchenko@linux.intel.com
  2134. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  2135. Patchset: cameras
  2136. ---
  2137. .../x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c | 6 ++++++
  2138. .../platform/x86/intel-int3472/intel_skl_int3472_common.h | 2 ++
  2139. .../platform/x86/intel-int3472/intel_skl_int3472_discrete.c | 4 ++--
  2140. 3 files changed, 10 insertions(+), 2 deletions(-)
  2141. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2142. index 49ea1e86c193..60c7128f44ee 100644
  2143. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2144. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2145. @@ -193,3 +193,9 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2146. return ret;
  2147. }
  2148. +
  2149. +void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472)
  2150. +{
  2151. + regulator_unregister(int3472->regulator.rdev);
  2152. + gpiod_put(int3472->regulator.gpio);
  2153. +}
  2154. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2155. index 765e01ec1604..50f73c6eab44 100644
  2156. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2157. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2158. @@ -112,7 +112,9 @@ union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
  2159. char *id);
  2160. int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
  2161. int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
  2162. +
  2163. int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2164. struct acpi_resource_gpio *agpio);
  2165. +void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472);
  2166. #endif
  2167. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2168. index fd681d2a73fe..2638d375e226 100644
  2169. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2170. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2171. @@ -400,15 +400,15 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
  2172. struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
  2173. gpiod_remove_lookup_table(&int3472->gpios);
  2174. - regulator_unregister(int3472->regulator.rdev);
  2175. clk_unregister(int3472->clock.clk);
  2176. if (int3472->clock.cl)
  2177. clkdev_drop(int3472->clock.cl);
  2178. - gpiod_put(int3472->regulator.gpio);
  2179. gpiod_put(int3472->clock.ena_gpio);
  2180. gpiod_put(int3472->clock.led_gpio);
  2181. + skl_int3472_unregister_regulator(int3472);
  2182. +
  2183. return 0;
  2184. }
  2185. --
  2186. 2.33.0
  2187. From 41625860cfb0264e6b3f575bd3c7330ce3df59e0 Mon Sep 17 00:00:00 2001
  2188. From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  2189. Date: Fri, 18 Jun 2021 15:55:14 +0300
  2190. Subject: [PATCH] platform/x86: intel_skl_int3472: Provide
  2191. skl_int3472_unregister_clock()
  2192. For the sake of APIs to be properly layered provide
  2193. skl_int3472_unregister_clock().
  2194. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  2195. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  2196. Tested-by: Daniel Scally <djrscally@gmail.com>
  2197. Link: https://lore.kernel.org/r/20210618125516.53510-6-andriy.shevchenko@linux.intel.com
  2198. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  2199. Patchset: cameras
  2200. ---
  2201. .../x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c | 6 ++++++
  2202. .../platform/x86/intel-int3472/intel_skl_int3472_common.h | 2 ++
  2203. .../platform/x86/intel-int3472/intel_skl_int3472_discrete.c | 5 ++---
  2204. 3 files changed, 10 insertions(+), 3 deletions(-)
  2205. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2206. index 60c7128f44ee..1700e7557a82 100644
  2207. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2208. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_clk_and_regulator.c
  2209. @@ -130,6 +130,12 @@ int skl_int3472_register_clock(struct int3472_discrete_device *int3472)
  2210. return ret;
  2211. }
  2212. +void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472)
  2213. +{
  2214. + clkdev_drop(int3472->clock.cl);
  2215. + clk_unregister(int3472->clock.clk);
  2216. +}
  2217. +
  2218. int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2219. struct acpi_resource_gpio *agpio)
  2220. {
  2221. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2222. index 50f73c6eab44..714fde73b524 100644
  2223. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2224. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_common.h
  2225. @@ -111,7 +111,9 @@ int skl_int3472_tps68470_probe(struct i2c_client *client);
  2226. union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
  2227. char *id);
  2228. int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
  2229. +
  2230. int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
  2231. +void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
  2232. int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
  2233. struct acpi_resource_gpio *agpio);
  2234. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2235. index 2638d375e226..17c6fe830765 100644
  2236. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2237. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2238. @@ -400,10 +400,9 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
  2239. struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
  2240. gpiod_remove_lookup_table(&int3472->gpios);
  2241. - clk_unregister(int3472->clock.clk);
  2242. - if (int3472->clock.cl)
  2243. - clkdev_drop(int3472->clock.cl);
  2244. + if (int3472->clock.ena_gpio)
  2245. + skl_int3472_unregister_clock(int3472);
  2246. gpiod_put(int3472->clock.ena_gpio);
  2247. gpiod_put(int3472->clock.led_gpio);
  2248. --
  2249. 2.33.0
  2250. From 7be2b7369e4bb716b797c5532f8381d73fd941e0 Mon Sep 17 00:00:00 2001
  2251. From: Dan Carpenter <dan.carpenter@oracle.com>
  2252. Date: Fri, 25 Jun 2021 16:01:04 +0300
  2253. Subject: [PATCH] platform/x86: intel_skl_int3472: Uninitialized variable in
  2254. skl_int3472_handle_gpio_resources()
  2255. This function returns negative error codes, zero (to indicate that
  2256. everything has been completed successfully) and one (to indicate that
  2257. more resources need to be handled still).
  2258. This code prints an uninitialized error message when the function
  2259. returns one which potentially leads to an Oops.
  2260. Fixes: 5de691bffe57 ("platform/x86: Add intel_skl_int3472 driver")
  2261. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
  2262. Reviewed-by: Daniel Scally <djrscally@gmail.com>
  2263. Link: https://lore.kernel.org/r/YNXTkLNtiTDlFlZa@mwanda
  2264. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  2265. Patchset: cameras
  2266. ---
  2267. .../platform/x86/intel-int3472/intel_skl_int3472_discrete.c | 4 ++--
  2268. 1 file changed, 2 insertions(+), 2 deletions(-)
  2269. diff --git a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2270. index 17c6fe830765..9fe0a2527e1c 100644
  2271. --- a/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2272. +++ b/drivers/platform/x86/intel-int3472/intel_skl_int3472_discrete.c
  2273. @@ -286,10 +286,10 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
  2274. int3472->ngpios++;
  2275. ACPI_FREE(obj);
  2276. - if (ret)
  2277. + if (ret < 0)
  2278. return dev_err_probe(int3472->dev, ret, err_msg);
  2279. - return 0;
  2280. + return ret;
  2281. }
  2282. static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
  2283. --
  2284. 2.33.0
  2285. From 0487dd4fbc6e26a0e03cae276049d094cfa6c448 Mon Sep 17 00:00:00 2001
  2286. From: Daniel Scally <djrscally@gmail.com>
  2287. Date: Mon, 5 Apr 2021 23:56:53 +0100
  2288. Subject: [PATCH] media: ipu3-cio2: Toggle sensor streaming in pm runtime ops
  2289. The .suspend() and .resume() runtime_pm operations for the ipu3-cio2
  2290. driver currently do not handle the sensor's stream. Setting .s_stream() on
  2291. or off for the sensor subdev means that sensors will pause and resume the
  2292. stream at the appropriate time even if their drivers don't implement those
  2293. operations.
  2294. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2295. Patchset: cameras
  2296. ---
  2297. drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 15 ++++++++++++++-
  2298. 1 file changed, 14 insertions(+), 1 deletion(-)
  2299. diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  2300. index fecef85bd62e..9dafb9470708 100644
  2301. --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  2302. +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  2303. @@ -1973,12 +1973,19 @@ static int __maybe_unused cio2_suspend(struct device *dev)
  2304. struct pci_dev *pci_dev = to_pci_dev(dev);
  2305. struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
  2306. struct cio2_queue *q = cio2->cur_queue;
  2307. + int r;
  2308. dev_dbg(dev, "cio2 suspend\n");
  2309. if (!cio2->streaming)
  2310. return 0;
  2311. /* Stop stream */
  2312. + r = v4l2_subdev_call(q->sensor, video, s_stream, 0);
  2313. + if (r) {
  2314. + dev_err(dev, "failed to stop sensor streaming\n");
  2315. + return r;
  2316. + }
  2317. +
  2318. cio2_hw_exit(cio2, q);
  2319. synchronize_irq(pci_dev->irq);
  2320. @@ -2013,8 +2020,14 @@ static int __maybe_unused cio2_resume(struct device *dev)
  2321. }
  2322. r = cio2_hw_init(cio2, q);
  2323. - if (r)
  2324. + if (r) {
  2325. dev_err(dev, "fail to init cio2 hw\n");
  2326. + return r;
  2327. + }
  2328. +
  2329. + r = v4l2_subdev_call(q->sensor, video, s_stream, 1);
  2330. + if (r)
  2331. + dev_err(dev, "fail to start sensor streaming\n");
  2332. return r;
  2333. }
  2334. --
  2335. 2.33.0
  2336. From d4d0ceeedc1d0f728e8eca398e88bfcb848cb99d Mon Sep 17 00:00:00 2001
  2337. From: Daniel Scally <djrscally@gmail.com>
  2338. Date: Mon, 5 Apr 2021 23:56:54 +0100
  2339. Subject: [PATCH] media: i2c: Add support for ov5693 sensor
  2340. The OV5693 is a 5 Mpx CMOS image sensor, connected via MIPI CSI-2. The
  2341. chip is capable of a single lane configuration, but currently only two
  2342. lanes are supported.
  2343. Most of the sensor's features are supported, with the main exception
  2344. being the lens correction algorithm.
  2345. The driver provides all mandatory, optional and recommended V4L2 controls
  2346. for maximum compatibility with libcamera.
  2347. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2348. Patchset: cameras
  2349. ---
  2350. MAINTAINERS | 7 +
  2351. drivers/media/i2c/Kconfig | 11 +
  2352. drivers/media/i2c/Makefile | 1 +
  2353. drivers/media/i2c/ov5693.c | 1557 ++++++++++++++++++++++++++++++++++++
  2354. 4 files changed, 1576 insertions(+)
  2355. create mode 100644 drivers/media/i2c/ov5693.c
  2356. diff --git a/MAINTAINERS b/MAINTAINERS
  2357. index 1db7311d78a6..567a5b64d297 100644
  2358. --- a/MAINTAINERS
  2359. +++ b/MAINTAINERS
  2360. @@ -13563,6 +13563,13 @@ S: Maintained
  2361. T: git git://linuxtv.org/media_tree.git
  2362. F: drivers/media/i2c/ov5675.c
  2363. +OMNIVISION OV5693 SENSOR DRIVER
  2364. +M: Daniel Scally <djrscally@gmail.com>
  2365. +L: linux-media@vger.kernel.org
  2366. +S: Maintained
  2367. +T: git git://linuxtv.org/media_tree.git
  2368. +F: drivers/media/i2c/ov5693.c
  2369. +
  2370. OMNIVISION OV5695 SENSOR DRIVER
  2371. M: Shunqian Zheng <zhengsq@rock-chips.com>
  2372. L: linux-media@vger.kernel.org
  2373. diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
  2374. index 462c0e059754..2893e74af99a 100644
  2375. --- a/drivers/media/i2c/Kconfig
  2376. +++ b/drivers/media/i2c/Kconfig
  2377. @@ -999,6 +999,17 @@ config VIDEO_OV5675
  2378. To compile this driver as a module, choose M here: the
  2379. module will be called ov5675.
  2380. +config VIDEO_OV5693
  2381. + tristate "OmniVision OV5693 sensor support"
  2382. + depends on I2C && VIDEO_V4L2
  2383. + select V4L2_FWNODE
  2384. + help
  2385. + This is a Video4Linux2 sensor driver for the OmniVision
  2386. + OV5693 camera.
  2387. +
  2388. + To compile this driver as a module, choose M here: the
  2389. + module will be called ov5693.
  2390. +
  2391. config VIDEO_OV5695
  2392. tristate "OmniVision OV5695 sensor support"
  2393. depends on I2C && VIDEO_V4L2
  2394. diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
  2395. index 0c067beca066..7d0884bc89f1 100644
  2396. --- a/drivers/media/i2c/Makefile
  2397. +++ b/drivers/media/i2c/Makefile
  2398. @@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
  2399. obj-$(CONFIG_VIDEO_OV5648) += ov5648.o
  2400. obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
  2401. obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
  2402. +obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
  2403. obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
  2404. obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
  2405. obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
  2406. diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
  2407. new file mode 100644
  2408. index 000000000000..276f625d4d23
  2409. --- /dev/null
  2410. +++ b/drivers/media/i2c/ov5693.c
  2411. @@ -0,0 +1,1557 @@
  2412. +// SPDX-License-Identifier: GPL-2.0
  2413. +/*
  2414. + * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
  2415. + *
  2416. + * Adapted from the atomisp-ov5693 driver, with contributions from:
  2417. + *
  2418. + * Daniel Scally
  2419. + * Jean-Michel Hautbois
  2420. + * Fabian Wuthrich
  2421. + * Tsuchiya Yuto
  2422. + * Jordan Hand
  2423. + * Jake Day
  2424. + */
  2425. +
  2426. +#include <asm/unaligned.h>
  2427. +#include <linux/acpi.h>
  2428. +#include <linux/clk.h>
  2429. +#include <linux/delay.h>
  2430. +#include <linux/device.h>
  2431. +#include <linux/i2c.h>
  2432. +#include <linux/module.h>
  2433. +#include <linux/pm_runtime.h>
  2434. +#include <linux/regulator/consumer.h>
  2435. +#include <linux/slab.h>
  2436. +#include <linux/types.h>
  2437. +#include <media/v4l2-ctrls.h>
  2438. +#include <media/v4l2-device.h>
  2439. +#include <media/v4l2-fwnode.h>
  2440. +
  2441. +/* System Control */
  2442. +#define OV5693_SW_RESET_REG 0x0103
  2443. +#define OV5693_SW_STREAM_REG 0x0100
  2444. +#define OV5693_START_STREAMING 0x01
  2445. +#define OV5693_STOP_STREAMING 0x00
  2446. +#define OV5693_SW_RESET 0x01
  2447. +
  2448. +#define OV5693_REG_CHIP_ID_H 0x300a
  2449. +#define OV5693_REG_CHIP_ID_L 0x300b
  2450. +/* Yes, this is right. The datasheet for the OV5693 gives its ID as 0x5690 */
  2451. +#define OV5693_CHIP_ID 0x5690
  2452. +
  2453. +/* Exposure */
  2454. +#define OV5693_EXPOSURE_L_CTRL_HH_REG 0x3500
  2455. +#define OV5693_EXPOSURE_L_CTRL_H_REG 0x3501
  2456. +#define OV5693_EXPOSURE_L_CTRL_L_REG 0x3502
  2457. +#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(14, 12)) >> 12)
  2458. +#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(11, 4)) >> 4)
  2459. +#define OV5693_EXPOSURE_CTRL_L(v) (((v) & GENMASK(3, 0)) << 4)
  2460. +#define OV5693_INTEGRATION_TIME_MARGIN 8
  2461. +#define OV5693_EXPOSURE_MIN 1
  2462. +#define OV5693_EXPOSURE_STEP 1
  2463. +
  2464. +/* Analogue Gain */
  2465. +#define OV5693_GAIN_CTRL_H_REG 0x350a
  2466. +#define OV5693_GAIN_CTRL_H(v) (((v) >> 4) & GENMASK(2, 0))
  2467. +#define OV5693_GAIN_CTRL_L_REG 0x350b
  2468. +#define OV5693_GAIN_CTRL_L(v) (((v) << 4) & GENMASK(7, 4))
  2469. +#define OV5693_GAIN_MIN 1
  2470. +#define OV5693_GAIN_MAX 127
  2471. +#define OV5693_GAIN_DEF 8
  2472. +#define OV5693_GAIN_STEP 1
  2473. +
  2474. +/* Digital Gain */
  2475. +#define OV5693_MWB_RED_GAIN_H_REG 0x3400
  2476. +#define OV5693_MWB_RED_GAIN_L_REG 0x3401
  2477. +#define OV5693_MWB_GREEN_GAIN_H_REG 0x3402
  2478. +#define OV5693_MWB_GREEN_GAIN_L_REG 0x3403
  2479. +#define OV5693_MWB_BLUE_GAIN_H_REG 0x3404
  2480. +#define OV5693_MWB_BLUE_GAIN_L_REG 0x3405
  2481. +#define OV5693_MWB_GAIN_H_CTRL(v) (((v) >> 8) & GENMASK(3, 0))
  2482. +#define OV5693_MWB_GAIN_L_CTRL(v) ((v) & GENMASK(7, 0))
  2483. +#define OV5693_MWB_GAIN_MAX 0x0fff
  2484. +#define OV5693_DIGITAL_GAIN_MIN 1
  2485. +#define OV5693_DIGITAL_GAIN_MAX 4095
  2486. +#define OV5693_DIGITAL_GAIN_DEF 1024
  2487. +#define OV5693_DIGITAL_GAIN_STEP 1
  2488. +
  2489. +/* Timing and Format */
  2490. +#define OV5693_CROP_START_X_H_REG 0x3800
  2491. +#define OV5693_CROP_START_X_H(v) (((v) & GENMASK(12, 8)) >> 8)
  2492. +#define OV5693_CROP_START_X_L_REG 0x3801
  2493. +#define OV5693_CROP_START_X_L(v) ((v) & GENMASK(7, 0))
  2494. +
  2495. +#define OV5693_CROP_START_Y_H_REG 0x3802
  2496. +#define OV5693_CROP_START_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
  2497. +#define OV5693_CROP_START_Y_L_REG 0x3803
  2498. +#define OV5693_CROP_START_Y_L(v) ((v) & GENMASK(7, 0))
  2499. +
  2500. +#define OV5693_CROP_END_X_H_REG 0x3804
  2501. +#define OV5693_CROP_END_X_H(v) (((v) & GENMASK(12, 8)) >> 8)
  2502. +#define OV5693_CROP_END_X_L_REG 0x3805
  2503. +#define OV5693_CROP_END_X_L(v) ((v) & GENMASK(7, 0))
  2504. +
  2505. +#define OV5693_CROP_END_Y_H_REG 0x3806
  2506. +#define OV5693_CROP_END_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
  2507. +#define OV5693_CROP_END_Y_L_REG 0x3807
  2508. +#define OV5693_CROP_END_Y_L(v) ((v) & GENMASK(7, 0))
  2509. +
  2510. +#define OV5693_OUTPUT_SIZE_X_H_REG 0x3808
  2511. +#define OV5693_OUTPUT_SIZE_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2512. +#define OV5693_OUTPUT_SIZE_X_L_REG 0x3809
  2513. +#define OV5693_OUTPUT_SIZE_X_L(v) ((v) & GENMASK(7, 0))
  2514. +
  2515. +#define OV5693_OUTPUT_SIZE_Y_H_REG 0x380a
  2516. +#define OV5693_OUTPUT_SIZE_Y_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2517. +#define OV5693_OUTPUT_SIZE_Y_L_REG 0x380b
  2518. +#define OV5693_OUTPUT_SIZE_Y_L(v) ((v) & GENMASK(7, 0))
  2519. +
  2520. +#define OV5693_TIMING_HTS_H_REG 0x380c
  2521. +#define OV5693_TIMING_HTS_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2522. +#define OV5693_TIMING_HTS_L_REG 0x380d
  2523. +#define OV5693_TIMING_HTS_L(v) ((v) & GENMASK(7, 0))
  2524. +#define OV5693_FIXED_PPL 2688U
  2525. +
  2526. +#define OV5693_TIMING_VTS_H_REG 0x380e
  2527. +#define OV5693_TIMING_VTS_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2528. +#define OV5693_TIMING_VTS_L_REG 0x380f
  2529. +#define OV5693_TIMING_VTS_L(v) ((v) & GENMASK(7, 0))
  2530. +#define OV5693_TIMING_MAX_VTS 0xffff
  2531. +#define OV5693_TIMING_MIN_VTS 0x04
  2532. +
  2533. +#define OV5693_OFFSET_START_X_H_REG 0x3810
  2534. +#define OV5693_OFFSET_START_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2535. +#define OV5693_OFFSET_START_X_L_REG 0x3811
  2536. +#define OV5693_OFFSET_START_X_L(v) ((v) & GENMASK(7, 0))
  2537. +
  2538. +#define OV5693_OFFSET_START_Y_H_REG 0x3812
  2539. +#define OV5693_OFFSET_START_Y_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2540. +#define OV5693_OFFSET_START_Y_L_REG 0x3813
  2541. +#define OV5693_OFFSET_START_Y_L(v) ((v) & GENMASK(7, 0))
  2542. +
  2543. +#define OV5693_SUB_INC_X_REG 0x3814
  2544. +#define OV5693_SUB_INC_Y_REG 0x3815
  2545. +
  2546. +#define OV5693_FORMAT1_REG 0x3820
  2547. +#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  2548. +#define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
  2549. +#define OV5693_FORMAT1_VBIN_EN BIT(0)
  2550. +#define OV5693_FORMAT2_REG 0x3821
  2551. +#define OV5693_FORMAT2_HDR_EN BIT(7)
  2552. +#define OV5693_FORMAT2_FLIP_HORZ_ISP_EN BIT(2)
  2553. +#define OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN BIT(1)
  2554. +#define OV5693_FORMAT2_HBIN_EN BIT(0)
  2555. +
  2556. +#define OV5693_ISP_CTRL2_REG 0x5002
  2557. +#define OV5693_ISP_SCALE_ENABLE BIT(7)
  2558. +
  2559. +/* Pixel Array */
  2560. +#define OV5693_NATIVE_WIDTH 2624
  2561. +#define OV5693_NATIVE_HEIGHT 1956
  2562. +#define OV5693_NATIVE_START_LEFT 0
  2563. +#define OV5693_NATIVE_START_TOP 0
  2564. +#define OV5693_ACTIVE_WIDTH 2592
  2565. +#define OV5693_ACTIVE_HEIGHT 1944
  2566. +#define OV5693_ACTIVE_START_LEFT 16
  2567. +#define OV5693_ACTIVE_START_TOP 6
  2568. +#define OV5693_MIN_CROP_WIDTH 2
  2569. +#define OV5693_MIN_CROP_HEIGHT 2
  2570. +
  2571. +/* Test Pattern */
  2572. +#define OV5693_TEST_PATTERN_REG 0x5e00
  2573. +#define OV5693_TEST_PATTERN_ENABLE BIT(7)
  2574. +#define OV5693_TEST_PATTERN_ROLLING BIT(6)
  2575. +#define OV5693_TEST_PATTERN_RANDOM 0x01
  2576. +#define OV5693_TEST_PATTERN_BARS 0x00
  2577. +
  2578. +/* System Frequencies */
  2579. +#define OV5693_XVCLK_FREQ 19200000
  2580. +#define OV5693_LINK_FREQ_400MHZ 400000000
  2581. +#define OV5693_PIXEL_RATE 160000000
  2582. +
  2583. +/* Miscellaneous */
  2584. +#define OV5693_NUM_SUPPLIES 2
  2585. +
  2586. +#define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd)
  2587. +
  2588. +struct ov5693_reg {
  2589. + u16 reg;
  2590. + u8 val;
  2591. +};
  2592. +
  2593. +struct ov5693_reg_list {
  2594. + u32 num_regs;
  2595. + const struct ov5693_reg *regs;
  2596. +};
  2597. +
  2598. +struct ov5693_device {
  2599. + struct i2c_client *client;
  2600. + struct device *dev;
  2601. +
  2602. + /* Protect against concurrent changes to controls */
  2603. + struct mutex lock;
  2604. +
  2605. + struct gpio_desc *reset;
  2606. + struct gpio_desc *powerdown;
  2607. + struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
  2608. + struct clk *clk;
  2609. +
  2610. + struct ov5693_mode {
  2611. + struct v4l2_rect crop;
  2612. + struct v4l2_mbus_framefmt format;
  2613. + bool binning_x;
  2614. + bool binning_y;
  2615. + unsigned int inc_x_odd;
  2616. + unsigned int inc_y_odd;
  2617. + unsigned int vts;
  2618. + } mode;
  2619. + bool streaming;
  2620. +
  2621. + struct v4l2_subdev sd;
  2622. + struct media_pad pad;
  2623. +
  2624. + struct ov5693_v4l2_ctrls {
  2625. + struct v4l2_ctrl_handler handler;
  2626. + struct v4l2_ctrl *link_freq;
  2627. + struct v4l2_ctrl *pixel_rate;
  2628. + struct v4l2_ctrl *exposure;
  2629. + struct v4l2_ctrl *analogue_gain;
  2630. + struct v4l2_ctrl *digital_gain;
  2631. + struct v4l2_ctrl *hflip;
  2632. + struct v4l2_ctrl *vflip;
  2633. + struct v4l2_ctrl *hblank;
  2634. + struct v4l2_ctrl *vblank;
  2635. + struct v4l2_ctrl *test_pattern;
  2636. + } ctrls;
  2637. +};
  2638. +
  2639. +static const struct ov5693_reg ov5693_global_regs[] = {
  2640. + {0x3016, 0xf0},
  2641. + {0x3017, 0xf0},
  2642. + {0x3018, 0xf0},
  2643. + {0x3022, 0x01},
  2644. + {0x3028, 0x44},
  2645. + {0x3098, 0x02},
  2646. + {0x3099, 0x19},
  2647. + {0x309a, 0x02},
  2648. + {0x309b, 0x01},
  2649. + {0x309c, 0x00},
  2650. + {0x30a0, 0xd2},
  2651. + {0x30a2, 0x01},
  2652. + {0x30b2, 0x00},
  2653. + {0x30b3, 0x7d},
  2654. + {0x30b4, 0x03},
  2655. + {0x30b5, 0x04},
  2656. + {0x30b6, 0x01},
  2657. + {0x3104, 0x21},
  2658. + {0x3106, 0x00},
  2659. + {0x3406, 0x01},
  2660. + {0x3503, 0x07},
  2661. + {0x350b, 0x40},
  2662. + {0x3601, 0x0a},
  2663. + {0x3602, 0x38},
  2664. + {0x3612, 0x80},
  2665. + {0x3620, 0x54},
  2666. + {0x3621, 0xc7},
  2667. + {0x3622, 0x0f},
  2668. + {0x3625, 0x10},
  2669. + {0x3630, 0x55},
  2670. + {0x3631, 0xf4},
  2671. + {0x3632, 0x00},
  2672. + {0x3633, 0x34},
  2673. + {0x3634, 0x02},
  2674. + {0x364d, 0x0d},
  2675. + {0x364f, 0xdd},
  2676. + {0x3660, 0x04},
  2677. + {0x3662, 0x10},
  2678. + {0x3663, 0xf1},
  2679. + {0x3665, 0x00},
  2680. + {0x3666, 0x20},
  2681. + {0x3667, 0x00},
  2682. + {0x366a, 0x80},
  2683. + {0x3680, 0xe0},
  2684. + {0x3681, 0x00},
  2685. + {0x3700, 0x42},
  2686. + {0x3701, 0x14},
  2687. + {0x3702, 0xa0},
  2688. + {0x3703, 0xd8},
  2689. + {0x3704, 0x78},
  2690. + {0x3705, 0x02},
  2691. + {0x370a, 0x00},
  2692. + {0x370b, 0x20},
  2693. + {0x370c, 0x0c},
  2694. + {0x370d, 0x11},
  2695. + {0x370e, 0x00},
  2696. + {0x370f, 0x40},
  2697. + {0x3710, 0x00},
  2698. + {0x371a, 0x1c},
  2699. + {0x371b, 0x05},
  2700. + {0x371c, 0x01},
  2701. + {0x371e, 0xa1},
  2702. + {0x371f, 0x0c},
  2703. + {0x3721, 0x00},
  2704. + {0x3724, 0x10},
  2705. + {0x3726, 0x00},
  2706. + {0x372a, 0x01},
  2707. + {0x3730, 0x10},
  2708. + {0x3738, 0x22},
  2709. + {0x3739, 0xe5},
  2710. + {0x373a, 0x50},
  2711. + {0x373b, 0x02},
  2712. + {0x373c, 0x41},
  2713. + {0x373f, 0x02},
  2714. + {0x3740, 0x42},
  2715. + {0x3741, 0x02},
  2716. + {0x3742, 0x18},
  2717. + {0x3743, 0x01},
  2718. + {0x3744, 0x02},
  2719. + {0x3747, 0x10},
  2720. + {0x374c, 0x04},
  2721. + {0x3751, 0xf0},
  2722. + {0x3752, 0x00},
  2723. + {0x3753, 0x00},
  2724. + {0x3754, 0xc0},
  2725. + {0x3755, 0x00},
  2726. + {0x3756, 0x1a},
  2727. + {0x3758, 0x00},
  2728. + {0x3759, 0x0f},
  2729. + {0x376b, 0x44},
  2730. + {0x375c, 0x04},
  2731. + {0x3774, 0x10},
  2732. + {0x3776, 0x00},
  2733. + {0x377f, 0x08},
  2734. + {0x3780, 0x22},
  2735. + {0x3781, 0x0c},
  2736. + {0x3784, 0x2c},
  2737. + {0x3785, 0x1e},
  2738. + {0x378f, 0xf5},
  2739. + {0x3791, 0xb0},
  2740. + {0x3795, 0x00},
  2741. + {0x3796, 0x64},
  2742. + {0x3797, 0x11},
  2743. + {0x3798, 0x30},
  2744. + {0x3799, 0x41},
  2745. + {0x379a, 0x07},
  2746. + {0x379b, 0xb0},
  2747. + {0x379c, 0x0c},
  2748. + {0x3a04, 0x06},
  2749. + {0x3a05, 0x14},
  2750. + {0x3e07, 0x20},
  2751. + {0x4000, 0x08},
  2752. + {0x4001, 0x04},
  2753. + {0x4004, 0x08},
  2754. + {0x4006, 0x20},
  2755. + {0x4008, 0x24},
  2756. + {0x4009, 0x10},
  2757. + {0x4058, 0x00},
  2758. + {0x4101, 0xb2},
  2759. + {0x4307, 0x31},
  2760. + {0x4511, 0x05},
  2761. + {0x4512, 0x01},
  2762. + {0x481f, 0x30},
  2763. + {0x4826, 0x2c},
  2764. + {0x4d02, 0xfd},
  2765. + {0x4d03, 0xf5},
  2766. + {0x4d04, 0x0c},
  2767. + {0x4d05, 0xcc},
  2768. + {0x4837, 0x0a},
  2769. + {0x5003, 0x20},
  2770. + {0x5013, 0x00},
  2771. + {0x5842, 0x01},
  2772. + {0x5843, 0x2b},
  2773. + {0x5844, 0x01},
  2774. + {0x5845, 0x92},
  2775. + {0x5846, 0x01},
  2776. + {0x5847, 0x8f},
  2777. + {0x5848, 0x01},
  2778. + {0x5849, 0x0c},
  2779. + {0x5e10, 0x0c},
  2780. + {0x3820, 0x00},
  2781. + {0x3821, 0x1e},
  2782. + {0x5041, 0x14}
  2783. +};
  2784. +
  2785. +static const struct ov5693_reg_list ov5693_global_setting = {
  2786. + .num_regs = ARRAY_SIZE(ov5693_global_regs),
  2787. + .regs = ov5693_global_regs,
  2788. +};
  2789. +
  2790. +static const struct v4l2_rect ov5693_default_crop = {
  2791. + .left = OV5693_ACTIVE_START_LEFT,
  2792. + .top = OV5693_ACTIVE_START_TOP,
  2793. + .width = OV5693_ACTIVE_WIDTH,
  2794. + .height = OV5693_ACTIVE_HEIGHT,
  2795. +};
  2796. +
  2797. +static const struct v4l2_mbus_framefmt ov5693_default_fmt = {
  2798. + .width = OV5693_ACTIVE_WIDTH,
  2799. + .height = OV5693_ACTIVE_HEIGHT,
  2800. + .code = MEDIA_BUS_FMT_SBGGR10_1X10,
  2801. +};
  2802. +
  2803. +static const s64 link_freq_menu_items[] = {
  2804. + OV5693_LINK_FREQ_400MHZ
  2805. +};
  2806. +
  2807. +static const char * const ov5693_supply_names[] = {
  2808. + "avdd",
  2809. + "dovdd",
  2810. +};
  2811. +
  2812. +static const char * const ov5693_test_pattern_menu[] = {
  2813. + "Disabled",
  2814. + "Random Data",
  2815. + "Colour Bars",
  2816. + "Colour Bars with Rolling Bar"
  2817. +};
  2818. +
  2819. +static const u8 ov5693_test_pattern_bits[] = {
  2820. + 0,
  2821. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_RANDOM,
  2822. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS,
  2823. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS |
  2824. + OV5693_TEST_PATTERN_ROLLING,
  2825. +};
  2826. +
  2827. +/* I2C I/O Operations */
  2828. +
  2829. +static int ov5693_read_reg(struct ov5693_device *ov5693, u16 addr, u8 *value)
  2830. +{
  2831. + struct i2c_client *client = ov5693->client;
  2832. + struct i2c_msg msgs[2];
  2833. + u8 addr_buf[2];
  2834. + u8 data_buf;
  2835. + int ret;
  2836. +
  2837. + put_unaligned_be16(addr, addr_buf);
  2838. +
  2839. + /* Write register address */
  2840. + msgs[0].addr = client->addr;
  2841. + msgs[0].flags = 0;
  2842. + msgs[0].len = ARRAY_SIZE(addr_buf);
  2843. + msgs[0].buf = addr_buf;
  2844. +
  2845. + /* Read register value */
  2846. + msgs[1].addr = client->addr;
  2847. + msgs[1].flags = I2C_M_RD;
  2848. + msgs[1].len = 1;
  2849. + msgs[1].buf = &data_buf;
  2850. +
  2851. + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  2852. + if (ret != ARRAY_SIZE(msgs))
  2853. + return -EIO;
  2854. +
  2855. + *value = data_buf;
  2856. +
  2857. + return 0;
  2858. +}
  2859. +
  2860. +static void ov5693_write_reg(struct ov5693_device *ov5693, u16 addr, u8 value,
  2861. + int *error)
  2862. +{
  2863. + unsigned char data[3] = { addr >> 8, addr & 0xff, value };
  2864. + int ret;
  2865. +
  2866. + if (*error < 0)
  2867. + return;
  2868. +
  2869. + ret = i2c_master_send(ov5693->client, data, sizeof(data));
  2870. + if (ret < 0) {
  2871. + dev_dbg(ov5693->dev, "i2c send error at address 0x%04x: %d\n",
  2872. + addr, ret);
  2873. + *error = ret;
  2874. + }
  2875. +}
  2876. +
  2877. +static int ov5693_write_reg_array(struct ov5693_device *ov5693,
  2878. + const struct ov5693_reg_list *reglist)
  2879. +{
  2880. + unsigned int i;
  2881. + int ret = 0;
  2882. +
  2883. + for (i = 0; i < reglist->num_regs; i++)
  2884. + ov5693_write_reg(ov5693, reglist->regs[i].reg,
  2885. + reglist->regs[i].val, &ret);
  2886. +
  2887. + return ret;
  2888. +}
  2889. +
  2890. +static int ov5693_update_bits(struct ov5693_device *ov5693, u16 address,
  2891. + u16 mask, u16 bits)
  2892. +{
  2893. + u8 value = 0;
  2894. + int ret;
  2895. +
  2896. + ret = ov5693_read_reg(ov5693, address, &value);
  2897. + if (ret)
  2898. + return ret;
  2899. +
  2900. + value &= ~mask;
  2901. + value |= bits;
  2902. +
  2903. + ov5693_write_reg(ov5693, address, value, &ret);
  2904. +
  2905. + return ret;
  2906. +}
  2907. +
  2908. +/* V4L2 Controls Functions */
  2909. +
  2910. +static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, bool enable)
  2911. +{
  2912. + u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
  2913. + OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
  2914. + int ret;
  2915. +
  2916. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG, bits,
  2917. + enable ? bits : 0);
  2918. + if (ret)
  2919. + return ret;
  2920. +
  2921. + return 0;
  2922. +}
  2923. +
  2924. +static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, bool enable)
  2925. +{
  2926. + u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
  2927. + OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
  2928. + int ret;
  2929. +
  2930. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG, bits,
  2931. + enable ? bits : 0);
  2932. + if (ret)
  2933. + return ret;
  2934. +
  2935. + return 0;
  2936. +}
  2937. +
  2938. +static int ov5693_get_exposure(struct ov5693_device *ov5693, s32 *value)
  2939. +{
  2940. + u8 exposure_hh = 0, exposure_h = 0, exposure_l = 0;
  2941. + int ret;
  2942. +
  2943. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_HH_REG, &exposure_hh);
  2944. + if (ret)
  2945. + return ret;
  2946. +
  2947. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_H_REG, &exposure_h);
  2948. + if (ret)
  2949. + return ret;
  2950. +
  2951. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_L_REG, &exposure_l);
  2952. + if (ret)
  2953. + return ret;
  2954. +
  2955. + /* The lowest 4 bits are unsupported fractional bits */
  2956. + *value = ((exposure_hh << 16) | (exposure_h << 8) | exposure_l) >> 4;
  2957. +
  2958. + return 0;
  2959. +}
  2960. +
  2961. +static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
  2962. +{
  2963. + int ret = 0;
  2964. +
  2965. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_HH_REG,
  2966. + OV5693_EXPOSURE_CTRL_HH(exposure), &ret);
  2967. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_H_REG,
  2968. + OV5693_EXPOSURE_CTRL_H(exposure), &ret);
  2969. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_L_REG,
  2970. + OV5693_EXPOSURE_CTRL_L(exposure), &ret);
  2971. +
  2972. + return ret;
  2973. +}
  2974. +
  2975. +static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain)
  2976. +{
  2977. + u8 gain_l = 0, gain_h = 0;
  2978. + int ret;
  2979. +
  2980. + ret = ov5693_read_reg(ov5693, OV5693_GAIN_CTRL_H_REG, &gain_h);
  2981. + if (ret)
  2982. + return ret;
  2983. +
  2984. + ret = ov5693_read_reg(ov5693, OV5693_GAIN_CTRL_L_REG, &gain_l);
  2985. + if (ret)
  2986. + return ret;
  2987. +
  2988. + /* As with exposure, the lowest 4 bits are fractional bits. */
  2989. + *gain = ((gain_h << 8) | gain_l) >> 4;
  2990. +
  2991. + return ret;
  2992. +}
  2993. +
  2994. +static int ov5693_digital_gain_configure(struct ov5693_device *ov5693, u32 gain)
  2995. +{
  2996. + int ret = 0;
  2997. +
  2998. + ov5693_write_reg(ov5693, OV5693_MWB_RED_GAIN_H_REG,
  2999. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  3000. + ov5693_write_reg(ov5693, OV5693_MWB_RED_GAIN_L_REG,
  3001. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  3002. + ov5693_write_reg(ov5693, OV5693_MWB_GREEN_GAIN_H_REG,
  3003. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  3004. + ov5693_write_reg(ov5693, OV5693_MWB_GREEN_GAIN_L_REG,
  3005. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  3006. + ov5693_write_reg(ov5693, OV5693_MWB_BLUE_GAIN_H_REG,
  3007. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  3008. + ov5693_write_reg(ov5693, OV5693_MWB_BLUE_GAIN_L_REG,
  3009. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  3010. +
  3011. + return ret;
  3012. +}
  3013. +
  3014. +static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain)
  3015. +{
  3016. + int ret = 0;
  3017. +
  3018. + ov5693_write_reg(ov5693, OV5693_GAIN_CTRL_L_REG,
  3019. + OV5693_GAIN_CTRL_L(gain), &ret);
  3020. + ov5693_write_reg(ov5693, OV5693_GAIN_CTRL_H_REG,
  3021. + OV5693_GAIN_CTRL_H(gain), &ret);
  3022. +
  3023. + return ret;
  3024. +}
  3025. +
  3026. +static int ov5693_vts_configure(struct ov5693_device *ov5693, u32 vblank)
  3027. +{
  3028. + u16 vts = ov5693->mode.format.height + vblank;
  3029. + int ret = 0;
  3030. +
  3031. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_H_REG,
  3032. + OV5693_TIMING_VTS_H(vts), &ret);
  3033. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_L_REG,
  3034. + OV5693_TIMING_VTS_L(vts), &ret);
  3035. +
  3036. + return ret;
  3037. +}
  3038. +
  3039. +static int ov5693_test_pattern_configure(struct ov5693_device *ov5693, u32 idx)
  3040. +{
  3041. + int ret = 0;
  3042. +
  3043. + ov5693_write_reg(ov5693, OV5693_TEST_PATTERN_REG,
  3044. + ov5693_test_pattern_bits[idx], &ret);
  3045. +
  3046. + return ret;
  3047. +}
  3048. +
  3049. +static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
  3050. +{
  3051. + struct ov5693_device *ov5693 =
  3052. + container_of(ctrl->handler, struct ov5693_device, ctrls.handler);
  3053. + int ret = 0;
  3054. +
  3055. + /* If VBLANK is altered we need to update exposure to compensate */
  3056. + if (ctrl->id == V4L2_CID_VBLANK) {
  3057. + int exposure_max;
  3058. +
  3059. + exposure_max = ov5693->mode.format.height + ctrl->val -
  3060. + OV5693_INTEGRATION_TIME_MARGIN;
  3061. + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
  3062. + ov5693->ctrls.exposure->minimum,
  3063. + exposure_max,
  3064. + ov5693->ctrls.exposure->step,
  3065. + min(ov5693->ctrls.exposure->val, exposure_max));
  3066. + }
  3067. +
  3068. + /* Only apply changes to the controls if the device is powered up */
  3069. + if (!pm_runtime_get_if_in_use(ov5693->dev))
  3070. + return 0;
  3071. +
  3072. + switch (ctrl->id) {
  3073. + case V4L2_CID_EXPOSURE:
  3074. + ret = ov5693_exposure_configure(ov5693, ctrl->val);
  3075. + break;
  3076. + case V4L2_CID_ANALOGUE_GAIN:
  3077. + ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
  3078. + break;
  3079. + case V4L2_CID_DIGITAL_GAIN:
  3080. + ret = ov5693_digital_gain_configure(ov5693, ctrl->val);
  3081. + break;
  3082. + case V4L2_CID_HFLIP:
  3083. + ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val);
  3084. + break;
  3085. + case V4L2_CID_VFLIP:
  3086. + ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val);
  3087. + break;
  3088. + case V4L2_CID_VBLANK:
  3089. + ret = ov5693_vts_configure(ov5693, ctrl->val);
  3090. + break;
  3091. + case V4L2_CID_TEST_PATTERN:
  3092. + ret = ov5693_test_pattern_configure(ov5693, ctrl->val);
  3093. + break;
  3094. + default:
  3095. + ret = -EINVAL;
  3096. + }
  3097. +
  3098. + pm_runtime_put(ov5693->dev);
  3099. +
  3100. + return ret;
  3101. +}
  3102. +
  3103. +static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
  3104. +{
  3105. + struct ov5693_device *ov5693 =
  3106. + container_of(ctrl->handler, struct ov5693_device, ctrls.handler);
  3107. +
  3108. + switch (ctrl->id) {
  3109. + case V4L2_CID_EXPOSURE_ABSOLUTE:
  3110. + return ov5693_get_exposure(ov5693, &ctrl->val);
  3111. + case V4L2_CID_AUTOGAIN:
  3112. + return ov5693_get_gain(ov5693, &ctrl->val);
  3113. + default:
  3114. + return -EINVAL;
  3115. + }
  3116. +}
  3117. +
  3118. +static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
  3119. + .s_ctrl = ov5693_s_ctrl,
  3120. + .g_volatile_ctrl = ov5693_g_volatile_ctrl
  3121. +};
  3122. +
  3123. +/* System Control Functions */
  3124. +
  3125. +static int ov5693_mode_configure(struct ov5693_device *ov5693)
  3126. +{
  3127. + const struct ov5693_mode *mode = &ov5693->mode;
  3128. + int ret = 0;
  3129. +
  3130. + /* Crop Start X */
  3131. + ov5693_write_reg(ov5693, OV5693_CROP_START_X_H_REG,
  3132. + OV5693_CROP_START_X_H(mode->crop.left), &ret);
  3133. + ov5693_write_reg(ov5693, OV5693_CROP_START_X_L_REG,
  3134. + OV5693_CROP_START_X_L(mode->crop.left), &ret);
  3135. +
  3136. + /* Offset X */
  3137. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_X_H_REG,
  3138. + OV5693_OFFSET_START_X_H(0), &ret);
  3139. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_X_L_REG,
  3140. + OV5693_OFFSET_START_X_L(0), &ret);
  3141. +
  3142. + /* Output Size X */
  3143. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_X_H_REG,
  3144. + OV5693_OUTPUT_SIZE_X_H(mode->format.width), &ret);
  3145. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_X_L_REG,
  3146. + OV5693_OUTPUT_SIZE_X_L(mode->format.width), &ret);
  3147. +
  3148. + /* Crop End X */
  3149. + ov5693_write_reg(ov5693, OV5693_CROP_END_X_H_REG,
  3150. + OV5693_CROP_END_X_H(mode->crop.left + mode->crop.width),
  3151. + &ret);
  3152. + ov5693_write_reg(ov5693, OV5693_CROP_END_X_L_REG,
  3153. + OV5693_CROP_END_X_L(mode->crop.left + mode->crop.width),
  3154. + &ret);
  3155. +
  3156. + /* Horizontal Total Size */
  3157. + ov5693_write_reg(ov5693, OV5693_TIMING_HTS_H_REG,
  3158. + OV5693_TIMING_HTS_H(OV5693_FIXED_PPL), &ret);
  3159. + ov5693_write_reg(ov5693, OV5693_TIMING_HTS_L_REG,
  3160. + OV5693_TIMING_HTS_L(OV5693_FIXED_PPL), &ret);
  3161. +
  3162. + /* Crop Start Y */
  3163. + ov5693_write_reg(ov5693, OV5693_CROP_START_Y_H_REG,
  3164. + OV5693_CROP_START_Y_H(mode->crop.top), &ret);
  3165. + ov5693_write_reg(ov5693, OV5693_CROP_START_Y_L_REG,
  3166. + OV5693_CROP_START_Y_L(mode->crop.top), &ret);
  3167. +
  3168. + /* Offset Y */
  3169. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_Y_H_REG,
  3170. + OV5693_OFFSET_START_Y_H(0), &ret);
  3171. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_Y_L_REG,
  3172. + OV5693_OFFSET_START_Y_L(0), &ret);
  3173. +
  3174. + /* Output Size Y */
  3175. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_Y_H_REG,
  3176. + OV5693_OUTPUT_SIZE_Y_H(mode->format.height), &ret);
  3177. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_Y_L_REG,
  3178. + OV5693_OUTPUT_SIZE_Y_L(mode->format.height), &ret);
  3179. +
  3180. + /* Crop End Y */
  3181. + ov5693_write_reg(ov5693, OV5693_CROP_END_Y_H_REG,
  3182. + OV5693_CROP_END_Y_H(mode->crop.top + mode->crop.height),
  3183. + &ret);
  3184. + ov5693_write_reg(ov5693, OV5693_CROP_END_Y_L_REG,
  3185. + OV5693_CROP_END_Y_L(mode->crop.top + mode->crop.height),
  3186. + &ret);
  3187. +
  3188. + /* Vertical Total Size */
  3189. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_H_REG,
  3190. + OV5693_TIMING_VTS_H(mode->vts), &ret);
  3191. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_L_REG,
  3192. + OV5693_TIMING_VTS_L(mode->vts), &ret);
  3193. +
  3194. + /* Subsample X increase */
  3195. + ov5693_write_reg(ov5693, OV5693_SUB_INC_X_REG,
  3196. + ((mode->inc_x_odd << 4) & 0xf0) | 0x01, &ret);
  3197. + /* Subsample Y increase */
  3198. + ov5693_write_reg(ov5693, OV5693_SUB_INC_Y_REG,
  3199. + ((mode->inc_y_odd << 4) & 0xf0) | 0x01, &ret);
  3200. +
  3201. + /* Binning */
  3202. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG,
  3203. + OV5693_FORMAT1_VBIN_EN,
  3204. + mode->binning_y ? OV5693_FORMAT1_VBIN_EN : 0);
  3205. + if (ret)
  3206. + return ret;
  3207. +
  3208. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG,
  3209. + OV5693_FORMAT2_HBIN_EN,
  3210. + mode->binning_x ? OV5693_FORMAT2_HBIN_EN : 0);
  3211. +
  3212. + return ret;
  3213. +}
  3214. +
  3215. +static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
  3216. +{
  3217. + int ret = 0;
  3218. +
  3219. + ov5693_write_reg(ov5693, OV5693_SW_STREAM_REG,
  3220. + standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING,
  3221. + &ret);
  3222. +
  3223. + return ret;
  3224. +}
  3225. +
  3226. +static int ov5693_sw_reset(struct ov5693_device *ov5693)
  3227. +{
  3228. + int ret = 0;
  3229. +
  3230. + ov5693_write_reg(ov5693, OV5693_SW_RESET_REG, OV5693_SW_RESET, &ret);
  3231. +
  3232. + return ret;
  3233. +}
  3234. +
  3235. +static int ov5693_sensor_init(struct ov5693_device *ov5693)
  3236. +{
  3237. + int ret = 0;
  3238. +
  3239. + ret = ov5693_sw_reset(ov5693);
  3240. + if (ret) {
  3241. + dev_err(ov5693->dev, "%s software reset error\n", __func__);
  3242. + return ret;
  3243. + }
  3244. +
  3245. + ret = ov5693_write_reg_array(ov5693, &ov5693_global_setting);
  3246. + if (ret) {
  3247. + dev_err(ov5693->dev, "%s global settings error\n", __func__);
  3248. + return ret;
  3249. + }
  3250. +
  3251. + ret = ov5693_mode_configure(ov5693);
  3252. + if (ret) {
  3253. + dev_err(ov5693->dev, "%s mode configure error\n", __func__);
  3254. + return ret;
  3255. + }
  3256. +
  3257. + ret = ov5693_sw_standby(ov5693, true);
  3258. + if (ret)
  3259. + dev_err(ov5693->dev, "%s software standby error\n", __func__);
  3260. +
  3261. + return ret;
  3262. +}
  3263. +
  3264. +static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
  3265. +{
  3266. + gpiod_set_value_cansleep(ov5693->reset, 1);
  3267. + gpiod_set_value_cansleep(ov5693->powerdown, 1);
  3268. +
  3269. + regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
  3270. +
  3271. + clk_disable_unprepare(ov5693->clk);
  3272. +}
  3273. +
  3274. +static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
  3275. +{
  3276. + int ret;
  3277. +
  3278. + gpiod_set_value_cansleep(ov5693->reset, 1);
  3279. + gpiod_set_value_cansleep(ov5693->powerdown, 1);
  3280. +
  3281. + ret = clk_prepare_enable(ov5693->clk);
  3282. + if (ret) {
  3283. + dev_err(ov5693->dev, "Failed to enable clk\n");
  3284. + goto fail_power;
  3285. + }
  3286. +
  3287. + ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies);
  3288. + if (ret) {
  3289. + dev_err(ov5693->dev, "Failed to enable regulators\n");
  3290. + goto fail_power;
  3291. + }
  3292. +
  3293. + gpiod_set_value_cansleep(ov5693->powerdown, 0);
  3294. + gpiod_set_value_cansleep(ov5693->reset, 0);
  3295. +
  3296. + usleep_range(5000, 7500);
  3297. +
  3298. + return 0;
  3299. +
  3300. +fail_power:
  3301. + ov5693_sensor_powerdown(ov5693);
  3302. + return ret;
  3303. +}
  3304. +
  3305. +static int __maybe_unused ov5693_sensor_suspend(struct device *dev)
  3306. +{
  3307. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  3308. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3309. +
  3310. + ov5693_sensor_powerdown(ov5693);
  3311. +
  3312. + return 0;
  3313. +}
  3314. +
  3315. +static int __maybe_unused ov5693_sensor_resume(struct device *dev)
  3316. +{
  3317. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  3318. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3319. + int ret;
  3320. +
  3321. + mutex_lock(&ov5693->lock);
  3322. +
  3323. + ret = ov5693_sensor_powerup(ov5693);
  3324. + if (ret)
  3325. + goto out_unlock;
  3326. +
  3327. + ret = ov5693_sensor_init(ov5693);
  3328. + if (ret) {
  3329. + dev_err(dev, "ov5693 sensor init failure\n");
  3330. + goto err_power;
  3331. + }
  3332. +
  3333. + goto out_unlock;
  3334. +
  3335. +err_power:
  3336. + ov5693_sensor_powerdown(ov5693);
  3337. +out_unlock:
  3338. + mutex_unlock(&ov5693->lock);
  3339. + return ret;
  3340. +}
  3341. +
  3342. +static int ov5693_detect(struct ov5693_device *ov5693)
  3343. +{
  3344. + u8 id_l = 0, id_h = 0;
  3345. + u16 id = 0;
  3346. + int ret;
  3347. +
  3348. + ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID_H, &id_h);
  3349. + if (ret)
  3350. + return ret;
  3351. +
  3352. + ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID_L, &id_l);
  3353. + if (ret)
  3354. + return ret;
  3355. +
  3356. + id = (id_h << 8) | id_l;
  3357. +
  3358. + if (id != OV5693_CHIP_ID) {
  3359. + dev_err(ov5693->dev, "sensor ID mismatch. Found 0x%04x\n", id);
  3360. + return -ENODEV;
  3361. + }
  3362. +
  3363. + return 0;
  3364. +}
  3365. +
  3366. +/* V4L2 Framework callbacks */
  3367. +
  3368. +static unsigned int __ov5693_calc_vts(u32 height)
  3369. +{
  3370. + /*
  3371. + * We need to set a sensible default VTS for whatever format height we
  3372. + * happen to be given from set_fmt(). This function just targets
  3373. + * an even multiple of 30fps.
  3374. + */
  3375. +
  3376. + unsigned int tgt_fps;
  3377. +
  3378. + tgt_fps = rounddown(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / height, 30);
  3379. +
  3380. + return ALIGN_DOWN(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / tgt_fps, 2);
  3381. +}
  3382. +
  3383. +static struct v4l2_mbus_framefmt *
  3384. +__ov5693_get_pad_format(struct ov5693_device *ov5693,
  3385. + struct v4l2_subdev_pad_config *cfg,
  3386. + unsigned int pad, enum v4l2_subdev_format_whence which)
  3387. +{
  3388. + switch (which) {
  3389. + case V4L2_SUBDEV_FORMAT_TRY:
  3390. + return v4l2_subdev_get_try_format(&ov5693->sd, cfg, pad);
  3391. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  3392. + return &ov5693->mode.format;
  3393. + default:
  3394. + return NULL;
  3395. + }
  3396. +}
  3397. +
  3398. +static struct v4l2_rect *
  3399. +__ov5693_get_pad_crop(struct ov5693_device *ov5693,
  3400. + struct v4l2_subdev_pad_config *cfg,
  3401. + unsigned int pad, enum v4l2_subdev_format_whence which)
  3402. +{
  3403. + switch (which) {
  3404. + case V4L2_SUBDEV_FORMAT_TRY:
  3405. + return v4l2_subdev_get_try_crop(&ov5693->sd, cfg, pad);
  3406. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  3407. + return &ov5693->mode.crop;
  3408. + }
  3409. +
  3410. + return NULL;
  3411. +}
  3412. +
  3413. +static int ov5693_get_fmt(struct v4l2_subdev *sd,
  3414. + struct v4l2_subdev_pad_config *cfg,
  3415. + struct v4l2_subdev_format *format)
  3416. +{
  3417. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3418. +
  3419. + format->format = ov5693->mode.format;
  3420. +
  3421. + return 0;
  3422. +}
  3423. +
  3424. +static int ov5693_set_fmt(struct v4l2_subdev *sd,
  3425. + struct v4l2_subdev_pad_config *cfg,
  3426. + struct v4l2_subdev_format *format)
  3427. +{
  3428. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3429. + const struct v4l2_rect *crop;
  3430. + struct v4l2_mbus_framefmt *fmt;
  3431. + unsigned int hratio, vratio;
  3432. + unsigned int width, height;
  3433. + unsigned int hblank;
  3434. + int exposure_max;
  3435. + int ret = 0;
  3436. +
  3437. + crop = __ov5693_get_pad_crop(ov5693, cfg, format->pad, format->which);
  3438. +
  3439. + /*
  3440. + * Align to two to simplify the binning calculations below, and clamp
  3441. + * the requested format at the crop rectangle
  3442. + */
  3443. + width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
  3444. + OV5693_MIN_CROP_WIDTH, crop->width);
  3445. + height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
  3446. + OV5693_MIN_CROP_HEIGHT, crop->height);
  3447. +
  3448. + /*
  3449. + * We can only support setting either the dimensions of the crop rect
  3450. + * or those dimensions binned (separately) by a factor of two.
  3451. + */
  3452. + hratio = clamp_t(unsigned int, DIV_ROUND_CLOSEST(crop->width, width), 1, 2);
  3453. + vratio = clamp_t(unsigned int, DIV_ROUND_CLOSEST(crop->height, height), 1, 2);
  3454. +
  3455. + fmt = __ov5693_get_pad_format(ov5693, cfg, format->pad, format->which);
  3456. +
  3457. + fmt->width = crop->width / hratio;
  3458. + fmt->height = crop->height / vratio;
  3459. + fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
  3460. +
  3461. + format->format = *fmt;
  3462. +
  3463. + if (format->which == V4L2_SUBDEV_FORMAT_TRY)
  3464. + return ret;
  3465. +
  3466. + mutex_lock(&ov5693->lock);
  3467. +
  3468. + ov5693->mode.binning_x = hratio > 1 ? true : false;
  3469. + ov5693->mode.inc_x_odd = hratio > 1 ? 3 : 1;
  3470. + ov5693->mode.binning_y = vratio > 1 ? true : false;
  3471. + ov5693->mode.inc_y_odd = vratio > 1 ? 3 : 1;
  3472. +
  3473. + ov5693->mode.vts = __ov5693_calc_vts(fmt->height);
  3474. +
  3475. + __v4l2_ctrl_modify_range(ov5693->ctrls.vblank,
  3476. + OV5693_TIMING_MIN_VTS,
  3477. + OV5693_TIMING_MAX_VTS - fmt->height,
  3478. + 1, ov5693->mode.vts - fmt->height);
  3479. + __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank,
  3480. + ov5693->mode.vts - fmt->height);
  3481. +
  3482. + hblank = OV5693_FIXED_PPL - fmt->width;
  3483. + __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1,
  3484. + hblank);
  3485. +
  3486. + exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
  3487. + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
  3488. + ov5693->ctrls.exposure->minimum, exposure_max,
  3489. + ov5693->ctrls.exposure->step,
  3490. + min(ov5693->ctrls.exposure->val, exposure_max));
  3491. +
  3492. + mutex_unlock(&ov5693->lock);
  3493. + return ret;
  3494. +}
  3495. +
  3496. +static int ov5693_get_selection(struct v4l2_subdev *sd,
  3497. + struct v4l2_subdev_pad_config *cfg,
  3498. + struct v4l2_subdev_selection *sel)
  3499. +{
  3500. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3501. +
  3502. + switch (sel->target) {
  3503. + case V4L2_SEL_TGT_CROP:
  3504. + mutex_lock(&ov5693->lock);
  3505. + sel->r = *__ov5693_get_pad_crop(ov5693, cfg, sel->pad,
  3506. + sel->which);
  3507. + mutex_unlock(&ov5693->lock);
  3508. + break;
  3509. + case V4L2_SEL_TGT_NATIVE_SIZE:
  3510. + sel->r.top = 0;
  3511. + sel->r.left = 0;
  3512. + sel->r.width = OV5693_NATIVE_WIDTH;
  3513. + sel->r.height = OV5693_NATIVE_HEIGHT;
  3514. + break;
  3515. + case V4L2_SEL_TGT_CROP_BOUNDS:
  3516. + case V4L2_SEL_TGT_CROP_DEFAULT:
  3517. + sel->r.top = OV5693_ACTIVE_START_TOP;
  3518. + sel->r.left = OV5693_ACTIVE_START_LEFT;
  3519. + sel->r.width = OV5693_ACTIVE_WIDTH;
  3520. + sel->r.height = OV5693_ACTIVE_HEIGHT;
  3521. + break;
  3522. + default:
  3523. + return -EINVAL;
  3524. + }
  3525. +
  3526. + return 0;
  3527. +}
  3528. +
  3529. +static int ov5693_set_selection(struct v4l2_subdev *sd,
  3530. + struct v4l2_subdev_pad_config *cfg,
  3531. + struct v4l2_subdev_selection *sel)
  3532. +{
  3533. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3534. + struct v4l2_mbus_framefmt *format;
  3535. + struct v4l2_rect *__crop;
  3536. + struct v4l2_rect rect;
  3537. +
  3538. + if (sel->target != V4L2_SEL_TGT_CROP)
  3539. + return -EINVAL;
  3540. +
  3541. + /*
  3542. + * Clamp the boundaries of the crop rectangle to the size of the sensor
  3543. + * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't
  3544. + * disrupted.
  3545. + */
  3546. + rect.left = clamp(ALIGN(sel->r.left, 2), OV5693_NATIVE_START_LEFT,
  3547. + OV5693_NATIVE_WIDTH);
  3548. + rect.top = clamp(ALIGN(sel->r.top, 2), OV5693_NATIVE_START_TOP,
  3549. + OV5693_NATIVE_HEIGHT);
  3550. + rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
  3551. + OV5693_MIN_CROP_WIDTH, OV5693_NATIVE_WIDTH);
  3552. + rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
  3553. + OV5693_MIN_CROP_HEIGHT, OV5693_NATIVE_HEIGHT);
  3554. +
  3555. + /* Make sure the crop rectangle isn't outside the bounds of the array */
  3556. + rect.width = min_t(unsigned int, rect.width,
  3557. + OV5693_NATIVE_WIDTH - rect.left);
  3558. + rect.height = min_t(unsigned int, rect.height,
  3559. + OV5693_NATIVE_HEIGHT - rect.top);
  3560. +
  3561. + __crop = __ov5693_get_pad_crop(ov5693, cfg, sel->pad, sel->which);
  3562. +
  3563. + if (rect.width != __crop->width || rect.height != __crop->height) {
  3564. + /*
  3565. + * Reset the output image size if the crop rectangle size has
  3566. + * been modified.
  3567. + */
  3568. + format = __ov5693_get_pad_format(ov5693, cfg, sel->pad, sel->which);
  3569. + format->width = rect.width;
  3570. + format->height = rect.height;
  3571. + }
  3572. +
  3573. + *__crop = rect;
  3574. + sel->r = rect;
  3575. +
  3576. + return 0;
  3577. +}
  3578. +
  3579. +static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
  3580. +{
  3581. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3582. + int ret;
  3583. +
  3584. + if (enable) {
  3585. + ret = pm_runtime_get_sync(ov5693->dev);
  3586. + if (ret < 0)
  3587. + goto err_power_down;
  3588. +
  3589. + ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler);
  3590. + if (ret)
  3591. + goto err_power_down;
  3592. + }
  3593. +
  3594. + mutex_lock(&ov5693->lock);
  3595. + ret = ov5693_sw_standby(ov5693, !enable);
  3596. + mutex_unlock(&ov5693->lock);
  3597. +
  3598. + if (ret)
  3599. + goto err_power_down;
  3600. + ov5693->streaming = !!enable;
  3601. +
  3602. + if (!enable)
  3603. + pm_runtime_put(ov5693->dev);
  3604. +
  3605. + return 0;
  3606. +err_power_down:
  3607. + pm_runtime_put_noidle(ov5693->dev);
  3608. + return ret;
  3609. +}
  3610. +
  3611. +static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
  3612. + struct v4l2_subdev_frame_interval *interval)
  3613. +{
  3614. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3615. + unsigned int framesize = OV5693_FIXED_PPL * (ov5693->mode.format.height +
  3616. + ov5693->ctrls.vblank->val);
  3617. + unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize);
  3618. +
  3619. + interval->interval.numerator = 1;
  3620. + interval->interval.denominator = fps;
  3621. +
  3622. + return 0;
  3623. +}
  3624. +
  3625. +static int ov5693_enum_mbus_code(struct v4l2_subdev *sd,
  3626. + struct v4l2_subdev_pad_config *cfg,
  3627. + struct v4l2_subdev_mbus_code_enum *code)
  3628. +{
  3629. + /* Only a single mbus format is supported */
  3630. + if (code->index > 0)
  3631. + return -EINVAL;
  3632. +
  3633. + code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
  3634. + return 0;
  3635. +}
  3636. +
  3637. +static int ov5693_enum_frame_size(struct v4l2_subdev *sd,
  3638. + struct v4l2_subdev_pad_config *cfg,
  3639. + struct v4l2_subdev_frame_size_enum *fse)
  3640. +{
  3641. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3642. + struct v4l2_rect *__crop;
  3643. +
  3644. + if (fse->index > 1 || fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
  3645. + return -EINVAL;
  3646. +
  3647. + __crop = __ov5693_get_pad_crop(ov5693, cfg, fse->pad, fse->which);
  3648. + if (!__crop)
  3649. + return -EINVAL;
  3650. +
  3651. + fse->min_width = __crop->width / (fse->index + 1);
  3652. + fse->min_height = __crop->height / (fse->index + 1);
  3653. + fse->max_width = fse->min_width;
  3654. + fse->max_height = fse->min_height;
  3655. +
  3656. + return 0;
  3657. +}
  3658. +
  3659. +static const struct v4l2_subdev_video_ops ov5693_video_ops = {
  3660. + .s_stream = ov5693_s_stream,
  3661. + .g_frame_interval = ov5693_g_frame_interval,
  3662. +};
  3663. +
  3664. +static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
  3665. + .enum_mbus_code = ov5693_enum_mbus_code,
  3666. + .enum_frame_size = ov5693_enum_frame_size,
  3667. + .get_fmt = ov5693_get_fmt,
  3668. + .set_fmt = ov5693_set_fmt,
  3669. + .get_selection = ov5693_get_selection,
  3670. + .set_selection = ov5693_set_selection,
  3671. +};
  3672. +
  3673. +static const struct v4l2_subdev_ops ov5693_ops = {
  3674. + .video = &ov5693_video_ops,
  3675. + .pad = &ov5693_pad_ops,
  3676. +};
  3677. +
  3678. +/* Sensor and Driver Configuration Functions */
  3679. +
  3680. +static int ov5693_init_controls(struct ov5693_device *ov5693)
  3681. +{
  3682. + const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
  3683. + struct v4l2_fwnode_device_properties props;
  3684. + int vblank_max, vblank_def;
  3685. + int exposure_max;
  3686. + int hblank;
  3687. + int ret;
  3688. +
  3689. + ret = v4l2_ctrl_handler_init(&ov5693->ctrls.handler, 12);
  3690. + if (ret)
  3691. + return ret;
  3692. +
  3693. + /* link freq */
  3694. + ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrls.handler,
  3695. + NULL, V4L2_CID_LINK_FREQ,
  3696. + 0, 0, link_freq_menu_items);
  3697. + if (ov5693->ctrls.link_freq)
  3698. + ov5693->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  3699. +
  3700. + /* pixel rate */
  3701. + ov5693->ctrls.pixel_rate = v4l2_ctrl_new_std(&ov5693->ctrls.handler, NULL,
  3702. + V4L2_CID_PIXEL_RATE, 0,
  3703. + OV5693_PIXEL_RATE, 1,
  3704. + OV5693_PIXEL_RATE);
  3705. +
  3706. + /* Exposure */
  3707. + exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
  3708. + ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3709. + V4L2_CID_EXPOSURE,
  3710. + OV5693_EXPOSURE_MIN,
  3711. + exposure_max,
  3712. + OV5693_EXPOSURE_STEP,
  3713. + exposure_max);
  3714. +
  3715. + /* Gain */
  3716. + ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrls.handler,
  3717. + ops, V4L2_CID_ANALOGUE_GAIN,
  3718. + OV5693_GAIN_MIN,
  3719. + OV5693_GAIN_MAX,
  3720. + OV5693_GAIN_STEP,
  3721. + OV5693_GAIN_DEF);
  3722. +
  3723. + ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3724. + V4L2_CID_DIGITAL_GAIN,
  3725. + OV5693_DIGITAL_GAIN_MIN,
  3726. + OV5693_DIGITAL_GAIN_MAX,
  3727. + OV5693_DIGITAL_GAIN_STEP,
  3728. + OV5693_DIGITAL_GAIN_DEF);
  3729. +
  3730. + /* Flip */
  3731. + ov5693->ctrls.hflip = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3732. + V4L2_CID_HFLIP, 0, 1, 1, 0);
  3733. +
  3734. + ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3735. + V4L2_CID_VFLIP, 0, 1, 1, 0);
  3736. +
  3737. + hblank = OV5693_FIXED_PPL - ov5693->mode.format.width;
  3738. + ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3739. + V4L2_CID_HBLANK, hblank,
  3740. + hblank, 1, hblank);
  3741. +
  3742. + if (ov5693->ctrls.hblank)
  3743. + ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  3744. +
  3745. + vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode.format.height;
  3746. + vblank_def = ov5693->mode.vts - ov5693->mode.format.height;
  3747. + ov5693->ctrls.vblank = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  3748. + V4L2_CID_VBLANK,
  3749. + OV5693_TIMING_MIN_VTS,
  3750. + vblank_max, 1, vblank_def);
  3751. +
  3752. + ov5693->ctrls.test_pattern = v4l2_ctrl_new_std_menu_items(
  3753. + &ov5693->ctrls.handler, ops,
  3754. + V4L2_CID_TEST_PATTERN,
  3755. + ARRAY_SIZE(ov5693_test_pattern_menu) - 1,
  3756. + 0, 0, ov5693_test_pattern_menu);
  3757. +
  3758. + if (ov5693->ctrls.handler.error) {
  3759. + dev_err(ov5693->dev, "Error initialising v4l2 ctrls\n");
  3760. + ret = ov5693->ctrls.handler.error;
  3761. + goto err_free_handler;
  3762. + }
  3763. +
  3764. + /* set properties from fwnode (e.g. rotation, orientation) */
  3765. + ret = v4l2_fwnode_device_parse(ov5693->dev, &props);
  3766. + if (ret)
  3767. + goto err_free_handler;
  3768. +
  3769. + ret = v4l2_ctrl_new_fwnode_properties(&ov5693->ctrls.handler, ops,
  3770. + &props);
  3771. + if (ret)
  3772. + goto err_free_handler;
  3773. +
  3774. + /* Use same lock for controls as for everything else. */
  3775. + ov5693->ctrls.handler.lock = &ov5693->lock;
  3776. + ov5693->sd.ctrl_handler = &ov5693->ctrls.handler;
  3777. +
  3778. + return 0;
  3779. +
  3780. +err_free_handler:
  3781. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  3782. + return ret;
  3783. +}
  3784. +
  3785. +static int ov5693_configure_gpios(struct ov5693_device *ov5693)
  3786. +{
  3787. + ov5693->reset = devm_gpiod_get_optional(ov5693->dev, "reset",
  3788. + GPIOD_OUT_HIGH);
  3789. + if (IS_ERR(ov5693->reset)) {
  3790. + dev_err(ov5693->dev, "Error fetching reset GPIO\n");
  3791. + return PTR_ERR(ov5693->reset);
  3792. + }
  3793. +
  3794. + ov5693->powerdown = devm_gpiod_get_optional(ov5693->dev, "powerdown",
  3795. + GPIOD_OUT_HIGH);
  3796. + if (IS_ERR(ov5693->powerdown)) {
  3797. + dev_err(ov5693->dev, "Error fetching powerdown GPIO\n");
  3798. + return PTR_ERR(ov5693->powerdown);
  3799. + }
  3800. +
  3801. + return 0;
  3802. +}
  3803. +
  3804. +static int ov5693_get_regulators(struct ov5693_device *ov5693)
  3805. +{
  3806. + unsigned int i;
  3807. +
  3808. + for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
  3809. + ov5693->supplies[i].supply = ov5693_supply_names[i];
  3810. +
  3811. + return devm_regulator_bulk_get(ov5693->dev, OV5693_NUM_SUPPLIES,
  3812. + ov5693->supplies);
  3813. +}
  3814. +
  3815. +static int ov5693_probe(struct i2c_client *client)
  3816. +{
  3817. + struct fwnode_handle *fwnode = dev_fwnode(&client->dev);
  3818. + struct fwnode_handle *endpoint;
  3819. + struct ov5693_device *ov5693;
  3820. + u32 clk_rate;
  3821. + int ret = 0;
  3822. +
  3823. + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
  3824. + if (!endpoint && !IS_ERR_OR_NULL(fwnode->secondary))
  3825. + endpoint = fwnode_graph_get_next_endpoint(fwnode->secondary, NULL);
  3826. + if (!endpoint)
  3827. + return -EPROBE_DEFER;
  3828. +
  3829. + ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
  3830. + if (!ov5693)
  3831. + return -ENOMEM;
  3832. +
  3833. + ov5693->client = client;
  3834. + ov5693->dev = &client->dev;
  3835. +
  3836. + mutex_init(&ov5693->lock);
  3837. +
  3838. + v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
  3839. +
  3840. + ov5693->clk = devm_clk_get(&client->dev, "xvclk");
  3841. + if (IS_ERR(ov5693->clk)) {
  3842. + dev_err(&client->dev, "Error getting clock\n");
  3843. + return PTR_ERR(ov5693->clk);
  3844. + }
  3845. +
  3846. + clk_rate = clk_get_rate(ov5693->clk);
  3847. + if (clk_rate != OV5693_XVCLK_FREQ) {
  3848. + dev_err(&client->dev, "Unsupported clk freq %u, expected %u\n",
  3849. + clk_rate, OV5693_XVCLK_FREQ);
  3850. + return -EINVAL;
  3851. + }
  3852. +
  3853. + ret = ov5693_configure_gpios(ov5693);
  3854. + if (ret)
  3855. + return ret;
  3856. +
  3857. + ret = ov5693_get_regulators(ov5693);
  3858. + if (ret) {
  3859. + dev_err(&client->dev, "Error fetching regulators\n");
  3860. + return ret;
  3861. + }
  3862. +
  3863. + ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  3864. + ov5693->pad.flags = MEDIA_PAD_FL_SOURCE;
  3865. + ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
  3866. +
  3867. + ov5693->mode.crop = ov5693_default_crop;
  3868. + ov5693->mode.format = ov5693_default_fmt;
  3869. + ov5693->mode.vts = __ov5693_calc_vts(ov5693->mode.format.height);
  3870. +
  3871. + ret = ov5693_init_controls(ov5693);
  3872. + if (ret)
  3873. + return ret;
  3874. +
  3875. + ret = media_entity_pads_init(&ov5693->sd.entity, 1, &ov5693->pad);
  3876. + if (ret)
  3877. + goto err_ctrl_handler_free;
  3878. +
  3879. + /*
  3880. + * We need the driver to work in the event that pm runtime is disable in
  3881. + * the kernel, so power up and verify the chip now. In the event that
  3882. + * runtime pm is disabled this will leave the chip on, so that streaming
  3883. + * will work.
  3884. + */
  3885. +
  3886. + ret = ov5693_sensor_powerup(ov5693);
  3887. + if (ret)
  3888. + goto err_media_entity_cleanup;
  3889. +
  3890. + ret = ov5693_detect(ov5693);
  3891. + if (ret)
  3892. + goto err_powerdown;
  3893. +
  3894. + pm_runtime_set_active(&client->dev);
  3895. + pm_runtime_get_noresume(&client->dev);
  3896. + pm_runtime_enable(&client->dev);
  3897. +
  3898. + ret = v4l2_async_register_subdev_sensor(&ov5693->sd);
  3899. + if (ret) {
  3900. + dev_err(&client->dev, "failed to register V4L2 subdev: %d",
  3901. + ret);
  3902. + goto err_pm_runtime;
  3903. + }
  3904. +
  3905. + pm_runtime_set_autosuspend_delay(&client->dev, 1000);
  3906. + pm_runtime_use_autosuspend(&client->dev);
  3907. + pm_runtime_put_autosuspend(&client->dev);
  3908. +
  3909. + return ret;
  3910. +
  3911. +err_pm_runtime:
  3912. + pm_runtime_disable(&client->dev);
  3913. + pm_runtime_put_noidle(&client->dev);
  3914. +err_powerdown:
  3915. + ov5693_sensor_powerdown(ov5693);
  3916. +err_media_entity_cleanup:
  3917. + media_entity_cleanup(&ov5693->sd.entity);
  3918. +err_ctrl_handler_free:
  3919. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  3920. +
  3921. + return ret;
  3922. +}
  3923. +
  3924. +static int ov5693_remove(struct i2c_client *client)
  3925. +{
  3926. + struct v4l2_subdev *sd = i2c_get_clientdata(client);
  3927. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  3928. +
  3929. + v4l2_async_unregister_subdev(sd);
  3930. + media_entity_cleanup(&ov5693->sd.entity);
  3931. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  3932. + mutex_destroy(&ov5693->lock);
  3933. +
  3934. + /*
  3935. + * Disable runtime PM. In case runtime PM is disabled in the kernel,
  3936. + * make sure to turn power off manually.
  3937. + */
  3938. + pm_runtime_disable(&client->dev);
  3939. + if (!pm_runtime_status_suspended(&client->dev))
  3940. + ov5693_sensor_powerdown(ov5693);
  3941. + pm_runtime_set_suspended(&client->dev);
  3942. +
  3943. + return 0;
  3944. +}
  3945. +
  3946. +static const struct dev_pm_ops ov5693_pm_ops = {
  3947. + SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL)
  3948. +};
  3949. +
  3950. +static const struct acpi_device_id ov5693_acpi_match[] = {
  3951. + {"INT33BE"},
  3952. + {},
  3953. +};
  3954. +MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match);
  3955. +
  3956. +static struct i2c_driver ov5693_driver = {
  3957. + .driver = {
  3958. + .name = "ov5693",
  3959. + .acpi_match_table = ov5693_acpi_match,
  3960. + .pm = &ov5693_pm_ops,
  3961. + },
  3962. + .probe_new = ov5693_probe,
  3963. + .remove = ov5693_remove,
  3964. +};
  3965. +module_i2c_driver(ov5693_driver);
  3966. +
  3967. +MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors");
  3968. +MODULE_LICENSE("GPL");
  3969. --
  3970. 2.33.0
  3971. From bbaa83538fbcfaf3d26a03019a2fad4ffe6243d8 Mon Sep 17 00:00:00 2001
  3972. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  3973. Date: Fri, 22 Jan 2021 20:58:13 +0100
  3974. Subject: [PATCH] cio2-bridge: Parse sensor orientation and rotation
  3975. MIME-Version: 1.0
  3976. Content-Type: text/plain; charset=UTF-8
  3977. Content-Transfer-Encoding: 8bit
  3978. The sensor orientation is read from the _PLC ACPI buffer and converted
  3979. to a v4l2 format.
  3980. See https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
  3981. page 351 for a definition of the Panel property.
  3982. The sensor rotation is read from the SSDB ACPI buffer and converted into
  3983. degrees.
  3984. Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
  3985. Patchset: cameras
  3986. ---
  3987. drivers/media/pci/intel/ipu3/cio2-bridge.c | 45 ++++++++++++++++++++--
  3988. drivers/media/pci/intel/ipu3/cio2-bridge.h | 3 ++
  3989. 2 files changed, 44 insertions(+), 4 deletions(-)
  3990. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3991. index 59a36f922675..d4a48cec2644 100644
  3992. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3993. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3994. @@ -29,6 +29,7 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
  3995. static const struct cio2_property_names prop_names = {
  3996. .clock_frequency = "clock-frequency",
  3997. .rotation = "rotation",
  3998. + .orientation = "orientation",
  3999. .bus_type = "bus-type",
  4000. .data_lanes = "data-lanes",
  4001. .remote_endpoint = "remote-endpoint",
  4002. @@ -72,11 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
  4003. return ret;
  4004. }
  4005. +static u32 cio2_bridge_parse_rotation(u8 rotation)
  4006. +{
  4007. + if (rotation == 1)
  4008. + return 180;
  4009. + return 0;
  4010. +}
  4011. +
  4012. +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
  4013. +{
  4014. + switch (panel) {
  4015. + case 4:
  4016. + return V4L2_FWNODE_ORIENTATION_FRONT;
  4017. + case 5:
  4018. + return V4L2_FWNODE_ORIENTATION_BACK;
  4019. + default:
  4020. + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  4021. + }
  4022. +}
  4023. +
  4024. static void cio2_bridge_create_fwnode_properties(
  4025. struct cio2_sensor *sensor,
  4026. struct cio2_bridge *bridge,
  4027. const struct cio2_sensor_config *cfg)
  4028. {
  4029. + u32 rotation;
  4030. + enum v4l2_fwnode_orientation orientation;
  4031. +
  4032. + rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
  4033. + orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
  4034. +
  4035. sensor->prop_names = prop_names;
  4036. sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CIO2_ENDPOINT]);
  4037. @@ -85,9 +111,12 @@ static void cio2_bridge_create_fwnode_properties(
  4038. sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
  4039. sensor->prop_names.clock_frequency,
  4040. sensor->ssdb.mclkspeed);
  4041. - sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
  4042. + sensor->dev_properties[1] = PROPERTY_ENTRY_U32(
  4043. sensor->prop_names.rotation,
  4044. - sensor->ssdb.degree);
  4045. + rotation);
  4046. + sensor->dev_properties[2] = PROPERTY_ENTRY_U32(
  4047. + sensor->prop_names.orientation,
  4048. + orientation);
  4049. sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
  4050. sensor->prop_names.bus_type,
  4051. @@ -159,6 +188,7 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
  4052. for (i = 0; i < bridge->n_sensors; i++) {
  4053. sensor = &bridge->sensors[i];
  4054. software_node_unregister_nodes(sensor->swnodes);
  4055. + ACPI_FREE(sensor->pld);
  4056. acpi_dev_put(sensor->adev);
  4057. }
  4058. }
  4059. @@ -170,6 +200,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  4060. struct fwnode_handle *fwnode;
  4061. struct cio2_sensor *sensor;
  4062. struct acpi_device *adev;
  4063. + acpi_status status;
  4064. int ret;
  4065. for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
  4066. @@ -191,11 +222,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  4067. if (ret)
  4068. goto err_put_adev;
  4069. + status = acpi_get_physical_device_location(adev->handle, &sensor->pld);
  4070. + if (ACPI_FAILURE(status))
  4071. + goto err_put_adev;
  4072. +
  4073. if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
  4074. dev_err(&adev->dev,
  4075. "Number of lanes in SSDB is invalid\n");
  4076. ret = -EINVAL;
  4077. - goto err_put_adev;
  4078. + goto err_free_pld;
  4079. }
  4080. cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
  4081. @@ -203,7 +238,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  4082. ret = software_node_register_nodes(sensor->swnodes);
  4083. if (ret)
  4084. - goto err_put_adev;
  4085. + goto err_free_pld;
  4086. fwnode = software_node_fwnode(&sensor->swnodes[
  4087. SWNODE_SENSOR_HID]);
  4088. @@ -225,6 +260,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  4089. err_free_swnodes:
  4090. software_node_unregister_nodes(sensor->swnodes);
  4091. +err_free_pld:
  4092. + ACPI_FREE(sensor->pld);
  4093. err_put_adev:
  4094. acpi_dev_put(sensor->adev);
  4095. return ret;
  4096. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4097. index dd0ffcafa489..924d99d20328 100644
  4098. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4099. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4100. @@ -80,6 +80,7 @@ struct cio2_sensor_ssdb {
  4101. struct cio2_property_names {
  4102. char clock_frequency[16];
  4103. char rotation[9];
  4104. + char orientation[12];
  4105. char bus_type[9];
  4106. char data_lanes[11];
  4107. char remote_endpoint[16];
  4108. @@ -106,6 +107,8 @@ struct cio2_sensor {
  4109. struct cio2_node_names node_names;
  4110. struct cio2_sensor_ssdb ssdb;
  4111. + struct acpi_pld_info *pld;
  4112. +
  4113. struct cio2_property_names prop_names;
  4114. struct property_entry ep_properties[5];
  4115. struct property_entry dev_properties[3];
  4116. --
  4117. 2.33.0
  4118. From 2daaab808ea446cbfee2022b1b94ac20cbeaf466 Mon Sep 17 00:00:00 2001
  4119. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  4120. Date: Sun, 24 Jan 2021 11:07:42 +0100
  4121. Subject: [PATCH] cio2-bridge: Use macros and add warnings
  4122. MIME-Version: 1.0
  4123. Content-Type: text/plain; charset=UTF-8
  4124. Content-Transfer-Encoding: 8bit
  4125. Use macros for the _PLD panel as defined in the ACPI spec 6.3 and emit
  4126. a warning if we see an unknown value.
  4127. Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
  4128. Patchset: cameras
  4129. ---
  4130. drivers/media/pci/intel/ipu3/cio2-bridge.c | 33 ++++++++++++++++------
  4131. drivers/media/pci/intel/ipu3/cio2-bridge.h | 13 +++++++++
  4132. 2 files changed, 37 insertions(+), 9 deletions(-)
  4133. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  4134. index d4a48cec2644..1052885caa25 100644
  4135. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  4136. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  4137. @@ -73,21 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
  4138. return ret;
  4139. }
  4140. -static u32 cio2_bridge_parse_rotation(u8 rotation)
  4141. +static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
  4142. {
  4143. - if (rotation == 1)
  4144. + switch (sensor->ssdb.degree) {
  4145. + case CIO2_SENSOR_ROTATION_NORMAL:
  4146. + return 0;
  4147. + case CIO2_SENSOR_ROTATION_INVERTED:
  4148. return 180;
  4149. - return 0;
  4150. + default:
  4151. + dev_warn(&sensor->adev->dev,
  4152. + "Unknown rotation %d. Assume 0 degree rotation\n",
  4153. + sensor->ssdb.degree);
  4154. + return 0;
  4155. + }
  4156. }
  4157. -static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
  4158. +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_sensor *sensor)
  4159. {
  4160. - switch (panel) {
  4161. - case 4:
  4162. + switch (sensor->pld->panel) {
  4163. + case CIO2_PLD_PANEL_FRONT:
  4164. return V4L2_FWNODE_ORIENTATION_FRONT;
  4165. - case 5:
  4166. + case CIO2_PLD_PANEL_BACK:
  4167. return V4L2_FWNODE_ORIENTATION_BACK;
  4168. + case CIO2_PLD_PANEL_TOP:
  4169. + case CIO2_PLD_PANEL_LEFT:
  4170. + case CIO2_PLD_PANEL_RIGHT:
  4171. + case CIO2_PLD_PANEL_UNKNOWN:
  4172. + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  4173. default:
  4174. + dev_warn(&sensor->adev->dev, "Unknown _PLD panel value %d\n",
  4175. + sensor->pld->panel);
  4176. return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  4177. }
  4178. }
  4179. @@ -100,8 +115,8 @@ static void cio2_bridge_create_fwnode_properties(
  4180. u32 rotation;
  4181. enum v4l2_fwnode_orientation orientation;
  4182. - rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
  4183. - orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
  4184. + rotation = cio2_bridge_parse_rotation(sensor);
  4185. + orientation = cio2_bridge_parse_orientation(sensor);
  4186. sensor->prop_names = prop_names;
  4187. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4188. index 924d99d20328..e1e388cc9f45 100644
  4189. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4190. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4191. @@ -12,6 +12,19 @@
  4192. #define CIO2_MAX_LANES 4
  4193. #define MAX_NUM_LINK_FREQS 3
  4194. +/* Values are estimated guesses as we don't have a spec */
  4195. +#define CIO2_SENSOR_ROTATION_NORMAL 0
  4196. +#define CIO2_SENSOR_ROTATION_INVERTED 1
  4197. +
  4198. +/* Panel position defined in _PLD section of ACPI Specification 6.3 */
  4199. +#define CIO2_PLD_PANEL_TOP 0
  4200. +#define CIO2_PLD_PANEL_BOTTOM 1
  4201. +#define CIO2_PLD_PANEL_LEFT 2
  4202. +#define CIO2_PLD_PANEL_RIGHT 3
  4203. +#define CIO2_PLD_PANEL_FRONT 4
  4204. +#define CIO2_PLD_PANEL_BACK 5
  4205. +#define CIO2_PLD_PANEL_UNKNOWN 6
  4206. +
  4207. #define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
  4208. (const struct cio2_sensor_config) { \
  4209. .hid = _HID, \
  4210. --
  4211. 2.33.0
  4212. From c5d21ba34347b8960c0450e92622177869a6ae37 Mon Sep 17 00:00:00 2001
  4213. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  4214. Date: Thu, 6 May 2021 07:52:44 +0200
  4215. Subject: [PATCH] cio2-bridge: Use correct dev_properties size
  4216. Patchset: cameras
  4217. ---
  4218. drivers/media/pci/intel/ipu3/cio2-bridge.h | 2 +-
  4219. 1 file changed, 1 insertion(+), 1 deletion(-)
  4220. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4221. index e1e388cc9f45..deaf5804f70d 100644
  4222. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4223. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  4224. @@ -124,7 +124,7 @@ struct cio2_sensor {
  4225. struct cio2_property_names prop_names;
  4226. struct property_entry ep_properties[5];
  4227. - struct property_entry dev_properties[3];
  4228. + struct property_entry dev_properties[4];
  4229. struct property_entry cio2_properties[3];
  4230. struct software_node_ref_args local_ref[1];
  4231. struct software_node_ref_args remote_ref[1];
  4232. --
  4233. 2.33.0
  4234. From b8b2e8e1b91d360c294c0b9260b249eb90be898e Mon Sep 17 00:00:00 2001
  4235. From: Daniel Scally <djrscally@gmail.com>
  4236. Date: Thu, 20 May 2021 23:31:04 +0100
  4237. Subject: [PATCH] media: i2c: Fix vertical flip in ov5693
  4238. The pinkness experienced by users with rotated sensors in their laptops
  4239. was due to an incorrect setting for the vertical flip function; the
  4240. datasheet for the sensor gives the settings as bits 1&2 in one place and
  4241. bits 1&6 in another.
  4242. Switch to flipping bit 6 instead of bit 2 for 0x3820 in the vertical
  4243. flip function to fix the pink hue.
  4244. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4245. Patchset: cameras
  4246. ---
  4247. drivers/media/i2c/ov5693.c | 2 +-
  4248. 1 file changed, 1 insertion(+), 1 deletion(-)
  4249. diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
  4250. index 276f625d4d23..1653fb49f6e0 100644
  4251. --- a/drivers/media/i2c/ov5693.c
  4252. +++ b/drivers/media/i2c/ov5693.c
  4253. @@ -133,7 +133,7 @@
  4254. #define OV5693_SUB_INC_Y_REG 0x3815
  4255. #define OV5693_FORMAT1_REG 0x3820
  4256. -#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  4257. +#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(6)
  4258. #define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
  4259. #define OV5693_FORMAT1_VBIN_EN BIT(0)
  4260. #define OV5693_FORMAT2_REG 0x3821
  4261. --
  4262. 2.33.0
  4263. From 8898454c0454f212a0aecef0b880cf51c5b0c9b1 Mon Sep 17 00:00:00 2001
  4264. From: Daniel Scally <djrscally@gmail.com>
  4265. Date: Fri, 9 Jul 2021 16:39:18 +0100
  4266. Subject: [PATCH] media: i2c: Add ACPI support to ov8865
  4267. The ov8865 sensor is sometimes found on x86 platforms enumerated via ACPI.
  4268. Add an ACPI match table to the driver so that it's probed on those
  4269. platforms.
  4270. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4271. Patchset: cameras
  4272. ---
  4273. drivers/media/i2c/ov8865.c | 8 ++++++++
  4274. 1 file changed, 8 insertions(+)
  4275. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4276. index 9ecf180635ee..a28adf45b1b1 100644
  4277. --- a/drivers/media/i2c/ov8865.c
  4278. +++ b/drivers/media/i2c/ov8865.c
  4279. @@ -5,6 +5,7 @@
  4280. * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
  4281. */
  4282. +#include <linux/acpi.h>
  4283. #include <linux/clk.h>
  4284. #include <linux/delay.h>
  4285. #include <linux/device.h>
  4286. @@ -2948,6 +2949,12 @@ static const struct dev_pm_ops ov8865_pm_ops = {
  4287. SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)
  4288. };
  4289. +static const struct acpi_device_id ov8865_acpi_match[] = {
  4290. + {"INT347A"},
  4291. + {},
  4292. +};
  4293. +MODULE_DEVICE_TABLE(acpi, ov8865_acpi_match);
  4294. +
  4295. static const struct of_device_id ov8865_of_match[] = {
  4296. { .compatible = "ovti,ov8865" },
  4297. { }
  4298. @@ -2958,6 +2965,7 @@ static struct i2c_driver ov8865_driver = {
  4299. .driver = {
  4300. .name = "ov8865",
  4301. .of_match_table = ov8865_of_match,
  4302. + .acpi_match_table = ov8865_acpi_match,
  4303. .pm = &ov8865_pm_ops,
  4304. },
  4305. .probe_new = ov8865_probe,
  4306. --
  4307. 2.33.0
  4308. From 9ca51e2ceb46d583c14f3aa3f048e2affe6bbcf7 Mon Sep 17 00:00:00 2001
  4309. From: Daniel Scally <djrscally@gmail.com>
  4310. Date: Sat, 10 Jul 2021 21:20:17 +0100
  4311. Subject: [PATCH] media: i2c: Fix incorrect value in comment
  4312. The PLL configuration defined here sets 72MHz (which is correct), not
  4313. 80MHz. Correct the comment.
  4314. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4315. Patchset: cameras
  4316. ---
  4317. drivers/media/i2c/ov8865.c | 2 +-
  4318. 1 file changed, 1 insertion(+), 1 deletion(-)
  4319. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4320. index a28adf45b1b1..7d716b0d47c1 100644
  4321. --- a/drivers/media/i2c/ov8865.c
  4322. +++ b/drivers/media/i2c/ov8865.c
  4323. @@ -713,7 +713,7 @@ static const struct ov8865_pll2_config ov8865_pll2_config_native = {
  4324. /*
  4325. * EXTCLK = 24 MHz
  4326. * DAC_CLK = 360 MHz
  4327. - * SCLK = 80 MHz
  4328. + * SCLK = 72 MHz
  4329. */
  4330. static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
  4331. --
  4332. 2.33.0
  4333. From 3b21a856d783be36d9f2ed2759e51c44163cae18 Mon Sep 17 00:00:00 2001
  4334. From: Daniel Scally <djrscally@gmail.com>
  4335. Date: Sat, 10 Jul 2021 22:21:52 +0100
  4336. Subject: [PATCH] media: i2c: Check fwnode->secondary for endpoint
  4337. The ov8865 driver is one of those that can be connected to a CIO2
  4338. device by the cio2-bridge code. This means that the absence of an
  4339. endpoint for this device is not necessarily fatal, as one might be
  4340. built by the cio2-bridge when it probes. Check fwnode->secondary for
  4341. an endpoint, and defer probing if one isn't found rather than fail.
  4342. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4343. Patchset: cameras
  4344. ---
  4345. drivers/media/i2c/ov8865.c | 11 ++++++-----
  4346. 1 file changed, 6 insertions(+), 5 deletions(-)
  4347. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4348. index 7d716b0d47c1..5fb290a6fc6a 100644
  4349. --- a/drivers/media/i2c/ov8865.c
  4350. +++ b/drivers/media/i2c/ov8865.c
  4351. @@ -2781,6 +2781,7 @@ static int ov8865_resume(struct device *dev)
  4352. static int ov8865_probe(struct i2c_client *client)
  4353. {
  4354. struct device *dev = &client->dev;
  4355. + struct fwnode_handle *fwnode = dev_fwnode(dev);
  4356. struct fwnode_handle *handle;
  4357. struct ov8865_sensor *sensor;
  4358. struct v4l2_subdev *subdev;
  4359. @@ -2797,11 +2798,11 @@ static int ov8865_probe(struct i2c_client *client)
  4360. /* Graph Endpoint */
  4361. - handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
  4362. - if (!handle) {
  4363. - dev_err(dev, "unable to find endpoint node\n");
  4364. - return -EINVAL;
  4365. - }
  4366. + handle = fwnode_graph_get_next_endpoint(fwnode, NULL);
  4367. + if (!handle && !IS_ERR_OR_NULL(fwnode->secondary))
  4368. + handle = fwnode_graph_get_next_endpoint(fwnode->secondary, NULL);
  4369. + if (!handle)
  4370. + return -EPROBE_DEFER;
  4371. sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
  4372. --
  4373. 2.33.0
  4374. From e43b667cb36e343789bf55168b4c6622642356df Mon Sep 17 00:00:00 2001
  4375. From: Daniel Scally <djrscally@gmail.com>
  4376. Date: Sat, 10 Jul 2021 22:00:25 +0100
  4377. Subject: [PATCH] media: i2c: Support 19.2MHz input clock in ov8865
  4378. The ov8865 driver as written expects a 24MHz input clock, but the sensor
  4379. is sometimes found on x86 platforms with a 19.2MHz input clock supplied.
  4380. Add a set of PLL configurations to the driver to support that rate too.
  4381. As ACPI doesn't auto-configure the clock rate, check for a clock-frequency
  4382. during probe and set that rate if one is found.
  4383. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4384. Patchset: cameras
  4385. ---
  4386. drivers/media/i2c/ov8865.c | 157 +++++++++++++++++++++++++++----------
  4387. 1 file changed, 114 insertions(+), 43 deletions(-)
  4388. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4389. index 5fb290a6fc6a..cae7dc9da49d 100644
  4390. --- a/drivers/media/i2c/ov8865.c
  4391. +++ b/drivers/media/i2c/ov8865.c
  4392. @@ -21,10 +21,6 @@
  4393. #include <media/v4l2-image-sizes.h>
  4394. #include <media/v4l2-mediabus.h>
  4395. -/* Clock rate */
  4396. -
  4397. -#define OV8865_EXTCLK_RATE 24000000
  4398. -
  4399. /* Register definitions */
  4400. /* System */
  4401. @@ -665,6 +661,9 @@ struct ov8865_sensor {
  4402. struct regulator *avdd;
  4403. struct regulator *dvdd;
  4404. struct regulator *dovdd;
  4405. +
  4406. + unsigned long extclk_rate;
  4407. + unsigned int extclk_rate_idx;
  4408. struct clk *extclk;
  4409. struct v4l2_fwnode_endpoint endpoint;
  4410. @@ -680,49 +679,83 @@ struct ov8865_sensor {
  4411. /* Static definitions */
  4412. /*
  4413. - * EXTCLK = 24 MHz
  4414. * PHY_SCLK = 720 MHz
  4415. * MIPI_PCLK = 90 MHz
  4416. */
  4417. -static const struct ov8865_pll1_config ov8865_pll1_config_native = {
  4418. - .pll_pre_div_half = 1,
  4419. - .pll_pre_div = 0,
  4420. - .pll_mul = 30,
  4421. - .m_div = 1,
  4422. - .mipi_div = 3,
  4423. - .pclk_div = 1,
  4424. - .sys_pre_div = 1,
  4425. - .sys_div = 2,
  4426. +
  4427. +static const struct ov8865_pll1_config ov8865_pll1_configs_native[] = {
  4428. + { /* 19.2 MHz input clock */
  4429. + .pll_pre_div_half = 1,
  4430. + .pll_pre_div = 2,
  4431. + .pll_mul = 75,
  4432. + .m_div = 1,
  4433. + .mipi_div = 3,
  4434. + .pclk_div = 1,
  4435. + .sys_pre_div = 1,
  4436. + .sys_div = 2,
  4437. + },
  4438. + { /* 24MHz input clock */
  4439. + .pll_pre_div_half = 1,
  4440. + .pll_pre_div = 0,
  4441. + .pll_mul = 30,
  4442. + .m_div = 1,
  4443. + .mipi_div = 3,
  4444. + .pclk_div = 1,
  4445. + .sys_pre_div = 1,
  4446. + .sys_div = 2,
  4447. + },
  4448. };
  4449. /*
  4450. - * EXTCLK = 24 MHz
  4451. * DAC_CLK = 360 MHz
  4452. * SCLK = 144 MHz
  4453. */
  4454. -static const struct ov8865_pll2_config ov8865_pll2_config_native = {
  4455. - .pll_pre_div_half = 1,
  4456. - .pll_pre_div = 0,
  4457. - .pll_mul = 30,
  4458. - .dac_div = 2,
  4459. - .sys_pre_div = 5,
  4460. - .sys_div = 0,
  4461. +static const struct ov8865_pll2_config ov8865_pll2_configs_native[] = {
  4462. + /* 19.2MHz input clock */
  4463. + {
  4464. + .pll_pre_div_half = 1,
  4465. + .pll_pre_div = 5,
  4466. + .pll_mul = 75,
  4467. + .dac_div = 1,
  4468. + .sys_pre_div = 1,
  4469. + .sys_div = 3,
  4470. + },
  4471. + /* 24MHz input clock */
  4472. + {
  4473. + .pll_pre_div_half = 1,
  4474. + .pll_pre_div = 0,
  4475. + .pll_mul = 30,
  4476. + .dac_div = 2,
  4477. + .sys_pre_div = 5,
  4478. + .sys_div = 0,
  4479. + }
  4480. };
  4481. /*
  4482. - * EXTCLK = 24 MHz
  4483. * DAC_CLK = 360 MHz
  4484. * SCLK = 72 MHz
  4485. */
  4486. -static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
  4487. +static const struct ov8865_pll2_config ov8865_pll2_configs_binning[] = {
  4488. + /* 19.2MHz input clock */
  4489. + {
  4490. + .pll_pre_div_half = 1,
  4491. + .pll_pre_div = 2,
  4492. + .pll_mul = 75,
  4493. + .dac_div = 2,
  4494. + .sys_pre_div = 10,
  4495. + .sys_div = 0,
  4496. + },
  4497. + /* 24MHz input clock */
  4498. + {
  4499. .pll_pre_div_half = 1,
  4500. .pll_pre_div = 0,
  4501. .pll_mul = 30,
  4502. .dac_div = 2,
  4503. .sys_pre_div = 10,
  4504. .sys_div = 0,
  4505. + }
  4506. };
  4507. static const struct ov8865_sclk_config ov8865_sclk_config_native = {
  4508. @@ -934,8 +967,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  4509. .frame_interval = { 1, 30 },
  4510. /* PLL */
  4511. - .pll1_config = &ov8865_pll1_config_native,
  4512. - .pll2_config = &ov8865_pll2_config_native,
  4513. + .pll1_config = ov8865_pll1_configs_native,
  4514. + .pll2_config = ov8865_pll2_configs_native,
  4515. .sclk_config = &ov8865_sclk_config_native,
  4516. /* Registers */
  4517. @@ -990,8 +1023,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  4518. .frame_interval = { 1, 30 },
  4519. /* PLL */
  4520. - .pll1_config = &ov8865_pll1_config_native,
  4521. - .pll2_config = &ov8865_pll2_config_native,
  4522. + .pll1_config = ov8865_pll1_configs_native,
  4523. + .pll2_config = ov8865_pll2_configs_native,
  4524. .sclk_config = &ov8865_sclk_config_native,
  4525. /* Registers */
  4526. @@ -1050,8 +1083,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  4527. .frame_interval = { 1, 30 },
  4528. /* PLL */
  4529. - .pll1_config = &ov8865_pll1_config_native,
  4530. - .pll2_config = &ov8865_pll2_config_binning,
  4531. + .pll1_config = ov8865_pll1_configs_native,
  4532. + .pll2_config = ov8865_pll2_configs_binning,
  4533. .sclk_config = &ov8865_sclk_config_native,
  4534. /* Registers */
  4535. @@ -1116,8 +1149,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  4536. .frame_interval = { 1, 90 },
  4537. /* PLL */
  4538. - .pll1_config = &ov8865_pll1_config_native,
  4539. - .pll2_config = &ov8865_pll2_config_binning,
  4540. + .pll1_config = ov8865_pll1_configs_native,
  4541. + .pll2_config = ov8865_pll2_configs_binning,
  4542. .sclk_config = &ov8865_sclk_config_native,
  4543. /* Registers */
  4544. @@ -1266,6 +1299,13 @@ static const struct ov8865_register_value ov8865_init_sequence[] = {
  4545. { 0x4503, 0x10 },
  4546. };
  4547. +/* Clock rate */
  4548. +
  4549. +static const unsigned long supported_extclk_rates[] = {
  4550. + 19200000,
  4551. + 24000000,
  4552. +};
  4553. +
  4554. static const s64 ov8865_link_freq_menu[] = {
  4555. 360000000,
  4556. };
  4557. @@ -1513,12 +1553,11 @@ static int ov8865_isp_configure(struct ov8865_sensor *sensor)
  4558. static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,
  4559. const struct ov8865_mode *mode)
  4560. {
  4561. - const struct ov8865_pll1_config *config = mode->pll1_config;
  4562. - unsigned long extclk_rate;
  4563. + const struct ov8865_pll1_config *config;
  4564. unsigned long pll1_rate;
  4565. - extclk_rate = clk_get_rate(sensor->extclk);
  4566. - pll1_rate = extclk_rate * config->pll_mul / config->pll_pre_div_half;
  4567. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  4568. + pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half;
  4569. switch (config->pll_pre_div) {
  4570. case 0:
  4571. @@ -1552,10 +1591,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
  4572. const struct ov8865_mode *mode,
  4573. u32 mbus_code)
  4574. {
  4575. - const struct ov8865_pll1_config *config = mode->pll1_config;
  4576. + const struct ov8865_pll1_config *config;
  4577. u8 value;
  4578. int ret;
  4579. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  4580. +
  4581. switch (mbus_code) {
  4582. case MEDIA_BUS_FMT_SBGGR10_1X10:
  4583. value = OV8865_MIPI_BIT_SEL(10);
  4584. @@ -1622,9 +1663,11 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
  4585. static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
  4586. const struct ov8865_mode *mode)
  4587. {
  4588. - const struct ov8865_pll2_config *config = mode->pll2_config;
  4589. + const struct ov8865_pll2_config *config;
  4590. int ret;
  4591. + config = &mode->pll2_config[sensor->extclk_rate_idx];
  4592. +
  4593. ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,
  4594. OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |
  4595. OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));
  4596. @@ -2053,9 +2096,11 @@ static int ov8865_mode_configure(struct ov8865_sensor *sensor,
  4597. static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,
  4598. const struct ov8865_mode *mode)
  4599. {
  4600. - const struct ov8865_pll1_config *config = mode->pll1_config;
  4601. + const struct ov8865_pll1_config *config;
  4602. unsigned long pll1_rate;
  4603. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  4604. +
  4605. pll1_rate = ov8865_mode_pll1_rate(sensor, mode);
  4606. return pll1_rate / config->m_div / 2;
  4607. @@ -2786,7 +2831,8 @@ static int ov8865_probe(struct i2c_client *client)
  4608. struct ov8865_sensor *sensor;
  4609. struct v4l2_subdev *subdev;
  4610. struct media_pad *pad;
  4611. - unsigned long rate;
  4612. + unsigned int rate;
  4613. + unsigned int i;
  4614. int ret;
  4615. sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
  4616. @@ -2863,13 +2909,38 @@ static int ov8865_probe(struct i2c_client *client)
  4617. goto error_endpoint;
  4618. }
  4619. - rate = clk_get_rate(sensor->extclk);
  4620. - if (rate != OV8865_EXTCLK_RATE) {
  4621. - dev_err(dev, "clock rate %lu Hz is unsupported\n", rate);
  4622. + /*
  4623. + * We could have either a 24MHz or 19.2MHz clock rate. Check for a
  4624. + * clock-frequency property and if found, set that rate. This should
  4625. + * cover ACPI case. If the system uses devicetree then the configured
  4626. + * rate should already be set, so we'll have to check it.
  4627. + */
  4628. +
  4629. + ret = fwnode_property_read_u32(fwnode, "clock-frequency", &rate);
  4630. + if (!ret) {
  4631. + ret = clk_set_rate(sensor->extclk, rate);
  4632. + if (ret) {
  4633. + dev_err(dev, "failed to set clock rate\n");
  4634. + return ret;
  4635. + }
  4636. + }
  4637. +
  4638. + sensor->extclk_rate = clk_get_rate(sensor->extclk);
  4639. +
  4640. + for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
  4641. + if (sensor->extclk_rate == supported_extclk_rates[i])
  4642. + break;
  4643. + }
  4644. +
  4645. + if (i == ARRAY_SIZE(supported_extclk_rates)) {
  4646. + dev_err(dev, "clock rate %lu Hz is unsupported\n",
  4647. + sensor->extclk_rate);
  4648. ret = -EINVAL;
  4649. goto error_endpoint;
  4650. }
  4651. + sensor->extclk_rate_idx = i;
  4652. +
  4653. /* Subdev, entity and pad */
  4654. subdev = &sensor->subdev;
  4655. --
  4656. 2.33.0
  4657. From 13f5cd8218ed183accc1ea89780b42355ef1b522 Mon Sep 17 00:00:00 2001
  4658. From: Daniel Scally <djrscally@gmail.com>
  4659. Date: Sat, 10 Jul 2021 22:19:10 +0100
  4660. Subject: [PATCH] media: i2c: Add .get_selection() support to ov8865
  4661. The ov8865 drivers media pad ops currently does not include
  4662. .get_selection() - add support for that callback.
  4663. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4664. Patchset: cameras
  4665. ---
  4666. drivers/media/i2c/ov8865.c | 61 ++++++++++++++++++++++++++++++++++++++
  4667. 1 file changed, 61 insertions(+)
  4668. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4669. index cae7dc9da49d..3ce0af7e0054 100644
  4670. --- a/drivers/media/i2c/ov8865.c
  4671. +++ b/drivers/media/i2c/ov8865.c
  4672. @@ -450,6 +450,15 @@
  4673. #define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES 2
  4674. #define OV8865_PRE_CTRL0_PATTERN_BLACK 3
  4675. +/* Pixel Array */
  4676. +
  4677. +#define OV8865_NATIVE_WIDTH 3296
  4678. +#define OV8865_NATIVE_HEIGHT 2528
  4679. +#define OV8865_ACTIVE_START_TOP 32
  4680. +#define OV8865_ACTIVE_START_LEFT 80
  4681. +#define OV8865_ACTIVE_WIDTH 3264
  4682. +#define OV8865_ACTIVE_HEIGHT 2448
  4683. +
  4684. /* Macros */
  4685. #define ov8865_subdev_sensor(s) \
  4686. @@ -2745,12 +2754,64 @@ static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
  4687. return 0;
  4688. }
  4689. +static void
  4690. +__ov8865_get_pad_crop(struct ov8865_sensor *sensor,
  4691. + struct v4l2_subdev_pad_config *cfg, unsigned int pad,
  4692. + enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
  4693. +{
  4694. + switch (which) {
  4695. + case V4L2_SUBDEV_FORMAT_TRY:
  4696. + *r = *v4l2_subdev_get_try_crop(&sensor->subdev, cfg, pad);
  4697. + break;
  4698. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  4699. + r->height = sensor->state.mode->output_size_y;
  4700. + r->width = sensor->state.mode->output_size_x;
  4701. + r->top = (OV8865_NATIVE_HEIGHT - sensor->state.mode->output_size_y) / 2;
  4702. + r->left = (OV8865_NATIVE_WIDTH - sensor->state.mode->output_size_x) / 2;
  4703. + break;
  4704. + }
  4705. +}
  4706. +
  4707. +static int ov8865_get_selection(struct v4l2_subdev *subdev,
  4708. + struct v4l2_subdev_pad_config *cfg,
  4709. + struct v4l2_subdev_selection *sel)
  4710. +{
  4711. + struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
  4712. +
  4713. + switch (sel->target) {
  4714. + case V4L2_SEL_TGT_CROP:
  4715. + mutex_lock(&sensor->mutex);
  4716. + __ov8865_get_pad_crop(sensor, cfg, sel->pad,
  4717. + sel->which, &sel->r);
  4718. + mutex_unlock(&sensor->mutex);
  4719. + break;
  4720. + case V4L2_SEL_TGT_NATIVE_SIZE:
  4721. + sel->r.top = 0;
  4722. + sel->r.left = 0;
  4723. + sel->r.width = OV8865_NATIVE_WIDTH;
  4724. + sel->r.height = OV8865_NATIVE_HEIGHT;
  4725. + break;
  4726. + case V4L2_SEL_TGT_CROP_BOUNDS:
  4727. + case V4L2_SEL_TGT_CROP_DEFAULT:
  4728. + sel->r.top = OV8865_ACTIVE_START_TOP;
  4729. + sel->r.left = OV8865_ACTIVE_START_LEFT;
  4730. + sel->r.width = OV8865_ACTIVE_WIDTH;
  4731. + sel->r.height = OV8865_ACTIVE_HEIGHT;
  4732. + break;
  4733. + default:
  4734. + return -EINVAL;
  4735. + }
  4736. +
  4737. + return 0;
  4738. +}
  4739. +
  4740. static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
  4741. .enum_mbus_code = ov8865_enum_mbus_code,
  4742. .get_fmt = ov8865_get_fmt,
  4743. .set_fmt = ov8865_set_fmt,
  4744. .enum_frame_size = ov8865_enum_frame_size,
  4745. .enum_frame_interval = ov8865_enum_frame_interval,
  4746. + .get_selection = ov8865_get_selection,
  4747. };
  4748. static const struct v4l2_subdev_ops ov8865_subdev_ops = {
  4749. --
  4750. 2.33.0
  4751. From b08e46416ae81314e89b7b3e74c0c69de1f41f4e Mon Sep 17 00:00:00 2001
  4752. From: Daniel Scally <djrscally@gmail.com>
  4753. Date: Sat, 10 Jul 2021 22:34:43 +0100
  4754. Subject: [PATCH] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN
  4755. The V4L2_CID_GAIN control for this driver configures registers that
  4756. the datasheet specifies as analogue gain. Switch the control's ID
  4757. to V4L2_CID_ANALOGUE_GAIN.
  4758. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4759. Patchset: cameras
  4760. ---
  4761. drivers/media/i2c/ov8865.c | 8 ++++----
  4762. 1 file changed, 4 insertions(+), 4 deletions(-)
  4763. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4764. index 3ce0af7e0054..c0c6b1d7e1ed 100644
  4765. --- a/drivers/media/i2c/ov8865.c
  4766. +++ b/drivers/media/i2c/ov8865.c
  4767. @@ -2137,7 +2137,7 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
  4768. /* Gain */
  4769. -static int ov8865_gain_configure(struct ov8865_sensor *sensor, u32 gain)
  4770. +static int ov8865_analog_gain_configure(struct ov8865_sensor *sensor, u32 gain)
  4771. {
  4772. int ret;
  4773. @@ -2447,8 +2447,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  4774. if (ret)
  4775. return ret;
  4776. break;
  4777. - case V4L2_CID_GAIN:
  4778. - ret = ov8865_gain_configure(sensor, ctrl->val);
  4779. + case V4L2_CID_ANALOGUE_GAIN:
  4780. + ret = ov8865_analog_gain_configure(sensor, ctrl->val);
  4781. if (ret)
  4782. return ret;
  4783. break;
  4784. @@ -2493,7 +2493,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4785. /* Gain */
  4786. - v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 128, 8191, 128, 128);
  4787. + v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 8191, 128, 128);
  4788. /* White Balance */
  4789. --
  4790. 2.33.0
  4791. From aa022a89b38f9807db2f243e21b2c4b33a0f51cc Mon Sep 17 00:00:00 2001
  4792. From: Daniel Scally <djrscally@gmail.com>
  4793. Date: Mon, 12 Jul 2021 22:54:56 +0100
  4794. Subject: [PATCH] media: i2c: Add vblank control to ov8865
  4795. Add a V4L2_CID_VBLANK control to the ov8865 driver.
  4796. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4797. Patchset: cameras
  4798. ---
  4799. drivers/media/i2c/ov8865.c | 34 ++++++++++++++++++++++++++++++++++
  4800. 1 file changed, 34 insertions(+)
  4801. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4802. index c0c6b1d7e1ed..5f67d85e33bc 100644
  4803. --- a/drivers/media/i2c/ov8865.c
  4804. +++ b/drivers/media/i2c/ov8865.c
  4805. @@ -183,6 +183,8 @@
  4806. #define OV8865_VTS_H(v) (((v) & GENMASK(11, 8)) >> 8)
  4807. #define OV8865_VTS_L_REG 0x380f
  4808. #define OV8865_VTS_L(v) ((v) & GENMASK(7, 0))
  4809. +#define OV8865_TIMING_MAX_VTS 0xffff
  4810. +#define OV8865_TIMING_MIN_VTS 0x04
  4811. #define OV8865_OFFSET_X_H_REG 0x3810
  4812. #define OV8865_OFFSET_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  4813. #define OV8865_OFFSET_X_L_REG 0x3811
  4814. @@ -658,6 +660,7 @@ struct ov8865_state {
  4815. struct ov8865_ctrls {
  4816. struct v4l2_ctrl *link_freq;
  4817. struct v4l2_ctrl *pixel_rate;
  4818. + struct v4l2_ctrl *vblank;
  4819. struct v4l2_ctrl_handler handler;
  4820. };
  4821. @@ -2212,6 +2215,20 @@ static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,
  4822. ov8865_test_pattern_bits[index]);
  4823. }
  4824. +/* Blanking */
  4825. +
  4826. +static int ov8865_vts_configure(struct ov8865_sensor *sensor, u32 vblank)
  4827. +{
  4828. + u16 vts = sensor->state.mode->output_size_y + vblank;
  4829. + int ret;
  4830. +
  4831. + ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(vts));
  4832. + if (ret)
  4833. + return ret;
  4834. +
  4835. + return ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(vts));
  4836. +}
  4837. +
  4838. /* State */
  4839. static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,
  4840. @@ -2463,6 +2480,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  4841. case V4L2_CID_TEST_PATTERN:
  4842. index = (unsigned int)ctrl->val;
  4843. return ov8865_test_pattern_configure(sensor, index);
  4844. + case V4L2_CID_VBLANK:
  4845. + return ov8865_vts_configure(sensor, ctrl->val);
  4846. default:
  4847. return -EINVAL;
  4848. }
  4849. @@ -2479,6 +2498,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4850. struct ov8865_ctrls *ctrls = &sensor->ctrls;
  4851. struct v4l2_ctrl_handler *handler = &ctrls->handler;
  4852. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  4853. + const struct ov8865_mode *mode = sensor->state.mode;
  4854. + unsigned int vblank_max, vblank_def;
  4855. int ret;
  4856. v4l2_ctrl_handler_init(handler, 32);
  4857. @@ -2514,6 +2535,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4858. ARRAY_SIZE(ov8865_test_pattern_menu) - 1,
  4859. 0, 0, ov8865_test_pattern_menu);
  4860. + /* Blanking */
  4861. + vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
  4862. + vblank_def = mode->vts - mode->output_size_y;
  4863. + ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
  4864. + OV8865_TIMING_MIN_VTS, vblank_max, 1,
  4865. + vblank_def);
  4866. +
  4867. /* MIPI CSI-2 */
  4868. ctrls->link_freq =
  4869. @@ -2696,6 +2724,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  4870. sensor->state.mbus_code != mbus_code)
  4871. ret = ov8865_state_configure(sensor, mode, mbus_code);
  4872. + __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS,
  4873. + OV8865_TIMING_MAX_VTS - mode->output_size_y,
  4874. + 1, mode->vts - mode->output_size_y);
  4875. +
  4876. complete:
  4877. mutex_unlock(&sensor->mutex);
  4878. @@ -3023,6 +3055,8 @@ static int ov8865_probe(struct i2c_client *client)
  4879. /* Sensor */
  4880. + sensor->state.mode = &ov8865_modes[0];
  4881. +
  4882. ret = ov8865_ctrls_init(sensor);
  4883. if (ret)
  4884. goto error_mutex;
  4885. --
  4886. 2.33.0
  4887. From 11edb4401ec485ac51a517be5f1e3c1b11957c71 Mon Sep 17 00:00:00 2001
  4888. From: Daniel Scally <djrscally@gmail.com>
  4889. Date: Tue, 13 Jul 2021 23:40:33 +0100
  4890. Subject: [PATCH] media: i2c: Add hblank control to ov8865
  4891. Add a V4L2_CID_HBLANK control to the ov8865 driver. This is read only
  4892. with timing control intended to be done via vblanking alone.
  4893. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4894. Patchset: cameras
  4895. ---
  4896. drivers/media/i2c/ov8865.c | 14 ++++++++++++++
  4897. 1 file changed, 14 insertions(+)
  4898. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4899. index 5f67d85e33bc..66754ff62a22 100644
  4900. --- a/drivers/media/i2c/ov8865.c
  4901. +++ b/drivers/media/i2c/ov8865.c
  4902. @@ -660,6 +660,7 @@ struct ov8865_state {
  4903. struct ov8865_ctrls {
  4904. struct v4l2_ctrl *link_freq;
  4905. struct v4l2_ctrl *pixel_rate;
  4906. + struct v4l2_ctrl *hblank;
  4907. struct v4l2_ctrl *vblank;
  4908. struct v4l2_ctrl_handler handler;
  4909. @@ -2500,6 +2501,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4910. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  4911. const struct ov8865_mode *mode = sensor->state.mode;
  4912. unsigned int vblank_max, vblank_def;
  4913. + unsigned int hblank;
  4914. int ret;
  4915. v4l2_ctrl_handler_init(handler, 32);
  4916. @@ -2536,6 +2538,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4917. 0, 0, ov8865_test_pattern_menu);
  4918. /* Blanking */
  4919. + hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
  4920. + ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,
  4921. + hblank, 1, hblank);
  4922. +
  4923. + if (ctrls->hblank)
  4924. + ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  4925. +
  4926. vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
  4927. vblank_def = mode->vts - mode->output_size_y;
  4928. ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
  4929. @@ -2684,6 +2693,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  4930. struct v4l2_mbus_framefmt *mbus_format = &format->format;
  4931. const struct ov8865_mode *mode;
  4932. u32 mbus_code = 0;
  4933. + unsigned int hblank;
  4934. unsigned int index;
  4935. int ret = 0;
  4936. @@ -2728,6 +2738,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  4937. OV8865_TIMING_MAX_VTS - mode->output_size_y,
  4938. 1, mode->vts - mode->output_size_y);
  4939. + hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
  4940. + __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
  4941. + hblank);
  4942. +
  4943. complete:
  4944. mutex_unlock(&sensor->mutex);
  4945. --
  4946. 2.33.0
  4947. From d27a9793580dcf69c63178e50c1935cd2636ec82 Mon Sep 17 00:00:00 2001
  4948. From: Daniel Scally <djrscally@gmail.com>
  4949. Date: Tue, 13 Jul 2021 23:43:17 +0100
  4950. Subject: [PATCH] media: i2c: cap exposure at height + vblank in ov8865
  4951. Exposure limits depend on the total height; when vblank is altered (and
  4952. thus the total height is altered), change the exposure limits to reflect
  4953. the new cap.
  4954. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  4955. Patchset: cameras
  4956. ---
  4957. drivers/media/i2c/ov8865.c | 24 ++++++++++++++++++++++--
  4958. 1 file changed, 22 insertions(+), 2 deletions(-)
  4959. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  4960. index 66754ff62a22..93e741952050 100644
  4961. --- a/drivers/media/i2c/ov8865.c
  4962. +++ b/drivers/media/i2c/ov8865.c
  4963. @@ -662,6 +662,7 @@ struct ov8865_ctrls {
  4964. struct v4l2_ctrl *pixel_rate;
  4965. struct v4l2_ctrl *hblank;
  4966. struct v4l2_ctrl *vblank;
  4967. + struct v4l2_ctrl *exposure;
  4968. struct v4l2_ctrl_handler handler;
  4969. };
  4970. @@ -2455,6 +2456,18 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  4971. unsigned int index;
  4972. int ret;
  4973. + /* If VBLANK is altered we need to update exposure to compensate */
  4974. + if (ctrl->id == V4L2_CID_VBLANK) {
  4975. + int exposure_max;
  4976. +
  4977. + exposure_max = sensor->state.mode->output_size_y + ctrl->val;
  4978. + __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
  4979. + sensor->ctrls.exposure->minimum,
  4980. + exposure_max,
  4981. + sensor->ctrls.exposure->step,
  4982. + min(sensor->ctrls.exposure->val, exposure_max));
  4983. + }
  4984. +
  4985. /* Wait for the sensor to be on before setting controls. */
  4986. if (pm_runtime_suspended(sensor->dev))
  4987. return 0;
  4988. @@ -2511,8 +2524,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  4989. /* Exposure */
  4990. - v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
  4991. - 512);
  4992. + ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
  4993. + 1048575, 16, 512);
  4994. /* Gain */
  4995. @@ -2695,6 +2708,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  4996. u32 mbus_code = 0;
  4997. unsigned int hblank;
  4998. unsigned int index;
  4999. + int exposure_max;
  5000. int ret = 0;
  5001. mutex_lock(&sensor->mutex);
  5002. @@ -2742,6 +2756,12 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  5003. __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
  5004. hblank);
  5005. + exposure_max = mode->vts;
  5006. + __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
  5007. + sensor->ctrls.exposure->minimum, exposure_max,
  5008. + sensor->ctrls.exposure->step,
  5009. + min(sensor->ctrls.exposure->val, exposure_max));
  5010. +
  5011. complete:
  5012. mutex_unlock(&sensor->mutex);
  5013. --
  5014. 2.33.0
  5015. From 15e734a203c861eac5794ccd6cfd1ccc31e4d9b9 Mon Sep 17 00:00:00 2001
  5016. From: Daniel Scally <djrscally@gmail.com>
  5017. Date: Wed, 14 Jul 2021 18:05:44 +0100
  5018. Subject: [PATCH] media: i2c: Remove unused macros from ov8865
  5019. There are a number of macros defined in this driver that aren't actually
  5020. used within it. There's a lot of macros defined in total, so removing the
  5021. unused ones helps make it a bit less busy.
  5022. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  5023. Patchset: cameras
  5024. ---
  5025. drivers/media/i2c/ov8865.c | 137 +------------------------------------
  5026. 1 file changed, 1 insertion(+), 136 deletions(-)
  5027. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  5028. index 93e741952050..fd4de2ea1fa9 100644
  5029. --- a/drivers/media/i2c/ov8865.c
  5030. +++ b/drivers/media/i2c/ov8865.c
  5031. @@ -46,8 +46,6 @@
  5032. #define OV8865_PLL_CTRL6_REG 0x306
  5033. #define OV8865_PLL_CTRL6_SYS_DIV(v) (((v) - 1) & BIT(0))
  5034. -#define OV8865_PLL_CTRL8_REG 0x308
  5035. -#define OV8865_PLL_CTRL9_REG 0x309
  5036. #define OV8865_PLL_CTRLA_REG 0x30a
  5037. #define OV8865_PLL_CTRLA_PRE_DIV_HALF(v) (((v) - 1) & BIT(0))
  5038. #define OV8865_PLL_CTRLB_REG 0x30b
  5039. @@ -60,41 +58,21 @@
  5040. #define OV8865_PLL_CTRLE_SYS_DIV(v) ((v) & GENMASK(2, 0))
  5041. #define OV8865_PLL_CTRLF_REG 0x30f
  5042. #define OV8865_PLL_CTRLF_SYS_PRE_DIV(v) (((v) - 1) & GENMASK(3, 0))
  5043. -#define OV8865_PLL_CTRL10_REG 0x310
  5044. -#define OV8865_PLL_CTRL11_REG 0x311
  5045. #define OV8865_PLL_CTRL12_REG 0x312
  5046. #define OV8865_PLL_CTRL12_PRE_DIV_HALF(v) ((((v) - 1) << 4) & BIT(4))
  5047. #define OV8865_PLL_CTRL12_DAC_DIV(v) (((v) - 1) & GENMASK(3, 0))
  5048. -#define OV8865_PLL_CTRL1B_REG 0x31b
  5049. -#define OV8865_PLL_CTRL1C_REG 0x31c
  5050. -
  5051. #define OV8865_PLL_CTRL1E_REG 0x31e
  5052. #define OV8865_PLL_CTRL1E_PLL1_NO_LAT BIT(3)
  5053. -#define OV8865_PAD_OEN0_REG 0x3000
  5054. -
  5055. -#define OV8865_PAD_OEN2_REG 0x3002
  5056. -
  5057. -#define OV8865_CLK_RST5_REG 0x3005
  5058. -
  5059. #define OV8865_CHIP_ID_HH_REG 0x300a
  5060. #define OV8865_CHIP_ID_HH_VALUE 0x00
  5061. #define OV8865_CHIP_ID_H_REG 0x300b
  5062. #define OV8865_CHIP_ID_H_VALUE 0x88
  5063. #define OV8865_CHIP_ID_L_REG 0x300c
  5064. #define OV8865_CHIP_ID_L_VALUE 0x65
  5065. -#define OV8865_PAD_OUT2_REG 0x300d
  5066. -
  5067. -#define OV8865_PAD_SEL2_REG 0x3010
  5068. -#define OV8865_PAD_PK_REG 0x3011
  5069. -#define OV8865_PAD_PK_DRIVE_STRENGTH_1X (0 << 5)
  5070. -#define OV8865_PAD_PK_DRIVE_STRENGTH_2X (1 << 5)
  5071. -#define OV8865_PAD_PK_DRIVE_STRENGTH_3X (2 << 5)
  5072. -#define OV8865_PAD_PK_DRIVE_STRENGTH_4X (3 << 5)
  5073. #define OV8865_PUMP_CLK_DIV_REG 0x3015
  5074. -#define OV8865_PUMP_CLK_DIV_PUMP_N(v) (((v) << 4) & GENMASK(6, 4))
  5075. #define OV8865_PUMP_CLK_DIV_PUMP_P(v) ((v) & GENMASK(2, 0))
  5076. #define OV8865_MIPI_SC_CTRL0_REG 0x3018
  5077. @@ -102,21 +80,12 @@
  5078. GENMASK(7, 5))
  5079. #define OV8865_MIPI_SC_CTRL0_MIPI_EN BIT(4)
  5080. #define OV8865_MIPI_SC_CTRL0_UNKNOWN BIT(1)
  5081. -#define OV8865_MIPI_SC_CTRL0_LANES_PD_MIPI BIT(0)
  5082. -#define OV8865_MIPI_SC_CTRL1_REG 0x3019
  5083. -#define OV8865_CLK_RST0_REG 0x301a
  5084. -#define OV8865_CLK_RST1_REG 0x301b
  5085. -#define OV8865_CLK_RST2_REG 0x301c
  5086. -#define OV8865_CLK_RST3_REG 0x301d
  5087. -#define OV8865_CLK_RST4_REG 0x301e
  5088. #define OV8865_PCLK_SEL_REG 0x3020
  5089. #define OV8865_PCLK_SEL_PCLK_DIV_MASK BIT(3)
  5090. #define OV8865_PCLK_SEL_PCLK_DIV(v) ((((v) - 1) << 3) & BIT(3))
  5091. -#define OV8865_MISC_CTRL_REG 0x3021
  5092. #define OV8865_MIPI_SC_CTRL2_REG 0x3022
  5093. -#define OV8865_MIPI_SC_CTRL2_CLK_LANES_PD_MIPI BIT(1)
  5094. #define OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC BIT(0)
  5095. #define OV8865_MIPI_BIT_SEL_REG 0x3031
  5096. @@ -125,7 +94,6 @@
  5097. #define OV8865_CLK_SEL0_PLL1_SYS_SEL(v) (((v) << 7) & BIT(7))
  5098. #define OV8865_CLK_SEL1_REG 0x3033
  5099. #define OV8865_CLK_SEL1_MIPI_EOF BIT(5)
  5100. -#define OV8865_CLK_SEL1_UNKNOWN BIT(2)
  5101. #define OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK BIT(1)
  5102. #define OV8865_CLK_SEL1_PLL_SCLK_SEL(v) (((v) << 1) & BIT(1))
  5103. @@ -142,7 +110,6 @@
  5104. #define OV8865_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
  5105. #define OV8865_EXPOSURE_CTRL_L_REG 0x3502
  5106. #define OV8865_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
  5107. -#define OV8865_EXPOSURE_GAIN_MANUAL_REG 0x3503
  5108. #define OV8865_GAIN_CTRL_H_REG 0x3508
  5109. #define OV8865_GAIN_CTRL_H(v) (((v) & GENMASK(12, 8)) >> 8)
  5110. @@ -197,18 +164,6 @@
  5111. #define OV8865_INC_X_ODD(v) ((v) & GENMASK(4, 0))
  5112. #define OV8865_INC_X_EVEN_REG 0x3815
  5113. #define OV8865_INC_X_EVEN(v) ((v) & GENMASK(4, 0))
  5114. -#define OV8865_VSYNC_START_H_REG 0x3816
  5115. -#define OV8865_VSYNC_START_H(v) (((v) & GENMASK(15, 8)) >> 8)
  5116. -#define OV8865_VSYNC_START_L_REG 0x3817
  5117. -#define OV8865_VSYNC_START_L(v) ((v) & GENMASK(7, 0))
  5118. -#define OV8865_VSYNC_END_H_REG 0x3818
  5119. -#define OV8865_VSYNC_END_H(v) (((v) & GENMASK(15, 8)) >> 8)
  5120. -#define OV8865_VSYNC_END_L_REG 0x3819
  5121. -#define OV8865_VSYNC_END_L(v) ((v) & GENMASK(7, 0))
  5122. -#define OV8865_HSYNC_FIRST_H_REG 0x381a
  5123. -#define OV8865_HSYNC_FIRST_H(v) (((v) & GENMASK(15, 8)) >> 8)
  5124. -#define OV8865_HSYNC_FIRST_L_REG 0x381b
  5125. -#define OV8865_HSYNC_FIRST_L(v) ((v) & GENMASK(7, 0))
  5126. #define OV8865_FORMAT1_REG 0x3820
  5127. #define OV8865_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  5128. @@ -240,10 +195,6 @@
  5129. #define OV8865_AUTO_SIZE_CTRL_CROP_END_X_REG BIT(2)
  5130. #define OV8865_AUTO_SIZE_CTRL_CROP_START_Y_REG BIT(1)
  5131. #define OV8865_AUTO_SIZE_CTRL_CROP_START_X_REG BIT(0)
  5132. -#define OV8865_AUTO_SIZE_X_OFFSET_H_REG 0x3842
  5133. -#define OV8865_AUTO_SIZE_X_OFFSET_L_REG 0x3843
  5134. -#define OV8865_AUTO_SIZE_Y_OFFSET_H_REG 0x3844
  5135. -#define OV8865_AUTO_SIZE_Y_OFFSET_L_REG 0x3845
  5136. #define OV8865_AUTO_SIZE_BOUNDARIES_REG 0x3846
  5137. #define OV8865_AUTO_SIZE_BOUNDARIES_Y(v) (((v) << 4) & GENMASK(7, 4))
  5138. #define OV8865_AUTO_SIZE_BOUNDARIES_X(v) ((v) & GENMASK(3, 0))
  5139. @@ -259,30 +210,10 @@
  5140. #define OV8865_BLC_CTRL0_TRIG_FORMAT_EN BIT(6)
  5141. #define OV8865_BLC_CTRL0_TRIG_GAIN_EN BIT(5)
  5142. #define OV8865_BLC_CTRL0_TRIG_EXPOSURE_EN BIT(4)
  5143. -#define OV8865_BLC_CTRL0_TRIG_MANUAL_EN BIT(3)
  5144. -#define OV8865_BLC_CTRL0_FREEZE_EN BIT(2)
  5145. -#define OV8865_BLC_CTRL0_ALWAYS_EN BIT(1)
  5146. #define OV8865_BLC_CTRL0_FILTER_EN BIT(0)
  5147. #define OV8865_BLC_CTRL1_REG 0x4001
  5148. -#define OV8865_BLC_CTRL1_DITHER_EN BIT(7)
  5149. -#define OV8865_BLC_CTRL1_ZERO_LINE_DIFF_EN BIT(6)
  5150. -#define OV8865_BLC_CTRL1_COL_SHIFT_256 (0 << 4)
  5151. #define OV8865_BLC_CTRL1_COL_SHIFT_128 (1 << 4)
  5152. -#define OV8865_BLC_CTRL1_COL_SHIFT_64 (2 << 4)
  5153. -#define OV8865_BLC_CTRL1_COL_SHIFT_32 (3 << 4)
  5154. #define OV8865_BLC_CTRL1_OFFSET_LIMIT_EN BIT(2)
  5155. -#define OV8865_BLC_CTRL1_COLUMN_CANCEL_EN BIT(1)
  5156. -#define OV8865_BLC_CTRL2_REG 0x4002
  5157. -#define OV8865_BLC_CTRL3_REG 0x4003
  5158. -#define OV8865_BLC_CTRL4_REG 0x4004
  5159. -#define OV8865_BLC_CTRL5_REG 0x4005
  5160. -#define OV8865_BLC_CTRL6_REG 0x4006
  5161. -#define OV8865_BLC_CTRL7_REG 0x4007
  5162. -#define OV8865_BLC_CTRL8_REG 0x4008
  5163. -#define OV8865_BLC_CTRL9_REG 0x4009
  5164. -#define OV8865_BLC_CTRLA_REG 0x400a
  5165. -#define OV8865_BLC_CTRLB_REG 0x400b
  5166. -#define OV8865_BLC_CTRLC_REG 0x400c
  5167. #define OV8865_BLC_CTRLD_REG 0x400d
  5168. #define OV8865_BLC_CTRLD_OFFSET_TRIGGER(v) ((v) & GENMASK(7, 0))
  5169. @@ -337,66 +268,8 @@
  5170. /* MIPI */
  5171. -#define OV8865_MIPI_CTRL0_REG 0x4800
  5172. -#define OV8865_MIPI_CTRL1_REG 0x4801
  5173. -#define OV8865_MIPI_CTRL2_REG 0x4802
  5174. -#define OV8865_MIPI_CTRL3_REG 0x4803
  5175. -#define OV8865_MIPI_CTRL4_REG 0x4804
  5176. -#define OV8865_MIPI_CTRL5_REG 0x4805
  5177. -#define OV8865_MIPI_CTRL6_REG 0x4806
  5178. -#define OV8865_MIPI_CTRL7_REG 0x4807
  5179. -#define OV8865_MIPI_CTRL8_REG 0x4808
  5180. -
  5181. -#define OV8865_MIPI_FCNT_MAX_H_REG 0x4810
  5182. -#define OV8865_MIPI_FCNT_MAX_L_REG 0x4811
  5183. -
  5184. -#define OV8865_MIPI_CTRL13_REG 0x4813
  5185. -#define OV8865_MIPI_CTRL14_REG 0x4814
  5186. -#define OV8865_MIPI_CTRL15_REG 0x4815
  5187. -#define OV8865_MIPI_EMBEDDED_DT_REG 0x4816
  5188. -
  5189. -#define OV8865_MIPI_HS_ZERO_MIN_H_REG 0x4818
  5190. -#define OV8865_MIPI_HS_ZERO_MIN_L_REG 0x4819
  5191. -#define OV8865_MIPI_HS_TRAIL_MIN_H_REG 0x481a
  5192. -#define OV8865_MIPI_HS_TRAIL_MIN_L_REG 0x481b
  5193. -#define OV8865_MIPI_CLK_ZERO_MIN_H_REG 0x481c
  5194. -#define OV8865_MIPI_CLK_ZERO_MIN_L_REG 0x481d
  5195. -#define OV8865_MIPI_CLK_PREPARE_MAX_REG 0x481e
  5196. -#define OV8865_MIPI_CLK_PREPARE_MIN_REG 0x481f
  5197. -#define OV8865_MIPI_CLK_POST_MIN_H_REG 0x4820
  5198. -#define OV8865_MIPI_CLK_POST_MIN_L_REG 0x4821
  5199. -#define OV8865_MIPI_CLK_TRAIL_MIN_H_REG 0x4822
  5200. -#define OV8865_MIPI_CLK_TRAIL_MIN_L_REG 0x4823
  5201. -#define OV8865_MIPI_LPX_P_MIN_H_REG 0x4824
  5202. -#define OV8865_MIPI_LPX_P_MIN_L_REG 0x4825
  5203. -#define OV8865_MIPI_HS_PREPARE_MIN_REG 0x4826
  5204. -#define OV8865_MIPI_HS_PREPARE_MAX_REG 0x4827
  5205. -#define OV8865_MIPI_HS_EXIT_MIN_H_REG 0x4828
  5206. -#define OV8865_MIPI_HS_EXIT_MIN_L_REG 0x4829
  5207. -#define OV8865_MIPI_UI_HS_ZERO_MIN_REG 0x482a
  5208. -#define OV8865_MIPI_UI_HS_TRAIL_MIN_REG 0x482b
  5209. -#define OV8865_MIPI_UI_CLK_ZERO_MIN_REG 0x482c
  5210. -#define OV8865_MIPI_UI_CLK_PREPARE_REG 0x482d
  5211. -#define OV8865_MIPI_UI_CLK_POST_MIN_REG 0x482e
  5212. -#define OV8865_MIPI_UI_CLK_TRAIL_MIN_REG 0x482f
  5213. -#define OV8865_MIPI_UI_LPX_P_MIN_REG 0x4830
  5214. -#define OV8865_MIPI_UI_HS_PREPARE_REG 0x4831
  5215. -#define OV8865_MIPI_UI_HS_EXIT_MIN_REG 0x4832
  5216. -#define OV8865_MIPI_PKT_START_SIZE_REG 0x4833
  5217. -
  5218. #define OV8865_MIPI_PCLK_PERIOD_REG 0x4837
  5219. -#define OV8865_MIPI_LP_GPIO0_REG 0x4838
  5220. -#define OV8865_MIPI_LP_GPIO1_REG 0x4839
  5221. -
  5222. -#define OV8865_MIPI_CTRL3C_REG 0x483c
  5223. -#define OV8865_MIPI_LP_GPIO4_REG 0x483d
  5224. -
  5225. -#define OV8865_MIPI_CTRL4A_REG 0x484a
  5226. -#define OV8865_MIPI_CTRL4B_REG 0x484b
  5227. -#define OV8865_MIPI_CTRL4C_REG 0x484c
  5228. -#define OV8865_MIPI_LANE_TEST_PATTERN_REG 0x484d
  5229. -#define OV8865_MIPI_FRAME_END_DELAY_REG 0x484e
  5230. -#define OV8865_MIPI_CLOCK_TEST_PATTERN_REG 0x484f
  5231. +
  5232. #define OV8865_MIPI_LANE_SEL01_REG 0x4850
  5233. #define OV8865_MIPI_LANE_SEL01_LANE0(v) (((v) << 0) & GENMASK(2, 0))
  5234. #define OV8865_MIPI_LANE_SEL01_LANE1(v) (((v) << 4) & GENMASK(6, 4))
  5235. @@ -407,7 +280,6 @@
  5236. /* ISP */
  5237. #define OV8865_ISP_CTRL0_REG 0x5000
  5238. -#define OV8865_ISP_CTRL0_LENC_EN BIT(7)
  5239. #define OV8865_ISP_CTRL0_WHITE_BALANCE_EN BIT(4)
  5240. #define OV8865_ISP_CTRL0_DPC_BLACK_EN BIT(2)
  5241. #define OV8865_ISP_CTRL0_DPC_WHITE_EN BIT(1)
  5242. @@ -416,17 +288,11 @@
  5243. #define OV8865_ISP_CTRL2_REG 0x5002
  5244. #define OV8865_ISP_CTRL2_DEBUG BIT(3)
  5245. #define OV8865_ISP_CTRL2_VARIOPIXEL_EN BIT(2)
  5246. -#define OV8865_ISP_CTRL2_VSYNC_LATCH_EN BIT(0)
  5247. -#define OV8865_ISP_CTRL3_REG 0x5003
  5248. #define OV8865_ISP_GAIN_RED_H_REG 0x5018
  5249. #define OV8865_ISP_GAIN_RED_H(v) (((v) & GENMASK(13, 6)) >> 6)
  5250. #define OV8865_ISP_GAIN_RED_L_REG 0x5019
  5251. #define OV8865_ISP_GAIN_RED_L(v) ((v) & GENMASK(5, 0))
  5252. -#define OV8865_ISP_GAIN_GREEN_H_REG 0x501a
  5253. -#define OV8865_ISP_GAIN_GREEN_H(v) (((v) & GENMASK(13, 6)) >> 6)
  5254. -#define OV8865_ISP_GAIN_GREEN_L_REG 0x501b
  5255. -#define OV8865_ISP_GAIN_GREEN_L(v) ((v) & GENMASK(5, 0))
  5256. #define OV8865_ISP_GAIN_BLUE_H_REG 0x501c
  5257. #define OV8865_ISP_GAIN_BLUE_H(v) (((v) & GENMASK(13, 6)) >> 6)
  5258. #define OV8865_ISP_GAIN_BLUE_L_REG 0x501d
  5259. @@ -434,7 +300,6 @@
  5260. /* VarioPixel */
  5261. -#define OV8865_VAP_CTRL0_REG 0x5900
  5262. #define OV8865_VAP_CTRL1_REG 0x5901
  5263. #define OV8865_VAP_CTRL1_HSUB_COEF(v) ((((v) - 1) << 2) & \
  5264. GENMASK(3, 2))
  5265. --
  5266. 2.33.0
  5267. From 0c71885c10af33ed271073d670d03c3ea41fbb65 Mon Sep 17 00:00:00 2001
  5268. From: Daniel Scally <djrscally@gmail.com>
  5269. Date: Fri, 16 Jul 2021 00:00:54 +0100
  5270. Subject: [PATCH] media: i2c: Switch exposure control unit to lines
  5271. The ov8865 driver currently has the unit of the V4L2_CID_EXPOSURE control
  5272. as 1/16th of a line. This is what the sensor expects, but isn't very
  5273. intuitive. Switch the control to be in units of a line and simply do the
  5274. 16x multiplication before passing the value to the sensor.
  5275. The datasheet for this sensor gives minimum exposure as 2 lines, so take
  5276. the opportunity to correct the lower bounds of the control.
  5277. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  5278. Patchset: cameras
  5279. ---
  5280. drivers/media/i2c/ov8865.c | 7 +++++--
  5281. 1 file changed, 5 insertions(+), 2 deletions(-)
  5282. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  5283. index fd4de2ea1fa9..1905028742d5 100644
  5284. --- a/drivers/media/i2c/ov8865.c
  5285. +++ b/drivers/media/i2c/ov8865.c
  5286. @@ -1991,6 +1991,9 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
  5287. {
  5288. int ret;
  5289. + /* The sensor stores exposure in units of 1/16th of a line */
  5290. + exposure *= 16;
  5291. +
  5292. ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
  5293. OV8865_EXPOSURE_CTRL_HH(exposure));
  5294. if (ret)
  5295. @@ -2389,8 +2392,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  5296. /* Exposure */
  5297. - ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
  5298. - 1048575, 16, 512);
  5299. + ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,
  5300. + 65535, 1, 32);
  5301. /* Gain */
  5302. --
  5303. 2.33.0
  5304. From 14f39d347de9bfd1ff52dfef55ef10a364938a96 Mon Sep 17 00:00:00 2001
  5305. From: Daniel Scally <djrscally@gmail.com>
  5306. Date: Fri, 16 Jul 2021 22:56:15 +0100
  5307. Subject: [PATCH] media: i2c: Add controls from fwnode to ov8865
  5308. Add V4L2_CID_ORIENTATION and V4L2_CID_ROTATION controls to the ov8865
  5309. driver by attempting to parse them from firmware.
  5310. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  5311. Patchset: cameras
  5312. ---
  5313. drivers/media/i2c/ov8865.c | 10 ++++++++++
  5314. 1 file changed, 10 insertions(+)
  5315. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  5316. index 1905028742d5..e88825ea76aa 100644
  5317. --- a/drivers/media/i2c/ov8865.c
  5318. +++ b/drivers/media/i2c/ov8865.c
  5319. @@ -2381,6 +2381,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  5320. struct v4l2_ctrl_handler *handler = &ctrls->handler;
  5321. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  5322. const struct ov8865_mode *mode = sensor->state.mode;
  5323. + struct v4l2_fwnode_device_properties props;
  5324. unsigned int vblank_max, vblank_def;
  5325. unsigned int hblank;
  5326. int ret;
  5327. @@ -2443,6 +2444,15 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  5328. v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,
  5329. INT_MAX, 1, 1);
  5330. + /* set properties from fwnode (e.g. rotation, orientation) */
  5331. + ret = v4l2_fwnode_device_parse(sensor->dev, &props);
  5332. + if (ret)
  5333. + goto error_ctrls;
  5334. +
  5335. + ret = v4l2_ctrl_new_fwnode_properties(handler, ops, &props);
  5336. + if (ret)
  5337. + goto error_ctrls;
  5338. +
  5339. if (handler->error) {
  5340. ret = handler->error;
  5341. goto error_ctrls;
  5342. --
  5343. 2.33.0
  5344. From 3bd30feb956376b0ffff78f2e7b2b7e9bd945608 Mon Sep 17 00:00:00 2001
  5345. From: Daniel Scally <djrscally@gmail.com>
  5346. Date: Wed, 14 Jul 2021 00:05:04 +0100
  5347. Subject: [PATCH] media: ipu3-cio2: Add INT347A to cio2-bridge
  5348. ACPI _HID INT347A represents the OV8865 sensor, the driver for which can
  5349. support the platforms that the cio2-bridge serves. Add it to the array
  5350. of supported sensors so the bridge will connect the sensor to the CIO2
  5351. device.
  5352. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  5353. Patchset: cameras
  5354. ---
  5355. drivers/media/pci/intel/ipu3/cio2-bridge.c | 2 ++
  5356. 1 file changed, 2 insertions(+)
  5357. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  5358. index 1052885caa25..856dc7439a59 100644
  5359. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  5360. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  5361. @@ -24,6 +24,8 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
  5362. CIO2_SENSOR_CONFIG("INT33BE", 0),
  5363. /* Omnivision OV2680 */
  5364. CIO2_SENSOR_CONFIG("OVTI2680", 0),
  5365. + /* Omnivision OV8865 */
  5366. + CIO2_SENSOR_CONFIG("INT347A", 1, 360000000),
  5367. };
  5368. static const struct cio2_property_names prop_names = {
  5369. --
  5370. 2.33.0