camera: add display power control in vip driver
[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 <mach/rk29-ipp.h>
40
41
42 static int debug;
43 module_param(debug, int, S_IRUGO|S_IWUSR);
44
45 #define dprintk(level, fmt, arg...) do {                        \
46         if (debug >= level)                                     \
47         printk(KERN_WARNING"rk29xx_camera: " fmt , ## arg); } while (0)
48
49 #define RK29CAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
50 #define RK29CAMERA_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
51
52 // VIP Reg Offset
53 #define RK29_VIP_AHBR_CTRL                0x00
54 #define RK29_VIP_INT_MASK                 0x04
55 #define RK29_VIP_INT_STS                  0x08
56 #define RK29_VIP_STS                      0x0c
57 #define RK29_VIP_CTRL                     0x10
58 #define RK29_VIP_CAPTURE_F1SA_Y           0x14
59 #define RK29_VIP_CAPTURE_F1SA_UV          0x18
60 #define RK29_VIP_CAPTURE_F1SA_Cr          0x1c
61 #define RK29_VIP_CAPTURE_F2SA_Y           0x20
62 #define RK29_VIP_CAPTURE_F2SA_UV          0x24
63 #define RK29_VIP_CAPTURE_F2SA_Cr          0x28
64 #define RK29_VIP_FB_SR                    0x2c
65 #define RK29_VIP_FS                       0x30
66 #define RK29_VIP_VIPRESERVED              0x34
67 #define RK29_VIP_CROP                     0x38
68 #define RK29_VIP_CRM                      0x3c
69 #define RK29_VIP_RESET                    0x40
70 #define RK29_VIP_L_SFT                    0x44
71
72 //The key register bit descrition
73 // VIP_CTRL Reg
74 #define  DISABLE_CAPTURE              (0x00<<0)
75 #define  ENABLE_CAPTURE               (0x01<<0)
76 #define  HSY_HIGH_ACTIVE              (0x00<<1)
77 #define  HSY_LOW_ACTIVE               (0x01<<1)
78 #define  VIP_CCIR656                  (0x00<<2)
79 #define  VIP_SENSOR                   (0x01<<2)
80 #define  SENSOR_UYVY                  (0x00<<3)
81 #define  SENSOR_YUYV                  (0x01<<3)
82 #define  VIP_YUV                      (0x00<<4)
83 #define  VIP_RAW                      (0x01<<4)
84 #define  CON_OR_PIN                   (0x00<<5)
85 #define  ONEFRAME                     (0x01<<5)
86 #define  VIPREGYUV420                 (0x00<<6)
87 #define  VIPREGYUV422                 (0x01<<6)
88 #define  FIELD0_START                 (0x00<<7)
89 #define  FIELD1_START                 (0x01<<7)
90 #define  CONTINUOUS                   (0x00<<8)
91 #define  PING_PONG                    (0x01<<8)
92 #define  POSITIVE_EDGE                (0x00<<9)
93 #define  NEGATIVE_EDGE                (0x01<<9)
94 #define  VIPREGNTSC                   (0x00<<10)
95 #define  VIPREGPAL                    (0x01<<10)
96 #define  VIP_DATA_LITTLEEND           (0x00<<11)
97 #define  VIP_DATA_BIGEND              (0x01<<11)
98 #define  VSY_LOW_ACTIVE               (0x00<<12)
99 #define  VSY_HIGH_ACTIVE              (0x01<<12)
100 #define  VIP_RAWINPUT_BYPASS          (0x00<<13)
101 #define  VIP_RAWINPUT_POSITIVE_EDGE   (0x01<<13)
102 #define  VIP_RAWINPUT_NEGATIVE_EDGE   (0x02<<13)
103
104 // GRF_SOC_CON0 Reg
105 #define  GRF_SOC_CON0_Reg             0xbc
106 #define  VIP_AXIMASTER                (0x00<<0)
107 #define  VIP_AHBMASTER                (0x01<<2)
108
109 // GRF_OS_REG0
110 #define  GRF_OS_REG0                  0xd0
111 #define  VIP_ACLK_DIV_HCLK_1          (0x00<<0)
112 #define  VIP_ACLK_DIV_HCLK_2          (0x01<<0)
113
114
115 #define MIN(x,y)   ((x<y) ? x: y)
116 #define MAX(x,y)    ((x>y) ? x: y)
117 #define RK29_SENSOR_24MHZ      24           /* MHz */
118 #define RK29_SENSOR_48MHZ      48
119
120 #define write_vip_reg(addr, val)  __raw_writel(val, addr+(rk29_camdev_info_ptr->base))
121 #define read_vip_reg(addr) __raw_readl(addr+(rk29_camdev_info_ptr->base))
122 #define mask_vip_reg(addr, msk, val)    write_vip_reg(addr, (val)|((~(msk))&read_vip_reg(addr)))
123
124 #define write_grf_reg(addr, val)  __raw_writel(val, addr+RK29_GRF_BASE)
125 #define read_grf_reg(addr) __raw_readl(addr+RK29_GRF_BASE)
126 #define mask_grf_reg(addr, msk, val)    write_vip_reg(addr, (val)|((~(msk))&read_vip_reg(addr)))
127
128 //Configure Macro
129 #define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 1)
130
131 /* limit to rk29 hardware capabilities */
132 #define RK29_CAM_BUS_PARAM   (SOCAM_MASTER |\
133                 SOCAM_HSYNC_ACTIVE_HIGH |\
134                 SOCAM_HSYNC_ACTIVE_LOW |\
135                 SOCAM_VSYNC_ACTIVE_HIGH |\
136                 SOCAM_VSYNC_ACTIVE_LOW |\
137                 SOCAM_PCLK_SAMPLE_RISING |\
138                 SOCAM_PCLK_SAMPLE_FALLING|\
139                 SOCAM_DATA_ACTIVE_HIGH |\
140                 SOCAM_DATA_ACTIVE_LOW|\
141                 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
142                 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
143
144 #define RK29_CAM_W_MIN        48
145 #define RK29_CAM_H_MIN        32
146 #define RK29_CAM_W_MAX        3856            /* ddl@rock-chips.com : 10M Pixel */
147 #define RK29_CAM_H_MAX        2764
148 #define RK29_CAM_FRAME_INVAL_INIT 3
149 #define RK29_CAM_FRAME_INVAL_DC 3          /* ddl@rock-chips.com :  */
150
151 #define RK29_CAM_AXI   0
152 #define RK29_CAM_AHB   1
153 #define CONFIG_RK29_CAM_WORK_BUS    RK29_CAM_AXI
154
155 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
156 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
157 extern void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
158             struct videobuf_queue_ops *ops,
159             struct device *dev,
160             spinlock_t *irqlock,
161             enum v4l2_buf_type type,
162             enum v4l2_field field,
163             unsigned int msize,
164             void *priv);
165
166 /* buffer for one video frame */
167 struct rk29_buffer
168 {
169     /* common v4l buffer stuff -- must be first */
170     struct videobuf_buffer vb;
171     const struct soc_camera_data_format        *fmt;
172     int                 inwork;
173 };
174 enum rk29_camera_reg_state
175 {
176         Reg_Invalidate,
177         Reg_Validate
178 };
179
180 struct rk29_camera_reg
181 {
182         unsigned int VipCtrl;
183         unsigned int VipCrop;
184         unsigned int VipFs;
185         unsigned int VipIntMsk;
186         unsigned int VipCrm;
187         enum rk29_camera_reg_state Inval;
188 };
189 struct rk29_camera_work
190 {
191         struct videobuf_buffer *vb;
192         struct rk29_camera_dev *pcdev;
193         struct work_struct work;
194 };
195 struct rk29_camera_dev
196 {
197     struct soc_camera_host      soc_host;
198     struct device               *dev;
199     /* RK2827x is only supposed to handle one camera on its Quick Capture
200      * interface. If anyone ever builds hardware to enable more than
201      * one camera, they will have to modify this driver too */
202     struct soc_camera_device *icd;
203
204         struct clk *aclk_ddr_lcdc;
205         struct clk *aclk_disp_matrix;
206
207         struct clk *hclk_cpu_display;
208         struct clk *vip_slave;
209
210         struct clk *vip_out;
211         struct clk *vip_input;
212         struct clk *vip_bus;
213
214         struct clk *hclk_disp_matrix;
215         struct clk *vip_matrix;
216
217         struct clk *pd_display;
218
219     void __iomem *base;
220         void __iomem *grf_base;
221     int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
222     unsigned int irq;
223         unsigned int fps;
224         unsigned int pixfmt;
225         unsigned int vipmem_phybase;
226         unsigned int vipmem_size;
227         unsigned int vipmem_bsize;
228         int host_width;
229         int host_height;
230
231     struct rk29camera_platform_data *pdata;
232     struct resource             *res;
233
234     struct list_head    capture;
235
236     spinlock_t          lock;
237
238     struct videobuf_buffer      *active;
239         struct videobuf_queue *vb_vidq_ptr;
240         struct rk29_camera_reg reginfo_suspend;
241         struct workqueue_struct *camera_wq;
242         struct rk29_camera_work *camera_work;
243         unsigned int camera_work_count;
244         struct hrtimer fps_timer;
245         struct work_struct camera_reinit_work;
246 };
247 static DEFINE_MUTEX(camera_lock);
248 static const char *rk29_cam_driver_description = "RK29_Camera";
249 static struct rk29_camera_dev *rk29_camdev_info_ptr;
250
251 static int rk29_camera_s_stream(struct soc_camera_device *icd, int enable);
252
253
254 /*
255  *  Videobuf operations
256  */
257 static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
258                                unsigned int *size)
259 {
260     struct soc_camera_device *icd = vq->priv_data;
261         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
262     struct rk29_camera_dev *pcdev = ici->priv;
263     int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
264
265     dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
266
267         /* planar capture requires Y, U and V buffers to be page aligned */
268         #if 0
269     *size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel);                               /* Y pages UV pages, yuv422*/
270         pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel);
271         #else
272         *size = PAGE_ALIGN((icd->user_width* icd->user_height * icd->current_fmt->depth + 7)>>3);                               /* Y pages UV pages, yuv422*/
273         pcdev->vipmem_bsize = PAGE_ALIGN((pcdev->host_width * pcdev->host_height * icd->current_fmt->depth + 7)>>3);
274         #endif
275
276         if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
277
278                 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
279                         *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
280                 }
281
282                 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
283                         kfree(pcdev->camera_work);
284                         pcdev->camera_work = NULL;
285                         pcdev->camera_work_count = 0;
286                 }
287
288                 if (pcdev->camera_work == NULL) {
289                         pcdev->camera_work = kmalloc(sizeof(struct rk29_camera_work)*(*count), GFP_KERNEL);
290                         if (pcdev->camera_work == NULL) {
291                                 RK29CAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
292                                 BUG();
293                         }
294                         pcdev->camera_work_count = *count;
295                 }
296         }
297
298     RK29CAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_bsize);
299
300     return 0;
301 }
302 static void rk29_videobuf_free(struct videobuf_queue *vq, struct rk29_buffer *buf)
303 {
304     struct soc_camera_device *icd = vq->priv_data;
305
306     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
307             &buf->vb, buf->vb.baddr, buf->vb.bsize);
308
309         /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
310         if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
311                 return;
312
313     if (in_interrupt())
314         BUG();
315
316     videobuf_dma_contig_free(vq, &buf->vb);
317     dev_dbg(&icd->dev, "%s freed\n", __func__);
318     buf->vb.state = VIDEOBUF_NEEDS_INIT;
319         return;
320 }
321 static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
322 {
323     struct soc_camera_device *icd = vq->priv_data;
324     struct rk29_buffer *buf;
325     int ret;
326
327     buf = container_of(vb, struct rk29_buffer, vb);
328
329     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
330             vb, vb->baddr, vb->bsize);
331
332     //RK29CAMERA_TR("\n%s..%d..  \n",__FUNCTION__,__LINE__);
333
334     /* Added list head initialization on alloc */
335     WARN_ON(!list_empty(&vb->queue));
336
337     /* This can be useful if you want to see if we actually fill
338      * the buffer with something */
339     //memset((void *)vb->baddr, 0xaa, vb->bsize);
340
341     BUG_ON(NULL == icd->current_fmt);
342
343     if (buf->fmt    != icd->current_fmt ||
344             vb->width   != icd->user_width ||
345             vb->height  != icd->user_height ||
346              vb->field   != field) {
347         buf->fmt    = icd->current_fmt;
348         vb->width   = icd->user_width;
349         vb->height  = icd->user_height;
350         vb->field   = field;
351         vb->state   = VIDEOBUF_NEEDS_INIT;
352     }
353
354     vb->size = (((vb->width * vb->height *buf->fmt->depth) + 7) >> 3) ;          /* ddl@rock-chips.com : fmt->depth is coorect */
355     if (0 != vb->baddr && vb->bsize < vb->size) {
356         ret = -EINVAL;
357         goto out;
358     }
359
360     if (vb->state == VIDEOBUF_NEEDS_INIT) {
361         ret = videobuf_iolock(vq, vb, NULL);
362         if (ret) {
363             goto fail;
364         }
365         vb->state = VIDEOBUF_PREPARED;
366     }
367     //RK29CAMERA_TR("\n%s..%d.. \n",__FUNCTION__,__LINE__);
368     return 0;
369 fail:
370     rk29_videobuf_free(vq, buf);
371 out:
372     return ret;
373 }
374
375 static inline void rk29_videobuf_capture(struct videobuf_buffer *vb)
376 {
377         unsigned int y_addr,uv_addr;
378         struct rk29_camera_dev *pcdev = rk29_camdev_info_ptr;
379
380     if (vb) {
381                 if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
382                         y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
383                         uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
384
385                         if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
386                                 RK29CAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
387                                                   pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
388                                 BUG();
389                         }
390                 } else {
391                         y_addr = vb->boff;
392                         uv_addr = y_addr + vb->width * vb->height;
393                 }
394         write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, y_addr);
395         write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, uv_addr);
396         write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, y_addr);
397         write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, uv_addr);
398         write_vip_reg(RK29_VIP_FB_SR,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
399     }
400 }
401 /* Locking: Caller holds q->irqlock */
402 static void rk29_videobuf_queue(struct videobuf_queue *vq,
403                                 struct videobuf_buffer *vb)
404 {
405     struct soc_camera_device *icd = vq->priv_data;
406     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
407     struct rk29_camera_dev *pcdev = ici->priv;
408
409     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
410             vb, vb->baddr, vb->bsize);
411
412     vb->state = VIDEOBUF_QUEUED;
413
414         if (list_empty(&pcdev->capture)) {
415                 list_add_tail(&vb->queue, &pcdev->capture);
416         } else {
417                 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
418                         list_add_tail(&vb->queue, &pcdev->capture);
419                 else
420                         BUG();    /* ddl@rock-chips.com : The same videobuffer queue again */
421         }
422
423     if (!pcdev->active) {
424         pcdev->active = vb;
425         rk29_videobuf_capture(vb);
426     }
427 }
428 static int rk29_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
429 {
430         switch (pixfmt)
431         {
432                 case V4L2_PIX_FMT_YUV422P:
433                 {
434                         *ippfmt = IPP_Y_CBCR_H2V1;
435                         break;
436                 }
437                 case V4L2_PIX_FMT_YUV420:
438                 {
439                         *ippfmt = IPP_Y_CBCR_H2V2;
440                         break;
441                 }
442                 default:
443                         goto rk29_pixfmt2ippfmt_err;
444         }
445
446         return 0;
447 rk29_pixfmt2ippfmt_err:
448         return -1;
449 }
450 static void rk29_camera_capture_process(struct work_struct *work)
451 {
452         struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
453         struct videobuf_buffer *vb = camera_work->vb;
454         struct rk29_camera_dev *pcdev = camera_work->pcdev;
455         struct rk29_ipp_req ipp_req;
456         unsigned long int flags;
457
458         ipp_req.src0.YrgbMst = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
459         ipp_req.src0.CbrMst= ipp_req.src0.YrgbMst + pcdev->host_width*pcdev->host_height;
460         ipp_req.src0.w = pcdev->host_width;
461         ipp_req.src0.h = pcdev->host_height;
462         rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
463
464         ipp_req.dst0.YrgbMst = vb->boff;
465         ipp_req.dst0.CbrMst= vb->boff+vb->width * vb->height;
466         ipp_req.dst0.w = pcdev->icd->user_width;
467         ipp_req.dst0.h = pcdev->icd->user_height;
468         rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
469
470         ipp_req.src_vir_w = ipp_req.src0.w;
471         ipp_req.dst_vir_w = ipp_req.dst0.w;
472         ipp_req.timeout = 100;
473         ipp_req.flag = IPP_ROT_0;
474
475         if (ipp_do_blit(&ipp_req)) {
476                 spin_lock_irqsave(&pcdev->lock, flags);
477                 vb->state = VIDEOBUF_ERROR;
478                 spin_unlock_irqrestore(&pcdev->lock, flags);
479                 RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error!\n", vb->i);
480                 RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
481                 RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
482                 RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
483                 RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
484                 RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
485                 RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
486                 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);
487             RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
488         }
489
490         wake_up(&(camera_work->vb->done));
491 }
492 static irqreturn_t rk29_camera_irq(int irq, void *data)
493 {
494     struct rk29_camera_dev *pcdev = data;
495     struct videobuf_buffer *vb;
496         struct rk29_camera_work *wk;
497
498     read_vip_reg(RK29_VIP_INT_STS);    /* clear vip interrupte single  */
499     /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
500     if (read_vip_reg(RK29_VIP_FB_SR) & 0x01) {
501                 pcdev->fps++;
502                 if (!pcdev->active)
503                         goto RK29_CAMERA_IRQ_END;
504
505         if (pcdev->frame_inval>0) {
506             pcdev->frame_inval--;
507             rk29_videobuf_capture(pcdev->active);
508             goto RK29_CAMERA_IRQ_END;
509         } else if (pcdev->frame_inval) {
510                 RK29CAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
511             pcdev->frame_inval = 0;
512         }
513
514         vb = pcdev->active;
515                 /* ddl@rock-chips.com : this vb may be deleted from queue */
516                 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
517                 list_del_init(&vb->queue);
518                 }
519
520         pcdev->active = NULL;
521         if (!list_empty(&pcdev->capture)) {
522             pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
523                         if (pcdev->active) {
524                                 rk29_videobuf_capture(pcdev->active);
525                         }
526         }
527
528         if (pcdev->active == NULL) {
529                         RK29CAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
530         }
531
532                 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
533                 vb->state = VIDEOBUF_DONE;
534                 do_gettimeofday(&vb->ts);
535                 vb->field_count++;
536                 }
537
538                 if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
539                         wk = pcdev->camera_work + vb->i;
540                         INIT_WORK(&(wk->work), rk29_camera_capture_process);
541                         wk->vb = vb;
542                         wk->pcdev = pcdev;
543                         queue_work(pcdev->camera_wq, &(wk->work));
544                 } else {
545                         wake_up(&vb->done);
546                 }
547     }
548
549 RK29_CAMERA_IRQ_END:
550     return IRQ_HANDLED;
551 }
552
553
554 static void rk29_videobuf_release(struct videobuf_queue *vq,
555                                   struct videobuf_buffer *vb)
556 {
557     struct rk29_buffer *buf = container_of(vb, struct rk29_buffer, vb);
558     struct soc_camera_device *icd = vq->priv_data;
559     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
560     struct rk29_camera_dev *pcdev = ici->priv;
561
562 #ifdef DEBUG
563     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
564             vb, vb->baddr, vb->bsize);
565
566     switch (vb->state)
567     {
568         case VIDEOBUF_ACTIVE:
569             dev_dbg(&icd->dev, "%s (active)\n", __func__);
570             break;
571         case VIDEOBUF_QUEUED:
572             dev_dbg(&icd->dev, "%s (queued)\n", __func__);
573             break;
574         case VIDEOBUF_PREPARED:
575             dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
576             break;
577         default:
578             dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
579             break;
580     }
581 #endif
582         if (vb == pcdev->active) {
583                 RK29CAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
584                 interruptible_sleep_on_timeout(&vb->done, 100);
585                 RK29CAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
586         }
587     rk29_videobuf_free(vq, buf);
588 }
589
590 static struct videobuf_queue_ops rk29_videobuf_ops =
591 {
592     .buf_setup      = rk29_videobuf_setup,
593     .buf_prepare    = rk29_videobuf_prepare,
594     .buf_queue      = rk29_videobuf_queue,
595     .buf_release    = rk29_videobuf_release,
596 };
597
598 static void rk29_camera_init_videobuf(struct videobuf_queue *q,
599                                       struct soc_camera_device *icd)
600 {
601     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
602     struct rk29_camera_dev *pcdev = ici->priv;
603
604     /* We must pass NULL as dev pointer, then all pci_* dma operations
605      * transform to normal dma_* ones. */
606     videobuf_queue_dma_contig_init(q,
607                                    &rk29_videobuf_ops,
608                                    ici->v4l2_dev.dev, &pcdev->lock,
609                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
610                                    V4L2_FIELD_NONE,
611                                    sizeof(struct rk29_buffer),
612                                    icd);
613         pcdev->vb_vidq_ptr = q;         /* ddl@rock-chips.com */
614 }
615 static int rk29_camera_activate(struct rk29_camera_dev *pcdev, struct soc_camera_device *icd)
616 {
617     unsigned long sensor_bus_flags = SOCAM_MCLK_24MHZ;
618     struct clk *parent;
619
620     RK29CAMERA_DG("%s..%d.. \n",__FUNCTION__,__LINE__);
621     if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix ||  !pcdev->hclk_cpu_display ||
622                 !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display ||
623                 IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) ||  IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) ||
624                 IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus))  {
625
626         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
627         goto RK29_CAMERA_ACTIVE_ERR;
628     }
629
630         if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix ||
631                 IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix))  {
632
633         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n");
634         goto RK29_CAMERA_ACTIVE_ERR;
635     }
636
637         clk_enable(pcdev->pd_display);
638
639         clk_enable(pcdev->aclk_ddr_lcdc);
640         clk_enable(pcdev->aclk_disp_matrix);
641
642         clk_enable(pcdev->hclk_cpu_display);
643         clk_enable(pcdev->vip_slave);
644
645 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
646         clk_enable(pcdev->hclk_disp_matrix);
647         clk_enable(pcdev->vip_matrix);
648 #endif
649
650         clk_enable(pcdev->vip_input);
651         clk_enable(pcdev->vip_bus);
652
653     //if (icd->ops->query_bus_param)                                                  /* ddl@rock-chips.com : Query Sensor's xclk */
654         //sensor_bus_flags = icd->ops->query_bus_param(icd);
655
656     if (sensor_bus_flags & SOCAM_MCLK_48MHZ) {
657         parent = clk_get(NULL, "clk48m");
658         if (!parent || IS_ERR(parent))
659              goto RK29_CAMERA_ACTIVE_ERR;
660     } else if (sensor_bus_flags & SOCAM_MCLK_27MHZ) {
661         parent = clk_get(NULL, "extclk");
662         if (!parent || IS_ERR(parent))
663              goto RK29_CAMERA_ACTIVE_ERR;
664     } else {
665         parent = clk_get(NULL, "xin24m");
666         if (!parent || IS_ERR(parent))
667              goto RK29_CAMERA_ACTIVE_ERR;
668     }
669
670     clk_set_parent(pcdev->vip_out, parent);
671
672     clk_enable(pcdev->vip_out);
673     rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_VIP_CLKOUT);
674     ndelay(10);
675
676 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
677         write_grf_reg(GRF_SOC_CON0_Reg, read_grf_reg(GRF_SOC_CON0_Reg)|VIP_AHBMASTER);  //VIP Config to AHB
678         write_grf_reg(GRF_OS_REG0, read_grf_reg(GRF_OS_REG0)&(~VIP_ACLK_DIV_HCLK_2));   //aclk:hclk = 1:1
679 #else
680         write_grf_reg(GRF_SOC_CON0_Reg, read_grf_reg(GRF_SOC_CON0_Reg)&(~VIP_AHBMASTER));  //VIP Config to AXI
681     write_grf_reg(GRF_OS_REG0, read_grf_reg(GRF_OS_REG0)|VIP_ACLK_DIV_HCLK_2);   //aclk:hclk = 2:1
682 #endif
683         ndelay(10);
684
685     write_vip_reg(RK29_VIP_RESET, 0x76543210);  /* ddl@rock-chips.com : vip software reset */
686     udelay(10);
687
688     write_vip_reg(RK29_VIP_AHBR_CTRL, 0x07);   /* ddl@rock-chips.com : vip ahb burst 16 */
689     write_vip_reg(RK29_VIP_INT_MASK, 0x01);    //capture complete interrupt enable
690     write_vip_reg(RK29_VIP_CRM,  0x00000000);  //Y/CB/CR color modification
691
692     return 0;
693 RK29_CAMERA_ACTIVE_ERR:
694     return -ENODEV;
695 }
696
697 static void rk29_camera_deactivate(struct rk29_camera_dev *pcdev)
698 {
699     //pcdev->active = NULL;
700
701     write_vip_reg(RK29_VIP_CTRL, 0);
702     read_vip_reg(RK29_VIP_INT_STS);             //clear vip interrupte single
703
704     rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_GPIO1B4);
705     clk_disable(pcdev->vip_out);
706
707         clk_disable(pcdev->vip_input);
708         clk_disable(pcdev->vip_bus);
709
710 #if (CONFIG_RK29_CAM_WORK_BUS==RK29_CAM_AHB)
711         clk_disable(pcdev->hclk_disp_matrix);
712         clk_disable(pcdev->vip_matrix);
713 #endif
714
715         clk_disable(pcdev->hclk_cpu_display);
716         clk_disable(pcdev->vip_slave);
717
718         clk_disable(pcdev->aclk_ddr_lcdc);
719         clk_disable(pcdev->aclk_disp_matrix);
720
721         clk_disable(pcdev->pd_display);
722     return;
723 }
724
725 /* The following two functions absolutely depend on the fact, that
726  * there can be only one camera on RK28 quick capture interface */
727 static int rk29_camera_add_device(struct soc_camera_device *icd)
728 {
729     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
730     struct rk29_camera_dev *pcdev = ici->priv;
731     struct device *control = to_soc_camera_control(icd);
732     struct v4l2_subdev *sd;
733     int ret;
734
735     mutex_lock(&camera_lock);
736
737     if (pcdev->icd) {
738         ret = -EBUSY;
739         goto ebusy;
740     }
741
742     dev_info(&icd->dev, "RK29 Camera driver attached to camera%d(%s)\n",
743              icd->devnum,dev_name(icd->pdev));
744
745         pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
746     pcdev->active = NULL;
747     pcdev->icd = NULL;
748         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
749         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
750      * if app havn't dequeue all videobuf before close camera device;
751         */
752     INIT_LIST_HEAD(&pcdev->capture);
753
754     ret = rk29_camera_activate(pcdev,icd);
755     if (ret)
756         goto ebusy;
757
758     /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe  */
759     if (control) {
760         sd = dev_get_drvdata(control);
761                 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
762         ret = v4l2_subdev_call(sd,core, init, 0);
763         if (ret)
764             goto ebusy;
765     }
766
767     pcdev->icd = icd;
768
769 ebusy:
770     mutex_unlock(&camera_lock);
771
772     return ret;
773 }
774 static void rk29_camera_remove_device(struct soc_camera_device *icd)
775 {
776     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
777     struct rk29_camera_dev *pcdev = ici->priv;
778         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
779
780         mutex_lock(&camera_lock);
781     BUG_ON(icd != pcdev->icd);
782
783     dev_info(&icd->dev, "RK29 Camera driver detached from camera%d(%s)\n",
784              icd->devnum,dev_name(icd->pdev));
785
786         /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
787            stream may be turn on again before close device, if suspend and resume happened. */
788         if (read_vip_reg(RK29_VIP_CTRL) & ENABLE_CAPTURE) {
789                 rk29_camera_s_stream(icd,0);
790         }
791
792     v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
793         rk29_camera_deactivate(pcdev);
794
795         /* ddl@rock-chips.com: Call videobuf_mmap_free here for free the struct video_buffer which malloc in videobuf_alloc */
796         #if 0
797         if (pcdev->vb_vidq_ptr) {
798                 videobuf_mmap_free(pcdev->vb_vidq_ptr);
799                 pcdev->vb_vidq_ptr = NULL;
800         }
801         #else
802         pcdev->vb_vidq_ptr = NULL;
803         #endif
804
805         if (pcdev->camera_work) {
806                 kfree(pcdev->camera_work);
807                 pcdev->camera_work = NULL;
808                 pcdev->camera_work_count = 0;
809         }
810
811         pcdev->active = NULL;
812     pcdev->icd = NULL;
813         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
814         /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
815      * if app havn't dequeue all videobuf before close camera device;
816         */
817     INIT_LIST_HEAD(&pcdev->capture);
818
819         mutex_unlock(&camera_lock);
820         RK29CAMERA_DG("%s exit\n",__FUNCTION__);
821
822         return;
823 }
824
825 static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
826 {
827     unsigned long bus_flags, camera_flags, common_flags;
828     unsigned int vip_ctrl_val = 0;
829     int ret = 0;
830
831     RK29CAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
832
833     bus_flags = RK29_CAM_BUS_PARAM;
834         if (icd->ops->query_bus_param)
835         camera_flags = icd->ops->query_bus_param(icd);
836         else
837                 camera_flags = 0;
838
839     common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
840     if (!common_flags) {
841         ret = -EINVAL;
842         goto RK29_CAMERA_SET_BUS_PARAM_END;
843     }
844
845     ret = icd->ops->set_bus_param(icd, common_flags);
846     if (ret < 0)
847         goto RK29_CAMERA_SET_BUS_PARAM_END;
848
849         if (common_flags & SOCAM_DATAWIDTH_8) {
850         icd->buswidth = 8;
851         } else if (common_flags & SOCAM_DATAWIDTH_10) {
852             icd->buswidth = 10;
853         }
854
855     vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL);
856     if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
857         vip_ctrl_val |= NEGATIVE_EDGE;
858     } else {
859                 vip_ctrl_val &= ~NEGATIVE_EDGE;
860     }
861     if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
862         vip_ctrl_val |= HSY_LOW_ACTIVE;
863     } else {
864                 vip_ctrl_val &= ~HSY_LOW_ACTIVE;
865     }
866     if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
867         vip_ctrl_val |= VSY_HIGH_ACTIVE;
868     } else {
869                 vip_ctrl_val &= ~VSY_HIGH_ACTIVE;
870     }
871
872     /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
873     //vip_ctrl_val |= ENABLE_CAPTURE;
874
875     write_vip_reg(RK29_VIP_CTRL, vip_ctrl_val);
876     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),
877                 read_grf_reg(GRF_SOC_CON0_Reg)&VIP_AHBMASTER, read_grf_reg(GRF_OS_REG0)&VIP_ACLK_DIV_HCLK_2);
878
879 RK29_CAMERA_SET_BUS_PARAM_END:
880         if (ret)
881         RK29CAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
882     return ret;
883 }
884
885 static int rk29_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
886 {
887     unsigned long bus_flags, camera_flags;
888     int ret;
889
890     bus_flags = RK29_CAM_BUS_PARAM;
891         if (icd->ops->query_bus_param) {
892         camera_flags = icd->ops->query_bus_param(icd);
893         } else {
894                 camera_flags = 0;
895         }
896     ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
897
898     if (ret < 0)
899         dev_warn(icd->dev.parent,
900                          "Flags incompatible: camera %lx, host %lx\n",
901                          camera_flags, bus_flags);
902     return ret;
903 }
904 static const struct soc_camera_data_format rk29_camera_formats[] = {
905         {
906                 .name           = "Planar YUV420 12 bit",
907                 .depth          = 12,
908                 .fourcc         = V4L2_PIX_FMT_YUV420,
909                 .colorspace     = V4L2_COLORSPACE_JPEG,
910         },{
911                 .name           = "Planar YUV422 16 bit",
912                 .depth          = 16,
913                 .fourcc         = V4L2_PIX_FMT_YUV422P,
914                 .colorspace     = V4L2_COLORSPACE_JPEG,
915         },{
916                 .name           = "Raw Bayer RGB 10 bit",
917                 .depth          = 16,
918                 .fourcc         = V4L2_PIX_FMT_SGRBG10,
919                 .colorspace     = V4L2_COLORSPACE_SRGB,
920         }
921 };
922
923 static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, __u32 cam_pixfmt, struct v4l2_rect *rect)
924 {
925         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
926     struct rk29_camera_dev *pcdev = ici->priv;
927     unsigned int vip_fs = 0,vip_crop = 0;
928     unsigned int vip_ctrl_val = VIP_SENSOR|ONEFRAME|DISABLE_CAPTURE;
929
930     switch (host_pixfmt)
931     {
932         case V4L2_PIX_FMT_YUV422P:
933             vip_ctrl_val |= VIPREGYUV422;
934                         pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
935                         pcdev->pixfmt = host_pixfmt;
936             break;
937         case V4L2_PIX_FMT_YUV420:
938             vip_ctrl_val |= VIPREGYUV420;
939                         if (pcdev->frame_inval != RK29_CAM_FRAME_INVAL_INIT)
940                                 pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
941                         pcdev->pixfmt = host_pixfmt;
942             break;
943                 case V4L2_PIX_FMT_SGRBG10:
944                         vip_ctrl_val |= (VIP_RAW | VIP_SENSOR | VIP_DATA_LITTLEEND);
945                         pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
946                         pcdev->pixfmt = host_pixfmt;
947                         break;
948         default:                                                                                /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
949             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422);
950             break;
951     }
952
953     switch (cam_pixfmt)
954     {
955         case V4L2_PIX_FMT_UYVY:
956             vip_ctrl_val |= SENSOR_UYVY;
957             break;
958         case V4L2_PIX_FMT_YUYV:
959             vip_ctrl_val |= SENSOR_YUYV;
960             break;
961         default :
962             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & SENSOR_YUYV);
963             break;
964     }
965
966     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 */
967
968     read_vip_reg(RK29_VIP_INT_STS);                     /* clear vip interrupte single  */
969
970     if (vip_ctrl_val & ONEFRAME)  {
971         vip_crop = ((rect->left<<16) + rect->top);
972         vip_fs  = (((rect->width + rect->left)<<16) + (rect->height+rect->top));
973     } else if (vip_ctrl_val & PING_PONG) {
974         BUG();
975     }
976
977     write_vip_reg(RK29_VIP_CROP, vip_crop);
978     write_vip_reg(RK29_VIP_FS, vip_fs);
979
980     write_vip_reg(RK29_VIP_FB_SR,  0x00000003);
981
982         pcdev->host_width = rect->width;
983         pcdev->host_height = rect->height;
984
985     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));
986         return;
987 }
988
989 static int rk29_camera_get_formats(struct soc_camera_device *icd, int idx,
990                                   struct soc_camera_format_xlate *xlate)
991 {
992     struct device *dev = icd->dev.parent;
993     int formats = 0, buswidth, ret;
994
995     buswidth = 8;
996
997     ret = rk29_camera_try_bus_param(icd, buswidth);
998     if (ret < 0)
999         return 0;
1000
1001     switch (icd->formats[idx].fourcc) {
1002         case V4L2_PIX_FMT_UYVY:
1003         case V4L2_PIX_FMT_YUYV:
1004             formats++;
1005             if (xlate) {
1006                 xlate->host_fmt = &rk29_camera_formats[0];
1007                 xlate->cam_fmt = icd->formats + idx;
1008                 xlate->buswidth = buswidth;
1009                 xlate++;
1010                 dev_dbg(dev, "Providing format %s using %s\n",
1011                         rk29_camera_formats[0].name,
1012                         icd->formats[idx].name);
1013             }
1014
1015             formats++;
1016             if (xlate) {
1017                 xlate->host_fmt = &rk29_camera_formats[1];
1018                 xlate->cam_fmt = icd->formats + idx;
1019                 xlate->buswidth = buswidth;
1020                 xlate++;
1021                 dev_dbg(dev, "Providing format %s using %s\n",
1022                         rk29_camera_formats[1].name,
1023                         icd->formats[idx].name);
1024             }
1025                         break;
1026                 case V4L2_PIX_FMT_SGRBG10:
1027                         formats++;
1028             if (xlate) {
1029                 xlate->host_fmt = &rk29_camera_formats[2];
1030                 xlate->cam_fmt = icd->formats + idx;
1031                 xlate->buswidth = 10;
1032                 xlate++;
1033                 dev_dbg(dev, "Providing format %s using %s\n",
1034                         rk29_camera_formats[2].name,
1035                         icd->formats[idx].name);
1036             }
1037                         break;
1038         default:
1039             break;
1040     }
1041
1042     return formats;
1043 }
1044
1045 static void rk29_camera_put_formats(struct soc_camera_device *icd)
1046 {
1047         return;
1048 }
1049
1050 static int rk29_camera_set_crop(struct soc_camera_device *icd,
1051                                struct v4l2_crop *a)
1052 {
1053     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1054     struct v4l2_format f;
1055     struct v4l2_pix_format *pix = &f.fmt.pix;
1056     int ret;
1057
1058     f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1059
1060     ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1061     if (ret < 0)
1062         return ret;
1063
1064     if ((pix->width < (a->c.left + a->c.width)) || (pix->height < (a->c.top + a->c.height)))  {
1065
1066         pix->width = a->c.left + a->c.width;
1067         pix->height = a->c.top + a->c.height;
1068
1069         v4l_bound_align_image(&pix->width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
1070             &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
1071             icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?4 : 0);
1072
1073         ret = v4l2_subdev_call(sd, video, s_fmt, &f);
1074         if (ret < 0)
1075             return ret;
1076     }
1077
1078     rk29_camera_setup_format(icd, icd->current_fmt->fourcc, pix->pixelformat, &a->c);
1079
1080     icd->user_width = pix->width;
1081     icd->user_height = pix->height;
1082
1083     return 0;
1084 }
1085
1086 static int rk29_camera_set_fmt(struct soc_camera_device *icd,
1087                               struct v4l2_format *f)
1088 {
1089     struct device *dev = icd->dev.parent;
1090     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1091     const struct soc_camera_data_format *cam_fmt = NULL;
1092     const struct soc_camera_format_xlate *xlate = NULL;
1093         struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
1094     struct rk29_camera_dev *pcdev = ici->priv;
1095     struct v4l2_pix_format *pix = &f->fmt.pix;
1096     struct v4l2_format cam_f = *f;
1097     struct v4l2_rect rect;
1098     int ret,usr_w,usr_h;
1099
1100         usr_w = pix->width;
1101         usr_h = pix->height;
1102     RK29CAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
1103
1104     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1105     if (!xlate) {
1106         dev_err(dev, "Format %x not found\n", pix->pixelformat);
1107         ret = -EINVAL;
1108         goto RK29_CAMERA_SET_FMT_END;
1109     }
1110
1111     cam_fmt = xlate->cam_fmt;
1112
1113     cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
1114     ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
1115     cam_f.fmt.pix.pixelformat = pix->pixelformat;
1116     *pix = cam_f.fmt.pix;
1117         #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1118         if ((pix->width != usr_w) || (pix->height != usr_h)) {
1119                 pix->width = usr_w;
1120                 pix->height = usr_h;
1121         }
1122         #endif
1123     icd->sense = NULL;
1124
1125     if (!ret) {
1126         rect.left = 0;
1127         rect.top = 0;
1128         rect.width = cam_f.fmt.pix.width;
1129         rect.height = cam_f.fmt.pix.height;
1130
1131         RK29CAMERA_DG("%s..%s..%s icd width:%d  host width:%d \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name,
1132                                    rect.width, pix->width);
1133         rk29_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect);
1134         icd->buswidth = xlate->buswidth;
1135         icd->current_fmt = xlate->host_fmt;
1136
1137                 if (((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))) {
1138                         BUG_ON(pcdev->vipmem_phybase == 0);
1139                 }
1140     }
1141
1142 RK29_CAMERA_SET_FMT_END:
1143         if (ret)
1144         RK29CAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
1145     return ret;
1146 }
1147 static bool rk29_camera_fmt_capturechk(struct v4l2_format *f)
1148 {
1149     bool ret = false;
1150
1151         if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1152                 ret = true;
1153         } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1154                 ret = true;
1155         } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1156                 ret = true;
1157         } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1158                 ret = true;
1159         } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1160                 ret = true;
1161         }
1162
1163         if (ret == true)
1164                 RK29CAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
1165         return ret;
1166 }
1167 static int rk29_camera_try_fmt(struct soc_camera_device *icd,
1168                                    struct v4l2_format *f)
1169 {
1170     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1171         struct rk29_camera_dev *pcdev = ici->priv;
1172     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1173     const struct soc_camera_format_xlate *xlate;
1174     struct v4l2_pix_format *pix = &f->fmt.pix;
1175     __u32 pixfmt = pix->pixelformat;
1176     enum v4l2_field field;
1177     int ret,usr_w,usr_h;
1178         bool is_capture = rk29_camera_fmt_capturechk(f);
1179         bool vipmem_is_overflow = false;
1180
1181         usr_w = pix->width;
1182         usr_h = pix->height;
1183         RK29CAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
1184
1185     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1186     if (!xlate) {
1187         dev_err(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
1188         ret = -EINVAL;
1189         goto RK29_CAMERA_TRY_FMT_END;
1190     }
1191    /* limit to rk29 hardware capabilities */
1192     v4l_bound_align_image(&pix->width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
1193               &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
1194               pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1195
1196     pix->bytesperline = pix->width * DIV_ROUND_UP(xlate->host_fmt->depth, 8);
1197     pix->sizeimage = pix->height * pix->bytesperline;
1198
1199     /* camera has to see its format, but the user the original one */
1200     pix->pixelformat = xlate->cam_fmt->fourcc;
1201     /* limit to sensor capabilities */
1202     ret = v4l2_subdev_call(sd, video, try_fmt, f);
1203     pix->pixelformat = pixfmt;
1204         #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1205         if ((pix->width > usr_w) && (pix->height > usr_h)) {
1206                 if (is_capture) {
1207                         vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size);
1208                 } else {
1209                         /* Assume preview buffer minimum is 4 */
1210                         vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size);
1211                 }
1212                 if (vipmem_is_overflow == false) {
1213                         pix->width = usr_w;
1214                         pix->height = usr_h;
1215                 } else {
1216                         RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",pix->width,pix->height,usr_w,usr_h);
1217                 }
1218         } else if ((pix->width < usr_w) && (pix->height < usr_h)) {
1219                 if (((usr_w>>1) < pix->width) && ((usr_h>>1) < pix->height)) {
1220                         if (is_capture) {
1221                                 vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size);
1222                         } else {
1223                                 vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size);
1224                         }
1225                         if (vipmem_is_overflow == false) {
1226                                 pix->width = usr_w;
1227                                 pix->height = usr_h;
1228                         } else {
1229                                 RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",pix->width,pix->height,usr_w,usr_h);
1230                         }
1231                 } else {
1232                         RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",pix->width,pix->height,usr_w,usr_h);
1233                 }
1234         }
1235         #endif
1236
1237     field = pix->field;
1238
1239     if (field == V4L2_FIELD_ANY) {
1240         pix->field = V4L2_FIELD_NONE;
1241     } else if (field != V4L2_FIELD_NONE) {
1242         dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
1243         ret = -EINVAL;
1244         goto RK29_CAMERA_TRY_FMT_END;
1245     }
1246
1247 RK29_CAMERA_TRY_FMT_END:
1248         if (ret)
1249         RK29CAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
1250     return ret;
1251 }
1252
1253 static int rk29_camera_reqbufs(struct soc_camera_file *icf,
1254                                struct v4l2_requestbuffers *p)
1255 {
1256     int i;
1257
1258     /* This is for locking debugging only. I removed spinlocks and now I
1259      * check whether .prepare is ever called on a linked buffer, or whether
1260      * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1261      * it hadn't triggered */
1262     for (i = 0; i < p->count; i++) {
1263         struct rk29_buffer *buf = container_of(icf->vb_vidq.bufs[i],
1264                                                            struct rk29_buffer, vb);
1265         buf->inwork = 0;
1266         INIT_LIST_HEAD(&buf->vb.queue);
1267     }
1268
1269     return 0;
1270 }
1271
1272 static unsigned int rk29_camera_poll(struct file *file, poll_table *pt)
1273 {
1274     struct soc_camera_file *icf = file->private_data;
1275     struct rk29_buffer *buf;
1276
1277     buf = list_entry(icf->vb_vidq.stream.next, struct rk29_buffer,
1278                      vb.stream);
1279
1280     poll_wait(file, &buf->vb.done, pt);
1281
1282     if (buf->vb.state == VIDEOBUF_DONE ||
1283             buf->vb.state == VIDEOBUF_ERROR)
1284         return POLLIN|POLLRDNORM;
1285
1286     return 0;
1287 }
1288
1289 static int rk29_camera_querycap(struct soc_camera_host *ici,
1290                                 struct v4l2_capability *cap)
1291 {
1292     /* cap->name is set by the firendly caller:-> */
1293     strlcpy(cap->card, rk29_cam_driver_description, sizeof(cap->card));
1294     cap->version = RK29_CAM_VERSION_CODE;
1295     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1296
1297     return 0;
1298 }
1299
1300 static int rk29_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
1301 {
1302     struct soc_camera_host *ici =
1303                     to_soc_camera_host(icd->dev.parent);
1304     struct rk29_camera_dev *pcdev = ici->priv;
1305         struct v4l2_subdev *sd;
1306     int ret = 0,tmp;
1307
1308         mutex_lock(&camera_lock);
1309         if ((pcdev->icd == icd) && (icd->ops->suspend)) {
1310                 rk29_camera_s_stream(icd, 0);
1311                 sd = soc_camera_to_subdev(icd);
1312                 v4l2_subdev_call(sd, video, s_stream, 0);
1313                 ret = icd->ops->suspend(icd, state);
1314
1315                 pcdev->reginfo_suspend.VipCtrl = read_vip_reg(RK29_VIP_CTRL);
1316                 pcdev->reginfo_suspend.VipCrop = read_vip_reg(RK29_VIP_CROP);
1317                 pcdev->reginfo_suspend.VipFs = read_vip_reg(RK29_VIP_FS);
1318                 pcdev->reginfo_suspend.VipIntMsk = read_vip_reg(RK29_VIP_INT_MASK);
1319                 pcdev->reginfo_suspend.VipCrm = read_vip_reg(RK29_VIP_CRM);
1320
1321                 tmp = pcdev->reginfo_suspend.VipFs>>16;         /* ddl@rock-chips.com */
1322                 tmp += pcdev->reginfo_suspend.VipCrop>>16;
1323                 pcdev->reginfo_suspend.VipFs = (pcdev->reginfo_suspend.VipFs & 0xffff) | (tmp<<16);
1324
1325                 pcdev->reginfo_suspend.Inval = Reg_Validate;
1326                 rk29_camera_deactivate(pcdev);
1327
1328                 RK29CAMERA_DG("%s Enter Success...\n", __FUNCTION__);
1329         } else {
1330                 RK29CAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
1331         }
1332         mutex_unlock(&camera_lock);
1333     return ret;
1334 }
1335
1336 static int rk29_camera_resume(struct soc_camera_device *icd)
1337 {
1338     struct soc_camera_host *ici =
1339                     to_soc_camera_host(icd->dev.parent);
1340     struct rk29_camera_dev *pcdev = ici->priv;
1341         struct v4l2_subdev *sd;
1342     int ret = 0;
1343
1344         mutex_lock(&camera_lock);
1345         if ((pcdev->icd == icd) && (icd->ops->resume)) {
1346                 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
1347                         rk29_camera_activate(pcdev, icd);
1348                         write_vip_reg(RK29_VIP_INT_MASK, pcdev->reginfo_suspend.VipIntMsk);
1349                         write_vip_reg(RK29_VIP_CRM, pcdev->reginfo_suspend.VipCrm);
1350                         write_vip_reg(RK29_VIP_CTRL, pcdev->reginfo_suspend.VipCtrl&~ENABLE_CAPTURE);
1351                         write_vip_reg(RK29_VIP_CROP, pcdev->reginfo_suspend.VipCrop);
1352                         write_vip_reg(RK29_VIP_FS, pcdev->reginfo_suspend.VipFs);
1353
1354                         rk29_videobuf_capture(pcdev->active);
1355                         rk29_camera_s_stream(icd, 1);
1356                         pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1357                 } else {
1358                         RK29CAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
1359                         goto rk29_camera_resume_end;
1360                 }
1361
1362                 ret = icd->ops->resume(icd);
1363                 sd = soc_camera_to_subdev(icd);
1364                 v4l2_subdev_call(sd, video, s_stream, 1);
1365
1366                 RK29CAMERA_DG("%s Enter success\n",__FUNCTION__);
1367         } else {
1368                 RK29CAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
1369         }
1370
1371 rk29_camera_resume_end:
1372         mutex_unlock(&camera_lock);
1373     return ret;
1374 }
1375
1376 static void rk29_camera_reinit_work(struct work_struct *work)
1377 {
1378         struct device *control;
1379     struct v4l2_subdev *sd;
1380         struct v4l2_format cam_f;
1381         const struct soc_camera_format_xlate *xlate;
1382         int ret;
1383
1384         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)&(~ENABLE_CAPTURE)));
1385
1386         control = to_soc_camera_control(rk29_camdev_info_ptr->icd);
1387         sd = dev_get_drvdata(control);
1388         ret = v4l2_subdev_call(sd,core, init, 1);
1389
1390         cam_f.fmt.pix.width = rk29_camdev_info_ptr->icd->user_width;
1391         cam_f.fmt.pix.height = rk29_camdev_info_ptr->icd->user_height;
1392         xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->fourcc);
1393         cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
1394         ret |= v4l2_subdev_call(sd, video, s_fmt, &cam_f);
1395
1396         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)|ENABLE_CAPTURE));
1397
1398         RK29CAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor now! ret:0x%x\n",ret);
1399 }
1400 static enum hrtimer_restart rk29_camera_fps_func(struct hrtimer *timer)
1401 {
1402         RK29CAMERA_DG("rk29_camera_fps_func fps:0x%x\n",rk29_camdev_info_ptr->fps);
1403         if (rk29_camdev_info_ptr->fps < 3) {
1404                 RK29CAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay!\n");
1405                 INIT_WORK(&rk29_camdev_info_ptr->camera_reinit_work, rk29_camera_reinit_work);
1406                 queue_work(rk29_camdev_info_ptr->camera_wq,&(rk29_camdev_info_ptr->camera_reinit_work));
1407         }
1408
1409         return HRTIMER_NORESTART;
1410 }
1411 static int rk29_camera_s_stream(struct soc_camera_device *icd, int enable)
1412 {
1413         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1414     struct rk29_camera_dev *pcdev = ici->priv;
1415     int vip_ctrl_val;
1416         int ret;
1417
1418         WARN_ON(pcdev->icd != icd);
1419
1420         vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL);
1421         if (enable) {
1422                 pcdev->fps = 0;
1423                 hrtimer_cancel(&pcdev->fps_timer);
1424                 hrtimer_start(&pcdev->fps_timer,ktime_set(2, 0),HRTIMER_MODE_REL);
1425                 vip_ctrl_val |= ENABLE_CAPTURE;
1426         } else {
1427         vip_ctrl_val &= ~ENABLE_CAPTURE;
1428                 ret = hrtimer_cancel(&pcdev->fps_timer);
1429                 ret |= flush_work(&rk29_camdev_info_ptr->camera_reinit_work);
1430                 RK29CAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
1431         }
1432         write_vip_reg(RK29_VIP_CTRL, vip_ctrl_val);
1433
1434         RK29CAMERA_DG("%s.. enable : 0x%x \n", __FUNCTION__, enable);
1435         return 0;
1436 }
1437
1438 static struct soc_camera_host_ops rk29_soc_camera_host_ops =
1439 {
1440     .owner              = THIS_MODULE,
1441     .add                = rk29_camera_add_device,
1442     .remove             = rk29_camera_remove_device,
1443     .suspend    = rk29_camera_suspend,
1444     .resume             = rk29_camera_resume,
1445     .set_crop   = rk29_camera_set_crop,
1446     .get_formats        = rk29_camera_get_formats,
1447     .put_formats        = rk29_camera_put_formats,
1448     .set_fmt    = rk29_camera_set_fmt,
1449     .try_fmt    = rk29_camera_try_fmt,
1450     .init_videobuf      = rk29_camera_init_videobuf,
1451     .reqbufs    = rk29_camera_reqbufs,
1452     .poll               = rk29_camera_poll,
1453     .querycap   = rk29_camera_querycap,
1454     .set_bus_param      = rk29_camera_set_bus_param,
1455     .s_stream = rk29_camera_s_stream   /* ddl@rock-chips.com : Add stream control for host */
1456 };
1457 static int rk29_camera_probe(struct platform_device *pdev)
1458 {
1459     struct rk29_camera_dev *pcdev;
1460     struct resource *res;
1461     int irq;
1462     int err = 0;
1463
1464     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
1465     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1466     irq = platform_get_irq(pdev, 0);
1467     if (!res || irq < 0) {
1468         err = -ENODEV;
1469         goto exit;
1470     }
1471
1472     pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
1473     if (!pcdev) {
1474         dev_err(&pdev->dev, "Could not allocate pcdev\n");
1475         err = -ENOMEM;
1476         goto exit_alloc;
1477     }
1478     rk29_camdev_info_ptr = pcdev;
1479
1480     /*config output clk*/
1481         pcdev->aclk_ddr_lcdc = clk_get(&pdev->dev, "aclk_ddr_lcdc");
1482         pcdev->aclk_disp_matrix = clk_get(&pdev->dev, "aclk_disp_matrix");
1483
1484         pcdev->hclk_cpu_display = clk_get(&pdev->dev, "hclk_cpu_display");
1485         pcdev->vip_slave = clk_get(&pdev->dev, "vip_slave");
1486         pcdev->vip_out = clk_get(&pdev->dev,"vip_out");
1487         pcdev->vip_input = clk_get(&pdev->dev,"vip_input");
1488         pcdev->vip_bus = clk_get(&pdev->dev, "vip_bus");
1489
1490         pcdev->hclk_disp_matrix = clk_get(&pdev->dev,"hclk_disp_matrix");
1491         pcdev->vip_matrix = clk_get(&pdev->dev,"vip_matrix");
1492
1493         pcdev->pd_display = clk_get(&pdev->dev,"pd_display");
1494
1495     if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix ||  !pcdev->hclk_cpu_display ||
1496                 !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display ||
1497                 IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) ||  IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) ||
1498                 IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus))  {
1499
1500         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
1501         err = -ENOENT;
1502         goto exit_reqmem;
1503     }
1504
1505         if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix ||
1506                 IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix))  {
1507
1508         RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n");
1509         err = -ENOENT;
1510         goto exit_reqmem;
1511     }
1512
1513     dev_set_drvdata(&pdev->dev, pcdev);
1514     pcdev->res = res;
1515
1516     pcdev->pdata = pdev->dev.platform_data;             /* ddl@rock-chips.com : Request IO in init function */
1517     if (pcdev->pdata && pcdev->pdata->io_init) {
1518         pcdev->pdata->io_init();
1519     }
1520         #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1521         if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) {
1522                 pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
1523                 pcdev->vipmem_size = pcdev->pdata->meminfo.size;
1524                 RK29CAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
1525         } else {
1526                 RK29CAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
1527                 pcdev->vipmem_phybase = 0;
1528                 pcdev->vipmem_size = 0;
1529         }
1530         #endif
1531     INIT_LIST_HEAD(&pcdev->capture);
1532     spin_lock_init(&pcdev->lock);
1533
1534     /*
1535      * Request the regions.
1536      */
1537     if (!request_mem_region(res->start, res->end - res->start + 1,
1538                             RK29_CAM_DRV_NAME)) {
1539         err = -EBUSY;
1540         goto exit_reqmem;
1541     }
1542
1543     pcdev->base = ioremap(res->start, res->end - res->start + 1);
1544     if (pcdev->base == NULL) {
1545         dev_err(pcdev->dev, "ioremap() of registers failed\n");
1546         err = -ENXIO;
1547         goto exit_ioremap;
1548     }
1549
1550     pcdev->irq = irq;
1551     pcdev->dev = &pdev->dev;
1552
1553     /* config buffer address */
1554     /* request irq */
1555     err = request_irq(pcdev->irq, rk29_camera_irq, 0, RK29_CAM_DRV_NAME,
1556                       pcdev);
1557     if (err) {
1558         dev_err(pcdev->dev, "Camera interrupt register failed \n");
1559         goto exit_reqirq;
1560     }
1561
1562         pcdev->camera_wq = create_workqueue("camera wq");
1563         if (pcdev->camera_wq == NULL)
1564                 goto exit_free_irq;
1565         INIT_WORK(&pcdev->camera_reinit_work, rk29_camera_reinit_work);
1566
1567     pcdev->soc_host.drv_name    = RK29_CAM_DRV_NAME;
1568     pcdev->soc_host.ops         = &rk29_soc_camera_host_ops;
1569     pcdev->soc_host.priv                = pcdev;
1570     pcdev->soc_host.v4l2_dev.dev        = &pdev->dev;
1571     pcdev->soc_host.nr          = pdev->id;
1572
1573     err = soc_camera_host_register(&pcdev->soc_host);
1574     if (err)
1575         goto exit_free_irq;
1576
1577         hrtimer_init(&pcdev->fps_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1578         pcdev->fps_timer.function = rk29_camera_fps_func;
1579
1580     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
1581     return 0;
1582
1583 exit_free_irq:
1584     free_irq(pcdev->irq, pcdev);
1585         if (pcdev->camera_wq) {
1586                 destroy_workqueue(pcdev->camera_wq);
1587                 pcdev->camera_wq = NULL;
1588         }
1589 exit_reqirq:
1590     iounmap(pcdev->base);
1591 exit_ioremap:
1592     release_mem_region(res->start, res->end - res->start + 1);
1593 exit_reqmem:
1594     if (pcdev->aclk_ddr_lcdc) {
1595                 clk_put(pcdev->aclk_ddr_lcdc);
1596                 pcdev->aclk_ddr_lcdc = NULL;
1597     }
1598         if (pcdev->aclk_disp_matrix) {
1599                 clk_put(pcdev->aclk_disp_matrix);
1600                 pcdev->aclk_disp_matrix = NULL;
1601     }
1602         if (pcdev->hclk_cpu_display) {
1603                 clk_put(pcdev->hclk_cpu_display);
1604                 pcdev->hclk_cpu_display = NULL;
1605     }
1606         if (pcdev->vip_slave) {
1607                 clk_put(pcdev->vip_slave);
1608                 pcdev->vip_slave = NULL;
1609     }
1610         if (pcdev->vip_out) {
1611                 clk_put(pcdev->vip_out);
1612                 pcdev->vip_out = NULL;
1613     }
1614         if (pcdev->vip_input) {
1615                 clk_put(pcdev->vip_input);
1616                 pcdev->vip_input = NULL;
1617     }
1618         if (pcdev->vip_bus) {
1619                 clk_put(pcdev->vip_bus);
1620                 pcdev->vip_bus = NULL;
1621     }
1622     if (pcdev->hclk_disp_matrix) {
1623                 clk_put(pcdev->hclk_disp_matrix);
1624                 pcdev->hclk_disp_matrix = NULL;
1625     }
1626         if (pcdev->vip_matrix) {
1627                 clk_put(pcdev->vip_matrix);
1628                 pcdev->vip_matrix = NULL;
1629     }
1630     kfree(pcdev);
1631 exit_alloc:
1632     rk29_camdev_info_ptr = NULL;
1633 exit:
1634     return err;
1635 }
1636
1637 static int __devexit rk29_camera_remove(struct platform_device *pdev)
1638 {
1639     struct rk29_camera_dev *pcdev = platform_get_drvdata(pdev);
1640     struct resource *res;
1641
1642     free_irq(pcdev->irq, pcdev);
1643
1644         if (pcdev->camera_wq) {
1645                 destroy_workqueue(pcdev->camera_wq);
1646                 pcdev->camera_wq = NULL;
1647         }
1648
1649     soc_camera_host_unregister(&pcdev->soc_host);
1650
1651     res = pcdev->res;
1652     release_mem_region(res->start, res->end - res->start + 1);
1653
1654     if (pcdev->pdata && pcdev->pdata->io_deinit) {         /* ddl@rock-chips.com : Free IO in deinit function */
1655         pcdev->pdata->io_deinit(0);
1656                 pcdev->pdata->io_deinit(1);
1657     }
1658
1659     kfree(pcdev);
1660     rk29_camdev_info_ptr = NULL;
1661     dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
1662
1663     return 0;
1664 }
1665
1666 static struct platform_driver rk29_camera_driver =
1667 {
1668     .driver     = {
1669         .name   = RK29_CAM_DRV_NAME,
1670     },
1671     .probe              = rk29_camera_probe,
1672     .remove             = __devexit_p(rk29_camera_remove),
1673 };
1674
1675
1676 static int __devinit rk29_camera_init(void)
1677 {
1678     RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
1679     return platform_driver_register(&rk29_camera_driver);
1680 }
1681
1682 static void __exit rk29_camera_exit(void)
1683 {
1684     platform_driver_unregister(&rk29_camera_driver);
1685 }
1686
1687 device_initcall_sync(rk29_camera_init);
1688 module_exit(rk29_camera_exit);
1689
1690 MODULE_DESCRIPTION("RK29 Soc Camera Host driver");
1691 MODULE_AUTHOR("ddl <ddl@rock-chips>");
1692 MODULE_LICENSE("GPL");