alvium-csi2.c 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Allied Vision Technologies GmbH Alvium camera driver
  4. *
  5. * Copyright (C) 2023 Tommaso Merciai
  6. * Copyright (C) 2023 Martin Hecht
  7. * Copyright (C) 2023 Avnet EMG GmbH
  8. */
  9. #include <linux/i2c.h>
  10. #include <linux/module.h>
  11. #include <linux/pm_runtime.h>
  12. #include <linux/regmap.h>
  13. #include <linux/regulator/consumer.h>
  14. #include <media/mipi-csi2.h>
  15. #include <media/v4l2-async.h>
  16. #include <media/v4l2-ctrls.h>
  17. #include <media/v4l2-device.h>
  18. #include <media/v4l2-fwnode.h>
  19. #include <media/v4l2-subdev.h>
  20. #include "alvium-csi2.h"
  21. static const struct v4l2_mbus_framefmt alvium_csi2_default_fmt = {
  22. .code = MEDIA_BUS_FMT_UYVY8_1X16,
  23. .width = 640,
  24. .height = 480,
  25. .colorspace = V4L2_COLORSPACE_SRGB,
  26. .ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB),
  27. .quantization = V4L2_QUANTIZATION_FULL_RANGE,
  28. .xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB),
  29. .field = V4L2_FIELD_NONE,
  30. };
  31. static const struct alvium_pixfmt alvium_csi2_fmts[] = {
  32. {
  33. /* UYVY8_2X8 */
  34. .id = ALVIUM_FMT_UYVY8_2X8,
  35. .code = MEDIA_BUS_FMT_UYVY8_2X8,
  36. .colorspace = V4L2_COLORSPACE_SRGB,
  37. .fmt_av_bit = ALVIUM_BIT_YUV422_8,
  38. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  39. .mipi_fmt_regval = MIPI_CSI2_DT_YUV422_8B,
  40. .bay_fmt_regval = -1,
  41. .is_raw = 0,
  42. }, {
  43. /* UYVY8_1X16 */
  44. .id = ALVIUM_FMT_UYVY8_1X16,
  45. .code = MEDIA_BUS_FMT_UYVY8_1X16,
  46. .colorspace = V4L2_COLORSPACE_SRGB,
  47. .fmt_av_bit = ALVIUM_BIT_YUV422_8,
  48. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  49. .mipi_fmt_regval = MIPI_CSI2_DT_YUV422_8B,
  50. .bay_fmt_regval = -1,
  51. .is_raw = 0,
  52. }, {
  53. /* YUYV8_1X16 */
  54. .id = ALVIUM_FMT_YUYV8_1X16,
  55. .code = MEDIA_BUS_FMT_YUYV8_1X16,
  56. .colorspace = V4L2_COLORSPACE_SRGB,
  57. .fmt_av_bit = ALVIUM_BIT_YUV422_8,
  58. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  59. .mipi_fmt_regval = MIPI_CSI2_DT_YUV422_8B,
  60. .bay_fmt_regval = -1,
  61. .is_raw = 0,
  62. }, {
  63. /* YUYV8_2X8 */
  64. .id = ALVIUM_FMT_YUYV8_2X8,
  65. .code = MEDIA_BUS_FMT_YUYV8_2X8,
  66. .colorspace = V4L2_COLORSPACE_SRGB,
  67. .fmt_av_bit = ALVIUM_BIT_YUV422_8,
  68. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  69. .mipi_fmt_regval = MIPI_CSI2_DT_YUV422_8B,
  70. .bay_fmt_regval = -1,
  71. .is_raw = 0,
  72. }, {
  73. /* YUYV10_1X20 */
  74. .id = ALVIUM_FMT_YUYV10_1X20,
  75. .code = MEDIA_BUS_FMT_YUYV10_1X20,
  76. .colorspace = V4L2_COLORSPACE_SRGB,
  77. .fmt_av_bit = ALVIUM_BIT_YUV422_10,
  78. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  79. .mipi_fmt_regval = MIPI_CSI2_DT_YUV422_10B,
  80. .bay_fmt_regval = -1,
  81. .is_raw = 0,
  82. }, {
  83. /* RGB888_1X24 */
  84. .id = ALVIUM_FMT_RGB888_1X24,
  85. .code = MEDIA_BUS_FMT_RGB888_1X24,
  86. .colorspace = V4L2_COLORSPACE_SRGB,
  87. .fmt_av_bit = ALVIUM_BIT_RGB888,
  88. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  89. .mipi_fmt_regval = MIPI_CSI2_DT_RGB888,
  90. .bay_fmt_regval = -1,
  91. .is_raw = 0,
  92. }, {
  93. /* RBG888_1X24 */
  94. .id = ALVIUM_FMT_RBG888_1X24,
  95. .code = MEDIA_BUS_FMT_RBG888_1X24,
  96. .colorspace = V4L2_COLORSPACE_SRGB,
  97. .fmt_av_bit = ALVIUM_BIT_RGB888,
  98. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  99. .mipi_fmt_regval = MIPI_CSI2_DT_RGB888,
  100. .bay_fmt_regval = -1,
  101. .is_raw = 0,
  102. }, {
  103. /* BGR888_1X24 */
  104. .id = ALVIUM_FMT_BGR888_1X24,
  105. .code = MEDIA_BUS_FMT_BGR888_1X24,
  106. .colorspace = V4L2_COLORSPACE_SRGB,
  107. .fmt_av_bit = ALVIUM_BIT_RGB888,
  108. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  109. .mipi_fmt_regval = MIPI_CSI2_DT_RGB888,
  110. .bay_fmt_regval = -1,
  111. .is_raw = 0,
  112. }, {
  113. /* RGB888_3X8 */
  114. .id = ALVIUM_FMT_RGB888_3X8,
  115. .code = MEDIA_BUS_FMT_RGB888_3X8,
  116. .colorspace = V4L2_COLORSPACE_SRGB,
  117. .fmt_av_bit = ALVIUM_BIT_RGB888,
  118. .bay_av_bit = ALVIUM_BIT_BAY_NONE,
  119. .mipi_fmt_regval = MIPI_CSI2_DT_RGB888,
  120. .bay_fmt_regval = -1,
  121. .is_raw = 0,
  122. }, {
  123. /* Y8_1X8 */
  124. .id = ALVIUM_FMT_Y8_1X8,
  125. .code = MEDIA_BUS_FMT_Y8_1X8,
  126. .colorspace = V4L2_COLORSPACE_RAW,
  127. .fmt_av_bit = ALVIUM_BIT_RAW8,
  128. .bay_av_bit = ALVIUM_BIT_BAY_MONO,
  129. .mipi_fmt_regval = MIPI_CSI2_DT_RAW8,
  130. .bay_fmt_regval = 0x00,
  131. .is_raw = 1,
  132. }, {
  133. /* SGRBG8_1X8 */
  134. .id = ALVIUM_FMT_SGRBG8_1X8,
  135. .code = MEDIA_BUS_FMT_SGRBG8_1X8,
  136. .colorspace = V4L2_COLORSPACE_RAW,
  137. .fmt_av_bit = ALVIUM_BIT_RAW8,
  138. .bay_av_bit = ALVIUM_BIT_BAY_GR,
  139. .mipi_fmt_regval = MIPI_CSI2_DT_RAW8,
  140. .bay_fmt_regval = 0x01,
  141. .is_raw = 1,
  142. }, {
  143. /* SRGGB8_1X8 */
  144. .id = ALVIUM_FMT_SRGGB8_1X8,
  145. .code = MEDIA_BUS_FMT_SRGGB8_1X8,
  146. .colorspace = V4L2_COLORSPACE_RAW,
  147. .fmt_av_bit = ALVIUM_BIT_RAW8,
  148. .bay_av_bit = ALVIUM_BIT_BAY_RG,
  149. .mipi_fmt_regval = MIPI_CSI2_DT_RAW8,
  150. .bay_fmt_regval = 0x02,
  151. .is_raw = 1,
  152. }, {
  153. /* SGBRG8_1X8 */
  154. .id = ALVIUM_FMT_SGBRG8_1X8,
  155. .code = MEDIA_BUS_FMT_SGBRG8_1X8,
  156. .colorspace = V4L2_COLORSPACE_RAW,
  157. .fmt_av_bit = ALVIUM_BIT_RAW8,
  158. .bay_av_bit = ALVIUM_BIT_BAY_GB,
  159. .mipi_fmt_regval = MIPI_CSI2_DT_RAW8,
  160. .bay_fmt_regval = 0x03,
  161. .is_raw = 1,
  162. }, {
  163. /* SBGGR8_1X8 */
  164. .id = ALVIUM_FMT_SBGGR8_1X8,
  165. .code = MEDIA_BUS_FMT_SBGGR8_1X8,
  166. .colorspace = V4L2_COLORSPACE_RAW,
  167. .fmt_av_bit = ALVIUM_BIT_RAW8,
  168. .bay_av_bit = ALVIUM_BIT_BAY_BG,
  169. .mipi_fmt_regval = MIPI_CSI2_DT_RAW8,
  170. .bay_fmt_regval = 0x04,
  171. .is_raw = 1,
  172. }, {
  173. /* Y10_1X10 */
  174. .id = ALVIUM_FMT_Y10_1X10,
  175. .code = MEDIA_BUS_FMT_Y10_1X10,
  176. .colorspace = V4L2_COLORSPACE_RAW,
  177. .fmt_av_bit = ALVIUM_BIT_RAW10,
  178. .bay_av_bit = ALVIUM_BIT_BAY_MONO,
  179. .mipi_fmt_regval = MIPI_CSI2_DT_RAW10,
  180. .bay_fmt_regval = 0x00,
  181. .is_raw = 1,
  182. }, {
  183. /* SGRBG10_1X10 */
  184. .id = ALVIUM_FMT_SGRBG10_1X10,
  185. .code = MEDIA_BUS_FMT_SGRBG10_1X10,
  186. .colorspace = V4L2_COLORSPACE_RAW,
  187. .fmt_av_bit = ALVIUM_BIT_RAW10,
  188. .bay_av_bit = ALVIUM_BIT_BAY_GR,
  189. .mipi_fmt_regval = MIPI_CSI2_DT_RAW10,
  190. .bay_fmt_regval = 0x01,
  191. .is_raw = 1,
  192. }, {
  193. /* SRGGB10_1X10 */
  194. .id = ALVIUM_FMT_SRGGB10_1X10,
  195. .code = MEDIA_BUS_FMT_SRGGB10_1X10,
  196. .colorspace = V4L2_COLORSPACE_RAW,
  197. .fmt_av_bit = ALVIUM_BIT_RAW10,
  198. .bay_av_bit = ALVIUM_BIT_BAY_RG,
  199. .mipi_fmt_regval = MIPI_CSI2_DT_RAW10,
  200. .bay_fmt_regval = 0x02,
  201. .is_raw = 1,
  202. }, {
  203. /* SGBRG10_1X10 */
  204. .id = ALVIUM_FMT_SGBRG10_1X10,
  205. .code = MEDIA_BUS_FMT_SGBRG10_1X10,
  206. .colorspace = V4L2_COLORSPACE_RAW,
  207. .fmt_av_bit = ALVIUM_BIT_RAW10,
  208. .bay_av_bit = ALVIUM_BIT_BAY_GB,
  209. .mipi_fmt_regval = MIPI_CSI2_DT_RAW10,
  210. .bay_fmt_regval = 0x03,
  211. .is_raw = 1,
  212. }, {
  213. /* SBGGR10_1X10 */
  214. .id = ALVIUM_FMT_SBGGR10_1X10,
  215. .code = MEDIA_BUS_FMT_SBGGR10_1X10,
  216. .colorspace = V4L2_COLORSPACE_RAW,
  217. .fmt_av_bit = ALVIUM_BIT_RAW10,
  218. .bay_av_bit = ALVIUM_BIT_BAY_BG,
  219. .mipi_fmt_regval = MIPI_CSI2_DT_RAW10,
  220. .bay_fmt_regval = 0x04,
  221. .is_raw = 1,
  222. }, {
  223. /* Y12_1X12 */
  224. .id = ALVIUM_FMT_Y12_1X12,
  225. .code = MEDIA_BUS_FMT_Y12_1X12,
  226. .colorspace = V4L2_COLORSPACE_RAW,
  227. .fmt_av_bit = ALVIUM_BIT_RAW12,
  228. .bay_av_bit = ALVIUM_BIT_BAY_MONO,
  229. .mipi_fmt_regval = MIPI_CSI2_DT_RAW12,
  230. .bay_fmt_regval = 0x00,
  231. .is_raw = 1,
  232. }, {
  233. /* SGRBG12_1X12 */
  234. .id = ALVIUM_FMT_SGRBG12_1X12,
  235. .code = MEDIA_BUS_FMT_SGRBG12_1X12,
  236. .colorspace = V4L2_COLORSPACE_RAW,
  237. .fmt_av_bit = ALVIUM_BIT_RAW12,
  238. .bay_av_bit = ALVIUM_BIT_BAY_GR,
  239. .mipi_fmt_regval = MIPI_CSI2_DT_RAW12,
  240. .bay_fmt_regval = 0x01,
  241. .is_raw = 1,
  242. }, {
  243. /* SRGGB12_1X12 */
  244. .id = ALVIUM_FMT_SRGGB12_1X12,
  245. .code = MEDIA_BUS_FMT_SRGGB12_1X12,
  246. .colorspace = V4L2_COLORSPACE_RAW,
  247. .fmt_av_bit = ALVIUM_BIT_RAW12,
  248. .bay_av_bit = ALVIUM_BIT_BAY_RG,
  249. .mipi_fmt_regval = MIPI_CSI2_DT_RAW12,
  250. .bay_fmt_regval = 0x02,
  251. .is_raw = 1,
  252. }, {
  253. /* SGBRG12_1X12 */
  254. .id = ALVIUM_FMT_SGBRG12_1X12,
  255. .code = MEDIA_BUS_FMT_SGBRG12_1X12,
  256. .colorspace = V4L2_COLORSPACE_RAW,
  257. .fmt_av_bit = ALVIUM_BIT_RAW12,
  258. .bay_av_bit = ALVIUM_BIT_BAY_GB,
  259. .mipi_fmt_regval = MIPI_CSI2_DT_RAW12,
  260. .bay_fmt_regval = 0x03,
  261. .is_raw = 1,
  262. }, {
  263. /* SBGGR12_1X12 */
  264. .id = ALVIUM_FMT_SBGGR12_1X12,
  265. .code = MEDIA_BUS_FMT_SBGGR12_1X12,
  266. .colorspace = V4L2_COLORSPACE_RAW,
  267. .fmt_av_bit = ALVIUM_BIT_RAW12,
  268. .bay_av_bit = ALVIUM_BIT_BAY_BG,
  269. .mipi_fmt_regval = MIPI_CSI2_DT_RAW12,
  270. .bay_fmt_regval = 0x04,
  271. .is_raw = 1,
  272. }, {
  273. /* SBGGR14_1X14 */
  274. .id = ALVIUM_FMT_SBGGR14_1X14,
  275. .code = MEDIA_BUS_FMT_SBGGR14_1X14,
  276. .colorspace = V4L2_COLORSPACE_RAW,
  277. .fmt_av_bit = ALVIUM_BIT_RAW14,
  278. .bay_av_bit = ALVIUM_BIT_BAY_GR,
  279. .mipi_fmt_regval = MIPI_CSI2_DT_RAW14,
  280. .bay_fmt_regval = 0x01,
  281. .is_raw = 1,
  282. }, {
  283. /* SGBRG14_1X14 */
  284. .id = ALVIUM_FMT_SGBRG14_1X14,
  285. .code = MEDIA_BUS_FMT_SGBRG14_1X14,
  286. .colorspace = V4L2_COLORSPACE_RAW,
  287. .fmt_av_bit = ALVIUM_BIT_RAW14,
  288. .bay_av_bit = ALVIUM_BIT_BAY_RG,
  289. .mipi_fmt_regval = MIPI_CSI2_DT_RAW14,
  290. .bay_fmt_regval = 0x02,
  291. .is_raw = 1,
  292. }, {
  293. /* SRGGB14_1X14 */
  294. .id = ALVIUM_FMT_SRGGB14_1X14,
  295. .code = MEDIA_BUS_FMT_SRGGB14_1X14,
  296. .colorspace = V4L2_COLORSPACE_RAW,
  297. .fmt_av_bit = ALVIUM_BIT_RAW14,
  298. .bay_av_bit = ALVIUM_BIT_BAY_GB,
  299. .mipi_fmt_regval = MIPI_CSI2_DT_RAW14,
  300. .bay_fmt_regval = 0x03,
  301. .is_raw = 1,
  302. }, {
  303. /* SGRBG14_1X14 */
  304. .id = ALVIUM_FMT_SGRBG14_1X14,
  305. .code = MEDIA_BUS_FMT_SGRBG14_1X14,
  306. .colorspace = V4L2_COLORSPACE_RAW,
  307. .fmt_av_bit = ALVIUM_BIT_RAW14,
  308. .bay_av_bit = ALVIUM_BIT_BAY_BG,
  309. .mipi_fmt_regval = MIPI_CSI2_DT_RAW14,
  310. .bay_fmt_regval = 0x04,
  311. .is_raw = 1,
  312. },
  313. { /* sentinel */ }
  314. };
  315. static int alvium_read(struct alvium_dev *alvium, u32 reg, u64 *val, int *err)
  316. {
  317. if (reg & REG_BCRM_V4L2) {
  318. reg &= ~REG_BCRM_V4L2;
  319. reg += alvium->bcrm_addr;
  320. }
  321. return cci_read(alvium->regmap, reg, val, err);
  322. }
  323. static int alvium_write(struct alvium_dev *alvium, u32 reg, u64 val, int *err)
  324. {
  325. if (reg & REG_BCRM_V4L2) {
  326. reg &= ~REG_BCRM_V4L2;
  327. reg += alvium->bcrm_addr;
  328. }
  329. return cci_write(alvium->regmap, reg, val, err);
  330. }
  331. static int alvium_write_hshake(struct alvium_dev *alvium, u32 reg, u64 val)
  332. {
  333. struct device *dev = &alvium->i2c_client->dev;
  334. u64 hshake_bit;
  335. int ret = 0;
  336. /* reset handshake bit and write alvium reg */
  337. alvium_write(alvium, REG_BCRM_WRITE_HANDSHAKE_RW, 0, &ret);
  338. alvium_write(alvium, reg, val, &ret);
  339. if (ret) {
  340. dev_err(dev, "Fail to write reg\n");
  341. return ret;
  342. }
  343. /* poll handshake bit since bit0 = 1 */
  344. read_poll_timeout(alvium_read, hshake_bit,
  345. ((hshake_bit & BCRM_HANDSHAKE_W_DONE_EN_BIT) == 1),
  346. 15000, 45000, true,
  347. alvium, REG_BCRM_WRITE_HANDSHAKE_RW,
  348. &hshake_bit, &ret);
  349. if (ret) {
  350. dev_err(dev, "poll bit[0] = 1, hshake reg fail\n");
  351. return ret;
  352. }
  353. /* reset handshake bit, write 0 to bit0 */
  354. alvium_write(alvium, REG_BCRM_WRITE_HANDSHAKE_RW, 0, &ret);
  355. if (ret) {
  356. dev_err(dev, "Fail to reset hshake reg\n");
  357. return ret;
  358. }
  359. /* poll handshake bit since bit0 = 0 */
  360. read_poll_timeout(alvium_read, hshake_bit,
  361. ((hshake_bit & BCRM_HANDSHAKE_W_DONE_EN_BIT) == 0),
  362. 15000, 45000, true,
  363. alvium, REG_BCRM_WRITE_HANDSHAKE_RW,
  364. &hshake_bit, &ret);
  365. if (ret) {
  366. dev_err(dev, "poll bit[0] = 0, hshake reg fail\n");
  367. return ret;
  368. }
  369. return 0;
  370. }
  371. static int alvium_get_bcrm_vers(struct alvium_dev *alvium)
  372. {
  373. struct device *dev = &alvium->i2c_client->dev;
  374. u64 min, maj;
  375. int ret = 0;
  376. ret = alvium_read(alvium, REG_BCRM_MINOR_VERSION_R, &min, &ret);
  377. ret = alvium_read(alvium, REG_BCRM_MAJOR_VERSION_R, &maj, &ret);
  378. if (ret)
  379. return ret;
  380. dev_info(dev, "bcrm version: %llu.%llu\n", min, maj);
  381. return 0;
  382. }
  383. static int alvium_get_fw_version(struct alvium_dev *alvium)
  384. {
  385. struct device *dev = &alvium->i2c_client->dev;
  386. u64 val;
  387. int ret;
  388. ret = alvium_read(alvium, REG_BCRM_DEVICE_FW, &val, NULL);
  389. if (ret)
  390. return ret;
  391. dev_info(dev, "fw version: %02u.%02u.%04u.%08x\n",
  392. (u8)((val & BCRM_DEVICE_FW_SPEC_MASK) >>
  393. BCRM_DEVICE_FW_SPEC_SHIFT),
  394. (u8)((val & BCRM_DEVICE_FW_MAJOR_MASK) >>
  395. BCRM_DEVICE_FW_MAJOR_SHIFT),
  396. (u16)((val & BCRM_DEVICE_FW_MINOR_MASK) >>
  397. BCRM_DEVICE_FW_MINOR_SHIFT),
  398. (u32)((val & BCRM_DEVICE_FW_PATCH_MASK) >>
  399. BCRM_DEVICE_FW_PATCH_SHIFT));
  400. return 0;
  401. }
  402. static int alvium_get_bcrm_addr(struct alvium_dev *alvium)
  403. {
  404. u64 val;
  405. int ret;
  406. ret = alvium_read(alvium, REG_BCRM_REG_ADDR_R, &val, NULL);
  407. if (ret)
  408. return ret;
  409. alvium->bcrm_addr = val;
  410. return 0;
  411. }
  412. static int alvium_is_alive(struct alvium_dev *alvium)
  413. {
  414. u64 bcrm, hbeat;
  415. int ret = 0;
  416. alvium_read(alvium, REG_BCRM_MINOR_VERSION_R, &bcrm, &ret);
  417. alvium_read(alvium, REG_BCRM_HEARTBEAT_RW, &hbeat, &ret);
  418. if (ret)
  419. return ret;
  420. return hbeat;
  421. }
  422. static void alvium_print_avail_mipi_fmt(struct alvium_dev *alvium)
  423. {
  424. struct device *dev = &alvium->i2c_client->dev;
  425. dev_dbg(dev, "avail mipi_fmt yuv420_8_leg: %u\n",
  426. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8_LEG]);
  427. dev_dbg(dev, "avail mipi_fmt yuv420_8: %u\n",
  428. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8]);
  429. dev_dbg(dev, "avail mipi_fmt yuv420_10: %u\n",
  430. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_10]);
  431. dev_dbg(dev, "avail mipi_fmt yuv420_8_csps: %u\n",
  432. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8_CSPS]);
  433. dev_dbg(dev, "avail mipi_fmt yuv420_10_csps: %u\n",
  434. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_10_CSPS]);
  435. dev_dbg(dev, "avail mipi_fmt yuv422_8: %u\n",
  436. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV422_8]);
  437. dev_dbg(dev, "avail mipi_fmt yuv422_10: %u\n",
  438. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV422_10]);
  439. dev_dbg(dev, "avail mipi_fmt rgb888: %u\n",
  440. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB888]);
  441. dev_dbg(dev, "avail mipi_fmt rgb666: %u\n",
  442. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB666]);
  443. dev_dbg(dev, "avail mipi_fmt rgb565: %u\n",
  444. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB565]);
  445. dev_dbg(dev, "avail mipi_fmt rgb555: %u\n",
  446. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB555]);
  447. dev_dbg(dev, "avail mipi_fmt rgb444: %u\n",
  448. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB444]);
  449. dev_dbg(dev, "avail mipi_fmt raw6: %u\n",
  450. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW6]);
  451. dev_dbg(dev, "avail mipi_fmt raw7: %u\n",
  452. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW7]);
  453. dev_dbg(dev, "avail mipi_fmt raw8: %u\n",
  454. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW8]);
  455. dev_dbg(dev, "avail mipi_fmt raw10: %u\n",
  456. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW10]);
  457. dev_dbg(dev, "avail mipi_fmt raw12: %u\n",
  458. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW12]);
  459. dev_dbg(dev, "avail mipi_fmt raw14: %u\n",
  460. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW14]);
  461. dev_dbg(dev, "avail mipi_fmt jpeg: %u\n",
  462. alvium->is_mipi_fmt_avail[ALVIUM_BIT_JPEG]);
  463. }
  464. static void alvium_print_avail_feat(struct alvium_dev *alvium)
  465. {
  466. struct device *dev = &alvium->i2c_client->dev;
  467. dev_dbg(dev, "feature rev_x: %u\n", alvium->avail_ft.rev_x);
  468. dev_dbg(dev, "feature rev_y: %u\n", alvium->avail_ft.rev_y);
  469. dev_dbg(dev, "feature int_autop: %u\n", alvium->avail_ft.int_autop);
  470. dev_dbg(dev, "feature black_lvl: %u\n", alvium->avail_ft.black_lvl);
  471. dev_dbg(dev, "feature gain: %u\n", alvium->avail_ft.gain);
  472. dev_dbg(dev, "feature gamma: %u\n", alvium->avail_ft.gamma);
  473. dev_dbg(dev, "feature contrast: %u\n", alvium->avail_ft.contrast);
  474. dev_dbg(dev, "feature sat: %u\n", alvium->avail_ft.sat);
  475. dev_dbg(dev, "feature hue: %u\n", alvium->avail_ft.hue);
  476. dev_dbg(dev, "feature whiteb: %u\n", alvium->avail_ft.whiteb);
  477. dev_dbg(dev, "feature sharp: %u\n", alvium->avail_ft.sharp);
  478. dev_dbg(dev, "feature auto_exp: %u\n", alvium->avail_ft.auto_exp);
  479. dev_dbg(dev, "feature auto_gain: %u\n", alvium->avail_ft.auto_gain);
  480. dev_dbg(dev, "feature auto_whiteb: %u\n", alvium->avail_ft.auto_whiteb);
  481. dev_dbg(dev, "feature dev_temp: %u\n", alvium->avail_ft.dev_temp);
  482. dev_dbg(dev, "feature acq_abort: %u\n", alvium->avail_ft.acq_abort);
  483. dev_dbg(dev, "feature acq_fr: %u\n", alvium->avail_ft.acq_fr);
  484. dev_dbg(dev, "feature fr_trigger: %u\n", alvium->avail_ft.fr_trigger);
  485. dev_dbg(dev, "feature exp_acq_line: %u\n",
  486. alvium->avail_ft.exp_acq_line);
  487. }
  488. static void alvium_print_avail_bayer(struct alvium_dev *alvium)
  489. {
  490. struct device *dev = &alvium->i2c_client->dev;
  491. dev_dbg(dev, "avail bayer mono: %u\n",
  492. alvium->is_bay_avail[ALVIUM_BIT_BAY_MONO]);
  493. dev_dbg(dev, "avail bayer gr: %u\n",
  494. alvium->is_bay_avail[ALVIUM_BIT_BAY_GR]);
  495. dev_dbg(dev, "avail bayer rg: %u\n",
  496. alvium->is_bay_avail[ALVIUM_BIT_BAY_RG]);
  497. dev_dbg(dev, "avail bayer gb: %u\n",
  498. alvium->is_bay_avail[ALVIUM_BIT_BAY_GB]);
  499. dev_dbg(dev, "avail bayer bg: %u\n",
  500. alvium->is_bay_avail[ALVIUM_BIT_BAY_BG]);
  501. }
  502. static int alvium_get_feat_inq(struct alvium_dev *alvium)
  503. {
  504. struct alvium_avail_feat *f;
  505. u64 val;
  506. int ret;
  507. ret = alvium_read(alvium, REG_BCRM_FEATURE_INQUIRY_R, &val, NULL);
  508. if (ret)
  509. return ret;
  510. f = (struct alvium_avail_feat *)&val;
  511. alvium->avail_ft = *f;
  512. alvium_print_avail_feat(alvium);
  513. return 0;
  514. }
  515. static int alvium_get_host_supp_csi_lanes(struct alvium_dev *alvium)
  516. {
  517. u64 val;
  518. int ret;
  519. ret = alvium_read(alvium, REG_BCRM_CSI2_LANE_COUNT_RW, &val, NULL);
  520. if (ret)
  521. return ret;
  522. alvium->h_sup_csi_lanes = val;
  523. return 0;
  524. }
  525. static int alvium_set_csi_lanes(struct alvium_dev *alvium)
  526. {
  527. struct device *dev = &alvium->i2c_client->dev;
  528. u64 num_lanes;
  529. int ret;
  530. num_lanes = alvium->ep.bus.mipi_csi2.num_data_lanes;
  531. if (num_lanes > alvium->h_sup_csi_lanes)
  532. return -EINVAL;
  533. ret = alvium_write_hshake(alvium, REG_BCRM_CSI2_LANE_COUNT_RW,
  534. num_lanes);
  535. if (ret) {
  536. dev_err(dev, "Fail to set csi lanes reg\n");
  537. return ret;
  538. }
  539. return 0;
  540. }
  541. static int alvium_set_lp2hs_delay(struct alvium_dev *alvium)
  542. {
  543. struct device *dev = &alvium->i2c_client->dev;
  544. int ret = 0;
  545. /*
  546. * The purpose of this reg is force a DPhy reset
  547. * for the period described by the millisecond on
  548. * the reg, before it starts streaming.
  549. *
  550. * To be clear, with that value bigger than 0 the
  551. * Alvium forces a dphy-reset on all lanes for that period.
  552. * That means all lanes go up into low power state.
  553. *
  554. */
  555. alvium_write(alvium, REG_BCRM_LP2HS_DELAY_RW,
  556. ALVIUM_LP2HS_DELAY_MS, &ret);
  557. if (ret) {
  558. dev_err(dev, "Fail to set lp2hs delay reg\n");
  559. return ret;
  560. }
  561. return 0;
  562. }
  563. static int alvium_get_csi_clk_params(struct alvium_dev *alvium)
  564. {
  565. u64 min_csi_clk, max_csi_clk;
  566. int ret = 0;
  567. alvium_read(alvium, REG_BCRM_CSI2_CLOCK_MIN_R, &min_csi_clk, &ret);
  568. alvium_read(alvium, REG_BCRM_CSI2_CLOCK_MAX_R, &max_csi_clk, &ret);
  569. if (ret)
  570. return ret;
  571. alvium->min_csi_clk = min_csi_clk;
  572. alvium->max_csi_clk = max_csi_clk;
  573. return 0;
  574. }
  575. static int alvium_set_csi_clk(struct alvium_dev *alvium)
  576. {
  577. struct device *dev = &alvium->i2c_client->dev;
  578. u64 csi_clk;
  579. int ret;
  580. csi_clk = clamp(alvium->ep.link_frequencies[0],
  581. (u64)alvium->min_csi_clk, (u64)alvium->max_csi_clk);
  582. if (alvium->ep.link_frequencies[0] != (u64)csi_clk) {
  583. dev_warn(dev,
  584. "requested csi clock (%llu MHz) out of range [%u, %u] Adjusted to %llu\n",
  585. alvium->ep.link_frequencies[0],
  586. alvium->min_csi_clk, alvium->max_csi_clk, csi_clk);
  587. }
  588. ret = alvium_write_hshake(alvium, REG_BCRM_CSI2_CLOCK_RW, csi_clk);
  589. if (ret) {
  590. dev_err(dev, "Fail to set csi clock reg\n");
  591. return ret;
  592. }
  593. alvium->link_freq = csi_clk;
  594. return 0;
  595. }
  596. static int alvium_get_img_width_params(struct alvium_dev *alvium)
  597. {
  598. u64 imgw, imgw_min, imgw_max, imgw_inc;
  599. int ret = 0;
  600. alvium_read(alvium, REG_BCRM_IMG_WIDTH_RW, &imgw, &ret);
  601. alvium_read(alvium, REG_BCRM_IMG_WIDTH_MIN_R, &imgw_min, &ret);
  602. alvium_read(alvium, REG_BCRM_IMG_WIDTH_MAX_R, &imgw_max, &ret);
  603. alvium_read(alvium, REG_BCRM_IMG_WIDTH_INC_R, &imgw_inc, &ret);
  604. if (ret)
  605. return ret;
  606. alvium->dft_img_width = imgw;
  607. alvium->img_min_width = imgw_min;
  608. alvium->img_max_width = imgw_max;
  609. alvium->img_inc_width = imgw_inc;
  610. return 0;
  611. }
  612. static int alvium_get_img_height_params(struct alvium_dev *alvium)
  613. {
  614. u64 imgh, imgh_min, imgh_max, imgh_inc;
  615. int ret = 0;
  616. alvium_read(alvium, REG_BCRM_IMG_HEIGHT_RW, &imgh, &ret);
  617. alvium_read(alvium, REG_BCRM_IMG_HEIGHT_MIN_R, &imgh_min, &ret);
  618. alvium_read(alvium, REG_BCRM_IMG_HEIGHT_MAX_R, &imgh_max, &ret);
  619. alvium_read(alvium, REG_BCRM_IMG_HEIGHT_INC_R, &imgh_inc, &ret);
  620. if (ret)
  621. return ret;
  622. alvium->dft_img_height = imgh;
  623. alvium->img_min_height = imgh_min;
  624. alvium->img_max_height = imgh_max;
  625. alvium->img_inc_height = imgh_inc;
  626. return 0;
  627. }
  628. static int alvium_set_img_width(struct alvium_dev *alvium, u32 width)
  629. {
  630. struct device *dev = &alvium->i2c_client->dev;
  631. int ret;
  632. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_WIDTH_RW, width);
  633. if (ret) {
  634. dev_err(dev, "Fail to set img width\n");
  635. return ret;
  636. }
  637. return 0;
  638. }
  639. static int alvium_set_img_height(struct alvium_dev *alvium, u32 height)
  640. {
  641. struct device *dev = &alvium->i2c_client->dev;
  642. int ret;
  643. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_HEIGHT_RW, height);
  644. if (ret) {
  645. dev_err(dev, "Fail to set img height\n");
  646. return ret;
  647. }
  648. return 0;
  649. }
  650. static int alvium_set_img_offx(struct alvium_dev *alvium, u32 offx)
  651. {
  652. struct device *dev = &alvium->i2c_client->dev;
  653. int ret;
  654. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_OFFSET_X_RW, offx);
  655. if (ret) {
  656. dev_err(dev, "Fail to set img offx\n");
  657. return ret;
  658. }
  659. return 0;
  660. }
  661. static int alvium_set_img_offy(struct alvium_dev *alvium, u32 offy)
  662. {
  663. struct device *dev = &alvium->i2c_client->dev;
  664. int ret;
  665. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_OFFSET_Y_RW, offy);
  666. if (ret) {
  667. dev_err(dev, "Fail to set img offy\n");
  668. return ret;
  669. }
  670. return 0;
  671. }
  672. static int alvium_get_offx_params(struct alvium_dev *alvium)
  673. {
  674. u64 min_offx, max_offx, inc_offx;
  675. int ret = 0;
  676. alvium_read(alvium, REG_BCRM_IMG_OFFSET_X_MIN_R, &min_offx, &ret);
  677. alvium_read(alvium, REG_BCRM_IMG_OFFSET_X_MAX_R, &max_offx, &ret);
  678. alvium_read(alvium, REG_BCRM_IMG_OFFSET_X_INC_R, &inc_offx, &ret);
  679. if (ret)
  680. return ret;
  681. alvium->min_offx = min_offx;
  682. alvium->max_offx = max_offx;
  683. alvium->inc_offx = inc_offx;
  684. return 0;
  685. }
  686. static int alvium_get_offy_params(struct alvium_dev *alvium)
  687. {
  688. u64 min_offy, max_offy, inc_offy;
  689. int ret = 0;
  690. alvium_read(alvium, REG_BCRM_IMG_OFFSET_Y_MIN_R, &min_offy, &ret);
  691. alvium_read(alvium, REG_BCRM_IMG_OFFSET_Y_MAX_R, &max_offy, &ret);
  692. alvium_read(alvium, REG_BCRM_IMG_OFFSET_Y_INC_R, &inc_offy, &ret);
  693. if (ret)
  694. return ret;
  695. alvium->min_offy = min_offy;
  696. alvium->max_offy = max_offy;
  697. alvium->inc_offy = inc_offy;
  698. return 0;
  699. }
  700. static int alvium_get_gain_params(struct alvium_dev *alvium)
  701. {
  702. u64 dft_gain, min_gain, max_gain, inc_gain;
  703. int ret = 0;
  704. alvium_read(alvium, REG_BCRM_GAIN_RW, &dft_gain, &ret);
  705. alvium_read(alvium, REG_BCRM_GAIN_MIN_R, &min_gain, &ret);
  706. alvium_read(alvium, REG_BCRM_GAIN_MAX_R, &max_gain, &ret);
  707. alvium_read(alvium, REG_BCRM_GAIN_INC_R, &inc_gain, &ret);
  708. if (ret)
  709. return ret;
  710. alvium->dft_gain = dft_gain;
  711. alvium->min_gain = min_gain;
  712. alvium->max_gain = max_gain;
  713. alvium->inc_gain = inc_gain;
  714. return 0;
  715. }
  716. static int alvium_get_exposure_params(struct alvium_dev *alvium)
  717. {
  718. u64 dft_exp, min_exp, max_exp, inc_exp;
  719. int ret = 0;
  720. alvium_read(alvium, REG_BCRM_EXPOSURE_TIME_RW, &dft_exp, &ret);
  721. alvium_read(alvium, REG_BCRM_EXPOSURE_TIME_MIN_R, &min_exp, &ret);
  722. alvium_read(alvium, REG_BCRM_EXPOSURE_TIME_MAX_R, &max_exp, &ret);
  723. alvium_read(alvium, REG_BCRM_EXPOSURE_TIME_INC_R, &inc_exp, &ret);
  724. if (ret)
  725. return ret;
  726. alvium->dft_exp = dft_exp;
  727. alvium->min_exp = min_exp;
  728. alvium->max_exp = max_exp;
  729. alvium->inc_exp = inc_exp;
  730. return 0;
  731. }
  732. static int alvium_get_red_balance_ratio_params(struct alvium_dev *alvium)
  733. {
  734. u64 dft_rb, min_rb, max_rb, inc_rb;
  735. int ret = 0;
  736. alvium_read(alvium, REG_BCRM_RED_BALANCE_RATIO_RW, &dft_rb, &ret);
  737. alvium_read(alvium, REG_BCRM_RED_BALANCE_RATIO_MIN_R, &min_rb, &ret);
  738. alvium_read(alvium, REG_BCRM_RED_BALANCE_RATIO_MAX_R, &max_rb, &ret);
  739. alvium_read(alvium, REG_BCRM_RED_BALANCE_RATIO_INC_R, &inc_rb, &ret);
  740. if (ret)
  741. return ret;
  742. alvium->dft_rbalance = dft_rb;
  743. alvium->min_rbalance = min_rb;
  744. alvium->max_rbalance = max_rb;
  745. alvium->inc_rbalance = inc_rb;
  746. return 0;
  747. }
  748. static int alvium_get_blue_balance_ratio_params(struct alvium_dev *alvium)
  749. {
  750. u64 dft_bb, min_bb, max_bb, inc_bb;
  751. int ret = 0;
  752. alvium_read(alvium, REG_BCRM_BLUE_BALANCE_RATIO_RW, &dft_bb, &ret);
  753. alvium_read(alvium, REG_BCRM_BLUE_BALANCE_RATIO_MIN_R, &min_bb, &ret);
  754. alvium_read(alvium, REG_BCRM_BLUE_BALANCE_RATIO_MAX_R, &max_bb, &ret);
  755. alvium_read(alvium, REG_BCRM_BLUE_BALANCE_RATIO_INC_R, &inc_bb, &ret);
  756. if (ret)
  757. return ret;
  758. alvium->dft_bbalance = dft_bb;
  759. alvium->min_bbalance = min_bb;
  760. alvium->max_bbalance = max_bb;
  761. alvium->inc_bbalance = inc_bb;
  762. return 0;
  763. }
  764. static int alvium_get_hue_params(struct alvium_dev *alvium)
  765. {
  766. u64 dft_hue, min_hue, max_hue, inc_hue;
  767. int ret = 0;
  768. alvium_read(alvium, REG_BCRM_HUE_RW, &dft_hue, &ret);
  769. alvium_read(alvium, REG_BCRM_HUE_MIN_R, &min_hue, &ret);
  770. alvium_read(alvium, REG_BCRM_HUE_MAX_R, &max_hue, &ret);
  771. alvium_read(alvium, REG_BCRM_HUE_INC_R, &inc_hue, &ret);
  772. if (ret)
  773. return ret;
  774. alvium->dft_hue = (s32)dft_hue;
  775. alvium->min_hue = (s32)min_hue;
  776. alvium->max_hue = (s32)max_hue;
  777. alvium->inc_hue = (s32)inc_hue;
  778. return 0;
  779. }
  780. static int alvium_get_black_lvl_params(struct alvium_dev *alvium)
  781. {
  782. u64 dft_blvl, min_blvl, max_blvl, inc_blvl;
  783. int ret = 0;
  784. alvium_read(alvium, REG_BCRM_BLACK_LEVEL_RW, &dft_blvl, &ret);
  785. alvium_read(alvium, REG_BCRM_BLACK_LEVEL_MIN_R, &min_blvl, &ret);
  786. alvium_read(alvium, REG_BCRM_BLACK_LEVEL_MAX_R, &max_blvl, &ret);
  787. alvium_read(alvium, REG_BCRM_BLACK_LEVEL_INC_R, &inc_blvl, &ret);
  788. if (ret)
  789. return ret;
  790. alvium->dft_black_lvl = (s32)dft_blvl;
  791. alvium->min_black_lvl = (s32)min_blvl;
  792. alvium->max_black_lvl = (s32)max_blvl;
  793. alvium->inc_black_lvl = (s32)inc_blvl;
  794. return 0;
  795. }
  796. static int alvium_get_gamma_params(struct alvium_dev *alvium)
  797. {
  798. u64 dft_g, min_g, max_g, inc_g;
  799. int ret = 0;
  800. alvium_read(alvium, REG_BCRM_GAMMA_RW, &dft_g, &ret);
  801. alvium_read(alvium, REG_BCRM_GAMMA_MIN_R, &min_g, &ret);
  802. alvium_read(alvium, REG_BCRM_GAMMA_MAX_R, &max_g, &ret);
  803. alvium_read(alvium, REG_BCRM_GAMMA_INC_R, &inc_g, &ret);
  804. if (ret)
  805. return ret;
  806. alvium->dft_gamma = dft_g;
  807. alvium->min_gamma = min_g;
  808. alvium->max_gamma = max_g;
  809. alvium->inc_gamma = inc_g;
  810. return 0;
  811. }
  812. static int alvium_get_sharpness_params(struct alvium_dev *alvium)
  813. {
  814. u64 dft_sh, min_sh, max_sh, inc_sh;
  815. int ret = 0;
  816. alvium_read(alvium, REG_BCRM_SHARPNESS_RW, &dft_sh, &ret);
  817. alvium_read(alvium, REG_BCRM_SHARPNESS_MIN_R, &min_sh, &ret);
  818. alvium_read(alvium, REG_BCRM_BLACK_LEVEL_MAX_R, &max_sh, &ret);
  819. alvium_read(alvium, REG_BCRM_SHARPNESS_INC_R, &inc_sh, &ret);
  820. if (ret)
  821. return ret;
  822. alvium->dft_sharp = (s32)dft_sh;
  823. alvium->min_sharp = (s32)min_sh;
  824. alvium->max_sharp = (s32)max_sh;
  825. alvium->inc_sharp = (s32)inc_sh;
  826. return 0;
  827. }
  828. static int alvium_get_contrast_params(struct alvium_dev *alvium)
  829. {
  830. u64 dft_c, min_c, max_c, inc_c;
  831. int ret = 0;
  832. alvium_read(alvium, REG_BCRM_CONTRAST_VALUE_RW, &dft_c, &ret);
  833. alvium_read(alvium, REG_BCRM_CONTRAST_VALUE_MIN_R, &min_c, &ret);
  834. alvium_read(alvium, REG_BCRM_CONTRAST_VALUE_MAX_R, &max_c, &ret);
  835. alvium_read(alvium, REG_BCRM_CONTRAST_VALUE_INC_R, &inc_c, &ret);
  836. if (ret)
  837. return ret;
  838. alvium->dft_contrast = dft_c;
  839. alvium->min_contrast = min_c;
  840. alvium->max_contrast = max_c;
  841. alvium->inc_contrast = inc_c;
  842. return 0;
  843. }
  844. static int alvium_get_saturation_params(struct alvium_dev *alvium)
  845. {
  846. u64 dft_sat, min_sat, max_sat, inc_sat;
  847. int ret = 0;
  848. alvium_read(alvium, REG_BCRM_SATURATION_RW, &dft_sat, &ret);
  849. alvium_read(alvium, REG_BCRM_SATURATION_MIN_R, &min_sat, &ret);
  850. alvium_read(alvium, REG_BCRM_SATURATION_MAX_R, &max_sat, &ret);
  851. alvium_read(alvium, REG_BCRM_SATURATION_INC_R, &inc_sat, &ret);
  852. if (ret)
  853. return ret;
  854. alvium->dft_sat = dft_sat;
  855. alvium->min_sat = min_sat;
  856. alvium->max_sat = max_sat;
  857. alvium->inc_sat = inc_sat;
  858. return 0;
  859. }
  860. static int alvium_set_bcm_mode(struct alvium_dev *alvium)
  861. {
  862. int ret = 0;
  863. alvium_write(alvium, REG_GENCP_CHANGEMODE_W, ALVIUM_BCM_MODE, &ret);
  864. alvium->bcrm_mode = ALVIUM_BCM_MODE;
  865. return ret;
  866. }
  867. static int alvium_get_mode(struct alvium_dev *alvium)
  868. {
  869. u64 bcrm_mode;
  870. int ret;
  871. ret = alvium_read(alvium, REG_GENCP_CURRENTMODE_R, &bcrm_mode, NULL);
  872. if (ret)
  873. return ret;
  874. switch (bcrm_mode) {
  875. case ALVIUM_BCM_MODE:
  876. alvium->bcrm_mode = ALVIUM_BCM_MODE;
  877. break;
  878. case ALVIUM_GENCP_MODE:
  879. alvium->bcrm_mode = ALVIUM_GENCP_MODE;
  880. break;
  881. }
  882. return 0;
  883. }
  884. static int alvium_get_avail_mipi_data_format(struct alvium_dev *alvium)
  885. {
  886. struct alvium_avail_mipi_fmt *avail_fmt;
  887. u64 val;
  888. int ret;
  889. ret = alvium_read(alvium, REG_BCRM_IMG_AVAILABLE_MIPI_DATA_FORMATS_R,
  890. &val, NULL);
  891. if (ret)
  892. return ret;
  893. avail_fmt = (struct alvium_avail_mipi_fmt *)&val;
  894. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8_LEG] =
  895. avail_fmt->yuv420_8_leg;
  896. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8] =
  897. avail_fmt->yuv420_8;
  898. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_10] =
  899. avail_fmt->yuv420_10;
  900. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_8_CSPS] =
  901. avail_fmt->yuv420_8_csps;
  902. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV420_10_CSPS] =
  903. avail_fmt->yuv420_10_csps;
  904. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV422_8] =
  905. avail_fmt->yuv422_8;
  906. alvium->is_mipi_fmt_avail[ALVIUM_BIT_YUV422_10] =
  907. avail_fmt->yuv422_10;
  908. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB888] =
  909. avail_fmt->rgb888;
  910. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB666] =
  911. avail_fmt->rgb666;
  912. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB565] =
  913. avail_fmt->rgb565;
  914. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB555] =
  915. avail_fmt->rgb555;
  916. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RGB444] =
  917. avail_fmt->rgb444;
  918. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW6] =
  919. avail_fmt->raw6;
  920. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW7] =
  921. avail_fmt->raw7;
  922. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW8] =
  923. avail_fmt->raw8;
  924. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW10] =
  925. avail_fmt->raw10;
  926. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW12] =
  927. avail_fmt->raw12;
  928. alvium->is_mipi_fmt_avail[ALVIUM_BIT_RAW14] =
  929. avail_fmt->raw14;
  930. alvium->is_mipi_fmt_avail[ALVIUM_BIT_JPEG] =
  931. avail_fmt->jpeg;
  932. alvium_print_avail_mipi_fmt(alvium);
  933. return 0;
  934. }
  935. static int alvium_setup_mipi_fmt(struct alvium_dev *alvium)
  936. {
  937. unsigned int avail_fmt_cnt = 0;
  938. unsigned int fmt = 0;
  939. size_t sz = 0;
  940. /* calculate fmt array size */
  941. for (fmt = 0; fmt < ALVIUM_NUM_SUPP_MIPI_DATA_FMT; fmt++) {
  942. if (!alvium->is_mipi_fmt_avail[alvium_csi2_fmts[fmt].fmt_av_bit])
  943. continue;
  944. if (!alvium_csi2_fmts[fmt].is_raw ||
  945. alvium->is_bay_avail[alvium_csi2_fmts[fmt].bay_av_bit])
  946. sz++;
  947. }
  948. /* init alvium_csi2_fmt array */
  949. alvium->alvium_csi2_fmt_n = sz;
  950. alvium->alvium_csi2_fmt =
  951. kmalloc_objs(struct alvium_pixfmt, sz);
  952. if (!alvium->alvium_csi2_fmt)
  953. return -ENOMEM;
  954. /* Create the alvium_csi2 fmt array from formats available */
  955. for (fmt = 0; fmt < ALVIUM_NUM_SUPP_MIPI_DATA_FMT; fmt++) {
  956. if (!alvium->is_mipi_fmt_avail[alvium_csi2_fmts[fmt].fmt_av_bit])
  957. continue;
  958. if (!alvium_csi2_fmts[fmt].is_raw ||
  959. alvium->is_bay_avail[alvium_csi2_fmts[fmt].bay_av_bit]) {
  960. alvium->alvium_csi2_fmt[avail_fmt_cnt] =
  961. alvium_csi2_fmts[fmt];
  962. avail_fmt_cnt++;
  963. }
  964. }
  965. return 0;
  966. }
  967. static int alvium_set_mipi_fmt(struct alvium_dev *alvium,
  968. const struct alvium_pixfmt *pixfmt)
  969. {
  970. struct device *dev = &alvium->i2c_client->dev;
  971. int ret;
  972. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_MIPI_DATA_FORMAT_RW,
  973. pixfmt->mipi_fmt_regval);
  974. if (ret) {
  975. dev_err(dev, "Fail to set mipi fmt\n");
  976. return ret;
  977. }
  978. return 0;
  979. }
  980. static int alvium_get_avail_bayer(struct alvium_dev *alvium)
  981. {
  982. struct alvium_avail_bayer *avail_bay;
  983. u64 val;
  984. int ret;
  985. ret = alvium_read(alvium, REG_BCRM_IMG_BAYER_PATTERN_INQUIRY_R,
  986. &val, NULL);
  987. if (ret)
  988. return ret;
  989. avail_bay = (struct alvium_avail_bayer *)&val;
  990. alvium->is_bay_avail[ALVIUM_BIT_BAY_MONO] = avail_bay->mono;
  991. alvium->is_bay_avail[ALVIUM_BIT_BAY_GR] = avail_bay->gr;
  992. alvium->is_bay_avail[ALVIUM_BIT_BAY_RG] = avail_bay->rg;
  993. alvium->is_bay_avail[ALVIUM_BIT_BAY_GB] = avail_bay->gb;
  994. alvium->is_bay_avail[ALVIUM_BIT_BAY_BG] = avail_bay->bg;
  995. alvium_print_avail_bayer(alvium);
  996. return 0;
  997. }
  998. static int alvium_set_bayer_pattern(struct alvium_dev *alvium,
  999. const struct alvium_pixfmt *pixfmt)
  1000. {
  1001. struct device *dev = &alvium->i2c_client->dev;
  1002. int ret;
  1003. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_BAYER_PATTERN_RW,
  1004. pixfmt->bay_fmt_regval);
  1005. if (ret) {
  1006. dev_err(dev, "Fail to set bayer pattern\n");
  1007. return ret;
  1008. }
  1009. return 0;
  1010. }
  1011. static int alvium_get_frame_interval(struct alvium_dev *alvium,
  1012. u64 *min_fr, u64 *max_fr)
  1013. {
  1014. int ret = 0;
  1015. alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MIN_R,
  1016. min_fr, &ret);
  1017. alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MAX_R,
  1018. max_fr, &ret);
  1019. return ret;
  1020. }
  1021. static int alvium_set_frame_rate(struct alvium_dev *alvium, u64 fr)
  1022. {
  1023. struct device *dev = &alvium->i2c_client->dev;
  1024. int ret;
  1025. ret = alvium_write_hshake(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_EN_RW,
  1026. 1);
  1027. if (ret) {
  1028. dev_err(dev, "Fail to set acquisition frame rate enable reg\n");
  1029. return ret;
  1030. }
  1031. ret = alvium_write_hshake(alvium, REG_BCRM_FRAME_START_TRIGGER_MODE_RW,
  1032. 0);
  1033. if (ret) {
  1034. dev_err(dev, "Fail to set frame start trigger mode reg\n");
  1035. return ret;
  1036. }
  1037. ret = alvium_write_hshake(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_RW,
  1038. fr);
  1039. if (ret) {
  1040. dev_err(dev, "Fail to set frame rate lanes reg\n");
  1041. return ret;
  1042. }
  1043. dev_dbg(dev, "set frame rate: %llu us\n", fr);
  1044. return 0;
  1045. }
  1046. static int alvium_set_stream_mipi(struct alvium_dev *alvium, bool on)
  1047. {
  1048. struct device *dev = &alvium->i2c_client->dev;
  1049. int ret;
  1050. ret = alvium_write_hshake(alvium, on ? REG_BCRM_ACQUISITION_START_RW :
  1051. REG_BCRM_ACQUISITION_STOP_RW, 0x01);
  1052. if (ret) {
  1053. dev_err(dev, "Fail set_stream_mipi\n");
  1054. return ret;
  1055. }
  1056. return 0;
  1057. }
  1058. static int alvium_get_gain(struct alvium_dev *alvium)
  1059. {
  1060. u64 gain;
  1061. int ret;
  1062. /* The unit is millibel (1 mB = 0.01 dB) */
  1063. ret = alvium_read(alvium, REG_BCRM_GAIN_RW, &gain, NULL);
  1064. if (ret)
  1065. return ret;
  1066. return gain;
  1067. }
  1068. static int alvium_set_ctrl_gain(struct alvium_dev *alvium, int gain)
  1069. {
  1070. struct device *dev = &alvium->i2c_client->dev;
  1071. int ret;
  1072. /* The unit is millibel (1 mB = 0.01 dB) */
  1073. ret = alvium_write_hshake(alvium, REG_BCRM_GAIN_RW, (u64)gain);
  1074. if (ret) {
  1075. dev_err(dev, "Fail to set gain value reg\n");
  1076. return ret;
  1077. }
  1078. return 0;
  1079. }
  1080. static int alvium_set_ctrl_auto_gain(struct alvium_dev *alvium, bool on)
  1081. {
  1082. struct device *dev = &alvium->i2c_client->dev;
  1083. int ret;
  1084. ret = alvium_write_hshake(alvium, REG_BCRM_GAIN_AUTO_RW,
  1085. on ? 0x02 : 0x00);
  1086. if (ret) {
  1087. dev_err(dev, "Fail to set autogain reg\n");
  1088. return ret;
  1089. }
  1090. return 0;
  1091. }
  1092. static int alvium_get_exposure(struct alvium_dev *alvium)
  1093. {
  1094. u64 exp;
  1095. int ret;
  1096. /* Exposure time in ns */
  1097. ret = alvium_read(alvium, REG_BCRM_EXPOSURE_TIME_RW, &exp, NULL);
  1098. if (ret)
  1099. return ret;
  1100. return exp;
  1101. }
  1102. static int alvium_set_ctrl_auto_exposure(struct alvium_dev *alvium, bool on)
  1103. {
  1104. struct device *dev = &alvium->i2c_client->dev;
  1105. int ret;
  1106. ret = alvium_write_hshake(alvium, REG_BCRM_WHITE_BALANCE_AUTO_RW,
  1107. on ? 0x02 : 0x00);
  1108. if (ret) {
  1109. dev_err(dev, "Fail to set autoexposure reg\n");
  1110. return ret;
  1111. }
  1112. return 0;
  1113. }
  1114. static int alvium_set_ctrl_exposure(struct alvium_dev *alvium, int exposure_ns)
  1115. {
  1116. struct device *dev = &alvium->i2c_client->dev;
  1117. int ret;
  1118. ret = alvium_write_hshake(alvium, REG_BCRM_EXPOSURE_TIME_RW,
  1119. (u64)exposure_ns);
  1120. if (ret) {
  1121. dev_err(dev, "Fail to set exposure value reg\n");
  1122. return ret;
  1123. }
  1124. return 0;
  1125. }
  1126. static int alvium_set_ctrl_blue_balance_ratio(struct alvium_dev *alvium,
  1127. int blue)
  1128. {
  1129. struct device *dev = &alvium->i2c_client->dev;
  1130. int ret;
  1131. ret = alvium_write_hshake(alvium, REG_BCRM_BLUE_BALANCE_RATIO_RW,
  1132. (u64)blue);
  1133. if (ret) {
  1134. dev_err(dev, "Fail to set blue ratio value reg\n");
  1135. return ret;
  1136. }
  1137. return 0;
  1138. }
  1139. static int alvium_set_ctrl_red_balance_ratio(struct alvium_dev *alvium, int red)
  1140. {
  1141. struct device *dev = &alvium->i2c_client->dev;
  1142. int ret;
  1143. ret = alvium_write_hshake(alvium, REG_BCRM_RED_BALANCE_RATIO_RW,
  1144. (u64)red);
  1145. if (ret) {
  1146. dev_err(dev, "Fail to set red ratio value reg\n");
  1147. return ret;
  1148. }
  1149. return 0;
  1150. }
  1151. static int alvium_set_ctrl_awb(struct alvium_dev *alvium, bool on)
  1152. {
  1153. struct device *dev = &alvium->i2c_client->dev;
  1154. int ret;
  1155. ret = alvium_write_hshake(alvium, REG_BCRM_WHITE_BALANCE_AUTO_RW,
  1156. on ? 0x02 : 0x00);
  1157. if (ret) {
  1158. dev_err(dev, "Fail to set awb reg\n");
  1159. return ret;
  1160. }
  1161. return 0;
  1162. }
  1163. static int alvium_set_ctrl_hue(struct alvium_dev *alvium, int val)
  1164. {
  1165. struct device *dev = &alvium->i2c_client->dev;
  1166. int ret;
  1167. ret = alvium_write_hshake(alvium, REG_BCRM_HUE_RW, (u64)val);
  1168. if (ret) {
  1169. dev_err(dev, "Fail to set hue value reg\n");
  1170. return ret;
  1171. }
  1172. return 0;
  1173. }
  1174. static int alvium_set_ctrl_contrast(struct alvium_dev *alvium, int val)
  1175. {
  1176. struct device *dev = &alvium->i2c_client->dev;
  1177. int ret;
  1178. ret = alvium_write_hshake(alvium, REG_BCRM_CONTRAST_VALUE_RW, (u64)val);
  1179. if (ret) {
  1180. dev_err(dev, "Fail to set contrast value reg\n");
  1181. return ret;
  1182. }
  1183. return 0;
  1184. }
  1185. static int alvium_set_ctrl_saturation(struct alvium_dev *alvium, int val)
  1186. {
  1187. struct device *dev = &alvium->i2c_client->dev;
  1188. int ret;
  1189. ret = alvium_write_hshake(alvium, REG_BCRM_SATURATION_RW, (u64)val);
  1190. if (ret) {
  1191. dev_err(dev, "Fail to set contrast value reg\n");
  1192. return ret;
  1193. }
  1194. return 0;
  1195. }
  1196. static int alvium_set_ctrl_gamma(struct alvium_dev *alvium, int val)
  1197. {
  1198. struct device *dev = &alvium->i2c_client->dev;
  1199. int ret;
  1200. ret = alvium_write_hshake(alvium, REG_BCRM_GAMMA_RW, (u64)val);
  1201. if (ret) {
  1202. dev_err(dev, "Fail to set gamma value reg\n");
  1203. return ret;
  1204. }
  1205. return 0;
  1206. }
  1207. static int alvium_set_ctrl_sharpness(struct alvium_dev *alvium, int val)
  1208. {
  1209. struct device *dev = &alvium->i2c_client->dev;
  1210. int ret;
  1211. ret = alvium_write_hshake(alvium, REG_BCRM_SHARPNESS_RW, (u64)val);
  1212. if (ret) {
  1213. dev_err(dev, "Fail to set sharpness value reg\n");
  1214. return ret;
  1215. }
  1216. return 0;
  1217. }
  1218. static int alvium_set_ctrl_hflip(struct alvium_dev *alvium, int val)
  1219. {
  1220. struct device *dev = &alvium->i2c_client->dev;
  1221. int ret;
  1222. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_REVERSE_X_RW, (u64)val);
  1223. if (ret) {
  1224. dev_err(dev, "Fail to set reverse_x value reg\n");
  1225. return ret;
  1226. }
  1227. return 0;
  1228. }
  1229. static int alvium_set_ctrl_vflip(struct alvium_dev *alvium, int val)
  1230. {
  1231. struct device *dev = &alvium->i2c_client->dev;
  1232. int ret;
  1233. ret = alvium_write_hshake(alvium, REG_BCRM_IMG_REVERSE_Y_RW, (u64)val);
  1234. if (ret) {
  1235. dev_err(dev, "Fail to set reverse_y value reg\n");
  1236. return ret;
  1237. }
  1238. return 0;
  1239. }
  1240. static int alvium_get_hw_features_params(struct alvium_dev *alvium)
  1241. {
  1242. struct device *dev = &alvium->i2c_client->dev;
  1243. int ret;
  1244. ret = alvium_get_csi_clk_params(alvium);
  1245. if (ret) {
  1246. dev_err(dev, "Fail to read min/max csi clock regs\n");
  1247. return ret;
  1248. }
  1249. ret = alvium_get_img_width_params(alvium);
  1250. if (ret) {
  1251. dev_err(dev, "Fail to read img width regs\n");
  1252. return ret;
  1253. }
  1254. ret = alvium_get_img_height_params(alvium);
  1255. if (ret) {
  1256. dev_err(dev, "Fail to read img height regs\n");
  1257. return ret;
  1258. }
  1259. ret = alvium_get_offx_params(alvium);
  1260. if (ret) {
  1261. dev_err(dev, "Fail to read offx regs\n");
  1262. return ret;
  1263. }
  1264. ret = alvium_get_offy_params(alvium);
  1265. if (ret) {
  1266. dev_err(dev, "Fail to read offy regs\n");
  1267. return ret;
  1268. }
  1269. ret = alvium_get_gain_params(alvium);
  1270. if (ret) {
  1271. dev_err(dev, "Fail to read gain regs\n");
  1272. return ret;
  1273. }
  1274. ret = alvium_get_exposure_params(alvium);
  1275. if (ret) {
  1276. dev_err(dev, "Fail to read min/max exp regs\n");
  1277. return ret;
  1278. }
  1279. ret = alvium_get_red_balance_ratio_params(alvium);
  1280. if (ret) {
  1281. dev_err(dev, "Fail to read red balance ratio regs\n");
  1282. return ret;
  1283. }
  1284. ret = alvium_get_blue_balance_ratio_params(alvium);
  1285. if (ret) {
  1286. dev_err(dev, "Fail to read blue balance ratio regs\n");
  1287. return ret;
  1288. }
  1289. ret = alvium_get_hue_params(alvium);
  1290. if (ret) {
  1291. dev_err(dev, "Fail to read hue regs\n");
  1292. return ret;
  1293. }
  1294. ret = alvium_get_contrast_params(alvium);
  1295. if (ret) {
  1296. dev_err(dev, "Fail to read contrast regs\n");
  1297. return ret;
  1298. }
  1299. ret = alvium_get_saturation_params(alvium);
  1300. if (ret) {
  1301. dev_err(dev, "Fail to read saturation regs\n");
  1302. return ret;
  1303. }
  1304. ret = alvium_get_black_lvl_params(alvium);
  1305. if (ret) {
  1306. dev_err(dev, "Fail to read black lvl regs\n");
  1307. return ret;
  1308. }
  1309. ret = alvium_get_gamma_params(alvium);
  1310. if (ret) {
  1311. dev_err(dev, "Fail to read gamma regs\n");
  1312. return ret;
  1313. }
  1314. ret = alvium_get_sharpness_params(alvium);
  1315. if (ret) {
  1316. dev_err(dev, "Fail to read sharpness regs\n");
  1317. return ret;
  1318. }
  1319. return 0;
  1320. }
  1321. static int alvium_get_hw_info(struct alvium_dev *alvium)
  1322. {
  1323. struct device *dev = &alvium->i2c_client->dev;
  1324. int ret;
  1325. ret = alvium_get_bcrm_vers(alvium);
  1326. if (ret) {
  1327. dev_err(dev, "Fail to read bcrm version reg\n");
  1328. return ret;
  1329. }
  1330. ret = alvium_get_bcrm_addr(alvium);
  1331. if (ret) {
  1332. dev_err(dev, "Fail to bcrm address reg\n");
  1333. return ret;
  1334. }
  1335. ret = alvium_get_fw_version(alvium);
  1336. if (ret) {
  1337. dev_err(dev, "Fail to read fw version reg\n");
  1338. return ret;
  1339. }
  1340. ret = alvium_get_host_supp_csi_lanes(alvium);
  1341. if (ret) {
  1342. dev_err(dev, "Fail to read host supported csi lanes reg\n");
  1343. return ret;
  1344. }
  1345. ret = alvium_get_feat_inq(alvium);
  1346. if (ret) {
  1347. dev_err(dev, "Fail to read bcrm feature inquiry reg\n");
  1348. return ret;
  1349. }
  1350. ret = alvium_get_hw_features_params(alvium);
  1351. if (ret) {
  1352. dev_err(dev, "Fail to read features params regs\n");
  1353. return ret;
  1354. }
  1355. ret = alvium_get_avail_mipi_data_format(alvium);
  1356. if (ret) {
  1357. dev_err(dev, "Fail to read available mipi data formats reg\n");
  1358. return ret;
  1359. }
  1360. ret = alvium_get_avail_bayer(alvium);
  1361. if (ret) {
  1362. dev_err(dev, "Fail to read available Bayer patterns reg\n");
  1363. return ret;
  1364. }
  1365. ret = alvium_get_mode(alvium);
  1366. if (ret) {
  1367. dev_err(dev, "Fail to get current mode reg\n");
  1368. return ret;
  1369. }
  1370. return 0;
  1371. }
  1372. static int alvium_hw_init(struct alvium_dev *alvium)
  1373. {
  1374. struct device *dev = &alvium->i2c_client->dev;
  1375. int ret;
  1376. /* Set Alvium BCM mode*/
  1377. ret = alvium_set_bcm_mode(alvium);
  1378. if (ret) {
  1379. dev_err(dev, "Fail to set BCM mode\n");
  1380. return ret;
  1381. }
  1382. ret = alvium_set_csi_lanes(alvium);
  1383. if (ret) {
  1384. dev_err(dev, "Fail to set csi lanes\n");
  1385. return ret;
  1386. }
  1387. ret = alvium_set_csi_clk(alvium);
  1388. if (ret) {
  1389. dev_err(dev, "Fail to set csi clk\n");
  1390. return ret;
  1391. }
  1392. ret = alvium_set_lp2hs_delay(alvium);
  1393. if (ret) {
  1394. dev_err(dev, "Fail to set lp2hs reg\n");
  1395. return ret;
  1396. }
  1397. return 0;
  1398. }
  1399. /* --------------- Subdev Operations --------------- */
  1400. static int alvium_s_frame_interval(struct v4l2_subdev *sd,
  1401. struct v4l2_subdev_state *sd_state,
  1402. struct v4l2_subdev_frame_interval *fi)
  1403. {
  1404. struct alvium_dev *alvium = sd_to_alvium(sd);
  1405. struct device *dev = &alvium->i2c_client->dev;
  1406. u64 req_fr, min_fr, max_fr;
  1407. struct v4l2_fract *interval;
  1408. int ret;
  1409. if (alvium->streaming)
  1410. return -EBUSY;
  1411. if (fi->interval.denominator == 0)
  1412. return -EINVAL;
  1413. ret = alvium_get_frame_interval(alvium, &min_fr, &max_fr);
  1414. if (ret) {
  1415. dev_err(dev, "Fail to get frame interval\n");
  1416. return ret;
  1417. }
  1418. dev_dbg(dev, "fi->interval.numerator = %d\n",
  1419. fi->interval.numerator);
  1420. dev_dbg(dev, "fi->interval.denominator = %d\n",
  1421. fi->interval.denominator);
  1422. req_fr = (u64)((fi->interval.denominator * USEC_PER_SEC) /
  1423. fi->interval.numerator);
  1424. req_fr = clamp(req_fr, min_fr, max_fr);
  1425. interval = v4l2_subdev_state_get_interval(sd_state, 0);
  1426. interval->numerator = fi->interval.numerator;
  1427. interval->denominator = fi->interval.denominator;
  1428. if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
  1429. return 0;
  1430. return alvium_set_frame_rate(alvium, req_fr);
  1431. }
  1432. static int alvium_enum_mbus_code(struct v4l2_subdev *sd,
  1433. struct v4l2_subdev_state *sd_state,
  1434. struct v4l2_subdev_mbus_code_enum *code)
  1435. {
  1436. struct alvium_dev *alvium = sd_to_alvium(sd);
  1437. if (code->index >= alvium->alvium_csi2_fmt_n)
  1438. return -EINVAL;
  1439. code->code = alvium->alvium_csi2_fmt[code->index].code;
  1440. return 0;
  1441. }
  1442. static const struct alvium_pixfmt *
  1443. alvium_code_to_pixfmt(struct alvium_dev *alvium, u32 code)
  1444. {
  1445. unsigned int i;
  1446. for (i = 0; alvium->alvium_csi2_fmt[i].code; ++i)
  1447. if (alvium->alvium_csi2_fmt[i].code == code)
  1448. return &alvium->alvium_csi2_fmt[i];
  1449. return &alvium->alvium_csi2_fmt[0];
  1450. }
  1451. static int alvium_enum_frame_size(struct v4l2_subdev *sd,
  1452. struct v4l2_subdev_state *state,
  1453. struct v4l2_subdev_frame_size_enum *fse)
  1454. {
  1455. struct alvium_dev *alvium = sd_to_alvium(sd);
  1456. const struct alvium_pixfmt *alvium_csi2_fmt;
  1457. if (fse->index)
  1458. return -EINVAL;
  1459. alvium_csi2_fmt = alvium_code_to_pixfmt(alvium, fse->code);
  1460. if (fse->code != alvium_csi2_fmt->code)
  1461. return -EINVAL;
  1462. fse->min_width = alvium->img_min_width;
  1463. fse->max_width = alvium->img_max_width;
  1464. fse->min_height = alvium->img_min_height;
  1465. fse->max_height = alvium->img_max_height;
  1466. return 0;
  1467. }
  1468. static int alvium_set_mode(struct alvium_dev *alvium,
  1469. struct v4l2_subdev_state *state)
  1470. {
  1471. struct v4l2_mbus_framefmt *fmt;
  1472. struct v4l2_rect *crop;
  1473. int ret;
  1474. crop = v4l2_subdev_state_get_crop(state, 0);
  1475. fmt = v4l2_subdev_state_get_format(state, 0);
  1476. v4l_bound_align_image(&fmt->width, alvium->img_min_width,
  1477. alvium->img_max_width, 0,
  1478. &fmt->height, alvium->img_min_height,
  1479. alvium->img_max_height, 0, 0);
  1480. /* alvium don't accept negative crop left/top */
  1481. crop->left = clamp((u32)max(0, crop->left), alvium->min_offx,
  1482. (u32)(alvium->img_max_width - fmt->width));
  1483. crop->top = clamp((u32)max(0, crop->top), alvium->min_offy,
  1484. (u32)(alvium->img_max_height - fmt->height));
  1485. ret = alvium_set_img_width(alvium, fmt->width);
  1486. if (ret)
  1487. return ret;
  1488. ret = alvium_set_img_height(alvium, fmt->height);
  1489. if (ret)
  1490. return ret;
  1491. ret = alvium_set_img_offx(alvium, crop->left);
  1492. if (ret)
  1493. return ret;
  1494. ret = alvium_set_img_offy(alvium, crop->top);
  1495. if (ret)
  1496. return ret;
  1497. return 0;
  1498. }
  1499. static int alvium_set_framefmt(struct alvium_dev *alvium,
  1500. struct v4l2_mbus_framefmt *format)
  1501. {
  1502. struct device *dev = &alvium->i2c_client->dev;
  1503. const struct alvium_pixfmt *alvium_csi2_fmt;
  1504. int ret = 0;
  1505. alvium_csi2_fmt = alvium_code_to_pixfmt(alvium, format->code);
  1506. ret = alvium_set_mipi_fmt(alvium, alvium_csi2_fmt);
  1507. if (ret)
  1508. return ret;
  1509. if (alvium_csi2_fmt->is_raw) {
  1510. ret = alvium_set_bayer_pattern(alvium, alvium_csi2_fmt);
  1511. if (ret)
  1512. return ret;
  1513. }
  1514. dev_dbg(dev, "start: %s, mipi_fmt_regval regval = 0x%llx",
  1515. __func__, alvium_csi2_fmt->mipi_fmt_regval);
  1516. return ret;
  1517. }
  1518. static int alvium_s_stream(struct v4l2_subdev *sd, int enable)
  1519. {
  1520. struct alvium_dev *alvium = sd_to_alvium(sd);
  1521. struct i2c_client *client = v4l2_get_subdevdata(&alvium->sd);
  1522. struct v4l2_mbus_framefmt *fmt;
  1523. struct v4l2_subdev_state *state;
  1524. int ret = 0;
  1525. state = v4l2_subdev_lock_and_get_active_state(sd);
  1526. if (enable) {
  1527. ret = pm_runtime_resume_and_get(&client->dev);
  1528. if (ret < 0)
  1529. goto out;
  1530. ret = __v4l2_ctrl_handler_setup(&alvium->ctrls.handler);
  1531. if (ret)
  1532. goto out;
  1533. ret = alvium_set_mode(alvium, state);
  1534. if (ret)
  1535. goto out;
  1536. fmt = v4l2_subdev_state_get_format(state, 0);
  1537. ret = alvium_set_framefmt(alvium, fmt);
  1538. if (ret)
  1539. goto out;
  1540. ret = alvium_set_stream_mipi(alvium, enable);
  1541. if (ret)
  1542. goto out;
  1543. } else {
  1544. alvium_set_stream_mipi(alvium, enable);
  1545. pm_runtime_put_autosuspend(&client->dev);
  1546. }
  1547. alvium->streaming = !!enable;
  1548. v4l2_subdev_unlock_state(state);
  1549. return 0;
  1550. out:
  1551. pm_runtime_put(&client->dev);
  1552. v4l2_subdev_unlock_state(state);
  1553. return ret;
  1554. }
  1555. static int alvium_init_state(struct v4l2_subdev *sd,
  1556. struct v4l2_subdev_state *state)
  1557. {
  1558. struct alvium_dev *alvium = sd_to_alvium(sd);
  1559. struct alvium_mode *mode = &alvium->mode;
  1560. struct v4l2_fract *interval;
  1561. struct v4l2_subdev_format sd_fmt = {
  1562. .which = V4L2_SUBDEV_FORMAT_TRY,
  1563. .format = alvium_csi2_default_fmt,
  1564. };
  1565. struct v4l2_subdev_crop sd_crop = {
  1566. .which = V4L2_SUBDEV_FORMAT_TRY,
  1567. .rect = {
  1568. .left = mode->crop.left,
  1569. .top = mode->crop.top,
  1570. .width = mode->crop.width,
  1571. .height = mode->crop.height,
  1572. },
  1573. };
  1574. *v4l2_subdev_state_get_crop(state, 0) = sd_crop.rect;
  1575. *v4l2_subdev_state_get_format(state, 0) = sd_fmt.format;
  1576. /* Setup initial frame interval*/
  1577. interval = v4l2_subdev_state_get_interval(state, 0);
  1578. interval->numerator = 1;
  1579. interval->denominator = ALVIUM_DEFAULT_FR_HZ;
  1580. return 0;
  1581. }
  1582. static int alvium_set_fmt(struct v4l2_subdev *sd,
  1583. struct v4l2_subdev_state *sd_state,
  1584. struct v4l2_subdev_format *format)
  1585. {
  1586. struct alvium_dev *alvium = sd_to_alvium(sd);
  1587. const struct alvium_pixfmt *alvium_csi2_fmt;
  1588. struct v4l2_mbus_framefmt *fmt;
  1589. struct v4l2_rect *crop;
  1590. fmt = v4l2_subdev_state_get_format(sd_state, 0);
  1591. crop = v4l2_subdev_state_get_crop(sd_state, 0);
  1592. v4l_bound_align_image(&format->format.width, alvium->img_min_width,
  1593. alvium->img_max_width, 0,
  1594. &format->format.height, alvium->img_min_height,
  1595. alvium->img_max_height, 0, 0);
  1596. /* Adjust left and top to prevent roll over sensor area */
  1597. crop->left = clamp((u32)crop->left, (u32)0,
  1598. (alvium->img_max_width - fmt->width));
  1599. crop->top = clamp((u32)crop->top, (u32)0,
  1600. (alvium->img_max_height - fmt->height));
  1601. /* Set also the crop width and height when set a new fmt */
  1602. crop->width = fmt->width;
  1603. crop->height = fmt->height;
  1604. alvium_csi2_fmt = alvium_code_to_pixfmt(alvium, format->format.code);
  1605. fmt->code = alvium_csi2_fmt->code;
  1606. *fmt = format->format;
  1607. return 0;
  1608. }
  1609. static int alvium_set_selection(struct v4l2_subdev *sd,
  1610. struct v4l2_subdev_state *sd_state,
  1611. struct v4l2_subdev_selection *sel)
  1612. {
  1613. struct alvium_dev *alvium = sd_to_alvium(sd);
  1614. struct v4l2_mbus_framefmt *fmt;
  1615. struct v4l2_rect *crop;
  1616. if (sel->target != V4L2_SEL_TGT_CROP)
  1617. return -EINVAL;
  1618. crop = v4l2_subdev_state_get_crop(sd_state, 0);
  1619. fmt = v4l2_subdev_state_get_format(sd_state, 0);
  1620. /*
  1621. * Alvium can only shift the origin of the img
  1622. * then we accept only value with the same value of the actual fmt
  1623. */
  1624. if (sel->r.width != fmt->width)
  1625. sel->r.width = fmt->width;
  1626. if (sel->r.height != fmt->height)
  1627. sel->r.height = fmt->height;
  1628. /* alvium don't accept negative crop left/top */
  1629. crop->left = clamp((u32)max(0, sel->r.left), alvium->min_offx,
  1630. alvium->img_max_width - sel->r.width);
  1631. crop->top = clamp((u32)max(0, sel->r.top), alvium->min_offy,
  1632. alvium->img_max_height - sel->r.height);
  1633. sel->r = *crop;
  1634. return 0;
  1635. }
  1636. static int alvium_get_selection(struct v4l2_subdev *sd,
  1637. struct v4l2_subdev_state *sd_state,
  1638. struct v4l2_subdev_selection *sel)
  1639. {
  1640. struct alvium_dev *alvium = sd_to_alvium(sd);
  1641. switch (sel->target) {
  1642. /* Current cropping area */
  1643. case V4L2_SEL_TGT_CROP:
  1644. sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
  1645. break;
  1646. /* Cropping bounds */
  1647. case V4L2_SEL_TGT_NATIVE_SIZE:
  1648. sel->r.top = 0;
  1649. sel->r.left = 0;
  1650. sel->r.width = alvium->img_max_width;
  1651. sel->r.height = alvium->img_max_height;
  1652. break;
  1653. /* Default cropping area */
  1654. case V4L2_SEL_TGT_CROP_BOUNDS:
  1655. case V4L2_SEL_TGT_CROP_DEFAULT:
  1656. sel->r.top = alvium->min_offy;
  1657. sel->r.left = alvium->min_offx;
  1658. sel->r.width = alvium->img_max_width;
  1659. sel->r.height = alvium->img_max_height;
  1660. break;
  1661. default:
  1662. return -EINVAL;
  1663. }
  1664. return 0;
  1665. }
  1666. static int alvium_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
  1667. {
  1668. struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
  1669. struct alvium_dev *alvium = sd_to_alvium(sd);
  1670. int val;
  1671. switch (ctrl->id) {
  1672. case V4L2_CID_ANALOGUE_GAIN:
  1673. val = alvium_get_gain(alvium);
  1674. if (val < 0)
  1675. return val;
  1676. alvium->ctrls.gain->val = val;
  1677. break;
  1678. case V4L2_CID_EXPOSURE:
  1679. val = alvium_get_exposure(alvium);
  1680. if (val < 0)
  1681. return val;
  1682. alvium->ctrls.exposure->val = val;
  1683. break;
  1684. }
  1685. return 0;
  1686. }
  1687. static int alvium_s_ctrl(struct v4l2_ctrl *ctrl)
  1688. {
  1689. struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
  1690. struct alvium_dev *alvium = sd_to_alvium(sd);
  1691. struct i2c_client *client = v4l2_get_subdevdata(&alvium->sd);
  1692. int ret;
  1693. /*
  1694. * Applying V4L2 control value only happens
  1695. * when power is up for streaming
  1696. */
  1697. if (!pm_runtime_get_if_in_use(&client->dev))
  1698. return 0;
  1699. switch (ctrl->id) {
  1700. case V4L2_CID_ANALOGUE_GAIN:
  1701. ret = alvium_set_ctrl_gain(alvium, ctrl->val);
  1702. break;
  1703. case V4L2_CID_AUTOGAIN:
  1704. ret = alvium_set_ctrl_auto_gain(alvium, ctrl->val);
  1705. break;
  1706. case V4L2_CID_EXPOSURE:
  1707. ret = alvium_set_ctrl_exposure(alvium, ctrl->val);
  1708. break;
  1709. case V4L2_CID_EXPOSURE_AUTO:
  1710. ret = alvium_set_ctrl_auto_exposure(alvium, ctrl->val);
  1711. break;
  1712. case V4L2_CID_RED_BALANCE:
  1713. ret = alvium_set_ctrl_red_balance_ratio(alvium, ctrl->val);
  1714. break;
  1715. case V4L2_CID_BLUE_BALANCE:
  1716. ret = alvium_set_ctrl_blue_balance_ratio(alvium, ctrl->val);
  1717. break;
  1718. case V4L2_CID_AUTO_WHITE_BALANCE:
  1719. ret = alvium_set_ctrl_awb(alvium, ctrl->val);
  1720. break;
  1721. case V4L2_CID_HUE:
  1722. ret = alvium_set_ctrl_hue(alvium, ctrl->val);
  1723. break;
  1724. case V4L2_CID_CONTRAST:
  1725. ret = alvium_set_ctrl_contrast(alvium, ctrl->val);
  1726. break;
  1727. case V4L2_CID_SATURATION:
  1728. ret = alvium_set_ctrl_saturation(alvium, ctrl->val);
  1729. break;
  1730. case V4L2_CID_GAMMA:
  1731. ret = alvium_set_ctrl_gamma(alvium, ctrl->val);
  1732. break;
  1733. case V4L2_CID_SHARPNESS:
  1734. ret = alvium_set_ctrl_sharpness(alvium, ctrl->val);
  1735. break;
  1736. case V4L2_CID_HFLIP:
  1737. ret = alvium_set_ctrl_hflip(alvium, ctrl->val);
  1738. break;
  1739. case V4L2_CID_VFLIP:
  1740. ret = alvium_set_ctrl_vflip(alvium, ctrl->val);
  1741. break;
  1742. default:
  1743. ret = -EINVAL;
  1744. break;
  1745. }
  1746. pm_runtime_put(&client->dev);
  1747. return ret;
  1748. }
  1749. static const struct v4l2_ctrl_ops alvium_ctrl_ops = {
  1750. .g_volatile_ctrl = alvium_g_volatile_ctrl,
  1751. .s_ctrl = alvium_s_ctrl,
  1752. };
  1753. static int alvium_ctrl_init(struct alvium_dev *alvium)
  1754. {
  1755. const struct v4l2_ctrl_ops *ops = &alvium_ctrl_ops;
  1756. struct alvium_ctrls *ctrls = &alvium->ctrls;
  1757. struct v4l2_ctrl_handler *hdl = &ctrls->handler;
  1758. struct v4l2_fwnode_device_properties props;
  1759. int ret;
  1760. v4l2_ctrl_handler_init(hdl, 32);
  1761. /* Pixel rate is fixed */
  1762. ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops,
  1763. V4L2_CID_PIXEL_RATE, 0,
  1764. ALVIUM_DEFAULT_PIXEL_RATE_MHZ, 1,
  1765. ALVIUM_DEFAULT_PIXEL_RATE_MHZ);
  1766. ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1767. /* Link freq is fixed */
  1768. ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops,
  1769. V4L2_CID_LINK_FREQ,
  1770. 0, 0, &alvium->link_freq);
  1771. ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
  1772. /* Auto/manual white balance */
  1773. if (alvium->avail_ft.auto_whiteb) {
  1774. ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
  1775. V4L2_CID_AUTO_WHITE_BALANCE,
  1776. 0, 1, 1, 1);
  1777. v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
  1778. }
  1779. ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops,
  1780. V4L2_CID_BLUE_BALANCE,
  1781. alvium->min_bbalance,
  1782. alvium->max_bbalance,
  1783. alvium->inc_bbalance,
  1784. alvium->dft_bbalance);
  1785. ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops,
  1786. V4L2_CID_RED_BALANCE,
  1787. alvium->min_rbalance,
  1788. alvium->max_rbalance,
  1789. alvium->inc_rbalance,
  1790. alvium->dft_rbalance);
  1791. /* Auto/manual exposure */
  1792. if (alvium->avail_ft.auto_exp) {
  1793. ctrls->auto_exp =
  1794. v4l2_ctrl_new_std_menu(hdl, ops,
  1795. V4L2_CID_EXPOSURE_AUTO,
  1796. V4L2_EXPOSURE_MANUAL, 0,
  1797. V4L2_EXPOSURE_AUTO);
  1798. v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
  1799. }
  1800. ctrls->exposure = v4l2_ctrl_new_std(hdl, ops,
  1801. V4L2_CID_EXPOSURE,
  1802. alvium->min_exp,
  1803. alvium->max_exp,
  1804. alvium->inc_exp,
  1805. alvium->dft_exp);
  1806. ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
  1807. /* Auto/manual gain */
  1808. if (alvium->avail_ft.auto_gain) {
  1809. ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops,
  1810. V4L2_CID_AUTOGAIN,
  1811. 0, 1, 1, 1);
  1812. v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
  1813. }
  1814. if (alvium->avail_ft.gain) {
  1815. ctrls->gain = v4l2_ctrl_new_std(hdl, ops,
  1816. V4L2_CID_ANALOGUE_GAIN,
  1817. alvium->min_gain,
  1818. alvium->max_gain,
  1819. alvium->inc_gain,
  1820. alvium->dft_gain);
  1821. ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
  1822. }
  1823. if (alvium->avail_ft.sat)
  1824. ctrls->saturation = v4l2_ctrl_new_std(hdl, ops,
  1825. V4L2_CID_SATURATION,
  1826. alvium->min_sat,
  1827. alvium->max_sat,
  1828. alvium->inc_sat,
  1829. alvium->dft_sat);
  1830. if (alvium->avail_ft.hue)
  1831. ctrls->hue = v4l2_ctrl_new_std(hdl, ops,
  1832. V4L2_CID_HUE,
  1833. alvium->min_hue,
  1834. alvium->max_hue,
  1835. alvium->inc_hue,
  1836. alvium->dft_hue);
  1837. if (alvium->avail_ft.contrast)
  1838. ctrls->contrast = v4l2_ctrl_new_std(hdl, ops,
  1839. V4L2_CID_CONTRAST,
  1840. alvium->min_contrast,
  1841. alvium->max_contrast,
  1842. alvium->inc_contrast,
  1843. alvium->dft_contrast);
  1844. if (alvium->avail_ft.gamma)
  1845. ctrls->gamma = v4l2_ctrl_new_std(hdl, ops,
  1846. V4L2_CID_GAMMA,
  1847. alvium->min_gamma,
  1848. alvium->max_gamma,
  1849. alvium->inc_gamma,
  1850. alvium->dft_gamma);
  1851. if (alvium->avail_ft.sharp)
  1852. ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops,
  1853. V4L2_CID_SHARPNESS,
  1854. alvium->min_sharp,
  1855. alvium->max_sharp,
  1856. alvium->inc_sharp,
  1857. alvium->dft_sharp);
  1858. if (alvium->avail_ft.rev_x)
  1859. ctrls->hflip = v4l2_ctrl_new_std(hdl, ops,
  1860. V4L2_CID_HFLIP,
  1861. 0, 1, 1, 0);
  1862. if (alvium->avail_ft.rev_y)
  1863. ctrls->vflip = v4l2_ctrl_new_std(hdl, ops,
  1864. V4L2_CID_VFLIP,
  1865. 0, 1, 1, 0);
  1866. if (hdl->error) {
  1867. ret = hdl->error;
  1868. goto free_ctrls;
  1869. }
  1870. ret = v4l2_fwnode_device_parse(&alvium->i2c_client->dev, &props);
  1871. if (ret)
  1872. goto free_ctrls;
  1873. ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &props);
  1874. if (ret)
  1875. goto free_ctrls;
  1876. alvium->sd.ctrl_handler = hdl;
  1877. return 0;
  1878. free_ctrls:
  1879. v4l2_ctrl_handler_free(hdl);
  1880. return ret;
  1881. }
  1882. static const struct v4l2_subdev_core_ops alvium_core_ops = {
  1883. .log_status = v4l2_ctrl_subdev_log_status,
  1884. };
  1885. static const struct v4l2_subdev_video_ops alvium_video_ops = {
  1886. .s_stream = alvium_s_stream,
  1887. };
  1888. static const struct v4l2_subdev_pad_ops alvium_pad_ops = {
  1889. .enum_mbus_code = alvium_enum_mbus_code,
  1890. .enum_frame_size = alvium_enum_frame_size,
  1891. .get_fmt = v4l2_subdev_get_fmt,
  1892. .set_fmt = alvium_set_fmt,
  1893. .get_selection = alvium_get_selection,
  1894. .set_selection = alvium_set_selection,
  1895. .get_frame_interval = v4l2_subdev_get_frame_interval,
  1896. .set_frame_interval = alvium_s_frame_interval,
  1897. };
  1898. static const struct v4l2_subdev_internal_ops alvium_internal_ops = {
  1899. .init_state = alvium_init_state,
  1900. };
  1901. static const struct v4l2_subdev_ops alvium_subdev_ops = {
  1902. .core = &alvium_core_ops,
  1903. .pad = &alvium_pad_ops,
  1904. .video = &alvium_video_ops,
  1905. };
  1906. static int alvium_subdev_init(struct alvium_dev *alvium)
  1907. {
  1908. struct i2c_client *client = alvium->i2c_client;
  1909. struct device *dev = &alvium->i2c_client->dev;
  1910. struct v4l2_subdev *sd = &alvium->sd;
  1911. int ret;
  1912. /* Setup the initial mode */
  1913. alvium->mode.fmt = alvium_csi2_default_fmt;
  1914. alvium->mode.width = alvium_csi2_default_fmt.width;
  1915. alvium->mode.height = alvium_csi2_default_fmt.height;
  1916. alvium->mode.crop.left = alvium->min_offx;
  1917. alvium->mode.crop.top = alvium->min_offy;
  1918. alvium->mode.crop.width = alvium_csi2_default_fmt.width;
  1919. alvium->mode.crop.height = alvium_csi2_default_fmt.height;
  1920. /* init alvium sd */
  1921. v4l2_i2c_subdev_init(sd, client, &alvium_subdev_ops);
  1922. sd->internal_ops = &alvium_internal_ops;
  1923. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  1924. alvium->pad.flags = MEDIA_PAD_FL_SOURCE;
  1925. sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
  1926. ret = media_entity_pads_init(&sd->entity, 1, &alvium->pad);
  1927. if (ret) {
  1928. dev_err(dev, "Could not register media entity\n");
  1929. return ret;
  1930. }
  1931. ret = alvium_ctrl_init(alvium);
  1932. if (ret) {
  1933. dev_err(dev, "Control initialization error %d\n", ret);
  1934. goto entity_cleanup;
  1935. }
  1936. alvium->sd.state_lock = alvium->ctrls.handler.lock;
  1937. ret = v4l2_subdev_init_finalize(sd);
  1938. if (ret < 0) {
  1939. dev_err(dev, "subdev initialization error %d\n", ret);
  1940. goto err_ctrls;
  1941. }
  1942. return 0;
  1943. err_ctrls:
  1944. v4l2_ctrl_handler_free(&alvium->ctrls.handler);
  1945. entity_cleanup:
  1946. media_entity_cleanup(&alvium->sd.entity);
  1947. return ret;
  1948. }
  1949. static void alvium_subdev_cleanup(struct alvium_dev *alvium)
  1950. {
  1951. v4l2_fwnode_endpoint_free(&alvium->ep);
  1952. v4l2_subdev_cleanup(&alvium->sd);
  1953. media_entity_cleanup(&alvium->sd.entity);
  1954. v4l2_ctrl_handler_free(&alvium->ctrls.handler);
  1955. }
  1956. static int alvium_get_dt_data(struct alvium_dev *alvium)
  1957. {
  1958. struct device *dev = &alvium->i2c_client->dev;
  1959. struct fwnode_handle *fwnode = dev_fwnode(dev);
  1960. struct fwnode_handle *endpoint;
  1961. if (!fwnode)
  1962. return -EINVAL;
  1963. /* Only CSI2 is supported for now: */
  1964. alvium->ep.bus_type = V4L2_MBUS_CSI2_DPHY;
  1965. endpoint = fwnode_graph_get_endpoint_by_id(fwnode, 0, 0, 0);
  1966. if (!endpoint) {
  1967. dev_err(dev, "endpoint node not found\n");
  1968. return -EINVAL;
  1969. }
  1970. if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &alvium->ep)) {
  1971. dev_err(dev, "could not parse endpoint\n");
  1972. goto error_out;
  1973. }
  1974. if (!alvium->ep.nr_of_link_frequencies) {
  1975. dev_err(dev, "no link frequencies defined");
  1976. goto error_out;
  1977. }
  1978. return 0;
  1979. error_out:
  1980. v4l2_fwnode_endpoint_free(&alvium->ep);
  1981. fwnode_handle_put(endpoint);
  1982. return -EINVAL;
  1983. }
  1984. static int alvium_set_power(struct alvium_dev *alvium, bool on)
  1985. {
  1986. int ret;
  1987. if (!on)
  1988. return regulator_disable(alvium->reg_vcc);
  1989. ret = regulator_enable(alvium->reg_vcc);
  1990. if (ret)
  1991. return ret;
  1992. /* alvium boot time 7s */
  1993. msleep(7000);
  1994. return 0;
  1995. }
  1996. static int alvium_runtime_resume(struct device *dev)
  1997. {
  1998. struct v4l2_subdev *sd = dev_get_drvdata(dev);
  1999. struct alvium_dev *alvium = sd_to_alvium(sd);
  2000. int ret;
  2001. ret = alvium_set_power(alvium, true);
  2002. if (ret)
  2003. return ret;
  2004. ret = alvium_hw_init(alvium);
  2005. if (ret) {
  2006. alvium_set_power(alvium, false);
  2007. return ret;
  2008. }
  2009. return 0;
  2010. }
  2011. static int alvium_runtime_suspend(struct device *dev)
  2012. {
  2013. struct v4l2_subdev *sd = dev_get_drvdata(dev);
  2014. struct alvium_dev *alvium = sd_to_alvium(sd);
  2015. alvium_set_power(alvium, false);
  2016. return 0;
  2017. }
  2018. static const struct dev_pm_ops alvium_pm_ops = {
  2019. RUNTIME_PM_OPS(alvium_runtime_suspend, alvium_runtime_resume, NULL)
  2020. };
  2021. static int alvium_probe(struct i2c_client *client)
  2022. {
  2023. struct device *dev = &client->dev;
  2024. struct alvium_dev *alvium;
  2025. int ret;
  2026. alvium = devm_kzalloc(dev, sizeof(*alvium), GFP_KERNEL);
  2027. if (!alvium)
  2028. return -ENOMEM;
  2029. alvium->i2c_client = client;
  2030. alvium->regmap = devm_cci_regmap_init_i2c(client, 16);
  2031. if (IS_ERR(alvium->regmap))
  2032. return PTR_ERR(alvium->regmap);
  2033. ret = alvium_get_dt_data(alvium);
  2034. if (ret)
  2035. return ret;
  2036. alvium->reg_vcc = devm_regulator_get_optional(dev, "vcc-ext-in");
  2037. if (IS_ERR(alvium->reg_vcc))
  2038. return dev_err_probe(dev, PTR_ERR(alvium->reg_vcc),
  2039. "no vcc-ext-in regulator provided\n");
  2040. ret = alvium_set_power(alvium, true);
  2041. if (ret)
  2042. goto err_powerdown;
  2043. if (!alvium_is_alive(alvium)) {
  2044. ret = -ENODEV;
  2045. dev_err_probe(dev, ret, "Device detection failed\n");
  2046. goto err_powerdown;
  2047. }
  2048. ret = alvium_get_hw_info(alvium);
  2049. if (ret) {
  2050. dev_err_probe(dev, ret, "get_hw_info fail\n");
  2051. goto err_powerdown;
  2052. }
  2053. ret = alvium_hw_init(alvium);
  2054. if (ret) {
  2055. dev_err_probe(dev, ret, "hw_init fail\n");
  2056. goto err_powerdown;
  2057. }
  2058. ret = alvium_setup_mipi_fmt(alvium);
  2059. if (ret) {
  2060. dev_err_probe(dev, ret, "setup_mipi_fmt fail\n");
  2061. goto err_powerdown;
  2062. }
  2063. /*
  2064. * Enable runtime PM without autosuspend:
  2065. *
  2066. * Don't use pm autosuspend (alvium have ~7s boot time).
  2067. * Alvium has been powered manually:
  2068. * - mark it as active
  2069. * - increase the usage count without resuming the device.
  2070. */
  2071. pm_runtime_set_active(dev);
  2072. pm_runtime_get_noresume(dev);
  2073. pm_runtime_enable(dev);
  2074. /* Initialize the V4L2 subdev. */
  2075. ret = alvium_subdev_init(alvium);
  2076. if (ret)
  2077. goto err_pm;
  2078. ret = v4l2_async_register_subdev(&alvium->sd);
  2079. if (ret < 0) {
  2080. dev_err_probe(dev, ret, "Could not register v4l2 device\n");
  2081. goto err_subdev;
  2082. }
  2083. return 0;
  2084. err_subdev:
  2085. alvium_subdev_cleanup(alvium);
  2086. err_pm:
  2087. pm_runtime_disable(dev);
  2088. pm_runtime_put_noidle(dev);
  2089. kfree(alvium->alvium_csi2_fmt);
  2090. err_powerdown:
  2091. alvium_set_power(alvium, false);
  2092. return ret;
  2093. }
  2094. static void alvium_remove(struct i2c_client *client)
  2095. {
  2096. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  2097. struct alvium_dev *alvium = sd_to_alvium(sd);
  2098. struct device *dev = &alvium->i2c_client->dev;
  2099. v4l2_async_unregister_subdev(sd);
  2100. alvium_subdev_cleanup(alvium);
  2101. kfree(alvium->alvium_csi2_fmt);
  2102. /*
  2103. * Disable runtime PM. In case runtime PM is disabled in the kernel,
  2104. * make sure to turn power off manually.
  2105. */
  2106. pm_runtime_disable(dev);
  2107. if (!pm_runtime_status_suspended(dev))
  2108. alvium_set_power(alvium, false);
  2109. pm_runtime_set_suspended(dev);
  2110. }
  2111. static const struct of_device_id alvium_of_ids[] = {
  2112. { .compatible = "alliedvision,alvium-csi2", },
  2113. { }
  2114. };
  2115. MODULE_DEVICE_TABLE(of, alvium_of_ids);
  2116. static struct i2c_driver alvium_i2c_driver = {
  2117. .driver = {
  2118. .name = "alvium-csi2",
  2119. .pm = pm_ptr(&alvium_pm_ops),
  2120. .of_match_table = alvium_of_ids,
  2121. },
  2122. .probe = alvium_probe,
  2123. .remove = alvium_remove,
  2124. };
  2125. module_i2c_driver(alvium_i2c_driver);
  2126. MODULE_DESCRIPTION("Allied Vision's Alvium Camera Driver");
  2127. MODULE_AUTHOR("Tommaso Merciai <tomm.merciai@gmail.com>");
  2128. MODULE_AUTHOR("Martin Hecht <martin.hecht@avnet.eu>");
  2129. MODULE_AUTHOR("Avnet Silica Software & Services EMEA");
  2130. MODULE_LICENSE("GPL");