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