camera: support obtain camera information(facing,orientation)
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk29_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
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/io.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/errno.h>
20 #include <linux/fs.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/mm.h>
24 #include <linux/moduleparam.h>
25 #include <linux/time.h>
26 #include <linux/clk.h>
27 #include <linux/version.h>
28 #include <linux/device.h>
29 #include <linux/platform_device.h>
30 #include <linux/mutex.h>
31 #include <linux/videodev2.h>
32 #include <mach/rk29_camera.h>
33 #include <mach/rk29_iomap.h>
34 #include <mach/iomux.h>
35 #include <media/v4l2-common.h>
36 #include <media/v4l2-dev.h>
37 #include <media/videobuf-dma-contig.h>
38 #include <media/soc_camera.h>
39 #include <media/soc_mediabus.h>
40 #include <mach/rk29-ipp.h>
41
42
43 static int debug;
44 module_param(debug, int, S_IRUGO|S_IWUSR);
45
46 #define dprintk(level, fmt, arg...) do {                        \
47         if (debug >= level)                                     \
48         printk(KERN_WARNING"rk29xx_camera: " fmt , ## arg); } while (0)
49
50 #define RK29CAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
51 #define RK29CAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
52
53 // VIP Reg Offset
54 #define RK29_VIP_AHBR_CTRL                0x00
55 #define RK29_VIP_INT_MASK                 0x04
56 #define RK29_VIP_INT_STS                  0x08
57 #define RK29_VIP_STS                      0x0c
58 #define RK29_VIP_CTRL                     0x10
59 #define RK29_VIP_CAPTURE_F1SA_Y           0x14
60 #define RK29_VIP_CAPTURE_F1SA_UV          0x18
61 #define RK29_VIP_CAPTURE_F1SA_Cr          0x1c
62 #define RK29_VIP_CAPTURE_F2SA_Y           0x20
63 #define RK29_VIP_CAPTURE_F2SA_UV          0x24
64 #define RK29_VIP_CAPTURE_F2SA_Cr          0x28
65 #define RK29_VIP_FB_SR                    0x2c
66 #define RK29_VIP_FS                       0x30
67 #define RK29_VIP_VIPRESERVED              0x34
68 #define RK29_VIP_CROP                     0x38
69 #define RK29_VIP_CRM                      0x3c
70 #define RK29_VIP_RESET                    0x40
71 #define RK29_VIP_L_SFT                    0x44
72
73 //The key register bit descrition
74 // VIP_CTRL Reg
75 #define  DISABLE_CAPTURE              (0x00<<0)
76 #define  ENABLE_CAPTURE               (0x01<<0)
77 #define  HSY_HIGH_ACTIVE              (0x00<<1)
78 #define  HSY_LOW_ACTIVE               (0x01<<1)
79 #define  VIP_CCIR656                  (0x00<<2)
80 #define  VIP_SENSOR                   (0x01<<2)
81 #define  SENSOR_UYVY                  (0x00<<3)
82 #define  SENSOR_YUYV                  (0x01<<3)
83 #define  VIP_YUV                      (0x00<<4)
84 #define  VIP_RAW                      (0x01<<4)
85 #define  CON_OR_PIN                   (0x00<<5)
86 #define  ONEFRAME                     (0x01<<5)
87 #define  VIPREGYUV420                 (0x00<<6)
88 #define  VIPREGYUV422                 (0x01<<6)
89 #define  FIELD0_START                 (0x00<<7)
90 #define  FIELD1_START                 (0x01<<7)
91 #define  CONTINUOUS                   (0x00<<8)
92 #define  PING_PONG                    (0x01<<8)
93 #define  POSITIVE_EDGE                (0x00<<9)
94 #define  NEGATIVE_EDGE                (0x01<<9)
95 #define  VIPREGNTSC                   (0x00<<10)
96 #define  VIPREGPAL                    (0x01<<10)
97 #define  VIP_DATA_LITTLEEND           (0x00<<11)
98 #define  VIP_DATA_BIGEND              (0x01<<11)
99 #define  VSY_LOW_ACTIVE               (0x00<<12)
100 #define  VSY_HIGH_ACTIVE              (0x01<<12)
101 #define  VIP_RAWINPUT_BYPASS          (0x00<<13)
102 #define  VIP_RAWINPUT_POSITIVE_EDGE   (0x01<<13)
103 #define  VIP_RAWINPUT_NEGATIVE_EDGE   (0x02<<13)
104
105 // GRF_SOC_CON0 Reg
106 #define  GRF_SOC_CON0_Reg             0xbc
107 #define  VIP_AXIMASTER                (0x00<<0)
108 #define  VIP_AHBMASTER                (0x01<<2)
109
110 // GRF_OS_REG0
111 #define  GRF_OS_REG0                  0xd0
112 #define  VIP_ACLK_DIV_HCLK_1          (0x00<<0)
113 #define  VIP_ACLK_DIV_HCLK_2          (0x01<<0)
114
115
116 #define MIN(x,y)   ((x<y) ? x: y)
117 #define MAX(x,y)    ((x>y) ? x: y)
118 #define RK29_SENSOR_24MHZ      24           /* MHz */
119 #define RK29_SENSOR_48MHZ      48
120
121 #define write_vip_reg(addr, val)  __raw_writel(val, addr+(rk29_camdev_info_ptr->base))
122 #define read_vip_reg(addr) __raw_readl(addr+(rk29_camdev_info_ptr->base))
123 #define mask_vip_reg(addr, msk, val)    write_vip_reg(addr, (val)|((~(msk))&read_vip_reg(addr)))
124
125 #define write_grf_reg(addr, val)  __raw_writel(val, addr+RK29_GRF_BASE)
126 #define read_grf_reg(addr) __raw_readl(addr+RK29_GRF_BASE)
127 #define mask_grf_reg(addr, msk, val)    write_vip_reg(addr, (val)|((~(msk))&read_vip_reg(addr)))
128
129 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
130 #define CAM_WORKQUEUE_IS_EN()   ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
131                                   || (pcdev->icd_cb.sensor_cb))
132 #define CAM_IPPWORK_IS_EN()     ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))                                  
133 #else
134 #define CAM_WORKQUEUE_IS_EN()   (true)
135 #define CAM_IPPWORK_IS_EN()     ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
136 #endif
137 //Configure Macro
138 /*
139 *            Driver Version Note
140 *v0.0.1 : this driver first support rk2918;
141 *v0.0.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420 
142 *         and V4L2_PIX_FMT_YUV422P;
143 *v0.0.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
144 *v0.0.4 : this driver support digital zoom;
145 */
146 #define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 3)
147
148 /* limit to rk29 hardware capabilities */
149 #define RK29_CAM_BUS_PARAM   (SOCAM_MASTER |\
150                 SOCAM_HSYNC_ACTIVE_HIGH |\
151                 SOCAM_HSYNC_ACTIVE_LOW |\
152                 SOCAM_VSYNC_ACTIVE_HIGH |\
153                 SOCAM_VSYNC_ACTIVE_LOW |\
154                 SOCAM_PCLK_SAMPLE_RISING |\
155                 SOCAM_PCLK_SAMPLE_FALLING|\
156                 SOCAM_DATA_ACTIVE_HIGH |\
157                 SOCAM_DATA_ACTIVE_LOW|\
158                 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
159                 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
160
161 #define RK29_CAM_W_MIN        48
162 #define RK29_CAM_H_MIN        32
163 #define RK29_CAM_W_MAX        3856            /* ddl@rock-chips.com : 10M Pixel */
164 #define RK29_CAM_H_MAX        2764
165 #define RK29_CAM_FRAME_INVAL_INIT 3
166 #define RK29_CAM_FRAME_INVAL_DC 3          /* ddl@rock-chips.com :  */
167
168 #define RK29_CAM_AXI   0
169 #define RK29_CAM_AHB   1
170 #define CONFIG_RK29_CAM_WORK_BUS    RK29_CAM_AXI
171
172 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
173 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
174
175 /* buffer for one video frame */
176 struct rk29_buffer
177 {
178     /* common v4l buffer stuff -- must be first */
179     struct videobuf_buffer vb;
180     enum v4l2_mbus_pixelcode    code;
181     int                 inwork;
182 };
183 enum rk29_camera_reg_state
184 {
185         Reg_Invalidate,
186         Reg_Validate
187 };
188
189 struct rk29_camera_reg
190 {
191         unsigned int VipCtrl;
192         unsigned int VipCrop;
193         unsigned int VipFs;
194         unsigned int VipIntMsk;
195         unsigned int VipCrm;
196         enum rk29_camera_reg_state Inval;
197 };
198 struct rk29_camera_work
199 {
200         struct videobuf_buffer *vb;
201         struct rk29_camera_dev *pcdev;
202         struct work_struct work;
203 };
204 struct rk29_camera_frmivalenum
205 {
206     struct v4l2_frmivalenum fival;
207     struct rk29_camera_frmivalenum *nxt;
208 };
209 struct rk29_camera_frmivalinfo
210 {
211     struct soc_camera_device *icd;
212     struct rk29_camera_frmivalenum *fival_list;
213 };
214 struct rk29_camera_zoominfo
215 {
216     struct semaphore sem;
217     struct v4l2_crop a;
218     int zoom_rate;
219 };
220 struct rk29_camera_dev
221 {
222     struct soc_camera_host      soc_host;
223     struct device               *dev;
224     /* RK2827x is only supposed to handle one camera on its Quick Capture
225      * interface. If anyone ever builds hardware to enable more than
226      * one camera, they will have to modify this driver too */
227     struct soc_camera_device *icd;
228
229         struct clk *aclk_ddr_lcdc;
230         struct clk *aclk_disp_matrix;
231
232         struct clk *hclk_cpu_display;
233         struct clk *vip_slave;
234
235         struct clk *vip_out;
236         struct clk *vip_input;
237         struct clk *vip_bus;
238
239         struct clk *hclk_disp_matrix;
240         struct clk *vip_matrix;
241
242         struct clk *pd_display;
243
244     void __iomem *base;
245         void __iomem *grf_base;
246     int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
247     unsigned int irq;
248         unsigned int fps;
249         unsigned int pixfmt;
250         unsigned int vipmem_phybase;
251         unsigned int vipmem_size;
252         unsigned int vipmem_bsize;
253         int host_width;
254         int host_height;
255
256     struct rk29camera_platform_data *pdata;
257     struct resource             *res;
258
259     struct list_head    capture;
260     struct rk29_camera_zoominfo zoominfo;
261     
262     spinlock_t          lock;
263
264     struct videobuf_buffer      *active;
265         struct rk29_camera_reg reginfo_suspend;
266         struct workqueue_struct *camera_wq;
267         struct rk29_camera_work *camera_work;
268         unsigned int camera_work_count;
269         struct hrtimer fps_timer;
270         struct work_struct camera_reinit_work;
271     int icd_init;
272     rk29_camera_sensor_cb_s icd_cb;
273     struct rk29_camera_frmivalinfo icd_frmival[2];
274 };
275
276 static const struct v4l2_queryctrl rk29_camera_controls[] =
277 {
278         #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
279     {
280         .id             = V4L2_CID_ZOOM_ABSOLUTE,
281         .type           = V4L2_CTRL_TYPE_INTEGER,
282         .name           = "DigitalZoom Control",
283         .minimum        = 100,
284         .maximum        = 300,
285         .step           = 5,
286         .default_value = 100,
287     },
288     #endif
289 };
290
291 static DEFINE_MUTEX(camera_lock);
292 static const char *rk29_cam_driver_description = "RK29_Camera";
293 static struct rk29_camera_dev *rk29_camdev_info_ptr;
294
295 static int rk29_camera_s_stream(struct soc_camera_device *icd, int enable);
296
297
298 /*
299  *  Videobuf operations
300  */
301 static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
302                                unsigned int *size)
303 {
304     struct soc_camera_device *icd = vq->priv_data;
305         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
306     struct rk29_camera_dev *pcdev = ici->priv;
307     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
308                                                 icd->current_fmt->host_fmt);
309
310     dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
311
312         if (bytes_per_line < 0)
313                 return bytes_per_line;
314
315         /* planar capture requires Y, U and V buffers to be page aligned */
316         *size = PAGE_ALIGN(bytes_per_line*icd->user_height);       /* Y pages UV pages, yuv422*/
317         pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line * pcdev->host_height);
318
319
320         if (CAM_WORKQUEUE_IS_EN()) {
321         #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
322         if (CAM_IPPWORK_IS_EN()) 
323         #endif
324         {
325             BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
326                 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
327                         *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
328                 }
329         }
330                 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
331                         kfree(pcdev->camera_work);
332                         pcdev->camera_work = NULL;
333                         pcdev->camera_work_count = 0;
334                 }
335
336                 if (pcdev->camera_work == NULL) {
337                         pcdev->camera_work = kmalloc(sizeof(struct rk29_camera_work)*(*count), GFP_KERNEL);
338                         if (pcdev->camera_work == NULL) {
339                                 RK29CAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
340                                 BUG();
341                         }
342                         pcdev->camera_work_count = *count;
343                 }
344         }
345
346     RK29CAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
347
348     return 0;
349 }
350 static void rk29_videobuf_free(struct videobuf_queue *vq, struct rk29_buffer *buf)
351 {
352     struct soc_camera_device *icd = vq->priv_data;
353
354     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
355             &buf->vb, buf->vb.baddr, buf->vb.bsize);
356
357         /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
358         if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
359                 return;
360
361     if (in_interrupt())
362         BUG();
363     /*
364          * This waits until this buffer is out of danger, i.e., until it is no
365          * longer in STATE_QUEUED or STATE_ACTIVE
366          */
367         //videobuf_waiton(vq, &buf->vb, 0, 0);
368     videobuf_dma_contig_free(vq, &buf->vb);
369     dev_dbg(&icd->dev, "%s freed\n", __func__);
370     buf->vb.state = VIDEOBUF_NEEDS_INIT;
371         return;
372 }
373 static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
374 {
375     struct soc_camera_device *icd = vq->priv_data;
376     struct rk29_buffer *buf;
377     int ret;
378     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
379                                                 icd->current_fmt->host_fmt);
380         if (bytes_per_line < 0)
381                 return bytes_per_line;
382
383     buf = container_of(vb, struct rk29_buffer, vb);
384
385     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
386             vb, vb->baddr, vb->bsize);
387
388     //RK29CAMERA_TR("\n%s..%d..  \n",__FUNCTION__,__LINE__);
389
390     /* Added list head initialization on alloc */
391     WARN_ON(!list_empty(&vb->queue));
392
393     /* This can be useful if you want to see if we actually fill
394      * the buffer with something */
395     //memset((void *)vb->baddr, 0xaa, vb->bsize);
396
397     BUG_ON(NULL == icd->current_fmt);
398
399     if (buf->code    != icd->current_fmt->code ||
400             vb->width   != icd->user_width ||
401             vb->height  != icd->user_height ||
402              vb->field   != field) {
403         buf->code    = icd->current_fmt->code;
404         vb->width   = icd->user_width;
405         vb->height  = icd->user_height;
406         vb->field   = field;
407         vb->state   = VIDEOBUF_NEEDS_INIT;
408     }
409
410     vb->size = bytes_per_line*vb->height;          /* ddl@rock-chips.com : fmt->depth is coorect */
411     if (0 != vb->baddr && vb->bsize < vb->size) {
412         ret = -EINVAL;
413         goto out;
414     }
415
416     if (vb->state == VIDEOBUF_NEEDS_INIT) {
417         ret = videobuf_iolock(vq, vb, NULL);
418         if (ret) {
419             goto fail;
420         }
421         vb->state = VIDEOBUF_PREPARED;
422     }
423     //RK29CAMERA_TR("\n%s..%d.. \n",__FUNCTION__,__LINE__);
424     return 0;
425 fail:
426     rk29_videobuf_free(vq, buf);
427 out:
428     return ret;
429 }
430
431 static inline void rk29_videobuf_capture(struct videobuf_buffer *vb)
432 {
433         unsigned int y_addr,uv_addr;
434         struct rk29_camera_dev *pcdev = rk29_camdev_info_ptr;
435
436     if (vb) {
437                 if (CAM_WORKQUEUE_IS_EN()) {
438                         y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
439                         uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
440
441                         if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
442                                 RK29CAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
443                                                   pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
444                                 BUG();
445                         }
446                 } else {
447                         y_addr = vb->boff;
448                         uv_addr = y_addr + vb->width * vb->height;
449                 }
450         write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, y_addr);
451         write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, uv_addr);
452         write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, y_addr);
453         write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, uv_addr);
454         write_vip_reg(RK29_VIP_FB_SR,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
455     }
456 }
457 /* Locking: Caller holds q->irqlock */
458 static void rk29_videobuf_queue(struct videobuf_queue *vq,
459                                 struct videobuf_buffer *vb)
460 {
461     struct soc_camera_device *icd = vq->priv_data;
462     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
463     struct rk29_camera_dev *pcdev = ici->priv;
464
465     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
466             vb, vb->baddr, vb->bsize);
467
468     vb->state = VIDEOBUF_QUEUED;
469
470         if (list_empty(&pcdev->capture)) {
471                 list_add_tail(&vb->queue, &pcdev->capture);
472         } else {
473                 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
474                         list_add_tail(&vb->queue, &pcdev->capture);
475                 else
476                         BUG();    /* ddl@rock-chips.com : The same videobuffer queue again */
477         }
478     if (!pcdev->active) {
479         pcdev->active = vb;
480         rk29_videobuf_capture(vb);
481     }
482 }
483 static int rk29_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
484 {
485         switch (pixfmt)
486         {
487                 case V4L2_PIX_FMT_NV16:
488         case V4L2_PIX_FMT_YUV422P:
489                 {
490                         *ippfmt = IPP_Y_CBCR_H2V1;
491                         break;
492                 }
493                 case V4L2_PIX_FMT_NV12:
494         case V4L2_PIX_FMT_YUV420:
495                 {
496                         *ippfmt = IPP_Y_CBCR_H2V2;
497                         break;
498                 }
499                 default:
500                         goto rk29_pixfmt2ippfmt_err;
501         }
502
503         return 0;
504 rk29_pixfmt2ippfmt_err:
505         return -1;
506 }
507 static void rk29_camera_capture_process(struct work_struct *work)
508 {
509         struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
510         struct videobuf_buffer *vb = camera_work->vb;
511         struct rk29_camera_dev *pcdev = camera_work->pcdev;
512         struct rk29_ipp_req ipp_req;
513         unsigned long int flags;
514     int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
515     int scale_times,w,h,vipdata_base;
516         
517     /*
518     *ddl@rock-chips.com: 
519     * IPP Dest image resolution is 2047x1088, so scale operation break up some times
520     */
521     if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
522         scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));        
523         scale_times++;
524     } else {
525         scale_times = 1;
526     }
527     
528     memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
529     
530     down(&pcdev->zoominfo.sem);
531     
532     ipp_req.timeout = 100;
533     ipp_req.flag = IPP_ROT_0;    
534     ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
535     ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
536     ipp_req.src_vir_w = pcdev->host_width;
537     rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
538     ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
539     ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
540     ipp_req.dst_vir_w = pcdev->icd->user_width;        
541     rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
542
543     vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
544     src_y_size = pcdev->host_width*pcdev->host_height;
545     dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
546     
547     for (h=0; h<scale_times; h++) {
548         for (w=0; w<scale_times; w++) {
549             
550             src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width 
551                         + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
552                     src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width/2
553                         + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
554
555             dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
556             dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
557
558                 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
559                 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
560                 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
561                 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
562
563                 if (ipp_blit_sync(&ipp_req)) {
564                         spin_lock_irqsave(&pcdev->lock, flags);
565                         vb->state = VIDEOBUF_ERROR;
566                         spin_unlock_irqrestore(&pcdev->lock, flags);
567
568                 RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
569                 RK29CAMERA_TR("widx:%d hidx:%d ",w,h);
570                 RK29CAMERA_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);
571                 RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
572                 RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
573                 RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
574                 RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
575                 RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
576                 RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
577                 RK29CAMERA_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);
578                 RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
579                 
580                         goto do_ipp_err;
581                 }
582         }
583     }
584
585     if (pcdev->icd_cb.sensor_cb)
586         (pcdev->icd_cb.sensor_cb)(vb);
587         
588 do_ipp_err:
589     up(&pcdev->zoominfo.sem);
590     wake_up(&(camera_work->vb->done)); 
591         return;
592 }
593 static irqreturn_t rk29_camera_irq(int irq, void *data)
594 {
595     struct rk29_camera_dev *pcdev = data;
596     struct videobuf_buffer *vb;
597         struct rk29_camera_work *wk;
598
599     read_vip_reg(RK29_VIP_INT_STS);    /* clear vip interrupte single  */
600     /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
601     if (read_vip_reg(RK29_VIP_FB_SR) & 0x01) {
602                 pcdev->fps++;
603                 if (!pcdev->active)
604                         goto RK29_CAMERA_IRQ_END;
605
606         if (pcdev->frame_inval>0) {
607             pcdev->frame_inval--;
608             rk29_videobuf_capture(pcdev->active);
609             goto RK29_CAMERA_IRQ_END;
610         } else if (pcdev->frame_inval) {
611                 RK29CAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
612             pcdev->frame_inval = 0;
613         }
614
615         vb = pcdev->active;
616                 /* ddl@rock-chips.com : this vb may be deleted from queue */
617                 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
618                 list_del_init(&vb->queue);
619                 }
620
621         pcdev->active = NULL;
622         if (!list_empty(&pcdev->capture)) {
623             pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
624                         if (pcdev->active) {
625                                 rk29_videobuf_capture(pcdev->active);
626                         }
627         }
628
629         if (pcdev->active == NULL) {
630                         RK29CAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
631         }
632
633                 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
634                 vb->state = VIDEOBUF_DONE;
635                 do_gettimeofday(&vb->ts);
636                 vb->field_count++;
637                 }
638
639                 if (CAM_WORKQUEUE_IS_EN()) {
640                         wk = pcdev->camera_work + vb->i;
641                         INIT_WORK(&(wk->work), rk29_camera_capture_process);
642                         wk->vb = vb;
643                         wk->pcdev = pcdev;
644                         queue_work(pcdev->camera_wq, &(wk->work));
645                 } else {                    
646                         wake_up(&vb->done);
647                 }
648     }
649
650 RK29_CAMERA_IRQ_END:
651     return IRQ_HANDLED;
652 }
653
654
655 static void rk29_videobuf_release(struct videobuf_queue *vq,
656                                   struct videobuf_buffer *vb)
657 {
658     struct rk29_buffer *buf = container_of(vb, struct rk29_buffer, vb);
659     struct soc_camera_device *icd = vq->priv_data;
660     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
661     struct rk29_camera_dev *pcdev = ici->priv;
662 #ifdef DEBUG
663     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
664             vb, vb->baddr, vb->bsize);
665
666     switch (vb->state)
667     {
668         case VIDEOBUF_ACTIVE:
669             dev_dbg(&icd->dev, "%s (active)\n", __func__);
670             break;
671         case VIDEOBUF_QUEUED:
672             dev_dbg(&icd->dev, "%s (queued)\n", __func__);
673             break;
674         case VIDEOBUF_PREPARED:
675             dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
676             break;
677         default:  
678             dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
679             break;
680     }
681 #endif  
682         if (vb == pcdev->active) {
683                 RK29CAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
684                 interruptible_sleep_on_timeout(&vb->done, 100);
685                 RK29CAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
686         }
687     rk29_videobuf_free(vq, buf);
688 }
689
690 static struct videobuf_queue_ops rk29_videobuf_ops =
691 {
692     .buf_setup      = rk29_videobuf_setup,
693     .buf_prepare    = rk29_videobuf_prepare,
694     .buf_queue      = rk29_videobuf_queue,
695     .buf_release    = rk29_videobuf_release,
696 };
697
698 static void rk29_camera_init_videobuf(struct videobuf_queue *q,
699                                       struct soc_camera_device *icd)
700 {
701     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
702     struct rk29_camera_dev *pcdev = ici->priv;
703
704     /* We must pass NULL as dev pointer, then all pci_* dma operations
705      * transform to normal dma_* ones. */
706     videobuf_queue_dma_contig_init(q,
707                                    &rk29_videobuf_ops,
708                                    ici->v4l2_dev.dev, &pcdev->lock,
709                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
710                                    V4L2_FIELD_NONE,
711                                    sizeof(struct rk29_buffer),
712                                    icd,&icd->video_lock);
713 }
714 static int rk29_camera_activate(struct rk29_camera_dev *pcdev, struct soc_camera_device *icd)
715 {
716     unsigned long sensor_bus_flags = SOCAM_MCLK_24MHZ;
717     struct clk *parent;
718
719     RK29CAMERA_DG("%s..%d.. \n",__FUNCTION__,__LINE__);
720     if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix ||  !pcdev->hclk_cpu_display ||
721                 !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display ||
722                 IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) ||  IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) ||
723                 IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus))  {
724
725         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
726         goto RK29_CAMERA_ACTIVE_ERR;
727     }
728
729         if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix ||
730                 IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix))  {
731
732         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n");
733         goto RK29_CAMERA_ACTIVE_ERR;
734     }
735
736         clk_enable(pcdev->pd_display);
737
738         clk_enable(pcdev->aclk_ddr_lcdc);
739         clk_enable(pcdev->aclk_disp_matrix);
740
741         clk_enable(pcdev->hclk_cpu_display);
742         clk_enable(pcdev->vip_slave);
743
744 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
745         clk_enable(pcdev->hclk_disp_matrix);
746         clk_enable(pcdev->vip_matrix);
747 #endif
748
749         clk_enable(pcdev->vip_input);
750         clk_enable(pcdev->vip_bus);
751
752     //if (icd->ops->query_bus_param)                                                  /* ddl@rock-chips.com : Query Sensor's xclk */
753         //sensor_bus_flags = icd->ops->query_bus_param(icd);
754
755     if (sensor_bus_flags & SOCAM_MCLK_48MHZ) {
756         parent = clk_get(NULL, "clk48m");
757         if (!parent || IS_ERR(parent))
758              goto RK29_CAMERA_ACTIVE_ERR;
759     } else if (sensor_bus_flags & SOCAM_MCLK_27MHZ) {
760         parent = clk_get(NULL, "extclk");
761         if (!parent || IS_ERR(parent))
762              goto RK29_CAMERA_ACTIVE_ERR;
763     } else {
764         parent = clk_get(NULL, "xin24m");
765         if (!parent || IS_ERR(parent))
766              goto RK29_CAMERA_ACTIVE_ERR;
767     }
768
769     clk_set_parent(pcdev->vip_out, parent);
770
771     clk_enable(pcdev->vip_out);
772     rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_VIP_CLKOUT);
773     ndelay(10);
774
775 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
776         write_grf_reg(GRF_SOC_CON0_Reg, read_grf_reg(GRF_SOC_CON0_Reg)|VIP_AHBMASTER);  //VIP Config to AHB
777         write_grf_reg(GRF_OS_REG0, read_grf_reg(GRF_OS_REG0)&(~VIP_ACLK_DIV_HCLK_2));   //aclk:hclk = 1:1
778 #else
779         write_grf_reg(GRF_SOC_CON0_Reg, read_grf_reg(GRF_SOC_CON0_Reg)&(~VIP_AHBMASTER));  //VIP Config to AXI
780     write_grf_reg(GRF_OS_REG0, read_grf_reg(GRF_OS_REG0)|VIP_ACLK_DIV_HCLK_2);   //aclk:hclk = 2:1
781 #endif
782         ndelay(10);
783
784     write_vip_reg(RK29_VIP_RESET, 0x76543210);  /* ddl@rock-chips.com : vip software reset */
785     udelay(10);
786
787     write_vip_reg(RK29_VIP_AHBR_CTRL, 0x07);   /* ddl@rock-chips.com : vip ahb burst 16 */
788     write_vip_reg(RK29_VIP_INT_MASK, 0x01);    //capture complete interrupt enable
789     write_vip_reg(RK29_VIP_CRM,  0x00000000);  //Y/CB/CR color modification
790
791     return 0;
792 RK29_CAMERA_ACTIVE_ERR:
793     return -ENODEV;
794 }
795
796 static void rk29_camera_deactivate(struct rk29_camera_dev *pcdev)
797 {
798     //pcdev->active = NULL;
799
800     write_vip_reg(RK29_VIP_CTRL, 0);
801     read_vip_reg(RK29_VIP_INT_STS);             //clear vip interrupte single
802
803     rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_GPIO1B4);
804     clk_disable(pcdev->vip_out);
805
806         clk_disable(pcdev->vip_input);
807         clk_disable(pcdev->vip_bus);
808
809 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
810         clk_disable(pcdev->hclk_disp_matrix);
811         clk_disable(pcdev->vip_matrix);
812 #endif
813
814         clk_disable(pcdev->hclk_cpu_display);
815         clk_disable(pcdev->vip_slave);
816
817         clk_disable(pcdev->aclk_ddr_lcdc);
818         clk_disable(pcdev->aclk_disp_matrix);
819
820         clk_disable(pcdev->pd_display);
821     return;
822 }
823
824 /* The following two functions absolutely depend on the fact, that
825  * there can be only one camera on RK28 quick capture interface */
826 static int rk29_camera_add_device(struct soc_camera_device *icd)
827 {
828     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
829     struct rk29_camera_dev *pcdev = ici->priv;
830     struct device *control = to_soc_camera_control(icd);
831     struct v4l2_subdev *sd;
832     int ret,i,icd_catch;
833     struct rk29_camera_frmivalenum *fival_list,*fival_nxt;
834     
835     mutex_lock(&camera_lock);
836
837     if (pcdev->icd) {
838         ret = -EBUSY;
839         goto ebusy;
840     }
841
842     dev_info(&icd->dev, "RK29 Camera driver attached to camera%d(%s)\n",
843              icd->devnum,dev_name(icd->pdev));
844
845         pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
846     pcdev->active = NULL;
847     pcdev->icd = NULL;
848         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
849     pcdev->zoominfo.zoom_rate = 100;
850         
851         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
852      * if app havn't dequeue all videobuf before close camera device;
853         */
854     INIT_LIST_HEAD(&pcdev->capture);
855
856     ret = rk29_camera_activate(pcdev,icd);
857     if (ret)
858         goto ebusy;
859
860     /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe  */
861     if (control) {
862         sd = dev_get_drvdata(control);
863                 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
864         #if 0
865         ret = v4l2_subdev_call(sd,core, init, 0);
866         if (ret)
867             goto ebusy;
868         #endif
869         v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
870     }
871     
872     pcdev->icd = icd;
873     pcdev->icd_init = 0;
874
875     icd_catch = 0;
876     for (i=0; i<2; i++) {
877         if (pcdev->icd_frmival[i].icd == icd)
878             icd_catch = 1;
879         if (pcdev->icd_frmival[i].icd == NULL) {
880             pcdev->icd_frmival[i].icd = icd;
881             icd_catch = 1;
882         }
883     }
884
885     if (icd_catch == 0) {
886         fival_list = pcdev->icd_frmival[0].fival_list;
887         fival_nxt = fival_list;
888         while(fival_nxt != NULL) {
889             fival_nxt = fival_list->nxt;
890             kfree(fival_list);
891             fival_list = fival_nxt;
892         }
893         pcdev->icd_frmival[0].icd = icd;
894         pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk29_camera_frmivalenum),GFP_KERNEL);
895     }
896 ebusy:
897     mutex_unlock(&camera_lock);
898
899     return ret;
900 }
901 static void rk29_camera_remove_device(struct soc_camera_device *icd)
902 {
903     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
904     struct rk29_camera_dev *pcdev = ici->priv;
905         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
906
907         mutex_lock(&camera_lock);
908     BUG_ON(icd != pcdev->icd);
909
910     dev_info(&icd->dev, "RK29 Camera driver detached from camera%d(%s)\n",
911              icd->devnum,dev_name(icd->pdev));
912
913         /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
914            stream may be turn on again before close device, if suspend and resume happened. */
915         if (read_vip_reg(RK29_VIP_CTRL) & ENABLE_CAPTURE) {
916                 rk29_camera_s_stream(icd,0);
917         }
918
919     v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
920         rk29_camera_deactivate(pcdev);
921
922         if (pcdev->camera_work) {
923                 kfree(pcdev->camera_work);
924                 pcdev->camera_work = NULL;
925                 pcdev->camera_work_count = 0;
926         }
927
928         pcdev->active = NULL;
929     pcdev->icd = NULL;
930     pcdev->icd_cb.sensor_cb = NULL;
931         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
932         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
933      * if app havn't dequeue all videobuf before close camera device;
934         */
935     INIT_LIST_HEAD(&pcdev->capture);
936
937         mutex_unlock(&camera_lock);
938         RK29CAMERA_DG("%s exit\n",__FUNCTION__);
939
940         return;
941 }
942 static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
943 {
944     unsigned long bus_flags, camera_flags, common_flags;
945     unsigned int vip_ctrl_val = 0;
946         const struct soc_mbus_pixelfmt *fmt;
947         int ret = 0;
948
949     RK29CAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
950
951         fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
952         if (!fmt)
953                 return -EINVAL;
954
955     bus_flags = RK29_CAM_BUS_PARAM;
956         /* If requested data width is supported by the platform, use it */
957         switch (fmt->bits_per_sample) {
958         case 10:
959                 if (!(bus_flags & SOCAM_DATAWIDTH_10))
960                         return -EINVAL;                 
961                 break;
962         case 9:
963                 if (!(bus_flags & SOCAM_DATAWIDTH_9))
964                         return -EINVAL;                 
965                 break;
966         case 8:
967                 if (!(bus_flags & SOCAM_DATAWIDTH_8))
968                         return -EINVAL;                 
969                 break;
970         default:
971                 return -EINVAL;
972         }
973     
974         if (icd->ops->query_bus_param)
975         camera_flags = icd->ops->query_bus_param(icd);
976         else
977                 camera_flags = 0;
978
979     common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
980     if (!common_flags) {
981         ret = -EINVAL;
982         goto RK29_CAMERA_SET_BUS_PARAM_END;
983     }
984
985     ret = icd->ops->set_bus_param(icd, common_flags);
986     if (ret < 0)
987         goto RK29_CAMERA_SET_BUS_PARAM_END;
988
989     vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL);
990     if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
991         vip_ctrl_val |= NEGATIVE_EDGE;
992     } else {
993                 vip_ctrl_val &= ~NEGATIVE_EDGE;
994     }
995     if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
996         vip_ctrl_val |= HSY_LOW_ACTIVE;
997     } else {
998                 vip_ctrl_val &= ~HSY_LOW_ACTIVE;
999     }
1000     if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1001         vip_ctrl_val |= VSY_HIGH_ACTIVE;
1002     } else {
1003                 vip_ctrl_val &= ~VSY_HIGH_ACTIVE;
1004     }
1005
1006     /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1007     //vip_ctrl_val |= ENABLE_CAPTURE;
1008
1009     write_vip_reg(RK29_VIP_CTRL, vip_ctrl_val);
1010     RK29CAMERA_DG("%s..ctrl:0x%x CtrReg=%x AXI_AHB:0x%x aclk_hclk:0x%x \n",__FUNCTION__,vip_ctrl_val,read_vip_reg(RK29_VIP_CTRL),
1011                 read_grf_reg(GRF_SOC_CON0_Reg)&VIP_AHBMASTER, read_grf_reg(GRF_OS_REG0)&VIP_ACLK_DIV_HCLK_2);
1012
1013 RK29_CAMERA_SET_BUS_PARAM_END:
1014         if (ret)
1015         RK29CAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1016     return ret;
1017 }
1018
1019 static int rk29_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1020 {
1021     unsigned long bus_flags, camera_flags;
1022     int ret;
1023
1024     bus_flags = RK29_CAM_BUS_PARAM;
1025         if (icd->ops->query_bus_param) {
1026         camera_flags = icd->ops->query_bus_param(icd);
1027         } else {
1028                 camera_flags = 0;
1029         }
1030     ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1031
1032     if (ret < 0)
1033         dev_warn(icd->dev.parent,
1034                          "Flags incompatible: camera %lx, host %lx\n",
1035                          camera_flags, bus_flags);
1036     return ret;
1037 }
1038
1039 static const struct soc_mbus_pixelfmt rk29_camera_formats[] = {
1040    {
1041                 .fourcc                 = V4L2_PIX_FMT_NV12,
1042                 .name                   = "YUV420 NV12",
1043                 .bits_per_sample        = 8,
1044                 .packing                = SOC_MBUS_PACKING_1_5X8,
1045                 .order                  = SOC_MBUS_ORDER_LE,
1046         },{
1047                 .fourcc                 = V4L2_PIX_FMT_NV16,
1048                 .name                   = "YUV422 NV16",
1049                 .bits_per_sample        = 8,
1050                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1051                 .order                  = SOC_MBUS_ORDER_LE,
1052         },{
1053                 .fourcc                 = V4L2_PIX_FMT_YUV420,
1054                 .name                   = "NV12(v0.0.1)",
1055                 .bits_per_sample        = 8,
1056                 .packing                = SOC_MBUS_PACKING_1_5X8,
1057                 .order                  = SOC_MBUS_ORDER_LE,
1058         },{
1059                 .fourcc                 = V4L2_PIX_FMT_YUV422P,
1060                 .name                   = "NV16(v0.0.1)",
1061                 .bits_per_sample        = 8,
1062                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1063                 .order                  = SOC_MBUS_ORDER_LE,
1064         }
1065 };
1066
1067 static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1068 {
1069         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1070     struct rk29_camera_dev *pcdev = ici->priv;
1071     unsigned int vip_fs = 0,vip_crop = 0;
1072     unsigned int vip_ctrl_val = VIP_SENSOR|ONEFRAME|DISABLE_CAPTURE;
1073
1074     switch (host_pixfmt)
1075     {
1076         case V4L2_PIX_FMT_NV16:
1077         case V4L2_PIX_FMT_YUV422P:  /* ddl@rock-chips.com: V4L2_PIX_FMT_YUV422P is V4L2_PIX_FMT_NV16 actually in 0.0.1 driver */
1078             vip_ctrl_val |= VIPREGYUV422;
1079                         pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
1080                         pcdev->pixfmt = host_pixfmt;
1081             break;
1082         case V4L2_PIX_FMT_NV12:
1083         case V4L2_PIX_FMT_YUV420:   /* ddl@rock-chips.com: V4L2_PIX_FMT_YUV420 is V4L2_PIX_FMT_NV12 actually in 0.0.1 driver */
1084             vip_ctrl_val |= VIPREGYUV420;
1085                         if (pcdev->frame_inval != RK29_CAM_FRAME_INVAL_INIT)
1086                                 pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
1087                         pcdev->pixfmt = host_pixfmt;
1088             break;
1089         default:                                                                                /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1090             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422);
1091             break;
1092     }
1093
1094     switch (icd_code)
1095     {
1096         case V4L2_MBUS_FMT_UYVY8_2X8:
1097             vip_ctrl_val |= SENSOR_UYVY;
1098             break;
1099         case V4L2_MBUS_FMT_YUYV8_2X8:
1100             vip_ctrl_val |= SENSOR_YUYV;
1101             break;
1102         default :
1103             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & SENSOR_YUYV);
1104             break;
1105     }
1106
1107     write_vip_reg(RK29_VIP_CTRL, vip_ctrl_val);         /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
1108
1109     read_vip_reg(RK29_VIP_INT_STS);                     /* clear vip interrupte single  */
1110
1111     if (vip_ctrl_val & ONEFRAME)  {
1112         vip_crop = ((rect->left<<16) + rect->top);
1113         vip_fs  = (((rect->width + rect->left)<<16) + (rect->height+rect->top));
1114     } else if (vip_ctrl_val & PING_PONG) {
1115         BUG();
1116     }
1117
1118     write_vip_reg(RK29_VIP_CROP, vip_crop);
1119     write_vip_reg(RK29_VIP_FS, vip_fs);
1120
1121     write_vip_reg(RK29_VIP_FB_SR,  0x00000003);
1122
1123         pcdev->host_width = rect->width;
1124         pcdev->host_height = rect->height;
1125
1126     RK29CAMERA_DG("%s.. crop:0x%x fs:0x%x ctrl:0x%x CtrlReg:0x%x\n",__FUNCTION__,vip_crop,vip_fs,vip_ctrl_val,read_vip_reg(RK29_VIP_CTRL));
1127         return;
1128 }
1129
1130 static int rk29_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1131                                   struct soc_camera_format_xlate *xlate)
1132 {
1133     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1134     struct device *dev = icd->dev.parent;
1135     int formats = 0, ret;
1136         enum v4l2_mbus_pixelcode code;
1137         const struct soc_mbus_pixelfmt *fmt;
1138
1139         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1140         if (ret < 0)
1141                 /* No more formats */
1142                 return 0;
1143
1144         fmt = soc_mbus_get_fmtdesc(code);
1145         if (!fmt) {
1146                 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1147                 return 0;
1148         }
1149
1150     ret = rk29_camera_try_bus_param(icd, fmt->bits_per_sample);
1151     if (ret < 0)
1152         return 0;
1153
1154     switch (code) {
1155         case V4L2_MBUS_FMT_UYVY8_2X8:
1156         case V4L2_MBUS_FMT_YUYV8_2X8:
1157             formats++;
1158             if (xlate) {
1159                 xlate->host_fmt = &rk29_camera_formats[0];
1160                 xlate->code     = code;
1161                 xlate++;
1162                 dev_dbg(dev, "Providing format %s using code %d\n",
1163                         rk29_camera_formats[0].name,code);
1164             }
1165
1166             formats++;
1167             if (xlate) {
1168                 xlate->host_fmt = &rk29_camera_formats[1];
1169                 xlate->code     = code;
1170                 xlate++;
1171                 dev_dbg(dev, "Providing format %s using code %d\n",
1172                         rk29_camera_formats[1].name,code);
1173             }
1174
1175             formats++;
1176             if (xlate) {
1177                 xlate->host_fmt = &rk29_camera_formats[2];
1178                 xlate->code     = code;
1179                 xlate++;
1180                 dev_dbg(dev, "Providing format %s using code %d\n",
1181                         rk29_camera_formats[2].name,code);
1182             } 
1183
1184             formats++;
1185             if (xlate) {
1186                 xlate->host_fmt = &rk29_camera_formats[3];
1187                 xlate->code     = code;
1188                 xlate++;
1189                 dev_dbg(dev, "Providing format %s using code %d\n",
1190                         rk29_camera_formats[3].name,code);;
1191             }
1192                         break;          
1193         default:
1194             break;
1195     }
1196
1197     return formats;
1198 }
1199
1200 static void rk29_camera_put_formats(struct soc_camera_device *icd)
1201 {
1202         return;
1203 }
1204
1205 static int rk29_camera_set_crop(struct soc_camera_device *icd,
1206                                struct v4l2_crop *a)
1207 {
1208     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1209         struct v4l2_mbus_framefmt mf;
1210         u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1211     int ret;
1212
1213     ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1214     if (ret < 0)
1215         return ret;
1216
1217     if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height)))  {
1218
1219         mf.width = a->c.left + a->c.width;
1220         mf.height = a->c.top + a->c.height;
1221
1222         v4l_bound_align_image(&mf.width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
1223             &mf.height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
1224             fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
1225
1226         ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1227         if (ret < 0)
1228             return ret;
1229     }
1230
1231     rk29_camera_setup_format(icd, fourcc, mf.code, &a->c);
1232
1233     icd->user_width = mf.width;
1234     icd->user_height = mf.height;
1235
1236     return 0;
1237 }
1238
1239 static int rk29_camera_set_fmt(struct soc_camera_device *icd,
1240                               struct v4l2_format *f)
1241 {
1242     struct device *dev = icd->dev.parent;
1243     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1244     const struct soc_camera_format_xlate *xlate = NULL;
1245         struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
1246     struct rk29_camera_dev *pcdev = ici->priv;
1247     struct v4l2_pix_format *pix = &f->fmt.pix;
1248     struct v4l2_mbus_framefmt mf;
1249     struct v4l2_rect rect;
1250     int ret,usr_w,usr_h;
1251     int stream_on = 0;
1252
1253         usr_w = pix->width;
1254         usr_h = pix->height;
1255     RK29CAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
1256
1257     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1258     if (!xlate) {
1259         dev_err(dev, "Format %x not found\n", pix->pixelformat);
1260         ret = -EINVAL;
1261         goto RK29_CAMERA_SET_FMT_END;
1262     }
1263     
1264     /* ddl@rock-chips.com: sensor init code transmit in here after open */
1265     if (pcdev->icd_init == 0) {
1266         v4l2_subdev_call(sd,core, init, 0);        
1267         pcdev->icd_init = 1;
1268     }
1269
1270     stream_on = read_vip_reg(RK29_VIP_CTRL);
1271     if (stream_on & ENABLE_CAPTURE)
1272         write_vip_reg(RK29_VIP_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1273     
1274         mf.width        = pix->width;
1275         mf.height       = pix->height;
1276         mf.field        = pix->field;
1277         mf.colorspace   = pix->colorspace;
1278         mf.code         = xlate->code;
1279
1280         ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1281
1282         if (mf.code != xlate->code)
1283                 return -EINVAL;
1284
1285         #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1286         if ((mf.width != usr_w) || (mf.height != usr_h)) {
1287         if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1288                 RK29CAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
1289                 ret = -EINVAL;
1290                 goto RK29_CAMERA_SET_FMT_END;
1291         }       
1292         if (unlikely((usr_w <16)||(usr_h < 16))) {
1293                 RK29CAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1294                 ret = -EINVAL;
1295             goto RK29_CAMERA_SET_FMT_END;
1296         }
1297                 mf.width = usr_w;
1298                 mf.height = usr_h;
1299         }
1300         #endif
1301     icd->sense = NULL;
1302
1303     if (!ret) {
1304         rect.left = 0;
1305         rect.top = 0;
1306         rect.width = mf.width;
1307         rect.height = mf.height;
1308
1309         down(&pcdev->zoominfo.sem);        
1310         pcdev->zoominfo.a.c.width = rect.width*100/pcdev->zoominfo.zoom_rate;
1311                 pcdev->zoominfo.a.c.width &= ~0x03;
1312                 pcdev->zoominfo.a.c.height = rect.height*100/pcdev->zoominfo.zoom_rate;
1313                 pcdev->zoominfo.a.c.height &= ~0x03;
1314                 pcdev->zoominfo.a.c.left = ((rect.width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
1315                 pcdev->zoominfo.a.c.top = ((rect.height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
1316         up(&pcdev->zoominfo.sem);
1317
1318         /* ddl@rock-chips.com: IPP work limit check */
1319         if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
1320             if (usr_w > 0x7f0) {
1321                 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
1322                     RK29CAMERA_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));
1323                     ret = -EINVAL;
1324                     goto RK29_CAMERA_SET_FMT_END;
1325                 }
1326             } else {
1327                 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
1328                     RK29CAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
1329                     ret = -EINVAL;
1330                     goto RK29_CAMERA_SET_FMT_END;
1331                 }
1332             }
1333         }
1334         
1335         RK29CAMERA_DG("%s..%s icd width:%d  host width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
1336                                    rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
1337                                    pix->width, pix->height);
1338         rk29_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
1339         
1340                 if (CAM_IPPWORK_IS_EN()) {
1341                         BUG_ON(pcdev->vipmem_phybase == 0);
1342                 }
1343
1344         pix->width = mf.width;
1345         pix->height = mf.height;
1346         pix->field = mf.field;
1347         pix->colorspace = mf.colorspace;
1348         icd->current_fmt = xlate;        
1349     }
1350
1351 RK29_CAMERA_SET_FMT_END:
1352     if (stream_on & ENABLE_CAPTURE)
1353         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL) | ENABLE_CAPTURE));
1354         if (ret)
1355         RK29CAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
1356     return ret;
1357 }
1358 static bool rk29_camera_fmt_capturechk(struct v4l2_format *f)
1359 {
1360     bool ret = false;
1361
1362         if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1363                 ret = true;
1364         } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1365                 ret = true;
1366         } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1367                 ret = true;
1368         } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1369                 ret = true;
1370         } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1371                 ret = true;
1372         }
1373
1374         if (ret == true)
1375                 RK29CAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
1376         return ret;
1377 }
1378 static int rk29_camera_try_fmt(struct soc_camera_device *icd,
1379                                    struct v4l2_format *f)
1380 {
1381     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1382         struct rk29_camera_dev *pcdev = ici->priv;
1383     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1384     const struct soc_camera_format_xlate *xlate;
1385     struct v4l2_pix_format *pix = &f->fmt.pix;
1386     __u32 pixfmt = pix->pixelformat;
1387     int ret,usr_w,usr_h,i;
1388         bool is_capture = rk29_camera_fmt_capturechk(f);
1389         bool vipmem_is_overflow = false;
1390     struct v4l2_mbus_framefmt mf;
1391
1392         usr_w = pix->width;
1393         usr_h = pix->height;
1394         RK29CAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
1395
1396     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1397     if (!xlate) {
1398         dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
1399                         (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
1400         ret = -EINVAL;
1401         RK29CAMERA_TR("%s(version:%c%c%c) support format:\n",rk29_cam_driver_description,(RK29_CAM_VERSION_CODE&0xff0000)>>16,
1402             (RK29_CAM_VERSION_CODE&0xff00)>>8,(RK29_CAM_VERSION_CODE&0xff));
1403         for (i = 0; i < icd->num_user_formats; i++)
1404                     RK29CAMERA_TR("(%c%c%c%c)-%s\n",
1405                     icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
1406                         (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
1407                         icd->user_formats[i].host_fmt->name);
1408         goto RK29_CAMERA_TRY_FMT_END;
1409     }
1410    /* limit to rk29 hardware capabilities */
1411     v4l_bound_align_image(&pix->width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
1412               &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
1413               pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
1414
1415     pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1416                                                     xlate->host_fmt);
1417         if (pix->bytesperline < 0)
1418                 return pix->bytesperline;
1419
1420     /* limit to sensor capabilities */
1421         mf.width        = pix->width;
1422         mf.height       = pix->height;
1423         mf.field        = pix->field;
1424         mf.colorspace   = pix->colorspace;
1425         mf.code         = xlate->code;
1426
1427         ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1428         if (ret < 0)
1429                 goto RK29_CAMERA_TRY_FMT_END;
1430     RK29CAMERA_DG("%s mf.width:%d  mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
1431         #ifdef CONFIG_VIDEO_RK29_WORK_IPP       
1432         if ((mf.width > usr_w) && (mf.height > usr_h)) {
1433                 if (is_capture) {
1434                         vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
1435                 } else {
1436                         /* Assume preview buffer minimum is 4 */
1437                         vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
1438                 }
1439                 if (vipmem_is_overflow == false) {
1440                         pix->width = usr_w;
1441                         pix->height = usr_h;
1442                 } else {
1443                         RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
1444             pix->width = mf.width;
1445             pix->height = mf.height;            
1446                 }
1447         } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
1448                 if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) {
1449                         if (is_capture) {
1450                                 vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
1451                         } else {
1452                                 vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
1453                         }
1454                         if (vipmem_is_overflow == false) {
1455                                 pix->width = usr_w;
1456                                 pix->height = usr_h;
1457                         } else {
1458                                 RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
1459                 pix->width = mf.width;
1460                 pix->height = mf.height;
1461                         }
1462                 } else {
1463                         RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
1464             pix->width = mf.width;
1465             pix->height = mf.height;
1466                 }
1467         }
1468         #else
1469     pix->width  = mf.width;
1470         pix->height     = mf.height;    
1471     #endif
1472     pix->colorspace     = mf.colorspace;    
1473
1474     switch (mf.field) {
1475         case V4L2_FIELD_ANY:
1476         case V4L2_FIELD_NONE:
1477                 pix->field      = V4L2_FIELD_NONE;
1478                 break;
1479         default:
1480                 /* TODO: support interlaced at least in pass-through mode */
1481                 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
1482                         mf.field);
1483                 goto RK29_CAMERA_TRY_FMT_END;
1484         }
1485
1486 RK29_CAMERA_TRY_FMT_END:
1487         if (ret)
1488         RK29CAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
1489     return ret;
1490 }
1491
1492 static int rk29_camera_reqbufs(struct soc_camera_device *icd,
1493                                struct v4l2_requestbuffers *p)
1494 {
1495     int i;
1496
1497     /* This is for locking debugging only. I removed spinlocks and now I
1498      * check whether .prepare is ever called on a linked buffer, or whether
1499      * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1500      * it hadn't triggered */
1501     for (i = 0; i < p->count; i++) {
1502         struct rk29_buffer *buf = container_of(icd->vb_vidq.bufs[i],
1503                                                            struct rk29_buffer, vb);
1504         buf->inwork = 0;
1505         INIT_LIST_HEAD(&buf->vb.queue);
1506     }
1507
1508     return 0;
1509 }
1510
1511 static unsigned int rk29_camera_poll(struct file *file, poll_table *pt)
1512 {
1513     struct soc_camera_device *icd = file->private_data;
1514     struct rk29_buffer *buf;
1515
1516     buf = list_entry(icd->vb_vidq.stream.next, struct rk29_buffer,
1517                      vb.stream);
1518
1519     poll_wait(file, &buf->vb.done, pt);
1520
1521     if (buf->vb.state == VIDEOBUF_DONE ||
1522             buf->vb.state == VIDEOBUF_ERROR)
1523         return POLLIN|POLLRDNORM;
1524
1525     return 0;
1526 }
1527
1528 static int rk29_camera_querycap(struct soc_camera_host *ici,
1529                                 struct v4l2_capability *cap)
1530 {
1531     struct rk29_camera_dev *pcdev = ici->priv;
1532     char orientation[5];
1533
1534     strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));    
1535     if (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->gpio_res[0].dev_name) == 0) {
1536         sprintf(orientation,"-%d",pcdev->pdata->gpio_res[0].orientation);
1537     } else {
1538         sprintf(orientation,"-%d",pcdev->pdata->gpio_res[1].orientation);
1539     }
1540     strcat(cap->card,orientation); 
1541     cap->version = RK29_CAM_VERSION_CODE;
1542     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1543
1544     return 0;
1545 }
1546
1547 static int rk29_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
1548 {
1549     struct soc_camera_host *ici =
1550                     to_soc_camera_host(icd->dev.parent);
1551     struct rk29_camera_dev *pcdev = ici->priv;
1552         struct v4l2_subdev *sd;
1553     int ret = 0,tmp;
1554
1555         mutex_lock(&camera_lock);
1556         if ((pcdev->icd == icd) && (icd->ops->suspend)) {
1557                 rk29_camera_s_stream(icd, 0);
1558                 sd = soc_camera_to_subdev(icd);
1559                 v4l2_subdev_call(sd, video, s_stream, 0);
1560                 ret = icd->ops->suspend(icd, state);
1561
1562                 pcdev->reginfo_suspend.VipCtrl = read_vip_reg(RK29_VIP_CTRL);
1563                 pcdev->reginfo_suspend.VipCrop = read_vip_reg(RK29_VIP_CROP);
1564                 pcdev->reginfo_suspend.VipFs = read_vip_reg(RK29_VIP_FS);
1565                 pcdev->reginfo_suspend.VipIntMsk = read_vip_reg(RK29_VIP_INT_MASK);
1566                 pcdev->reginfo_suspend.VipCrm = read_vip_reg(RK29_VIP_CRM);
1567
1568                 tmp = pcdev->reginfo_suspend.VipFs>>16;         /* ddl@rock-chips.com */
1569                 tmp += pcdev->reginfo_suspend.VipCrop>>16;
1570                 pcdev->reginfo_suspend.VipFs = (pcdev->reginfo_suspend.VipFs & 0xffff) | (tmp<<16);
1571
1572                 pcdev->reginfo_suspend.Inval = Reg_Validate;
1573                 rk29_camera_deactivate(pcdev);
1574
1575                 RK29CAMERA_DG("%s Enter Success...\n", __FUNCTION__);
1576         } else {
1577                 RK29CAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
1578         }
1579         mutex_unlock(&camera_lock);
1580     return ret;
1581 }
1582
1583 static int rk29_camera_resume(struct soc_camera_device *icd)
1584 {
1585     struct soc_camera_host *ici =
1586                     to_soc_camera_host(icd->dev.parent);
1587     struct rk29_camera_dev *pcdev = ici->priv;
1588         struct v4l2_subdev *sd;
1589     int ret = 0;
1590
1591         mutex_lock(&camera_lock);
1592         if ((pcdev->icd == icd) && (icd->ops->resume)) {
1593                 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
1594                         rk29_camera_activate(pcdev, icd);
1595                         write_vip_reg(RK29_VIP_INT_MASK, pcdev->reginfo_suspend.VipIntMsk);
1596                         write_vip_reg(RK29_VIP_CRM, pcdev->reginfo_suspend.VipCrm);
1597                         write_vip_reg(RK29_VIP_CTRL, pcdev->reginfo_suspend.VipCtrl&~ENABLE_CAPTURE);
1598                         write_vip_reg(RK29_VIP_CROP, pcdev->reginfo_suspend.VipCrop);
1599                         write_vip_reg(RK29_VIP_FS, pcdev->reginfo_suspend.VipFs);
1600
1601                         rk29_videobuf_capture(pcdev->active);
1602                         rk29_camera_s_stream(icd, 1);
1603                         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1604                 } else {
1605                         RK29CAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
1606                         goto rk29_camera_resume_end;
1607                 }
1608
1609                 ret = icd->ops->resume(icd);
1610                 sd = soc_camera_to_subdev(icd);
1611                 v4l2_subdev_call(sd, video, s_stream, 1);
1612
1613                 RK29CAMERA_DG("%s Enter success\n",__FUNCTION__);
1614         } else {
1615                 RK29CAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
1616         }
1617
1618 rk29_camera_resume_end:
1619         mutex_unlock(&camera_lock);
1620     return ret;
1621 }
1622
1623 static void rk29_camera_reinit_work(struct work_struct *work)
1624 {
1625         struct device *control;
1626     struct v4l2_subdev *sd;
1627         struct v4l2_mbus_framefmt mf;
1628         const struct soc_camera_format_xlate *xlate;
1629         int ret;
1630
1631         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)&(~ENABLE_CAPTURE)));
1632
1633         control = to_soc_camera_control(rk29_camdev_info_ptr->icd);
1634         sd = dev_get_drvdata(control);
1635         ret = v4l2_subdev_call(sd,core, init, 1);
1636
1637         mf.width = rk29_camdev_info_ptr->icd->user_width;
1638         mf.height = rk29_camdev_info_ptr->icd->user_height;
1639         xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->host_fmt->fourcc);        
1640         mf.code = xlate->code;
1641
1642         ret |= v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1643
1644         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)|ENABLE_CAPTURE));
1645
1646         RK29CAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor now! ret:0x%x\n",ret);
1647 }
1648 static enum hrtimer_restart rk29_camera_fps_func(struct hrtimer *timer)
1649 {
1650     struct rk29_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
1651     int rec_flag,i;
1652     
1653         RK29CAMERA_DG("rk29_camera_fps_func fps:0x%x\n",rk29_camdev_info_ptr->fps);
1654         if (rk29_camdev_info_ptr->fps < 2) {
1655                 RK29CAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay!\n");
1656                 INIT_WORK(&rk29_camdev_info_ptr->camera_reinit_work, rk29_camera_reinit_work);
1657                 queue_work(rk29_camdev_info_ptr->camera_wq,&(rk29_camdev_info_ptr->camera_reinit_work));
1658         } else {
1659             for (i=0; i<2; i++) {
1660             if (rk29_camdev_info_ptr->icd == rk29_camdev_info_ptr->icd_frmival[i].icd) {
1661                 fival_nxt = rk29_camdev_info_ptr->icd_frmival[i].fival_list;                
1662             }
1663         }
1664         
1665         rec_flag = 0;
1666         fival_pre = fival_nxt;
1667         while (fival_nxt != NULL) {
1668
1669             RK29CAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&rk29_camdev_info_ptr->icd->dev), 
1670                 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
1671                             (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
1672                             fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
1673                             fival_nxt->fival.discrete.numerator);
1674             
1675             if (((fival_nxt->fival.pixel_format == rk29_camdev_info_ptr->pixfmt) 
1676                 && (fival_nxt->fival.height == rk29_camdev_info_ptr->icd->user_height)
1677                 && (fival_nxt->fival.width == rk29_camdev_info_ptr->icd->user_width))
1678                 || (fival_nxt->fival.discrete.denominator == 0)) {
1679
1680                 if (fival_nxt->fival.discrete.denominator == 0) {
1681                     fival_nxt->fival.index = 0;
1682                     fival_nxt->fival.width = rk29_camdev_info_ptr->icd->user_width;
1683                     fival_nxt->fival.height= rk29_camdev_info_ptr->icd->user_height;
1684                     fival_nxt->fival.pixel_format = rk29_camdev_info_ptr->pixfmt;
1685                     fival_nxt->fival.discrete.denominator = rk29_camdev_info_ptr->fps+2;
1686                     fival_nxt->fival.discrete.numerator = 1;
1687                     fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
1688                 } else {                
1689                     if (abs(rk29_camdev_info_ptr->fps + 2 - fival_nxt->fival.discrete.numerator) > 2) {
1690                         fival_nxt->fival.discrete.denominator = rk29_camdev_info_ptr->fps+2;
1691                         fival_nxt->fival.discrete.numerator = 1;
1692                         fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
1693                     }
1694                 }
1695                 rec_flag = 1;
1696                 fival_rec = fival_nxt;
1697             }
1698             fival_pre = fival_nxt;
1699             fival_nxt = fival_nxt->nxt;            
1700         }
1701
1702         if ((rec_flag == 0) && fival_pre) {
1703             fival_pre->nxt = kzalloc(sizeof(struct rk29_camera_frmivalenum), GFP_ATOMIC);
1704             if (fival_pre->nxt != NULL) {
1705                 fival_pre->nxt->fival.index = fival_pre->fival.index++;
1706                 fival_pre->nxt->fival.width = rk29_camdev_info_ptr->icd->user_width;
1707                 fival_pre->nxt->fival.height= rk29_camdev_info_ptr->icd->user_height;
1708                 fival_pre->nxt->fival.pixel_format = rk29_camdev_info_ptr->pixfmt;
1709
1710                 fival_pre->nxt->fival.discrete.denominator = rk29_camdev_info_ptr->fps+2;
1711                 fival_pre->nxt->fival.discrete.numerator = 1;
1712                 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
1713                 rec_flag = 1;
1714                 fival_rec = fival_pre->nxt;
1715             }
1716         }
1717         }
1718
1719         return HRTIMER_NORESTART;
1720 }
1721 static int rk29_camera_s_stream(struct soc_camera_device *icd, int enable)
1722 {
1723         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1724     struct rk29_camera_dev *pcdev = ici->priv;
1725     int vip_ctrl_val;
1726         int ret;
1727
1728         WARN_ON(pcdev->icd != icd);
1729
1730         vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL);
1731         if (enable) {
1732                 pcdev->fps = 0;
1733                 hrtimer_cancel(&pcdev->fps_timer);
1734                 hrtimer_start(&pcdev->fps_timer,ktime_set(1, 0),HRTIMER_MODE_REL);
1735                 vip_ctrl_val |= ENABLE_CAPTURE;
1736         } else {
1737         vip_ctrl_val &= ~ENABLE_CAPTURE;
1738                 ret = hrtimer_cancel(&pcdev->fps_timer);
1739                 ret |= flush_work(&rk29_camdev_info_ptr->camera_reinit_work);
1740                 RK29CAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
1741         }
1742         write_vip_reg(RK29_VIP_CTRL, vip_ctrl_val);
1743
1744         RK29CAMERA_DG("%s.. enable : 0x%x \n", __FUNCTION__, enable);
1745         return 0;
1746 }
1747 int rk29_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
1748 {
1749     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1750     struct rk29_camera_dev *pcdev = ici->priv;
1751     struct rk29_camera_frmivalenum *fival_list = NULL;
1752     int i,ret = 0;
1753     
1754     for (i=0; i<2; i++) {
1755         if (pcdev->icd_frmival[i].icd == icd) {
1756             fival_list = pcdev->icd_frmival[i].fival_list;            
1757         }
1758     }
1759     
1760     if (fival_list != NULL) {
1761         i = 0;
1762         while (fival_list != NULL) {
1763             if ((fival->pixel_format == fival_list->fival.pixel_format)
1764                 && (fival->height == fival_list->fival.height) 
1765                 && (fival->width == fival_list->fival.width)) {
1766                 if (i == fival->index)
1767                     break;
1768                 i++;
1769             }                
1770             fival_list = fival_list->nxt;                
1771         }
1772         
1773         if ((i==fival->index) && (fival_list != NULL)) {
1774             memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
1775         } else {
1776             ret = -EINVAL;
1777         }
1778     } else {
1779         RK29CAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
1780         ret = -EINVAL;
1781     }
1782
1783     return ret;
1784 }
1785
1786 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
1787 static int rk29_camera_set_digit_zoom(struct soc_camera_device *icd,
1788                                                                 const struct v4l2_queryctrl *qctrl, int zoom_rate)
1789 {
1790         struct v4l2_crop a;
1791         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1792         struct rk29_camera_dev *pcdev = ici->priv;
1793         
1794 /* ddl@rock-chips.com : The largest resolution is 2047x1088, so larger resolution must be operated some times
1795    (Assume operate times is 4),but resolution which ipp can operate ,it is width and height must be even. */
1796         a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1797         a.c.width = pcdev->host_width*100/zoom_rate;
1798         a.c.width &= ~0x03;    
1799         a.c.height = pcdev->host_height*100/zoom_rate;
1800         a.c.height &= ~0x03;
1801         
1802         a.c.left = ((pcdev->host_width - a.c.width)>>1)&(~0x01);
1803         a.c.top = ((pcdev->host_height - a.c.height)>>1)&(~0x01);
1804
1805     down(&pcdev->zoominfo.sem);
1806         pcdev->zoominfo.a.c.height = a.c.height;
1807         pcdev->zoominfo.a.c.width = a.c.width;
1808         pcdev->zoominfo.a.c.top = a.c.top;
1809         pcdev->zoominfo.a.c.left = a.c.left;
1810     up(&pcdev->zoominfo.sem);
1811     
1812         RK29CAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, pcdev->host_width, pcdev->host_height );
1813
1814         return 0;
1815 }
1816 #endif
1817 static inline struct v4l2_queryctrl const *rk29_camera_soc_camera_find_qctrl(
1818         struct soc_camera_host_ops *ops, int id)
1819 {
1820         int i;
1821
1822         for (i = 0; i < ops->num_controls; i++)
1823                 if (ops->controls[i].id == id)
1824                         return &ops->controls[i];
1825
1826         return NULL;
1827 }
1828
1829
1830 static int rk29_camera_set_ctrl(struct soc_camera_device *icd,
1831                                                                 struct v4l2_control *sctrl)
1832 {
1833
1834         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1835         const struct v4l2_queryctrl *qctrl;
1836     struct rk29_camera_dev *pcdev = ici->priv;
1837     int ret = 0;
1838
1839         qctrl = rk29_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
1840         if (!qctrl) {
1841                 ret = -ENOIOCTLCMD;
1842         goto rk29_camera_set_ctrl_end;
1843         }
1844
1845         switch (sctrl->id)
1846         {
1847         #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
1848                 case V4L2_CID_ZOOM_ABSOLUTE:
1849                 {
1850                         if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
1851                         ret = -EINVAL;
1852                 goto rk29_camera_set_ctrl_end;
1853                 }
1854             ret = rk29_camera_set_digit_zoom(icd, qctrl, sctrl->value);
1855                         if (ret == 0) {
1856                                 pcdev->zoominfo.zoom_rate = sctrl->value;
1857             } else { 
1858                 goto rk29_camera_set_ctrl_end;
1859             }
1860                         break;
1861                 }
1862     #endif
1863                 default:
1864                         ret = -ENOIOCTLCMD;
1865                         break;
1866         }
1867 rk29_camera_set_ctrl_end:
1868         return ret;
1869 }
1870
1871 static struct soc_camera_host_ops rk29_soc_camera_host_ops =
1872 {
1873     .owner              = THIS_MODULE,
1874     .add                = rk29_camera_add_device,
1875     .remove             = rk29_camera_remove_device,
1876     .suspend    = rk29_camera_suspend,
1877     .resume             = rk29_camera_resume,
1878     .enum_frameinervals = rk29_camera_enum_frameintervals,
1879     .set_crop   = rk29_camera_set_crop,
1880     .get_formats        = rk29_camera_get_formats, 
1881     .put_formats        = rk29_camera_put_formats,
1882     .set_fmt    = rk29_camera_set_fmt,
1883     .try_fmt    = rk29_camera_try_fmt,
1884     .init_videobuf      = rk29_camera_init_videobuf,
1885     .reqbufs    = rk29_camera_reqbufs,
1886     .poll               = rk29_camera_poll,
1887     .querycap   = rk29_camera_querycap,
1888     .set_bus_param      = rk29_camera_set_bus_param,
1889     .s_stream = rk29_camera_s_stream,   /* ddl@rock-chips.com : Add stream control for host */
1890     .set_ctrl = rk29_camera_set_ctrl,
1891     .controls = rk29_camera_controls,
1892     .num_controls = ARRAY_SIZE(rk29_camera_controls)
1893     
1894 };
1895 static int rk29_camera_probe(struct platform_device *pdev)
1896 {
1897     struct rk29_camera_dev *pcdev;
1898     struct resource *res;
1899     struct rk29_camera_frmivalenum *fival_list,*fival_nxt;
1900     int irq,i;
1901     int err = 0;
1902
1903     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
1904     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1905     irq = platform_get_irq(pdev, 0);
1906     if (!res || irq < 0) {
1907         err = -ENODEV;
1908         goto exit;
1909     }
1910
1911     pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
1912     if (!pcdev) {
1913         dev_err(&pdev->dev, "Could not allocate pcdev\n");
1914         err = -ENOMEM;
1915         goto exit_alloc;
1916     }
1917     rk29_camdev_info_ptr = pcdev;
1918
1919     /*config output clk*/
1920         pcdev->aclk_ddr_lcdc = clk_get(&pdev->dev, "aclk_ddr_lcdc");
1921         pcdev->aclk_disp_matrix = clk_get(&pdev->dev, "aclk_disp_matrix");
1922
1923         pcdev->hclk_cpu_display = clk_get(&pdev->dev, "hclk_cpu_display");
1924         pcdev->vip_slave = clk_get(&pdev->dev, "vip_slave");
1925         pcdev->vip_out = clk_get(&pdev->dev,"vip_out");
1926         pcdev->vip_input = clk_get(&pdev->dev,"vip_input");
1927         pcdev->vip_bus = clk_get(&pdev->dev, "vip_bus");
1928
1929         pcdev->hclk_disp_matrix = clk_get(&pdev->dev,"hclk_disp_matrix");
1930         pcdev->vip_matrix = clk_get(&pdev->dev,"vip_matrix");
1931
1932         pcdev->pd_display = clk_get(&pdev->dev,"pd_display");
1933
1934         pcdev->zoominfo.zoom_rate = 100;
1935
1936     if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix ||  !pcdev->hclk_cpu_display ||
1937                 !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display ||
1938                 IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) ||  IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) ||
1939                 IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus))  {
1940
1941         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
1942         err = -ENOENT;
1943         goto exit_reqmem;
1944     }
1945
1946         if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix ||
1947                 IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix))  {
1948
1949         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n");
1950         err = -ENOENT;
1951         goto exit_reqmem;
1952     }
1953
1954     dev_set_drvdata(&pdev->dev, pcdev);
1955     pcdev->res = res;
1956
1957     pcdev->pdata = pdev->dev.platform_data;             /* ddl@rock-chips.com : Request IO in init function */
1958     if (pcdev->pdata && pcdev->pdata->io_init) {
1959         pcdev->pdata->io_init();
1960     }
1961         #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1962         if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) {
1963                 pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
1964                 pcdev->vipmem_size = pcdev->pdata->meminfo.size;
1965                 RK29CAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
1966         } else {
1967                 RK29CAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
1968                 pcdev->vipmem_phybase = 0;
1969                 pcdev->vipmem_size = 0;
1970         }
1971         #endif
1972     INIT_LIST_HEAD(&pcdev->capture);
1973     spin_lock_init(&pcdev->lock);
1974     sema_init(&pcdev->zoominfo.sem,1);
1975
1976     /*
1977      * Request the regions.
1978      */
1979     if (!request_mem_region(res->start, res->end - res->start + 1,
1980                             RK29_CAM_DRV_NAME)) {
1981         err = -EBUSY;
1982         goto exit_reqmem;
1983     }
1984
1985     pcdev->base = ioremap(res->start, res->end - res->start + 1);
1986     if (pcdev->base == NULL) {
1987         dev_err(pcdev->dev, "ioremap() of registers failed\n");
1988         err = -ENXIO;
1989         goto exit_ioremap;
1990     }
1991
1992     pcdev->irq = irq;
1993     pcdev->dev = &pdev->dev;
1994
1995     /* config buffer address */
1996     /* request irq */
1997     err = request_irq(pcdev->irq, rk29_camera_irq, 0, RK29_CAM_DRV_NAME,
1998                       pcdev);
1999     if (err) {
2000         dev_err(pcdev->dev, "Camera interrupt register failed \n");
2001         goto exit_reqirq;
2002     }
2003
2004         pcdev->camera_wq = create_workqueue("rk_camera_workqueue");
2005         if (pcdev->camera_wq == NULL)
2006                 goto exit_free_irq;
2007         INIT_WORK(&pcdev->camera_reinit_work, rk29_camera_reinit_work);
2008
2009     for (i=0; i<2; i++) {
2010         pcdev->icd_frmival[i].icd = NULL;
2011         pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk29_camera_frmivalenum),GFP_KERNEL);
2012         
2013     }
2014
2015     pcdev->soc_host.drv_name    = RK29_CAM_DRV_NAME;
2016     pcdev->soc_host.ops         = &rk29_soc_camera_host_ops;
2017     pcdev->soc_host.priv                = pcdev;
2018     pcdev->soc_host.v4l2_dev.dev        = &pdev->dev;
2019     pcdev->soc_host.nr          = pdev->id;
2020
2021     err = soc_camera_host_register(&pcdev->soc_host);
2022     if (err)
2023         goto exit_free_irq;
2024
2025         hrtimer_init(&pcdev->fps_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2026         pcdev->fps_timer.function = rk29_camera_fps_func;
2027     pcdev->icd_cb.sensor_cb = NULL;
2028
2029     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
2030     return 0;
2031
2032 exit_free_irq:
2033     
2034     for (i=0; i<2; i++) {
2035         fival_list = pcdev->icd_frmival[i].fival_list;
2036         fival_nxt = fival_list;
2037         while(fival_nxt != NULL) {
2038             fival_nxt = fival_list->nxt;
2039             kfree(fival_list);
2040             fival_list = fival_nxt;
2041         }
2042     }
2043     
2044     free_irq(pcdev->irq, pcdev);
2045         if (pcdev->camera_wq) {
2046                 destroy_workqueue(pcdev->camera_wq);
2047                 pcdev->camera_wq = NULL;
2048         }
2049 exit_reqirq:
2050     iounmap(pcdev->base);
2051 exit_ioremap:
2052     release_mem_region(res->start, res->end - res->start + 1);
2053 exit_reqmem:
2054     if (pcdev->aclk_ddr_lcdc) {
2055                 clk_put(pcdev->aclk_ddr_lcdc);
2056                 pcdev->aclk_ddr_lcdc = NULL;
2057     }
2058         if (pcdev->aclk_disp_matrix) {
2059                 clk_put(pcdev->aclk_disp_matrix);
2060                 pcdev->aclk_disp_matrix = NULL;
2061     }
2062         if (pcdev->hclk_cpu_display) {
2063                 clk_put(pcdev->hclk_cpu_display);
2064                 pcdev->hclk_cpu_display = NULL;
2065     }
2066         if (pcdev->vip_slave) {
2067                 clk_put(pcdev->vip_slave);
2068                 pcdev->vip_slave = NULL;
2069     }
2070         if (pcdev->vip_out) {
2071                 clk_put(pcdev->vip_out);
2072                 pcdev->vip_out = NULL;
2073     }
2074         if (pcdev->vip_input) {
2075                 clk_put(pcdev->vip_input);
2076                 pcdev->vip_input = NULL;
2077     }
2078         if (pcdev->vip_bus) {
2079                 clk_put(pcdev->vip_bus);
2080                 pcdev->vip_bus = NULL;
2081     }
2082     if (pcdev->hclk_disp_matrix) {
2083                 clk_put(pcdev->hclk_disp_matrix);
2084                 pcdev->hclk_disp_matrix = NULL;
2085     }
2086         if (pcdev->vip_matrix) {
2087                 clk_put(pcdev->vip_matrix);
2088                 pcdev->vip_matrix = NULL;
2089     }
2090     kfree(pcdev);
2091 exit_alloc:
2092     rk29_camdev_info_ptr = NULL;
2093 exit:
2094     return err;
2095 }
2096
2097 static int __devexit rk29_camera_remove(struct platform_device *pdev)
2098 {
2099     struct rk29_camera_dev *pcdev = platform_get_drvdata(pdev);
2100     struct resource *res;
2101     struct rk29_camera_frmivalenum *fival_list,*fival_nxt;
2102     int i;
2103     
2104     free_irq(pcdev->irq, pcdev);
2105
2106         if (pcdev->camera_wq) {
2107                 destroy_workqueue(pcdev->camera_wq);
2108                 pcdev->camera_wq = NULL;
2109         }
2110
2111     for (i=0; i<2; i++) {
2112         fival_list = pcdev->icd_frmival[i].fival_list;
2113         fival_nxt = fival_list;
2114         while(fival_nxt != NULL) {
2115             fival_nxt = fival_list->nxt;
2116             kfree(fival_list);
2117             fival_list = fival_nxt;
2118         }
2119     }
2120
2121     soc_camera_host_unregister(&pcdev->soc_host);
2122
2123     res = pcdev->res;
2124     release_mem_region(res->start, res->end - res->start + 1);
2125
2126     if (pcdev->pdata && pcdev->pdata->io_deinit) {         /* ddl@rock-chips.com : Free IO in deinit function */
2127         pcdev->pdata->io_deinit(0);
2128                 pcdev->pdata->io_deinit(1);
2129     }
2130
2131     kfree(pcdev);
2132     rk29_camdev_info_ptr = NULL;
2133     dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
2134
2135     return 0;
2136 }
2137
2138 static struct platform_driver rk29_camera_driver =
2139 {
2140     .driver     = {
2141         .name   = RK29_CAM_DRV_NAME,
2142     },
2143     .probe              = rk29_camera_probe,
2144     .remove             = __devexit_p(rk29_camera_remove),
2145 };
2146
2147
2148 static int __devinit rk29_camera_init(void)
2149 {
2150     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
2151     return platform_driver_register(&rk29_camera_driver);
2152 }
2153
2154 static void __exit rk29_camera_exit(void)
2155 {
2156     platform_driver_unregister(&rk29_camera_driver);
2157 }
2158
2159 device_initcall_sync(rk29_camera_init);
2160 module_exit(rk29_camera_exit);
2161
2162 MODULE_DESCRIPTION("RK29 Soc Camera Host driver");
2163 MODULE_AUTHOR("ddl <ddl@rock-chips>");
2164 MODULE_LICENSE("GPL");