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