camera:cif support rk3188M
authorzyc <zyc@rock-chips.com>
Fri, 19 Jul 2013 08:56:02 +0000 (16:56 +0800)
committerzyc <zyc@rock-chips.com>
Fri, 19 Jul 2013 08:56:22 +0000 (16:56 +0800)
drivers/media/video/nt99252_3way.c
drivers/media/video/nt99340_2way.c
drivers/media/video/rk30_camera_oneframe.c

index 4ac781e8618d085383638b48e9bb737dca164ff0..9984824f9ebfeb48517de6d436c452a6c242ca65 100755 (executable)
@@ -1,12 +1,14 @@
 \r
 #include "generic_sensor.h"\r
-/*
+/*\r
 *      Driver Version Note\r
 *v0.0.1: this driver is compatible with generic_sensor\r
 *v0.1.1:\r
 *        add sensor_focus_af_const_pause_usr_cb;\r
+*v0.1.2:\r
+         crop for rk3188m\r
 */\r
-static int version = KERNEL_VERSION(0,1,1);\r
+static int version = KERNEL_VERSION(0,1,2);\r
 module_param(version, int, S_IRUGO);\r
 \r
 static int debug =1;\r
@@ -23,8 +25,13 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_BUS_PARAM                     (SOCAM_MASTER |\\r
                                              SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
                                              SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)\r
-#define SENSOR_PREVIEW_W                     800\r
-#define SENSOR_PREVIEW_H                     600\r
+#if defined(CONFIG_SOC_RK3188M)\r
+#define SENSOR_PREVIEW_W                     (800 - 20)\r
+#define SENSOR_PREVIEW_H                     (600 - 20)\r
+#else\r
+#define SENSOR_PREVIEW_W                                        (800)\r
+#define SENSOR_PREVIEW_H                                        (600)\r
+#endif\r
 #define SENSOR_PREVIEW_FPS                   15000     // 15fps \r
 #define SENSOR_FULLRES_L_FPS                 5000      // 7.5fps\r
 #define SENSOR_FULLRES_H_FPS                 10000      // 7.5fps\r
@@ -714,8 +721,8 @@ static      struct rk_sensor_reg sensor_Exposure14[]=
        SensorEnd\r
 };\r
 \r
-static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
-       sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {/*sensor_Exposure04,*/sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+       sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,/*sensor_Exposure14,*/NULL,\r
 };\r
 \r
 \r
@@ -882,7 +889,7 @@ static struct v4l2_querymenu sensor_menus[] =
 static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
 {\r
        new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
-       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
        new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
        new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
 };\r
@@ -952,6 +959,11 @@ static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framef
     if (capture) {\r
         //sensor_ae_transfer(client);\r
     }\r
+#if defined(CONFIG_SOC_RK3188M)\r
+       mf->width-=20;\r
+       mf->height-=20;\r
+       msleep(300);\r
+#endif\r
     return 0;\r
 }\r
 \r
@@ -1088,9 +1100,9 @@ static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){
 static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
        return 0;\r
 }\r
-static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)
-{
-    return 0;
+static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)\r
+{\r
+    return 0;\r
 }\r
 static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
        return 0;\r
index 0df32184822c1ad209d01469e101446337a6d75e..c99efcbf6e87f978749b642cca5ca207e90e640c 100755 (executable)
@@ -1,12 +1,14 @@
 \r
 #include "generic_sensor.h"\r
-/*
+/*\r
 *      Driver Version Note\r
 *v0.0.1: this driver is compatible with generic_sensor\r
 *v0.1.1:\r
 *        add sensor_focus_af_const_pause_usr_cb;\r
+*v0.1.2:\r
+         crop for rk3188m\r
 */\r
-static int version = KERNEL_VERSION(0,1,1);\r
+static int version = KERNEL_VERSION(0,1,2);\r
 module_param(version, int, S_IRUGO);\r
 \r
 static int debug =1;\r
@@ -24,8 +26,13 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
                           SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
                           SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)\r
 \r
-#define SENSOR_PREVIEW_W                     800\r
-#define SENSOR_PREVIEW_H                     600\r
+#if defined(CONFIG_SOC_RK3188M)\r
+#define SENSOR_PREVIEW_W                                        (800 - 20)\r
+#define SENSOR_PREVIEW_H                                        (600 - 20)\r
+#else\r
+#define SENSOR_PREVIEW_W                                        (800)\r
+#define SENSOR_PREVIEW_H                                        (600)\r
+#endif\r
 #define SENSOR_PREVIEW_FPS                   15000     // 15fps \r
 #define SENSOR_FULLRES_L_FPS                 5000      // 7.5fps\r
 #define SENSOR_FULLRES_H_FPS                 10000      // 7.5fps\r
@@ -769,8 +776,8 @@ static      struct rk_sensor_reg sensor_Exposure14[]=
        SensorEnd\r
 };\r
 \r
-static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
-       sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {/*sensor_Exposure04,*/sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+       sensor_Exposure11, sensor_Exposure12,sensor_Exposure13/*,sensor_Exposure14*/,NULL,\r
 };\r
 \r
 static struct rk_sensor_reg sensor_Saturation0[]=\r
@@ -928,7 +935,7 @@ static struct v4l2_querymenu sensor_menus[] =
 static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
 {\r
        new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
-       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
        new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
        new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
 };\r
@@ -1003,6 +1010,11 @@ static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framef
     if (capture) {\r
        // sensor_ae_transfer(client);\r
     }\r
+#if defined(CONFIG_SOC_RK3188M)\r
+    mf->width-=20;\r
+    mf->height-=20;\r
+       msleep(300);\r
+#endif\r
     return 0;\r
 }\r
 \r
@@ -1143,9 +1155,9 @@ static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){
 static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
        return 0;\r
 }\r
-static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)
-{
-    return 0;
+static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)\r
+{\r
+    return 0;\r
 }\r
 static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
        return 0;\r
index 2d2fd857b3e885b187e58529b46a11e1b64b7fe3..6c0d15de4925c7c9e02463c3ae88ca713e1c6ee2 100755 (executable)
@@ -305,9 +305,13 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 *v0.3.9:
 *         1. return real sensor output size in rk_camera_enum_frameintervals;
 *         2. wake up vb after add camera work to list in rk_camera_capture_process;
+*v0.3.b:
+          1. support rk3188m, delay 300ms todo softrest for first frame to avoid chip abnormal running
+          2.  sync stream off with irq thread for 3188m
+
 */
 
-#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x09)
+#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x0b)
 static int version = RK_CAM_VERSION_CODE;
 module_param(version, int, S_IRUGO);
 
@@ -398,6 +402,11 @@ struct rk_camera_timer{
        struct hrtimer timer;
     bool istarted;
        };
+#if defined(CONFIG_SOC_RK3188M)
+#define CONFIG_CIF_STOP_SYNC 1
+#else
+#define CONFIG_CIF_STOP_SYNC 0
+#endif
 struct rk_cif_clk 
 {
     //************must modify start************/
@@ -468,6 +477,10 @@ struct rk_camera_dev
     unsigned int reinit_times; 
     struct videobuf_queue *video_vq;
     bool stop_cif;
+       #if CONFIG_CIF_STOP_SYNC
+       wait_queue_head_t cif_stop_done;
+       volatile bool cif_stopped;
+       #endif
     struct timeval first_tv;
 
        int chip_id;
@@ -496,7 +509,7 @@ static const char *rk_cam_driver_description = "RK_Camera";
 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
 static void rk_camera_capture_process(struct work_struct *work);
 static int rk_camera_scale_crop_arm(struct work_struct *work);
-
+static void rk_camera_soft_reset(struct rk_camera_dev *rk_pcdev);
 /*
  *  Videobuf operations
  */
@@ -673,9 +686,7 @@ static void rk_camera_store_register(struct rk_camera_dev *pcdev)
        pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
        pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
        
-       cru_set_soft_reset(SOFT_RST_CIF0, true);
-       udelay(5);
-       cru_set_soft_reset(SOFT_RST_CIF0, false);
+       rk_camera_soft_reset(pcdev);
 }
 static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
 {
@@ -1244,6 +1255,54 @@ rk_camera_capture_process_end:
     wake_up(&(camera_work->vb->done));     /* ddl@rock-chips.com : v0.3.9 */ 
     return;
 }
+#if defined(CONFIG_SOC_RK3188M)
+static void rk_camera_special_process_for_3188M(struct work_struct *work){
+       struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);    
+       struct rk_camera_dev *pcdev = camera_work->pcdev;        
+       unsigned long flags = 0;
+       unsigned long tmp_cifctrl; 
+       tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+       mdelay(300);
+       rk_videobuf_capture(pcdev->active,pcdev);
+       spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
+       list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
+       spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);        
+       
+       if(((tmp_cifctrl & ENABLE_CAPTURE) == 0)){
+               
+               write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
+               }
+       return;
+}
+#endif
+
+static void rk_camera_soft_reset(struct rk_camera_dev *pcdev){
+#if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928))
+                                                                  mdelay(100);
+                                                                       if(IS_CIF0()){
+                                                               //              pmu_set_idle_request(IDLE_REQ_VIO, true);
+                                                                               cru_set_soft_reset(SOFT_RST_CIF0, true);
+                                                                               udelay(5);
+                                                                               cru_set_soft_reset(SOFT_RST_CIF0, false);
+                                                               //              pmu_set_idle_request(IDLE_REQ_VIO, false);
+                                               
+                                                                       }else{
+                                                               //              pmu_set_idle_request(IDLE_REQ_VIO, true);
+                                                                               cru_set_soft_reset(SOFT_RST_CIF1, true);
+                                                                               udelay(5);
+                                                                               cru_set_soft_reset(SOFT_RST_CIF1, false);
+                                                               //              pmu_set_idle_request(IDLE_REQ_VIO, false);      
+                                                                       }
+#elif defined(CONFIG_ARCH_RK3188)
+                                               //              pmu_set_idle_request(IDLE_REQ_VIO, true);
+                                                               cru_set_soft_reset(SOFT_RST_CIF0, true);
+                                                               udelay(5);
+                                                               cru_set_soft_reset(SOFT_RST_CIF0, false);
+                                               //              pmu_set_idle_request(IDLE_REQ_VIO, false);
+                                               
+#endif
+       return;
+}
 static irqreturn_t rk_camera_irq(int irq, void *data)
 {
     struct rk_camera_dev *pcdev = data;
@@ -1255,12 +1314,14 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
      
     tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
     tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+#if (CONFIG_CIF_STOP_SYNC == 0)
     if(pcdev->stop_cif == true)
         {
         printk("cif has stopped by app,needn't to deal this irq\n");
        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
          return IRQ_HANDLED;
              }
+#endif
     if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/){//bit9 =1 ,bit0 = 0
        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200);  /* clear vip interrupte single  */
         if(tmp_cifctrl & ENABLE_CAPTURE)
@@ -1271,12 +1332,45 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
     /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
     if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01);  /* clear vip interrupte single  */
+               
+#if CONFIG_CIF_STOP_SYNC
+                       if(pcdev->stop_cif == true) {
+                               //RK30_CAM_DEBUG_TRACE("%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  */
+                               
+                               //              write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0);     //capture complete interrupt enable
+                               rk_camera_soft_reset(pcdev);
+                               pcdev->cif_stopped = true;
+                               wake_up(&pcdev->cif_stop_done);
+
+                               return IRQ_HANDLED;
+                       }
+#endif
         if (!pcdev->fps) {
             do_gettimeofday(&pcdev->first_tv);            
         }
                pcdev->fps++;
                if (!pcdev->active)
                        goto RK_CAMERA_IRQ_END;
+#if defined(CONFIG_SOC_RK3188M)
+               //for 3188M
+
+               if(pcdev->fps == 1){
+                       if (CAM_WORKQUEUE_IS_EN()) {
+                                       if (!list_empty(&pcdev->camera_work_queue)) {
+                                               pcdev->frame_inval--;
+                                               wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
+                                               list_del_init(&wk->queue);
+                                               INIT_WORK(&(wk->work), rk_camera_special_process_for_3188M);
+                                       wk->vb = pcdev->active;
+                                       wk->pcdev = pcdev;
+                                       queue_work(pcdev->camera_wq, &(wk->work));
+                                       
+                               return IRQ_HANDLED;
+                                       }                                               
+                       } 
+               }
+#endif
         if (pcdev->frame_inval>0) {
             pcdev->frame_inval--;
             rk_videobuf_capture(pcdev->active,pcdev);
@@ -2606,12 +2700,21 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
        struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
        struct rk_camera_dev *pcdev = fps_timer->pcdev;
     int rec_flag,i;
+       unsigned long flags;
    // static unsigned int last_fps = 0;
     struct soc_camera_link *tmp_soc_cam_link;
     tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
 
        RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
        if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
+               
+               spin_lock_irqsave(&pcdev->lock, flags);
+               if(((pcdev->active==NULL) && !(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE))||
+                       (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01)){
+                       RKCAMERA_TR("%s:no active buffer,wait app enque buffer!\n",__func__);
+               }
+               spin_unlock_irqrestore(&pcdev->lock, flags);
+               goto fps_end;
                RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
                pcdev->camera_reinit_work.pcdev = pcdev;
                //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
@@ -2676,6 +2779,8 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
             }
         }
        }
+
+fps_end:
     pcdev->last_fps = pcdev->fps ;
     pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
     pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
@@ -2717,10 +2822,22 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
         flush_work(&(pcdev->camera_reinit_work.work));
         
         cif_ctrl_val &= ~ENABLE_CAPTURE;
-               spin_lock_irqsave(&pcdev->lock, flags);
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
-        pcdev->stop_cif = true;
-       spin_unlock_irqrestore(&pcdev->lock, flags);
+       pcdev->stop_cif = true;
+#if CONFIG_CIF_STOP_SYNC
+                       
+                       init_waitqueue_head(&pcdev->cif_stop_done);
+                       if (wait_event_interruptible_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(300)) == 0) {
+                               RKCAMERA_DG("%s:%d, wait cif stop timeout!\n",__func__,__LINE__);
+                               write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+                               mdelay(300);
+                               rk_camera_soft_reset(pcdev);
+                       }
+#else
+       spin_lock_irqsave(&pcdev->lock, flags);
+       write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+       spin_unlock_irqrestore(&pcdev->lock, flags);
+
+#endif
                flush_workqueue((pcdev->camera_wq));
                RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
        }