IMX219.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741
  1. /******************************************************************************\ |* Copyright (c) 2020 by VeriSilicon Holdings Co., Ltd. ("VeriSilicon") *| |* All Rights Reserved. *| |* *| |* The material in this file is confidential and contains trade secrets of *| |* of VeriSilicon. This is proprietary information owned or licensed by *| |* VeriSilicon. No part of this work may be disclosed, reproduced, copied, *| |* transmitted, or used in any way for any purpose, without the express *| |* written permission of VeriSilicon. *| |* *|
  2. \******************************************************************************/
  3. #include <ebase/types.h>
  4. #include <ebase/trace.h>
  5. #include <ebase/builtins.h>
  6. #include <common/return_codes.h>
  7. #include <common/misc.h>
  8. #include <sys/ioctl.h>
  9. #include <fcntl.h>
  10. #include <isi/isi.h>
  11. #include <isi/isi_iss.h>
  12. #include <isi/isi_priv.h>
  13. #include <vvsensor.h>
  14. #include "IMX219_priv.h"
  15. #include "imx219.h"
  16. CREATE_TRACER( IMX219_INFO , "IMX219: ", INFO, 1);
  17. CREATE_TRACER( IMX219_WARN , "IMX219: ", WARNING, 1);
  18. CREATE_TRACER( IMX219_ERROR, "IMX219: ", ERROR, 1);
  19. CREATE_TRACER( IMX219_DEBUG, "IMX219: ", INFO, 0);
  20. CREATE_TRACER( IMX219_REG_INFO , "IMX219: ", INFO, 0);
  21. CREATE_TRACER( IMX219_REG_DEBUG, "IMX219: ", INFO, 0);
  22. #ifdef SUBDEV_V4L2
  23. #include <sys/ioctl.h>
  24. #include <sys/mman.h>
  25. #include <fcntl.h>
  26. #include <linux/videodev2.h>
  27. #include <linux/v4l2-subdev.h>
  28. #undef TRACE
  29. #define TRACE(x, ...)
  30. #endif
  31. #define IMX219_MIN_GAIN_STEP ( 1.0f/16.0f ) /**< min gain step size used by GUI (hardware min = 1/16; 1/16..32/16 depending on actual gain ) */
  32. #define IMX219_MAX_GAIN_AEC ( 32.0f ) /**< max. gain used by the AEC (arbitrarily chosen, hardware limit = 62.0, driver limit = 32.0 ) */
  33. #define IMX219_VS_MAX_INTEGRATION_TIME (0.0018)
  34. /*****************************************************************************
  35. *Sensor Info
  36. *****************************************************************************/
  37. static const char SensorName[16] = "IMX219";
  38. static struct vvcam_mode_info pimx219_mode_info[] = {
  39. {
  40. .index = 0,
  41. .width = 1920,
  42. .height = 1080,
  43. .fps = 30,
  44. .hdr_mode = SENSOR_MODE_LINEAR,
  45. .bit_width = 10,
  46. .bayer_pattern = BAYER_RGGB,
  47. .mipi_phy_freq = 912, /* Pixel rate is fixed at 182.4M for all the modes */
  48. .mipi_line_num = 2,
  49. .config_file_3a = "IMX219_1920x1080_raw10", //3aconfig_IMX219_1920x1080_raw10.json
  50. .preg_data = (void *)"imx219 sensor liner mode 1920*1080@30",
  51. },
  52. };
  53. static RESULT IMX219_IsiRegisterWriteIss(IsiSensorHandle_t handle, const uint32_t address, const uint32_t value);
  54. static RESULT IMX219_IsiSensorSetPowerIss(IsiSensorHandle_t handle, bool_t on) {
  55. RESULT result = RET_SUCCESS;
  56. int ret = 0;
  57. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  58. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  59. return RET_NULL_POINTER;
  60. }
  61. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  62. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  63. int32_t enable = on;
  64. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_POWER, &enable);
  65. if (ret != 0) {
  66. // to do
  67. //TRACE(IMX219_ERROR, "%s: sensor set power error!\n", __func__);
  68. //return (RET_FAILURE);
  69. }
  70. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  71. return (result);
  72. }
  73. static RESULT IMX219_IsiResetSensorIss(IsiSensorHandle_t handle) {
  74. RESULT result = RET_SUCCESS;
  75. int ret = 0;
  76. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  77. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  78. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  79. return RET_NULL_POINTER;
  80. }
  81. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  82. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_RESET, NULL);
  83. if (ret != 0) {
  84. TRACE(IMX219_ERROR, "%s: sensor reset error!\n", __func__);
  85. return (RET_FAILURE);
  86. }
  87. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  88. return (result);
  89. }
  90. #ifdef SUBDEV_CHAR
  91. static RESULT IMX219_IsiSensorSetClkIss(IsiSensorHandle_t handle, uint32_t clk) {
  92. RESULT result = RET_SUCCESS;
  93. int32_t ret = 0;
  94. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  95. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  96. return RET_NULL_POINTER;
  97. }
  98. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  99. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  100. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_CLK, &clk);
  101. if (ret != 0) {
  102. // to do
  103. //TRACE(IMX219_ERROR, "%s: sensor set clk error!\n", __func__);
  104. //return (RET_FAILURE);
  105. }
  106. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  107. return (result);
  108. }
  109. static RESULT IMX219_IsiSensorGetClkIss
  110. (IsiSensorHandle_t handle, uint32_t * pclk) {
  111. RESULT result = RET_SUCCESS;
  112. int ret = 0;
  113. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  114. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  115. return RET_NULL_POINTER;
  116. }
  117. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  118. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  119. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_G_CLK, pclk);
  120. if (ret != 0) {
  121. // to do
  122. //TRACE(IMX219_ERROR, "%s: sensor get clk error!\n", __func__);
  123. //return (RET_FAILURE);
  124. }
  125. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  126. return (result);
  127. }
  128. static RESULT IMX219_IsiConfigSensorSCCBIss(IsiSensorHandle_t handle)
  129. {
  130. return RET_SUCCESS;
  131. }
  132. #endif
  133. static RESULT IMX219_IsiRegisterReadIss
  134. (IsiSensorHandle_t handle, const uint32_t address, uint32_t * p_value) {
  135. RESULT result = RET_SUCCESS;
  136. int32_t ret = 0;
  137. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  138. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  139. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  140. return RET_NULL_POINTER;
  141. }
  142. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  143. struct vvcam_sccb_data sccb_data;
  144. sccb_data.addr = address;
  145. sccb_data.data = 0;
  146. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_READ_REG, &sccb_data);
  147. if (ret != 0) {
  148. TRACE(IMX219_ERROR, "%s: read sensor register error!\n",
  149. __func__);
  150. return (RET_FAILURE);
  151. }
  152. *p_value = sccb_data.data;
  153. TRACE(IMX219_INFO, "%s (exit) result = %d\n", __func__, result);
  154. return (result);
  155. }
  156. static RESULT IMX219_IsiRegisterWriteIss
  157. (IsiSensorHandle_t handle, const uint32_t address, const uint32_t value) {
  158. RESULT result = RET_SUCCESS;
  159. int ret = 0;
  160. TRACE(IMX219_INFO, "%s (enter) write %d\n", __func__, value);
  161. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  162. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  163. return RET_NULL_POINTER;
  164. }
  165. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  166. struct vvcam_sccb_data sccb_data;
  167. sccb_data.addr = address;
  168. sccb_data.data = value;
  169. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_WRITE_REG, &sccb_data);
  170. if (ret != 0) {
  171. TRACE(IMX219_ERROR, "%s: write sensor register error!\n",
  172. __func__);
  173. return (RET_FAILURE);
  174. }
  175. TRACE(IMX219_INFO, "%s (exit) result = %d\n", __func__, result);
  176. return (result);
  177. }
  178. static RESULT IMX219_IsiQuerySensorSupportIss(HalHandle_t HalHandle, vvcam_mode_info_array_t *pSensorSupportInfo)
  179. {
  180. TRACE(IMX219_DEBUG, "enter %s", __func__);
  181. //int ret = 0;
  182. struct vvcam_mode_info_array *psensor_mode_info_arry;
  183. HalContext_t *pHalCtx = HalHandle;
  184. if ( pHalCtx == NULL ) {
  185. return RET_NULL_POINTER;
  186. }
  187. psensor_mode_info_arry = pSensorSupportInfo;
  188. #if 0
  189. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_QUERY, psensor_mode_info_arry);
  190. if (ret != 0) {
  191. TRACE(IMX219_ERROR, "%s: sensor kernel query error! Use isi query\n",__func__);
  192. psensor_mode_info_arry->count = sizeof(pimx219_mode_info) / sizeof(struct vvcam_mode_info);
  193. memcpy(psensor_mode_info_arry->modes, pimx219_mode_info, sizeof(pimx219_mode_info));
  194. }
  195. #endif
  196. psensor_mode_info_arry->count = sizeof(pimx219_mode_info) / sizeof(struct vvcam_mode_info);
  197. memcpy(psensor_mode_info_arry->modes, pimx219_mode_info, sizeof(pimx219_mode_info));
  198. TRACE(IMX219_DEBUG, "%s-%s-%d: cnt=%d\n", __FILE__, __func__, __LINE__, psensor_mode_info_arry->count);
  199. return RET_SUCCESS;
  200. }
  201. static RESULT IMX219_IsiQuerySensorIss(IsiSensorHandle_t handle, vvcam_mode_info_array_t *pSensorInfo)
  202. {
  203. RESULT result = RET_SUCCESS;
  204. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  205. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  206. return RET_NULL_POINTER;
  207. }
  208. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  209. IMX219_IsiQuerySensorSupportIss(pHalCtx,pSensorInfo);
  210. return result;
  211. }
  212. static RESULT IMX219_IsiGetSensorModeIss(IsiSensorHandle_t handle,void *mode)
  213. {
  214. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  215. if (pIMX219Ctx == NULL) {
  216. return (RET_WRONG_HANDLE);
  217. }
  218. memcpy(mode,&(pIMX219Ctx->SensorMode), sizeof(pIMX219Ctx->SensorMode));
  219. return ( RET_SUCCESS );
  220. }
  221. static RESULT IMX219_IsiCreateSensorIss(IsiSensorInstanceConfig_t * pConfig) {
  222. RESULT result = RET_SUCCESS;
  223. IMX219_Context_t *pIMX219Ctx;
  224. TRACE(IMX219_INFO, "%s (enter) v1.6\n", __func__);
  225. if (!pConfig || !pConfig->pSensor)
  226. return (RET_NULL_POINTER);
  227. pIMX219Ctx = (IMX219_Context_t *) malloc(sizeof(IMX219_Context_t));
  228. if (!pIMX219Ctx) {
  229. TRACE(IMX219_ERROR, "%s: Can't allocate imx219 context\n",
  230. __func__);
  231. return (RET_OUTOFMEM);
  232. }
  233. MEMSET(pIMX219Ctx, 0, sizeof(IMX219_Context_t));
  234. result = HalAddRef(pConfig->HalHandle);
  235. if (result != RET_SUCCESS) {
  236. free(pIMX219Ctx);
  237. return (result);
  238. }
  239. pIMX219Ctx->IsiCtx.HalHandle = pConfig->HalHandle;
  240. pIMX219Ctx->IsiCtx.pSensor = pConfig->pSensor;
  241. pIMX219Ctx->GroupHold = BOOL_FALSE;
  242. pIMX219Ctx->OldGain = 0;
  243. pIMX219Ctx->OldIntegrationTime = 0;
  244. pIMX219Ctx->Configured = BOOL_FALSE;
  245. pIMX219Ctx->Streaming = BOOL_FALSE;
  246. pIMX219Ctx->TestPattern = BOOL_FALSE;
  247. pIMX219Ctx->isAfpsRun = BOOL_FALSE;
  248. pIMX219Ctx->SensorMode.index = pConfig->SensorModeIndex;
  249. pConfig->hSensor = (IsiSensorHandle_t) pIMX219Ctx;
  250. #ifdef SUBDEV_CHAR
  251. struct vvcam_mode_info *SensorDefaultMode = NULL;
  252. for (int i=0; i < sizeof(pimx219_mode_info)/ sizeof(struct vvcam_mode_info); i++)
  253. {
  254. if (pimx219_mode_info[i].index == pIMX219Ctx->SensorMode.index)
  255. {
  256. SensorDefaultMode = &(pimx219_mode_info[i]);
  257. break;
  258. }
  259. }
  260. if (SensorDefaultMode != NULL)
  261. {
  262. strcpy(pIMX219Ctx->SensorRegCfgFile, get_vi_config_path());
  263. switch(SensorDefaultMode->index)
  264. {
  265. case 0:
  266. strcat(pIMX219Ctx->SensorRegCfgFile,
  267. "IMX219_mipi4lane_1920x1080@30.txt");
  268. break;
  269. default:
  270. break;
  271. }
  272. if (access(pIMX219Ctx->SensorRegCfgFile, F_OK) == 0) {
  273. pIMX219Ctx->KernelDriverFlag = 0;
  274. memcpy(&(pIMX219Ctx->SensorMode),SensorDefaultMode,sizeof(struct vvcam_mode_info));
  275. } else {
  276. pIMX219Ctx->KernelDriverFlag = 1;
  277. }
  278. }else
  279. {
  280. pIMX219Ctx->KernelDriverFlag = 1;
  281. }
  282. result = IMX219_IsiSensorSetPowerIss(pIMX219Ctx, BOOL_TRUE);
  283. RETURN_RESULT_IF_DIFFERENT(RET_SUCCESS, result);
  284. uint32_t SensorClkIn = 0;
  285. if (pIMX219Ctx->KernelDriverFlag) {
  286. result = IMX219_IsiSensorGetClkIss(pIMX219Ctx, &SensorClkIn);
  287. RETURN_RESULT_IF_DIFFERENT(RET_SUCCESS, result);
  288. }
  289. result = IMX219_IsiSensorSetClkIss(pIMX219Ctx, SensorClkIn);
  290. RETURN_RESULT_IF_DIFFERENT(RET_SUCCESS, result);
  291. result = IMX219_IsiResetSensorIss(pIMX219Ctx);
  292. RETURN_RESULT_IF_DIFFERENT(RET_SUCCESS, result);
  293. pIMX219Ctx->pattern = ISI_BPAT_BGBGGRGR;
  294. if (!pIMX219Ctx->KernelDriverFlag) {
  295. result = IMX219_IsiConfigSensorSCCBIss(pIMX219Ctx);
  296. RETURN_RESULT_IF_DIFFERENT(RET_SUCCESS, result);
  297. }
  298. #endif
  299. TRACE(IMX219_INFO, "%s (exit pConfig->hSensor = %p)\n", __func__, pConfig->hSensor);
  300. return (result);
  301. }
  302. static RESULT IMX219_IsiGetRegCfgIss(const char *registerFileName,
  303. struct vvcam_sccb_array *arry)
  304. {
  305. if (NULL == registerFileName) {
  306. TRACE(IMX219_ERROR, "%s:registerFileName is NULL\n", __func__);
  307. return (RET_NULL_POINTER);
  308. }
  309. #ifdef SUBDEV_CHAR
  310. FILE *fp = NULL;
  311. fp = fopen(registerFileName, "rb");
  312. if (!fp) {
  313. TRACE(IMX219_ERROR, "%s:load register file %s error!\n",
  314. __func__, registerFileName);
  315. return (RET_FAILURE);
  316. }
  317. char LineBuf[512];
  318. uint32_t FileTotalLine = 0;
  319. while (!feof(fp)) {
  320. fgets(LineBuf, 512, fp);
  321. FileTotalLine++;
  322. }
  323. arry->sccb_data =
  324. malloc(FileTotalLine * sizeof(struct vvcam_sccb_data));
  325. if (arry->sccb_data == NULL) {
  326. TRACE(IMX219_ERROR, "%s:malloc failed NULL Point!\n", __func__,
  327. registerFileName);
  328. return (RET_FAILURE);
  329. }
  330. rewind(fp);
  331. arry->count = 0;
  332. while (!feof(fp)) {
  333. memset(LineBuf, 0, sizeof(LineBuf));
  334. fgets(LineBuf, 512, fp);
  335. int result =
  336. sscanf(LineBuf, "0x%x 0x%x",
  337. &(arry->sccb_data[arry->count].addr),
  338. &(arry->sccb_data[arry->count].data));
  339. if (result != 2)
  340. continue;
  341. arry->count++;
  342. }
  343. #endif
  344. return 0;
  345. }
  346. static RESULT IMX219_IsiInitSensorIss(IsiSensorHandle_t handle) {
  347. RESULT result = RET_SUCCESS;
  348. int ret = 0;
  349. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  350. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  351. TRACE(IMX219_INFO, "%s (enter handle = %p)\n", __func__, handle);
  352. if (pIMX219Ctx == NULL) {
  353. return (RET_WRONG_HANDLE);
  354. }
  355. TRACE(IMX219_INFO, "%s (pIMX219Ctx->KernelDriverFlag = %d)\n", __func__, pIMX219Ctx->KernelDriverFlag);
  356. if (pIMX219Ctx->KernelDriverFlag) {
  357. ;
  358. } else {
  359. /* sensor doesn't enter LP-11 state upon power up until and unless
  360. * streaming is started, so upon power up switch the modes to:
  361. * streaming -> standby
  362. */
  363. ret = IMX219_IsiRegisterWriteIss(handle, 0x0100, 0x1);
  364. if (ret != 0) {
  365. return (RET_FAILURE);
  366. }
  367. ret = IMX219_IsiRegisterWriteIss(handle, 0x0100, 0x0);
  368. if (ret != 0) {
  369. return (RET_FAILURE);
  370. }
  371. osSleep(1);
  372. TRACE(IMX219_INFO, "%s (001)\n", __func__);
  373. struct vvcam_sccb_array arry;
  374. result = IMX219_IsiGetRegCfgIss(pIMX219Ctx->SensorRegCfgFile, &arry);
  375. if (result != 0) {
  376. TRACE(IMX219_ERROR,
  377. "%s:IMX219_IsiGetRegCfgIss error!\n", __func__);
  378. return (RET_FAILURE);
  379. }
  380. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_WRITE_ARRAY, &arry);
  381. if (ret != 0) {
  382. TRACE(IMX219_ERROR, "%s:Sensor Write Reg arry error!\n",
  383. __func__);
  384. return (RET_FAILURE);
  385. }
  386. TRACE(IMX219_INFO, "%s (pIMX219Ctx->SensorMode.index = %d)\n", __func__, pIMX219Ctx->SensorMode.index);
  387. switch(pIMX219Ctx->SensorMode.index)
  388. {
  389. case 0:
  390. pIMX219Ctx->one_line_exp_time = 0.00001890; // line_time = line_length / pclk
  391. pIMX219Ctx->FrameLengthLines = 0xAA8;
  392. pIMX219Ctx->CurFrameLengthLines = pIMX219Ctx->FrameLengthLines;
  393. pIMX219Ctx->MaxIntegrationLine = pIMX219Ctx->CurFrameLengthLines - 16;
  394. pIMX219Ctx->MinIntegrationLine = 1;
  395. pIMX219Ctx->AecMaxGain = 16;
  396. pIMX219Ctx->AecMinGain = 1;
  397. break;
  398. default:
  399. return (RET_FAILURE);
  400. }
  401. pIMX219Ctx->AecIntegrationTimeIncrement = pIMX219Ctx->one_line_exp_time;
  402. pIMX219Ctx->AecMinIntegrationTime =
  403. pIMX219Ctx->one_line_exp_time * pIMX219Ctx->MinIntegrationLine;
  404. pIMX219Ctx->AecMaxIntegrationTime =
  405. pIMX219Ctx->one_line_exp_time * pIMX219Ctx->MaxIntegrationLine;
  406. pIMX219Ctx->MaxFps = pIMX219Ctx->SensorMode.fps;
  407. pIMX219Ctx->MinFps = 1;
  408. pIMX219Ctx->CurrFps = pIMX219Ctx->MaxFps;
  409. }
  410. TRACE(IMX219_INFO, "%s (pIMX219Ctx->one_line_exp_time = %f)\n", __func__, pIMX219Ctx->one_line_exp_time);
  411. TRACE(IMX219_INFO, "%s (pIMX219Ctx->MinIntegrationLine = %d, pIMX219Ctx->MaxIntegrationLine = %d)\n", __func__, pIMX219Ctx->MinIntegrationLine, pIMX219Ctx->MaxIntegrationLine);
  412. return (result);
  413. }
  414. static RESULT IMX219_IsiReleaseSensorIss(IsiSensorHandle_t handle) {
  415. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  416. RESULT result = RET_SUCCESS;
  417. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  418. if (pIMX219Ctx == NULL)
  419. return (RET_WRONG_HANDLE);
  420. (void)IMX219_IsiSensorSetStreamingIss(pIMX219Ctx, BOOL_FALSE);
  421. (void)IMX219_IsiSensorSetPowerIss(pIMX219Ctx, BOOL_FALSE);
  422. (void)HalDelRef(pIMX219Ctx->IsiCtx.HalHandle);
  423. MEMSET(pIMX219Ctx, 0, sizeof(IMX219_Context_t));
  424. free(pIMX219Ctx);
  425. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  426. return (result);
  427. }
  428. struct imx219_fmt {
  429. int width;
  430. int height;
  431. int fps;
  432. };
  433. static RESULT IMX219_IsiSetupSensorIss
  434. (IsiSensorHandle_t handle, const IsiSensorConfig_t * pConfig) {
  435. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  436. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  437. RESULT result = RET_SUCCESS;
  438. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  439. if (!pIMX219Ctx) {
  440. TRACE(IMX219_ERROR,
  441. "%s: Invalid sensor handle (NULL pointer detected)\n",
  442. __func__);
  443. return (RET_WRONG_HANDLE);
  444. }
  445. if (!pConfig) {
  446. TRACE(IMX219_ERROR,
  447. "%s: Invalid configuration (NULL pointer detected)\n",
  448. __func__);
  449. return (RET_NULL_POINTER);
  450. }
  451. if (pIMX219Ctx->Streaming != BOOL_FALSE) {
  452. return RET_WRONG_STATE;
  453. }
  454. memcpy(&pIMX219Ctx->Config, pConfig, sizeof(IsiSensorConfig_t));
  455. /* 1.) SW reset of image sensor (via I2C register interface) be careful, bits 6..0 are reserved, reset bit is not sticky */
  456. TRACE(IMX219_DEBUG, "%s: IMX219 System-Reset executed\n", __func__);
  457. osSleep(100);
  458. //IMX219_AecSetModeParameters not defined yet as of 2021/8/9.
  459. //result = IMX219_AecSetModeParameters(pIMX219Ctx, pConfig);
  460. //if (result != RET_SUCCESS) {
  461. // TRACE(IMX219_ERROR, "%s: SetupOutputWindow failed.\n",
  462. // __func__);
  463. // return (result);
  464. //}
  465. #if 1
  466. struct imx219_fmt fmt;
  467. fmt.width = pConfig->Resolution.width;
  468. fmt.height = pConfig->Resolution.height;
  469. ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_FPS, &fmt);//result = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_FPS, &fmt);
  470. #endif
  471. pIMX219Ctx->Configured = BOOL_TRUE;
  472. TRACE(IMX219_INFO, "%s: (exit) ret=0x%x \n", __func__, result);
  473. return result;
  474. }
  475. static RESULT IMX219_IsiChangeSensorResolutionIss(IsiSensorHandle_t handle, uint16_t width, uint16_t height) {
  476. RESULT result = RET_SUCCESS;
  477. #if 0
  478. struct imx219_fmt fmt;
  479. fmt.width = width;
  480. fmt.height = height;
  481. int ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_FPS, &fmt);
  482. #endif
  483. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  484. return (result);
  485. }
  486. static RESULT IMX219_IsiSensorSetStreamingIss
  487. (IsiSensorHandle_t handle, bool_t on) {
  488. RESULT result = RET_SUCCESS;
  489. int ret = 0;
  490. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  491. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  492. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  493. return RET_NULL_POINTER;
  494. }
  495. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  496. if (pIMX219Ctx->Configured != BOOL_TRUE)
  497. return RET_WRONG_STATE;
  498. int32_t enable = (uint32_t) on;
  499. #if 0
  500. IMX219_IsiRegisterWriteIss(handle, 0x0601, 0x2); // pattern=IMX219_TEST_PATTERN_SOLID_COLOR
  501. IMX219_IsiRegisterWriteIss(handle, 0x0603, 0xff); // pattern
  502. IMX219_IsiRegisterWriteIss(handle, 0x0605, 0x2); // pattern
  503. IMX219_IsiRegisterWriteIss(handle, 0x0607, 0x2); // pattern
  504. IMX219_IsiRegisterWriteIss(handle, 0x0609, 0x2); // pattern
  505. #endif
  506. if (on == true) {
  507. ret = IMX219_IsiRegisterWriteIss(handle, 0x0100, 0x1);
  508. } else {
  509. ret = IMX219_IsiRegisterWriteIss(handle, 0x0100, 0x00);
  510. }
  511. if (ret != 0) {
  512. return (RET_FAILURE);
  513. }
  514. pIMX219Ctx->Streaming = on;
  515. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  516. return (result);
  517. }
  518. static int32_t sensor_get_chip_id(IsiSensorHandle_t handle, uint32_t *chip_id)
  519. {
  520. RESULT result = RET_SUCCESS;
  521. int32_t ret = 0;
  522. int32_t chip_id_high = 0;
  523. int32_t chip_id_low = 0;
  524. ret = IMX219_IsiRegisterReadIss(handle, 0x0, &chip_id_high);
  525. if (ret != 0) {
  526. TRACE(IMX219_ERROR,
  527. "%s: Read Sensor correct ID Error! \n", __func__);
  528. return (RET_FAILURE);
  529. }
  530. ret = IMX219_IsiRegisterReadIss(handle, 0x1, &chip_id_low);
  531. if (ret != 0) {
  532. TRACE(IMX219_ERROR,
  533. "%s: Read Sensor correct ID Error! \n", __func__);
  534. return (RET_FAILURE);
  535. }
  536. *chip_id = ((chip_id_high & 0xff)<<8) | (chip_id_low & 0xff);
  537. return 0;
  538. }
  539. static RESULT IMX219_IsiCheckSensorConnectionIss(IsiSensorHandle_t handle) {
  540. RESULT result = RET_SUCCESS;
  541. int ret = 0;
  542. uint32_t correct_id = 0x219;
  543. uint32_t sensor_id = 0;
  544. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  545. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  546. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  547. return RET_NULL_POINTER;
  548. }
  549. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  550. ret = sensor_get_chip_id(handle, &sensor_id);
  551. if (ret != 0) {
  552. TRACE(IMX219_ERROR,
  553. "%s: Read Sensor chip ID Error! \n", __func__);
  554. return (RET_FAILURE);
  555. }
  556. if (correct_id != sensor_id) {
  557. TRACE(IMX219_ERROR, "%s:ChipID =0x%x sensor_id=%x error! \n",
  558. __func__, correct_id, sensor_id);
  559. return (RET_FAILURE);
  560. }
  561. printf("%s ChipID = 0x%08x, sensor_id = 0x%08x, success! \n", __func__,
  562. correct_id, sensor_id);
  563. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  564. return (result);
  565. }
  566. static RESULT IMX219_IsiGetSensorRevisionIss
  567. (IsiSensorHandle_t handle, uint32_t * p_value) {
  568. RESULT result = RET_SUCCESS;
  569. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  570. *p_value = 0X5690;
  571. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  572. return (result);
  573. }
  574. static RESULT IMX219_IsiGetGainLimitsIss
  575. (IsiSensorHandle_t handle, float *pMinGain, float *pMaxGain) {
  576. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  577. RESULT result = RET_SUCCESS;
  578. /*TODO*/
  579. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  580. if (pIMX219Ctx == NULL) {
  581. TRACE(IMX219_ERROR,
  582. "%s: Invalid sensor handle (NULL pointer detected)\n",
  583. __func__);
  584. return (RET_WRONG_HANDLE);
  585. }
  586. if ((pMinGain == NULL) || (pMaxGain == NULL)) {
  587. TRACE(IMX219_ERROR, "%s: NULL pointer received!!\n");
  588. return (RET_NULL_POINTER);
  589. }
  590. *pMinGain = pIMX219Ctx->AecMinGain;
  591. *pMaxGain = pIMX219Ctx->AecMaxGain;
  592. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  593. return (result);
  594. }
  595. static RESULT IMX219_IsiGetIntegrationTimeLimitsIss
  596. (IsiSensorHandle_t handle,
  597. float *pMinIntegrationTime, float *pMaxIntegrationTime) {
  598. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  599. RESULT result = RET_SUCCESS;
  600. /*TODO*/
  601. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  602. if (pIMX219Ctx == NULL) {
  603. TRACE(IMX219_ERROR,
  604. "%s: Invalid sensor handle (NULL pointer detected)\n",
  605. __func__);
  606. return (RET_WRONG_HANDLE);
  607. }
  608. if ((pMinIntegrationTime == NULL) || (pMaxIntegrationTime == NULL)) {
  609. TRACE(IMX219_ERROR, "%s: NULL pointer received!!\n");
  610. return (RET_NULL_POINTER);
  611. }
  612. *pMinIntegrationTime = pIMX219Ctx->AecMinIntegrationTime;
  613. *pMaxIntegrationTime = pIMX219Ctx->AecMaxIntegrationTime;
  614. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  615. return (result);
  616. }
  617. RESULT IMX219_IsiGetGainIss(IsiSensorHandle_t handle, float *pSetGain) {
  618. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  619. RESULT result = RET_SUCCESS;
  620. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  621. if (pIMX219Ctx == NULL) {
  622. TRACE(IMX219_ERROR,
  623. "%s: Invalid sensor handle (NULL pointer detected)\n",
  624. __func__);
  625. return (RET_WRONG_HANDLE);
  626. }
  627. if (pSetGain == NULL) {
  628. return (RET_NULL_POINTER);
  629. }
  630. *pSetGain = pIMX219Ctx->AecCurGain;
  631. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  632. return (result);
  633. }
  634. RESULT IMX219_IsiGetLongGainIss(IsiSensorHandle_t handle, float *gain)
  635. {
  636. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  637. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  638. if (pIMX219Ctx == NULL) {
  639. TRACE(IMX219_ERROR,"%s: Invalid sensor handle (NULL pointer detected)\n",__func__);
  640. return (RET_WRONG_HANDLE);
  641. }
  642. if (gain == NULL) {
  643. return (RET_NULL_POINTER);
  644. }
  645. *gain = pIMX219Ctx->AecCurLongGain;
  646. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  647. return (RET_SUCCESS);
  648. }
  649. RESULT IMX219_IsiGetVSGainIss(IsiSensorHandle_t handle, float *pSetGain) {
  650. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  651. RESULT result = RET_SUCCESS;
  652. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  653. if (pIMX219Ctx == NULL) {
  654. TRACE(IMX219_ERROR,
  655. "%s: Invalid sensor handle (NULL pointer detected)\n",
  656. __func__);
  657. return (RET_WRONG_HANDLE);
  658. }
  659. if (pSetGain == NULL) {
  660. return (RET_NULL_POINTER);
  661. }
  662. *pSetGain = pIMX219Ctx->AecCurVSGain;
  663. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  664. return (result);
  665. }
  666. RESULT IMX219_IsiGetGainIncrementIss(IsiSensorHandle_t handle, float *pIncr) {
  667. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  668. RESULT result = RET_SUCCESS;
  669. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  670. if (pIMX219Ctx == NULL) {
  671. TRACE(IMX219_ERROR,
  672. "%s: Invalid sensor handle (NULL pointer detected)\n",
  673. __func__);
  674. return (RET_WRONG_HANDLE);
  675. }
  676. if (pIncr == NULL)
  677. return (RET_NULL_POINTER);
  678. *pIncr = pIMX219Ctx->AecGainIncrement;
  679. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  680. return (result);
  681. }
  682. RESULT IMX219_IsiSetGainIss
  683. (IsiSensorHandle_t handle,
  684. float NewGain, float *pSetGain, float *hdr_ratio) {
  685. RESULT result = RET_SUCCESS;
  686. int32_t again = 0, dgain = 0, ret = 0;
  687. float gain_left;
  688. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  689. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  690. return RET_NULL_POINTER;
  691. }
  692. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  693. //IMX219 specific
  694. again = 256-256/NewGain;
  695. if (again >=232) {
  696. again = 232;
  697. }
  698. gain_left = NewGain / (256.0 / (256.0 - (float)again)); // what's left after again
  699. TRACE(IMX219_INFO, "%s: NewGain=%f again=%d, gain_left=%f dgain integer=%d dgain float=%f dgain float reg=%u\n"
  700. , __func__, NewGain, again, gain_left, (unsigned int)gain_left, (gain_left - (unsigned int)gain_left), (unsigned int)((float)(gain_left - (unsigned int)gain_left) * 256.0));
  701. ret = IMX219_IsiRegisterWriteIss(handle, 0x157, again);
  702. if (ret != 0) {
  703. return (RET_FAILURE);
  704. }
  705. ret = IMX219_IsiRegisterWriteIss(handle, 0x158, ((unsigned int)gain_left > 15 ) ? 15 : (unsigned int)gain_left);
  706. if (ret != 0) {
  707. return (RET_FAILURE);
  708. }
  709. ret = IMX219_IsiRegisterWriteIss(handle, 0x159, (unsigned int)((float)(gain_left - (unsigned int)gain_left) * 256.0));
  710. if (ret != 0) {
  711. return (RET_FAILURE);
  712. }
  713. pIMX219Ctx->AecCurGain = ((float)(NewGain));
  714. *pSetGain = pIMX219Ctx->AecCurGain;
  715. TRACE(IMX219_DEBUG, "%s: g=%f\n", __func__, *pSetGain);
  716. return (result);
  717. }
  718. RESULT IMX219_IsiSetLongGainIss(IsiSensorHandle_t handle, float gain)
  719. {
  720. int ret = 0;
  721. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  722. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  723. if (!pIMX219Ctx || !pIMX219Ctx->IsiCtx.HalHandle)
  724. {
  725. TRACE(IMX219_ERROR,"%s: Invalid sensor handle (NULL pointer detected)\n",__func__);
  726. return (RET_WRONG_HANDLE);
  727. }
  728. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  729. uint32_t SensorGain = 0;
  730. SensorGain = gain * pIMX219Ctx->gain_accuracy;
  731. if (pIMX219Ctx->LastLongGain != SensorGain)
  732. {
  733. /*TODO*/
  734. #if 0
  735. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_LONG_GAIN, &SensorGain);
  736. if (ret != 0)
  737. {
  738. return (RET_FAILURE);
  739. TRACE(IMX219_ERROR,"%s: set long gain failed\n");
  740. }
  741. #endif
  742. pIMX219Ctx->LastLongGain = SensorGain;
  743. pIMX219Ctx->AecCurLongGain = gain;
  744. }
  745. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  746. return (RET_SUCCESS);
  747. }
  748. RESULT IMX219_IsiSetVSGainIss
  749. (IsiSensorHandle_t handle,
  750. float NewIntegrationTime,
  751. float NewGain, float *pSetGain, float *hdr_ratio) {
  752. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  753. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  754. RESULT result = RET_SUCCESS;
  755. #if 0
  756. float Gain = 0.0f;
  757. uint32_t ucGain = 0U;
  758. uint32_t again = 0U;
  759. #endif
  760. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  761. if (!pIMX219Ctx) {
  762. TRACE(IMX219_ERROR,
  763. "%s: Invalid sensor handle (NULL pointer detected)\n",
  764. __func__);
  765. return (RET_WRONG_HANDLE);
  766. }
  767. if (!pSetGain || !hdr_ratio)
  768. return (RET_NULL_POINTER);
  769. uint32_t SensorGain = 0;
  770. SensorGain = NewGain * pIMX219Ctx->gain_accuracy;
  771. /*TODO*/
  772. //ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_VSGAIN, &SensorGain);
  773. pIMX219Ctx->AecCurVSGain = NewGain;
  774. *pSetGain = pIMX219Ctx->AecCurGain;
  775. TRACE(IMX219_DEBUG, "%s: g=%f\n", __func__, *pSetGain);
  776. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  777. return (result);
  778. }
  779. RESULT IMX219_IsiSetBayerPattern(IsiSensorHandle_t handle, uint8_t pattern)
  780. {
  781. RESULT result = RET_SUCCESS;
  782. #if 0
  783. uint8_t h_shift = 0, v_shift = 0;
  784. uint32_t val_h = 0, val_l = 0;
  785. uint16_t val = 0;
  786. uint8_t Start_p = 0;
  787. bool_t streaming_status;
  788. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  789. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  790. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  791. return RET_NULL_POINTER;
  792. }
  793. // pattern 0:B 1:GB 2:GR 3:R
  794. streaming_status = pIMX219Ctx->Streaming;
  795. result = IMX219_IsiSensorSetStreamingIss(handle, 0);
  796. switch (pattern) {
  797. case BAYER_BGGR:
  798. Start_p = 0;
  799. break;
  800. case BAYER_GBRG:
  801. Start_p = 1;
  802. break;
  803. case BAYER_GRBG:
  804. Start_p = 2;
  805. break;
  806. case BAYER_RGGB:
  807. Start_p = 3;
  808. break;
  809. }
  810. h_shift = Start_p % 2;
  811. v_shift = Start_p / 2;
  812. IMX219_IsiRegisterReadIss(handle, 0x30a0, &val_h);
  813. IMX219_IsiRegisterReadIss(handle, 0x30a1, &val_l);
  814. val = (((val_h << 8) & 0xff00) | (val_l & 0x00ff)) + h_shift;
  815. val_h = (val >> 8) & 0xff;
  816. val_l = val & 0xff;
  817. IMX219_IsiRegisterWriteIss(handle, 0x30a0, (uint8_t)val_h);
  818. IMX219_IsiRegisterWriteIss(handle, 0x30a1, (uint8_t)val_l);
  819. IMX219_IsiRegisterReadIss(handle, 0x30a2, &val_h);
  820. IMX219_IsiRegisterReadIss(handle, 0x30a3, &val_l);
  821. val = (((val_h << 8) & 0xff00) | (val_l & 0x00ff)) + v_shift;
  822. val_h = (val >> 8) & 0xff;
  823. val_l = val & 0xff;
  824. IMX219_IsiRegisterWriteIss(handle, 0x30a2, (uint8_t)val_h);
  825. IMX219_IsiRegisterWriteIss(handle, 0x30a3, (uint8_t)val_l);
  826. IMX219_IsiRegisterReadIss(handle, 0x30a4, &val_h);
  827. IMX219_IsiRegisterReadIss(handle, 0x30a5, &val_l);
  828. val = (((val_h << 8) & 0xff00) | (val_l & 0x00ff)) + h_shift;
  829. val_h = (val >> 8) & 0xff;
  830. val_l = val & 0xff;
  831. IMX219_IsiRegisterWriteIss(handle, 0x30a4, (uint8_t)val_h);
  832. IMX219_IsiRegisterWriteIss(handle, 0x30a5, (uint8_t)val_l);
  833. IMX219_IsiRegisterReadIss(handle, 0x30a6, &val_h);
  834. IMX219_IsiRegisterReadIss(handle, 0x30a7, &val_l);
  835. val = (((val_h << 8) & 0xff00) | (val_l & 0x00ff)) + v_shift;
  836. val_h = (val >> 8) & 0xff;
  837. val_l = val & 0xff;
  838. IMX219_IsiRegisterWriteIss(handle, 0x30a6, (uint8_t)val_h);
  839. IMX219_IsiRegisterWriteIss(handle, 0x30a7, (uint8_t)val_l);
  840. pIMX219Ctx->pattern = pattern;
  841. result = IMX219_IsiSensorSetStreamingIss(handle, streaming_status);
  842. #endif
  843. return (result);
  844. }
  845. RESULT IMX219_IsiGetIntegrationTimeIss
  846. (IsiSensorHandle_t handle, float *pSetIntegrationTime)
  847. {
  848. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  849. RESULT result = RET_SUCCESS;
  850. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  851. if (!pIMX219Ctx) {
  852. TRACE(IMX219_ERROR,
  853. "%s: Invalid sensor handle (NULL pointer detected)\n",
  854. __func__);
  855. return (RET_WRONG_HANDLE);
  856. }
  857. if (!pSetIntegrationTime)
  858. return (RET_NULL_POINTER);
  859. *pSetIntegrationTime = pIMX219Ctx->AecCurIntegrationTime;
  860. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  861. return (result);
  862. }
  863. RESULT IMX219_IsiGetLongIntegrationTimeIss(IsiSensorHandle_t handle, float *pIntegrationTime)
  864. {
  865. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  866. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  867. if (!pIMX219Ctx) {
  868. TRACE(IMX219_ERROR,"%s: Invalid sensor handle (NULL pointer detected)\n",__func__);
  869. return (RET_WRONG_HANDLE);
  870. }
  871. if (!pIntegrationTime)
  872. return (RET_NULL_POINTER);
  873. pIMX219Ctx->AecCurLongIntegrationTime = pIMX219Ctx->AecCurIntegrationTime;
  874. *pIntegrationTime = pIMX219Ctx->AecCurLongIntegrationTime;
  875. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  876. return (RET_SUCCESS);
  877. }
  878. RESULT IMX219_IsiGetVSIntegrationTimeIss
  879. (IsiSensorHandle_t handle, float *pSetIntegrationTime)
  880. {
  881. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  882. RESULT result = RET_SUCCESS;
  883. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  884. if (!pIMX219Ctx) {
  885. TRACE(IMX219_ERROR,
  886. "%s: Invalid sensor handle (NULL pointer detected)\n",
  887. __func__);
  888. return (RET_WRONG_HANDLE);
  889. }
  890. if (!pSetIntegrationTime)
  891. return (RET_NULL_POINTER);
  892. *pSetIntegrationTime = pIMX219Ctx->AecCurVSIntegrationTime;
  893. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  894. return (result);
  895. }
  896. RESULT IMX219_IsiGetIntegrationTimeIncrementIss
  897. (IsiSensorHandle_t handle, float *pIncr)
  898. {
  899. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  900. RESULT result = RET_SUCCESS;
  901. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  902. if (!pIMX219Ctx) {
  903. TRACE(IMX219_ERROR,
  904. "%s: Invalid sensor handle (NULL pointer detected)\n",
  905. __func__);
  906. return (RET_WRONG_HANDLE);
  907. }
  908. if (!pIncr)
  909. return (RET_NULL_POINTER);
  910. //_smallest_ increment the sensor/driver can handle (e.g. used for sliders in the application)
  911. *pIncr = pIMX219Ctx->AecIntegrationTimeIncrement;
  912. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  913. return (result);
  914. }
  915. RESULT IMX219_IsiSetIntegrationTimeIss
  916. (IsiSensorHandle_t handle,
  917. float NewIntegrationTime,
  918. float *pSetIntegrationTime,
  919. uint8_t * pNumberOfFramesToSkip, float *hdr_ratio)
  920. {
  921. RESULT result = RET_SUCCESS;
  922. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  923. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  924. uint32_t exp_line = 0;
  925. uint32_t exp_line_old = 0;
  926. int ret = 0;
  927. TRACE(IMX219_INFO, "%s: (enter handle = %p)\n", __func__, handle);
  928. if (!pIMX219Ctx) {
  929. TRACE(IMX219_ERROR,
  930. "%s: Invalid sensor handle (NULL pointer detected)\n",
  931. __func__);
  932. return (RET_WRONG_HANDLE);
  933. }
  934. if (!pSetIntegrationTime || !pNumberOfFramesToSkip) {
  935. TRACE(IMX219_ERROR,
  936. "%s: Invalid parameter (NULL pointer detected)\n",
  937. __func__);
  938. return (RET_NULL_POINTER);
  939. }
  940. exp_line = NewIntegrationTime / pIMX219Ctx->one_line_exp_time;
  941. exp_line_old = exp_line;
  942. exp_line =
  943. MIN(pIMX219Ctx->MaxIntegrationLine,
  944. MAX(pIMX219Ctx->MinIntegrationLine, exp_line));
  945. TRACE(IMX219_DEBUG, "%s: set AEC_PK_EXPO=0x%05x min_exp_line = %d, max_exp_line = %d\n", __func__, exp_line, pIMX219Ctx->MinIntegrationLine, pIMX219Ctx->MaxIntegrationLine);
  946. if (exp_line != pIMX219Ctx->OldIntegrationTime) {
  947. /*TODO*/
  948. //ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_EXP, &exp_line);
  949. pIMX219Ctx->OldIntegrationTime = exp_line; // remember current integration time
  950. pIMX219Ctx->AecCurIntegrationTime =
  951. exp_line * pIMX219Ctx->one_line_exp_time;
  952. *pNumberOfFramesToSkip = 1U; //skip 1 frame
  953. } else {
  954. *pNumberOfFramesToSkip = 0U; //no frame skip
  955. }
  956. if (NewIntegrationTime > pIMX219Ctx->MaxIntegrationLine * pIMX219Ctx->one_line_exp_time)
  957. NewIntegrationTime = pIMX219Ctx->MaxIntegrationLine * pIMX219Ctx->one_line_exp_time;
  958. // IMX219 specific
  959. // int vts = exp_line + 16;
  960. ret = IMX219_IsiRegisterWriteIss(handle, 0x015A, (exp_line>>8));
  961. if (ret != 0) {
  962. return (RET_FAILURE);
  963. }
  964. ret = IMX219_IsiRegisterWriteIss(handle, 0x015B, (exp_line&0xff));
  965. if (ret != 0) {
  966. return (RET_FAILURE);
  967. }
  968. if (exp_line_old != exp_line) {
  969. *pSetIntegrationTime = pIMX219Ctx->AecCurIntegrationTime;
  970. } else {
  971. *pSetIntegrationTime = NewIntegrationTime;
  972. }
  973. TRACE(IMX219_DEBUG, "%s: Ti=%f\n", __func__, *pSetIntegrationTime);
  974. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  975. return (result);
  976. }
  977. RESULT IMX219_IsiSetLongIntegrationTimeIss(IsiSensorHandle_t handle,float IntegrationTime)
  978. {
  979. int ret;
  980. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  981. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  982. if (!handle || !pIMX219Ctx->IsiCtx.HalHandle)
  983. {
  984. TRACE(IMX219_ERROR,"%s: Invalid sensor handle (NULL pointer detected)\n",__func__);
  985. return (RET_WRONG_HANDLE);
  986. }
  987. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  988. uint32_t exp_line = 0;
  989. exp_line = IntegrationTime / pIMX219Ctx->one_line_exp_time;
  990. exp_line = MIN(pIMX219Ctx->MaxIntegrationLine, MAX(pIMX219Ctx->MinIntegrationLine, exp_line));
  991. if (exp_line != pIMX219Ctx->LastLongExpLine)
  992. {
  993. if (pIMX219Ctx->KernelDriverFlag)
  994. {
  995. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_LONG_EXP, &exp_line);
  996. if (ret != 0)
  997. {
  998. TRACE(IMX219_ERROR,"%s: set long gain failed\n");
  999. return RET_FAILURE;
  1000. }
  1001. }
  1002. pIMX219Ctx->LastLongExpLine = exp_line;
  1003. pIMX219Ctx->AecCurLongIntegrationTime = pIMX219Ctx->LastLongExpLine*pIMX219Ctx->one_line_exp_time;
  1004. }
  1005. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1006. return (RET_SUCCESS);
  1007. }
  1008. RESULT IMX219_IsiSetVSIntegrationTimeIss
  1009. (IsiSensorHandle_t handle,
  1010. float NewIntegrationTime,
  1011. float *pSetVSIntegrationTime,
  1012. uint8_t * pNumberOfFramesToSkip, float *hdr_ratio)
  1013. {
  1014. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1015. RESULT result = RET_SUCCESS;
  1016. uint32_t exp_line = 0;
  1017. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1018. if (!pIMX219Ctx) {
  1019. TRACE(IMX219_ERROR,
  1020. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1021. __func__);
  1022. return (RET_WRONG_HANDLE);
  1023. }
  1024. if (!pSetVSIntegrationTime || !pNumberOfFramesToSkip) {
  1025. TRACE(IMX219_ERROR,
  1026. "%s: Invalid parameter (NULL pointer detected)\n",
  1027. __func__);
  1028. return (RET_NULL_POINTER);
  1029. }
  1030. TRACE(IMX219_INFO,
  1031. "%s: maxIntegrationTime-=%f minIntegrationTime = %f\n", __func__,
  1032. pIMX219Ctx->AecMaxIntegrationTime,
  1033. pIMX219Ctx->AecMinIntegrationTime);
  1034. exp_line = NewIntegrationTime / pIMX219Ctx->one_line_exp_time;
  1035. exp_line =
  1036. MIN(pIMX219Ctx->MaxIntegrationLine,
  1037. MAX(pIMX219Ctx->MinIntegrationLine, exp_line));
  1038. if (exp_line != pIMX219Ctx->OldVsIntegrationTime) {
  1039. /*TODO*/
  1040. // ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_VSEXP, &exp_line);
  1041. } else if (1){
  1042. pIMX219Ctx->OldVsIntegrationTime = exp_line;
  1043. pIMX219Ctx->AecCurVSIntegrationTime = exp_line * pIMX219Ctx->one_line_exp_time; //remember current integration time
  1044. *pNumberOfFramesToSkip = 1U; //skip 1 frame
  1045. } else {
  1046. *pNumberOfFramesToSkip = 0U; //no frame skip
  1047. }
  1048. *pSetVSIntegrationTime = pIMX219Ctx->AecCurVSIntegrationTime;
  1049. TRACE(IMX219_DEBUG, "%s: NewIntegrationTime=%f\n", __func__,
  1050. NewIntegrationTime);
  1051. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1052. return (result);
  1053. }
  1054. RESULT IMX219_IsiExposureControlIss
  1055. (IsiSensorHandle_t handle,
  1056. float NewGain,
  1057. float NewIntegrationTime,
  1058. uint8_t * pNumberOfFramesToSkip,
  1059. float *pSetGain, float *pSetIntegrationTime, float *hdr_ratio)
  1060. {
  1061. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1062. RESULT result = RET_SUCCESS;
  1063. int TmpGain;
  1064. /*TODO*/
  1065. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1066. if (pIMX219Ctx == NULL) {
  1067. TRACE(IMX219_ERROR,
  1068. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1069. __func__);
  1070. return (RET_WRONG_HANDLE);
  1071. }
  1072. if ((pNumberOfFramesToSkip == NULL) || (pSetGain == NULL)
  1073. || (pSetIntegrationTime == NULL)) {
  1074. TRACE(IMX219_ERROR,
  1075. "%s: Invalid parameter (NULL pointer detected)\n",
  1076. __func__);
  1077. return (RET_NULL_POINTER);
  1078. }
  1079. TRACE(IMX219_ERROR, "%s: g=%f, Ti=%f\n", __func__, NewGain,
  1080. NewIntegrationTime);
  1081. result = IMX219_IsiSetIntegrationTimeIss(handle, NewIntegrationTime,
  1082. pSetIntegrationTime,
  1083. pNumberOfFramesToSkip, hdr_ratio);
  1084. result = IMX219_IsiSetGainIss(handle, NewGain, pSetGain, hdr_ratio);
  1085. pIMX219Ctx->CurHdrRatio = *hdr_ratio;
  1086. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1087. return result;
  1088. }
  1089. RESULT IMX219_IsiGetCurrentExposureIss
  1090. (IsiSensorHandle_t handle, float *pSetGain, float *pSetIntegrationTime, float *hdr_ratio) {
  1091. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1092. RESULT result = RET_SUCCESS;
  1093. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1094. if (pIMX219Ctx == NULL) {
  1095. TRACE(IMX219_ERROR,
  1096. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1097. __func__);
  1098. return (RET_WRONG_HANDLE);
  1099. }
  1100. if ((pSetGain == NULL) || (pSetIntegrationTime == NULL))
  1101. return (RET_NULL_POINTER);
  1102. *pSetGain = pIMX219Ctx->AecCurGain;
  1103. *pSetIntegrationTime = pIMX219Ctx->AecCurIntegrationTime;
  1104. *hdr_ratio = pIMX219Ctx->CurHdrRatio;
  1105. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1106. return (result);
  1107. }
  1108. RESULT IMX219_IsiGetResolutionIss(IsiSensorHandle_t handle, uint16_t *pwidth, uint16_t *pheight) {
  1109. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1110. RESULT result = RET_SUCCESS;
  1111. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1112. if (pIMX219Ctx == NULL) {
  1113. TRACE(IMX219_ERROR,
  1114. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1115. __func__);
  1116. return (RET_WRONG_HANDLE);
  1117. }
  1118. *pwidth = pIMX219Ctx->SensorMode.width;
  1119. *pheight = pIMX219Ctx->SensorMode.height;
  1120. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1121. return (result);
  1122. }
  1123. RESULT IMX219_IsiGetSensorFpsIss(IsiSensorHandle_t handle, uint32_t * pfps)
  1124. {
  1125. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1126. RESULT result = RET_SUCCESS;
  1127. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1128. if (pIMX219Ctx == NULL) {
  1129. TRACE(IMX219_ERROR,
  1130. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1131. __func__);
  1132. return (RET_WRONG_HANDLE);
  1133. }
  1134. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  1135. if (pIMX219Ctx->KernelDriverFlag) {
  1136. /*TODO*/
  1137. ioctl(pHalCtx->sensor_fd, VVSENSORIOC_G_FPS, pfps);
  1138. pIMX219Ctx->CurrFps = *pfps;
  1139. }
  1140. *pfps = pIMX219Ctx->CurrFps;
  1141. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1142. return (result);
  1143. }
  1144. RESULT IMX219_IsiSetSensorFpsIss(IsiSensorHandle_t handle, uint32_t fps)
  1145. {
  1146. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1147. RESULT result = RET_SUCCESS;
  1148. int32_t ret = 0;
  1149. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1150. if (pIMX219Ctx == NULL) {
  1151. TRACE(IMX219_ERROR,
  1152. "%s: Invalid sensor handle (NULL pointer detected)\n",
  1153. __func__);
  1154. return (RET_WRONG_HANDLE);
  1155. }
  1156. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  1157. if (fps > pIMX219Ctx->MaxFps) {
  1158. TRACE(IMX219_ERROR,
  1159. "%s: set fps(%d) out of range, correct to %d (%d, %d)\n",
  1160. __func__, fps, pIMX219Ctx->MaxFps, pIMX219Ctx->MinFps,
  1161. pIMX219Ctx->MaxFps);
  1162. fps = pIMX219Ctx->MaxFps;
  1163. }
  1164. if (fps < pIMX219Ctx->MinFps) {
  1165. TRACE(IMX219_ERROR,
  1166. "%s: set fps(%d) out of range, correct to %d (%d, %d)\n",
  1167. __func__, fps, pIMX219Ctx->MinFps, pIMX219Ctx->MinFps,
  1168. pIMX219Ctx->MaxFps);
  1169. fps = pIMX219Ctx->MinFps;
  1170. }
  1171. if (pIMX219Ctx->KernelDriverFlag) {
  1172. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_FPS, &fps);
  1173. if (ret != 0) {
  1174. TRACE(IMX219_ERROR, "%s: set sensor fps=%d error\n",
  1175. __func__);
  1176. return (RET_FAILURE);
  1177. }
  1178. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_G_SENSOR_MODE, &(pIMX219Ctx->SensorMode));
  1179. {
  1180. pIMX219Ctx->MaxIntegrationLine = pIMX219Ctx->SensorMode.ae_info.max_integration_time;
  1181. pIMX219Ctx->AecMaxIntegrationTime = pIMX219Ctx->MaxIntegrationLine * pIMX219Ctx->one_line_exp_time;
  1182. }
  1183. #ifdef SUBDEV_CHAR
  1184. struct vvcam_ae_info_s ae_info;
  1185. ret =
  1186. ioctl(pHalCtx->sensor_fd, VVSENSORIOC_G_AE_INFO, &ae_info);
  1187. if (ret != 0) {
  1188. TRACE(IMX219_ERROR, "%s:sensor get ae info error!\n",
  1189. __func__);
  1190. return (RET_FAILURE);
  1191. }
  1192. pIMX219Ctx->one_line_exp_time =
  1193. (float)ae_info.one_line_exp_time_ns / 1000000000;
  1194. pIMX219Ctx->MaxIntegrationLine = ae_info.max_integration_time;
  1195. pIMX219Ctx->AecMaxIntegrationTime =
  1196. pIMX219Ctx->MaxIntegrationLine *
  1197. pIMX219Ctx->one_line_exp_time;
  1198. #endif
  1199. }
  1200. TRACE(IMX219_INFO, "%s: set sensor fps = %d\n", __func__,
  1201. pIMX219Ctx->CurrFps);
  1202. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1203. return (result);
  1204. }
  1205. static RESULT IMX219_IsiActivateTestPattern(IsiSensorHandle_t handle,
  1206. const bool_t enable)
  1207. {
  1208. RESULT result = RET_SUCCESS;
  1209. TRACE(IMX219_INFO, "%s: (enter)\n", __func__);
  1210. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1211. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  1212. return RET_NULL_POINTER;
  1213. }
  1214. if (pIMX219Ctx->Configured != BOOL_TRUE)
  1215. return RET_WRONG_STATE;
  1216. if (BOOL_TRUE == enable) {
  1217. //result = IMX219_IsiRegisterWriteIss(handle, 0x3253, 0x80);
  1218. } else {
  1219. //result = IMX219_IsiRegisterWriteIss(handle, 0x3253, 0x00);
  1220. }
  1221. pIMX219Ctx->TestPattern = enable;
  1222. TRACE(IMX219_INFO, "%s: (exit)\n", __func__);
  1223. return (result);
  1224. }
  1225. static RESULT IMX219_IsiSensorSetBlcIss(IsiSensorHandle_t handle, sensor_blc_t * pblc)
  1226. {
  1227. int32_t ret = 0;
  1228. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1229. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  1230. return RET_WRONG_HANDLE;
  1231. }
  1232. if (pblc == NULL)
  1233. return RET_NULL_POINTER;
  1234. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  1235. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_BLC, pblc);
  1236. if (ret != 0)
  1237. {
  1238. TRACE(IMX219_ERROR, "%s: set wb error\n", __func__);
  1239. }
  1240. return RET_SUCCESS;
  1241. }
  1242. static RESULT IMX219_IsiSensorSetWBIss(IsiSensorHandle_t handle, sensor_white_balance_t * pwb)
  1243. {
  1244. int32_t ret = 0;
  1245. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1246. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  1247. return RET_WRONG_HANDLE;
  1248. }
  1249. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  1250. if (pwb == NULL)
  1251. return RET_NULL_POINTER;
  1252. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_S_WB, pwb);
  1253. if (ret != 0)
  1254. {
  1255. TRACE(IMX219_ERROR, "%s: set wb error\n", __func__);
  1256. }
  1257. return RET_SUCCESS;
  1258. }
  1259. static RESULT IMX219_IsiGetSensorAWBModeIss(IsiSensorHandle_t handle, IsiSensorAwbMode_t *pawbmode)
  1260. {
  1261. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1262. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  1263. return RET_NULL_POINTER;
  1264. }
  1265. if (pIMX219Ctx->SensorMode.hdr_mode == SENSOR_MODE_HDR_NATIVE){
  1266. *pawbmode = ISI_SENSOR_AWB_MODE_SENSOR;
  1267. }else{
  1268. *pawbmode = ISI_SENSOR_AWB_MODE_NORMAL;
  1269. }
  1270. return RET_SUCCESS;
  1271. }
  1272. static RESULT IMX219_IsiSensorGetExpandCurveIss(IsiSensorHandle_t handle, sensor_expand_curve_t * pexpand_curve)
  1273. {
  1274. int32_t ret = 0;
  1275. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1276. if (pIMX219Ctx == NULL || pIMX219Ctx->IsiCtx.HalHandle == NULL) {
  1277. return RET_NULL_POINTER;
  1278. }
  1279. HalContext_t *pHalCtx = (HalContext_t *) pIMX219Ctx->IsiCtx.HalHandle;
  1280. ret = ioctl(pHalCtx->sensor_fd, VVSENSORIOC_G_EXPAND_CURVE, pexpand_curve);
  1281. if (ret != 0)
  1282. {
  1283. TRACE(IMX219_ERROR, "%s: get expand cure error\n", __func__);
  1284. return RET_FAILURE;
  1285. }
  1286. return RET_SUCCESS;
  1287. }
  1288. static RESULT IMX219_IsiGetCapsIss(IsiSensorHandle_t handle,
  1289. IsiSensorCaps_t * pIsiSensorCaps)
  1290. {
  1291. IMX219_Context_t *pIMX219Ctx = (IMX219_Context_t *) handle;
  1292. RESULT result = RET_SUCCESS;
  1293. TRACE(IMX219_INFO, "%s (enter)\n", __func__);
  1294. if (pIMX219Ctx == NULL) {
  1295. return (RET_WRONG_HANDLE);
  1296. }
  1297. if (pIsiSensorCaps == NULL) {
  1298. return (RET_NULL_POINTER);
  1299. }
  1300. pIsiSensorCaps->BusWidth = pIMX219Ctx->SensorMode.bit_width;
  1301. pIsiSensorCaps->Mode = ISI_MODE_BAYER;
  1302. pIsiSensorCaps->FieldSelection = ISI_FIELDSEL_BOTH;
  1303. pIsiSensorCaps->YCSequence = ISI_YCSEQ_YCBYCR;
  1304. pIsiSensorCaps->Conv422 = ISI_CONV422_NOCOSITED;
  1305. pIsiSensorCaps->BPat = pIMX219Ctx->SensorMode.bayer_pattern;
  1306. pIsiSensorCaps->HPol = ISI_HPOL_REFPOS;
  1307. pIsiSensorCaps->VPol = ISI_VPOL_NEG;
  1308. pIsiSensorCaps->Edge = ISI_EDGE_RISING;
  1309. pIsiSensorCaps->Resolution.width = pIMX219Ctx->SensorMode.width;
  1310. pIsiSensorCaps->Resolution.height = pIMX219Ctx->SensorMode.height;
  1311. pIsiSensorCaps->SmiaMode = ISI_SMIA_OFF;
  1312. pIsiSensorCaps->MipiLanes = ISI_MIPI_2LANES;
  1313. if (pIsiSensorCaps->BusWidth == 10) {
  1314. pIsiSensorCaps->MipiMode = ISI_MIPI_MODE_RAW_10;
  1315. }else if (pIsiSensorCaps->BusWidth == 12){
  1316. pIsiSensorCaps->MipiMode = ISI_MIPI_MODE_RAW_12;
  1317. }else{
  1318. pIsiSensorCaps->MipiMode = ISI_MIPI_OFF;
  1319. }
  1320. TRACE(IMX219_INFO, "%s (exit)\n", __func__);
  1321. return result;
  1322. }
  1323. RESULT IMX219_IsiGetSensorIss(IsiSensor_t *pIsiSensor)
  1324. {
  1325. RESULT result = RET_SUCCESS;
  1326. TRACE( IMX219_INFO, "%s (enter)\n", __func__);
  1327. if ( pIsiSensor != NULL ) {
  1328. pIsiSensor->pszName = SensorName;
  1329. pIsiSensor->pIsiCreateSensorIss = IMX219_IsiCreateSensorIss;
  1330. pIsiSensor->pIsiInitSensorIss = IMX219_IsiInitSensorIss;
  1331. pIsiSensor->pIsiGetSensorModeIss = IMX219_IsiGetSensorModeIss;
  1332. pIsiSensor->pIsiResetSensorIss = IMX219_IsiResetSensorIss;
  1333. pIsiSensor->pIsiReleaseSensorIss = IMX219_IsiReleaseSensorIss;
  1334. pIsiSensor->pIsiGetCapsIss = IMX219_IsiGetCapsIss;
  1335. pIsiSensor->pIsiSetupSensorIss = IMX219_IsiSetupSensorIss;
  1336. pIsiSensor->pIsiChangeSensorResolutionIss = IMX219_IsiChangeSensorResolutionIss;
  1337. pIsiSensor->pIsiSensorSetStreamingIss = IMX219_IsiSensorSetStreamingIss;
  1338. pIsiSensor->pIsiSensorSetPowerIss = IMX219_IsiSensorSetPowerIss;
  1339. pIsiSensor->pIsiCheckSensorConnectionIss = IMX219_IsiCheckSensorConnectionIss;
  1340. pIsiSensor->pIsiGetSensorRevisionIss = IMX219_IsiGetSensorRevisionIss;
  1341. pIsiSensor->pIsiRegisterReadIss = IMX219_IsiRegisterReadIss;
  1342. pIsiSensor->pIsiRegisterWriteIss = IMX219_IsiRegisterWriteIss;
  1343. /* AEC functions */
  1344. pIsiSensor->pIsiExposureControlIss = IMX219_IsiExposureControlIss;
  1345. pIsiSensor->pIsiGetGainLimitsIss = IMX219_IsiGetGainLimitsIss;
  1346. pIsiSensor->pIsiGetIntegrationTimeLimitsIss = IMX219_IsiGetIntegrationTimeLimitsIss;
  1347. pIsiSensor->pIsiGetCurrentExposureIss = IMX219_IsiGetCurrentExposureIss;
  1348. pIsiSensor->pIsiGetVSGainIss = IMX219_IsiGetVSGainIss;
  1349. pIsiSensor->pIsiGetGainIss = IMX219_IsiGetGainIss;
  1350. pIsiSensor->pIsiGetLongGainIss = IMX219_IsiGetLongGainIss;
  1351. pIsiSensor->pIsiGetGainIncrementIss = IMX219_IsiGetGainIncrementIss;
  1352. pIsiSensor->pIsiSetGainIss = IMX219_IsiSetGainIss;
  1353. pIsiSensor->pIsiGetIntegrationTimeIss = IMX219_IsiGetIntegrationTimeIss;
  1354. pIsiSensor->pIsiGetVSIntegrationTimeIss = IMX219_IsiGetVSIntegrationTimeIss;
  1355. pIsiSensor->pIsiGetLongIntegrationTimeIss = IMX219_IsiGetLongIntegrationTimeIss;
  1356. pIsiSensor->pIsiGetIntegrationTimeIncrementIss = IMX219_IsiGetIntegrationTimeIncrementIss;
  1357. pIsiSensor->pIsiSetIntegrationTimeIss = IMX219_IsiSetIntegrationTimeIss;
  1358. pIsiSensor->pIsiQuerySensorIss = IMX219_IsiQuerySensorIss;
  1359. pIsiSensor->pIsiGetResolutionIss = IMX219_IsiGetResolutionIss;
  1360. pIsiSensor->pIsiGetSensorFpsIss = IMX219_IsiGetSensorFpsIss;
  1361. pIsiSensor->pIsiSetSensorFpsIss = IMX219_IsiSetSensorFpsIss;
  1362. pIsiSensor->pIsiSensorGetExpandCurveIss = IMX219_IsiSensorGetExpandCurveIss;
  1363. /* AWB specific functions */
  1364. /* Testpattern */
  1365. pIsiSensor->pIsiActivateTestPattern = IMX219_IsiActivateTestPattern;
  1366. pIsiSensor->pIsiSetBayerPattern = IMX219_IsiSetBayerPattern;
  1367. pIsiSensor->pIsiSensorSetBlcIss = IMX219_IsiSensorSetBlcIss;
  1368. pIsiSensor->pIsiSensorSetWBIss = IMX219_IsiSensorSetWBIss;
  1369. pIsiSensor->pIsiGetSensorAWBModeIss = IMX219_IsiGetSensorAWBModeIss;
  1370. } else {
  1371. result = RET_NULL_POINTER;
  1372. }
  1373. TRACE( IMX219_INFO, "%s (exit)\n", __func__);
  1374. return ( result );
  1375. }
  1376. /*****************************************************************************
  1377. * each sensor driver need declare this struct for isi load
  1378. *****************************************************************************/
  1379. IsiCamDrvConfig_t IMX219_IsiCamDrvConfig = {
  1380. 0,
  1381. IMX219_IsiQuerySensorSupportIss,
  1382. IMX219_IsiGetSensorIss,
  1383. {
  1384. SensorName, /**< IsiSensor_t.pszName */
  1385. 0, /**< IsiSensor_t.pIsiInitIss>*/
  1386. 0, /**< IsiSensor_t.pIsiResetSensorIss>*/
  1387. 0, /**< IsiSensor_t.pRegisterTable */
  1388. 0, /**< IsiSensor_t.pIsiSensorCaps */
  1389. 0, /**< IsiSensor_t.pIsiCreateSensorIss */
  1390. 0, /**< IsiSensor_t.pIsiReleaseSensorIss */
  1391. 0, /**< IsiSensor_t.pIsiGetCapsIss */
  1392. 0, /**< IsiSensor_t.pIsiSetupSensorIss */
  1393. 0, /**< IsiSensor_t.pIsiChangeSensorResolutionIss */
  1394. 0, /**< IsiSensor_t.pIsiSensorSetStreamingIss */
  1395. 0, /**< IsiSensor_t.pIsiSensorSetPowerIss */
  1396. 0, /**< IsiSensor_t.pIsiCheckSensorConnectionIss */
  1397. 0, /**< IsiSensor_t.pIsiGetSensorRevisionIss */
  1398. 0, /**< IsiSensor_t.pIsiRegisterReadIss */
  1399. 0, /**< IsiSensor_t.pIsiRegisterWriteIss */
  1400. 0, /**< IsiSensor_t.pIsiExposureControlIss */
  1401. 0, /**< IsiSensor_t.pIsiGetGainLimitsIss */
  1402. 0, /**< IsiSensor_t.pIsiGetIntegrationTimeLimitsIss */
  1403. 0, /**< IsiSensor_t.pIsiGetCurrentExposureIss */
  1404. 0, /**< IsiSensor_t.pIsiGetGainIss */
  1405. 0, /**< IsiSensor_t.pIsiGetVSGainIss */
  1406. 0, /**< IsiSensor_t.pIsiGetGainIncrementIss */
  1407. 0, /**< IsiSensor_t.pIsiGetGainIncrementIss */
  1408. 0, /**< IsiSensor_t.pIsiSetGainIss */
  1409. 0, /**< IsiSensor_t.pIsiGetIntegrationTimeIss */
  1410. 0, /**< IsiSensor_t.pIsiGetIntegrationTimeIncrementIss */
  1411. 0, /**< IsiSensor_t.pIsiSetIntegrationTimeIss */
  1412. 0, /**< IsiSensor_t.pIsiGetResolutionIss */
  1413. 0, /**< IsiSensor_t.pIsiGetAfpsInfoIss */
  1414. 0, /**< IsiSensor_t.pIsiMdiInitMotoDriveMds */
  1415. 0, /**< IsiSensor_t.pIsiMdiSetupMotoDrive */
  1416. 0, /**< IsiSensor_t.pIsiMdiFocusSet */
  1417. 0, /**< IsiSensor_t.pIsiMdiFocusGet */
  1418. 0, /**< IsiSensor_t.pIsiMdiFocusCalibrate */
  1419. 0, /**< IsiSensor_t.pIsiGetSensorMipiInfoIss */
  1420. 0, /**< IsiSensor_t.pIsiActivateTestPattern */
  1421. 0, /**< IsiSensor_t.pIsiSetBayerPattern */
  1422. }
  1423. };