hpm_mt9m114.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /*
  2. * Copyright (c) 2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include "hpm_mt9m114.h"
  8. #include "board.h"
  9. #include "hpm_clock_drv.h"
  10. #include <math.h>
  11. #if defined(MT9M114_SHOW_DEBUG_INFO) && MT9M114_SHOW_DEBUG_INFO
  12. #define DEBUG_INFO(...) printf(__VA_ARGS__)
  13. #else
  14. #define DEBUG_INFO(...)
  15. #endif
  16. #if MT9M114_ERROR_ACTION_BLOCK
  17. #define ERROR_ACTION() do { \
  18. DEBUG_INFO("[ERROR]:%s %d\n", __func__, __LINE__); \
  19. for (;;) { \
  20. } \
  21. } while (0)
  22. #else
  23. #define ERROR_ACTION() return (status_fail)
  24. #endif
  25. const mt9m114_reg_t mt9m114_vga[] = {
  26. {MT9M114_VAR_CAM_SENSOR_CFG_Y_ADDR_START, 2, 0x0000}, /* cam_sensor_cfg_y_addr_start = 0 */
  27. {MT9M114_VAR_CAM_SENSOR_CFG_X_ADDR_START, 2, 0x0000}, /* cam_sensor_cfg_x_addr_start = 0 */
  28. {MT9M114_VAR_CAM_SENSOR_CFG_Y_ADDR_END, 2, 0x03CD}, /* cam_sensor_cfg_y_addr_end = 973 */
  29. {MT9M114_VAR_CAM_SENSOR_CFG_X_ADDR_END, 2, 0x050D}, /* cam_sensor_cfg_x_addr_end = 1293 */
  30. {MT9M114_VAR_CAM_SENSOR_CFG_CPIPE_LAST_ROW, 2, 0x01E3}, /* cam_sensor_cfg_cpipe_last_row = 483 */
  31. {MT9M114_VAR_CAM_CROP_WINDOW_WIDTH, 2, 0x0280}, /* cam_crop_window_width = 640 */
  32. {MT9M114_VAR_CAM_CROP_WINDOW_HEIGHT, 2, 0x01E0}, /* cam_crop_window_height = 480 */
  33. {MT9M114_VAR_CAM_OUTPUT_WIDTH, 2, 0x0280}, /* cam_output_width = 640 */
  34. {MT9M114_VAR_CAM_OUTPUT_HEIGHT, 2, 0x01E0}, /* cam_output_height = 480 */
  35. {MT9M114_VAR_CAM_STAT_AWB_CLIP_WINDOW_XEND, 2, 0x027F}, /* cam_stat_awb_clip_window_xend = 639 */
  36. {MT9M114_VAR_CAM_STAT_AWB_CLIP_WINDOW_YEND, 2, 0x01DF}, /* cam_stat_awb_clip_window_yend = 479 */
  37. {MT9M114_VAR_CAM_STAT_AE_INITIAL_WINDOW_XEND, 2, 0x007F}, /* cam_stat_ae_initial_window_xend = 127 */
  38. {MT9M114_VAR_CAM_STAT_AE_INITIAL_WINDOW_YEND, 2, 0x005F}, /* cam_stat_ae_initial_window_yend = 95 */
  39. };
  40. const mt9m114_reg_t mt9m114_init_config[] = {
  41. {MT9M114_REG_LOGICAL_ADDRESS_ACCESS, 2u, 0x1000},
  42. /* PLL Fout = (Fin * 2 * m) / ((n + 1) * (p + 1)) */
  43. {MT9M114_VAR_CAM_SYSCTL_PLL_ENABLE, 1u, 0x01}, /* cam_sysctl_pll_enable = 1 */
  44. {MT9M114_VAR_CAM_SYSCTL_PLL_DIVIDER_M_N, 2u, 0x0120}, /* cam_sysctl_pll_divider_m_n = 288 */
  45. {MT9M114_VAR_CAM_SYSCTL_PLL_DIVIDER_P, 2u, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */
  46. {MT9M114_VAR_CAM_SENSOR_CFG_PIXCLK, 4u, 0x2DC6C00}, /* cam_sensor_cfg_pixclk = 48000000 */
  47. {0x316A, 2, 0x8270}, /* auto txlo_row for hot pixel and linear full well optimization */
  48. {0x316C, 2, 0x8270}, /* auto txlo for hot pixel and linear full well optimization */
  49. {0x3ED0, 2, 0x2305}, /* eclipse setting, ecl range=1, ecl value=2, ivln=3 */
  50. {0x3ED2, 2, 0x77CF}, /* TX_hi=12 */
  51. {0x316E, 2, 0x8202}, /* auto ecl , threshold 2x, ecl=0 at high gain, ecl=2 for low gain */
  52. {0x3180, 2, 0x87FF}, /* enable delta dark */
  53. {0x30D4, 2, 0x6080}, /* disable column correction due to AE oscillation problem */
  54. {0xA802, 2, 0x0008}, /* RESERVED_AE_TRACK_02 */
  55. {0x3E14, 2, 0xFF39}, /* Enabling pixout clamping to VAA during ADC streaming to solve column band issue */
  56. /* APGA */
  57. {0xC95E, 2u, 0x0000},
  58. {MT9M114_VAR_CAM_SENSOR_CFG_ROW_SPEED, 2u, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */
  59. {MT9M114_VAR_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN, 2u, 0x01C3}, /* cam_sensor_cfg_fine_integ_time_min = 451 */
  60. {MT9M114_VAR_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 2u, 0x03BA}, /* cam_sensor_cfg_fine_integ_time_max = 954 */
  61. {MT9M114_VAR_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, 2u, 0x02DE}, /* cam_sensor_cfg_frame_length_lines = 734 */
  62. {MT9M114_VAR_CAM_SENSOR_CFG_LINE_LENGTH_PCK, 2u, 0x04A5}, /* cam_sensor_cfg_line_length_pck = 1189 */
  63. {MT9M114_VAR_CAM_SENSOR_CFG_FINE_CORRECTION, 2u, 0x00E0}, /* cam_sensor_cfg_fine_correction = 224 */
  64. {MT9M114_VAR_CAM_SENSOR_CFG_REG_0_DATA, 2u, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */
  65. {MT9M114_VAR_CAM_SENSOR_CONTROL_READ_MODE, 2u, 0x0332}, /* cam_sensor_control_read_mode = 816 */
  66. {MT9M114_VAR_CAM_CROP_WINDOW_XOFFSET, 2u, 0x0000}, /* cam_crop_window_xoffset = 0 */
  67. {MT9M114_VAR_CAM_CROP_WINDOW_YOFFSET, 2u, 0x0000}, /* cam_crop_window_yoffset = 0 */
  68. {MT9M114_VAR_CAM_CROP_CROPMODE, 1u, 0x03}, /* cam_crop_cropmode = 3 */
  69. {MT9M114_VAR_CAM_AET_AEMODE, 1u, 0x00}, /* cam_aet_aemode = 0 */
  70. {MT9M114_VAR_CAM_AET_MAX_FRAME_RATE, 2u, 0x3700}, /* cam_aet_max_frame_rate = 14080 */
  71. {MT9M114_VAR_CAM_AET_MIN_FRAME_RATE, 2u, 0x3700}, /* cam_aet_min_frame_rate = 14080 */
  72. /* Camera control module */
  73. {0xC892, 2u, 0x0267},
  74. {0xC894, 2u, 0xFF1A},
  75. {0xC896, 2u, 0xFFB3},
  76. {0xC898, 2u, 0xFF80},
  77. {0xC89A, 2u, 0x0166},
  78. {0xC89C, 2u, 0x0003},
  79. {0xC89E, 2u, 0xFF9A},
  80. {0xC8A0, 2u, 0xFEB4},
  81. {0xC8A2, 2u, 0x024D},
  82. {0xC8A4, 2u, 0x01BF},
  83. {0xC8A6, 2u, 0xFF01},
  84. {0xC8A8, 2u, 0xFFF3},
  85. {0xC8AA, 2u, 0xFF75},
  86. {0xC8AC, 2u, 0x0198},
  87. {0xC8AE, 2u, 0xFFFD},
  88. {0xC8B0, 2u, 0xFF9A},
  89. {0xC8B2, 2u, 0xFEE7},
  90. {0xC8B4, 2u, 0x02A8},
  91. {0xC8B6, 2u, 0x01D9},
  92. {0xC8B8, 2u, 0xFF26},
  93. {0xC8BA, 2u, 0xFFF3},
  94. {0xC8BC, 2u, 0xFFB3},
  95. {0xC8BE, 2u, 0x0132},
  96. {0xC8C0, 2u, 0xFFE8},
  97. {0xC8C2, 2u, 0xFFDA},
  98. {0xC8C4, 2u, 0xFECD},
  99. {0xC8C6, 2u, 0x02C2},
  100. {0xC8C8, 2u, 0x0075},
  101. {0xC8CA, 2u, 0x011C},
  102. {0xC8CC, 2u, 0x009A},
  103. {0xC8CE, 2u, 0x0105},
  104. {0xC8D0, 2u, 0x00A4},
  105. {0xC8D2, 2u, 0x00AC},
  106. {0xC8D4, 2u, 0x0A8C},
  107. {0xC8D6, 2u, 0x0F0A},
  108. {0xC8D8, 2u, 0x1964},
  109. /* Automatic White balance */
  110. {MT9M114_VAR_CAM_AWB_AWB_XSHIFT_PRE_ADJ, 2u, 0x0033},
  111. {MT9M114_VAR_CAM_AWB_AWB_YSHIFT_PRE_ADJ, 2u, 0x003C},
  112. {MT9M114_VAR_CAM_AWB_AWB_XSCALE, 1u, 0x03},
  113. {MT9M114_VAR_CAM_AWB_AWB_YSCALE, 1u, 0x02},
  114. {0xC8F4, 2u, 0x0000},
  115. {0xC8F6, 2u, 0x0000},
  116. {0xC8F8, 2u, 0x0000},
  117. {0xC8FA, 2u, 0xE724},
  118. {0xC8FC, 2u, 0x1583},
  119. {0xC8FE, 2u, 0x2045},
  120. {0xC900, 2u, 0x03FF},
  121. {0xC902, 2u, 0x007C},
  122. {0xC90C, 1u, 0x80},
  123. {0xC90D, 1u, 0x80},
  124. {0xC90E, 1u, 0x80},
  125. {0xC90F, 1u, 0x88},
  126. {0xC910, 1u, 0x80},
  127. {0xC911, 1u, 0x80},
  128. /* CPIPE Preference */
  129. {0xC926, 2u, 0x0020},
  130. {0xC928, 2u, 0x009A},
  131. {0xC946, 2u, 0x0070},
  132. {0xC948, 2u, 0x00F3},
  133. {0xC944, 1u, 0x20},
  134. {0xC945, 1u, 0x9A},
  135. {0xC92A, 1u, 0x80},
  136. {0xC92B, 1u, 0x4B},
  137. {0xC92C, 1u, 0x00},
  138. {0xC92D, 1u, 0xFF},
  139. {0xC92E, 1u, 0x3C},
  140. {0xC92F, 1u, 0x02},
  141. {0xC930, 1u, 0x06},
  142. {0xC931, 1u, 0x64},
  143. {0xC932, 1u, 0x01},
  144. {0xC933, 1u, 0x0C},
  145. {0xC934, 1u, 0x3C},
  146. {0xC935, 1u, 0x3C},
  147. {0xC936, 1u, 0x3C},
  148. {0xC937, 1u, 0x0F},
  149. {0xC938, 1u, 0x64},
  150. {0xC939, 1u, 0x64},
  151. {0xC93A, 1u, 0x64},
  152. {0xC93B, 1u, 0x32},
  153. {0xC93C, 2u, 0x0020},
  154. {0xC93E, 2u, 0x009A},
  155. {0xC940, 2u, 0x00DC},
  156. {0xC942, 1u, 0x38},
  157. {0xC943, 1u, 0x30},
  158. {0xC944, 1u, 0x50},
  159. {0xC945, 1u, 0x19},
  160. {0xC94A, 2u, 0x0230},
  161. {0xC94C, 2u, 0x0010},
  162. {0xC94E, 2u, 0x01CD},
  163. {0xC950, 1u, 0x05},
  164. {0xC951, 1u, 0x40},
  165. {0xC87B, 1u, 0x1B},
  166. {0xC890, 2u, 0x0080},
  167. {0xC886, 2u, 0x0100},
  168. {0xC87C, 2u, 0x005A},
  169. {0xB42A, 1u, 0x05},
  170. {0xA80A, 1u, 0x20},
  171. {MT9M114_VAR_CAM_STAT_AWB_CLIP_WINDOW_XSTART, 2u, 0x0000}, /* cam_stat_awb_clip_window_xstart = 0 */
  172. {MT9M114_VAR_CAM_STAT_AWB_CLIP_WINDOW_YSTART, 2u, 0x0000}, /* cam_stat_awb_clip_window_ystart = 0 */
  173. {MT9M114_VAR_CAM_STAT_AE_INITIAL_WINDOW_XSTART, 2u, 0x0000}, /* cam_stat_ae_initial_window_xstart = 0 */
  174. {MT9M114_VAR_CAM_STAT_AE_INITIAL_WINDOW_YSTART, 2u, 0x0000}, /* cam_stat_ae_initial_window_ystart = 0 */
  175. {MT9M114_REG_PAD_SLEW, 2u, 0x0777}, /* Pad slew rate */
  176. {MT9M114_VAR_CAM_OUTPUT_FORMAT_YUV, 2u, 0x0038}, /* Must set cam_output_format_yuv_clip for CSI */
  177. };
  178. hpm_stat_t mt9m114_read_register(camera_context_t *context, uint32_t reg, uint32_t reg_size, void *value)
  179. {
  180. hpm_stat_t status;
  181. uint16_t subaddr = ((reg & 0xff) << 8) | ((reg & 0xff00) >> 8);
  182. uint8_t data[4];
  183. uint8_t i = 0;
  184. status = i2c_master_address_read(context->ptr, context->i2c_device_addr, \
  185. (uint8_t *)&subaddr, MT9M114_REG_ADDR_LEN, \
  186. data, reg_size);
  187. if (status_success == status) {
  188. while (reg_size--) {
  189. ((uint8_t *)value)[i++] = data[reg_size];
  190. }
  191. }
  192. return status;
  193. }
  194. hpm_stat_t mt9m114_write_register(camera_context_t *context, uint32_t reg, uint32_t reg_size, uint32_t value)
  195. {
  196. uint16_t subaddr = ((reg & 0xff) << 8) | ((reg & 0xff00) >> 8);
  197. uint8_t data[4];
  198. uint8_t i;
  199. i = reg_size;
  200. while (i--) {
  201. data[i] = (uint8_t)value;
  202. value >>= 8;
  203. }
  204. return i2c_master_address_write(context->ptr, context->i2c_device_addr, \
  205. (uint8_t *)&subaddr, MT9M114_REG_ADDR_LEN, \
  206. data, reg_size);
  207. }
  208. hpm_stat_t mt9m114_modify_register(camera_context_t *context, uint32_t reg, uint32_t reg_size, uint32_t mask, uint32_t value)
  209. {
  210. hpm_stat_t status;
  211. uint32_t reg_value;
  212. status = mt9m114_read_register(context, reg, reg_size, &reg_value);
  213. if (status_success != status) {
  214. return status;
  215. }
  216. reg_value = (reg_value & ~(mask)) | (value & mask);
  217. return mt9m114_write_register(context, reg, reg_size, reg_value);
  218. }
  219. hpm_stat_t mt9m114_multiwrite(camera_context_t *context, const mt9m114_reg_t regs[], uint32_t num)
  220. {
  221. hpm_stat_t status = status_success;
  222. for (uint32_t i = 0; i < num; i++) {
  223. status = mt9m114_write_register(context, regs[i].reg, regs[i].size, regs[i].value);
  224. if (status_success != status) {
  225. ERROR_ACTION();
  226. }
  227. }
  228. return status;
  229. }
  230. hpm_stat_t mt9m114_host_command(camera_context_t *context, uint16_t command)
  231. {
  232. if (mt9m114_write_register(context, MT9M114_REG_COMMAND_REGISTER, 2, (command | MT9M114_COMMAND_OK)) != 0) {
  233. return status_fail;
  234. }
  235. for (int i = 0; i < MT9M114_HOST_CMD_TIMEOUT; i++, context->delay_ms(1)) {
  236. uint16_t reg_data;
  237. if (mt9m114_read_register(context, MT9M114_REG_COMMAND_REGISTER, 2, &reg_data) != 0) {
  238. return status_fail;
  239. }
  240. if ((reg_data & command) == 0) {
  241. return (reg_data & MT9M114_COMMAND_OK) ? 0 : -1;
  242. }
  243. if (i == (MT9M114_HOST_CMD_TIMEOUT - 1)) {
  244. return status_fail;
  245. }
  246. }
  247. return status_success;
  248. }
  249. hpm_stat_t mt9m114_refresh(camera_context_t *context)
  250. {
  251. hpm_stat_t ret = mt9m114_host_command(context, MT9M114_COMMAND_REFRESH);
  252. if (ret != status_success) {
  253. return ret;
  254. }
  255. uint8_t reg_data;
  256. if (mt9m114_read_register(context, MT9M114_VAR_SEQ_ERROR_CODE, 1, &reg_data) != 0) {
  257. return status_fail;
  258. }
  259. return reg_data == 0 ? status_success : status_fail;
  260. }
  261. hpm_stat_t mt9m114_get_current_state(camera_context_t *context, uint8_t *state)
  262. {
  263. return mt9m114_read_register(context, MT9M114_VAR_SYSMGR_CURRENT_STATE, 1u, state);
  264. }
  265. hpm_stat_t mt9m114_software_reset(camera_context_t *context)
  266. {
  267. hpm_stat_t status;
  268. uint16_t value;
  269. assert(context->delay_ms != NULL);
  270. mt9m114_modify_register(context, MT9M114_REG_RESET_AND_MISC_CONTROL, 2, 0x01, 0x01);
  271. context->delay_ms(1);
  272. mt9m114_modify_register(context, MT9M114_REG_RESET_AND_MISC_CONTROL, 2, 0x01, 0x00);
  273. context->delay_ms(50);
  274. /* forever loop if softreset is not done. Loop until reg 0x80's bit 1 is 0 */
  275. while (1) {
  276. status = mt9m114_read_register(context, MT9M114_REG_COMMAND_REGISTER, 2u, &value);
  277. if (status != status_success) {
  278. ERROR_ACTION();
  279. }
  280. if (!(value & MT9M114_COMMAND_SET_STATE)) {
  281. DEBUG_INFO("[Camera]:sw reset finish\n");
  282. break;
  283. }
  284. }
  285. return status_success;
  286. }
  287. hpm_stat_t mt9m114_setstate(camera_context_t *context, uint16_t next_state)
  288. {
  289. uint16_t value;
  290. hpm_stat_t status = status_success;
  291. /* Set the desired next state. */
  292. status = mt9m114_write_register(context, MT9M114_VAR_SYSMGR_NEXT_STATE, 1, next_state);
  293. if (status_success != status) {
  294. ERROR_ACTION();
  295. }
  296. /* Check that the FW is ready to accept a new command. */
  297. context->delay_ms(1);
  298. while (1) {
  299. status = mt9m114_read_register(context, MT9M114_REG_COMMAND_REGISTER, 2u, &value);
  300. if (status_success != status) {
  301. ERROR_ACTION();
  302. }
  303. if (!(value & MT9M114_COMMAND_SET_STATE)) {
  304. break;
  305. }
  306. DEBUG_INFO("[Camera]:Set State cmd bit is already set\n");
  307. }
  308. DEBUG_INFO("[Camera]:Issue the Set State command 0x%x\n", next_state);
  309. /* Issue the Set State command. */
  310. return mt9m114_host_command(context, MT9M114_COMMAND_SET_STATE);
  311. }
  312. hpm_stat_t mt9m114_set_pixformat(camera_context_t *context, display_pixel_format_t pixformat)
  313. {
  314. uint16_t reg = 0;
  315. switch (pixformat) {
  316. case display_pixel_format_yuv422:
  317. reg = MT9M114_OUTPUT_FORMAT_YUV | MT9M114_OUTPUT_FORMAT_SWAP_BYTES;
  318. break;
  319. case display_pixel_format_rgb565:
  320. reg = MT9M114_OUTPUT_FORMAT_RGB | MT9M114_OUTPUT_FORMAT_RGB565 | MT9M114_OUTPUT_FORMAT_SWAP_BYTES;
  321. break;
  322. default:
  323. return status_invalid_argument;
  324. }
  325. if (mt9m114_write_register(context, MT9M114_VAR_CAM_OUTPUT_FORMAT, 2, reg) != 0) {
  326. return status_fail;
  327. }
  328. return mt9m114_setstate(context, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
  329. }
  330. hpm_stat_t mt9m114_set_framerate(camera_context_t *context, int framerate)
  331. {
  332. if (mt9m114_write_register(context, MT9M114_VAR_CAM_AET_MAX_FRAME_RATE, 2, framerate * 256) != 0) {
  333. return status_fail;
  334. }
  335. if (mt9m114_write_register(context, MT9M114_VAR_CAM_AET_MIN_FRAME_RATE, 2, framerate * 128) != 0) {
  336. return status_fail;
  337. }
  338. return mt9m114_setstate(context, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
  339. }
  340. hpm_stat_t mt9m114_set_brightness(camera_context_t *context, int level) /* -16 to +16 */
  341. {
  342. int new_level = level * 2;
  343. if ((new_level < -32) || (32 < new_level)) {
  344. return status_fail;
  345. }
  346. if (mt9m114_write_register(context, MT9M114_VAR_UVC_BRIGHTNESS_CONTROL, 2, new_level + 55) != 0) {
  347. return status_fail;
  348. }
  349. return mt9m114_refresh(context);
  350. }
  351. hpm_stat_t mt9m114_start(camera_context_t *handle)
  352. {
  353. return mt9m114_setstate(handle, MT9M114_SYS_STATE_START_STREAMING);
  354. }
  355. hpm_stat_t mt9m114_stop(camera_context_t *handle)
  356. {
  357. return mt9m114_setstate(handle, MT9M114_SYS_STATE_ENTER_SUSPEND);
  358. }
  359. hpm_stat_t mt9m114_check_chip_id(camera_context_t *handle)
  360. {
  361. hpm_stat_t status = status_success;
  362. uint16_t chip_id;
  363. status = mt9m114_read_register(handle, MT9M114_REG_CHIP_ID, 2u, &chip_id);
  364. if (status_success != status) {
  365. DEBUG_INFO("[ERROR] read MT9M114 chipid register failed %d\n", status);
  366. return status_fail;
  367. }
  368. if (MT9M114_CHIP_ID != chip_id) {
  369. DEBUG_INFO("[ERROR] chipid is %04x(expect %04x)\n", chip_id, MT9M114_CHIP_ID);
  370. return status_fail;
  371. }
  372. return status_success;
  373. }
  374. hpm_stat_t mt9m114_enable_mono(camera_context_t *handle, bool enable)
  375. {
  376. uint16_t value = 0;
  377. mt9m114_read_register(handle, 0x332E, 2u, &value);
  378. if (enable)
  379. value = value | 0x0004;
  380. else
  381. value = value & 0xFFFB;
  382. mt9m114_write_register(handle, 0x332E, 2u, value);
  383. return 0;
  384. }
  385. hpm_stat_t mt9m114_init(camera_context_t *context, camera_config_t *camera_config)
  386. {
  387. hpm_stat_t status = status_success;
  388. /* set init configs */
  389. DEBUG_INFO("[Camera]:set frame per sec ...\n");
  390. mt9m114_multiwrite(context, mt9m114_init_config, ARRAY_SIZE(mt9m114_init_config));
  391. /* Pixel format. */
  392. DEBUG_INFO("[Camera]:set format...\n");
  393. status = mt9m114_set_pixformat(context, camera_config->pixel_format);
  394. if (status_success != status) {
  395. DEBUG_INFO("[ERROR] set output format %d\n", status);
  396. ERROR_ACTION();
  397. }
  398. /* set cam port output control... */
  399. DEBUG_INFO("[Camera]:set cam port output control...\n");
  400. status = mt9m114_write_register(context, MT9M114_VAR_CAM_PORT_OUTPUT_CONTROL, 2, 0x8008);
  401. if (status_success != status) {
  402. DEBUG_INFO("[ERROR] set cam port output control... %d\n", status);
  403. ERROR_ACTION();
  404. }
  405. /* set resolution... */
  406. DEBUG_INFO("[Camera]:set resolution...\n");
  407. status = mt9m114_multiwrite(context, mt9m114_vga, ARRAY_SIZE(mt9m114_vga));
  408. if (status_success != status) {
  409. DEBUG_INFO("[ERROR] set resolution... %d\n", status);
  410. ERROR_ACTION();
  411. }
  412. /* set change command */
  413. DEBUG_INFO("[Camera]:set change command...\n");
  414. status = mt9m114_setstate(context, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
  415. if (status_success != status) {
  416. DEBUG_INFO("[ERROR] set change command... %d\n", status);
  417. ERROR_ACTION();
  418. }
  419. DEBUG_INFO("MT9M114 init done\n");
  420. return status;
  421. }