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