return __mt9e013_flush_reg_array(client, &ctrl);
}
-static int wait_power_on_lock(struct v4l2_subdev *sd)
-{
- struct mt9e013_device *dev = to_mt9e013_sensor(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int power_state;
-
- power_state = atomic_read(&dev->power_state);
-
- /* not powered on before, this is not allowed */
- if (power_state == POWER_OFF)
- return -EINVAL;
-
- if (power_state == POWER_ON_INPROGRESS) {
- if (!wait_for_completion_timeout(&dev->power_complete,
- 2 * HZ)) {
- /*
- * this is really abnormal case that power on
- * should not take such long time.
- */
- dev_err(&client->dev, "waiting power up timeout!\n");
- return -EAGAIN;
- }
- power_state = atomic_read(&dev->power_state);
- }
-
- if (power_state == POWER_ON_ERROR) {
- dev_err(&client->dev, "power up err!\n");
- return -EIO;
- }
-
- return 0;
-}
-
static int mt9e013_t_focus_abs(struct v4l2_subdev *sd, s32 value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
static long mt9e013_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
- int ret;
-
switch (cmd) {
case ATOMISP_IOC_S_EXPOSURE:
- ret = wait_power_on_lock(sd);
- if (ret)
- return ret;
-
return mt9e013_s_exposure(sd, (struct atomisp_exposure *)arg);
case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
return mt9e013_g_priv_int_data(sd, arg);
return ret;
}
-static void mt9e013_powerup_work(struct work_struct *work)
-{
- struct mt9e013_device *dev = container_of(work,
- struct mt9e013_device, work);
-
- int ret;
-
- ret = power_up(&dev->sd);
- if (!ret) {
- /* init motor initial position */
- ret = __mt9e013_init(&dev->sd, 0);
- }
-
- if (ret)
- atomic_set(&dev->power_state, POWER_ON_ERROR);
- else
- atomic_set(&dev->power_state, POWER_ON);
-
- complete(&dev->power_complete);
-}
-
static int mt9e013_s_power(struct v4l2_subdev *sd, int on)
{
struct mt9e013_device *dev = to_mt9e013_sensor(sd);
- int ret = 0;
- int power_state;
-
- power_state = atomic_read(&dev->power_state);
+ int ret;
if (on == 0) {
- if (power_state == POWER_OFF)
- return 0;
- else
- ret = wait_power_on_lock(sd);
-
- if (ret == -EAGAIN)
- cancel_work_sync(&dev->work);
-
mt9e013_uninit(sd);
ret = power_down(sd);
- atomic_set(&dev->power_state, POWER_OFF);
+ dev->power = 0;
} else {
- if (power_state == POWER_OFF) {
- atomic_set(&dev->power_state, POWER_ON_INPROGRESS);
- queue_work(dev->work_queue, &dev->work);
+ ret = power_up(sd);
+ if (!ret) {
+ dev->power = 1;
+ /* init motor initial position */
+ return __mt9e013_init(sd, 0);
}
}
if ((octrl == NULL) || (octrl->tweak == NULL))
return -EINVAL;
- ret = wait_power_on_lock(sd);
- if (ret)
- return ret;
-
mutex_lock(&dev->input_lock);
ret = octrl->tweak(sd, ctrl->value);
mutex_unlock(&dev->input_lock);
return ret;
}
- ret = wait_power_on_lock(sd);
- if (ret)
- return ret;
-
mutex_lock(&dev->input_lock);
dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9e013_device *dev = to_mt9e013_sensor(sd);
- ret = wait_power_on_lock(sd);
- if (ret)
- return ret;
-
mutex_lock(&dev->input_lock);
if (enable) {
if (!dev->keeps_focus_pos) {
dev->platform_data = pdata;
- atomic_set(&dev->power_state, POWER_OFF);
- dev->work_queue = create_singlethread_workqueue("mt9e013_work");
- if (dev->work_queue == NULL) {
- v4l2_err(client, "Failed to initialize work queue\n");
- return -EINVAL;
- }
- INIT_WORK(&dev->work, mt9e013_powerup_work);
- init_completion(&dev->power_complete);
-
mutex_lock(&dev->input_lock);
ret = mt9e013_s_power(sd, 1);
return ret;
}
- ret = wait_power_on_lock(sd);
- if (ret)
- goto fail_csi_cfg;
-
ret = dev->platform_data->csi_cfg(sd, 1);
if (ret)
goto fail_csi_cfg;