diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2013-02-22 16:02:23 -0700 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-02-09 22:42:31 +0100 |
commit | 5fd9a152073bf951ff0a4be84386e4b317c295e0 (patch) | |
tree | 3bc3c1be9b3cd471e4f14b010655eaa99cc6030f /drivers/media/platform | |
parent | 90edae32b29e7be81cc5e7ae2cb72acac41d9bc8 (diff) |
fix camera power down
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
(cherry picked from commit 7a0e6c99a098a8c3b4ca41631814c5d6675530e7)
(cherry picked from commit ede1722ea15228345ab4fe6df3836c4b7447f82d)
Diffstat (limited to 'drivers/media/platform')
-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 49350548ae97..c7711268be6f 100644 --- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c +++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c @@ -1555,6 +1555,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 * @@ -1698,9 +1729,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; @@ -1757,7 +1786,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); @@ -1782,6 +1810,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; |