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