• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &reg_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, &reg_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, &reg_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 }