summaryrefslogtreecommitdiff
path: root/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mxc/capture/mxc_v4l2_capture.c')
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
index 14b73b8c36c0..423575c9d881 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
@@ -325,7 +325,7 @@ static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
- PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
+ cam->v2f.fmt.pix.sizeimage) {
pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
"not allocated,index=%d, length=%d\n", buf->index,
buf->length);
@@ -1133,6 +1133,26 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
case V4L2_MXC_ROTATE_90_LEFT:
tmp_rotation = IPU_ROTATE_90_LEFT;
break;
+ case V4L2_MXC_CAM_ROTATE_NONE:
+ if (vidioc_int_s_ctrl(cam->sensor, c)) {
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_MXC_CAM_ROTATE_VERT_FLIP:
+ if (vidioc_int_s_ctrl(cam->sensor, c)) {
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_MXC_CAM_ROTATE_HORIZ_FLIP:
+ if (vidioc_int_s_ctrl(cam->sensor, c)) {
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_MXC_CAM_ROTATE_180:
+ if (vidioc_int_s_ctrl(cam->sensor, c)) {
+ ret = -EINVAL;
+ }
+ break;
default:
ret = -EINVAL;
}
@@ -1739,12 +1759,13 @@ static int mxc_v4l_close(struct file *file)
err = stop_preview(cam);
cam->overlay_on = false;
}
- if (cam->capture_pid == current->pid) {
- err |= mxc_streamoff(cam);
- wake_up_interruptible(&cam->enc_queue);
- }
if (--cam->open_count == 0) {
+ if (cam->capture_pid == current->pid) {
+ err |= mxc_streamoff(cam);
+ wake_up_interruptible(&cam->enc_queue);
+ }
+
vidioc_int_s_power(cam->sensor, 0);
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi,
false, false);
@@ -2008,6 +2029,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
int index = buf->index;
pr_debug(" case VIDIOC_QBUF\n");
+ up(&cam->busy_lock);
spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
if ((cam->frame[index].buffer.flags & 0x7) ==
V4L2_BUF_FLAG_MAPPED) {
@@ -2033,6 +2055,8 @@ static long mxc_v4l_do_ioctl(struct file *file,
buf->flags = cam->frame[index].buffer.flags;
spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
+ if (down_interruptible(&cam->busy_lock))
+ return -EBUSY;
break;
}
@@ -2049,7 +2073,10 @@ static long mxc_v4l_do_ioctl(struct file *file,
break;
}
+ up(&cam->busy_lock);
retval = mxc_v4l_dqueue(cam, buf);
+ if (down_interruptible(&cam->busy_lock))
+ return -EBUSY;
break;
}
@@ -2660,6 +2687,14 @@ static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
spin_lock_init(&cam->queue_int_lock);
spin_lock_init(&cam->dqueue_int_lock);
+ cam->dummy_frame.vaddress = dma_alloc_coherent(0,
+ SZ_8M, &cam->dummy_frame.paddress,
+ GFP_DMA | GFP_KERNEL);
+ if (cam->dummy_frame.vaddress == 0)
+ pr_err("ERROR: v4l2 capture: Allocate dummy frame "
+ "failed.\n");
+ cam->dummy_frame.buffer.length = SZ_8M;
+
cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
cam->self->module = THIS_MODULE;
sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
@@ -2754,6 +2789,14 @@ static int mxc_v4l2_probe(struct platform_device *pdev)
static int mxc_v4l2_remove(struct platform_device *pdev)
{
cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
+
+ if (cam->dummy_frame.vaddress != 0) {
+ dma_free_coherent(0, cam->dummy_frame.buffer.length,
+ cam->dummy_frame.vaddress,
+ cam->dummy_frame.paddress);
+ cam->dummy_frame.vaddress = 0;
+ }
+
if (cam->open_count) {
pr_err("ERROR: v4l2 capture:camera open "
"-- setting ops to NULL\n");