imx319.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 Intel Corporation
  3. #include <asm/unaligned.h>
  4. #include <linux/acpi.h>
  5. #include <linux/i2c.h>
  6. #include <linux/module.h>
  7. #include <linux/pm_runtime.h>
  8. #include <media/v4l2-ctrls.h>
  9. #include <media/v4l2-device.h>
  10. #include <media/v4l2-event.h>
  11. #include <media/v4l2-fwnode.h>
  12. #define IMX319_REG_MODE_SELECT 0x0100
  13. #define IMX319_MODE_STANDBY 0x00
  14. #define IMX319_MODE_STREAMING 0x01
  15. /* Chip ID */
  16. #define IMX319_REG_CHIP_ID 0x0016
  17. #define IMX319_CHIP_ID 0x0319
  18. /* V_TIMING internal */
  19. #define IMX319_REG_FLL 0x0340
  20. #define IMX319_FLL_MAX 0xffff
  21. /* Exposure control */
  22. #define IMX319_REG_EXPOSURE 0x0202
  23. #define IMX319_EXPOSURE_MIN 1
  24. #define IMX319_EXPOSURE_STEP 1
  25. #define IMX319_EXPOSURE_DEFAULT 0x04f6
  26. /*
  27. * the digital control register for all color control looks like:
  28. * +-----------------+------------------+
  29. * | [7:0] | [15:8] |
  30. * +-----------------+------------------+
  31. * | 0x020f | 0x020e |
  32. * --------------------------------------
  33. * it is used to calculate the digital gain times value(integral + fractional)
  34. * the [15:8] bits is the fractional part and [7:0] bits is the integral
  35. * calculation equation is:
  36. * gain value (unit: times) = REG[15:8] + REG[7:0]/0x100
  37. * Only value in 0x0100 ~ 0x0FFF range is allowed.
  38. * Analog gain use 10 bits in the registers and allowed range is 0 ~ 960
  39. */
  40. /* Analog gain control */
  41. #define IMX319_REG_ANALOG_GAIN 0x0204
  42. #define IMX319_ANA_GAIN_MIN 0
  43. #define IMX319_ANA_GAIN_MAX 960
  44. #define IMX319_ANA_GAIN_STEP 1
  45. #define IMX319_ANA_GAIN_DEFAULT 0
  46. /* Digital gain control */
  47. #define IMX319_REG_DPGA_USE_GLOBAL_GAIN 0x3ff9
  48. #define IMX319_REG_DIG_GAIN_GLOBAL 0x020e
  49. #define IMX319_DGTL_GAIN_MIN 256
  50. #define IMX319_DGTL_GAIN_MAX 4095
  51. #define IMX319_DGTL_GAIN_STEP 1
  52. #define IMX319_DGTL_GAIN_DEFAULT 256
  53. /* Test Pattern Control */
  54. #define IMX319_REG_TEST_PATTERN 0x0600
  55. #define IMX319_TEST_PATTERN_DISABLED 0
  56. #define IMX319_TEST_PATTERN_SOLID_COLOR 1
  57. #define IMX319_TEST_PATTERN_COLOR_BARS 2
  58. #define IMX319_TEST_PATTERN_GRAY_COLOR_BARS 3
  59. #define IMX319_TEST_PATTERN_PN9 4
  60. /* Flip Control */
  61. #define IMX319_REG_ORIENTATION 0x0101
  62. /* default link frequency and external clock */
  63. #define IMX319_LINK_FREQ_DEFAULT 482400000
  64. #define IMX319_EXT_CLK 19200000
  65. #define IMX319_LINK_FREQ_INDEX 0
  66. struct imx319_reg {
  67. u16 address;
  68. u8 val;
  69. };
  70. struct imx319_reg_list {
  71. u32 num_of_regs;
  72. const struct imx319_reg *regs;
  73. };
  74. /* Mode : resolution and related config&values */
  75. struct imx319_mode {
  76. /* Frame width */
  77. u32 width;
  78. /* Frame height */
  79. u32 height;
  80. /* V-timing */
  81. u32 fll_def;
  82. u32 fll_min;
  83. /* H-timing */
  84. u32 llp;
  85. /* index of link frequency */
  86. u32 link_freq_index;
  87. /* Default register values */
  88. struct imx319_reg_list reg_list;
  89. };
  90. struct imx319_hwcfg {
  91. u32 ext_clk; /* sensor external clk */
  92. s64 *link_freqs; /* CSI-2 link frequencies */
  93. unsigned int nr_of_link_freqs;
  94. };
  95. struct imx319 {
  96. struct v4l2_subdev sd;
  97. struct media_pad pad;
  98. struct v4l2_ctrl_handler ctrl_handler;
  99. /* V4L2 Controls */
  100. struct v4l2_ctrl *link_freq;
  101. struct v4l2_ctrl *pixel_rate;
  102. struct v4l2_ctrl *vblank;
  103. struct v4l2_ctrl *hblank;
  104. struct v4l2_ctrl *exposure;
  105. struct v4l2_ctrl *vflip;
  106. struct v4l2_ctrl *hflip;
  107. /* Current mode */
  108. const struct imx319_mode *cur_mode;
  109. struct imx319_hwcfg *hwcfg;
  110. s64 link_def_freq; /* CSI-2 link default frequency */
  111. /*
  112. * Mutex for serialized access:
  113. * Protect sensor set pad format and start/stop streaming safely.
  114. * Protect access to sensor v4l2 controls.
  115. */
  116. struct mutex mutex;
  117. /* Streaming on/off */
  118. bool streaming;
  119. /* True if the device has been identified */
  120. bool identified;
  121. };
  122. static const struct imx319_reg imx319_global_regs[] = {
  123. { 0x0136, 0x13 },
  124. { 0x0137, 0x33 },
  125. { 0x3c7e, 0x05 },
  126. { 0x3c7f, 0x07 },
  127. { 0x4d39, 0x0b },
  128. { 0x4d41, 0x33 },
  129. { 0x4d43, 0x0c },
  130. { 0x4d49, 0x89 },
  131. { 0x4e05, 0x0b },
  132. { 0x4e0d, 0x33 },
  133. { 0x4e0f, 0x0c },
  134. { 0x4e15, 0x89 },
  135. { 0x4e49, 0x2a },
  136. { 0x4e51, 0x33 },
  137. { 0x4e53, 0x0c },
  138. { 0x4e59, 0x89 },
  139. { 0x5601, 0x4f },
  140. { 0x560b, 0x45 },
  141. { 0x562f, 0x0a },
  142. { 0x5643, 0x0a },
  143. { 0x5645, 0x0c },
  144. { 0x56ef, 0x51 },
  145. { 0x586f, 0x33 },
  146. { 0x5873, 0x89 },
  147. { 0x5905, 0x33 },
  148. { 0x5907, 0x89 },
  149. { 0x590d, 0x33 },
  150. { 0x590f, 0x89 },
  151. { 0x5915, 0x33 },
  152. { 0x5917, 0x89 },
  153. { 0x5969, 0x1c },
  154. { 0x596b, 0x72 },
  155. { 0x5971, 0x33 },
  156. { 0x5973, 0x89 },
  157. { 0x5975, 0x33 },
  158. { 0x5977, 0x89 },
  159. { 0x5979, 0x1c },
  160. { 0x597b, 0x72 },
  161. { 0x5985, 0x33 },
  162. { 0x5987, 0x89 },
  163. { 0x5999, 0x1c },
  164. { 0x599b, 0x72 },
  165. { 0x59a5, 0x33 },
  166. { 0x59a7, 0x89 },
  167. { 0x7485, 0x08 },
  168. { 0x7487, 0x0c },
  169. { 0x7489, 0xc7 },
  170. { 0x748b, 0x8b },
  171. { 0x9004, 0x09 },
  172. { 0x9200, 0x6a },
  173. { 0x9201, 0x22 },
  174. { 0x9202, 0x6a },
  175. { 0x9203, 0x23 },
  176. { 0x9204, 0x5f },
  177. { 0x9205, 0x23 },
  178. { 0x9206, 0x5f },
  179. { 0x9207, 0x24 },
  180. { 0x9208, 0x5f },
  181. { 0x9209, 0x26 },
  182. { 0x920a, 0x5f },
  183. { 0x920b, 0x27 },
  184. { 0x920c, 0x5f },
  185. { 0x920d, 0x29 },
  186. { 0x920e, 0x5f },
  187. { 0x920f, 0x2a },
  188. { 0x9210, 0x5f },
  189. { 0x9211, 0x2c },
  190. { 0xbc22, 0x1a },
  191. { 0xf01f, 0x04 },
  192. { 0xf021, 0x03 },
  193. { 0xf023, 0x02 },
  194. { 0xf03d, 0x05 },
  195. { 0xf03f, 0x03 },
  196. { 0xf041, 0x02 },
  197. { 0xf0af, 0x04 },
  198. { 0xf0b1, 0x03 },
  199. { 0xf0b3, 0x02 },
  200. { 0xf0cd, 0x05 },
  201. { 0xf0cf, 0x03 },
  202. { 0xf0d1, 0x02 },
  203. { 0xf13f, 0x04 },
  204. { 0xf141, 0x03 },
  205. { 0xf143, 0x02 },
  206. { 0xf15d, 0x05 },
  207. { 0xf15f, 0x03 },
  208. { 0xf161, 0x02 },
  209. { 0xf1cf, 0x04 },
  210. { 0xf1d1, 0x03 },
  211. { 0xf1d3, 0x02 },
  212. { 0xf1ed, 0x05 },
  213. { 0xf1ef, 0x03 },
  214. { 0xf1f1, 0x02 },
  215. { 0xf287, 0x04 },
  216. { 0xf289, 0x03 },
  217. { 0xf28b, 0x02 },
  218. { 0xf2a5, 0x05 },
  219. { 0xf2a7, 0x03 },
  220. { 0xf2a9, 0x02 },
  221. { 0xf2b7, 0x04 },
  222. { 0xf2b9, 0x03 },
  223. { 0xf2bb, 0x02 },
  224. { 0xf2d5, 0x05 },
  225. { 0xf2d7, 0x03 },
  226. { 0xf2d9, 0x02 },
  227. };
  228. static const struct imx319_reg_list imx319_global_setting = {
  229. .num_of_regs = ARRAY_SIZE(imx319_global_regs),
  230. .regs = imx319_global_regs,
  231. };
  232. static const struct imx319_reg mode_3264x2448_regs[] = {
  233. { 0x0112, 0x0a },
  234. { 0x0113, 0x0a },
  235. { 0x0114, 0x03 },
  236. { 0x0342, 0x0f },
  237. { 0x0343, 0x80 },
  238. { 0x0340, 0x0c },
  239. { 0x0341, 0xaa },
  240. { 0x0344, 0x00 },
  241. { 0x0345, 0x00 },
  242. { 0x0346, 0x00 },
  243. { 0x0347, 0x00 },
  244. { 0x0348, 0x0c },
  245. { 0x0349, 0xcf },
  246. { 0x034a, 0x09 },
  247. { 0x034b, 0x9f },
  248. { 0x0220, 0x00 },
  249. { 0x0221, 0x11 },
  250. { 0x0381, 0x01 },
  251. { 0x0383, 0x01 },
  252. { 0x0385, 0x01 },
  253. { 0x0387, 0x01 },
  254. { 0x0900, 0x00 },
  255. { 0x0901, 0x11 },
  256. { 0x0902, 0x0a },
  257. { 0x3140, 0x02 },
  258. { 0x3141, 0x00 },
  259. { 0x3f0d, 0x0a },
  260. { 0x3f14, 0x01 },
  261. { 0x3f3c, 0x01 },
  262. { 0x3f4d, 0x01 },
  263. { 0x3f4c, 0x01 },
  264. { 0x4254, 0x7f },
  265. { 0x0401, 0x00 },
  266. { 0x0404, 0x00 },
  267. { 0x0405, 0x10 },
  268. { 0x0408, 0x00 },
  269. { 0x0409, 0x08 },
  270. { 0x040a, 0x00 },
  271. { 0x040b, 0x08 },
  272. { 0x040c, 0x0c },
  273. { 0x040d, 0xc0 },
  274. { 0x040e, 0x09 },
  275. { 0x040f, 0x90 },
  276. { 0x034c, 0x0c },
  277. { 0x034d, 0xc0 },
  278. { 0x034e, 0x09 },
  279. { 0x034f, 0x90 },
  280. { 0x3261, 0x00 },
  281. { 0x3264, 0x00 },
  282. { 0x3265, 0x10 },
  283. { 0x0301, 0x05 },
  284. { 0x0303, 0x04 },
  285. { 0x0305, 0x04 },
  286. { 0x0306, 0x01 },
  287. { 0x0307, 0x92 },
  288. { 0x0309, 0x0a },
  289. { 0x030b, 0x02 },
  290. { 0x030d, 0x02 },
  291. { 0x030e, 0x00 },
  292. { 0x030f, 0xfa },
  293. { 0x0310, 0x00 },
  294. { 0x0820, 0x0f },
  295. { 0x0821, 0x13 },
  296. { 0x0822, 0x33 },
  297. { 0x0823, 0x33 },
  298. { 0x3e20, 0x01 },
  299. { 0x3e37, 0x00 },
  300. { 0x3e3b, 0x01 },
  301. { 0x38a3, 0x01 },
  302. { 0x38a8, 0x00 },
  303. { 0x38a9, 0x00 },
  304. { 0x38aa, 0x00 },
  305. { 0x38ab, 0x00 },
  306. { 0x3234, 0x00 },
  307. { 0x3fc1, 0x00 },
  308. { 0x3235, 0x00 },
  309. { 0x3802, 0x00 },
  310. { 0x3143, 0x04 },
  311. { 0x360a, 0x00 },
  312. { 0x0b00, 0x00 },
  313. { 0x0106, 0x00 },
  314. { 0x0b05, 0x01 },
  315. { 0x0b06, 0x01 },
  316. { 0x3230, 0x00 },
  317. { 0x3602, 0x01 },
  318. { 0x3607, 0x01 },
  319. { 0x3c00, 0x00 },
  320. { 0x3c01, 0x48 },
  321. { 0x3c02, 0xc8 },
  322. { 0x3c03, 0xaa },
  323. { 0x3c04, 0x91 },
  324. { 0x3c05, 0x54 },
  325. { 0x3c06, 0x26 },
  326. { 0x3c07, 0x20 },
  327. { 0x3c08, 0x51 },
  328. { 0x3d80, 0x00 },
  329. { 0x3f50, 0x00 },
  330. { 0x3f56, 0x00 },
  331. { 0x3f57, 0x30 },
  332. { 0x3f78, 0x01 },
  333. { 0x3f79, 0x18 },
  334. { 0x3f7c, 0x00 },
  335. { 0x3f7d, 0x00 },
  336. { 0x3fba, 0x00 },
  337. { 0x3fbb, 0x00 },
  338. { 0xa081, 0x00 },
  339. { 0xe014, 0x00 },
  340. { 0x0202, 0x0a },
  341. { 0x0203, 0x7a },
  342. { 0x0224, 0x01 },
  343. { 0x0225, 0xf4 },
  344. { 0x0204, 0x00 },
  345. { 0x0205, 0x00 },
  346. { 0x0216, 0x00 },
  347. { 0x0217, 0x00 },
  348. { 0x020e, 0x01 },
  349. { 0x020f, 0x00 },
  350. { 0x0210, 0x01 },
  351. { 0x0211, 0x00 },
  352. { 0x0212, 0x01 },
  353. { 0x0213, 0x00 },
  354. { 0x0214, 0x01 },
  355. { 0x0215, 0x00 },
  356. { 0x0218, 0x01 },
  357. { 0x0219, 0x00 },
  358. { 0x3614, 0x00 },
  359. { 0x3616, 0x0d },
  360. { 0x3617, 0x56 },
  361. { 0xb612, 0x20 },
  362. { 0xb613, 0x20 },
  363. { 0xb614, 0x20 },
  364. { 0xb615, 0x20 },
  365. { 0xb616, 0x0a },
  366. { 0xb617, 0x0a },
  367. { 0xb618, 0x20 },
  368. { 0xb619, 0x20 },
  369. { 0xb61a, 0x20 },
  370. { 0xb61b, 0x20 },
  371. { 0xb61c, 0x0a },
  372. { 0xb61d, 0x0a },
  373. { 0xb666, 0x30 },
  374. { 0xb667, 0x30 },
  375. { 0xb668, 0x30 },
  376. { 0xb669, 0x30 },
  377. { 0xb66a, 0x14 },
  378. { 0xb66b, 0x14 },
  379. { 0xb66c, 0x20 },
  380. { 0xb66d, 0x20 },
  381. { 0xb66e, 0x20 },
  382. { 0xb66f, 0x20 },
  383. { 0xb670, 0x10 },
  384. { 0xb671, 0x10 },
  385. { 0x3237, 0x00 },
  386. { 0x3900, 0x00 },
  387. { 0x3901, 0x00 },
  388. { 0x3902, 0x00 },
  389. { 0x3904, 0x00 },
  390. { 0x3905, 0x00 },
  391. { 0x3906, 0x00 },
  392. { 0x3907, 0x00 },
  393. { 0x3908, 0x00 },
  394. { 0x3909, 0x00 },
  395. { 0x3912, 0x00 },
  396. { 0x3930, 0x00 },
  397. { 0x3931, 0x00 },
  398. { 0x3933, 0x00 },
  399. { 0x3934, 0x00 },
  400. { 0x3935, 0x00 },
  401. { 0x3936, 0x00 },
  402. { 0x3937, 0x00 },
  403. { 0x30ac, 0x00 },
  404. };
  405. static const struct imx319_reg mode_3280x2464_regs[] = {
  406. { 0x0112, 0x0a },
  407. { 0x0113, 0x0a },
  408. { 0x0114, 0x03 },
  409. { 0x0342, 0x0f },
  410. { 0x0343, 0x80 },
  411. { 0x0340, 0x0c },
  412. { 0x0341, 0xaa },
  413. { 0x0344, 0x00 },
  414. { 0x0345, 0x00 },
  415. { 0x0346, 0x00 },
  416. { 0x0347, 0x00 },
  417. { 0x0348, 0x0c },
  418. { 0x0349, 0xcf },
  419. { 0x034a, 0x09 },
  420. { 0x034b, 0x9f },
  421. { 0x0220, 0x00 },
  422. { 0x0221, 0x11 },
  423. { 0x0381, 0x01 },
  424. { 0x0383, 0x01 },
  425. { 0x0385, 0x01 },
  426. { 0x0387, 0x01 },
  427. { 0x0900, 0x00 },
  428. { 0x0901, 0x11 },
  429. { 0x0902, 0x0a },
  430. { 0x3140, 0x02 },
  431. { 0x3141, 0x00 },
  432. { 0x3f0d, 0x0a },
  433. { 0x3f14, 0x01 },
  434. { 0x3f3c, 0x01 },
  435. { 0x3f4d, 0x01 },
  436. { 0x3f4c, 0x01 },
  437. { 0x4254, 0x7f },
  438. { 0x0401, 0x00 },
  439. { 0x0404, 0x00 },
  440. { 0x0405, 0x10 },
  441. { 0x0408, 0x00 },
  442. { 0x0409, 0x00 },
  443. { 0x040a, 0x00 },
  444. { 0x040b, 0x00 },
  445. { 0x040c, 0x0c },
  446. { 0x040d, 0xd0 },
  447. { 0x040e, 0x09 },
  448. { 0x040f, 0xa0 },
  449. { 0x034c, 0x0c },
  450. { 0x034d, 0xd0 },
  451. { 0x034e, 0x09 },
  452. { 0x034f, 0xa0 },
  453. { 0x3261, 0x00 },
  454. { 0x3264, 0x00 },
  455. { 0x3265, 0x10 },
  456. { 0x0301, 0x05 },
  457. { 0x0303, 0x04 },
  458. { 0x0305, 0x04 },
  459. { 0x0306, 0x01 },
  460. { 0x0307, 0x92 },
  461. { 0x0309, 0x0a },
  462. { 0x030b, 0x02 },
  463. { 0x030d, 0x02 },
  464. { 0x030e, 0x00 },
  465. { 0x030f, 0xfa },
  466. { 0x0310, 0x00 },
  467. { 0x0820, 0x0f },
  468. { 0x0821, 0x13 },
  469. { 0x0822, 0x33 },
  470. { 0x0823, 0x33 },
  471. { 0x3e20, 0x01 },
  472. { 0x3e37, 0x00 },
  473. { 0x3e3b, 0x01 },
  474. { 0x38a3, 0x01 },
  475. { 0x38a8, 0x00 },
  476. { 0x38a9, 0x00 },
  477. { 0x38aa, 0x00 },
  478. { 0x38ab, 0x00 },
  479. { 0x3234, 0x00 },
  480. { 0x3fc1, 0x00 },
  481. { 0x3235, 0x00 },
  482. { 0x3802, 0x00 },
  483. { 0x3143, 0x04 },
  484. { 0x360a, 0x00 },
  485. { 0x0b00, 0x00 },
  486. { 0x0106, 0x00 },
  487. { 0x0b05, 0x01 },
  488. { 0x0b06, 0x01 },
  489. { 0x3230, 0x00 },
  490. { 0x3602, 0x01 },
  491. { 0x3607, 0x01 },
  492. { 0x3c00, 0x00 },
  493. { 0x3c01, 0x48 },
  494. { 0x3c02, 0xc8 },
  495. { 0x3c03, 0xaa },
  496. { 0x3c04, 0x91 },
  497. { 0x3c05, 0x54 },
  498. { 0x3c06, 0x26 },
  499. { 0x3c07, 0x20 },
  500. { 0x3c08, 0x51 },
  501. { 0x3d80, 0x00 },
  502. { 0x3f50, 0x00 },
  503. { 0x3f56, 0x00 },
  504. { 0x3f57, 0x30 },
  505. { 0x3f78, 0x01 },
  506. { 0x3f79, 0x18 },
  507. { 0x3f7c, 0x00 },
  508. { 0x3f7d, 0x00 },
  509. { 0x3fba, 0x00 },
  510. { 0x3fbb, 0x00 },
  511. { 0xa081, 0x00 },
  512. { 0xe014, 0x00 },
  513. { 0x0202, 0x0a },
  514. { 0x0203, 0x7a },
  515. { 0x0224, 0x01 },
  516. { 0x0225, 0xf4 },
  517. { 0x0204, 0x00 },
  518. { 0x0205, 0x00 },
  519. { 0x0216, 0x00 },
  520. { 0x0217, 0x00 },
  521. { 0x020e, 0x01 },
  522. { 0x020f, 0x00 },
  523. { 0x0210, 0x01 },
  524. { 0x0211, 0x00 },
  525. { 0x0212, 0x01 },
  526. { 0x0213, 0x00 },
  527. { 0x0214, 0x01 },
  528. { 0x0215, 0x00 },
  529. { 0x0218, 0x01 },
  530. { 0x0219, 0x00 },
  531. { 0x3614, 0x00 },
  532. { 0x3616, 0x0d },
  533. { 0x3617, 0x56 },
  534. { 0xb612, 0x20 },
  535. { 0xb613, 0x20 },
  536. { 0xb614, 0x20 },
  537. { 0xb615, 0x20 },
  538. { 0xb616, 0x0a },
  539. { 0xb617, 0x0a },
  540. { 0xb618, 0x20 },
  541. { 0xb619, 0x20 },
  542. { 0xb61a, 0x20 },
  543. { 0xb61b, 0x20 },
  544. { 0xb61c, 0x0a },
  545. { 0xb61d, 0x0a },
  546. { 0xb666, 0x30 },
  547. { 0xb667, 0x30 },
  548. { 0xb668, 0x30 },
  549. { 0xb669, 0x30 },
  550. { 0xb66a, 0x14 },
  551. { 0xb66b, 0x14 },
  552. { 0xb66c, 0x20 },
  553. { 0xb66d, 0x20 },
  554. { 0xb66e, 0x20 },
  555. { 0xb66f, 0x20 },
  556. { 0xb670, 0x10 },
  557. { 0xb671, 0x10 },
  558. { 0x3237, 0x00 },
  559. { 0x3900, 0x00 },
  560. { 0x3901, 0x00 },
  561. { 0x3902, 0x00 },
  562. { 0x3904, 0x00 },
  563. { 0x3905, 0x00 },
  564. { 0x3906, 0x00 },
  565. { 0x3907, 0x00 },
  566. { 0x3908, 0x00 },
  567. { 0x3909, 0x00 },
  568. { 0x3912, 0x00 },
  569. { 0x3930, 0x00 },
  570. { 0x3931, 0x00 },
  571. { 0x3933, 0x00 },
  572. { 0x3934, 0x00 },
  573. { 0x3935, 0x00 },
  574. { 0x3936, 0x00 },
  575. { 0x3937, 0x00 },
  576. { 0x30ac, 0x00 },
  577. };
  578. static const struct imx319_reg mode_1936x1096_regs[] = {
  579. { 0x0112, 0x0a },
  580. { 0x0113, 0x0a },
  581. { 0x0114, 0x03 },
  582. { 0x0342, 0x0f },
  583. { 0x0343, 0x80 },
  584. { 0x0340, 0x0c },
  585. { 0x0341, 0xaa },
  586. { 0x0344, 0x00 },
  587. { 0x0345, 0x00 },
  588. { 0x0346, 0x02 },
  589. { 0x0347, 0xac },
  590. { 0x0348, 0x0c },
  591. { 0x0349, 0xcf },
  592. { 0x034a, 0x06 },
  593. { 0x034b, 0xf3 },
  594. { 0x0220, 0x00 },
  595. { 0x0221, 0x11 },
  596. { 0x0381, 0x01 },
  597. { 0x0383, 0x01 },
  598. { 0x0385, 0x01 },
  599. { 0x0387, 0x01 },
  600. { 0x0900, 0x00 },
  601. { 0x0901, 0x11 },
  602. { 0x0902, 0x0a },
  603. { 0x3140, 0x02 },
  604. { 0x3141, 0x00 },
  605. { 0x3f0d, 0x0a },
  606. { 0x3f14, 0x01 },
  607. { 0x3f3c, 0x01 },
  608. { 0x3f4d, 0x01 },
  609. { 0x3f4c, 0x01 },
  610. { 0x4254, 0x7f },
  611. { 0x0401, 0x00 },
  612. { 0x0404, 0x00 },
  613. { 0x0405, 0x10 },
  614. { 0x0408, 0x02 },
  615. { 0x0409, 0xa0 },
  616. { 0x040a, 0x00 },
  617. { 0x040b, 0x00 },
  618. { 0x040c, 0x07 },
  619. { 0x040d, 0x90 },
  620. { 0x040e, 0x04 },
  621. { 0x040f, 0x48 },
  622. { 0x034c, 0x07 },
  623. { 0x034d, 0x90 },
  624. { 0x034e, 0x04 },
  625. { 0x034f, 0x48 },
  626. { 0x3261, 0x00 },
  627. { 0x3264, 0x00 },
  628. { 0x3265, 0x10 },
  629. { 0x0301, 0x05 },
  630. { 0x0303, 0x04 },
  631. { 0x0305, 0x04 },
  632. { 0x0306, 0x01 },
  633. { 0x0307, 0x92 },
  634. { 0x0309, 0x0a },
  635. { 0x030b, 0x02 },
  636. { 0x030d, 0x02 },
  637. { 0x030e, 0x00 },
  638. { 0x030f, 0xfa },
  639. { 0x0310, 0x00 },
  640. { 0x0820, 0x0f },
  641. { 0x0821, 0x13 },
  642. { 0x0822, 0x33 },
  643. { 0x0823, 0x33 },
  644. { 0x3e20, 0x01 },
  645. { 0x3e37, 0x00 },
  646. { 0x3e3b, 0x01 },
  647. { 0x38a3, 0x01 },
  648. { 0x38a8, 0x00 },
  649. { 0x38a9, 0x00 },
  650. { 0x38aa, 0x00 },
  651. { 0x38ab, 0x00 },
  652. { 0x3234, 0x00 },
  653. { 0x3fc1, 0x00 },
  654. { 0x3235, 0x00 },
  655. { 0x3802, 0x00 },
  656. { 0x3143, 0x04 },
  657. { 0x360a, 0x00 },
  658. { 0x0b00, 0x00 },
  659. { 0x0106, 0x00 },
  660. { 0x0b05, 0x01 },
  661. { 0x0b06, 0x01 },
  662. { 0x3230, 0x00 },
  663. { 0x3602, 0x01 },
  664. { 0x3607, 0x01 },
  665. { 0x3c00, 0x00 },
  666. { 0x3c01, 0x48 },
  667. { 0x3c02, 0xc8 },
  668. { 0x3c03, 0xaa },
  669. { 0x3c04, 0x91 },
  670. { 0x3c05, 0x54 },
  671. { 0x3c06, 0x26 },
  672. { 0x3c07, 0x20 },
  673. { 0x3c08, 0x51 },
  674. { 0x3d80, 0x00 },
  675. { 0x3f50, 0x00 },
  676. { 0x3f56, 0x00 },
  677. { 0x3f57, 0x30 },
  678. { 0x3f78, 0x01 },
  679. { 0x3f79, 0x18 },
  680. { 0x3f7c, 0x00 },
  681. { 0x3f7d, 0x00 },
  682. { 0x3fba, 0x00 },
  683. { 0x3fbb, 0x00 },
  684. { 0xa081, 0x00 },
  685. { 0xe014, 0x00 },
  686. { 0x0202, 0x05 },
  687. { 0x0203, 0x34 },
  688. { 0x0224, 0x01 },
  689. { 0x0225, 0xf4 },
  690. { 0x0204, 0x00 },
  691. { 0x0205, 0x00 },
  692. { 0x0216, 0x00 },
  693. { 0x0217, 0x00 },
  694. { 0x020e, 0x01 },
  695. { 0x020f, 0x00 },
  696. { 0x0210, 0x01 },
  697. { 0x0211, 0x00 },
  698. { 0x0212, 0x01 },
  699. { 0x0213, 0x00 },
  700. { 0x0214, 0x01 },
  701. { 0x0215, 0x00 },
  702. { 0x0218, 0x01 },
  703. { 0x0219, 0x00 },
  704. { 0x3614, 0x00 },
  705. { 0x3616, 0x0d },
  706. { 0x3617, 0x56 },
  707. { 0xb612, 0x20 },
  708. { 0xb613, 0x20 },
  709. { 0xb614, 0x20 },
  710. { 0xb615, 0x20 },
  711. { 0xb616, 0x0a },
  712. { 0xb617, 0x0a },
  713. { 0xb618, 0x20 },
  714. { 0xb619, 0x20 },
  715. { 0xb61a, 0x20 },
  716. { 0xb61b, 0x20 },
  717. { 0xb61c, 0x0a },
  718. { 0xb61d, 0x0a },
  719. { 0xb666, 0x30 },
  720. { 0xb667, 0x30 },
  721. { 0xb668, 0x30 },
  722. { 0xb669, 0x30 },
  723. { 0xb66a, 0x14 },
  724. { 0xb66b, 0x14 },
  725. { 0xb66c, 0x20 },
  726. { 0xb66d, 0x20 },
  727. { 0xb66e, 0x20 },
  728. { 0xb66f, 0x20 },
  729. { 0xb670, 0x10 },
  730. { 0xb671, 0x10 },
  731. { 0x3237, 0x00 },
  732. { 0x3900, 0x00 },
  733. { 0x3901, 0x00 },
  734. { 0x3902, 0x00 },
  735. { 0x3904, 0x00 },
  736. { 0x3905, 0x00 },
  737. { 0x3906, 0x00 },
  738. { 0x3907, 0x00 },
  739. { 0x3908, 0x00 },
  740. { 0x3909, 0x00 },
  741. { 0x3912, 0x00 },
  742. { 0x3930, 0x00 },
  743. { 0x3931, 0x00 },
  744. { 0x3933, 0x00 },
  745. { 0x3934, 0x00 },
  746. { 0x3935, 0x00 },
  747. { 0x3936, 0x00 },
  748. { 0x3937, 0x00 },
  749. { 0x30ac, 0x00 },
  750. };
  751. static const struct imx319_reg mode_1920x1080_regs[] = {
  752. { 0x0112, 0x0a },
  753. { 0x0113, 0x0a },
  754. { 0x0114, 0x03 },
  755. { 0x0342, 0x0f },
  756. { 0x0343, 0x80 },
  757. { 0x0340, 0x0c },
  758. { 0x0341, 0xaa },
  759. { 0x0344, 0x00 },
  760. { 0x0345, 0x00 },
  761. { 0x0346, 0x02 },
  762. { 0x0347, 0xb4 },
  763. { 0x0348, 0x0c },
  764. { 0x0349, 0xcf },
  765. { 0x034a, 0x06 },
  766. { 0x034b, 0xeb },
  767. { 0x0220, 0x00 },
  768. { 0x0221, 0x11 },
  769. { 0x0381, 0x01 },
  770. { 0x0383, 0x01 },
  771. { 0x0385, 0x01 },
  772. { 0x0387, 0x01 },
  773. { 0x0900, 0x00 },
  774. { 0x0901, 0x11 },
  775. { 0x0902, 0x0a },
  776. { 0x3140, 0x02 },
  777. { 0x3141, 0x00 },
  778. { 0x3f0d, 0x0a },
  779. { 0x3f14, 0x01 },
  780. { 0x3f3c, 0x01 },
  781. { 0x3f4d, 0x01 },
  782. { 0x3f4c, 0x01 },
  783. { 0x4254, 0x7f },
  784. { 0x0401, 0x00 },
  785. { 0x0404, 0x00 },
  786. { 0x0405, 0x10 },
  787. { 0x0408, 0x02 },
  788. { 0x0409, 0xa8 },
  789. { 0x040a, 0x00 },
  790. { 0x040b, 0x00 },
  791. { 0x040c, 0x07 },
  792. { 0x040d, 0x80 },
  793. { 0x040e, 0x04 },
  794. { 0x040f, 0x38 },
  795. { 0x034c, 0x07 },
  796. { 0x034d, 0x80 },
  797. { 0x034e, 0x04 },
  798. { 0x034f, 0x38 },
  799. { 0x3261, 0x00 },
  800. { 0x3264, 0x00 },
  801. { 0x3265, 0x10 },
  802. { 0x0301, 0x05 },
  803. { 0x0303, 0x04 },
  804. { 0x0305, 0x04 },
  805. { 0x0306, 0x01 },
  806. { 0x0307, 0x92 },
  807. { 0x0309, 0x0a },
  808. { 0x030b, 0x02 },
  809. { 0x030d, 0x02 },
  810. { 0x030e, 0x00 },
  811. { 0x030f, 0xfa },
  812. { 0x0310, 0x00 },
  813. { 0x0820, 0x0f },
  814. { 0x0821, 0x13 },
  815. { 0x0822, 0x33 },
  816. { 0x0823, 0x33 },
  817. { 0x3e20, 0x01 },
  818. { 0x3e37, 0x00 },
  819. { 0x3e3b, 0x01 },
  820. { 0x38a3, 0x01 },
  821. { 0x38a8, 0x00 },
  822. { 0x38a9, 0x00 },
  823. { 0x38aa, 0x00 },
  824. { 0x38ab, 0x00 },
  825. { 0x3234, 0x00 },
  826. { 0x3fc1, 0x00 },
  827. { 0x3235, 0x00 },
  828. { 0x3802, 0x00 },
  829. { 0x3143, 0x04 },
  830. { 0x360a, 0x00 },
  831. { 0x0b00, 0x00 },
  832. { 0x0106, 0x00 },
  833. { 0x0b05, 0x01 },
  834. { 0x0b06, 0x01 },
  835. { 0x3230, 0x00 },
  836. { 0x3602, 0x01 },
  837. { 0x3607, 0x01 },
  838. { 0x3c00, 0x00 },
  839. { 0x3c01, 0x48 },
  840. { 0x3c02, 0xc8 },
  841. { 0x3c03, 0xaa },
  842. { 0x3c04, 0x91 },
  843. { 0x3c05, 0x54 },
  844. { 0x3c06, 0x26 },
  845. { 0x3c07, 0x20 },
  846. { 0x3c08, 0x51 },
  847. { 0x3d80, 0x00 },
  848. { 0x3f50, 0x00 },
  849. { 0x3f56, 0x00 },
  850. { 0x3f57, 0x30 },
  851. { 0x3f78, 0x01 },
  852. { 0x3f79, 0x18 },
  853. { 0x3f7c, 0x00 },
  854. { 0x3f7d, 0x00 },
  855. { 0x3fba, 0x00 },
  856. { 0x3fbb, 0x00 },
  857. { 0xa081, 0x00 },
  858. { 0xe014, 0x00 },
  859. { 0x0202, 0x05 },
  860. { 0x0203, 0x34 },
  861. { 0x0224, 0x01 },
  862. { 0x0225, 0xf4 },
  863. { 0x0204, 0x00 },
  864. { 0x0205, 0x00 },
  865. { 0x0216, 0x00 },
  866. { 0x0217, 0x00 },
  867. { 0x020e, 0x01 },
  868. { 0x020f, 0x00 },
  869. { 0x0210, 0x01 },
  870. { 0x0211, 0x00 },
  871. { 0x0212, 0x01 },
  872. { 0x0213, 0x00 },
  873. { 0x0214, 0x01 },
  874. { 0x0215, 0x00 },
  875. { 0x0218, 0x01 },
  876. { 0x0219, 0x00 },
  877. { 0x3614, 0x00 },
  878. { 0x3616, 0x0d },
  879. { 0x3617, 0x56 },
  880. { 0xb612, 0x20 },
  881. { 0xb613, 0x20 },
  882. { 0xb614, 0x20 },
  883. { 0xb615, 0x20 },
  884. { 0xb616, 0x0a },
  885. { 0xb617, 0x0a },
  886. { 0xb618, 0x20 },
  887. { 0xb619, 0x20 },
  888. { 0xb61a, 0x20 },
  889. { 0xb61b, 0x20 },
  890. { 0xb61c, 0x0a },
  891. { 0xb61d, 0x0a },
  892. { 0xb666, 0x30 },
  893. { 0xb667, 0x30 },
  894. { 0xb668, 0x30 },
  895. { 0xb669, 0x30 },
  896. { 0xb66a, 0x14 },
  897. { 0xb66b, 0x14 },
  898. { 0xb66c, 0x20 },
  899. { 0xb66d, 0x20 },
  900. { 0xb66e, 0x20 },
  901. { 0xb66f, 0x20 },
  902. { 0xb670, 0x10 },
  903. { 0xb671, 0x10 },
  904. { 0x3237, 0x00 },
  905. { 0x3900, 0x00 },
  906. { 0x3901, 0x00 },
  907. { 0x3902, 0x00 },
  908. { 0x3904, 0x00 },
  909. { 0x3905, 0x00 },
  910. { 0x3906, 0x00 },
  911. { 0x3907, 0x00 },
  912. { 0x3908, 0x00 },
  913. { 0x3909, 0x00 },
  914. { 0x3912, 0x00 },
  915. { 0x3930, 0x00 },
  916. { 0x3931, 0x00 },
  917. { 0x3933, 0x00 },
  918. { 0x3934, 0x00 },
  919. { 0x3935, 0x00 },
  920. { 0x3936, 0x00 },
  921. { 0x3937, 0x00 },
  922. { 0x30ac, 0x00 },
  923. };
  924. static const struct imx319_reg mode_1640x1232_regs[] = {
  925. { 0x0112, 0x0a },
  926. { 0x0113, 0x0a },
  927. { 0x0114, 0x03 },
  928. { 0x0342, 0x08 },
  929. { 0x0343, 0x20 },
  930. { 0x0340, 0x18 },
  931. { 0x0341, 0x2a },
  932. { 0x0344, 0x00 },
  933. { 0x0345, 0x00 },
  934. { 0x0346, 0x00 },
  935. { 0x0347, 0x00 },
  936. { 0x0348, 0x0c },
  937. { 0x0349, 0xcf },
  938. { 0x034a, 0x09 },
  939. { 0x034b, 0x9f },
  940. { 0x0220, 0x00 },
  941. { 0x0221, 0x11 },
  942. { 0x0381, 0x01 },
  943. { 0x0383, 0x01 },
  944. { 0x0385, 0x01 },
  945. { 0x0387, 0x01 },
  946. { 0x0900, 0x01 },
  947. { 0x0901, 0x22 },
  948. { 0x0902, 0x0a },
  949. { 0x3140, 0x02 },
  950. { 0x3141, 0x00 },
  951. { 0x3f0d, 0x0a },
  952. { 0x3f14, 0x01 },
  953. { 0x3f3c, 0x02 },
  954. { 0x3f4d, 0x01 },
  955. { 0x3f4c, 0x01 },
  956. { 0x4254, 0x7f },
  957. { 0x0401, 0x00 },
  958. { 0x0404, 0x00 },
  959. { 0x0405, 0x10 },
  960. { 0x0408, 0x00 },
  961. { 0x0409, 0x00 },
  962. { 0x040a, 0x00 },
  963. { 0x040b, 0x00 },
  964. { 0x040c, 0x06 },
  965. { 0x040d, 0x68 },
  966. { 0x040e, 0x04 },
  967. { 0x040f, 0xd0 },
  968. { 0x034c, 0x06 },
  969. { 0x034d, 0x68 },
  970. { 0x034e, 0x04 },
  971. { 0x034f, 0xd0 },
  972. { 0x3261, 0x00 },
  973. { 0x3264, 0x00 },
  974. { 0x3265, 0x10 },
  975. { 0x0301, 0x05 },
  976. { 0x0303, 0x04 },
  977. { 0x0305, 0x04 },
  978. { 0x0306, 0x01 },
  979. { 0x0307, 0x92 },
  980. { 0x0309, 0x0a },
  981. { 0x030b, 0x02 },
  982. { 0x030d, 0x02 },
  983. { 0x030e, 0x00 },
  984. { 0x030f, 0xfa },
  985. { 0x0310, 0x00 },
  986. { 0x0820, 0x0f },
  987. { 0x0821, 0x13 },
  988. { 0x0822, 0x33 },
  989. { 0x0823, 0x33 },
  990. { 0x3e20, 0x01 },
  991. { 0x3e37, 0x00 },
  992. { 0x3e3b, 0x01 },
  993. { 0x38a3, 0x01 },
  994. { 0x38a8, 0x00 },
  995. { 0x38a9, 0x00 },
  996. { 0x38aa, 0x00 },
  997. { 0x38ab, 0x00 },
  998. { 0x3234, 0x00 },
  999. { 0x3fc1, 0x00 },
  1000. { 0x3235, 0x00 },
  1001. { 0x3802, 0x00 },
  1002. { 0x3143, 0x04 },
  1003. { 0x360a, 0x00 },
  1004. { 0x0b00, 0x00 },
  1005. { 0x0106, 0x00 },
  1006. { 0x0b05, 0x01 },
  1007. { 0x0b06, 0x01 },
  1008. { 0x3230, 0x00 },
  1009. { 0x3602, 0x01 },
  1010. { 0x3607, 0x01 },
  1011. { 0x3c00, 0x00 },
  1012. { 0x3c01, 0xba },
  1013. { 0x3c02, 0xc8 },
  1014. { 0x3c03, 0xaa },
  1015. { 0x3c04, 0x91 },
  1016. { 0x3c05, 0x54 },
  1017. { 0x3c06, 0x26 },
  1018. { 0x3c07, 0x20 },
  1019. { 0x3c08, 0x51 },
  1020. { 0x3d80, 0x00 },
  1021. { 0x3f50, 0x00 },
  1022. { 0x3f56, 0x00 },
  1023. { 0x3f57, 0x30 },
  1024. { 0x3f78, 0x00 },
  1025. { 0x3f79, 0x34 },
  1026. { 0x3f7c, 0x00 },
  1027. { 0x3f7d, 0x00 },
  1028. { 0x3fba, 0x00 },
  1029. { 0x3fbb, 0x00 },
  1030. { 0xa081, 0x04 },
  1031. { 0xe014, 0x00 },
  1032. { 0x0202, 0x04 },
  1033. { 0x0203, 0xf6 },
  1034. { 0x0224, 0x01 },
  1035. { 0x0225, 0xf4 },
  1036. { 0x0204, 0x00 },
  1037. { 0x0205, 0x00 },
  1038. { 0x0216, 0x00 },
  1039. { 0x0217, 0x00 },
  1040. { 0x020e, 0x01 },
  1041. { 0x020f, 0x00 },
  1042. { 0x0210, 0x01 },
  1043. { 0x0211, 0x00 },
  1044. { 0x0212, 0x01 },
  1045. { 0x0213, 0x00 },
  1046. { 0x0214, 0x01 },
  1047. { 0x0215, 0x00 },
  1048. { 0x0218, 0x01 },
  1049. { 0x0219, 0x00 },
  1050. { 0x3614, 0x00 },
  1051. { 0x3616, 0x0d },
  1052. { 0x3617, 0x56 },
  1053. { 0xb612, 0x20 },
  1054. { 0xb613, 0x20 },
  1055. { 0xb614, 0x20 },
  1056. { 0xb615, 0x20 },
  1057. { 0xb616, 0x0a },
  1058. { 0xb617, 0x0a },
  1059. { 0xb618, 0x20 },
  1060. { 0xb619, 0x20 },
  1061. { 0xb61a, 0x20 },
  1062. { 0xb61b, 0x20 },
  1063. { 0xb61c, 0x0a },
  1064. { 0xb61d, 0x0a },
  1065. { 0xb666, 0x30 },
  1066. { 0xb667, 0x30 },
  1067. { 0xb668, 0x30 },
  1068. { 0xb669, 0x30 },
  1069. { 0xb66a, 0x14 },
  1070. { 0xb66b, 0x14 },
  1071. { 0xb66c, 0x20 },
  1072. { 0xb66d, 0x20 },
  1073. { 0xb66e, 0x20 },
  1074. { 0xb66f, 0x20 },
  1075. { 0xb670, 0x10 },
  1076. { 0xb671, 0x10 },
  1077. { 0x3237, 0x00 },
  1078. { 0x3900, 0x00 },
  1079. { 0x3901, 0x00 },
  1080. { 0x3902, 0x00 },
  1081. { 0x3904, 0x00 },
  1082. { 0x3905, 0x00 },
  1083. { 0x3906, 0x00 },
  1084. { 0x3907, 0x00 },
  1085. { 0x3908, 0x00 },
  1086. { 0x3909, 0x00 },
  1087. { 0x3912, 0x00 },
  1088. { 0x3930, 0x00 },
  1089. { 0x3931, 0x00 },
  1090. { 0x3933, 0x00 },
  1091. { 0x3934, 0x00 },
  1092. { 0x3935, 0x00 },
  1093. { 0x3936, 0x00 },
  1094. { 0x3937, 0x00 },
  1095. { 0x30ac, 0x00 },
  1096. };
  1097. static const struct imx319_reg mode_1640x922_regs[] = {
  1098. { 0x0112, 0x0a },
  1099. { 0x0113, 0x0a },
  1100. { 0x0114, 0x03 },
  1101. { 0x0342, 0x08 },
  1102. { 0x0343, 0x20 },
  1103. { 0x0340, 0x18 },
  1104. { 0x0341, 0x2a },
  1105. { 0x0344, 0x00 },
  1106. { 0x0345, 0x00 },
  1107. { 0x0346, 0x01 },
  1108. { 0x0347, 0x30 },
  1109. { 0x0348, 0x0c },
  1110. { 0x0349, 0xcf },
  1111. { 0x034a, 0x08 },
  1112. { 0x034b, 0x6f },
  1113. { 0x0220, 0x00 },
  1114. { 0x0221, 0x11 },
  1115. { 0x0381, 0x01 },
  1116. { 0x0383, 0x01 },
  1117. { 0x0385, 0x01 },
  1118. { 0x0387, 0x01 },
  1119. { 0x0900, 0x01 },
  1120. { 0x0901, 0x22 },
  1121. { 0x0902, 0x0a },
  1122. { 0x3140, 0x02 },
  1123. { 0x3141, 0x00 },
  1124. { 0x3f0d, 0x0a },
  1125. { 0x3f14, 0x01 },
  1126. { 0x3f3c, 0x02 },
  1127. { 0x3f4d, 0x01 },
  1128. { 0x3f4c, 0x01 },
  1129. { 0x4254, 0x7f },
  1130. { 0x0401, 0x00 },
  1131. { 0x0404, 0x00 },
  1132. { 0x0405, 0x10 },
  1133. { 0x0408, 0x00 },
  1134. { 0x0409, 0x00 },
  1135. { 0x040a, 0x00 },
  1136. { 0x040b, 0x02 },
  1137. { 0x040c, 0x06 },
  1138. { 0x040d, 0x68 },
  1139. { 0x040e, 0x03 },
  1140. { 0x040f, 0x9a },
  1141. { 0x034c, 0x06 },
  1142. { 0x034d, 0x68 },
  1143. { 0x034e, 0x03 },
  1144. { 0x034f, 0x9a },
  1145. { 0x3261, 0x00 },
  1146. { 0x3264, 0x00 },
  1147. { 0x3265, 0x10 },
  1148. { 0x0301, 0x05 },
  1149. { 0x0303, 0x04 },
  1150. { 0x0305, 0x04 },
  1151. { 0x0306, 0x01 },
  1152. { 0x0307, 0x92 },
  1153. { 0x0309, 0x0a },
  1154. { 0x030b, 0x02 },
  1155. { 0x030d, 0x02 },
  1156. { 0x030e, 0x00 },
  1157. { 0x030f, 0xfa },
  1158. { 0x0310, 0x00 },
  1159. { 0x0820, 0x0f },
  1160. { 0x0821, 0x13 },
  1161. { 0x0822, 0x33 },
  1162. { 0x0823, 0x33 },
  1163. { 0x3e20, 0x01 },
  1164. { 0x3e37, 0x00 },
  1165. { 0x3e3b, 0x01 },
  1166. { 0x38a3, 0x01 },
  1167. { 0x38a8, 0x00 },
  1168. { 0x38a9, 0x00 },
  1169. { 0x38aa, 0x00 },
  1170. { 0x38ab, 0x00 },
  1171. { 0x3234, 0x00 },
  1172. { 0x3fc1, 0x00 },
  1173. { 0x3235, 0x00 },
  1174. { 0x3802, 0x00 },
  1175. { 0x3143, 0x04 },
  1176. { 0x360a, 0x00 },
  1177. { 0x0b00, 0x00 },
  1178. { 0x0106, 0x00 },
  1179. { 0x0b05, 0x01 },
  1180. { 0x0b06, 0x01 },
  1181. { 0x3230, 0x00 },
  1182. { 0x3602, 0x01 },
  1183. { 0x3607, 0x01 },
  1184. { 0x3c00, 0x00 },
  1185. { 0x3c01, 0xba },
  1186. { 0x3c02, 0xc8 },
  1187. { 0x3c03, 0xaa },
  1188. { 0x3c04, 0x91 },
  1189. { 0x3c05, 0x54 },
  1190. { 0x3c06, 0x26 },
  1191. { 0x3c07, 0x20 },
  1192. { 0x3c08, 0x51 },
  1193. { 0x3d80, 0x00 },
  1194. { 0x3f50, 0x00 },
  1195. { 0x3f56, 0x00 },
  1196. { 0x3f57, 0x30 },
  1197. { 0x3f78, 0x00 },
  1198. { 0x3f79, 0x34 },
  1199. { 0x3f7c, 0x00 },
  1200. { 0x3f7d, 0x00 },
  1201. { 0x3fba, 0x00 },
  1202. { 0x3fbb, 0x00 },
  1203. { 0xa081, 0x04 },
  1204. { 0xe014, 0x00 },
  1205. { 0x0202, 0x04 },
  1206. { 0x0203, 0xf6 },
  1207. { 0x0224, 0x01 },
  1208. { 0x0225, 0xf4 },
  1209. { 0x0204, 0x00 },
  1210. { 0x0205, 0x00 },
  1211. { 0x0216, 0x00 },
  1212. { 0x0217, 0x00 },
  1213. { 0x020e, 0x01 },
  1214. { 0x020f, 0x00 },
  1215. { 0x0210, 0x01 },
  1216. { 0x0211, 0x00 },
  1217. { 0x0212, 0x01 },
  1218. { 0x0213, 0x00 },
  1219. { 0x0214, 0x01 },
  1220. { 0x0215, 0x00 },
  1221. { 0x0218, 0x01 },
  1222. { 0x0219, 0x00 },
  1223. { 0x3614, 0x00 },
  1224. { 0x3616, 0x0d },
  1225. { 0x3617, 0x56 },
  1226. { 0xb612, 0x20 },
  1227. { 0xb613, 0x20 },
  1228. { 0xb614, 0x20 },
  1229. { 0xb615, 0x20 },
  1230. { 0xb616, 0x0a },
  1231. { 0xb617, 0x0a },
  1232. { 0xb618, 0x20 },
  1233. { 0xb619, 0x20 },
  1234. { 0xb61a, 0x20 },
  1235. { 0xb61b, 0x20 },
  1236. { 0xb61c, 0x0a },
  1237. { 0xb61d, 0x0a },
  1238. { 0xb666, 0x30 },
  1239. { 0xb667, 0x30 },
  1240. { 0xb668, 0x30 },
  1241. { 0xb669, 0x30 },
  1242. { 0xb66a, 0x14 },
  1243. { 0xb66b, 0x14 },
  1244. { 0xb66c, 0x20 },
  1245. { 0xb66d, 0x20 },
  1246. { 0xb66e, 0x20 },
  1247. { 0xb66f, 0x20 },
  1248. { 0xb670, 0x10 },
  1249. { 0xb671, 0x10 },
  1250. { 0x3237, 0x00 },
  1251. { 0x3900, 0x00 },
  1252. { 0x3901, 0x00 },
  1253. { 0x3902, 0x00 },
  1254. { 0x3904, 0x00 },
  1255. { 0x3905, 0x00 },
  1256. { 0x3906, 0x00 },
  1257. { 0x3907, 0x00 },
  1258. { 0x3908, 0x00 },
  1259. { 0x3909, 0x00 },
  1260. { 0x3912, 0x00 },
  1261. { 0x3930, 0x00 },
  1262. { 0x3931, 0x00 },
  1263. { 0x3933, 0x00 },
  1264. { 0x3934, 0x00 },
  1265. { 0x3935, 0x00 },
  1266. { 0x3936, 0x00 },
  1267. { 0x3937, 0x00 },
  1268. { 0x30ac, 0x00 },
  1269. };
  1270. static const struct imx319_reg mode_1296x736_regs[] = {
  1271. { 0x0112, 0x0a },
  1272. { 0x0113, 0x0a },
  1273. { 0x0114, 0x03 },
  1274. { 0x0342, 0x08 },
  1275. { 0x0343, 0x20 },
  1276. { 0x0340, 0x18 },
  1277. { 0x0341, 0x2a },
  1278. { 0x0344, 0x00 },
  1279. { 0x0345, 0x00 },
  1280. { 0x0346, 0x01 },
  1281. { 0x0347, 0xf0 },
  1282. { 0x0348, 0x0c },
  1283. { 0x0349, 0xcf },
  1284. { 0x034a, 0x07 },
  1285. { 0x034b, 0xaf },
  1286. { 0x0220, 0x00 },
  1287. { 0x0221, 0x11 },
  1288. { 0x0381, 0x01 },
  1289. { 0x0383, 0x01 },
  1290. { 0x0385, 0x01 },
  1291. { 0x0387, 0x01 },
  1292. { 0x0900, 0x01 },
  1293. { 0x0901, 0x22 },
  1294. { 0x0902, 0x0a },
  1295. { 0x3140, 0x02 },
  1296. { 0x3141, 0x00 },
  1297. { 0x3f0d, 0x0a },
  1298. { 0x3f14, 0x01 },
  1299. { 0x3f3c, 0x02 },
  1300. { 0x3f4d, 0x01 },
  1301. { 0x3f4c, 0x01 },
  1302. { 0x4254, 0x7f },
  1303. { 0x0401, 0x00 },
  1304. { 0x0404, 0x00 },
  1305. { 0x0405, 0x10 },
  1306. { 0x0408, 0x00 },
  1307. { 0x0409, 0xac },
  1308. { 0x040a, 0x00 },
  1309. { 0x040b, 0x00 },
  1310. { 0x040c, 0x05 },
  1311. { 0x040d, 0x10 },
  1312. { 0x040e, 0x02 },
  1313. { 0x040f, 0xe0 },
  1314. { 0x034c, 0x05 },
  1315. { 0x034d, 0x10 },
  1316. { 0x034e, 0x02 },
  1317. { 0x034f, 0xe0 },
  1318. { 0x3261, 0x00 },
  1319. { 0x3264, 0x00 },
  1320. { 0x3265, 0x10 },
  1321. { 0x0301, 0x05 },
  1322. { 0x0303, 0x04 },
  1323. { 0x0305, 0x04 },
  1324. { 0x0306, 0x01 },
  1325. { 0x0307, 0x92 },
  1326. { 0x0309, 0x0a },
  1327. { 0x030b, 0x02 },
  1328. { 0x030d, 0x02 },
  1329. { 0x030e, 0x00 },
  1330. { 0x030f, 0xfa },
  1331. { 0x0310, 0x00 },
  1332. { 0x0820, 0x0f },
  1333. { 0x0821, 0x13 },
  1334. { 0x0822, 0x33 },
  1335. { 0x0823, 0x33 },
  1336. { 0x3e20, 0x01 },
  1337. { 0x3e37, 0x00 },
  1338. { 0x3e3b, 0x01 },
  1339. { 0x38a3, 0x01 },
  1340. { 0x38a8, 0x00 },
  1341. { 0x38a9, 0x00 },
  1342. { 0x38aa, 0x00 },
  1343. { 0x38ab, 0x00 },
  1344. { 0x3234, 0x00 },
  1345. { 0x3fc1, 0x00 },
  1346. { 0x3235, 0x00 },
  1347. { 0x3802, 0x00 },
  1348. { 0x3143, 0x04 },
  1349. { 0x360a, 0x00 },
  1350. { 0x0b00, 0x00 },
  1351. { 0x0106, 0x00 },
  1352. { 0x0b05, 0x01 },
  1353. { 0x0b06, 0x01 },
  1354. { 0x3230, 0x00 },
  1355. { 0x3602, 0x01 },
  1356. { 0x3607, 0x01 },
  1357. { 0x3c00, 0x00 },
  1358. { 0x3c01, 0xba },
  1359. { 0x3c02, 0xc8 },
  1360. { 0x3c03, 0xaa },
  1361. { 0x3c04, 0x91 },
  1362. { 0x3c05, 0x54 },
  1363. { 0x3c06, 0x26 },
  1364. { 0x3c07, 0x20 },
  1365. { 0x3c08, 0x51 },
  1366. { 0x3d80, 0x00 },
  1367. { 0x3f50, 0x00 },
  1368. { 0x3f56, 0x00 },
  1369. { 0x3f57, 0x30 },
  1370. { 0x3f78, 0x00 },
  1371. { 0x3f79, 0x34 },
  1372. { 0x3f7c, 0x00 },
  1373. { 0x3f7d, 0x00 },
  1374. { 0x3fba, 0x00 },
  1375. { 0x3fbb, 0x00 },
  1376. { 0xa081, 0x04 },
  1377. { 0xe014, 0x00 },
  1378. { 0x0202, 0x04 },
  1379. { 0x0203, 0xf6 },
  1380. { 0x0224, 0x01 },
  1381. { 0x0225, 0xf4 },
  1382. { 0x0204, 0x00 },
  1383. { 0x0205, 0x00 },
  1384. { 0x0216, 0x00 },
  1385. { 0x0217, 0x00 },
  1386. { 0x020e, 0x01 },
  1387. { 0x020f, 0x00 },
  1388. { 0x0210, 0x01 },
  1389. { 0x0211, 0x00 },
  1390. { 0x0212, 0x01 },
  1391. { 0x0213, 0x00 },
  1392. { 0x0214, 0x01 },
  1393. { 0x0215, 0x00 },
  1394. { 0x0218, 0x01 },
  1395. { 0x0219, 0x00 },
  1396. { 0x3614, 0x00 },
  1397. { 0x3616, 0x0d },
  1398. { 0x3617, 0x56 },
  1399. { 0xb612, 0x20 },
  1400. { 0xb613, 0x20 },
  1401. { 0xb614, 0x20 },
  1402. { 0xb615, 0x20 },
  1403. { 0xb616, 0x0a },
  1404. { 0xb617, 0x0a },
  1405. { 0xb618, 0x20 },
  1406. { 0xb619, 0x20 },
  1407. { 0xb61a, 0x20 },
  1408. { 0xb61b, 0x20 },
  1409. { 0xb61c, 0x0a },
  1410. { 0xb61d, 0x0a },
  1411. { 0xb666, 0x30 },
  1412. { 0xb667, 0x30 },
  1413. { 0xb668, 0x30 },
  1414. { 0xb669, 0x30 },
  1415. { 0xb66a, 0x14 },
  1416. { 0xb66b, 0x14 },
  1417. { 0xb66c, 0x20 },
  1418. { 0xb66d, 0x20 },
  1419. { 0xb66e, 0x20 },
  1420. { 0xb66f, 0x20 },
  1421. { 0xb670, 0x10 },
  1422. { 0xb671, 0x10 },
  1423. { 0x3237, 0x00 },
  1424. { 0x3900, 0x00 },
  1425. { 0x3901, 0x00 },
  1426. { 0x3902, 0x00 },
  1427. { 0x3904, 0x00 },
  1428. { 0x3905, 0x00 },
  1429. { 0x3906, 0x00 },
  1430. { 0x3907, 0x00 },
  1431. { 0x3908, 0x00 },
  1432. { 0x3909, 0x00 },
  1433. { 0x3912, 0x00 },
  1434. { 0x3930, 0x00 },
  1435. { 0x3931, 0x00 },
  1436. { 0x3933, 0x00 },
  1437. { 0x3934, 0x00 },
  1438. { 0x3935, 0x00 },
  1439. { 0x3936, 0x00 },
  1440. { 0x3937, 0x00 },
  1441. { 0x30ac, 0x00 },
  1442. };
  1443. static const struct imx319_reg mode_1280x720_regs[] = {
  1444. { 0x0112, 0x0a },
  1445. { 0x0113, 0x0a },
  1446. { 0x0114, 0x03 },
  1447. { 0x0342, 0x08 },
  1448. { 0x0343, 0x20 },
  1449. { 0x0340, 0x18 },
  1450. { 0x0341, 0x2a },
  1451. { 0x0344, 0x00 },
  1452. { 0x0345, 0x00 },
  1453. { 0x0346, 0x02 },
  1454. { 0x0347, 0x00 },
  1455. { 0x0348, 0x0c },
  1456. { 0x0349, 0xcf },
  1457. { 0x034a, 0x07 },
  1458. { 0x034b, 0x9f },
  1459. { 0x0220, 0x00 },
  1460. { 0x0221, 0x11 },
  1461. { 0x0381, 0x01 },
  1462. { 0x0383, 0x01 },
  1463. { 0x0385, 0x01 },
  1464. { 0x0387, 0x01 },
  1465. { 0x0900, 0x01 },
  1466. { 0x0901, 0x22 },
  1467. { 0x0902, 0x0a },
  1468. { 0x3140, 0x02 },
  1469. { 0x3141, 0x00 },
  1470. { 0x3f0d, 0x0a },
  1471. { 0x3f14, 0x01 },
  1472. { 0x3f3c, 0x02 },
  1473. { 0x3f4d, 0x01 },
  1474. { 0x3f4c, 0x01 },
  1475. { 0x4254, 0x7f },
  1476. { 0x0401, 0x00 },
  1477. { 0x0404, 0x00 },
  1478. { 0x0405, 0x10 },
  1479. { 0x0408, 0x00 },
  1480. { 0x0409, 0xb4 },
  1481. { 0x040a, 0x00 },
  1482. { 0x040b, 0x00 },
  1483. { 0x040c, 0x05 },
  1484. { 0x040d, 0x00 },
  1485. { 0x040e, 0x02 },
  1486. { 0x040f, 0xd0 },
  1487. { 0x034c, 0x05 },
  1488. { 0x034d, 0x00 },
  1489. { 0x034e, 0x02 },
  1490. { 0x034f, 0xd0 },
  1491. { 0x3261, 0x00 },
  1492. { 0x3264, 0x00 },
  1493. { 0x3265, 0x10 },
  1494. { 0x0301, 0x05 },
  1495. { 0x0303, 0x04 },
  1496. { 0x0305, 0x04 },
  1497. { 0x0306, 0x01 },
  1498. { 0x0307, 0x92 },
  1499. { 0x0309, 0x0a },
  1500. { 0x030b, 0x02 },
  1501. { 0x030d, 0x02 },
  1502. { 0x030e, 0x00 },
  1503. { 0x030f, 0xfa },
  1504. { 0x0310, 0x00 },
  1505. { 0x0820, 0x0f },
  1506. { 0x0821, 0x13 },
  1507. { 0x0822, 0x33 },
  1508. { 0x0823, 0x33 },
  1509. { 0x3e20, 0x01 },
  1510. { 0x3e37, 0x00 },
  1511. { 0x3e3b, 0x01 },
  1512. { 0x38a3, 0x01 },
  1513. { 0x38a8, 0x00 },
  1514. { 0x38a9, 0x00 },
  1515. { 0x38aa, 0x00 },
  1516. { 0x38ab, 0x00 },
  1517. { 0x3234, 0x00 },
  1518. { 0x3fc1, 0x00 },
  1519. { 0x3235, 0x00 },
  1520. { 0x3802, 0x00 },
  1521. { 0x3143, 0x04 },
  1522. { 0x360a, 0x00 },
  1523. { 0x0b00, 0x00 },
  1524. { 0x0106, 0x00 },
  1525. { 0x0b05, 0x01 },
  1526. { 0x0b06, 0x01 },
  1527. { 0x3230, 0x00 },
  1528. { 0x3602, 0x01 },
  1529. { 0x3607, 0x01 },
  1530. { 0x3c00, 0x00 },
  1531. { 0x3c01, 0xba },
  1532. { 0x3c02, 0xc8 },
  1533. { 0x3c03, 0xaa },
  1534. { 0x3c04, 0x91 },
  1535. { 0x3c05, 0x54 },
  1536. { 0x3c06, 0x26 },
  1537. { 0x3c07, 0x20 },
  1538. { 0x3c08, 0x51 },
  1539. { 0x3d80, 0x00 },
  1540. { 0x3f50, 0x00 },
  1541. { 0x3f56, 0x00 },
  1542. { 0x3f57, 0x30 },
  1543. { 0x3f78, 0x00 },
  1544. { 0x3f79, 0x34 },
  1545. { 0x3f7c, 0x00 },
  1546. { 0x3f7d, 0x00 },
  1547. { 0x3fba, 0x00 },
  1548. { 0x3fbb, 0x00 },
  1549. { 0xa081, 0x04 },
  1550. { 0xe014, 0x00 },
  1551. { 0x0202, 0x04 },
  1552. { 0x0203, 0xf6 },
  1553. { 0x0224, 0x01 },
  1554. { 0x0225, 0xf4 },
  1555. { 0x0204, 0x00 },
  1556. { 0x0205, 0x00 },
  1557. { 0x0216, 0x00 },
  1558. { 0x0217, 0x00 },
  1559. { 0x020e, 0x01 },
  1560. { 0x020f, 0x00 },
  1561. { 0x0210, 0x01 },
  1562. { 0x0211, 0x00 },
  1563. { 0x0212, 0x01 },
  1564. { 0x0213, 0x00 },
  1565. { 0x0214, 0x01 },
  1566. { 0x0215, 0x00 },
  1567. { 0x0218, 0x01 },
  1568. { 0x0219, 0x00 },
  1569. { 0x3614, 0x00 },
  1570. { 0x3616, 0x0d },
  1571. { 0x3617, 0x56 },
  1572. { 0xb612, 0x20 },
  1573. { 0xb613, 0x20 },
  1574. { 0xb614, 0x20 },
  1575. { 0xb615, 0x20 },
  1576. { 0xb616, 0x0a },
  1577. { 0xb617, 0x0a },
  1578. { 0xb618, 0x20 },
  1579. { 0xb619, 0x20 },
  1580. { 0xb61a, 0x20 },
  1581. { 0xb61b, 0x20 },
  1582. { 0xb61c, 0x0a },
  1583. { 0xb61d, 0x0a },
  1584. { 0xb666, 0x30 },
  1585. { 0xb667, 0x30 },
  1586. { 0xb668, 0x30 },
  1587. { 0xb669, 0x30 },
  1588. { 0xb66a, 0x14 },
  1589. { 0xb66b, 0x14 },
  1590. { 0xb66c, 0x20 },
  1591. { 0xb66d, 0x20 },
  1592. { 0xb66e, 0x20 },
  1593. { 0xb66f, 0x20 },
  1594. { 0xb670, 0x10 },
  1595. { 0xb671, 0x10 },
  1596. { 0x3237, 0x00 },
  1597. { 0x3900, 0x00 },
  1598. { 0x3901, 0x00 },
  1599. { 0x3902, 0x00 },
  1600. { 0x3904, 0x00 },
  1601. { 0x3905, 0x00 },
  1602. { 0x3906, 0x00 },
  1603. { 0x3907, 0x00 },
  1604. { 0x3908, 0x00 },
  1605. { 0x3909, 0x00 },
  1606. { 0x3912, 0x00 },
  1607. { 0x3930, 0x00 },
  1608. { 0x3931, 0x00 },
  1609. { 0x3933, 0x00 },
  1610. { 0x3934, 0x00 },
  1611. { 0x3935, 0x00 },
  1612. { 0x3936, 0x00 },
  1613. { 0x3937, 0x00 },
  1614. { 0x30ac, 0x00 },
  1615. };
  1616. static const char * const imx319_test_pattern_menu[] = {
  1617. "Disabled",
  1618. "Solid Colour",
  1619. "Eight Vertical Colour Bars",
  1620. "Colour Bars With Fade to Grey",
  1621. "Pseudorandom Sequence (PN9)",
  1622. };
  1623. /* supported link frequencies */
  1624. static const s64 link_freq_menu_items[] = {
  1625. IMX319_LINK_FREQ_DEFAULT,
  1626. };
  1627. /* Mode configs */
  1628. static const struct imx319_mode supported_modes[] = {
  1629. {
  1630. .width = 3280,
  1631. .height = 2464,
  1632. .fll_def = 3242,
  1633. .fll_min = 3242,
  1634. .llp = 3968,
  1635. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1636. .reg_list = {
  1637. .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
  1638. .regs = mode_3280x2464_regs,
  1639. },
  1640. },
  1641. {
  1642. .width = 3264,
  1643. .height = 2448,
  1644. .fll_def = 3242,
  1645. .fll_min = 3242,
  1646. .llp = 3968,
  1647. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1648. .reg_list = {
  1649. .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
  1650. .regs = mode_3264x2448_regs,
  1651. },
  1652. },
  1653. {
  1654. .width = 1936,
  1655. .height = 1096,
  1656. .fll_def = 3242,
  1657. .fll_min = 3242,
  1658. .llp = 3968,
  1659. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1660. .reg_list = {
  1661. .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
  1662. .regs = mode_1936x1096_regs,
  1663. },
  1664. },
  1665. {
  1666. .width = 1920,
  1667. .height = 1080,
  1668. .fll_def = 3242,
  1669. .fll_min = 3242,
  1670. .llp = 3968,
  1671. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1672. .reg_list = {
  1673. .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
  1674. .regs = mode_1920x1080_regs,
  1675. },
  1676. },
  1677. {
  1678. .width = 1640,
  1679. .height = 1232,
  1680. .fll_def = 5146,
  1681. .fll_min = 5146,
  1682. .llp = 2500,
  1683. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1684. .reg_list = {
  1685. .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
  1686. .regs = mode_1640x1232_regs,
  1687. },
  1688. },
  1689. {
  1690. .width = 1640,
  1691. .height = 922,
  1692. .fll_def = 5146,
  1693. .fll_min = 5146,
  1694. .llp = 2500,
  1695. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1696. .reg_list = {
  1697. .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
  1698. .regs = mode_1640x922_regs,
  1699. },
  1700. },
  1701. {
  1702. .width = 1296,
  1703. .height = 736,
  1704. .fll_def = 5146,
  1705. .fll_min = 5146,
  1706. .llp = 2500,
  1707. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1708. .reg_list = {
  1709. .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
  1710. .regs = mode_1296x736_regs,
  1711. },
  1712. },
  1713. {
  1714. .width = 1280,
  1715. .height = 720,
  1716. .fll_def = 5146,
  1717. .fll_min = 5146,
  1718. .llp = 2500,
  1719. .link_freq_index = IMX319_LINK_FREQ_INDEX,
  1720. .reg_list = {
  1721. .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
  1722. .regs = mode_1280x720_regs,
  1723. },
  1724. },
  1725. };
  1726. static inline struct imx319 *to_imx319(struct v4l2_subdev *_sd)
  1727. {
  1728. return container_of(_sd, struct imx319, sd);
  1729. }
  1730. /* Get bayer order based on flip setting. */
  1731. static u32 imx319_get_format_code(struct imx319 *imx319)
  1732. {
  1733. /*
  1734. * Only one bayer order is supported.
  1735. * It depends on the flip settings.
  1736. */
  1737. u32 code;
  1738. static const u32 codes[2][2] = {
  1739. { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
  1740. { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
  1741. };
  1742. lockdep_assert_held(&imx319->mutex);
  1743. code = codes[imx319->vflip->val][imx319->hflip->val];
  1744. return code;
  1745. }
  1746. /* Read registers up to 4 at a time */
  1747. static int imx319_read_reg(struct imx319 *imx319, u16 reg, u32 len, u32 *val)
  1748. {
  1749. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  1750. struct i2c_msg msgs[2];
  1751. u8 addr_buf[2];
  1752. u8 data_buf[4] = { 0 };
  1753. int ret;
  1754. if (len > 4)
  1755. return -EINVAL;
  1756. put_unaligned_be16(reg, addr_buf);
  1757. /* Write register address */
  1758. msgs[0].addr = client->addr;
  1759. msgs[0].flags = 0;
  1760. msgs[0].len = ARRAY_SIZE(addr_buf);
  1761. msgs[0].buf = addr_buf;
  1762. /* Read data from register */
  1763. msgs[1].addr = client->addr;
  1764. msgs[1].flags = I2C_M_RD;
  1765. msgs[1].len = len;
  1766. msgs[1].buf = &data_buf[4 - len];
  1767. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  1768. if (ret != ARRAY_SIZE(msgs))
  1769. return -EIO;
  1770. *val = get_unaligned_be32(data_buf);
  1771. return 0;
  1772. }
  1773. /* Write registers up to 4 at a time */
  1774. static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
  1775. {
  1776. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  1777. u8 buf[6];
  1778. if (len > 4)
  1779. return -EINVAL;
  1780. put_unaligned_be16(reg, buf);
  1781. put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
  1782. if (i2c_master_send(client, buf, len + 2) != len + 2)
  1783. return -EIO;
  1784. return 0;
  1785. }
  1786. /* Write a list of registers */
  1787. static int imx319_write_regs(struct imx319 *imx319,
  1788. const struct imx319_reg *regs, u32 len)
  1789. {
  1790. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  1791. int ret;
  1792. u32 i;
  1793. for (i = 0; i < len; i++) {
  1794. ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
  1795. if (ret) {
  1796. dev_err_ratelimited(&client->dev,
  1797. "write reg 0x%4.4x return err %d",
  1798. regs[i].address, ret);
  1799. return ret;
  1800. }
  1801. }
  1802. return 0;
  1803. }
  1804. /* Open sub-device */
  1805. static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  1806. {
  1807. struct imx319 *imx319 = to_imx319(sd);
  1808. struct v4l2_mbus_framefmt *try_fmt =
  1809. v4l2_subdev_get_try_format(sd, fh->state, 0);
  1810. mutex_lock(&imx319->mutex);
  1811. /* Initialize try_fmt */
  1812. try_fmt->width = imx319->cur_mode->width;
  1813. try_fmt->height = imx319->cur_mode->height;
  1814. try_fmt->code = imx319_get_format_code(imx319);
  1815. try_fmt->field = V4L2_FIELD_NONE;
  1816. mutex_unlock(&imx319->mutex);
  1817. return 0;
  1818. }
  1819. static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
  1820. {
  1821. struct imx319 *imx319 = container_of(ctrl->handler,
  1822. struct imx319, ctrl_handler);
  1823. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  1824. s64 max;
  1825. int ret;
  1826. /* Propagate change of current control to all related controls */
  1827. switch (ctrl->id) {
  1828. case V4L2_CID_VBLANK:
  1829. /* Update max exposure while meeting expected vblanking */
  1830. max = imx319->cur_mode->height + ctrl->val - 18;
  1831. __v4l2_ctrl_modify_range(imx319->exposure,
  1832. imx319->exposure->minimum,
  1833. max, imx319->exposure->step, max);
  1834. break;
  1835. }
  1836. /*
  1837. * Applying V4L2 control value only happens
  1838. * when power is up for streaming
  1839. */
  1840. if (!pm_runtime_get_if_in_use(&client->dev))
  1841. return 0;
  1842. switch (ctrl->id) {
  1843. case V4L2_CID_ANALOGUE_GAIN:
  1844. /* Analog gain = 1024/(1024 - ctrl->val) times */
  1845. ret = imx319_write_reg(imx319, IMX319_REG_ANALOG_GAIN, 2,
  1846. ctrl->val);
  1847. break;
  1848. case V4L2_CID_DIGITAL_GAIN:
  1849. ret = imx319_write_reg(imx319, IMX319_REG_DIG_GAIN_GLOBAL, 2,
  1850. ctrl->val);
  1851. break;
  1852. case V4L2_CID_EXPOSURE:
  1853. ret = imx319_write_reg(imx319, IMX319_REG_EXPOSURE, 2,
  1854. ctrl->val);
  1855. break;
  1856. case V4L2_CID_VBLANK:
  1857. /* Update FLL that meets expected vertical blanking */
  1858. ret = imx319_write_reg(imx319, IMX319_REG_FLL, 2,
  1859. imx319->cur_mode->height + ctrl->val);
  1860. break;
  1861. case V4L2_CID_TEST_PATTERN:
  1862. ret = imx319_write_reg(imx319, IMX319_REG_TEST_PATTERN,
  1863. 2, ctrl->val);
  1864. break;
  1865. case V4L2_CID_HFLIP:
  1866. case V4L2_CID_VFLIP:
  1867. ret = imx319_write_reg(imx319, IMX319_REG_ORIENTATION, 1,
  1868. imx319->hflip->val |
  1869. imx319->vflip->val << 1);
  1870. break;
  1871. default:
  1872. ret = -EINVAL;
  1873. dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
  1874. ctrl->id, ctrl->val);
  1875. break;
  1876. }
  1877. pm_runtime_put(&client->dev);
  1878. return ret;
  1879. }
  1880. static const struct v4l2_ctrl_ops imx319_ctrl_ops = {
  1881. .s_ctrl = imx319_set_ctrl,
  1882. };
  1883. static int imx319_enum_mbus_code(struct v4l2_subdev *sd,
  1884. struct v4l2_subdev_state *sd_state,
  1885. struct v4l2_subdev_mbus_code_enum *code)
  1886. {
  1887. struct imx319 *imx319 = to_imx319(sd);
  1888. if (code->index > 0)
  1889. return -EINVAL;
  1890. mutex_lock(&imx319->mutex);
  1891. code->code = imx319_get_format_code(imx319);
  1892. mutex_unlock(&imx319->mutex);
  1893. return 0;
  1894. }
  1895. static int imx319_enum_frame_size(struct v4l2_subdev *sd,
  1896. struct v4l2_subdev_state *sd_state,
  1897. struct v4l2_subdev_frame_size_enum *fse)
  1898. {
  1899. struct imx319 *imx319 = to_imx319(sd);
  1900. if (fse->index >= ARRAY_SIZE(supported_modes))
  1901. return -EINVAL;
  1902. mutex_lock(&imx319->mutex);
  1903. if (fse->code != imx319_get_format_code(imx319)) {
  1904. mutex_unlock(&imx319->mutex);
  1905. return -EINVAL;
  1906. }
  1907. mutex_unlock(&imx319->mutex);
  1908. fse->min_width = supported_modes[fse->index].width;
  1909. fse->max_width = fse->min_width;
  1910. fse->min_height = supported_modes[fse->index].height;
  1911. fse->max_height = fse->min_height;
  1912. return 0;
  1913. }
  1914. static void imx319_update_pad_format(struct imx319 *imx319,
  1915. const struct imx319_mode *mode,
  1916. struct v4l2_subdev_format *fmt)
  1917. {
  1918. fmt->format.width = mode->width;
  1919. fmt->format.height = mode->height;
  1920. fmt->format.code = imx319_get_format_code(imx319);
  1921. fmt->format.field = V4L2_FIELD_NONE;
  1922. }
  1923. static int imx319_do_get_pad_format(struct imx319 *imx319,
  1924. struct v4l2_subdev_state *sd_state,
  1925. struct v4l2_subdev_format *fmt)
  1926. {
  1927. struct v4l2_mbus_framefmt *framefmt;
  1928. struct v4l2_subdev *sd = &imx319->sd;
  1929. if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
  1930. framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
  1931. fmt->format = *framefmt;
  1932. } else {
  1933. imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
  1934. }
  1935. return 0;
  1936. }
  1937. static int imx319_get_pad_format(struct v4l2_subdev *sd,
  1938. struct v4l2_subdev_state *sd_state,
  1939. struct v4l2_subdev_format *fmt)
  1940. {
  1941. struct imx319 *imx319 = to_imx319(sd);
  1942. int ret;
  1943. mutex_lock(&imx319->mutex);
  1944. ret = imx319_do_get_pad_format(imx319, sd_state, fmt);
  1945. mutex_unlock(&imx319->mutex);
  1946. return ret;
  1947. }
  1948. static int
  1949. imx319_set_pad_format(struct v4l2_subdev *sd,
  1950. struct v4l2_subdev_state *sd_state,
  1951. struct v4l2_subdev_format *fmt)
  1952. {
  1953. struct imx319 *imx319 = to_imx319(sd);
  1954. const struct imx319_mode *mode;
  1955. struct v4l2_mbus_framefmt *framefmt;
  1956. s32 vblank_def;
  1957. s32 vblank_min;
  1958. s64 h_blank;
  1959. u64 pixel_rate;
  1960. u32 height;
  1961. mutex_lock(&imx319->mutex);
  1962. /*
  1963. * Only one bayer order is supported.
  1964. * It depends on the flip settings.
  1965. */
  1966. fmt->format.code = imx319_get_format_code(imx319);
  1967. mode = v4l2_find_nearest_size(supported_modes,
  1968. ARRAY_SIZE(supported_modes),
  1969. width, height,
  1970. fmt->format.width, fmt->format.height);
  1971. imx319_update_pad_format(imx319, mode, fmt);
  1972. if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
  1973. framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
  1974. *framefmt = fmt->format;
  1975. } else {
  1976. imx319->cur_mode = mode;
  1977. pixel_rate = imx319->link_def_freq * 2 * 4;
  1978. do_div(pixel_rate, 10);
  1979. __v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
  1980. /* Update limits and set FPS to default */
  1981. height = imx319->cur_mode->height;
  1982. vblank_def = imx319->cur_mode->fll_def - height;
  1983. vblank_min = imx319->cur_mode->fll_min - height;
  1984. height = IMX319_FLL_MAX - height;
  1985. __v4l2_ctrl_modify_range(imx319->vblank, vblank_min, height, 1,
  1986. vblank_def);
  1987. __v4l2_ctrl_s_ctrl(imx319->vblank, vblank_def);
  1988. h_blank = mode->llp - imx319->cur_mode->width;
  1989. /*
  1990. * Currently hblank is not changeable.
  1991. * So FPS control is done only by vblank.
  1992. */
  1993. __v4l2_ctrl_modify_range(imx319->hblank, h_blank,
  1994. h_blank, 1, h_blank);
  1995. }
  1996. mutex_unlock(&imx319->mutex);
  1997. return 0;
  1998. }
  1999. /* Verify chip ID */
  2000. static int imx319_identify_module(struct imx319 *imx319)
  2001. {
  2002. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  2003. int ret;
  2004. u32 val;
  2005. if (imx319->identified)
  2006. return 0;
  2007. ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
  2008. if (ret)
  2009. return ret;
  2010. if (val != IMX319_CHIP_ID) {
  2011. dev_err(&client->dev, "chip id mismatch: %x!=%x",
  2012. IMX319_CHIP_ID, val);
  2013. return -EIO;
  2014. }
  2015. imx319->identified = true;
  2016. return 0;
  2017. }
  2018. /* Start streaming */
  2019. static int imx319_start_streaming(struct imx319 *imx319)
  2020. {
  2021. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  2022. const struct imx319_reg_list *reg_list;
  2023. int ret;
  2024. ret = imx319_identify_module(imx319);
  2025. if (ret)
  2026. return ret;
  2027. /* Global Setting */
  2028. reg_list = &imx319_global_setting;
  2029. ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
  2030. if (ret) {
  2031. dev_err(&client->dev, "failed to set global settings");
  2032. return ret;
  2033. }
  2034. /* Apply default values of current mode */
  2035. reg_list = &imx319->cur_mode->reg_list;
  2036. ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
  2037. if (ret) {
  2038. dev_err(&client->dev, "failed to set mode");
  2039. return ret;
  2040. }
  2041. /* set digital gain control to all color mode */
  2042. ret = imx319_write_reg(imx319, IMX319_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
  2043. if (ret)
  2044. return ret;
  2045. /* Apply customized values from user */
  2046. ret = __v4l2_ctrl_handler_setup(imx319->sd.ctrl_handler);
  2047. if (ret)
  2048. return ret;
  2049. return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
  2050. 1, IMX319_MODE_STREAMING);
  2051. }
  2052. /* Stop streaming */
  2053. static int imx319_stop_streaming(struct imx319 *imx319)
  2054. {
  2055. return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
  2056. 1, IMX319_MODE_STANDBY);
  2057. }
  2058. static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
  2059. {
  2060. struct imx319 *imx319 = to_imx319(sd);
  2061. struct i2c_client *client = v4l2_get_subdevdata(sd);
  2062. int ret = 0;
  2063. mutex_lock(&imx319->mutex);
  2064. if (imx319->streaming == enable) {
  2065. mutex_unlock(&imx319->mutex);
  2066. return 0;
  2067. }
  2068. if (enable) {
  2069. ret = pm_runtime_resume_and_get(&client->dev);
  2070. if (ret < 0)
  2071. goto err_unlock;
  2072. /*
  2073. * Apply default & customized values
  2074. * and then start streaming.
  2075. */
  2076. ret = imx319_start_streaming(imx319);
  2077. if (ret)
  2078. goto err_rpm_put;
  2079. } else {
  2080. imx319_stop_streaming(imx319);
  2081. pm_runtime_put(&client->dev);
  2082. }
  2083. imx319->streaming = enable;
  2084. /* vflip and hflip cannot change during streaming */
  2085. __v4l2_ctrl_grab(imx319->vflip, enable);
  2086. __v4l2_ctrl_grab(imx319->hflip, enable);
  2087. mutex_unlock(&imx319->mutex);
  2088. return ret;
  2089. err_rpm_put:
  2090. pm_runtime_put(&client->dev);
  2091. err_unlock:
  2092. mutex_unlock(&imx319->mutex);
  2093. return ret;
  2094. }
  2095. static int __maybe_unused imx319_suspend(struct device *dev)
  2096. {
  2097. struct v4l2_subdev *sd = dev_get_drvdata(dev);
  2098. struct imx319 *imx319 = to_imx319(sd);
  2099. if (imx319->streaming)
  2100. imx319_stop_streaming(imx319);
  2101. return 0;
  2102. }
  2103. static int __maybe_unused imx319_resume(struct device *dev)
  2104. {
  2105. struct v4l2_subdev *sd = dev_get_drvdata(dev);
  2106. struct imx319 *imx319 = to_imx319(sd);
  2107. int ret;
  2108. if (imx319->streaming) {
  2109. ret = imx319_start_streaming(imx319);
  2110. if (ret)
  2111. goto error;
  2112. }
  2113. return 0;
  2114. error:
  2115. imx319_stop_streaming(imx319);
  2116. imx319->streaming = 0;
  2117. return ret;
  2118. }
  2119. static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
  2120. .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
  2121. .unsubscribe_event = v4l2_event_subdev_unsubscribe,
  2122. };
  2123. static const struct v4l2_subdev_video_ops imx319_video_ops = {
  2124. .s_stream = imx319_set_stream,
  2125. };
  2126. static const struct v4l2_subdev_pad_ops imx319_pad_ops = {
  2127. .enum_mbus_code = imx319_enum_mbus_code,
  2128. .get_fmt = imx319_get_pad_format,
  2129. .set_fmt = imx319_set_pad_format,
  2130. .enum_frame_size = imx319_enum_frame_size,
  2131. };
  2132. static const struct v4l2_subdev_ops imx319_subdev_ops = {
  2133. .core = &imx319_subdev_core_ops,
  2134. .video = &imx319_video_ops,
  2135. .pad = &imx319_pad_ops,
  2136. };
  2137. static const struct media_entity_operations imx319_subdev_entity_ops = {
  2138. .link_validate = v4l2_subdev_link_validate,
  2139. };
  2140. static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
  2141. .open = imx319_open,
  2142. };
  2143. /* Initialize control handlers */
  2144. static int imx319_init_controls(struct imx319 *imx319)
  2145. {
  2146. struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
  2147. struct v4l2_ctrl_handler *ctrl_hdlr;
  2148. s64 exposure_max;
  2149. s64 vblank_def;
  2150. s64 vblank_min;
  2151. s64 hblank;
  2152. u64 pixel_rate;
  2153. const struct imx319_mode *mode;
  2154. u32 max;
  2155. int ret;
  2156. ctrl_hdlr = &imx319->ctrl_handler;
  2157. ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
  2158. if (ret)
  2159. return ret;
  2160. ctrl_hdlr->lock = &imx319->mutex;
  2161. max = ARRAY_SIZE(link_freq_menu_items) - 1;
  2162. imx319->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx319_ctrl_ops,
  2163. V4L2_CID_LINK_FREQ, max, 0,
  2164. link_freq_menu_items);
  2165. if (imx319->link_freq)
  2166. imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  2167. /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
  2168. pixel_rate = imx319->link_def_freq * 2 * 4;
  2169. do_div(pixel_rate, 10);
  2170. /* By default, PIXEL_RATE is read only */
  2171. imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2172. V4L2_CID_PIXEL_RATE, pixel_rate,
  2173. pixel_rate, 1, pixel_rate);
  2174. /* Initial vblank/hblank/exposure parameters based on current mode */
  2175. mode = imx319->cur_mode;
  2176. vblank_def = mode->fll_def - mode->height;
  2177. vblank_min = mode->fll_min - mode->height;
  2178. imx319->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2179. V4L2_CID_VBLANK, vblank_min,
  2180. IMX319_FLL_MAX - mode->height,
  2181. 1, vblank_def);
  2182. hblank = mode->llp - mode->width;
  2183. imx319->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2184. V4L2_CID_HBLANK, hblank, hblank,
  2185. 1, hblank);
  2186. if (imx319->hblank)
  2187. imx319->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  2188. /* fll >= exposure time + adjust parameter (default value is 18) */
  2189. exposure_max = mode->fll_def - 18;
  2190. imx319->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2191. V4L2_CID_EXPOSURE,
  2192. IMX319_EXPOSURE_MIN, exposure_max,
  2193. IMX319_EXPOSURE_STEP,
  2194. IMX319_EXPOSURE_DEFAULT);
  2195. imx319->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2196. V4L2_CID_HFLIP, 0, 1, 1, 0);
  2197. imx319->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
  2198. V4L2_CID_VFLIP, 0, 1, 1, 0);
  2199. v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
  2200. IMX319_ANA_GAIN_MIN, IMX319_ANA_GAIN_MAX,
  2201. IMX319_ANA_GAIN_STEP, IMX319_ANA_GAIN_DEFAULT);
  2202. /* Digital gain */
  2203. v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
  2204. IMX319_DGTL_GAIN_MIN, IMX319_DGTL_GAIN_MAX,
  2205. IMX319_DGTL_GAIN_STEP, IMX319_DGTL_GAIN_DEFAULT);
  2206. v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx319_ctrl_ops,
  2207. V4L2_CID_TEST_PATTERN,
  2208. ARRAY_SIZE(imx319_test_pattern_menu) - 1,
  2209. 0, 0, imx319_test_pattern_menu);
  2210. if (ctrl_hdlr->error) {
  2211. ret = ctrl_hdlr->error;
  2212. dev_err(&client->dev, "control init failed: %d", ret);
  2213. goto error;
  2214. }
  2215. imx319->sd.ctrl_handler = ctrl_hdlr;
  2216. return 0;
  2217. error:
  2218. v4l2_ctrl_handler_free(ctrl_hdlr);
  2219. return ret;
  2220. }
  2221. static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
  2222. {
  2223. struct imx319_hwcfg *cfg;
  2224. struct v4l2_fwnode_endpoint bus_cfg = {
  2225. .bus_type = V4L2_MBUS_CSI2_DPHY
  2226. };
  2227. struct fwnode_handle *ep;
  2228. struct fwnode_handle *fwnode = dev_fwnode(dev);
  2229. unsigned int i;
  2230. int ret;
  2231. if (!fwnode)
  2232. return NULL;
  2233. ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
  2234. if (!ep)
  2235. return NULL;
  2236. ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
  2237. if (ret)
  2238. goto out_err;
  2239. cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
  2240. if (!cfg)
  2241. goto out_err;
  2242. ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
  2243. &cfg->ext_clk);
  2244. if (ret) {
  2245. dev_err(dev, "can't get clock frequency");
  2246. goto out_err;
  2247. }
  2248. dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
  2249. if (cfg->ext_clk != IMX319_EXT_CLK) {
  2250. dev_err(dev, "external clock %d is not supported",
  2251. cfg->ext_clk);
  2252. goto out_err;
  2253. }
  2254. dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
  2255. if (!bus_cfg.nr_of_link_frequencies) {
  2256. dev_warn(dev, "no link frequencies defined");
  2257. goto out_err;
  2258. }
  2259. cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
  2260. cfg->link_freqs = devm_kcalloc(dev,
  2261. bus_cfg.nr_of_link_frequencies + 1,
  2262. sizeof(*cfg->link_freqs), GFP_KERNEL);
  2263. if (!cfg->link_freqs)
  2264. goto out_err;
  2265. for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
  2266. cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
  2267. dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
  2268. }
  2269. v4l2_fwnode_endpoint_free(&bus_cfg);
  2270. fwnode_handle_put(ep);
  2271. return cfg;
  2272. out_err:
  2273. v4l2_fwnode_endpoint_free(&bus_cfg);
  2274. fwnode_handle_put(ep);
  2275. return NULL;
  2276. }
  2277. static int imx319_probe(struct i2c_client *client)
  2278. {
  2279. struct imx319 *imx319;
  2280. bool full_power;
  2281. int ret;
  2282. u32 i;
  2283. imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
  2284. if (!imx319)
  2285. return -ENOMEM;
  2286. mutex_init(&imx319->mutex);
  2287. /* Initialize subdev */
  2288. v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
  2289. full_power = acpi_dev_state_d0(&client->dev);
  2290. if (full_power) {
  2291. /* Check module identity */
  2292. ret = imx319_identify_module(imx319);
  2293. if (ret) {
  2294. dev_err(&client->dev, "failed to find sensor: %d", ret);
  2295. goto error_probe;
  2296. }
  2297. }
  2298. imx319->hwcfg = imx319_get_hwcfg(&client->dev);
  2299. if (!imx319->hwcfg) {
  2300. dev_err(&client->dev, "failed to get hwcfg");
  2301. ret = -ENODEV;
  2302. goto error_probe;
  2303. }
  2304. imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
  2305. for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
  2306. if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
  2307. dev_dbg(&client->dev, "link freq index %d matched", i);
  2308. break;
  2309. }
  2310. }
  2311. if (i == imx319->hwcfg->nr_of_link_freqs) {
  2312. dev_err(&client->dev, "no link frequency supported");
  2313. ret = -EINVAL;
  2314. goto error_probe;
  2315. }
  2316. /* Set default mode to max resolution */
  2317. imx319->cur_mode = &supported_modes[0];
  2318. ret = imx319_init_controls(imx319);
  2319. if (ret) {
  2320. dev_err(&client->dev, "failed to init controls: %d", ret);
  2321. goto error_probe;
  2322. }
  2323. /* Initialize subdev */
  2324. imx319->sd.internal_ops = &imx319_internal_ops;
  2325. imx319->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
  2326. V4L2_SUBDEV_FL_HAS_EVENTS;
  2327. imx319->sd.entity.ops = &imx319_subdev_entity_ops;
  2328. imx319->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
  2329. /* Initialize source pad */
  2330. imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
  2331. ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
  2332. if (ret) {
  2333. dev_err(&client->dev, "failed to init entity pads: %d", ret);
  2334. goto error_handler_free;
  2335. }
  2336. ret = v4l2_async_register_subdev_sensor(&imx319->sd);
  2337. if (ret < 0)
  2338. goto error_media_entity;
  2339. /* Set the device's state to active if it's in D0 state. */
  2340. if (full_power)
  2341. pm_runtime_set_active(&client->dev);
  2342. pm_runtime_enable(&client->dev);
  2343. pm_runtime_idle(&client->dev);
  2344. return 0;
  2345. error_media_entity:
  2346. media_entity_cleanup(&imx319->sd.entity);
  2347. error_handler_free:
  2348. v4l2_ctrl_handler_free(imx319->sd.ctrl_handler);
  2349. error_probe:
  2350. mutex_destroy(&imx319->mutex);
  2351. return ret;
  2352. }
  2353. static void imx319_remove(struct i2c_client *client)
  2354. {
  2355. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  2356. struct imx319 *imx319 = to_imx319(sd);
  2357. v4l2_async_unregister_subdev(sd);
  2358. media_entity_cleanup(&sd->entity);
  2359. v4l2_ctrl_handler_free(sd->ctrl_handler);
  2360. pm_runtime_disable(&client->dev);
  2361. pm_runtime_set_suspended(&client->dev);
  2362. mutex_destroy(&imx319->mutex);
  2363. }
  2364. static const struct dev_pm_ops imx319_pm_ops = {
  2365. SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
  2366. };
  2367. static const struct acpi_device_id imx319_acpi_ids[] __maybe_unused = {
  2368. { "SONY319A" },
  2369. { /* sentinel */ }
  2370. };
  2371. MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
  2372. static struct i2c_driver imx319_i2c_driver = {
  2373. .driver = {
  2374. .name = "imx319",
  2375. .pm = &imx319_pm_ops,
  2376. .acpi_match_table = ACPI_PTR(imx319_acpi_ids),
  2377. },
  2378. .probe_new = imx319_probe,
  2379. .remove = imx319_remove,
  2380. .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
  2381. };
  2382. module_i2c_driver(imx319_i2c_driver);
  2383. MODULE_AUTHOR("Qiu, Tianshu <[email protected]>");
  2384. MODULE_AUTHOR("Rapolu, Chiranjeevi <[email protected]>");
  2385. MODULE_AUTHOR("Bingbu Cao <[email protected]>");
  2386. MODULE_AUTHOR("Yang, Hyungwoo");
  2387. MODULE_DESCRIPTION("Sony imx319 sensor driver");
  2388. MODULE_LICENSE("GPL v2");