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) ||\
13 defined(CONFIG_ARCH_RK30) ||\
14 defined(CONFIG_ARCH_RK3188) ||\
15 defined(CONFIG_ARCH_RK3026))
17 #include <linux/init.h>
18 #include <linux/module.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <linux/dma-mapping.h>
23 #include <linux/errno.h>
25 #include <linux/interrupt.h>
26 #include <linux/kernel.h>
28 #include <linux/moduleparam.h>
29 #include <linux/time.h>
30 #include <linux/clk.h>
31 #include <linux/version.h>
32 #include <linux/device.h>
33 #include <linux/platform_device.h>
34 #include <linux/mutex.h>
35 #include <linux/videodev2.h>
36 #include <linux/kthread.h>
37 #include <mach/iomux.h>
38 #include <media/v4l2-common.h>
39 #include <media/v4l2-dev.h>
40 #include <media/videobuf-dma-contig.h>
41 #include <media/soc_camera.h>
42 #include <media/soc_mediabus.h>
45 #include <plat/vpu_service.h>
46 #include "../../video/rockchip/rga/rga.h"
47 #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK3188)
48 #include <mach/rk30_camera.h>
52 #include <plat/efuse.h>
53 #if (defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026))
54 #include <mach/rk2928_camera.h>
57 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
59 #include <asm/cacheflush.h>
62 module_param(debug, int, S_IRUGO|S_IWUSR);
64 #define CAMMODULE_NAME "rk_cam_cif"
66 #define wprintk(level, fmt, arg...) do { \
68 printk(KERN_WARNING "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
70 #define dprintk(level, fmt, arg...) do { \
72 printk(KERN_DEBUG "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
74 #define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
75 #define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
76 #define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
79 #define CIF_CIF_CTRL 0x00
80 #define CIF_CIF_INTEN 0x04
81 #define CIF_CIF_INTSTAT 0x08
82 #define CIF_CIF_FOR 0x0c
83 #define CIF_CIF_LINE_NUM_ADDR 0x10
84 #define CIF_CIF_FRM0_ADDR_Y 0x14
85 #define CIF_CIF_FRM0_ADDR_UV 0x18
86 #define CIF_CIF_FRM1_ADDR_Y 0x1c
87 #define CIF_CIF_FRM1_ADDR_UV 0x20
88 #define CIF_CIF_VIR_LINE_WIDTH 0x24
89 #define CIF_CIF_SET_SIZE 0x28
90 #define CIF_CIF_SCM_ADDR_Y 0x2c
91 #define CIF_CIF_SCM_ADDR_U 0x30
92 #define CIF_CIF_SCM_ADDR_V 0x34
93 #define CIF_CIF_WB_UP_FILTER 0x38
94 #define CIF_CIF_WB_LOW_FILTER 0x3c
95 #define CIF_CIF_WBC_CNT 0x40
96 #define CIF_CIF_CROP 0x44
97 #define CIF_CIF_SCL_CTRL 0x48
98 #define CIF_CIF_SCL_DST 0x4c
99 #define CIF_CIF_SCL_FCT 0x50
100 #define CIF_CIF_SCL_VALID_NUM 0x54
101 #define CIF_CIF_LINE_LOOP_CTR 0x58
102 #define CIF_CIF_FRAME_STATUS 0x60
103 #define CIF_CIF_CUR_DST 0x64
104 #define CIF_CIF_LAST_LINE 0x68
105 #define CIF_CIF_LAST_PIX 0x6c
107 //The key register bit descrition
108 // CIF_CTRL Reg , ignore SCM,WBC,ISP,
109 #define DISABLE_CAPTURE (0x00<<0)
110 #define ENABLE_CAPTURE (0x01<<0)
111 #define MODE_ONEFRAME (0x00<<1)
112 #define MODE_PINGPONG (0x01<<1)
113 #define MODE_LINELOOP (0x02<<1)
114 #define AXI_BURST_16 (0x0F << 12)
117 #define FRAME_END_EN (0x01<<1)
118 #define BUS_ERR_EN (0x01<<6)
119 #define SCL_ERR_EN (0x01<<7)
122 #define VSY_HIGH_ACTIVE (0x01<<0)
123 #define VSY_LOW_ACTIVE (0x00<<0)
124 #define HSY_LOW_ACTIVE (0x01<<1)
125 #define HSY_HIGH_ACTIVE (0x00<<1)
126 #define INPUT_MODE_YUV (0x00<<2)
127 #define INPUT_MODE_PAL (0x02<<2)
128 #define INPUT_MODE_NTSC (0x03<<2)
129 #define INPUT_MODE_RAW (0x04<<2)
130 #define INPUT_MODE_JPEG (0x05<<2)
131 #define INPUT_MODE_MIPI (0x06<<2)
132 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
133 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
134 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
135 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
136 #define YUV_INPUT_422 (0x00<<7)
137 #define YUV_INPUT_420 (0x01<<7)
138 #define INPUT_420_ORDER_EVEN (0x00<<8)
139 #define INPUT_420_ORDER_ODD (0x01<<8)
140 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
141 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
142 #define RAW_DATA_WIDTH_8 (0x00<<11)
143 #define RAW_DATA_WIDTH_10 (0x01<<11)
144 #define RAW_DATA_WIDTH_12 (0x02<<11)
145 #define YUV_OUTPUT_422 (0x00<<16)
146 #define YUV_OUTPUT_420 (0x01<<16)
147 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
148 #define OUTPUT_420_ORDER_ODD (0x01<<17)
149 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
150 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
151 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
152 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
155 #define ENABLE_SCL_DOWN (0x01<<0)
156 #define DISABLE_SCL_DOWN (0x00<<0)
157 #define ENABLE_SCL_UP (0x01<<1)
158 #define DISABLE_SCL_UP (0x00<<1)
159 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
160 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
161 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
162 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
163 #define ENABLE_32BIT_BYPASS (0x01<<6)
164 #define DISABLE_32BIT_BYPASS (0x00<<6)
167 #define MIN(x,y) ((x<y) ? x: y)
168 #define MAX(x,y) ((x>y) ? x: y)
169 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
170 #define RK_SENSOR_48MHZ 48
172 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
173 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
174 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
176 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
178 #define CRU_PCLK_REG30 0xbc
179 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
180 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
181 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
182 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
184 #define CRU_CIF_RST_REG30 0x128
185 #define MASK_RST_CIF0 (0x01 << 30)
186 #define MASK_RST_CIF1 (0x01 << 31)
187 #define RQUEST_RST_CIF0 (0x01 << 14)
188 #define RQUEST_RST_CIF1 (0x01 << 15)
190 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
191 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
192 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
195 #if defined(CONFIG_ARCH_RK3026)
197 #define CRU_PCLK_REG30 0xbc
198 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<23)|(0x1<<7))
199 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<23)|(0x0<<7))
200 #define ENANABLE_INVERT_PCLK_CIF1 ENANABLE_INVERT_PCLK_CIF0
201 #define DISABLE_INVERT_PCLK_CIF1 DISABLE_INVERT_PCLK_CIF0
203 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
204 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
205 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
208 #if defined(CONFIG_ARCH_RK2928)
209 #define write_cru_reg(addr, val)
210 #define read_cru_reg(addr) 0
211 #define mask_cru_reg(addr, msk, val)
215 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
217 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
218 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
219 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
220 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
221 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
224 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
225 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
226 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
228 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
229 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
230 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
232 #define write_grf_reg(addr, val)
233 #define read_grf_reg(addr) 0
234 #define mask_grf_reg(addr, msk, val)
237 #define CAM_WORKQUEUE_IS_EN() (true)
238 #define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
240 #define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
241 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
242 #define CROP_ALIGN_BYTES (0x03)
243 #define CIF_DO_CROP 0
244 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
245 #define CROP_ALIGN_BYTES (0x0f)
246 #define CIF_DO_CROP 0
247 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
248 #define CROP_ALIGN_BYTES (0x03)
249 #define CIF_DO_CROP 0
250 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
251 #define CROP_ALIGN_BYTES (0x0F)
252 #define CIF_DO_CROP 1
256 * Driver Version Note
258 *v0.0.x : this driver is 2.6.32 kernel driver;
259 *v0.1.x : this driver is 3.0.8 kernel driver;
261 *v0.x.1 : this driver first support rk2918;
262 *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
263 * and V4L2_PIX_FMT_YUV422P;
264 *v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
265 *v0.x.4 : this driver support digital zoom;
266 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
267 *v0.x.6 : this driver improve test framerate method;
268 *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
269 we do crop with cif and do scale with ipp , we will fix this next version.
270 *v0.x.8 : temp version,reinit capture list when setup video buf.
271 *v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version.
272 2. flush workqueue when releas buffer
273 *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
275 2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
276 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
277 4. add menu configs for convineuent to customize sensor series
278 *v0.x.b: specify the version is NOT sure stable.
279 *v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
280 2. irq process is splitted to two step.
281 *v0.x.e: fix bugs of early suspend when display_pd is closed.
282 *v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
283 *v0.x.11: fix struct rk_camera_work may be reentrant
284 *v0.x.13: 1.add scale by arm,rga and pp.
285 2.CIF do the crop when digital zoom.
286 3.fix bug in prob func:request mem twice.
287 4.video_vq may be null when reinit work,fix it
288 5.arm scale algorithm has something wrong(may exceed the bound of width or height) ,fix it.
290 * 1. support rk3066b;
292 * 1. support 8Mega picture;
294 * 1. invalidate the limit which scale is invalidat when scale ratio > 2;
295 *v0.x.1b: 1. fix oops bug when using arm to do scale_crop if preview buffer is not allocated correctly
296 2. rk_camera_set_fmt will called twice, optimize the procedure. at the first time call ,just to do the sensor init.
299 * 1. fix query resolution error;
301 * 1. add mv9335+ov5650 driver;
302 * 2. fix 2928 digitzoom erro(arm crop scale) of selected zone;
304 * 1. support rk3188; Must soft reset cif controller after each frame irq;
306 * 1. fix ctrl register capture bit may be turn on in rk_videobuf_capture function
309 * 1. compatible with generic_sensor;
312 * 1. fix use v4l2_mbus_framefmt.reserved array overflow in generic_sensor_s_fmt;
315 * 1. support rk3028 , read 3028 chip id by efuse for check cif controller is normal or not;
317 * 1. return real sensor output size in rk_camera_enum_frameintervals;
318 * 2. wake up vb after add camera work to list in rk_camera_capture_process;
320 * 1. this verison is support for 3188M, the version has been revert in v0.3.d;
322 * 1. this version is support for rk3028a;
325 * 1. this version is support query fov orientation;
327 * 1. fix vb struct may be used again which have been free after stream off, some code modify in soc_camera.c,
329 * 1. fix cif clk out can't be turn off;
332 * 1. modify cif irq ,remove judge reg_lastpixel==host_width.
336 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x12)
337 static int version = RK_CAM_VERSION_CODE;
338 module_param(version, int, S_IRUGO);
340 /* limit to rk29 hardware capabilities */
341 #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
342 SOCAM_HSYNC_ACTIVE_HIGH |\
343 SOCAM_HSYNC_ACTIVE_LOW |\
344 SOCAM_VSYNC_ACTIVE_HIGH |\
345 SOCAM_VSYNC_ACTIVE_LOW |\
346 SOCAM_PCLK_SAMPLE_RISING |\
347 SOCAM_PCLK_SAMPLE_FALLING|\
348 SOCAM_DATA_ACTIVE_HIGH |\
349 SOCAM_DATA_ACTIVE_LOW|\
350 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
351 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
353 #define RK_CAM_W_MIN 48
354 #define RK_CAM_H_MIN 32
355 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
356 #define RK_CAM_H_MAX 2764
357 #define RK_CAM_FRAME_INVAL_INIT 3
358 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
359 #define RK30_CAM_FRAME_MEASURE 5
362 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
363 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
364 /* buffer for one video frame */
365 struct rk_camera_buffer
367 /* common v4l buffer stuff -- must be first */
368 struct videobuf_buffer vb;
369 enum v4l2_mbus_pixelcode code;
372 enum rk_camera_reg_state
380 unsigned int cifCtrl;
381 unsigned int cifCrop;
383 unsigned int cifIntEn;
385 unsigned int cifVirWidth;
386 unsigned int cifScale;
387 // unsigned int VipCrm;
388 enum rk_camera_reg_state Inval;
390 struct rk_camera_work
392 struct videobuf_buffer *vb;
393 struct rk_camera_dev *pcdev;
394 struct work_struct work;
395 struct list_head queue;
398 struct rk_camera_frmivalenum
400 struct v4l2_frmivalenum fival;
401 struct rk_camera_frmivalenum *nxt;
403 struct rk_camera_frmivalinfo
405 struct soc_camera_device *icd;
406 struct rk_camera_frmivalenum *fival_list;
408 struct rk_camera_zoominfo
410 struct semaphore sem;
416 #if CAMERA_VIDEOBUF_ARM_ACCESS
417 struct rk29_camera_vbinfo
419 unsigned int phy_addr;
420 void __iomem *vir_addr;
424 struct rk_camera_timer{
425 struct rk_camera_dev *pcdev;
426 struct hrtimer timer;
431 //************must modify start************/
433 struct clk *aclk_cif;
434 struct clk *hclk_cif;
435 struct clk *cif_clk_in;
436 struct clk *cif_clk_out;
437 //************must modify end************/
447 struct v4l2_rect bounds;
450 struct rk_cif_irqinfo
453 unsigned long cifirq_idx;
454 unsigned long cifirq_normal_idx;
455 unsigned long cifirq_abnormal_idx;
457 unsigned long dmairq_idx;
463 struct soc_camera_host soc_host;
465 /* RK2827x is only supposed to handle one camera on its Quick Capture
466 * interface. If anyone ever builds hardware to enable more than
467 * one camera, they will have to modify this driver too */
468 struct soc_camera_device *icd;
470 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
473 unsigned int last_fps;
474 unsigned long frame_interval;
477 unsigned int vipmem_phybase;
478 void __iomem *vipmem_virbase;
479 unsigned int vipmem_size;
480 unsigned int vipmem_bsize;
481 #if CAMERA_VIDEOBUF_ARM_ACCESS
482 struct rk29_camera_vbinfo *vbinfo;
483 unsigned int vbinfo_count;
487 int host_left; //sensor output size ?
493 struct rk_cif_crop cropinfo;
494 struct rk_cif_irqinfo irqinfo;
496 struct rk29camera_platform_data *pdata;
497 struct resource *res;
498 struct list_head capture;
499 struct rk_camera_zoominfo zoominfo;
503 struct videobuf_buffer *active;
504 struct rk_camera_reg reginfo_suspend;
505 struct workqueue_struct *camera_wq;
506 struct rk_camera_work *camera_work;
507 struct list_head camera_work_queue;
508 spinlock_t camera_work_lock;
509 unsigned int camera_work_count;
510 struct rk_camera_timer fps_timer;
511 struct rk_camera_work camera_reinit_work;
513 rk29_camera_sensor_cb_s icd_cb;
514 struct rk_camera_frmivalinfo icd_frmival[2];
516 unsigned int reinit_times;
517 struct videobuf_queue *video_vq;
519 struct timeval first_tv;
524 static const struct v4l2_queryctrl rk_camera_controls[] =
527 .id = V4L2_CID_ZOOM_ABSOLUTE,
528 .type = V4L2_CTRL_TYPE_INTEGER,
529 .name = "DigitalZoom Control",
533 .default_value = 100,
537 static struct rk_cif_clk cif_clk[2];
539 static DEFINE_MUTEX(camera_lock);
540 static const char *rk_cam_driver_description = "RK_Camera";
542 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
543 static void rk_camera_capture_process(struct work_struct *work);
544 static int rk_camera_scale_crop_arm(struct work_struct *work);
546 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
548 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg;
549 enum cru_soft_reset cif_reset_index = SOFT_RST_CIF0;
551 if (IS_CIF0() == false) {
553 cif_reset_index = SOFT_RST_CIF1;
555 RKCAMERA_TR("%s: CIF1 is invalidate\n",__FUNCTION__);
560 if (only_rst == true) {
561 cru_set_soft_reset(cif_reset_index, true);
563 cru_set_soft_reset(cif_reset_index, false);
565 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
566 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
567 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
568 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
569 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
570 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
571 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
573 cru_set_soft_reset(cif_reset_index, true);
575 cru_set_soft_reset(cif_reset_index, false);
577 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
578 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
579 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
580 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
581 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
582 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
583 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
590 * Videobuf operations
592 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
595 struct soc_camera_device *icd = vq->priv_data;
596 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
597 struct rk_camera_dev *pcdev = ici->priv;
599 struct rk_camera_work *wk;
601 struct soc_mbus_pixelfmt fmt;
603 int bytes_per_line_host;
604 fmt.packing = SOC_MBUS_PACKING_1_5X8;
606 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
607 icd->current_fmt->host_fmt);
608 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
609 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
611 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
612 bytes_per_line_host = pcdev->host_width*3;
614 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
615 icd->current_fmt->host_fmt);
616 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
618 if (bytes_per_line_host < 0)
619 return bytes_per_line_host;
621 /* planar capture requires Y, U and V buffers to be page aligned */
622 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
623 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
625 if (CAM_WORKQUEUE_IS_EN()) {
627 if (CAM_IPPWORK_IS_EN()) {
628 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
629 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
630 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
634 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
635 kfree(pcdev->camera_work);
636 pcdev->camera_work = NULL;
637 pcdev->camera_work_count = 0;
640 if (pcdev->camera_work == NULL) {
641 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
642 if (pcdev->camera_work == NULL) {
643 RKCAMERA_TR("kmalloc failed\n");
646 INIT_LIST_HEAD(&pcdev->camera_work_queue);
648 for (i=0; i<(*count); i++) {
650 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
653 pcdev->camera_work_count = (*count);
655 #if CAMERA_VIDEOBUF_ARM_ACCESS
656 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
657 kfree(pcdev->vbinfo);
658 pcdev->vbinfo = NULL;
659 pcdev->vbinfo_count = 0x00;
662 if (pcdev->vbinfo == NULL) {
663 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
664 if (pcdev->vbinfo == NULL) {
665 RKCAMERA_TR("vbinfo kmalloc fail\n");
668 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
669 pcdev->vbinfo_count = *count;
673 pcdev->video_vq = vq;
674 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
678 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
680 struct soc_camera_device *icd = vq->priv_data;
682 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
683 &buf->vb, buf->vb.baddr, buf->vb.bsize);
685 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
686 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
692 * This waits until this buffer is out of danger, i.e., until it is no
693 * longer in STATE_QUEUED or STATE_ACTIVE
695 videobuf_waiton(vq, &buf->vb, 0, 0);
696 videobuf_dma_contig_free(vq, &buf->vb);
697 dev_dbg(&icd->dev, "%s freed\n", __func__);
698 buf->vb.state = VIDEOBUF_NEEDS_INIT;
701 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
703 struct soc_camera_device *icd = vq->priv_data;
704 struct rk_camera_buffer *buf;
706 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
707 icd->current_fmt->host_fmt);
708 if ((bytes_per_line < 0) || (vb->boff == 0))
711 buf = container_of(vb, struct rk_camera_buffer, vb);
713 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
714 vb, vb->baddr, vb->bsize);
716 /* Added list head initialization on alloc */
717 WARN_ON(!list_empty(&vb->queue));
719 BUG_ON(NULL == icd->current_fmt);
721 if (buf->code != icd->current_fmt->code ||
722 vb->width != icd->user_width ||
723 vb->height != icd->user_height ||
724 vb->field != field) {
725 buf->code = icd->current_fmt->code;
726 vb->width = icd->user_width;
727 vb->height = icd->user_height;
729 vb->state = VIDEOBUF_NEEDS_INIT;
732 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
733 if (0 != vb->baddr && vb->bsize < vb->size) {
738 if (vb->state == VIDEOBUF_NEEDS_INIT) {
739 ret = videobuf_iolock(vq, vb, NULL);
743 vb->state = VIDEOBUF_PREPARED;
748 rk_videobuf_free(vq, buf);
753 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
755 unsigned int y_addr,uv_addr;
756 struct rk_camera_dev *pcdev = rk_pcdev;
759 if (CAM_WORKQUEUE_IS_EN()) {
760 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
761 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
762 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
763 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
764 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
769 uv_addr = y_addr + vb->width * vb->height;
771 #if defined(CONFIG_ARCH_RK3188)
772 rk_camera_cif_reset(pcdev,false);
774 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
775 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
776 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
777 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
778 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
781 /* Locking: Caller holds q->irqlock */
782 static void rk_videobuf_queue(struct videobuf_queue *vq,
783 struct videobuf_buffer *vb)
785 struct soc_camera_device *icd = vq->priv_data;
786 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
787 struct rk_camera_dev *pcdev = ici->priv;
788 #if CAMERA_VIDEOBUF_ARM_ACCESS
789 struct rk29_camera_vbinfo *vb_info;
792 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
793 vb, vb->baddr, vb->bsize);
795 vb->state = VIDEOBUF_QUEUED;
796 if (list_empty(&pcdev->capture)) {
797 list_add_tail(&vb->queue, &pcdev->capture);
799 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
800 list_add_tail(&vb->queue, &pcdev->capture);
802 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
804 #if CAMERA_VIDEOBUF_ARM_ACCESS
806 vb_info = pcdev->vbinfo+vb->i;
807 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
808 if (vb_info->vir_addr) {
809 iounmap(vb_info->vir_addr);
810 release_mem_region(vb_info->phy_addr, vb_info->size);
811 vb_info->vir_addr = NULL;
812 vb_info->phy_addr = 0x00;
813 vb_info->size = 0x00;
816 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
817 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
820 if (vb_info->vir_addr) {
821 vb_info->size = vb->bsize;
822 vb_info->phy_addr = vb->boff;
824 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
829 if (!pcdev->active) {
831 rk_videobuf_capture(vb,pcdev);
834 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
835 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
839 case V4L2_PIX_FMT_NV16:
840 case V4L2_PIX_FMT_NV61:
842 *ippfmt = IPP_Y_CBCR_H2V1;
845 case V4L2_PIX_FMT_NV12:
846 case V4L2_PIX_FMT_NV21:
848 *ippfmt = IPP_Y_CBCR_H2V2;
852 goto rk_pixfmt2ippfmt_err;
856 rk_pixfmt2ippfmt_err:
860 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
861 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
865 case V4L2_PIX_FMT_YUV420:
866 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.
867 case V4L2_PIX_FMT_YUYV:
869 *ippfmt = RK_FORMAT_YCbCr_420_SP;
872 case V4L2_PIX_FMT_YVU420:
873 case V4L2_PIX_FMT_VYUY:
874 case V4L2_PIX_FMT_YVYU:
876 *ippfmt = RK_FORMAT_YCrCb_420_SP;
879 case V4L2_PIX_FMT_RGB565:
881 *ippfmt = RK_FORMAT_RGB_565;
884 case V4L2_PIX_FMT_RGB24:
886 *ippfmt = RK_FORMAT_RGB_888;
890 goto rk_pixfmt2rgafmt_err;
894 rk_pixfmt2rgafmt_err:
898 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
899 static int rk_camera_scale_crop_pp(struct work_struct *work){
900 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
901 struct videobuf_buffer *vb = camera_work->vb;
902 struct rk_camera_dev *pcdev = camera_work->pcdev;
904 unsigned long int flags;
910 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
912 memset(&init, 0, sizeof(init));
913 init.srcAddr = vipdata_base;
914 init.srcFormat = PP_IN_FORMAT_YUV420SEMI;
915 init.srcWidth = init.srcHStride = pcdev->zoominfo.vir_width;
916 init.srcHeight = init.srcVStride = pcdev->zoominfo.vir_height;
918 init.dstAddr = vb->boff;
919 init.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE;
920 init.dstWidth = init.dstHStride = pcdev->icd->user_width;
921 init.dstHeight = init.dstVStride = pcdev->icd->user_height;
923 printk("srcWidth = %d,srcHeight = %d,dstWidth = %d,dstHeight = %d\n",init.srcWidth,init.srcHeight,init.dstWidth,init.dstHeight);
925 ret = ppOpInit(&hnd, &init);
931 printk("can not create ppOp handle\n");
937 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
938 extern rga_service_info rga_service;
939 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
940 extern void rga_service_session_clear(rga_session *session);
941 static int rk_camera_scale_crop_rga(struct work_struct *work){
942 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
943 struct videobuf_buffer *vb = camera_work->vb;
944 struct rk_camera_dev *pcdev = camera_work->pcdev;
946 unsigned long int flags;
952 const struct soc_mbus_pixelfmt *fmt;
954 fmt = soc_mbus_get_fmtdesc(pcdev->icd->current_fmt->code);
955 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
956 if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
957 && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
958 RKCAMERA_TR("RGA not support this format !\n");
961 if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
962 scale_times = MAX((pcdev->icd->user_width/0x800),(pcdev->icd->user_height/0x800));
967 session.pid = current->pid;
968 INIT_LIST_HEAD(&session.waiting);
969 INIT_LIST_HEAD(&session.running);
970 INIT_LIST_HEAD(&session.list_session);
971 init_waitqueue_head(&session.wait);
972 /* no need to protect */
973 list_add_tail(&session.list_session, &rga_service.session);
974 atomic_set(&session.task_running, 0);
975 atomic_set(&session.num_done, 0);
977 memset(&req,0,sizeof(struct rga_req));
978 req.src.act_w = pcdev->zoominfo.a.c.width/scale_times;
979 req.src.act_h = pcdev->zoominfo.a.c.height/scale_times;
981 req.src.vir_w = pcdev->zoominfo.vir_width;
982 req.src.vir_h =pcdev->zoominfo.vir_height;
983 req.src.yrgb_addr = vipdata_base;
984 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
985 req.src.v_addr = req.src.uv_addr ;
986 req.src.format =fmt->fourcc;
987 rk_pixfmt2rgafmt(fmt->fourcc,&req.src.format);
988 req.src.x_offset = pcdev->zoominfo.a.c.left;
989 req.src.y_offset = pcdev->zoominfo.a.c.top;
991 req.dst.act_w = pcdev->icd->user_width/scale_times;
992 req.dst.act_h = pcdev->icd->user_height/scale_times;
994 req.dst.vir_w = pcdev->icd->user_width;
995 req.dst.vir_h = pcdev->icd->user_height;
996 req.dst.x_offset = 0;
997 req.dst.y_offset = 0;
998 req.dst.yrgb_addr = vb->boff;
999 rk_pixfmt2rgafmt(pcdev->icd->current_fmt->host_fmt->fourcc,&req.dst.format);
1001 req.clip.xmax = req.dst.vir_w-1;
1003 req.clip.ymax = req.dst.vir_h -1;
1005 req.rotate_mode = 1;
1010 req.mmu_info.mmu_en = 0;
1012 for (h=0; h<scale_times; h++) {
1013 for (w=0; w<scale_times; w++) {
1016 req.src.yrgb_addr = vipdata_base;
1017 req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
1018 req.src.x_offset = pcdev->zoominfo.a.c.left+w*pcdev->zoominfo.a.c.width/scale_times;
1019 req.src.y_offset = pcdev->zoominfo.a.c.top+h*pcdev->zoominfo.a.c.height/scale_times;
1020 req.dst.x_offset = pcdev->icd->user_width*w/scale_times;
1021 req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
1022 req.dst.yrgb_addr = vb->boff ;
1023 // 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);
1024 // 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);
1025 // RKCAMERA_TR("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
1027 while(rga_times-- > 0) {
1028 if (rga_blit_sync(&session, &req)){
1029 RKCAMERA_TR("rga do erro,do again,rga_times = %d!\n",rga_times);
1035 if (rga_times <= 0) {
1036 spin_lock_irqsave(&pcdev->lock, flags);
1037 vb->state = VIDEOBUF_NEEDS_INIT;
1038 spin_unlock_irqrestore(&pcdev->lock, flags);
1039 mutex_lock(&rga_service.lock);
1040 list_del(&session.list_session);
1041 rga_service_session_clear(&session);
1042 mutex_unlock(&rga_service.lock);
1048 mutex_lock(&rga_service.lock);
1049 list_del(&session.list_session);
1050 rga_service_session_clear(&session);
1051 mutex_unlock(&rga_service.lock);
1060 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
1062 static int rk_camera_scale_crop_ipp(struct work_struct *work)
1064 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1065 struct videobuf_buffer *vb = camera_work->vb;
1066 struct rk_camera_dev *pcdev = camera_work->pcdev;
1068 unsigned long int flags;
1070 struct rk29_ipp_req ipp_req;
1071 int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
1072 int scale_times,w,h;
1073 int ret = 0, scale_crop_ret=0;
1076 *ddl@rock-chips.com:
1077 * IPP Dest image resolution is 2047x1088, so scale operation break up some times
1079 if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
1080 scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));
1085 memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
1088 ipp_req.timeout = 3000;
1089 ipp_req.flag = IPP_ROT_0;
1090 ipp_req.store_clip_mode =1;
1091 ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
1092 ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
1093 ipp_req.src_vir_w = pcdev->zoominfo.vir_width;
1094 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
1095 ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
1096 ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
1097 ipp_req.dst_vir_w = pcdev->icd->user_width;
1098 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
1099 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
1100 src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height; //vipmem
1101 dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
1102 for (h=0; h<scale_times; h++) {
1103 for (w=0; w<scale_times; w++) {
1104 src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width
1105 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
1106 src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width/2
1107 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
1109 dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
1110 dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
1112 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
1113 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
1114 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
1115 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
1117 if (ipp_blit_sync(&ipp_req)){
1118 RKCAMERA_TR("ipp do erro, so switch to arm \n");
1119 scale_crop_ret = 0x01;
1125 if (scale_crop_ret == 0x01) {
1126 ret = rk_camera_scale_crop_arm(work);
1130 spin_lock_irqsave(&pcdev->lock, flags);
1131 vb->state = VIDEOBUF_NEEDS_INIT;
1132 spin_unlock_irqrestore(&pcdev->lock, flags);
1133 RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP and ARM operated is error:\n",vb->i);
1134 RKCAMERA_TR("widx:%d hidx:%d ",w,h);
1135 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);
1136 RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
1137 RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
1138 RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
1139 RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
1140 RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
1141 RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
1142 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);
1143 RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
1149 static int rk_camera_scale_crop_arm(struct work_struct *work)
1151 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1152 struct videobuf_buffer *vb = camera_work->vb;
1153 struct rk_camera_dev *pcdev = camera_work->pcdev;
1154 struct rk29_camera_vbinfo *vb_info;
1155 unsigned char *psY,*pdY,*psUV,*pdUV;
1156 unsigned char *src,*dst;
1157 unsigned long src_phy,dst_phy;
1158 int srcW,srcH,cropW,cropH,dstW,dstH;
1159 long zoomindstxIntInv,zoomindstyIntInv;
1161 long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
1164 int ret = 0, shift_bits = 0;
1166 src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
1167 src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
1168 psUV = psY + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
1170 srcW = pcdev->zoominfo.vir_width;
1171 srcH = pcdev->zoominfo.vir_height;
1172 cropW = pcdev->zoominfo.a.c.width;
1173 cropH = pcdev->zoominfo.a.c.height;
1175 psY = psY + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width+pcdev->zoominfo.a.c.left;
1176 psUV = psUV + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width/2+pcdev->zoominfo.a.c.left;
1178 vb_info = pcdev->vbinfo+vb->i;
1179 dst_phy = vb_info->phy_addr;
1180 dst = pdY = (unsigned char*)vb_info->vir_addr;
1181 pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
1182 dstW = pcdev->icd->user_width;
1183 dstH = pcdev->icd->user_height;
1185 zoomindstxIntInv = ((unsigned long)(cropW)<<16)/dstW + 1;
1186 zoomindstyIntInv = ((unsigned long)(cropH)<<16)/dstH + 1;
1187 #ifdef CONFIG_SOC_RK3028
1188 shift_bits = (pcdev->chip_id == 0x42)?0:2;
1191 //for(y = 0; y<dstH - 1 ; y++ ) {
1192 for(y = 0; y<dstH; y++ ) {
1193 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1194 yCoeff01 = 0xffff - yCoeff00;
1195 sY = (y*zoomindstyIntInv >> 16);
1196 sY = (sY >= srcH - 1)? (srcH - 2) : sY;
1197 for(x = 0; x<dstW; x++ ) {
1198 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1199 xCoeff01 = 0xffff - xCoeff00;
1200 sX = (x*zoomindstxIntInv >> 16);
1201 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1202 a = (psY[sY*srcW + sX]<<shift_bits);
1203 b = (psY[sY*srcW + sX + 1]<<shift_bits);
1204 c = (psY[(sY+1)*srcW + sX]<<shift_bits);
1205 d = (psY[(sY+1)*srcW + sX + 1]<<shift_bits);
1207 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1208 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1209 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1222 //for(y = 0; y<dstH - 1 ; y++ ) {
1223 for(y = 0; y<dstH; y++ ) {
1224 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1225 yCoeff01 = 0xffff - yCoeff00;
1226 sY = (y*zoomindstyIntInv >> 16);
1227 sY = (sY >= srcH -1)? (srcH - 2) : sY;
1228 for(x = 0; x<dstW; x++ ) {
1229 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1230 xCoeff01 = 0xffff - xCoeff00;
1231 sX = (x*zoomindstxIntInv >> 16);
1232 sX = (sX >= srcW -1)?(srcW- 2) : sX;
1234 a = (psUV[(sY*srcW + sX)*2]<<shift_bits);
1235 b = (psUV[(sY*srcW + sX + 1)*2]<<shift_bits);
1236 c = (psUV[((sY+1)*srcW + sX)*2]<<shift_bits);
1237 d = (psUV[((sY+1)*srcW + sX + 1)*2]<<shift_bits);
1240 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1241 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1242 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1247 a = (psUV[(sY*srcW + sX)*2 + 1]<<shift_bits);
1248 b = (psUV[(sY*srcW + sX + 1)*2 + 1]<<shift_bits);
1249 c = (psUV[((sY+1)*srcW + sX)*2 + 1]<<shift_bits);
1250 d = (psUV[((sY+1)*srcW + sX + 1)*2 + 1]<<shift_bits);
1252 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1253 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1254 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1261 dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
1262 outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
1264 dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
1265 outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
1269 static void rk_camera_capture_process(struct work_struct *work)
1271 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1272 struct videobuf_buffer *vb = camera_work->vb;
1273 struct rk_camera_dev *pcdev = camera_work->pcdev;
1274 //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;
1275 unsigned long flags = 0;
1278 if (atomic_read(&pcdev->stop_cif)==true) {
1280 goto rk_camera_capture_process_end;
1283 if (!CAM_WORKQUEUE_IS_EN()) {
1285 goto rk_camera_capture_process_end;
1288 down(&pcdev->zoominfo.sem);
1289 if (pcdev->icd_cb.scale_crop_cb){
1290 err = (pcdev->icd_cb.scale_crop_cb)(work);
1292 up(&pcdev->zoominfo.sem);
1294 if (pcdev->icd_cb.sensor_cb)
1295 (pcdev->icd_cb.sensor_cb)(vb);
1297 rk_camera_capture_process_end:
1299 vb->state = VIDEOBUF_ERROR;
1301 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1302 vb->state = VIDEOBUF_DONE;
1306 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1307 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1308 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1309 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
1313 static void rk_camera_cifrest_delay(struct work_struct *work)
1315 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1316 struct rk_camera_dev *pcdev = camera_work->pcdev;
1317 unsigned long flags = 0;
1320 rk_camera_cif_reset(pcdev,false);
1322 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1323 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1324 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1326 spin_lock_irqsave(&pcdev->lock,flags);
1327 if (atomic_read(&pcdev->stop_cif) == false) {
1328 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
1329 RKCAMERA_DG2("After reset cif, enable capture again!\n");
1331 spin_unlock_irqrestore(&pcdev->lock,flags);
1335 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
1337 struct rk_camera_dev *pcdev = data;
1338 struct rk_camera_work *wk;
1339 unsigned int reg_cifctrl,reg_lastpix,reg_lastline;
1341 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1343 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1344 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
1345 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
1347 pcdev->irqinfo.cifirq_idx++;
1348 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1349 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1350 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1351 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1353 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1356 if(reg_cifctrl & ENABLE_CAPTURE) {
1357 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1360 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1361 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1362 if (!list_empty(&pcdev->camera_work_queue)) {
1363 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1364 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1365 list_del_init(&wk->queue);
1366 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1368 queue_work(pcdev->camera_wq, &(wk->work));
1376 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1378 struct rk_camera_dev *pcdev = data;
1379 struct videobuf_buffer *vb;
1380 struct rk_camera_work *wk;
1382 unsigned long reg_cifctrl;
1384 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1385 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1386 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
1387 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1389 pcdev->irqinfo.dmairq_idx++;
1390 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1391 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1396 do_gettimeofday(&pcdev->first_tv);
1401 if (pcdev->frame_inval>0) {
1402 pcdev->frame_inval--;
1403 rk_videobuf_capture(pcdev->active,pcdev);
1405 } else if (pcdev->frame_inval) {
1406 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1407 pcdev->frame_inval = 0;
1410 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1411 do_gettimeofday(&tv);
1412 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1413 /(RK30_CAM_FRAME_MEASURE-1);
1418 printk("no acticve buffer!!!\n");
1422 /* ddl@rock-chips.com : this vb may be deleted from queue */
1423 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1424 list_del_init(&vb->queue);
1426 pcdev->active = NULL;
1427 if (!list_empty(&pcdev->capture)) {
1428 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1429 if (pcdev->active) {
1430 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1431 rk_videobuf_capture(pcdev->active,pcdev);
1434 if (pcdev->active == NULL) {
1435 RKCAMERA_DG1("video_buf queue is empty!\n");
1438 do_gettimeofday(&vb->ts);
1439 if (CAM_WORKQUEUE_IS_EN()) {
1440 if (!list_empty(&pcdev->camera_work_queue)) {
1441 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1442 list_del_init(&wk->queue);
1443 INIT_WORK(&(wk->work), rk_camera_capture_process);
1446 queue_work(pcdev->camera_wq, &(wk->work));
1449 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1450 vb->state = VIDEOBUF_DONE;
1458 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1459 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1463 static irqreturn_t rk_camera_irq(int irq, void *data)
1465 struct rk_camera_dev *pcdev = data;
1466 unsigned long reg_intstat;
1468 spin_lock(&pcdev->lock);
1470 if(atomic_read(&pcdev->stop_cif) == true) {
1471 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
1475 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1477 if (reg_intstat & 0x0200)
1478 rk_camera_cifirq(irq,data);
1480 if (reg_intstat & 0x01)
1481 rk_camera_dmairq(irq,data);
1484 spin_unlock(&pcdev->lock);
1489 static void rk_videobuf_release(struct videobuf_queue *vq,
1490 struct videobuf_buffer *vb)
1492 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1493 struct soc_camera_device *icd = vq->priv_data;
1494 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1495 struct rk_camera_dev *pcdev = ici->priv;
1496 #if CAMERA_VIDEOBUF_ARM_ACCESS
1497 struct rk29_camera_vbinfo *vb_info =NULL;
1501 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1502 vb, vb->baddr, vb->bsize);
1506 case VIDEOBUF_ACTIVE:
1507 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1509 case VIDEOBUF_QUEUED:
1510 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1512 case VIDEOBUF_PREPARED:
1513 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1516 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1521 flush_workqueue(pcdev->camera_wq);
1523 rk_videobuf_free(vq, buf);
1525 #if CAMERA_VIDEOBUF_ARM_ACCESS
1526 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1527 vb_info = pcdev->vbinfo + vb->i;
1529 if (vb_info->vir_addr) {
1530 iounmap(vb_info->vir_addr);
1531 release_mem_region(vb_info->phy_addr, vb_info->size);
1532 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1539 static struct videobuf_queue_ops rk_videobuf_ops =
1541 .buf_setup = rk_videobuf_setup,
1542 .buf_prepare = rk_videobuf_prepare,
1543 .buf_queue = rk_videobuf_queue,
1544 .buf_release = rk_videobuf_release,
1547 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1548 struct soc_camera_device *icd)
1550 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1551 struct rk_camera_dev *pcdev = ici->priv;
1553 /* We must pass NULL as dev pointer, then all pci_* dma operations
1554 * transform to normal dma_* ones. */
1555 videobuf_queue_dma_contig_init(q,
1557 ici->v4l2_dev.dev, &pcdev->lock,
1558 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1560 sizeof(struct rk_camera_buffer),
1561 icd,&icd->video_lock);
1564 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1567 struct rk_cif_clk *clk;
1568 struct clk *cif_clk_out_div;
1570 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1571 if ((cif<0)||(cif>1)) {
1572 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1574 goto rk_camera_clk_ctrl_end;
1577 clk = &cif_clk[cif];
1579 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1580 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1582 goto rk_camera_clk_ctrl_end;
1585 spin_lock(&clk->lock);
1586 if (on && !clk->on) {
1587 clk_enable(clk->pd_cif);
1588 clk_enable(clk->aclk_cif);
1589 clk_enable(clk->hclk_cif);
1590 clk_enable(clk->cif_clk_in);
1591 clk_enable(clk->cif_clk_out);
1592 clk_set_rate(clk->cif_clk_out,clk_rate);
1594 } else if (!on && clk->on) {
1595 clk_disable(clk->aclk_cif);
1596 clk_disable(clk->hclk_cif);
1597 clk_disable(clk->cif_clk_in);
1598 clk_disable(clk->cif_clk_out);
1599 clk_disable(clk->pd_cif);
1602 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
1604 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
1605 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
1606 cif_clk_out_div = clk_get(NULL, "cif_out_div");
1610 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
1611 err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
1612 clk_put(cif_clk_out_div);
1618 RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__);
1620 spin_unlock(&clk->lock);
1621 rk_camera_clk_ctrl_end:
1624 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1627 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1629 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1630 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1634 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1637 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1643 /* The following two functions absolutely depend on the fact, that
1644 * there can be only one camera on RK28 quick capture interface */
1645 static int rk_camera_add_device(struct soc_camera_device *icd)
1647 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1648 struct rk_camera_dev *pcdev = ici->priv;
1649 struct device *control = to_soc_camera_control(icd);
1650 struct v4l2_subdev *sd;
1651 int ret,i,icd_catch;
1652 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1653 struct v4l2_cropcap cropcap;
1654 struct v4l2_mbus_framefmt mf;
1655 const struct soc_camera_format_xlate *xlate = NULL;
1657 mutex_lock(&camera_lock);
1664 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1666 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1667 pcdev->active = NULL;
1669 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1670 pcdev->zoominfo.zoom_rate = 100;
1671 pcdev->fps_timer.istarted = false;
1673 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1674 * if app havn't dequeue all videobuf before close camera device;
1676 INIT_LIST_HEAD(&pcdev->capture);
1678 ret = rk_camera_activate(pcdev,icd);
1681 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1683 sd = dev_get_drvdata(control);
1684 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1686 ret = v4l2_subdev_call(sd,core, init, 0);
1690 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1692 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1693 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1695 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1698 mf.field = V4L2_FIELD_NONE;
1699 mf.code = xlate->code;
1700 mf.reserved[6] = 0xfefe5a5a;
1701 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1703 pcdev->cropinfo.bounds.left = 0;
1704 pcdev->cropinfo.bounds.top = 0;
1705 pcdev->cropinfo.bounds.width = mf.width;
1706 pcdev->cropinfo.bounds.height = mf.height;
1710 pcdev->icd_init = 0;
1713 for (i=0; i<2; i++) {
1714 if (pcdev->icd_frmival[i].icd == icd)
1716 if (pcdev->icd_frmival[i].icd == NULL) {
1717 pcdev->icd_frmival[i].icd = icd;
1721 if (icd_catch == 0) {
1722 fival_list = pcdev->icd_frmival[0].fival_list;
1723 fival_nxt = fival_list;
1724 while(fival_nxt != NULL) {
1725 fival_nxt = fival_list->nxt;
1727 fival_list = fival_nxt;
1729 pcdev->icd_frmival[0].icd = icd;
1730 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1733 mutex_unlock(&camera_lock);
1737 static void rk_camera_remove_device(struct soc_camera_device *icd)
1739 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1740 struct rk_camera_dev *pcdev = ici->priv;
1741 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1742 #if CAMERA_VIDEOBUF_ARM_ACCESS
1743 struct rk29_camera_vbinfo *vb_info;
1747 mutex_lock(&camera_lock);
1748 BUG_ON(icd != pcdev->icd);
1750 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1752 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1753 stream may be turn on again before close device, if suspend and resume happened. */
1754 if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
1755 rk_camera_s_stream(icd,0);
1758 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
1759 //if stream off is not been executed,timer is running.
1760 if(pcdev->fps_timer.istarted){
1761 hrtimer_cancel(&pcdev->fps_timer.timer);
1762 pcdev->fps_timer.istarted = false;
1764 flush_work(&(pcdev->camera_reinit_work.work));
1765 flush_workqueue((pcdev->camera_wq));
1767 if (pcdev->camera_work) {
1768 kfree(pcdev->camera_work);
1769 pcdev->camera_work = NULL;
1770 pcdev->camera_work_count = 0;
1771 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1773 rk_camera_deactivate(pcdev);
1774 #if CAMERA_VIDEOBUF_ARM_ACCESS
1775 if (pcdev->vbinfo) {
1776 vb_info = pcdev->vbinfo;
1777 for (i=0; i<pcdev->vbinfo_count; i++) {
1778 if (vb_info->vir_addr) {
1779 iounmap(vb_info->vir_addr);
1780 release_mem_region(vb_info->phy_addr, vb_info->size);
1781 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1785 kfree(pcdev->vbinfo);
1786 pcdev->vbinfo = NULL;
1787 pcdev->vbinfo_count = 0;
1790 pcdev->active = NULL;
1792 pcdev->icd_cb.sensor_cb = NULL;
1793 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1794 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1795 * if app havn't dequeue all videobuf before close camera device;
1797 INIT_LIST_HEAD(&pcdev->capture);
1799 mutex_unlock(&camera_lock);
1803 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1805 unsigned long bus_flags, camera_flags, common_flags;
1806 unsigned int cif_for = 0;
1807 const struct soc_mbus_pixelfmt *fmt;
1809 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1810 struct rk_camera_dev *pcdev = ici->priv;
1813 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1817 bus_flags = RK_CAM_BUS_PARAM;
1818 /* If requested data width is supported by the platform, use it */
1819 switch (fmt->bits_per_sample) {
1821 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1825 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1829 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1836 if (icd->ops->query_bus_param)
1837 camera_flags = icd->ops->query_bus_param(icd);
1841 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1842 if (!common_flags) {
1844 goto RK_CAMERA_SET_BUS_PARAM_END;
1847 ret = icd->ops->set_bus_param(icd, common_flags);
1849 goto RK_CAMERA_SET_BUS_PARAM_END;
1851 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1853 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1855 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1857 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1861 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1863 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1866 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
1867 cif_for |= HSY_LOW_ACTIVE;
1869 cif_for &= ~HSY_LOW_ACTIVE;
1871 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1872 cif_for |= VSY_HIGH_ACTIVE;
1874 cif_for &= ~VSY_HIGH_ACTIVE;
1877 /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1878 //vip_ctrl_val |= ENABLE_CAPTURE;
1879 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1880 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1882 RK_CAMERA_SET_BUS_PARAM_END:
1884 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1888 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1890 unsigned long bus_flags, camera_flags;
1893 bus_flags = RK_CAM_BUS_PARAM;
1894 if (icd->ops->query_bus_param) {
1895 camera_flags = icd->ops->query_bus_param(icd);
1899 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1902 dev_warn(icd->dev.parent,
1903 "Flags incompatible: camera %lx, host %lx\n",
1904 camera_flags, bus_flags);
1908 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1910 .fourcc = V4L2_PIX_FMT_NV12,
1911 .name = "YUV420 NV12",
1912 .bits_per_sample = 8,
1913 .packing = SOC_MBUS_PACKING_1_5X8,
1914 .order = SOC_MBUS_ORDER_LE,
1916 .fourcc = V4L2_PIX_FMT_NV16,
1917 .name = "YUV422 NV16",
1918 .bits_per_sample = 8,
1919 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1920 .order = SOC_MBUS_ORDER_LE,
1922 .fourcc = V4L2_PIX_FMT_NV21,
1923 .name = "YUV420 NV21",
1924 .bits_per_sample = 8,
1925 .packing = SOC_MBUS_PACKING_1_5X8,
1926 .order = SOC_MBUS_ORDER_LE,
1928 .fourcc = V4L2_PIX_FMT_NV61,
1929 .name = "YUV422 NV61",
1930 .bits_per_sample = 8,
1931 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1932 .order = SOC_MBUS_ORDER_LE,
1934 .fourcc = V4L2_PIX_FMT_RGB565,
1936 .bits_per_sample = 8,
1937 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1938 .order = SOC_MBUS_ORDER_LE,
1940 .fourcc = V4L2_PIX_FMT_RGB24,
1942 .bits_per_sample = 8,
1943 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1944 .order = SOC_MBUS_ORDER_LE,
1948 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1950 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1951 struct rk_camera_dev *pcdev = ici->priv;
1952 unsigned int cif_fs = 0,cif_crop = 0;
1953 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;
1955 const struct soc_mbus_pixelfmt *fmt;
1956 fmt = soc_mbus_get_fmtdesc(icd_code);
1958 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1959 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1960 host_pixfmt = V4L2_PIX_FMT_NV12;
1961 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1962 host_pixfmt = V4L2_PIX_FMT_NV21;
1964 switch (host_pixfmt)
1966 case V4L2_PIX_FMT_NV16:
1967 cif_fmt_val &= ~YUV_OUTPUT_422;
1968 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1969 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1970 pcdev->pixfmt = host_pixfmt;
1972 case V4L2_PIX_FMT_NV61:
1973 cif_fmt_val &= ~YUV_OUTPUT_422;
1974 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1975 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1976 pcdev->pixfmt = host_pixfmt;
1978 case V4L2_PIX_FMT_NV12:
1979 cif_fmt_val |= YUV_OUTPUT_420;
1980 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1981 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1982 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1983 pcdev->pixfmt = host_pixfmt;
1985 case V4L2_PIX_FMT_NV21:
1986 cif_fmt_val |= YUV_OUTPUT_420;
1987 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1988 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1989 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1990 pcdev->pixfmt = host_pixfmt;
1992 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1993 cif_fmt_val |= YUV_OUTPUT_422;
1998 case V4L2_MBUS_FMT_UYVY8_2X8:
1999 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
2001 case V4L2_MBUS_FMT_YUYV8_2X8:
2002 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
2004 case V4L2_MBUS_FMT_YVYU8_2X8:
2005 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
2007 case V4L2_MBUS_FMT_VYUY8_2X8:
2008 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
2011 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
2016 rk_camera_cif_reset(pcdev,true);
2018 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
2019 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable
2021 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 */
2023 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
2024 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
2025 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
2027 } else{ // this is one frame mode
2028 cif_crop = (rect->left+ (rect->top<<16));
2029 cif_fs = ((rect->width ) + (rect->height<<16));
2032 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
2033 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
2034 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
2035 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
2038 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
2039 RKCAMERA_DG1("CIF_CIF_CROP:0x%x CIF_CIF_FS:0x%x CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val);
2043 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
2044 struct soc_camera_format_xlate *xlate)
2046 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2047 struct device *dev = icd->dev.parent;
2048 int formats = 0, ret;
2049 enum v4l2_mbus_pixelcode code;
2050 const struct soc_mbus_pixelfmt *fmt;
2052 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
2054 /* No more formats */
2057 fmt = soc_mbus_get_fmtdesc(code);
2059 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
2063 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
2068 case V4L2_MBUS_FMT_UYVY8_2X8:
2069 case V4L2_MBUS_FMT_YUYV8_2X8:
2070 case V4L2_MBUS_FMT_YVYU8_2X8:
2071 case V4L2_MBUS_FMT_VYUY8_2X8:
2074 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
2077 xlate->host_fmt = &rk_camera_formats[0];
2080 dev_dbg(dev, "Providing format %s using code %d\n",
2081 rk_camera_formats[0].name,code);
2086 xlate->host_fmt = &rk_camera_formats[1];
2089 dev_dbg(dev, "Providing format %s using code %d\n",
2090 rk_camera_formats[1].name,code);
2095 xlate->host_fmt = &rk_camera_formats[2];
2098 dev_dbg(dev, "Providing format %s using code %d\n",
2099 rk_camera_formats[2].name,code);
2104 xlate->host_fmt = &rk_camera_formats[3];
2107 dev_dbg(dev, "Providing format %s using code %d\n",
2108 rk_camera_formats[3].name,code);
2114 xlate->host_fmt = &rk_camera_formats[4];
2117 dev_dbg(dev, "Providing format %s using code %d\n",
2118 rk_camera_formats[4].name,code);
2122 xlate->host_fmt = &rk_camera_formats[5];
2125 dev_dbg(dev, "Providing format %s using code %d\n",
2126 rk_camera_formats[5].name,code);
2138 static void rk_camera_put_formats(struct soc_camera_device *icd)
2142 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
2144 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2147 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
2150 /* ddl@rock-chips.com: driver decide the cropping rectangle */
2151 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
2155 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
2157 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
2158 struct rk_camera_dev *pcdev = ici->priv;
2160 spin_lock(&pcdev->cropinfo.lock);
2161 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
2162 spin_unlock(&pcdev->cropinfo.lock);
2166 static int rk_camera_set_crop(struct soc_camera_device *icd,
2167 struct v4l2_crop *crop)
2169 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
2170 struct rk_camera_dev *pcdev = ici->priv;
2172 spin_lock(&pcdev->cropinfo.lock);
2173 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
2174 spin_unlock(&pcdev->cropinfo.lock);
2177 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
2181 if (f->fmt.pix.priv == 0xfefe5a5a) {
2185 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
2187 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
2189 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
2191 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
2193 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
2195 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
2200 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
2203 static int rk_camera_set_fmt(struct soc_camera_device *icd,
2204 struct v4l2_format *f)
2206 struct device *dev = icd->dev.parent;
2207 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2208 const struct soc_camera_format_xlate *xlate = NULL;
2209 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
2210 struct rk_camera_dev *pcdev = ici->priv;
2211 struct v4l2_pix_format *pix = &f->fmt.pix;
2212 struct v4l2_mbus_framefmt mf;
2213 struct v4l2_rect rect;
2214 int ret,usr_w,usr_h,sensor_w,sensor_h;
2216 int ratio, bounds_aspect;
2219 usr_h = pix->height;
2221 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
2222 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
2224 dev_err(dev, "Format %x not found\n", pix->pixelformat);
2226 goto RK_CAMERA_SET_FMT_END;
2229 /* ddl@rock-chips.com: sensor init code transmit in here after open */
2230 if (pcdev->icd_init == 0) {
2231 v4l2_subdev_call(sd,core, init, 0);
2232 pcdev->icd_init = 1;
2235 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2236 if (stream_on & ENABLE_CAPTURE)
2237 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
2239 mf.width = pix->width;
2240 mf.height = pix->height;
2241 mf.field = pix->field;
2242 mf.colorspace = pix->colorspace;
2243 mf.code = xlate->code;
2244 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
2247 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2248 if (mf.code != xlate->code)
2251 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
2252 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
2253 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
2254 if ((mf.width*10/mf.height) != bounds_aspect) {
2255 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
2256 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
2258 mf.width = pcdev->cropinfo.bounds.width/4;
2259 mf.height = pcdev->cropinfo.bounds.height/4;
2261 mf.field = pix->field;
2262 mf.colorspace = pix->colorspace;
2263 mf.code = xlate->code;
2264 mf.reserved[0] = pix->priv;
2267 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2268 if (mf.code != xlate->code)
2273 sensor_w = mf.width;
2274 sensor_h = mf.height;
2276 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); // 4 align
2279 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); // 2 align
2282 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2284 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2285 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2287 goto RK_CAMERA_SET_FMT_END;
2289 if (unlikely((usr_w <16)||(usr_h < 16))) {
2290 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2292 goto RK_CAMERA_SET_FMT_END;
2295 spin_lock(&pcdev->cropinfo.lock);
2296 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2297 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2298 //Scale + Crop center is for keep aspect ratio unchange
2299 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2300 pcdev->host_width = ratio*usr_w/10;
2301 pcdev->host_height = ratio*usr_h/10;
2302 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2303 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2305 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2306 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2308 //Scale + crop(user define)
2309 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2310 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2311 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2312 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2315 pcdev->host_left &= (~0x01);
2316 pcdev->host_top &= (~0x01);
2318 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2319 //Crop Center for cif can work , then scale
2320 pcdev->host_width = mf.width;
2321 pcdev->host_height = mf.height;
2322 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2323 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2325 //Crop center for cif can work + crop(user define), then scale
2326 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2327 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2328 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2329 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2332 pcdev->host_left &= (~0x01);
2333 pcdev->host_top &= (~0x01);
2335 spin_unlock(&pcdev->cropinfo.lock);
2337 spin_lock(&pcdev->cropinfo.lock);
2338 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2339 pcdev->host_width = mf.width;
2340 pcdev->host_height = mf.height;
2341 pcdev->host_left = 0;
2342 pcdev->host_top = 0;
2344 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2345 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2346 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2347 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2349 spin_unlock(&pcdev->cropinfo.lock);
2354 rect.width = pcdev->host_width;
2355 rect.height = pcdev->host_height;
2356 rect.left = pcdev->host_left;
2357 rect.top = pcdev->host_top;
2359 down(&pcdev->zoominfo.sem);
2360 #if CIF_DO_CROP // this crop is only for digital zoom
2361 pcdev->zoominfo.a.c.left = 0;
2362 pcdev->zoominfo.a.c.top = 0;
2363 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2364 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2365 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2366 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2367 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2368 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2369 //recalculate the CIF width & height
2370 rect.width = pcdev->zoominfo.a.c.width ;
2371 rect.height = pcdev->zoominfo.a.c.height;
2372 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2373 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2375 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2376 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2377 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2378 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2379 //now digital zoom use ipp to do crop and scale
2380 if(pcdev->zoominfo.zoom_rate != 100){
2381 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2382 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2384 pcdev->zoominfo.a.c.left = 0;
2385 pcdev->zoominfo.a.c.top = 0;
2387 pcdev->zoominfo.vir_width = pcdev->host_width;
2388 pcdev->zoominfo.vir_height = pcdev->host_height;
2390 up(&pcdev->zoominfo.sem);
2392 /* ddl@rock-chips.com: IPP work limit check */
2393 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2394 if (usr_w > 0x7f0) {
2395 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2396 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));
2398 goto RK_CAMERA_SET_FMT_END;
2401 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2402 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2404 goto RK_CAMERA_SET_FMT_END;
2409 RKCAMERA_DG1("%s CIF Host:%dx%d@(%d,%d) Sensor:%dx%d->%dx%d User crop:(%d,%d,%d,%d)in(%d,%d) (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name,
2410 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2411 sensor_w,sensor_h,mf.width,mf.height,
2412 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2413 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2414 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2415 pix->width, pix->height);
2417 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2419 if (CAM_IPPWORK_IS_EN()) {
2420 BUG_ON(pcdev->vipmem_phybase == 0);
2423 pix->height = usr_h;
2424 pix->field = mf.field;
2425 pix->colorspace = mf.colorspace;
2426 icd->current_fmt = xlate;
2427 pcdev->icd_width = mf.width;
2428 pcdev->icd_height = mf.height;
2431 RK_CAMERA_SET_FMT_END:
2432 if (stream_on & ENABLE_CAPTURE)
2433 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2435 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2439 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2440 struct v4l2_format *f)
2442 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2443 struct rk_camera_dev *pcdev = ici->priv;
2444 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2445 const struct soc_camera_format_xlate *xlate;
2446 struct v4l2_pix_format *pix = &f->fmt.pix;
2447 __u32 pixfmt = pix->pixelformat;
2448 int ret,usr_w,usr_h,i;
2449 bool is_capture = rk_camera_fmt_capturechk(f);
2450 bool vipmem_is_overflow = false;
2451 struct v4l2_mbus_framefmt mf;
2452 int bytes_per_line_host;
2455 usr_h = pix->height;
2457 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2459 dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2460 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2462 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2463 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2464 for (i = 0; i < icd->num_user_formats; i++)
2465 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2466 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2467 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2468 icd->user_formats[i].host_fmt->name);
2469 goto RK_CAMERA_TRY_FMT_END;
2471 /* limit to rk29 hardware capabilities */
2472 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2473 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2474 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2476 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2478 if (pix->bytesperline < 0)
2479 return pix->bytesperline;
2481 /* limit to sensor capabilities */
2482 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2483 mf.width = pix->width;
2484 mf.height = pix->height;
2485 mf.field = pix->field;
2486 mf.colorspace = pix->colorspace;
2487 mf.code = xlate->code;
2488 /* ddl@rock-chips.com : It is query max resolution only. */
2489 if ((usr_w == 10000) && (usr_h == 10000)) {
2490 mf.reserved[6] = 0xfefe5a5a;
2493 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2495 goto RK_CAMERA_TRY_FMT_END;
2498 if((usr_w == 10000) && (usr_h == 10000)) {
2499 pix->width = mf.width;
2500 pix->height = mf.height;
2501 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2502 goto RK_CAMERA_TRY_FMT_END;
2504 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2507 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2508 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2510 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2512 /* Assume preview buffer minimum is 4 */
2513 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2515 if (vipmem_is_overflow == false) {
2517 pix->height = usr_h;
2519 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
2520 pix->width = mf.width;
2521 pix->height = mf.height;
2523 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2525 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2526 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2527 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2528 pix->width = mf.width;
2529 pix->height = mf.height;
2535 pix->colorspace = mf.colorspace;
2538 case V4L2_FIELD_ANY:
2539 case V4L2_FIELD_NONE:
2540 pix->field = V4L2_FIELD_NONE;
2543 /* TODO: support interlaced at least in pass-through mode */
2544 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
2546 goto RK_CAMERA_TRY_FMT_END;
2549 RK_CAMERA_TRY_FMT_END:
2551 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2555 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2556 struct v4l2_requestbuffers *p)
2560 /* This is for locking debugging only. I removed spinlocks and now I
2561 * check whether .prepare is ever called on a linked buffer, or whether
2562 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2563 * it hadn't triggered */
2564 for (i = 0; i < p->count; i++) {
2565 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2566 struct rk_camera_buffer, vb);
2568 INIT_LIST_HEAD(&buf->vb.queue);
2574 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2576 struct soc_camera_device *icd = file->private_data;
2577 struct rk_camera_buffer *buf;
2579 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2582 poll_wait(file, &buf->vb.done, pt);
2584 if (buf->vb.state == VIDEOBUF_DONE ||
2585 buf->vb.state == VIDEOBUF_ERROR)
2586 return POLLIN|POLLRDNORM;
2591 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2592 * 10 5 1 3 3 3 + 5 < 32
2594 static int rk_camera_querycap(struct soc_camera_host *ici,
2595 struct v4l2_capability *cap)
2597 struct rk_camera_dev *pcdev = ici->priv;
2598 struct rkcamera_platform_data *new_camera;
2599 char orientation[5];
2603 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2604 memset(orientation,0x00,sizeof(orientation));
2605 for (i=0; i<RK_CAM_NUM;i++) {
2606 if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
2607 sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
2608 sprintf(fov,"_50_50");
2613 new_camera = pcdev->pdata->register_dev_new;
2614 while (strstr(new_camera->dev_name,"end")==NULL) {
2615 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2616 sprintf(orientation,"-%d",new_camera->orientation);
2617 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2622 if (orientation[0] != '-') {
2623 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2624 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2625 strcat(cap->card,"-270");
2627 strcat(cap->card,"-90");
2629 strcat(cap->card,orientation);
2632 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2633 cap->version = RK_CAM_VERSION_CODE;
2634 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2638 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2640 struct soc_camera_host *ici =
2641 to_soc_camera_host(icd->dev.parent);
2642 struct rk_camera_dev *pcdev = ici->priv;
2643 struct v4l2_subdev *sd;
2646 mutex_lock(&camera_lock);
2647 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2648 rk_camera_s_stream(icd, 0);
2649 sd = soc_camera_to_subdev(icd);
2650 v4l2_subdev_call(sd, video, s_stream, 0);
2651 ret = icd->ops->suspend(icd, state);
2653 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2654 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2655 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2656 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2657 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2658 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2659 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2661 pcdev->reginfo_suspend.Inval = Reg_Validate;
2662 rk_camera_deactivate(pcdev);
2664 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2666 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2668 mutex_unlock(&camera_lock);
2672 static int rk_camera_resume(struct soc_camera_device *icd)
2674 struct soc_camera_host *ici =
2675 to_soc_camera_host(icd->dev.parent);
2676 struct rk_camera_dev *pcdev = ici->priv;
2677 struct v4l2_subdev *sd;
2680 mutex_lock(&camera_lock);
2681 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2682 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2683 rk_camera_activate(pcdev, icd);
2684 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2685 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2686 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2687 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2688 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2689 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2690 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2691 rk_videobuf_capture(pcdev->active,pcdev);
2692 rk_camera_s_stream(icd, 1);
2693 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2695 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2696 goto rk_camera_resume_end;
2699 ret = icd->ops->resume(icd);
2700 sd = soc_camera_to_subdev(icd);
2701 v4l2_subdev_call(sd, video, s_stream, 1);
2703 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2705 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2708 rk_camera_resume_end:
2709 mutex_unlock(&camera_lock);
2713 static void rk_camera_reinit_work(struct work_struct *work)
2715 struct v4l2_subdev *sd;
2716 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2717 struct rk_camera_dev *pcdev = camera_work->pcdev;
2718 struct soc_camera_link *tmp_soc_cam_link;
2720 unsigned long flags = 0;
2721 if(pcdev->icd == NULL)
2723 sd = soc_camera_to_subdev(pcdev->icd);
2724 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2727 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2728 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2729 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2730 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2731 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2732 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2733 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2734 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2735 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2737 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2738 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2739 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2740 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2741 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2742 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2745 atomic_set(&pcdev->stop_cif,true);
2746 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2747 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2749 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2750 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2751 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2752 if (NULL == pcdev->video_vq->bufs[index])
2755 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2756 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2757 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2758 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2759 printk("wake up video buffer index = %d !!!\n",index);
2762 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2764 RKCAMERA_TR("video queue has somthing wrong !!\n");
2767 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2769 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2771 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2772 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2773 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2775 // static unsigned int last_fps = 0;
2776 struct soc_camera_link *tmp_soc_cam_link;
2777 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2779 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2780 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2781 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);
2782 pcdev->camera_reinit_work.pcdev = pcdev;
2783 //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2784 pcdev->reinit_times++;
2785 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2786 } else if(!pcdev->timer_get_fps) {
2787 pcdev->timer_get_fps = true;
2788 for (i=0; i<2; i++) {
2789 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2790 fival_nxt = pcdev->icd_frmival[i].fival_list;
2795 fival_pre = fival_nxt;
2796 while (fival_nxt != NULL) {
2798 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
2799 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2800 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2801 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2802 fival_nxt->fival.discrete.numerator);
2804 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2805 && (fival_nxt->fival.height == pcdev->icd->user_height)
2806 && (fival_nxt->fival.width == pcdev->icd->user_width))
2807 || (fival_nxt->fival.discrete.denominator == 0)) {
2809 if (fival_nxt->fival.discrete.denominator == 0) {
2810 fival_nxt->fival.index = 0;
2811 fival_nxt->fival.width = pcdev->icd->user_width;
2812 fival_nxt->fival.height= pcdev->icd->user_height;
2813 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2814 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2815 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2816 |(pcdev->icd_height);
2817 fival_nxt->fival.discrete.numerator = 1000000;
2818 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2821 fival_rec = fival_nxt;
2823 fival_pre = fival_nxt;
2824 fival_nxt = fival_nxt->nxt;
2827 if ((rec_flag == 0) && fival_pre) {
2828 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2829 if (fival_pre->nxt != NULL) {
2830 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2831 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2832 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2833 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2835 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2836 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2837 |(pcdev->icd_height);
2838 fival_pre->nxt->fival.discrete.numerator = 1000000;
2839 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2841 fival_rec = fival_pre->nxt;
2845 pcdev->last_fps = pcdev->fps ;
2846 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2847 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2848 //return HRTIMER_NORESTART;
2849 if(pcdev->reinit_times >=2)
2850 return HRTIMER_NORESTART;
2852 return HRTIMER_RESTART;
2854 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2856 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2857 struct rk_camera_dev *pcdev = ici->priv;
2860 unsigned long flags;
2862 WARN_ON(pcdev->icd != icd);
2864 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2867 pcdev->last_fps = 0;
2868 pcdev->frame_interval = 0;
2869 hrtimer_cancel(&(pcdev->fps_timer.timer));
2870 pcdev->fps_timer.pcdev = pcdev;
2871 pcdev->timer_get_fps = false;
2872 pcdev->reinit_times = 0;
2874 spin_lock_irqsave(&pcdev->lock,flags);
2875 atomic_set(&pcdev->stop_cif,false);
2876 pcdev->irqinfo.cifirq_idx = 0;
2877 pcdev->irqinfo.cifirq_normal_idx = 0;
2878 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2879 pcdev->irqinfo.dmairq_idx = 0;
2881 cif_ctrl_val |= ENABLE_CAPTURE;
2882 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2883 spin_unlock_irqrestore(&pcdev->lock,flags);
2885 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2886 pcdev->fps_timer.istarted = true;
2888 //cancel timer before stop cif
2889 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2890 pcdev->fps_timer.istarted = false;
2891 flush_work(&(pcdev->camera_reinit_work.work));
2893 cif_ctrl_val &= ~ENABLE_CAPTURE;
2894 spin_lock_irqsave(&pcdev->lock, flags);
2895 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2896 atomic_set(&pcdev->stop_cif,true);
2897 spin_unlock_irqrestore(&pcdev->lock, flags);
2898 flush_workqueue((pcdev->camera_wq));
2900 //must be reinit,or will be somthing wrong in irq process.
2901 if(enable == false) {
2902 pcdev->active = NULL;
2903 INIT_LIST_HEAD(&pcdev->capture);
2905 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2908 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2910 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2911 struct rk_camera_dev *pcdev = ici->priv;
2912 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2913 struct rk_camera_frmivalenum *fival_list = NULL;
2914 struct v4l2_frmivalenum *fival_head = NULL;
2915 struct rkcamera_platform_data *new_camera;
2916 int i,ret = 0,index;
2917 const struct soc_camera_format_xlate *xlate;
2918 struct v4l2_mbus_framefmt mf;
2921 index = fival->index & 0x00ffffff;
2922 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2923 for (i=0; i<2; i++) {
2924 if (pcdev->icd_frmival[i].icd == icd) {
2925 fival_list = pcdev->icd_frmival[i].fival_list;
2929 if (fival_list != NULL) {
2931 while (fival_list != NULL) {
2932 if ((fival->pixel_format == fival_list->fival.pixel_format)
2933 && (fival->height == fival_list->fival.height)
2934 && (fival->width == fival_list->fival.width)) {
2939 fival_list = fival_list->nxt;
2942 if ((i==index) && (fival_list != NULL)) {
2943 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2948 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2953 for (i=0; i<RK_CAM_NUM; i++) {
2954 if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
2955 fival_head = pcdev->pdata->info[i].fival;
2961 while (fival_head->width && fival_head->height) {
2962 if ((fival->pixel_format == fival_head->pixel_format)
2963 && (fival->height == fival_head->height)
2964 && (fival->width == fival_head->width)) {
2973 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2974 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2976 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2977 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2978 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2979 mf.width = fival->width;
2980 mf.height = fival->height;
2981 mf.code = xlate->code;
2983 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2985 fival->reserved[1] = (mf.width<<16)|(mf.height);
2987 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2988 fival->width, fival->height,
2989 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2990 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2991 fival->discrete.denominator,fival->discrete.numerator);
2994 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2995 fival->width,fival->height,
2996 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2997 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
3000 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
3001 fival->width,fival->height,
3002 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
3003 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
3006 goto rk_camera_enum_frameintervals_end;
3010 new_camera = pcdev->pdata->register_dev_new;
3011 while (strstr(new_camera->dev_name,"end")==NULL) {
3012 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
3020 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
3021 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
3024 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
3025 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
3026 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
3027 mf.width = fival->width;
3028 mf.height = fival->height;
3029 mf.code = xlate->code;
3031 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
3033 fival->discrete.numerator= 1000;
3034 fival->discrete.denominator = 15000;
3035 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
3036 fival->reserved[1] = (mf.width<<16)|(mf.height);
3040 rk_camera_enum_frameintervals_end:
3044 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
3045 const struct v4l2_queryctrl *qctrl, int zoom_rate)
3048 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
3049 struct rk_camera_dev *pcdev = ici->priv;
3051 unsigned long tmp_cifctrl;
3054 //change the crop and scale parameters
3057 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3058 //a.c.width = pcdev->host_width*100/zoom_rate;
3059 a.c.width = pcdev->host_width*100/zoom_rate;
3060 a.c.width &= ~CROP_ALIGN_BYTES;
3061 a.c.height = pcdev->host_height*100/zoom_rate;
3062 a.c.height &= ~CROP_ALIGN_BYTES;
3063 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
3064 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
3065 atomic_set(&pcdev->stop_cif,true);
3066 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
3067 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
3068 hrtimer_cancel(&(pcdev->fps_timer.timer));
3069 flush_workqueue((pcdev->camera_wq));
3071 down(&pcdev->zoominfo.sem);
3072 pcdev->zoominfo.a.c.left = 0;
3073 pcdev->zoominfo.a.c.top = 0;
3074 pcdev->zoominfo.a.c.width = a.c.width;
3075 pcdev->zoominfo.a.c.height = a.c.height;
3076 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
3077 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
3078 pcdev->frame_inval = 1;
3079 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
3080 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
3081 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
3082 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
3084 rk_videobuf_capture(pcdev->active,pcdev);
3085 if(tmp_cifctrl & ENABLE_CAPTURE)
3086 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
3087 up(&pcdev->zoominfo.sem);
3089 atomic_set(&pcdev->stop_cif,false);
3090 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
3091 RKCAMERA_DG1("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 );
3093 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3094 a.c.width = pcdev->host_width*100/zoom_rate;
3095 a.c.width &= ~CROP_ALIGN_BYTES;
3096 a.c.height = pcdev->host_height*100/zoom_rate;
3097 a.c.height &= ~CROP_ALIGN_BYTES;
3098 a.c.left = (pcdev->host_width - a.c.width)>>1;
3099 a.c.top = (pcdev->host_height - a.c.height)>>1;
3101 down(&pcdev->zoominfo.sem);
3102 pcdev->zoominfo.a.c.height = a.c.height;
3103 pcdev->zoominfo.a.c.width = a.c.width;
3104 pcdev->zoominfo.a.c.top = a.c.top;
3105 pcdev->zoominfo.a.c.left = a.c.left;
3106 pcdev->zoominfo.vir_width = pcdev->host_width;
3107 pcdev->zoominfo.vir_height= pcdev->host_height;
3108 up(&pcdev->zoominfo.sem);
3110 RKCAMERA_DG1("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 );
3116 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
3117 struct soc_camera_host_ops *ops, int id)
3121 for (i = 0; i < ops->num_controls; i++)
3122 if (ops->controls[i].id == id)
3123 return &ops->controls[i];
3129 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
3130 struct v4l2_control *sctrl)
3133 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
3134 const struct v4l2_queryctrl *qctrl;
3135 struct rk_camera_dev *pcdev = ici->priv;
3139 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
3142 goto rk_camera_set_ctrl_end;
3147 case V4L2_CID_ZOOM_ABSOLUTE:
3149 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
3151 goto rk_camera_set_ctrl_end;
3153 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
3155 pcdev->zoominfo.zoom_rate = sctrl->value;
3157 goto rk_camera_set_ctrl_end;
3165 rk_camera_set_ctrl_end:
3169 static struct soc_camera_host_ops rk_soc_camera_host_ops =
3171 .owner = THIS_MODULE,
3172 .add = rk_camera_add_device,
3173 .remove = rk_camera_remove_device,
3174 .suspend = rk_camera_suspend,
3175 .resume = rk_camera_resume,
3176 .enum_frameinervals = rk_camera_enum_frameintervals,
3177 .cropcap = rk_camera_cropcap,
3178 .set_crop = rk_camera_set_crop,
3179 .get_crop = rk_camera_get_crop,
3180 .get_formats = rk_camera_get_formats,
3181 .put_formats = rk_camera_put_formats,
3182 .set_fmt = rk_camera_set_fmt,
3183 .try_fmt = rk_camera_try_fmt,
3184 .init_videobuf = rk_camera_init_videobuf,
3185 .reqbufs = rk_camera_reqbufs,
3186 .poll = rk_camera_poll,
3187 .querycap = rk_camera_querycap,
3188 .set_bus_param = rk_camera_set_bus_param,
3189 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
3190 .set_ctrl = rk_camera_set_ctrl,
3191 .controls = rk_camera_controls,
3192 .num_controls = ARRAY_SIZE(rk_camera_controls)
3194 static void rk_camera_cif_iomux(int cif_index)
3196 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
3200 iomux_set(CIF0_CLKOUT);
3201 write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_8MA));
3202 write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
3203 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
3207 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
3208 iomux_set(CIF0_D10);
3209 iomux_set(CIF0_D11);
3210 RKCAMERA_TR("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
3216 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
3219 #elif defined(CONFIG_ARCH_RK30)
3223 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
3224 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
3225 rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME, GPIO1B_CIF0_DATA0);
3226 rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME, GPIO1B_CIF0_DATA1);
3228 #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
3229 rk30_mux_api_set(GPIO1B6_CIFDATA10_NAME, GPIO1B_CIF_DATA10);
3230 rk30_mux_api_set(GPIO1B7_CIFDATA11_NAME, GPIO1B_CIF_DATA11);
3236 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
3237 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
3238 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
3239 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
3240 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
3241 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
3242 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
3243 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
3245 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
3246 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
3247 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
3248 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
3249 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
3250 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
3251 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
3252 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
3256 RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
3263 static int rk_camera_probe(struct platform_device *pdev)
3265 struct rk_camera_dev *pcdev;
3266 struct resource *res;
3267 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3268 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
3271 struct rk_cif_clk *clk=NULL;
3273 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3274 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3276 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3277 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3281 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3282 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3286 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3287 irq = platform_get_irq(pdev, 0);
3288 if (!res || irq < 0) {
3292 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3294 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3299 pcdev->zoominfo.zoom_rate = 100;
3300 pcdev->hostid = pdev->id;
3301 #ifdef CONFIG_SOC_RK3028
3302 pcdev->chip_id = rk3028_version_val();
3304 pcdev->chip_id = -1;
3310 cif_clk[0].pd_cif = clk_get(NULL, "pd_cif0");
3311 cif_clk[0].aclk_cif = clk_get(NULL, "aclk_cif0");
3312 cif_clk[0].hclk_cif = clk_get(NULL, "hclk_cif0");
3313 cif_clk[0].cif_clk_in = clk_get(NULL, "cif0_in");
3314 cif_clk[0].cif_clk_out = clk_get(NULL, "cif0_out");
3315 spin_lock_init(&cif_clk[0].lock);
3316 cif_clk[0].on = false;
3317 rk_camera_cif_iomux(0);
3320 cif_clk[1].pd_cif = clk_get(NULL, "pd_cif1");
3321 cif_clk[1].aclk_cif = clk_get(NULL, "aclk_cif1");
3322 cif_clk[1].hclk_cif = clk_get(NULL, "hclk_cif1");
3323 cif_clk[1].cif_clk_in = clk_get(NULL, "cif1_in");
3324 cif_clk[1].cif_clk_out = clk_get(NULL, "cif1_out");
3325 spin_lock_init(&cif_clk[1].lock);
3326 cif_clk[1].on = false;
3327 rk_camera_cif_iomux(1);
3330 dev_set_drvdata(&pdev->dev, pcdev);
3332 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3334 if (pcdev->pdata && pcdev->pdata->io_init) {
3335 pcdev->pdata->io_init();
3337 if (pcdev->pdata->sensor_mclk == NULL)
3338 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3341 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
3342 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
3344 if (meminfo_ptr->vbase == NULL) {
3346 if ((meminfo_ptr->start == meminfo_ptrr->start)
3347 && (meminfo_ptr->size == meminfo_ptrr->size) && meminfo_ptrr->vbase) {
3349 meminfo_ptr->vbase = meminfo_ptrr->vbase;
3352 if (!request_mem_region(meminfo_ptr->start,meminfo_ptr->size,"rk29_vipmem")) {
3354 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);
3355 goto exit_ioremap_vipmem;
3357 meminfo_ptr->vbase = pcdev->vipmem_virbase = ioremap_cached(meminfo_ptr->start,meminfo_ptr->size);
3358 if (pcdev->vipmem_virbase == NULL) {
3359 RKCAMERA_TR("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
3361 goto exit_ioremap_vipmem;
3366 pcdev->vipmem_phybase = meminfo_ptr->start;
3367 pcdev->vipmem_size = meminfo_ptr->size;
3368 pcdev->vipmem_virbase = meminfo_ptr->vbase;
3370 INIT_LIST_HEAD(&pcdev->capture);
3371 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3372 spin_lock_init(&pcdev->lock);
3373 spin_lock_init(&pcdev->camera_work_lock);
3375 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3376 spin_lock_init(&pcdev->cropinfo.lock);
3377 sema_init(&pcdev->zoominfo.sem,1);
3380 * Request the regions.
3383 if (!request_mem_region(res->start, res->end - res->start + 1,
3384 RK29_CAM_DRV_NAME)) {
3386 goto exit_reqmem_vip;
3388 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3389 if (pcdev->base == NULL) {
3390 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3392 goto exit_ioremap_vip;
3396 pcdev->irqinfo.irq = irq;
3397 pcdev->dev = &pdev->dev;
3399 /* config buffer address */
3402 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3405 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3411 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3413 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3415 if (pcdev->camera_wq == NULL) {
3416 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3420 pcdev->camera_reinit_work.pcdev = pcdev;
3421 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3423 for (i=0; i<2; i++) {
3424 pcdev->icd_frmival[i].icd = NULL;
3425 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3428 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3429 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3430 pcdev->soc_host.priv = pcdev;
3431 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3432 pcdev->soc_host.nr = pdev->id;
3434 err = soc_camera_host_register(&pcdev->soc_host);
3436 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3439 pcdev->fps_timer.pcdev = pcdev;
3440 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3441 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3442 pcdev->icd_cb.sensor_cb = NULL;
3444 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3445 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3446 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3447 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3448 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3449 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3450 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3451 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3457 for (i=0; i<2; i++) {
3458 fival_list = pcdev->icd_frmival[i].fival_list;
3459 fival_nxt = fival_list;
3460 while(fival_nxt != NULL) {
3461 fival_nxt = fival_list->nxt;
3463 fival_list = fival_nxt;
3467 free_irq(pcdev->irqinfo.irq, pcdev);
3468 if (pcdev->camera_wq) {
3469 destroy_workqueue(pcdev->camera_wq);
3470 pcdev->camera_wq = NULL;
3473 iounmap(pcdev->base);
3475 release_mem_region(res->start, res->end - res->start + 1);
3476 exit_ioremap_vipmem:
3477 if (pcdev->vipmem_virbase)
3478 iounmap(pcdev->vipmem_virbase);
3479 release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
3483 clk_put(clk->pd_cif);
3485 clk_put(clk->aclk_cif);
3487 clk_put(clk->hclk_cif);
3488 if (clk->cif_clk_in)
3489 clk_put(clk->cif_clk_in);
3490 if (clk->cif_clk_out)
3491 clk_put(clk->cif_clk_out);
3500 static int __devexit rk_camera_remove(struct platform_device *pdev)
3502 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3503 struct resource *res;
3504 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3505 struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
3508 free_irq(pcdev->irqinfo.irq, pcdev);
3510 if (pcdev->camera_wq) {
3511 destroy_workqueue(pcdev->camera_wq);
3512 pcdev->camera_wq = NULL;
3515 for (i=0; i<2; i++) {
3516 fival_list = pcdev->icd_frmival[i].fival_list;
3517 fival_nxt = fival_list;
3518 while(fival_nxt != NULL) {
3519 fival_nxt = fival_list->nxt;
3521 fival_list = fival_nxt;
3525 soc_camera_host_unregister(&pcdev->soc_host);
3527 meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
3528 meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
3529 if (meminfo_ptr->vbase) {
3530 if (meminfo_ptr->vbase == meminfo_ptrr->vbase) {
3531 meminfo_ptr->vbase = NULL;
3533 iounmap((void __iomem*)pcdev->vipmem_virbase);
3534 release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
3535 meminfo_ptr->vbase = NULL;
3540 iounmap((void __iomem*)pcdev->base);
3541 release_mem_region(res->start, res->end - res->start + 1);
3542 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3543 pcdev->pdata->io_deinit(0);
3544 pcdev->pdata->io_deinit(1);
3549 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3554 static struct platform_driver rk_camera_driver =
3557 .name = RK29_CAM_DRV_NAME,
3559 .probe = rk_camera_probe,
3560 .remove = __devexit_p(rk_camera_remove),
3563 static int rk_camera_init_async(void *unused)
3565 platform_driver_register(&rk_camera_driver);
3569 static int __devinit rk_camera_init(void)
3571 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3575 static void __exit rk_camera_exit(void)
3577 platform_driver_unregister(&rk_camera_driver);
3580 device_initcall_sync(rk_camera_init);
3581 module_exit(rk_camera_exit);
3583 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3584 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3585 MODULE_LICENSE("GPL");