aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-04-09 12:51:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 13:32:14 -0400
commit3c5da0baaada8e8c7176a3e310dfdb4362f74d80 (patch)
tree502bd796f303fcb4a35f0aac2a2be71e81d263ce /drivers/media
parent91f4eb0acb99a34e4b7fe9aee65ff9790be523c0 (diff)
[media] m5mols: Refactored controls handling
This patch is a prerequisite for the new controls addition. It consolidates the control handling code, which is moved to m5mols_controls.c and staticized. The controls initialization is reordered to better reflect the control clusters and make the diffs smaller when new controls are added. To make the code easier to follow when more controls is added use separate set function for each control. Rewrite the image effect registers handling. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
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)