From fbe9cde1f96b29e5515ded19f89a631113fc5716 Mon Sep 17 00:00:00 2001
From: ddl <ddl@rock-chips.com>
Date: Wed, 16 Jan 2013 16:28:16 +0800
Subject: [PATCH] camera(v0.4.1d): sync pingpong mode

---
 drivers/media/video/rk30_camera_pingpong.c | 57 +++++++++++++++++-----
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/media/video/rk30_camera_pingpong.c b/drivers/media/video/rk30_camera_pingpong.c
index 36bb8c05d0be..d23f2307723f 100755
--- a/drivers/media/video/rk30_camera_pingpong.c
+++ b/drivers/media/video/rk30_camera_pingpong.c
@@ -276,8 +276,20 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 *         1. support rk3066b;
 *v0.4.15:
 *         1. cif work on pingping mode;
+*v0.x.17: 
+*         1. support 8Mega picture;
+*v0.x.19:
+*         1. invalidate the limit which scale is invalidat when scale ratio > 2;
+*v0.x.1b: 1. fix oops bug  when using arm to do scale_crop if preview buffer is not allocated correctly 
+          2. rk_camera_set_fmt will called twice, optimize the procedure. at the first time call ,just to do the sensor init.
+
+*v0.x.1c:
+*         1. fix query resolution error;
+*v0.x.1d: 
+*         1. add mv9335+ov5650 driver;
+*         2. fix 2928 digitzoom erro(arm crop scale) of selected zone;
 */
-#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0x15)
+#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0x1d)
 
 /* limit to rk29 hardware capabilities */
 #define RK_CAM_BUS_PARAM   (SOCAM_MASTER |\
@@ -535,6 +547,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 				RKCAMERA_TR("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
 				BUG();
 			}
+            memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
 			pcdev->vbinfo_count = *count;
         }
 #endif        
@@ -574,8 +587,8 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer
     int ret;
     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
 						icd->current_fmt->host_fmt);
-	if (bytes_per_line < 0)
-		return bytes_per_line;
+	if ((bytes_per_line < 0) || (vb->boff == 0))
+		return -EINVAL;
 
     buf = container_of(vb, struct rk_camera_buffer, vb);
 
@@ -1052,8 +1065,8 @@ static int rk_camera_scale_crop_arm(struct work_struct *work)
     cropW = pcdev->zoominfo.a.c.width;
     cropH = pcdev->zoominfo.a.c.height;
 	
-    psY = psY + (srcW-cropW);
-    psUV = psUV + (srcW-cropW); 
+    psY = psY + (srcW-cropW)/2;
+    psUV = psUV + (srcW-cropW)/2; 
     
     vb_info = pcdev->vbinfo+vb->i; 
     dst_phy = vb_info->phy_addr;
@@ -1200,7 +1213,7 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
 
     
     if(pcdev->stop_cif == true) {
-        RKCAMERA_TR("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
+        //RKCAMERA_TR("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
     	write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
         return IRQ_HANDLED;
     }
@@ -1858,7 +1871,6 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
 	cif_crop = (rect->left+ (rect->top<<16));
 	cif_fs	= ((rect->width ) + (rect->height<<16));
     
-	RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__);
 
 	write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
 	write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
@@ -2018,7 +2030,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
 
 	usr_w = pix->width;
 	usr_h = pix->height;
-    RKCAMERA_TR("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
+    RKCAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
     if (!xlate) {
         dev_err(dev, "Format %x not found\n", pix->pixelformat);
@@ -2030,6 +2042,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
     if (pcdev->icd_init == 0) {
         v4l2_subdev_call(sd,core, init, 0); 
         pcdev->icd_init = 1;
+        return 0;
     }
     stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
     if (stream_on & ENABLE_CAPTURE)
@@ -2189,6 +2202,8 @@ static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
 		ret = true;
 	} else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
 		ret = true;
+	} else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
+		ret = true;
 	}
 
 	if (ret == true)
@@ -2212,8 +2227,7 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
     
 	usr_w = pix->width;
 	usr_h = pix->height;
-	RKCAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
-
+    
     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
     if (!xlate) {
         dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
@@ -2239,16 +2253,31 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
 		return pix->bytesperline;
 
     /* limit to sensor capabilities */
+    memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
 	mf.width	= pix->width;
 	mf.height	= pix->height;
 	mf.field	= pix->field;
 	mf.colorspace	= pix->colorspace;
 	mf.code		= xlate->code;
+    /* ddl@rock-chips.com : It is query max resolution only. */
+    if ((usr_w == 10000) && (usr_h == 10000)) {
+        mf.reserved[6] = 0xfefe5a5a;
+    }
 
 	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
 	if (ret < 0)
 		goto RK_CAMERA_TRY_FMT_END;
-    RKCAMERA_DG("%s mf.width:%d  mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
+    
+	//query resolution.
+	if((usr_w == 10000) && (usr_h == 10000)) {
+		pix->width = mf.width;
+        pix->height = mf.height;
+        RKCAMERA_DG("%s: Sensor resolution : %dx%d\n",__FUNCTION__,mf.width,mf.height);
+		goto RK_CAMERA_TRY_FMT_END;
+	} else {
+        RKCAMERA_DG("%s: user demand: %dx%d  sensor output: %dx%d \n",__FUNCTION__,usr_w,usr_h,mf.width,mf.height);
+	}
+    
 	#ifdef CONFIG_VIDEO_RK29_WORK_IPP       
 	if ((mf.width != usr_w) || (mf.height != usr_h)) {
         bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt); 
@@ -2266,14 +2295,16 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
             pix->width = mf.width;
             pix->height = mf.height;            
 		}
-        
+        /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
+        #if 0     
         if ((mf.width < usr_w) || (mf.height < usr_h)) {
             if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
                 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
                 pix->width = mf.width;
                 pix->height = mf.height;
             }
-        }        
+        }    
+        #endif
 	}
 	#else
 	//need to change according to crop and scale capablicity
-- 
2.34.1