diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2013-10-22 12:44:51 -0700 |
---|---|---|
committer | Max Krummenacher <max.krummenacher@toradex.com> | 2015-12-26 13:46:19 +0100 |
commit | 7a0e6c99a098a8c3b4ca41631814c5d6675530e7 (patch) | |
tree | 6955df0762ebc4f90949417ea119ed8f8aafd332 | |
parent | 90a9dfc61fcd7dd4ce4c1aa4cbcaf22addc7c0d5 (diff) |
fix camera power down
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
-rw-r--r-- | drivers/media/platform/mxc/capture/mxc_v4l2_capture.c | 41 | ||||
-rw-r--r-- | drivers/media/platform/mxc/capture/mxc_v4l2_capture.h | 2 |
2 files changed, 38 insertions, 5 deletions
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c index ed2d82245407..57f1ad9e28cb 100644 --- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c +++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c @@ -1564,6 +1564,37 @@ static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf) return retval; } +static void power_down_callback(struct work_struct *work) +{ + cam_data *cam = container_of(work, struct _cam_data, power_down_work.work); + + down(&cam->busy_lock); + if (!cam->open_count) { + vidioc_int_s_power(cam->sensor, 0); + cam->power_on = 0; + } + up(&cam->busy_lock); +} + +/* cam->busy_lock is held */ +void power_up_camera(cam_data *cam) +{ + if (cam->power_on) { + cancel_delayed_work(&cam->power_down_work); + return; + } + vidioc_int_s_power(cam->sensor, 1); + vidioc_int_init(cam->sensor); + vidioc_int_dev_init(cam->sensor); + cam->power_on = 1; +} + + +void power_off_camera(cam_data *cam) +{ + schedule_delayed_work(&cam->power_down_work, (HZ * 2)); +} + /*! * V4L interface - open function * @@ -1707,9 +1738,7 @@ static int mxc_v4l_open(struct file *file) cam_fmt.fmt.pix.pixelformat, csi_param); clk_prepare_enable(sensor->sensor_clk); - vidioc_int_s_power(cam->sensor, 1); - vidioc_int_init(cam->sensor); - vidioc_int_dev_init(cam->sensor); + power_up_camera(cam); } file->private_data = dev; @@ -1766,7 +1795,6 @@ static int mxc_v4l_close(struct file *file) } if (--cam->open_count == 0) { - vidioc_int_s_power(cam->sensor, 0); clk_disable_unprepare(sensor->sensor_clk); wait_event_interruptible(cam->power_queue, cam->low_power == false); @@ -1791,6 +1819,7 @@ static int mxc_v4l_close(struct file *file) wake_up_interruptible(&cam->enc_queue); mxc_free_frames(cam); cam->enc_counter++; + power_off_camera(cam); } up(&cam->busy_lock); @@ -2672,6 +2701,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev) init_MUTEX(&cam->param_lock); init_MUTEX(&cam->busy_lock); + INIT_DELAYED_WORK(&cam->power_down_work, power_down_callback); cam->video_dev = video_device_alloc(); if (cam->video_dev == NULL) @@ -2959,7 +2989,8 @@ static int mxc_v4l2_resume(struct platform_device *pdev) wake_up_interruptible(&cam->power_queue); if (cam->sensor && cam->open_count) { - vidioc_int_s_power(cam->sensor, 1); + if ((cam->overlay_on == true) || (cam->capture_on == true)) + vidioc_int_s_power(cam->sensor, 1); if (!cam->mclk_on[cam->mclk_source]) { ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h index f6717752d4b9..d16b40574c63 100644 --- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h +++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h @@ -114,6 +114,8 @@ typedef struct _cam_data { struct semaphore busy_lock; int open_count; + struct delayed_work power_down_work; + int power_on; /* params lock for this camera */ struct semaphore param_lock; |