summaryrefslogtreecommitdiff
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorTroy Kisky <troy.kisky@boundarydevices.com>2013-02-22 16:02:23 -0700
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-02-09 22:42:31 +0100
commit5fd9a152073bf951ff0a4be84386e4b317c295e0 (patch)
tree3bc3c1be9b3cd471e4f14b010655eaa99cc6030f /drivers/media/platform
parent90edae32b29e7be81cc5e7ae2cb72acac41d9bc8 (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.c41
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.h2
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;