1
0
Fork 0

[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>
hifive-unleashed-5.1
Sylwester Nawrocki 2012-05-09 11:53:09 -03:00 committed by Mauro Carvalho Chehab
parent dd9c471dd3
commit 9346459ae0
3 changed files with 60 additions and 46 deletions

View File

@ -158,7 +158,7 @@ struct m5mols_version {
* @ffmt: current fmt according to resolution type * @ffmt: current fmt according to resolution type
* @res_type: current resolution type * @res_type: current resolution type
* @irq_waitq: waitqueue for the capture * @irq_waitq: waitqueue for the capture
* @flags: state variable for the interrupt handler * @irq_done: set to 1 in the interrupt handler
* @handle: control handler * @handle: control handler
* @auto_exposure: auto/manual exposure control * @auto_exposure: auto/manual exposure control
* @exposure_bias: exposure compensation control * @exposure_bias: exposure compensation control
@ -167,6 +167,7 @@ struct m5mols_version {
* @auto_iso: auto/manual ISO sensitivity control * @auto_iso: auto/manual ISO sensitivity control
* @iso: manual ISO sensitivity control * @iso: manual ISO sensitivity control
* @auto_wb: auto white balance control * @auto_wb: auto white balance control
* @lock_3a: 3A lock control
* @colorfx: color effect control * @colorfx: color effect control
* @saturation: saturation control * @saturation: saturation control
* @zoom: zoom control * @zoom: zoom control
@ -175,11 +176,9 @@ struct m5mols_version {
* @jpeg_quality: JPEG compression quality control * @jpeg_quality: JPEG compression quality control
* @ver: information of the version * @ver: information of the version
* @cap: the capture mode attributes * @cap: the capture mode attributes
* @power: current sensor's power status
* @isp_ready: 1 when the ISP controller has completed booting * @isp_ready: 1 when the ISP controller has completed booting
* @power: current sensor's power status
* @ctrl_sync: 1 when the control handler state is restored in H/W * @ctrl_sync: 1 when the control handler state is restored in H/W
* @lock_ae: true means the Auto Exposure is locked
* @lock_awb: true means the Aut WhiteBalance is locked
* @resolution: register value for current resolution * @resolution: register value for current resolution
* @mode: register value for current operation mode * @mode: register value for current operation mode
* @set_power: optional power callback to the board code * @set_power: optional power callback to the board code
@ -209,6 +208,7 @@ struct m5mols_info {
}; };
struct v4l2_ctrl *auto_wb; struct v4l2_ctrl *auto_wb;
struct v4l2_ctrl *lock_3a;
struct v4l2_ctrl *colorfx; struct v4l2_ctrl *colorfx;
struct v4l2_ctrl *saturation; struct v4l2_ctrl *saturation;
struct v4l2_ctrl *zoom; struct v4l2_ctrl *zoom;
@ -223,8 +223,6 @@ struct m5mols_info {
unsigned int power:1; unsigned int power:1;
unsigned int ctrl_sync:1; unsigned int ctrl_sync:1;
bool lock_ae;
bool lock_awb;
u8 resolution; u8 resolution;
u8 mode; u8 mode;

View File

@ -106,7 +106,6 @@ static int m5mols_capture_info(struct m5mols_info *info)
int m5mols_start_capture(struct m5mols_info *info) int m5mols_start_capture(struct m5mols_info *info)
{ {
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
u8 resolution = info->resolution;
int ret; int ret;
/* /*
@ -120,16 +119,12 @@ int m5mols_start_capture(struct m5mols_info *info)
if (!ret) if (!ret)
ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG); ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
if (!ret) if (!ret)
ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, resolution); ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
if (!ret)
ret = m5mols_lock_3a(info, true);
if (!ret) if (!ret)
ret = m5mols_set_mode(info, REG_CAPTURE); ret = m5mols_set_mode(info, REG_CAPTURE);
if (!ret) if (!ret)
/* Wait until a frame is captured to ISP internal memory */ /* Wait until a frame is captured to ISP internal memory */
ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000); ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
if (!ret)
ret = m5mols_lock_3a(info, false);
if (ret) if (ret)
return ret; return ret;

View File

@ -139,7 +139,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
if (mode > REG_SCENE_CANDLE) if (mode > REG_SCENE_CANDLE)
return -EINVAL; return -EINVAL;
ret = m5mols_lock_3a(info, false); ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
if (!ret) if (!ret)
ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode); ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
if (!ret) if (!ret)
@ -186,42 +186,34 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
return ret; return ret;
} }
static int m5mols_lock_ae(struct m5mols_info *info, bool lock) static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
{ {
bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
int ret = 0; int ret = 0;
if (info->lock_ae != lock) if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
ret = m5mols_write(&info->sd, AE_LOCK, bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
lock ? REG_AE_LOCK : REG_AE_UNLOCK);
if (!ret)
info->lock_ae = lock;
return ret; ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
} REG_AE_LOCK : REG_AE_UNLOCK);
if (ret)
return ret;
}
static int m5mols_lock_awb(struct m5mols_info *info, bool lock) if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
{ && info->auto_wb->val) {
int ret = 0; bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
if (info->lock_awb != lock) ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
ret = m5mols_write(&info->sd, AWB_LOCK, REG_AWB_LOCK : REG_AWB_UNLOCK);
lock ? REG_AWB_LOCK : REG_AWB_UNLOCK); if (ret)
if (!ret) return ret;
info->lock_awb = lock; }
return ret; if (!info->ver.af || !af_lock)
} return ret;
/* m5mols_lock_3a() - Lock 3A(Auto Exposure, Auto Whitebalance, Auto Focus) */ if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
int m5mols_lock_3a(struct m5mols_info *info, bool lock)
{
int ret;
ret = m5mols_lock_ae(info, lock);
if (!ret)
ret = m5mols_lock_awb(info, lock);
/* Don't need to handle unlocking AF */
if (!ret && is_available_af(info) && lock)
ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP); ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
return ret; return ret;
@ -249,13 +241,13 @@ static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
static int m5mols_set_exposure(struct m5mols_info *info, int exposure) static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
{ {
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
int ret; int ret = 0;
ret = m5mols_lock_ae(info, exposure != V4L2_EXPOSURE_AUTO);
if (ret < 0)
return ret;
if (exposure == V4L2_EXPOSURE_AUTO) { if (exposure == V4L2_EXPOSURE_AUTO) {
/* Unlock auto exposure */
info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
m5mols_3a_lock(info, info->lock_3a);
ret = m5mols_set_metering_mode(info, info->metering->val); ret = m5mols_set_metering_mode(info, info->metering->val);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -429,6 +421,26 @@ static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
if (status != REG_ISO_AUTO) if (status != REG_ISO_AUTO)
info->iso->val = status - 1; info->iso->val = status - 1;
break; break;
case V4L2_CID_3A_LOCK:
ctrl->val &= ~0x7;
ret = m5mols_read_u8(sd, AE_LOCK, &status);
if (ret)
return ret;
if (status)
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
ret = m5mols_read_u8(sd, AWB_LOCK, &status);
if (ret)
return ret;
if (status)
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
if (!status)
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
break;
} }
return ret; return ret;
@ -461,6 +473,10 @@ static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
} }
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_3A_LOCK:
ret = m5mols_3a_lock(info, ctrl);
break;
case V4L2_CID_ZOOM_ABSOLUTE: case V4L2_CID_ZOOM_ABSOLUTE:
ret = m5mols_write(sd, MON_ZOOM, ctrl->val); ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
break; break;
@ -585,6 +601,9 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops, info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80); V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
if (info->handle.error) { if (info->handle.error) {
int ret = info->handle.error; int ret = info->handle.error;
v4l2_err(sd, "Failed to initialize controls: %d\n", ret); v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
@ -597,6 +616,8 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
V4L2_CTRL_FLAG_UPDATE; V4L2_CTRL_FLAG_UPDATE;
v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false); v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER); m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER); m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR); m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);