ov8858.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2023 Jacopo Mondi <jacopo.mondi@ideasonboard.com>
  4. * Copyright (C) 2022 Nicholas Roth <nicholas@rothemail.net>
  5. * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
  6. */
  7. #include <linux/unaligned.h>
  8. #include <linux/clk.h>
  9. #include <linux/delay.h>
  10. #include <linux/device.h>
  11. #include <linux/gpio/consumer.h>
  12. #include <linux/i2c.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/pm_runtime.h>
  16. #include <linux/property.h>
  17. #include <linux/regulator/consumer.h>
  18. #include <linux/slab.h>
  19. #include <media/media-entity.h>
  20. #include <media/v4l2-async.h>
  21. #include <media/v4l2-common.h>
  22. #include <media/v4l2-ctrls.h>
  23. #include <media/v4l2-device.h>
  24. #include <media/v4l2-fwnode.h>
  25. #include <media/v4l2-mediabus.h>
  26. #include <media/v4l2-subdev.h>
  27. #define OV8858_LINK_FREQ 360000000U
  28. #define OV8858_XVCLK_FREQ 24000000
  29. #define OV8858_REG_SIZE_SHIFT 16
  30. #define OV8858_REG_ADDR_MASK 0xffff
  31. #define OV8858_REG_8BIT(n) ((1U << OV8858_REG_SIZE_SHIFT) | (n))
  32. #define OV8858_REG_16BIT(n) ((2U << OV8858_REG_SIZE_SHIFT) | (n))
  33. #define OV8858_REG_24BIT(n) ((3U << OV8858_REG_SIZE_SHIFT) | (n))
  34. #define OV8858_REG_SC_CTRL0100 OV8858_REG_8BIT(0x0100)
  35. #define OV8858_MODE_SW_STANDBY 0x0
  36. #define OV8858_MODE_STREAMING 0x1
  37. #define OV8858_REG_CHIP_ID OV8858_REG_24BIT(0x300a)
  38. #define OV8858_CHIP_ID 0x008858
  39. #define OV8858_REG_SUB_ID OV8858_REG_8BIT(0x302a)
  40. #define OV8858_R1A 0xb0
  41. #define OV8858_R2A 0xb2
  42. #define OV8858_REG_LONG_EXPO OV8858_REG_24BIT(0x3500)
  43. #define OV8858_EXPOSURE_MIN 4
  44. #define OV8858_EXPOSURE_STEP 1
  45. #define OV8858_EXPOSURE_MARGIN 4
  46. #define OV8858_REG_LONG_GAIN OV8858_REG_16BIT(0x3508)
  47. #define OV8858_LONG_GAIN_MIN 0x0
  48. #define OV8858_LONG_GAIN_MAX 0x7ff
  49. #define OV8858_LONG_GAIN_STEP 1
  50. #define OV8858_LONG_GAIN_DEFAULT 0x80
  51. #define OV8858_REG_LONG_DIGIGAIN OV8858_REG_16BIT(0x350a)
  52. #define OV8858_LONG_DIGIGAIN_H_MASK 0x3fc0
  53. #define OV8858_LONG_DIGIGAIN_L_MASK 0x3f
  54. #define OV8858_LONG_DIGIGAIN_H_SHIFT 2
  55. #define OV8858_LONG_DIGIGAIN_MIN 0x0
  56. #define OV8858_LONG_DIGIGAIN_MAX 0x3fff
  57. #define OV8858_LONG_DIGIGAIN_STEP 1
  58. #define OV8858_LONG_DIGIGAIN_DEFAULT 0x200
  59. #define OV8858_REG_VTS OV8858_REG_16BIT(0x380e)
  60. #define OV8858_VTS_MAX 0x7fff
  61. #define OV8858_REG_TEST_PATTERN OV8858_REG_8BIT(0x5e00)
  62. #define OV8858_TEST_PATTERN_ENABLE 0x80
  63. #define OV8858_TEST_PATTERN_DISABLE 0x0
  64. #define REG_NULL 0xffff
  65. static const char * const ov8858_supply_names[] = {
  66. "avdd", /* Analog power */
  67. "dovdd", /* Digital I/O power */
  68. "dvdd", /* Digital core power */
  69. };
  70. struct regval {
  71. u16 addr;
  72. u8 val;
  73. };
  74. struct regval_modes {
  75. const struct regval *mode_2lanes;
  76. const struct regval *mode_4lanes;
  77. };
  78. struct ov8858_mode {
  79. u32 width;
  80. u32 height;
  81. u32 hts_def;
  82. u32 vts_def;
  83. u32 exp_def;
  84. const struct regval_modes reg_modes;
  85. };
  86. struct ov8858 {
  87. struct clk *xvclk;
  88. struct gpio_desc *reset_gpio;
  89. struct gpio_desc *pwdn_gpio;
  90. struct regulator_bulk_data supplies[ARRAY_SIZE(ov8858_supply_names)];
  91. struct v4l2_subdev subdev;
  92. struct media_pad pad;
  93. struct v4l2_ctrl_handler ctrl_handler;
  94. struct v4l2_ctrl *exposure;
  95. struct v4l2_ctrl *hblank;
  96. struct v4l2_ctrl *vblank;
  97. const struct regval *global_regs;
  98. unsigned int num_lanes;
  99. };
  100. static inline struct ov8858 *sd_to_ov8858(struct v4l2_subdev *sd)
  101. {
  102. return container_of(sd, struct ov8858, subdev);
  103. }
  104. static const struct regval ov8858_global_regs_r1a[] = {
  105. {0x0100, 0x00},
  106. {0x0100, 0x00},
  107. {0x0100, 0x00},
  108. {0x0100, 0x00},
  109. {0x0302, 0x1e},
  110. {0x0303, 0x00},
  111. {0x0304, 0x03},
  112. {0x030e, 0x00},
  113. {0x030f, 0x09},
  114. {0x0312, 0x01},
  115. {0x031e, 0x0c},
  116. {0x3600, 0x00},
  117. {0x3601, 0x00},
  118. {0x3602, 0x00},
  119. {0x3603, 0x00},
  120. {0x3604, 0x22},
  121. {0x3605, 0x30},
  122. {0x3606, 0x00},
  123. {0x3607, 0x20},
  124. {0x3608, 0x11},
  125. {0x3609, 0x28},
  126. {0x360a, 0x00},
  127. {0x360b, 0x06},
  128. {0x360c, 0xdc},
  129. {0x360d, 0x40},
  130. {0x360e, 0x0c},
  131. {0x360f, 0x20},
  132. {0x3610, 0x07},
  133. {0x3611, 0x20},
  134. {0x3612, 0x88},
  135. {0x3613, 0x80},
  136. {0x3614, 0x58},
  137. {0x3615, 0x00},
  138. {0x3616, 0x4a},
  139. {0x3617, 0xb0},
  140. {0x3618, 0x56},
  141. {0x3619, 0x70},
  142. {0x361a, 0x99},
  143. {0x361b, 0x00},
  144. {0x361c, 0x07},
  145. {0x361d, 0x00},
  146. {0x361e, 0x00},
  147. {0x361f, 0x00},
  148. {0x3638, 0xff},
  149. {0x3633, 0x0c},
  150. {0x3634, 0x0c},
  151. {0x3635, 0x0c},
  152. {0x3636, 0x0c},
  153. {0x3645, 0x13},
  154. {0x3646, 0x83},
  155. {0x364a, 0x07},
  156. {0x3015, 0x01},
  157. {0x3018, 0x32},
  158. {0x3020, 0x93},
  159. {0x3022, 0x01},
  160. {0x3031, 0x0a},
  161. {0x3034, 0x00},
  162. {0x3106, 0x01},
  163. {0x3305, 0xf1},
  164. {0x3308, 0x00},
  165. {0x3309, 0x28},
  166. {0x330a, 0x00},
  167. {0x330b, 0x20},
  168. {0x330c, 0x00},
  169. {0x330d, 0x00},
  170. {0x330e, 0x00},
  171. {0x330f, 0x40},
  172. {0x3307, 0x04},
  173. {0x3500, 0x00},
  174. {0x3501, 0x4d},
  175. {0x3502, 0x40},
  176. {0x3503, 0x00},
  177. {0x3505, 0x80},
  178. {0x3508, 0x04},
  179. {0x3509, 0x00},
  180. {0x350c, 0x00},
  181. {0x350d, 0x80},
  182. {0x3510, 0x00},
  183. {0x3511, 0x02},
  184. {0x3512, 0x00},
  185. {0x3700, 0x18},
  186. {0x3701, 0x0c},
  187. {0x3702, 0x28},
  188. {0x3703, 0x19},
  189. {0x3704, 0x14},
  190. {0x3705, 0x00},
  191. {0x3706, 0x35},
  192. {0x3707, 0x04},
  193. {0x3708, 0x24},
  194. {0x3709, 0x33},
  195. {0x370a, 0x00},
  196. {0x370b, 0xb5},
  197. {0x370c, 0x04},
  198. {0x3718, 0x12},
  199. {0x3719, 0x31},
  200. {0x3712, 0x42},
  201. {0x3714, 0x24},
  202. {0x371e, 0x19},
  203. {0x371f, 0x40},
  204. {0x3720, 0x05},
  205. {0x3721, 0x05},
  206. {0x3724, 0x06},
  207. {0x3725, 0x01},
  208. {0x3726, 0x06},
  209. {0x3728, 0x05},
  210. {0x3729, 0x02},
  211. {0x372a, 0x03},
  212. {0x372b, 0x53},
  213. {0x372c, 0xa3},
  214. {0x372d, 0x53},
  215. {0x372e, 0x06},
  216. {0x372f, 0x10},
  217. {0x3730, 0x01},
  218. {0x3731, 0x06},
  219. {0x3732, 0x14},
  220. {0x3733, 0x10},
  221. {0x3734, 0x40},
  222. {0x3736, 0x20},
  223. {0x373a, 0x05},
  224. {0x373b, 0x06},
  225. {0x373c, 0x0a},
  226. {0x373e, 0x03},
  227. {0x3755, 0x10},
  228. {0x3758, 0x00},
  229. {0x3759, 0x4c},
  230. {0x375a, 0x06},
  231. {0x375b, 0x13},
  232. {0x375c, 0x20},
  233. {0x375d, 0x02},
  234. {0x375e, 0x00},
  235. {0x375f, 0x14},
  236. {0x3768, 0x22},
  237. {0x3769, 0x44},
  238. {0x376a, 0x44},
  239. {0x3761, 0x00},
  240. {0x3762, 0x00},
  241. {0x3763, 0x00},
  242. {0x3766, 0xff},
  243. {0x376b, 0x00},
  244. {0x3772, 0x23},
  245. {0x3773, 0x02},
  246. {0x3774, 0x16},
  247. {0x3775, 0x12},
  248. {0x3776, 0x04},
  249. {0x3777, 0x00},
  250. {0x3778, 0x1b},
  251. {0x37a0, 0x44},
  252. {0x37a1, 0x3d},
  253. {0x37a2, 0x3d},
  254. {0x37a3, 0x00},
  255. {0x37a4, 0x00},
  256. {0x37a5, 0x00},
  257. {0x37a6, 0x00},
  258. {0x37a7, 0x44},
  259. {0x37a8, 0x4c},
  260. {0x37a9, 0x4c},
  261. {0x3760, 0x00},
  262. {0x376f, 0x01},
  263. {0x37aa, 0x44},
  264. {0x37ab, 0x2e},
  265. {0x37ac, 0x2e},
  266. {0x37ad, 0x33},
  267. {0x37ae, 0x0d},
  268. {0x37af, 0x0d},
  269. {0x37b0, 0x00},
  270. {0x37b1, 0x00},
  271. {0x37b2, 0x00},
  272. {0x37b3, 0x42},
  273. {0x37b4, 0x42},
  274. {0x37b5, 0x33},
  275. {0x37b6, 0x00},
  276. {0x37b7, 0x00},
  277. {0x37b8, 0x00},
  278. {0x37b9, 0xff},
  279. {0x3800, 0x00},
  280. {0x3801, 0x0c},
  281. {0x3802, 0x00},
  282. {0x3803, 0x0c},
  283. {0x3804, 0x0c},
  284. {0x3805, 0xd3},
  285. {0x3806, 0x09},
  286. {0x3807, 0xa3},
  287. {0x3808, 0x06},
  288. {0x3809, 0x60},
  289. {0x380a, 0x04},
  290. {0x380b, 0xc8},
  291. {0x380c, 0x07},
  292. {0x380d, 0x88},
  293. {0x380e, 0x04},
  294. {0x380f, 0xdc},
  295. {0x3810, 0x00},
  296. {0x3811, 0x04},
  297. {0x3813, 0x02},
  298. {0x3814, 0x03},
  299. {0x3815, 0x01},
  300. {0x3820, 0x00},
  301. {0x3821, 0x67},
  302. {0x382a, 0x03},
  303. {0x382b, 0x01},
  304. {0x3830, 0x08},
  305. {0x3836, 0x02},
  306. {0x3837, 0x18},
  307. {0x3841, 0xff},
  308. {0x3846, 0x48},
  309. {0x3d85, 0x14},
  310. {0x3f08, 0x08},
  311. {0x3f0a, 0x80},
  312. {0x4000, 0xf1},
  313. {0x4001, 0x10},
  314. {0x4005, 0x10},
  315. {0x4002, 0x27},
  316. {0x4009, 0x81},
  317. {0x400b, 0x0c},
  318. {0x401b, 0x00},
  319. {0x401d, 0x00},
  320. {0x4020, 0x00},
  321. {0x4021, 0x04},
  322. {0x4022, 0x04},
  323. {0x4023, 0xb9},
  324. {0x4024, 0x05},
  325. {0x4025, 0x2a},
  326. {0x4026, 0x05},
  327. {0x4027, 0x2b},
  328. {0x4028, 0x00},
  329. {0x4029, 0x02},
  330. {0x402a, 0x04},
  331. {0x402b, 0x04},
  332. {0x402c, 0x02},
  333. {0x402d, 0x02},
  334. {0x402e, 0x08},
  335. {0x402f, 0x02},
  336. {0x401f, 0x00},
  337. {0x4034, 0x3f},
  338. {0x403d, 0x04},
  339. {0x4300, 0xff},
  340. {0x4301, 0x00},
  341. {0x4302, 0x0f},
  342. {0x4316, 0x00},
  343. {0x4500, 0x38},
  344. {0x4503, 0x18},
  345. {0x4600, 0x00},
  346. {0x4601, 0xcb},
  347. {0x481f, 0x32},
  348. {0x4837, 0x16},
  349. {0x4850, 0x10},
  350. {0x4851, 0x32},
  351. {0x4b00, 0x2a},
  352. {0x4b0d, 0x00},
  353. {0x4d00, 0x04},
  354. {0x4d01, 0x18},
  355. {0x4d02, 0xc3},
  356. {0x4d03, 0xff},
  357. {0x4d04, 0xff},
  358. {0x4d05, 0xff},
  359. {0x5000, 0x7e},
  360. {0x5001, 0x01},
  361. {0x5002, 0x08},
  362. {0x5003, 0x20},
  363. {0x5046, 0x12},
  364. {0x5901, 0x00},
  365. {0x5e00, 0x00},
  366. {0x5e01, 0x41},
  367. {0x382d, 0x7f},
  368. {0x4825, 0x3a},
  369. {0x4826, 0x40},
  370. {0x4808, 0x25},
  371. {REG_NULL, 0x00},
  372. };
  373. static const struct regval ov8858_global_regs_r2a_2lane[] = {
  374. /*
  375. * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
  376. * v00_01_00 (05/29/2014) : initial setting
  377. * AM19 : 3617 <- 0xC0
  378. * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
  379. */
  380. {0x0103, 0x01}, /* software reset */
  381. {0x0100, 0x00}, /* software standby */
  382. {0x0302, 0x1e}, /* pll1_multi */
  383. {0x0303, 0x00}, /* pll1_divm */
  384. {0x0304, 0x03}, /* pll1_div_mipi */
  385. {0x030e, 0x02}, /* pll2_rdiv */
  386. {0x030f, 0x04}, /* pll2_divsp */
  387. {0x0312, 0x03}, /* pll2_pre_div0, pll2_r_divdac */
  388. {0x031e, 0x0c}, /* pll1_no_lat */
  389. {0x3600, 0x00},
  390. {0x3601, 0x00},
  391. {0x3602, 0x00},
  392. {0x3603, 0x00},
  393. {0x3604, 0x22},
  394. {0x3605, 0x20},
  395. {0x3606, 0x00},
  396. {0x3607, 0x20},
  397. {0x3608, 0x11},
  398. {0x3609, 0x28},
  399. {0x360a, 0x00},
  400. {0x360b, 0x05},
  401. {0x360c, 0xd4},
  402. {0x360d, 0x40},
  403. {0x360e, 0x0c},
  404. {0x360f, 0x20},
  405. {0x3610, 0x07},
  406. {0x3611, 0x20},
  407. {0x3612, 0x88},
  408. {0x3613, 0x80},
  409. {0x3614, 0x58},
  410. {0x3615, 0x00},
  411. {0x3616, 0x4a},
  412. {0x3617, 0x90},
  413. {0x3618, 0x5a},
  414. {0x3619, 0x70},
  415. {0x361a, 0x99},
  416. {0x361b, 0x0a},
  417. {0x361c, 0x07},
  418. {0x361d, 0x00},
  419. {0x361e, 0x00},
  420. {0x361f, 0x00},
  421. {0x3638, 0xff},
  422. {0x3633, 0x0f},
  423. {0x3634, 0x0f},
  424. {0x3635, 0x0f},
  425. {0x3636, 0x12},
  426. {0x3645, 0x13},
  427. {0x3646, 0x83},
  428. {0x364a, 0x07},
  429. {0x3015, 0x00},
  430. {0x3018, 0x32}, /* MIPI 2 lane */
  431. {0x3020, 0x93}, /* Clock switch output normal, pclk_div =/1 */
  432. {0x3022, 0x01}, /* pd_mipi enable when rst_sync */
  433. {0x3031, 0x0a}, /* MIPI 10-bit mode */
  434. {0x3034, 0x00},
  435. {0x3106, 0x01}, /* sclk_div, sclk_pre_div */
  436. {0x3305, 0xf1},
  437. {0x3308, 0x00},
  438. {0x3309, 0x28},
  439. {0x330a, 0x00},
  440. {0x330b, 0x20},
  441. {0x330c, 0x00},
  442. {0x330d, 0x00},
  443. {0x330e, 0x00},
  444. {0x330f, 0x40},
  445. {0x3307, 0x04},
  446. {0x3500, 0x00}, /* exposure H */
  447. {0x3501, 0x4d}, /* exposure M */
  448. {0x3502, 0x40}, /* exposure L */
  449. {0x3503, 0x80}, /* gain delay ?, exposure delay 1 frame, real gain */
  450. {0x3505, 0x80}, /* gain option */
  451. {0x3508, 0x02}, /* gain H */
  452. {0x3509, 0x00}, /* gain L */
  453. {0x350c, 0x00}, /* short gain H */
  454. {0x350d, 0x80}, /* short gain L */
  455. {0x3510, 0x00}, /* short exposure H */
  456. {0x3511, 0x02}, /* short exposure M */
  457. {0x3512, 0x00}, /* short exposure L */
  458. {0x3700, 0x18},
  459. {0x3701, 0x0c},
  460. {0x3702, 0x28},
  461. {0x3703, 0x19},
  462. {0x3704, 0x14},
  463. {0x3705, 0x00},
  464. {0x3706, 0x82},
  465. {0x3707, 0x04},
  466. {0x3708, 0x24},
  467. {0x3709, 0x33},
  468. {0x370a, 0x01},
  469. {0x370b, 0x82},
  470. {0x370c, 0x04},
  471. {0x3718, 0x12},
  472. {0x3719, 0x31},
  473. {0x3712, 0x42},
  474. {0x3714, 0x24},
  475. {0x371e, 0x19},
  476. {0x371f, 0x40},
  477. {0x3720, 0x05},
  478. {0x3721, 0x05},
  479. {0x3724, 0x06},
  480. {0x3725, 0x01},
  481. {0x3726, 0x06},
  482. {0x3728, 0x05},
  483. {0x3729, 0x02},
  484. {0x372a, 0x03},
  485. {0x372b, 0x53},
  486. {0x372c, 0xa3},
  487. {0x372d, 0x53},
  488. {0x372e, 0x06},
  489. {0x372f, 0x10},
  490. {0x3730, 0x01},
  491. {0x3731, 0x06},
  492. {0x3732, 0x14},
  493. {0x3733, 0x10},
  494. {0x3734, 0x40},
  495. {0x3736, 0x20},
  496. {0x373a, 0x05},
  497. {0x373b, 0x06},
  498. {0x373c, 0x0a},
  499. {0x373e, 0x03},
  500. {0x3750, 0x0a},
  501. {0x3751, 0x0e},
  502. {0x3755, 0x10},
  503. {0x3758, 0x00},
  504. {0x3759, 0x4c},
  505. {0x375a, 0x06},
  506. {0x375b, 0x13},
  507. {0x375c, 0x20},
  508. {0x375d, 0x02},
  509. {0x375e, 0x00},
  510. {0x375f, 0x14},
  511. {0x3768, 0x22},
  512. {0x3769, 0x44},
  513. {0x376a, 0x44},
  514. {0x3761, 0x00},
  515. {0x3762, 0x00},
  516. {0x3763, 0x00},
  517. {0x3766, 0xff},
  518. {0x376b, 0x00},
  519. {0x3772, 0x23},
  520. {0x3773, 0x02},
  521. {0x3774, 0x16},
  522. {0x3775, 0x12},
  523. {0x3776, 0x04},
  524. {0x3777, 0x00},
  525. {0x3778, 0x17},
  526. {0x37a0, 0x44},
  527. {0x37a1, 0x3d},
  528. {0x37a2, 0x3d},
  529. {0x37a3, 0x00},
  530. {0x37a4, 0x00},
  531. {0x37a5, 0x00},
  532. {0x37a6, 0x00},
  533. {0x37a7, 0x44},
  534. {0x37a8, 0x4c},
  535. {0x37a9, 0x4c},
  536. {0x3760, 0x00},
  537. {0x376f, 0x01},
  538. {0x37aa, 0x44},
  539. {0x37ab, 0x2e},
  540. {0x37ac, 0x2e},
  541. {0x37ad, 0x33},
  542. {0x37ae, 0x0d},
  543. {0x37af, 0x0d},
  544. {0x37b0, 0x00},
  545. {0x37b1, 0x00},
  546. {0x37b2, 0x00},
  547. {0x37b3, 0x42},
  548. {0x37b4, 0x42},
  549. {0x37b5, 0x31},
  550. {0x37b6, 0x00},
  551. {0x37b7, 0x00},
  552. {0x37b8, 0x00},
  553. {0x37b9, 0xff},
  554. {0x3800, 0x00}, /* x start H */
  555. {0x3801, 0x0c}, /* x start L */
  556. {0x3802, 0x00}, /* y start H */
  557. {0x3803, 0x0c}, /* y start L */
  558. {0x3804, 0x0c}, /* x end H */
  559. {0x3805, 0xd3}, /* x end L */
  560. {0x3806, 0x09}, /* y end H */
  561. {0x3807, 0xa3}, /* y end L */
  562. {0x3808, 0x06}, /* x output size H */
  563. {0x3809, 0x60}, /* x output size L */
  564. {0x380a, 0x04}, /* y output size H */
  565. {0x380b, 0xc8}, /* y output size L */
  566. {0x380c, 0x07}, /* HTS H */
  567. {0x380d, 0x88}, /* HTS L */
  568. {0x380e, 0x04}, /* VTS H */
  569. {0x380f, 0xdc}, /* VTS L */
  570. {0x3810, 0x00}, /* ISP x win H */
  571. {0x3811, 0x04}, /* ISP x win L */
  572. {0x3813, 0x02}, /* ISP y win L */
  573. {0x3814, 0x03}, /* x odd inc */
  574. {0x3815, 0x01}, /* x even inc */
  575. {0x3820, 0x00}, /* vflip off */
  576. {0x3821, 0x67}, /* mirror on, bin on */
  577. {0x382a, 0x03}, /* y odd inc */
  578. {0x382b, 0x01}, /* y even inc */
  579. {0x3830, 0x08},
  580. {0x3836, 0x02},
  581. {0x3837, 0x18},
  582. {0x3841, 0xff}, /* window auto size enable */
  583. {0x3846, 0x48},
  584. {0x3d85, 0x16}, /* OTP power up load data enable with BIST */
  585. {0x3d8c, 0x73}, /* OTP setting start High */
  586. {0x3d8d, 0xde}, /* OTP setting start Low */
  587. {0x3f08, 0x08},
  588. {0x3f0a, 0x00},
  589. {0x4000, 0xf1}, /* out_range_trig, format_chg_trig */
  590. {0x4001, 0x10}, /* total 128 black column */
  591. {0x4005, 0x10}, /* BLC target L */
  592. {0x4002, 0x27}, /* value used to limit BLC offset */
  593. {0x4009, 0x81}, /* final BLC offset limitation enable */
  594. {0x400b, 0x0c}, /* DCBLC on, DCBLC manual mode on */
  595. {0x401b, 0x00}, /* zero line R coefficient */
  596. {0x401d, 0x00}, /* zoro line T coefficient */
  597. {0x4020, 0x00}, /* Anchor left start H */
  598. {0x4021, 0x04}, /* Anchor left start L */
  599. {0x4022, 0x06}, /* Anchor left end H */
  600. {0x4023, 0x00}, /* Anchor left end L */
  601. {0x4024, 0x0f}, /* Anchor right start H */
  602. {0x4025, 0x2a}, /* Anchor right start L */
  603. {0x4026, 0x0f}, /* Anchor right end H */
  604. {0x4027, 0x2b}, /* Anchor right end L */
  605. {0x4028, 0x00}, /* top zero line start */
  606. {0x4029, 0x02}, /* top zero line number */
  607. {0x402a, 0x04}, /* top black line start */
  608. {0x402b, 0x04}, /* top black line number */
  609. {0x402c, 0x00}, /* bottom zero line start */
  610. {0x402d, 0x02}, /* bottom zoro line number */
  611. {0x402e, 0x04}, /* bottom black line start */
  612. {0x402f, 0x04}, /* bottom black line number */
  613. {0x401f, 0x00}, /* interpolation x/y disable, Anchor one disable */
  614. {0x4034, 0x3f},
  615. {0x403d, 0x04}, /* md_precision_en */
  616. {0x4300, 0xff}, /* clip max H */
  617. {0x4301, 0x00}, /* clip min H */
  618. {0x4302, 0x0f}, /* clip min L, clip max L */
  619. {0x4316, 0x00},
  620. {0x4500, 0x58},
  621. {0x4503, 0x18},
  622. {0x4600, 0x00},
  623. {0x4601, 0xcb},
  624. {0x481f, 0x32}, /* clk prepare min */
  625. {0x4837, 0x16}, /* global timing */
  626. {0x4850, 0x10}, /* lane 1 = 1, lane 0 = 0 */
  627. {0x4851, 0x32}, /* lane 3 = 3, lane 2 = 2 */
  628. {0x4b00, 0x2a},
  629. {0x4b0d, 0x00},
  630. {0x4d00, 0x04}, /* temperature sensor */
  631. {0x4d01, 0x18},
  632. {0x4d02, 0xc3},
  633. {0x4d03, 0xff},
  634. {0x4d04, 0xff},
  635. {0x4d05, 0xff}, /* temperature sensor */
  636. {0x5000, 0xfe}, /* lenc on, slave/master AWB gain/statistics enable */
  637. {0x5001, 0x01}, /* BLC on */
  638. {0x5002, 0x08}, /* H scale off, WBMATCH off, OTP_DPC */
  639. {0x5003, 0x20}, /* DPC_DBC buffer control enable, WB */
  640. {0x501e, 0x93}, /* enable digital gain */
  641. {0x5046, 0x12},
  642. {0x5780, 0x3e}, /* DPC */
  643. {0x5781, 0x0f},
  644. {0x5782, 0x44},
  645. {0x5783, 0x02},
  646. {0x5784, 0x01},
  647. {0x5785, 0x00},
  648. {0x5786, 0x00},
  649. {0x5787, 0x04},
  650. {0x5788, 0x02},
  651. {0x5789, 0x0f},
  652. {0x578a, 0xfd},
  653. {0x578b, 0xf5},
  654. {0x578c, 0xf5},
  655. {0x578d, 0x03},
  656. {0x578e, 0x08},
  657. {0x578f, 0x0c},
  658. {0x5790, 0x08},
  659. {0x5791, 0x04},
  660. {0x5792, 0x00},
  661. {0x5793, 0x52},
  662. {0x5794, 0xa3}, /* DPC */
  663. {0x5871, 0x0d}, /* Lenc */
  664. {0x5870, 0x18},
  665. {0x586e, 0x10},
  666. {0x586f, 0x08},
  667. {0x58f7, 0x01},
  668. {0x58f8, 0x3d}, /* Lenc */
  669. {0x5901, 0x00}, /* H skip off, V skip off */
  670. {0x5b00, 0x02}, /* OTP DPC start address */
  671. {0x5b01, 0x10}, /* OTP DPC start address */
  672. {0x5b02, 0x03}, /* OTP DPC end address */
  673. {0x5b03, 0xcf}, /* OTP DPC end address */
  674. {0x5b05, 0x6c}, /* recover method = 2b11, */
  675. {0x5e00, 0x00}, /* use 0x3ff to test pattern off */
  676. {0x5e01, 0x41}, /* window cut enable */
  677. {0x382d, 0x7f},
  678. {0x4825, 0x3a}, /* lpx_p_min */
  679. {0x4826, 0x40}, /* hs_prepare_min */
  680. {0x4808, 0x25}, /* wake up delay in 1/1024 s */
  681. {0x3763, 0x18},
  682. {0x3768, 0xcc},
  683. {0x470b, 0x28},
  684. {0x4202, 0x00},
  685. {0x400d, 0x10}, /* BLC offset trigger L */
  686. {0x4040, 0x04}, /* BLC gain th2 */
  687. {0x403e, 0x04}, /* BLC gain th1 */
  688. {0x4041, 0xc6}, /* BLC */
  689. {0x3007, 0x80},
  690. {0x400a, 0x01},
  691. {REG_NULL, 0x00},
  692. };
  693. /*
  694. * Xclk 24Mhz
  695. * max_framerate 30fps
  696. * mipi_datarate per lane 720Mbps
  697. */
  698. static const struct regval ov8858_1632x1224_regs_2lane[] = {
  699. /*
  700. * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
  701. * v00_01_00 (05/29/2014) : initial setting
  702. * AM19 : 3617 <- 0xC0
  703. * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
  704. */
  705. {0x0100, 0x00},
  706. {0x3501, 0x4d}, /* exposure M */
  707. {0x3502, 0x40}, /* exposure L */
  708. {0x3778, 0x17},
  709. {0x3808, 0x06}, /* x output size H */
  710. {0x3809, 0x60}, /* x output size L */
  711. {0x380a, 0x04}, /* y output size H */
  712. {0x380b, 0xc8}, /* y output size L */
  713. {0x380c, 0x07}, /* HTS H */
  714. {0x380d, 0x88}, /* HTS L */
  715. {0x380e, 0x04}, /* VTS H */
  716. {0x380f, 0xdc}, /* VTS L */
  717. {0x3814, 0x03}, /* x odd inc */
  718. {0x3821, 0x67}, /* mirror on, bin on */
  719. {0x382a, 0x03}, /* y odd inc */
  720. {0x3830, 0x08},
  721. {0x3836, 0x02},
  722. {0x3f0a, 0x00},
  723. {0x4001, 0x10}, /* total 128 black column */
  724. {0x4022, 0x06}, /* Anchor left end H */
  725. {0x4023, 0x00}, /* Anchor left end L */
  726. {0x4025, 0x2a}, /* Anchor right start L */
  727. {0x4027, 0x2b}, /* Anchor right end L */
  728. {0x402b, 0x04}, /* top black line number */
  729. {0x402f, 0x04}, /* bottom black line number */
  730. {0x4500, 0x58},
  731. {0x4600, 0x00},
  732. {0x4601, 0xcb},
  733. {0x382d, 0x7f},
  734. {0x0100, 0x01},
  735. {REG_NULL, 0x00},
  736. };
  737. /*
  738. * Xclk 24Mhz
  739. * max_framerate 15fps
  740. * mipi_datarate per lane 720Mbps
  741. */
  742. static const struct regval ov8858_3264x2448_regs_2lane[] = {
  743. {0x0100, 0x00},
  744. {0x3501, 0x9a}, /* exposure M */
  745. {0x3502, 0x20}, /* exposure L */
  746. {0x3778, 0x1a},
  747. {0x3808, 0x0c}, /* x output size H */
  748. {0x3809, 0xc0}, /* x output size L */
  749. {0x380a, 0x09}, /* y output size H */
  750. {0x380b, 0x90}, /* y output size L */
  751. {0x380c, 0x07}, /* HTS H */
  752. {0x380d, 0x94}, /* HTS L */
  753. {0x380e, 0x09}, /* VTS H */
  754. {0x380f, 0xaa}, /* VTS L */
  755. {0x3814, 0x01}, /* x odd inc */
  756. {0x3821, 0x46}, /* mirror on, bin off */
  757. {0x382a, 0x01}, /* y odd inc */
  758. {0x3830, 0x06},
  759. {0x3836, 0x01},
  760. {0x3f0a, 0x00},
  761. {0x4001, 0x00}, /* total 256 black column */
  762. {0x4022, 0x0c}, /* Anchor left end H */
  763. {0x4023, 0x60}, /* Anchor left end L */
  764. {0x4025, 0x36}, /* Anchor right start L */
  765. {0x4027, 0x37}, /* Anchor right end L */
  766. {0x402b, 0x08}, /* top black line number */
  767. {0x402f, 0x08}, /* bottom black line number */
  768. {0x4500, 0x58},
  769. {0x4600, 0x01},
  770. {0x4601, 0x97},
  771. {0x382d, 0xff},
  772. {REG_NULL, 0x00},
  773. };
  774. static const struct regval ov8858_global_regs_r2a_4lane[] = {
  775. /*
  776. * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
  777. * v00_01_00 (05/29/2014) : initial setting
  778. * AM19 : 3617 <- 0xC0
  779. * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
  780. */
  781. {0x0103, 0x01}, /* software reset for OVTATool only */
  782. {0x0103, 0x01}, /* software reset */
  783. {0x0100, 0x00}, /* software standby */
  784. {0x0302, 0x1e}, /* pll1_multi */
  785. {0x0303, 0x00}, /* pll1_divm */
  786. {0x0304, 0x03}, /* pll1_div_mipi */
  787. {0x030e, 0x00}, /* pll2_rdiv */
  788. {0x030f, 0x04}, /* pll2_divsp */
  789. {0x0312, 0x01}, /* pll2_pre_div0, pll2_r_divdac */
  790. {0x031e, 0x0c}, /* pll1_no_lat */
  791. {0x3600, 0x00},
  792. {0x3601, 0x00},
  793. {0x3602, 0x00},
  794. {0x3603, 0x00},
  795. {0x3604, 0x22},
  796. {0x3605, 0x20},
  797. {0x3606, 0x00},
  798. {0x3607, 0x20},
  799. {0x3608, 0x11},
  800. {0x3609, 0x28},
  801. {0x360a, 0x00},
  802. {0x360b, 0x05},
  803. {0x360c, 0xd4},
  804. {0x360d, 0x40},
  805. {0x360e, 0x0c},
  806. {0x360f, 0x20},
  807. {0x3610, 0x07},
  808. {0x3611, 0x20},
  809. {0x3612, 0x88},
  810. {0x3613, 0x80},
  811. {0x3614, 0x58},
  812. {0x3615, 0x00},
  813. {0x3616, 0x4a},
  814. {0x3617, 0x90},
  815. {0x3618, 0x5a},
  816. {0x3619, 0x70},
  817. {0x361a, 0x99},
  818. {0x361b, 0x0a},
  819. {0x361c, 0x07},
  820. {0x361d, 0x00},
  821. {0x361e, 0x00},
  822. {0x361f, 0x00},
  823. {0x3638, 0xff},
  824. {0x3633, 0x0f},
  825. {0x3634, 0x0f},
  826. {0x3635, 0x0f},
  827. {0x3636, 0x12},
  828. {0x3645, 0x13},
  829. {0x3646, 0x83},
  830. {0x364a, 0x07},
  831. {0x3015, 0x01},
  832. {0x3018, 0x72}, /* MIPI 4 lane */
  833. {0x3020, 0x93}, /* Clock switch output normal, pclk_div =/1 */
  834. {0x3022, 0x01}, /* pd_mipi enable when rst_sync */
  835. {0x3031, 0x0a}, /* MIPI 10-bit mode */
  836. {0x3034, 0x00},
  837. {0x3106, 0x01}, /* sclk_div, sclk_pre_div */
  838. {0x3305, 0xf1},
  839. {0x3308, 0x00},
  840. {0x3309, 0x28},
  841. {0x330a, 0x00},
  842. {0x330b, 0x20},
  843. {0x330c, 0x00},
  844. {0x330d, 0x00},
  845. {0x330e, 0x00},
  846. {0x330f, 0x40},
  847. {0x3307, 0x04},
  848. {0x3500, 0x00}, /* exposure H */
  849. {0x3501, 0x4d}, /* exposure M */
  850. {0x3502, 0x40}, /* exposure L */
  851. {0x3503, 0x80}, /* gain delay ?, exposure delay 1 frame, real gain */
  852. {0x3505, 0x80}, /* gain option */
  853. {0x3508, 0x02}, /* gain H */
  854. {0x3509, 0x00}, /* gain L */
  855. {0x350c, 0x00}, /* short gain H */
  856. {0x350d, 0x80}, /* short gain L */
  857. {0x3510, 0x00}, /* short exposure H */
  858. {0x3511, 0x02}, /* short exposure M */
  859. {0x3512, 0x00}, /* short exposure L */
  860. {0x3700, 0x30},
  861. {0x3701, 0x18},
  862. {0x3702, 0x50},
  863. {0x3703, 0x32},
  864. {0x3704, 0x28},
  865. {0x3705, 0x00},
  866. {0x3706, 0x82},
  867. {0x3707, 0x08},
  868. {0x3708, 0x48},
  869. {0x3709, 0x66},
  870. {0x370a, 0x01},
  871. {0x370b, 0x82},
  872. {0x370c, 0x07},
  873. {0x3718, 0x14},
  874. {0x3719, 0x31},
  875. {0x3712, 0x44},
  876. {0x3714, 0x24},
  877. {0x371e, 0x31},
  878. {0x371f, 0x7f},
  879. {0x3720, 0x0a},
  880. {0x3721, 0x0a},
  881. {0x3724, 0x0c},
  882. {0x3725, 0x02},
  883. {0x3726, 0x0c},
  884. {0x3728, 0x0a},
  885. {0x3729, 0x03},
  886. {0x372a, 0x06},
  887. {0x372b, 0xa6},
  888. {0x372c, 0xa6},
  889. {0x372d, 0xa6},
  890. {0x372e, 0x0c},
  891. {0x372f, 0x20},
  892. {0x3730, 0x02},
  893. {0x3731, 0x0c},
  894. {0x3732, 0x28},
  895. {0x3733, 0x10},
  896. {0x3734, 0x40},
  897. {0x3736, 0x30},
  898. {0x373a, 0x0a},
  899. {0x373b, 0x0b},
  900. {0x373c, 0x14},
  901. {0x373e, 0x06},
  902. {0x3750, 0x0a},
  903. {0x3751, 0x0e},
  904. {0x3755, 0x10},
  905. {0x3758, 0x00},
  906. {0x3759, 0x4c},
  907. {0x375a, 0x0c},
  908. {0x375b, 0x26},
  909. {0x375c, 0x20},
  910. {0x375d, 0x04},
  911. {0x375e, 0x00},
  912. {0x375f, 0x28},
  913. {0x3768, 0x22},
  914. {0x3769, 0x44},
  915. {0x376a, 0x44},
  916. {0x3761, 0x00},
  917. {0x3762, 0x00},
  918. {0x3763, 0x00},
  919. {0x3766, 0xff},
  920. {0x376b, 0x00},
  921. {0x3772, 0x46},
  922. {0x3773, 0x04},
  923. {0x3774, 0x2c},
  924. {0x3775, 0x13},
  925. {0x3776, 0x08},
  926. {0x3777, 0x00},
  927. {0x3778, 0x17},
  928. {0x37a0, 0x88},
  929. {0x37a1, 0x7a},
  930. {0x37a2, 0x7a},
  931. {0x37a3, 0x00},
  932. {0x37a4, 0x00},
  933. {0x37a5, 0x00},
  934. {0x37a6, 0x00},
  935. {0x37a7, 0x88},
  936. {0x37a8, 0x98},
  937. {0x37a9, 0x98},
  938. {0x3760, 0x00},
  939. {0x376f, 0x01},
  940. {0x37aa, 0x88},
  941. {0x37ab, 0x5c},
  942. {0x37ac, 0x5c},
  943. {0x37ad, 0x55},
  944. {0x37ae, 0x19},
  945. {0x37af, 0x19},
  946. {0x37b0, 0x00},
  947. {0x37b1, 0x00},
  948. {0x37b2, 0x00},
  949. {0x37b3, 0x84},
  950. {0x37b4, 0x84},
  951. {0x37b5, 0x60},
  952. {0x37b6, 0x00},
  953. {0x37b7, 0x00},
  954. {0x37b8, 0x00},
  955. {0x37b9, 0xff},
  956. {0x3800, 0x00}, /* x start H */
  957. {0x3801, 0x0c}, /* x start L */
  958. {0x3802, 0x00}, /* y start H */
  959. {0x3803, 0x0c}, /* y start L */
  960. {0x3804, 0x0c}, /* x end H */
  961. {0x3805, 0xd3}, /* x end L */
  962. {0x3806, 0x09}, /* y end H */
  963. {0x3807, 0xa3}, /* y end L */
  964. {0x3808, 0x06}, /* x output size H */
  965. {0x3809, 0x60}, /* x output size L */
  966. {0x380a, 0x04}, /* y output size H */
  967. {0x380b, 0xc8}, /* y output size L */
  968. {0x380c, 0x07}, /* HTS H */
  969. {0x380d, 0x88}, /* HTS L */
  970. {0x380e, 0x04}, /* VTS H */
  971. {0x380f, 0xdc}, /* VTS L */
  972. {0x3810, 0x00}, /* ISP x win H */
  973. {0x3811, 0x04}, /* ISP x win L */
  974. {0x3813, 0x02}, /* ISP y win L */
  975. {0x3814, 0x03}, /* x odd inc */
  976. {0x3815, 0x01}, /* x even inc */
  977. {0x3820, 0x00}, /* vflip off */
  978. {0x3821, 0x67}, /* mirror on, bin o */
  979. {0x382a, 0x03}, /* y odd inc */
  980. {0x382b, 0x01}, /* y even inc */
  981. {0x3830, 0x08},
  982. {0x3836, 0x02},
  983. {0x3837, 0x18},
  984. {0x3841, 0xff}, /* window auto size enable */
  985. {0x3846, 0x48},
  986. {0x3d85, 0x16}, /* OTP power up load data/setting enable */
  987. {0x3d8c, 0x73}, /* OTP setting start High */
  988. {0x3d8d, 0xde}, /* OTP setting start Low */
  989. {0x3f08, 0x10},
  990. {0x3f0a, 0x00},
  991. {0x4000, 0xf1}, /* out_range/format_chg/gain/exp_chg trig enable */
  992. {0x4001, 0x10}, /* total 128 black column */
  993. {0x4005, 0x10}, /* BLC target L */
  994. {0x4002, 0x27}, /* value used to limit BLC offset */
  995. {0x4009, 0x81}, /* final BLC offset limitation enable */
  996. {0x400b, 0x0c}, /* DCBLC on, DCBLC manual mode on */
  997. {0x401b, 0x00}, /* zero line R coefficient */
  998. {0x401d, 0x00}, /* zoro line T coefficient */
  999. {0x4020, 0x00}, /* Anchor left start H */
  1000. {0x4021, 0x04}, /* Anchor left start L */
  1001. {0x4022, 0x06}, /* Anchor left end H */
  1002. {0x4023, 0x00}, /* Anchor left end L */
  1003. {0x4024, 0x0f}, /* Anchor right start H */
  1004. {0x4025, 0x2a}, /* Anchor right start L */
  1005. {0x4026, 0x0f}, /* Anchor right end H */
  1006. {0x4027, 0x2b}, /* Anchor right end L */
  1007. {0x4028, 0x00}, /* top zero line start */
  1008. {0x4029, 0x02}, /* top zero line number */
  1009. {0x402a, 0x04}, /* top black line start */
  1010. {0x402b, 0x04}, /* top black line number */
  1011. {0x402c, 0x00}, /* bottom zero line start */
  1012. {0x402d, 0x02}, /* bottom zoro line number */
  1013. {0x402e, 0x04}, /* bottom black line start */
  1014. {0x402f, 0x04}, /* bottom black line number */
  1015. {0x401f, 0x00}, /* interpolation x/y disable, Anchor one disable */
  1016. {0x4034, 0x3f},
  1017. {0x403d, 0x04}, /* md_precision_en */
  1018. {0x4300, 0xff}, /* clip max H */
  1019. {0x4301, 0x00}, /* clip min H */
  1020. {0x4302, 0x0f}, /* clip min L, clip max L */
  1021. {0x4316, 0x00},
  1022. {0x4500, 0x58},
  1023. {0x4503, 0x18},
  1024. {0x4600, 0x00},
  1025. {0x4601, 0xcb},
  1026. {0x481f, 0x32}, /* clk prepare min */
  1027. {0x4837, 0x16}, /* global timing */
  1028. {0x4850, 0x10}, /* lane 1 = 1, lane 0 = 0 */
  1029. {0x4851, 0x32}, /* lane 3 = 3, lane 2 = 2 */
  1030. {0x4b00, 0x2a},
  1031. {0x4b0d, 0x00},
  1032. {0x4d00, 0x04}, /* temperature sensor */
  1033. {0x4d01, 0x18},
  1034. {0x4d02, 0xc3},
  1035. {0x4d03, 0xff},
  1036. {0x4d04, 0xff},
  1037. {0x4d05, 0xff}, /* temperature sensor */
  1038. {0x5000, 0xfe}, /* lenc on, slave/master AWB gain/statistics enable */
  1039. {0x5001, 0x01}, /* BLC on */
  1040. {0x5002, 0x08}, /* WBMATCH sensor's gain, H scale/WBMATCH/OTP_DPC off */
  1041. {0x5003, 0x20}, /* DPC_DBC buffer control enable, WB */
  1042. {0x501e, 0x93}, /* enable digital gain */
  1043. {0x5046, 0x12},
  1044. {0x5780, 0x3e}, /* DPC */
  1045. {0x5781, 0x0f},
  1046. {0x5782, 0x44},
  1047. {0x5783, 0x02},
  1048. {0x5784, 0x01},
  1049. {0x5785, 0x00},
  1050. {0x5786, 0x00},
  1051. {0x5787, 0x04},
  1052. {0x5788, 0x02},
  1053. {0x5789, 0x0f},
  1054. {0x578a, 0xfd},
  1055. {0x578b, 0xf5},
  1056. {0x578c, 0xf5},
  1057. {0x578d, 0x03},
  1058. {0x578e, 0x08},
  1059. {0x578f, 0x0c},
  1060. {0x5790, 0x08},
  1061. {0x5791, 0x04},
  1062. {0x5792, 0x00},
  1063. {0x5793, 0x52},
  1064. {0x5794, 0xa3}, /* DPC */
  1065. {0x5871, 0x0d}, /* Lenc */
  1066. {0x5870, 0x18},
  1067. {0x586e, 0x10},
  1068. {0x586f, 0x08},
  1069. {0x58f7, 0x01},
  1070. {0x58f8, 0x3d}, /* Lenc */
  1071. {0x5901, 0x00}, /* H skip off, V skip off */
  1072. {0x5b00, 0x02}, /* OTP DPC start address */
  1073. {0x5b01, 0x10}, /* OTP DPC start address */
  1074. {0x5b02, 0x03}, /* OTP DPC end address */
  1075. {0x5b03, 0xcf}, /* OTP DPC end address */
  1076. {0x5b05, 0x6c}, /* recover method = 2b11 */
  1077. {0x5e00, 0x00}, /* use 0x3ff to test pattern off */
  1078. {0x5e01, 0x41}, /* window cut enable */
  1079. {0x382d, 0x7f},
  1080. {0x4825, 0x3a}, /* lpx_p_min */
  1081. {0x4826, 0x40}, /* hs_prepare_min */
  1082. {0x4808, 0x25}, /* wake up delay in 1/1024 s */
  1083. {0x3763, 0x18},
  1084. {0x3768, 0xcc},
  1085. {0x470b, 0x28},
  1086. {0x4202, 0x00},
  1087. {0x400d, 0x10}, /* BLC offset trigger L */
  1088. {0x4040, 0x04}, /* BLC gain th2 */
  1089. {0x403e, 0x04}, /* BLC gain th1 */
  1090. {0x4041, 0xc6}, /* BLC */
  1091. {0x3007, 0x80},
  1092. {0x400a, 0x01},
  1093. {REG_NULL, 0x00},
  1094. };
  1095. /*
  1096. * Xclk 24Mhz
  1097. * max_framerate 60fps
  1098. * mipi_datarate per lane 720Mbps
  1099. */
  1100. static const struct regval ov8858_1632x1224_regs_4lane[] = {
  1101. {0x0100, 0x00},
  1102. {0x3501, 0x4d}, /* exposure M */
  1103. {0x3502, 0x40}, /* exposure L */
  1104. {0x3808, 0x06}, /* x output size H */
  1105. {0x3809, 0x60}, /* x output size L */
  1106. {0x380a, 0x04}, /* y output size H */
  1107. {0x380b, 0xc8}, /* y output size L */
  1108. {0x380c, 0x07}, /* HTS H */
  1109. {0x380d, 0x88}, /* HTS L */
  1110. {0x380e, 0x04}, /* VTS H */
  1111. {0x380f, 0xdc}, /* VTS L */
  1112. {0x3814, 0x03}, /* x odd inc */
  1113. {0x3821, 0x67}, /* mirror on, bin on */
  1114. {0x382a, 0x03}, /* y odd inc */
  1115. {0x3830, 0x08},
  1116. {0x3836, 0x02},
  1117. {0x3f0a, 0x00},
  1118. {0x4001, 0x10}, /* total 128 black column */
  1119. {0x4022, 0x06}, /* Anchor left end H */
  1120. {0x4023, 0x00}, /* Anchor left end L */
  1121. {0x4025, 0x2a}, /* Anchor right start L */
  1122. {0x4027, 0x2b}, /* Anchor right end L */
  1123. {0x402b, 0x04}, /* top black line number */
  1124. {0x402f, 0x04}, /* bottom black line number */
  1125. {0x4500, 0x58},
  1126. {0x4600, 0x00},
  1127. {0x4601, 0xcb},
  1128. {0x382d, 0x7f},
  1129. {0x0100, 0x01},
  1130. {REG_NULL, 0x00},
  1131. };
  1132. /*
  1133. * Xclk 24Mhz
  1134. * max_framerate 30fps
  1135. * mipi_datarate per lane 720Mbps
  1136. */
  1137. static const struct regval ov8858_3264x2448_regs_4lane[] = {
  1138. {0x0100, 0x00},
  1139. {0x3501, 0x9a}, /* exposure M */
  1140. {0x3502, 0x20}, /* exposure L */
  1141. {0x3808, 0x0c}, /* x output size H */
  1142. {0x3809, 0xc0}, /* x output size L */
  1143. {0x380a, 0x09}, /* y output size H */
  1144. {0x380b, 0x90}, /* y output size L */
  1145. {0x380c, 0x07}, /* HTS H */
  1146. {0x380d, 0x94}, /* HTS L */
  1147. {0x380e, 0x09}, /* VTS H */
  1148. {0x380f, 0xaa}, /* VTS L */
  1149. {0x3814, 0x01}, /* x odd inc */
  1150. {0x3821, 0x46}, /* mirror on, bin off */
  1151. {0x382a, 0x01}, /* y odd inc */
  1152. {0x3830, 0x06},
  1153. {0x3836, 0x01},
  1154. {0x3f0a, 0x00},
  1155. {0x4001, 0x00}, /* total 256 black column */
  1156. {0x4022, 0x0c}, /* Anchor left end H */
  1157. {0x4023, 0x60}, /* Anchor left end L */
  1158. {0x4025, 0x36}, /* Anchor right start L */
  1159. {0x4027, 0x37}, /* Anchor right end L */
  1160. {0x402b, 0x08}, /* top black line number */
  1161. {0x402f, 0x08}, /* interpolation x/y disable, Anchor one disable */
  1162. {0x4500, 0x58},
  1163. {0x4600, 0x01},
  1164. {0x4601, 0x97},
  1165. {0x382d, 0xff},
  1166. {REG_NULL, 0x00},
  1167. };
  1168. static const struct ov8858_mode ov8858_modes[] = {
  1169. {
  1170. .width = 3264,
  1171. .height = 2448,
  1172. .exp_def = 2464,
  1173. .hts_def = 1940 * 2,
  1174. .vts_def = 2472,
  1175. .reg_modes = {
  1176. .mode_2lanes = ov8858_3264x2448_regs_2lane,
  1177. .mode_4lanes = ov8858_3264x2448_regs_4lane,
  1178. },
  1179. },
  1180. {
  1181. .width = 1632,
  1182. .height = 1224,
  1183. .exp_def = 1232,
  1184. .hts_def = 1928 * 2,
  1185. .vts_def = 1244,
  1186. .reg_modes = {
  1187. .mode_2lanes = ov8858_1632x1224_regs_2lane,
  1188. .mode_4lanes = ov8858_1632x1224_regs_4lane,
  1189. },
  1190. },
  1191. };
  1192. static const s64 link_freq_menu_items[] = {
  1193. OV8858_LINK_FREQ
  1194. };
  1195. static const char * const ov8858_test_pattern_menu[] = {
  1196. "Disabled",
  1197. "Vertical Color Bar Type 1",
  1198. "Vertical Color Bar Type 2",
  1199. "Vertical Color Bar Type 3",
  1200. "Vertical Color Bar Type 4"
  1201. };
  1202. /* ----------------------------------------------------------------------------
  1203. * HW access
  1204. */
  1205. static int ov8858_write(struct ov8858 *ov8858, u32 reg, u32 val, int *err)
  1206. {
  1207. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1208. unsigned int len = (reg >> OV8858_REG_SIZE_SHIFT) & 3;
  1209. u16 addr = reg & OV8858_REG_ADDR_MASK;
  1210. u8 buf[6];
  1211. int ret;
  1212. if (err && *err)
  1213. return *err;
  1214. put_unaligned_be16(addr, buf);
  1215. put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
  1216. ret = i2c_master_send(client, buf, len + 2);
  1217. if (ret != len + 2) {
  1218. ret = ret < 0 ? ret : -EIO;
  1219. if (err)
  1220. *err = ret;
  1221. dev_err(&client->dev,
  1222. "Failed to write reg %u: %d\n", addr, ret);
  1223. return ret;
  1224. }
  1225. return 0;
  1226. }
  1227. static int ov8858_write_array(struct ov8858 *ov8858, const struct regval *regs)
  1228. {
  1229. unsigned int i;
  1230. int ret = 0;
  1231. for (i = 0; ret == 0 && regs[i].addr != REG_NULL; ++i) {
  1232. ov8858_write(ov8858, OV8858_REG_8BIT(regs[i].addr),
  1233. regs[i].val, &ret);
  1234. }
  1235. return ret;
  1236. }
  1237. static int ov8858_read(struct ov8858 *ov8858, u32 reg, u32 *val)
  1238. {
  1239. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1240. __be16 reg_addr_be = cpu_to_be16(reg & OV8858_REG_ADDR_MASK);
  1241. unsigned int len = (reg >> OV8858_REG_SIZE_SHIFT) & 3;
  1242. struct i2c_msg msgs[2];
  1243. __be32 data_be = 0;
  1244. u8 *data_be_p;
  1245. int ret;
  1246. data_be_p = (u8 *)&data_be;
  1247. /* Write register address */
  1248. msgs[0].addr = client->addr;
  1249. msgs[0].flags = 0;
  1250. msgs[0].len = 2;
  1251. msgs[0].buf = (u8 *)&reg_addr_be;
  1252. /* Read data from register */
  1253. msgs[1].addr = client->addr;
  1254. msgs[1].flags = I2C_M_RD;
  1255. msgs[1].len = len;
  1256. msgs[1].buf = &data_be_p[4 - len];
  1257. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  1258. if (ret != ARRAY_SIZE(msgs)) {
  1259. ret = ret < 0 ? ret : -EIO;
  1260. dev_err(&client->dev,
  1261. "Failed to read reg %u: %d\n", reg, ret);
  1262. return ret;
  1263. }
  1264. *val = be32_to_cpu(data_be);
  1265. return 0;
  1266. }
  1267. /* ----------------------------------------------------------------------------
  1268. * Streaming
  1269. */
  1270. static int ov8858_start_stream(struct ov8858 *ov8858,
  1271. struct v4l2_subdev_state *state)
  1272. {
  1273. struct v4l2_mbus_framefmt *format;
  1274. const struct ov8858_mode *mode;
  1275. const struct regval *reg_list;
  1276. int ret;
  1277. ret = ov8858_write_array(ov8858, ov8858->global_regs);
  1278. if (ret)
  1279. return ret;
  1280. format = v4l2_subdev_state_get_format(state, 0);
  1281. mode = v4l2_find_nearest_size(ov8858_modes, ARRAY_SIZE(ov8858_modes),
  1282. width, height, format->width,
  1283. format->height);
  1284. reg_list = ov8858->num_lanes == 4
  1285. ? mode->reg_modes.mode_4lanes
  1286. : mode->reg_modes.mode_2lanes;
  1287. ret = ov8858_write_array(ov8858, reg_list);
  1288. if (ret)
  1289. return ret;
  1290. /* 200 usec max to let PLL stabilize. */
  1291. fsleep(200);
  1292. ret = __v4l2_ctrl_handler_setup(&ov8858->ctrl_handler);
  1293. if (ret)
  1294. return ret;
  1295. ret = ov8858_write(ov8858, OV8858_REG_SC_CTRL0100,
  1296. OV8858_MODE_STREAMING, NULL);
  1297. if (ret)
  1298. return ret;
  1299. /* t5 (fixed) = 10msec before entering streaming state */
  1300. fsleep(10000);
  1301. return 0;
  1302. }
  1303. static int ov8858_stop_stream(struct ov8858 *ov8858)
  1304. {
  1305. return ov8858_write(ov8858, OV8858_REG_SC_CTRL0100,
  1306. OV8858_MODE_SW_STANDBY, NULL);
  1307. }
  1308. static int ov8858_s_stream(struct v4l2_subdev *sd, int on)
  1309. {
  1310. struct i2c_client *client = v4l2_get_subdevdata(sd);
  1311. struct ov8858 *ov8858 = sd_to_ov8858(sd);
  1312. struct v4l2_subdev_state *state;
  1313. int ret = 0;
  1314. state = v4l2_subdev_lock_and_get_active_state(sd);
  1315. if (on) {
  1316. ret = pm_runtime_resume_and_get(&client->dev);
  1317. if (ret < 0)
  1318. goto unlock_and_return;
  1319. ret = ov8858_start_stream(ov8858, state);
  1320. if (ret) {
  1321. dev_err(&client->dev, "Failed to start streaming\n");
  1322. pm_runtime_put_sync(&client->dev);
  1323. goto unlock_and_return;
  1324. }
  1325. } else {
  1326. ov8858_stop_stream(ov8858);
  1327. pm_runtime_put_autosuspend(&client->dev);
  1328. }
  1329. unlock_and_return:
  1330. v4l2_subdev_unlock_state(state);
  1331. return ret;
  1332. }
  1333. static const struct v4l2_subdev_video_ops ov8858_video_ops = {
  1334. .s_stream = ov8858_s_stream,
  1335. };
  1336. /* ----------------------------------------------------------------------------
  1337. * Pad ops
  1338. */
  1339. static int ov8858_set_fmt(struct v4l2_subdev *sd,
  1340. struct v4l2_subdev_state *state,
  1341. struct v4l2_subdev_format *fmt)
  1342. {
  1343. struct ov8858 *ov8858 = sd_to_ov8858(sd);
  1344. const struct ov8858_mode *mode;
  1345. s64 h_blank, vblank_def;
  1346. mode = v4l2_find_nearest_size(ov8858_modes, ARRAY_SIZE(ov8858_modes),
  1347. width, height, fmt->format.width,
  1348. fmt->format.height);
  1349. fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
  1350. fmt->format.width = mode->width;
  1351. fmt->format.height = mode->height;
  1352. fmt->format.field = V4L2_FIELD_NONE;
  1353. /* Store the format in the current subdev state. */
  1354. *v4l2_subdev_state_get_format(state, 0) = fmt->format;
  1355. if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
  1356. return 0;
  1357. /* Adjust control limits when a new mode is applied. */
  1358. h_blank = mode->hts_def - mode->width;
  1359. __v4l2_ctrl_modify_range(ov8858->hblank, h_blank, h_blank, 1,
  1360. h_blank);
  1361. vblank_def = mode->vts_def - mode->height;
  1362. __v4l2_ctrl_modify_range(ov8858->vblank, vblank_def,
  1363. OV8858_VTS_MAX - mode->height, 1,
  1364. vblank_def);
  1365. return 0;
  1366. }
  1367. static int ov8858_enum_frame_sizes(struct v4l2_subdev *sd,
  1368. struct v4l2_subdev_state *state,
  1369. struct v4l2_subdev_frame_size_enum *fse)
  1370. {
  1371. if (fse->index >= ARRAY_SIZE(ov8858_modes))
  1372. return -EINVAL;
  1373. if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
  1374. return -EINVAL;
  1375. fse->min_width = ov8858_modes[fse->index].width;
  1376. fse->max_width = ov8858_modes[fse->index].width;
  1377. fse->max_height = ov8858_modes[fse->index].height;
  1378. fse->min_height = ov8858_modes[fse->index].height;
  1379. return 0;
  1380. }
  1381. static int ov8858_enum_mbus_code(struct v4l2_subdev *sd,
  1382. struct v4l2_subdev_state *state,
  1383. struct v4l2_subdev_mbus_code_enum *code)
  1384. {
  1385. if (code->index != 0)
  1386. return -EINVAL;
  1387. code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
  1388. return 0;
  1389. }
  1390. static int ov8858_init_state(struct v4l2_subdev *sd,
  1391. struct v4l2_subdev_state *sd_state)
  1392. {
  1393. const struct ov8858_mode *def_mode = &ov8858_modes[0];
  1394. struct v4l2_subdev_format fmt = {
  1395. .which = V4L2_SUBDEV_FORMAT_TRY,
  1396. .format = {
  1397. .width = def_mode->width,
  1398. .height = def_mode->height,
  1399. },
  1400. };
  1401. ov8858_set_fmt(sd, sd_state, &fmt);
  1402. return 0;
  1403. }
  1404. static const struct v4l2_subdev_pad_ops ov8858_pad_ops = {
  1405. .enum_mbus_code = ov8858_enum_mbus_code,
  1406. .enum_frame_size = ov8858_enum_frame_sizes,
  1407. .get_fmt = v4l2_subdev_get_fmt,
  1408. .set_fmt = ov8858_set_fmt,
  1409. };
  1410. static const struct v4l2_subdev_ops ov8858_subdev_ops = {
  1411. .video = &ov8858_video_ops,
  1412. .pad = &ov8858_pad_ops,
  1413. };
  1414. static const struct v4l2_subdev_internal_ops ov8858_internal_ops = {
  1415. .init_state = ov8858_init_state,
  1416. };
  1417. /* ----------------------------------------------------------------------------
  1418. * Controls handling
  1419. */
  1420. static int ov8858_enable_test_pattern(struct ov8858 *ov8858, u32 pattern)
  1421. {
  1422. u32 val;
  1423. if (pattern)
  1424. val = (pattern - 1) | OV8858_TEST_PATTERN_ENABLE;
  1425. else
  1426. val = OV8858_TEST_PATTERN_DISABLE;
  1427. return ov8858_write(ov8858, OV8858_REG_TEST_PATTERN, val, NULL);
  1428. }
  1429. static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl)
  1430. {
  1431. struct ov8858 *ov8858 = container_of(ctrl->handler,
  1432. struct ov8858, ctrl_handler);
  1433. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1434. struct v4l2_mbus_framefmt *format;
  1435. struct v4l2_subdev_state *state;
  1436. u16 digi_gain;
  1437. s64 max_exp;
  1438. int ret;
  1439. /*
  1440. * The control handler and the subdev state use the same mutex and the
  1441. * mutex is guaranteed to be locked:
  1442. * - by the core when s_ctrl is called int the VIDIOC_S_CTRL call path
  1443. * - by the driver when s_ctrl is called in the s_stream(1) call path
  1444. */
  1445. state = v4l2_subdev_get_locked_active_state(&ov8858->subdev);
  1446. format = v4l2_subdev_state_get_format(state, 0);
  1447. /* Propagate change of current control to all related controls */
  1448. switch (ctrl->id) {
  1449. case V4L2_CID_VBLANK:
  1450. /* Update max exposure while meeting expected vblanking */
  1451. max_exp = format->height + ctrl->val - OV8858_EXPOSURE_MARGIN;
  1452. __v4l2_ctrl_modify_range(ov8858->exposure,
  1453. ov8858->exposure->minimum, max_exp,
  1454. ov8858->exposure->step,
  1455. ov8858->exposure->default_value);
  1456. break;
  1457. }
  1458. if (!pm_runtime_get_if_in_use(&client->dev))
  1459. return 0;
  1460. switch (ctrl->id) {
  1461. case V4L2_CID_EXPOSURE:
  1462. /* 4 least significant bits of exposure are fractional part */
  1463. ret = ov8858_write(ov8858, OV8858_REG_LONG_EXPO,
  1464. ctrl->val << 4, NULL);
  1465. break;
  1466. case V4L2_CID_ANALOGUE_GAIN:
  1467. ret = ov8858_write(ov8858, OV8858_REG_LONG_GAIN,
  1468. ctrl->val, NULL);
  1469. break;
  1470. case V4L2_CID_DIGITAL_GAIN:
  1471. /*
  1472. * Digital gain is assembled as:
  1473. * 0x350a[7:0] = dgain[13:6]
  1474. * 0x350b[5:0] = dgain[5:0]
  1475. * Reassemble the control value to write it in one go.
  1476. */
  1477. digi_gain = (ctrl->val & OV8858_LONG_DIGIGAIN_L_MASK)
  1478. | ((ctrl->val & OV8858_LONG_DIGIGAIN_H_MASK) <<
  1479. OV8858_LONG_DIGIGAIN_H_SHIFT);
  1480. ret = ov8858_write(ov8858, OV8858_REG_LONG_DIGIGAIN,
  1481. digi_gain, NULL);
  1482. break;
  1483. case V4L2_CID_VBLANK:
  1484. ret = ov8858_write(ov8858, OV8858_REG_VTS,
  1485. ctrl->val + format->height, NULL);
  1486. break;
  1487. case V4L2_CID_TEST_PATTERN:
  1488. ret = ov8858_enable_test_pattern(ov8858, ctrl->val);
  1489. break;
  1490. default:
  1491. ret = -EINVAL;
  1492. dev_warn(&client->dev, "%s Unhandled id: 0x%x\n",
  1493. __func__, ctrl->id);
  1494. break;
  1495. }
  1496. pm_runtime_put(&client->dev);
  1497. return ret;
  1498. }
  1499. static const struct v4l2_ctrl_ops ov8858_ctrl_ops = {
  1500. .s_ctrl = ov8858_set_ctrl,
  1501. };
  1502. /* ----------------------------------------------------------------------------
  1503. * Power Management
  1504. */
  1505. static int ov8858_power_on(struct ov8858 *ov8858)
  1506. {
  1507. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1508. struct device *dev = &client->dev;
  1509. unsigned long delay_us;
  1510. int ret;
  1511. if (clk_get_rate(ov8858->xvclk) != OV8858_XVCLK_FREQ)
  1512. dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
  1513. ret = clk_prepare_enable(ov8858->xvclk);
  1514. if (ret < 0) {
  1515. dev_err(dev, "Failed to enable xvclk\n");
  1516. return ret;
  1517. }
  1518. ret = regulator_bulk_enable(ARRAY_SIZE(ov8858_supply_names),
  1519. ov8858->supplies);
  1520. if (ret < 0) {
  1521. dev_err(dev, "Failed to enable regulators\n");
  1522. goto disable_clk;
  1523. }
  1524. /*
  1525. * The chip manual only suggests 8192 cycles prior to first SCCB
  1526. * transaction, but a double sleep between the release of gpios
  1527. * helps with sporadic failures observed at probe time.
  1528. */
  1529. delay_us = DIV_ROUND_UP(8192, OV8858_XVCLK_FREQ / 1000 / 1000);
  1530. gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
  1531. fsleep(delay_us);
  1532. gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0);
  1533. fsleep(delay_us);
  1534. return 0;
  1535. disable_clk:
  1536. clk_disable_unprepare(ov8858->xvclk);
  1537. return ret;
  1538. }
  1539. static void ov8858_power_off(struct ov8858 *ov8858)
  1540. {
  1541. gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1);
  1542. clk_disable_unprepare(ov8858->xvclk);
  1543. gpiod_set_value_cansleep(ov8858->reset_gpio, 1);
  1544. regulator_bulk_disable(ARRAY_SIZE(ov8858_supply_names),
  1545. ov8858->supplies);
  1546. }
  1547. static int ov8858_runtime_resume(struct device *dev)
  1548. {
  1549. struct i2c_client *client = to_i2c_client(dev);
  1550. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  1551. struct ov8858 *ov8858 = sd_to_ov8858(sd);
  1552. return ov8858_power_on(ov8858);
  1553. }
  1554. static int ov8858_runtime_suspend(struct device *dev)
  1555. {
  1556. struct i2c_client *client = to_i2c_client(dev);
  1557. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  1558. struct ov8858 *ov8858 = sd_to_ov8858(sd);
  1559. ov8858_power_off(ov8858);
  1560. return 0;
  1561. }
  1562. static const struct dev_pm_ops ov8858_pm_ops = {
  1563. SET_RUNTIME_PM_OPS(ov8858_runtime_suspend,
  1564. ov8858_runtime_resume, NULL)
  1565. };
  1566. /* ----------------------------------------------------------------------------
  1567. * Probe and initialization
  1568. */
  1569. static int ov8858_init_ctrls(struct ov8858 *ov8858)
  1570. {
  1571. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1572. struct v4l2_ctrl_handler *handler = &ov8858->ctrl_handler;
  1573. const struct ov8858_mode *mode = &ov8858_modes[0];
  1574. struct v4l2_fwnode_device_properties props;
  1575. s64 exposure_max, vblank_def;
  1576. unsigned int pixel_rate;
  1577. struct v4l2_ctrl *ctrl;
  1578. u32 h_blank;
  1579. int ret;
  1580. ret = v4l2_ctrl_handler_init(handler, 10);
  1581. if (ret)
  1582. return ret;
  1583. ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
  1584. 0, 0, link_freq_menu_items);
  1585. if (ctrl)
  1586. ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1587. /* pixel rate = link frequency * 2 * lanes / bpp */
  1588. pixel_rate = OV8858_LINK_FREQ * 2 * ov8858->num_lanes / 10;
  1589. v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
  1590. 0, pixel_rate, 1, pixel_rate);
  1591. h_blank = mode->hts_def - mode->width;
  1592. ov8858->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
  1593. h_blank, h_blank, 1, h_blank);
  1594. if (ov8858->hblank)
  1595. ov8858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1596. vblank_def = mode->vts_def - mode->height;
  1597. ov8858->vblank = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
  1598. V4L2_CID_VBLANK, vblank_def,
  1599. OV8858_VTS_MAX - mode->height,
  1600. 1, vblank_def);
  1601. exposure_max = mode->vts_def - OV8858_EXPOSURE_MARGIN;
  1602. ov8858->exposure = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
  1603. V4L2_CID_EXPOSURE,
  1604. OV8858_EXPOSURE_MIN,
  1605. exposure_max, OV8858_EXPOSURE_STEP,
  1606. mode->exp_def);
  1607. v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
  1608. OV8858_LONG_GAIN_MIN, OV8858_LONG_GAIN_MAX,
  1609. OV8858_LONG_GAIN_STEP, OV8858_LONG_GAIN_DEFAULT);
  1610. v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
  1611. OV8858_LONG_DIGIGAIN_MIN, OV8858_LONG_DIGIGAIN_MAX,
  1612. OV8858_LONG_DIGIGAIN_STEP,
  1613. OV8858_LONG_DIGIGAIN_DEFAULT);
  1614. v4l2_ctrl_new_std_menu_items(handler, &ov8858_ctrl_ops,
  1615. V4L2_CID_TEST_PATTERN,
  1616. ARRAY_SIZE(ov8858_test_pattern_menu) - 1,
  1617. 0, 0, ov8858_test_pattern_menu);
  1618. if (handler->error) {
  1619. ret = handler->error;
  1620. goto err_free_handler;
  1621. }
  1622. ret = v4l2_fwnode_device_parse(&client->dev, &props);
  1623. if (ret)
  1624. goto err_free_handler;
  1625. ret = v4l2_ctrl_new_fwnode_properties(handler, &ov8858_ctrl_ops,
  1626. &props);
  1627. if (ret)
  1628. goto err_free_handler;
  1629. ov8858->subdev.ctrl_handler = handler;
  1630. return 0;
  1631. err_free_handler:
  1632. dev_err(&client->dev, "Failed to init controls: %d\n", ret);
  1633. v4l2_ctrl_handler_free(handler);
  1634. return ret;
  1635. }
  1636. static int ov8858_check_sensor_id(struct ov8858 *ov8858)
  1637. {
  1638. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1639. u32 id = 0;
  1640. int ret;
  1641. ret = ov8858_read(ov8858, OV8858_REG_CHIP_ID, &id);
  1642. if (ret)
  1643. return ret;
  1644. if (id != OV8858_CHIP_ID) {
  1645. dev_err(&client->dev, "Unexpected sensor id 0x%x\n", id);
  1646. return -ENODEV;
  1647. }
  1648. ret = ov8858_read(ov8858, OV8858_REG_SUB_ID, &id);
  1649. if (ret)
  1650. return ret;
  1651. dev_info(&client->dev, "Detected OV8858 sensor, revision 0x%x\n", id);
  1652. if (id == OV8858_R2A) {
  1653. /* R2A supports 2 and 4 lanes modes. */
  1654. ov8858->global_regs = ov8858->num_lanes == 4
  1655. ? ov8858_global_regs_r2a_4lane
  1656. : ov8858_global_regs_r2a_2lane;
  1657. } else if (ov8858->num_lanes == 2) {
  1658. /*
  1659. * R1A only supports 2 lanes mode and it's only partially
  1660. * supported.
  1661. */
  1662. ov8858->global_regs = ov8858_global_regs_r1a;
  1663. dev_warn(&client->dev, "R1A may not work well!\n");
  1664. } else {
  1665. dev_err(&client->dev,
  1666. "Unsupported number of data lanes for R1A revision.\n");
  1667. return -EINVAL;
  1668. }
  1669. return 0;
  1670. }
  1671. static int ov8858_configure_regulators(struct ov8858 *ov8858)
  1672. {
  1673. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1674. unsigned int i;
  1675. for (i = 0; i < ARRAY_SIZE(ov8858_supply_names); i++)
  1676. ov8858->supplies[i].supply = ov8858_supply_names[i];
  1677. return devm_regulator_bulk_get(&client->dev,
  1678. ARRAY_SIZE(ov8858_supply_names),
  1679. ov8858->supplies);
  1680. }
  1681. static int ov8858_parse_of(struct ov8858 *ov8858)
  1682. {
  1683. struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
  1684. struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
  1685. struct device *dev = &client->dev;
  1686. struct fwnode_handle *endpoint;
  1687. int ret;
  1688. endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
  1689. if (!endpoint) {
  1690. dev_err(dev, "Failed to get endpoint\n");
  1691. return -EINVAL;
  1692. }
  1693. ret = v4l2_fwnode_endpoint_parse(endpoint, &vep);
  1694. fwnode_handle_put(endpoint);
  1695. if (ret) {
  1696. dev_err(dev, "Failed to parse endpoint: %d\n", ret);
  1697. return ret;
  1698. }
  1699. ov8858->num_lanes = vep.bus.mipi_csi2.num_data_lanes;
  1700. switch (ov8858->num_lanes) {
  1701. case 4:
  1702. case 2:
  1703. break;
  1704. default:
  1705. dev_err(dev, "Unsupported number of data lanes %u\n",
  1706. ov8858->num_lanes);
  1707. return -EINVAL;
  1708. }
  1709. return 0;
  1710. }
  1711. static int ov8858_probe(struct i2c_client *client)
  1712. {
  1713. struct device *dev = &client->dev;
  1714. struct v4l2_subdev *sd;
  1715. struct ov8858 *ov8858;
  1716. int ret;
  1717. ov8858 = devm_kzalloc(dev, sizeof(*ov8858), GFP_KERNEL);
  1718. if (!ov8858)
  1719. return -ENOMEM;
  1720. ov8858->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
  1721. if (IS_ERR(ov8858->xvclk))
  1722. return dev_err_probe(dev, PTR_ERR(ov8858->xvclk),
  1723. "Failed to get xvclk\n");
  1724. ov8858->reset_gpio = devm_gpiod_get_optional(dev, "reset",
  1725. GPIOD_OUT_HIGH);
  1726. if (IS_ERR(ov8858->reset_gpio))
  1727. return dev_err_probe(dev, PTR_ERR(ov8858->reset_gpio),
  1728. "Failed to get reset gpio\n");
  1729. ov8858->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
  1730. GPIOD_OUT_HIGH);
  1731. if (IS_ERR(ov8858->pwdn_gpio))
  1732. return dev_err_probe(dev, PTR_ERR(ov8858->pwdn_gpio),
  1733. "Failed to get powerdown gpio\n");
  1734. v4l2_i2c_subdev_init(&ov8858->subdev, client, &ov8858_subdev_ops);
  1735. ov8858->subdev.internal_ops = &ov8858_internal_ops;
  1736. ret = ov8858_configure_regulators(ov8858);
  1737. if (ret)
  1738. return dev_err_probe(dev, ret, "Failed to get regulators\n");
  1739. ret = ov8858_parse_of(ov8858);
  1740. if (ret)
  1741. return ret;
  1742. ret = ov8858_init_ctrls(ov8858);
  1743. if (ret)
  1744. return ret;
  1745. sd = &ov8858->subdev;
  1746. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  1747. ov8858->pad.flags = MEDIA_PAD_FL_SOURCE;
  1748. sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
  1749. ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad);
  1750. if (ret < 0)
  1751. goto err_free_handler;
  1752. sd->state_lock = ov8858->ctrl_handler.lock;
  1753. ret = v4l2_subdev_init_finalize(sd);
  1754. if (ret < 0) {
  1755. dev_err(&client->dev, "Subdev initialization error %d\n", ret);
  1756. goto err_clean_entity;
  1757. }
  1758. ret = ov8858_power_on(ov8858);
  1759. if (ret)
  1760. goto err_clean_entity;
  1761. pm_runtime_set_active(dev);
  1762. pm_runtime_get_noresume(dev);
  1763. pm_runtime_enable(dev);
  1764. ret = ov8858_check_sensor_id(ov8858);
  1765. if (ret)
  1766. goto err_power_off;
  1767. pm_runtime_set_autosuspend_delay(dev, 1000);
  1768. pm_runtime_use_autosuspend(dev);
  1769. ret = v4l2_async_register_subdev_sensor(sd);
  1770. if (ret) {
  1771. dev_err(dev, "v4l2 async register subdev failed\n");
  1772. goto err_power_off;
  1773. }
  1774. pm_runtime_put_autosuspend(dev);
  1775. return 0;
  1776. err_power_off:
  1777. pm_runtime_disable(dev);
  1778. pm_runtime_put_noidle(dev);
  1779. ov8858_power_off(ov8858);
  1780. err_clean_entity:
  1781. media_entity_cleanup(&sd->entity);
  1782. err_free_handler:
  1783. v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
  1784. return ret;
  1785. }
  1786. static void ov8858_remove(struct i2c_client *client)
  1787. {
  1788. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  1789. struct ov8858 *ov8858 = sd_to_ov8858(sd);
  1790. v4l2_async_unregister_subdev(sd);
  1791. media_entity_cleanup(&sd->entity);
  1792. v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
  1793. pm_runtime_disable(&client->dev);
  1794. if (!pm_runtime_status_suspended(&client->dev))
  1795. ov8858_power_off(ov8858);
  1796. pm_runtime_set_suspended(&client->dev);
  1797. }
  1798. static const struct of_device_id ov8858_of_match[] = {
  1799. { .compatible = "ovti,ov8858" },
  1800. { /* sentinel */ },
  1801. };
  1802. MODULE_DEVICE_TABLE(of, ov8858_of_match);
  1803. static struct i2c_driver ov8858_i2c_driver = {
  1804. .driver = {
  1805. .name = "ov8858",
  1806. .pm = &ov8858_pm_ops,
  1807. .of_match_table = ov8858_of_match,
  1808. },
  1809. .probe = ov8858_probe,
  1810. .remove = ov8858_remove,
  1811. };
  1812. module_i2c_driver(ov8858_i2c_driver);
  1813. MODULE_DESCRIPTION("OmniVision OV8858 sensor driver");
  1814. MODULE_LICENSE("GPL");