Skip to content

Commit

Permalink
[media] m5mols: Extend the busy wait helper
Browse files Browse the repository at this point in the history
Make m5mols_busy_wait function jiffies based rather than relying
on some fixed number of I2C read iterations while busy waiting
for the device to execute a request. With fixed number of iterations
we may be getting different wait times, depending on the I2C speed.

In some conditions we have to wait even if the I2C communications
fails, in those cases M5MOLS_I2C_RDY_WAIT_MASK should be passed
as the mask argument to m5mols_busy_wait().

Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
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>
  • Loading branch information
HeungJun Kim authored and Mauro Carvalho Chehab committed Dec 30, 2011
1 parent 69eb180 commit 575d625
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
10 changes: 9 additions & 1 deletion drivers/media/video/m5mols/m5mols.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,15 @@ int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
int m5mols_busy(struct v4l2_subdev *sd, u32 reg, u8 value);

int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
int timeout);

/* Mask value for busy waiting until M-5MOLS I2C interface is initialized */
#define M5MOLS_I2C_RDY_WAIT_FL (1 << 16)
/* ISP state transition timeout, in ms */
#define M5MOLS_MODE_CHANGE_TIMEOUT 200
#define M5MOLS_BUSY_WAIT_DEF_TIMEOUT 250

/*
* Mode operation of the M-5MOLS
Expand Down
47 changes: 33 additions & 14 deletions drivers/media/video/m5mols/m5mols_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,19 +272,35 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
return 0;
}

int m5mols_busy(struct v4l2_subdev *sd, u32 reg, u8 mask)
/**
* m5mols_busy_wait - Busy waiting with I2C register polling
* @reg: the I2C_REG() address of an 8-bit status register to check
* @value: expected status register value
* @mask: bit mask for the read status register value
* @timeout: timeout in miliseconds, or -1 for default timeout
*
* The @reg register value is ORed with @mask before comparing with @value.
*
* Return: 0 if the requested condition became true within less than
* @timeout ms, or else negative errno.
*/
int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
int timeout)
{
u8 busy;
int i;
int ret;
int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
unsigned long end = jiffies + msecs_to_jiffies(ms);
u8 status;

for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) {
ret = m5mols_read_u8(sd, reg, &busy);
if (ret < 0)
do {
int ret = m5mols_read_u8(sd, reg, &status);

if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
return ret;
if ((busy & mask) == mask)
if (!ret && (status & mask & 0xff) == (value & 0xff))
return 0;
}
usleep_range(100, 250);
} while (ms > 0 && time_is_after_jiffies(end));

return -EBUSY;
}

Expand Down Expand Up @@ -316,8 +332,10 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
{
int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);

return ret ? ret : m5mols_busy(sd, mode, SYSTEM_SYSMODE);
if (ret < 0)
return ret;
return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
M5MOLS_MODE_CHANGE_TIMEOUT);
}

/**
Expand Down Expand Up @@ -829,9 +847,10 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
if (!ret)
ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
if (!ret)
ret = m5mols_busy(sd, SYSTEM_STATUS, REG_AF_IDLE);
if (!ret)
v4l2_info(sd, "Success soft-landing lens\n");
ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
0xff, -1);
if (ret < 0)
v4l2_warn(sd, "Soft landing lens failed\n");
}

ret = m5mols_sensor_power(info, false);
Expand Down

0 comments on commit 575d625

Please sign in to comment.