mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
media: i2c: lens: fix motor is closed after execute v4l2-ctl
Signed-off-by: Hu Kejun <william.hu@rock-chips.com> Change-Id: I76060b416f4ce84cc1881c952ec1d6ca46eeede2
This commit is contained in:
@@ -65,6 +65,8 @@ struct ces6301_device {
|
||||
struct regulator *supply;
|
||||
struct i2c_client *client;
|
||||
bool power_on;
|
||||
|
||||
atomic_t open_cnt;
|
||||
};
|
||||
|
||||
struct TimeTabel_s {
|
||||
@@ -532,22 +534,24 @@ static int ces6301_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
return rval;
|
||||
}
|
||||
|
||||
ces6301_init(client);
|
||||
if (dev_vcm->power_on && atomic_inc_return(&dev_vcm->open_cnt) == 1) {
|
||||
ces6301_init(client);
|
||||
|
||||
dev_dbg(&client->dev, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = 1000 * ces6301_move_time(dev_vcm, CES6301_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac += CES6301_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac >= dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
dev_dbg(&client->dev, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = 1000 * ces6301_move_time(dev_vcm, CES6301_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac += CES6301_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac >= dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -560,20 +564,22 @@ static int ces6301_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
int dac = dev_vcm->current_lens_pos;
|
||||
unsigned int move_time;
|
||||
|
||||
dev_dbg(&client->dev, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = 1000 * ces6301_move_time(dev_vcm, CES6301_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= 0) {
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= CES6301_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
if (dev_vcm->power_on && atomic_dec_return(&dev_vcm->open_cnt) == 0) {
|
||||
dev_dbg(&client->dev, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = 1000 * ces6301_move_time(dev_vcm, CES6301_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= 0) {
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= CES6301_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac < 0) {
|
||||
dac = 0;
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
if (dac < 0) {
|
||||
dac = 0;
|
||||
ces6301_set_dac(dev_vcm, dac);
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_put(sd->dev);
|
||||
@@ -1053,6 +1059,7 @@ static int ces6301_probe(struct i2c_client *client,
|
||||
ces6301_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
|
||||
ces6301_dev->vcm_movefull_t =
|
||||
ces6301_move_time(ces6301_dev, CES6301_MAX_REG);
|
||||
atomic_set(&ces6301_dev->open_cnt, 0);
|
||||
pm_runtime_enable(&client->dev);
|
||||
|
||||
add_sysfs_interfaces(&client->dev);
|
||||
|
||||
@@ -77,6 +77,8 @@ struct dw9763_device {
|
||||
struct mutex lock;
|
||||
struct regulator *supply;
|
||||
bool power_on;
|
||||
|
||||
atomic_t open_cnt;
|
||||
};
|
||||
|
||||
static inline struct dw9763_device *to_dw9763_vcm(struct v4l2_ctrl *ctrl)
|
||||
@@ -405,23 +407,25 @@ static int dw9763_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
return rval;
|
||||
}
|
||||
|
||||
dw9763_init(client);
|
||||
if (dev_vcm->power_on && atomic_inc_return(&dev_vcm->open_cnt) == 1) {
|
||||
dw9763_init(client);
|
||||
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
|
||||
move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 100);
|
||||
dac += DW9763_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac > dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 100);
|
||||
dac += DW9763_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac > dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -444,27 +448,29 @@ static int dw9763_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
atomic_read(&sd->dev->power.usage_count));
|
||||
#endif
|
||||
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
if (dev_vcm->power_on && atomic_dec_return(&dev_vcm->open_cnt) == 0) {
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
|
||||
dac -= DW9763_GRADUAL_MOVELENS_STEPS;
|
||||
move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= DW9763_GRADUAL_MOVELENS_STEPS) {
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= DW9763_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= DW9763_GRADUAL_MOVELENS_STEPS) {
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= DW9763_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac < DW9763_GRADUAL_MOVELENS_STEPS) {
|
||||
dac = DW9763_GRADUAL_MOVELENS_STEPS / 2;
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
if (dac < DW9763_GRADUAL_MOVELENS_STEPS) {
|
||||
dac = DW9763_GRADUAL_MOVELENS_STEPS / 2;
|
||||
dw9763_set_dac(dev_vcm, dac);
|
||||
}
|
||||
/* set to power down mode */
|
||||
ret = dw9763_write_reg(client, 0x02, 1, 0x01);
|
||||
if (ret)
|
||||
dev_err(&client->dev, "failed to set power down mode!\n");
|
||||
}
|
||||
/* set to power down mode */
|
||||
ret = dw9763_write_reg(client, 0x02, 1, 0x01);
|
||||
if (ret)
|
||||
dev_err(&client->dev, "failed to set power down mode!\n");
|
||||
|
||||
pm_runtime_put(sd->dev);
|
||||
#ifdef CONFIG_PM
|
||||
@@ -926,6 +932,7 @@ static int dw9763_probe(struct i2c_client *client,
|
||||
|
||||
dw9763_dev->vcm_movefull_t =
|
||||
dw9763_move_time(dw9763_dev, DW9763_MAX_REG);
|
||||
atomic_set(&dw9763_dev->open_cnt, 0);
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
|
||||
@@ -85,6 +85,7 @@ struct dw9800v_device {
|
||||
struct i2c_client *client;
|
||||
bool power_on;
|
||||
|
||||
atomic_t open_cnt;
|
||||
};
|
||||
|
||||
static inline struct dw9800v_device *to_dw9800v_vcm(struct v4l2_ctrl *ctrl)
|
||||
@@ -426,24 +427,27 @@ static int dw9800v_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
pm_runtime_put_noidle(sd->dev);
|
||||
return rval;
|
||||
}
|
||||
dw9800v_init(client);
|
||||
|
||||
usleep_range(1000, 1200);
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
if (dev_vcm->power_on && atomic_inc_return(&dev_vcm->open_cnt) == 1) {
|
||||
dw9800v_init(client);
|
||||
|
||||
move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac += DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac >= dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
usleep_range(1000, 1200);
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac <= dev_vcm->current_lens_pos) {
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac += DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac >= dev_vcm->current_lens_pos)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac > dev_vcm->current_lens_pos) {
|
||||
dac = dev_vcm->current_lens_pos;
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -465,23 +469,25 @@ static int dw9800v_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
v4l2_info(sd, "%s: enter, power.usage_count(%d)!\n", __func__,
|
||||
atomic_read(&sd->dev->power.usage_count));
|
||||
#endif
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= DW9800V_GRADUAL_MOVELENS_STEPS) {
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
if (dev_vcm->power_on && atomic_dec_return(&dev_vcm->open_cnt) == 0) {
|
||||
v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
|
||||
__func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
|
||||
move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
|
||||
while (dac >= DW9800V_GRADUAL_MOVELENS_STEPS) {
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
usleep_range(move_time, move_time + 1000);
|
||||
dac -= DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
if (dac <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac < DW9800V_GRADUAL_MOVELENS_STEPS) {
|
||||
dac = DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
if (dac < DW9800V_GRADUAL_MOVELENS_STEPS) {
|
||||
dac = DW9800V_GRADUAL_MOVELENS_STEPS;
|
||||
dw9800v_set_dac(dev_vcm, dac);
|
||||
}
|
||||
/* set to power down mode */
|
||||
dw9800v_write_reg(client, 0x02, 1, 0x01);
|
||||
}
|
||||
/* set to power down mode */
|
||||
dw9800v_write_reg(client, 0x02, 1, 0x01);
|
||||
|
||||
pm_runtime_put(sd->dev);
|
||||
|
||||
@@ -926,6 +932,8 @@ static int dw9800v_probe(struct i2c_client *client,
|
||||
|
||||
dw9800v_dev->vcm_movefull_t =
|
||||
dw9800v_move_time(dw9800v_dev, DW9800V_MAX_REG);
|
||||
atomic_set(&dw9800v_dev->open_cnt, 0);
|
||||
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
@@ -943,14 +951,12 @@ err_power_off:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dw9800v_remove(struct i2c_client *client)
|
||||
static void dw9800v_remove(struct i2c_client *client)
|
||||
{
|
||||
struct dw9800v_device *dw9800v_dev = i2c_get_clientdata(client);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
dw9800v_subdev_cleanup(dw9800v_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw9800v_init(struct i2c_client *client)
|
||||
|
||||
Reference in New Issue
Block a user