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) ||defined(CONFIG_ARCH_RK3188)
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)||defined(CONFIG_ARCH_RK3188)
44 #include <mach/rk30_camera.h>
48 #include <plat/efuse.h>
49 #if defined(CONFIG_ARCH_RK2928)
50 #include <mach/rk2928_camera.h>
53 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
55 #include <asm/cacheflush.h>
58 module_param(debug, int, S_IRUGO|S_IWUSR);
60 #define CAMMODULE_NAME "rk_cam_cif"
62 #define dprintk(level, fmt, arg...) do { \
64 printk(KERN_WARNING "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
66 #define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
67 #define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
69 #define CIF_CIF_CTRL 0x00
70 #define CIF_CIF_INTEN 0x04
71 #define CIF_CIF_INTSTAT 0x08
72 #define CIF_CIF_FOR 0x0c
73 #define CIF_CIF_LINE_NUM_ADDR 0x10
74 #define CIF_CIF_FRM0_ADDR_Y 0x14
75 #define CIF_CIF_FRM0_ADDR_UV 0x18
76 #define CIF_CIF_FRM1_ADDR_Y 0x1c
77 #define CIF_CIF_FRM1_ADDR_UV 0x20
78 #define CIF_CIF_VIR_LINE_WIDTH 0x24
79 #define CIF_CIF_SET_SIZE 0x28
80 #define CIF_CIF_SCM_ADDR_Y 0x2c
81 #define CIF_CIF_SCM_ADDR_U 0x30
82 #define CIF_CIF_SCM_ADDR_V 0x34
83 #define CIF_CIF_WB_UP_FILTER 0x38
84 #define CIF_CIF_WB_LOW_FILTER 0x3c
85 #define CIF_CIF_WBC_CNT 0x40
86 #define CIF_CIF_CROP 0x44
87 #define CIF_CIF_SCL_CTRL 0x48
88 #define CIF_CIF_SCL_DST 0x4c
89 #define CIF_CIF_SCL_FCT 0x50
90 #define CIF_CIF_SCL_VALID_NUM 0x54
91 #define CIF_CIF_LINE_LOOP_CTR 0x58
92 #define CIF_CIF_FRAME_STATUS 0x60
93 #define CIF_CIF_CUR_DST 0x64
94 #define CIF_CIF_LAST_LINE 0x68
95 #define CIF_CIF_LAST_PIX 0x6c
97 //The key register bit descrition
98 // CIF_CTRL Reg , ignore SCM,WBC,ISP,
99 #define DISABLE_CAPTURE (0x00<<0)
100 #define ENABLE_CAPTURE (0x01<<0)
101 #define MODE_ONEFRAME (0x00<<1)
102 #define MODE_PINGPONG (0x01<<1)
103 #define MODE_LINELOOP (0x02<<1)
104 #define AXI_BURST_16 (0x0F << 12)
107 #define FRAME_END_EN (0x01<<1)
108 #define BUS_ERR_EN (0x01<<6)
109 #define SCL_ERR_EN (0x01<<7)
112 #define VSY_HIGH_ACTIVE (0x01<<0)
113 #define VSY_LOW_ACTIVE (0x00<<0)
114 #define HSY_LOW_ACTIVE (0x01<<1)
115 #define HSY_HIGH_ACTIVE (0x00<<1)
116 #define INPUT_MODE_YUV (0x00<<2)
117 #define INPUT_MODE_PAL (0x02<<2)
118 #define INPUT_MODE_NTSC (0x03<<2)
119 #define INPUT_MODE_RAW (0x04<<2)
120 #define INPUT_MODE_JPEG (0x05<<2)
121 #define INPUT_MODE_MIPI (0x06<<2)
122 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
123 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
124 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
125 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
126 #define YUV_INPUT_422 (0x00<<7)
127 #define YUV_INPUT_420 (0x01<<7)
128 #define INPUT_420_ORDER_EVEN (0x00<<8)
129 #define INPUT_420_ORDER_ODD (0x01<<8)
130 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
131 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
132 #define RAW_DATA_WIDTH_8 (0x00<<11)
133 #define RAW_DATA_WIDTH_10 (0x01<<11)
134 #define RAW_DATA_WIDTH_12 (0x02<<11)
135 #define YUV_OUTPUT_422 (0x00<<16)
136 #define YUV_OUTPUT_420 (0x01<<16)
137 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
138 #define OUTPUT_420_ORDER_ODD (0x01<<17)
139 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
140 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
141 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
142 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
145 #define ENABLE_SCL_DOWN (0x01<<0)
146 #define DISABLE_SCL_DOWN (0x00<<0)
147 #define ENABLE_SCL_UP (0x01<<1)
148 #define DISABLE_SCL_UP (0x00<<1)
149 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
150 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
151 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
152 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
153 #define ENABLE_32BIT_BYPASS (0x01<<6)
154 #define DISABLE_32BIT_BYPASS (0x00<<6)
157 #define MIN(x,y) ((x<y) ? x: y)
158 #define MAX(x,y) ((x>y) ? x: y)
159 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
160 #define RK_SENSOR_48MHZ 48
162 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
163 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
164 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
166 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
168 #define CRU_PCLK_REG30 0xbc
169 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
170 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
171 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
172 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
174 #define CRU_CIF_RST_REG30 0x128
175 #define MASK_RST_CIF0 (0x01 << 30)
176 #define MASK_RST_CIF1 (0x01 << 31)
177 #define RQUEST_RST_CIF0 (0x01 << 14)
178 #define RQUEST_RST_CIF1 (0x01 << 15)
180 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
181 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
182 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
185 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
187 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
188 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
189 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
190 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
191 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
194 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
195 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
196 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
198 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
199 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
200 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
202 #define write_grf_reg(addr, val)
203 #define read_grf_reg(addr) 0
204 #define mask_grf_reg(addr, msk, val)
207 #if defined(CONFIG_ARCH_RK2928)
208 #define write_cru_reg(addr, val)
209 #define read_cru_reg(addr) 0
210 #define mask_cru_reg(addr, msk, val)
214 //when work_with_ipp is not enabled,CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF is not defined.something wrong with it
215 #ifdef CONFIG_VIDEO_RK29_WORK_IPP//CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
216 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
217 #define CAM_WORKQUEUE_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
218 || (pcdev->icd_cb.sensor_cb))
219 #define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))
221 #define CAM_WORKQUEUE_IS_EN() (true)
222 #define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
224 #else //CONFIG_VIDEO_RK29_WORK_IPP
225 #define CAM_WORKQUEUE_IS_EN() (false)
226 #define CAM_IPPWORK_IS_EN() (false)
229 #define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
230 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
231 #define CROP_ALIGN_BYTES (0x03)
232 #define CIF_DO_CROP 0
233 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
234 #define CROP_ALIGN_BYTES (0x0f)
235 #define CIF_DO_CROP 0
236 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
237 #define CROP_ALIGN_BYTES (0x03)
238 #define CIF_DO_CROP 0
239 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
240 #define CROP_ALIGN_BYTES (0x0F)
241 #define CIF_DO_CROP 1
245 * Driver Version Note
247 *v0.0.x : this driver is 2.6.32 kernel driver;
248 *v0.1.x : this driver is 3.0.8 kernel driver;
250 *v0.x.1 : this driver first support rk2918;
251 *v0.x.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420
252 * and V4L2_PIX_FMT_YUV422P;
253 *v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
254 *v0.x.4 : this driver support digital zoom;
255 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
256 *v0.x.6 : this driver improve test framerate method;
257 *v0.x.7 : digital zoom use the ipp to do scale and crop , otherwise ipp just do the scale. Something wrong with digital zoom if
258 we do crop with cif and do scale with ipp , we will fix this next version.
259 *v0.x.8 : temp version,reinit capture list when setup video buf.
260 *v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version.
261 2. flush workqueue when releas buffer
262 *v0.x.a: 1. reset cif and wake up vb when cif have't receive data in a fixed time(now setted as 2 secs) so that app can
264 2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
265 3. when front and back camera are the same sensor,and one has the flash ,other is not,flash can't work corrrectly ,fix it
266 4. add menu configs for convineuent to customize sensor series
267 *v0.x.b: specify the version is NOT sure stable.
268 *v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
269 2. irq process is splitted to two step.
270 *v0.x.e: fix bugs of early suspend when display_pd is closed.
271 *v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
272 *v0.x.11: fix struct rk_camera_work may be reentrant
273 *v0.x.13: 1.add scale by arm,rga and pp.
274 2.CIF do the crop when digital zoom.
275 3.fix bug in prob func:request mem twice.
276 4.video_vq may be null when reinit work,fix it
277 5.arm scale algorithm has something wrong(may exceed the bound of width or height) ,fix it.
279 * 1. support rk3066b;
281 * 1. support 8Mega picture;
283 * 1. invalidate the limit which scale is invalidat when scale ratio > 2;
284 *v0.x.1b: 1. fix oops bug when using arm to do scale_crop if preview buffer is not allocated correctly
285 2. rk_camera_set_fmt will called twice, optimize the procedure. at the first time call ,just to do the sensor init.
288 * 1. fix query resolution error;
290 * 1. add mv9335+ov5650 driver;
291 * 2. fix 2928 digitzoom erro(arm crop scale) of selected zone;
293 * 1. support rk3188; Must soft reset cif controller after each frame irq;
295 * 1. fix ctrl register capture bit may be turn on in rk_videobuf_capture function
298 * 1. compatible with generic_sensor;
301 * 1. fix use v4l2_mbus_framefmt.reserved array overflow in generic_sensor_s_fmt;
304 * 1. support rk3028 , read 3028 chip id by efuse for check cif controller is normal or not;
307 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x07)
308 static int version = RK_CAM_VERSION_CODE;
309 module_param(version, int, S_IRUGO);
311 /* limit to rk29 hardware capabilities */
312 #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
313 SOCAM_HSYNC_ACTIVE_HIGH |\
314 SOCAM_HSYNC_ACTIVE_LOW |\
315 SOCAM_VSYNC_ACTIVE_HIGH |\
316 SOCAM_VSYNC_ACTIVE_LOW |\
317 SOCAM_PCLK_SAMPLE_RISING |\
318 SOCAM_PCLK_SAMPLE_FALLING|\
319 SOCAM_DATA_ACTIVE_HIGH |\
320 SOCAM_DATA_ACTIVE_LOW|\
321 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
322 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
324 #define RK_CAM_W_MIN 48
325 #define RK_CAM_H_MIN 32
326 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
327 #define RK_CAM_H_MAX 2764
328 #define RK_CAM_FRAME_INVAL_INIT 3
329 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
330 #define RK30_CAM_FRAME_MEASURE 5
331 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
332 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
333 /* buffer for one video frame */
334 struct rk_camera_buffer
336 /* common v4l buffer stuff -- must be first */
337 struct videobuf_buffer vb;
338 enum v4l2_mbus_pixelcode code;
341 enum rk_camera_reg_state
349 unsigned int cifCtrl;
350 unsigned int cifCrop;
352 unsigned int cifIntEn;
354 unsigned int cifVirWidth;
355 unsigned int cifScale;
356 // unsigned int VipCrm;
357 enum rk_camera_reg_state Inval;
359 struct rk_camera_work
361 struct videobuf_buffer *vb;
362 struct rk_camera_dev *pcdev;
363 struct work_struct work;
364 struct list_head queue;
367 struct rk_camera_frmivalenum
369 struct v4l2_frmivalenum fival;
370 struct rk_camera_frmivalenum *nxt;
372 struct rk_camera_frmivalinfo
374 struct soc_camera_device *icd;
375 struct rk_camera_frmivalenum *fival_list;
377 struct rk_camera_zoominfo
379 struct semaphore sem;
385 #if CAMERA_VIDEOBUF_ARM_ACCESS
386 struct rk29_camera_vbinfo
388 unsigned int phy_addr;
389 void __iomem *vir_addr;
393 struct rk_camera_timer{
394 struct rk_camera_dev *pcdev;
395 struct hrtimer timer;
400 //************must modify start************/
402 struct clk *aclk_cif;
403 struct clk *hclk_cif;
404 struct clk *cif_clk_in;
405 struct clk *cif_clk_out;
406 //************must modify end************/
414 struct soc_camera_host soc_host;
416 /* RK2827x is only supposed to handle one camera on its Quick Capture
417 * interface. If anyone ever builds hardware to enable more than
418 * one camera, they will have to modify this driver too */
419 struct soc_camera_device *icd;
421 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
424 unsigned int last_fps;
425 unsigned long frame_interval;
428 unsigned int vipmem_phybase;
429 void __iomem *vipmem_virbase;
430 unsigned int vipmem_size;
431 unsigned int vipmem_bsize;
432 #if CAMERA_VIDEOBUF_ARM_ACCESS
433 struct rk29_camera_vbinfo *vbinfo;
434 unsigned int vbinfo_count;
438 int host_left; //sensor output size ?
444 struct rk29camera_platform_data *pdata;
445 struct resource *res;
446 struct list_head capture;
447 struct rk_camera_zoominfo zoominfo;
451 struct videobuf_buffer *active;
452 struct rk_camera_reg reginfo_suspend;
453 struct workqueue_struct *camera_wq;
454 struct rk_camera_work *camera_work;
455 struct list_head camera_work_queue;
456 spinlock_t camera_work_lock;
457 unsigned int camera_work_count;
458 struct rk_camera_timer fps_timer;
459 struct rk_camera_work camera_reinit_work;
461 rk29_camera_sensor_cb_s icd_cb;
462 struct rk_camera_frmivalinfo icd_frmival[2];
463 // atomic_t to_process_frames;
465 unsigned int reinit_times;
466 struct videobuf_queue *video_vq;
468 struct timeval first_tv;
473 static const struct v4l2_queryctrl rk_camera_controls[] =
475 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
477 .id = V4L2_CID_ZOOM_ABSOLUTE,
478 .type = V4L2_CTRL_TYPE_INTEGER,
479 .name = "DigitalZoom Control",
483 .default_value = 100,
488 static struct rk_cif_clk cif_clk[2];
490 static DEFINE_MUTEX(camera_lock);
491 static const char *rk_cam_driver_description = "RK_Camera";
493 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
494 static void rk_camera_capture_process(struct work_struct *work);
495 static int rk_camera_scale_crop_arm(struct work_struct *work);
498 * Videobuf operations
500 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
503 struct soc_camera_device *icd = vq->priv_data;
504 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
505 struct rk_camera_dev *pcdev = ici->priv;
507 struct rk_camera_work *wk;
509 struct soc_mbus_pixelfmt fmt;
511 int bytes_per_line_host;
512 fmt.packing = SOC_MBUS_PACKING_1_5X8;
514 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
515 icd->current_fmt->host_fmt);
516 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
517 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
519 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
520 bytes_per_line_host = pcdev->host_width*3;
522 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
523 icd->current_fmt->host_fmt);
524 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
526 if (bytes_per_line_host < 0)
527 return bytes_per_line_host;
529 /* planar capture requires Y, U and V buffers to be page aligned */
530 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
531 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
533 if (CAM_WORKQUEUE_IS_EN()) {
534 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
535 if (CAM_IPPWORK_IS_EN())
538 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
539 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
540 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
543 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
544 kfree(pcdev->camera_work);
545 pcdev->camera_work = NULL;
546 pcdev->camera_work_count = 0;
549 if (pcdev->camera_work == NULL) {
550 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
551 if (pcdev->camera_work == NULL) {
552 RKCAMERA_TR("kmalloc failed\n");
555 INIT_LIST_HEAD(&pcdev->camera_work_queue);
557 for (i=0; i<(*count); i++) {
559 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
562 pcdev->camera_work_count = (*count);
564 #if CAMERA_VIDEOBUF_ARM_ACCESS
565 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
566 kfree(pcdev->vbinfo);
567 pcdev->vbinfo = NULL;
568 pcdev->vbinfo_count = 0x00;
571 if (pcdev->vbinfo == NULL) {
572 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
573 if (pcdev->vbinfo == NULL) {
574 RKCAMERA_TR("vbinfo kmalloc fail\n");
577 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
578 pcdev->vbinfo_count = *count;
582 pcdev->video_vq = vq;
583 RKCAMERA_DG("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
587 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
589 struct soc_camera_device *icd = vq->priv_data;
591 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
592 &buf->vb, buf->vb.baddr, buf->vb.bsize);
594 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
595 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
601 * This waits until this buffer is out of danger, i.e., until it is no
602 * longer in STATE_QUEUED or STATE_ACTIVE
604 //videobuf_waiton(vq, &buf->vb, 0, 0);
605 videobuf_dma_contig_free(vq, &buf->vb);
606 dev_dbg(&icd->dev, "%s freed\n", __func__);
607 buf->vb.state = VIDEOBUF_NEEDS_INIT;
610 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
612 struct soc_camera_device *icd = vq->priv_data;
613 struct rk_camera_buffer *buf;
615 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
616 icd->current_fmt->host_fmt);
617 if ((bytes_per_line < 0) || (vb->boff == 0))
620 buf = container_of(vb, struct rk_camera_buffer, vb);
622 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
623 vb, vb->baddr, vb->bsize);
625 /* Added list head initialization on alloc */
626 WARN_ON(!list_empty(&vb->queue));
628 BUG_ON(NULL == icd->current_fmt);
630 if (buf->code != icd->current_fmt->code ||
631 vb->width != icd->user_width ||
632 vb->height != icd->user_height ||
633 vb->field != field) {
634 buf->code = icd->current_fmt->code;
635 vb->width = icd->user_width;
636 vb->height = icd->user_height;
638 vb->state = VIDEOBUF_NEEDS_INIT;
641 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
642 if (0 != vb->baddr && vb->bsize < vb->size) {
647 if (vb->state == VIDEOBUF_NEEDS_INIT) {
648 ret = videobuf_iolock(vq, vb, NULL);
652 vb->state = VIDEOBUF_PREPARED;
657 rk_videobuf_free(vq, buf);
661 #if defined(CONFIG_ARCH_RK3188)
662 static void rk_camera_store_register(struct rk_camera_dev *pcdev)
665 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
666 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
667 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
668 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
669 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
670 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
671 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
673 cru_set_soft_reset(SOFT_RST_CIF0, true);
675 cru_set_soft_reset(SOFT_RST_CIF0, false);
677 static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
679 if (pcdev->reginfo_suspend.cifCtrl&ENABLE_CAPTURE)
680 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
681 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
682 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
683 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
684 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
685 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
686 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
687 if (pcdev->reginfo_suspend.cifCtrl&ENABLE_CAPTURE)
688 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl);
693 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
695 unsigned int y_addr,uv_addr;
696 struct rk_camera_dev *pcdev = rk_pcdev;
699 if (CAM_WORKQUEUE_IS_EN()) {
700 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
701 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
702 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
703 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
704 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
709 uv_addr = y_addr + vb->width * vb->height;
711 #if defined(CONFIG_ARCH_RK3188)
712 rk_camera_store_register(pcdev);
713 rk_camera_restore_register(pcdev);
715 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
716 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
717 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
718 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
719 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
722 /* Locking: Caller holds q->irqlock */
723 static void rk_videobuf_queue(struct videobuf_queue *vq,
724 struct videobuf_buffer *vb)
726 struct soc_camera_device *icd = vq->priv_data;
727 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
728 struct rk_camera_dev *pcdev = ici->priv;
729 #if CAMERA_VIDEOBUF_ARM_ACCESS
730 struct rk29_camera_vbinfo *vb_info;
733 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
734 vb, vb->baddr, vb->bsize);
736 vb->state = VIDEOBUF_QUEUED;
737 if (list_empty(&pcdev->capture)) {
738 list_add_tail(&vb->queue, &pcdev->capture);
740 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
741 list_add_tail(&vb->queue, &pcdev->capture);
743 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
745 #if CAMERA_VIDEOBUF_ARM_ACCESS
747 vb_info = pcdev->vbinfo+vb->i;
748 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
749 if (vb_info->vir_addr) {
750 iounmap(vb_info->vir_addr);
751 release_mem_region(vb_info->phy_addr, vb_info->size);
752 vb_info->vir_addr = NULL;
753 vb_info->phy_addr = 0x00;
754 vb_info->size = 0x00;
757 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
758 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
761 if (vb_info->vir_addr) {
762 vb_info->size = vb->bsize;
763 vb_info->phy_addr = vb->boff;
765 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
770 if (!pcdev->active) {
772 rk_videobuf_capture(vb,pcdev);
775 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
779 case V4L2_PIX_FMT_NV16:
780 case V4L2_PIX_FMT_NV61:
782 *ippfmt = IPP_Y_CBCR_H2V1;
785 case V4L2_PIX_FMT_NV12:
786 case V4L2_PIX_FMT_NV21:
788 *ippfmt = IPP_Y_CBCR_H2V2;
792 goto rk_pixfmt2ippfmt_err;
796 rk_pixfmt2ippfmt_err:
799 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
800 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
804 case V4L2_PIX_FMT_YUV420:
805 case V4L2_PIX_FMT_UYVY: // yuv 422, but sensor has defined this format(in fact ,should be defined yuv 420), treat this as yuv 420.
806 case V4L2_PIX_FMT_YUYV:
808 *ippfmt = RK_FORMAT_YCbCr_420_SP;
811 case V4L2_PIX_FMT_YVU420:
812 case V4L2_PIX_FMT_VYUY:
813 case V4L2_PIX_FMT_YVYU:
815 *ippfmt = RK_FORMAT_YCrCb_420_SP;
818 case V4L2_PIX_FMT_RGB565:
820 *ippfmt = RK_FORMAT_RGB_565;
823 case V4L2_PIX_FMT_RGB24:
825 *ippfmt = RK_FORMAT_RGB_888;
829 goto rk_pixfmt2rgafmt_err;
833 rk_pixfmt2rgafmt_err:
837 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
838 static int rk_camera_scale_crop_pp(struct work_struct *work){
839 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
840 struct videobuf_buffer *vb = camera_work->vb;
841 struct rk_camera_dev *pcdev = camera_work->pcdev;
843 unsigned long int flags;
849 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
851 memset(&init, 0, sizeof(init));
852 init.srcAddr = vipdata_base;
853 init.srcFormat = PP_IN_FORMAT_YUV420SEMI;
854 init.srcWidth = init.srcHStride = pcdev->zoominfo.vir_width;
855 init.srcHeight = init.srcVStride = pcdev->zoominfo.vir_height;
857 init.dstAddr = vb->boff;
858 init.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE;
859 init.dstWidth = init.dstHStride = pcdev->icd->user_width;
860 init.dstHeight = init.dstVStride = pcdev->icd->user_height;
862 printk("srcWidth = %d,srcHeight = %d,dstWidth = %d,dstHeight = %d\n",init.srcWidth,init.srcHeight,init.dstWidth,init.dstHeight);
864 ret = ppOpInit(&hnd, &init);
870 printk("can not create ppOp handle\n");
876 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
877 extern rga_service_info rga_service;
878 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
879 extern void rga_service_session_clear(rga_session *session);
880 static int rk_camera_scale_crop_rga(struct work_struct *work){
881 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
882 struct videobuf_buffer *vb = camera_work->vb;
883 struct rk_camera_dev *pcdev = camera_work->pcdev;
885 unsigned long int flags;
891 const struct soc_mbus_pixelfmt *fmt;
893 fmt = soc_mbus_get_fmtdesc(pcdev->icd->current_fmt->code);
894 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
895 if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
896 && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
897 RKCAMERA_TR("RGA not support this format !\n");
900 if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
901 scale_times = MAX((pcdev->icd->user_width/0x800),(pcdev->icd->user_height/0x800));
906 session.pid = current->pid;
907 INIT_LIST_HEAD(&session.waiting);
908 INIT_LIST_HEAD(&session.running);
909 INIT_LIST_HEAD(&session.list_session);
910 init_waitqueue_head(&session.wait);
911 /* no need to protect */
912 list_add_tail(&session.list_session, &rga_service.session);
913 atomic_set(&session.task_running, 0);
914 atomic_set(&session.num_done, 0);
916 memset(&req,0,sizeof(struct rga_req));
917 req.src.act_w = pcdev->zoominfo.a.c.width/scale_times;
918 req.src.act_h = pcdev->zoominfo.a.c.height/scale_times;
920 req.src.vir_w = pcdev->zoominfo.vir_width;
921 req.src.vir_h =pcdev->zoominfo.vir_height;
922 req.src.yrgb_addr = vipdata_base;
923 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
924 req.src.v_addr = req.src.uv_addr ;
925 req.src.format =fmt->fourcc;
926 rk_pixfmt2rgafmt(fmt->fourcc,&req.src.format);
927 req.src.x_offset = pcdev->zoominfo.a.c.left;
928 req.src.y_offset = pcdev->zoominfo.a.c.top;
930 req.dst.act_w = pcdev->icd->user_width/scale_times;
931 req.dst.act_h = pcdev->icd->user_height/scale_times;
933 req.dst.vir_w = pcdev->icd->user_width;
934 req.dst.vir_h = pcdev->icd->user_height;
935 req.dst.x_offset = 0;
936 req.dst.y_offset = 0;
937 req.dst.yrgb_addr = vb->boff;
938 rk_pixfmt2rgafmt(pcdev->icd->current_fmt->host_fmt->fourcc,&req.dst.format);
940 req.clip.xmax = req.dst.vir_w-1;
942 req.clip.ymax = req.dst.vir_h -1;
949 req.mmu_info.mmu_en = 0;
951 for (h=0; h<scale_times; h++) {
952 for (w=0; w<scale_times; w++) {
955 req.src.yrgb_addr = vipdata_base;
956 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
957 req.src.x_offset = pcdev->zoominfo.a.c.left+w*pcdev->zoominfo.a.c.width/scale_times;
958 req.src.y_offset = pcdev->zoominfo.a.c.top+h*pcdev->zoominfo.a.c.height/scale_times;
959 req.dst.x_offset = pcdev->icd->user_width*w/scale_times;
960 req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
961 req.dst.yrgb_addr = vb->boff ;
962 // RKCAMERA_TR("src.act_w = %d , src.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
963 // RKCAMERA_TR("dst.act_w = %d , dst.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
964 // RKCAMERA_TR("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
966 while(rga_times-- > 0) {
967 if (rga_blit_sync(&session, &req)){
968 RKCAMERA_TR("rga do erro,do again,rga_times = %d!\n",rga_times);
974 if (rga_times <= 0) {
975 spin_lock_irqsave(&pcdev->lock, flags);
976 vb->state = VIDEOBUF_NEEDS_INIT;
977 spin_unlock_irqrestore(&pcdev->lock, flags);
978 mutex_lock(&rga_service.lock);
979 list_del(&session.list_session);
980 rga_service_session_clear(&session);
981 mutex_unlock(&rga_service.lock);
987 mutex_lock(&rga_service.lock);
988 list_del(&session.list_session);
989 rga_service_session_clear(&session);
990 mutex_unlock(&rga_service.lock);
999 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
1001 static int rk_camera_scale_crop_ipp(struct work_struct *work)
1003 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1004 struct videobuf_buffer *vb = camera_work->vb;
1005 struct rk_camera_dev *pcdev = camera_work->pcdev;
1007 unsigned long int flags;
1009 struct rk29_ipp_req ipp_req;
1010 int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
1011 int scale_times,w,h;
1012 int ret = 0, scale_crop_ret=0;
1015 *ddl@rock-chips.com:
1016 * IPP Dest image resolution is 2047x1088, so scale operation break up some times
1018 if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
1019 scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));
1024 memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
1027 ipp_req.timeout = 3000;
1028 ipp_req.flag = IPP_ROT_0;
1029 ipp_req.store_clip_mode =1;
1030 ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
1031 ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
1032 ipp_req.src_vir_w = pcdev->zoominfo.vir_width;
1033 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
1034 ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
1035 ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
1036 ipp_req.dst_vir_w = pcdev->icd->user_width;
1037 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
1038 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
1039 src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height; //vipmem
1040 dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
1041 for (h=0; h<scale_times; h++) {
1042 for (w=0; w<scale_times; w++) {
1043 src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width
1044 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
1045 src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width/2
1046 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
1048 dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
1049 dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
1051 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
1052 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
1053 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
1054 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
1056 if (ipp_blit_sync(&ipp_req)){
1057 RKCAMERA_TR("ipp do erro, so switch to arm \n");
1058 scale_crop_ret = 0x01;
1064 if (scale_crop_ret == 0x01) {
1065 ret = rk_camera_scale_crop_arm(work);
1069 spin_lock_irqsave(&pcdev->lock, flags);
1070 vb->state = VIDEOBUF_NEEDS_INIT;
1071 spin_unlock_irqrestore(&pcdev->lock, flags);
1072 RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP and ARM operated is error:\n",vb->i);
1073 RKCAMERA_TR("widx:%d hidx:%d ",w,h);
1074 RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
1075 RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
1076 RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
1077 RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
1078 RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
1079 RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
1080 RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
1081 RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
1082 RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
1088 static int rk_camera_scale_crop_arm(struct work_struct *work)
1090 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1091 struct videobuf_buffer *vb = camera_work->vb;
1092 struct rk_camera_dev *pcdev = camera_work->pcdev;
1093 struct rk29_camera_vbinfo *vb_info;
1094 unsigned char *psY,*pdY,*psUV,*pdUV;
1095 unsigned char *src,*dst;
1096 unsigned long src_phy,dst_phy;
1097 int srcW,srcH,cropW,cropH,dstW,dstH;
1098 long zoomindstxIntInv,zoomindstyIntInv;
1100 long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
1103 int ret = 0, shift_bits = 0;
1105 src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
1106 src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
1107 psUV = psY + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
1109 srcW = pcdev->zoominfo.vir_width;
1110 srcH = pcdev->zoominfo.vir_height;
1111 cropW = pcdev->zoominfo.a.c.width;
1112 cropH = pcdev->zoominfo.a.c.height;
1114 psY = psY + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width+pcdev->zoominfo.a.c.left;
1115 psUV = psUV + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width/2+pcdev->zoominfo.a.c.left;
1117 vb_info = pcdev->vbinfo+vb->i;
1118 dst_phy = vb_info->phy_addr;
1119 dst = pdY = (unsigned char*)vb_info->vir_addr;
1120 pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
1121 dstW = pcdev->icd->user_width;
1122 dstH = pcdev->icd->user_height;
1124 zoomindstxIntInv = ((unsigned long)(cropW)<<16)/dstW + 1;
1125 zoomindstyIntInv = ((unsigned long)(cropH)<<16)/dstH + 1;
1126 #ifdef CONFIG_SOC_RK3028
1127 shift_bits = (pcdev->chip_id == 0x42)?0:2;
1130 //for(y = 0; y<dstH - 1 ; y++ ) {
1131 for(y = 0; y<dstH; y++ ) {
1132 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1133 yCoeff01 = 0xffff - yCoeff00;
1134 sY = (y*zoomindstyIntInv >> 16);
1135 sY = (sY >= srcH - 1)? (srcH - 2) : sY;
1136 for(x = 0; x<dstW; x++ ) {
1137 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1138 xCoeff01 = 0xffff - xCoeff00;
1139 sX = (x*zoomindstxIntInv >> 16);
1140 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1141 a = (psY[sY*srcW + sX]<<shift_bits);
1142 b = (psY[sY*srcW + sX + 1]<<shift_bits);
1143 c = (psY[(sY+1)*srcW + sX]<<shift_bits);
1144 d = (psY[(sY+1)*srcW + sX + 1]<<shift_bits);
1146 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1147 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1148 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1161 //for(y = 0; y<dstH - 1 ; y++ ) {
1162 for(y = 0; y<dstH; y++ ) {
1163 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1164 yCoeff01 = 0xffff - yCoeff00;
1165 sY = (y*zoomindstyIntInv >> 16);
1166 sY = (sY >= srcH -1)? (srcH - 2) : sY;
1167 for(x = 0; x<dstW; x++ ) {
1168 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1169 xCoeff01 = 0xffff - xCoeff00;
1170 sX = (x*zoomindstxIntInv >> 16);
1171 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1173 a = (psUV[(sY*srcW + sX)*2]<<shift_bits);
1174 b = (psUV[(sY*srcW + sX + 1)*2]<<shift_bits);
1175 c = (psUV[((sY+1)*srcW + sX)*2]<<shift_bits);
1176 d = (psUV[((sY+1)*srcW + sX + 1)*2]<<shift_bits);
1179 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1180 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1181 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1186 a = (psUV[(sY*srcW + sX)*2 + 1]<<shift_bits);
1187 b = (psUV[(sY*srcW + sX + 1)*2 + 1]<<shift_bits);
1188 c = (psUV[((sY+1)*srcW + sX)*2 + 1]<<shift_bits);
1189 d = (psUV[((sY+1)*srcW + sX + 1)*2 + 1]<<shift_bits);
1191 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1192 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1193 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1200 dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
1201 outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
1203 dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
1204 outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
1208 static void rk_camera_capture_process(struct work_struct *work)
1210 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1211 struct videobuf_buffer *vb = camera_work->vb;
1212 struct rk_camera_dev *pcdev = camera_work->pcdev;
1213 //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;
1214 unsigned long flags = 0;
1217 if (!CAM_WORKQUEUE_IS_EN())
1218 goto rk_camera_capture_process_end;
1220 down(&pcdev->zoominfo.sem);
1221 if (pcdev->icd_cb.scale_crop_cb){
1222 err = (pcdev->icd_cb.scale_crop_cb)(work);
1224 up(&pcdev->zoominfo.sem);
1226 if (pcdev->icd_cb.sensor_cb)
1227 (pcdev->icd_cb.sensor_cb)(vb);
1229 rk_camera_capture_process_end:
1231 vb->state = VIDEOBUF_ERROR;
1233 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1234 vb->state = VIDEOBUF_DONE;
1238 wake_up(&(camera_work->vb->done));
1239 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1240 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1241 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1244 static irqreturn_t rk_camera_irq(int irq, void *data)
1246 struct rk_camera_dev *pcdev = data;
1247 struct videobuf_buffer *vb;
1248 struct rk_camera_work *wk;
1250 unsigned long tmp_intstat;
1251 unsigned long tmp_cifctrl;
1253 tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1254 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1255 if(pcdev->stop_cif == true)
1257 printk("cif has stopped by app,needn't to deal this irq\n");
1258 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
1261 if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/){//bit9 =1 ,bit0 = 0
1262 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1263 if(tmp_cifctrl & ENABLE_CAPTURE)
1264 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
1268 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1269 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
1270 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1272 do_gettimeofday(&pcdev->first_tv);
1276 goto RK_CAMERA_IRQ_END;
1277 if (pcdev->frame_inval>0) {
1278 pcdev->frame_inval--;
1279 rk_videobuf_capture(pcdev->active,pcdev);
1280 goto RK_CAMERA_IRQ_END;
1281 } else if (pcdev->frame_inval) {
1282 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1283 pcdev->frame_inval = 0;
1285 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1286 do_gettimeofday(&tv);
1287 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1288 /(RK30_CAM_FRAME_MEASURE-1);
1292 printk("no acticve buffer!!!\n");
1293 goto RK_CAMERA_IRQ_END;
1295 /* ddl@rock-chips.com : this vb may be deleted from queue */
1296 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1297 list_del_init(&vb->queue);
1299 pcdev->active = NULL;
1300 if (!list_empty(&pcdev->capture)) {
1301 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1302 if (pcdev->active) {
1303 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1304 rk_videobuf_capture(pcdev->active,pcdev);
1307 if (pcdev->active == NULL) {
1308 RKCAMERA_DG("video_buf queue is empty!\n");
1311 do_gettimeofday(&vb->ts);
1312 if (CAM_WORKQUEUE_IS_EN()) {
1313 if (!list_empty(&pcdev->camera_work_queue)) {
1314 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1315 list_del_init(&wk->queue);
1316 INIT_WORK(&(wk->work), rk_camera_capture_process);
1319 queue_work(pcdev->camera_wq, &(wk->work));
1322 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1323 vb->state = VIDEOBUF_DONE;
1332 if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
1333 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
1338 static void rk_videobuf_release(struct videobuf_queue *vq,
1339 struct videobuf_buffer *vb)
1341 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1342 struct soc_camera_device *icd = vq->priv_data;
1343 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1344 struct rk_camera_dev *pcdev = ici->priv;
1345 #if CAMERA_VIDEOBUF_ARM_ACCESS
1346 struct rk29_camera_vbinfo *vb_info =NULL;
1350 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1351 vb, vb->baddr, vb->bsize);
1355 case VIDEOBUF_ACTIVE:
1356 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1358 case VIDEOBUF_QUEUED:
1359 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1361 case VIDEOBUF_PREPARED:
1362 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1365 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1369 if (vb == pcdev->active) {
1370 RKCAMERA_DG("Wait for this video buf(0x%x) write finished!\n ",(unsigned int)vb);
1371 interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
1372 RKCAMERA_DG("This video buf(0x%x) write finished, release now!!\n",(unsigned int)vb);
1375 flush_workqueue(pcdev->camera_wq);
1376 #if CAMERA_VIDEOBUF_ARM_ACCESS
1377 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1378 vb_info = pcdev->vbinfo + vb->i;
1380 if (vb_info->vir_addr) {
1381 iounmap(vb_info->vir_addr);
1382 release_mem_region(vb_info->phy_addr, vb_info->size);
1383 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1388 rk_videobuf_free(vq, buf);
1391 static struct videobuf_queue_ops rk_videobuf_ops =
1393 .buf_setup = rk_videobuf_setup,
1394 .buf_prepare = rk_videobuf_prepare,
1395 .buf_queue = rk_videobuf_queue,
1396 .buf_release = rk_videobuf_release,
1399 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1400 struct soc_camera_device *icd)
1402 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1403 struct rk_camera_dev *pcdev = ici->priv;
1405 /* We must pass NULL as dev pointer, then all pci_* dma operations
1406 * transform to normal dma_* ones. */
1407 videobuf_queue_dma_contig_init(q,
1409 ici->v4l2_dev.dev, &pcdev->lock,
1410 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1412 sizeof(struct rk_camera_buffer),
1413 icd,&icd->video_lock);
1416 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1419 struct rk_cif_clk *clk;
1421 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1422 if ((cif<0)||(cif>1)) {
1423 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1425 goto rk_camera_clk_ctrl_end;
1428 clk = &cif_clk[cif];
1430 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1431 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1433 goto rk_camera_clk_ctrl_end;
1436 spin_lock(&clk->lock);
1437 if (on && !clk->on) {
1438 clk_enable(clk->pd_cif);
1439 clk_enable(clk->aclk_cif);
1440 clk_enable(clk->hclk_cif);
1441 clk_enable(clk->cif_clk_in);
1442 clk_enable(clk->cif_clk_out);
1443 clk_set_rate(clk->cif_clk_out,clk_rate);
1445 } else if (!on && clk->on) {
1446 clk_disable(clk->aclk_cif);
1447 clk_disable(clk->hclk_cif);
1448 clk_disable(clk->cif_clk_in);
1449 clk_disable(clk->cif_clk_out);
1450 clk_disable(clk->pd_cif);
1453 spin_unlock(&clk->lock);
1454 rk_camera_clk_ctrl_end:
1458 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1461 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1465 //soft reset the registers
1466 #if 0 //has somthing wrong when suspend and resume now
1468 printk("before set cru register reset cif0 0x%x\n\n",read_cru_reg(CRU_CIF_RST_REG30));
1471 printk("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
1472 printk("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
1473 printk("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
1474 printk("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
1475 printk("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
1476 printk("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
1477 printk("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
1478 printk("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
1479 printk("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
1481 printk("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
1482 printk("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
1483 printk("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
1484 printk("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
1485 printk("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
1486 printk("CIF_CIF_FRAME_STATUS = 0X%x\n\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
1490 write_cru_reg(CRU_CIF_RST_REG30,(/*read_cru_reg(CRU_CIF_RST_REG30)|*/MASK_RST_CIF0|RQUEST_RST_CIF0 ));
1491 printk("set cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1492 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1494 printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1496 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1497 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1500 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1501 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1502 RKCAMERA_DG("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base, CIF_CIF_CTRL));
1506 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1509 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1515 /* The following two functions absolutely depend on the fact, that
1516 * there can be only one camera on RK28 quick capture interface */
1517 static int rk_camera_add_device(struct soc_camera_device *icd)
1519 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1520 struct rk_camera_dev *pcdev = ici->priv;
1521 struct device *control = to_soc_camera_control(icd);
1522 struct v4l2_subdev *sd;
1523 int ret,i,icd_catch;
1524 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1526 mutex_lock(&camera_lock);
1533 RKCAMERA_DG("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1535 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1536 pcdev->active = NULL;
1538 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1539 pcdev->zoominfo.zoom_rate = 100;
1540 pcdev->fps_timer.istarted = false;
1542 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1543 * if app havn't dequeue all videobuf before close camera device;
1545 INIT_LIST_HEAD(&pcdev->capture);
1547 ret = rk_camera_activate(pcdev,icd);
1550 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1552 sd = dev_get_drvdata(control);
1553 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1555 ret = v4l2_subdev_call(sd,core, init, 0);
1559 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1562 pcdev->icd_init = 0;
1565 for (i=0; i<2; i++) {
1566 if (pcdev->icd_frmival[i].icd == icd)
1568 if (pcdev->icd_frmival[i].icd == NULL) {
1569 pcdev->icd_frmival[i].icd = icd;
1573 if (icd_catch == 0) {
1574 fival_list = pcdev->icd_frmival[0].fival_list;
1575 fival_nxt = fival_list;
1576 while(fival_nxt != NULL) {
1577 fival_nxt = fival_list->nxt;
1579 fival_list = fival_nxt;
1581 pcdev->icd_frmival[0].icd = icd;
1582 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1585 mutex_unlock(&camera_lock);
1589 static void rk_camera_remove_device(struct soc_camera_device *icd)
1591 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1592 struct rk_camera_dev *pcdev = ici->priv;
1593 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1594 #if CAMERA_VIDEOBUF_ARM_ACCESS
1595 struct rk29_camera_vbinfo *vb_info;
1599 mutex_lock(&camera_lock);
1600 BUG_ON(icd != pcdev->icd);
1602 RKCAMERA_DG("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1604 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1605 stream may be turn on again before close device, if suspend and resume happened. */
1606 if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
1607 rk_camera_s_stream(icd,0);
1610 //soft reset the registers
1611 #if 0 //has somthing wrong when suspend and resume now
1613 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF0|RQUEST_RST_CIF0 | (read_cru_reg(CRU_CIF_RST_REG30)));
1614 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1616 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1617 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1620 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
1621 //if stream off is not been executed,timer is running.
1622 if(pcdev->fps_timer.istarted){
1623 hrtimer_cancel(&pcdev->fps_timer.timer);
1624 pcdev->fps_timer.istarted = false;
1626 flush_work(&(pcdev->camera_reinit_work.work));
1627 flush_workqueue((pcdev->camera_wq));
1629 if (pcdev->camera_work) {
1630 kfree(pcdev->camera_work);
1631 pcdev->camera_work = NULL;
1632 pcdev->camera_work_count = 0;
1633 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1635 rk_camera_deactivate(pcdev);
1636 #if CAMERA_VIDEOBUF_ARM_ACCESS
1637 if (pcdev->vbinfo) {
1638 vb_info = pcdev->vbinfo;
1639 for (i=0; i<pcdev->vbinfo_count; i++) {
1640 if (vb_info->vir_addr) {
1641 iounmap(vb_info->vir_addr);
1642 release_mem_region(vb_info->phy_addr, vb_info->size);
1643 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1647 kfree(pcdev->vbinfo);
1648 pcdev->vbinfo = NULL;
1649 pcdev->vbinfo_count = 0;
1652 pcdev->active = NULL;
1654 pcdev->icd_cb.sensor_cb = NULL;
1655 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1656 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1657 * if app havn't dequeue all videobuf before close camera device;
1659 INIT_LIST_HEAD(&pcdev->capture);
1661 mutex_unlock(&camera_lock);
1662 RKCAMERA_DG("%s exit\n",__FUNCTION__);
1666 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1668 unsigned long bus_flags, camera_flags, common_flags;
1669 unsigned int cif_ctrl_val = 0;
1670 const struct soc_mbus_pixelfmt *fmt;
1672 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1673 struct rk_camera_dev *pcdev = ici->priv;
1675 RKCAMERA_DG("%s enter\n",__FUNCTION__);
1677 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1681 bus_flags = RK_CAM_BUS_PARAM;
1682 /* If requested data width is supported by the platform, use it */
1683 switch (fmt->bits_per_sample) {
1685 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1689 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1693 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1700 if (icd->ops->query_bus_param)
1701 camera_flags = icd->ops->query_bus_param(icd);
1705 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1706 if (!common_flags) {
1708 goto RK_CAMERA_SET_BUS_PARAM_END;
1711 ret = icd->ops->set_bus_param(icd, common_flags);
1713 goto RK_CAMERA_SET_BUS_PARAM_END;
1715 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1716 RKCAMERA_DG("cif_ctrl_val = 0x%x\n",cif_ctrl_val);
1717 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1719 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1720 RKCAMERA_DG("enable cif0 pclk invert\n");
1722 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1723 RKCAMERA_DG("enable cif1 pclk invert\n");
1727 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1728 RKCAMERA_DG("diable cif0 pclk invert\n");
1730 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1731 RKCAMERA_DG("diable cif1 pclk invert\n");
1734 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
1735 cif_ctrl_val |= HSY_LOW_ACTIVE;
1737 cif_ctrl_val &= ~HSY_LOW_ACTIVE;
1739 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1740 cif_ctrl_val |= VSY_HIGH_ACTIVE;
1742 cif_ctrl_val &= ~VSY_HIGH_ACTIVE;
1745 /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1746 //vip_ctrl_val |= ENABLE_CAPTURE;
1747 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
1748 RKCAMERA_DG("ctrl:0x%x CIF_CIF_FOR=%x \n",cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1750 RK_CAMERA_SET_BUS_PARAM_END:
1752 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1756 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1758 unsigned long bus_flags, camera_flags;
1761 bus_flags = RK_CAM_BUS_PARAM;
1762 if (icd->ops->query_bus_param) {
1763 camera_flags = icd->ops->query_bus_param(icd);
1767 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1770 dev_warn(icd->dev.parent,
1771 "Flags incompatible: camera %lx, host %lx\n",
1772 camera_flags, bus_flags);
1776 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1778 .fourcc = V4L2_PIX_FMT_NV12,
1779 .name = "YUV420 NV12",
1780 .bits_per_sample = 8,
1781 .packing = SOC_MBUS_PACKING_1_5X8,
1782 .order = SOC_MBUS_ORDER_LE,
1784 .fourcc = V4L2_PIX_FMT_NV16,
1785 .name = "YUV422 NV16",
1786 .bits_per_sample = 8,
1787 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1788 .order = SOC_MBUS_ORDER_LE,
1790 .fourcc = V4L2_PIX_FMT_NV21,
1791 .name = "YUV420 NV21",
1792 .bits_per_sample = 8,
1793 .packing = SOC_MBUS_PACKING_1_5X8,
1794 .order = SOC_MBUS_ORDER_LE,
1796 .fourcc = V4L2_PIX_FMT_NV61,
1797 .name = "YUV422 NV61",
1798 .bits_per_sample = 8,
1799 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1800 .order = SOC_MBUS_ORDER_LE,
1802 .fourcc = V4L2_PIX_FMT_RGB565,
1804 .bits_per_sample = 8,
1805 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1806 .order = SOC_MBUS_ORDER_LE,
1808 .fourcc = V4L2_PIX_FMT_RGB24,
1810 .bits_per_sample = 8,
1811 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1812 .order = SOC_MBUS_ORDER_LE,
1816 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1818 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1819 struct rk_camera_dev *pcdev = ici->priv;
1820 unsigned int cif_fs = 0,cif_crop = 0;
1821 unsigned int cif_fmt_val = read_cif_reg(pcdev->base,CIF_CIF_FOR) | INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN;
1823 const struct soc_mbus_pixelfmt *fmt;
1824 fmt = soc_mbus_get_fmtdesc(icd_code);
1826 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1827 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1828 host_pixfmt = V4L2_PIX_FMT_NV12;
1829 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1830 host_pixfmt = V4L2_PIX_FMT_NV21;
1832 switch (host_pixfmt)
1834 case V4L2_PIX_FMT_NV16:
1835 cif_fmt_val &= ~YUV_OUTPUT_422;
1836 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1837 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1838 pcdev->pixfmt = host_pixfmt;
1840 case V4L2_PIX_FMT_NV61:
1841 cif_fmt_val &= ~YUV_OUTPUT_422;
1842 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1843 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1844 pcdev->pixfmt = host_pixfmt;
1846 case V4L2_PIX_FMT_NV12:
1847 cif_fmt_val |= YUV_OUTPUT_420;
1848 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1849 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1850 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1851 pcdev->pixfmt = host_pixfmt;
1853 case V4L2_PIX_FMT_NV21:
1854 cif_fmt_val |= YUV_OUTPUT_420;
1855 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1856 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1857 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1858 pcdev->pixfmt = host_pixfmt;
1860 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1861 cif_fmt_val |= YUV_OUTPUT_422;
1866 case V4L2_MBUS_FMT_UYVY8_2X8:
1867 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1869 case V4L2_MBUS_FMT_YUYV8_2X8:
1870 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1872 case V4L2_MBUS_FMT_YVYU8_2X8:
1873 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1875 case V4L2_MBUS_FMT_VYUY8_2X8:
1876 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1879 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1883 #if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928))
1886 //pmu_set_idle_request(IDLE_REQ_VIO, true);
1887 cru_set_soft_reset(SOFT_RST_CIF0, true);
1889 cru_set_soft_reset(SOFT_RST_CIF0, false);
1890 //pmu_set_idle_request(IDLE_REQ_VIO, false);
1893 //pmu_set_idle_request(IDLE_REQ_VIO, true);
1894 cru_set_soft_reset(SOFT_RST_CIF1, true);
1896 cru_set_soft_reset(SOFT_RST_CIF1, false);
1897 //pmu_set_idle_request(IDLE_REQ_VIO, false);
1899 #elif defined(CONFIG_ARCH_RK3188)
1900 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1901 cru_set_soft_reset(SOFT_RST_CIF0, true);
1903 cru_set_soft_reset(SOFT_RST_CIF0, false);
1904 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1907 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1908 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable
1910 write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val); /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
1912 // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */
1913 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1914 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1915 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1917 } else{ // this is one frame mode
1918 cif_crop = (rect->left+ (rect->top<<16));
1919 cif_fs = ((rect->width ) + (rect->height<<16));
1922 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1923 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1924 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1925 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1928 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1929 RKCAMERA_DG("crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1933 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1934 struct soc_camera_format_xlate *xlate)
1936 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1937 struct device *dev = icd->dev.parent;
1938 int formats = 0, ret;
1939 enum v4l2_mbus_pixelcode code;
1940 const struct soc_mbus_pixelfmt *fmt;
1942 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1944 /* No more formats */
1947 fmt = soc_mbus_get_fmtdesc(code);
1949 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1953 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1958 case V4L2_MBUS_FMT_UYVY8_2X8:
1959 case V4L2_MBUS_FMT_YUYV8_2X8:
1960 case V4L2_MBUS_FMT_YVYU8_2X8:
1961 case V4L2_MBUS_FMT_VYUY8_2X8:
1962 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1965 xlate->host_fmt = &rk_camera_formats[0];
1968 dev_dbg(dev, "Providing format %s using code %d\n",
1969 rk_camera_formats[0].name,code);
1974 xlate->host_fmt = &rk_camera_formats[1];
1977 dev_dbg(dev, "Providing format %s using code %d\n",
1978 rk_camera_formats[1].name,code);
1983 xlate->host_fmt = &rk_camera_formats[2];
1986 dev_dbg(dev, "Providing format %s using code %d\n",
1987 rk_camera_formats[2].name,code);
1992 xlate->host_fmt = &rk_camera_formats[3];
1995 dev_dbg(dev, "Providing format %s using code %d\n",
1996 rk_camera_formats[3].name,code);
2002 xlate->host_fmt = &rk_camera_formats[4];
2005 dev_dbg(dev, "Providing format %s using code %d\n",
2006 rk_camera_formats[4].name,code);
2010 xlate->host_fmt = &rk_camera_formats[5];
2013 dev_dbg(dev, "Providing format %s using code %d\n",
2014 rk_camera_formats[5].name,code);
2025 static void rk_camera_put_formats(struct soc_camera_device *icd)
2030 static int rk_camera_set_crop(struct soc_camera_device *icd,
2031 struct v4l2_crop *a)
2033 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2034 struct v4l2_mbus_framefmt mf;
2035 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
2038 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
2042 if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) {
2044 mf.width = a->c.left + a->c.width;
2045 mf.height = a->c.top + a->c.height;
2047 v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2048 &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2049 fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
2051 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2056 rk_camera_setup_format(icd, fourcc, mf.code, &a->c);
2058 icd->user_width = mf.width;
2059 icd->user_height = mf.height;
2063 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
2067 if (f->fmt.pix.priv == 0xfefe5a5a) {
2071 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
2073 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
2075 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
2077 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
2079 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
2081 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
2086 RKCAMERA_DG("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
2089 static int rk_camera_set_fmt(struct soc_camera_device *icd,
2090 struct v4l2_format *f)
2092 struct device *dev = icd->dev.parent;
2093 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2094 const struct soc_camera_format_xlate *xlate = NULL;
2095 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
2096 struct rk_camera_dev *pcdev = ici->priv;
2097 struct v4l2_pix_format *pix = &f->fmt.pix;
2098 struct v4l2_mbus_framefmt mf;
2099 struct v4l2_rect rect;
2100 int ret,usr_w,usr_h;
2104 usr_h = pix->height;
2106 RKCAMERA_DG("enter width:%d height:%d\n",usr_w,usr_h);
2107 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
2109 dev_err(dev, "Format %x not found\n", pix->pixelformat);
2111 goto RK_CAMERA_SET_FMT_END;
2114 /* ddl@rock-chips.com: sensor init code transmit in here after open */
2115 if (pcdev->icd_init == 0) {
2116 v4l2_subdev_call(sd,core, init, 0);
2117 pcdev->icd_init = 1;
2120 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2121 if (stream_on & ENABLE_CAPTURE)
2122 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
2124 mf.width = pix->width;
2125 mf.height = pix->height;
2126 mf.field = pix->field;
2127 mf.colorspace = pix->colorspace;
2128 mf.code = xlate->code;
2129 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
2131 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2132 if (mf.code != xlate->code)
2135 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2136 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2138 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2139 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2141 goto RK_CAMERA_SET_FMT_END;
2143 if (unlikely((usr_w <16)||(usr_h < 16))) {
2144 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2146 goto RK_CAMERA_SET_FMT_END;
2149 if((mf.width*10/mf.height) != (usr_w*10/usr_h)){
2150 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2151 pcdev->host_width = ratio*usr_w/10;
2152 pcdev->host_height = ratio*usr_h/10;
2153 //for ipp ,need 4 bit alligned.
2154 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2155 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2156 RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
2158 else{ // needn't crop ,just scaled by ipp
2159 pcdev->host_width = mf.width;
2160 pcdev->host_height = mf.height;
2163 pcdev->host_width = usr_w;
2164 pcdev->host_height = usr_h;
2167 //according to crop and scale capability to change , here just cropt to user needed
2168 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2169 RKCAMERA_TR("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
2171 goto RK_CAMERA_SET_FMT_END;
2173 if (unlikely((usr_w <16)||(usr_h < 16))) {
2174 RKCAMERA_TR("Senor invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2176 goto RK_CAMERA_SET_FMT_END;
2178 pcdev->host_width = usr_w;
2179 pcdev->host_height = usr_h;
2184 RKCAMERA_DG("host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",
2185 pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h);
2186 rect.width = pcdev->host_width;
2187 rect.height = pcdev->host_height;
2188 rect.left = ((mf.width-pcdev->host_width )>>1)&(~0x01);
2189 rect.top = ((mf.height-pcdev->host_height)>>1)&(~0x01);
2190 pcdev->host_left = rect.left;
2191 pcdev->host_top = rect.top;
2193 down(&pcdev->zoominfo.sem);
2195 pcdev->zoominfo.a.c.left = 0;
2196 pcdev->zoominfo.a.c.top = 0;
2197 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2198 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2199 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2200 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2201 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2202 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2203 //recalculate the CIF width & height
2204 rect.width = pcdev->zoominfo.a.c.width ;
2205 rect.height = pcdev->zoominfo.a.c.height;
2206 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2207 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2209 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2210 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2211 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2212 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2213 //now digital zoom use ipp to do crop and scale
2214 if(pcdev->zoominfo.zoom_rate != 100){
2215 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2216 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2218 pcdev->zoominfo.a.c.left = 0;
2219 pcdev->zoominfo.a.c.top = 0;
2221 pcdev->zoominfo.vir_width = pcdev->host_width;
2222 pcdev->zoominfo.vir_height = pcdev->host_height;
2224 up(&pcdev->zoominfo.sem);
2226 /* ddl@rock-chips.com: IPP work limit check */
2227 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2228 if (usr_w > 0x7f0) {
2229 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2230 RKCAMERA_TR("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f));
2232 goto RK_CAMERA_SET_FMT_END;
2235 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2236 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2238 goto RK_CAMERA_SET_FMT_END;
2242 RKCAMERA_DG(" %s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name,
2243 rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2244 pix->width, pix->height);
2245 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2247 if (CAM_IPPWORK_IS_EN()) {
2248 BUG_ON(pcdev->vipmem_phybase == 0);
2251 pix->height = usr_h;
2252 pix->field = mf.field;
2253 pix->colorspace = mf.colorspace;
2254 icd->current_fmt = xlate;
2255 pcdev->icd_width = mf.width;
2256 pcdev->icd_height = mf.height;
2259 RK_CAMERA_SET_FMT_END:
2260 if (stream_on & ENABLE_CAPTURE)
2261 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2263 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2267 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2268 struct v4l2_format *f)
2270 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2271 struct rk_camera_dev *pcdev = ici->priv;
2272 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2273 const struct soc_camera_format_xlate *xlate;
2274 struct v4l2_pix_format *pix = &f->fmt.pix;
2275 __u32 pixfmt = pix->pixelformat;
2276 int ret,usr_w,usr_h,i;
2277 bool is_capture = rk_camera_fmt_capturechk(f);
2278 bool vipmem_is_overflow = false;
2279 struct v4l2_mbus_framefmt mf;
2280 int bytes_per_line_host;
2283 usr_h = pix->height;
2285 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2287 dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2288 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2290 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2291 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2292 for (i = 0; i < icd->num_user_formats; i++)
2293 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2294 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2295 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2296 icd->user_formats[i].host_fmt->name);
2297 goto RK_CAMERA_TRY_FMT_END;
2299 /* limit to rk29 hardware capabilities */
2300 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2301 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2302 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2304 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2306 if (pix->bytesperline < 0)
2307 return pix->bytesperline;
2309 /* limit to sensor capabilities */
2310 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2311 mf.width = pix->width;
2312 mf.height = pix->height;
2313 mf.field = pix->field;
2314 mf.colorspace = pix->colorspace;
2315 mf.code = xlate->code;
2316 /* ddl@rock-chips.com : It is query max resolution only. */
2317 if ((usr_w == 10000) && (usr_h == 10000)) {
2318 mf.reserved[6] = 0xfefe5a5a;
2321 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2323 goto RK_CAMERA_TRY_FMT_END;
2326 if((usr_w == 10000) && (usr_h == 10000)) {
2327 pix->width = mf.width;
2328 pix->height = mf.height;
2329 RKCAMERA_DG("Sensor resolution : %dx%d\n",mf.width,mf.height);
2330 goto RK_CAMERA_TRY_FMT_END;
2332 RKCAMERA_DG("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2335 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2336 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2337 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2339 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2341 /* Assume preview buffer minimum is 4 */
2342 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2344 if (vipmem_is_overflow == false) {
2346 pix->height = usr_h;
2348 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
2349 pix->width = mf.width;
2350 pix->height = mf.height;
2352 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2354 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2355 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2356 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2357 pix->width = mf.width;
2358 pix->height = mf.height;
2364 //need to change according to crop and scale capablicity
2365 if ((mf.width > usr_w) && (mf.height > usr_h)) {
2367 pix->height = usr_h;
2368 } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
2369 RKCAMERA_TR("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
2370 pix->width = mf.width;
2371 pix->height = mf.height;
2374 pix->colorspace = mf.colorspace;
2377 case V4L2_FIELD_ANY:
2378 case V4L2_FIELD_NONE:
2379 pix->field = V4L2_FIELD_NONE;
2382 /* TODO: support interlaced at least in pass-through mode */
2383 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
2385 goto RK_CAMERA_TRY_FMT_END;
2388 RK_CAMERA_TRY_FMT_END:
2390 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2394 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2395 struct v4l2_requestbuffers *p)
2399 /* This is for locking debugging only. I removed spinlocks and now I
2400 * check whether .prepare is ever called on a linked buffer, or whether
2401 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2402 * it hadn't triggered */
2403 for (i = 0; i < p->count; i++) {
2404 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2405 struct rk_camera_buffer, vb);
2407 INIT_LIST_HEAD(&buf->vb.queue);
2413 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2415 struct soc_camera_device *icd = file->private_data;
2416 struct rk_camera_buffer *buf;
2418 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2421 poll_wait(file, &buf->vb.done, pt);
2423 if (buf->vb.state == VIDEOBUF_DONE ||
2424 buf->vb.state == VIDEOBUF_ERROR)
2425 return POLLIN|POLLRDNORM;
2430 static int rk_camera_querycap(struct soc_camera_host *ici,
2431 struct v4l2_capability *cap)
2433 struct rk_camera_dev *pcdev = ici->priv;
2434 struct rkcamera_platform_data *new_camera;
2435 char orientation[5];
2438 strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
2439 memset(orientation,0x00,sizeof(orientation));
2440 for (i=0; i<RK_CAM_NUM;i++) {
2441 if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
2442 sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
2447 new_camera = pcdev->pdata->register_dev_new;
2448 while (strstr(new_camera->dev_name,"end")==NULL) {
2449 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2450 sprintf(orientation,"-%d",new_camera->orientation);
2455 if (orientation[0] != '-') {
2456 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2457 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2458 strcat(cap->card,"-270");
2460 strcat(cap->card,"-90");
2462 strcat(cap->card,orientation);
2464 cap->version = RK_CAM_VERSION_CODE;
2465 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2469 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2471 struct soc_camera_host *ici =
2472 to_soc_camera_host(icd->dev.parent);
2473 struct rk_camera_dev *pcdev = ici->priv;
2474 struct v4l2_subdev *sd;
2477 mutex_lock(&camera_lock);
2478 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2479 rk_camera_s_stream(icd, 0);
2480 sd = soc_camera_to_subdev(icd);
2481 v4l2_subdev_call(sd, video, s_stream, 0);
2482 ret = icd->ops->suspend(icd, state);
2484 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2485 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2486 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2487 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2488 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2489 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2490 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2492 pcdev->reginfo_suspend.Inval = Reg_Validate;
2493 rk_camera_deactivate(pcdev);
2495 RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__);
2497 RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2499 mutex_unlock(&camera_lock);
2503 static int rk_camera_resume(struct soc_camera_device *icd)
2505 struct soc_camera_host *ici =
2506 to_soc_camera_host(icd->dev.parent);
2507 struct rk_camera_dev *pcdev = ici->priv;
2508 struct v4l2_subdev *sd;
2511 mutex_lock(&camera_lock);
2512 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2513 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2514 rk_camera_activate(pcdev, icd);
2515 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2516 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2517 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2518 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2519 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2520 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2521 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2522 rk_videobuf_capture(pcdev->active,pcdev);
2523 rk_camera_s_stream(icd, 1);
2524 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2526 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2527 goto rk_camera_resume_end;
2530 ret = icd->ops->resume(icd);
2531 sd = soc_camera_to_subdev(icd);
2532 v4l2_subdev_call(sd, video, s_stream, 1);
2534 RKCAMERA_DG("%s Enter success\n",__FUNCTION__);
2536 RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2539 rk_camera_resume_end:
2540 mutex_unlock(&camera_lock);
2544 static void rk_camera_reinit_work(struct work_struct *work)
2546 struct v4l2_subdev *sd;
2547 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2548 struct rk_camera_dev *pcdev = camera_work->pcdev;
2549 struct soc_camera_link *tmp_soc_cam_link;
2551 unsigned long flags = 0;
2552 if(pcdev->icd == NULL)
2554 sd = soc_camera_to_subdev(pcdev->icd);
2555 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2558 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2559 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2560 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2561 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2562 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2563 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2564 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2565 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2566 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2568 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2569 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2570 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2571 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2572 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2573 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2576 pcdev->stop_cif = true;
2577 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2578 RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
2579 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2580 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2581 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2582 if (NULL == pcdev->video_vq->bufs[index])
2585 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
2587 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2588 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2589 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2590 printk("wake up video buffer index = %d !!!\n",index);
2593 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2595 RKCAMERA_TR("video queue has somthing wrong !!\n");
2598 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2600 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2602 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2603 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2604 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2606 // static unsigned int last_fps = 0;
2607 struct soc_camera_link *tmp_soc_cam_link;
2608 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2610 RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2611 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2612 RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
2613 pcdev->camera_reinit_work.pcdev = pcdev;
2614 //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2615 pcdev->reinit_times++;
2616 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2617 } else if(!pcdev->timer_get_fps) {
2618 pcdev->timer_get_fps = true;
2619 for (i=0; i<2; i++) {
2620 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2621 fival_nxt = pcdev->icd_frmival[i].fival_list;
2626 fival_pre = fival_nxt;
2627 while (fival_nxt != NULL) {
2629 RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
2630 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2631 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2632 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2633 fival_nxt->fival.discrete.numerator);
2635 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2636 && (fival_nxt->fival.height == pcdev->icd->user_height)
2637 && (fival_nxt->fival.width == pcdev->icd->user_width))
2638 || (fival_nxt->fival.discrete.denominator == 0)) {
2640 if (fival_nxt->fival.discrete.denominator == 0) {
2641 fival_nxt->fival.index = 0;
2642 fival_nxt->fival.width = pcdev->icd->user_width;
2643 fival_nxt->fival.height= pcdev->icd->user_height;
2644 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2645 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2646 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2647 |(pcdev->icd_height);
2648 fival_nxt->fival.discrete.numerator = 1000000;
2649 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2652 fival_rec = fival_nxt;
2654 fival_pre = fival_nxt;
2655 fival_nxt = fival_nxt->nxt;
2658 if ((rec_flag == 0) && fival_pre) {
2659 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2660 if (fival_pre->nxt != NULL) {
2661 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2662 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2663 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2664 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2666 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2667 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2668 |(pcdev->icd_height);
2669 fival_pre->nxt->fival.discrete.numerator = 1000000;
2670 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2672 fival_rec = fival_pre->nxt;
2676 pcdev->last_fps = pcdev->fps ;
2677 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2678 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2679 //return HRTIMER_NORESTART;
2680 if(pcdev->reinit_times >=2)
2681 return HRTIMER_NORESTART;
2683 return HRTIMER_RESTART;
2685 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2687 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2688 struct rk_camera_dev *pcdev = ici->priv;
2691 unsigned long flags;
2693 WARN_ON(pcdev->icd != icd);
2695 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2698 pcdev->last_fps = 0;
2699 pcdev->frame_interval = 0;
2700 hrtimer_cancel(&(pcdev->fps_timer.timer));
2701 pcdev->fps_timer.pcdev = pcdev;
2702 pcdev->timer_get_fps = false;
2703 pcdev->reinit_times = 0;
2704 pcdev->stop_cif = false;
2705 // hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2706 cif_ctrl_val |= ENABLE_CAPTURE;
2707 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2708 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2709 pcdev->fps_timer.istarted = true;
2711 //cancel timer before stop cif
2712 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2713 pcdev->fps_timer.istarted = false;
2714 flush_work(&(pcdev->camera_reinit_work.work));
2716 cif_ctrl_val &= ~ENABLE_CAPTURE;
2717 spin_lock_irqsave(&pcdev->lock, flags);
2718 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2719 pcdev->stop_cif = true;
2720 spin_unlock_irqrestore(&pcdev->lock, flags);
2721 flush_workqueue((pcdev->camera_wq));
2722 RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
2724 //must be reinit,or will be somthing wrong in irq process.
2725 if(enable == false) {
2726 pcdev->active = NULL;
2727 INIT_LIST_HEAD(&pcdev->capture);
2729 RKCAMERA_DG("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2732 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2734 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2735 struct rk_camera_dev *pcdev = ici->priv;
2736 struct rk_camera_frmivalenum *fival_list = NULL;
2737 struct v4l2_frmivalenum *fival_head = NULL;
2738 struct rkcamera_platform_data *new_camera;
2739 int i,ret = 0,index;
2741 index = fival->index & 0x00ffffff;
2742 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2743 for (i=0; i<2; i++) {
2744 if (pcdev->icd_frmival[i].icd == icd) {
2745 fival_list = pcdev->icd_frmival[i].fival_list;
2749 if (fival_list != NULL) {
2751 while (fival_list != NULL) {
2752 if ((fival->pixel_format == fival_list->fival.pixel_format)
2753 && (fival->height == fival_list->fival.height)
2754 && (fival->width == fival_list->fival.width)) {
2759 fival_list = fival_list->nxt;
2762 if ((i==index) && (fival_list != NULL)) {
2763 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2768 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2773 for (i=0; i<RK_CAM_NUM; i++) {
2774 if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
2775 fival_head = pcdev->pdata->info[i].fival;
2781 while (fival_head->width && fival_head->height) {
2782 if ((fival->pixel_format == fival_head->pixel_format)
2783 && (fival->height == fival_head->height)
2784 && (fival->width == fival_head->width)) {
2793 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2794 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2795 fival->reserved[1] = (pcdev->icd_width<<16)|(pcdev->icd_height);
2796 RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2797 fival->width, fival->height,
2798 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2799 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2800 fival->discrete.denominator,fival->discrete.numerator);
2803 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2804 fival->width,fival->height,
2805 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2806 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2809 RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2810 fival->width,fival->height,
2811 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2812 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2815 goto rk_camera_enum_frameintervals_end;
2819 new_camera = pcdev->pdata->register_dev_new;
2820 while (strstr(new_camera->dev_name,"end")==NULL) {
2821 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2829 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2830 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2832 fival->discrete.numerator= 1000;
2833 fival->discrete.denominator = 15000;
2834 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2838 rk_camera_enum_frameintervals_end:
2842 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2843 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2844 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2847 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2848 struct rk_camera_dev *pcdev = ici->priv;
2850 unsigned long tmp_cifctrl;
2853 //change the crop and scale parameters
2856 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2857 //a.c.width = pcdev->host_width*100/zoom_rate;
2858 a.c.width = pcdev->host_width*100/zoom_rate;
2859 a.c.width &= ~CROP_ALIGN_BYTES;
2860 a.c.height = pcdev->host_height*100/zoom_rate;
2861 a.c.height &= ~CROP_ALIGN_BYTES;
2862 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2863 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2864 pcdev->stop_cif = true;
2865 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2866 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2867 hrtimer_cancel(&(pcdev->fps_timer.timer));
2868 flush_workqueue((pcdev->camera_wq));
2869 down(&pcdev->zoominfo.sem);
2870 pcdev->zoominfo.a.c.left = 0;
2871 pcdev->zoominfo.a.c.top = 0;
2872 pcdev->zoominfo.a.c.width = a.c.width;
2873 pcdev->zoominfo.a.c.height = a.c.height;
2874 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2875 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2876 pcdev->frame_inval = 1;
2877 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2878 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2879 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2880 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2882 rk_videobuf_capture(pcdev->active,pcdev);
2883 if(tmp_cifctrl & ENABLE_CAPTURE)
2884 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2885 up(&pcdev->zoominfo.sem);
2886 pcdev->stop_cif = false;
2887 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2888 RKCAMERA_DG("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2890 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2891 a.c.width = pcdev->host_width*100/zoom_rate;
2892 a.c.width &= ~CROP_ALIGN_BYTES;
2893 a.c.height = pcdev->host_height*100/zoom_rate;
2894 a.c.height &= ~CROP_ALIGN_BYTES;
2895 a.c.left = (pcdev->host_width - a.c.width)>>1;
2896 a.c.top = (pcdev->host_height - a.c.height)>>1;
2897 down(&pcdev->zoominfo.sem);
2898 pcdev->zoominfo.a.c.height = a.c.height;
2899 pcdev->zoominfo.a.c.width = a.c.width;
2900 pcdev->zoominfo.a.c.top = a.c.top;
2901 pcdev->zoominfo.a.c.left = a.c.left;
2902 pcdev->zoominfo.vir_width = pcdev->host_width;
2903 pcdev->zoominfo.vir_height= pcdev->host_height;
2904 up(&pcdev->zoominfo.sem);
2905 RKCAMERA_DG("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2911 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2912 struct soc_camera_host_ops *ops, int id)
2916 for (i = 0; i < ops->num_controls; i++)
2917 if (ops->controls[i].id == id)
2918 return &ops->controls[i];
2924 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2925 struct v4l2_control *sctrl)
2928 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2929 const struct v4l2_queryctrl *qctrl;
2930 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2931 struct rk_camera_dev *pcdev = ici->priv;
2935 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2938 goto rk_camera_set_ctrl_end;
2943 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2944 case V4L2_CID_ZOOM_ABSOLUTE:
2946 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2948 goto rk_camera_set_ctrl_end;
2950 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2952 pcdev->zoominfo.zoom_rate = sctrl->value;
2954 goto rk_camera_set_ctrl_end;
2963 rk_camera_set_ctrl_end:
2967 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2969 .owner = THIS_MODULE,
2970 .add = rk_camera_add_device,
2971 .remove = rk_camera_remove_device,
2972 .suspend = rk_camera_suspend,
2973 .resume = rk_camera_resume,
2974 .enum_frameinervals = rk_camera_enum_frameintervals,
2975 .set_crop = rk_camera_set_crop,
2976 .get_formats = rk_camera_get_formats,
2977 .put_formats = rk_camera_put_formats,
2978 .set_fmt = rk_camera_set_fmt,
2979 .try_fmt = rk_camera_try_fmt,
2980 .init_videobuf = rk_camera_init_videobuf,
2981 .reqbufs = rk_camera_reqbufs,
2982 .poll = rk_camera_poll,
2983 .querycap = rk_camera_querycap,
2984 .set_bus_param = rk_camera_set_bus_param,
2985 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2986 .set_ctrl = rk_camera_set_ctrl,
2987 .controls = rk_camera_controls,
2988 .num_controls = ARRAY_SIZE(rk_camera_controls)
2990 static void rk_camera_cif_iomux(int cif_index)
2992 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
2995 iomux_set(CIF0_CLKOUT);
2996 write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_8MA));
2997 write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
2998 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
3002 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
3003 iomux_set(CIF0_D10);
3004 iomux_set(CIF0_D11);
3005 RKCAMERA_TR("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
3010 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
3013 #elif defined(CONFIG_ARCH_RK30)
3016 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
3017 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
3018 rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME, GPIO1B_CIF0_DATA0);
3019 rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME, GPIO1B_CIF0_DATA1);
3021 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
3022 rk30_mux_api_set(GPIO1B6_CIFDATA10_NAME, GPIO1B_CIF_DATA10);
3023 rk30_mux_api_set(GPIO1B7_CIFDATA11_NAME, GPIO1B_CIF_DATA11);
3027 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
3028 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
3029 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
3030 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
3031 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
3032 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
3033 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
3034 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
3036 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
3037 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
3038 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
3039 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
3040 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
3041 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
3042 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
3043 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
3046 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
3053 static int rk_camera_probe(struct platform_device *pdev)
3055 struct rk_camera_dev *pcdev;
3056 struct resource *res;
3057 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3058 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
3061 struct rk_cif_clk *clk=NULL;
3063 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3064 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3066 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3067 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3071 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3072 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3076 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3077 irq = platform_get_irq(pdev, 0);
3078 if (!res || irq < 0) {
3082 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3084 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3089 pcdev->zoominfo.zoom_rate = 100;
3090 pcdev->hostid = pdev->id;
3091 #ifdef CONFIG_SOC_RK3028
3092 pcdev->chip_id = rk3028_version_val();
3094 pcdev->chip_id = -1;
3098 cif_clk[0].pd_cif = clk_get(NULL, "pd_cif0");
3099 cif_clk[0].aclk_cif = clk_get(NULL, "aclk_cif0");
3100 cif_clk[0].hclk_cif = clk_get(NULL, "hclk_cif0");
3101 cif_clk[0].cif_clk_in = clk_get(NULL, "cif0_in");
3102 cif_clk[0].cif_clk_out = clk_get(NULL, "cif0_out");
3103 spin_lock_init(&cif_clk[0].lock);
3104 cif_clk[0].on = false;
3105 rk_camera_cif_iomux(0);
3108 cif_clk[1].pd_cif = clk_get(NULL, "pd_cif1");
3109 cif_clk[1].aclk_cif = clk_get(NULL, "aclk_cif1");
3110 cif_clk[1].hclk_cif = clk_get(NULL, "hclk_cif1");
3111 cif_clk[1].cif_clk_in = clk_get(NULL, "cif1_in");
3112 cif_clk[1].cif_clk_out = clk_get(NULL, "cif1_out");
3113 spin_lock_init(&cif_clk[1].lock);
3114 cif_clk[1].on = false;
3115 rk_camera_cif_iomux(1);
3118 dev_set_drvdata(&pdev->dev, pcdev);
3120 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3122 if (pcdev->pdata && pcdev->pdata->io_init) {
3123 pcdev->pdata->io_init();
3125 if (pcdev->pdata->sensor_mclk == NULL)
3126 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3128 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
3129 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
3130 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
3132 if (meminfo_ptr->vbase == NULL) {
3134 if ((meminfo_ptr->start == meminfo_ptrr->start)
3135 && (meminfo_ptr->size == meminfo_ptrr->size) && meminfo_ptrr->vbase) {
3137 meminfo_ptr->vbase = meminfo_ptrr->vbase;
3140 if (!request_mem_region(meminfo_ptr->start,meminfo_ptr->size,"rk29_vipmem")) {
3142 RKCAMERA_TR("%s(%d): request_mem_region(start:0x%x size:0x%x) failed \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
3143 goto exit_ioremap_vipmem;
3145 meminfo_ptr->vbase = pcdev->vipmem_virbase = ioremap_cached(meminfo_ptr->start,meminfo_ptr->size);
3146 if (pcdev->vipmem_virbase == NULL) {
3147 RKCAMERA_TR("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
3149 goto exit_ioremap_vipmem;
3154 pcdev->vipmem_phybase = meminfo_ptr->start;
3155 pcdev->vipmem_size = meminfo_ptr->size;
3156 pcdev->vipmem_virbase = meminfo_ptr->vbase;
3158 INIT_LIST_HEAD(&pcdev->capture);
3159 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3160 spin_lock_init(&pcdev->lock);
3161 spin_lock_init(&pcdev->camera_work_lock);
3162 sema_init(&pcdev->zoominfo.sem,1);
3165 * Request the regions.
3168 if (!request_mem_region(res->start, res->end - res->start + 1,
3169 RK29_CAM_DRV_NAME)) {
3171 goto exit_reqmem_vip;
3173 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3174 if (pcdev->base == NULL) {
3175 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3177 goto exit_ioremap_vip;
3182 pcdev->dev = &pdev->dev;
3184 /* config buffer address */
3187 err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3190 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3195 //#ifdef CONFIG_VIDEO_RK29_WORK_IPP
3197 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3199 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3201 if (pcdev->camera_wq == NULL) {
3202 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3206 pcdev->camera_reinit_work.pcdev = pcdev;
3207 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3209 for (i=0; i<2; i++) {
3210 pcdev->icd_frmival[i].icd = NULL;
3211 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3214 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3215 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3216 pcdev->soc_host.priv = pcdev;
3217 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3218 pcdev->soc_host.nr = pdev->id;
3220 err = soc_camera_host_register(&pcdev->soc_host);
3222 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3225 pcdev->fps_timer.pcdev = pcdev;
3226 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3227 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3228 pcdev->icd_cb.sensor_cb = NULL;
3230 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3231 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3232 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3233 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3234 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3235 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3236 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3237 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3239 RKCAMERA_DG("%s exit \n",__FUNCTION__);
3244 for (i=0; i<2; i++) {
3245 fival_list = pcdev->icd_frmival[i].fival_list;
3246 fival_nxt = fival_list;
3247 while(fival_nxt != NULL) {
3248 fival_nxt = fival_list->nxt;
3250 fival_list = fival_nxt;
3254 free_irq(pcdev->irq, pcdev);
3255 if (pcdev->camera_wq) {
3256 destroy_workqueue(pcdev->camera_wq);
3257 pcdev->camera_wq = NULL;
3260 iounmap(pcdev->base);
3262 release_mem_region(res->start, res->end - res->start + 1);
3263 exit_ioremap_vipmem:
3264 if (pcdev->vipmem_virbase)
3265 iounmap(pcdev->vipmem_virbase);
3266 release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
3270 clk_put(clk->pd_cif);
3272 clk_put(clk->aclk_cif);
3274 clk_put(clk->hclk_cif);
3275 if (clk->cif_clk_in)
3276 clk_put(clk->cif_clk_in);
3277 if (clk->cif_clk_out)
3278 clk_put(clk->cif_clk_out);
3287 static int __devexit rk_camera_remove(struct platform_device *pdev)
3289 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3290 struct resource *res;
3291 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3292 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
3295 free_irq(pcdev->irq, pcdev);
3297 if (pcdev->camera_wq) {
3298 destroy_workqueue(pcdev->camera_wq);
3299 pcdev->camera_wq = NULL;
3302 for (i=0; i<2; i++) {
3303 fival_list = pcdev->icd_frmival[i].fival_list;
3304 fival_nxt = fival_list;
3305 while(fival_nxt != NULL) {
3306 fival_nxt = fival_list->nxt;
3308 fival_list = fival_nxt;
3312 soc_camera_host_unregister(&pcdev->soc_host);
3314 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
3315 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
3316 if (meminfo_ptr->vbase) {
3317 if (meminfo_ptr->vbase == meminfo_ptrr->vbase) {
3318 meminfo_ptr->vbase = NULL;
3320 iounmap((void __iomem*)pcdev->vipmem_virbase);
3321 release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
3322 meminfo_ptr->vbase = NULL;
3327 iounmap((void __iomem*)pcdev->base);
3328 release_mem_region(res->start, res->end - res->start + 1);
3329 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3330 pcdev->pdata->io_deinit(0);
3331 pcdev->pdata->io_deinit(1);
3336 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3341 static struct platform_driver rk_camera_driver =
3344 .name = RK29_CAM_DRV_NAME,
3346 .probe = rk_camera_probe,
3347 .remove = __devexit_p(rk_camera_remove),
3350 static int rk_camera_init_async(void *unused)
3352 platform_driver_register(&rk_camera_driver);
3356 static int __devinit rk_camera_init(void)
3358 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3362 static void __exit rk_camera_exit(void)
3364 platform_driver_unregister(&rk_camera_driver);
3367 device_initcall_sync(rk_camera_init);
3368 module_exit(rk_camera_exit);
3370 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3371 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3372 MODULE_LICENSE("GPL");