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