aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/m5mols
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-05-09 10:53:09 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 13:35:04 -0400
commit9346459ae0317ec6a6930b4566417e033f74a2bf (patch)
treef8ab68ecd9e66fb504ef7483526d27b5d44c2250 /drivers/media/video/m5mols
parentdd9c471dd37c25127236dd36cd1f55c488228cf1 (diff)
[media] m5mols: Add 3A lock control
Add control for locking automatic exposure, focus and white balance adjustments. While at it, tidy up the data structure documentation. 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/video/m5mols')
-rw-r--r--drivers/media/video/m5mols/m5mols.h10
-rw-r--r--drivers/media/video/m5mols/m5mols_capture.c7
-rw-r--r--drivers/media/video/m5mols/m5mols_controls.c89
3 files changed, 60 insertions, 46 deletions
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h
index 00f8d3162bdc..bb589917b65b 100644
--- a/drivers/media/video/m5mols/m5mols.h
+++ b/drivers/media/video/m5mols/m5mols.h
@@ -158,7 +158,7 @@ struct m5mols_version {
158 * @ffmt: current fmt according to resolution type 158 * @ffmt: current fmt according to resolution type
159 * @res_type: current resolution type 159 * @res_type: current resolution type
160 * @irq_waitq: waitqueue for the capture 160 * @irq_waitq: waitqueue for the capture
161 * @flags: state variable for the interrupt handler 161 * @irq_done: set to 1 in the interrupt handler
162 * @handle: control handler 162 * @handle: control handler
163 * @auto_exposure: auto/manual exposure control 163 * @auto_exposure: auto/manual exposure control
164 * @exposure_bias: exposure compensation control 164 * @exposure_bias: exposure compensation control
@@ -167,6 +167,7 @@ struct m5mols_version {
167 * @auto_iso: auto/manual ISO sensitivity control 167 * @auto_iso: auto/manual ISO sensitivity control
168 * @iso: manual ISO sensitivity control 168 * @iso: manual ISO sensitivity control
169 * @auto_wb: auto white balance control 169 * @auto_wb: auto white balance control
170 * @lock_3a: 3A lock control
170 * @colorfx: color effect control 171 * @colorfx: color effect control
171 * @saturation: saturation control 172 * @saturation: saturation control
172 * @zoom: zoom control 173 * @zoom: zoom control
@@ -175,11 +176,9 @@ struct m5mols_version {
175 * @jpeg_quality: JPEG compression quality control 176 * @jpeg_quality: JPEG compression quality control
176 * @ver: information of the version 177 * @ver: information of the version
177 * @cap: the capture mode attributes 178 * @cap: the capture mode attributes
178 * @power: current sensor's power status
179 * @isp_ready: 1 when the ISP controller has completed booting 179 * @isp_ready: 1 when the ISP controller has completed booting
180 * @power: current sensor's power status
180 * @ctrl_sync: 1 when the control handler state is restored in H/W 181 * @ctrl_sync: 1 when the control handler state is restored in H/W
181 * @lock_ae: true means the Auto Exposure is locked
182 * @lock_awb: true means the Aut WhiteBalance is locked
183 * @resolution: register value for current resolution 182 * @resolution: register value for current resolution
184 * @mode: register value for current operation mode 183 * @mode: register value for current operation mode
185 * @set_power: optional power callback to the board code 184 * @set_power: optional power callback to the board code
@@ -209,6 +208,7 @@ struct m5mols_info {
209 }; 208 };
210 struct v4l2_ctrl *auto_wb; 209 struct v4l2_ctrl *auto_wb;
211 210
211 struct v4l2_ctrl *lock_3a;
212 struct v4l2_ctrl *colorfx; 212 struct v4l2_ctrl *colorfx;
213 struct v4l2_ctrl *saturation; 213 struct v4l2_ctrl *saturation;
214 struct v4l2_ctrl *zoom; 214 struct v4l2_ctrl *zoom;
@@ -223,8 +223,6 @@ struct m5mols_info {
223 unsigned int power:1; 223 unsigned int power:1;
224 unsigned int ctrl_sync:1; 224 unsigned int ctrl_sync:1;
225 225
226 bool lock_ae;
227 bool lock_awb;
228 u8 resolution; 226 u8 resolution;
229 u8 mode; 227 u8 mode;
230 228
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c
index 4f27aed11722..cb243bd278ce 100644
--- a/drivers/media/video/m5mols/m5mols_capture.c
+++ b/drivers/media/video/m5mols/m5mols_capture.c
@@ -106,7 +106,6 @@ static int m5mols_capture_info(struct m5mols_info *info)
106int m5mols_start_capture(struct m5mols_info *info) 106int m5mols_start_capture(struct m5mols_info *info)
107{ 107{
108 struct v4l2_subdev *sd = &info->sd; 108 struct v4l2_subdev *sd = &info->sd;
109 u8 resolution = info->resolution;
110 int ret; 109 int ret;
111 110
112 /* 111 /*
@@ -120,16 +119,12 @@ int m5mols_start_capture(struct m5mols_info *info)
120 if (!ret) 119 if (!ret)
121 ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG); 120 ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
122 if (!ret) 121 if (!ret)
123 ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, resolution); 122 ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
124 if (!ret)
125 ret = m5mols_lock_3a(info, true);
126 if (!ret) 123 if (!ret)
127 ret = m5mols_set_mode(info, REG_CAPTURE); 124 ret = m5mols_set_mode(info, REG_CAPTURE);
128 if (!ret) 125 if (!ret)
129 /* Wait until a frame is captured to ISP internal memory */ 126 /* Wait until a frame is captured to ISP internal memory */
130 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000); 127 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
131 if (!ret)
132 ret = m5mols_lock_3a(info, false);
133 if (ret) 128 if (ret)
134 return ret; 129 return ret;
135 130
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c
index 1c3b1e0a7bba..392a028730e2 100644
--- a/drivers/media/video/m5mols/m5mols_controls.c
+++ b/drivers/media/video/m5mols/m5mols_controls.c
@@ -139,7 +139,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
139 if (mode > REG_SCENE_CANDLE) 139 if (mode > REG_SCENE_CANDLE)
140 return -EINVAL; 140 return -EINVAL;
141 141
142 ret = m5mols_lock_3a(info, false); 142 ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
143 if (!ret) 143 if (!ret)
144 ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode); 144 ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
145 if (!ret) 145 if (!ret)
@@ -186,42 +186,34 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
186 return ret; 186 return ret;
187} 187}
188 188
189static int m5mols_lock_ae(struct m5mols_info *info, bool lock) 189static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
190{ 190{
191 bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
191 int ret = 0; 192 int ret = 0;
192 193
193 if (info->lock_ae != lock) 194 if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
194 ret = m5mols_write(&info->sd, AE_LOCK, 195 bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
195 lock ? REG_AE_LOCK : REG_AE_UNLOCK);
196 if (!ret)
197 info->lock_ae = lock;
198 196
199 return ret; 197 ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
200} 198 REG_AE_LOCK : REG_AE_UNLOCK);
201 199 if (ret)
202static int m5mols_lock_awb(struct m5mols_info *info, bool lock) 200 return ret;
203{ 201 }
204 int ret = 0;
205 202
206 if (info->lock_awb != lock) 203 if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
207 ret = m5mols_write(&info->sd, AWB_LOCK, 204 && info->auto_wb->val) {
208 lock ? REG_AWB_LOCK : REG_AWB_UNLOCK); 205 bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
209 if (!ret)
210 info->lock_awb = lock;
211 206
212 return ret; 207 ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
213} 208 REG_AWB_LOCK : REG_AWB_UNLOCK);
209 if (ret)
210 return ret;
211 }
214 212
215/* m5mols_lock_3a() - Lock 3A(Auto Exposure, Auto Whitebalance, Auto Focus) */ 213 if (!info->ver.af || !af_lock)
216int m5mols_lock_3a(struct m5mols_info *info, bool lock) 214 return ret;
217{
218 int ret;
219 215
220 ret = m5mols_lock_ae(info, lock); 216 if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
221 if (!ret)
222 ret = m5mols_lock_awb(info, lock);
223 /* Don't need to handle unlocking AF */
224 if (!ret && is_available_af(info) && lock)
225 ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP); 217 ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
226 218
227 return ret; 219 return ret;
@@ -249,13 +241,13 @@ static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
249static int m5mols_set_exposure(struct m5mols_info *info, int exposure) 241static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
250{ 242{
251 struct v4l2_subdev *sd = &info->sd; 243 struct v4l2_subdev *sd = &info->sd;
252 int ret; 244 int ret = 0;
253
254 ret = m5mols_lock_ae(info, exposure != V4L2_EXPOSURE_AUTO);
255 if (ret < 0)
256 return ret;
257 245
258 if (exposure == V4L2_EXPOSURE_AUTO) { 246 if (exposure == V4L2_EXPOSURE_AUTO) {
247 /* Unlock auto exposure */
248 info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
249 m5mols_3a_lock(info, info->lock_3a);
250
259 ret = m5mols_set_metering_mode(info, info->metering->val); 251 ret = m5mols_set_metering_mode(info, info->metering->val);
260 if (ret < 0) 252 if (ret < 0)
261 return ret; 253 return ret;
@@ -429,6 +421,26 @@ static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
429 if (status != REG_ISO_AUTO) 421 if (status != REG_ISO_AUTO)
430 info->iso->val = status - 1; 422 info->iso->val = status - 1;
431 break; 423 break;
424
425 case V4L2_CID_3A_LOCK:
426 ctrl->val &= ~0x7;
427
428 ret = m5mols_read_u8(sd, AE_LOCK, &status);
429 if (ret)
430 return ret;
431 if (status)
432 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
433
434 ret = m5mols_read_u8(sd, AWB_LOCK, &status);
435 if (ret)
436 return ret;
437 if (status)
438 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
439
440 ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
441 if (!status)
442 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
443 break;
432 } 444 }
433 445
434 return ret; 446 return ret;
@@ -461,6 +473,10 @@ static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
461 } 473 }
462 474
463 switch (ctrl->id) { 475 switch (ctrl->id) {
476 case V4L2_CID_3A_LOCK:
477 ret = m5mols_3a_lock(info, ctrl);
478 break;
479
464 case V4L2_CID_ZOOM_ABSOLUTE: 480 case V4L2_CID_ZOOM_ABSOLUTE:
465 ret = m5mols_write(sd, MON_ZOOM, ctrl->val); 481 ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
466 break; 482 break;
@@ -585,6 +601,9 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
585 info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops, 601 info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
586 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80); 602 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
587 603
604 info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
605 V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
606
588 if (info->handle.error) { 607 if (info->handle.error) {
589 int ret = info->handle.error; 608 int ret = info->handle.error;
590 v4l2_err(sd, "Failed to initialize controls: %d\n", ret); 609 v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
@@ -597,6 +616,8 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
597 V4L2_CTRL_FLAG_UPDATE; 616 V4L2_CTRL_FLAG_UPDATE;
598 v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false); 617 v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
599 618
619 info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
620
600 m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER); 621 m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
601 m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER); 622 m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
602 m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR); 623 m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);