aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/m5mols/m5mols.h24
-rw-r--r--drivers/media/video/m5mols/m5mols_capture.c4
-rw-r--r--drivers/media/video/m5mols/m5mols_controls.c227
-rw-r--r--drivers/media/video/m5mols/m5mols_core.c93
4 files changed, 198 insertions, 150 deletions
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h
index 0acc3d69b851..ed75bbeddc15 100644
--- a/drivers/media/video/m5mols/m5mols.h
+++ b/drivers/media/video/m5mols/m5mols.h
@@ -160,12 +160,12 @@ struct m5mols_version {
160 * @irq_waitq: waitqueue for the capture 160 * @irq_waitq: waitqueue for the capture
161 * @flags: state variable for the interrupt handler 161 * @flags: state variable for the interrupt handler
162 * @handle: control handler 162 * @handle: control handler
163 * @autoexposure: Auto Exposure control 163 * @auto_exposure: auto/manual exposure control
164 * @exposure: Exposure control 164 * @exposure: manual exposure control
165 * @autowb: Auto White Balance control 165 * @autowb: Auto White Balance control
166 * @colorfx: Color effect control 166 * @colorfx: color effect control
167 * @saturation: Saturation control 167 * @saturation: saturation control
168 * @zoom: Zoom control 168 * @zoom: zoom control
169 * @ver: information of the version 169 * @ver: information of the version
170 * @cap: the capture mode attributes 170 * @cap: the capture mode attributes
171 * @power: current sensor's power status 171 * @power: current sensor's power status
@@ -188,12 +188,13 @@ struct m5mols_info {
188 atomic_t irq_done; 188 atomic_t irq_done;
189 189
190 struct v4l2_ctrl_handler handle; 190 struct v4l2_ctrl_handler handle;
191 struct {
192 /* exposure/auto-exposure cluster */
193 struct v4l2_ctrl *auto_exposure;
194 struct v4l2_ctrl *exposure;
195 };
191 196
192 /* Autoexposure/exposure control cluster */ 197 struct v4l2_ctrl *auto_wb;
193 struct v4l2_ctrl *autoexposure;
194 struct v4l2_ctrl *exposure;
195
196 struct v4l2_ctrl *autowb;
197 struct v4l2_ctrl *colorfx; 198 struct v4l2_ctrl *colorfx;
198 struct v4l2_ctrl *saturation; 199 struct v4l2_ctrl *saturation;
199 struct v4l2_ctrl *zoom; 200 struct v4l2_ctrl *zoom;
@@ -277,7 +278,7 @@ int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
277 * The available executing order between each modes are as follows: 278 * The available executing order between each modes are as follows:
278 * PARAMETER <---> MONITOR <---> CAPTURE 279 * PARAMETER <---> MONITOR <---> CAPTURE
279 */ 280 */
280int m5mols_mode(struct m5mols_info *info, u8 mode); 281int m5mols_set_mode(struct m5mols_info *info, u8 mode);
281 282
282int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg); 283int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
283int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout); 284int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
@@ -286,6 +287,7 @@ int m5mols_start_capture(struct m5mols_info *info);
286int m5mols_do_scenemode(struct m5mols_info *info, u8 mode); 287int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
287int m5mols_lock_3a(struct m5mols_info *info, bool lock); 288int m5mols_lock_3a(struct m5mols_info *info, bool lock);
288int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); 289int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
290int m5mols_init_controls(struct v4l2_subdev *sd);
289 291
290/* The firmware function */ 292/* The firmware function */
291int m5mols_update_fw(struct v4l2_subdev *sd, 293int m5mols_update_fw(struct v4l2_subdev *sd,
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c
index ba25e8e2ba4c..4f27aed11722 100644
--- a/drivers/media/video/m5mols/m5mols_capture.c
+++ b/drivers/media/video/m5mols/m5mols_capture.c
@@ -114,7 +114,7 @@ int m5mols_start_capture(struct m5mols_info *info)
114 * format. The frame capture is initiated during switching from Monitor 114 * format. The frame capture is initiated during switching from Monitor
115 * to Capture mode. 115 * to Capture mode.
116 */ 116 */
117 ret = m5mols_mode(info, REG_MONITOR); 117 ret = m5mols_set_mode(info, REG_MONITOR);
118 if (!ret) 118 if (!ret)
119 ret = m5mols_restore_controls(info); 119 ret = m5mols_restore_controls(info);
120 if (!ret) 120 if (!ret)
@@ -124,7 +124,7 @@ int m5mols_start_capture(struct m5mols_info *info)
124 if (!ret) 124 if (!ret)
125 ret = m5mols_lock_3a(info, true); 125 ret = m5mols_lock_3a(info, true);
126 if (!ret) 126 if (!ret)
127 ret = m5mols_mode(info, REG_CAPTURE); 127 ret = m5mols_set_mode(info, REG_CAPTURE);
128 if (!ret) 128 if (!ret)
129 /* Wait until a frame is captured to ISP internal memory */ 129 /* Wait until a frame is captured to ISP internal memory */
130 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000); 130 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c
index d135d20d09cf..464ec0cdfb78 100644
--- a/drivers/media/video/m5mols/m5mols_controls.c
+++ b/drivers/media/video/m5mols/m5mols_controls.c
@@ -169,7 +169,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
169 if (!ret) 169 if (!ret)
170 ret = m5mols_write(sd, AE_ISO, scenemode.iso); 170 ret = m5mols_write(sd, AE_ISO, scenemode.iso);
171 if (!ret) 171 if (!ret)
172 ret = m5mols_mode(info, REG_CAPTURE); 172 ret = m5mols_set_mode(info, REG_CAPTURE);
173 if (!ret) 173 if (!ret)
174 ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr); 174 ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
175 if (!ret) 175 if (!ret)
@@ -181,7 +181,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
181 if (!ret) 181 if (!ret)
182 ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode); 182 ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
183 if (!ret) 183 if (!ret)
184 ret = m5mols_mode(info, REG_MONITOR); 184 ret = m5mols_set_mode(info, REG_MONITOR);
185 185
186 return ret; 186 return ret;
187} 187}
@@ -227,73 +227,194 @@ int m5mols_lock_3a(struct m5mols_info *info, bool lock)
227 return ret; 227 return ret;
228} 228}
229 229
230/* m5mols_set_ctrl() - The main s_ctrl function called by m5mols_set_ctrl() */ 230/* Set exposure/auto exposure cluster */
231int m5mols_set_ctrl(struct v4l2_ctrl *ctrl) 231static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
232{
233 struct v4l2_subdev *sd = &info->sd;
234 int ret;
235
236 ret = m5mols_lock_ae(info, exposure != V4L2_EXPOSURE_AUTO);
237 if (ret < 0)
238 return ret;
239
240 if (exposure == V4L2_EXPOSURE_AUTO) {
241 ret = m5mols_write(sd, AE_MODE, REG_AE_ALL);
242 if (ret < 0)
243 return ret;
244 }
245
246 if (exposure == V4L2_EXPOSURE_MANUAL) {
247 ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
248 if (ret == 0)
249 ret = m5mols_write(sd, AE_MAN_GAIN_MON,
250 info->exposure->val);
251 if (ret == 0)
252 ret = m5mols_write(sd, AE_MAN_GAIN_CAP,
253 info->exposure->val);
254 }
255
256 return ret;
257}
258
259static int m5mols_set_white_balance(struct m5mols_info *info, int awb)
260{
261 int ret;
262
263 ret = m5mols_lock_awb(info, !awb);
264 if (ret < 0)
265 return ret;
266
267 return m5mols_write(&info->sd, AWB_MODE, awb ? REG_AWB_AUTO :
268 REG_AWB_PRESET);
269}
270
271static int m5mols_set_saturation(struct m5mols_info *info, int val)
272{
273 int ret = m5mols_write(&info->sd, MON_CHROMA_LVL, val);
274 if (ret < 0)
275 return ret;
276
277 return m5mols_write(&info->sd, MON_CHROMA_EN, REG_CHROMA_ON);
278}
279
280static int m5mols_set_color_effect(struct m5mols_info *info, int val)
281{
282 unsigned int m_effect = REG_COLOR_EFFECT_OFF;
283 unsigned int p_effect = REG_EFFECT_OFF;
284 unsigned int cfix_r = 0, cfix_b = 0;
285 struct v4l2_subdev *sd = &info->sd;
286 int ret = 0;
287
288 switch (val) {
289 case V4L2_COLORFX_BW:
290 m_effect = REG_COLOR_EFFECT_ON;
291 break;
292 case V4L2_COLORFX_NEGATIVE:
293 p_effect = REG_EFFECT_NEGA;
294 break;
295 case V4L2_COLORFX_EMBOSS:
296 p_effect = REG_EFFECT_EMBOSS;
297 break;
298 case V4L2_COLORFX_SEPIA:
299 m_effect = REG_COLOR_EFFECT_ON;
300 cfix_r = REG_CFIXR_SEPIA;
301 cfix_b = REG_CFIXB_SEPIA;
302 break;
303 }
304
305 ret = m5mols_write(sd, PARM_EFFECT, p_effect);
306 if (!ret)
307 ret = m5mols_write(sd, MON_EFFECT, m_effect);
308
309 if (ret == 0 && m_effect == REG_COLOR_EFFECT_ON) {
310 ret = m5mols_write(sd, MON_CFIXR, cfix_r);
311 if (!ret)
312 ret = m5mols_write(sd, MON_CFIXB, cfix_b);
313 }
314
315 v4l2_dbg(1, m5mols_debug, sd,
316 "p_effect: %#x, m_effect: %#x, r: %#x, b: %#x (%d)\n",
317 p_effect, m_effect, cfix_r, cfix_b, ret);
318
319 return ret;
320}
321
322static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
232{ 323{
233 struct v4l2_subdev *sd = to_sd(ctrl); 324 struct v4l2_subdev *sd = to_sd(ctrl);
234 struct m5mols_info *info = to_m5mols(sd); 325 struct m5mols_info *info = to_m5mols(sd);
326 int ispstate = info->mode;
235 int ret; 327 int ret;
236 328
329 /*
330 * If needed, defer restoring the controls until
331 * the device is fully initialized.
332 */
333 if (!info->isp_ready) {
334 info->ctrl_sync = 0;
335 return 0;
336 }
337
338 ret = m5mols_mode(info, REG_PARAMETER);
339 if (ret < 0)
340 return ret;
341
237 switch (ctrl->id) { 342 switch (ctrl->id) {
238 case V4L2_CID_ZOOM_ABSOLUTE: 343 case V4L2_CID_ZOOM_ABSOLUTE:
239 return m5mols_write(sd, MON_ZOOM, ctrl->val); 344 ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
345 break;
240 346
241 case V4L2_CID_EXPOSURE_AUTO: 347 case V4L2_CID_EXPOSURE_AUTO:
242 ret = m5mols_lock_ae(info, 348 ret = m5mols_set_exposure(info, ctrl->val);
243 ctrl->val == V4L2_EXPOSURE_AUTO ? false : true); 349 break;
244 if (!ret && ctrl->val == V4L2_EXPOSURE_AUTO)
245 ret = m5mols_write(sd, AE_MODE, REG_AE_ALL);
246 if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL) {
247 int val = info->exposure->val;
248 ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
249 if (!ret)
250 ret = m5mols_write(sd, AE_MAN_GAIN_MON, val);
251 if (!ret)
252 ret = m5mols_write(sd, AE_MAN_GAIN_CAP, val);
253 }
254 return ret;
255 350
256 case V4L2_CID_AUTO_WHITE_BALANCE: 351 case V4L2_CID_AUTO_WHITE_BALANCE:
257 ret = m5mols_lock_awb(info, ctrl->val ? false : true); 352 ret = m5mols_set_white_balance(info, ctrl->val);
258 if (!ret) 353 break;
259 ret = m5mols_write(sd, AWB_MODE, ctrl->val ?
260 REG_AWB_AUTO : REG_AWB_PRESET);
261 return ret;
262 354
263 case V4L2_CID_SATURATION: 355 case V4L2_CID_SATURATION:
264 ret = m5mols_write(sd, MON_CHROMA_LVL, ctrl->val); 356 ret = m5mols_set_saturation(info, ctrl->val);
265 if (!ret) 357 break;
266 ret = m5mols_write(sd, MON_CHROMA_EN, REG_CHROMA_ON);
267 return ret;
268 358
269 case V4L2_CID_COLORFX: 359 case V4L2_CID_COLORFX:
270 /* 360 ret = m5mols_set_color_effect(info, ctrl->val);
271 * This control uses two kinds of registers: normal & color. 361 break;
272 * The normal effect belongs to category 1, while the color 362 }
273 * one belongs to category 2. 363 if (ret < 0)
274 * 364 return ret;
275 * The normal effect uses one register: CAT1_EFFECT. 365
276 * The color effect uses three registers: 366 return m5mols_mode(info, ispstate);
277 * CAT2_COLOR_EFFECT, CAT2_CFIXR, CAT2_CFIXB. 367}
278 */ 368
279 ret = m5mols_write(sd, PARM_EFFECT, 369static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
280 ctrl->val == V4L2_COLORFX_NEGATIVE ? REG_EFFECT_NEGA : 370 .s_ctrl = m5mols_s_ctrl,
281 ctrl->val == V4L2_COLORFX_EMBOSS ? REG_EFFECT_EMBOSS : 371};
282 REG_EFFECT_OFF); 372
283 if (!ret) 373int m5mols_init_controls(struct v4l2_subdev *sd)
284 ret = m5mols_write(sd, MON_EFFECT, 374{
285 ctrl->val == V4L2_COLORFX_SEPIA ? 375 struct m5mols_info *info = to_m5mols(sd);
286 REG_COLOR_EFFECT_ON : REG_COLOR_EFFECT_OFF); 376 u16 exposure_max;
287 if (!ret) 377 u16 zoom_step;
288 ret = m5mols_write(sd, MON_CFIXR, 378 int ret;
289 ctrl->val == V4L2_COLORFX_SEPIA ? 379
290 REG_CFIXR_SEPIA : 0); 380 /* Determine the firmware dependant control range and step values */
291 if (!ret) 381 ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
292 ret = m5mols_write(sd, MON_CFIXB, 382 if (ret < 0)
293 ctrl->val == V4L2_COLORFX_SEPIA ? 383 return ret;
294 REG_CFIXB_SEPIA : 0); 384
385 zoom_step = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
386
387 v4l2_ctrl_handler_init(&info->handle, 6);
388
389 info->auto_wb = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
390 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
391
392 info->auto_exposure = v4l2_ctrl_new_std_menu(&info->handle,
393 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
394 1, ~0x03, V4L2_EXPOSURE_AUTO);
395
396 info->exposure = v4l2_ctrl_new_std(&info->handle,
397 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
398 0, exposure_max, 1, exposure_max / 2);
399
400 info->saturation = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
401 V4L2_CID_SATURATION, 1, 5, 1, 3);
402
403 info->zoom = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
404 V4L2_CID_ZOOM_ABSOLUTE, 1, 70, zoom_step, 1);
405
406 info->colorfx = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
407 V4L2_CID_COLORFX, 4, 0, V4L2_COLORFX_NONE);
408
409 if (info->handle.error) {
410 int ret = info->handle.error;
411 v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
412 v4l2_ctrl_handler_free(&info->handle);
295 return ret; 413 return ret;
296 } 414 }
297 415
298 return -EINVAL; 416 v4l2_ctrl_auto_cluster(2, &info->auto_exposure, 1, false);
417 sd->ctrl_handler = &info->handle;
418
419 return 0;
299} 420}
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c
index d718aee01c77..ac7d28b6ddf2 100644
--- a/drivers/media/video/m5mols/m5mols_core.c
+++ b/drivers/media/video/m5mols/m5mols_core.c
@@ -362,14 +362,14 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
362} 362}
363 363
364/** 364/**
365 * m5mols_mode - manage the M-5MOLS's mode 365 * m5mols_set_mode - set the M-5MOLS controller mode
366 * @mode: the required operation mode 366 * @mode: the required operation mode
367 * 367 *
368 * The commands of M-5MOLS are grouped into specific modes. Each functionality 368 * The commands of M-5MOLS are grouped into specific modes. Each functionality
369 * can be guaranteed only when the sensor is operating in mode which which 369 * can be guaranteed only when the sensor is operating in mode which a command
370 * a command belongs to. 370 * belongs to.
371 */ 371 */
372int m5mols_mode(struct m5mols_info *info, u8 mode) 372int m5mols_set_mode(struct m5mols_info *info, u8 mode)
373{ 373{
374 struct v4l2_subdev *sd = &info->sd; 374 struct v4l2_subdev *sd = &info->sd;
375 int ret = -EINVAL; 375 int ret = -EINVAL;
@@ -645,13 +645,13 @@ static int m5mols_start_monitor(struct m5mols_info *info)
645 struct v4l2_subdev *sd = &info->sd; 645 struct v4l2_subdev *sd = &info->sd;
646 int ret; 646 int ret;
647 647
648 ret = m5mols_mode(info, REG_PARAMETER); 648 ret = m5mols_set_mode(info, REG_PARAMETER);
649 if (!ret) 649 if (!ret)
650 ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution); 650 ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
651 if (!ret) 651 if (!ret)
652 ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30); 652 ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
653 if (!ret) 653 if (!ret)
654 ret = m5mols_mode(info, REG_MONITOR); 654 ret = m5mols_set_mode(info, REG_MONITOR);
655 if (!ret) 655 if (!ret)
656 ret = m5mols_restore_controls(info); 656 ret = m5mols_restore_controls(info);
657 657
@@ -674,42 +674,13 @@ static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
674 return ret; 674 return ret;
675 } 675 }
676 676
677 return m5mols_mode(info, REG_PARAMETER); 677 return m5mols_set_mode(info, REG_PARAMETER);
678} 678}
679 679
680static const struct v4l2_subdev_video_ops m5mols_video_ops = { 680static const struct v4l2_subdev_video_ops m5mols_video_ops = {
681 .s_stream = m5mols_s_stream, 681 .s_stream = m5mols_s_stream,
682}; 682};
683 683
684static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
685{
686 struct v4l2_subdev *sd = to_sd(ctrl);
687 struct m5mols_info *info = to_m5mols(sd);
688 int ispstate = info->mode;
689 int ret;
690
691 /*
692 * If needed, defer restoring the controls until
693 * the device is fully initialized.
694 */
695 if (!info->isp_ready) {
696 info->ctrl_sync = 0;
697 return 0;
698 }
699
700 ret = m5mols_mode(info, REG_PARAMETER);
701 if (ret < 0)
702 return ret;
703 ret = m5mols_set_ctrl(ctrl);
704 if (ret < 0)
705 return ret;
706 return m5mols_mode(info, ispstate);
707}
708
709static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
710 .s_ctrl = m5mols_s_ctrl,
711};
712
713static int m5mols_sensor_power(struct m5mols_info *info, bool enable) 684static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
714{ 685{
715 struct v4l2_subdev *sd = &info->sd; 686 struct v4l2_subdev *sd = &info->sd;
@@ -802,52 +773,6 @@ static int m5mols_fw_start(struct v4l2_subdev *sd)
802 return ret; 773 return ret;
803} 774}
804 775
805static int m5mols_init_controls(struct m5mols_info *info)
806{
807 struct v4l2_subdev *sd = &info->sd;
808 u16 max_exposure;
809 u16 step_zoom;
810 int ret;
811
812 /* Determine value's range & step of controls for various FW version */
813 ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
814 if (!ret)
815 step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
816 if (ret)
817 return ret;
818
819 v4l2_ctrl_handler_init(&info->handle, 6);
820 info->autowb = v4l2_ctrl_new_std(&info->handle,
821 &m5mols_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
822 0, 1, 1, 0);
823 info->saturation = v4l2_ctrl_new_std(&info->handle,
824 &m5mols_ctrl_ops, V4L2_CID_SATURATION,
825 1, 5, 1, 3);
826 info->zoom = v4l2_ctrl_new_std(&info->handle,
827 &m5mols_ctrl_ops, V4L2_CID_ZOOM_ABSOLUTE,
828 1, 70, step_zoom, 1);
829 info->exposure = v4l2_ctrl_new_std(&info->handle,
830 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
831 0, max_exposure, 1, (int)max_exposure/2);
832 info->colorfx = v4l2_ctrl_new_std_menu(&info->handle,
833 &m5mols_ctrl_ops, V4L2_CID_COLORFX,
834 4, (1 << V4L2_COLORFX_BW), V4L2_COLORFX_NONE);
835 info->autoexposure = v4l2_ctrl_new_std_menu(&info->handle,
836 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
837 1, 0, V4L2_EXPOSURE_AUTO);
838
839 sd->ctrl_handler = &info->handle;
840 if (info->handle.error) {
841 v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
842 v4l2_ctrl_handler_free(&info->handle);
843 return info->handle.error;
844 }
845
846 v4l2_ctrl_cluster(2, &info->autoexposure);
847
848 return 0;
849}
850
851/** 776/**
852 * m5mols_s_power - Main sensor power control function 777 * m5mols_s_power - Main sensor power control function
853 * 778 *
@@ -868,7 +793,7 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
868 } 793 }
869 794
870 if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) { 795 if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
871 ret = m5mols_mode(info, REG_MONITOR); 796 ret = m5mols_set_mode(info, REG_MONITOR);
872 if (!ret) 797 if (!ret)
873 ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP); 798 ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
874 if (!ret) 799 if (!ret)
@@ -1010,7 +935,7 @@ static int __devinit m5mols_probe(struct i2c_client *client,
1010 935
1011 ret = m5mols_fw_start(sd); 936 ret = m5mols_fw_start(sd);
1012 if (!ret) 937 if (!ret)
1013 ret = m5mols_init_controls(info); 938 ret = m5mols_init_controls(sd);
1014 939
1015 m5mols_sensor_power(info, false); 940 m5mols_sensor_power(info, false);
1016 if (!ret) 941 if (!ret)