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