Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285408
b: refs/heads/master
c: ce808a4
h: refs/heads/master
v: v3
  • Loading branch information
HeungJun Kim authored and Mauro Carvalho Chehab committed Dec 30, 2011
1 parent df05f08 commit a335988
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 75 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: 575d6252a715c599964ec6ec06428e6362c0633e
refs/heads/master: ce808a478ae5b79e52ea170b35c459829296330f
9 changes: 2 additions & 7 deletions trunk/drivers/media/video/m5mols/m5mols.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ struct m5mols_version {
* @ffmt: current fmt according to resolution type
* @res_type: current resolution type
* @irq_waitq: waitqueue for the capture
* @work_irq: workqueue for the IRQ
* @flags: state variable for the interrupt handler
* @handle: control handler
* @autoexposure: Auto Exposure control
Expand All @@ -180,7 +179,6 @@ struct m5mols_version {
* @lock_ae: true means the Auto Exposure is locked
* @lock_awb: true means the Aut WhiteBalance is locked
* @resolution: register value for current resolution
* @interrupt: register value for current interrupt status
* @mode: register value for current operation mode
* @mode_save: register value for current operation mode for saving
* @set_power: optional power callback to the board code
Expand All @@ -192,8 +190,7 @@ struct m5mols_info {
struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
int res_type;
wait_queue_head_t irq_waitq;
struct work_struct work_irq;
unsigned long flags;
atomic_t irq_done;

struct v4l2_ctrl_handler handle;
/* Autoexposure/exposure control cluster */
Expand All @@ -213,14 +210,11 @@ struct m5mols_info {
bool lock_ae;
bool lock_awb;
u8 resolution;
u8 interrupt;
u8 mode;
u8 mode_save;
int (*set_power)(struct device *dev, int on);
};

#define ST_CAPT_IRQ 0

#define is_powered(__info) (__info->power)
#define is_ctrl_synced(__info) (__info->ctrl_sync)
#define is_available_af(__info) (__info->ver.af)
Expand Down Expand Up @@ -290,6 +284,7 @@ int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
int m5mols_mode(struct m5mols_info *info, u8 mode);

int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
int m5mols_sync_controls(struct m5mols_info *info);
int m5mols_start_capture(struct m5mols_info *info);
int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
Expand Down
34 changes: 5 additions & 29 deletions trunk/drivers/media/video/m5mols/m5mols_capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,6 @@
#include "m5mols.h"
#include "m5mols_reg.h"

static int m5mols_capture_error_handler(struct m5mols_info *info,
int timeout)
{
int ret;

/* Disable all interrupts and clear relevant interrupt staus bits */
ret = m5mols_write(&info->sd, SYSTEM_INT_ENABLE,
info->interrupt & ~(REG_INT_CAPTURE));
if (ret)
return ret;

if (timeout == 0)
return -ETIMEDOUT;

return 0;
}
/**
* m5mols_read_rational - I2C read of a rational number
*
Expand Down Expand Up @@ -121,7 +105,6 @@ int m5mols_start_capture(struct m5mols_info *info)
{
struct v4l2_subdev *sd = &info->sd;
u8 resolution = info->resolution;
int timeout;
int ret;

/*
Expand All @@ -142,14 +125,9 @@ int m5mols_start_capture(struct m5mols_info *info)
ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE);
if (!ret)
ret = m5mols_mode(info, REG_CAPTURE);
if (!ret) {
if (!ret)
/* Wait for capture interrupt, after changing capture mode */
timeout = wait_event_interruptible_timeout(info->irq_waitq,
test_bit(ST_CAPT_IRQ, &info->flags),
msecs_to_jiffies(2000));
if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags))
ret = m5mols_capture_error_handler(info, timeout);
}
ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
if (!ret)
ret = m5mols_lock_3a(info, false);
if (ret)
Expand All @@ -175,15 +153,13 @@ int m5mols_start_capture(struct m5mols_info *info)
ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
if (!ret) {
/* Wait for the capture completion interrupt */
timeout = wait_event_interruptible_timeout(info->irq_waitq,
test_bit(ST_CAPT_IRQ, &info->flags),
msecs_to_jiffies(2000));
if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags)) {
ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
if (!ret) {
ret = m5mols_capture_info(info);
if (!ret)
v4l2_subdev_notify(sd, 0, &info->cap.total);
}
}

return m5mols_capture_error_handler(info, timeout);
return ret;
}
56 changes: 18 additions & 38 deletions trunk/drivers/media/video/m5mols/m5mols_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,20 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
return ret;
}

int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
{
struct m5mols_info *info = to_m5mols(sd);

int ret = wait_event_interruptible_timeout(info->irq_waitq,
atomic_add_unless(&info->irq_done, -1, 0),
msecs_to_jiffies(timeout));
if (ret <= 0)
return ret ? ret : -ETIMEDOUT;

return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
}

/**
* m5mols_reg_mode - Write the mode and check busy status
*
Expand Down Expand Up @@ -889,46 +903,12 @@ static const struct v4l2_subdev_ops m5mols_ops = {
.video = &m5mols_video_ops,
};

static void m5mols_irq_work(struct work_struct *work)
{
struct m5mols_info *info =
container_of(work, struct m5mols_info, work_irq);
struct v4l2_subdev *sd = &info->sd;
u8 reg;
int ret;

if (!is_powered(info) ||
m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt))
return;

switch (info->interrupt & REG_INT_MASK) {
case REG_INT_AF:
if (!is_available_af(info))
break;
ret = m5mols_read_u8(sd, AF_STATUS, &reg);
v4l2_dbg(2, m5mols_debug, sd, "AF %s\n",
reg == REG_AF_FAIL ? "Failed" :
reg == REG_AF_SUCCESS ? "Success" :
reg == REG_AF_IDLE ? "Idle" : "Busy");
break;
case REG_INT_CAPTURE:
if (!test_and_set_bit(ST_CAPT_IRQ, &info->flags))
wake_up_interruptible(&info->irq_waitq);

v4l2_dbg(2, m5mols_debug, sd, "CAPTURE\n");
break;
default:
v4l2_dbg(2, m5mols_debug, sd, "Undefined: %02x\n", reg);
break;
};
}

static irqreturn_t m5mols_irq_handler(int irq, void *data)
{
struct v4l2_subdev *sd = data;
struct m5mols_info *info = to_m5mols(sd);
struct m5mols_info *info = to_m5mols(data);

schedule_work(&info->work_irq);
atomic_set(&info->irq_done, 1);
wake_up_interruptible(&info->irq_waitq);

return IRQ_HANDLED;
}
Expand Down Expand Up @@ -987,14 +967,14 @@ static int __devinit m5mols_probe(struct i2c_client *client,
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

init_waitqueue_head(&info->irq_waitq);
INIT_WORK(&info->work_irq, m5mols_irq_work);
ret = request_irq(client->irq, m5mols_irq_handler,
IRQF_TRIGGER_RISING, MODULE_NAME, sd);
if (ret) {
dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
goto out_me;
}
info->res_type = M5MOLS_RESTYPE_MONITOR;

return 0;
out_me:
media_entity_cleanup(&sd->entity);
Expand Down

0 comments on commit a335988

Please sign in to comment.