aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/fimc/fimc_capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/fimc/fimc_capture.c')
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c
index 7d00c8b..f76345c 100644
--- a/drivers/media/video/samsung/fimc/fimc_capture.c
+++ b/drivers/media/video/samsung/fimc/fimc_capture.c
@@ -32,6 +32,10 @@
#include "fimc.h"
+#ifdef CONFIG_MACH_KONA
+extern fimc_is;
+#endif
+
static struct pm_qos_request_list bus_qos_pm_qos_req;
static const struct v4l2_fmtdesc capture_fmts[] = {
@@ -816,6 +820,7 @@ static int fimc_configure_subdev(struct fimc_control *ctrl)
if (!sd) {
fimc_err("%s: v4l2 subdev board registering failed\n",
__func__);
+ return -ENODEV;
}
/* Assign subdev to proper camera device pointer */
ctrl->cam->sd = sd;
@@ -1435,7 +1440,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f)
mbus_fmt = &ctrl->cap->mbus_fmt;
mbus_fmt->width = pix->width;
mbus_fmt->height = pix->height;
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE)
/* Unfortuntely, we have to use pix->field (not pix->priv) since
* pix.field is already used in the below else condtion statement
* (in case that sub-devices are not registered)
@@ -1445,6 +1450,11 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f)
#if defined(CONFIG_MACH_GC1)
mbus_fmt->field = pix->priv;
#endif
+
+#if defined(CONFIG_MACH_KONA)
+ if(!fimc_is)
+ mbus_fmt->field = pix->field;
+#endif
printk(KERN_INFO "%s mbus_fmt->width = %d, height = %d,\n",
__func__,mbus_fmt->width ,mbus_fmt->height);
@@ -1927,6 +1937,8 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b)
case V4L2_PIX_FMT_YVYU: /* fall through */
case V4L2_PIX_FMT_NV16: /* fall through */
case V4L2_PIX_FMT_NV61: /* fall through */
+ fimc_err("%s : w %d h %d \n",__func__,
+ cap->fmt.width, cap->fmt.height);
fimc_info1("%s : 1plane\n", __func__);
ret = fimc_alloc_buffers(ctrl, 1,
cap->fmt.width * cap->fmt.height, SZ_4K, bpp, cap->pktdata_enable, cap->pktdata_size);
@@ -1940,6 +1952,7 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b)
break;
case V4L2_PIX_FMT_NV12:
+
fimc_info1("%s : 2plane for NV12\n", __func__);
ret = fimc_alloc_buffers(ctrl, 2,
cap->fmt.width * cap->fmt.height, SZ_64K, bpp, cap->pktdata_enable, cap->pktdata_size);
@@ -2143,6 +2156,7 @@ int fimc_querybuf_capture(void *fh, struct v4l2_buffer *b)
int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c)
{
struct fimc_control *ctrl = fh;
+ struct v4l2_frmsizeenum cam_frmsize;
int ret = 0;
fimc_dbg("%s\n", __func__);
@@ -2164,6 +2178,24 @@ int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c)
c->value = ctrl->cap->cacheable;
break;
+ case V4L2_CID_CAMERA_SENSOR_OUTPUT_SIZE:
+ cam_frmsize.index = -1;
+ cam_frmsize.discrete.width = 0;
+ cam_frmsize.discrete.height = 0;
+
+ ret = v4l2_subdev_call(ctrl->cam->sd, video, enum_framesizes,
+ &cam_frmsize);
+ if (ret < 0) {
+ dev_err(ctrl->dev, "%s: enum_framesizes failed\n",
+ __func__);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+ } else {
+ c->value = (cam_frmsize.discrete.width << 16)|(cam_frmsize.discrete.height&0xFFFF);
+ dev_err(ctrl->dev,"sensor_output (%d, %d)\n", cam_frmsize.discrete.width, cam_frmsize.discrete.height);
+ }
+ break;
+
default:
/* get ctrl supported by subdev */
/* WriteBack doesn't have subdev_call */
@@ -2248,7 +2280,7 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
clk_disable(ctrl->cam->clk);
fimc->mclk_status = CAM_MCLK_OFF;
ctrl->cam->initialized = 0;
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
/* 100ms: increase delay.
* There are cases that sensor doesn't get revived
* inspite of doing power reset.*/
@@ -2723,7 +2755,7 @@ int fimc_streamon_capture(void *fh)
}
}
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
#ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF
v4l2_subdev_call(cam->sd, video, s_stream,
STREAM_MODE_WAIT_OFF);
@@ -2753,7 +2785,7 @@ int fimc_streamon_capture(void *fh)
cap->fmt.pixelformat);
}
}
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
if (1) {
#else
if (cap->fmt.priv != V4L2_PIX_FMT_MODE_CAPTURE) {
@@ -2930,9 +2962,20 @@ int fimc_streamon_capture(void *fh)
fimc_start_capture(ctrl);
ctrl->status = FIMC_STREAMON;
- if (ctrl->is.sd && fimc_cam_use)
+ if (ctrl->is.sd && fimc_cam_use) {
ret = v4l2_subdev_call(ctrl->is.sd, video, s_stream, 1);
- printk(KERN_INFO "%s-- fimc%d\n", __func__, ctrl->id);
+ if (ret < 0) {
+ dev_err(ctrl->dev, "%s: s_stream failed\n",
+ __func__);
+ if (cam->type == CAM_TYPE_MIPI) {
+ if (cam->id == CAMERA_CSI_C)
+ s3c_csis_stop(CSI_CH_0);
+ else
+ s3c_csis_stop(CSI_CH_1);
+ }
+ return ret;
+ }
+ }
/* if available buffer did not remained */
return 0;
@@ -3135,17 +3178,16 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
int available_bufnum;
size_t length = 0;
int i;
+ unsigned long spin_flags;
if (!cap || !ctrl->cam) {
fimc_err("%s: No capture device.\n", __func__);
return -ENODEV;
}
- mutex_lock(&ctrl->v4l2_lock);
if (pdata->hw_ver >= 0x51) {
if (cap->bufs[idx].state != VIDEOBUF_IDLE) {
fimc_err("%s: invalid state idx : %d\n", __func__, idx);
- mutex_unlock(&ctrl->v4l2_lock);
return -EINVAL;
} else {
if (b->memory == V4L2_MEMORY_USERPTR) {
@@ -3167,7 +3209,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
if (ret < 0) {
fimc_err("%s: _qbuf_dmabuf error.\n",
__func__);
- mutex_unlock(&ctrl->v4l2_lock);
return -ENODEV;
}
for (i = 0; i < vb->num_planes; i++) {
@@ -3181,7 +3222,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
} else {
fimc_err("%s: Wrong sg value.\n",
__func__);
- mutex_unlock(&ctrl->v4l2_lock);
return -ENODEV;
}
}
@@ -3203,6 +3243,7 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
#endif
}
+ spin_lock_irqsave(&ctrl->inq_lock, spin_flags);
fimc_hwset_output_buf_sequence(ctrl, idx, FIMC_FRAMECNT_SEQ_ENABLE);
cap->bufs[idx].state = VIDEOBUF_QUEUED;
if (ctrl->status == FIMC_BUFFER_STOP) {
@@ -3217,13 +3258,12 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
ctrl->restart = true;
}
}
+ spin_unlock_irqrestore(&ctrl->inq_lock, spin_flags);
}
} else {
fimc_add_inqueue(ctrl, b->index);
}
- mutex_unlock(&ctrl->v4l2_lock);
-
if (!cap->cacheable)
return 0;