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)
161 #define MIN(x,y) ((x<y) ? x: y)
162 #define MAX(x,y) ((x>y) ? x: y)
163 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
164 #define RK_SENSOR_48MHZ 48
166 #define __raw_readl(p) (*(unsigned long *)(p))
167 #define __raw_writel(v,p) (*(unsigned long *)(p) = (v))
169 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
170 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
171 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
174 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
176 #define CRU_PCLK_REG30 0xbc
177 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
178 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
179 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
180 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
182 #define CRU_CIF_RST_REG30 0x128
183 #define MASK_RST_CIF0 (0x01 << 30)
184 #define MASK_RST_CIF1 (0x01 << 31)
185 #define RQUEST_RST_CIF0 (0x01 << 14)
186 #define RQUEST_RST_CIF1 (0x01 << 15)
188 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
189 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
190 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
193 /*********yzm**********/
195 static u32 CRU_PCLK_REG30;
196 static u32 CRU_CLK_OUT;
197 static u32 clk_cif_out_src_gate_en;
198 static u32 CRU_CLKSEL29_CON;
199 static u32 cif0_clk_sel;
200 static u32 ENANABLE_INVERT_PCLK_CIF0;
201 static u32 DISABLE_INVERT_PCLK_CIF0;
202 static u32 ENANABLE_INVERT_PCLK_CIF1;
203 static u32 DISABLE_INVERT_PCLK_CIF1;
204 static u32 CHIP_NAME;
206 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK_CRU_VIRT)
207 #define read_cru_reg(addr) __raw_readl(addr+RK_CRU_VIRT)
208 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
209 /*********yzm*********end*/
211 #if defined(CONFIG_ARCH_RK2928)
212 #define write_cru_reg(addr, val)
213 #define read_cru_reg(addr) 0
214 #define mask_cru_reg(addr, msk, val)
219 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
221 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
222 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
223 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
224 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
225 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
228 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
229 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
230 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
232 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
233 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
234 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
236 #define write_grf_reg(addr, val)
237 #define read_grf_reg(addr) 0
238 #define mask_grf_reg(addr, msk, val)
241 #define CAM_WORKQUEUE_IS_EN() (true)
242 #define CAM_IPPWORK_IS_EN() (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
244 #define IS_CIF0() (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
245 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
246 #define CROP_ALIGN_BYTES (0x03)
247 #define CIF_DO_CROP 0
248 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
249 #define CROP_ALIGN_BYTES (0x0f)
250 #define CIF_DO_CROP 0
251 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
252 #define CROP_ALIGN_BYTES (0x03)
253 #define CIF_DO_CROP 0
254 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
255 #define CROP_ALIGN_BYTES (0x0F)
256 #define CIF_DO_CROP 1
260 *v0.1.0 : this driver is 3.10 kernel driver;
261 copy and updata from v0.3.0x19;
264 1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
265 cause warning, so remove this spin lock .
267 1. rk3126 and rk3128 use different dts file.
269 1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
271 1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk
273 1. Improve the code to support all configuration.reset,af,flash...
275 1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
277 1. Add power and powerdown controled by PMU.
279 1. Support front and rear camera support are the same.
281 1. Support pingpong mode.
282 2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0
283 3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
284 4. Support flash control when preview size == picture size
286 1. Support rk3288 cif driver
287 2. Query and upload iommu info
289 1. Vpu_service compatible has change ,fix it.
291 1. setting cif capture en bit can't stop cif really,reset cif instead.
293 1. use of_find_node_by_name to get vpu node instead of of_find_compatible_node
295 1. support focus mode.
297 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0xe)
298 static int version = RK_CAM_VERSION_CODE;
299 module_param(version, int, S_IRUGO);
301 /* limit to rk29 hardware capabilities */
302 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
303 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
304 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
305 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
306 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
307 V4L2_MBUS_PCLK_SAMPLE_RISING |\
308 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
309 V4L2_MBUS_DATA_ACTIVE_HIGH |\
310 V4L2_MBUS_DATA_ACTIVE_LOW|\
311 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
312 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
314 #define RK_CAM_W_MIN 48
315 #define RK_CAM_H_MIN 32
316 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
317 #define RK_CAM_H_MAX 2764
318 #define RK_CAM_FRAME_INVAL_INIT 0
319 #define RK_CAM_FRAME_INVAL_DC 0 /* ddl@rock-chips.com : */
320 #define RK30_CAM_FRAME_MEASURE 5
323 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
324 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
325 /* buffer for one video frame */
326 struct rk_camera_buffer
328 /* common v4l buffer stuff -- must be first */
329 struct videobuf_buffer vb;
330 enum v4l2_mbus_pixelcode code;
333 enum rk_camera_reg_state
341 unsigned int cifCtrl;
342 unsigned int cifCrop;
344 unsigned int cifIntEn;
346 unsigned int cifVirWidth;
347 unsigned int cifScale;
348 /* unsigned int VipCrm;*/
349 enum rk_camera_reg_state Inval;
351 struct rk_camera_work
353 struct videobuf_buffer *vb;
354 struct rk_camera_dev *pcdev;
355 struct work_struct work;
356 struct list_head queue;
359 struct rk_camera_frmivalenum
361 struct v4l2_frmivalenum fival;
362 struct rk_camera_frmivalenum *nxt;
364 struct rk_camera_frmivalinfo
366 struct soc_camera_device *icd;
367 struct rk_camera_frmivalenum *fival_list;
369 struct rk_camera_zoominfo
371 struct semaphore sem;
377 #if CAMERA_VIDEOBUF_ARM_ACCESS
378 struct rk29_camera_vbinfo
380 unsigned int phy_addr;
381 void __iomem *vir_addr;
385 struct rk_camera_timer{
386 struct rk_camera_dev *pcdev;
387 struct hrtimer timer;
392 /************must modify start************/
394 struct clk *aclk_cif;
395 struct clk *hclk_cif;
396 struct clk *cif_clk_in;
397 struct clk *cif_clk_out;
398 /************must modify end************/
408 struct v4l2_rect bounds;
411 struct rk_cif_irqinfo
414 unsigned long cifirq_idx;
415 unsigned long cifirq_normal_idx;
416 unsigned long cifirq_abnormal_idx;
418 unsigned long dmairq_idx;
424 struct soc_camera_host soc_host;
426 /* RK2827x is only supposed to handle one camera on its Quick Capture
427 * interface. If anyone ever builds hardware to enable more than
428 * one camera, they will have to modify this driver too */
429 struct soc_camera_device *icd;
431 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
434 unsigned int last_fps;
435 unsigned long frame_interval;
438 unsigned int vipmem_phybase;
439 void __iomem *vipmem_virbase;
440 unsigned int vipmem_size;
441 unsigned int vipmem_bsize;
442 #if CAMERA_VIDEOBUF_ARM_ACCESS
443 struct rk29_camera_vbinfo *vbinfo;
444 unsigned int vbinfo_count;
448 int host_left; /*sensor output size ?*/
454 struct rk_cif_crop cropinfo;
455 struct rk_cif_irqinfo irqinfo;
457 struct rk29camera_platform_data *pdata;
458 struct resource *res;
459 struct list_head capture;
460 struct rk_camera_zoominfo zoominfo;
464 struct videobuf_buffer *active;
465 struct rk_camera_reg reginfo_suspend;
466 struct workqueue_struct *camera_wq;
467 struct rk_camera_work *camera_work;
468 struct list_head camera_work_queue;
469 spinlock_t camera_work_lock;
470 unsigned int camera_work_count;
471 struct rk_camera_timer fps_timer;
472 struct rk_camera_work camera_reinit_work;
474 rk29_camera_sensor_cb_s icd_cb;
475 struct rk_camera_frmivalinfo icd_frmival[2];
477 unsigned int reinit_times;
478 struct videobuf_queue *video_vq;
480 wait_queue_head_t cif_stop_done;
481 volatile bool cif_stopped;
482 struct timeval first_tv;
487 static const struct v4l2_queryctrl rk_camera_controls[] =
490 .id = V4L2_CID_ZOOM_ABSOLUTE,
491 .type = V4L2_CTRL_TYPE_INTEGER,
492 .name = "DigitalZoom Control",
496 .default_value = 100,
500 static struct rk_cif_clk cif_clk[2];
502 static DEFINE_MUTEX(camera_lock);
503 static const char *rk_cam_driver_description = "RK_Camera";
505 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
506 static void rk_camera_capture_process(struct work_struct *work);
508 static void rk_camera_diffchips(const char *rockchip_name)
510 if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
512 CRU_PCLK_REG30 = 0xbc;
513 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
514 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7));
515 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
516 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
519 clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7));
520 CRU_CLKSEL29_CON = 0xb8;
521 cif0_clk_sel = ((0x1<<23)|(0x0<<7));
525 else if(strstr(rockchip_name,"3288"))
527 CRU_PCLK_REG30 = 0xd4;
528 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x1<<4));
529 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x0<<4));
530 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
531 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
539 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
541 void __iomem *reg = RK_CRU_VIRT + RK_CRU_SOFTRST_CON;
543 if(CHIP_NAME == 3126){
544 val = on ? 0x10001U << 14 : 0x10000U << 14;
545 }else if(CHIP_NAME == 3288){
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(CHIP_NAME == 3126){
558 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
559 }else if(CHIP_NAME == 3288){
560 RK_CRU_SOFTRST_CON = RK3288_CRU_SOFTRSTS_CON(6);
563 if (only_rst == true) {
564 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
566 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
568 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
569 if (ctrl_reg & ENABLE_CAPTURE) {
570 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
572 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
573 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
574 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
575 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
576 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
577 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
578 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
579 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
581 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
583 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
585 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
586 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
587 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
588 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
589 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
590 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
591 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
592 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
593 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
600 * Videobuf operations
602 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
605 struct soc_camera_device *icd = vq->priv_data;
606 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
607 struct rk_camera_dev *pcdev = ici->priv;
609 struct rk_camera_work *wk;
611 struct soc_mbus_pixelfmt fmt;
613 int bytes_per_line_host;
614 fmt.packing = SOC_MBUS_PACKING_1_5X8;
616 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
619 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
620 icd->current_fmt->host_fmt);
621 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
622 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
624 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
625 bytes_per_line_host = pcdev->host_width*3;
627 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
628 icd->current_fmt->host_fmt);
629 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
631 if (bytes_per_line_host < 0)
632 return bytes_per_line_host;
634 /* planar capture requires Y, U and V buffers to be page aligned */
635 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
636 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
638 if (CAM_WORKQUEUE_IS_EN()) {
640 if (CAM_IPPWORK_IS_EN()) {
641 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
642 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
643 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
647 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
648 kfree(pcdev->camera_work);
649 pcdev->camera_work = NULL;
650 pcdev->camera_work_count = 0;
653 if (pcdev->camera_work == NULL) {
654 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
655 if (pcdev->camera_work == NULL) {
656 RKCAMERA_TR("kmalloc failed\n");
659 INIT_LIST_HEAD(&pcdev->camera_work_queue);
661 for (i=0; i<(*count); i++) {
663 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
666 pcdev->camera_work_count = (*count);
668 #if CAMERA_VIDEOBUF_ARM_ACCESS
669 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
670 kfree(pcdev->vbinfo);
671 pcdev->vbinfo = NULL;
672 pcdev->vbinfo_count = 0x00;
675 if (pcdev->vbinfo == NULL) {
676 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
677 if (pcdev->vbinfo == NULL) {
678 RKCAMERA_TR("vbinfo kmalloc fail\n");
681 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
682 pcdev->vbinfo_count = *count;
686 pcdev->video_vq = vq;
687 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
691 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
693 struct soc_camera_device *icd = vq->priv_data;
695 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
698 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
699 &buf->vb, buf->vb.baddr, buf->vb.bsize);
701 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
702 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
708 * This waits until this buffer is out of danger, i.e., until it is no
709 * longer in STATE_QUEUED or STATE_ACTIVE
711 videobuf_waiton(vq, &buf->vb, 0, 0);
712 videobuf_dma_contig_free(vq, &buf->vb);
713 /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
714 buf->vb.state = VIDEOBUF_NEEDS_INIT;
717 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
719 struct soc_camera_device *icd = vq->priv_data;
720 struct rk_camera_buffer *buf;
722 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
723 icd->current_fmt->host_fmt);
725 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
727 if ((bytes_per_line < 0) || (vb->boff == 0))
730 buf = container_of(vb, struct rk_camera_buffer, vb);
732 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
733 /* vb, vb->baddr, vb->bsize);*/ /*yzm*/
735 /* Added list head initialization on alloc */
736 WARN_ON(!list_empty(&vb->queue));
738 BUG_ON(NULL == icd->current_fmt);
740 if (buf->code != icd->current_fmt->code ||
741 vb->width != icd->user_width ||
742 vb->height != icd->user_height ||
743 vb->field != field) {
744 buf->code = icd->current_fmt->code;
745 vb->width = icd->user_width;
746 vb->height = icd->user_height;
748 vb->state = VIDEOBUF_NEEDS_INIT;
751 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
752 if (0 != vb->baddr && vb->bsize < vb->size) {
757 if (vb->state == VIDEOBUF_NEEDS_INIT) {
758 ret = videobuf_iolock(vq, vb, NULL);
762 vb->state = VIDEOBUF_PREPARED;
767 rk_videobuf_free(vq, buf);
772 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
774 unsigned int y_addr,uv_addr;
775 struct rk_camera_dev *pcdev = rk_pcdev;
777 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
781 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
782 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
783 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
784 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
785 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
786 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
791 uv_addr = y_addr + vb->width * vb->height;
793 #if defined(CONFIG_ARCH_RK3188)
794 rk_camera_cif_reset(pcdev,false);
796 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
797 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
798 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
799 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
800 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
803 /* Locking: Caller holds q->irqlock */
804 static void rk_videobuf_queue(struct videobuf_queue *vq,
805 struct videobuf_buffer *vb)
807 struct soc_camera_device *icd = vq->priv_data;
808 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
809 struct rk_camera_dev *pcdev = ici->priv;
810 #if CAMERA_VIDEOBUF_ARM_ACCESS
811 struct rk29_camera_vbinfo *vb_info;
815 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
817 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
818 vb, vb->baddr, vb->bsize); */ /*yzm*/
820 vb->state = VIDEOBUF_QUEUED;
821 if (list_empty(&pcdev->capture)) {
822 list_add_tail(&vb->queue, &pcdev->capture);
824 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
825 list_add_tail(&vb->queue, &pcdev->capture);
827 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
829 #if CAMERA_VIDEOBUF_ARM_ACCESS
831 vb_info = pcdev->vbinfo+vb->i;
832 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
833 if (vb_info->vir_addr) {
834 iounmap(vb_info->vir_addr);
835 release_mem_region(vb_info->phy_addr, vb_info->size);
836 vb_info->vir_addr = NULL;
837 vb_info->phy_addr = 0x00;
838 vb_info->size = 0x00;
841 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
842 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
845 if (vb_info->vir_addr) {
846 vb_info->size = vb->bsize;
847 vb_info->phy_addr = vb->boff;
849 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
854 if (!pcdev->active) {
856 rk_videobuf_capture(vb,pcdev);
857 if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
858 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
863 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
864 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
867 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
871 case V4L2_PIX_FMT_YUV420:
872 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.*/
873 case V4L2_PIX_FMT_YUYV:
875 *ippfmt = RK_FORMAT_YCbCr_420_SP;
878 case V4L2_PIX_FMT_YVU420:
879 case V4L2_PIX_FMT_VYUY:
880 case V4L2_PIX_FMT_YVYU:
882 *ippfmt = RK_FORMAT_YCrCb_420_SP;
885 case V4L2_PIX_FMT_RGB565:
887 *ippfmt = RK_FORMAT_RGB_565;
890 case V4L2_PIX_FMT_RGB24:
892 *ippfmt = RK_FORMAT_RGB_888;
896 goto rk_pixfmt2rgafmt_err;
900 rk_pixfmt2rgafmt_err:
904 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
905 static int rk_camera_scale_crop_pp(struct work_struct *work){
906 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
907 struct videobuf_buffer *vb = camera_work->vb;
908 struct rk_camera_dev *pcdev = camera_work->pcdev;
910 unsigned long int flags;
918 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
919 extern rga_service_info rga_service;
920 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
921 extern void rga_service_session_clear(rga_session *session);
922 static int rk_camera_scale_crop_rga(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;
933 const struct soc_mbus_pixelfmt *fmt;
936 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
943 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
945 static int rk_camera_scale_crop_ipp(struct work_struct *work)
951 static void rk_camera_capture_process(struct work_struct *work)
953 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
954 struct videobuf_buffer *vb = camera_work->vb;
955 struct rk_camera_dev *pcdev = camera_work->pcdev;
956 /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code; */
957 unsigned long flags = 0;
960 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
963 if (atomic_read(&pcdev->stop_cif)==true) {
965 goto rk_camera_capture_process_end;
968 if (!CAM_WORKQUEUE_IS_EN()) {
970 goto rk_camera_capture_process_end;
973 down(&pcdev->zoominfo.sem);
974 if (pcdev->icd_cb.scale_crop_cb){
975 err = (pcdev->icd_cb.scale_crop_cb)(work);
977 up(&pcdev->zoominfo.sem);
979 if (pcdev->icd_cb.sensor_cb)
980 (pcdev->icd_cb.sensor_cb)(vb);
982 rk_camera_capture_process_end:
984 vb->state = VIDEOBUF_ERROR;
986 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
987 vb->state = VIDEOBUF_DONE;
991 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
992 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
993 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
994 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
998 static void rk_camera_cifrest_delay(struct work_struct *work)
1000 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1001 struct rk_camera_dev *pcdev = camera_work->pcdev;
1002 unsigned long flags = 0;
1004 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1008 rk_camera_cif_reset(pcdev,false);
1010 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1011 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1012 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1014 spin_lock_irqsave(&pcdev->lock,flags);
1015 if (atomic_read(&pcdev->stop_cif) == false) {
1016 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
1017 RKCAMERA_DG2("After reset cif, enable capture again!\n");
1019 spin_unlock_irqrestore(&pcdev->lock,flags);
1023 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
1025 struct rk_camera_dev *pcdev = data;
1026 struct rk_camera_work *wk;
1027 unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
1029 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1032 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1034 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1035 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
1036 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
1038 pcdev->irqinfo.cifirq_idx++;
1039 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1040 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1041 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1042 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1044 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1047 if(reg_cifctrl & ENABLE_CAPTURE) {
1048 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1051 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1052 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1053 if (!list_empty(&pcdev->camera_work_queue)) {
1054 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1055 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1056 list_del_init(&wk->queue);
1057 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1059 queue_work(pcdev->camera_wq, &(wk->work));
1067 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1069 struct rk_camera_dev *pcdev = data;
1070 struct videobuf_buffer *vb;
1071 struct rk_camera_work *wk;
1073 unsigned long reg_cifctrl;
1075 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1078 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1079 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1080 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { //frame 0 ready yzm
1081 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1083 pcdev->irqinfo.dmairq_idx++;
1084 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1085 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1090 do_gettimeofday(&pcdev->first_tv);
1095 if (pcdev->frame_inval>0) {
1096 pcdev->frame_inval--;
1097 rk_videobuf_capture(pcdev->active,pcdev);
1099 } else if (pcdev->frame_inval) {
1100 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1101 pcdev->frame_inval = 0;
1104 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1105 do_gettimeofday(&tv);
1106 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1107 /(RK30_CAM_FRAME_MEASURE-1);
1112 printk("no acticve buffer!!!\n");
1116 /* ddl@rock-chips.com : this vb may be deleted from queue */
1117 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1118 list_del_init(&vb->queue);
1120 pcdev->active = NULL;
1121 if (!list_empty(&pcdev->capture)) {
1122 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1123 if (pcdev->active) {
1124 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1125 rk_videobuf_capture(pcdev->active,pcdev);
1128 if (pcdev->active == NULL) {
1129 RKCAMERA_DG1("video_buf queue is empty!\n");
1132 do_gettimeofday(&vb->ts);
1133 if (CAM_WORKQUEUE_IS_EN()) {
1134 if (!list_empty(&pcdev->camera_work_queue)) {
1135 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1136 list_del_init(&wk->queue);
1137 INIT_WORK(&(wk->work), rk_camera_capture_process);
1140 queue_work(pcdev->camera_wq, &(wk->work));
1143 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1144 vb->state = VIDEOBUF_DONE;
1152 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1153 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1157 static irqreturn_t rk_camera_irq(int irq, void *data)
1159 struct rk_camera_dev *pcdev = data;
1160 unsigned int reg_intstat;
1162 //should set value in cif irq
1163 static int rec_stop_cif = 0;
1165 spin_lock(&pcdev->lock);
1168 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1169 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%x\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1170 if (reg_intstat & 0x0200){
1171 rk_camera_cifirq(irq,data);
1172 if(atomic_read(&pcdev->stop_cif))
1175 debug_printk("receive cif stop request, recevie cif irq,reg_intstat = 0x%x\n",reg_intstat);
1179 if (reg_intstat & 0x01){
1180 if(rec_stop_cif == 1){
1181 pcdev->cif_stopped = true;
1183 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
1184 //workaround: disabled capen can't stop cif really,so should reset instead.
1185 rk_camera_cif_reset(pcdev,false);
1186 debug_printk("receive cif stop request,recevie dma irq ,reg_intstat = 0x%x\n",reg_intstat);
1187 wake_up(&pcdev->cif_stop_done);
1189 rk_camera_dmairq(irq,data);
1193 spin_unlock(&pcdev->lock);
1198 static void rk_videobuf_release(struct videobuf_queue *vq,
1199 struct videobuf_buffer *vb)
1201 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1202 struct soc_camera_device *icd = vq->priv_data;
1203 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1204 struct rk_camera_dev *pcdev = ici->priv;
1205 #if CAMERA_VIDEOBUF_ARM_ACCESS
1206 struct rk29_camera_vbinfo *vb_info =NULL;
1211 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1214 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1215 vb, vb->baddr, vb->bsize);
1219 case VIDEOBUF_ACTIVE:
1220 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1222 case VIDEOBUF_QUEUED:
1223 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1225 case VIDEOBUF_PREPARED:
1226 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1229 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1234 flush_workqueue(pcdev->camera_wq);
1236 rk_videobuf_free(vq, buf);
1238 #if CAMERA_VIDEOBUF_ARM_ACCESS
1239 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1240 vb_info = pcdev->vbinfo + vb->i;
1242 if (vb_info->vir_addr) {
1243 iounmap(vb_info->vir_addr);
1244 release_mem_region(vb_info->phy_addr, vb_info->size);
1245 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1252 static struct videobuf_queue_ops rk_videobuf_ops =
1254 .buf_setup = rk_videobuf_setup,
1255 .buf_prepare = rk_videobuf_prepare,
1256 .buf_queue = rk_videobuf_queue,
1257 .buf_release = rk_videobuf_release,
1260 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1261 struct soc_camera_device *icd)
1263 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1264 struct rk_camera_dev *pcdev = ici->priv;
1266 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1269 /* We must pass NULL as dev pointer, then all pci_* dma operations
1270 * transform to normal dma_* ones. */
1271 videobuf_queue_dma_contig_init(q,
1273 ici->v4l2_dev.dev, &pcdev->lock,
1274 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1276 sizeof(struct rk_camera_buffer),
1277 icd,&(ici->host_lock) );
1280 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1283 struct rk_cif_clk *clk;
1285 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1288 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1289 if ((cif<0)||(cif>1)) {
1290 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1292 goto rk_camera_clk_ctrl_end;
1295 clk = &cif_clk[cif];
1297 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1298 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1300 goto rk_camera_clk_ctrl_end;
1303 //spin_lock(&clk->lock);
1304 if (on && !clk->on) {
1305 clk_prepare_enable(clk->pd_cif); /*yzm*/
1306 clk_prepare_enable(clk->aclk_cif);
1307 clk_prepare_enable(clk->hclk_cif);
1308 clk_prepare_enable(clk->cif_clk_in);
1309 clk_prepare_enable(clk->cif_clk_out);
1310 clk_set_rate(clk->cif_clk_out,clk_rate);
1312 } else if (!on && clk->on) {
1313 clk_set_rate(clk->cif_clk_out,36000000);/*yzm :just for close clk which base on XIN24M */
1314 clk_disable_unprepare(clk->aclk_cif);
1315 clk_disable_unprepare(clk->hclk_cif);
1316 clk_disable_unprepare(clk->cif_clk_in);
1317 if(CHIP_NAME == 3126){
1318 write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
1319 write_cru_reg(CRU_CLK_OUT, 0x00800080);
1321 clk_disable_unprepare(clk->cif_clk_out);
1322 clk_disable_unprepare(clk->pd_cif);
1326 //spin_unlock(&clk->lock);
1327 rk_camera_clk_ctrl_end:
1330 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1333 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1336 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1338 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1339 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1343 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1346 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1348 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1354 /* The following two functions absolutely depend on the fact, that
1355 * there can be only one camera on RK28 quick capture interface */
1356 static int rk_camera_add_device(struct soc_camera_device *icd)
1358 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1359 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1360 struct device *control = to_soc_camera_control(icd);
1361 struct v4l2_subdev *sd;
1362 int ret,i,icd_catch;
1363 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1364 struct v4l2_cropcap cropcap;
1365 struct v4l2_mbus_framefmt mf;
1366 const struct soc_camera_format_xlate *xlate = NULL;
1368 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1371 mutex_lock(&camera_lock);
1378 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1380 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1381 pcdev->active = NULL;
1383 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1384 pcdev->zoominfo.zoom_rate = 100;
1385 pcdev->fps_timer.istarted = false;
1387 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1388 * if app havn't dequeue all videobuf before close camera device;
1390 INIT_LIST_HEAD(&pcdev->capture);
1392 ret = rk_camera_activate(pcdev,icd);
1395 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1396 if (control) { //TRUE in open ,FALSE in kernel start
1397 sd = dev_get_drvdata(control);
1398 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1400 ret = v4l2_subdev_call(sd,core, init, 0);
1404 /* call generic_sensor_ioctl*/
1405 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1406 /* call generic_sensor_cropcap*/
1407 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1408 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1410 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1413 mf.field = V4L2_FIELD_NONE;
1414 mf.code = xlate->code;
1415 mf.reserved[6] = 0xfefe5a5a;
1416 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1418 pcdev->cropinfo.bounds.left = 0;
1419 pcdev->cropinfo.bounds.top = 0;
1420 pcdev->cropinfo.bounds.width = mf.width;
1421 pcdev->cropinfo.bounds.height = mf.height;
1425 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1427 pcdev->icd_init = 0;
1430 for (i=0; i<2; i++) {
1431 if (pcdev->icd_frmival[i].icd == icd)
1433 if (pcdev->icd_frmival[i].icd == NULL) {
1434 pcdev->icd_frmival[i].icd = icd;
1438 if (icd_catch == 0) {
1439 fival_list = pcdev->icd_frmival[0].fival_list;
1440 fival_nxt = fival_list;
1441 while(fival_nxt != NULL) {
1442 fival_nxt = fival_list->nxt;
1444 fival_list = fival_nxt;
1446 pcdev->icd_frmival[0].icd = icd;
1447 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1450 mutex_unlock(&camera_lock);
1454 static void rk_camera_remove_device(struct soc_camera_device *icd)
1456 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1457 struct rk_camera_dev *pcdev = ici->priv;
1458 /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
1459 #if CAMERA_VIDEOBUF_ARM_ACCESS
1460 struct rk29_camera_vbinfo *vb_info;
1464 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1467 mutex_lock(&camera_lock);
1468 BUG_ON(icd != pcdev->icd);
1470 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1472 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1473 stream may be turn on again before close device, if suspend and resume happened. */
1474 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1475 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1476 rk_camera_s_stream(icd,0);
1478 /* move DEACTIVATE into generic_sensor_s_power*/
1479 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
1480 /* if stream off is not been executed,timer is running.*/
1481 if(pcdev->fps_timer.istarted){
1482 hrtimer_cancel(&pcdev->fps_timer.timer);
1483 pcdev->fps_timer.istarted = false;
1485 flush_work(&(pcdev->camera_reinit_work.work));
1486 flush_workqueue((pcdev->camera_wq));
1488 if (pcdev->camera_work) {
1489 kfree(pcdev->camera_work);
1490 pcdev->camera_work = NULL;
1491 pcdev->camera_work_count = 0;
1492 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1494 rk_camera_deactivate(pcdev);
1495 #if CAMERA_VIDEOBUF_ARM_ACCESS
1496 if (pcdev->vbinfo) {
1497 vb_info = pcdev->vbinfo;
1498 for (i=0; i<pcdev->vbinfo_count; i++) {
1499 if (vb_info->vir_addr) {
1500 iounmap(vb_info->vir_addr);
1501 release_mem_region(vb_info->phy_addr, vb_info->size);
1502 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1506 kfree(pcdev->vbinfo);
1507 pcdev->vbinfo = NULL;
1508 pcdev->vbinfo_count = 0;
1511 pcdev->active = NULL;
1513 pcdev->icd_cb.sensor_cb = NULL;
1514 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1515 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1516 * if app havn't dequeue all videobuf before close camera device;
1518 INIT_LIST_HEAD(&pcdev->capture);
1520 mutex_unlock(&camera_lock);
1524 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1526 unsigned long bus_flags, camera_flags, common_flags = 0;
1527 unsigned int cif_for = 0;
1528 const struct soc_mbus_pixelfmt *fmt;
1530 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /*yzm*/
1531 struct rk_camera_dev *pcdev = ici->priv;
1533 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1536 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1540 bus_flags = RK_CAM_BUS_PARAM;
1541 /* If requested data width is supported by the platform, use it */
1542 switch (fmt->bits_per_sample) {
1544 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1548 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1552 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1558 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1559 if (icd->ops->query_bus_param)
1560 camera_flags = icd->ops->query_bus_param(icd);
1564 /**************yzm************
1565 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1566 if (!common_flags) {
1568 goto RK_CAMERA_SET_BUS_PARAM_END;
1571 /***************yzm************end*/
1574 common_flags = camera_flags;
1575 ret = icd->ops->set_bus_param(icd, common_flags);
1577 goto RK_CAMERA_SET_BUS_PARAM_END;
1579 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1581 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1583 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1585 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1589 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1591 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1595 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1596 cif_for |= HSY_LOW_ACTIVE;
1598 cif_for &= ~HSY_LOW_ACTIVE;
1600 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1601 cif_for |= VSY_HIGH_ACTIVE;
1603 cif_for &= ~VSY_HIGH_ACTIVE;
1606 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1607 //vip_ctrl_val |= ENABLE_CAPTURE;
1608 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1609 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1611 RK_CAMERA_SET_BUS_PARAM_END:
1613 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1617 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1619 /* unsigned long bus_flags, camera_flags;*/
1622 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1623 /**********yzm***********
1625 bus_flags = RK_CAM_BUS_PARAM;
1626 if (icd->ops->query_bus_param) {
1627 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1631 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1634 dev_warn(icd->dev.parent,
1635 "Flags incompatible: camera %lx, host %lx\n",
1636 camera_flags, bus_flags);
1639 *///************yzm **************end
1644 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1646 .fourcc = V4L2_PIX_FMT_NV12,
1647 .name = "YUV420 NV12",
1648 .bits_per_sample = 8,
1649 .packing = SOC_MBUS_PACKING_1_5X8,
1650 .order = SOC_MBUS_ORDER_LE,
1652 .fourcc = V4L2_PIX_FMT_NV16,
1653 .name = "YUV422 NV16",
1654 .bits_per_sample = 8,
1655 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1656 .order = SOC_MBUS_ORDER_LE,
1658 .fourcc = V4L2_PIX_FMT_NV21,
1659 .name = "YUV420 NV21",
1660 .bits_per_sample = 8,
1661 .packing = SOC_MBUS_PACKING_1_5X8,
1662 .order = SOC_MBUS_ORDER_LE,
1664 .fourcc = V4L2_PIX_FMT_NV61,
1665 .name = "YUV422 NV61",
1666 .bits_per_sample = 8,
1667 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1668 .order = SOC_MBUS_ORDER_LE,
1670 .fourcc = V4L2_PIX_FMT_RGB565,
1672 .bits_per_sample = 8,
1673 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1674 .order = SOC_MBUS_ORDER_LE,
1676 .fourcc = V4L2_PIX_FMT_RGB24,
1678 .bits_per_sample = 8,
1679 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1680 .order = SOC_MBUS_ORDER_LE,
1685 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1687 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1688 struct rk_camera_dev *pcdev = ici->priv;
1689 unsigned int cif_fs = 0,cif_crop = 0;
1690 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;
1692 const struct soc_mbus_pixelfmt *fmt;
1693 fmt = soc_mbus_get_fmtdesc(icd_code);
1695 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1698 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1699 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1700 host_pixfmt = V4L2_PIX_FMT_NV12;
1701 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1702 host_pixfmt = V4L2_PIX_FMT_NV21;
1704 switch (host_pixfmt)
1706 case V4L2_PIX_FMT_NV16:
1707 cif_fmt_val &= ~YUV_OUTPUT_422;
1708 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1709 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1710 pcdev->pixfmt = host_pixfmt;
1712 case V4L2_PIX_FMT_NV61:
1713 cif_fmt_val &= ~YUV_OUTPUT_422;
1714 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1715 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1716 pcdev->pixfmt = host_pixfmt;
1718 case V4L2_PIX_FMT_NV12:
1719 cif_fmt_val |= YUV_OUTPUT_420;
1720 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1721 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1722 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1723 pcdev->pixfmt = host_pixfmt;
1725 case V4L2_PIX_FMT_NV21:
1726 cif_fmt_val |= YUV_OUTPUT_420;
1727 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1728 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1729 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1730 pcdev->pixfmt = host_pixfmt;
1732 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1733 cif_fmt_val |= YUV_OUTPUT_422;
1738 case V4L2_MBUS_FMT_UYVY8_2X8:
1739 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1741 case V4L2_MBUS_FMT_YUYV8_2X8:
1742 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1744 case V4L2_MBUS_FMT_YVYU8_2X8:
1745 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1747 case V4L2_MBUS_FMT_VYUY8_2X8:
1748 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1751 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1756 rk_camera_cif_reset(pcdev,true);
1758 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1759 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1761 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 */
1763 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1764 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1765 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1767 } else{ /* this is one frame mode*/
1768 cif_crop = (rect->left + (rect->top <<16));
1769 cif_fs = (rect->width + (rect->height <<16));
1772 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1773 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1774 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1775 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1777 /*MUST bypass scale */
1778 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1779 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);
1783 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1784 struct soc_camera_format_xlate *xlate)
1786 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1787 struct device *dev = icd->parent;/*yzm*/
1788 int formats = 0, ret;
1789 enum v4l2_mbus_pixelcode code;
1790 const struct soc_mbus_pixelfmt *fmt;
1792 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1795 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); /*call generic_sensor_enum_fmt()*/
1797 /* No more formats */
1800 fmt = soc_mbus_get_fmtdesc(code);
1802 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1806 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1811 case V4L2_MBUS_FMT_UYVY8_2X8:
1812 case V4L2_MBUS_FMT_YUYV8_2X8:
1813 case V4L2_MBUS_FMT_YVYU8_2X8:
1814 case V4L2_MBUS_FMT_VYUY8_2X8:
1817 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1820 xlate->host_fmt = &rk_camera_formats[0];
1823 dev_dbg(dev, "Providing format %s using code %d\n",
1824 rk_camera_formats[0].name,code);
1829 xlate->host_fmt = &rk_camera_formats[1];
1832 dev_dbg(dev, "Providing format %s using code %d\n",
1833 rk_camera_formats[1].name,code);
1838 xlate->host_fmt = &rk_camera_formats[2];
1841 dev_dbg(dev, "Providing format %s using code %d\n",
1842 rk_camera_formats[2].name,code);
1847 xlate->host_fmt = &rk_camera_formats[3];
1850 dev_dbg(dev, "Providing format %s using code %d\n",
1851 rk_camera_formats[3].name,code);
1857 xlate->host_fmt = &rk_camera_formats[4];
1860 dev_dbg(dev, "Providing format %s using code %d\n",
1861 rk_camera_formats[4].name,code);
1865 xlate->host_fmt = &rk_camera_formats[5];
1868 dev_dbg(dev, "Providing format %s using code %d\n",
1869 rk_camera_formats[5].name,code);
1881 static void rk_camera_put_formats(struct soc_camera_device *icd)
1884 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1888 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1890 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1893 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1895 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1898 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1899 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1903 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1905 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1906 struct rk_camera_dev *pcdev = ici->priv;
1908 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1911 spin_lock(&pcdev->cropinfo.lock);
1912 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1913 spin_unlock(&pcdev->cropinfo.lock);
1917 static int rk_camera_set_crop(struct soc_camera_device *icd,
1918 const struct v4l2_crop *crop)
1920 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1921 struct rk_camera_dev *pcdev = ici->priv;
1923 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1926 spin_lock(&pcdev->cropinfo.lock);
1927 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1928 spin_unlock(&pcdev->cropinfo.lock);
1931 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1935 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1938 if (f->fmt.pix.priv == 0xfefe5a5a) {
1942 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1944 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1946 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1948 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1950 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1952 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1957 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1960 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1961 struct v4l2_format *f)
1963 struct device *dev = icd->parent;/*yzm*/
1964 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1965 const struct soc_camera_format_xlate *xlate = NULL;
1966 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1967 struct rk_camera_dev *pcdev = ici->priv;
1968 struct v4l2_pix_format *pix = &f->fmt.pix;
1969 struct v4l2_mbus_framefmt mf;
1970 struct v4l2_rect rect;
1971 int ret,usr_w,usr_h,sensor_w,sensor_h;
1973 int ratio, bounds_aspect;
1975 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1979 usr_h = pix->height;
1981 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
1982 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1984 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1986 goto RK_CAMERA_SET_FMT_END;
1989 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1990 if (pcdev->icd_init == 0) {
1991 v4l2_subdev_call(sd,core, init, 0); /*call generic_sensor_init()*/
1992 pcdev->icd_init = 1;
1993 return 0; /*directly return !!!!!!*/
1995 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1996 if (stream_on & ENABLE_CAPTURE)
1997 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1999 mf.width = pix->width;
2000 mf.height = pix->height;
2001 mf.field = pix->field;
2002 mf.colorspace = pix->colorspace;
2003 mf.code = xlate->code;
2004 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
2007 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); /*generic_sensor_s_fmt*/
2008 if (mf.code != xlate->code)
2011 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
2012 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
2013 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
2014 if ((mf.width*10/mf.height) != bounds_aspect) {
2015 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
2016 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
2018 mf.width = pcdev->cropinfo.bounds.width/4;
2019 mf.height = pcdev->cropinfo.bounds.height/4;
2021 mf.field = pix->field;
2022 mf.colorspace = pix->colorspace;
2023 mf.code = xlate->code;
2024 mf.reserved[0] = pix->priv;
2027 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2028 if (mf.code != xlate->code)
2033 sensor_w = mf.width;
2034 sensor_h = mf.height;
2036 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
2039 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
2042 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2044 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2045 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2047 goto RK_CAMERA_SET_FMT_END;
2049 if (unlikely((usr_w <16)||(usr_h < 16))) {
2050 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2052 goto RK_CAMERA_SET_FMT_END;
2055 spin_lock(&pcdev->cropinfo.lock);
2056 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2057 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2058 /*Scale + Crop center is for keep aspect ratio unchange*/
2059 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2060 pcdev->host_width = ratio*usr_w/10;
2061 pcdev->host_height = ratio*usr_h/10;
2062 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2063 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2065 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2066 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2068 /*Scale + crop(user define)*/
2069 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2070 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2071 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2072 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2075 pcdev->host_left &= (~0x01);
2076 pcdev->host_top &= (~0x01);
2078 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2079 /*Crop Center for cif can work , then scale*/
2080 pcdev->host_width = mf.width;
2081 pcdev->host_height = mf.height;
2082 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2083 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2085 /*Crop center for cif can work + crop(user define), then scale */
2086 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2087 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2088 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2089 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2092 pcdev->host_left &= (~0x01);
2093 pcdev->host_top &= (~0x01);
2095 spin_unlock(&pcdev->cropinfo.lock);
2097 spin_lock(&pcdev->cropinfo.lock);
2098 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2099 pcdev->host_width = mf.width;
2100 pcdev->host_height = mf.height;
2101 pcdev->host_left = 0;
2102 pcdev->host_top = 0;
2104 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2105 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2106 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2107 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2109 spin_unlock(&pcdev->cropinfo.lock);
2114 rect.width = pcdev->host_width;
2115 rect.height = pcdev->host_height;
2116 rect.left = pcdev->host_left;
2117 rect.top = pcdev->host_top;
2119 down(&pcdev->zoominfo.sem);
2120 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2121 pcdev->zoominfo.a.c.left = 0;
2122 pcdev->zoominfo.a.c.top = 0;
2123 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2124 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2125 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2126 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2127 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2128 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2129 /*recalculate the CIF width & height*/
2130 rect.width = pcdev->zoominfo.a.c.width ;
2131 rect.height = pcdev->zoominfo.a.c.height;
2132 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2133 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2135 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2136 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2137 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2138 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2139 /*now digital zoom use ipp to do crop and scale*/
2140 if(pcdev->zoominfo.zoom_rate != 100){
2141 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2142 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2144 pcdev->zoominfo.a.c.left = 0;
2145 pcdev->zoominfo.a.c.top = 0;
2147 pcdev->zoominfo.vir_width = pcdev->host_width;
2148 pcdev->zoominfo.vir_height = pcdev->host_height;
2150 up(&pcdev->zoominfo.sem);
2152 /* ddl@rock-chips.com: IPP work limit check */
2153 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2154 if (usr_w > 0x7f0) {
2155 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2156 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));
2158 goto RK_CAMERA_SET_FMT_END;
2161 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2162 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2164 goto RK_CAMERA_SET_FMT_END;
2169 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,
2170 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2171 sensor_w,sensor_h,mf.width,mf.height,
2172 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2173 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2174 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2175 pix->width, pix->height);
2177 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2179 if (CAM_IPPWORK_IS_EN()) {
2180 BUG_ON(pcdev->vipmem_phybase == 0);
2183 pix->height = usr_h;
2184 pix->field = mf.field;
2185 pix->colorspace = mf.colorspace;
2186 icd->current_fmt = xlate;
2187 pcdev->icd_width = mf.width;
2188 pcdev->icd_height = mf.height;
2191 RK_CAMERA_SET_FMT_END:
2192 if (stream_on & ENABLE_CAPTURE)
2193 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2195 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2199 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2200 struct v4l2_format *f)
2202 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2203 struct rk_camera_dev *pcdev = ici->priv;
2204 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2205 const struct soc_camera_format_xlate *xlate;
2206 struct v4l2_pix_format *pix = &f->fmt.pix;
2207 __u32 pixfmt = pix->pixelformat;
2208 int ret,usr_w,usr_h,i;
2209 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2210 bool vipmem_is_overflow = false;
2211 struct v4l2_mbus_framefmt mf;
2212 int bytes_per_line_host;
2215 usr_h = pix->height;
2217 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2219 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2221 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2222 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
2223 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2225 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2226 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2227 for (i = 0; i < icd->num_user_formats; i++)
2228 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2229 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2230 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2231 icd->user_formats[i].host_fmt->name);
2232 goto RK_CAMERA_TRY_FMT_END;
2234 /* limit to rk29 hardware capabilities */
2235 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2236 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2237 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2239 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2241 if (pix->bytesperline < 0)
2242 return pix->bytesperline;
2244 /* limit to sensor capabilities */
2245 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2246 mf.width = pix->width;
2247 mf.height = pix->height;
2248 mf.field = pix->field;
2249 mf.colorspace = pix->colorspace;
2250 mf.code = xlate->code;
2251 /* ddl@rock-chips.com : It is query max resolution only. */
2252 if ((usr_w == 10000) && (usr_h == 10000)) {
2253 mf.reserved[6] = 0xfefe5a5a;
2255 /* call generic_sensor_try_fmt()*/
2256 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2258 goto RK_CAMERA_TRY_FMT_END;
2260 /*query resolution.*/
2261 if((usr_w == 10000) && (usr_h == 10000)) {
2262 pix->width = mf.width;
2263 pix->height = mf.height;
2264 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2265 goto RK_CAMERA_TRY_FMT_END;
2267 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2270 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2271 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2273 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2275 /* Assume preview buffer minimum is 4 */
2276 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2278 if (vipmem_is_overflow == false) {
2280 pix->height = usr_h;
2282 /*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*/
2283 pix->width = mf.width;
2284 pix->height = mf.height;
2286 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2288 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2289 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2290 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2291 pix->width = mf.width;
2292 pix->height = mf.height;
2298 pix->colorspace = mf.colorspace;
2301 case V4L2_FIELD_ANY:
2302 case V4L2_FIELD_NONE:
2303 pix->field = V4L2_FIELD_NONE;
2306 /* TODO: support interlaced at least in pass-through mode */
2307 dev_err(icd->parent, "Field type %d unsupported.\n",
2309 goto RK_CAMERA_TRY_FMT_END;
2312 RK_CAMERA_TRY_FMT_END:
2314 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2318 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2319 struct v4l2_requestbuffers *p)
2323 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2326 /* This is for locking debugging only. I removed spinlocks and now I
2327 * check whether .prepare is ever called on a linked buffer, or whether
2328 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2329 * it hadn't triggered */
2330 for (i = 0; i < p->count; i++) {
2331 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2332 struct rk_camera_buffer, vb);
2334 INIT_LIST_HEAD(&buf->vb.queue);
2340 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2342 struct soc_camera_device *icd = file->private_data;
2343 struct rk_camera_buffer *buf;
2345 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2348 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2351 poll_wait(file, &buf->vb.done, pt);
2353 if (buf->vb.state == VIDEOBUF_DONE ||
2354 buf->vb.state == VIDEOBUF_ERROR)
2355 return POLLIN|POLLRDNORM;
2360 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2361 * 10 5 1 3 3 3 + 5 < 32
2364 static int rk_camera_querycap(struct soc_camera_host *ici,
2365 struct v4l2_capability *cap)
2367 struct rk_camera_dev *pcdev = ici->priv;
2368 struct rkcamera_platform_data *new_camera;
2369 char orientation[5];
2373 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2376 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2377 memset(orientation,0x00,sizeof(orientation));
2380 new_camera = pcdev->pdata->register_dev_new;
2381 while(new_camera != NULL){
2382 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2383 sprintf(orientation,"-%d",new_camera->orientation);
2384 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2386 new_camera = new_camera->next_camera;
2389 if (orientation[0] != '-') {
2390 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2391 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2392 strcat(cap->card,"-270");
2394 strcat(cap->card,"-90");
2396 strcat(cap->card,orientation);
2399 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2400 cap->version = RK_CAM_VERSION_CODE;
2401 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2402 cap->reserved[0] = pcdev->pdata->iommu_enabled;
2403 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2407 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2409 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2410 struct rk_camera_dev *pcdev = ici->priv;
2411 struct v4l2_subdev *sd;
2414 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2417 mutex_lock(&camera_lock);
2418 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2419 rk_camera_s_stream(icd, 0);
2420 sd = soc_camera_to_subdev(icd);
2421 v4l2_subdev_call(sd, video, s_stream, 0);
2422 ret = icd->ops->suspend(icd, state);
2424 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2425 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2426 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2427 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2428 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2429 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2430 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2432 pcdev->reginfo_suspend.Inval = Reg_Validate;
2433 rk_camera_deactivate(pcdev);
2435 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2437 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2439 mutex_unlock(&camera_lock);
2443 static int rk_camera_resume(struct soc_camera_device *icd)
2445 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2446 struct rk_camera_dev *pcdev = ici->priv;
2447 struct v4l2_subdev *sd;
2450 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2453 mutex_lock(&camera_lock);
2454 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2455 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2456 rk_camera_activate(pcdev, icd);
2457 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2458 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2459 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2460 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2461 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2462 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2463 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2464 rk_videobuf_capture(pcdev->active,pcdev);
2465 rk_camera_s_stream(icd, 1);
2466 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2468 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2469 goto rk_camera_resume_end;
2472 ret = icd->ops->resume(icd);
2473 sd = soc_camera_to_subdev(icd);
2474 v4l2_subdev_call(sd, video, s_stream, 1);
2476 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2478 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2481 rk_camera_resume_end:
2482 mutex_unlock(&camera_lock);
2486 static void rk_camera_reinit_work(struct work_struct *work)
2488 struct v4l2_subdev *sd;
2489 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2490 struct rk_camera_dev *pcdev = camera_work->pcdev;
2491 /*struct soc_camera_link *tmp_soc_cam_link;*/
2492 struct v4l2_mbus_framefmt mf;
2494 unsigned long flags = 0;
2497 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2500 if(pcdev->icd == NULL)
2502 sd = soc_camera_to_subdev(pcdev->icd);
2503 /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2506 RKCAMERA_TR("CIF_CIF_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2507 RKCAMERA_TR("CIF_CIF_INTEN = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2508 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2509 RKCAMERA_TR("CIF_CIF_FOR = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2510 RKCAMERA_TR("CIF_CIF_CROP = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2511 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2512 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2513 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%lx\n",read_cru_reg(CRU_PCLK_REG30));
2514 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2516 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2517 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2518 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2519 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2520 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2521 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2522 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2523 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2524 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2527 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2528 if (pcdev->reinit_times == 1) {
2529 if (ctrl & ENABLE_CAPTURE) {
2530 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2531 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2532 rk_camera_cif_reset(pcdev,false);
2535 v4l2_subdev_call(sd,core, init, 0);
2537 mf.width = pcdev->icd_width;
2538 mf.height = pcdev->icd_height;
2539 mf.field = V4L2_FIELD_NONE;
2540 mf.code = pcdev->icd->current_fmt->code;
2541 mf.reserved[0] = 0x5a5afefe;
2544 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2546 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2547 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2548 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2549 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2550 rk_camera_cif_reset(pcdev,false);
2551 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2556 atomic_set(&pcdev->stop_cif,true);
2557 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2558 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2560 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2561 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2562 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2563 if (NULL == pcdev->video_vq->bufs[index])
2566 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2567 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2568 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2569 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2570 printk("wake up video buffer index = %d !!!\n",index);
2573 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2575 RKCAMERA_TR("video queue has somthing wrong !!\n");
2578 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2580 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2582 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2583 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2584 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2586 /*static unsigned int last_fps = 0;*/
2587 /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
2588 /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2590 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2592 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2593 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2594 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2595 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2596 pcdev->camera_reinit_work.pcdev = pcdev;
2597 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2598 pcdev->reinit_times++;
2599 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2600 } else if(!pcdev->timer_get_fps) {
2601 pcdev->timer_get_fps = true;
2602 for (i=0; i<2; i++) {
2603 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2604 fival_nxt = pcdev->icd_frmival[i].fival_list;
2609 fival_pre = fival_nxt;
2610 while (fival_nxt != NULL) {
2612 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
2613 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2614 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2615 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2616 fival_nxt->fival.discrete.numerator);
2618 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2619 && (fival_nxt->fival.height == pcdev->icd->user_height)
2620 && (fival_nxt->fival.width == pcdev->icd->user_width))
2621 || (fival_nxt->fival.discrete.denominator == 0)) {
2623 if (fival_nxt->fival.discrete.denominator == 0) {
2624 fival_nxt->fival.index = 0;
2625 fival_nxt->fival.width = pcdev->icd->user_width;
2626 fival_nxt->fival.height= pcdev->icd->user_height;
2627 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2628 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2629 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2630 |(pcdev->icd_height);
2631 fival_nxt->fival.discrete.numerator = 1000000;
2632 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2635 fival_rec = fival_nxt;
2637 fival_pre = fival_nxt;
2638 fival_nxt = fival_nxt->nxt;
2641 if ((rec_flag == 0) && fival_pre) {
2642 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2643 if (fival_pre->nxt != NULL) {
2644 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2645 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2646 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2647 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2649 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2650 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2651 |(pcdev->icd_height);
2652 fival_pre->nxt->fival.discrete.numerator = 1000000;
2653 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2655 fival_rec = fival_pre->nxt;
2660 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2661 pcdev->reinit_times = 0;
2663 pcdev->last_fps = pcdev->fps ;
2664 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2665 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2666 /*return HRTIMER_NORESTART;*/
2667 if(pcdev->reinit_times >=2)
2668 return HRTIMER_NORESTART;
2670 return HRTIMER_RESTART;
2672 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2674 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2675 struct rk_camera_dev *pcdev = ici->priv;
2678 unsigned long flags;
2680 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2682 WARN_ON(pcdev->icd != icd);
2684 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2687 pcdev->last_fps = 0;
2688 pcdev->frame_interval = 0;
2689 hrtimer_cancel(&(pcdev->fps_timer.timer));
2690 pcdev->fps_timer.pcdev = pcdev;
2691 pcdev->timer_get_fps = false;
2692 pcdev->reinit_times = 0;
2694 spin_lock_irqsave(&pcdev->lock,flags);
2695 atomic_set(&pcdev->stop_cif,false);
2696 pcdev->cif_stopped = false;
2697 pcdev->irqinfo.cifirq_idx = 0;
2698 pcdev->irqinfo.cifirq_normal_idx = 0;
2699 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2700 pcdev->irqinfo.dmairq_idx = 0;
2702 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2703 cif_ctrl_val |= ENABLE_CAPTURE;
2704 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2705 spin_unlock_irqrestore(&pcdev->lock,flags);
2706 printk("%s:stream enable CIF_CIF_CTRL 0x%lx\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2707 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2708 pcdev->fps_timer.istarted = true;
2710 /*cancel timer before stop cif*/
2711 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2712 pcdev->fps_timer.istarted = false;
2713 flush_work(&(pcdev->camera_reinit_work.work));
2715 cif_ctrl_val &= ~ENABLE_CAPTURE;
2716 spin_lock_irqsave(&pcdev->lock, flags);
2717 //write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2718 atomic_set(&pcdev->stop_cif,true);
2719 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2720 spin_unlock_irqrestore(&pcdev->lock, flags);
2722 init_waitqueue_head(&pcdev->cif_stop_done);
2723 if (wait_event_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(1000)) == 0) {
2724 RKCAMERA_TR("%s:%d, wait cif stop timeout!",__func__,__LINE__);
2725 pcdev->cif_stopped = true;
2728 flush_workqueue((pcdev->camera_wq));
2731 /*must be reinit,or will be somthing wrong in irq process.*/
2732 if(enable == false) {
2733 pcdev->active = NULL;
2734 INIT_LIST_HEAD(&pcdev->capture);
2736 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%lx\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2739 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2741 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2742 struct rk_camera_dev *pcdev = ici->priv;
2743 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2744 struct rk_camera_frmivalenum *fival_list = NULL;
2745 struct v4l2_frmivalenum *fival_head = NULL;
2746 struct rkcamera_platform_data *new_camera;
2747 int i,ret = 0,index;
2748 const struct soc_camera_format_xlate *xlate;
2749 struct v4l2_mbus_framefmt mf;
2752 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2754 index = fival->index & 0x00ffffff;
2755 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2756 for (i=0; i<2; i++) {
2757 if (pcdev->icd_frmival[i].icd == icd) {
2758 fival_list = pcdev->icd_frmival[i].fival_list;
2762 if (fival_list != NULL) {
2764 while (fival_list != NULL) {
2765 if ((fival->pixel_format == fival_list->fival.pixel_format)
2766 && (fival->height == fival_list->fival.height)
2767 && (fival->width == fival_list->fival.width)) {
2772 fival_list = fival_list->nxt;
2775 if ((i==index) && (fival_list != NULL)) {
2776 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2781 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2788 while (fival_head->width && fival_head->height) {
2789 if ((fival->pixel_format == fival_head->pixel_format)
2790 && (fival->height == fival_head->height)
2791 && (fival->width == fival_head->width)) {
2800 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2801 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2803 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2804 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2805 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2806 mf.width = fival->width;
2807 mf.height = fival->height;
2808 mf.code = xlate->code;
2810 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2812 fival->reserved[1] = (mf.width<<16)|(mf.height);
2814 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2815 fival->width, fival->height,
2816 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2817 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2818 fival->discrete.denominator,fival->discrete.numerator);
2821 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2822 fival->width,fival->height,
2823 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2824 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2827 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2828 fival->width,fival->height,
2829 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2830 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2833 goto rk_camera_enum_frameintervals_end;
2837 new_camera = pcdev->pdata->register_dev_new;
2838 while(new_camera != NULL){
2839 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2843 new_camera = new_camera->next_camera;
2847 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2848 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2851 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2852 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2853 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2854 mf.width = fival->width;
2855 mf.height = fival->height;
2856 mf.code = xlate->code;
2858 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2860 fival->discrete.numerator= 1000;
2861 fival->discrete.denominator = 15000;
2862 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2863 fival->reserved[1] = (mf.width<<16)|(mf.height);
2867 rk_camera_enum_frameintervals_end:
2871 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2872 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2875 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2876 struct rk_camera_dev *pcdev = ici->priv;
2878 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2882 unsigned long tmp_cifctrl;
2885 /*change the crop and scale parameters*/
2888 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2889 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2890 a.c.width = pcdev->host_width*100/zoom_rate;
2891 a.c.width &= ~CROP_ALIGN_BYTES;
2892 a.c.height = pcdev->host_height*100/zoom_rate;
2893 a.c.height &= ~CROP_ALIGN_BYTES;
2894 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2895 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2896 atomic_set(&pcdev->stop_cif,true);
2897 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2898 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2899 hrtimer_cancel(&(pcdev->fps_timer.timer));
2900 flush_workqueue((pcdev->camera_wq));
2902 down(&pcdev->zoominfo.sem);
2903 pcdev->zoominfo.a.c.left = 0;
2904 pcdev->zoominfo.a.c.top = 0;
2905 pcdev->zoominfo.a.c.width = a.c.width;
2906 pcdev->zoominfo.a.c.height = a.c.height;
2907 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2908 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2909 pcdev->frame_inval = 1;
2910 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2911 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2912 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2913 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2915 rk_videobuf_capture(pcdev->active,pcdev);
2916 if(tmp_cifctrl & ENABLE_CAPTURE)
2917 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2918 up(&pcdev->zoominfo.sem);
2920 atomic_set(&pcdev->stop_cif,false);
2921 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2922 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 );
2924 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2925 a.c.width = pcdev->host_width*100/zoom_rate;
2926 a.c.width &= ~CROP_ALIGN_BYTES;
2927 a.c.height = pcdev->host_height*100/zoom_rate;
2928 a.c.height &= ~CROP_ALIGN_BYTES;
2929 a.c.left = (pcdev->host_width - a.c.width)>>1;
2930 a.c.top = (pcdev->host_height - a.c.height)>>1;
2932 down(&pcdev->zoominfo.sem);
2933 pcdev->zoominfo.a.c.height = a.c.height;
2934 pcdev->zoominfo.a.c.width = a.c.width;
2935 pcdev->zoominfo.a.c.top = a.c.top;
2936 pcdev->zoominfo.a.c.left = a.c.left;
2937 pcdev->zoominfo.vir_width = pcdev->host_width;
2938 pcdev->zoominfo.vir_height= pcdev->host_height;
2939 up(&pcdev->zoominfo.sem);
2941 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 );
2947 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2948 struct soc_camera_host_ops *ops, int id)
2952 for (i = 0; i < ops->num_controls; i++)
2953 if (ops->controls[i].id == id)
2954 return &ops->controls[i];
2960 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2961 struct v4l2_control *sctrl)
2963 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2964 const struct v4l2_queryctrl *qctrl;
2965 struct rk_camera_dev *pcdev = ici->priv;
2969 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2971 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2974 goto rk_camera_set_ctrl_end;
2979 case V4L2_CID_ZOOM_ABSOLUTE:
2981 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2983 goto rk_camera_set_ctrl_end;
2985 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2987 pcdev->zoominfo.zoom_rate = sctrl->value;
2989 goto rk_camera_set_ctrl_end;
2997 rk_camera_set_ctrl_end:
3001 static struct soc_camera_host_ops rk_soc_camera_host_ops =
3003 .owner = THIS_MODULE,
3004 .add = rk_camera_add_device,
3005 .remove = rk_camera_remove_device,
3006 .suspend = rk_camera_suspend,
3007 .resume = rk_camera_resume,
3008 .enum_frameinervals = rk_camera_enum_frameintervals,
3009 .cropcap = rk_camera_cropcap,
3010 .set_crop = rk_camera_set_crop,
3011 .get_crop = rk_camera_get_crop,
3012 .get_formats = rk_camera_get_formats,
3013 .put_formats = rk_camera_put_formats,
3014 .set_fmt = rk_camera_set_fmt,
3015 .try_fmt = rk_camera_try_fmt,
3016 .init_videobuf = rk_camera_init_videobuf,
3017 .reqbufs = rk_camera_reqbufs,
3018 .poll = rk_camera_poll,
3019 .querycap = rk_camera_querycap,
3020 .set_bus_param = rk_camera_set_bus_param,
3021 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
3022 .set_ctrl = rk_camera_set_ctrl,
3023 .controls = rk_camera_controls,
3024 .num_controls = ARRAY_SIZE(rk_camera_controls)
3027 /**********yzm***********/
3028 static int rk_camera_cif_iomux(struct device *dev)
3031 struct pinctrl *pinctrl;
3032 struct pinctrl_state *state;
3034 char state_str[20] = {0};
3036 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3037 strcpy(state_str,"cif_pin_all");
3039 if(CHIP_NAME == 3288){
3040 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
3045 pinctrl = devm_pinctrl_get(dev);
3046 if (IS_ERR(pinctrl)) {
3047 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
3050 state = pinctrl_lookup_state(pinctrl,
3053 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
3057 if (!IS_ERR(state)) {
3058 retval = pinctrl_select_state(pinctrl, state);
3061 "%s:could not set %s pins\n",__func__,state_str);
3069 /***********yzm***********/
3070 static int rk_camera_probe(struct platform_device *pdev)
3072 struct rk_camera_dev *pcdev;
3073 struct resource *res;
3074 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3077 struct rk_cif_clk *clk=NULL;
3078 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
3080 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3082 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3083 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3085 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3086 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3090 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3091 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3095 /***********yzm**********/
3096 rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3098 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3099 irq = platform_get_irq(pdev, 0);
3101 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3102 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3103 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3105 if (!res || irq < 0) {
3109 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3111 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3116 pcdev->zoominfo.zoom_rate = 100;
3117 pcdev->hostid = pdev->id; /* get host id*/
3118 #ifdef CONFIG_SOC_RK3028
3119 pcdev->chip_id = rk3028_version_val();
3121 pcdev->chip_id = -1;
3124 /***********yzm***********/
3126 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3128 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3129 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3130 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3131 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3132 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3133 //spin_lock_init(&cif_clk[0].lock);
3134 cif_clk[0].on = false;
3135 rk_camera_cif_iomux(dev_cif);/*yzm*/
3138 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only yzm*/
3139 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3140 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3141 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3142 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3143 //spin_lock_init(&cif_clk[1].lock);
3144 cif_clk[1].on = false;
3145 rk_camera_cif_iomux(dev_cif);/*yzm*/
3148 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3150 /***********yzm**********/
3151 dev_set_drvdata(&pdev->dev, pcdev);
3153 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3154 /*= rk_camera_platform_data */
3155 if (pcdev->pdata && pcdev->pdata->io_init) {
3157 pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
3159 if (pcdev->pdata->sensor_mclk == NULL)
3160 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3163 INIT_LIST_HEAD(&pcdev->capture);
3164 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3165 spin_lock_init(&pcdev->lock);
3166 spin_lock_init(&pcdev->camera_work_lock);
3168 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3169 spin_lock_init(&pcdev->cropinfo.lock);
3170 sema_init(&pcdev->zoominfo.sem,1);
3173 * Request the regions.
3176 if (!request_mem_region(res->start, res->end - res->start + 1,
3177 RK29_CAM_DRV_NAME)) {
3179 goto exit_reqmem_vip;
3181 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3182 if (pcdev->base == NULL) {
3183 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3185 goto exit_ioremap_vip;
3189 pcdev->irqinfo.irq = irq;
3190 pcdev->dev = &pdev->dev;
3192 /* config buffer address */
3195 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, IRQF_DISABLED | IRQF_SHARED , RK29_CAM_DRV_NAME,
3198 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3204 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3206 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3208 if (pcdev->camera_wq == NULL) {
3209 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3213 pcdev->camera_reinit_work.pcdev = pcdev;
3214 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3216 for (i=0; i<2; i++) {
3217 pcdev->icd_frmival[i].icd = NULL;
3218 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3221 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3222 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3223 pcdev->soc_host.priv = pcdev; /*to itself,csll in rk_camera_add_device*/
3224 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3225 pcdev->soc_host.nr = pdev->id;
3226 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3227 err = soc_camera_host_register(&pcdev->soc_host);
3231 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3234 pcdev->fps_timer.pcdev = pcdev;
3235 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3236 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3237 pcdev->icd_cb.sensor_cb = NULL;
3239 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3240 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3241 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3242 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3243 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3244 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3245 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3246 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3252 for (i=0; i<2; i++) {
3253 fival_list = pcdev->icd_frmival[i].fival_list;
3254 fival_nxt = fival_list;
3255 while(fival_nxt != NULL) {
3256 fival_nxt = fival_list->nxt;
3258 fival_list = fival_nxt;
3262 free_irq(pcdev->irqinfo.irq, pcdev);
3263 if (pcdev->camera_wq) {
3264 destroy_workqueue(pcdev->camera_wq);
3265 pcdev->camera_wq = NULL;
3268 iounmap(pcdev->base);
3270 release_mem_region(res->start, res->end - res->start + 1);
3274 clk_put(clk->pd_cif);
3276 clk_put(clk->aclk_cif);
3278 clk_put(clk->hclk_cif);
3279 if (clk->cif_clk_in)
3280 clk_put(clk->cif_clk_in);
3281 if (clk->cif_clk_out)
3282 clk_put(clk->cif_clk_out);
3291 static int __exit rk_camera_remove(struct platform_device *pdev)
3293 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3294 struct resource *res;
3295 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3298 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3301 free_irq(pcdev->irqinfo.irq, pcdev);
3303 if (pcdev->camera_wq) {
3304 destroy_workqueue(pcdev->camera_wq);
3305 pcdev->camera_wq = NULL;
3308 for (i=0; i<2; i++) {
3309 fival_list = pcdev->icd_frmival[i].fival_list;
3310 fival_nxt = fival_list;
3311 while(fival_nxt != NULL) {
3312 fival_nxt = fival_list->nxt;
3314 fival_list = fival_nxt;
3318 soc_camera_host_unregister(&pcdev->soc_host);
3321 iounmap((void __iomem*)pcdev->base);
3322 release_mem_region(res->start, res->end - res->start + 1);
3323 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3324 pcdev->pdata->io_deinit(0);
3325 pcdev->pdata->io_deinit(1);
3330 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3335 static struct platform_driver rk_camera_driver =
3338 .name = RK29_CAM_DRV_NAME, /*host */
3340 .probe = rk_camera_probe,
3341 .remove = (rk_camera_remove),
3344 static int rk_camera_init_async(void *unused)
3347 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3348 platform_driver_register(&rk_camera_driver);
3352 static int __init rk_camera_init(void)
3355 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3357 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3362 static void __exit rk_camera_exit(void)
3364 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3366 platform_driver_unregister(&rk_camera_driver);
3369 device_initcall_sync(rk_camera_init);
3370 module_exit(rk_camera_exit);
3372 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3373 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3374 MODULE_LICENSE("GPL");