UPSTREAM: usb: dwc2: Avoid more calls to dwc2_core_reset()
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk30_camera_oneframe.c
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/io.h>
4 #include <linux/delay.h>
5 #include <linux/slab.h>
6 #include <linux/dma-mapping.h>
7 #include <linux/errno.h>
8 #include <linux/fs.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/mm.h>
12 #include <linux/moduleparam.h>
13 #include <linux/time.h>
14 #include <linux/clk.h>
15 #include <linux/version.h>
16 #include <linux/device.h>
17 #include <linux/platform_device.h>
18 #include <linux/mutex.h>
19 #include <linux/videodev2.h>
20 #include <linux/kthread.h>
21
22 #include <media/v4l2-common.h>
23 #include <media/v4l2-dev.h>
24 #include <media/videobuf-dma-contig.h>
25 #include <media/soc_camera.h>
26 #include <media/soc_mediabus.h>
27 #include <media/videobuf-core.h>
28 #include <linux/rockchip/iomap.h>
29
30 #include "../../video/rockchip/rga/rga.h"
31 #include "../../../arch/arm/mach-rockchip/rk30_camera.h"
32 #include <linux/rockchip/cru.h>
33
34 #include <asm/cacheflush.h>
35
36 #include <linux/of_address.h>
37 #include <linux/of_platform.h>
38 #include <linux/of_fdt.h>
39 #include <media/soc_camera.h>
40 #include <media/camsys_head.h>
41 #include <linux/of.h>
42 #include <linux/of_irq.h>
43  
44 static int debug = 0;
45 module_param(debug, int, S_IRUGO|S_IWUSR);
46
47 #define CAMMODULE_NAME     "rk_cam_cif"   
48
49 #define wprintk(level, fmt, arg...) do {                        \
50         if (debug >= level)                                     \
51             printk(KERN_ERR "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
52
53 #define dprintk(level, fmt, arg...) do {                        \
54         if (debug >= level)                                     \
55             printk(KERN_ERR"%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)      
56
57 #define RKCAMERA_TR(format, ...)  printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
58 #define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
59 #define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
60 #define debug_printk(format, ...) dprintk(3, format, ## __VA_ARGS__)
61
62 /* CIF Reg Offset*/
63 #define  CIF_CIF_CTRL                       0x00
64 #define  CIF_CIF_INTEN                      0x04
65 #define  CIF_CIF_INTSTAT                    0x08
66 #define  CIF_CIF_FOR                        0x0c
67 #define  CIF_CIF_LINE_NUM_ADDR              0x10
68 #define  CIF_CIF_FRM0_ADDR_Y                0x14
69 #define  CIF_CIF_FRM0_ADDR_UV               0x18
70 #define  CIF_CIF_FRM1_ADDR_Y                0x1c
71 #define  CIF_CIF_FRM1_ADDR_UV               0x20
72 #define  CIF_CIF_VIR_LINE_WIDTH             0x24
73 #define  CIF_CIF_SET_SIZE                   0x28
74 #define  CIF_CIF_SCM_ADDR_Y                 0x2c
75 #define  CIF_CIF_SCM_ADDR_U                 0x30
76 #define  CIF_CIF_SCM_ADDR_V                 0x34
77 #define  CIF_CIF_WB_UP_FILTER               0x38
78 #define  CIF_CIF_WB_LOW_FILTER              0x3c
79 #define  CIF_CIF_WBC_CNT                    0x40
80 #define  CIF_CIF_CROP                       0x44
81 #define  CIF_CIF_SCL_CTRL                   0x48
82 #define  CIF_CIF_SCL_DST                    0x4c
83 #define  CIF_CIF_SCL_FCT                    0x50
84 #define  CIF_CIF_SCL_VALID_NUM              0x54
85 #define  CIF_CIF_LINE_LOOP_CTR              0x58
86 #define  CIF_CIF_FRAME_STATUS               0x60
87 #define  CIF_CIF_CUR_DST                    0x64
88 #define  CIF_CIF_LAST_LINE                  0x68
89 #define  CIF_CIF_LAST_PIX                   0x6c
90
91 /*The key register bit descrition*/
92 /* CIF_CTRL Reg , ignore SCM,WBC,ISP,*/
93 #define  DISABLE_CAPTURE              (0x00<<0)
94 #define  ENABLE_CAPTURE               (0x01<<0)
95 #define  MODE_ONEFRAME                (0x00<<1)
96 #define  MODE_PINGPONG                (0x01<<1)
97 #define  MODE_LINELOOP                (0x02<<1)
98 #define  AXI_BURST_16                 (0x0F << 12)
99
100 /*CIF_CIF_INTEN*/
101 #define  FRAME_END_EN                   (0x01<<1)
102 #define  BUS_ERR_EN                             (0x01<<6)
103 #define  SCL_ERR_EN                             (0x01<<7)
104
105 /*CIF_CIF_FOR*/
106 #define  VSY_HIGH_ACTIVE                   (0x01<<0)
107 #define  VSY_LOW_ACTIVE                    (0x00<<0)
108 #define  HSY_LOW_ACTIVE                                (0x01<<1)
109 #define  HSY_HIGH_ACTIVE                               (0x00<<1)
110 #define  INPUT_MODE_YUV                                (0x00<<2)
111 #define  INPUT_MODE_PAL                                (0x02<<2)
112 #define  INPUT_MODE_NTSC                               (0x03<<2)
113 #define  INPUT_MODE_RAW                                (0x04<<2)
114 #define  INPUT_MODE_JPEG                               (0x05<<2)
115 #define  INPUT_MODE_MIPI                               (0x06<<2)
116 #define  YUV_INPUT_ORDER_UYVY(ori)             (ori & (~(0x03<<5)))
117 #define  YUV_INPUT_ORDER_YVYU(ori)                 ((ori & (~(0x01<<6)))|(0x01<<5))
118 #define  YUV_INPUT_ORDER_VYUY(ori)                 ((ori & (~(0x01<<5))) | (0x1<<6))
119 #define  YUV_INPUT_ORDER_YUYV(ori)                 (ori|(0x03<<5))
120 #define  YUV_INPUT_422                         (0x00<<7)
121 #define  YUV_INPUT_420                         (0x01<<7)
122 #define  INPUT_420_ORDER_EVEN                  (0x00<<8)
123 #define  INPUT_420_ORDER_ODD                   (0x01<<8)
124 #define  CCIR_INPUT_ORDER_ODD                  (0x00<<9)
125 #define  CCIR_INPUT_ORDER_EVEN             (0x01<<9)
126 #define  RAW_DATA_WIDTH_8                  (0x00<<11)
127 #define  RAW_DATA_WIDTH_10                 (0x01<<11)
128 #define  RAW_DATA_WIDTH_12                 (0x02<<11)   
129 #define  YUV_OUTPUT_422                    (0x00<<16)
130 #define  YUV_OUTPUT_420                    (0x01<<16)
131 #define  OUTPUT_420_ORDER_EVEN             (0x00<<17)
132 #define  OUTPUT_420_ORDER_ODD              (0x01<<17)
133 #define  RAWD_DATA_LITTLE_ENDIAN           (0x00<<18)
134 #define  RAWD_DATA_BIG_ENDIAN              (0x01<<18)
135 #define  UV_STORAGE_ORDER_UVUV             (0x00<<19)
136 #define  UV_STORAGE_ORDER_VUVU             (0x01<<19)
137
138 /*CIF_CIF_SCL_CTRL*/
139 #define ENABLE_SCL_DOWN                    (0x01<<0)            
140 #define DISABLE_SCL_DOWN                   (0x00<<0)
141 #define ENABLE_SCL_UP                      (0x01<<1)            
142 #define DISABLE_SCL_UP                     (0x00<<1)
143 #define ENABLE_YUV_16BIT_BYPASS            (0x01<<4)
144 #define DISABLE_YUV_16BIT_BYPASS           (0x00<<4)
145 #define ENABLE_RAW_16BIT_BYPASS            (0x01<<5)
146 #define DISABLE_RAW_16BIT_BYPASS           (0x00<<5)
147 #define ENABLE_32BIT_BYPASS                (0x01<<6)
148 #define DISABLE_32BIT_BYPASS               (0x00<<6)
149
150 extern unsigned long rk_cif_grf_base;
151 extern unsigned long rk_cif_cru_base;
152
153
154 #define MIN(x,y)   ((x<y) ? x: y)
155 #define MAX(x,y)    ((x>y) ? x: y)
156 #define RK_SENSOR_24MHZ      24*1000*1000          /* MHz */
157 #define RK_SENSOR_48MHZ      48
158
159 #define __raw_readl(p)            (*(unsigned int *)(p))
160 #define __raw_writel(v,p)     (*(unsigned int *)(p) = (v))
161
162 #define write_cif_reg(base,addr, val)  __raw_writel(val, addr+(base))
163 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
164 #define mask_cif_reg(addr, msk, val)    write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
165
166
167 static u32 CRU_PCLK_REG30;
168 static u32 CRU_CLK_OUT;
169 static u32 clk_cif_out_src_gate_en;
170 static u32 CRU_CLKSEL29_CON;
171 static u32 cif0_clk_sel;
172 static u32 ENANABLE_INVERT_PCLK_CIF0;
173 static u32 DISABLE_INVERT_PCLK_CIF0;
174 static u32 ENANABLE_INVERT_PCLK_CIF1;
175 static u32 DISABLE_INVERT_PCLK_CIF1;
176 static u32 CHIP_NAME;
177
178 #define write_cru_reg(addr, val)            __raw_writel(val, addr+RK_CRU_VIRT)
179 #define read_cru_reg(addr)                  __raw_readl(addr+RK_CRU_VIRT)
180 #define mask_cru_reg(addr, msk, val)        write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
181
182 #define rk3368_write_cru_reg(addr, val)            __raw_writel(val, addr+rk_cif_cru_base)
183 #define rk3368_read_cru_reg(addr)                  __raw_readl(addr+rk_cif_cru_base)
184 #define rk3368_mask_cru_reg(addr, msk, val)        rk3368_write_cru_reg(addr,(val)|((~(msk))&rk3368_read_cru_reg(addr)))
185
186 #define CAM_WORKQUEUE_IS_EN()   (true)
187 #define CAM_IPPWORK_IS_EN()     (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
188
189 #define IS_CIF0()               (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
190 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
191 #define CROP_ALIGN_BYTES (0x03)
192 #define CIF_DO_CROP 0
193 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
194 #define CROP_ALIGN_BYTES (0x0f)
195 #define CIF_DO_CROP 0
196 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
197 #define CROP_ALIGN_BYTES (0x03)
198 #define CIF_DO_CROP 0
199 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
200 #define CROP_ALIGN_BYTES (0x0F)
201 #define CIF_DO_CROP 1
202 #endif
203
204 /*
205 *v0.1.0 : this driver is 3.10 kernel driver;
206                 copy and updata from v0.3.0x19;
207                 support rk312x;
208 *v0.1.1:
209          1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
210             cause warning, so remove this spin lock .
211 *v0.1.2:
212                  1. rk3126 and rk3128 use different dts file.            
213 *v0.1.3:
214                  1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
215 *v0.1.4:
216                  1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk 
217 *v0.1.5:        
218            1. Improve the code to support all configuration.reset,af,flash...
219 *v0.1.6:
220                  1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
221 *v0.1.7:
222                  1. Add  power and powerdown controled by PMU.
223 *v0.1.8:
224                  1. Support front and rear camera support are the same.
225 *v0.1.9:
226                  1. Support pingpong mode.
227                  2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0
228                  3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
229                  4. Support flash control when preview size == picture size
230 *v0.1.a:
231                  1. Support rk3288 cif driver
232                  2. Query and upload iommu info
233 *v0.1.b:
234                  1. Vpu_service compatible has change ,fix it.
235 *v0.1.c:
236                  1. setting cif capture en bit can't stop cif really,reset cif instead.
237 *v0.1.d:
238                  1. use of_find_node_by_name to get vpu node instead of of_find_compatible_node 
239 *v0.1.e:
240                  1. support focus mode.
241 *v0.1.f:
242          1. focus mode have some bug,fix it.
243 *v0.2.0:
244                 1. support rk3368.
245 */
246 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0)
247 static int version = RK_CAM_VERSION_CODE;
248 module_param(version, int, S_IRUGO);
249
250 /* limit to rk29 hardware capabilities */
251 #define RK_CAM_BUS_PARAM   (V4L2_MBUS_MASTER |\
252                 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
253                 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
254                 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
255                 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
256                 V4L2_MBUS_PCLK_SAMPLE_RISING |\
257                 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
258                 V4L2_MBUS_DATA_ACTIVE_HIGH |\
259                 V4L2_MBUS_DATA_ACTIVE_LOW|\
260                 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
261                 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
262
263 #define RK_CAM_W_MIN        48
264 #define RK_CAM_H_MIN        32
265 #define RK_CAM_W_MAX        3856                /* ddl@rock-chips.com : 10M Pixel */
266 #define RK_CAM_H_MAX        2764
267 #define RK_CAM_FRAME_INVAL_INIT      0
268 #define RK_CAM_FRAME_INVAL_DC        0          /* ddl@rock-chips.com :  */
269 #define RK30_CAM_FRAME_MEASURE       5
270
271
272 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
273 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
274 /* buffer for one video frame */
275 struct rk_camera_buffer
276 {
277     /* common v4l buffer stuff -- must be first */
278     struct videobuf_buffer vb;
279     enum v4l2_mbus_pixelcode    code;
280     int                 inwork;
281 };
282 enum rk_camera_reg_state
283 {
284         Reg_Invalidate,
285         Reg_Validate
286 };
287
288 struct rk_camera_reg
289 {
290         unsigned int cifCtrl;
291         unsigned int cifCrop;
292         unsigned int cifFs;
293         unsigned int cifIntEn;
294         unsigned int cifFmt;
295     unsigned int cifVirWidth;
296     unsigned int cifScale;
297 /*      unsigned int VipCrm;*/
298         enum rk_camera_reg_state Inval;
299 };
300 struct rk_camera_work
301 {
302         struct videobuf_buffer *vb;
303         struct rk_camera_dev *pcdev;
304         struct work_struct work;
305     struct list_head queue;
306     unsigned int index;    
307 };
308 struct rk_camera_frmivalenum
309 {
310     struct v4l2_frmivalenum fival;
311     struct rk_camera_frmivalenum *nxt;
312 };
313 struct rk_camera_frmivalinfo
314 {
315     struct soc_camera_device *icd;
316     struct rk_camera_frmivalenum *fival_list;
317 };
318 struct rk_camera_zoominfo
319 {
320     struct semaphore sem;
321     struct v4l2_crop a;
322     int vir_width;
323     int vir_height;
324     int zoom_rate;
325 };
326 #if CAMERA_VIDEOBUF_ARM_ACCESS
327 struct rk29_camera_vbinfo
328 {
329     unsigned long phy_addr;
330     void __iomem *vir_addr;
331     unsigned int size;
332 };
333 #endif
334 struct rk_camera_timer{
335         struct rk_camera_dev *pcdev;
336         struct hrtimer timer;
337     bool istarted;
338 };
339 struct rk_cif_clk 
340 {
341     /************must modify start************/
342         struct clk *pd_cif;
343         struct clk *aclk_cif;
344     struct clk *hclk_cif;
345     struct clk *cif_clk_in;
346     struct clk *cif_clk_out;
347         /************must modify end************/
348
349    // spinlock_t lock;
350     bool on;
351 };
352
353 struct rk_cif_crop
354 {
355     spinlock_t lock;
356     struct v4l2_rect c;
357     struct v4l2_rect bounds;
358 };
359
360 struct rk_cif_irqinfo
361 {
362     unsigned int irq;
363     unsigned long cifirq_idx;
364     unsigned long cifirq_normal_idx;
365     unsigned long cifirq_abnormal_idx;
366
367     unsigned long dmairq_idx;
368     spinlock_t lock;
369 };
370
371 struct rk_camera_dev
372 {
373     struct soc_camera_host      soc_host;    
374     struct device               *dev;
375     /* RK2827x is only supposed to handle one camera on its Quick Capture
376      * interface. If anyone ever builds hardware to enable more than
377      * one camera, they will have to modify this driver too */
378     struct soc_camera_device *icd;
379     void __iomem *base;
380     int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
381
382     unsigned int fps;
383     unsigned int last_fps;
384     unsigned long frame_interval;
385     unsigned int pixfmt;
386     /*for ipp   */
387     unsigned long vipmem_phybase;
388     void __iomem *vipmem_virbase;
389     unsigned int vipmem_size;
390     unsigned int vipmem_bsize;
391 #if CAMERA_VIDEOBUF_ARM_ACCESS    
392     struct rk29_camera_vbinfo *vbinfo;
393     unsigned int vbinfo_count;
394 #endif    
395     int host_width;
396     int host_height;
397     int host_left;  /*sensor output size ?*/
398     int host_top;
399     int hostid;
400     int icd_width;
401     int icd_height;
402
403     struct rk_cif_crop cropinfo;
404     struct rk_cif_irqinfo irqinfo;
405
406     struct rk29camera_platform_data *pdata;
407     struct resource             *res;
408     struct list_head    capture;
409     struct rk_camera_zoominfo zoominfo;
410
411     spinlock_t          lock;
412
413     struct videobuf_buffer      *active;
414     struct rk_camera_reg reginfo_suspend;
415     struct workqueue_struct *camera_wq;
416     struct rk_camera_work *camera_work;
417     struct list_head camera_work_queue;
418     spinlock_t camera_work_lock;
419     unsigned int camera_work_count;
420     struct rk_camera_timer fps_timer;
421     struct rk_camera_work camera_reinit_work;
422     int icd_init;
423     rk29_camera_sensor_cb_s icd_cb;
424     struct rk_camera_frmivalinfo icd_frmival[2];
425     bool timer_get_fps;
426     unsigned int reinit_times; 
427     struct videobuf_queue *video_vq;
428     atomic_t stop_cif;
429         wait_queue_head_t cif_stop_done;
430         volatile  bool cif_stopped;
431     struct timeval first_tv;
432     
433     int chip_id;
434 };
435
436 static const struct v4l2_queryctrl rk_camera_controls[] =
437 {
438     {
439         .id             = V4L2_CID_ZOOM_ABSOLUTE,
440         .type           = V4L2_CTRL_TYPE_INTEGER,
441         .name           = "DigitalZoom Control",
442         .minimum        = 100,
443         .maximum        = 300,
444         .step           = 5,
445         .default_value = 100,
446     }
447 };
448
449 static struct rk_cif_clk  cif_clk[2];
450
451 static DEFINE_MUTEX(camera_lock);
452 static const char *rk_cam_driver_description = "RK_Camera";
453
454 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
455 static void rk_camera_capture_process(struct work_struct *work);
456
457 static void rk_camera_diffchips(const char *rockchip_name)
458 {
459         if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
460         {       
461                 CRU_PCLK_REG30 = 0xbc;
462                 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
463                 DISABLE_INVERT_PCLK_CIF0  = ((0x1<<23)|(0x0<<7));
464                 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
465                 DISABLE_INVERT_PCLK_CIF1  = DISABLE_INVERT_PCLK_CIF0;
466
467                 CRU_CLK_OUT = 0xdc;
468                 clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7));
469                 CRU_CLKSEL29_CON = 0xb8;
470                 cif0_clk_sel = ((0x1<<23)|(0x0<<7));
471
472                 CHIP_NAME = 3126;
473         }
474         else if(strstr(rockchip_name,"3288"))
475         {       
476                 CRU_PCLK_REG30 = 0xd4;
477                 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x1<<4));
478                 DISABLE_INVERT_PCLK_CIF0  = ((0x1<<20)|(0x0<<4));
479                 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
480                 DISABLE_INVERT_PCLK_CIF1  = DISABLE_INVERT_PCLK_CIF0;
481
482                 CRU_CLK_OUT = 0x16c;
483                 CHIP_NAME = 3288;
484         }
485         else if(strstr(rockchip_name,"3368"))
486         {       
487                 CRU_PCLK_REG30 = 0x154;
488                 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x1<<13));
489                 DISABLE_INVERT_PCLK_CIF0  = ((0x1<<29)|(0x0<<13));
490                 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
491                 DISABLE_INVERT_PCLK_CIF1  = DISABLE_INVERT_PCLK_CIF0;
492
493                 //CRU_CLK_OUT = 0x16c;
494                 CHIP_NAME = 3368;
495         }
496 }
497 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
498 {
499         u32 val = 0;
500         void __iomem *reg;
501         
502         if(CHIP_NAME == 3368)
503                 reg = (void*)(rk_cif_cru_base + RK_CRU_SOFTRST_CON);
504         else
505                 reg = (void*)(RK_CRU_VIRT + RK_CRU_SOFTRST_CON);
506
507         if(CHIP_NAME == 3126){
508                 val = on ? 0x10001U << 14 : 0x10000U << 14;
509         }else if(CHIP_NAME == 3288){
510                 val = on ? 0x10001U << 8 : 0x10000U << 8;
511         }else if(CHIP_NAME == 3368){
512                 val = on ? 0x10001U << 8 : 0x10000U << 8;
513         }
514         writel_relaxed(val, reg);
515         dsb(sy);
516 }
517
518 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
519 {
520     int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
521         u32 RK_CRU_SOFTRST_CON = 0;
522         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
523         if(CHIP_NAME == 3126){
524                 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
525         }else if(CHIP_NAME == 3288){
526                 RK_CRU_SOFTRST_CON = RK3288_CRU_SOFTRSTS_CON(6);
527         }else if(CHIP_NAME == 3368){
528                 RK_CRU_SOFTRST_CON = RK3368_CRU_SOFTRSTS_CON(6);
529         }
530         
531         if (only_rst == true) {
532         rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
533         udelay(5);
534         rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
535     } else {
536         ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
537         if (ctrl_reg & ENABLE_CAPTURE) {
538             write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
539         }
540         crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
541         set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
542         inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
543         for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
544         vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
545         scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
546         y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
547         uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
548         
549         rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
550         udelay(5);
551         rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON); 
552
553         write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
554             write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
555             write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
556             write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
557             write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
558             write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
559             write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
560             write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg);      /*ddl@rock-chips.com v0.3.0x13 */
561             write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
562     }
563     return;
564 }
565
566
567 /*
568  *  Videobuf operations
569  */
570 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
571                                unsigned int *size)
572 {
573     struct soc_camera_device *icd = vq->priv_data;
574         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
575     struct rk_camera_dev *pcdev = ici->priv;
576         unsigned int i;
577     struct rk_camera_work *wk;
578
579          struct soc_mbus_pixelfmt fmt;
580         int bytes_per_line;
581         int bytes_per_line_host;
582         fmt.packing = SOC_MBUS_PACKING_1_5X8;
583
584         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
585
586
587                 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
588                                                 icd->current_fmt->host_fmt);
589         if(icd->current_fmt->host_fmt->fourcc ==  V4L2_PIX_FMT_RGB565)
590                  bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
591                                                 &fmt);
592         else if(icd->current_fmt->host_fmt->fourcc ==  V4L2_PIX_FMT_RGB24)
593                 bytes_per_line_host = pcdev->host_width*3;
594         else
595                 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
596                                            icd->current_fmt->host_fmt);
597    /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
598
599         if (bytes_per_line_host < 0)
600                 return bytes_per_line_host;
601
602         /* planar capture requires Y, U and V buffers to be page aligned */
603         *size = PAGE_ALIGN(bytes_per_line*icd->user_height);       /* Y pages UV pages, yuv422*/
604         pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
605
606         if (CAM_WORKQUEUE_IS_EN()) {
607                 
608         if (CAM_IPPWORK_IS_EN())  {
609             BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
610                 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
611                         *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
612                 }
613         }
614         
615                 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
616                         kfree(pcdev->camera_work);
617                         pcdev->camera_work = NULL;
618                         pcdev->camera_work_count = 0;
619                 }
620
621                 if (pcdev->camera_work == NULL) {
622                         pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
623                         if (pcdev->camera_work == NULL) {
624                                 RKCAMERA_TR("kmalloc failed\n");
625                                 BUG();
626                         }
627             INIT_LIST_HEAD(&pcdev->camera_work_queue);
628
629             for (i=0; i<(*count); i++) {
630                 wk->index = i;                
631                 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
632                 wk++; 
633             }
634                         pcdev->camera_work_count = (*count);
635                 }
636 #if CAMERA_VIDEOBUF_ARM_ACCESS
637         if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
638             kfree(pcdev->vbinfo);
639             pcdev->vbinfo = NULL;
640             pcdev->vbinfo_count = 0x00;
641         }
642
643         if (pcdev->vbinfo == NULL) {
644             pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
645             if (pcdev->vbinfo == NULL) {
646                                 RKCAMERA_TR("vbinfo kmalloc fail\n");
647                                 BUG();
648                         }
649             memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
650                         pcdev->vbinfo_count = *count;
651         }
652 #endif        
653         }
654     pcdev->video_vq = vq;
655     RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
656
657     return 0;
658 }
659 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
660 {
661     struct soc_camera_device *icd = vq->priv_data;
662
663         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
664
665
666     dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
667             &buf->vb, buf->vb.baddr, buf->vb.bsize);
668
669         /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
670         if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
671                 return;
672
673     if (in_interrupt())
674         BUG();
675     /*
676          * This waits until this buffer is out of danger, i.e., until it is no
677          * longer in STATE_QUEUED or STATE_ACTIVE
678          */
679         videobuf_waiton(vq, &buf->vb, 0, 0);
680     videobuf_dma_contig_free(vq, &buf->vb);
681     buf->vb.state = VIDEOBUF_NEEDS_INIT;
682         return;
683 }
684 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
685 {
686     struct soc_camera_device *icd = vq->priv_data;
687     struct rk_camera_buffer *buf;
688     int ret;
689     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
690                                                 icd->current_fmt->host_fmt);
691
692         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
693         
694         if ((bytes_per_line < 0) || (vb->boff == 0))
695                 return -EINVAL;
696
697     buf = container_of(vb, struct rk_camera_buffer, vb);
698
699     /* Added list head initialization on alloc */
700     WARN_ON(!list_empty(&vb->queue));    
701
702     BUG_ON(NULL == icd->current_fmt);
703
704     if (buf->code    != icd->current_fmt->code ||
705             vb->width   != icd->user_width ||
706             vb->height  != icd->user_height ||
707              vb->field   != field) {
708         buf->code    = icd->current_fmt->code;
709         vb->width   = icd->user_width;
710         vb->height  = icd->user_height;
711         vb->field   = field;
712         vb->state   = VIDEOBUF_NEEDS_INIT;
713     }
714
715     vb->size = bytes_per_line*vb->height;          /* ddl@rock-chips.com : fmt->depth is coorect */
716     if (0 != vb->baddr && vb->bsize < vb->size) {
717         ret = -EINVAL;
718         goto out;
719     }
720
721     if (vb->state == VIDEOBUF_NEEDS_INIT) {
722         ret = videobuf_iolock(vq, vb, NULL);
723         if (ret) {
724             goto fail;
725         }
726         vb->state = VIDEOBUF_PREPARED;
727     }
728     
729     return 0;
730 fail:
731     rk_videobuf_free(vq, buf);
732 out:
733     return ret;
734 }
735
736 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
737 {
738         unsigned long y_addr,uv_addr;
739         struct rk_camera_dev *pcdev = rk_pcdev;
740
741         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
742
743
744     if (vb) {
745                 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
746                         y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
747                         uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
748                         if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
749                                 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
750                                                   pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
751                                 BUG();
752                         }
753                 } else {
754                         y_addr = vb->boff;
755                         uv_addr = y_addr + vb->width * vb->height;
756                 }
757 #if defined(CONFIG_ARCH_RK3188)
758                 rk_camera_cif_reset(pcdev,false);
759 #endif
760         write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
761         write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
762         write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
763         write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
764         write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
765     }
766 }
767 /* Locking: Caller holds q->irqlock */
768 static void rk_videobuf_queue(struct videobuf_queue *vq,
769                                 struct videobuf_buffer *vb)
770 {
771     struct soc_camera_device *icd = vq->priv_data;
772         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
773     struct rk_camera_dev *pcdev = ici->priv;
774 #if CAMERA_VIDEOBUF_ARM_ACCESS    
775     struct rk29_camera_vbinfo *vb_info;
776 #endif
777
778
779         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
780
781     vb->state = VIDEOBUF_QUEUED;
782         if (list_empty(&pcdev->capture)) {
783                 list_add_tail(&vb->queue, &pcdev->capture);
784         } else {
785                 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
786                         list_add_tail(&vb->queue, &pcdev->capture);
787                 else
788                         BUG();    /* ddl@rock-chips.com : The same videobuffer queue again */
789         }
790 #if CAMERA_VIDEOBUF_ARM_ACCESS
791     if (pcdev->vbinfo) {
792         vb_info = pcdev->vbinfo+vb->i;
793         if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
794             if (vb_info->vir_addr) {
795                 iounmap(vb_info->vir_addr);
796                 release_mem_region(vb_info->phy_addr, vb_info->size);
797                 vb_info->vir_addr = NULL;
798                 vb_info->phy_addr = 0x00;
799                 vb_info->size = 0x00;
800             }
801
802             if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
803                 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize); 
804             }
805             
806             if (vb_info->vir_addr) {
807                 vb_info->size = vb->bsize;
808                 vb_info->phy_addr = vb->boff;
809             } else {
810                 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
811             }
812         }
813     }
814 #endif    
815     if (!pcdev->active) {
816         pcdev->active = vb;
817         rk_videobuf_capture(vb,pcdev);
818         if (atomic_read(&pcdev->stop_cif) == false) {           //ddl@rock-chips.com v0.3.0x13
819             write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
820         }       
821     }
822 }
823
824 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
825 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
826 {
827
828         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
829
830         switch (pixfmt)
831         {
832                 case V4L2_PIX_FMT_YUV420:
833                 case V4L2_PIX_FMT_UYVY: /* yuv 422, but sensor has defined this format(in fact ,should be defined yuv 420), treat this as yuv 420.*/
834                 case V4L2_PIX_FMT_YUYV: 
835                         {
836                                 *ippfmt = RK_FORMAT_YCbCr_420_SP;
837                                 break;
838                         }
839                 case V4L2_PIX_FMT_YVU420:
840                 case V4L2_PIX_FMT_VYUY:
841                 case V4L2_PIX_FMT_YVYU:
842                         {
843                                 *ippfmt = RK_FORMAT_YCrCb_420_SP;
844                                 break;
845                         }
846                 case V4L2_PIX_FMT_RGB565:
847                         {
848                                 *ippfmt = RK_FORMAT_RGB_565;
849                                 break;
850                         }
851                 case V4L2_PIX_FMT_RGB24:
852                         {
853                                 *ippfmt = RK_FORMAT_RGB_888;
854                                 break;
855                         }
856                 default:
857                         goto rk_pixfmt2rgafmt_err;
858         }
859
860         return 0;
861 rk_pixfmt2rgafmt_err:
862         return -1;
863 }
864 #endif
865 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
866 static int rk_camera_scale_crop_pp(struct work_struct *work){
867         struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
868         struct videobuf_buffer *vb = camera_work->vb;
869         struct rk_camera_dev *pcdev = camera_work->pcdev;
870         int vipdata_base;
871         unsigned long int flags;
872         int scale_times,w,h;
873         int src_y_offset;
874         int ret = 0;
875
876         return ret;
877 }
878 #endif
879 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
880 extern rga_service_info rga_service;
881 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
882 extern   void rga_service_session_clear(rga_session *session);
883 static int rk_camera_scale_crop_rga(struct work_struct *work){
884         struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
885         struct videobuf_buffer *vb = camera_work->vb;
886         struct rk_camera_dev *pcdev = camera_work->pcdev;
887         int vipdata_base;
888         unsigned long int flags;
889         int scale_times,w,h;
890         int src_y_offset;
891         struct rga_req req;
892         rga_session session;
893         int rga_times = 3;
894         const struct soc_mbus_pixelfmt *fmt;
895         int ret = 0;
896
897         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
898
899                 return ret;
900         
901 }
902
903 #endif
904 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
905
906 static int rk_camera_scale_crop_ipp(struct work_struct *work)
907 {
908    
909         return 0;    
910 }
911 #endif
912 static void rk_camera_capture_process(struct work_struct *work)
913 {
914     struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);    
915     struct videobuf_buffer *vb = camera_work->vb;    
916     struct rk_camera_dev *pcdev = camera_work->pcdev;    
917     unsigned long flags = 0;    
918     int err = 0;    
919
920         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
921
922
923     if (atomic_read(&pcdev->stop_cif)==true) {
924         err = -EINVAL;
925         goto rk_camera_capture_process_end; 
926     }
927     
928     if (!CAM_WORKQUEUE_IS_EN()) {
929         err = -EINVAL;
930         goto rk_camera_capture_process_end; 
931     }
932     
933     down(&pcdev->zoominfo.sem);
934     if (pcdev->icd_cb.scale_crop_cb){
935         err = (pcdev->icd_cb.scale_crop_cb)(work);
936         }
937     up(&pcdev->zoominfo.sem); 
938     
939     if (pcdev->icd_cb.sensor_cb)        
940         (pcdev->icd_cb.sensor_cb)(vb);    
941
942 rk_camera_capture_process_end:    
943     if (err) {        
944         vb->state = VIDEOBUF_ERROR;    
945     } else {
946         if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
947                 vb->state = VIDEOBUF_DONE;
948                 vb->field_count++;
949                 }
950     }       
951     spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
952     list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
953     spin_unlock_irqrestore(&pcdev->camera_work_lock, flags); 
954     wake_up(&(camera_work->vb->done));     /* ddl@rock-chips.com : v0.3.9 */ 
955     return;
956 }
957
958 static void rk_camera_cifrest_delay(struct work_struct *work)
959 {
960     struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);  
961     struct rk_camera_dev *pcdev = camera_work->pcdev; 
962     unsigned long flags = 0;   
963
964         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
965
966     
967     mdelay(1);
968     rk_camera_cif_reset(pcdev,false);
969
970     spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
971     list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
972     spin_unlock_irqrestore(&pcdev->camera_work_lock, flags); 
973
974     spin_lock_irqsave(&pcdev->lock,flags);
975     if (atomic_read(&pcdev->stop_cif) == false) {
976         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
977         RKCAMERA_DG2("After reset cif, enable capture again!\n");
978     }
979     spin_unlock_irqrestore(&pcdev->lock,flags);
980     return;
981 }
982
983 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
984 {
985     struct rk_camera_dev *pcdev = data;
986     struct rk_camera_work *wk;
987     unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
988
989         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
990
991
992     write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200);  /* clear vip interrupte single  */
993     
994     reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
995     reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
996     reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
997         
998     pcdev->irqinfo.cifirq_idx++;    
999     if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1000         pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1001         RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1002                     reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1003     } else {
1004         pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1005     }
1006     
1007     if(reg_cifctrl & ENABLE_CAPTURE) {
1008         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1009     } 
1010
1011     if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1012         if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1013             if (!list_empty(&pcdev->camera_work_queue)) {
1014                 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1015                 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1016                 list_del_init(&wk->queue);
1017                 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1018                 wk->pcdev = pcdev;                
1019                 queue_work(pcdev->camera_wq, &(wk->work));
1020             }  
1021         }
1022     }
1023     
1024     return IRQ_HANDLED;
1025 }
1026
1027 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1028 {
1029     struct rk_camera_dev *pcdev = data;
1030     struct videobuf_buffer *vb;
1031         struct rk_camera_work *wk;
1032         struct timeval tv;
1033     unsigned long reg_cifctrl;
1034
1035         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1036
1037
1038     reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1039     /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1040     if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {   //frame 0 ready yzm
1041         write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01);  /* clear vip interrupte single  */
1042
1043         pcdev->irqinfo.dmairq_idx++;
1044         if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1045             write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000002);
1046             goto end;
1047         }
1048
1049         if (!pcdev->fps) {
1050             do_gettimeofday(&pcdev->first_tv);            
1051         }
1052         pcdev->fps++;
1053         if (!pcdev->active)
1054             goto end;
1055         if (pcdev->frame_inval>0) {
1056             pcdev->frame_inval--;
1057             rk_videobuf_capture(pcdev->active,pcdev);
1058             goto end;
1059         } else if (pcdev->frame_inval) {
1060             RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1061             pcdev->frame_inval = 0;
1062         }
1063         
1064         if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1065             do_gettimeofday(&tv);            
1066             pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1067                 /(RK30_CAM_FRAME_MEASURE-1);
1068         }
1069         
1070         vb = pcdev->active;
1071         if (!vb) {
1072             printk("no acticve buffer!!!\n");
1073             goto end;
1074         }
1075         
1076         /* ddl@rock-chips.com : this vb may be deleted from queue */
1077         if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1078             list_del_init(&vb->queue);
1079         }
1080         pcdev->active = NULL;
1081         if (!list_empty(&pcdev->capture)) {
1082             pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1083             if (pcdev->active) {
1084                 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);                     
1085                 rk_videobuf_capture(pcdev->active,pcdev);
1086             }
1087         }
1088         if (pcdev->active == NULL) {
1089             RKCAMERA_DG1("video_buf queue is empty!\n");
1090         }
1091
1092         do_gettimeofday(&vb->ts);
1093         if (CAM_WORKQUEUE_IS_EN()) {
1094             if (!list_empty(&pcdev->camera_work_queue)) {
1095                 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1096                 list_del_init(&wk->queue);
1097                 INIT_WORK(&(wk->work), rk_camera_capture_process);
1098                 wk->vb = vb;
1099                 wk->pcdev = pcdev;
1100                 queue_work(pcdev->camera_wq, &(wk->work));
1101             }                                   
1102         } else {
1103             if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1104                 vb->state = VIDEOBUF_DONE;              
1105                 vb->field_count++;
1106             }
1107             wake_up(&vb->done);
1108         }
1109     }
1110
1111 end:
1112     if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1113         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1114     return IRQ_HANDLED;
1115 }
1116
1117 static irqreturn_t rk_camera_irq(int irq, void *data)
1118 {
1119     struct rk_camera_dev *pcdev = data;
1120     unsigned int reg_intstat;
1121
1122         //should set value in cif irq    
1123         static int rec_stop_cif = 0;
1124
1125     spin_lock(&pcdev->lock);
1126
1127
1128     reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1129         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%x\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1130     if (reg_intstat & 0x0200){
1131         rk_camera_cifirq(irq,data);
1132                 if(atomic_read(&pcdev->stop_cif))
1133                         rec_stop_cif ++;
1134                 if(rec_stop_cif){
1135                 debug_printk("receive cif stop request, recevie cif irq,reg_intstat = 0x%x\n",reg_intstat);
1136                 }
1137     }
1138
1139     if (reg_intstat & 0x01){
1140         if(rec_stop_cif == 1){
1141                         pcdev->cif_stopped = true;
1142                         rec_stop_cif = 0;
1143                         write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
1144                         //workaround: disabled capen can't stop cif really,so should reset instead.
1145                         rk_camera_cif_reset(pcdev,false);
1146                         debug_printk("receive cif stop request,recevie dma irq ,reg_intstat = 0x%x\n",reg_intstat);
1147                         wake_up(&pcdev->cif_stop_done);
1148         }else
1149                         rk_camera_dmairq(irq,data);
1150     }
1151
1152 //end:    
1153     spin_unlock(&pcdev->lock);
1154     return IRQ_HANDLED;
1155 }
1156
1157
1158 static void rk_videobuf_release(struct videobuf_queue *vq,
1159                                   struct videobuf_buffer *vb)
1160 {
1161     struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1162     struct soc_camera_device *icd = vq->priv_data;
1163         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1164     struct rk_camera_dev *pcdev = ici->priv;
1165 #if CAMERA_VIDEOBUF_ARM_ACCESS    
1166     struct rk29_camera_vbinfo *vb_info =NULL;
1167 #endif
1168
1169 #ifdef DEBUG
1170
1171         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1172
1173
1174     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1175             vb, vb->baddr, vb->bsize);
1176
1177     switch (vb->state)
1178     {
1179         case VIDEOBUF_ACTIVE:
1180             dev_dbg(&icd->dev, "%s (active)\n", __func__);
1181             break;
1182         case VIDEOBUF_QUEUED:
1183             dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1184             break;
1185         case VIDEOBUF_PREPARED:
1186             dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1187             break;
1188         default:  
1189             dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1190             break;
1191     }
1192 #endif
1193
1194     flush_workqueue(pcdev->camera_wq); 
1195     
1196     rk_videobuf_free(vq, buf);
1197     
1198 #if CAMERA_VIDEOBUF_ARM_ACCESS
1199     if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1200         vb_info = pcdev->vbinfo + vb->i;
1201         
1202         if (vb_info->vir_addr) {
1203             iounmap(vb_info->vir_addr);
1204             release_mem_region(vb_info->phy_addr, vb_info->size);
1205             memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1206         }       
1207                 
1208         }
1209 #endif  
1210 }
1211
1212 static struct videobuf_queue_ops rk_videobuf_ops =
1213 {
1214     .buf_setup      = rk_videobuf_setup,
1215     .buf_prepare    = rk_videobuf_prepare,
1216     .buf_queue      = rk_videobuf_queue,
1217     .buf_release    = rk_videobuf_release,
1218 };
1219
1220 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1221                                       struct soc_camera_device *icd)
1222 {
1223         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1224     struct rk_camera_dev *pcdev = ici->priv;
1225
1226         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1227
1228
1229     /* We must pass NULL as dev pointer, then all pci_* dma operations
1230      * transform to normal dma_* ones. */
1231     videobuf_queue_dma_contig_init(q,
1232                                    &rk_videobuf_ops,
1233                                    ici->v4l2_dev.dev, &pcdev->lock,
1234                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
1235                                    V4L2_FIELD_NONE,
1236                                    sizeof(struct rk_camera_buffer),
1237                                    icd,&(ici->host_lock) );
1238 }
1239
1240 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1241 {
1242     int err = 0,cif;    
1243     struct rk_cif_clk *clk;
1244
1245         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1246
1247
1248     cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1249     if ((cif<0)||(cif>1)) {
1250         RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1251         err = -1;
1252         goto rk_camera_clk_ctrl_end;
1253     } 
1254
1255     clk = &cif_clk[cif];
1256    
1257     if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1258         RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1259         err = -ENOENT;
1260         goto rk_camera_clk_ctrl_end;
1261     }
1262    
1263     //spin_lock(&clk->lock);
1264     if (on && !clk->on) {
1265                 if(CHIP_NAME != 3368)
1266                 clk_prepare_enable(clk->pd_cif);
1267
1268         clk_prepare_enable(clk->aclk_cif);
1269         clk_prepare_enable(clk->hclk_cif);
1270         clk_prepare_enable(clk->cif_clk_in);
1271         clk_prepare_enable(clk->cif_clk_out);
1272         clk_set_rate(clk->cif_clk_out,clk_rate);
1273         clk->on = true;
1274     } else if (!on && clk->on) {
1275                 clk_set_rate(clk->cif_clk_out,36000000);/*just for close clk which base on XIN24M */
1276         clk_disable_unprepare(clk->aclk_cif);
1277         clk_disable_unprepare(clk->hclk_cif);
1278         clk_disable_unprepare(clk->cif_clk_in);
1279                 if(CHIP_NAME == 3126){
1280                         write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
1281                         write_cru_reg(CRU_CLK_OUT, 0x00800080);
1282                 }
1283         clk_disable_unprepare(clk->cif_clk_out);
1284                 if(CHIP_NAME != 3368)
1285                 clk_disable_unprepare(clk->pd_cif);
1286                 
1287                 clk->on = false;
1288     }
1289     //spin_unlock(&clk->lock);
1290 rk_camera_clk_ctrl_end:
1291     return err;
1292 }
1293 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1294 {
1295     /*
1296     * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1297     */
1298
1299         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1300
1301     write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
1302         //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01);    //capture complete interrupt enable
1303     return 0;
1304 }
1305
1306 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1307
1308     /*
1309     * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1310     */
1311         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1312
1313     
1314     return;
1315 }
1316
1317 /* The following two functions absolutely depend on the fact, that
1318  * there can be only one camera on RK28 quick capture interface */
1319 static int rk_camera_add_device(struct soc_camera_device *icd)
1320 {
1321         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1322     struct rk_camera_dev *pcdev = ici->priv;    /*Initialize in rk_camra_prob*/
1323     struct device *control = to_soc_camera_control(icd);
1324     struct v4l2_subdev *sd;
1325     int ret,i,icd_catch;
1326     struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1327     struct v4l2_cropcap cropcap;
1328     struct v4l2_mbus_framefmt mf;
1329     const struct soc_camera_format_xlate *xlate = NULL;
1330
1331         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1332
1333     
1334     mutex_lock(&camera_lock);
1335
1336     if (pcdev->icd) {
1337         ret = -EBUSY;
1338         goto ebusy;
1339     }
1340
1341     RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1342
1343         pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1344     pcdev->active = NULL;
1345     pcdev->icd = NULL;
1346         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1347     pcdev->zoominfo.zoom_rate = 100;
1348     pcdev->fps_timer.istarted = false;
1349         
1350         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1351      * if app havn't dequeue all videobuf before close camera device;
1352         */
1353     INIT_LIST_HEAD(&pcdev->capture);
1354
1355     ret = rk_camera_activate(pcdev,icd);
1356     if (ret)
1357         goto ebusy;
1358     /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe  */
1359     if (control) {              //TRUE in open ,FALSE in kernel start
1360         sd = dev_get_drvdata(control);
1361                 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1362         #if 0
1363         ret = v4l2_subdev_call(sd,core, init, 0);
1364         if (ret)
1365             goto ebusy;
1366         #endif
1367         v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1368         if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1369             memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1370         } else {
1371             xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1372             mf.width = 10000;
1373             mf.height = 10000;
1374             mf.field = V4L2_FIELD_NONE;
1375             mf.code = xlate->code;
1376             mf.reserved[6] = 0xfefe5a5a;
1377             v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1378
1379             pcdev->cropinfo.bounds.left = 0;
1380             pcdev->cropinfo.bounds.top = 0;
1381             pcdev->cropinfo.bounds.width = mf.width;
1382             pcdev->cropinfo.bounds.height = mf.height;
1383         }
1384     }
1385
1386         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1387     pcdev->icd = icd;
1388     pcdev->icd_init = 0;
1389     
1390     icd_catch = 0;
1391     for (i=0; i<2; i++) {
1392         if (pcdev->icd_frmival[i].icd == icd)
1393             icd_catch = 1;
1394         if (pcdev->icd_frmival[i].icd == NULL) {
1395             pcdev->icd_frmival[i].icd = icd;
1396             icd_catch = 1;
1397         }
1398     }
1399     if (icd_catch == 0) {
1400         fival_list = pcdev->icd_frmival[0].fival_list;
1401         fival_nxt = fival_list;
1402         while(fival_nxt != NULL) {
1403             fival_nxt = fival_list->nxt;
1404             kfree(fival_list);
1405             fival_list = fival_nxt;
1406         }
1407         pcdev->icd_frmival[0].icd = icd;
1408         pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1409     }
1410 ebusy:
1411     mutex_unlock(&camera_lock);
1412
1413     return ret;
1414 }
1415 static void rk_camera_remove_device(struct soc_camera_device *icd)
1416 {
1417         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1418     struct rk_camera_dev *pcdev = ici->priv;
1419 #if CAMERA_VIDEOBUF_ARM_ACCESS    
1420     struct rk29_camera_vbinfo *vb_info;
1421     unsigned int i;
1422 #endif 
1423
1424         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1425
1426
1427         mutex_lock(&camera_lock);
1428     BUG_ON(icd != pcdev->icd);
1429
1430     RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1431     
1432     /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1433            stream may be turn on again before close device, if suspend and resume happened. */
1434         /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1435         if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) {       /* ddl@rock-chips.com: v0.3.0x15*/
1436                 rk_camera_s_stream(icd,0);
1437         } 
1438         /* move DEACTIVATE into generic_sensor_s_power*/
1439     /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/
1440     /* if stream off is not been executed,timer is running.*/
1441     if(pcdev->fps_timer.istarted){
1442          hrtimer_cancel(&pcdev->fps_timer.timer);
1443          pcdev->fps_timer.istarted = false;
1444     }
1445     flush_work(&(pcdev->camera_reinit_work.work));
1446         flush_workqueue((pcdev->camera_wq));
1447     
1448         if (pcdev->camera_work) {
1449                 kfree(pcdev->camera_work);
1450                 pcdev->camera_work = NULL;
1451                 pcdev->camera_work_count = 0;
1452         INIT_LIST_HEAD(&pcdev->camera_work_queue);
1453         }
1454         rk_camera_deactivate(pcdev);
1455 #if CAMERA_VIDEOBUF_ARM_ACCESS
1456     if (pcdev->vbinfo) {
1457         vb_info = pcdev->vbinfo;
1458         for (i=0; i<pcdev->vbinfo_count; i++) {
1459             if (vb_info->vir_addr) {
1460                 iounmap(vb_info->vir_addr);
1461                 release_mem_region(vb_info->phy_addr, vb_info->size);
1462                 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1463             }
1464             vb_info++;
1465         }
1466                 kfree(pcdev->vbinfo);
1467                 pcdev->vbinfo = NULL;
1468                 pcdev->vbinfo_count = 0;
1469         }
1470 #endif
1471         pcdev->active = NULL;
1472     pcdev->icd = NULL;
1473     pcdev->icd_cb.sensor_cb = NULL;
1474         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1475         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1476      * if app havn't dequeue all videobuf before close camera device;
1477         */
1478     INIT_LIST_HEAD(&pcdev->capture);
1479
1480         mutex_unlock(&camera_lock);
1481
1482         return;
1483 }
1484 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1485 {
1486     unsigned long bus_flags, camera_flags, common_flags = 0;
1487     unsigned int cif_for = 0;
1488         const struct soc_mbus_pixelfmt *fmt;
1489         int ret = 0;
1490         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1491         struct rk_camera_dev *pcdev = ici->priv;
1492
1493         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1494
1495
1496         fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1497         if (!fmt)
1498                 return -EINVAL;
1499
1500     bus_flags = RK_CAM_BUS_PARAM;
1501         /* If requested data width is supported by the platform, use it */
1502         switch (fmt->bits_per_sample) {
1503         case 10:
1504                 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1505                         return -EINVAL;                 
1506                 break;
1507         case 9:
1508                 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1509                         return -EINVAL;                 
1510                 break;
1511         case 8:
1512                 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1513                         return -EINVAL;                 
1514                 break;
1515         default:
1516                 return -EINVAL;
1517         }
1518         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1519         if (icd->ops->query_bus_param)
1520         camera_flags = icd->ops->query_bus_param(icd);
1521         else
1522                 camera_flags = 0;
1523
1524 /**************yzm************
1525     common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1526     if (!common_flags) {
1527         ret = -EINVAL;
1528         goto RK_CAMERA_SET_BUS_PARAM_END;
1529     }
1530 */
1531 /***************yzm************end*/
1532
1533         
1534         common_flags = camera_flags;
1535     ret = icd->ops->set_bus_param(icd, common_flags);
1536     if (ret < 0)
1537         goto RK_CAMERA_SET_BUS_PARAM_END;
1538
1539     cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1540     
1541     if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1542         if(IS_CIF0()) {
1543                         if(CHIP_NAME == 3368)
1544                         rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1545                         else
1546                                 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1547         } else {
1548                 if(CHIP_NAME == 3368)
1549                         rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1550                         else
1551                                 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1552         }
1553     } else {
1554                 if(IS_CIF0()){
1555                         if(CHIP_NAME == 3368)
1556                                 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1557                         else
1558                                 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1559         } else {
1560                 if(CHIP_NAME == 3368)
1561                                 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1562                         else
1563                                 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1564         }
1565     }
1566     
1567     if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1568         cif_for |= HSY_LOW_ACTIVE;
1569     } else {
1570                 cif_for &= ~HSY_LOW_ACTIVE;
1571     }
1572     if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1573         cif_for |= VSY_HIGH_ACTIVE;
1574     } else {
1575                 cif_for &= ~VSY_HIGH_ACTIVE;
1576     }
1577
1578     // ddl@rock-chips.com : Don't enable capture here, enable in stream_on 
1579     //vip_ctrl_val |= ENABLE_CAPTURE;
1580     write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1581     RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1582
1583 RK_CAMERA_SET_BUS_PARAM_END:
1584         if (ret)
1585         RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1586     return ret;
1587 }
1588
1589 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1590 {
1591 /*    unsigned long bus_flags, camera_flags;*/
1592 /*    int ret;*/
1593
1594         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1595 /**********yzm***********
1596
1597     bus_flags = RK_CAM_BUS_PARAM;
1598         if (icd->ops->query_bus_param) {
1599         camera_flags = icd->ops->query_bus_param(icd);  //generic_sensor_query_bus_param()
1600         } else {
1601                 camera_flags = 0;
1602         }
1603     ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1604
1605     if (ret < 0)
1606         dev_warn(icd->dev.parent,
1607                          "Flags incompatible: camera %lx, host %lx\n",
1608                          camera_flags, bus_flags);
1609
1610     return ret;
1611 *///************yzm **************end
1612         return 0;
1613
1614 }
1615
1616 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1617    {
1618                 .fourcc                 = V4L2_PIX_FMT_NV12,
1619                 .name                   = "YUV420 NV12",
1620                 .bits_per_sample        = 8,
1621                 .packing                = SOC_MBUS_PACKING_1_5X8,
1622                 .order                  = SOC_MBUS_ORDER_LE,
1623         },{
1624                 .fourcc                 = V4L2_PIX_FMT_NV16,
1625                 .name                   = "YUV422 NV16",
1626                 .bits_per_sample        = 8,
1627                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1628                 .order                  = SOC_MBUS_ORDER_LE,
1629         },{
1630                 .fourcc                 = V4L2_PIX_FMT_NV21,
1631                 .name                   = "YUV420 NV21",
1632                 .bits_per_sample        = 8,
1633                 .packing                = SOC_MBUS_PACKING_1_5X8,
1634                 .order                  = SOC_MBUS_ORDER_LE,
1635         },{
1636                 .fourcc                 = V4L2_PIX_FMT_NV61,
1637                 .name                   = "YUV422 NV61",
1638                 .bits_per_sample        = 8,
1639                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1640                 .order                  = SOC_MBUS_ORDER_LE,
1641         },{
1642                 .fourcc                 = V4L2_PIX_FMT_RGB565,
1643                 .name                   = "RGB565",
1644                 .bits_per_sample        = 8,
1645                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1646                 .order                  = SOC_MBUS_ORDER_LE,
1647         },{
1648                 .fourcc                 = V4L2_PIX_FMT_RGB24,
1649                 .name                   = "RGB888",
1650                 .bits_per_sample        = 8,
1651                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1652                 .order                  = SOC_MBUS_ORDER_LE,
1653         }
1654
1655 };
1656
1657 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1658 {
1659         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1660     struct rk_camera_dev *pcdev = ici->priv;
1661     unsigned int cif_fs = 0,cif_crop = 0;
1662     unsigned int cif_fmt_val = read_cif_reg(pcdev->base,CIF_CIF_FOR) | INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN;
1663         
1664         const struct soc_mbus_pixelfmt *fmt;
1665         fmt = soc_mbus_get_fmtdesc(icd_code);
1666
1667         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1668
1669
1670         if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1671                 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1672                         host_pixfmt = V4L2_PIX_FMT_NV12;
1673                 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1674                         host_pixfmt = V4L2_PIX_FMT_NV21;
1675         }
1676     switch (host_pixfmt)
1677     {
1678         case V4L2_PIX_FMT_NV16:
1679             cif_fmt_val &= ~YUV_OUTPUT_422;
1680                     cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1681                     pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1682                     pcdev->pixfmt = host_pixfmt;
1683             break;
1684         case V4L2_PIX_FMT_NV61:
1685                 cif_fmt_val &= ~YUV_OUTPUT_422;
1686                 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1687                 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1688                 pcdev->pixfmt = host_pixfmt;
1689                 break;
1690         case V4L2_PIX_FMT_NV12:
1691             cif_fmt_val |= YUV_OUTPUT_420;
1692                 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1693                         if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1694                                 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1695                         pcdev->pixfmt = host_pixfmt;
1696             break;
1697         case V4L2_PIX_FMT_NV21:
1698                 cif_fmt_val |= YUV_OUTPUT_420;
1699                 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1700                 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1701                         pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1702                 pcdev->pixfmt = host_pixfmt;
1703                 break;
1704             default:   /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1705                         cif_fmt_val |= YUV_OUTPUT_422;
1706                 break;
1707     }
1708     switch (icd_code)
1709     {
1710         case V4L2_MBUS_FMT_UYVY8_2X8:
1711             cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1712             break;
1713         case V4L2_MBUS_FMT_YUYV8_2X8:
1714             cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1715             break;
1716         case V4L2_MBUS_FMT_YVYU8_2X8:
1717                 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1718                 break;
1719         case V4L2_MBUS_FMT_VYUY8_2X8:
1720                 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1721                 break;
1722         default :
1723                         cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1724             break;
1725     }
1726
1727     mdelay(100);
1728     rk_camera_cif_reset(pcdev,true);
1729     
1730     write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
1731     //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200);    /*capture complete interrupt enable*/
1732
1733     write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val);         /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
1734
1735     write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); 
1736     if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1737                 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1738             BUG();      
1739     } else{ /* this is one frame mode*/
1740             cif_crop = (rect->left + (rect->top <<16));
1741             cif_fs      = (rect->width + (rect->height <<16));
1742         }
1743
1744         write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1745         write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1746         write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1747         write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000003);
1748
1749     /*MUST bypass scale */
1750         write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1751     RKCAMERA_DG1("CIF_CIF_CROP:0x%x  CIF_CIF_FS:0x%x  CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val);
1752         return;
1753 }
1754
1755 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1756                                   struct soc_camera_format_xlate *xlate)
1757 {
1758     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1759         struct device *dev = icd->parent;
1760     int formats = 0, ret;
1761         enum v4l2_mbus_pixelcode code;
1762         const struct soc_mbus_pixelfmt *fmt;
1763
1764         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1765
1766
1767         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1768         if (ret < 0)
1769                 /* No more formats */
1770                 return 0;
1771
1772         fmt = soc_mbus_get_fmtdesc(code);
1773         if (!fmt) {
1774                 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1775                 return 0;
1776         }
1777
1778     ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1779     if (ret < 0)
1780         return 0;
1781
1782     switch (code) {
1783         case V4L2_MBUS_FMT_UYVY8_2X8:
1784         case V4L2_MBUS_FMT_YUYV8_2X8:
1785         case V4L2_MBUS_FMT_YVYU8_2X8:
1786         case V4L2_MBUS_FMT_VYUY8_2X8:
1787         {
1788         
1789 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1790                 formats++;
1791                 if (xlate) {
1792                         xlate->host_fmt = &rk_camera_formats[0];
1793                         xlate->code = code;
1794                         xlate++;
1795                         dev_dbg(dev, "Providing format %s using code %d\n",
1796                                 rk_camera_formats[0].name,code);
1797                 }
1798                 
1799                 formats++;
1800                 if (xlate) {
1801                         xlate->host_fmt = &rk_camera_formats[1];
1802                         xlate->code = code;
1803                         xlate++;
1804                         dev_dbg(dev, "Providing format %s using code %d\n",
1805                                 rk_camera_formats[1].name,code);
1806                 }
1807                 
1808                 formats++;
1809                 if (xlate) {
1810                         xlate->host_fmt = &rk_camera_formats[2];
1811                         xlate->code = code;
1812                         xlate++;
1813                         dev_dbg(dev, "Providing format %s using code %d\n",
1814                                 rk_camera_formats[2].name,code);
1815                 } 
1816                 
1817                 formats++;
1818                 if (xlate) {
1819                         xlate->host_fmt = &rk_camera_formats[3];
1820                         xlate->code = code;
1821                         xlate++;
1822                         dev_dbg(dev, "Providing format %s using code %d\n",
1823                                 rk_camera_formats[3].name,code);
1824                 }
1825                 break;  
1826 #else 
1827                 formats++;
1828                 if (xlate) {
1829                         xlate->host_fmt = &rk_camera_formats[4];
1830                         xlate->code = code;
1831                         xlate++;
1832                         dev_dbg(dev, "Providing format %s using code %d\n",
1833                                 rk_camera_formats[4].name,code);
1834                 }
1835                 formats++;
1836                 if (xlate) {
1837                         xlate->host_fmt = &rk_camera_formats[5];
1838                         xlate->code = code;
1839                         xlate++;
1840                         dev_dbg(dev, "Providing format %s using code %d\n",
1841                                 rk_camera_formats[5].name,code);
1842                 }
1843                         break;          
1844 #endif                  
1845         }
1846         default:
1847             break;
1848     }
1849
1850     return formats;
1851 }
1852
1853 static void rk_camera_put_formats(struct soc_camera_device *icd)
1854 {
1855
1856         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1857
1858         return;
1859 }
1860 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1861 {
1862     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1863     int ret=0;
1864
1865         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1866
1867     ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1868     if (ret != 0)
1869         goto end;
1870     /* ddl@rock-chips.com: driver decide the cropping rectangle */
1871     memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1872 end:    
1873     return ret;
1874 }
1875 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1876 {
1877         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1878     struct rk_camera_dev *pcdev = ici->priv;
1879
1880         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1881
1882
1883     spin_lock(&pcdev->cropinfo.lock);
1884     memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1885     spin_unlock(&pcdev->cropinfo.lock);
1886     
1887     return 0;
1888 }
1889 static int rk_camera_set_crop(struct soc_camera_device *icd,
1890                                const struct v4l2_crop *crop)
1891 {
1892         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1893     struct rk_camera_dev *pcdev = ici->priv;
1894
1895         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1896
1897
1898     spin_lock(&pcdev->cropinfo.lock);
1899     memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1900     spin_unlock(&pcdev->cropinfo.lock);
1901     return 0;
1902 }
1903 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1904 {
1905     bool ret = false;
1906
1907         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1908
1909
1910     if (f->fmt.pix.priv == 0xfefe5a5a) {
1911         ret = true;
1912     }   
1913    
1914         if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1915                 ret = true;
1916         } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1917                 ret = true;
1918         } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1919                 ret = true;
1920         } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1921                 ret = true;
1922         } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1923                 ret = true;
1924         } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1925                 ret = true;
1926         }
1927
1928         if (ret == true)
1929                 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1930         return ret;
1931 }
1932 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1933                               struct v4l2_format *f)
1934 {
1935         struct device *dev = icd->parent;
1936     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1937     const struct soc_camera_format_xlate *xlate = NULL;
1938         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1939     struct rk_camera_dev *pcdev = ici->priv;
1940     struct v4l2_pix_format *pix = &f->fmt.pix;
1941     struct v4l2_mbus_framefmt mf;
1942     struct v4l2_rect rect;
1943     int ret,usr_w,usr_h,sensor_w,sensor_h;
1944     int stream_on = 0;
1945     int ratio, bounds_aspect;
1946
1947         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1948
1949         
1950         usr_w = pix->width;
1951         usr_h = pix->height;
1952     
1953     RKCAMERA_DG1("enter width:%d  height:%d\n",usr_w,usr_h);
1954     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1955     if (!xlate) {
1956         dev_err(dev, "Format %x not found\n", pix->pixelformat);
1957         ret = -EINVAL;
1958         goto RK_CAMERA_SET_FMT_END;
1959     }
1960     
1961     /* ddl@rock-chips.com: sensor init code transmit in here after open */
1962     if (pcdev->icd_init == 0) {
1963         v4l2_subdev_call(sd,core, init, 0);
1964         pcdev->icd_init = 1;
1965         return 0;
1966     }
1967     stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1968     if (stream_on & ENABLE_CAPTURE)
1969         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1970
1971     mf.width    = pix->width;
1972     mf.height   = pix->height;
1973     mf.field    = pix->field;
1974     mf.colorspace       = pix->colorspace;
1975     mf.code             = xlate->code;
1976     mf.reserved[0] = pix->priv;              /* ddl@rock-chips.com : v0.3.3 */
1977     mf.reserved[1] = 0;
1978
1979     ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1980     if (mf.code != xlate->code)
1981                 return -EINVAL;                 
1982
1983     if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) && 
1984         (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
1985         bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
1986         if ((mf.width*10/mf.height) != bounds_aspect) {
1987             RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
1988                         usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
1989             
1990             mf.width    = pcdev->cropinfo.bounds.width/4;
1991             mf.height   = pcdev->cropinfo.bounds.height/4;
1992
1993             mf.field    = pix->field;
1994             mf.colorspace       = pix->colorspace;
1995             mf.code             = xlate->code;
1996             mf.reserved[0] = pix->priv; 
1997             mf.reserved[1] = 0;
1998
1999             ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2000             if (mf.code != xlate->code)
2001                 return -EINVAL; 
2002         }
2003     }
2004
2005     sensor_w = mf.width;
2006     sensor_h = mf.height;
2007
2008     ratio = ((mf.width*mf.reserved[1])/100)&(~0x03);      /* 4 align*/
2009     mf.width -= ratio;
2010
2011     ratio = ((ratio*mf.height/mf.width)+1)&(~0x01);       /* 2 align*/
2012     mf.height -= ratio;
2013
2014         if ((mf.width != usr_w) || (mf.height != usr_h)) {
2015         
2016         if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2017                 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2018                 ret = -EINVAL;
2019                 goto RK_CAMERA_SET_FMT_END;
2020         }       
2021         if (unlikely((usr_w <16)||(usr_h < 16))) {
2022                 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2023                 ret = -EINVAL;
2024             goto RK_CAMERA_SET_FMT_END;
2025         }
2026         
2027                 spin_lock(&pcdev->cropinfo.lock);
2028                 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {  
2029             if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {        
2030                 /*Scale + Crop center is for keep aspect ratio unchange*/
2031                 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2032                 pcdev->host_width = ratio*usr_w/10;
2033                 pcdev->host_height = ratio*usr_h/10;
2034                 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2035                 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2036
2037                 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2038                 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2039             } else {    
2040                 /*Scale + crop(user define)*/
2041                 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2042                 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2043                 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2044                 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2045             }
2046
2047             pcdev->host_left &= (~0x01);
2048             pcdev->host_top &= (~0x01);
2049         } else { 
2050             if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2051                 /*Crop Center for cif can work , then scale*/
2052                 pcdev->host_width = mf.width;
2053                 pcdev->host_height = mf.height;
2054                 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2055                 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2056             } else {
2057                 /*Crop center for cif can work + crop(user define), then scale */
2058                 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2059                 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2060                 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2061                 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2062             }
2063
2064             pcdev->host_left &= (~0x01);
2065             pcdev->host_top &= (~0x01);
2066         }
2067         spin_unlock(&pcdev->cropinfo.lock);
2068     } else {
2069         spin_lock(&pcdev->cropinfo.lock);
2070         if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2071             pcdev->host_width = mf.width;
2072             pcdev->host_height = mf.height;
2073             pcdev->host_left = 0;
2074             pcdev->host_top = 0;
2075         } else {
2076             pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2077             pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2078             pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2079             pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2080         }
2081         spin_unlock(&pcdev->cropinfo.lock);
2082     }
2083     
2084     icd->sense = NULL;
2085     if (!ret) {
2086         rect.width = pcdev->host_width;
2087         rect.height = pcdev->host_height;
2088         rect.left = pcdev->host_left;
2089         rect.top = pcdev->host_top;
2090         
2091         down(&pcdev->zoominfo.sem);
2092 #if CIF_DO_CROP   /* this crop is only for digital zoom*/
2093         pcdev->zoominfo.a.c.left = 0;
2094         pcdev->zoominfo.a.c.top = 0;
2095         pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2096         pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2097         pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2098         pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2099         pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2100         pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2101         /*recalculate the CIF width & height*/
2102         rect.width = pcdev->zoominfo.a.c.width ;
2103         rect.height = pcdev->zoominfo.a.c.height;
2104         rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2105         rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2106 #else
2107         pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2108         pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2109         pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2110         pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2111         /*now digital zoom use ipp to do crop and scale*/
2112         if(pcdev->zoominfo.zoom_rate != 100){
2113             pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2114             pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2115         } else {
2116             pcdev->zoominfo.a.c.left = 0;
2117             pcdev->zoominfo.a.c.top = 0;
2118         }
2119         pcdev->zoominfo.vir_width = pcdev->host_width;
2120         pcdev->zoominfo.vir_height = pcdev->host_height;
2121 #endif
2122         up(&pcdev->zoominfo.sem);
2123
2124         /* ddl@rock-chips.com: IPP work limit check */
2125         if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2126             if (usr_w > 0x7f0) {
2127                 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2128                     RKCAMERA_TR("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f));
2129                     ret = -EINVAL;
2130                     goto RK_CAMERA_SET_FMT_END;
2131                 }
2132             } else {
2133                 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2134                     RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2135                     ret = -EINVAL;
2136                     goto RK_CAMERA_SET_FMT_END;
2137                 }
2138             }
2139         }
2140         
2141         RKCAMERA_DG1("%s CIF Host:%dx%d@(%d,%d) Sensor:%dx%d->%dx%d User crop:(%d,%d,%d,%d)in(%d,%d) (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name,
2142                                    pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2143                                    sensor_w,sensor_h,mf.width,mf.height,
2144                                    pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2145                                    pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2146                                    pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2147                                    pix->width, pix->height);
2148                                    
2149         rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
2150         
2151                 if (CAM_IPPWORK_IS_EN()) {
2152                         BUG_ON(pcdev->vipmem_phybase == 0);
2153                 }
2154         pix->width = usr_w;
2155         pix->height = usr_h;
2156         pix->field = mf.field;
2157         pix->colorspace = mf.colorspace;
2158         icd->current_fmt = xlate;   
2159         pcdev->icd_width = mf.width;
2160         pcdev->icd_height = mf.height;
2161     }
2162
2163 RK_CAMERA_SET_FMT_END:
2164     if (stream_on & ENABLE_CAPTURE)
2165         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2166         if (ret)
2167         RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
2168     return ret;
2169 }
2170
2171 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2172                                    struct v4l2_format *f)
2173 {
2174         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2175         struct rk_camera_dev *pcdev = ici->priv;
2176     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2177     const struct soc_camera_format_xlate *xlate;
2178     struct v4l2_pix_format *pix = &f->fmt.pix;
2179     __u32 pixfmt = pix->pixelformat;
2180     int ret,usr_w,usr_h,i;
2181         bool is_capture = rk_camera_fmt_capturechk(f);  /* testing f is in line with the already set*/
2182         bool vipmem_is_overflow = false;
2183     struct v4l2_mbus_framefmt mf;
2184     int bytes_per_line_host;
2185     
2186         usr_w = pix->width;
2187         usr_h = pix->height;
2188     
2189         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2190
2191     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);  
2192     if (!xlate) {
2193         /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2194                 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2195                         (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2196         ret = -EINVAL;
2197         RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2198             (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2199         for (i = 0; i < icd->num_user_formats; i++)
2200                     RKCAMERA_TR("(%c%c%c%c)-%s\n",
2201                     icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2202                         (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2203                         icd->user_formats[i].host_fmt->name);
2204         goto RK_CAMERA_TRY_FMT_END;
2205     }
2206    /* limit to rk29 hardware capabilities */
2207     v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2208               &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2209               pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2210
2211     pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2212                                                     xlate->host_fmt);
2213         if (pix->bytesperline < 0)
2214                 return pix->bytesperline;
2215
2216     /* limit to sensor capabilities */
2217     memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2218         mf.width        = pix->width;
2219         mf.height       = pix->height;
2220         mf.field        = pix->field;
2221         mf.colorspace   = pix->colorspace;
2222         mf.code         = xlate->code;
2223     /* ddl@rock-chips.com : It is query max resolution only. */
2224     if ((usr_w == 10000) && (usr_h == 10000)) {
2225         mf.reserved[6] = 0xfefe5a5a;
2226     }
2227         ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2228         if (ret < 0)
2229                 goto RK_CAMERA_TRY_FMT_END;
2230     
2231         /*query resolution.*/
2232         if((usr_w == 10000) && (usr_h == 10000)) {
2233                 pix->width = mf.width;
2234         pix->height = mf.height;
2235         RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2236                 goto RK_CAMERA_TRY_FMT_END;
2237         } else {
2238         RKCAMERA_DG1("user demand: %dx%d  sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2239         }    
2240             
2241         if ((mf.width != usr_w) || (mf.height != usr_h)) {
2242         bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt); 
2243                 if (is_capture) {
2244                         vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2245                 } else {
2246                         /* Assume preview buffer minimum is 4 */
2247                         vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2248                 }        
2249                 if (vipmem_is_overflow == false) {
2250                         pix->width = usr_w;
2251                         pix->height = usr_h;
2252                 } else {
2253                         /*RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);*/
2254             pix->width = mf.width;
2255             pix->height = mf.height;            
2256                 }
2257         /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2258         #if 0     
2259         if ((mf.width < usr_w) || (mf.height < usr_h)) {
2260             if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2261                 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2262                 pix->width = mf.width;
2263                 pix->height = mf.height;
2264             }
2265         }    
2266         #endif
2267         }
2268         
2269     pix->colorspace     = mf.colorspace;    
2270
2271     switch (mf.field) {
2272         case V4L2_FIELD_ANY:
2273         case V4L2_FIELD_NONE:
2274                 pix->field      = V4L2_FIELD_NONE;
2275                 break;
2276         default:
2277                 /* TODO: support interlaced at least in pass-through mode */
2278                 dev_err(icd->parent, "Field type %d unsupported.\n",
2279                         mf.field);
2280                 goto RK_CAMERA_TRY_FMT_END;
2281         }
2282
2283 RK_CAMERA_TRY_FMT_END:
2284         if (ret<0)
2285         RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
2286     return ret;
2287 }
2288
2289 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2290                                struct v4l2_requestbuffers *p)
2291 {
2292     int i;
2293
2294         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2295
2296
2297     /* This is for locking debugging only. I removed spinlocks and now I
2298      * check whether .prepare is ever called on a linked buffer, or whether
2299      * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2300      * it hadn't triggered */
2301     for (i = 0; i < p->count; i++) {
2302         struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2303                                                            struct rk_camera_buffer, vb);
2304         buf->inwork = 0;
2305         INIT_LIST_HEAD(&buf->vb.queue);
2306     }
2307
2308     return 0;
2309 }
2310
2311 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2312 {
2313     struct soc_camera_device *icd = file->private_data;
2314     struct rk_camera_buffer *buf;
2315
2316         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2317
2318
2319     buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2320                     vb.stream);
2321
2322     poll_wait(file, &buf->vb.done, pt);
2323
2324     if (buf->vb.state == VIDEOBUF_DONE ||
2325             buf->vb.state == VIDEOBUF_ERROR)
2326         return POLLIN|POLLRDNORM;
2327
2328     return 0;
2329 }
2330 /*
2331 *card:  sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2332 *           10          5           1            3              3                3         + 5 < 32           
2333 */
2334
2335 static int rk_camera_querycap(struct soc_camera_host *ici,
2336                                 struct v4l2_capability *cap)
2337 {
2338     struct rk_camera_dev *pcdev = ici->priv;
2339     struct rkcamera_platform_data *new_camera;
2340     char orientation[5];
2341     char fov[9];
2342     int i;
2343
2344         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2345
2346
2347     strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);       
2348     memset(orientation,0x00,sizeof(orientation));
2349
2350     i=0;
2351     new_camera = pcdev->pdata->register_dev_new;
2352     while(new_camera != NULL){
2353         if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2354             sprintf(orientation,"-%d",new_camera->orientation);
2355             sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2356         }
2357         new_camera = new_camera->next_camera;
2358     }
2359     
2360     if (orientation[0] != '-') {
2361         RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2362         if (strstr(dev_name(pcdev->icd->pdev),"front")) 
2363             strcat(cap->card,"-270");
2364         else 
2365             strcat(cap->card,"-90");
2366     } else {
2367         strcat(cap->card,orientation); 
2368     }
2369     
2370     strcat(cap->card,fov);                          /* ddl@rock-chips.com: v0.3.f */
2371     cap->version = RK_CAM_VERSION_CODE;
2372     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2373         cap->reserved[0] = pcdev->pdata->iommu_enabled;
2374         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2375
2376     return 0;
2377 }
2378 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2379 {
2380         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2381     struct rk_camera_dev *pcdev = ici->priv;
2382         struct v4l2_subdev *sd;
2383     int ret = 0;
2384
2385         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2386
2387
2388         mutex_lock(&camera_lock);
2389         if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2390                 rk_camera_s_stream(icd, 0);
2391                 sd = soc_camera_to_subdev(icd);
2392                 v4l2_subdev_call(sd, video, s_stream, 0);
2393                 ret = icd->ops->suspend(icd, state);
2394
2395                 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2396                 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2397                 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2398                 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2399                 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2400                 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2401                 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2402                 
2403                 pcdev->reginfo_suspend.Inval = Reg_Validate;
2404                 rk_camera_deactivate(pcdev);
2405
2406                 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2407         } else {
2408                 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2409         }
2410         mutex_unlock(&camera_lock);
2411     return ret;
2412 }
2413
2414 static int rk_camera_resume(struct soc_camera_device *icd)
2415 {
2416         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2417     struct rk_camera_dev *pcdev = ici->priv;
2418         struct v4l2_subdev *sd;
2419     int ret = 0;
2420
2421         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2422
2423
2424         mutex_lock(&camera_lock);
2425         if ((pcdev->icd == icd) && (icd->ops->resume)) {
2426                 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2427                         rk_camera_activate(pcdev, icd);
2428                         write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2429                         write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2430                         write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2431                         write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2432                         write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2433                         write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2434                         write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2435                         rk_videobuf_capture(pcdev->active,pcdev);
2436                         rk_camera_s_stream(icd, 1);
2437                         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2438                 } else {
2439                         RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2440                         goto rk_camera_resume_end;
2441                 }
2442
2443                 ret = icd->ops->resume(icd);
2444                 sd = soc_camera_to_subdev(icd);
2445                 v4l2_subdev_call(sd, video, s_stream, 1);
2446
2447                 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2448         } else {
2449                 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2450         }
2451
2452 rk_camera_resume_end:
2453         mutex_unlock(&camera_lock);
2454     return ret;
2455 }
2456
2457 static void rk_camera_reinit_work(struct work_struct *work)
2458 {
2459     struct v4l2_subdev *sd;
2460         struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2461         struct rk_camera_dev *pcdev = camera_work->pcdev;
2462     struct v4l2_mbus_framefmt mf;
2463     int index = 0;
2464         unsigned long flags = 0;
2465     int ctrl;
2466
2467         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2468         //return;
2469         
2470     if(pcdev->icd == NULL)
2471         return;
2472     sd = soc_camera_to_subdev(pcdev->icd);
2473         /*dump regs*/
2474         {
2475                 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2476                 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2477                 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2478                 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2479                 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2480                 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2481                 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2482                 if(CHIP_NAME == 3368)
2483                         RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",rk3368_read_cru_reg(CRU_PCLK_REG30));
2484                 else
2485                         RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2486                 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2487                 
2488                 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2489                 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2490         RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2491         RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2492         RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2493         RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2494         RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2495         RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2496         RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2497         }
2498         
2499     ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);          /*ddl@rock-chips.com v0.3.0x13*/
2500     if (pcdev->reinit_times == 1) {
2501         if (ctrl & ENABLE_CAPTURE) {        
2502             RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2503             pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2504             rk_camera_cif_reset(pcdev,false);
2505
2506             
2507             v4l2_subdev_call(sd,core, init, 0); 
2508             
2509             mf.width    = pcdev->icd_width;
2510             mf.height   = pcdev->icd_height;
2511             mf.field    = V4L2_FIELD_NONE;            
2512             mf.code             = pcdev->icd->current_fmt->code;
2513             mf.reserved[0] = 0x5a5afefe;              
2514             mf.reserved[1] = 0;
2515
2516             v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2517             
2518             write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2519         } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) { 
2520             RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2521             pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2522             rk_camera_cif_reset(pcdev,false);
2523             write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2524         }
2525         return;
2526     }
2527     
2528     atomic_set(&pcdev->stop_cif,true);
2529         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2530         RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2531         
2532     if(pcdev->video_vq && pcdev->video_vq->irqlock){
2533         spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2534         for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2535             if (NULL == pcdev->video_vq->bufs[index])
2536                 continue;
2537
2538             if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2539                 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2540                 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2541                 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2542                 printk("wake up video buffer index = %d  !!!\n",index);
2543             }
2544         }
2545         spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags); 
2546     }else{
2547         RKCAMERA_TR("video queue has somthing wrong !!\n");
2548     }
2549
2550         RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2551 }
2552 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2553 {
2554     struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2555         struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2556         struct rk_camera_dev *pcdev = fps_timer->pcdev;
2557     int rec_flag,i;
2558
2559         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2560
2561         RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2562         if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2563                 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2564                             pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2565                 pcdev->camera_reinit_work.pcdev = pcdev;
2566                 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2567         pcdev->reinit_times++;
2568                 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2569         } else if(!pcdev->timer_get_fps) {
2570             pcdev->timer_get_fps = true;
2571             for (i=0; i<2; i++) {
2572             if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2573                 fival_nxt = pcdev->icd_frmival[i].fival_list;                
2574             }
2575         }
2576         
2577         rec_flag = 0;
2578         fival_pre = fival_nxt;
2579         while (fival_nxt != NULL) {
2580
2581             RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control),
2582                 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2583                             (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2584                             fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2585                             fival_nxt->fival.discrete.numerator);
2586             
2587             if (((fival_nxt->fival.pixel_format == pcdev->pixfmt) 
2588                 && (fival_nxt->fival.height == pcdev->icd->user_height)
2589                 && (fival_nxt->fival.width == pcdev->icd->user_width))
2590                 || (fival_nxt->fival.discrete.denominator == 0)) {
2591
2592                 if (fival_nxt->fival.discrete.denominator == 0) {
2593                     fival_nxt->fival.index = 0;
2594                     fival_nxt->fival.width = pcdev->icd->user_width;
2595                     fival_nxt->fival.height= pcdev->icd->user_height;
2596                     fival_nxt->fival.pixel_format = pcdev->pixfmt;
2597                     fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2598                     fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2599                                                     |(pcdev->icd_height);
2600                     fival_nxt->fival.discrete.numerator = 1000000;
2601                     fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2602                 }
2603                 rec_flag = 1;
2604                 fival_rec = fival_nxt;
2605             }
2606             fival_pre = fival_nxt;
2607             fival_nxt = fival_nxt->nxt;            
2608         }
2609
2610         if ((rec_flag == 0) && fival_pre) {
2611             fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2612             if (fival_pre->nxt != NULL) {
2613                 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2614                 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2615                 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2616                 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2617
2618                 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2619                 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2620                                                     |(pcdev->icd_height);
2621                 fival_pre->nxt->fival.discrete.numerator = 1000000;
2622                 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2623                 rec_flag = 1;
2624                 fival_rec = fival_pre->nxt;
2625             }
2626         }
2627         }
2628
2629     if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times))             /*ddl@rock-chips.com v0.3.0x13*/
2630         pcdev->reinit_times = 0;
2631         
2632     pcdev->last_fps = pcdev->fps ;
2633     pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2634     pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2635     /*return HRTIMER_NORESTART;*/
2636     if(pcdev->reinit_times >=2)
2637         return HRTIMER_NORESTART;
2638     else
2639         return HRTIMER_RESTART;
2640 }
2641 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2642 {
2643         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2644     struct rk_camera_dev *pcdev = ici->priv;
2645     int cif_ctrl_val;
2646         int ret;
2647         unsigned long flags;
2648
2649         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);     
2650
2651         WARN_ON(pcdev->icd != icd);
2652
2653         cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2654         if (enable) {
2655                 pcdev->fps = 0;
2656         pcdev->last_fps = 0;
2657         pcdev->frame_interval = 0;
2658                 hrtimer_cancel(&(pcdev->fps_timer.timer));
2659                 pcdev->fps_timer.pcdev = pcdev;
2660         pcdev->timer_get_fps = false;
2661         pcdev->reinit_times  = 0;
2662
2663         spin_lock_irqsave(&pcdev->lock,flags);
2664         atomic_set(&pcdev->stop_cif,false);
2665                 pcdev->cif_stopped = false;
2666         pcdev->irqinfo.cifirq_idx = 0;
2667         pcdev->irqinfo.cifirq_normal_idx = 0;
2668         pcdev->irqinfo.cifirq_abnormal_idx = 0;
2669         pcdev->irqinfo.dmairq_idx = 0;
2670                 
2671                 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200);    /*capture complete interrupt enable*/
2672                 cif_ctrl_val |= ENABLE_CAPTURE;
2673         write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2674         spin_unlock_irqrestore(&pcdev->lock,flags);
2675         printk("%s:stream enable CIF_CIF_CTRL 0x%x\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2676                 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2677         pcdev->fps_timer.istarted = true;
2678         } else {
2679             /*cancel timer before stop cif*/
2680                 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2681         pcdev->fps_timer.istarted = false;
2682         flush_work(&(pcdev->camera_reinit_work.work));
2683         
2684         cif_ctrl_val &= ~ENABLE_CAPTURE;
2685                 spin_lock_irqsave(&pcdev->lock, flags);
2686         //write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2687         atomic_set(&pcdev->stop_cif,true);
2688                 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0); 
2689         spin_unlock_irqrestore(&pcdev->lock, flags);
2690                 
2691                 init_waitqueue_head(&pcdev->cif_stop_done);
2692                 if (wait_event_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(1000)) == 0) {
2693                         RKCAMERA_TR("%s:%d, wait cif stop timeout!",__func__,__LINE__);
2694                         pcdev->cif_stopped = true;
2695                 }
2696
2697                 flush_workqueue((pcdev->camera_wq));
2698                 //msleep(100);
2699         }
2700     /*must be reinit,or will be somthing wrong in irq process.*/
2701     if(enable == false) {
2702         pcdev->active = NULL;
2703         INIT_LIST_HEAD(&pcdev->capture);
2704     }
2705         RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2706         return 0;
2707 }
2708 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2709 {
2710         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2711     struct rk_camera_dev *pcdev = ici->priv;
2712     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2713     struct rk_camera_frmivalenum *fival_list = NULL;
2714     struct v4l2_frmivalenum *fival_head = NULL;
2715     struct rkcamera_platform_data *new_camera;
2716     int i,ret = 0,index;
2717     const struct soc_camera_format_xlate *xlate;
2718     struct v4l2_mbus_framefmt mf;
2719     __u32 pixfmt;
2720
2721         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);     
2722     
2723     index = fival->index & 0x00ffffff;
2724     if ((fival->index & 0xff000000) == 0xff000000) {   /* ddl@rock-chips.com: detect framerate */ 
2725         for (i=0; i<2; i++) {
2726             if (pcdev->icd_frmival[i].icd == icd) {
2727                 fival_list = pcdev->icd_frmival[i].fival_list;            
2728             }
2729         }
2730         
2731         if (fival_list != NULL) {
2732             i = 0;
2733             while (fival_list != NULL) {
2734                 if ((fival->pixel_format == fival_list->fival.pixel_format)
2735                     && (fival->height == fival_list->fival.height) 
2736                     && (fival->width == fival_list->fival.width)) {
2737                     if (i == index)
2738                         break;
2739                     i++;
2740                 }                
2741                 fival_list = fival_list->nxt;                
2742             }
2743             
2744             if ((i==index) && (fival_list != NULL)) {
2745                 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2746             } else {
2747                 ret = -EINVAL;
2748             }
2749         } else {
2750             RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2751             ret = -EINVAL;
2752         }
2753     }  else {  
2754
2755         if (fival_head) {
2756             i = 0;
2757             while (fival_head->width && fival_head->height) {
2758                 if ((fival->pixel_format == fival_head->pixel_format)
2759                     && (fival->height == fival_head->height) 
2760                     && (fival->width == fival_head->width)) {
2761                     if (i == index) {
2762                         break;
2763                     }
2764                     i++;
2765                 }
2766                 fival_head++;  
2767             }
2768
2769             if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2770                 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2771
2772                 pixfmt = fival->pixel_format;     /* ddl@rock-chips.com: v0.3.9 */
2773                 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2774                 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2775                 mf.width        = fival->width;
2776                 mf.height       = fival->height;                
2777                 mf.code         = xlate->code;                
2778
2779                 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2780                 
2781                 fival->reserved[1] = (mf.width<<16)|(mf.height);
2782                 
2783                 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2784                     fival->width, fival->height,
2785                     fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2786                             (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2787                              fival->discrete.denominator,fival->discrete.numerator);                        
2788             } else {
2789                 if (index == 0)
2790                     RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2791                         fival->width,fival->height, 
2792                         fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2793                                     (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2794                                     index);
2795                 else
2796                     RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2797                         fival->width,fival->height, 
2798                         fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2799                                     (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2800                                     index);
2801                 ret = -EINVAL;
2802                 goto rk_camera_enum_frameintervals_end;
2803             }
2804         } else {
2805             i = 0x00;
2806             new_camera = pcdev->pdata->register_dev_new;
2807             while(new_camera != NULL){
2808                 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2809                     i = 0x01;                
2810                     break;
2811                 }
2812                 new_camera = new_camera->next_camera;
2813             }
2814
2815             if (i == 0x00) {
2816                 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2817                     __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2818             } else {
2819
2820                 pixfmt = fival->pixel_format;     /* ddl@rock-chips.com: v0.3.9 */
2821                 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2822                 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2823                 mf.width        = fival->width;
2824                 mf.height       = fival->height;                
2825                 mf.code         = xlate->code;                
2826
2827                 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2828                 
2829                 fival->discrete.numerator= 1000;
2830                 fival->discrete.denominator = 15000;
2831                 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2832                 fival->reserved[1] = (mf.width<<16)|(mf.height);                
2833             }
2834         }
2835     }
2836 rk_camera_enum_frameintervals_end:
2837     return ret;
2838 }
2839
2840 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2841                                                                 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2842 {
2843         struct v4l2_crop a;
2844         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2845         struct rk_camera_dev *pcdev = ici->priv;
2846
2847         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2848
2849
2850 #if CIF_DO_CROP    
2851         unsigned long tmp_cifctrl; 
2852 #endif  
2853
2854         /*change the crop and scale parameters*/
2855         
2856 #if CIF_DO_CROP
2857     a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2858     /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2859     a.c.width = pcdev->host_width*100/zoom_rate;
2860     a.c.width &= ~CROP_ALIGN_BYTES;    
2861     a.c.height = pcdev->host_height*100/zoom_rate;
2862     a.c.height &= ~CROP_ALIGN_BYTES;
2863     a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2864     a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2865     atomic_set(&pcdev->stop_cif,true);
2866     tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2867     write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2868     hrtimer_cancel(&(pcdev->fps_timer.timer));
2869     flush_workqueue((pcdev->camera_wq));
2870     
2871     down(&pcdev->zoominfo.sem);
2872     pcdev->zoominfo.a.c.left = 0;
2873     pcdev->zoominfo.a.c.top = 0;
2874     pcdev->zoominfo.a.c.width = a.c.width;
2875     pcdev->zoominfo.a.c.height = a.c.height;
2876     pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2877     pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2878     pcdev->frame_inval = 1;
2879     write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2880     write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2881     write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2882     write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2883     if(pcdev->active)
2884         rk_videobuf_capture(pcdev->active,pcdev);
2885     if(tmp_cifctrl & ENABLE_CAPTURE)
2886         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2887     up(&pcdev->zoominfo.sem);
2888     
2889     atomic_set(&pcdev->stop_cif,false);
2890     hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2891     RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2892 #else
2893     a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2894     a.c.width = pcdev->host_width*100/zoom_rate;
2895     a.c.width &= ~CROP_ALIGN_BYTES;    
2896     a.c.height = pcdev->host_height*100/zoom_rate;
2897     a.c.height &= ~CROP_ALIGN_BYTES;
2898     a.c.left = (pcdev->host_width - a.c.width)>>1;
2899     a.c.top = (pcdev->host_height - a.c.height)>>1;
2900     
2901     down(&pcdev->zoominfo.sem);
2902     pcdev->zoominfo.a.c.height = a.c.height;
2903     pcdev->zoominfo.a.c.width = a.c.width;
2904     pcdev->zoominfo.a.c.top = a.c.top;
2905     pcdev->zoominfo.a.c.left = a.c.left;
2906     pcdev->zoominfo.vir_width = pcdev->host_width;
2907     pcdev->zoominfo.vir_height= pcdev->host_height;
2908     up(&pcdev->zoominfo.sem);
2909     
2910     RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2911 #endif  
2912
2913         return 0;
2914 }
2915
2916 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2917         struct soc_camera_host_ops *ops, int id)
2918 {
2919
2920         int i;
2921         for (i = 0; i < ops->num_controls; i++)
2922                 if (ops->controls[i].id == id)
2923                         return &ops->controls[i];
2924
2925         return NULL;
2926 }
2927
2928
2929 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2930                                                                 struct v4l2_control *sctrl)
2931 {
2932         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2933         const struct v4l2_queryctrl *qctrl;
2934     struct rk_camera_dev *pcdev = ici->priv;
2935
2936     int ret = 0;
2937
2938         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2939
2940         qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2941         if (!qctrl) {
2942                 ret = -ENOIOCTLCMD;
2943         goto rk_camera_set_ctrl_end;
2944         }
2945
2946         switch (sctrl->id)
2947         {
2948                 case V4L2_CID_ZOOM_ABSOLUTE:
2949                 {
2950                         if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2951                         ret = -EINVAL;
2952                 goto rk_camera_set_ctrl_end;
2953                 }
2954             ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2955                         if (ret == 0) {
2956                                 pcdev->zoominfo.zoom_rate = sctrl->value;
2957             } else { 
2958                 goto rk_camera_set_ctrl_end;
2959             }
2960                         break;
2961                 }
2962                 default:
2963                         ret = -ENOIOCTLCMD;
2964                         break;
2965         }
2966 rk_camera_set_ctrl_end:
2967         return ret;
2968 }
2969
2970 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2971 {
2972     .owner              = THIS_MODULE,
2973     .add                = rk_camera_add_device,
2974     .remove             = rk_camera_remove_device,
2975     .suspend    = rk_camera_suspend,
2976     .resume             = rk_camera_resume,
2977     .enum_frameinervals = rk_camera_enum_frameintervals,
2978     .cropcap    = rk_camera_cropcap,
2979     .set_crop   = rk_camera_set_crop,
2980     .get_crop   = rk_camera_get_crop,
2981     .get_formats        = rk_camera_get_formats, 
2982     .put_formats        = rk_camera_put_formats,
2983     .set_fmt    = rk_camera_set_fmt,
2984     .try_fmt    = rk_camera_try_fmt,
2985     .init_videobuf      = rk_camera_init_videobuf,
2986     .reqbufs    = rk_camera_reqbufs,
2987     .poll               = rk_camera_poll,
2988     .querycap   = rk_camera_querycap,
2989     .set_bus_param      = rk_camera_set_bus_param,
2990     .s_stream = rk_camera_s_stream,   /* ddl@rock-chips.com : Add stream control for host */
2991     .set_ctrl = rk_camera_set_ctrl,
2992     .controls = rk_camera_controls,
2993     .num_controls = ARRAY_SIZE(rk_camera_controls)
2994 };
2995
2996 static int rk_camera_cif_iomux(struct device *dev)
2997 {
2998
2999     struct pinctrl      *pinctrl;
3000     struct pinctrl_state    *state;
3001     int retval = 0;
3002     char state_str[20] = {0};
3003
3004         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3005     strcpy(state_str,"cif_pin_all");
3006
3007         if(CHIP_NAME == 3288){
3008                 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
3009         }else if(CHIP_NAME == 3368){
3010                 //__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0900);
3011                 __raw_writel(((1<<1)|(1<<(1+16))),rk_cif_grf_base+0x0900);
3012         }
3013
3014     /*mux CIF0_CLKOUT*/
3015
3016     pinctrl = devm_pinctrl_get(dev);
3017     if (IS_ERR(pinctrl)) {
3018         printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
3019         return -1;
3020     }
3021     state = pinctrl_lookup_state(pinctrl,
3022                          state_str);
3023     if (IS_ERR(state)){
3024         dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
3025         return -1;
3026         }
3027
3028     if (!IS_ERR(state)) {
3029         retval = pinctrl_select_state(pinctrl, state);
3030         if (retval){
3031             dev_err(dev,
3032                 "%s:could not set %s pins\n",__func__,state_str);
3033                 return -1;
3034
3035                 }
3036     }
3037     return 0;
3038             
3039 }
3040 static int rk_camera_probe(struct platform_device *pdev)
3041 {
3042     struct rk_camera_dev *pcdev;
3043     struct resource *res;
3044     struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3045     int irq,i;
3046     int err = 0;
3047     struct rk_cif_clk *clk=NULL;
3048         struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;
3049
3050         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3051
3052         RKCAMERA_TR("%s version: v%d.%d.%d  Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3053         (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);    
3054
3055     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3056         RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3057         BUG();
3058     }
3059
3060     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3061         RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3062         BUG();
3063     }
3064
3065         rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3066
3067     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3068     irq = platform_get_irq(pdev, 0);
3069
3070         /*      irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3071         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3072         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3073         */
3074     if (!res || irq < 0) {
3075         err = -ENODEV;
3076         goto exit;
3077     }
3078     pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3079     if (!pcdev) {
3080         dev_err(&pdev->dev, "Could not allocate pcdev\n");
3081         err = -ENOMEM;
3082         goto exit_alloc;
3083     }
3084
3085     pcdev->zoominfo.zoom_rate = 100;
3086     pcdev->hostid = pdev->id;        /* get host id*/
3087     #ifdef CONFIG_SOC_RK3028
3088     pcdev->chip_id = rk3028_version_val();
3089     #else
3090     pcdev->chip_id = -1;
3091     #endif
3092
3093         if (IS_CIF0()) {
3094                 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3095         clk = &cif_clk[0];
3096                 if(CHIP_NAME != 3368)
3097                 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3098
3099         cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3100         cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3101         cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3102         cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3103         //spin_lock_init(&cif_clk[0].lock);
3104         cif_clk[0].on = false;
3105         rk_camera_cif_iomux(dev_cif);
3106     } else {
3107         clk = &cif_clk[1];
3108                 if(CHIP_NAME != 3368)
3109                 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0  only */
3110
3111         cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3112         cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3113         cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3114         cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3115         //spin_lock_init(&cif_clk[1].lock);
3116         cif_clk[1].on = false;
3117         rk_camera_cif_iomux(dev_cif);
3118     }
3119
3120         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3121
3122     dev_set_drvdata(&pdev->dev, pcdev);
3123     pcdev->res = res;
3124     pcdev->pdata = pdev->dev.platform_data;             /* ddl@rock-chips.com : Request IO in init function */
3125         if (pcdev->pdata && pcdev->pdata->io_init) {
3126                 
3127         pcdev->pdata->io_init();
3128
3129         if (pcdev->pdata->sensor_mclk == NULL)
3130             pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3131     }
3132
3133     INIT_LIST_HEAD(&pcdev->capture);
3134     INIT_LIST_HEAD(&pcdev->camera_work_queue);
3135     spin_lock_init(&pcdev->lock);
3136     spin_lock_init(&pcdev->camera_work_lock);
3137
3138     memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3139     spin_lock_init(&pcdev->cropinfo.lock);
3140     sema_init(&pcdev->zoominfo.sem,1);
3141
3142     /*
3143      * Request the regions.
3144      */
3145     if(res) {
3146         if (!request_mem_region(res->start, res->end - res->start + 1,
3147                                 RK29_CAM_DRV_NAME)) {
3148             err = -EBUSY;
3149             goto exit_reqmem_vip;
3150         }
3151         pcdev->base = ioremap(res->start, res->end - res->start + 1);
3152         if (pcdev->base == NULL) {
3153             dev_err(pcdev->dev, "ioremap() of registers failed\n");
3154             err = -ENXIO;
3155             goto exit_ioremap_vip;
3156         }
3157     }
3158         
3159     pcdev->irqinfo.irq = irq;
3160     pcdev->dev = &pdev->dev;
3161
3162     /* config buffer address */
3163     /* request irq */
3164     if(irq > 0){
3165                 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, IRQF_DISABLED | IRQF_SHARED , RK29_CAM_DRV_NAME,
3166                           pcdev);
3167         if (err) {
3168             dev_err(pcdev->dev, "Camera interrupt register failed \n");
3169             goto exit_reqirq;
3170         }
3171         }
3172    
3173     if(IS_CIF0()) {
3174         pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3175     } else {
3176         pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3177     }
3178     if (pcdev->camera_wq == NULL) {
3179         RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3180         goto exit_free_irq;
3181     }
3182
3183         pcdev->camera_reinit_work.pcdev = pcdev;
3184         INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3185
3186     for (i=0; i<2; i++) {
3187         pcdev->icd_frmival[i].icd = NULL;
3188         pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3189         
3190     }
3191     pcdev->soc_host.drv_name    = RK29_CAM_DRV_NAME;
3192     pcdev->soc_host.ops         = &rk_soc_camera_host_ops;
3193     pcdev->soc_host.priv                = pcdev;
3194     pcdev->soc_host.v4l2_dev.dev        = &pdev->dev;
3195     pcdev->soc_host.nr          = pdev->id;
3196         debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3197     err = soc_camera_host_register(&pcdev->soc_host);
3198
3199
3200     if (err) {
3201         RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3202         goto exit_free_irq;
3203     }
3204         pcdev->fps_timer.pcdev = pcdev;
3205         hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3206         pcdev->fps_timer.timer.function = rk_camera_fps_func;
3207     pcdev->icd_cb.sensor_cb = NULL;
3208
3209 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3210     pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3211 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3212     pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3213 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3214     pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;     
3215 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3216         pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp; 
3217 #endif
3218     return 0;
3219
3220 exit_free_irq:
3221     
3222     for (i=0; i<2; i++) {
3223         fival_list = pcdev->icd_frmival[i].fival_list;
3224         fival_nxt = fival_list;
3225         while(fival_nxt != NULL) {
3226             fival_nxt = fival_list->nxt;
3227             kfree(fival_list);
3228             fival_list = fival_nxt;
3229         }
3230     }
3231     
3232     free_irq(pcdev->irqinfo.irq, pcdev);
3233         if (pcdev->camera_wq) {
3234                 destroy_workqueue(pcdev->camera_wq);
3235                 pcdev->camera_wq = NULL;
3236         }
3237 exit_reqirq:
3238     iounmap(pcdev->base);
3239 exit_ioremap_vip:
3240     release_mem_region(res->start, res->end - res->start + 1);
3241 exit_reqmem_vip:
3242     if (clk) {
3243                 if(CHIP_NAME != 3368){
3244                         if (clk->pd_cif)
3245                             clk_put(clk->pd_cif);
3246                 }
3247         if (clk->aclk_cif)
3248             clk_put(clk->aclk_cif);
3249         if (clk->hclk_cif)
3250             clk_put(clk->hclk_cif);
3251         if (clk->cif_clk_in)
3252             clk_put(clk->cif_clk_in);
3253         if (clk->cif_clk_out)
3254             clk_put(clk->cif_clk_out);
3255     }
3256     kfree(pcdev);
3257 exit_alloc:
3258
3259 exit:
3260     return err;
3261 }
3262
3263 static int rk_camera_remove(struct platform_device *pdev)
3264 {
3265     struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3266     struct resource *res;
3267     struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3268     int i;
3269
3270         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3271
3272         
3273     free_irq(pcdev->irqinfo.irq, pcdev);
3274
3275         if (pcdev->camera_wq) {
3276                 destroy_workqueue(pcdev->camera_wq);
3277                 pcdev->camera_wq = NULL;
3278         }
3279
3280     for (i=0; i<2; i++) {
3281         fival_list = pcdev->icd_frmival[i].fival_list;
3282         fival_nxt = fival_list;
3283         while(fival_nxt != NULL) {
3284             fival_nxt = fival_list->nxt;
3285             kfree(fival_list);
3286             fival_list = fival_nxt;
3287         }
3288     }
3289
3290     soc_camera_host_unregister(&pcdev->soc_host);
3291
3292     res = pcdev->res;
3293     iounmap((void __iomem*)pcdev->base);
3294     release_mem_region(res->start, res->end - res->start + 1);
3295     if (pcdev->pdata && pcdev->pdata->io_deinit) {         /* ddl@rock-chips.com : Free IO in deinit function */
3296         pcdev->pdata->io_deinit(0);
3297         pcdev->pdata->io_deinit(1);
3298     }
3299
3300     kfree(pcdev);
3301
3302     dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3303
3304     return 0;
3305 }
3306
3307 static struct platform_driver rk_camera_driver =
3308 {
3309     .driver     = {
3310         .name   = RK29_CAM_DRV_NAME,       /*host */      
3311     },
3312     .probe              = rk_camera_probe,
3313     .remove             = (rk_camera_remove),
3314 };
3315
3316 static int rk_camera_init_async(void *unused)
3317 {
3318
3319         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3320     platform_driver_register(&rk_camera_driver);        
3321     return 0;
3322 }
3323
3324 static int __init rk_camera_init(void)
3325 {
3326
3327         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3328
3329     kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3330         
3331     return 0;
3332 }
3333
3334 static void __exit rk_camera_exit(void)
3335 {
3336         debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3337
3338     platform_driver_unregister(&rk_camera_driver);
3339 }
3340
3341 device_initcall_sync(rk_camera_init);
3342 module_exit(rk_camera_exit);
3343
3344 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3345 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3346 MODULE_LICENSE("GPL");