0010-cameras.patch 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288
  1. From 8fece22ef6bef3222a8a5745f713ba057ad17daf Mon Sep 17 00:00:00 2001
  2. From: Daniel Scally <djrscally@gmail.com>
  3. Date: Mon, 5 Apr 2021 23:56:53 +0100
  4. Subject: [PATCH] media: ipu3-cio2: Toggle sensor streaming in pm runtime ops
  5. The .suspend() and .resume() runtime_pm operations for the ipu3-cio2
  6. driver currently do not handle the sensor's stream. Setting .s_stream() on
  7. or off for the sensor subdev means that sensors will pause and resume the
  8. stream at the appropriate time even if their drivers don't implement those
  9. operations.
  10. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  11. Patchset: cameras
  12. ---
  13. drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 15 ++++++++++++++-
  14. 1 file changed, 14 insertions(+), 1 deletion(-)
  15. diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  16. index 47db0ee0fcbf..7bb86e246ebe 100644
  17. --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  18. +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
  19. @@ -1973,12 +1973,19 @@ static int __maybe_unused cio2_suspend(struct device *dev)
  20. struct pci_dev *pci_dev = to_pci_dev(dev);
  21. struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
  22. struct cio2_queue *q = cio2->cur_queue;
  23. + int r;
  24. dev_dbg(dev, "cio2 suspend\n");
  25. if (!cio2->streaming)
  26. return 0;
  27. /* Stop stream */
  28. + r = v4l2_subdev_call(q->sensor, video, s_stream, 0);
  29. + if (r) {
  30. + dev_err(dev, "failed to stop sensor streaming\n");
  31. + return r;
  32. + }
  33. +
  34. cio2_hw_exit(cio2, q);
  35. synchronize_irq(pci_dev->irq);
  36. @@ -2013,8 +2020,14 @@ static int __maybe_unused cio2_resume(struct device *dev)
  37. }
  38. r = cio2_hw_init(cio2, q);
  39. - if (r)
  40. + if (r) {
  41. dev_err(dev, "fail to init cio2 hw\n");
  42. + return r;
  43. + }
  44. +
  45. + r = v4l2_subdev_call(q->sensor, video, s_stream, 1);
  46. + if (r)
  47. + dev_err(dev, "fail to start sensor streaming\n");
  48. return r;
  49. }
  50. --
  51. 2.33.0
  52. From 1fffb04c66c705299584045543abc2e32b9c2d2f Mon Sep 17 00:00:00 2001
  53. From: Daniel Scally <djrscally@gmail.com>
  54. Date: Mon, 5 Apr 2021 23:56:54 +0100
  55. Subject: [PATCH] media: i2c: Add support for ov5693 sensor
  56. The OV5693 is a 5 Mpx CMOS image sensor, connected via MIPI CSI-2. The
  57. chip is capable of a single lane configuration, but currently only two
  58. lanes are supported.
  59. Most of the sensor's features are supported, with the main exception
  60. being the lens correction algorithm.
  61. The driver provides all mandatory, optional and recommended V4L2 controls
  62. for maximum compatibility with libcamera.
  63. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  64. Patchset: cameras
  65. ---
  66. MAINTAINERS | 7 +
  67. drivers/media/i2c/Kconfig | 11 +
  68. drivers/media/i2c/Makefile | 1 +
  69. drivers/media/i2c/ov5693.c | 1557 ++++++++++++++++++++++++++++++++++++
  70. 4 files changed, 1576 insertions(+)
  71. create mode 100644 drivers/media/i2c/ov5693.c
  72. diff --git a/MAINTAINERS b/MAINTAINERS
  73. index d7b4f32875a9..db66227a14f8 100644
  74. --- a/MAINTAINERS
  75. +++ b/MAINTAINERS
  76. @@ -13751,6 +13751,13 @@ S: Maintained
  77. T: git git://linuxtv.org/media_tree.git
  78. F: drivers/media/i2c/ov5675.c
  79. +OMNIVISION OV5693 SENSOR DRIVER
  80. +M: Daniel Scally <djrscally@gmail.com>
  81. +L: linux-media@vger.kernel.org
  82. +S: Maintained
  83. +T: git git://linuxtv.org/media_tree.git
  84. +F: drivers/media/i2c/ov5693.c
  85. +
  86. OMNIVISION OV5695 SENSOR DRIVER
  87. M: Shunqian Zheng <zhengsq@rock-chips.com>
  88. L: linux-media@vger.kernel.org
  89. diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
  90. index 588f8eb95984..dee06f535f2c 100644
  91. --- a/drivers/media/i2c/Kconfig
  92. +++ b/drivers/media/i2c/Kconfig
  93. @@ -1014,6 +1014,17 @@ config VIDEO_OV5675
  94. To compile this driver as a module, choose M here: the
  95. module will be called ov5675.
  96. +config VIDEO_OV5693
  97. + tristate "OmniVision OV5693 sensor support"
  98. + depends on I2C && VIDEO_V4L2
  99. + select V4L2_FWNODE
  100. + help
  101. + This is a Video4Linux2 sensor driver for the OmniVision
  102. + OV5693 camera.
  103. +
  104. + To compile this driver as a module, choose M here: the
  105. + module will be called ov5693.
  106. +
  107. config VIDEO_OV5695
  108. tristate "OmniVision OV5695 sensor support"
  109. depends on I2C && VIDEO_V4L2
  110. diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
  111. index 1168fa6b84ed..011e90c1a288 100644
  112. --- a/drivers/media/i2c/Makefile
  113. +++ b/drivers/media/i2c/Makefile
  114. @@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
  115. obj-$(CONFIG_VIDEO_OV5648) += ov5648.o
  116. obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
  117. obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
  118. +obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
  119. obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
  120. obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
  121. obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
  122. diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
  123. new file mode 100644
  124. index 000000000000..9499ee10f56c
  125. --- /dev/null
  126. +++ b/drivers/media/i2c/ov5693.c
  127. @@ -0,0 +1,1557 @@
  128. +// SPDX-License-Identifier: GPL-2.0
  129. +/*
  130. + * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
  131. + *
  132. + * Adapted from the atomisp-ov5693 driver, with contributions from:
  133. + *
  134. + * Daniel Scally
  135. + * Jean-Michel Hautbois
  136. + * Fabian Wuthrich
  137. + * Tsuchiya Yuto
  138. + * Jordan Hand
  139. + * Jake Day
  140. + */
  141. +
  142. +#include <asm/unaligned.h>
  143. +#include <linux/acpi.h>
  144. +#include <linux/clk.h>
  145. +#include <linux/delay.h>
  146. +#include <linux/device.h>
  147. +#include <linux/i2c.h>
  148. +#include <linux/module.h>
  149. +#include <linux/pm_runtime.h>
  150. +#include <linux/regulator/consumer.h>
  151. +#include <linux/slab.h>
  152. +#include <linux/types.h>
  153. +#include <media/v4l2-ctrls.h>
  154. +#include <media/v4l2-device.h>
  155. +#include <media/v4l2-fwnode.h>
  156. +
  157. +/* System Control */
  158. +#define OV5693_SW_RESET_REG 0x0103
  159. +#define OV5693_SW_STREAM_REG 0x0100
  160. +#define OV5693_START_STREAMING 0x01
  161. +#define OV5693_STOP_STREAMING 0x00
  162. +#define OV5693_SW_RESET 0x01
  163. +
  164. +#define OV5693_REG_CHIP_ID_H 0x300a
  165. +#define OV5693_REG_CHIP_ID_L 0x300b
  166. +/* Yes, this is right. The datasheet for the OV5693 gives its ID as 0x5690 */
  167. +#define OV5693_CHIP_ID 0x5690
  168. +
  169. +/* Exposure */
  170. +#define OV5693_EXPOSURE_L_CTRL_HH_REG 0x3500
  171. +#define OV5693_EXPOSURE_L_CTRL_H_REG 0x3501
  172. +#define OV5693_EXPOSURE_L_CTRL_L_REG 0x3502
  173. +#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(14, 12)) >> 12)
  174. +#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(11, 4)) >> 4)
  175. +#define OV5693_EXPOSURE_CTRL_L(v) (((v) & GENMASK(3, 0)) << 4)
  176. +#define OV5693_INTEGRATION_TIME_MARGIN 8
  177. +#define OV5693_EXPOSURE_MIN 1
  178. +#define OV5693_EXPOSURE_STEP 1
  179. +
  180. +/* Analogue Gain */
  181. +#define OV5693_GAIN_CTRL_H_REG 0x350a
  182. +#define OV5693_GAIN_CTRL_H(v) (((v) >> 4) & GENMASK(2, 0))
  183. +#define OV5693_GAIN_CTRL_L_REG 0x350b
  184. +#define OV5693_GAIN_CTRL_L(v) (((v) << 4) & GENMASK(7, 4))
  185. +#define OV5693_GAIN_MIN 1
  186. +#define OV5693_GAIN_MAX 127
  187. +#define OV5693_GAIN_DEF 8
  188. +#define OV5693_GAIN_STEP 1
  189. +
  190. +/* Digital Gain */
  191. +#define OV5693_MWB_RED_GAIN_H_REG 0x3400
  192. +#define OV5693_MWB_RED_GAIN_L_REG 0x3401
  193. +#define OV5693_MWB_GREEN_GAIN_H_REG 0x3402
  194. +#define OV5693_MWB_GREEN_GAIN_L_REG 0x3403
  195. +#define OV5693_MWB_BLUE_GAIN_H_REG 0x3404
  196. +#define OV5693_MWB_BLUE_GAIN_L_REG 0x3405
  197. +#define OV5693_MWB_GAIN_H_CTRL(v) (((v) >> 8) & GENMASK(3, 0))
  198. +#define OV5693_MWB_GAIN_L_CTRL(v) ((v) & GENMASK(7, 0))
  199. +#define OV5693_MWB_GAIN_MAX 0x0fff
  200. +#define OV5693_DIGITAL_GAIN_MIN 1
  201. +#define OV5693_DIGITAL_GAIN_MAX 4095
  202. +#define OV5693_DIGITAL_GAIN_DEF 1024
  203. +#define OV5693_DIGITAL_GAIN_STEP 1
  204. +
  205. +/* Timing and Format */
  206. +#define OV5693_CROP_START_X_H_REG 0x3800
  207. +#define OV5693_CROP_START_X_H(v) (((v) & GENMASK(12, 8)) >> 8)
  208. +#define OV5693_CROP_START_X_L_REG 0x3801
  209. +#define OV5693_CROP_START_X_L(v) ((v) & GENMASK(7, 0))
  210. +
  211. +#define OV5693_CROP_START_Y_H_REG 0x3802
  212. +#define OV5693_CROP_START_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
  213. +#define OV5693_CROP_START_Y_L_REG 0x3803
  214. +#define OV5693_CROP_START_Y_L(v) ((v) & GENMASK(7, 0))
  215. +
  216. +#define OV5693_CROP_END_X_H_REG 0x3804
  217. +#define OV5693_CROP_END_X_H(v) (((v) & GENMASK(12, 8)) >> 8)
  218. +#define OV5693_CROP_END_X_L_REG 0x3805
  219. +#define OV5693_CROP_END_X_L(v) ((v) & GENMASK(7, 0))
  220. +
  221. +#define OV5693_CROP_END_Y_H_REG 0x3806
  222. +#define OV5693_CROP_END_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
  223. +#define OV5693_CROP_END_Y_L_REG 0x3807
  224. +#define OV5693_CROP_END_Y_L(v) ((v) & GENMASK(7, 0))
  225. +
  226. +#define OV5693_OUTPUT_SIZE_X_H_REG 0x3808
  227. +#define OV5693_OUTPUT_SIZE_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  228. +#define OV5693_OUTPUT_SIZE_X_L_REG 0x3809
  229. +#define OV5693_OUTPUT_SIZE_X_L(v) ((v) & GENMASK(7, 0))
  230. +
  231. +#define OV5693_OUTPUT_SIZE_Y_H_REG 0x380a
  232. +#define OV5693_OUTPUT_SIZE_Y_H(v) (((v) & GENMASK(15, 8)) >> 8)
  233. +#define OV5693_OUTPUT_SIZE_Y_L_REG 0x380b
  234. +#define OV5693_OUTPUT_SIZE_Y_L(v) ((v) & GENMASK(7, 0))
  235. +
  236. +#define OV5693_TIMING_HTS_H_REG 0x380c
  237. +#define OV5693_TIMING_HTS_H(v) (((v) & GENMASK(15, 8)) >> 8)
  238. +#define OV5693_TIMING_HTS_L_REG 0x380d
  239. +#define OV5693_TIMING_HTS_L(v) ((v) & GENMASK(7, 0))
  240. +#define OV5693_FIXED_PPL 2688U
  241. +
  242. +#define OV5693_TIMING_VTS_H_REG 0x380e
  243. +#define OV5693_TIMING_VTS_H(v) (((v) & GENMASK(15, 8)) >> 8)
  244. +#define OV5693_TIMING_VTS_L_REG 0x380f
  245. +#define OV5693_TIMING_VTS_L(v) ((v) & GENMASK(7, 0))
  246. +#define OV5693_TIMING_MAX_VTS 0xffff
  247. +#define OV5693_TIMING_MIN_VTS 0x04
  248. +
  249. +#define OV5693_OFFSET_START_X_H_REG 0x3810
  250. +#define OV5693_OFFSET_START_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  251. +#define OV5693_OFFSET_START_X_L_REG 0x3811
  252. +#define OV5693_OFFSET_START_X_L(v) ((v) & GENMASK(7, 0))
  253. +
  254. +#define OV5693_OFFSET_START_Y_H_REG 0x3812
  255. +#define OV5693_OFFSET_START_Y_H(v) (((v) & GENMASK(15, 8)) >> 8)
  256. +#define OV5693_OFFSET_START_Y_L_REG 0x3813
  257. +#define OV5693_OFFSET_START_Y_L(v) ((v) & GENMASK(7, 0))
  258. +
  259. +#define OV5693_SUB_INC_X_REG 0x3814
  260. +#define OV5693_SUB_INC_Y_REG 0x3815
  261. +
  262. +#define OV5693_FORMAT1_REG 0x3820
  263. +#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  264. +#define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
  265. +#define OV5693_FORMAT1_VBIN_EN BIT(0)
  266. +#define OV5693_FORMAT2_REG 0x3821
  267. +#define OV5693_FORMAT2_HDR_EN BIT(7)
  268. +#define OV5693_FORMAT2_FLIP_HORZ_ISP_EN BIT(2)
  269. +#define OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN BIT(1)
  270. +#define OV5693_FORMAT2_HBIN_EN BIT(0)
  271. +
  272. +#define OV5693_ISP_CTRL2_REG 0x5002
  273. +#define OV5693_ISP_SCALE_ENABLE BIT(7)
  274. +
  275. +/* Pixel Array */
  276. +#define OV5693_NATIVE_WIDTH 2624
  277. +#define OV5693_NATIVE_HEIGHT 1956
  278. +#define OV5693_NATIVE_START_LEFT 0
  279. +#define OV5693_NATIVE_START_TOP 0
  280. +#define OV5693_ACTIVE_WIDTH 2592
  281. +#define OV5693_ACTIVE_HEIGHT 1944
  282. +#define OV5693_ACTIVE_START_LEFT 16
  283. +#define OV5693_ACTIVE_START_TOP 6
  284. +#define OV5693_MIN_CROP_WIDTH 2
  285. +#define OV5693_MIN_CROP_HEIGHT 2
  286. +
  287. +/* Test Pattern */
  288. +#define OV5693_TEST_PATTERN_REG 0x5e00
  289. +#define OV5693_TEST_PATTERN_ENABLE BIT(7)
  290. +#define OV5693_TEST_PATTERN_ROLLING BIT(6)
  291. +#define OV5693_TEST_PATTERN_RANDOM 0x01
  292. +#define OV5693_TEST_PATTERN_BARS 0x00
  293. +
  294. +/* System Frequencies */
  295. +#define OV5693_XVCLK_FREQ 19200000
  296. +#define OV5693_LINK_FREQ_400MHZ 400000000
  297. +#define OV5693_PIXEL_RATE 160000000
  298. +
  299. +/* Miscellaneous */
  300. +#define OV5693_NUM_SUPPLIES 2
  301. +
  302. +#define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd)
  303. +
  304. +struct ov5693_reg {
  305. + u16 reg;
  306. + u8 val;
  307. +};
  308. +
  309. +struct ov5693_reg_list {
  310. + u32 num_regs;
  311. + const struct ov5693_reg *regs;
  312. +};
  313. +
  314. +struct ov5693_device {
  315. + struct i2c_client *client;
  316. + struct device *dev;
  317. +
  318. + /* Protect against concurrent changes to controls */
  319. + struct mutex lock;
  320. +
  321. + struct gpio_desc *reset;
  322. + struct gpio_desc *powerdown;
  323. + struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
  324. + struct clk *clk;
  325. +
  326. + struct ov5693_mode {
  327. + struct v4l2_rect crop;
  328. + struct v4l2_mbus_framefmt format;
  329. + bool binning_x;
  330. + bool binning_y;
  331. + unsigned int inc_x_odd;
  332. + unsigned int inc_y_odd;
  333. + unsigned int vts;
  334. + } mode;
  335. + bool streaming;
  336. +
  337. + struct v4l2_subdev sd;
  338. + struct media_pad pad;
  339. +
  340. + struct ov5693_v4l2_ctrls {
  341. + struct v4l2_ctrl_handler handler;
  342. + struct v4l2_ctrl *link_freq;
  343. + struct v4l2_ctrl *pixel_rate;
  344. + struct v4l2_ctrl *exposure;
  345. + struct v4l2_ctrl *analogue_gain;
  346. + struct v4l2_ctrl *digital_gain;
  347. + struct v4l2_ctrl *hflip;
  348. + struct v4l2_ctrl *vflip;
  349. + struct v4l2_ctrl *hblank;
  350. + struct v4l2_ctrl *vblank;
  351. + struct v4l2_ctrl *test_pattern;
  352. + } ctrls;
  353. +};
  354. +
  355. +static const struct ov5693_reg ov5693_global_regs[] = {
  356. + {0x3016, 0xf0},
  357. + {0x3017, 0xf0},
  358. + {0x3018, 0xf0},
  359. + {0x3022, 0x01},
  360. + {0x3028, 0x44},
  361. + {0x3098, 0x02},
  362. + {0x3099, 0x19},
  363. + {0x309a, 0x02},
  364. + {0x309b, 0x01},
  365. + {0x309c, 0x00},
  366. + {0x30a0, 0xd2},
  367. + {0x30a2, 0x01},
  368. + {0x30b2, 0x00},
  369. + {0x30b3, 0x7d},
  370. + {0x30b4, 0x03},
  371. + {0x30b5, 0x04},
  372. + {0x30b6, 0x01},
  373. + {0x3104, 0x21},
  374. + {0x3106, 0x00},
  375. + {0x3406, 0x01},
  376. + {0x3503, 0x07},
  377. + {0x350b, 0x40},
  378. + {0x3601, 0x0a},
  379. + {0x3602, 0x38},
  380. + {0x3612, 0x80},
  381. + {0x3620, 0x54},
  382. + {0x3621, 0xc7},
  383. + {0x3622, 0x0f},
  384. + {0x3625, 0x10},
  385. + {0x3630, 0x55},
  386. + {0x3631, 0xf4},
  387. + {0x3632, 0x00},
  388. + {0x3633, 0x34},
  389. + {0x3634, 0x02},
  390. + {0x364d, 0x0d},
  391. + {0x364f, 0xdd},
  392. + {0x3660, 0x04},
  393. + {0x3662, 0x10},
  394. + {0x3663, 0xf1},
  395. + {0x3665, 0x00},
  396. + {0x3666, 0x20},
  397. + {0x3667, 0x00},
  398. + {0x366a, 0x80},
  399. + {0x3680, 0xe0},
  400. + {0x3681, 0x00},
  401. + {0x3700, 0x42},
  402. + {0x3701, 0x14},
  403. + {0x3702, 0xa0},
  404. + {0x3703, 0xd8},
  405. + {0x3704, 0x78},
  406. + {0x3705, 0x02},
  407. + {0x370a, 0x00},
  408. + {0x370b, 0x20},
  409. + {0x370c, 0x0c},
  410. + {0x370d, 0x11},
  411. + {0x370e, 0x00},
  412. + {0x370f, 0x40},
  413. + {0x3710, 0x00},
  414. + {0x371a, 0x1c},
  415. + {0x371b, 0x05},
  416. + {0x371c, 0x01},
  417. + {0x371e, 0xa1},
  418. + {0x371f, 0x0c},
  419. + {0x3721, 0x00},
  420. + {0x3724, 0x10},
  421. + {0x3726, 0x00},
  422. + {0x372a, 0x01},
  423. + {0x3730, 0x10},
  424. + {0x3738, 0x22},
  425. + {0x3739, 0xe5},
  426. + {0x373a, 0x50},
  427. + {0x373b, 0x02},
  428. + {0x373c, 0x41},
  429. + {0x373f, 0x02},
  430. + {0x3740, 0x42},
  431. + {0x3741, 0x02},
  432. + {0x3742, 0x18},
  433. + {0x3743, 0x01},
  434. + {0x3744, 0x02},
  435. + {0x3747, 0x10},
  436. + {0x374c, 0x04},
  437. + {0x3751, 0xf0},
  438. + {0x3752, 0x00},
  439. + {0x3753, 0x00},
  440. + {0x3754, 0xc0},
  441. + {0x3755, 0x00},
  442. + {0x3756, 0x1a},
  443. + {0x3758, 0x00},
  444. + {0x3759, 0x0f},
  445. + {0x376b, 0x44},
  446. + {0x375c, 0x04},
  447. + {0x3774, 0x10},
  448. + {0x3776, 0x00},
  449. + {0x377f, 0x08},
  450. + {0x3780, 0x22},
  451. + {0x3781, 0x0c},
  452. + {0x3784, 0x2c},
  453. + {0x3785, 0x1e},
  454. + {0x378f, 0xf5},
  455. + {0x3791, 0xb0},
  456. + {0x3795, 0x00},
  457. + {0x3796, 0x64},
  458. + {0x3797, 0x11},
  459. + {0x3798, 0x30},
  460. + {0x3799, 0x41},
  461. + {0x379a, 0x07},
  462. + {0x379b, 0xb0},
  463. + {0x379c, 0x0c},
  464. + {0x3a04, 0x06},
  465. + {0x3a05, 0x14},
  466. + {0x3e07, 0x20},
  467. + {0x4000, 0x08},
  468. + {0x4001, 0x04},
  469. + {0x4004, 0x08},
  470. + {0x4006, 0x20},
  471. + {0x4008, 0x24},
  472. + {0x4009, 0x10},
  473. + {0x4058, 0x00},
  474. + {0x4101, 0xb2},
  475. + {0x4307, 0x31},
  476. + {0x4511, 0x05},
  477. + {0x4512, 0x01},
  478. + {0x481f, 0x30},
  479. + {0x4826, 0x2c},
  480. + {0x4d02, 0xfd},
  481. + {0x4d03, 0xf5},
  482. + {0x4d04, 0x0c},
  483. + {0x4d05, 0xcc},
  484. + {0x4837, 0x0a},
  485. + {0x5003, 0x20},
  486. + {0x5013, 0x00},
  487. + {0x5842, 0x01},
  488. + {0x5843, 0x2b},
  489. + {0x5844, 0x01},
  490. + {0x5845, 0x92},
  491. + {0x5846, 0x01},
  492. + {0x5847, 0x8f},
  493. + {0x5848, 0x01},
  494. + {0x5849, 0x0c},
  495. + {0x5e10, 0x0c},
  496. + {0x3820, 0x00},
  497. + {0x3821, 0x1e},
  498. + {0x5041, 0x14}
  499. +};
  500. +
  501. +static const struct ov5693_reg_list ov5693_global_setting = {
  502. + .num_regs = ARRAY_SIZE(ov5693_global_regs),
  503. + .regs = ov5693_global_regs,
  504. +};
  505. +
  506. +static const struct v4l2_rect ov5693_default_crop = {
  507. + .left = OV5693_ACTIVE_START_LEFT,
  508. + .top = OV5693_ACTIVE_START_TOP,
  509. + .width = OV5693_ACTIVE_WIDTH,
  510. + .height = OV5693_ACTIVE_HEIGHT,
  511. +};
  512. +
  513. +static const struct v4l2_mbus_framefmt ov5693_default_fmt = {
  514. + .width = OV5693_ACTIVE_WIDTH,
  515. + .height = OV5693_ACTIVE_HEIGHT,
  516. + .code = MEDIA_BUS_FMT_SBGGR10_1X10,
  517. +};
  518. +
  519. +static const s64 link_freq_menu_items[] = {
  520. + OV5693_LINK_FREQ_400MHZ
  521. +};
  522. +
  523. +static const char * const ov5693_supply_names[] = {
  524. + "avdd",
  525. + "dovdd",
  526. +};
  527. +
  528. +static const char * const ov5693_test_pattern_menu[] = {
  529. + "Disabled",
  530. + "Random Data",
  531. + "Colour Bars",
  532. + "Colour Bars with Rolling Bar"
  533. +};
  534. +
  535. +static const u8 ov5693_test_pattern_bits[] = {
  536. + 0,
  537. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_RANDOM,
  538. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS,
  539. + OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS |
  540. + OV5693_TEST_PATTERN_ROLLING,
  541. +};
  542. +
  543. +/* I2C I/O Operations */
  544. +
  545. +static int ov5693_read_reg(struct ov5693_device *ov5693, u16 addr, u8 *value)
  546. +{
  547. + struct i2c_client *client = ov5693->client;
  548. + struct i2c_msg msgs[2];
  549. + u8 addr_buf[2];
  550. + u8 data_buf;
  551. + int ret;
  552. +
  553. + put_unaligned_be16(addr, addr_buf);
  554. +
  555. + /* Write register address */
  556. + msgs[0].addr = client->addr;
  557. + msgs[0].flags = 0;
  558. + msgs[0].len = ARRAY_SIZE(addr_buf);
  559. + msgs[0].buf = addr_buf;
  560. +
  561. + /* Read register value */
  562. + msgs[1].addr = client->addr;
  563. + msgs[1].flags = I2C_M_RD;
  564. + msgs[1].len = 1;
  565. + msgs[1].buf = &data_buf;
  566. +
  567. + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  568. + if (ret != ARRAY_SIZE(msgs))
  569. + return -EIO;
  570. +
  571. + *value = data_buf;
  572. +
  573. + return 0;
  574. +}
  575. +
  576. +static void ov5693_write_reg(struct ov5693_device *ov5693, u16 addr, u8 value,
  577. + int *error)
  578. +{
  579. + unsigned char data[3] = { addr >> 8, addr & 0xff, value };
  580. + int ret;
  581. +
  582. + if (*error < 0)
  583. + return;
  584. +
  585. + ret = i2c_master_send(ov5693->client, data, sizeof(data));
  586. + if (ret < 0) {
  587. + dev_dbg(ov5693->dev, "i2c send error at address 0x%04x: %d\n",
  588. + addr, ret);
  589. + *error = ret;
  590. + }
  591. +}
  592. +
  593. +static int ov5693_write_reg_array(struct ov5693_device *ov5693,
  594. + const struct ov5693_reg_list *reglist)
  595. +{
  596. + unsigned int i;
  597. + int ret = 0;
  598. +
  599. + for (i = 0; i < reglist->num_regs; i++)
  600. + ov5693_write_reg(ov5693, reglist->regs[i].reg,
  601. + reglist->regs[i].val, &ret);
  602. +
  603. + return ret;
  604. +}
  605. +
  606. +static int ov5693_update_bits(struct ov5693_device *ov5693, u16 address,
  607. + u16 mask, u16 bits)
  608. +{
  609. + u8 value = 0;
  610. + int ret;
  611. +
  612. + ret = ov5693_read_reg(ov5693, address, &value);
  613. + if (ret)
  614. + return ret;
  615. +
  616. + value &= ~mask;
  617. + value |= bits;
  618. +
  619. + ov5693_write_reg(ov5693, address, value, &ret);
  620. +
  621. + return ret;
  622. +}
  623. +
  624. +/* V4L2 Controls Functions */
  625. +
  626. +static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, bool enable)
  627. +{
  628. + u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
  629. + OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
  630. + int ret;
  631. +
  632. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG, bits,
  633. + enable ? bits : 0);
  634. + if (ret)
  635. + return ret;
  636. +
  637. + return 0;
  638. +}
  639. +
  640. +static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, bool enable)
  641. +{
  642. + u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
  643. + OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
  644. + int ret;
  645. +
  646. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG, bits,
  647. + enable ? bits : 0);
  648. + if (ret)
  649. + return ret;
  650. +
  651. + return 0;
  652. +}
  653. +
  654. +static int ov5693_get_exposure(struct ov5693_device *ov5693, s32 *value)
  655. +{
  656. + u8 exposure_hh = 0, exposure_h = 0, exposure_l = 0;
  657. + int ret;
  658. +
  659. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_HH_REG, &exposure_hh);
  660. + if (ret)
  661. + return ret;
  662. +
  663. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_H_REG, &exposure_h);
  664. + if (ret)
  665. + return ret;
  666. +
  667. + ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_L_CTRL_L_REG, &exposure_l);
  668. + if (ret)
  669. + return ret;
  670. +
  671. + /* The lowest 4 bits are unsupported fractional bits */
  672. + *value = ((exposure_hh << 16) | (exposure_h << 8) | exposure_l) >> 4;
  673. +
  674. + return 0;
  675. +}
  676. +
  677. +static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
  678. +{
  679. + int ret = 0;
  680. +
  681. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_HH_REG,
  682. + OV5693_EXPOSURE_CTRL_HH(exposure), &ret);
  683. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_H_REG,
  684. + OV5693_EXPOSURE_CTRL_H(exposure), &ret);
  685. + ov5693_write_reg(ov5693, OV5693_EXPOSURE_L_CTRL_L_REG,
  686. + OV5693_EXPOSURE_CTRL_L(exposure), &ret);
  687. +
  688. + return ret;
  689. +}
  690. +
  691. +static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain)
  692. +{
  693. + u8 gain_l = 0, gain_h = 0;
  694. + int ret;
  695. +
  696. + ret = ov5693_read_reg(ov5693, OV5693_GAIN_CTRL_H_REG, &gain_h);
  697. + if (ret)
  698. + return ret;
  699. +
  700. + ret = ov5693_read_reg(ov5693, OV5693_GAIN_CTRL_L_REG, &gain_l);
  701. + if (ret)
  702. + return ret;
  703. +
  704. + /* As with exposure, the lowest 4 bits are fractional bits. */
  705. + *gain = ((gain_h << 8) | gain_l) >> 4;
  706. +
  707. + return ret;
  708. +}
  709. +
  710. +static int ov5693_digital_gain_configure(struct ov5693_device *ov5693, u32 gain)
  711. +{
  712. + int ret = 0;
  713. +
  714. + ov5693_write_reg(ov5693, OV5693_MWB_RED_GAIN_H_REG,
  715. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  716. + ov5693_write_reg(ov5693, OV5693_MWB_RED_GAIN_L_REG,
  717. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  718. + ov5693_write_reg(ov5693, OV5693_MWB_GREEN_GAIN_H_REG,
  719. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  720. + ov5693_write_reg(ov5693, OV5693_MWB_GREEN_GAIN_L_REG,
  721. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  722. + ov5693_write_reg(ov5693, OV5693_MWB_BLUE_GAIN_H_REG,
  723. + OV5693_MWB_GAIN_H_CTRL(gain), &ret);
  724. + ov5693_write_reg(ov5693, OV5693_MWB_BLUE_GAIN_L_REG,
  725. + OV5693_MWB_GAIN_L_CTRL(gain), &ret);
  726. +
  727. + return ret;
  728. +}
  729. +
  730. +static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain)
  731. +{
  732. + int ret = 0;
  733. +
  734. + ov5693_write_reg(ov5693, OV5693_GAIN_CTRL_L_REG,
  735. + OV5693_GAIN_CTRL_L(gain), &ret);
  736. + ov5693_write_reg(ov5693, OV5693_GAIN_CTRL_H_REG,
  737. + OV5693_GAIN_CTRL_H(gain), &ret);
  738. +
  739. + return ret;
  740. +}
  741. +
  742. +static int ov5693_vts_configure(struct ov5693_device *ov5693, u32 vblank)
  743. +{
  744. + u16 vts = ov5693->mode.format.height + vblank;
  745. + int ret = 0;
  746. +
  747. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_H_REG,
  748. + OV5693_TIMING_VTS_H(vts), &ret);
  749. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_L_REG,
  750. + OV5693_TIMING_VTS_L(vts), &ret);
  751. +
  752. + return ret;
  753. +}
  754. +
  755. +static int ov5693_test_pattern_configure(struct ov5693_device *ov5693, u32 idx)
  756. +{
  757. + int ret = 0;
  758. +
  759. + ov5693_write_reg(ov5693, OV5693_TEST_PATTERN_REG,
  760. + ov5693_test_pattern_bits[idx], &ret);
  761. +
  762. + return ret;
  763. +}
  764. +
  765. +static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
  766. +{
  767. + struct ov5693_device *ov5693 =
  768. + container_of(ctrl->handler, struct ov5693_device, ctrls.handler);
  769. + int ret = 0;
  770. +
  771. + /* If VBLANK is altered we need to update exposure to compensate */
  772. + if (ctrl->id == V4L2_CID_VBLANK) {
  773. + int exposure_max;
  774. +
  775. + exposure_max = ov5693->mode.format.height + ctrl->val -
  776. + OV5693_INTEGRATION_TIME_MARGIN;
  777. + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
  778. + ov5693->ctrls.exposure->minimum,
  779. + exposure_max,
  780. + ov5693->ctrls.exposure->step,
  781. + min(ov5693->ctrls.exposure->val, exposure_max));
  782. + }
  783. +
  784. + /* Only apply changes to the controls if the device is powered up */
  785. + if (!pm_runtime_get_if_in_use(ov5693->dev))
  786. + return 0;
  787. +
  788. + switch (ctrl->id) {
  789. + case V4L2_CID_EXPOSURE:
  790. + ret = ov5693_exposure_configure(ov5693, ctrl->val);
  791. + break;
  792. + case V4L2_CID_ANALOGUE_GAIN:
  793. + ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
  794. + break;
  795. + case V4L2_CID_DIGITAL_GAIN:
  796. + ret = ov5693_digital_gain_configure(ov5693, ctrl->val);
  797. + break;
  798. + case V4L2_CID_HFLIP:
  799. + ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val);
  800. + break;
  801. + case V4L2_CID_VFLIP:
  802. + ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val);
  803. + break;
  804. + case V4L2_CID_VBLANK:
  805. + ret = ov5693_vts_configure(ov5693, ctrl->val);
  806. + break;
  807. + case V4L2_CID_TEST_PATTERN:
  808. + ret = ov5693_test_pattern_configure(ov5693, ctrl->val);
  809. + break;
  810. + default:
  811. + ret = -EINVAL;
  812. + }
  813. +
  814. + pm_runtime_put(ov5693->dev);
  815. +
  816. + return ret;
  817. +}
  818. +
  819. +static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
  820. +{
  821. + struct ov5693_device *ov5693 =
  822. + container_of(ctrl->handler, struct ov5693_device, ctrls.handler);
  823. +
  824. + switch (ctrl->id) {
  825. + case V4L2_CID_EXPOSURE_ABSOLUTE:
  826. + return ov5693_get_exposure(ov5693, &ctrl->val);
  827. + case V4L2_CID_AUTOGAIN:
  828. + return ov5693_get_gain(ov5693, &ctrl->val);
  829. + default:
  830. + return -EINVAL;
  831. + }
  832. +}
  833. +
  834. +static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
  835. + .s_ctrl = ov5693_s_ctrl,
  836. + .g_volatile_ctrl = ov5693_g_volatile_ctrl
  837. +};
  838. +
  839. +/* System Control Functions */
  840. +
  841. +static int ov5693_mode_configure(struct ov5693_device *ov5693)
  842. +{
  843. + const struct ov5693_mode *mode = &ov5693->mode;
  844. + int ret = 0;
  845. +
  846. + /* Crop Start X */
  847. + ov5693_write_reg(ov5693, OV5693_CROP_START_X_H_REG,
  848. + OV5693_CROP_START_X_H(mode->crop.left), &ret);
  849. + ov5693_write_reg(ov5693, OV5693_CROP_START_X_L_REG,
  850. + OV5693_CROP_START_X_L(mode->crop.left), &ret);
  851. +
  852. + /* Offset X */
  853. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_X_H_REG,
  854. + OV5693_OFFSET_START_X_H(0), &ret);
  855. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_X_L_REG,
  856. + OV5693_OFFSET_START_X_L(0), &ret);
  857. +
  858. + /* Output Size X */
  859. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_X_H_REG,
  860. + OV5693_OUTPUT_SIZE_X_H(mode->format.width), &ret);
  861. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_X_L_REG,
  862. + OV5693_OUTPUT_SIZE_X_L(mode->format.width), &ret);
  863. +
  864. + /* Crop End X */
  865. + ov5693_write_reg(ov5693, OV5693_CROP_END_X_H_REG,
  866. + OV5693_CROP_END_X_H(mode->crop.left + mode->crop.width),
  867. + &ret);
  868. + ov5693_write_reg(ov5693, OV5693_CROP_END_X_L_REG,
  869. + OV5693_CROP_END_X_L(mode->crop.left + mode->crop.width),
  870. + &ret);
  871. +
  872. + /* Horizontal Total Size */
  873. + ov5693_write_reg(ov5693, OV5693_TIMING_HTS_H_REG,
  874. + OV5693_TIMING_HTS_H(OV5693_FIXED_PPL), &ret);
  875. + ov5693_write_reg(ov5693, OV5693_TIMING_HTS_L_REG,
  876. + OV5693_TIMING_HTS_L(OV5693_FIXED_PPL), &ret);
  877. +
  878. + /* Crop Start Y */
  879. + ov5693_write_reg(ov5693, OV5693_CROP_START_Y_H_REG,
  880. + OV5693_CROP_START_Y_H(mode->crop.top), &ret);
  881. + ov5693_write_reg(ov5693, OV5693_CROP_START_Y_L_REG,
  882. + OV5693_CROP_START_Y_L(mode->crop.top), &ret);
  883. +
  884. + /* Offset Y */
  885. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_Y_H_REG,
  886. + OV5693_OFFSET_START_Y_H(0), &ret);
  887. + ov5693_write_reg(ov5693, OV5693_OFFSET_START_Y_L_REG,
  888. + OV5693_OFFSET_START_Y_L(0), &ret);
  889. +
  890. + /* Output Size Y */
  891. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_Y_H_REG,
  892. + OV5693_OUTPUT_SIZE_Y_H(mode->format.height), &ret);
  893. + ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_Y_L_REG,
  894. + OV5693_OUTPUT_SIZE_Y_L(mode->format.height), &ret);
  895. +
  896. + /* Crop End Y */
  897. + ov5693_write_reg(ov5693, OV5693_CROP_END_Y_H_REG,
  898. + OV5693_CROP_END_Y_H(mode->crop.top + mode->crop.height),
  899. + &ret);
  900. + ov5693_write_reg(ov5693, OV5693_CROP_END_Y_L_REG,
  901. + OV5693_CROP_END_Y_L(mode->crop.top + mode->crop.height),
  902. + &ret);
  903. +
  904. + /* Vertical Total Size */
  905. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_H_REG,
  906. + OV5693_TIMING_VTS_H(mode->vts), &ret);
  907. + ov5693_write_reg(ov5693, OV5693_TIMING_VTS_L_REG,
  908. + OV5693_TIMING_VTS_L(mode->vts), &ret);
  909. +
  910. + /* Subsample X increase */
  911. + ov5693_write_reg(ov5693, OV5693_SUB_INC_X_REG,
  912. + ((mode->inc_x_odd << 4) & 0xf0) | 0x01, &ret);
  913. + /* Subsample Y increase */
  914. + ov5693_write_reg(ov5693, OV5693_SUB_INC_Y_REG,
  915. + ((mode->inc_y_odd << 4) & 0xf0) | 0x01, &ret);
  916. +
  917. + /* Binning */
  918. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG,
  919. + OV5693_FORMAT1_VBIN_EN,
  920. + mode->binning_y ? OV5693_FORMAT1_VBIN_EN : 0);
  921. + if (ret)
  922. + return ret;
  923. +
  924. + ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG,
  925. + OV5693_FORMAT2_HBIN_EN,
  926. + mode->binning_x ? OV5693_FORMAT2_HBIN_EN : 0);
  927. +
  928. + return ret;
  929. +}
  930. +
  931. +static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
  932. +{
  933. + int ret = 0;
  934. +
  935. + ov5693_write_reg(ov5693, OV5693_SW_STREAM_REG,
  936. + standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING,
  937. + &ret);
  938. +
  939. + return ret;
  940. +}
  941. +
  942. +static int ov5693_sw_reset(struct ov5693_device *ov5693)
  943. +{
  944. + int ret = 0;
  945. +
  946. + ov5693_write_reg(ov5693, OV5693_SW_RESET_REG, OV5693_SW_RESET, &ret);
  947. +
  948. + return ret;
  949. +}
  950. +
  951. +static int ov5693_sensor_init(struct ov5693_device *ov5693)
  952. +{
  953. + int ret = 0;
  954. +
  955. + ret = ov5693_sw_reset(ov5693);
  956. + if (ret) {
  957. + dev_err(ov5693->dev, "%s software reset error\n", __func__);
  958. + return ret;
  959. + }
  960. +
  961. + ret = ov5693_write_reg_array(ov5693, &ov5693_global_setting);
  962. + if (ret) {
  963. + dev_err(ov5693->dev, "%s global settings error\n", __func__);
  964. + return ret;
  965. + }
  966. +
  967. + ret = ov5693_mode_configure(ov5693);
  968. + if (ret) {
  969. + dev_err(ov5693->dev, "%s mode configure error\n", __func__);
  970. + return ret;
  971. + }
  972. +
  973. + ret = ov5693_sw_standby(ov5693, true);
  974. + if (ret)
  975. + dev_err(ov5693->dev, "%s software standby error\n", __func__);
  976. +
  977. + return ret;
  978. +}
  979. +
  980. +static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
  981. +{
  982. + gpiod_set_value_cansleep(ov5693->reset, 1);
  983. + gpiod_set_value_cansleep(ov5693->powerdown, 1);
  984. +
  985. + regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
  986. +
  987. + clk_disable_unprepare(ov5693->clk);
  988. +}
  989. +
  990. +static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
  991. +{
  992. + int ret;
  993. +
  994. + gpiod_set_value_cansleep(ov5693->reset, 1);
  995. + gpiod_set_value_cansleep(ov5693->powerdown, 1);
  996. +
  997. + ret = clk_prepare_enable(ov5693->clk);
  998. + if (ret) {
  999. + dev_err(ov5693->dev, "Failed to enable clk\n");
  1000. + goto fail_power;
  1001. + }
  1002. +
  1003. + ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies);
  1004. + if (ret) {
  1005. + dev_err(ov5693->dev, "Failed to enable regulators\n");
  1006. + goto fail_power;
  1007. + }
  1008. +
  1009. + gpiod_set_value_cansleep(ov5693->powerdown, 0);
  1010. + gpiod_set_value_cansleep(ov5693->reset, 0);
  1011. +
  1012. + usleep_range(5000, 7500);
  1013. +
  1014. + return 0;
  1015. +
  1016. +fail_power:
  1017. + ov5693_sensor_powerdown(ov5693);
  1018. + return ret;
  1019. +}
  1020. +
  1021. +static int __maybe_unused ov5693_sensor_suspend(struct device *dev)
  1022. +{
  1023. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  1024. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1025. +
  1026. + ov5693_sensor_powerdown(ov5693);
  1027. +
  1028. + return 0;
  1029. +}
  1030. +
  1031. +static int __maybe_unused ov5693_sensor_resume(struct device *dev)
  1032. +{
  1033. + struct v4l2_subdev *sd = dev_get_drvdata(dev);
  1034. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1035. + int ret;
  1036. +
  1037. + mutex_lock(&ov5693->lock);
  1038. +
  1039. + ret = ov5693_sensor_powerup(ov5693);
  1040. + if (ret)
  1041. + goto out_unlock;
  1042. +
  1043. + ret = ov5693_sensor_init(ov5693);
  1044. + if (ret) {
  1045. + dev_err(dev, "ov5693 sensor init failure\n");
  1046. + goto err_power;
  1047. + }
  1048. +
  1049. + goto out_unlock;
  1050. +
  1051. +err_power:
  1052. + ov5693_sensor_powerdown(ov5693);
  1053. +out_unlock:
  1054. + mutex_unlock(&ov5693->lock);
  1055. + return ret;
  1056. +}
  1057. +
  1058. +static int ov5693_detect(struct ov5693_device *ov5693)
  1059. +{
  1060. + u8 id_l = 0, id_h = 0;
  1061. + u16 id = 0;
  1062. + int ret;
  1063. +
  1064. + ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID_H, &id_h);
  1065. + if (ret)
  1066. + return ret;
  1067. +
  1068. + ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID_L, &id_l);
  1069. + if (ret)
  1070. + return ret;
  1071. +
  1072. + id = (id_h << 8) | id_l;
  1073. +
  1074. + if (id != OV5693_CHIP_ID) {
  1075. + dev_err(ov5693->dev, "sensor ID mismatch. Found 0x%04x\n", id);
  1076. + return -ENODEV;
  1077. + }
  1078. +
  1079. + return 0;
  1080. +}
  1081. +
  1082. +/* V4L2 Framework callbacks */
  1083. +
  1084. +static unsigned int __ov5693_calc_vts(u32 height)
  1085. +{
  1086. + /*
  1087. + * We need to set a sensible default VTS for whatever format height we
  1088. + * happen to be given from set_fmt(). This function just targets
  1089. + * an even multiple of 30fps.
  1090. + */
  1091. +
  1092. + unsigned int tgt_fps;
  1093. +
  1094. + tgt_fps = rounddown(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / height, 30);
  1095. +
  1096. + return ALIGN_DOWN(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / tgt_fps, 2);
  1097. +}
  1098. +
  1099. +static struct v4l2_mbus_framefmt *
  1100. +__ov5693_get_pad_format(struct ov5693_device *ov5693,
  1101. + struct v4l2_subdev_state *state,
  1102. + unsigned int pad, enum v4l2_subdev_format_whence which)
  1103. +{
  1104. + switch (which) {
  1105. + case V4L2_SUBDEV_FORMAT_TRY:
  1106. + return v4l2_subdev_get_try_format(&ov5693->sd, state, pad);
  1107. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  1108. + return &ov5693->mode.format;
  1109. + default:
  1110. + return NULL;
  1111. + }
  1112. +}
  1113. +
  1114. +static struct v4l2_rect *
  1115. +__ov5693_get_pad_crop(struct ov5693_device *ov5693,
  1116. + struct v4l2_subdev_state *state,
  1117. + unsigned int pad, enum v4l2_subdev_format_whence which)
  1118. +{
  1119. + switch (which) {
  1120. + case V4L2_SUBDEV_FORMAT_TRY:
  1121. + return v4l2_subdev_get_try_crop(&ov5693->sd, state, pad);
  1122. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  1123. + return &ov5693->mode.crop;
  1124. + }
  1125. +
  1126. + return NULL;
  1127. +}
  1128. +
  1129. +static int ov5693_get_fmt(struct v4l2_subdev *sd,
  1130. + struct v4l2_subdev_state *state,
  1131. + struct v4l2_subdev_format *format)
  1132. +{
  1133. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1134. +
  1135. + format->format = ov5693->mode.format;
  1136. +
  1137. + return 0;
  1138. +}
  1139. +
  1140. +static int ov5693_set_fmt(struct v4l2_subdev *sd,
  1141. + struct v4l2_subdev_state *state,
  1142. + struct v4l2_subdev_format *format)
  1143. +{
  1144. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1145. + const struct v4l2_rect *crop;
  1146. + struct v4l2_mbus_framefmt *fmt;
  1147. + unsigned int hratio, vratio;
  1148. + unsigned int width, height;
  1149. + unsigned int hblank;
  1150. + int exposure_max;
  1151. + int ret = 0;
  1152. +
  1153. + crop = __ov5693_get_pad_crop(ov5693, state, format->pad, format->which);
  1154. +
  1155. + /*
  1156. + * Align to two to simplify the binning calculations below, and clamp
  1157. + * the requested format at the crop rectangle
  1158. + */
  1159. + width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
  1160. + OV5693_MIN_CROP_WIDTH, crop->width);
  1161. + height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
  1162. + OV5693_MIN_CROP_HEIGHT, crop->height);
  1163. +
  1164. + /*
  1165. + * We can only support setting either the dimensions of the crop rect
  1166. + * or those dimensions binned (separately) by a factor of two.
  1167. + */
  1168. + hratio = clamp_t(unsigned int, DIV_ROUND_CLOSEST(crop->width, width), 1, 2);
  1169. + vratio = clamp_t(unsigned int, DIV_ROUND_CLOSEST(crop->height, height), 1, 2);
  1170. +
  1171. + fmt = __ov5693_get_pad_format(ov5693, state, format->pad, format->which);
  1172. +
  1173. + fmt->width = crop->width / hratio;
  1174. + fmt->height = crop->height / vratio;
  1175. + fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
  1176. +
  1177. + format->format = *fmt;
  1178. +
  1179. + if (format->which == V4L2_SUBDEV_FORMAT_TRY)
  1180. + return ret;
  1181. +
  1182. + mutex_lock(&ov5693->lock);
  1183. +
  1184. + ov5693->mode.binning_x = hratio > 1 ? true : false;
  1185. + ov5693->mode.inc_x_odd = hratio > 1 ? 3 : 1;
  1186. + ov5693->mode.binning_y = vratio > 1 ? true : false;
  1187. + ov5693->mode.inc_y_odd = vratio > 1 ? 3 : 1;
  1188. +
  1189. + ov5693->mode.vts = __ov5693_calc_vts(fmt->height);
  1190. +
  1191. + __v4l2_ctrl_modify_range(ov5693->ctrls.vblank,
  1192. + OV5693_TIMING_MIN_VTS,
  1193. + OV5693_TIMING_MAX_VTS - fmt->height,
  1194. + 1, ov5693->mode.vts - fmt->height);
  1195. + __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank,
  1196. + ov5693->mode.vts - fmt->height);
  1197. +
  1198. + hblank = OV5693_FIXED_PPL - fmt->width;
  1199. + __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1,
  1200. + hblank);
  1201. +
  1202. + exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
  1203. + __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
  1204. + ov5693->ctrls.exposure->minimum, exposure_max,
  1205. + ov5693->ctrls.exposure->step,
  1206. + min(ov5693->ctrls.exposure->val, exposure_max));
  1207. +
  1208. + mutex_unlock(&ov5693->lock);
  1209. + return ret;
  1210. +}
  1211. +
  1212. +static int ov5693_get_selection(struct v4l2_subdev *sd,
  1213. + struct v4l2_subdev_state *state,
  1214. + struct v4l2_subdev_selection *sel)
  1215. +{
  1216. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1217. +
  1218. + switch (sel->target) {
  1219. + case V4L2_SEL_TGT_CROP:
  1220. + mutex_lock(&ov5693->lock);
  1221. + sel->r = *__ov5693_get_pad_crop(ov5693, state, sel->pad,
  1222. + sel->which);
  1223. + mutex_unlock(&ov5693->lock);
  1224. + break;
  1225. + case V4L2_SEL_TGT_NATIVE_SIZE:
  1226. + sel->r.top = 0;
  1227. + sel->r.left = 0;
  1228. + sel->r.width = OV5693_NATIVE_WIDTH;
  1229. + sel->r.height = OV5693_NATIVE_HEIGHT;
  1230. + break;
  1231. + case V4L2_SEL_TGT_CROP_BOUNDS:
  1232. + case V4L2_SEL_TGT_CROP_DEFAULT:
  1233. + sel->r.top = OV5693_ACTIVE_START_TOP;
  1234. + sel->r.left = OV5693_ACTIVE_START_LEFT;
  1235. + sel->r.width = OV5693_ACTIVE_WIDTH;
  1236. + sel->r.height = OV5693_ACTIVE_HEIGHT;
  1237. + break;
  1238. + default:
  1239. + return -EINVAL;
  1240. + }
  1241. +
  1242. + return 0;
  1243. +}
  1244. +
  1245. +static int ov5693_set_selection(struct v4l2_subdev *sd,
  1246. + struct v4l2_subdev_state *state,
  1247. + struct v4l2_subdev_selection *sel)
  1248. +{
  1249. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1250. + struct v4l2_mbus_framefmt *format;
  1251. + struct v4l2_rect *__crop;
  1252. + struct v4l2_rect rect;
  1253. +
  1254. + if (sel->target != V4L2_SEL_TGT_CROP)
  1255. + return -EINVAL;
  1256. +
  1257. + /*
  1258. + * Clamp the boundaries of the crop rectangle to the size of the sensor
  1259. + * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't
  1260. + * disrupted.
  1261. + */
  1262. + rect.left = clamp(ALIGN(sel->r.left, 2), OV5693_NATIVE_START_LEFT,
  1263. + OV5693_NATIVE_WIDTH);
  1264. + rect.top = clamp(ALIGN(sel->r.top, 2), OV5693_NATIVE_START_TOP,
  1265. + OV5693_NATIVE_HEIGHT);
  1266. + rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
  1267. + OV5693_MIN_CROP_WIDTH, OV5693_NATIVE_WIDTH);
  1268. + rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
  1269. + OV5693_MIN_CROP_HEIGHT, OV5693_NATIVE_HEIGHT);
  1270. +
  1271. + /* Make sure the crop rectangle isn't outside the bounds of the array */
  1272. + rect.width = min_t(unsigned int, rect.width,
  1273. + OV5693_NATIVE_WIDTH - rect.left);
  1274. + rect.height = min_t(unsigned int, rect.height,
  1275. + OV5693_NATIVE_HEIGHT - rect.top);
  1276. +
  1277. + __crop = __ov5693_get_pad_crop(ov5693, state, sel->pad, sel->which);
  1278. +
  1279. + if (rect.width != __crop->width || rect.height != __crop->height) {
  1280. + /*
  1281. + * Reset the output image size if the crop rectangle size has
  1282. + * been modified.
  1283. + */
  1284. + format = __ov5693_get_pad_format(ov5693, state, sel->pad, sel->which);
  1285. + format->width = rect.width;
  1286. + format->height = rect.height;
  1287. + }
  1288. +
  1289. + *__crop = rect;
  1290. + sel->r = rect;
  1291. +
  1292. + return 0;
  1293. +}
  1294. +
  1295. +static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
  1296. +{
  1297. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1298. + int ret;
  1299. +
  1300. + if (enable) {
  1301. + ret = pm_runtime_get_sync(ov5693->dev);
  1302. + if (ret < 0)
  1303. + goto err_power_down;
  1304. +
  1305. + ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler);
  1306. + if (ret)
  1307. + goto err_power_down;
  1308. + }
  1309. +
  1310. + mutex_lock(&ov5693->lock);
  1311. + ret = ov5693_sw_standby(ov5693, !enable);
  1312. + mutex_unlock(&ov5693->lock);
  1313. +
  1314. + if (ret)
  1315. + goto err_power_down;
  1316. + ov5693->streaming = !!enable;
  1317. +
  1318. + if (!enable)
  1319. + pm_runtime_put(ov5693->dev);
  1320. +
  1321. + return 0;
  1322. +err_power_down:
  1323. + pm_runtime_put_noidle(ov5693->dev);
  1324. + return ret;
  1325. +}
  1326. +
  1327. +static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
  1328. + struct v4l2_subdev_frame_interval *interval)
  1329. +{
  1330. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1331. + unsigned int framesize = OV5693_FIXED_PPL * (ov5693->mode.format.height +
  1332. + ov5693->ctrls.vblank->val);
  1333. + unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize);
  1334. +
  1335. + interval->interval.numerator = 1;
  1336. + interval->interval.denominator = fps;
  1337. +
  1338. + return 0;
  1339. +}
  1340. +
  1341. +static int ov5693_enum_mbus_code(struct v4l2_subdev *sd,
  1342. + struct v4l2_subdev_state *state,
  1343. + struct v4l2_subdev_mbus_code_enum *code)
  1344. +{
  1345. + /* Only a single mbus format is supported */
  1346. + if (code->index > 0)
  1347. + return -EINVAL;
  1348. +
  1349. + code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
  1350. + return 0;
  1351. +}
  1352. +
  1353. +static int ov5693_enum_frame_size(struct v4l2_subdev *sd,
  1354. + struct v4l2_subdev_state *state,
  1355. + struct v4l2_subdev_frame_size_enum *fse)
  1356. +{
  1357. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1358. + struct v4l2_rect *__crop;
  1359. +
  1360. + if (fse->index > 1 || fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
  1361. + return -EINVAL;
  1362. +
  1363. + __crop = __ov5693_get_pad_crop(ov5693, state, fse->pad, fse->which);
  1364. + if (!__crop)
  1365. + return -EINVAL;
  1366. +
  1367. + fse->min_width = __crop->width / (fse->index + 1);
  1368. + fse->min_height = __crop->height / (fse->index + 1);
  1369. + fse->max_width = fse->min_width;
  1370. + fse->max_height = fse->min_height;
  1371. +
  1372. + return 0;
  1373. +}
  1374. +
  1375. +static const struct v4l2_subdev_video_ops ov5693_video_ops = {
  1376. + .s_stream = ov5693_s_stream,
  1377. + .g_frame_interval = ov5693_g_frame_interval,
  1378. +};
  1379. +
  1380. +static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
  1381. + .enum_mbus_code = ov5693_enum_mbus_code,
  1382. + .enum_frame_size = ov5693_enum_frame_size,
  1383. + .get_fmt = ov5693_get_fmt,
  1384. + .set_fmt = ov5693_set_fmt,
  1385. + .get_selection = ov5693_get_selection,
  1386. + .set_selection = ov5693_set_selection,
  1387. +};
  1388. +
  1389. +static const struct v4l2_subdev_ops ov5693_ops = {
  1390. + .video = &ov5693_video_ops,
  1391. + .pad = &ov5693_pad_ops,
  1392. +};
  1393. +
  1394. +/* Sensor and Driver Configuration Functions */
  1395. +
  1396. +static int ov5693_init_controls(struct ov5693_device *ov5693)
  1397. +{
  1398. + const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
  1399. + struct v4l2_fwnode_device_properties props;
  1400. + int vblank_max, vblank_def;
  1401. + int exposure_max;
  1402. + int hblank;
  1403. + int ret;
  1404. +
  1405. + ret = v4l2_ctrl_handler_init(&ov5693->ctrls.handler, 12);
  1406. + if (ret)
  1407. + return ret;
  1408. +
  1409. + /* link freq */
  1410. + ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrls.handler,
  1411. + NULL, V4L2_CID_LINK_FREQ,
  1412. + 0, 0, link_freq_menu_items);
  1413. + if (ov5693->ctrls.link_freq)
  1414. + ov5693->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1415. +
  1416. + /* pixel rate */
  1417. + ov5693->ctrls.pixel_rate = v4l2_ctrl_new_std(&ov5693->ctrls.handler, NULL,
  1418. + V4L2_CID_PIXEL_RATE, 0,
  1419. + OV5693_PIXEL_RATE, 1,
  1420. + OV5693_PIXEL_RATE);
  1421. +
  1422. + /* Exposure */
  1423. + exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
  1424. + ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1425. + V4L2_CID_EXPOSURE,
  1426. + OV5693_EXPOSURE_MIN,
  1427. + exposure_max,
  1428. + OV5693_EXPOSURE_STEP,
  1429. + exposure_max);
  1430. +
  1431. + /* Gain */
  1432. + ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrls.handler,
  1433. + ops, V4L2_CID_ANALOGUE_GAIN,
  1434. + OV5693_GAIN_MIN,
  1435. + OV5693_GAIN_MAX,
  1436. + OV5693_GAIN_STEP,
  1437. + OV5693_GAIN_DEF);
  1438. +
  1439. + ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1440. + V4L2_CID_DIGITAL_GAIN,
  1441. + OV5693_DIGITAL_GAIN_MIN,
  1442. + OV5693_DIGITAL_GAIN_MAX,
  1443. + OV5693_DIGITAL_GAIN_STEP,
  1444. + OV5693_DIGITAL_GAIN_DEF);
  1445. +
  1446. + /* Flip */
  1447. + ov5693->ctrls.hflip = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1448. + V4L2_CID_HFLIP, 0, 1, 1, 0);
  1449. +
  1450. + ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1451. + V4L2_CID_VFLIP, 0, 1, 1, 0);
  1452. +
  1453. + hblank = OV5693_FIXED_PPL - ov5693->mode.format.width;
  1454. + ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1455. + V4L2_CID_HBLANK, hblank,
  1456. + hblank, 1, hblank);
  1457. +
  1458. + if (ov5693->ctrls.hblank)
  1459. + ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1460. +
  1461. + vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode.format.height;
  1462. + vblank_def = ov5693->mode.vts - ov5693->mode.format.height;
  1463. + ov5693->ctrls.vblank = v4l2_ctrl_new_std(&ov5693->ctrls.handler, ops,
  1464. + V4L2_CID_VBLANK,
  1465. + OV5693_TIMING_MIN_VTS,
  1466. + vblank_max, 1, vblank_def);
  1467. +
  1468. + ov5693->ctrls.test_pattern = v4l2_ctrl_new_std_menu_items(
  1469. + &ov5693->ctrls.handler, ops,
  1470. + V4L2_CID_TEST_PATTERN,
  1471. + ARRAY_SIZE(ov5693_test_pattern_menu) - 1,
  1472. + 0, 0, ov5693_test_pattern_menu);
  1473. +
  1474. + if (ov5693->ctrls.handler.error) {
  1475. + dev_err(ov5693->dev, "Error initialising v4l2 ctrls\n");
  1476. + ret = ov5693->ctrls.handler.error;
  1477. + goto err_free_handler;
  1478. + }
  1479. +
  1480. + /* set properties from fwnode (e.g. rotation, orientation) */
  1481. + ret = v4l2_fwnode_device_parse(ov5693->dev, &props);
  1482. + if (ret)
  1483. + goto err_free_handler;
  1484. +
  1485. + ret = v4l2_ctrl_new_fwnode_properties(&ov5693->ctrls.handler, ops,
  1486. + &props);
  1487. + if (ret)
  1488. + goto err_free_handler;
  1489. +
  1490. + /* Use same lock for controls as for everything else. */
  1491. + ov5693->ctrls.handler.lock = &ov5693->lock;
  1492. + ov5693->sd.ctrl_handler = &ov5693->ctrls.handler;
  1493. +
  1494. + return 0;
  1495. +
  1496. +err_free_handler:
  1497. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  1498. + return ret;
  1499. +}
  1500. +
  1501. +static int ov5693_configure_gpios(struct ov5693_device *ov5693)
  1502. +{
  1503. + ov5693->reset = devm_gpiod_get_optional(ov5693->dev, "reset",
  1504. + GPIOD_OUT_HIGH);
  1505. + if (IS_ERR(ov5693->reset)) {
  1506. + dev_err(ov5693->dev, "Error fetching reset GPIO\n");
  1507. + return PTR_ERR(ov5693->reset);
  1508. + }
  1509. +
  1510. + ov5693->powerdown = devm_gpiod_get_optional(ov5693->dev, "powerdown",
  1511. + GPIOD_OUT_HIGH);
  1512. + if (IS_ERR(ov5693->powerdown)) {
  1513. + dev_err(ov5693->dev, "Error fetching powerdown GPIO\n");
  1514. + return PTR_ERR(ov5693->powerdown);
  1515. + }
  1516. +
  1517. + return 0;
  1518. +}
  1519. +
  1520. +static int ov5693_get_regulators(struct ov5693_device *ov5693)
  1521. +{
  1522. + unsigned int i;
  1523. +
  1524. + for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
  1525. + ov5693->supplies[i].supply = ov5693_supply_names[i];
  1526. +
  1527. + return devm_regulator_bulk_get(ov5693->dev, OV5693_NUM_SUPPLIES,
  1528. + ov5693->supplies);
  1529. +}
  1530. +
  1531. +static int ov5693_probe(struct i2c_client *client)
  1532. +{
  1533. + struct fwnode_handle *fwnode = dev_fwnode(&client->dev);
  1534. + struct fwnode_handle *endpoint;
  1535. + struct ov5693_device *ov5693;
  1536. + u32 clk_rate;
  1537. + int ret = 0;
  1538. +
  1539. + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
  1540. + if (!endpoint && !IS_ERR_OR_NULL(fwnode->secondary))
  1541. + endpoint = fwnode_graph_get_next_endpoint(fwnode->secondary, NULL);
  1542. + if (!endpoint)
  1543. + return -EPROBE_DEFER;
  1544. +
  1545. + ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
  1546. + if (!ov5693)
  1547. + return -ENOMEM;
  1548. +
  1549. + ov5693->client = client;
  1550. + ov5693->dev = &client->dev;
  1551. +
  1552. + mutex_init(&ov5693->lock);
  1553. +
  1554. + v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
  1555. +
  1556. + ov5693->clk = devm_clk_get(&client->dev, "xvclk");
  1557. + if (IS_ERR(ov5693->clk)) {
  1558. + dev_err(&client->dev, "Error getting clock\n");
  1559. + return PTR_ERR(ov5693->clk);
  1560. + }
  1561. +
  1562. + clk_rate = clk_get_rate(ov5693->clk);
  1563. + if (clk_rate != OV5693_XVCLK_FREQ) {
  1564. + dev_err(&client->dev, "Unsupported clk freq %u, expected %u\n",
  1565. + clk_rate, OV5693_XVCLK_FREQ);
  1566. + return -EINVAL;
  1567. + }
  1568. +
  1569. + ret = ov5693_configure_gpios(ov5693);
  1570. + if (ret)
  1571. + return ret;
  1572. +
  1573. + ret = ov5693_get_regulators(ov5693);
  1574. + if (ret) {
  1575. + dev_err(&client->dev, "Error fetching regulators\n");
  1576. + return ret;
  1577. + }
  1578. +
  1579. + ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  1580. + ov5693->pad.flags = MEDIA_PAD_FL_SOURCE;
  1581. + ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
  1582. +
  1583. + ov5693->mode.crop = ov5693_default_crop;
  1584. + ov5693->mode.format = ov5693_default_fmt;
  1585. + ov5693->mode.vts = __ov5693_calc_vts(ov5693->mode.format.height);
  1586. +
  1587. + ret = ov5693_init_controls(ov5693);
  1588. + if (ret)
  1589. + return ret;
  1590. +
  1591. + ret = media_entity_pads_init(&ov5693->sd.entity, 1, &ov5693->pad);
  1592. + if (ret)
  1593. + goto err_ctrl_handler_free;
  1594. +
  1595. + /*
  1596. + * We need the driver to work in the event that pm runtime is disable in
  1597. + * the kernel, so power up and verify the chip now. In the event that
  1598. + * runtime pm is disabled this will leave the chip on, so that streaming
  1599. + * will work.
  1600. + */
  1601. +
  1602. + ret = ov5693_sensor_powerup(ov5693);
  1603. + if (ret)
  1604. + goto err_media_entity_cleanup;
  1605. +
  1606. + ret = ov5693_detect(ov5693);
  1607. + if (ret)
  1608. + goto err_powerdown;
  1609. +
  1610. + pm_runtime_set_active(&client->dev);
  1611. + pm_runtime_get_noresume(&client->dev);
  1612. + pm_runtime_enable(&client->dev);
  1613. +
  1614. + ret = v4l2_async_register_subdev_sensor(&ov5693->sd);
  1615. + if (ret) {
  1616. + dev_err(&client->dev, "failed to register V4L2 subdev: %d",
  1617. + ret);
  1618. + goto err_pm_runtime;
  1619. + }
  1620. +
  1621. + pm_runtime_set_autosuspend_delay(&client->dev, 1000);
  1622. + pm_runtime_use_autosuspend(&client->dev);
  1623. + pm_runtime_put_autosuspend(&client->dev);
  1624. +
  1625. + return ret;
  1626. +
  1627. +err_pm_runtime:
  1628. + pm_runtime_disable(&client->dev);
  1629. + pm_runtime_put_noidle(&client->dev);
  1630. +err_powerdown:
  1631. + ov5693_sensor_powerdown(ov5693);
  1632. +err_media_entity_cleanup:
  1633. + media_entity_cleanup(&ov5693->sd.entity);
  1634. +err_ctrl_handler_free:
  1635. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  1636. +
  1637. + return ret;
  1638. +}
  1639. +
  1640. +static int ov5693_remove(struct i2c_client *client)
  1641. +{
  1642. + struct v4l2_subdev *sd = i2c_get_clientdata(client);
  1643. + struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
  1644. +
  1645. + v4l2_async_unregister_subdev(sd);
  1646. + media_entity_cleanup(&ov5693->sd.entity);
  1647. + v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
  1648. + mutex_destroy(&ov5693->lock);
  1649. +
  1650. + /*
  1651. + * Disable runtime PM. In case runtime PM is disabled in the kernel,
  1652. + * make sure to turn power off manually.
  1653. + */
  1654. + pm_runtime_disable(&client->dev);
  1655. + if (!pm_runtime_status_suspended(&client->dev))
  1656. + ov5693_sensor_powerdown(ov5693);
  1657. + pm_runtime_set_suspended(&client->dev);
  1658. +
  1659. + return 0;
  1660. +}
  1661. +
  1662. +static const struct dev_pm_ops ov5693_pm_ops = {
  1663. + SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL)
  1664. +};
  1665. +
  1666. +static const struct acpi_device_id ov5693_acpi_match[] = {
  1667. + {"INT33BE"},
  1668. + {},
  1669. +};
  1670. +MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match);
  1671. +
  1672. +static struct i2c_driver ov5693_driver = {
  1673. + .driver = {
  1674. + .name = "ov5693",
  1675. + .acpi_match_table = ov5693_acpi_match,
  1676. + .pm = &ov5693_pm_ops,
  1677. + },
  1678. + .probe_new = ov5693_probe,
  1679. + .remove = ov5693_remove,
  1680. +};
  1681. +module_i2c_driver(ov5693_driver);
  1682. +
  1683. +MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors");
  1684. +MODULE_LICENSE("GPL");
  1685. --
  1686. 2.33.0
  1687. From 03aa0f41b7b8a7f26aa7dfe9f776f37a90d49968 Mon Sep 17 00:00:00 2001
  1688. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  1689. Date: Fri, 22 Jan 2021 20:58:13 +0100
  1690. Subject: [PATCH] cio2-bridge: Parse sensor orientation and rotation
  1691. MIME-Version: 1.0
  1692. Content-Type: text/plain; charset=UTF-8
  1693. Content-Transfer-Encoding: 8bit
  1694. The sensor orientation is read from the _PLC ACPI buffer and converted
  1695. to a v4l2 format.
  1696. See https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
  1697. page 351 for a definition of the Panel property.
  1698. The sensor rotation is read from the SSDB ACPI buffer and converted into
  1699. degrees.
  1700. Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
  1701. Patchset: cameras
  1702. ---
  1703. drivers/media/pci/intel/ipu3/cio2-bridge.c | 45 ++++++++++++++++++++--
  1704. drivers/media/pci/intel/ipu3/cio2-bridge.h | 3 ++
  1705. 2 files changed, 44 insertions(+), 4 deletions(-)
  1706. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1707. index 30d29b96a339..77c97bf6521e 100644
  1708. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1709. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1710. @@ -29,6 +29,7 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
  1711. static const struct cio2_property_names prop_names = {
  1712. .clock_frequency = "clock-frequency",
  1713. .rotation = "rotation",
  1714. + .orientation = "orientation",
  1715. .bus_type = "bus-type",
  1716. .data_lanes = "data-lanes",
  1717. .remote_endpoint = "remote-endpoint",
  1718. @@ -72,11 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
  1719. return ret;
  1720. }
  1721. +static u32 cio2_bridge_parse_rotation(u8 rotation)
  1722. +{
  1723. + if (rotation == 1)
  1724. + return 180;
  1725. + return 0;
  1726. +}
  1727. +
  1728. +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
  1729. +{
  1730. + switch (panel) {
  1731. + case 4:
  1732. + return V4L2_FWNODE_ORIENTATION_FRONT;
  1733. + case 5:
  1734. + return V4L2_FWNODE_ORIENTATION_BACK;
  1735. + default:
  1736. + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  1737. + }
  1738. +}
  1739. +
  1740. static void cio2_bridge_create_fwnode_properties(
  1741. struct cio2_sensor *sensor,
  1742. struct cio2_bridge *bridge,
  1743. const struct cio2_sensor_config *cfg)
  1744. {
  1745. + u32 rotation;
  1746. + enum v4l2_fwnode_orientation orientation;
  1747. +
  1748. + rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
  1749. + orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
  1750. +
  1751. sensor->prop_names = prop_names;
  1752. sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CIO2_ENDPOINT]);
  1753. @@ -85,9 +111,12 @@ static void cio2_bridge_create_fwnode_properties(
  1754. sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
  1755. sensor->prop_names.clock_frequency,
  1756. sensor->ssdb.mclkspeed);
  1757. - sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
  1758. + sensor->dev_properties[1] = PROPERTY_ENTRY_U32(
  1759. sensor->prop_names.rotation,
  1760. - sensor->ssdb.degree);
  1761. + rotation);
  1762. + sensor->dev_properties[2] = PROPERTY_ENTRY_U32(
  1763. + sensor->prop_names.orientation,
  1764. + orientation);
  1765. sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
  1766. sensor->prop_names.bus_type,
  1767. @@ -159,6 +188,7 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
  1768. for (i = 0; i < bridge->n_sensors; i++) {
  1769. sensor = &bridge->sensors[i];
  1770. software_node_unregister_nodes(sensor->swnodes);
  1771. + ACPI_FREE(sensor->pld);
  1772. acpi_dev_put(sensor->adev);
  1773. }
  1774. }
  1775. @@ -170,6 +200,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  1776. struct fwnode_handle *fwnode;
  1777. struct cio2_sensor *sensor;
  1778. struct acpi_device *adev;
  1779. + acpi_status status;
  1780. int ret;
  1781. for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
  1782. @@ -191,11 +222,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  1783. if (ret)
  1784. goto err_put_adev;
  1785. + status = acpi_get_physical_device_location(adev->handle, &sensor->pld);
  1786. + if (ACPI_FAILURE(status))
  1787. + goto err_put_adev;
  1788. +
  1789. if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
  1790. dev_err(&adev->dev,
  1791. "Number of lanes in SSDB is invalid\n");
  1792. ret = -EINVAL;
  1793. - goto err_put_adev;
  1794. + goto err_free_pld;
  1795. }
  1796. cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
  1797. @@ -203,7 +238,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  1798. ret = software_node_register_nodes(sensor->swnodes);
  1799. if (ret)
  1800. - goto err_put_adev;
  1801. + goto err_free_pld;
  1802. fwnode = software_node_fwnode(&sensor->swnodes[
  1803. SWNODE_SENSOR_HID]);
  1804. @@ -225,6 +260,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
  1805. err_free_swnodes:
  1806. software_node_unregister_nodes(sensor->swnodes);
  1807. +err_free_pld:
  1808. + ACPI_FREE(sensor->pld);
  1809. err_put_adev:
  1810. acpi_dev_put(adev);
  1811. return ret;
  1812. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1813. index dd0ffcafa489..924d99d20328 100644
  1814. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1815. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1816. @@ -80,6 +80,7 @@ struct cio2_sensor_ssdb {
  1817. struct cio2_property_names {
  1818. char clock_frequency[16];
  1819. char rotation[9];
  1820. + char orientation[12];
  1821. char bus_type[9];
  1822. char data_lanes[11];
  1823. char remote_endpoint[16];
  1824. @@ -106,6 +107,8 @@ struct cio2_sensor {
  1825. struct cio2_node_names node_names;
  1826. struct cio2_sensor_ssdb ssdb;
  1827. + struct acpi_pld_info *pld;
  1828. +
  1829. struct cio2_property_names prop_names;
  1830. struct property_entry ep_properties[5];
  1831. struct property_entry dev_properties[3];
  1832. --
  1833. 2.33.0
  1834. From fc2cfc701e95734f7125444a2a313d353c377c21 Mon Sep 17 00:00:00 2001
  1835. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  1836. Date: Sun, 24 Jan 2021 11:07:42 +0100
  1837. Subject: [PATCH] cio2-bridge: Use macros and add warnings
  1838. MIME-Version: 1.0
  1839. Content-Type: text/plain; charset=UTF-8
  1840. Content-Transfer-Encoding: 8bit
  1841. Use macros for the _PLD panel as defined in the ACPI spec 6.3 and emit
  1842. a warning if we see an unknown value.
  1843. Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
  1844. Patchset: cameras
  1845. ---
  1846. drivers/media/pci/intel/ipu3/cio2-bridge.c | 33 ++++++++++++++++------
  1847. drivers/media/pci/intel/ipu3/cio2-bridge.h | 13 +++++++++
  1848. 2 files changed, 37 insertions(+), 9 deletions(-)
  1849. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1850. index 77c97bf6521e..7e582135dfb8 100644
  1851. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1852. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  1853. @@ -73,21 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
  1854. return ret;
  1855. }
  1856. -static u32 cio2_bridge_parse_rotation(u8 rotation)
  1857. +static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
  1858. {
  1859. - if (rotation == 1)
  1860. + switch (sensor->ssdb.degree) {
  1861. + case CIO2_SENSOR_ROTATION_NORMAL:
  1862. + return 0;
  1863. + case CIO2_SENSOR_ROTATION_INVERTED:
  1864. return 180;
  1865. - return 0;
  1866. + default:
  1867. + dev_warn(&sensor->adev->dev,
  1868. + "Unknown rotation %d. Assume 0 degree rotation\n",
  1869. + sensor->ssdb.degree);
  1870. + return 0;
  1871. + }
  1872. }
  1873. -static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
  1874. +static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_sensor *sensor)
  1875. {
  1876. - switch (panel) {
  1877. - case 4:
  1878. + switch (sensor->pld->panel) {
  1879. + case CIO2_PLD_PANEL_FRONT:
  1880. return V4L2_FWNODE_ORIENTATION_FRONT;
  1881. - case 5:
  1882. + case CIO2_PLD_PANEL_BACK:
  1883. return V4L2_FWNODE_ORIENTATION_BACK;
  1884. + case CIO2_PLD_PANEL_TOP:
  1885. + case CIO2_PLD_PANEL_LEFT:
  1886. + case CIO2_PLD_PANEL_RIGHT:
  1887. + case CIO2_PLD_PANEL_UNKNOWN:
  1888. + return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  1889. default:
  1890. + dev_warn(&sensor->adev->dev, "Unknown _PLD panel value %d\n",
  1891. + sensor->pld->panel);
  1892. return V4L2_FWNODE_ORIENTATION_EXTERNAL;
  1893. }
  1894. }
  1895. @@ -100,8 +115,8 @@ static void cio2_bridge_create_fwnode_properties(
  1896. u32 rotation;
  1897. enum v4l2_fwnode_orientation orientation;
  1898. - rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
  1899. - orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
  1900. + rotation = cio2_bridge_parse_rotation(sensor);
  1901. + orientation = cio2_bridge_parse_orientation(sensor);
  1902. sensor->prop_names = prop_names;
  1903. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1904. index 924d99d20328..e1e388cc9f45 100644
  1905. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1906. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1907. @@ -12,6 +12,19 @@
  1908. #define CIO2_MAX_LANES 4
  1909. #define MAX_NUM_LINK_FREQS 3
  1910. +/* Values are estimated guesses as we don't have a spec */
  1911. +#define CIO2_SENSOR_ROTATION_NORMAL 0
  1912. +#define CIO2_SENSOR_ROTATION_INVERTED 1
  1913. +
  1914. +/* Panel position defined in _PLD section of ACPI Specification 6.3 */
  1915. +#define CIO2_PLD_PANEL_TOP 0
  1916. +#define CIO2_PLD_PANEL_BOTTOM 1
  1917. +#define CIO2_PLD_PANEL_LEFT 2
  1918. +#define CIO2_PLD_PANEL_RIGHT 3
  1919. +#define CIO2_PLD_PANEL_FRONT 4
  1920. +#define CIO2_PLD_PANEL_BACK 5
  1921. +#define CIO2_PLD_PANEL_UNKNOWN 6
  1922. +
  1923. #define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
  1924. (const struct cio2_sensor_config) { \
  1925. .hid = _HID, \
  1926. --
  1927. 2.33.0
  1928. From c474682f6c76fd1f26632943d4932d6098772e0f Mon Sep 17 00:00:00 2001
  1929. From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
  1930. Date: Thu, 6 May 2021 07:52:44 +0200
  1931. Subject: [PATCH] cio2-bridge: Use correct dev_properties size
  1932. Patchset: cameras
  1933. ---
  1934. drivers/media/pci/intel/ipu3/cio2-bridge.h | 2 +-
  1935. 1 file changed, 1 insertion(+), 1 deletion(-)
  1936. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1937. index e1e388cc9f45..deaf5804f70d 100644
  1938. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1939. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
  1940. @@ -124,7 +124,7 @@ struct cio2_sensor {
  1941. struct cio2_property_names prop_names;
  1942. struct property_entry ep_properties[5];
  1943. - struct property_entry dev_properties[3];
  1944. + struct property_entry dev_properties[4];
  1945. struct property_entry cio2_properties[3];
  1946. struct software_node_ref_args local_ref[1];
  1947. struct software_node_ref_args remote_ref[1];
  1948. --
  1949. 2.33.0
  1950. From e66aec08602b646bfcf6270b69ded6d3b796e1d0 Mon Sep 17 00:00:00 2001
  1951. From: Daniel Scally <djrscally@gmail.com>
  1952. Date: Thu, 20 May 2021 23:31:04 +0100
  1953. Subject: [PATCH] media: i2c: Fix vertical flip in ov5693
  1954. The pinkness experienced by users with rotated sensors in their laptops
  1955. was due to an incorrect setting for the vertical flip function; the
  1956. datasheet for the sensor gives the settings as bits 1&2 in one place and
  1957. bits 1&6 in another.
  1958. Switch to flipping bit 6 instead of bit 2 for 0x3820 in the vertical
  1959. flip function to fix the pink hue.
  1960. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  1961. Patchset: cameras
  1962. ---
  1963. drivers/media/i2c/ov5693.c | 2 +-
  1964. 1 file changed, 1 insertion(+), 1 deletion(-)
  1965. diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
  1966. index 9499ee10f56c..c558f9b48c83 100644
  1967. --- a/drivers/media/i2c/ov5693.c
  1968. +++ b/drivers/media/i2c/ov5693.c
  1969. @@ -133,7 +133,7 @@
  1970. #define OV5693_SUB_INC_Y_REG 0x3815
  1971. #define OV5693_FORMAT1_REG 0x3820
  1972. -#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  1973. +#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(6)
  1974. #define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
  1975. #define OV5693_FORMAT1_VBIN_EN BIT(0)
  1976. #define OV5693_FORMAT2_REG 0x3821
  1977. --
  1978. 2.33.0
  1979. From ed2894638e71f4cc68ef7dedda1386bbefe8f638 Mon Sep 17 00:00:00 2001
  1980. From: Daniel Scally <djrscally@gmail.com>
  1981. Date: Fri, 9 Jul 2021 16:39:18 +0100
  1982. Subject: [PATCH] media: i2c: Add ACPI support to ov8865
  1983. The ov8865 sensor is sometimes found on x86 platforms enumerated via ACPI.
  1984. Add an ACPI match table to the driver so that it's probed on those
  1985. platforms.
  1986. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  1987. Patchset: cameras
  1988. ---
  1989. drivers/media/i2c/ov8865.c | 8 ++++++++
  1990. 1 file changed, 8 insertions(+)
  1991. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  1992. index ce50f3ea87b8..fe60cda3dea7 100644
  1993. --- a/drivers/media/i2c/ov8865.c
  1994. +++ b/drivers/media/i2c/ov8865.c
  1995. @@ -5,6 +5,7 @@
  1996. * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
  1997. */
  1998. +#include <linux/acpi.h>
  1999. #include <linux/clk.h>
  2000. #include <linux/delay.h>
  2001. #include <linux/device.h>
  2002. @@ -2946,6 +2947,12 @@ static const struct dev_pm_ops ov8865_pm_ops = {
  2003. SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)
  2004. };
  2005. +static const struct acpi_device_id ov8865_acpi_match[] = {
  2006. + {"INT347A"},
  2007. + {},
  2008. +};
  2009. +MODULE_DEVICE_TABLE(acpi, ov8865_acpi_match);
  2010. +
  2011. static const struct of_device_id ov8865_of_match[] = {
  2012. { .compatible = "ovti,ov8865" },
  2013. { }
  2014. @@ -2956,6 +2963,7 @@ static struct i2c_driver ov8865_driver = {
  2015. .driver = {
  2016. .name = "ov8865",
  2017. .of_match_table = ov8865_of_match,
  2018. + .acpi_match_table = ov8865_acpi_match,
  2019. .pm = &ov8865_pm_ops,
  2020. },
  2021. .probe_new = ov8865_probe,
  2022. --
  2023. 2.33.0
  2024. From 41988d26abb411c01abe3e8965b91790c9f0d99a Mon Sep 17 00:00:00 2001
  2025. From: Daniel Scally <djrscally@gmail.com>
  2026. Date: Sat, 10 Jul 2021 21:20:17 +0100
  2027. Subject: [PATCH] media: i2c: Fix incorrect value in comment
  2028. The PLL configuration defined here sets 72MHz (which is correct), not
  2029. 80MHz. Correct the comment.
  2030. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2031. Patchset: cameras
  2032. ---
  2033. drivers/media/i2c/ov8865.c | 2 +-
  2034. 1 file changed, 1 insertion(+), 1 deletion(-)
  2035. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2036. index fe60cda3dea7..2ef146e7e7ef 100644
  2037. --- a/drivers/media/i2c/ov8865.c
  2038. +++ b/drivers/media/i2c/ov8865.c
  2039. @@ -713,7 +713,7 @@ static const struct ov8865_pll2_config ov8865_pll2_config_native = {
  2040. /*
  2041. * EXTCLK = 24 MHz
  2042. * DAC_CLK = 360 MHz
  2043. - * SCLK = 80 MHz
  2044. + * SCLK = 72 MHz
  2045. */
  2046. static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
  2047. --
  2048. 2.33.0
  2049. From 95a6c0d584e4a27ec58f3c23cdf93ae808dc0d93 Mon Sep 17 00:00:00 2001
  2050. From: Daniel Scally <djrscally@gmail.com>
  2051. Date: Sat, 10 Jul 2021 22:21:52 +0100
  2052. Subject: [PATCH] media: i2c: Check fwnode->secondary for endpoint
  2053. The ov8865 driver is one of those that can be connected to a CIO2
  2054. device by the cio2-bridge code. This means that the absence of an
  2055. endpoint for this device is not necessarily fatal, as one might be
  2056. built by the cio2-bridge when it probes. Check fwnode->secondary for
  2057. an endpoint, and defer probing if one isn't found rather than fail.
  2058. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2059. Patchset: cameras
  2060. ---
  2061. drivers/media/i2c/ov8865.c | 11 ++++++-----
  2062. 1 file changed, 6 insertions(+), 5 deletions(-)
  2063. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2064. index 2ef146e7e7ef..a3199721bbca 100644
  2065. --- a/drivers/media/i2c/ov8865.c
  2066. +++ b/drivers/media/i2c/ov8865.c
  2067. @@ -2779,6 +2779,7 @@ static int ov8865_resume(struct device *dev)
  2068. static int ov8865_probe(struct i2c_client *client)
  2069. {
  2070. struct device *dev = &client->dev;
  2071. + struct fwnode_handle *fwnode = dev_fwnode(dev);
  2072. struct fwnode_handle *handle;
  2073. struct ov8865_sensor *sensor;
  2074. struct v4l2_subdev *subdev;
  2075. @@ -2795,11 +2796,11 @@ static int ov8865_probe(struct i2c_client *client)
  2076. /* Graph Endpoint */
  2077. - handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
  2078. - if (!handle) {
  2079. - dev_err(dev, "unable to find endpoint node\n");
  2080. - return -EINVAL;
  2081. - }
  2082. + handle = fwnode_graph_get_next_endpoint(fwnode, NULL);
  2083. + if (!handle && !IS_ERR_OR_NULL(fwnode->secondary))
  2084. + handle = fwnode_graph_get_next_endpoint(fwnode->secondary, NULL);
  2085. + if (!handle)
  2086. + return -EPROBE_DEFER;
  2087. sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
  2088. --
  2089. 2.33.0
  2090. From d950f6dc61ba8aacd47f1dfda2526ccd2370cb34 Mon Sep 17 00:00:00 2001
  2091. From: Daniel Scally <djrscally@gmail.com>
  2092. Date: Sat, 10 Jul 2021 22:00:25 +0100
  2093. Subject: [PATCH] media: i2c: Support 19.2MHz input clock in ov8865
  2094. The ov8865 driver as written expects a 24MHz input clock, but the sensor
  2095. is sometimes found on x86 platforms with a 19.2MHz input clock supplied.
  2096. Add a set of PLL configurations to the driver to support that rate too.
  2097. As ACPI doesn't auto-configure the clock rate, check for a clock-frequency
  2098. during probe and set that rate if one is found.
  2099. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2100. Patchset: cameras
  2101. ---
  2102. drivers/media/i2c/ov8865.c | 157 +++++++++++++++++++++++++++----------
  2103. 1 file changed, 114 insertions(+), 43 deletions(-)
  2104. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2105. index a3199721bbca..53e6bcbe18d6 100644
  2106. --- a/drivers/media/i2c/ov8865.c
  2107. +++ b/drivers/media/i2c/ov8865.c
  2108. @@ -21,10 +21,6 @@
  2109. #include <media/v4l2-image-sizes.h>
  2110. #include <media/v4l2-mediabus.h>
  2111. -/* Clock rate */
  2112. -
  2113. -#define OV8865_EXTCLK_RATE 24000000
  2114. -
  2115. /* Register definitions */
  2116. /* System */
  2117. @@ -665,6 +661,9 @@ struct ov8865_sensor {
  2118. struct regulator *avdd;
  2119. struct regulator *dvdd;
  2120. struct regulator *dovdd;
  2121. +
  2122. + unsigned long extclk_rate;
  2123. + unsigned int extclk_rate_idx;
  2124. struct clk *extclk;
  2125. struct v4l2_fwnode_endpoint endpoint;
  2126. @@ -680,49 +679,83 @@ struct ov8865_sensor {
  2127. /* Static definitions */
  2128. /*
  2129. - * EXTCLK = 24 MHz
  2130. * PHY_SCLK = 720 MHz
  2131. * MIPI_PCLK = 90 MHz
  2132. */
  2133. -static const struct ov8865_pll1_config ov8865_pll1_config_native = {
  2134. - .pll_pre_div_half = 1,
  2135. - .pll_pre_div = 0,
  2136. - .pll_mul = 30,
  2137. - .m_div = 1,
  2138. - .mipi_div = 3,
  2139. - .pclk_div = 1,
  2140. - .sys_pre_div = 1,
  2141. - .sys_div = 2,
  2142. +
  2143. +static const struct ov8865_pll1_config ov8865_pll1_configs_native[] = {
  2144. + { /* 19.2 MHz input clock */
  2145. + .pll_pre_div_half = 1,
  2146. + .pll_pre_div = 2,
  2147. + .pll_mul = 75,
  2148. + .m_div = 1,
  2149. + .mipi_div = 3,
  2150. + .pclk_div = 1,
  2151. + .sys_pre_div = 1,
  2152. + .sys_div = 2,
  2153. + },
  2154. + { /* 24MHz input clock */
  2155. + .pll_pre_div_half = 1,
  2156. + .pll_pre_div = 0,
  2157. + .pll_mul = 30,
  2158. + .m_div = 1,
  2159. + .mipi_div = 3,
  2160. + .pclk_div = 1,
  2161. + .sys_pre_div = 1,
  2162. + .sys_div = 2,
  2163. + },
  2164. };
  2165. /*
  2166. - * EXTCLK = 24 MHz
  2167. * DAC_CLK = 360 MHz
  2168. * SCLK = 144 MHz
  2169. */
  2170. -static const struct ov8865_pll2_config ov8865_pll2_config_native = {
  2171. - .pll_pre_div_half = 1,
  2172. - .pll_pre_div = 0,
  2173. - .pll_mul = 30,
  2174. - .dac_div = 2,
  2175. - .sys_pre_div = 5,
  2176. - .sys_div = 0,
  2177. +static const struct ov8865_pll2_config ov8865_pll2_configs_native[] = {
  2178. + /* 19.2MHz input clock */
  2179. + {
  2180. + .pll_pre_div_half = 1,
  2181. + .pll_pre_div = 5,
  2182. + .pll_mul = 75,
  2183. + .dac_div = 1,
  2184. + .sys_pre_div = 1,
  2185. + .sys_div = 3,
  2186. + },
  2187. + /* 24MHz input clock */
  2188. + {
  2189. + .pll_pre_div_half = 1,
  2190. + .pll_pre_div = 0,
  2191. + .pll_mul = 30,
  2192. + .dac_div = 2,
  2193. + .sys_pre_div = 5,
  2194. + .sys_div = 0,
  2195. + }
  2196. };
  2197. /*
  2198. - * EXTCLK = 24 MHz
  2199. * DAC_CLK = 360 MHz
  2200. * SCLK = 72 MHz
  2201. */
  2202. -static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
  2203. +static const struct ov8865_pll2_config ov8865_pll2_configs_binning[] = {
  2204. + /* 19.2MHz input clock */
  2205. + {
  2206. + .pll_pre_div_half = 1,
  2207. + .pll_pre_div = 2,
  2208. + .pll_mul = 75,
  2209. + .dac_div = 2,
  2210. + .sys_pre_div = 10,
  2211. + .sys_div = 0,
  2212. + },
  2213. + /* 24MHz input clock */
  2214. + {
  2215. .pll_pre_div_half = 1,
  2216. .pll_pre_div = 0,
  2217. .pll_mul = 30,
  2218. .dac_div = 2,
  2219. .sys_pre_div = 10,
  2220. .sys_div = 0,
  2221. + }
  2222. };
  2223. static const struct ov8865_sclk_config ov8865_sclk_config_native = {
  2224. @@ -934,8 +967,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  2225. .frame_interval = { 1, 30 },
  2226. /* PLL */
  2227. - .pll1_config = &ov8865_pll1_config_native,
  2228. - .pll2_config = &ov8865_pll2_config_native,
  2229. + .pll1_config = ov8865_pll1_configs_native,
  2230. + .pll2_config = ov8865_pll2_configs_native,
  2231. .sclk_config = &ov8865_sclk_config_native,
  2232. /* Registers */
  2233. @@ -990,8 +1023,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  2234. .frame_interval = { 1, 30 },
  2235. /* PLL */
  2236. - .pll1_config = &ov8865_pll1_config_native,
  2237. - .pll2_config = &ov8865_pll2_config_native,
  2238. + .pll1_config = ov8865_pll1_configs_native,
  2239. + .pll2_config = ov8865_pll2_configs_native,
  2240. .sclk_config = &ov8865_sclk_config_native,
  2241. /* Registers */
  2242. @@ -1050,8 +1083,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  2243. .frame_interval = { 1, 30 },
  2244. /* PLL */
  2245. - .pll1_config = &ov8865_pll1_config_native,
  2246. - .pll2_config = &ov8865_pll2_config_binning,
  2247. + .pll1_config = ov8865_pll1_configs_native,
  2248. + .pll2_config = ov8865_pll2_configs_binning,
  2249. .sclk_config = &ov8865_sclk_config_native,
  2250. /* Registers */
  2251. @@ -1116,8 +1149,8 @@ static const struct ov8865_mode ov8865_modes[] = {
  2252. .frame_interval = { 1, 90 },
  2253. /* PLL */
  2254. - .pll1_config = &ov8865_pll1_config_native,
  2255. - .pll2_config = &ov8865_pll2_config_binning,
  2256. + .pll1_config = ov8865_pll1_configs_native,
  2257. + .pll2_config = ov8865_pll2_configs_binning,
  2258. .sclk_config = &ov8865_sclk_config_native,
  2259. /* Registers */
  2260. @@ -1266,6 +1299,13 @@ static const struct ov8865_register_value ov8865_init_sequence[] = {
  2261. { 0x4503, 0x10 },
  2262. };
  2263. +/* Clock rate */
  2264. +
  2265. +static const unsigned long supported_extclk_rates[] = {
  2266. + 19200000,
  2267. + 24000000,
  2268. +};
  2269. +
  2270. static const s64 ov8865_link_freq_menu[] = {
  2271. 360000000,
  2272. };
  2273. @@ -1513,12 +1553,11 @@ static int ov8865_isp_configure(struct ov8865_sensor *sensor)
  2274. static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,
  2275. const struct ov8865_mode *mode)
  2276. {
  2277. - const struct ov8865_pll1_config *config = mode->pll1_config;
  2278. - unsigned long extclk_rate;
  2279. + const struct ov8865_pll1_config *config;
  2280. unsigned long pll1_rate;
  2281. - extclk_rate = clk_get_rate(sensor->extclk);
  2282. - pll1_rate = extclk_rate * config->pll_mul / config->pll_pre_div_half;
  2283. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  2284. + pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half;
  2285. switch (config->pll_pre_div) {
  2286. case 0:
  2287. @@ -1552,10 +1591,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
  2288. const struct ov8865_mode *mode,
  2289. u32 mbus_code)
  2290. {
  2291. - const struct ov8865_pll1_config *config = mode->pll1_config;
  2292. + const struct ov8865_pll1_config *config;
  2293. u8 value;
  2294. int ret;
  2295. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  2296. +
  2297. switch (mbus_code) {
  2298. case MEDIA_BUS_FMT_SBGGR10_1X10:
  2299. value = OV8865_MIPI_BIT_SEL(10);
  2300. @@ -1622,9 +1663,11 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
  2301. static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
  2302. const struct ov8865_mode *mode)
  2303. {
  2304. - const struct ov8865_pll2_config *config = mode->pll2_config;
  2305. + const struct ov8865_pll2_config *config;
  2306. int ret;
  2307. + config = &mode->pll2_config[sensor->extclk_rate_idx];
  2308. +
  2309. ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,
  2310. OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |
  2311. OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));
  2312. @@ -2053,9 +2096,11 @@ static int ov8865_mode_configure(struct ov8865_sensor *sensor,
  2313. static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,
  2314. const struct ov8865_mode *mode)
  2315. {
  2316. - const struct ov8865_pll1_config *config = mode->pll1_config;
  2317. + const struct ov8865_pll1_config *config;
  2318. unsigned long pll1_rate;
  2319. + config = &mode->pll1_config[sensor->extclk_rate_idx];
  2320. +
  2321. pll1_rate = ov8865_mode_pll1_rate(sensor, mode);
  2322. return pll1_rate / config->m_div / 2;
  2323. @@ -2784,7 +2829,8 @@ static int ov8865_probe(struct i2c_client *client)
  2324. struct ov8865_sensor *sensor;
  2325. struct v4l2_subdev *subdev;
  2326. struct media_pad *pad;
  2327. - unsigned long rate;
  2328. + unsigned int rate;
  2329. + unsigned int i;
  2330. int ret;
  2331. sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
  2332. @@ -2861,13 +2907,38 @@ static int ov8865_probe(struct i2c_client *client)
  2333. goto error_endpoint;
  2334. }
  2335. - rate = clk_get_rate(sensor->extclk);
  2336. - if (rate != OV8865_EXTCLK_RATE) {
  2337. - dev_err(dev, "clock rate %lu Hz is unsupported\n", rate);
  2338. + /*
  2339. + * We could have either a 24MHz or 19.2MHz clock rate. Check for a
  2340. + * clock-frequency property and if found, set that rate. This should
  2341. + * cover ACPI case. If the system uses devicetree then the configured
  2342. + * rate should already be set, so we'll have to check it.
  2343. + */
  2344. +
  2345. + ret = fwnode_property_read_u32(fwnode, "clock-frequency", &rate);
  2346. + if (!ret) {
  2347. + ret = clk_set_rate(sensor->extclk, rate);
  2348. + if (ret) {
  2349. + dev_err(dev, "failed to set clock rate\n");
  2350. + return ret;
  2351. + }
  2352. + }
  2353. +
  2354. + sensor->extclk_rate = clk_get_rate(sensor->extclk);
  2355. +
  2356. + for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
  2357. + if (sensor->extclk_rate == supported_extclk_rates[i])
  2358. + break;
  2359. + }
  2360. +
  2361. + if (i == ARRAY_SIZE(supported_extclk_rates)) {
  2362. + dev_err(dev, "clock rate %lu Hz is unsupported\n",
  2363. + sensor->extclk_rate);
  2364. ret = -EINVAL;
  2365. goto error_endpoint;
  2366. }
  2367. + sensor->extclk_rate_idx = i;
  2368. +
  2369. /* Subdev, entity and pad */
  2370. subdev = &sensor->subdev;
  2371. --
  2372. 2.33.0
  2373. From 1cdd9af1d3719197c22906ac5965c3ef737fd2bc Mon Sep 17 00:00:00 2001
  2374. From: Daniel Scally <djrscally@gmail.com>
  2375. Date: Sat, 10 Jul 2021 22:19:10 +0100
  2376. Subject: [PATCH] media: i2c: Add .get_selection() support to ov8865
  2377. The ov8865 drivers media pad ops currently does not include
  2378. .get_selection() - add support for that callback.
  2379. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2380. Patchset: cameras
  2381. ---
  2382. drivers/media/i2c/ov8865.c | 61 ++++++++++++++++++++++++++++++++++++++
  2383. 1 file changed, 61 insertions(+)
  2384. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2385. index 53e6bcbe18d6..2f487c25ed56 100644
  2386. --- a/drivers/media/i2c/ov8865.c
  2387. +++ b/drivers/media/i2c/ov8865.c
  2388. @@ -450,6 +450,15 @@
  2389. #define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES 2
  2390. #define OV8865_PRE_CTRL0_PATTERN_BLACK 3
  2391. +/* Pixel Array */
  2392. +
  2393. +#define OV8865_NATIVE_WIDTH 3296
  2394. +#define OV8865_NATIVE_HEIGHT 2528
  2395. +#define OV8865_ACTIVE_START_TOP 32
  2396. +#define OV8865_ACTIVE_START_LEFT 80
  2397. +#define OV8865_ACTIVE_WIDTH 3264
  2398. +#define OV8865_ACTIVE_HEIGHT 2448
  2399. +
  2400. /* Macros */
  2401. #define ov8865_subdev_sensor(s) \
  2402. @@ -2743,12 +2752,64 @@ static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
  2403. return 0;
  2404. }
  2405. +static void
  2406. +__ov8865_get_pad_crop(struct ov8865_sensor *sensor,
  2407. + struct v4l2_subdev_state *state, unsigned int pad,
  2408. + enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
  2409. +{
  2410. + switch (which) {
  2411. + case V4L2_SUBDEV_FORMAT_TRY:
  2412. + *r = *v4l2_subdev_get_try_crop(&sensor->subdev, state, pad);
  2413. + break;
  2414. + case V4L2_SUBDEV_FORMAT_ACTIVE:
  2415. + r->height = sensor->state.mode->output_size_y;
  2416. + r->width = sensor->state.mode->output_size_x;
  2417. + r->top = (OV8865_NATIVE_HEIGHT - sensor->state.mode->output_size_y) / 2;
  2418. + r->left = (OV8865_NATIVE_WIDTH - sensor->state.mode->output_size_x) / 2;
  2419. + break;
  2420. + }
  2421. +}
  2422. +
  2423. +static int ov8865_get_selection(struct v4l2_subdev *subdev,
  2424. + struct v4l2_subdev_state *state,
  2425. + struct v4l2_subdev_selection *sel)
  2426. +{
  2427. + struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
  2428. +
  2429. + switch (sel->target) {
  2430. + case V4L2_SEL_TGT_CROP:
  2431. + mutex_lock(&sensor->mutex);
  2432. + __ov8865_get_pad_crop(sensor, state, sel->pad,
  2433. + sel->which, &sel->r);
  2434. + mutex_unlock(&sensor->mutex);
  2435. + break;
  2436. + case V4L2_SEL_TGT_NATIVE_SIZE:
  2437. + sel->r.top = 0;
  2438. + sel->r.left = 0;
  2439. + sel->r.width = OV8865_NATIVE_WIDTH;
  2440. + sel->r.height = OV8865_NATIVE_HEIGHT;
  2441. + break;
  2442. + case V4L2_SEL_TGT_CROP_BOUNDS:
  2443. + case V4L2_SEL_TGT_CROP_DEFAULT:
  2444. + sel->r.top = OV8865_ACTIVE_START_TOP;
  2445. + sel->r.left = OV8865_ACTIVE_START_LEFT;
  2446. + sel->r.width = OV8865_ACTIVE_WIDTH;
  2447. + sel->r.height = OV8865_ACTIVE_HEIGHT;
  2448. + break;
  2449. + default:
  2450. + return -EINVAL;
  2451. + }
  2452. +
  2453. + return 0;
  2454. +}
  2455. +
  2456. static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
  2457. .enum_mbus_code = ov8865_enum_mbus_code,
  2458. .get_fmt = ov8865_get_fmt,
  2459. .set_fmt = ov8865_set_fmt,
  2460. .enum_frame_size = ov8865_enum_frame_size,
  2461. .enum_frame_interval = ov8865_enum_frame_interval,
  2462. + .get_selection = ov8865_get_selection,
  2463. };
  2464. static const struct v4l2_subdev_ops ov8865_subdev_ops = {
  2465. --
  2466. 2.33.0
  2467. From 4b92be6fc4d9ce258cb2911271458dac768c5529 Mon Sep 17 00:00:00 2001
  2468. From: Daniel Scally <djrscally@gmail.com>
  2469. Date: Sat, 10 Jul 2021 22:34:43 +0100
  2470. Subject: [PATCH] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN
  2471. The V4L2_CID_GAIN control for this driver configures registers that
  2472. the datasheet specifies as analogue gain. Switch the control's ID
  2473. to V4L2_CID_ANALOGUE_GAIN.
  2474. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2475. Patchset: cameras
  2476. ---
  2477. drivers/media/i2c/ov8865.c | 8 ++++----
  2478. 1 file changed, 4 insertions(+), 4 deletions(-)
  2479. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2480. index 2f487c25ed56..b91c952b6ef9 100644
  2481. --- a/drivers/media/i2c/ov8865.c
  2482. +++ b/drivers/media/i2c/ov8865.c
  2483. @@ -2137,7 +2137,7 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
  2484. /* Gain */
  2485. -static int ov8865_gain_configure(struct ov8865_sensor *sensor, u32 gain)
  2486. +static int ov8865_analog_gain_configure(struct ov8865_sensor *sensor, u32 gain)
  2487. {
  2488. int ret;
  2489. @@ -2447,8 +2447,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  2490. if (ret)
  2491. return ret;
  2492. break;
  2493. - case V4L2_CID_GAIN:
  2494. - ret = ov8865_gain_configure(sensor, ctrl->val);
  2495. + case V4L2_CID_ANALOGUE_GAIN:
  2496. + ret = ov8865_analog_gain_configure(sensor, ctrl->val);
  2497. if (ret)
  2498. return ret;
  2499. break;
  2500. @@ -2493,7 +2493,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2501. /* Gain */
  2502. - v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 128, 8191, 128, 128);
  2503. + v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 8191, 128, 128);
  2504. /* White Balance */
  2505. --
  2506. 2.33.0
  2507. From 7d1925b84012cd665f110843c9708d49f04251ba Mon Sep 17 00:00:00 2001
  2508. From: Daniel Scally <djrscally@gmail.com>
  2509. Date: Mon, 12 Jul 2021 22:54:56 +0100
  2510. Subject: [PATCH] media: i2c: Add vblank control to ov8865
  2511. Add a V4L2_CID_VBLANK control to the ov8865 driver.
  2512. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2513. Patchset: cameras
  2514. ---
  2515. drivers/media/i2c/ov8865.c | 34 ++++++++++++++++++++++++++++++++++
  2516. 1 file changed, 34 insertions(+)
  2517. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2518. index b91c952b6ef9..4430115607a4 100644
  2519. --- a/drivers/media/i2c/ov8865.c
  2520. +++ b/drivers/media/i2c/ov8865.c
  2521. @@ -183,6 +183,8 @@
  2522. #define OV8865_VTS_H(v) (((v) & GENMASK(11, 8)) >> 8)
  2523. #define OV8865_VTS_L_REG 0x380f
  2524. #define OV8865_VTS_L(v) ((v) & GENMASK(7, 0))
  2525. +#define OV8865_TIMING_MAX_VTS 0xffff
  2526. +#define OV8865_TIMING_MIN_VTS 0x04
  2527. #define OV8865_OFFSET_X_H_REG 0x3810
  2528. #define OV8865_OFFSET_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2529. #define OV8865_OFFSET_X_L_REG 0x3811
  2530. @@ -658,6 +660,7 @@ struct ov8865_state {
  2531. struct ov8865_ctrls {
  2532. struct v4l2_ctrl *link_freq;
  2533. struct v4l2_ctrl *pixel_rate;
  2534. + struct v4l2_ctrl *vblank;
  2535. struct v4l2_ctrl_handler handler;
  2536. };
  2537. @@ -2212,6 +2215,20 @@ static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,
  2538. ov8865_test_pattern_bits[index]);
  2539. }
  2540. +/* Blanking */
  2541. +
  2542. +static int ov8865_vts_configure(struct ov8865_sensor *sensor, u32 vblank)
  2543. +{
  2544. + u16 vts = sensor->state.mode->output_size_y + vblank;
  2545. + int ret;
  2546. +
  2547. + ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(vts));
  2548. + if (ret)
  2549. + return ret;
  2550. +
  2551. + return ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(vts));
  2552. +}
  2553. +
  2554. /* State */
  2555. static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,
  2556. @@ -2463,6 +2480,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  2557. case V4L2_CID_TEST_PATTERN:
  2558. index = (unsigned int)ctrl->val;
  2559. return ov8865_test_pattern_configure(sensor, index);
  2560. + case V4L2_CID_VBLANK:
  2561. + return ov8865_vts_configure(sensor, ctrl->val);
  2562. default:
  2563. return -EINVAL;
  2564. }
  2565. @@ -2479,6 +2498,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2566. struct ov8865_ctrls *ctrls = &sensor->ctrls;
  2567. struct v4l2_ctrl_handler *handler = &ctrls->handler;
  2568. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  2569. + const struct ov8865_mode *mode = sensor->state.mode;
  2570. + unsigned int vblank_max, vblank_def;
  2571. int ret;
  2572. v4l2_ctrl_handler_init(handler, 32);
  2573. @@ -2514,6 +2535,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2574. ARRAY_SIZE(ov8865_test_pattern_menu) - 1,
  2575. 0, 0, ov8865_test_pattern_menu);
  2576. + /* Blanking */
  2577. + vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
  2578. + vblank_def = mode->vts - mode->output_size_y;
  2579. + ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
  2580. + OV8865_TIMING_MIN_VTS, vblank_max, 1,
  2581. + vblank_def);
  2582. +
  2583. /* MIPI CSI-2 */
  2584. ctrls->link_freq =
  2585. @@ -2694,6 +2722,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  2586. sensor->state.mbus_code != mbus_code)
  2587. ret = ov8865_state_configure(sensor, mode, mbus_code);
  2588. + __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS,
  2589. + OV8865_TIMING_MAX_VTS - mode->output_size_y,
  2590. + 1, mode->vts - mode->output_size_y);
  2591. +
  2592. complete:
  2593. mutex_unlock(&sensor->mutex);
  2594. @@ -3021,6 +3053,8 @@ static int ov8865_probe(struct i2c_client *client)
  2595. /* Sensor */
  2596. + sensor->state.mode = &ov8865_modes[0];
  2597. +
  2598. ret = ov8865_ctrls_init(sensor);
  2599. if (ret)
  2600. goto error_mutex;
  2601. --
  2602. 2.33.0
  2603. From fae13f2527d31ac88825d933c0650dee946f4a99 Mon Sep 17 00:00:00 2001
  2604. From: Daniel Scally <djrscally@gmail.com>
  2605. Date: Tue, 13 Jul 2021 23:40:33 +0100
  2606. Subject: [PATCH] media: i2c: Add hblank control to ov8865
  2607. Add a V4L2_CID_HBLANK control to the ov8865 driver. This is read only
  2608. with timing control intended to be done via vblanking alone.
  2609. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2610. Patchset: cameras
  2611. ---
  2612. drivers/media/i2c/ov8865.c | 14 ++++++++++++++
  2613. 1 file changed, 14 insertions(+)
  2614. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2615. index 4430115607a4..e9b5f4d8e79b 100644
  2616. --- a/drivers/media/i2c/ov8865.c
  2617. +++ b/drivers/media/i2c/ov8865.c
  2618. @@ -660,6 +660,7 @@ struct ov8865_state {
  2619. struct ov8865_ctrls {
  2620. struct v4l2_ctrl *link_freq;
  2621. struct v4l2_ctrl *pixel_rate;
  2622. + struct v4l2_ctrl *hblank;
  2623. struct v4l2_ctrl *vblank;
  2624. struct v4l2_ctrl_handler handler;
  2625. @@ -2500,6 +2501,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2626. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  2627. const struct ov8865_mode *mode = sensor->state.mode;
  2628. unsigned int vblank_max, vblank_def;
  2629. + unsigned int hblank;
  2630. int ret;
  2631. v4l2_ctrl_handler_init(handler, 32);
  2632. @@ -2536,6 +2538,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2633. 0, 0, ov8865_test_pattern_menu);
  2634. /* Blanking */
  2635. + hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
  2636. + ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,
  2637. + hblank, 1, hblank);
  2638. +
  2639. + if (ctrls->hblank)
  2640. + ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  2641. +
  2642. vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
  2643. vblank_def = mode->vts - mode->output_size_y;
  2644. ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
  2645. @@ -2682,6 +2691,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  2646. struct v4l2_mbus_framefmt *mbus_format = &format->format;
  2647. const struct ov8865_mode *mode;
  2648. u32 mbus_code = 0;
  2649. + unsigned int hblank;
  2650. unsigned int index;
  2651. int ret = 0;
  2652. @@ -2726,6 +2736,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  2653. OV8865_TIMING_MAX_VTS - mode->output_size_y,
  2654. 1, mode->vts - mode->output_size_y);
  2655. + hblank = mode->hts < mode->output_size_x ? 0 : mode->hts - mode->output_size_x;
  2656. + __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
  2657. + hblank);
  2658. +
  2659. complete:
  2660. mutex_unlock(&sensor->mutex);
  2661. --
  2662. 2.33.0
  2663. From b7e13a8d50b692d98824bc21a49bffe3020a71f2 Mon Sep 17 00:00:00 2001
  2664. From: Daniel Scally <djrscally@gmail.com>
  2665. Date: Tue, 13 Jul 2021 23:43:17 +0100
  2666. Subject: [PATCH] media: i2c: cap exposure at height + vblank in ov8865
  2667. Exposure limits depend on the total height; when vblank is altered (and
  2668. thus the total height is altered), change the exposure limits to reflect
  2669. the new cap.
  2670. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2671. Patchset: cameras
  2672. ---
  2673. drivers/media/i2c/ov8865.c | 24 ++++++++++++++++++++++--
  2674. 1 file changed, 22 insertions(+), 2 deletions(-)
  2675. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2676. index e9b5f4d8e79b..893cc58dc265 100644
  2677. --- a/drivers/media/i2c/ov8865.c
  2678. +++ b/drivers/media/i2c/ov8865.c
  2679. @@ -662,6 +662,7 @@ struct ov8865_ctrls {
  2680. struct v4l2_ctrl *pixel_rate;
  2681. struct v4l2_ctrl *hblank;
  2682. struct v4l2_ctrl *vblank;
  2683. + struct v4l2_ctrl *exposure;
  2684. struct v4l2_ctrl_handler handler;
  2685. };
  2686. @@ -2455,6 +2456,18 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
  2687. unsigned int index;
  2688. int ret;
  2689. + /* If VBLANK is altered we need to update exposure to compensate */
  2690. + if (ctrl->id == V4L2_CID_VBLANK) {
  2691. + int exposure_max;
  2692. +
  2693. + exposure_max = sensor->state.mode->output_size_y + ctrl->val;
  2694. + __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
  2695. + sensor->ctrls.exposure->minimum,
  2696. + exposure_max,
  2697. + sensor->ctrls.exposure->step,
  2698. + min(sensor->ctrls.exposure->val, exposure_max));
  2699. + }
  2700. +
  2701. /* Wait for the sensor to be on before setting controls. */
  2702. if (pm_runtime_suspended(sensor->dev))
  2703. return 0;
  2704. @@ -2511,8 +2524,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  2705. /* Exposure */
  2706. - v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
  2707. - 512);
  2708. + ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
  2709. + 1048575, 16, 512);
  2710. /* Gain */
  2711. @@ -2693,6 +2706,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  2712. u32 mbus_code = 0;
  2713. unsigned int hblank;
  2714. unsigned int index;
  2715. + int exposure_max;
  2716. int ret = 0;
  2717. mutex_lock(&sensor->mutex);
  2718. @@ -2740,6 +2754,12 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
  2719. __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
  2720. hblank);
  2721. + exposure_max = mode->vts;
  2722. + __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
  2723. + sensor->ctrls.exposure->minimum, exposure_max,
  2724. + sensor->ctrls.exposure->step,
  2725. + min(sensor->ctrls.exposure->val, exposure_max));
  2726. +
  2727. complete:
  2728. mutex_unlock(&sensor->mutex);
  2729. --
  2730. 2.33.0
  2731. From 0db2021f46fb10c11be60f4a75918a5fb857224a Mon Sep 17 00:00:00 2001
  2732. From: Daniel Scally <djrscally@gmail.com>
  2733. Date: Wed, 14 Jul 2021 18:05:44 +0100
  2734. Subject: [PATCH] media: i2c: Remove unused macros from ov8865
  2735. There are a number of macros defined in this driver that aren't actually
  2736. used within it. There's a lot of macros defined in total, so removing the
  2737. unused ones helps make it a bit less busy.
  2738. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2739. Patchset: cameras
  2740. ---
  2741. drivers/media/i2c/ov8865.c | 137 +------------------------------------
  2742. 1 file changed, 1 insertion(+), 136 deletions(-)
  2743. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2744. index 893cc58dc265..fb81b822987d 100644
  2745. --- a/drivers/media/i2c/ov8865.c
  2746. +++ b/drivers/media/i2c/ov8865.c
  2747. @@ -46,8 +46,6 @@
  2748. #define OV8865_PLL_CTRL6_REG 0x306
  2749. #define OV8865_PLL_CTRL6_SYS_DIV(v) (((v) - 1) & BIT(0))
  2750. -#define OV8865_PLL_CTRL8_REG 0x308
  2751. -#define OV8865_PLL_CTRL9_REG 0x309
  2752. #define OV8865_PLL_CTRLA_REG 0x30a
  2753. #define OV8865_PLL_CTRLA_PRE_DIV_HALF(v) (((v) - 1) & BIT(0))
  2754. #define OV8865_PLL_CTRLB_REG 0x30b
  2755. @@ -60,41 +58,21 @@
  2756. #define OV8865_PLL_CTRLE_SYS_DIV(v) ((v) & GENMASK(2, 0))
  2757. #define OV8865_PLL_CTRLF_REG 0x30f
  2758. #define OV8865_PLL_CTRLF_SYS_PRE_DIV(v) (((v) - 1) & GENMASK(3, 0))
  2759. -#define OV8865_PLL_CTRL10_REG 0x310
  2760. -#define OV8865_PLL_CTRL11_REG 0x311
  2761. #define OV8865_PLL_CTRL12_REG 0x312
  2762. #define OV8865_PLL_CTRL12_PRE_DIV_HALF(v) ((((v) - 1) << 4) & BIT(4))
  2763. #define OV8865_PLL_CTRL12_DAC_DIV(v) (((v) - 1) & GENMASK(3, 0))
  2764. -#define OV8865_PLL_CTRL1B_REG 0x31b
  2765. -#define OV8865_PLL_CTRL1C_REG 0x31c
  2766. -
  2767. #define OV8865_PLL_CTRL1E_REG 0x31e
  2768. #define OV8865_PLL_CTRL1E_PLL1_NO_LAT BIT(3)
  2769. -#define OV8865_PAD_OEN0_REG 0x3000
  2770. -
  2771. -#define OV8865_PAD_OEN2_REG 0x3002
  2772. -
  2773. -#define OV8865_CLK_RST5_REG 0x3005
  2774. -
  2775. #define OV8865_CHIP_ID_HH_REG 0x300a
  2776. #define OV8865_CHIP_ID_HH_VALUE 0x00
  2777. #define OV8865_CHIP_ID_H_REG 0x300b
  2778. #define OV8865_CHIP_ID_H_VALUE 0x88
  2779. #define OV8865_CHIP_ID_L_REG 0x300c
  2780. #define OV8865_CHIP_ID_L_VALUE 0x65
  2781. -#define OV8865_PAD_OUT2_REG 0x300d
  2782. -
  2783. -#define OV8865_PAD_SEL2_REG 0x3010
  2784. -#define OV8865_PAD_PK_REG 0x3011
  2785. -#define OV8865_PAD_PK_DRIVE_STRENGTH_1X (0 << 5)
  2786. -#define OV8865_PAD_PK_DRIVE_STRENGTH_2X (1 << 5)
  2787. -#define OV8865_PAD_PK_DRIVE_STRENGTH_3X (2 << 5)
  2788. -#define OV8865_PAD_PK_DRIVE_STRENGTH_4X (3 << 5)
  2789. #define OV8865_PUMP_CLK_DIV_REG 0x3015
  2790. -#define OV8865_PUMP_CLK_DIV_PUMP_N(v) (((v) << 4) & GENMASK(6, 4))
  2791. #define OV8865_PUMP_CLK_DIV_PUMP_P(v) ((v) & GENMASK(2, 0))
  2792. #define OV8865_MIPI_SC_CTRL0_REG 0x3018
  2793. @@ -102,21 +80,12 @@
  2794. GENMASK(7, 5))
  2795. #define OV8865_MIPI_SC_CTRL0_MIPI_EN BIT(4)
  2796. #define OV8865_MIPI_SC_CTRL0_UNKNOWN BIT(1)
  2797. -#define OV8865_MIPI_SC_CTRL0_LANES_PD_MIPI BIT(0)
  2798. -#define OV8865_MIPI_SC_CTRL1_REG 0x3019
  2799. -#define OV8865_CLK_RST0_REG 0x301a
  2800. -#define OV8865_CLK_RST1_REG 0x301b
  2801. -#define OV8865_CLK_RST2_REG 0x301c
  2802. -#define OV8865_CLK_RST3_REG 0x301d
  2803. -#define OV8865_CLK_RST4_REG 0x301e
  2804. #define OV8865_PCLK_SEL_REG 0x3020
  2805. #define OV8865_PCLK_SEL_PCLK_DIV_MASK BIT(3)
  2806. #define OV8865_PCLK_SEL_PCLK_DIV(v) ((((v) - 1) << 3) & BIT(3))
  2807. -#define OV8865_MISC_CTRL_REG 0x3021
  2808. #define OV8865_MIPI_SC_CTRL2_REG 0x3022
  2809. -#define OV8865_MIPI_SC_CTRL2_CLK_LANES_PD_MIPI BIT(1)
  2810. #define OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC BIT(0)
  2811. #define OV8865_MIPI_BIT_SEL_REG 0x3031
  2812. @@ -125,7 +94,6 @@
  2813. #define OV8865_CLK_SEL0_PLL1_SYS_SEL(v) (((v) << 7) & BIT(7))
  2814. #define OV8865_CLK_SEL1_REG 0x3033
  2815. #define OV8865_CLK_SEL1_MIPI_EOF BIT(5)
  2816. -#define OV8865_CLK_SEL1_UNKNOWN BIT(2)
  2817. #define OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK BIT(1)
  2818. #define OV8865_CLK_SEL1_PLL_SCLK_SEL(v) (((v) << 1) & BIT(1))
  2819. @@ -142,7 +110,6 @@
  2820. #define OV8865_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2821. #define OV8865_EXPOSURE_CTRL_L_REG 0x3502
  2822. #define OV8865_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
  2823. -#define OV8865_EXPOSURE_GAIN_MANUAL_REG 0x3503
  2824. #define OV8865_GAIN_CTRL_H_REG 0x3508
  2825. #define OV8865_GAIN_CTRL_H(v) (((v) & GENMASK(12, 8)) >> 8)
  2826. @@ -197,18 +164,6 @@
  2827. #define OV8865_INC_X_ODD(v) ((v) & GENMASK(4, 0))
  2828. #define OV8865_INC_X_EVEN_REG 0x3815
  2829. #define OV8865_INC_X_EVEN(v) ((v) & GENMASK(4, 0))
  2830. -#define OV8865_VSYNC_START_H_REG 0x3816
  2831. -#define OV8865_VSYNC_START_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2832. -#define OV8865_VSYNC_START_L_REG 0x3817
  2833. -#define OV8865_VSYNC_START_L(v) ((v) & GENMASK(7, 0))
  2834. -#define OV8865_VSYNC_END_H_REG 0x3818
  2835. -#define OV8865_VSYNC_END_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2836. -#define OV8865_VSYNC_END_L_REG 0x3819
  2837. -#define OV8865_VSYNC_END_L(v) ((v) & GENMASK(7, 0))
  2838. -#define OV8865_HSYNC_FIRST_H_REG 0x381a
  2839. -#define OV8865_HSYNC_FIRST_H(v) (((v) & GENMASK(15, 8)) >> 8)
  2840. -#define OV8865_HSYNC_FIRST_L_REG 0x381b
  2841. -#define OV8865_HSYNC_FIRST_L(v) ((v) & GENMASK(7, 0))
  2842. #define OV8865_FORMAT1_REG 0x3820
  2843. #define OV8865_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
  2844. @@ -240,10 +195,6 @@
  2845. #define OV8865_AUTO_SIZE_CTRL_CROP_END_X_REG BIT(2)
  2846. #define OV8865_AUTO_SIZE_CTRL_CROP_START_Y_REG BIT(1)
  2847. #define OV8865_AUTO_SIZE_CTRL_CROP_START_X_REG BIT(0)
  2848. -#define OV8865_AUTO_SIZE_X_OFFSET_H_REG 0x3842
  2849. -#define OV8865_AUTO_SIZE_X_OFFSET_L_REG 0x3843
  2850. -#define OV8865_AUTO_SIZE_Y_OFFSET_H_REG 0x3844
  2851. -#define OV8865_AUTO_SIZE_Y_OFFSET_L_REG 0x3845
  2852. #define OV8865_AUTO_SIZE_BOUNDARIES_REG 0x3846
  2853. #define OV8865_AUTO_SIZE_BOUNDARIES_Y(v) (((v) << 4) & GENMASK(7, 4))
  2854. #define OV8865_AUTO_SIZE_BOUNDARIES_X(v) ((v) & GENMASK(3, 0))
  2855. @@ -259,30 +210,10 @@
  2856. #define OV8865_BLC_CTRL0_TRIG_FORMAT_EN BIT(6)
  2857. #define OV8865_BLC_CTRL0_TRIG_GAIN_EN BIT(5)
  2858. #define OV8865_BLC_CTRL0_TRIG_EXPOSURE_EN BIT(4)
  2859. -#define OV8865_BLC_CTRL0_TRIG_MANUAL_EN BIT(3)
  2860. -#define OV8865_BLC_CTRL0_FREEZE_EN BIT(2)
  2861. -#define OV8865_BLC_CTRL0_ALWAYS_EN BIT(1)
  2862. #define OV8865_BLC_CTRL0_FILTER_EN BIT(0)
  2863. #define OV8865_BLC_CTRL1_REG 0x4001
  2864. -#define OV8865_BLC_CTRL1_DITHER_EN BIT(7)
  2865. -#define OV8865_BLC_CTRL1_ZERO_LINE_DIFF_EN BIT(6)
  2866. -#define OV8865_BLC_CTRL1_COL_SHIFT_256 (0 << 4)
  2867. #define OV8865_BLC_CTRL1_COL_SHIFT_128 (1 << 4)
  2868. -#define OV8865_BLC_CTRL1_COL_SHIFT_64 (2 << 4)
  2869. -#define OV8865_BLC_CTRL1_COL_SHIFT_32 (3 << 4)
  2870. #define OV8865_BLC_CTRL1_OFFSET_LIMIT_EN BIT(2)
  2871. -#define OV8865_BLC_CTRL1_COLUMN_CANCEL_EN BIT(1)
  2872. -#define OV8865_BLC_CTRL2_REG 0x4002
  2873. -#define OV8865_BLC_CTRL3_REG 0x4003
  2874. -#define OV8865_BLC_CTRL4_REG 0x4004
  2875. -#define OV8865_BLC_CTRL5_REG 0x4005
  2876. -#define OV8865_BLC_CTRL6_REG 0x4006
  2877. -#define OV8865_BLC_CTRL7_REG 0x4007
  2878. -#define OV8865_BLC_CTRL8_REG 0x4008
  2879. -#define OV8865_BLC_CTRL9_REG 0x4009
  2880. -#define OV8865_BLC_CTRLA_REG 0x400a
  2881. -#define OV8865_BLC_CTRLB_REG 0x400b
  2882. -#define OV8865_BLC_CTRLC_REG 0x400c
  2883. #define OV8865_BLC_CTRLD_REG 0x400d
  2884. #define OV8865_BLC_CTRLD_OFFSET_TRIGGER(v) ((v) & GENMASK(7, 0))
  2885. @@ -337,66 +268,8 @@
  2886. /* MIPI */
  2887. -#define OV8865_MIPI_CTRL0_REG 0x4800
  2888. -#define OV8865_MIPI_CTRL1_REG 0x4801
  2889. -#define OV8865_MIPI_CTRL2_REG 0x4802
  2890. -#define OV8865_MIPI_CTRL3_REG 0x4803
  2891. -#define OV8865_MIPI_CTRL4_REG 0x4804
  2892. -#define OV8865_MIPI_CTRL5_REG 0x4805
  2893. -#define OV8865_MIPI_CTRL6_REG 0x4806
  2894. -#define OV8865_MIPI_CTRL7_REG 0x4807
  2895. -#define OV8865_MIPI_CTRL8_REG 0x4808
  2896. -
  2897. -#define OV8865_MIPI_FCNT_MAX_H_REG 0x4810
  2898. -#define OV8865_MIPI_FCNT_MAX_L_REG 0x4811
  2899. -
  2900. -#define OV8865_MIPI_CTRL13_REG 0x4813
  2901. -#define OV8865_MIPI_CTRL14_REG 0x4814
  2902. -#define OV8865_MIPI_CTRL15_REG 0x4815
  2903. -#define OV8865_MIPI_EMBEDDED_DT_REG 0x4816
  2904. -
  2905. -#define OV8865_MIPI_HS_ZERO_MIN_H_REG 0x4818
  2906. -#define OV8865_MIPI_HS_ZERO_MIN_L_REG 0x4819
  2907. -#define OV8865_MIPI_HS_TRAIL_MIN_H_REG 0x481a
  2908. -#define OV8865_MIPI_HS_TRAIL_MIN_L_REG 0x481b
  2909. -#define OV8865_MIPI_CLK_ZERO_MIN_H_REG 0x481c
  2910. -#define OV8865_MIPI_CLK_ZERO_MIN_L_REG 0x481d
  2911. -#define OV8865_MIPI_CLK_PREPARE_MAX_REG 0x481e
  2912. -#define OV8865_MIPI_CLK_PREPARE_MIN_REG 0x481f
  2913. -#define OV8865_MIPI_CLK_POST_MIN_H_REG 0x4820
  2914. -#define OV8865_MIPI_CLK_POST_MIN_L_REG 0x4821
  2915. -#define OV8865_MIPI_CLK_TRAIL_MIN_H_REG 0x4822
  2916. -#define OV8865_MIPI_CLK_TRAIL_MIN_L_REG 0x4823
  2917. -#define OV8865_MIPI_LPX_P_MIN_H_REG 0x4824
  2918. -#define OV8865_MIPI_LPX_P_MIN_L_REG 0x4825
  2919. -#define OV8865_MIPI_HS_PREPARE_MIN_REG 0x4826
  2920. -#define OV8865_MIPI_HS_PREPARE_MAX_REG 0x4827
  2921. -#define OV8865_MIPI_HS_EXIT_MIN_H_REG 0x4828
  2922. -#define OV8865_MIPI_HS_EXIT_MIN_L_REG 0x4829
  2923. -#define OV8865_MIPI_UI_HS_ZERO_MIN_REG 0x482a
  2924. -#define OV8865_MIPI_UI_HS_TRAIL_MIN_REG 0x482b
  2925. -#define OV8865_MIPI_UI_CLK_ZERO_MIN_REG 0x482c
  2926. -#define OV8865_MIPI_UI_CLK_PREPARE_REG 0x482d
  2927. -#define OV8865_MIPI_UI_CLK_POST_MIN_REG 0x482e
  2928. -#define OV8865_MIPI_UI_CLK_TRAIL_MIN_REG 0x482f
  2929. -#define OV8865_MIPI_UI_LPX_P_MIN_REG 0x4830
  2930. -#define OV8865_MIPI_UI_HS_PREPARE_REG 0x4831
  2931. -#define OV8865_MIPI_UI_HS_EXIT_MIN_REG 0x4832
  2932. -#define OV8865_MIPI_PKT_START_SIZE_REG 0x4833
  2933. -
  2934. #define OV8865_MIPI_PCLK_PERIOD_REG 0x4837
  2935. -#define OV8865_MIPI_LP_GPIO0_REG 0x4838
  2936. -#define OV8865_MIPI_LP_GPIO1_REG 0x4839
  2937. -
  2938. -#define OV8865_MIPI_CTRL3C_REG 0x483c
  2939. -#define OV8865_MIPI_LP_GPIO4_REG 0x483d
  2940. -
  2941. -#define OV8865_MIPI_CTRL4A_REG 0x484a
  2942. -#define OV8865_MIPI_CTRL4B_REG 0x484b
  2943. -#define OV8865_MIPI_CTRL4C_REG 0x484c
  2944. -#define OV8865_MIPI_LANE_TEST_PATTERN_REG 0x484d
  2945. -#define OV8865_MIPI_FRAME_END_DELAY_REG 0x484e
  2946. -#define OV8865_MIPI_CLOCK_TEST_PATTERN_REG 0x484f
  2947. +
  2948. #define OV8865_MIPI_LANE_SEL01_REG 0x4850
  2949. #define OV8865_MIPI_LANE_SEL01_LANE0(v) (((v) << 0) & GENMASK(2, 0))
  2950. #define OV8865_MIPI_LANE_SEL01_LANE1(v) (((v) << 4) & GENMASK(6, 4))
  2951. @@ -407,7 +280,6 @@
  2952. /* ISP */
  2953. #define OV8865_ISP_CTRL0_REG 0x5000
  2954. -#define OV8865_ISP_CTRL0_LENC_EN BIT(7)
  2955. #define OV8865_ISP_CTRL0_WHITE_BALANCE_EN BIT(4)
  2956. #define OV8865_ISP_CTRL0_DPC_BLACK_EN BIT(2)
  2957. #define OV8865_ISP_CTRL0_DPC_WHITE_EN BIT(1)
  2958. @@ -416,17 +288,11 @@
  2959. #define OV8865_ISP_CTRL2_REG 0x5002
  2960. #define OV8865_ISP_CTRL2_DEBUG BIT(3)
  2961. #define OV8865_ISP_CTRL2_VARIOPIXEL_EN BIT(2)
  2962. -#define OV8865_ISP_CTRL2_VSYNC_LATCH_EN BIT(0)
  2963. -#define OV8865_ISP_CTRL3_REG 0x5003
  2964. #define OV8865_ISP_GAIN_RED_H_REG 0x5018
  2965. #define OV8865_ISP_GAIN_RED_H(v) (((v) & GENMASK(13, 6)) >> 6)
  2966. #define OV8865_ISP_GAIN_RED_L_REG 0x5019
  2967. #define OV8865_ISP_GAIN_RED_L(v) ((v) & GENMASK(5, 0))
  2968. -#define OV8865_ISP_GAIN_GREEN_H_REG 0x501a
  2969. -#define OV8865_ISP_GAIN_GREEN_H(v) (((v) & GENMASK(13, 6)) >> 6)
  2970. -#define OV8865_ISP_GAIN_GREEN_L_REG 0x501b
  2971. -#define OV8865_ISP_GAIN_GREEN_L(v) ((v) & GENMASK(5, 0))
  2972. #define OV8865_ISP_GAIN_BLUE_H_REG 0x501c
  2973. #define OV8865_ISP_GAIN_BLUE_H(v) (((v) & GENMASK(13, 6)) >> 6)
  2974. #define OV8865_ISP_GAIN_BLUE_L_REG 0x501d
  2975. @@ -434,7 +300,6 @@
  2976. /* VarioPixel */
  2977. -#define OV8865_VAP_CTRL0_REG 0x5900
  2978. #define OV8865_VAP_CTRL1_REG 0x5901
  2979. #define OV8865_VAP_CTRL1_HSUB_COEF(v) ((((v) - 1) << 2) & \
  2980. GENMASK(3, 2))
  2981. --
  2982. 2.33.0
  2983. From 68e8a20981873f10e4b715d933d6afafc0ec4c9a Mon Sep 17 00:00:00 2001
  2984. From: Daniel Scally <djrscally@gmail.com>
  2985. Date: Fri, 16 Jul 2021 00:00:54 +0100
  2986. Subject: [PATCH] media: i2c: Switch exposure control unit to lines
  2987. The ov8865 driver currently has the unit of the V4L2_CID_EXPOSURE control
  2988. as 1/16th of a line. This is what the sensor expects, but isn't very
  2989. intuitive. Switch the control to be in units of a line and simply do the
  2990. 16x multiplication before passing the value to the sensor.
  2991. The datasheet for this sensor gives minimum exposure as 2 lines, so take
  2992. the opportunity to correct the lower bounds of the control.
  2993. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  2994. Patchset: cameras
  2995. ---
  2996. drivers/media/i2c/ov8865.c | 7 +++++--
  2997. 1 file changed, 5 insertions(+), 2 deletions(-)
  2998. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  2999. index fb81b822987d..27520c731e47 100644
  3000. --- a/drivers/media/i2c/ov8865.c
  3001. +++ b/drivers/media/i2c/ov8865.c
  3002. @@ -1991,6 +1991,9 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
  3003. {
  3004. int ret;
  3005. + /* The sensor stores exposure in units of 1/16th of a line */
  3006. + exposure *= 16;
  3007. +
  3008. ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
  3009. OV8865_EXPOSURE_CTRL_HH(exposure));
  3010. if (ret)
  3011. @@ -2389,8 +2392,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  3012. /* Exposure */
  3013. - ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
  3014. - 1048575, 16, 512);
  3015. + ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,
  3016. + 65535, 1, 32);
  3017. /* Gain */
  3018. --
  3019. 2.33.0
  3020. From fb522a944506adf314c74a2f206d99f37ef496b4 Mon Sep 17 00:00:00 2001
  3021. From: Daniel Scally <djrscally@gmail.com>
  3022. Date: Fri, 16 Jul 2021 22:56:15 +0100
  3023. Subject: [PATCH] media: i2c: Add controls from fwnode to ov8865
  3024. Add V4L2_CID_ORIENTATION and V4L2_CID_ROTATION controls to the ov8865
  3025. driver by attempting to parse them from firmware.
  3026. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  3027. Patchset: cameras
  3028. ---
  3029. drivers/media/i2c/ov8865.c | 10 ++++++++++
  3030. 1 file changed, 10 insertions(+)
  3031. diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
  3032. index 27520c731e47..f746917719ae 100644
  3033. --- a/drivers/media/i2c/ov8865.c
  3034. +++ b/drivers/media/i2c/ov8865.c
  3035. @@ -2381,6 +2381,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  3036. struct v4l2_ctrl_handler *handler = &ctrls->handler;
  3037. const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
  3038. const struct ov8865_mode *mode = sensor->state.mode;
  3039. + struct v4l2_fwnode_device_properties props;
  3040. unsigned int vblank_max, vblank_def;
  3041. unsigned int hblank;
  3042. int ret;
  3043. @@ -2443,6 +2444,15 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
  3044. v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,
  3045. INT_MAX, 1, 1);
  3046. + /* set properties from fwnode (e.g. rotation, orientation) */
  3047. + ret = v4l2_fwnode_device_parse(sensor->dev, &props);
  3048. + if (ret)
  3049. + goto error_ctrls;
  3050. +
  3051. + ret = v4l2_ctrl_new_fwnode_properties(handler, ops, &props);
  3052. + if (ret)
  3053. + goto error_ctrls;
  3054. +
  3055. if (handler->error) {
  3056. ret = handler->error;
  3057. goto error_ctrls;
  3058. --
  3059. 2.33.0
  3060. From 1d2217b6ac81a41279d11411bfe77196aec5cc84 Mon Sep 17 00:00:00 2001
  3061. From: Daniel Scally <djrscally@gmail.com>
  3062. Date: Wed, 14 Jul 2021 00:05:04 +0100
  3063. Subject: [PATCH] media: ipu3-cio2: Add INT347A to cio2-bridge
  3064. ACPI _HID INT347A represents the OV8865 sensor, the driver for which can
  3065. support the platforms that the cio2-bridge serves. Add it to the array
  3066. of supported sensors so the bridge will connect the sensor to the CIO2
  3067. device.
  3068. Signed-off-by: Daniel Scally <djrscally@gmail.com>
  3069. Patchset: cameras
  3070. ---
  3071. drivers/media/pci/intel/ipu3/cio2-bridge.c | 2 ++
  3072. 1 file changed, 2 insertions(+)
  3073. diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3074. index 7e582135dfb8..045b15498aca 100644
  3075. --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3076. +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
  3077. @@ -24,6 +24,8 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
  3078. CIO2_SENSOR_CONFIG("INT33BE", 0),
  3079. /* Omnivision OV2680 */
  3080. CIO2_SENSOR_CONFIG("OVTI2680", 0),
  3081. + /* Omnivision OV8865 */
  3082. + CIO2_SENSOR_CONFIG("INT347A", 1, 360000000),
  3083. };
  3084. static const struct cio2_property_names prop_names = {
  3085. --
  3086. 2.33.0