camera: camera add support sensor callback which sensor driver can do something after...
authorddl <ddl@rockchip.com>
Thu, 26 May 2011 08:29:31 +0000 (16:29 +0800)
committerddl <ddl@rockchip.com>
Thu, 26 May 2011 08:38:52 +0000 (16:38 +0800)
arch/arm/mach-rk29/include/mach/rk29_camera.h
drivers/media/video/mt9p111.c
drivers/media/video/rk29_camera_oneframe.c

index bbbdb010fba21ab030d3605733850c431842ad09..599b54cfc542ee6ac8f076fcc7b6e3bdcaa2eb85 100755 (executable)
 #define RK29_CAM_SUBDEV_ACTIVATE            0x00
 #define RK29_CAM_SUBDEV_DEACTIVATE          0x01
 #define RK29_CAM_SUBDEV_IOREQUEST                      0x02
-
+#define RK29_CAM_SUBDEV_CB_REGISTER         0x03
 
 enum rk29camera_ioctrl_cmd
 {
@@ -181,5 +181,9 @@ struct rk29camera_platform_ioctl_cb {
     int (*sensor_flash_cb)(struct rk29camera_gpio_res *res, int on);    
 };
 
+typedef struct rk29_camera_sensor_cb {
+    int (*sensor_cb)(void *arg); 
+}rk29_camera_sensor_cb_s;
+
 #endif /* __ASM_ARCH_CAMERA_H_ */
 
index 978faf10701f85cbbc5bb3cb14fab2115134c58f..579004414ecfac1700569129ff9e930d0ccd7f48 100755 (executable)
@@ -4242,6 +4242,11 @@ sensor_video_probe_err:
 
     return ret;
 }
+static int sensor_cb(struct videobuf_buffer *vb)
+{
+
+    return 0;
+}
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
        struct i2c_client *client = sd->priv;
@@ -4291,6 +4296,12 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
             #endif
                        break;
                }
+        case RK29_CAM_SUBDEV_CB_REGISTER:
+        {
+            icd_cb = (rk29_camera_sensor_cb_s*)arg;
+            icd_cb->sensor_cb = sensor_cb;
+            break;    
+        }
                default:
                {
                        SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
index 39f0b2411758bb203f2935066e6db16b9864cdbe..065b5c1d35bf0adffd4e412a69455f67505ecb2c 100755 (executable)
@@ -125,6 +125,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define read_grf_reg(addr) __raw_readl(addr+RK29_GRF_BASE)
 #define mask_grf_reg(addr, msk, val)    write_vip_reg(addr, (val)|((~(msk))&read_vip_reg(addr)))
 
+#define CAM_WORKQUEUE_IS_EN()   ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
+                                  || (pcdev->icd_cb.sensor_cb))
+#define CAM_IPPWORK_IS_EN()     ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))                                  
+
 //Configure Macro
 #define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 1)
 
@@ -243,6 +247,8 @@ struct rk29_camera_dev
        unsigned int camera_work_count;
        struct hrtimer fps_timer;
        struct work_struct camera_reinit_work;
+
+    rk29_camera_sensor_cb_s icd_cb;
 };
 static DEFINE_MUTEX(camera_lock);
 static const char *rk29_cam_driver_description = "RK29_Camera";
@@ -273,12 +279,12 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
        pcdev->vipmem_bsize = PAGE_ALIGN((pcdev->host_width * pcdev->host_height * icd->current_fmt->depth + 7)>>3);
        #endif
 
-       if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
-
-               if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
-                       *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
-               }
-
+       if (CAM_WORKQUEUE_IS_EN()) {
+        if (CAM_IPPWORK_IS_EN()) {
+               if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
+                       *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
+               }
+        }
                if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
                        kfree(pcdev->camera_work);
                        pcdev->camera_work = NULL;
@@ -378,7 +384,7 @@ static inline void rk29_videobuf_capture(struct videobuf_buffer *vb)
        struct rk29_camera_dev *pcdev = rk29_camdev_info_ptr;
 
     if (vb) {
-               if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
+               if (CAM_IPPWORK_IS_EN()) {
                        y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
                        uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
 
@@ -455,37 +461,42 @@ static void rk29_camera_capture_process(struct work_struct *work)
        struct rk29_ipp_req ipp_req;
        unsigned long int flags;
 
-       ipp_req.src0.YrgbMst = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
-       ipp_req.src0.CbrMst= ipp_req.src0.YrgbMst + pcdev->host_width*pcdev->host_height;
-       ipp_req.src0.w = pcdev->host_width;
-       ipp_req.src0.h = pcdev->host_height;
-       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
-
-       ipp_req.dst0.YrgbMst = vb->boff;
-       ipp_req.dst0.CbrMst= vb->boff+vb->width * vb->height;
-       ipp_req.dst0.w = pcdev->icd->user_width;
-       ipp_req.dst0.h = pcdev->icd->user_height;
-       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
-
-       ipp_req.src_vir_w = ipp_req.src0.w;
-       ipp_req.dst_vir_w = ipp_req.dst0.w;
-       ipp_req.timeout = 100;
-       ipp_req.flag = IPP_ROT_0;
-
-       if (ipp_do_blit(&ipp_req)) {
-               spin_lock_irqsave(&pcdev->lock, flags);
-               vb->state = VIDEOBUF_ERROR;
-               spin_unlock_irqrestore(&pcdev->lock, flags);
-               RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error!\n", vb->i);
-               RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
-               RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
-               RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
-               RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
-               RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
-               RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
-               RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
-           RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
-       }
+    if (CAM_IPPWORK_IS_EN()) {
+       ipp_req.src0.YrgbMst = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
+       ipp_req.src0.CbrMst= ipp_req.src0.YrgbMst + pcdev->host_width*pcdev->host_height;
+       ipp_req.src0.w = pcdev->host_width;
+       ipp_req.src0.h = pcdev->host_height;
+       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
+
+       ipp_req.dst0.YrgbMst = vb->boff;
+       ipp_req.dst0.CbrMst= vb->boff+vb->width * vb->height;
+       ipp_req.dst0.w = pcdev->icd->user_width;
+       ipp_req.dst0.h = pcdev->icd->user_height;
+       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
+
+       ipp_req.src_vir_w = ipp_req.src0.w;
+       ipp_req.dst_vir_w = ipp_req.dst0.w;
+       ipp_req.timeout = 100;
+       ipp_req.flag = IPP_ROT_0;
+
+       if (ipp_do_blit(&ipp_req)) {
+               spin_lock_irqsave(&pcdev->lock, flags);
+               vb->state = VIDEOBUF_ERROR;
+               spin_unlock_irqrestore(&pcdev->lock, flags);
+               RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error!\n", vb->i);
+               RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
+               RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
+               RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
+               RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+               RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
+               RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
+               RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
+           RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
+       }
+    } 
+
+    if (pcdev->icd_cb.sensor_cb)
+        (pcdev->icd_cb.sensor_cb)(vb);
 
        wake_up(&(camera_work->vb->done));
 }
@@ -535,7 +546,7 @@ static irqreturn_t rk29_camera_irq(int irq, void *data)
                vb->field_count++;
                }
 
-               if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
+               if (CAM_WORKQUEUE_IS_EN()) {
                        wk = pcdev->camera_work + vb->i;
                        INIT_WORK(&(wk->work), rk29_camera_capture_process);
                        wk->vb = vb;
@@ -762,6 +773,7 @@ static int rk29_camera_add_device(struct soc_camera_device *icd)
         ret = v4l2_subdev_call(sd,core, init, 0);
         if (ret)
             goto ebusy;
+        v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
     }
 
     pcdev->icd = icd;
@@ -810,6 +822,7 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
 
        pcdev->active = NULL;
     pcdev->icd = NULL;
+    pcdev->icd_cb.sensor_cb = NULL;
        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
        /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
      * if app havn't dequeue all videobuf before close camera device;
@@ -1134,7 +1147,7 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
         icd->buswidth = xlate->buswidth;
         icd->current_fmt = xlate->host_fmt;
 
-               if (((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))) {
+               if (CAM_IPPWORK_IS_EN()) {
                        BUG_ON(pcdev->vipmem_phybase == 0);
                }
     }
@@ -1576,6 +1589,7 @@ static int rk29_camera_probe(struct platform_device *pdev)
 
        hrtimer_init(&pcdev->fps_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        pcdev->fps_timer.function = rk29_camera_fps_func;
+    pcdev->icd_cb.sensor_cb = NULL;
 
     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
     return 0;