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