ark_isp_exposure_cmos.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. #include <linux/kernel.h>
  2. #include <linux/string.h>
  3. #include <linux/math64.h>
  4. #include "ark_camera.h"
  5. #include "ark_isp_exposure_cmos.h"
  6. #include "ark_isp_exposure.h"
  7. extern cmos_exposure_t isp_exposure;
  8. static void boundary_min_check_u16 (u16_t * param, u32_t min)
  9. {
  10. if((*param) < min)
  11. {
  12. *param = (u16_t)min;
  13. }
  14. }
  15. static void boundary_max_check_u16 (u16_t * param, u32_t max)
  16. {
  17. if((*param) > max)
  18. {
  19. *param = (u16_t)max;
  20. }
  21. }
  22. static void boundary_min_check (u32_t * param, u32_t min)
  23. {
  24. if((*param) < min)
  25. {
  26. *param = min;
  27. }
  28. }
  29. static void boundary_max_check (u32_t * param, u32_t max)
  30. {
  31. if((*param) > max)
  32. {
  33. *param = max;
  34. }
  35. }
  36. static void boundaries_check (u32_t * param, u32_t min, u32_t max)
  37. {
  38. boundary_min_check(param, min);
  39. boundary_max_check(param, max);
  40. }
  41. u32_t exposure_limit_calculate(
  42. u16_t exp_lines,
  43. u32_t max_again,
  44. u32_t max_dgain,
  45. u16_t shift,
  46. u16_t gain_shift
  47. )
  48. {
  49. i64_t exp = exp_lines * shift;
  50. exp *= max_again * max_dgain;
  51. exp = exp >> gain_shift;
  52. return (u32_t)exp;
  53. }
  54. // function limits the exposure to the nearest multiple of flicker half-period.
  55. static u32_t exposure_antiflicker_correct (
  56. u32_t exposure_lines,
  57. u32_t flicker_freq,
  58. u32_t lines_per_500ms,
  59. u16_t sys_factor
  60. )
  61. {
  62. int N;
  63. if (flicker_freq == 0)
  64. {
  65. return exposure_lines;
  66. }
  67. N = (exposure_lines * flicker_freq) / (lines_per_500ms);
  68. N = N < 1 ? 1 : N;
  69. return (N * lines_per_500ms) / flicker_freq;
  70. }
  71. // 计算下一次的曝光量(积分时间/增益)
  72. int isp_exposure_cmos_calculate (
  73. cmos_exposure_ptr_t p_exp,
  74. u32_t exp_increment,
  75. u32_t exp_increment_max,
  76. u32_t exp_increment_min,
  77. u32_t exp_increment_offset
  78. )
  79. {
  80. unsigned int max_lines_short;
  81. // unsigned int max_lines_long;
  82. u32_t exposure_1st, exposure_2nd;
  83. u32_t new_exposure;
  84. u32_t old_exposure_ashort;
  85. i64_t temp64;
  86. int same_exp = 0; // 检查理论曝光值是否相同
  87. int exp_dir = 0; // 1 曝光量增加 0 曝光量不变 -1 曝光量减小
  88. static int flicker_state = 0;
  89. int new_flicker_state;
  90. old_exposure_ashort = p_exp->cmos_inttime.exposure_ashort;
  91. // max_lines_long = p_exp->cmos_inttime.max_lines_target;
  92. max_lines_short = p_exp->cmos_inttime.max_lines_target;
  93. // 根据直方图误差调整理论曝光量 exposure
  94. // new_exposure的计算会出现32位溢出
  95. // new_exposure = (p_exp->exposure * exp_increment + (exp_increment_offset >> 1)) / exp_increment_offset;
  96. temp64 = p_exp->exposure;
  97. temp64 *= exp_increment;
  98. //temp64 += (exp_increment_offset >> 1); // 不做四舍五入处理, 避免曝光量误差过大导致画面亮度轻微抖动
  99. new_exposure = div_s64(temp64, exp_increment_offset);
  100. // p_exp->last_exposure = p_exp->exposure;
  101. /*
  102. XM_printf ("\t\texposure = %10d, new_exposure = %10d, increment = %10d\n",
  103. p_exp->exposure,
  104. new_exposure,
  105. exp_increment);
  106. */
  107. if(p_exp->exposure == new_exposure)
  108. {
  109. same_exp = 1;
  110. exp_dir = 0;
  111. }
  112. else if(p_exp->exposure < new_exposure)
  113. {
  114. // 曝光量增加
  115. exp_dir = 1;
  116. }
  117. else
  118. {
  119. // 曝光量减小
  120. exp_dir = -1;
  121. }
  122. p_exp->exposure = new_exposure;
  123. // 检查曝光量的范围
  124. boundaries_check (
  125. &p_exp->exposure,
  126. p_exp->exp_llimit,
  127. p_exp->exp_tlimit
  128. );
  129. exposure_1st = p_exp->exposure;
  130. exposure_2nd = p_exp->exposure;
  131. // the exposure/gain is allocated as following:
  132. // 1) analog gain
  133. // 2) digital gain
  134. // 3) exposure time
  135. // 4) antiflicker correction (if enabled) -> setting exposure times to finite s
  136. // 5) adjust again/dgain if necessary
  137. // 检查sensor是否具有模拟增益.
  138. // 若有, 计算sensor的模拟增益
  139. if(1 != p_exp->cmos_gain.max_again_target)
  140. {
  141. // 根据曝光量exposure_1st, 计算模拟增益again, 然后修正exposure_1st
  142. exposure_1st = (*p_exp->cmos_sensor.analog_gain_from_exposure_calculate) (
  143. &p_exp->cmos_gain,
  144. exposure_1st,
  145. p_exp->cmos_inttime.max_flicker_lines * p_exp->sys_factor
  146. );
  147. }
  148. // 检查sensor是否具有数字增益.
  149. // 若有, 计算sensor的数字增益
  150. if(1 != p_exp->cmos_gain.max_dgain_target)
  151. {
  152. // 根据曝光量exposure_1st, 计算数字增益again, 然后修正exposure_1st
  153. exposure_1st = (*p_exp->cmos_sensor.digital_gain_from_exposure_calculate) (
  154. &p_exp->cmos_gain,
  155. exposure_1st, // 曝光量
  156. p_exp->cmos_inttime.max_flicker_lines * p_exp->sys_factor // 最大积分行数量
  157. );
  158. }
  159. // 根据估计的增益值(模拟+数字), 计算所需的曝光积分行数
  160. //p_exp->cmos_inttime.exposure_ashort = ((exposure_1st + p_exp->sys_factor - 1) / p_exp->sys_factor);
  161. if(p_exp->cmos_inttime.flicker_freq) // 频闪时, 计算顺序为 1) 曝光行, 2) 模拟增益 3) 数字增益
  162. p_exp->cmos_inttime.exposure_ashort = ((exposure_2nd ) / p_exp->sys_factor);
  163. else
  164. p_exp->cmos_inttime.exposure_ashort = ((exposure_1st ) / p_exp->sys_factor); // 禁止四舍五入, 会导致exposure_ashort * sys_factor大于exposure_2nd,
  165. // 这样第二次校正时不会进行模拟增益校正,从而导致曝光不稳,出现闪烁.
  166. //if(p_exp->cmos_inttime.exposure_ashort >= p_exp->cmos_inttime.max_flicker_lines)
  167. // p_exp->cmos_inttime.exposure_ashort = p_exp->cmos_inttime.max_flicker_lines;
  168. if(p_exp->cmos_inttime.exposure_ashort >= p_exp->cmos_inttime.max_lines)
  169. p_exp->cmos_inttime.exposure_ashort = p_exp->cmos_inttime.max_lines;
  170. if(p_exp->cmos_inttime.exposure_ashort > max_lines_short)
  171. p_exp->cmos_inttime.exposure_ashort = max_lines_short;
  172. // anti-flicker 校正
  173. if(p_exp->cmos_inttime.flicker_freq && (new_exposure >= p_exp->cmos_inttime.max_flicker_lines * p_exp->sys_factor))
  174. {
  175. // 消除50/60hz频闪会导致室外白天场景(不需要消除频闪)下的曝光行计算不准确.
  176. // 由于无法判断50/60hz频闪场景, 又需要保证白天曝光的准确性,
  177. // 通过判断总曝光量为最大行曝光量的2倍时, 开启50/60hz频闪消除算法
  178. // 20170806 由于无法准确判断频闪(缺乏硬件支持), 且频闪使能判定算法不可靠, 因此频闪使能时不再考虑曝光是否过曝等问题,
  179. // 由使用者决定开启(50/60Hz)或关闭频闪功能
  180. u32_t new_exposure_ashort = exposure_antiflicker_correct(
  181. p_exp->cmos_inttime.exposure_ashort,
  182. p_exp->cmos_inttime.flicker_freq,
  183. p_exp->cmos_inttime.lines_per_500ms,
  184. p_exp->sys_factor
  185. );
  186. // 以下算法为防止反复导致频闪
  187. // new_exposure inttime again
  188. // 184434 364 1.979245364
  189. // 190197 728 1.020545373 曝光剧烈变化点
  190. // 181495 364 1.947705615 曝光反复点, 维持
  191. // 140651 364 1.509390024 曝光反复点
  192. if(new_exposure_ashort == old_exposure_ashort)
  193. {
  194. p_exp->cmos_inttime.exposure_ashort = new_exposure_ashort;
  195. }
  196. else if(exp_dir == (-1))
  197. {
  198. // 曝光量减小
  199. //double gain = ((double)exposure_2nd) / p_exp->sys_factor;
  200. //gain = gain / new_exposure_ashort;
  201. //if(gain >= 1.75 && gain < 2.0)
  202. u32_t igain = exposure_2nd / new_exposure_ashort;
  203. if( igain >= (p_exp->sys_factor * 6/5) && igain < (p_exp->sys_factor * 2) )
  204. {
  205. // 1.75 ~ 2.00 维持,使用老的inttime
  206. p_exp->cmos_inttime.exposure_ashort = old_exposure_ashort;
  207. }
  208. else
  209. {
  210. // < 1.75 或者 >= 2.00, 使用新的inttime
  211. p_exp->cmos_inttime.exposure_ashort = new_exposure_ashort;
  212. XM_printf ("dec old=%d, new=%d\n", old_exposure_ashort, new_exposure_ashort);
  213. }
  214. }
  215. else
  216. {
  217. // 曝光量增加
  218. // 新的曝光行计数必须大于老的曝光行计数
  219. if(new_exposure_ashort > old_exposure_ashort)
  220. {
  221. p_exp->cmos_inttime.exposure_ashort = new_exposure_ashort;
  222. XM_printf ("inc old=%d, new=%d\n", old_exposure_ashort, new_exposure_ashort);
  223. }
  224. else
  225. {
  226. p_exp->cmos_inttime.exposure_ashort = old_exposure_ashort;
  227. }
  228. }
  229. /*
  230. p_exp->cmos_inttime.exposure_ashort = exposure_antiflicker_correct(
  231. p_exp->cmos_inttime.exposure_ashort,
  232. p_exp->cmos_inttime.flicker_freq,
  233. p_exp->cmos_inttime.lines_per_500ms,
  234. p_exp->sys_factor
  235. );
  236. */
  237. new_flicker_state = 1;
  238. }
  239. else if(p_exp->cmos_inttime.flicker_freq)
  240. {
  241. new_flicker_state = 0;
  242. }
  243. else
  244. {
  245. new_flicker_state = 0;
  246. }
  247. if(new_flicker_state != flicker_state)
  248. {
  249. flicker_state = new_flicker_state;
  250. XM_printf ("%s\n", flicker_state ? "exp --> flick" : "exp --> antif");
  251. }
  252. // 根据确定的曝光行数第二遍校正模拟及数字增益
  253. if(1 != p_exp->cmos_gain.max_again_target)
  254. {
  255. exposure_2nd = (*p_exp->cmos_sensor.analog_gain_from_exposure_calculate) (
  256. &p_exp->cmos_gain,
  257. exposure_2nd,
  258. (p_exp->cmos_inttime.exposure_ashort * p_exp->sys_factor)
  259. );
  260. }
  261. if(1 != p_exp->cmos_gain.max_dgain_target)
  262. {
  263. exposure_2nd = (*p_exp->cmos_sensor.digital_gain_from_exposure_calculate) (
  264. &p_exp->cmos_gain,
  265. exposure_2nd,
  266. (p_exp->cmos_inttime.exposure_ashort * p_exp->sys_factor)
  267. );
  268. }
  269. return same_exp;
  270. }
  271. // 根据计算的曝光设置更新sensor设置
  272. int isp_cmos_inttime_update (cmos_exposure_ptr_t p_exp)
  273. {
  274. // 修改曝光行积分数量/模拟/数字增益
  275. return p_exp->cmos_sensor.cmos_inttime_gain_update (&p_exp->cmos_inttime, &p_exp->cmos_gain);
  276. }
  277. void isp_cmos_inttime_update_manual (cmos_exposure_ptr_t p_exp)
  278. {
  279. // 修改曝光行积分数量/模拟/数字增益
  280. p_exp->cmos_sensor.cmos_inttime_gain_update_manual (&p_exp->cmos_inttime, &p_exp->cmos_gain);
  281. }
  282. // 设置帧率
  283. int isp_cmos_set_framerate (cmos_exposure_ptr_t p_exp, u8_t fps)
  284. {
  285. cmos_inttime_ptr_t inttime;
  286. if(!p_exp->cmos_sensor.cmos_fps_set)
  287. {
  288. XM_printf ("cmos_fps_set can't be empty\n");
  289. return -1;
  290. }
  291. (*p_exp->cmos_sensor.cmos_fps_set) (&p_exp->cmos_inttime, fps);
  292. p_exp->fps = fps;
  293. inttime = &p_exp->cmos_inttime;
  294. boundary_min_check_u16(&inttime->min_lines_target, 1);
  295. inttime->min_lines = inttime->min_lines_target;
  296. inttime->max_lines_target = (u16_t)(inttime->full_lines - 2);
  297. inttime->max_lines = inttime->max_lines_target;
  298. if(inttime->max_lines > inttime->full_lines_limit)
  299. inttime->max_lines = inttime->full_lines_limit;
  300. // 更新flicker设置
  301. inttime->max_flicker_lines = (u16_t)exposure_antiflicker_correct(
  302. inttime->max_lines,
  303. inttime->flicker_freq,
  304. inttime->lines_per_500ms,
  305. p_exp->sys_factor
  306. );
  307. // 最小曝光量不考虑周期性flicker现象
  308. inttime->min_flicker_lines = inttime->min_lines;
  309. return 0;
  310. }
  311. // 使能/禁止flicker
  312. int isp_cmos_set_flicker_freq (cmos_exposure_ptr_t p_exp, u8_t flicker_freq)
  313. {
  314. #if ISP_RAW_ENABLE
  315. flicker_freq = 0;
  316. #endif
  317. if( flicker_freq != 0
  318. && flicker_freq != 50
  319. && flicker_freq != 60)
  320. {
  321. XM_printf ("illegal flicker freqency (%d)\n", flicker_freq);
  322. return -1;
  323. }
  324. if(flicker_freq == 0)
  325. XM_printf ("exposure anti-flicker disable\n");
  326. else
  327. XM_printf ("exposure anti-flicker %d Hz\n");
  328. //OS_EnterRegion ();
  329. p_exp->cmos_inttime.flicker_freq = flicker_freq;
  330. // 更新flicker设置
  331. // max_flicker_lines 小于或等于 p_exp->cmos_inttime.max_lines
  332. p_exp->cmos_inttime.max_flicker_lines = (u16_t)exposure_antiflicker_correct(
  333. p_exp->cmos_inttime.max_lines,
  334. p_exp->cmos_inttime.flicker_freq,
  335. p_exp->cmos_inttime.lines_per_500ms,
  336. p_exp->sys_factor
  337. );
  338. // 最小曝光量不考虑周期性flicker现象
  339. p_exp->cmos_inttime.min_flicker_lines = p_exp->cmos_inttime.min_lines;
  340. // 最大曝光量估算
  341. p_exp->exp_tlimit = exposure_limit_calculate(
  342. p_exp->cmos_inttime.max_flicker_lines,
  343. p_exp->cmos_gain.max_again,
  344. p_exp->cmos_gain.max_dgain,
  345. (u16_t)p_exp->sys_factor,
  346. (u16_t)(p_exp->cmos_gain.again_shift + p_exp->cmos_gain.dgain_shift)
  347. );
  348. // 最小曝光量估算
  349. p_exp->exp_llimit = exposure_limit_calculate(
  350. p_exp->cmos_inttime.min_flicker_lines,
  351. 1,
  352. 1,
  353. (u16_t)p_exp->sys_factor,
  354. 0
  355. );
  356. //OS_LeaveRegion();
  357. return 0;
  358. }
  359. int isp_exposure_cmos_initialize (cmos_exposure_ptr_t p_exp)
  360. {
  361. cmos_gain_ptr_t gain;
  362. cmos_inttime_ptr_t inttime;
  363. unsigned int light_freq;
  364. isp_init_cmos_sensor (&p_exp->cmos_sensor);
  365. if(!p_exp->cmos_sensor.cmos_gain_initialize || !p_exp->cmos_sensor.cmos_inttime_initialize)
  366. {
  367. XM_printf ("the sensor's cmos_gain_initialize or cmos_inttime_initialize can't be empty\n");
  368. return -1;
  369. }
  370. // gain 初始化
  371. gain = (*p_exp->cmos_sensor.cmos_gain_initialize) ();
  372. if(!gain)
  373. {
  374. XM_printf ("the gain instance can't be empty\n");
  375. return -1;
  376. }
  377. memcpy (&p_exp->cmos_gain, gain, sizeof(p_exp->cmos_gain));
  378. gain = &p_exp->cmos_gain;
  379. // 缺省增益设置为1
  380. gain->again = 1 << gain->again_shift;
  381. gain->dgain = 1 << gain->dgain_shift;
  382. gain->iso = 100;
  383. gain->max_again = gain->max_again_target;
  384. gain->max_dgain = gain->max_dgain_target;
  385. // 曝光积分行数初始化
  386. inttime = (*p_exp->cmos_sensor.cmos_inttime_initialize)();
  387. if(!inttime)
  388. {
  389. XM_printf ("the inttime instance can't be empty\n");
  390. return -1;
  391. }
  392. memcpy (&p_exp->cmos_inttime, inttime, sizeof(p_exp->cmos_inttime));
  393. p_exp->cmos_inttime.flicker_freq = 0; // 缺省禁止flicker
  394. p_exp->cmos_inttime.exposure_ashort = inttime->min_lines_target;
  395. // 检查inttime参数
  396. // 设置sensor的初始参数(积分时间及增益设置)
  397. isp_cmos_inttime_update (p_exp);
  398. // 缺省帧率 30帧
  399. isp_cmos_set_framerate (p_exp, 30);
  400. #if 0
  401. light_freq = AP_GetMenuItem (APPMENUITEM_LIGHT_FREQ);
  402. if(light_freq == AP_SETTING_LIGHT_FREQ_50HZ)
  403. isp_cmos_set_flicker_freq (p_exp, 50);
  404. else if(light_freq == AP_SETTING_LIGHT_FREQ_60HZ)
  405. isp_cmos_set_flicker_freq (p_exp, 60);
  406. else //if(light_freq == AP_SETTING_LIGHT_FREQ_OFF)
  407. isp_cmos_set_flicker_freq (p_exp, 0);
  408. #endif
  409. // 估计一个初始曝光值
  410. p_exp->sys_factor = 256;//128; //64;
  411. p_exp->exposure = p_exp->cmos_inttime.exposure_ashort * p_exp->sys_factor;
  412. // 缺省禁止flicker
  413. isp_cmos_set_flicker_freq (p_exp, 0);
  414. #if 0
  415. // 最大曝光量估算
  416. p_exp->exp_tlimit = exposure_limit_calculate(
  417. p_exp->cmos_inttime.max_flicker_lines,
  418. p_exp->cmos_gain.max_again,
  419. p_exp->cmos_gain.max_dgain,
  420. (u16_t)p_exp->sys_factor,
  421. (u16_t)(p_exp->cmos_gain.again_shift + p_exp->cmos_gain.dgain_shift)
  422. );
  423. // 最小曝光量估算
  424. p_exp->exp_llimit = exposure_limit_calculate(
  425. p_exp->cmos_inttime.min_flicker_lines,
  426. 1,
  427. 1,
  428. (u16_t)p_exp->sys_factor,
  429. 0
  430. );
  431. #endif
  432. p_exp->physical_exposure = 0;
  433. return 0;
  434. }
  435. void isp_min_integration_time_set (cmos_exposure_ptr_t p_exp, u16_t value)
  436. {
  437. p_exp->cmos_inttime.min_lines_target = value;
  438. }
  439. void isp_max_integration_time_set (cmos_exposure_ptr_t p_exp, u16_t value)
  440. {
  441. p_exp->cmos_inttime.max_lines_target = value;
  442. }
  443. extern isp_ae_t p_ae;
  444. // 初始化cmos sensor的实例
  445. int arkn141_isp_ae_initialize (cmos_exposure_ptr_t p_exp)
  446. {
  447. int i, j;
  448. u8_t hist_thresh[4] = {0x10, 0x40, 0x80, 0xc0};
  449. u8_t win_weight[3][3] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
  450. memset (p_exp, 0, sizeof(*p_exp));
  451. isp_auto_exposure_initialize (&(p_exp->cmos_ae));
  452. isp_exposure_cmos_initialize (p_exp);
  453. isp_min_integration_time_set (p_exp, ISP_SYSTEM_MIN_INTEGRATION_TIME_DEFAULT);
  454. isp_max_integration_time_set (p_exp, ISP_SYSTEM_MAX_INTEGRATION_TIME_DEFAULT);
  455. for (i = 0; i < 4; i ++)
  456. {
  457. p_ae.histoBand[i] = hist_thresh[i];
  458. }
  459. for (i = 0; i < 3; i ++)
  460. {
  461. for (j = 0; j < 3; j ++)
  462. {
  463. p_ae.winWeight[i][j] = win_weight[i][i];
  464. }
  465. }
  466. p_ae.bright_target = AE_BRIGHT_TARGET_DEFAULT;
  467. p_ae.black_target = 128;
  468. p_ae.compensation = AE_COMPENSATION_DEFAULT;
  469. if(p_exp->cmos_sensor.cmos_isp_ae_init)
  470. {
  471. (*p_exp->cmos_sensor.cmos_isp_ae_init)(&p_ae);
  472. }
  473. isp_histogram_thresh_write (&p_exp->cmos_ae, p_ae.histoBand);
  474. isp_ae_window_weight_write (&p_exp->cmos_ae, p_ae.winWeight);
  475. //isp_histogram_thresh_write (&p_exp->cmos_ae, hist_thresh);
  476. //isp_ae_window_weight_write (&p_exp->cmos_ae, win_weight);
  477. isp_histogram_thread_update (p_exp);
  478. isp_system_ae_bright_target_write (&p_exp->cmos_ae, p_ae.bright_target);
  479. isp_system_ae_black_target_write (&p_exp->cmos_ae, p_ae.black_target);
  480. isp_system_ae_compensation_write (&p_exp->cmos_ae, p_ae.compensation);
  481. isp_system_ae_ev_write (&p_exp->cmos_ae, 0);
  482. isp_auto_exposure_compensation (&p_exp->cmos_ae, p_exp->cmos_ae.histogram.bands);
  483. return 0;
  484. }
  485. int arkn141_isp_ae_run (cmos_exposure_ptr_t p_exp)
  486. {
  487. int ret = isp_auto_exposure_run (&p_exp->cmos_ae, p_exp, 0);
  488. return ret;
  489. }
  490. int arkn141_isp_set_sensor_readout_direction (cmos_exposure_ptr_t p_exp,
  491. unsigned int horz_reverse_direction, unsigned int vert_reverse_direction)
  492. {
  493. if(p_exp && p_exp->cmos_sensor.cmos_sensor_set_readout_direction)
  494. {
  495. return (*p_exp->cmos_sensor.cmos_sensor_set_readout_direction) (horz_reverse_direction, vert_reverse_direction);
  496. }
  497. else
  498. return (-1);
  499. }
  500. unsigned int cmos_calc_inttime_gain (cmos_exposure_t *p_isp_exposure)
  501. {
  502. i64_t inttime_gain;
  503. inttime_gain = p_isp_exposure->cmos_inttime.exposure_ashort;
  504. inttime_gain *= p_isp_exposure->cmos_gain.again;
  505. inttime_gain >>= p_isp_exposure->cmos_gain.again_shift;
  506. inttime_gain *= p_isp_exposure->cmos_gain.dgain;
  507. inttime_gain >>= p_isp_exposure->cmos_gain.dgain_shift;
  508. return (unsigned int)inttime_gain;
  509. }