2 * V4L2 Driver for RK28 camera host
4 * Copyright (C) 2006, Sascha Hauer, Pengutronix
5 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
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.
12 #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK30)
13 #include <linux/init.h>
14 #include <linux/module.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/errno.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
24 #include <linux/moduleparam.h>
25 #include <linux/time.h>
26 #include <linux/clk.h>
27 #include <linux/version.h>
28 #include <linux/device.h>
29 #include <linux/platform_device.h>
30 #include <linux/mutex.h>
31 #include <linux/videodev2.h>
32 #include <linux/kthread.h>
33 #include <mach/iomux.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-dev.h>
36 #include <media/videobuf-dma-contig.h>
37 #include <media/soc_camera.h>
38 #include <media/soc_mediabus.h>
41 #include <plat/vpu_service.h>
42 #include "../../video/rockchip/rga/rga.h"
43 #if defined(CONFIG_ARCH_RK30)
44 #include <mach/rk30_camera.h>
49 #if defined(CONFIG_ARCH_RK2928)
50 #include <mach/rk2928_camera.h>
52 #include <asm/cacheflush.h>
54 module_param(debug, int, S_IRUGO|S_IWUSR);
56 #define dprintk(level, fmt, arg...) do { \
58 printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
60 #define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
61 #define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
63 #define CIF_CIF_CTRL 0x00
64 #define CIF_CIF_INTEN 0x04
65 #define CIF_CIF_INTSTAT 0x08
66 #define CIF_CIF_FOR 0x0c
67 #define CIF_CIF_LINE_NUM_ADDR 0x10
68 #define CIF_CIF_FRM0_ADDR_Y 0x14
69 #define CIF_CIF_FRM0_ADDR_UV 0x18
70 #define CIF_CIF_FRM1_ADDR_Y 0x1c
71 #define CIF_CIF_FRM1_ADDR_UV 0x20
72 #define CIF_CIF_VIR_LINE_WIDTH 0x24
73 #define CIF_CIF_SET_SIZE 0x28
74 #define CIF_CIF_SCM_ADDR_Y 0x2c
75 #define CIF_CIF_SCM_ADDR_U 0x30
76 #define CIF_CIF_SCM_ADDR_V 0x34
77 #define CIF_CIF_WB_UP_FILTER 0x38
78 #define CIF_CIF_WB_LOW_FILTER 0x3c
79 #define CIF_CIF_WBC_CNT 0x40
80 #define CIF_CIF_CROP 0x44
81 #define CIF_CIF_SCL_CTRL 0x48
82 #define CIF_CIF_SCL_DST 0x4c
83 #define CIF_CIF_SCL_FCT 0x50
84 #define CIF_CIF_SCL_VALID_NUM 0x54
85 #define CIF_CIF_LINE_LOOP_CTR 0x58
86 #define CIF_CIF_FRAME_STATUS 0x60
87 #define CIF_CIF_CUR_DST 0x64
88 #define CIF_CIF_LAST_LINE 0x68
89 #define CIF_CIF_LAST_PIX 0x6c
91 //The key register bit descrition
92 // CIF_CTRL Reg , ignore SCM,WBC,ISP,
93 #define DISABLE_CAPTURE (0x00<<0)
94 #define ENABLE_CAPTURE (0x01<<0)
95 #define MODE_ONEFRAME (0x00<<1)
96 #define MODE_PINGPONG (0x01<<1)
97 #define MODE_LINELOOP (0x02<<1)
98 #define AXI_BURST_16 (0x0F << 12)
101 #define FRAME_END_EN (0x01<<1)
102 #define BUS_ERR_EN (0x01<<6)
103 #define SCL_ERR_EN (0x01<<7)
106 #define VSY_HIGH_ACTIVE (0x01<<0)
107 #define VSY_LOW_ACTIVE (0x00<<0)
108 #define HSY_LOW_ACTIVE (0x01<<1)
109 #define HSY_HIGH_ACTIVE (0x00<<1)
110 #define INPUT_MODE_YUV (0x00<<2)
111 #define INPUT_MODE_PAL (0x02<<2)
112 #define INPUT_MODE_NTSC (0x03<<2)
113 #define INPUT_MODE_RAW (0x04<<2)
114 #define INPUT_MODE_JPEG (0x05<<2)
115 #define INPUT_MODE_MIPI (0x06<<2)
116 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
117 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
118 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
119 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
120 #define YUV_INPUT_422 (0x00<<7)
121 #define YUV_INPUT_420 (0x01<<7)
122 #define INPUT_420_ORDER_EVEN (0x00<<8)
123 #define INPUT_420_ORDER_ODD (0x01<<8)
124 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
125 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
126 #define RAW_DATA_WIDTH_8 (0x00<<11)
127 #define RAW_DATA_WIDTH_10 (0x01<<11)
128 #define RAW_DATA_WIDTH_12 (0x02<<11)
129 #define YUV_OUTPUT_422 (0x00<<16)
130 #define YUV_OUTPUT_420 (0x01<<16)
131 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
132 #define OUTPUT_420_ORDER_ODD (0x01<<17)
133 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
134 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
135 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
136 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
139 #define ENABLE_SCL_DOWN (0x01<<0)
140 #define DISABLE_SCL_DOWN (0x00<<0)
141 #define ENABLE_SCL_UP (0x01<<1)
142 #define DISABLE_SCL_UP (0x00<<1)
143 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
144 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
145 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
146 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
147 #define ENABLE_32BIT_BYPASS (0x01<<6)
148 #define DISABLE_32BIT_BYPASS (0x00<<6)
151 #define MIN(x,y) ((x<y) ? x: y)
152 #define MAX(x,y) ((x>y) ? x: y)
153 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
154 #define RK_SENSOR_48MHZ 48
156 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
157 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
158 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
160 #if defined(CONFIG_ARCH_RK30)
162 #define CRU_PCLK_REG30 0xbc
163 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
164 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
165 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
166 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
168 #define CRU_CIF_RST_REG30 0x128
169 #define MASK_RST_CIF0 (0x01 << 30)
170 #define MASK_RST_CIF1 (0x01 << 31)
171 #define RQUEST_RST_CIF0 (0x01 << 14)
172 #define RQUEST_RST_CIF1 (0x01 << 15)
174 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
175 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
176 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
179 #if defined(CONFIG_ARCH_RK3066B)
181 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
182 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
183 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
184 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
185 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
188 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
189 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
190 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
192 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
193 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
194 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
196 #define write_grf_reg(addr, val)
197 #define read_grf_reg(addr) 0
198 #define mask_grf_reg(addr, msk, val)
201 #if defined(CONFIG_ARCH_RK2928)
202 #define write_cru_reg(addr, val)
203 #define read_cru_reg(addr) 0
204 #define mask_cru_reg(addr, msk, val)
208 //when work_with_ipp is not enabled,CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF is not defined.something wrong with it
209 #ifdef CONFIG_VIDEO_RK29_WORK_IPP//CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
210 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
211 #define CAM_WORKQUEUE_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
212 || (pcdev->icd_cb.sensor_cb))
213 #define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))
215 #define CAM_WORKQUEUE_IS_EN() (true)
216 #define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
218 #else //CONFIG_VIDEO_RK29_WORK_IPP
219 #define CAM_WORKQUEUE_IS_EN() (false)
220 #define CAM_IPPWORK_IS_EN() (false)
223 #define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
224 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
225 #define CROP_ALIGN_BYTES (0x03)
226 #define CIF_DO_CROP 0
227 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
228 #define CROP_ALIGN_BYTES (0x03)
229 #define CIF_DO_CROP 0
230 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
231 #define CROP_ALIGN_BYTES (0x03)
232 #define CIF_DO_CROP 0
233 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
234 #define CROP_ALIGN_BYTES (0x0F)
235 #define CIF_DO_CROP 1
239 * Driver Version Note
241 *v0.0.x : this driver is 2.6.32 kernel driver;
242 *v0.1.x : this driver is 3.0.8 kernel driver;
244 *v0.x.1 : this driver first support rk2918;
245 *v0.x.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420
246 * and V4L2_PIX_FMT_YUV422P;
247 *v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
248 *v0.x.4 : this driver support digital zoom;
249 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
250 *v0.x.6 : this driver improve test framerate method;
251 *v0.x.7 : digital zoom use the ipp to do scale and crop , otherwise ipp just do the scale. Something wrong with digital zoom if
252 we do crop with cif and do scale with ipp , we will fix this next version.
253 *v0.x.8 : temp version,reinit capture list when setup video buf.
254 *v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version.
255 2. flush workqueue when releas buffer
256 *v0.x.a: 1. reset cif and wake up vb when cif have't receive data in a fixed time(now setted as 2 secs) so that app can
258 2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
259 3. when front and back camera are the same sensor,and one has the flash ,other is not,flash can't work corrrectly ,fix it
260 4. add menu configs for convineuent to customize sensor series
261 *v0.x.b: specify the version is NOT sure stable.
262 *v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
263 2. irq process is splitted to two step.
264 *v0.x.e: fix bugs of early suspend when display_pd is closed.
265 *v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
266 *v0.x.11: fix struct rk_camera_work may be reentrant
267 *v0.x.13: 1.add scale by arm,rga and pp.
268 2.CIF do the crop when digital zoom.
269 3.fix bug in prob func:request mem twice.
270 4.video_vq may be null when reinit work,fix it
271 5.arm scale algorithm has something wrong(may exceed the bound of width or height) ,fix it.
273 * 1. support rk3066b;
276 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0x15)
278 /* limit to rk29 hardware capabilities */
279 #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
280 SOCAM_HSYNC_ACTIVE_HIGH |\
281 SOCAM_HSYNC_ACTIVE_LOW |\
282 SOCAM_VSYNC_ACTIVE_HIGH |\
283 SOCAM_VSYNC_ACTIVE_LOW |\
284 SOCAM_PCLK_SAMPLE_RISING |\
285 SOCAM_PCLK_SAMPLE_FALLING|\
286 SOCAM_DATA_ACTIVE_HIGH |\
287 SOCAM_DATA_ACTIVE_LOW|\
288 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
289 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
291 #define RK_CAM_W_MIN 48
292 #define RK_CAM_H_MIN 32
293 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
294 #define RK_CAM_H_MAX 2764
295 #define RK_CAM_FRAME_INVAL_INIT 3
296 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
297 #define RK30_CAM_FRAME_MEASURE 5
298 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
299 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
301 /* buffer for one video frame */
302 struct rk_camera_buffer
304 /* common v4l buffer stuff -- must be first */
305 struct videobuf_buffer vb;
306 enum v4l2_mbus_pixelcode code;
309 enum rk_camera_reg_state
317 unsigned int cifCtrl;
318 unsigned int cifCrop;
320 unsigned int cifIntEn;
322 unsigned int cifVirWidth;
323 unsigned int cifScale;
324 // unsigned int VipCrm;
325 enum rk_camera_reg_state Inval;
327 struct rk_camera_work
329 struct videobuf_buffer *vb;
330 struct rk_camera_dev *pcdev;
331 struct work_struct work;
332 struct list_head queue;
335 struct rk_camera_frmivalenum
337 struct v4l2_frmivalenum fival;
338 struct rk_camera_frmivalenum *nxt;
340 struct rk_camera_frmivalinfo
342 struct soc_camera_device *icd;
343 struct rk_camera_frmivalenum *fival_list;
345 struct rk_camera_zoominfo
347 struct semaphore sem;
353 #if CAMERA_VIDEOBUF_ARM_ACCESS
354 struct rk29_camera_vbinfo
356 unsigned int phy_addr;
357 void __iomem *vir_addr;
361 struct rk_camera_timer{
362 struct rk_camera_dev *pcdev;
363 struct hrtimer timer;
368 struct soc_camera_host soc_host;
370 /* RK2827x is only supposed to handle one camera on its Quick Capture
371 * interface. If anyone ever builds hardware to enable more than
372 * one camera, they will have to modify this driver too */
373 struct soc_camera_device *icd;
375 //************must modify start************/
377 struct clk *aclk_cif;
378 struct clk *hclk_cif;
379 struct clk *cif_clk_in;
380 struct clk *cif_clk_out;
381 //************must modify end************/
383 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
386 unsigned int last_fps;
387 unsigned long frame_interval;
390 unsigned int vipmem_phybase;
391 void __iomem *vipmem_virbase;
392 unsigned int vipmem_size;
393 unsigned int vipmem_bsize;
394 #if CAMERA_VIDEOBUF_ARM_ACCESS
395 struct rk29_camera_vbinfo *vbinfo;
396 unsigned int vbinfo_count;
400 int host_left; //sensor output size ?
406 struct rk29camera_platform_data *pdata;
407 struct resource *res;
408 struct list_head capture;
409 struct rk_camera_zoominfo zoominfo;
413 struct videobuf_buffer *active;
414 struct rk_camera_reg reginfo_suspend;
415 struct workqueue_struct *camera_wq;
416 struct rk_camera_work *camera_work;
417 struct list_head camera_work_queue;
418 spinlock_t camera_work_lock;
419 unsigned int camera_work_count;
420 struct rk_camera_timer fps_timer;
421 struct rk_camera_work camera_reinit_work;
423 rk29_camera_sensor_cb_s icd_cb;
424 struct rk_camera_frmivalinfo icd_frmival[2];
425 // atomic_t to_process_frames;
427 unsigned int reinit_times;
428 struct videobuf_queue *video_vq;
430 struct timeval first_tv;
433 static const struct v4l2_queryctrl rk_camera_controls[] =
435 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
437 .id = V4L2_CID_ZOOM_ABSOLUTE,
438 .type = V4L2_CTRL_TYPE_INTEGER,
439 .name = "DigitalZoom Control",
443 .default_value = 100,
448 static DEFINE_MUTEX(camera_lock);
449 static const char *rk_cam_driver_description = "RK_Camera";
451 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
452 static void rk_camera_capture_process(struct work_struct *work);
456 * Videobuf operations
458 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
461 struct soc_camera_device *icd = vq->priv_data;
462 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
463 struct rk_camera_dev *pcdev = ici->priv;
465 struct rk_camera_work *wk;
467 struct soc_mbus_pixelfmt fmt;
469 int bytes_per_line_host;
470 fmt.packing = SOC_MBUS_PACKING_1_5X8;
472 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
473 icd->current_fmt->host_fmt);
474 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
475 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
477 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
478 bytes_per_line_host = pcdev->host_width*3;
480 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
481 icd->current_fmt->host_fmt);
482 printk("user code = %d,packing = %d",icd->current_fmt->code,fmt.packing);
483 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
485 if (bytes_per_line_host < 0)
486 return bytes_per_line_host;
488 /* planar capture requires Y, U and V buffers to be page aligned */
489 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
490 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
492 if (CAM_WORKQUEUE_IS_EN()) {
493 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
494 if (CAM_IPPWORK_IS_EN())
497 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
498 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
499 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
502 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
503 kfree(pcdev->camera_work);
504 pcdev->camera_work = NULL;
505 pcdev->camera_work_count = 0;
508 if (pcdev->camera_work == NULL) {
509 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
510 if (pcdev->camera_work == NULL) {
511 RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
514 INIT_LIST_HEAD(&pcdev->camera_work_queue);
516 for (i=0; i<(*count); i++) {
518 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
521 pcdev->camera_work_count = (*count);
523 #if CAMERA_VIDEOBUF_ARM_ACCESS
524 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
525 kfree(pcdev->vbinfo);
526 pcdev->vbinfo = NULL;
527 pcdev->vbinfo_count = 0x00;
530 if (pcdev->vbinfo == NULL) {
531 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
532 if (pcdev->vbinfo == NULL) {
533 RKCAMERA_TR("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
536 pcdev->vbinfo_count = *count;
540 pcdev->video_vq = vq;
541 RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
545 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
547 struct soc_camera_device *icd = vq->priv_data;
549 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
550 &buf->vb, buf->vb.baddr, buf->vb.bsize);
552 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
553 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
559 * This waits until this buffer is out of danger, i.e., until it is no
560 * longer in STATE_QUEUED or STATE_ACTIVE
562 //videobuf_waiton(vq, &buf->vb, 0, 0);
563 videobuf_dma_contig_free(vq, &buf->vb);
564 dev_dbg(&icd->dev, "%s freed\n", __func__);
565 buf->vb.state = VIDEOBUF_NEEDS_INIT;
568 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
570 struct soc_camera_device *icd = vq->priv_data;
571 struct rk_camera_buffer *buf;
573 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
574 icd->current_fmt->host_fmt);
575 if (bytes_per_line < 0)
576 return bytes_per_line;
578 buf = container_of(vb, struct rk_camera_buffer, vb);
580 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
581 vb, vb->baddr, vb->bsize);
583 /* Added list head initialization on alloc */
584 WARN_ON(!list_empty(&vb->queue));
586 BUG_ON(NULL == icd->current_fmt);
588 if (buf->code != icd->current_fmt->code ||
589 vb->width != icd->user_width ||
590 vb->height != icd->user_height ||
591 vb->field != field) {
592 buf->code = icd->current_fmt->code;
593 vb->width = icd->user_width;
594 vb->height = icd->user_height;
596 vb->state = VIDEOBUF_NEEDS_INIT;
599 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
600 if (0 != vb->baddr && vb->bsize < vb->size) {
605 if (vb->state == VIDEOBUF_NEEDS_INIT) {
606 ret = videobuf_iolock(vq, vb, NULL);
610 vb->state = VIDEOBUF_PREPARED;
615 rk_videobuf_free(vq, buf);
620 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
622 unsigned int y_addr,uv_addr;
623 struct rk_camera_dev *pcdev = rk_pcdev;
626 if (CAM_WORKQUEUE_IS_EN()) {
627 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
628 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
629 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
630 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
631 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
636 uv_addr = y_addr + vb->width * vb->height;
638 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
639 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
640 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
641 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
642 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
645 /* Locking: Caller holds q->irqlock */
646 static void rk_videobuf_queue(struct videobuf_queue *vq,
647 struct videobuf_buffer *vb)
649 struct soc_camera_device *icd = vq->priv_data;
650 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
651 struct rk_camera_dev *pcdev = ici->priv;
652 #if CAMERA_VIDEOBUF_ARM_ACCESS
653 struct rk29_camera_vbinfo *vb_info;
656 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
657 vb, vb->baddr, vb->bsize);
659 vb->state = VIDEOBUF_QUEUED;
660 if (list_empty(&pcdev->capture)) {
661 list_add_tail(&vb->queue, &pcdev->capture);
663 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
664 list_add_tail(&vb->queue, &pcdev->capture);
666 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
668 #if CAMERA_VIDEOBUF_ARM_ACCESS
670 vb_info = pcdev->vbinfo+vb->i;
671 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
672 if (vb_info->vir_addr) {
673 iounmap(vb_info->vir_addr);
674 release_mem_region(vb_info->phy_addr, vb_info->size);
675 vb_info->vir_addr = NULL;
676 vb_info->phy_addr = 0x00;
677 vb_info->size = 0x00;
680 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
681 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
684 if (vb_info->vir_addr) {
685 vb_info->size = vb->bsize;
686 vb_info->phy_addr = vb->boff;
688 RKCAMERA_TR("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
693 if (!pcdev->active) {
695 rk_videobuf_capture(vb,pcdev);
698 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
702 case V4L2_PIX_FMT_NV16:
703 case V4L2_PIX_FMT_NV61:
705 *ippfmt = IPP_Y_CBCR_H2V1;
708 case V4L2_PIX_FMT_NV12:
709 case V4L2_PIX_FMT_NV21:
711 *ippfmt = IPP_Y_CBCR_H2V2;
715 goto rk_pixfmt2ippfmt_err;
719 rk_pixfmt2ippfmt_err:
723 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
727 case V4L2_PIX_FMT_YUV420:
728 case V4L2_PIX_FMT_UYVY: // yuv 422, but sensor has defined this format(in fact ,should be defined yuv 420), treat this as yuv 420.
729 case V4L2_PIX_FMT_YUYV:
731 *ippfmt = RK_FORMAT_YCbCr_420_SP;
734 case V4L2_PIX_FMT_YVU420:
735 case V4L2_PIX_FMT_VYUY:
736 case V4L2_PIX_FMT_YVYU:
738 *ippfmt = RK_FORMAT_YCrCb_420_SP;
741 case V4L2_PIX_FMT_RGB565:
743 *ippfmt = RK_FORMAT_RGB_565;
746 case V4L2_PIX_FMT_RGB24:
748 *ippfmt = RK_FORMAT_RGB_888;
752 goto rk_pixfmt2rgafmt_err;
756 rk_pixfmt2rgafmt_err:
759 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
760 static int rk_camera_scale_crop_pp(struct work_struct *work){
761 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
762 struct videobuf_buffer *vb = camera_work->vb;
763 struct rk_camera_dev *pcdev = camera_work->pcdev;
765 unsigned long int flags;
771 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
773 memset(&init, 0, sizeof(init));
774 init.srcAddr = vipdata_base;
775 init.srcFormat = PP_IN_FORMAT_YUV420SEMI;
776 init.srcWidth = init.srcHStride = pcdev->zoominfo.vir_width;
777 init.srcHeight = init.srcVStride = pcdev->zoominfo.vir_height;
779 init.dstAddr = vb->boff;
780 init.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE;
781 init.dstWidth = init.dstHStride = pcdev->icd->user_width;
782 init.dstHeight = init.dstVStride = pcdev->icd->user_height;
784 printk("srcWidth = %d,srcHeight = %d,dstWidth = %d,dstHeight = %d\n",init.srcWidth,init.srcHeight,init.dstWidth,init.dstHeight);
786 ret = ppOpInit(&hnd, &init);
792 printk("can not create ppOp handle\n");
798 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
799 extern rga_service_info rga_service;
800 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
801 extern void rga_service_session_clear(rga_session *session);
802 static int rk_camera_scale_crop_rga(struct work_struct *work){
803 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
804 struct videobuf_buffer *vb = camera_work->vb;
805 struct rk_camera_dev *pcdev = camera_work->pcdev;
807 unsigned long int flags;
813 const struct soc_mbus_pixelfmt *fmt;
815 fmt = soc_mbus_get_fmtdesc(pcdev->icd->current_fmt->code);
816 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
817 if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
818 && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
819 RKCAMERA_TR("RGA not support this format !\n");
822 if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
823 scale_times = MAX((pcdev->icd->user_width/0x800),(pcdev->icd->user_height/0x800));
828 session.pid = current->pid;
829 INIT_LIST_HEAD(&session.waiting);
830 INIT_LIST_HEAD(&session.running);
831 INIT_LIST_HEAD(&session.list_session);
832 init_waitqueue_head(&session.wait);
833 /* no need to protect */
834 list_add_tail(&session.list_session, &rga_service.session);
835 atomic_set(&session.task_running, 0);
836 atomic_set(&session.num_done, 0);
838 memset(&req,0,sizeof(struct rga_req));
839 req.src.act_w = pcdev->zoominfo.a.c.width/scale_times;
840 req.src.act_h = pcdev->zoominfo.a.c.height/scale_times;
842 req.src.vir_w = pcdev->zoominfo.vir_width;
843 req.src.vir_h =pcdev->zoominfo.vir_height;
844 req.src.yrgb_addr = vipdata_base;
845 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
846 req.src.v_addr = req.src.uv_addr ;
847 req.src.format =fmt->fourcc;
848 rk_pixfmt2rgafmt(fmt->fourcc,&req.src.format);
849 req.src.x_offset = pcdev->zoominfo.a.c.left;
850 req.src.y_offset = pcdev->zoominfo.a.c.top;
852 req.dst.act_w = pcdev->icd->user_width/scale_times;
853 req.dst.act_h = pcdev->icd->user_height/scale_times;
855 req.dst.vir_w = pcdev->icd->user_width;
856 req.dst.vir_h = pcdev->icd->user_height;
857 req.dst.x_offset = 0;
858 req.dst.y_offset = 0;
859 req.dst.yrgb_addr = vb->boff;
860 rk_pixfmt2rgafmt(pcdev->icd->current_fmt->host_fmt->fourcc,&req.dst.format);
862 req.clip.xmax = req.dst.vir_w-1;
864 req.clip.ymax = req.dst.vir_h -1;
871 req.mmu_info.mmu_en = 0;
873 for (h=0; h<scale_times; h++) {
874 for (w=0; w<scale_times; w++) {
877 req.src.yrgb_addr = vipdata_base;
878 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
879 req.src.x_offset = pcdev->zoominfo.a.c.left+w*pcdev->zoominfo.a.c.width/scale_times;
880 req.src.y_offset = pcdev->zoominfo.a.c.top+h*pcdev->zoominfo.a.c.height/scale_times;
881 req.dst.x_offset = pcdev->icd->user_width*w/scale_times;
882 req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
883 req.dst.yrgb_addr = vb->boff ;
884 // RKCAMERA_TR("src.act_w = %d , src.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
885 // RKCAMERA_TR("dst.act_w = %d , dst.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
886 // RKCAMERA_TR("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
888 while(rga_times-- > 0) {
889 if (rga_blit_sync(&session, &req)){
890 RKCAMERA_TR("rga do erro,do again,rga_times = %d!\n",rga_times);
896 if (rga_times <= 0) {
897 spin_lock_irqsave(&pcdev->lock, flags);
898 vb->state = VIDEOBUF_NEEDS_INIT;
899 spin_unlock_irqrestore(&pcdev->lock, flags);
900 mutex_lock(&rga_service.lock);
901 list_del(&session.list_session);
902 rga_service_session_clear(&session);
903 mutex_unlock(&rga_service.lock);
909 mutex_lock(&rga_service.lock);
910 list_del(&session.list_session);
911 rga_service_session_clear(&session);
912 mutex_unlock(&rga_service.lock);
921 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
923 static int rk_camera_scale_crop_ipp(struct work_struct *work)
925 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
926 struct videobuf_buffer *vb = camera_work->vb;
927 struct rk_camera_dev *pcdev = camera_work->pcdev;
929 unsigned long int flags;
931 struct rk29_ipp_req ipp_req;
932 int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
937 * IPP Dest image resolution is 2047x1088, so scale operation break up some times
939 if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
940 scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));
945 memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
948 ipp_req.timeout = 3000;
949 ipp_req.flag = IPP_ROT_0;
950 ipp_req.store_clip_mode =1;
951 ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
952 ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
953 ipp_req.src_vir_w = pcdev->zoominfo.vir_width;
954 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
955 ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
956 ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
957 ipp_req.dst_vir_w = pcdev->icd->user_width;
958 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
959 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
960 src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height; //vipmem
961 dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
962 for (h=0; h<scale_times; h++) {
963 for (w=0; w<scale_times; w++) {
965 src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width
966 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
967 src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width/2
968 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
970 dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
971 dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
973 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
974 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
975 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
976 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
977 while(ipp_times-- > 0) {
978 if (ipp_blit_sync(&ipp_req)){
979 RKCAMERA_TR("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
985 if (ipp_times <= 0) {
986 spin_lock_irqsave(&pcdev->lock, flags);
987 vb->state = VIDEOBUF_NEEDS_INIT;
988 spin_unlock_irqrestore(&pcdev->lock, flags);
989 RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
990 RKCAMERA_TR("widx:%d hidx:%d ",w,h);
991 RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
992 RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
993 RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
994 RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
995 RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
996 RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
997 RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
998 RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
999 RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
1010 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
1011 static int rk_camera_scale_crop_arm(struct work_struct *work)
1013 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1014 struct videobuf_buffer *vb = camera_work->vb;
1015 struct rk_camera_dev *pcdev = camera_work->pcdev;
1016 struct rk29_camera_vbinfo *vb_info;
1017 unsigned char *psY,*pdY,*psUV,*pdUV;
1018 unsigned char *src,*dst;
1019 unsigned long src_phy,dst_phy;
1020 int srcW,srcH,cropW,cropH,dstW,dstH;
1021 long zoomindstxIntInv,zoomindstyIntInv;
1023 long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
1028 src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
1029 src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
1030 psUV = psY + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
1032 srcW = pcdev->zoominfo.vir_width;
1033 srcH = pcdev->zoominfo.vir_height;
1034 cropW = pcdev->zoominfo.a.c.width;
1035 cropH = pcdev->zoominfo.a.c.height;
1037 psY = psY + (srcW-cropW);
1038 psUV = psUV + (srcW-cropW);
1040 vb_info = pcdev->vbinfo+vb->i;
1041 dst_phy = vb_info->phy_addr;
1042 dst = pdY = (unsigned char*)vb_info->vir_addr;
1043 pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
1044 dstW = pcdev->icd->user_width;
1045 dstH = pcdev->icd->user_height;
1047 zoomindstxIntInv = ((unsigned long)cropW<<16)/dstW + 1;
1048 zoomindstyIntInv = ((unsigned long)cropH<<16)/dstH + 1;
1051 //for(y = 0; y<dstH - 1 ; y++ ) {
1052 for(y = 0; y<dstH; y++ ) {
1053 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1054 yCoeff01 = 0xffff - yCoeff00;
1055 sY = (y*zoomindstyIntInv >> 16);
1056 sY = (sY >= srcH - 1)? (srcH - 2) : sY;
1057 for(x = 0; x<dstW; x++ ) {
1058 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1059 xCoeff01 = 0xffff - xCoeff00;
1060 sX = (x*zoomindstxIntInv >> 16);
1061 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1062 a = psY[sY*srcW + sX];
1063 b = psY[sY*srcW + sX + 1];
1064 c = psY[(sY+1)*srcW + sX];
1065 d = psY[(sY+1)*srcW + sX + 1];
1067 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1068 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1069 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1082 //for(y = 0; y<dstH - 1 ; y++ ) {
1083 for(y = 0; y<dstH; y++ ) {
1084 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1085 yCoeff01 = 0xffff - yCoeff00;
1086 sY = (y*zoomindstyIntInv >> 16);
1087 sY = (sY >= srcH -1)? (srcH - 2) : sY;
1088 for(x = 0; x<dstW; x++ ) {
1089 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1090 xCoeff01 = 0xffff - xCoeff00;
1091 sX = (x*zoomindstxIntInv >> 16);
1092 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1094 a = psUV[(sY*srcW + sX)*2];
1095 b = psUV[(sY*srcW + sX + 1)*2];
1096 c = psUV[((sY+1)*srcW + sX)*2];
1097 d = psUV[((sY+1)*srcW + sX + 1)*2];
1099 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1100 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1101 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1106 a = psUV[(sY*srcW + sX)*2 + 1];
1107 b = psUV[(sY*srcW + sX + 1)*2 + 1];
1108 c = psUV[((sY+1)*srcW + sX)*2 + 1];
1109 d = psUV[((sY+1)*srcW + sX + 1)*2 + 1];
1111 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1112 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1113 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1120 rk_camera_scale_crop_arm_end:
1122 dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
1123 outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
1125 dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
1126 outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
1131 static void rk_camera_capture_process(struct work_struct *work)
1133 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1134 struct videobuf_buffer *vb = camera_work->vb;
1135 struct rk_camera_dev *pcdev = camera_work->pcdev;
1136 //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;
1137 unsigned long flags = 0;
1140 if (!CAM_WORKQUEUE_IS_EN())
1141 goto rk_camera_capture_process_end;
1143 down(&pcdev->zoominfo.sem);
1144 if (pcdev->icd_cb.scale_crop_cb){
1145 err = (pcdev->icd_cb.scale_crop_cb)(work);
1147 up(&pcdev->zoominfo.sem);
1149 if (pcdev->icd_cb.sensor_cb)
1150 (pcdev->icd_cb.sensor_cb)(vb);
1152 rk_camera_capture_process_end:
1154 vb->state = VIDEOBUF_ERROR;
1156 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1157 vb->state = VIDEOBUF_DONE;
1161 wake_up(&(camera_work->vb->done));
1162 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1163 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1164 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1167 static irqreturn_t rk_camera_irq(int irq, void *data)
1169 struct rk_camera_dev *pcdev = data;
1170 struct videobuf_buffer *vb;
1171 struct rk_camera_work *wk;
1173 unsigned long tmp_intstat;
1174 unsigned long tmp_cifctrl;
1176 tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1177 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1178 if(pcdev->stop_cif == true)
1180 printk("cif has stopped by app,needn't to deal this irq\n");
1181 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
1184 if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/){//bit9 =1 ,bit0 = 0
1185 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1186 if(tmp_cifctrl & ENABLE_CAPTURE)
1187 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
1191 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1192 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
1193 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1195 do_gettimeofday(&pcdev->first_tv);
1199 goto RK_CAMERA_IRQ_END;
1200 if (pcdev->frame_inval>0) {
1201 pcdev->frame_inval--;
1202 rk_videobuf_capture(pcdev->active,pcdev);
1203 goto RK_CAMERA_IRQ_END;
1204 } else if (pcdev->frame_inval) {
1205 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1206 pcdev->frame_inval = 0;
1208 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1209 do_gettimeofday(&tv);
1210 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1211 /(RK30_CAM_FRAME_MEASURE-1);
1215 printk("no acticve buffer!!!\n");
1216 goto RK_CAMERA_IRQ_END;
1218 /* ddl@rock-chips.com : this vb may be deleted from queue */
1219 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1220 list_del_init(&vb->queue);
1222 pcdev->active = NULL;
1223 if (!list_empty(&pcdev->capture)) {
1224 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1225 if (pcdev->active) {
1226 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1227 rk_videobuf_capture(pcdev->active,pcdev);
1230 if (pcdev->active == NULL) {
1231 RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
1234 do_gettimeofday(&vb->ts);
1235 if (CAM_WORKQUEUE_IS_EN()) {
1236 if (!list_empty(&pcdev->camera_work_queue)) {
1237 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1238 list_del_init(&wk->queue);
1239 INIT_WORK(&(wk->work), rk_camera_capture_process);
1242 queue_work(pcdev->camera_wq, &(wk->work));
1245 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1246 vb->state = VIDEOBUF_DONE;
1255 if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
1256 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
1261 static void rk_videobuf_release(struct videobuf_queue *vq,
1262 struct videobuf_buffer *vb)
1264 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1265 struct soc_camera_device *icd = vq->priv_data;
1266 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1267 struct rk_camera_dev *pcdev = ici->priv;
1268 #if CAMERA_VIDEOBUF_ARM_ACCESS
1269 struct rk29_camera_vbinfo *vb_info =NULL;
1273 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1274 vb, vb->baddr, vb->bsize);
1278 case VIDEOBUF_ACTIVE:
1279 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1281 case VIDEOBUF_QUEUED:
1282 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1284 case VIDEOBUF_PREPARED:
1285 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1288 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1292 if (vb == pcdev->active) {
1293 RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
1294 interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
1295 RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
1298 flush_workqueue(pcdev->camera_wq);
1299 #if CAMERA_VIDEOBUF_ARM_ACCESS
1300 if (pcdev->vbinfo) {
1301 vb_info = pcdev->vbinfo + vb->i;
1303 if (vb_info->vir_addr) {
1304 iounmap(vb_info->vir_addr);
1305 release_mem_region(vb_info->phy_addr, vb_info->size);
1306 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1311 rk_videobuf_free(vq, buf);
1314 static struct videobuf_queue_ops rk_videobuf_ops =
1316 .buf_setup = rk_videobuf_setup,
1317 .buf_prepare = rk_videobuf_prepare,
1318 .buf_queue = rk_videobuf_queue,
1319 .buf_release = rk_videobuf_release,
1322 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1323 struct soc_camera_device *icd)
1325 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1326 struct rk_camera_dev *pcdev = ici->priv;
1328 /* We must pass NULL as dev pointer, then all pci_* dma operations
1329 * transform to normal dma_* ones. */
1330 videobuf_queue_dma_contig_init(q,
1332 ici->v4l2_dev.dev, &pcdev->lock,
1333 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1335 sizeof(struct rk_camera_buffer),
1336 icd,&icd->video_lock);
1338 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1342 if(!pcdev->aclk_cif || !pcdev->hclk_cif || !pcdev->cif_clk_in || !pcdev->cif_clk_out){
1343 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1345 goto RK_CAMERA_ACTIVE_ERR;
1348 clk_enable(pcdev->pd_cif);
1349 clk_enable(pcdev->aclk_cif);
1351 clk_enable(pcdev->hclk_cif);
1352 clk_enable(pcdev->cif_clk_in);
1354 //if (icd->ops->query_bus_param) /* ddl@rock-chips.com : Query Sensor's xclk */
1355 //sensor_bus_flags = icd->ops->query_bus_param(icd);
1356 clk_enable(pcdev->cif_clk_out);
1357 clk_set_rate(pcdev->cif_clk_out,RK_SENSOR_24MHZ);
1360 //soft reset the registers
1361 #if 0 //has somthing wrong when suspend and resume now
1363 printk("before set cru register reset cif0 0x%x\n\n",read_cru_reg(CRU_CIF_RST_REG30));
1366 printk("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
1367 printk("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
1368 printk("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
1369 printk("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
1370 printk("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
1371 printk("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
1372 printk("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
1373 printk("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
1374 printk("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
1376 printk("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
1377 printk("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
1378 printk("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
1379 printk("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
1380 printk("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
1381 printk("CIF_CIF_FRAME_STATUS = 0X%x\n\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
1385 write_cru_reg(CRU_CIF_RST_REG30,(/*read_cru_reg(CRU_CIF_RST_REG30)|*/MASK_RST_CIF0|RQUEST_RST_CIF0 ));
1386 printk("set cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1387 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1389 printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1391 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1392 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1395 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1396 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1397 RKCAMERA_DG("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
1399 RK_CAMERA_ACTIVE_ERR:
1403 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1405 clk_disable(pcdev->aclk_cif);
1407 clk_disable(pcdev->hclk_cif);
1408 clk_disable(pcdev->cif_clk_in);
1410 clk_disable(pcdev->cif_clk_out);
1411 clk_enable(pcdev->cif_clk_out);
1412 clk_set_rate(pcdev->cif_clk_out,48*1000*1000);
1413 clk_disable(pcdev->cif_clk_out);
1415 clk_disable(pcdev->pd_cif);
1420 /* The following two functions absolutely depend on the fact, that
1421 * there can be only one camera on RK28 quick capture interface */
1422 static int rk_camera_add_device(struct soc_camera_device *icd)
1424 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1425 struct rk_camera_dev *pcdev = ici->priv;
1426 struct device *control = to_soc_camera_control(icd);
1427 struct v4l2_subdev *sd;
1428 int ret,i,icd_catch;
1429 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1431 mutex_lock(&camera_lock);
1438 RKCAMERA_DG("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1440 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1441 pcdev->active = NULL;
1443 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1444 pcdev->zoominfo.zoom_rate = 100;
1445 pcdev->fps_timer.istarted = false;
1447 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1448 * if app havn't dequeue all videobuf before close camera device;
1450 INIT_LIST_HEAD(&pcdev->capture);
1452 ret = rk_camera_activate(pcdev,icd);
1455 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1457 sd = dev_get_drvdata(control);
1458 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1460 ret = v4l2_subdev_call(sd,core, init, 0);
1464 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1467 pcdev->icd_init = 0;
1470 for (i=0; i<2; i++) {
1471 if (pcdev->icd_frmival[i].icd == icd)
1473 if (pcdev->icd_frmival[i].icd == NULL) {
1474 pcdev->icd_frmival[i].icd = icd;
1478 if (icd_catch == 0) {
1479 fival_list = pcdev->icd_frmival[0].fival_list;
1480 fival_nxt = fival_list;
1481 while(fival_nxt != NULL) {
1482 fival_nxt = fival_list->nxt;
1484 fival_list = fival_nxt;
1486 pcdev->icd_frmival[0].icd = icd;
1487 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1490 mutex_unlock(&camera_lock);
1494 static void rk_camera_remove_device(struct soc_camera_device *icd)
1496 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1497 struct rk_camera_dev *pcdev = ici->priv;
1498 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1499 #if CAMERA_VIDEOBUF_ARM_ACCESS
1500 struct rk29_camera_vbinfo *vb_info;
1504 mutex_lock(&camera_lock);
1505 BUG_ON(icd != pcdev->icd);
1507 RKCAMERA_DG("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1509 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1510 stream may be turn on again before close device, if suspend and resume happened. */
1511 if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
1512 rk_camera_s_stream(icd,0);
1515 //soft reset the registers
1516 #if 0 //has somthing wrong when suspend and resume now
1518 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF0|RQUEST_RST_CIF0 | (read_cru_reg(CRU_CIF_RST_REG30)));
1519 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1521 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1522 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1525 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
1526 //if stream off is not been executed,timer is running.
1527 if(pcdev->fps_timer.istarted){
1528 hrtimer_cancel(&pcdev->fps_timer.timer);
1529 pcdev->fps_timer.istarted = false;
1531 flush_work(&(pcdev->camera_reinit_work.work));
1532 flush_workqueue((pcdev->camera_wq));
1534 if (pcdev->camera_work) {
1535 kfree(pcdev->camera_work);
1536 pcdev->camera_work = NULL;
1537 pcdev->camera_work_count = 0;
1538 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1540 rk_camera_deactivate(pcdev);
1541 #if CAMERA_VIDEOBUF_ARM_ACCESS
1542 if (pcdev->vbinfo) {
1543 vb_info = pcdev->vbinfo;
1544 for (i=0; i<pcdev->vbinfo_count; i++) {
1545 if (vb_info->vir_addr) {
1546 iounmap(vb_info->vir_addr);
1547 release_mem_region(vb_info->phy_addr, vb_info->size);
1548 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1552 kfree(pcdev->vbinfo);
1553 pcdev->vbinfo = NULL;
1554 pcdev->vbinfo_count = 0;
1557 pcdev->active = NULL;
1559 pcdev->icd_cb.sensor_cb = NULL;
1560 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1561 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1562 * if app havn't dequeue all videobuf before close camera device;
1564 INIT_LIST_HEAD(&pcdev->capture);
1566 mutex_unlock(&camera_lock);
1567 RKCAMERA_DG("%s exit\n",__FUNCTION__);
1571 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1573 unsigned long bus_flags, camera_flags, common_flags;
1574 unsigned int cif_ctrl_val = 0;
1575 const struct soc_mbus_pixelfmt *fmt;
1577 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1578 struct rk_camera_dev *pcdev = ici->priv;
1579 RKCAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
1581 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1585 bus_flags = RK_CAM_BUS_PARAM;
1586 /* If requested data width is supported by the platform, use it */
1587 switch (fmt->bits_per_sample) {
1589 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1593 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1597 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1604 if (icd->ops->query_bus_param)
1605 camera_flags = icd->ops->query_bus_param(icd);
1609 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1610 if (!common_flags) {
1612 goto RK_CAMERA_SET_BUS_PARAM_END;
1615 ret = icd->ops->set_bus_param(icd, common_flags);
1617 goto RK_CAMERA_SET_BUS_PARAM_END;
1619 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1620 RKCAMERA_DG("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
1621 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1623 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1624 RKCAMERA_DG("enable cif0 pclk invert\n");
1626 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1627 RKCAMERA_DG("enable cif1 pclk invert\n");
1631 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1632 RKCAMERA_DG("diable cif0 pclk invert\n");
1634 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1635 RKCAMERA_DG("diable cif1 pclk invert\n");
1638 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
1639 cif_ctrl_val |= HSY_LOW_ACTIVE;
1641 cif_ctrl_val &= ~HSY_LOW_ACTIVE;
1643 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1644 cif_ctrl_val |= VSY_HIGH_ACTIVE;
1646 cif_ctrl_val &= ~VSY_HIGH_ACTIVE;
1649 /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1650 //vip_ctrl_val |= ENABLE_CAPTURE;
1651 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
1652 RKCAMERA_DG("%s..ctrl:0x%x CIF_CIF_FOR=%x \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1654 RK_CAMERA_SET_BUS_PARAM_END:
1656 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1660 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1662 unsigned long bus_flags, camera_flags;
1665 bus_flags = RK_CAM_BUS_PARAM;
1666 if (icd->ops->query_bus_param) {
1667 camera_flags = icd->ops->query_bus_param(icd);
1671 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1674 dev_warn(icd->dev.parent,
1675 "Flags incompatible: camera %lx, host %lx\n",
1676 camera_flags, bus_flags);
1680 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1682 .fourcc = V4L2_PIX_FMT_NV12,
1683 .name = "YUV420 NV12",
1684 .bits_per_sample = 8,
1685 .packing = SOC_MBUS_PACKING_1_5X8,
1686 .order = SOC_MBUS_ORDER_LE,
1688 .fourcc = V4L2_PIX_FMT_NV16,
1689 .name = "YUV422 NV16",
1690 .bits_per_sample = 8,
1691 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1692 .order = SOC_MBUS_ORDER_LE,
1694 .fourcc = V4L2_PIX_FMT_NV21,
1695 .name = "YUV420 NV21",
1696 .bits_per_sample = 8,
1697 .packing = SOC_MBUS_PACKING_1_5X8,
1698 .order = SOC_MBUS_ORDER_LE,
1700 .fourcc = V4L2_PIX_FMT_NV61,
1701 .name = "YUV422 NV61",
1702 .bits_per_sample = 8,
1703 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1704 .order = SOC_MBUS_ORDER_LE,
1706 .fourcc = V4L2_PIX_FMT_RGB565,
1708 .bits_per_sample = 8,
1709 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1710 .order = SOC_MBUS_ORDER_LE,
1712 .fourcc = V4L2_PIX_FMT_RGB24,
1714 .bits_per_sample = 8,
1715 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1716 .order = SOC_MBUS_ORDER_LE,
1720 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1722 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1723 struct rk_camera_dev *pcdev = ici->priv;
1724 unsigned int cif_fs = 0,cif_crop = 0;
1725 unsigned int cif_fmt_val = read_cif_reg(pcdev->base,CIF_CIF_FOR) | INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN;
1727 const struct soc_mbus_pixelfmt *fmt;
1728 fmt = soc_mbus_get_fmtdesc(icd_code);
1730 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1731 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1732 host_pixfmt = V4L2_PIX_FMT_NV12;
1733 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1734 host_pixfmt = V4L2_PIX_FMT_NV21;
1736 switch (host_pixfmt)
1738 case V4L2_PIX_FMT_NV16:
1739 cif_fmt_val &= ~YUV_OUTPUT_422;
1740 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1741 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1742 pcdev->pixfmt = host_pixfmt;
1744 case V4L2_PIX_FMT_NV61:
1745 cif_fmt_val &= ~YUV_OUTPUT_422;
1746 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1747 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1748 pcdev->pixfmt = host_pixfmt;
1750 case V4L2_PIX_FMT_NV12:
1751 cif_fmt_val |= YUV_OUTPUT_420;
1752 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1753 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1754 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1755 pcdev->pixfmt = host_pixfmt;
1757 case V4L2_PIX_FMT_NV21:
1758 cif_fmt_val |= YUV_OUTPUT_420;
1759 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1760 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1761 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1762 pcdev->pixfmt = host_pixfmt;
1764 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1765 cif_fmt_val |= YUV_OUTPUT_422;
1770 case V4L2_MBUS_FMT_UYVY8_2X8:
1771 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1773 case V4L2_MBUS_FMT_YUYV8_2X8:
1774 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1776 case V4L2_MBUS_FMT_YVYU8_2X8:
1777 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1779 case V4L2_MBUS_FMT_VYUY8_2X8:
1780 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1783 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1788 #ifdef CONFIG_ARCH_RK30
1791 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1792 cru_set_soft_reset(SOFT_RST_CIF0, true);
1794 cru_set_soft_reset(SOFT_RST_CIF0, false);
1795 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1798 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1799 cru_set_soft_reset(SOFT_RST_CIF1, true);
1801 cru_set_soft_reset(SOFT_RST_CIF1, false);
1802 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1806 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1807 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable
1809 write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val); /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
1811 // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */
1812 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1813 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1814 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1816 } else{ // this is one frame mode
1817 cif_crop = (rect->left+ (rect->top<<16));
1818 cif_fs = ((rect->width ) + (rect->height<<16));
1820 RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__);
1822 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1823 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1824 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1825 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1828 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1829 RKCAMERA_DG("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1833 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1834 struct soc_camera_format_xlate *xlate)
1836 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1837 struct device *dev = icd->dev.parent;
1838 int formats = 0, ret;
1839 enum v4l2_mbus_pixelcode code;
1840 const struct soc_mbus_pixelfmt *fmt;
1842 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1844 /* No more formats */
1847 fmt = soc_mbus_get_fmtdesc(code);
1849 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1853 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1858 case V4L2_MBUS_FMT_UYVY8_2X8:
1859 case V4L2_MBUS_FMT_YUYV8_2X8:
1860 case V4L2_MBUS_FMT_YVYU8_2X8:
1861 case V4L2_MBUS_FMT_VYUY8_2X8:
1862 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1865 xlate->host_fmt = &rk_camera_formats[0];
1868 dev_dbg(dev, "Providing format %s using code %d\n",
1869 rk_camera_formats[0].name,code);
1874 xlate->host_fmt = &rk_camera_formats[1];
1877 dev_dbg(dev, "Providing format %s using code %d\n",
1878 rk_camera_formats[1].name,code);
1883 xlate->host_fmt = &rk_camera_formats[2];
1886 dev_dbg(dev, "Providing format %s using code %d\n",
1887 rk_camera_formats[2].name,code);
1892 xlate->host_fmt = &rk_camera_formats[3];
1895 dev_dbg(dev, "Providing format %s using code %d\n",
1896 rk_camera_formats[3].name,code);
1902 xlate->host_fmt = &rk_camera_formats[4];
1905 dev_dbg(dev, "Providing format %s using code %d\n",
1906 rk_camera_formats[4].name,code);
1910 xlate->host_fmt = &rk_camera_formats[5];
1913 dev_dbg(dev, "Providing format %s using code %d\n",
1914 rk_camera_formats[5].name,code);
1925 static void rk_camera_put_formats(struct soc_camera_device *icd)
1930 static int rk_camera_set_crop(struct soc_camera_device *icd,
1931 struct v4l2_crop *a)
1933 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1934 struct v4l2_mbus_framefmt mf;
1935 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1938 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1942 if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) {
1944 mf.width = a->c.left + a->c.width;
1945 mf.height = a->c.top + a->c.height;
1947 v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
1948 &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
1949 fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
1951 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1956 rk_camera_setup_format(icd, fourcc, mf.code, &a->c);
1958 icd->user_width = mf.width;
1959 icd->user_height = mf.height;
1964 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1965 struct v4l2_format *f)
1967 struct device *dev = icd->dev.parent;
1968 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1969 const struct soc_camera_format_xlate *xlate = NULL;
1970 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
1971 struct rk_camera_dev *pcdev = ici->priv;
1972 struct v4l2_pix_format *pix = &f->fmt.pix;
1973 struct v4l2_mbus_framefmt mf;
1974 struct v4l2_rect rect;
1975 int ret,usr_w,usr_h;
1979 usr_h = pix->height;
1980 RKCAMERA_TR("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
1981 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1983 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1985 goto RK_CAMERA_SET_FMT_END;
1988 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1989 if (pcdev->icd_init == 0) {
1990 v4l2_subdev_call(sd,core, init, 0);
1991 pcdev->icd_init = 1;
1993 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1994 if (stream_on & ENABLE_CAPTURE)
1995 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1997 mf.width = pix->width;
1998 mf.height = pix->height;
1999 mf.field = pix->field;
2000 mf.colorspace = pix->colorspace;
2001 mf.code = xlate->code;
2002 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2003 if (mf.code != xlate->code)
2005 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2006 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2008 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2009 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2011 goto RK_CAMERA_SET_FMT_END;
2013 if (unlikely((usr_w <16)||(usr_h < 16))) {
2014 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2016 goto RK_CAMERA_SET_FMT_END;
2019 if((mf.width*10/mf.height) != (usr_w*10/usr_h)){
2020 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2021 pcdev->host_width = ratio*usr_w/10;
2022 pcdev->host_height = ratio*usr_h/10;
2023 //for ipp ,need 4 bit alligned.
2024 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2025 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2026 RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
2028 else{ // needn't crop ,just scaled by ipp
2029 pcdev->host_width = mf.width;
2030 pcdev->host_height = mf.height;
2034 pcdev->host_width = usr_w;
2035 pcdev->host_height = usr_h;
2038 //according to crop and scale capability to change , here just cropt to user needed
2039 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2040 RKCAMERA_TR("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
2042 goto RK_CAMERA_SET_FMT_END;
2044 if (unlikely((usr_w <16)||(usr_h < 16))) {
2045 RKCAMERA_TR("Senor invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2047 goto RK_CAMERA_SET_FMT_END;
2049 pcdev->host_width = usr_w;
2050 pcdev->host_height = usr_h;
2054 RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__,
2055 pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h);
2056 rect.width = pcdev->host_width;
2057 rect.height = pcdev->host_height;
2058 rect.left = ((mf.width-pcdev->host_width )>>1)&(~0x01);
2059 rect.top = ((mf.height-pcdev->host_height)>>1)&(~0x01);
2060 pcdev->host_left = rect.left;
2061 pcdev->host_top = rect.top;
2063 down(&pcdev->zoominfo.sem);
2065 pcdev->zoominfo.a.c.left = 0;
2066 pcdev->zoominfo.a.c.top = 0;
2067 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2068 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2069 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2070 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2071 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2072 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2073 //recalculate the CIF width & height
2074 rect.width = pcdev->zoominfo.a.c.width ;
2075 rect.height = pcdev->zoominfo.a.c.height;
2076 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2077 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2079 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2080 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2081 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2082 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2083 //now digital zoom use ipp to do crop and scale
2084 if(pcdev->zoominfo.zoom_rate != 100){
2085 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2086 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2089 pcdev->zoominfo.a.c.left = 0;
2090 pcdev->zoominfo.a.c.top = 0;
2092 pcdev->zoominfo.vir_width = pcdev->host_width;
2093 pcdev->zoominfo.vir_height = pcdev->host_height;
2095 up(&pcdev->zoominfo.sem);
2097 /* ddl@rock-chips.com: IPP work limit check */
2098 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2099 if (usr_w > 0x7f0) {
2100 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2101 RKCAMERA_TR("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f));
2103 goto RK_CAMERA_SET_FMT_END;
2106 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2107 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2109 goto RK_CAMERA_SET_FMT_END;
2113 RKCAMERA_DG("%s..%s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
2114 rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2115 pix->width, pix->height);
2116 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2118 if (CAM_IPPWORK_IS_EN()) {
2119 BUG_ON(pcdev->vipmem_phybase == 0);
2122 pix->height = usr_h;
2123 pix->field = mf.field;
2124 pix->colorspace = mf.colorspace;
2125 icd->current_fmt = xlate;
2126 pcdev->icd_width = mf.width;
2127 pcdev->icd_height = mf.height;
2130 RK_CAMERA_SET_FMT_END:
2131 if (stream_on & ENABLE_CAPTURE)
2132 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2134 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2137 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
2141 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
2143 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
2145 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
2147 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
2149 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
2154 RKCAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
2157 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2158 struct v4l2_format *f)
2160 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2161 struct rk_camera_dev *pcdev = ici->priv;
2162 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2163 const struct soc_camera_format_xlate *xlate;
2164 struct v4l2_pix_format *pix = &f->fmt.pix;
2165 __u32 pixfmt = pix->pixelformat;
2166 int ret,usr_w,usr_h,i;
2167 bool is_capture = rk_camera_fmt_capturechk(f);
2168 bool vipmem_is_overflow = false;
2169 struct v4l2_mbus_framefmt mf;
2170 int bytes_per_line_host;
2173 usr_h = pix->height;
2174 RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
2176 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2178 dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2179 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2181 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2182 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2183 for (i = 0; i < icd->num_user_formats; i++)
2184 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2185 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2186 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2187 icd->user_formats[i].host_fmt->name);
2188 goto RK_CAMERA_TRY_FMT_END;
2190 /* limit to rk29 hardware capabilities */
2191 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2192 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2193 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2195 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2197 if (pix->bytesperline < 0)
2198 return pix->bytesperline;
2200 /* limit to sensor capabilities */
2201 mf.width = pix->width;
2202 mf.height = pix->height;
2203 mf.field = pix->field;
2204 mf.colorspace = pix->colorspace;
2205 mf.code = xlate->code;
2207 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2209 goto RK_CAMERA_TRY_FMT_END;
2210 RKCAMERA_DG("%s mf.width:%d mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
2211 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2212 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2213 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2215 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2217 /* Assume preview buffer minimum is 4 */
2218 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2220 if (vipmem_is_overflow == false) {
2222 pix->height = usr_h;
2224 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
2225 pix->width = mf.width;
2226 pix->height = mf.height;
2229 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2230 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2231 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2232 pix->width = mf.width;
2233 pix->height = mf.height;
2238 //need to change according to crop and scale capablicity
2239 if ((mf.width > usr_w) && (mf.height > usr_h)) {
2241 pix->height = usr_h;
2242 } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
2243 RKCAMERA_TR("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
2244 pix->width = mf.width;
2245 pix->height = mf.height;
2248 pix->colorspace = mf.colorspace;
2251 case V4L2_FIELD_ANY:
2252 case V4L2_FIELD_NONE:
2253 pix->field = V4L2_FIELD_NONE;
2256 /* TODO: support interlaced at least in pass-through mode */
2257 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
2259 goto RK_CAMERA_TRY_FMT_END;
2262 RK_CAMERA_TRY_FMT_END:
2264 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2268 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2269 struct v4l2_requestbuffers *p)
2273 /* This is for locking debugging only. I removed spinlocks and now I
2274 * check whether .prepare is ever called on a linked buffer, or whether
2275 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2276 * it hadn't triggered */
2277 for (i = 0; i < p->count; i++) {
2278 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2279 struct rk_camera_buffer, vb);
2281 INIT_LIST_HEAD(&buf->vb.queue);
2287 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2289 struct soc_camera_device *icd = file->private_data;
2290 struct rk_camera_buffer *buf;
2292 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2295 poll_wait(file, &buf->vb.done, pt);
2297 if (buf->vb.state == VIDEOBUF_DONE ||
2298 buf->vb.state == VIDEOBUF_ERROR)
2299 return POLLIN|POLLRDNORM;
2304 static int rk_camera_querycap(struct soc_camera_host *ici,
2305 struct v4l2_capability *cap)
2307 struct rk_camera_dev *pcdev = ici->priv;
2308 char orientation[5];
2311 strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
2312 memset(orientation,0x00,sizeof(orientation));
2313 for (i=0; i<RK_CAM_NUM;i++) {
2314 if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
2315 sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
2319 if (orientation[0] != '-') {
2320 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2321 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2322 strcat(cap->card,"-270");
2324 strcat(cap->card,"-90");
2326 strcat(cap->card,orientation);
2328 cap->version = RK_CAM_VERSION_CODE;
2329 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2333 static void rk_camera_store_register(struct rk_camera_dev *pcdev)
2335 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2336 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2337 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2338 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2339 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2340 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2341 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2343 static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
2345 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2346 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2347 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2348 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2349 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2350 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2351 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2353 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2355 struct soc_camera_host *ici =
2356 to_soc_camera_host(icd->dev.parent);
2357 struct rk_camera_dev *pcdev = ici->priv;
2358 struct v4l2_subdev *sd;
2361 mutex_lock(&camera_lock);
2362 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2363 rk_camera_s_stream(icd, 0);
2364 sd = soc_camera_to_subdev(icd);
2365 v4l2_subdev_call(sd, video, s_stream, 0);
2366 ret = icd->ops->suspend(icd, state);
2368 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2369 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2370 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2371 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2372 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2373 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2374 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2376 pcdev->reginfo_suspend.Inval = Reg_Validate;
2377 rk_camera_deactivate(pcdev);
2379 RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__);
2381 RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2383 mutex_unlock(&camera_lock);
2387 static int rk_camera_resume(struct soc_camera_device *icd)
2389 struct soc_camera_host *ici =
2390 to_soc_camera_host(icd->dev.parent);
2391 struct rk_camera_dev *pcdev = ici->priv;
2392 struct v4l2_subdev *sd;
2395 mutex_lock(&camera_lock);
2396 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2397 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2398 rk_camera_activate(pcdev, icd);
2399 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2400 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2401 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2402 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2403 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2404 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2405 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2406 rk_videobuf_capture(pcdev->active,pcdev);
2407 rk_camera_s_stream(icd, 1);
2408 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2410 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2411 goto rk_camera_resume_end;
2414 ret = icd->ops->resume(icd);
2415 sd = soc_camera_to_subdev(icd);
2416 v4l2_subdev_call(sd, video, s_stream, 1);
2418 RKCAMERA_DG("%s Enter success\n",__FUNCTION__);
2420 RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2423 rk_camera_resume_end:
2424 mutex_unlock(&camera_lock);
2428 static void rk_camera_reinit_work(struct work_struct *work)
2430 struct v4l2_subdev *sd;
2431 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2432 struct rk_camera_dev *pcdev = camera_work->pcdev;
2433 struct soc_camera_link *tmp_soc_cam_link;
2435 unsigned long flags = 0;
2436 if(pcdev->icd == NULL)
2438 sd = soc_camera_to_subdev(pcdev->icd);
2439 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2442 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2443 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2444 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2445 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2446 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2447 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2448 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2449 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2450 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2452 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2453 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2454 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2455 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2456 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2457 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2460 pcdev->stop_cif = true;
2461 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2462 RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
2463 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2464 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2465 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2466 if (NULL == pcdev->video_vq->bufs[index])
2469 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
2471 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2472 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2473 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2474 printk("wake up video buffer index = %d !!!\n",index);
2477 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2479 RKCAMERA_TR("video queue has somthing wrong !!\n");
2482 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2484 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2486 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2487 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2488 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2490 // static unsigned int last_fps = 0;
2491 struct soc_camera_link *tmp_soc_cam_link;
2492 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2494 RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2495 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2496 RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
2497 pcdev->camera_reinit_work.pcdev = pcdev;
2498 //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2499 pcdev->reinit_times++;
2500 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2501 } else if(!pcdev->timer_get_fps) {
2502 pcdev->timer_get_fps = true;
2503 for (i=0; i<2; i++) {
2504 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2505 fival_nxt = pcdev->icd_frmival[i].fival_list;
2510 fival_pre = fival_nxt;
2511 while (fival_nxt != NULL) {
2513 RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
2514 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2515 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2516 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2517 fival_nxt->fival.discrete.numerator);
2519 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2520 && (fival_nxt->fival.height == pcdev->icd->user_height)
2521 && (fival_nxt->fival.width == pcdev->icd->user_width))
2522 || (fival_nxt->fival.discrete.denominator == 0)) {
2524 if (fival_nxt->fival.discrete.denominator == 0) {
2525 fival_nxt->fival.index = 0;
2526 fival_nxt->fival.width = pcdev->icd->user_width;
2527 fival_nxt->fival.height= pcdev->icd->user_height;
2528 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2529 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2530 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2531 |(pcdev->icd_height);
2532 fival_nxt->fival.discrete.numerator = 1000000;
2533 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2536 fival_rec = fival_nxt;
2538 fival_pre = fival_nxt;
2539 fival_nxt = fival_nxt->nxt;
2542 if ((rec_flag == 0) && fival_pre) {
2543 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2544 if (fival_pre->nxt != NULL) {
2545 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2546 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2547 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2548 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2550 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2551 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2552 |(pcdev->icd_height);
2553 fival_pre->nxt->fival.discrete.numerator = 1000000;
2554 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2556 fival_rec = fival_pre->nxt;
2560 pcdev->last_fps = pcdev->fps ;
2561 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2562 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2563 //return HRTIMER_NORESTART;
2564 if(pcdev->reinit_times >=2)
2565 return HRTIMER_NORESTART;
2567 return HRTIMER_RESTART;
2569 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2571 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2572 struct rk_camera_dev *pcdev = ici->priv;
2575 unsigned long flags;
2577 WARN_ON(pcdev->icd != icd);
2579 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2582 pcdev->last_fps = 0;
2583 pcdev->frame_interval = 0;
2584 hrtimer_cancel(&(pcdev->fps_timer.timer));
2585 pcdev->fps_timer.pcdev = pcdev;
2586 pcdev->timer_get_fps = false;
2587 pcdev->reinit_times = 0;
2588 pcdev->stop_cif = false;
2589 // hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2590 cif_ctrl_val |= ENABLE_CAPTURE;
2591 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2592 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2593 pcdev->fps_timer.istarted = true;
2595 //cancel timer before stop cif
2596 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2597 pcdev->fps_timer.istarted = false;
2598 flush_work(&(pcdev->camera_reinit_work.work));
2600 cif_ctrl_val &= ~ENABLE_CAPTURE;
2601 spin_lock_irqsave(&pcdev->lock, flags);
2602 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2603 pcdev->stop_cif = true;
2604 spin_unlock_irqrestore(&pcdev->lock, flags);
2605 flush_workqueue((pcdev->camera_wq));
2606 RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
2608 //must be reinit,or will be somthing wrong in irq process.
2609 if(enable == false){
2610 pcdev->active = NULL;
2611 INIT_LIST_HEAD(&pcdev->capture);
2613 RKCAMERA_DG("%s.. enable : 0x%x , CIF_CIF_CTRL = 0x%x\n", __FUNCTION__, enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2616 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2618 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2619 struct rk_camera_dev *pcdev = ici->priv;
2620 struct rk_camera_frmivalenum *fival_list = NULL;
2621 struct v4l2_frmivalenum *fival_head = NULL;
2622 int i,ret = 0,index;
2624 index = fival->index & 0x00ffffff;
2625 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2626 for (i=0; i<2; i++) {
2627 if (pcdev->icd_frmival[i].icd == icd) {
2628 fival_list = pcdev->icd_frmival[i].fival_list;
2632 if (fival_list != NULL) {
2634 while (fival_list != NULL) {
2635 if ((fival->pixel_format == fival_list->fival.pixel_format)
2636 && (fival->height == fival_list->fival.height)
2637 && (fival->width == fival_list->fival.width)) {
2642 fival_list = fival_list->nxt;
2645 if ((i==index) && (fival_list != NULL)) {
2646 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2651 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2656 for (i=0; i<RK_CAM_NUM; i++) {
2657 if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
2658 fival_head = pcdev->pdata->info[i].fival;
2662 if (fival_head == NULL) {
2663 RKCAMERA_TR("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
2665 goto rk_camera_enum_frameintervals_end;
2669 while (fival_head->width && fival_head->height) {
2670 if ((fival->pixel_format == fival_head->pixel_format)
2671 && (fival->height == fival_head->height)
2672 && (fival->width == fival_head->width)) {
2681 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2682 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2683 RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2684 fival->width, fival->height,
2685 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2686 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2687 fival->discrete.denominator,fival->discrete.numerator);
2690 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2691 fival->width,fival->height,
2692 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2693 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2696 RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2697 fival->width,fival->height,
2698 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2699 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2704 rk_camera_enum_frameintervals_end:
2708 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2709 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2710 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2713 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2714 struct rk_camera_dev *pcdev = ici->priv;
2716 unsigned long tmp_cifctrl;
2719 //change the crop and scale parameters
2722 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2723 //a.c.width = pcdev->host_width*100/zoom_rate;
2724 a.c.width = pcdev->host_width*100/zoom_rate;
2725 a.c.width &= ~CROP_ALIGN_BYTES;
2726 a.c.height = pcdev->host_height*100/zoom_rate;
2727 a.c.height &= ~CROP_ALIGN_BYTES;
2728 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2729 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2730 pcdev->stop_cif = true;
2731 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2732 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2733 hrtimer_cancel(&(pcdev->fps_timer.timer));
2734 flush_workqueue((pcdev->camera_wq));
2735 down(&pcdev->zoominfo.sem);
2736 pcdev->zoominfo.a.c.left = 0;
2737 pcdev->zoominfo.a.c.top = 0;
2738 pcdev->zoominfo.a.c.width = a.c.width;
2739 pcdev->zoominfo.a.c.height = a.c.height;
2740 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2741 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2742 pcdev->frame_inval = 1;
2743 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2744 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2745 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2746 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2748 rk_videobuf_capture(pcdev->active,pcdev);
2749 if(tmp_cifctrl & ENABLE_CAPTURE)
2750 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2751 up(&pcdev->zoominfo.sem);
2752 pcdev->stop_cif = false;
2753 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2754 RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2756 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2757 a.c.width = pcdev->host_width*100/zoom_rate;
2758 a.c.width &= ~CROP_ALIGN_BYTES;
2759 a.c.height = pcdev->host_height*100/zoom_rate;
2760 a.c.height &= ~CROP_ALIGN_BYTES;
2761 a.c.left = (pcdev->host_width - a.c.width)>>1;
2762 a.c.top = (pcdev->host_height - a.c.height)>>1;
2763 down(&pcdev->zoominfo.sem);
2764 pcdev->zoominfo.a.c.height = a.c.height;
2765 pcdev->zoominfo.a.c.width = a.c.width;
2766 pcdev->zoominfo.a.c.top = a.c.top;
2767 pcdev->zoominfo.a.c.left = a.c.left;
2768 pcdev->zoominfo.vir_width = pcdev->host_width;
2769 pcdev->zoominfo.vir_height= pcdev->host_height;
2770 up(&pcdev->zoominfo.sem);
2771 RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2777 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2778 struct soc_camera_host_ops *ops, int id)
2782 for (i = 0; i < ops->num_controls; i++)
2783 if (ops->controls[i].id == id)
2784 return &ops->controls[i];
2790 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2791 struct v4l2_control *sctrl)
2794 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2795 const struct v4l2_queryctrl *qctrl;
2796 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2797 struct rk_camera_dev *pcdev = ici->priv;
2801 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2804 goto rk_camera_set_ctrl_end;
2809 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2810 case V4L2_CID_ZOOM_ABSOLUTE:
2812 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2814 goto rk_camera_set_ctrl_end;
2816 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2818 pcdev->zoominfo.zoom_rate = sctrl->value;
2820 goto rk_camera_set_ctrl_end;
2829 rk_camera_set_ctrl_end:
2833 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2835 .owner = THIS_MODULE,
2836 .add = rk_camera_add_device,
2837 .remove = rk_camera_remove_device,
2838 .suspend = rk_camera_suspend,
2839 .resume = rk_camera_resume,
2840 .enum_frameinervals = rk_camera_enum_frameintervals,
2841 .set_crop = rk_camera_set_crop,
2842 .get_formats = rk_camera_get_formats,
2843 .put_formats = rk_camera_put_formats,
2844 .set_fmt = rk_camera_set_fmt,
2845 .try_fmt = rk_camera_try_fmt,
2846 .init_videobuf = rk_camera_init_videobuf,
2847 .reqbufs = rk_camera_reqbufs,
2848 .poll = rk_camera_poll,
2849 .querycap = rk_camera_querycap,
2850 .set_bus_param = rk_camera_set_bus_param,
2851 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2852 .set_ctrl = rk_camera_set_ctrl,
2853 .controls = rk_camera_controls,
2854 .num_controls = ARRAY_SIZE(rk_camera_controls)
2857 static void rk_camera_cif_iomux(int cif_index)
2859 #if defined(CONFIG_ARCH_RK3066B)
2862 rk30_mux_api_set(GPIO3B3_CIFCLKOUT_NAME, GPIO3B_CIFCLKOUT);
2863 write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_8MA));
2864 write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
2865 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
2866 rk30_mux_api_set(GPIO3B4_CIFDATA0_HSADCDATA8_NAME, GPIO3B_CIFDATA0);
2867 rk30_mux_api_set(GPIO3B5_CIFDATA1_HSADCDATA9_NAME, GPIO3B_CIFDATA1);
2869 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
2870 rk30_mux_api_set(GPIO3B6_CIFDATA10_I2C3SDA_NAME, GPIO3B_CIFDATA10);
2871 rk30_mux_api_set(GPIO3B7_CIFDATA11_I2C3SCL_NAME, GPIO3B_CIFDATA11);
2872 RKCAMERA_TR("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
2877 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
2880 #elif defined(CONFIG_ARCH_RK30)
2883 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
2884 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
2885 rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME, GPIO1B_CIF0_DATA0);
2886 rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME, GPIO1B_CIF0_DATA1);
2888 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
2889 rk30_mux_api_set(GPIO1B6_CIFDATA10_NAME, GPIO1B_CIF_DATA10);
2890 rk30_mux_api_set(GPIO1B7_CIFDATA11_NAME, GPIO1B_CIF_DATA11);
2894 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
2895 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
2896 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
2897 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
2898 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
2899 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
2900 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
2901 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
2903 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
2904 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
2905 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
2906 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
2907 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
2908 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
2909 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
2910 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
2913 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
2920 static int rk_camera_probe(struct platform_device *pdev)
2922 struct rk_camera_dev *pcdev;
2923 struct resource *res;
2924 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
2925 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
2929 printk("%s version: v%d.%d.%d Zoom by %s\n",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2930 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
2932 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
2933 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
2937 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
2938 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
2942 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2943 irq = platform_get_irq(pdev, 0);
2944 if (!res || irq < 0) {
2948 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
2950 dev_err(&pdev->dev, "Could not allocate pcdev\n");
2955 pcdev->zoominfo.zoom_rate = 100;
2956 pcdev->hostid = pdev->id;
2957 /*config output clk*/ // must modify start
2959 pcdev->pd_cif = clk_get(NULL, "pd_cif0");
2960 pcdev->aclk_cif = clk_get(NULL, "aclk_cif0");
2961 pcdev->hclk_cif = clk_get(NULL, "hclk_cif0");
2962 pcdev->cif_clk_in = clk_get(NULL, "cif0_in");
2963 pcdev->cif_clk_out = clk_get(NULL, "cif0_out");
2964 rk_camera_cif_iomux(0);
2966 pcdev->pd_cif = clk_get(NULL, "pd_cif1");
2967 pcdev->aclk_cif = clk_get(NULL, "aclk_cif1");
2968 pcdev->hclk_cif = clk_get(NULL, "hclk_cif1");
2969 pcdev->cif_clk_in = clk_get(NULL, "cif1_in");
2970 pcdev->cif_clk_out = clk_get(NULL, "cif1_out");
2972 rk_camera_cif_iomux(1);
2975 if(IS_ERR(pcdev->pd_cif) || IS_ERR(pcdev->aclk_cif) || IS_ERR(pcdev->hclk_cif) || IS_ERR(pcdev->cif_clk_in) || IS_ERR(pcdev->cif_clk_out)){
2976 RKCAMERA_TR(KERN_ERR "%s(%d): failed to get cif clock source\n",__FUNCTION__,__LINE__);
2978 goto exit_reqmem_vip;
2981 dev_set_drvdata(&pdev->dev, pcdev);
2983 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
2985 if (pcdev->pdata && pcdev->pdata->io_init) {
2986 pcdev->pdata->io_init();
2988 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2989 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
2990 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
2992 if (meminfo_ptr->vbase == NULL) {
2994 if ((meminfo_ptr->start == meminfo_ptrr->start)
2995 && (meminfo_ptr->size == meminfo_ptrr->size) && meminfo_ptrr->vbase) {
2997 meminfo_ptr->vbase = meminfo_ptrr->vbase;
3000 if (!request_mem_region(meminfo_ptr->start,meminfo_ptr->size,"rk29_vipmem")) {
3002 RKCAMERA_TR("%s(%d): request_mem_region(start:0x%x size:0x%x) failed \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
3003 goto exit_ioremap_vipmem;
3005 meminfo_ptr->vbase = pcdev->vipmem_virbase = ioremap_cached(meminfo_ptr->start,meminfo_ptr->size);
3006 if (pcdev->vipmem_virbase == NULL) {
3007 RKCAMERA_TR("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
3009 goto exit_ioremap_vipmem;
3014 pcdev->vipmem_phybase = meminfo_ptr->start;
3015 pcdev->vipmem_size = meminfo_ptr->size;
3016 pcdev->vipmem_virbase = meminfo_ptr->vbase;
3018 INIT_LIST_HEAD(&pcdev->capture);
3019 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3020 spin_lock_init(&pcdev->lock);
3021 spin_lock_init(&pcdev->camera_work_lock);
3022 sema_init(&pcdev->zoominfo.sem,1);
3025 * Request the regions.
3028 if (!request_mem_region(res->start, res->end - res->start + 1,
3029 RK29_CAM_DRV_NAME)) {
3031 goto exit_reqmem_vip;
3033 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3034 if (pcdev->base == NULL) {
3035 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3037 goto exit_ioremap_vip;
3042 pcdev->dev = &pdev->dev;
3044 /* config buffer address */
3047 err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3050 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3055 //#ifdef CONFIG_VIDEO_RK29_WORK_IPP
3057 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3059 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3061 if (pcdev->camera_wq == NULL)
3065 pcdev->camera_reinit_work.pcdev = pcdev;
3066 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3068 for (i=0; i<2; i++) {
3069 pcdev->icd_frmival[i].icd = NULL;
3070 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3073 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3074 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3075 pcdev->soc_host.priv = pcdev;
3076 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3077 pcdev->soc_host.nr = pdev->id;
3079 err = soc_camera_host_register(&pcdev->soc_host);
3082 pcdev->fps_timer.pcdev = pcdev;
3083 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3084 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3085 pcdev->icd_cb.sensor_cb = NULL;
3087 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3088 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3089 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3090 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3091 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3092 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3093 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3094 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3096 RKCAMERA_DG("%s(%d) Exit \n",__FUNCTION__,__LINE__);
3101 for (i=0; i<2; i++) {
3102 fival_list = pcdev->icd_frmival[i].fival_list;
3103 fival_nxt = fival_list;
3104 while(fival_nxt != NULL) {
3105 fival_nxt = fival_list->nxt;
3107 fival_list = fival_nxt;
3111 free_irq(pcdev->irq, pcdev);
3112 if (pcdev->camera_wq) {
3113 destroy_workqueue(pcdev->camera_wq);
3114 pcdev->camera_wq = NULL;
3117 iounmap(pcdev->base);
3119 release_mem_region(res->start, res->end - res->start + 1);
3120 exit_ioremap_vipmem:
3121 if (pcdev->vipmem_virbase)
3122 iounmap(pcdev->vipmem_virbase);
3123 release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
3126 pcdev->aclk_cif = NULL;
3128 pcdev->hclk_cif = NULL;
3129 if(pcdev->cif_clk_in)
3130 pcdev->cif_clk_in = NULL;
3131 if(pcdev->cif_clk_out)
3132 pcdev->cif_clk_out = NULL;
3141 static int __devexit rk_camera_remove(struct platform_device *pdev)
3143 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3144 struct resource *res;
3145 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3146 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
3149 free_irq(pcdev->irq, pcdev);
3151 if (pcdev->camera_wq) {
3152 destroy_workqueue(pcdev->camera_wq);
3153 pcdev->camera_wq = NULL;
3156 for (i=0; i<2; i++) {
3157 fival_list = pcdev->icd_frmival[i].fival_list;
3158 fival_nxt = fival_list;
3159 while(fival_nxt != NULL) {
3160 fival_nxt = fival_list->nxt;
3162 fival_list = fival_nxt;
3166 soc_camera_host_unregister(&pcdev->soc_host);
3168 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
3169 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
3170 if (meminfo_ptr->vbase) {
3171 if (meminfo_ptr->vbase == meminfo_ptrr->vbase) {
3172 meminfo_ptr->vbase = NULL;
3174 iounmap((void __iomem*)pcdev->vipmem_phybase);
3175 release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
3176 meminfo_ptr->vbase = NULL;
3181 iounmap((void __iomem*)pcdev->base);
3182 release_mem_region(res->start, res->end - res->start + 1);
3183 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3184 pcdev->pdata->io_deinit(0);
3185 pcdev->pdata->io_deinit(1);
3190 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3195 static struct platform_driver rk_camera_driver =
3198 .name = RK29_CAM_DRV_NAME,
3200 .probe = rk_camera_probe,
3201 .remove = __devexit_p(rk_camera_remove),
3204 static int rk_camera_init_async(void *unused)
3206 platform_driver_register(&rk_camera_driver);
3210 static int __devinit rk_camera_init(void)
3212 RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
3213 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3217 static void __exit rk_camera_exit(void)
3219 platform_driver_unregister(&rk_camera_driver);
3222 device_initcall_sync(rk_camera_init);
3223 module_exit(rk_camera_exit);
3225 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3226 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3227 MODULE_LICENSE("GPL");