1 #include <linux/init.h>
2 #include <linux/module.h>
4 #include <linux/delay.h>
5 #include <linux/slab.h>
6 #include <linux/dma-mapping.h>
7 #include <linux/errno.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
12 #include <linux/moduleparam.h>
13 #include <linux/time.h>
14 #include <linux/clk.h>
15 #include <linux/version.h>
16 #include <linux/device.h>
17 #include <linux/platform_device.h>
18 #include <linux/mutex.h>
19 #include <linux/videodev2.h>
20 #include <linux/kthread.h>
22 #include <media/v4l2-common.h>
23 #include <media/v4l2-dev.h>
24 #include <media/videobuf-dma-contig.h>
25 #include <media/soc_camera.h>
26 #include <media/soc_mediabus.h>
27 #include <media/videobuf-core.h>
28 #include <linux/rockchip/iomap.h>
30 #include "../../video/rockchip/rga/rga.h"
31 #include "../../../arch/arm/mach-rockchip/rk30_camera.h"/*yzm*/
32 #include <linux/rockchip/cru.h>
36 #include <plat/efuse.h>
37 #if (defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026))
38 #include <mach/rk2928_camera.h>
41 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
44 #include <asm/cacheflush.h>
46 #include <linux/of_address.h>
47 #include <linux/of_platform.h>
48 #include <linux/of_fdt.h>
49 #include <media/soc_camera.h>
50 #include <media/camsys_head.h>
52 #include <linux/of_irq.h>
55 module_param(debug, int, S_IRUGO|S_IWUSR);
57 #define CAMMODULE_NAME "rk_cam_cif"
59 #define wprintk(level, fmt, arg...) do { \
61 printk(KERN_ERR "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
63 #define dprintk(level, fmt, arg...) do { \
65 printk(KERN_ERR"%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
67 #define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
68 #define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
69 #define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
70 #define debug_printk(format, ...) dprintk(3, format, ## __VA_ARGS__)
73 #define CIF_CIF_CTRL 0x00
74 #define CIF_CIF_INTEN 0x04
75 #define CIF_CIF_INTSTAT 0x08
76 #define CIF_CIF_FOR 0x0c
77 #define CIF_CIF_LINE_NUM_ADDR 0x10
78 #define CIF_CIF_FRM0_ADDR_Y 0x14
79 #define CIF_CIF_FRM0_ADDR_UV 0x18
80 #define CIF_CIF_FRM1_ADDR_Y 0x1c
81 #define CIF_CIF_FRM1_ADDR_UV 0x20
82 #define CIF_CIF_VIR_LINE_WIDTH 0x24
83 #define CIF_CIF_SET_SIZE 0x28
84 #define CIF_CIF_SCM_ADDR_Y 0x2c
85 #define CIF_CIF_SCM_ADDR_U 0x30
86 #define CIF_CIF_SCM_ADDR_V 0x34
87 #define CIF_CIF_WB_UP_FILTER 0x38
88 #define CIF_CIF_WB_LOW_FILTER 0x3c
89 #define CIF_CIF_WBC_CNT 0x40
90 #define CIF_CIF_CROP 0x44
91 #define CIF_CIF_SCL_CTRL 0x48
92 #define CIF_CIF_SCL_DST 0x4c
93 #define CIF_CIF_SCL_FCT 0x50
94 #define CIF_CIF_SCL_VALID_NUM 0x54
95 #define CIF_CIF_LINE_LOOP_CTR 0x58
96 #define CIF_CIF_FRAME_STATUS 0x60
97 #define CIF_CIF_CUR_DST 0x64
98 #define CIF_CIF_LAST_LINE 0x68
99 #define CIF_CIF_LAST_PIX 0x6c
101 /*The key register bit descrition*/
102 /* CIF_CTRL Reg , ignore SCM,WBC,ISP,*/
103 #define DISABLE_CAPTURE (0x00<<0)
104 #define ENABLE_CAPTURE (0x01<<0)
105 #define MODE_ONEFRAME (0x00<<1)
106 #define MODE_PINGPONG (0x01<<1)
107 #define MODE_LINELOOP (0x02<<1)
108 #define AXI_BURST_16 (0x0F << 12)
111 #define FRAME_END_EN (0x01<<1)
112 #define BUS_ERR_EN (0x01<<6)
113 #define SCL_ERR_EN (0x01<<7)
116 #define VSY_HIGH_ACTIVE (0x01<<0)
117 #define VSY_LOW_ACTIVE (0x00<<0)
118 #define HSY_LOW_ACTIVE (0x01<<1)
119 #define HSY_HIGH_ACTIVE (0x00<<1)
120 #define INPUT_MODE_YUV (0x00<<2)
121 #define INPUT_MODE_PAL (0x02<<2)
122 #define INPUT_MODE_NTSC (0x03<<2)
123 #define INPUT_MODE_RAW (0x04<<2)
124 #define INPUT_MODE_JPEG (0x05<<2)
125 #define INPUT_MODE_MIPI (0x06<<2)
126 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
127 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
128 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
129 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
130 #define YUV_INPUT_422 (0x00<<7)
131 #define YUV_INPUT_420 (0x01<<7)
132 #define INPUT_420_ORDER_EVEN (0x00<<8)
133 #define INPUT_420_ORDER_ODD (0x01<<8)
134 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
135 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
136 #define RAW_DATA_WIDTH_8 (0x00<<11)
137 #define RAW_DATA_WIDTH_10 (0x01<<11)
138 #define RAW_DATA_WIDTH_12 (0x02<<11)
139 #define YUV_OUTPUT_422 (0x00<<16)
140 #define YUV_OUTPUT_420 (0x01<<16)
141 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
142 #define OUTPUT_420_ORDER_ODD (0x01<<17)
143 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
144 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
145 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
146 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
149 #define ENABLE_SCL_DOWN (0x01<<0)
150 #define DISABLE_SCL_DOWN (0x00<<0)
151 #define ENABLE_SCL_UP (0x01<<1)
152 #define DISABLE_SCL_UP (0x00<<1)
153 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
154 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
155 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
156 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
157 #define ENABLE_32BIT_BYPASS (0x01<<6)
158 #define DISABLE_32BIT_BYPASS (0x00<<6)
160 //CIF_CIF_FRAME_STATUS
161 #define CIF_F0_READY (0x01<<0)
162 #define CIF_F1_READY (0x01<<1)
164 extern unsigned long rk_cif_grf_base;
165 extern unsigned long rk_cif_cru_base;
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 __raw_readl(p) (*(unsigned int *)(p))
173 #define __raw_writel(v,p) (*(unsigned int *)(p) = (v))
175 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
176 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
177 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
180 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
182 #define CRU_PCLK_REG30 0xbc
183 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
184 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
185 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
186 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
188 #define CRU_CIF_RST_REG30 0x128
189 #define MASK_RST_CIF0 (0x01 << 30)
190 #define MASK_RST_CIF1 (0x01 << 31)
191 #define RQUEST_RST_CIF0 (0x01 << 14)
192 #define RQUEST_RST_CIF1 (0x01 << 15)
194 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
195 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
196 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
199 /*********yzm**********/
201 static u32 CRU_PCLK_REG30;
202 static u32 CRU_CLK_OUT;
203 static u32 CRU_CLKSEL29_CON;
204 static u32 ENANABLE_INVERT_PCLK_CIF0;
205 static u32 DISABLE_INVERT_PCLK_CIF0;
206 static u32 ENANABLE_INVERT_PCLK_CIF1;
207 static u32 DISABLE_INVERT_PCLK_CIF1;
208 static u32 CHIP_NAME;
210 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK_CRU_VIRT)
211 #define read_cru_reg(addr) __raw_readl(addr+RK_CRU_VIRT)
212 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
214 #define rk3368_write_cru_reg(addr, val) __raw_writel(val, addr+rk_cif_cru_base)
215 #define rk3368_read_cru_reg(addr) __raw_readl(addr+rk_cif_cru_base)
216 #define rk3368_mask_cru_reg(addr, msk, val) rk3368_write_cru_reg(addr,(val)|((~(msk))&rk3368_read_cru_reg(addr)))
218 /*********yzm*********end*/
220 #if defined(CONFIG_ARCH_RK2928)
221 #define write_cru_reg(addr, val)
222 #define read_cru_reg(addr) 0
223 #define mask_cru_reg(addr, msk, val)
228 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
230 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
231 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
232 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
233 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
234 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
237 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
238 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
239 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
241 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
242 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
243 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
245 #define write_grf_reg(addr, val)
246 #define read_grf_reg(addr) 0
247 #define mask_grf_reg(addr, msk, val)
250 #define CAM_WORKQUEUE_IS_EN() (false)//(true)
251 #define CAM_IPPWORK_IS_EN() (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
253 #define IS_CIF0() (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
254 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
255 #define CROP_ALIGN_BYTES (0x03)
256 #define CIF_DO_CROP 0
257 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
258 #define CROP_ALIGN_BYTES (0x0f)
259 #define CIF_DO_CROP 0
260 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
261 #define CROP_ALIGN_BYTES (0x03)
262 #define CIF_DO_CROP 0
263 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
264 #define CROP_ALIGN_BYTES (0x0F)
265 #define CIF_DO_CROP 1
269 *v0.1.0 : this driver is 3.10 kernel driver;
270 copy and updata from v0.3.0x19;
273 1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
274 cause warning, so remove this spin lock .
276 1. rk3126 and rk3128 use different dts file.
278 1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
280 1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk
282 1. Improve the code to support all configuration.reset,af,flash...
284 1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
286 1. Add power and powerdown controled by PMU.
288 1. Support front and rear camera support are the same.
290 1. Support pingpong mode.
291 2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0.
292 3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
296 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0xa)
297 static int version = RK_CAM_VERSION_CODE;
298 module_param(version, int, S_IRUGO);
300 /* limit to rk29 hardware capabilities */
301 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
302 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
303 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
304 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
305 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
306 V4L2_MBUS_PCLK_SAMPLE_RISING |\
307 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
308 V4L2_MBUS_DATA_ACTIVE_HIGH |\
309 V4L2_MBUS_DATA_ACTIVE_LOW|\
310 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
311 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
313 #define RK_CAM_W_MIN 48
314 #define RK_CAM_H_MIN 32
315 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
316 #define RK_CAM_H_MAX 2764
317 #define RK_CAM_FRAME_INVAL_INIT 0
318 #define RK_CAM_FRAME_INVAL_DC 0 /* ddl@rock-chips.com : */
319 #define RK30_CAM_FRAME_MEASURE 5
322 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
323 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
324 /* buffer for one video frame */
325 struct rk_camera_buffer
327 /* common v4l buffer stuff -- must be first */
328 struct videobuf_buffer vb;
329 enum v4l2_mbus_pixelcode code;
332 enum rk_camera_reg_state
340 unsigned int cifCtrl;
341 unsigned int cifCrop;
343 unsigned int cifIntEn;
345 unsigned int cifVirWidth;
346 unsigned int cifScale;
347 /* unsigned int VipCrm;*/
348 enum rk_camera_reg_state Inval;
350 struct rk_camera_work
352 struct videobuf_buffer *vb;
353 struct rk_camera_dev *pcdev;
354 struct work_struct work;
355 struct list_head queue;
358 struct rk_camera_frmivalenum
360 struct v4l2_frmivalenum fival;
361 struct rk_camera_frmivalenum *nxt;
363 struct rk_camera_frmivalinfo
365 struct soc_camera_device *icd;
366 struct rk_camera_frmivalenum *fival_list;
368 struct rk_camera_zoominfo
370 struct semaphore sem;
376 #if CAMERA_VIDEOBUF_ARM_ACCESS
377 struct rk29_camera_vbinfo
379 unsigned long phy_addr;
380 void __iomem *vir_addr;
384 struct rk_camera_timer{
385 struct rk_camera_dev *pcdev;
386 struct hrtimer timer;
391 /************must modify start************/
393 struct clk *aclk_cif;
394 struct clk *hclk_cif;
395 struct clk *cif_clk_in;
396 struct clk *cif_clk_out;
397 /************must modify end************/
407 struct v4l2_rect bounds;
410 struct rk_cif_irqinfo
413 unsigned long cifirq_idx;
414 unsigned long cifirq_normal_idx;
415 unsigned long cifirq_abnormal_idx;
417 unsigned long dmairq_idx;
423 struct soc_camera_host soc_host;
425 /* RK2827x is only supposed to handle one camera on its Quick Capture
426 * interface. If anyone ever builds hardware to enable more than
427 * one camera, they will have to modify this driver too */
428 struct soc_camera_device *icd;
430 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
433 unsigned int last_fps;
434 unsigned long frame_interval;
437 unsigned long vipmem_phybase;
438 void __iomem *vipmem_virbase;
439 unsigned int vipmem_size;
440 unsigned int vipmem_bsize;
441 #if CAMERA_VIDEOBUF_ARM_ACCESS
442 struct rk29_camera_vbinfo *vbinfo;
443 unsigned int vbinfo_count;
447 int host_left; /*sensor output size ?*/
453 struct rk_cif_crop cropinfo;
454 struct rk_cif_irqinfo irqinfo;
456 struct rk29camera_platform_data *pdata;
457 struct resource *res;
458 struct list_head capture;
459 struct rk_camera_zoominfo zoominfo;
463 struct videobuf_buffer *active0;
464 struct videobuf_buffer *active1;
466 struct rk_camera_reg reginfo_suspend;
467 struct workqueue_struct *camera_wq;
468 struct rk_camera_work *camera_work;
469 struct list_head camera_work_queue;
470 spinlock_t camera_work_lock;
471 unsigned int camera_work_count;
472 struct rk_camera_timer fps_timer;
473 struct rk_camera_work camera_reinit_work;
475 rk29_camera_sensor_cb_s icd_cb;
476 struct rk_camera_frmivalinfo icd_frmival[2];
478 unsigned int reinit_times;
479 struct videobuf_queue *video_vq;
481 struct timeval first_tv;
486 static const struct v4l2_queryctrl rk_camera_controls[] =
489 .id = V4L2_CID_ZOOM_ABSOLUTE,
490 .type = V4L2_CTRL_TYPE_INTEGER,
491 .name = "DigitalZoom Control",
495 .default_value = 100,
499 static struct rk_cif_clk cif_clk[2];
501 static DEFINE_MUTEX(camera_lock);
502 static const char *rk_cam_driver_description = "RK_Camera";
504 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
505 static void rk_camera_capture_process(struct work_struct *work);
507 static void rk_camera_diffchips(const char *rockchip_name)
509 if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
511 CRU_PCLK_REG30 = 0xbc;
512 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
513 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7));
514 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
515 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
518 CRU_CLKSEL29_CON = 0xb8;
521 }else if(strstr(rockchip_name,"3368"))
523 CRU_PCLK_REG30 = 0x154;
524 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x1<<13));
525 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x0<<13));
526 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
527 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
529 //CRU_CLK_OUT = 0x16c;
533 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
538 if(CHIP_NAME == 3368)
539 reg = (void*)(rk_cif_cru_base + RK_CRU_SOFTRST_CON);
541 reg = (void*)(RK_CRU_VIRT + RK_CRU_SOFTRST_CON);
543 if(CHIP_NAME == 3126){
544 val = on ? 0x10001U << 14 : 0x10000U << 14;
545 }else if(CHIP_NAME == 3368){
546 val = on ? 0x10001U << 8 : 0x10000U << 8;
548 writel_relaxed(val, reg);
552 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
554 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
555 u32 RK_CRU_SOFTRST_CON = 0;
556 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
557 if(strstr(pcdev->pdata->rockchip_name,"3128")||strstr(pcdev->pdata->rockchip_name,"3126"))
558 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
559 else if(strstr(pcdev->pdata->rockchip_name,"3368"))
560 RK_CRU_SOFTRST_CON = RK3368_CRU_SOFTRSTS_CON(6);
562 if (only_rst == true) {
563 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
565 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
567 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
568 if (ctrl_reg & ENABLE_CAPTURE) {
569 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
571 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
572 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
573 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
574 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
575 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
576 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
577 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
578 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
580 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
582 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
584 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
585 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
586 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
587 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
588 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
589 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
590 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
591 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
592 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
599 * Videobuf operations
601 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
604 struct soc_camera_device *icd = vq->priv_data;
605 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
606 struct rk_camera_dev *pcdev = ici->priv;
608 struct rk_camera_work *wk;
610 struct soc_mbus_pixelfmt fmt;
612 int bytes_per_line_host;
613 fmt.packing = SOC_MBUS_PACKING_1_5X8;
615 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
618 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
619 icd->current_fmt->host_fmt);
620 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
621 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
623 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
624 bytes_per_line_host = pcdev->host_width*3;
626 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
627 icd->current_fmt->host_fmt);
628 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
630 if (bytes_per_line_host < 0)
631 return bytes_per_line_host;
633 /* planar capture requires Y, U and V buffers to be page aligned */
634 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
635 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
637 if (CAM_WORKQUEUE_IS_EN()) {
639 if (CAM_IPPWORK_IS_EN()) {
640 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
641 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
642 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
646 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
647 kfree(pcdev->camera_work);
648 pcdev->camera_work = NULL;
649 pcdev->camera_work_count = 0;
652 if (pcdev->camera_work == NULL) {
653 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
654 if (pcdev->camera_work == NULL) {
655 RKCAMERA_TR("kmalloc failed\n");
658 INIT_LIST_HEAD(&pcdev->camera_work_queue);
660 for (i=0; i<(*count); i++) {
662 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
665 pcdev->camera_work_count = (*count);
667 #if CAMERA_VIDEOBUF_ARM_ACCESS
668 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
669 kfree(pcdev->vbinfo);
670 pcdev->vbinfo = NULL;
671 pcdev->vbinfo_count = 0x00;
674 if (pcdev->vbinfo == NULL) {
675 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
676 if (pcdev->vbinfo == NULL) {
677 RKCAMERA_TR("vbinfo kmalloc fail\n");
680 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
681 pcdev->vbinfo_count = *count;
685 pcdev->video_vq = vq;
686 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
690 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
692 struct soc_camera_device *icd = vq->priv_data;
694 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
697 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
698 &buf->vb, buf->vb.baddr, buf->vb.bsize);
700 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
701 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
707 * This waits until this buffer is out of danger, i.e., until it is no
708 * longer in STATE_QUEUED or STATE_ACTIVE
710 videobuf_waiton(vq, &buf->vb, 0, 0);
711 videobuf_dma_contig_free(vq, &buf->vb);
712 /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
713 buf->vb.state = VIDEOBUF_NEEDS_INIT;
716 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
718 struct soc_camera_device *icd = vq->priv_data;
719 struct rk_camera_buffer *buf;
721 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
722 icd->current_fmt->host_fmt);
724 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
726 if ((bytes_per_line < 0) || (vb->boff == 0))
729 buf = container_of(vb, struct rk_camera_buffer, vb);
731 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
732 /* vb, vb->baddr, vb->bsize);*/ /*yzm*/
734 /* Added list head initialization on alloc */
735 WARN_ON(!list_empty(&vb->queue));
737 BUG_ON(NULL == icd->current_fmt);
739 if (buf->code != icd->current_fmt->code ||
740 vb->width != icd->user_width ||
741 vb->height != icd->user_height ||
742 vb->field != field) {
743 buf->code = icd->current_fmt->code;
744 vb->width = icd->user_width;
745 vb->height = icd->user_height;
747 vb->state = VIDEOBUF_NEEDS_INIT;
750 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
751 if (0 != vb->baddr && vb->bsize < vb->size) {
756 if (vb->state == VIDEOBUF_NEEDS_INIT) {
757 ret = videobuf_iolock(vq, vb, NULL);
761 vb->state = VIDEOBUF_PREPARED;
766 rk_videobuf_free(vq, buf);
771 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev, int fmt_ready)
773 unsigned long y_addr,uv_addr;
774 struct rk_camera_dev *pcdev = rk_pcdev;
776 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
780 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
781 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
782 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
783 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
784 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
785 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
790 uv_addr = y_addr + vb->width * vb->height;
792 #if defined(CONFIG_ARCH_RK3188)
793 rk_camera_cif_reset(pcdev,false);
799 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
800 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
803 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
804 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
807 printk("%s(%d): fmt_ready(%d) is wrong!\n", __FUNCTION__, __LINE__,fmt_ready);
813 /* Locking: Caller holds q->irqlock */
814 static void rk_videobuf_queue(struct videobuf_queue *vq,
815 struct videobuf_buffer *vb)
817 struct soc_camera_device *icd = vq->priv_data;
818 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
819 struct rk_camera_dev *pcdev = ici->priv;
820 #if CAMERA_VIDEOBUF_ARM_ACCESS
821 struct rk29_camera_vbinfo *vb_info;
825 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
827 vb->state = VIDEOBUF_QUEUED;
828 if (list_empty(&pcdev->capture)) {
829 list_add_tail(&vb->queue, &pcdev->capture);
831 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
832 list_add_tail(&vb->queue, &pcdev->capture);
834 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
836 #if CAMERA_VIDEOBUF_ARM_ACCESS
838 vb_info = pcdev->vbinfo+vb->i;
839 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
840 if (vb_info->vir_addr) {
841 iounmap(vb_info->vir_addr);
842 release_mem_region(vb_info->phy_addr, vb_info->size);
843 vb_info->vir_addr = NULL;
844 vb_info->phy_addr = 0x00;
845 vb_info->size = 0x00;
848 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
849 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
852 if (vb_info->vir_addr) {
853 vb_info->size = vb->bsize;
854 vb_info->phy_addr = vb->boff;
856 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
862 if (!pcdev->active0) {
864 rk_videobuf_capture(vb,pcdev,0);
865 /*if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
866 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
868 list_del_init(&(vb->queue));
869 } else if (!pcdev->active1) {
871 rk_videobuf_capture(vb,pcdev,1);
872 /*if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
873 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
875 list_del_init(&(vb->queue));
880 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
881 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
884 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
888 case V4L2_PIX_FMT_YUV420:
889 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.*/
890 case V4L2_PIX_FMT_YUYV:
892 *ippfmt = RK_FORMAT_YCbCr_420_SP;
895 case V4L2_PIX_FMT_YVU420:
896 case V4L2_PIX_FMT_VYUY:
897 case V4L2_PIX_FMT_YVYU:
899 *ippfmt = RK_FORMAT_YCrCb_420_SP;
902 case V4L2_PIX_FMT_RGB565:
904 *ippfmt = RK_FORMAT_RGB_565;
907 case V4L2_PIX_FMT_RGB24:
909 *ippfmt = RK_FORMAT_RGB_888;
913 goto rk_pixfmt2rgafmt_err;
917 rk_pixfmt2rgafmt_err:
921 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
922 static int rk_camera_scale_crop_pp(struct work_struct *work){
923 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
924 struct videobuf_buffer *vb = camera_work->vb;
925 struct rk_camera_dev *pcdev = camera_work->pcdev;
927 unsigned long int flags;
935 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
936 extern rga_service_info rga_service;
937 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
938 extern void rga_service_session_clear(rga_session *session);
939 static int rk_camera_scale_crop_rga(struct work_struct *work){
940 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
941 struct videobuf_buffer *vb = camera_work->vb;
942 struct rk_camera_dev *pcdev = camera_work->pcdev;
944 unsigned long int flags;
950 const struct soc_mbus_pixelfmt *fmt;
953 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
960 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
962 static int rk_camera_scale_crop_ipp(struct work_struct *work)
968 static void rk_camera_capture_process(struct work_struct *work)
970 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
971 struct videobuf_buffer *vb = camera_work->vb;
972 struct rk_camera_dev *pcdev = camera_work->pcdev;
973 /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code; */
974 unsigned long flags = 0;
977 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
980 if (atomic_read(&pcdev->stop_cif)==true) {
982 goto rk_camera_capture_process_end;
985 if (!CAM_WORKQUEUE_IS_EN()) {
987 goto rk_camera_capture_process_end;
990 down(&pcdev->zoominfo.sem);
991 if (pcdev->icd_cb.scale_crop_cb){
992 err = (pcdev->icd_cb.scale_crop_cb)(work);
994 up(&pcdev->zoominfo.sem);
996 if (pcdev->icd_cb.sensor_cb)
997 (pcdev->icd_cb.sensor_cb)(vb);
999 rk_camera_capture_process_end:
1001 vb->state = VIDEOBUF_ERROR;
1003 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1004 vb->state = VIDEOBUF_DONE;
1008 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1009 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1010 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1011 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
1015 static void rk_camera_cifrest_delay(struct work_struct *work)
1017 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1018 struct rk_camera_dev *pcdev = camera_work->pcdev;
1019 unsigned long flags = 0;
1021 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1025 rk_camera_cif_reset(pcdev,false);
1027 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1028 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1029 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1031 spin_lock_irqsave(&pcdev->lock,flags);
1032 if (atomic_read(&pcdev->stop_cif) == false) {
1033 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
1034 RKCAMERA_DG2("After reset cif, enable capture again!\n");
1036 spin_unlock_irqrestore(&pcdev->lock,flags);
1040 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
1042 struct rk_camera_dev *pcdev = data;
1043 struct rk_camera_work *wk;
1044 unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
1046 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1049 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1051 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1052 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
1053 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
1055 pcdev->irqinfo.cifirq_idx++;
1056 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1057 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1058 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1059 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1061 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1064 if(reg_cifctrl & ENABLE_CAPTURE) {
1065 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1068 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1069 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1070 if (!list_empty(&pcdev->camera_work_queue)) {
1071 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1072 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1073 list_del_init(&wk->queue);
1074 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1076 queue_work(pcdev->camera_wq, &(wk->work));
1084 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1086 struct rk_camera_dev *pcdev = data;
1087 struct videobuf_buffer *vb;
1088 struct rk_camera_work *wk;
1090 unsigned long reg_cifctrl;
1091 unsigned long tmp_cif_frmst;
1092 struct videobuf_buffer **active = 0;
1093 struct videobuf_buffer *active_buf = NULL;
1096 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1099 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1100 tmp_cif_frmst = read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS);
1101 /* ddl@rock-chps.com : Current VIP is run in Pingpong Frame Mode */
1102 if (tmp_cif_frmst & (CIF_F0_READY | CIF_F1_READY)) { //frame 0 or 1 ready yzm
1103 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1105 pcdev->irqinfo.dmairq_idx++;
1106 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1107 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1111 if (!pcdev->fps) {//µÚÒ»´Î½øÈëÖжÏ
1112 do_gettimeofday(&pcdev->first_tv);
1115 if((tmp_cif_frmst & CIF_F0_READY) && (tmp_cif_frmst & CIF_F1_READY)){
1116 printk("%s:f0 && f1 ready ,need to resart cif!!!!!\n",__func__);
1117 reg_cifctrl &=~ENABLE_CAPTURE;
1123 if (tmp_cif_frmst & CIF_F0_READY){
1124 active = &pcdev->active0;
1126 } else if (tmp_cif_frmst & CIF_F1_READY){
1127 active = &pcdev->active1;
1130 printk("irq frame status erro \n");
1134 printk("active = NULL\n");
1138 if (pcdev->frame_inval>0) {//¹ØÓÚ¹ýÂËÇ°¼¸Ö¡µÄ£¬ÏÖÔÚûÓÐÓõ½
1139 pcdev->frame_inval--;
1140 rk_videobuf_capture(*active,pcdev,flag);
1141 } else if (pcdev->frame_inval) {
1142 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1143 pcdev->frame_inval = 0;
1146 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {//¹ýÂËÇ°¼¸Ö¡,¿ªÊ¼¶¨Ê±
1147 do_gettimeofday(&tv);
1148 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1149 /(RK30_CAM_FRAME_MEASURE-1);
1155 printk("no acticve buffer!!!\n");
1159 if (!list_empty(&pcdev->capture)) {
1160 active_buf = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1163 WARN_ON(active_buf->state != VIDEOBUF_QUEUED);
1164 if ((flag == 0) && ((active_buf->i)%2 == 0)){
1165 pcdev->active0 = active_buf;
1166 } else if ((flag == 1) && ((active_buf->i)%2 == 1)){
1167 pcdev->active1 = active_buf;
1169 RKCAMERA_DG1("irq frame status erro or no a suitable buf!\n");
1172 rk_videobuf_capture(active_buf,pcdev,flag);
1173 list_del_init(&(active_buf->queue));
1176 RKCAMERA_DG1("video_buf queue is empty!\n");
1180 do_gettimeofday(&vb->ts);
1181 if (CAM_WORKQUEUE_IS_EN()) {
1182 if (!list_empty(&pcdev->camera_work_queue)) {
1183 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1184 list_del_init(&wk->queue);
1185 INIT_WORK(&(wk->work), rk_camera_capture_process);
1188 queue_work(pcdev->camera_wq, &(wk->work));
1191 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1192 vb->state = VIDEOBUF_DONE;
1200 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1201 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1205 static irqreturn_t rk_camera_irq(int irq, void *data)
1207 struct rk_camera_dev *pcdev = data;
1208 unsigned long reg_intstat;
1211 spin_lock(&pcdev->lock);
1213 if(atomic_read(&pcdev->stop_cif) == true) {
1214 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
1218 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1219 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%lx\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1220 if (reg_intstat & 0x0200)
1221 rk_camera_cifirq(irq,data);
1223 if (reg_intstat & 0x01)
1224 rk_camera_dmairq(irq,data);
1227 spin_unlock(&pcdev->lock);
1232 static void rk_videobuf_release(struct videobuf_queue *vq,
1233 struct videobuf_buffer *vb)
1235 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1236 struct soc_camera_device *icd = vq->priv_data;
1237 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1238 struct rk_camera_dev *pcdev = ici->priv;
1239 #if CAMERA_VIDEOBUF_ARM_ACCESS
1240 struct rk29_camera_vbinfo *vb_info =NULL;
1245 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1248 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1249 vb, vb->baddr, vb->bsize);
1253 case VIDEOBUF_ACTIVE:
1254 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1256 case VIDEOBUF_QUEUED:
1257 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1259 case VIDEOBUF_PREPARED:
1260 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1263 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1268 flush_workqueue(pcdev->camera_wq);
1270 rk_videobuf_free(vq, buf);
1272 #if CAMERA_VIDEOBUF_ARM_ACCESS
1273 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1274 vb_info = pcdev->vbinfo + vb->i;
1276 if (vb_info->vir_addr) {
1277 iounmap(vb_info->vir_addr);
1278 release_mem_region(vb_info->phy_addr, vb_info->size);
1279 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1286 static struct videobuf_queue_ops rk_videobuf_ops =
1288 .buf_setup = rk_videobuf_setup,
1289 .buf_prepare = rk_videobuf_prepare,
1290 .buf_queue = rk_videobuf_queue,
1291 .buf_release = rk_videobuf_release,
1294 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1295 struct soc_camera_device *icd)
1297 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1298 struct rk_camera_dev *pcdev = ici->priv;
1300 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1303 /* We must pass NULL as dev pointer, then all pci_* dma operations
1304 * transform to normal dma_* ones. */
1305 videobuf_queue_dma_contig_init(q,
1307 ici->v4l2_dev.dev, &pcdev->lock,
1308 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1310 sizeof(struct rk_camera_buffer),
1311 icd,&(ici->host_lock) );
1314 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1317 struct rk_cif_clk *clk;
1319 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1322 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1323 if ((cif<0)||(cif>1)) {
1324 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1326 goto rk_camera_clk_ctrl_end;
1329 clk = &cif_clk[cif];
1331 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1332 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1334 goto rk_camera_clk_ctrl_end;
1337 //spin_lock(&clk->lock);
1338 if (on && !clk->on) {
1339 if(CHIP_NAME != 3368)
1340 clk_prepare_enable(clk->pd_cif); /*yzm*/
1341 clk_prepare_enable(clk->aclk_cif);
1342 clk_prepare_enable(clk->hclk_cif);
1343 clk_prepare_enable(clk->cif_clk_in);
1344 clk_prepare_enable(clk->cif_clk_out);
1345 clk_set_rate(clk->cif_clk_out,clk_rate);
1347 } else if (!on && clk->on) {
1348 clk_set_rate(clk->cif_clk_out,36000000);/*yzm :just for close clk which base on XIN24M */
1350 clk_disable_unprepare(clk->aclk_cif);
1351 clk_disable_unprepare(clk->hclk_cif);
1352 clk_disable_unprepare(clk->cif_clk_in);
1353 if(CHIP_NAME == 3126){
1354 write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
1355 write_cru_reg(CRU_CLK_OUT, 0x00800080);
1357 clk_disable_unprepare(clk->cif_clk_out);
1358 if(CHIP_NAME != 3368)
1359 clk_disable_unprepare(clk->pd_cif);
1362 //spin_unlock(&clk->lock);
1363 rk_camera_clk_ctrl_end:
1366 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1369 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1372 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1374 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1375 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1379 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1382 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1384 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1390 /* The following two functions absolutely depend on the fact, that
1391 * there can be only one camera on RK28 quick capture interface */
1392 static int rk_camera_add_device(struct soc_camera_device *icd)
1394 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1395 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1396 struct device *control = to_soc_camera_control(icd);
1397 struct v4l2_subdev *sd;
1398 int ret,i,icd_catch;
1399 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1400 struct v4l2_cropcap cropcap;
1401 struct v4l2_mbus_framefmt mf;
1402 const struct soc_camera_format_xlate *xlate = NULL;
1404 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1407 mutex_lock(&camera_lock);
1414 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1416 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1417 //pcdev->active = NULL;
1418 pcdev->active0 = NULL;
1419 pcdev->active1 = NULL;
1420 pcdev->active_buf = 0;
1422 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1423 pcdev->zoominfo.zoom_rate = 100;
1424 pcdev->fps_timer.istarted = false;
1426 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1427 * if app havn't dequeue all videobuf before close camera device;
1429 INIT_LIST_HEAD(&pcdev->capture);
1431 ret = rk_camera_activate(pcdev,icd);
1434 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1435 if (control) { //TRUE in open ,FALSE in kernel start
1436 sd = dev_get_drvdata(control);
1437 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1439 ret = v4l2_subdev_call(sd,core, init, 0);
1443 /* call generic_sensor_ioctl*/
1444 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1445 /* call generic_sensor_cropcap*/
1446 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1447 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1449 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1452 mf.field = V4L2_FIELD_NONE;
1453 mf.code = xlate->code;
1454 mf.reserved[6] = 0xfefe5a5a;
1455 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1457 pcdev->cropinfo.bounds.left = 0;
1458 pcdev->cropinfo.bounds.top = 0;
1459 pcdev->cropinfo.bounds.width = mf.width;
1460 pcdev->cropinfo.bounds.height = mf.height;
1464 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1466 pcdev->icd_init = 0;
1469 for (i=0; i<2; i++) {
1470 if (pcdev->icd_frmival[i].icd == icd)
1472 if (pcdev->icd_frmival[i].icd == NULL) {
1473 pcdev->icd_frmival[i].icd = icd;
1477 if (icd_catch == 0) {
1478 fival_list = pcdev->icd_frmival[0].fival_list;
1479 fival_nxt = fival_list;
1480 while(fival_nxt != NULL) {
1481 fival_nxt = fival_list->nxt;
1483 fival_list = fival_nxt;
1485 pcdev->icd_frmival[0].icd = icd;
1486 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1489 mutex_unlock(&camera_lock);
1493 static void rk_camera_remove_device(struct soc_camera_device *icd)
1495 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1496 struct rk_camera_dev *pcdev = ici->priv;
1497 /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
1498 #if CAMERA_VIDEOBUF_ARM_ACCESS
1499 struct rk29_camera_vbinfo *vb_info;
1503 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1506 mutex_lock(&camera_lock);
1507 BUG_ON(icd != pcdev->icd);
1509 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1511 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1512 stream may be turn on again before close device, if suspend and resume happened. */
1513 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1514 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1515 rk_camera_s_stream(icd,0);
1517 /* move DEACTIVATE into generic_sensor_s_power*/
1518 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
1519 /* if stream off is not been executed,timer is running.*/
1520 if(pcdev->fps_timer.istarted){
1521 hrtimer_cancel(&pcdev->fps_timer.timer);
1522 pcdev->fps_timer.istarted = false;
1524 flush_work(&(pcdev->camera_reinit_work.work));
1525 flush_workqueue((pcdev->camera_wq));
1527 if (pcdev->camera_work) {
1528 kfree(pcdev->camera_work);
1529 pcdev->camera_work = NULL;
1530 pcdev->camera_work_count = 0;
1531 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1533 rk_camera_deactivate(pcdev);
1534 #if CAMERA_VIDEOBUF_ARM_ACCESS
1535 if (pcdev->vbinfo) {
1536 vb_info = pcdev->vbinfo;
1537 for (i=0; i<pcdev->vbinfo_count; i++) {
1538 if (vb_info->vir_addr) {
1539 iounmap(vb_info->vir_addr);
1540 release_mem_region(vb_info->phy_addr, vb_info->size);
1541 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1545 kfree(pcdev->vbinfo);
1546 pcdev->vbinfo = NULL;
1547 pcdev->vbinfo_count = 0;
1550 //pcdev->active = NULL;
1551 pcdev->active0 = NULL;
1552 pcdev->active1 = NULL;
1553 pcdev->active_buf = 0;
1555 pcdev->icd_cb.sensor_cb = NULL;
1556 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1557 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1558 * if app havn't dequeue all videobuf before close camera device;
1560 INIT_LIST_HEAD(&pcdev->capture);
1562 mutex_unlock(&camera_lock);
1566 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1568 unsigned long bus_flags, camera_flags, common_flags = 0;
1569 unsigned int cif_for = 0;
1570 const struct soc_mbus_pixelfmt *fmt;
1572 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /*yzm*/
1573 struct rk_camera_dev *pcdev = ici->priv;
1575 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1578 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1582 bus_flags = RK_CAM_BUS_PARAM;
1583 /* If requested data width is supported by the platform, use it */
1584 switch (fmt->bits_per_sample) {
1586 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1590 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1594 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1600 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1601 if (icd->ops->query_bus_param)
1602 camera_flags = icd->ops->query_bus_param(icd);
1606 /**************yzm************
1607 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1608 if (!common_flags) {
1610 goto RK_CAMERA_SET_BUS_PARAM_END;
1613 /***************yzm************end*/
1616 common_flags = camera_flags;
1617 ret = icd->ops->set_bus_param(icd, common_flags);
1619 goto RK_CAMERA_SET_BUS_PARAM_END;
1621 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1623 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1625 if(CHIP_NAME == 3368)
1626 rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1628 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1630 if(CHIP_NAME == 3368)
1631 rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1633 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1637 if(CHIP_NAME == 3368)
1638 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1640 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1642 if(CHIP_NAME == 3368)
1643 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1645 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1649 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1650 cif_for |= HSY_LOW_ACTIVE;
1652 cif_for &= ~HSY_LOW_ACTIVE;
1654 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1655 cif_for |= VSY_HIGH_ACTIVE;
1657 cif_for &= ~VSY_HIGH_ACTIVE;
1660 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1661 //vip_ctrl_val |= ENABLE_CAPTURE;
1662 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1663 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1665 RK_CAMERA_SET_BUS_PARAM_END:
1667 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1671 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1673 /* unsigned long bus_flags, camera_flags;*/
1676 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1677 /**********yzm***********
1679 bus_flags = RK_CAM_BUS_PARAM;
1680 if (icd->ops->query_bus_param) {
1681 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1685 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1688 dev_warn(icd->dev.parent,
1689 "Flags incompatible: camera %lx, host %lx\n",
1690 camera_flags, bus_flags);
1693 *///************yzm **************end
1698 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1700 .fourcc = V4L2_PIX_FMT_NV12,
1701 .name = "YUV420 NV12",
1702 .bits_per_sample = 8,
1703 .packing = SOC_MBUS_PACKING_1_5X8,
1704 .order = SOC_MBUS_ORDER_LE,
1706 .fourcc = V4L2_PIX_FMT_NV16,
1707 .name = "YUV422 NV16",
1708 .bits_per_sample = 8,
1709 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1710 .order = SOC_MBUS_ORDER_LE,
1712 .fourcc = V4L2_PIX_FMT_NV21,
1713 .name = "YUV420 NV21",
1714 .bits_per_sample = 8,
1715 .packing = SOC_MBUS_PACKING_1_5X8,
1716 .order = SOC_MBUS_ORDER_LE,
1718 .fourcc = V4L2_PIX_FMT_NV61,
1719 .name = "YUV422 NV61",
1720 .bits_per_sample = 8,
1721 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1722 .order = SOC_MBUS_ORDER_LE,
1724 .fourcc = V4L2_PIX_FMT_RGB565,
1726 .bits_per_sample = 8,
1727 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1728 .order = SOC_MBUS_ORDER_LE,
1730 .fourcc = V4L2_PIX_FMT_RGB24,
1732 .bits_per_sample = 8,
1733 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1734 .order = SOC_MBUS_ORDER_LE,
1739 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1741 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1742 struct rk_camera_dev *pcdev = ici->priv;
1743 unsigned int cif_fs = 0,cif_crop = 0;
1744 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;
1746 const struct soc_mbus_pixelfmt *fmt;
1747 fmt = soc_mbus_get_fmtdesc(icd_code);
1749 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1752 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1753 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1754 host_pixfmt = V4L2_PIX_FMT_NV12;
1755 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1756 host_pixfmt = V4L2_PIX_FMT_NV21;
1758 switch (host_pixfmt)
1760 case V4L2_PIX_FMT_NV16:
1761 cif_fmt_val &= ~YUV_OUTPUT_422;
1762 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1763 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1764 pcdev->pixfmt = host_pixfmt;
1766 case V4L2_PIX_FMT_NV61:
1767 cif_fmt_val &= ~YUV_OUTPUT_422;
1768 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1769 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1770 pcdev->pixfmt = host_pixfmt;
1772 case V4L2_PIX_FMT_NV12:
1773 cif_fmt_val |= YUV_OUTPUT_420;
1774 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1775 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1776 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1777 pcdev->pixfmt = host_pixfmt;
1779 case V4L2_PIX_FMT_NV21:
1780 cif_fmt_val |= YUV_OUTPUT_420;
1781 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1782 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1783 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1784 pcdev->pixfmt = host_pixfmt;
1786 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1787 cif_fmt_val |= YUV_OUTPUT_422;
1792 case V4L2_MBUS_FMT_UYVY8_2X8:
1793 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1795 case V4L2_MBUS_FMT_YUYV8_2X8:
1796 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1798 case V4L2_MBUS_FMT_YVYU8_2X8:
1799 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1801 case V4L2_MBUS_FMT_VYUY8_2X8:
1802 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1805 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1810 rk_camera_cif_reset(pcdev,true);
1812 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1813 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1815 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 */
1817 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1818 /*if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1819 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1821 } else*/{ /* this is one frame mode*/
1822 cif_crop = (rect->left + (rect->top <<16));
1823 cif_fs = (rect->width + (rect->height <<16));
1826 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1827 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1828 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1829 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1831 /*MUST bypass scale */
1832 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1833 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);
1837 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1838 struct soc_camera_format_xlate *xlate)
1840 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1841 struct device *dev = icd->parent;/*yzm*/
1842 int formats = 0, ret;
1843 enum v4l2_mbus_pixelcode code;
1844 const struct soc_mbus_pixelfmt *fmt;
1846 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1849 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); /*call generic_sensor_enum_fmt()*/
1851 /* No more formats */
1854 fmt = soc_mbus_get_fmtdesc(code);
1856 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1860 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1865 case V4L2_MBUS_FMT_UYVY8_2X8:
1866 case V4L2_MBUS_FMT_YUYV8_2X8:
1867 case V4L2_MBUS_FMT_YVYU8_2X8:
1868 case V4L2_MBUS_FMT_VYUY8_2X8:
1871 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1874 xlate->host_fmt = &rk_camera_formats[0];
1877 dev_dbg(dev, "Providing format %s using code %d\n",
1878 rk_camera_formats[0].name,code);
1883 xlate->host_fmt = &rk_camera_formats[1];
1886 dev_dbg(dev, "Providing format %s using code %d\n",
1887 rk_camera_formats[1].name,code);
1892 xlate->host_fmt = &rk_camera_formats[2];
1895 dev_dbg(dev, "Providing format %s using code %d\n",
1896 rk_camera_formats[2].name,code);
1901 xlate->host_fmt = &rk_camera_formats[3];
1904 dev_dbg(dev, "Providing format %s using code %d\n",
1905 rk_camera_formats[3].name,code);
1911 xlate->host_fmt = &rk_camera_formats[4];
1914 dev_dbg(dev, "Providing format %s using code %d\n",
1915 rk_camera_formats[4].name,code);
1919 xlate->host_fmt = &rk_camera_formats[5];
1922 dev_dbg(dev, "Providing format %s using code %d\n",
1923 rk_camera_formats[5].name,code);
1935 static void rk_camera_put_formats(struct soc_camera_device *icd)
1938 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1942 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1944 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1947 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1949 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1952 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1953 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1957 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1959 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1960 struct rk_camera_dev *pcdev = ici->priv;
1962 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1965 spin_lock(&pcdev->cropinfo.lock);
1966 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1967 spin_unlock(&pcdev->cropinfo.lock);
1971 static int rk_camera_set_crop(struct soc_camera_device *icd,
1972 const struct v4l2_crop *crop)
1974 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1975 struct rk_camera_dev *pcdev = ici->priv;
1977 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1980 spin_lock(&pcdev->cropinfo.lock);
1981 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1982 spin_unlock(&pcdev->cropinfo.lock);
1985 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1989 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1992 if (f->fmt.pix.priv == 0xfefe5a5a) {
1996 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1998 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
2000 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
2002 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
2004 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
2006 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
2011 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
2014 static int rk_camera_set_fmt(struct soc_camera_device *icd,
2015 struct v4l2_format *f)
2017 struct device *dev = icd->parent;/*yzm*/
2018 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2019 const struct soc_camera_format_xlate *xlate = NULL;
2020 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2021 struct rk_camera_dev *pcdev = ici->priv;
2022 struct v4l2_pix_format *pix = &f->fmt.pix;
2023 struct v4l2_mbus_framefmt mf;
2024 struct v4l2_rect rect;
2025 int ret,usr_w,usr_h,sensor_w,sensor_h;
2027 int ratio, bounds_aspect;
2029 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2033 usr_h = pix->height;
2035 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
2036 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
2038 dev_err(dev, "Format %x not found\n", pix->pixelformat);
2040 goto RK_CAMERA_SET_FMT_END;
2043 /* ddl@rock-chips.com: sensor init code transmit in here after open */
2044 if (pcdev->icd_init == 0) {
2045 v4l2_subdev_call(sd,core, init, 0); /*call generic_sensor_init()*/
2046 pcdev->icd_init = 1;
2047 return 0; /*directly return !!!!!!*/
2049 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2050 if (stream_on & ENABLE_CAPTURE)
2051 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
2053 mf.width = pix->width;
2054 mf.height = pix->height;
2055 mf.field = pix->field;
2056 mf.colorspace = pix->colorspace;
2057 mf.code = xlate->code;
2058 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
2061 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); /*generic_sensor_s_fmt*/
2062 if (mf.code != xlate->code)
2065 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
2066 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
2067 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
2068 if ((mf.width*10/mf.height) != bounds_aspect) {
2069 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
2070 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
2072 mf.width = pcdev->cropinfo.bounds.width/4;
2073 mf.height = pcdev->cropinfo.bounds.height/4;
2075 mf.field = pix->field;
2076 mf.colorspace = pix->colorspace;
2077 mf.code = xlate->code;
2078 mf.reserved[0] = pix->priv;
2081 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2082 if (mf.code != xlate->code)
2087 sensor_w = mf.width;
2088 sensor_h = mf.height;
2090 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
2093 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
2096 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2098 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2099 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2101 goto RK_CAMERA_SET_FMT_END;
2103 if (unlikely((usr_w <16)||(usr_h < 16))) {
2104 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2106 goto RK_CAMERA_SET_FMT_END;
2109 spin_lock(&pcdev->cropinfo.lock);
2110 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2111 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2112 /*Scale + Crop center is for keep aspect ratio unchange*/
2113 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2114 pcdev->host_width = ratio*usr_w/10;
2115 pcdev->host_height = ratio*usr_h/10;
2116 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2117 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2119 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2120 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2122 /*Scale + crop(user define)*/
2123 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2124 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2125 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2126 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2129 pcdev->host_left &= (~0x01);
2130 pcdev->host_top &= (~0x01);
2132 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2133 /*Crop Center for cif can work , then scale*/
2134 pcdev->host_width = mf.width;
2135 pcdev->host_height = mf.height;
2136 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2137 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2139 /*Crop center for cif can work + crop(user define), then scale */
2140 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2141 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2142 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2143 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2146 pcdev->host_left &= (~0x01);
2147 pcdev->host_top &= (~0x01);
2149 spin_unlock(&pcdev->cropinfo.lock);
2151 spin_lock(&pcdev->cropinfo.lock);
2152 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2153 pcdev->host_width = mf.width;
2154 pcdev->host_height = mf.height;
2155 pcdev->host_left = 0;
2156 pcdev->host_top = 0;
2158 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2159 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2160 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2161 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2163 spin_unlock(&pcdev->cropinfo.lock);
2168 rect.width = pcdev->host_width;
2169 rect.height = pcdev->host_height;
2170 rect.left = pcdev->host_left;
2171 rect.top = pcdev->host_top;
2173 down(&pcdev->zoominfo.sem);
2174 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2175 pcdev->zoominfo.a.c.left = 0;
2176 pcdev->zoominfo.a.c.top = 0;
2177 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2178 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2179 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2180 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2181 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2182 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2183 /*recalculate the CIF width & height*/
2184 rect.width = pcdev->zoominfo.a.c.width ;
2185 rect.height = pcdev->zoominfo.a.c.height;
2186 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2187 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2189 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2190 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2191 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2192 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2193 /*now digital zoom use ipp to do crop and scale*/
2194 if(pcdev->zoominfo.zoom_rate != 100){
2195 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2196 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2198 pcdev->zoominfo.a.c.left = 0;
2199 pcdev->zoominfo.a.c.top = 0;
2201 pcdev->zoominfo.vir_width = pcdev->host_width;
2202 pcdev->zoominfo.vir_height = pcdev->host_height;
2204 up(&pcdev->zoominfo.sem);
2206 /* ddl@rock-chips.com: IPP work limit check */
2207 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2208 if (usr_w > 0x7f0) {
2209 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2210 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));
2212 goto RK_CAMERA_SET_FMT_END;
2215 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2216 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2218 goto RK_CAMERA_SET_FMT_END;
2223 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,
2224 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2225 sensor_w,sensor_h,mf.width,mf.height,
2226 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2227 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2228 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2229 pix->width, pix->height);
2231 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2233 if (CAM_IPPWORK_IS_EN()) {
2234 BUG_ON(pcdev->vipmem_phybase == 0);
2237 pix->height = usr_h;
2238 pix->field = mf.field;
2239 pix->colorspace = mf.colorspace;
2240 icd->current_fmt = xlate;
2241 pcdev->icd_width = mf.width;
2242 pcdev->icd_height = mf.height;
2245 RK_CAMERA_SET_FMT_END:
2246 if (stream_on & ENABLE_CAPTURE)
2247 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2249 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2253 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2254 struct v4l2_format *f)
2256 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2257 struct rk_camera_dev *pcdev = ici->priv;
2258 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2259 const struct soc_camera_format_xlate *xlate;
2260 struct v4l2_pix_format *pix = &f->fmt.pix;
2261 __u32 pixfmt = pix->pixelformat;
2262 int ret,usr_w,usr_h,i;
2263 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2264 bool vipmem_is_overflow = false;
2265 struct v4l2_mbus_framefmt mf;
2266 int bytes_per_line_host;
2269 usr_h = pix->height;
2271 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2273 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2275 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2276 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
2277 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2279 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2280 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2281 for (i = 0; i < icd->num_user_formats; i++)
2282 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2283 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2284 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2285 icd->user_formats[i].host_fmt->name);
2286 goto RK_CAMERA_TRY_FMT_END;
2288 /* limit to rk29 hardware capabilities */
2289 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2290 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2291 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2293 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2295 if (pix->bytesperline < 0)
2296 return pix->bytesperline;
2298 /* limit to sensor capabilities */
2299 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2300 mf.width = pix->width;
2301 mf.height = pix->height;
2302 mf.field = pix->field;
2303 mf.colorspace = pix->colorspace;
2304 mf.code = xlate->code;
2305 /* ddl@rock-chips.com : It is query max resolution only. */
2306 if ((usr_w == 10000) && (usr_h == 10000)) {
2307 mf.reserved[6] = 0xfefe5a5a;
2309 /* call generic_sensor_try_fmt()*/
2310 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2312 goto RK_CAMERA_TRY_FMT_END;
2314 /*query resolution.*/
2315 if((usr_w == 10000) && (usr_h == 10000)) {
2316 pix->width = mf.width;
2317 pix->height = mf.height;
2318 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2319 goto RK_CAMERA_TRY_FMT_END;
2321 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2324 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2325 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2327 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2329 /* Assume preview buffer minimum is 4 */
2330 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2332 if (vipmem_is_overflow == false) {
2334 pix->height = usr_h;
2336 /*RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);*/ /*yzm*/
2337 pix->width = mf.width;
2338 pix->height = mf.height;
2340 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2342 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2343 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2344 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2345 pix->width = mf.width;
2346 pix->height = mf.height;
2352 pix->colorspace = mf.colorspace;
2355 case V4L2_FIELD_ANY:
2356 case V4L2_FIELD_NONE:
2357 pix->field = V4L2_FIELD_NONE;
2360 /* TODO: support interlaced at least in pass-through mode */
2361 dev_err(icd->parent, "Field type %d unsupported.\n",
2363 goto RK_CAMERA_TRY_FMT_END;
2366 RK_CAMERA_TRY_FMT_END:
2368 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2372 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2373 struct v4l2_requestbuffers *p)
2377 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2380 /* This is for locking debugging only. I removed spinlocks and now I
2381 * check whether .prepare is ever called on a linked buffer, or whether
2382 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2383 * it hadn't triggered */
2384 for (i = 0; i < p->count; i++) {
2385 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2386 struct rk_camera_buffer, vb);
2388 INIT_LIST_HEAD(&buf->vb.queue);
2394 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2396 struct soc_camera_device *icd = file->private_data;
2397 struct rk_camera_buffer *buf;
2399 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2402 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2405 poll_wait(file, &buf->vb.done, pt);
2407 if (buf->vb.state == VIDEOBUF_DONE ||
2408 buf->vb.state == VIDEOBUF_ERROR)
2409 return POLLIN|POLLRDNORM;
2414 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2415 * 10 5 1 3 3 3 + 5 < 32
2418 static int rk_camera_querycap(struct soc_camera_host *ici,
2419 struct v4l2_capability *cap)
2421 struct rk_camera_dev *pcdev = ici->priv;
2422 struct rkcamera_platform_data *new_camera;
2423 char orientation[5];
2427 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2430 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2431 memset(orientation,0x00,sizeof(orientation));
2434 new_camera = pcdev->pdata->register_dev_new;
2435 while(new_camera != NULL){
2436 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2437 sprintf(orientation,"-%d",new_camera->orientation);
2438 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2440 new_camera = new_camera->next_camera;
2443 if (orientation[0] != '-') {
2444 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2445 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2446 strcat(cap->card,"-270");
2448 strcat(cap->card,"-90");
2450 strcat(cap->card,orientation);
2453 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2454 cap->version = RK_CAM_VERSION_CODE;
2455 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2456 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2460 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2462 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2463 struct rk_camera_dev *pcdev = ici->priv;
2464 struct v4l2_subdev *sd;
2467 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2470 mutex_lock(&camera_lock);
2471 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2472 rk_camera_s_stream(icd, 0);
2473 sd = soc_camera_to_subdev(icd);
2474 v4l2_subdev_call(sd, video, s_stream, 0);
2475 ret = icd->ops->suspend(icd, state);
2477 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2478 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2479 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2480 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2481 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2482 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2483 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2485 pcdev->reginfo_suspend.Inval = Reg_Validate;
2486 rk_camera_deactivate(pcdev);
2488 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2490 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2492 mutex_unlock(&camera_lock);
2496 static int rk_camera_resume(struct soc_camera_device *icd)
2498 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2499 struct rk_camera_dev *pcdev = ici->priv;
2500 struct v4l2_subdev *sd;
2503 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2506 mutex_lock(&camera_lock);
2507 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2508 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2509 rk_camera_activate(pcdev, icd);
2510 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2511 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2512 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2513 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2514 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2515 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2516 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2517 //rk_videobuf_capture(pcdev->active,pcdev);
2518 rk_videobuf_capture(pcdev->active0,pcdev,0);
2519 rk_videobuf_capture(pcdev->active1,pcdev,1);
2520 rk_camera_s_stream(icd, 1);
2521 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2523 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2524 goto rk_camera_resume_end;
2527 ret = icd->ops->resume(icd);
2528 sd = soc_camera_to_subdev(icd);
2529 v4l2_subdev_call(sd, video, s_stream, 1);
2531 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2533 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2536 rk_camera_resume_end:
2537 mutex_unlock(&camera_lock);
2541 static void rk_camera_reinit_work(struct work_struct *work)
2543 struct v4l2_subdev *sd;
2544 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2545 struct rk_camera_dev *pcdev = camera_work->pcdev;
2546 /*struct soc_camera_link *tmp_soc_cam_link;*/
2547 struct v4l2_mbus_framefmt mf;
2549 unsigned long flags = 0;
2552 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2555 if(pcdev->icd == NULL)
2557 sd = soc_camera_to_subdev(pcdev->icd);
2558 /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2561 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2562 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2563 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2564 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2565 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2566 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2567 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2568 if(CHIP_NAME == 3368)
2569 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",rk3368_read_cru_reg(CRU_PCLK_REG30));
2571 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2572 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2574 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2575 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2576 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2577 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2578 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2579 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2580 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2581 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2582 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2585 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2586 if (pcdev->reinit_times == 1) {
2587 if (ctrl & ENABLE_CAPTURE) {
2588 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2589 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2590 rk_camera_cif_reset(pcdev,false);
2593 v4l2_subdev_call(sd,core, init, 0);
2595 mf.width = pcdev->icd_width;
2596 mf.height = pcdev->icd_height;
2597 mf.field = V4L2_FIELD_NONE;
2598 mf.code = pcdev->icd->current_fmt->code;
2599 mf.reserved[0] = 0x5a5afefe;
2602 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2604 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2605 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2606 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2607 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2608 rk_camera_cif_reset(pcdev,false);
2609 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2614 atomic_set(&pcdev->stop_cif,true);
2615 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2616 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2618 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2619 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2620 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2621 if (NULL == pcdev->video_vq->bufs[index])
2624 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2625 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2626 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2627 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2628 printk("wake up video buffer index = %d !!!\n",index);
2631 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2633 RKCAMERA_TR("video queue has somthing wrong !!\n");
2636 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2638 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2640 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2641 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2642 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2644 /*static unsigned int last_fps = 0;*/
2645 /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
2646 /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2648 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2650 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2651 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2652 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2653 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2654 pcdev->camera_reinit_work.pcdev = pcdev;
2655 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2656 pcdev->reinit_times++;
2657 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));//Æô¶¯¹¤×÷¶ÓÁжÔÓ¦µÄº¯Êý
2658 } else if(!pcdev->timer_get_fps) {
2659 pcdev->timer_get_fps = true;
2660 for (i=0; i<2; i++) {
2661 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2662 fival_nxt = pcdev->icd_frmival[i].fival_list;
2667 fival_pre = fival_nxt;
2668 while (fival_nxt != NULL) {
2670 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
2671 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2672 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2673 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2674 fival_nxt->fival.discrete.numerator);
2676 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2677 && (fival_nxt->fival.height == pcdev->icd->user_height)
2678 && (fival_nxt->fival.width == pcdev->icd->user_width))
2679 || (fival_nxt->fival.discrete.denominator == 0)) {
2681 if (fival_nxt->fival.discrete.denominator == 0) {
2682 fival_nxt->fival.index = 0;
2683 fival_nxt->fival.width = pcdev->icd->user_width;
2684 fival_nxt->fival.height= pcdev->icd->user_height;
2685 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2686 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2687 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2688 |(pcdev->icd_height);
2689 fival_nxt->fival.discrete.numerator = 1000000;
2690 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2693 fival_rec = fival_nxt;
2695 fival_pre = fival_nxt;
2696 fival_nxt = fival_nxt->nxt;
2699 if ((rec_flag == 0) && fival_pre) {
2700 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2701 if (fival_pre->nxt != NULL) {
2702 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2703 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2704 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2705 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2707 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2708 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2709 |(pcdev->icd_height);
2710 fival_pre->nxt->fival.discrete.numerator = 1000000;
2711 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2713 fival_rec = fival_pre->nxt;
2718 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2719 pcdev->reinit_times = 0;
2721 pcdev->last_fps = pcdev->fps ;
2722 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2723 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2724 /*return HRTIMER_NORESTART;*/
2725 if(pcdev->reinit_times >=2)
2726 return HRTIMER_NORESTART;
2728 return HRTIMER_RESTART;
2730 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2732 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2733 struct rk_camera_dev *pcdev = ici->priv;
2736 unsigned long flags;
2738 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2740 WARN_ON(pcdev->icd != icd);
2742 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2745 pcdev->last_fps = 0;
2746 pcdev->frame_interval = 0;
2747 hrtimer_cancel(&(pcdev->fps_timer.timer));
2748 pcdev->fps_timer.pcdev = pcdev;
2749 pcdev->timer_get_fps = false;
2750 pcdev->reinit_times = 0;
2752 spin_lock_irqsave(&pcdev->lock,flags);
2753 atomic_set(&pcdev->stop_cif,false);
2754 pcdev->irqinfo.cifirq_idx = 0;
2755 pcdev->irqinfo.cifirq_normal_idx = 0;
2756 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2757 pcdev->irqinfo.dmairq_idx = 0;
2759 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2760 cif_ctrl_val |= ENABLE_CAPTURE;
2761 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2762 spin_unlock_irqrestore(&pcdev->lock,flags);
2763 printk("%s:stream enable CIF_CIF_CTRL 0x%lx\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2764 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2765 pcdev->fps_timer.istarted = true;
2767 /*cancel timer before stop cif*/
2768 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2769 pcdev->fps_timer.istarted = false;
2770 flush_work(&(pcdev->camera_reinit_work.work));
2772 cif_ctrl_val &= ~ENABLE_CAPTURE;
2773 spin_lock_irqsave(&pcdev->lock, flags);
2774 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2775 atomic_set(&pcdev->stop_cif,true);
2776 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2777 spin_unlock_irqrestore(&pcdev->lock, flags);
2778 flush_workqueue((pcdev->camera_wq));
2781 /*must be reinit,or will be somthing wrong in irq process.*/
2782 if(enable == false) {
2783 //pcdev->active = NULL;
2784 pcdev->active0 = NULL;
2785 pcdev->active1 = NULL;
2786 pcdev->active_buf = 0;
2787 INIT_LIST_HEAD(&pcdev->capture);
2789 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2792 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2794 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2795 struct rk_camera_dev *pcdev = ici->priv;
2796 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2797 struct rk_camera_frmivalenum *fival_list = NULL;
2798 struct v4l2_frmivalenum *fival_head = NULL;
2799 struct rkcamera_platform_data *new_camera;
2800 int i,ret = 0,index;
2801 const struct soc_camera_format_xlate *xlate;
2802 struct v4l2_mbus_framefmt mf;
2805 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2807 index = fival->index & 0x00ffffff;
2808 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2809 for (i=0; i<2; i++) {
2810 if (pcdev->icd_frmival[i].icd == icd) {
2811 fival_list = pcdev->icd_frmival[i].fival_list;
2815 if (fival_list != NULL) {
2817 while (fival_list != NULL) {
2818 if ((fival->pixel_format == fival_list->fival.pixel_format)
2819 && (fival->height == fival_list->fival.height)
2820 && (fival->width == fival_list->fival.width)) {
2825 fival_list = fival_list->nxt;
2828 if ((i==index) && (fival_list != NULL)) {
2829 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2834 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2841 while (fival_head->width && fival_head->height) {
2842 if ((fival->pixel_format == fival_head->pixel_format)
2843 && (fival->height == fival_head->height)
2844 && (fival->width == fival_head->width)) {
2853 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2854 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2856 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2857 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2858 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2859 mf.width = fival->width;
2860 mf.height = fival->height;
2861 mf.code = xlate->code;
2863 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2865 fival->reserved[1] = (mf.width<<16)|(mf.height);
2867 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2868 fival->width, fival->height,
2869 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2870 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2871 fival->discrete.denominator,fival->discrete.numerator);
2874 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2875 fival->width,fival->height,
2876 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2877 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2880 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2881 fival->width,fival->height,
2882 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2883 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2886 goto rk_camera_enum_frameintervals_end;
2890 new_camera = pcdev->pdata->register_dev_new;
2891 while(new_camera != NULL){
2892 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2896 new_camera = new_camera->next_camera;
2900 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2901 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2904 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2905 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2906 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2907 mf.width = fival->width;
2908 mf.height = fival->height;
2909 mf.code = xlate->code;
2911 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2913 fival->discrete.numerator= 1000;
2914 fival->discrete.denominator = 15000;
2915 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2916 fival->reserved[1] = (mf.width<<16)|(mf.height);
2920 rk_camera_enum_frameintervals_end:
2924 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2925 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2928 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2929 struct rk_camera_dev *pcdev = ici->priv;
2931 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2935 unsigned long tmp_cifctrl;
2938 /*change the crop and scale parameters*/
2941 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2942 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2943 a.c.width = pcdev->host_width*100/zoom_rate;
2944 a.c.width &= ~CROP_ALIGN_BYTES;
2945 a.c.height = pcdev->host_height*100/zoom_rate;
2946 a.c.height &= ~CROP_ALIGN_BYTES;
2947 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2948 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2949 atomic_set(&pcdev->stop_cif,true);
2950 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2951 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2952 hrtimer_cancel(&(pcdev->fps_timer.timer));
2953 flush_workqueue((pcdev->camera_wq));
2955 down(&pcdev->zoominfo.sem);
2956 pcdev->zoominfo.a.c.left = 0;
2957 pcdev->zoominfo.a.c.top = 0;
2958 pcdev->zoominfo.a.c.width = a.c.width;
2959 pcdev->zoominfo.a.c.height = a.c.height;
2960 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2961 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2962 pcdev->frame_inval = 1;
2963 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2964 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2965 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2966 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2968 //rk_videobuf_capture(pcdev->active,pcdev);
2970 rk_videobuf_capture(pcdev->active0,pcdev,0);
2972 rk_videobuf_capture(pcdev->active1,pcdev,1);
2973 if(tmp_cifctrl & ENABLE_CAPTURE)
2974 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2975 up(&pcdev->zoominfo.sem);
2977 atomic_set(&pcdev->stop_cif,false);
2978 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2979 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 );
2981 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2982 a.c.width = pcdev->host_width*100/zoom_rate;
2983 a.c.width &= ~CROP_ALIGN_BYTES;
2984 a.c.height = pcdev->host_height*100/zoom_rate;
2985 a.c.height &= ~CROP_ALIGN_BYTES;
2986 a.c.left = (pcdev->host_width - a.c.width)>>1;
2987 a.c.top = (pcdev->host_height - a.c.height)>>1;
2989 down(&pcdev->zoominfo.sem);
2990 pcdev->zoominfo.a.c.height = a.c.height;
2991 pcdev->zoominfo.a.c.width = a.c.width;
2992 pcdev->zoominfo.a.c.top = a.c.top;
2993 pcdev->zoominfo.a.c.left = a.c.left;
2994 pcdev->zoominfo.vir_width = pcdev->host_width;
2995 pcdev->zoominfo.vir_height= pcdev->host_height;
2996 up(&pcdev->zoominfo.sem);
2998 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 );
3004 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
3005 struct soc_camera_host_ops *ops, int id)
3009 for (i = 0; i < ops->num_controls; i++)
3010 if (ops->controls[i].id == id)
3011 return &ops->controls[i];
3017 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
3018 struct v4l2_control *sctrl)
3020 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
3021 const struct v4l2_queryctrl *qctrl;
3022 struct rk_camera_dev *pcdev = ici->priv;
3026 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3028 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
3031 goto rk_camera_set_ctrl_end;
3036 case V4L2_CID_ZOOM_ABSOLUTE:
3038 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
3040 goto rk_camera_set_ctrl_end;
3042 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
3044 pcdev->zoominfo.zoom_rate = sctrl->value;
3046 goto rk_camera_set_ctrl_end;
3054 rk_camera_set_ctrl_end:
3058 static struct soc_camera_host_ops rk_soc_camera_host_ops =
3060 .owner = THIS_MODULE,
3061 .add = rk_camera_add_device,
3062 .remove = rk_camera_remove_device,
3063 .suspend = rk_camera_suspend,
3064 .resume = rk_camera_resume,
3065 .enum_frameinervals = rk_camera_enum_frameintervals,
3066 .cropcap = rk_camera_cropcap,
3067 .set_crop = rk_camera_set_crop,
3068 .get_crop = rk_camera_get_crop,
3069 .get_formats = rk_camera_get_formats,
3070 .put_formats = rk_camera_put_formats,
3071 .set_fmt = rk_camera_set_fmt,
3072 .try_fmt = rk_camera_try_fmt,
3073 .init_videobuf = rk_camera_init_videobuf,
3074 .reqbufs = rk_camera_reqbufs,
3075 .poll = rk_camera_poll,
3076 .querycap = rk_camera_querycap,
3077 .set_bus_param = rk_camera_set_bus_param,
3078 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
3079 .set_ctrl = rk_camera_set_ctrl,
3080 .controls = rk_camera_controls,
3081 .num_controls = ARRAY_SIZE(rk_camera_controls)
3084 /**********yzm***********/
3085 static int rk_camera_cif_iomux(struct device *dev)
3088 struct pinctrl *pinctrl;
3089 struct pinctrl_state *state;
3091 char state_str[20] = {0};
3093 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3094 if(CHIP_NAME == 3368)
3095 strcpy(state_str,"cif_pin_all");
3097 strcpy(state_str,"cif_pin_jpe");
3099 /*__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);*/
3104 pinctrl = devm_pinctrl_get(dev);
3105 if (IS_ERR(pinctrl)) {
3106 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
3109 state = pinctrl_lookup_state(pinctrl,
3112 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
3116 if (!IS_ERR(state)) {
3117 retval = pinctrl_select_state(pinctrl, state);
3120 "%s:could not set %s pins\n",__func__,state_str);
3128 /***********yzm***********/
3129 static int rk_camera_probe(struct platform_device *pdev)
3131 struct rk_camera_dev *pcdev;
3132 struct resource *res;
3133 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3136 struct rk_cif_clk *clk=NULL;
3137 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
3139 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3141 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3142 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3144 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3145 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3149 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3150 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3154 /***********yzm**********/
3155 rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3157 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3158 irq = platform_get_irq(pdev, 0);
3160 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3161 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3162 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3164 if (!res || irq < 0) {
3168 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3170 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3175 pcdev->zoominfo.zoom_rate = 100;
3176 pcdev->hostid = pdev->id; /* get host id*/
3177 #ifdef CONFIG_SOC_RK3028
3178 pcdev->chip_id = rk3028_version_val();
3180 pcdev->chip_id = -1;
3183 /***********yzm***********/
3185 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3187 if(CHIP_NAME != 3368)
3188 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3189 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3190 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3191 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3192 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3193 //spin_lock_init(&cif_clk[0].lock);
3194 cif_clk[0].on = false;
3195 rk_camera_cif_iomux(dev_cif);/*yzm*/
3198 if(CHIP_NAME != 3368)
3199 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only yzm*/
3200 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3201 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3202 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3203 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3204 //spin_lock_init(&cif_clk[1].lock);
3205 cif_clk[1].on = false;
3206 rk_camera_cif_iomux(dev_cif);/*yzm*/
3209 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3211 /***********yzm**********/
3212 dev_set_drvdata(&pdev->dev, pcdev);
3214 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3215 /*= rk_camera_platform_data */
3216 if (pcdev->pdata && pcdev->pdata->io_init) {
3218 pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
3220 if (pcdev->pdata->sensor_mclk == NULL)
3221 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3224 INIT_LIST_HEAD(&pcdev->capture);
3225 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3226 spin_lock_init(&pcdev->lock);
3227 spin_lock_init(&pcdev->camera_work_lock);
3229 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3230 spin_lock_init(&pcdev->cropinfo.lock);
3231 sema_init(&pcdev->zoominfo.sem,1);
3234 * Request the regions.
3237 if (!request_mem_region(res->start, res->end - res->start + 1,
3238 RK29_CAM_DRV_NAME)) {
3240 goto exit_reqmem_vip;
3242 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3243 if (pcdev->base == NULL) {
3244 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3246 goto exit_ioremap_vip;
3250 pcdev->irqinfo.irq = irq;
3251 pcdev->dev = &pdev->dev;
3253 /* config buffer address */
3256 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3259 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3265 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3267 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3269 if (pcdev->camera_wq == NULL) {
3270 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3274 pcdev->camera_reinit_work.pcdev = pcdev;
3275 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3277 for (i=0; i<2; i++) {
3278 pcdev->icd_frmival[i].icd = NULL;
3279 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3282 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3283 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3284 pcdev->soc_host.priv = pcdev; /*to itself,csll in rk_camera_add_device*/
3285 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3286 pcdev->soc_host.nr = pdev->id;
3287 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3288 err = soc_camera_host_register(&pcdev->soc_host);
3292 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3295 pcdev->fps_timer.pcdev = pcdev;
3296 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3297 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3298 pcdev->icd_cb.sensor_cb = NULL;
3300 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3301 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3302 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3303 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3304 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3305 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3306 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3307 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3313 for (i=0; i<2; i++) {
3314 fival_list = pcdev->icd_frmival[i].fival_list;
3315 fival_nxt = fival_list;
3316 while(fival_nxt != NULL) {
3317 fival_nxt = fival_list->nxt;
3319 fival_list = fival_nxt;
3323 free_irq(pcdev->irqinfo.irq, pcdev);
3324 if (pcdev->camera_wq) {
3325 destroy_workqueue(pcdev->camera_wq);
3326 pcdev->camera_wq = NULL;
3329 iounmap(pcdev->base);
3331 release_mem_region(res->start, res->end - res->start + 1);
3334 if(CHIP_NAME != 3368){
3336 clk_put(clk->pd_cif);
3339 clk_put(clk->aclk_cif);
3341 clk_put(clk->hclk_cif);
3342 if (clk->cif_clk_in)
3343 clk_put(clk->cif_clk_in);
3344 if (clk->cif_clk_out)
3345 clk_put(clk->cif_clk_out);
3354 static int __exit rk_camera_remove(struct platform_device *pdev)
3356 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3357 struct resource *res;
3358 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3361 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3364 free_irq(pcdev->irqinfo.irq, pcdev);
3366 if (pcdev->camera_wq) {
3367 destroy_workqueue(pcdev->camera_wq);
3368 pcdev->camera_wq = NULL;
3371 for (i=0; i<2; i++) {
3372 fival_list = pcdev->icd_frmival[i].fival_list;
3373 fival_nxt = fival_list;
3374 while(fival_nxt != NULL) {
3375 fival_nxt = fival_list->nxt;
3377 fival_list = fival_nxt;
3381 soc_camera_host_unregister(&pcdev->soc_host);
3384 iounmap((void __iomem*)pcdev->base);
3385 release_mem_region(res->start, res->end - res->start + 1);
3386 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3387 pcdev->pdata->io_deinit(0);
3388 pcdev->pdata->io_deinit(1);
3393 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3398 static struct platform_driver rk_camera_driver =
3401 .name = RK29_CAM_DRV_NAME, /*host */
3403 .probe = rk_camera_probe,
3404 .remove = (rk_camera_remove),
3407 static int rk_camera_init_async(void *unused)
3410 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3411 platform_driver_register(&rk_camera_driver);
3415 static int __init rk_camera_init(void)
3418 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3420 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3425 static void __exit rk_camera_exit(void)
3427 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3429 platform_driver_unregister(&rk_camera_driver);
3432 device_initcall_sync(rk_camera_init);
3433 module_exit(rk_camera_exit);
3435 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3436 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3437 MODULE_LICENSE("GPL");