Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331233
b: refs/heads/master
c: 5565a2a
h: refs/heads/master
i:
  331231: 81ee053
v: v3
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Oct 1, 2012
1 parent 17e4d4d commit b3b033a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 05fb4da441c9197a59d537cf7f88522716287c61
refs/heads/master: 5565a2ad47cdd8e697a28137bd8379455667bc1c
18 changes: 11 additions & 7 deletions trunk/drivers/media/i2c/m5mols/m5mols.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ struct m5mols_version {
* @pdata: platform data
* @sd: v4l-subdev instance
* @pad: media pad
* @ffmt: current fmt according to resolution type
* @res_type: current resolution type
* @irq_waitq: waitqueue for the capture
* @irq_done: set to 1 in the interrupt handler
* @handle: control handler
Expand All @@ -174,21 +172,22 @@ struct m5mols_version {
* @wdr: wide dynamic range control
* @stabilization: image stabilization control
* @jpeg_quality: JPEG compression quality control
* @set_power: optional power callback to the board code
* @lock: mutex protecting the structure fields below
* @ffmt: current fmt according to resolution type
* @res_type: current resolution type
* @ver: information of the version
* @cap: the capture mode attributes
* @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
* @resolution: register value for current resolution
* @mode: register value for current operation mode
* @set_power: optional power callback to the board code
*/
struct m5mols_info {
const struct m5mols_platform_data *pdata;
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
int res_type;

wait_queue_head_t irq_waitq;
atomic_t irq_done;
Expand Down Expand Up @@ -216,6 +215,13 @@ struct m5mols_info {
struct v4l2_ctrl *stabilization;
struct v4l2_ctrl *jpeg_quality;

int (*set_power)(struct device *dev, int on);

struct mutex lock;

struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
int res_type;

struct m5mols_version ver;
struct m5mols_capture cap;

Expand All @@ -225,8 +231,6 @@ struct m5mols_info {

u8 resolution;
u8 mode;

int (*set_power)(struct device *dev, int on);
};

#define is_available_af(__info) (__info->ver.af)
Expand Down
77 changes: 51 additions & 26 deletions trunk/drivers/media/i2c/m5mols/m5mols_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,13 +551,18 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
{
struct m5mols_info *info = to_m5mols(sd);
struct v4l2_mbus_framefmt *format;
int ret = 0;

mutex_lock(&info->lock);

format = __find_format(info, fh, fmt->which, info->res_type);
if (!format)
return -EINVAL;
fmt->format = *format;
else
ret = -EINVAL;

fmt->format = *format;
return 0;
mutex_unlock(&info->lock);
return ret;
}

static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
Expand All @@ -578,6 +583,7 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
if (!sfmt)
return 0;

mutex_lock(&info->lock);

format->code = m5mols_default_ffmt[type].code;
format->colorspace = V4L2_COLORSPACE_JPEG;
Expand All @@ -589,7 +595,8 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
info->res_type = type;
}

return 0;
mutex_unlock(&info->lock);
return ret;
}

static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
Expand Down Expand Up @@ -661,20 +668,25 @@ static int m5mols_start_monitor(struct m5mols_info *info)
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
{
struct m5mols_info *info = to_m5mols(sd);
u32 code = info->ffmt[info->res_type].code;
u32 code;
int ret;

if (enable) {
int ret = -EINVAL;
mutex_lock(&info->lock);
code = info->ffmt[info->res_type].code;

if (enable) {
if (is_code(code, M5MOLS_RESTYPE_MONITOR))
ret = m5mols_start_monitor(info);
if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
ret = m5mols_start_capture(info);

return ret;
else
ret = -EINVAL;
} else {
ret = m5mols_set_mode(info, REG_PARAMETER);
}

return m5mols_set_mode(info, REG_PARAMETER);
mutex_unlock(&info->lock);
return ret;
}

static const struct v4l2_subdev_video_ops m5mols_video_ops = {
Expand Down Expand Up @@ -773,6 +785,20 @@ static int m5mols_fw_start(struct v4l2_subdev *sd)
return ret;
}

/* Execute the lens soft-landing algorithm */
static int m5mols_auto_focus_stop(struct m5mols_info *info)
{
int ret;

ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
if (!ret)
ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF);
if (!ret)
ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE,
0xff, -1);
return ret;
}

/**
* m5mols_s_power - Main sensor power control function
*
Expand All @@ -785,29 +811,26 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
struct m5mols_info *info = to_m5mols(sd);
int ret;

mutex_lock(&info->lock);

if (on) {
ret = m5mols_sensor_power(info, true);
if (!ret)
ret = m5mols_fw_start(sd);
return ret;
}
} else {
if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
ret = m5mols_set_mode(info, REG_MONITOR);
if (!ret)
ret = m5mols_auto_focus_stop(info);
if (ret < 0)
v4l2_warn(sd, "Soft landing lens failed\n");
}
ret = m5mols_sensor_power(info, false);

if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
ret = m5mols_set_mode(info, REG_MONITOR);
if (!ret)
ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
if (!ret)
ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
if (!ret)
ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
0xff, -1);
if (ret < 0)
v4l2_warn(sd, "Soft landing lens failed\n");
info->ctrl_sync = 0;
}

ret = m5mols_sensor_power(info, false);
info->ctrl_sync = 0;

mutex_unlock(&info->lock);
return ret;
}

Expand Down Expand Up @@ -912,6 +935,8 @@ static int __devinit m5mols_probe(struct i2c_client *client,
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

init_waitqueue_head(&info->irq_waitq);
mutex_init(&info->lock);

ret = request_irq(client->irq, m5mols_irq_handler,
IRQF_TRIGGER_RISING, MODULE_NAME, sd);
if (ret) {
Expand Down

0 comments on commit b3b033a

Please sign in to comment.