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 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0xa)
290 static int version = RK_CAM_VERSION_CODE;
291 module_param(version, int, S_IRUGO);
293 /* limit to rk29 hardware capabilities */
294 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
295 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
296 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
297 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
298 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
299 V4L2_MBUS_PCLK_SAMPLE_RISING |\
300 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
301 V4L2_MBUS_DATA_ACTIVE_HIGH |\
302 V4L2_MBUS_DATA_ACTIVE_LOW|\
303 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
304 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
306 #define RK_CAM_W_MIN 48
307 #define RK_CAM_H_MIN 32
308 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
309 #define RK_CAM_H_MAX 2764
310 #define RK_CAM_FRAME_INVAL_INIT 0
311 #define RK_CAM_FRAME_INVAL_DC 0 /* ddl@rock-chips.com : */
312 #define RK30_CAM_FRAME_MEASURE 5
315 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
316 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
317 /* buffer for one video frame */
318 struct rk_camera_buffer
320 /* common v4l buffer stuff -- must be first */
321 struct videobuf_buffer vb;
322 enum v4l2_mbus_pixelcode code;
325 enum rk_camera_reg_state
333 unsigned int cifCtrl;
334 unsigned int cifCrop;
336 unsigned int cifIntEn;
338 unsigned int cifVirWidth;
339 unsigned int cifScale;
340 /* unsigned int VipCrm;*/
341 enum rk_camera_reg_state Inval;
343 struct rk_camera_work
345 struct videobuf_buffer *vb;
346 struct rk_camera_dev *pcdev;
347 struct work_struct work;
348 struct list_head queue;
351 struct rk_camera_frmivalenum
353 struct v4l2_frmivalenum fival;
354 struct rk_camera_frmivalenum *nxt;
356 struct rk_camera_frmivalinfo
358 struct soc_camera_device *icd;
359 struct rk_camera_frmivalenum *fival_list;
361 struct rk_camera_zoominfo
363 struct semaphore sem;
369 #if CAMERA_VIDEOBUF_ARM_ACCESS
370 struct rk29_camera_vbinfo
372 unsigned int phy_addr;
373 void __iomem *vir_addr;
377 struct rk_camera_timer{
378 struct rk_camera_dev *pcdev;
379 struct hrtimer timer;
384 /************must modify start************/
386 struct clk *aclk_cif;
387 struct clk *hclk_cif;
388 struct clk *cif_clk_in;
389 struct clk *cif_clk_out;
390 /************must modify end************/
400 struct v4l2_rect bounds;
403 struct rk_cif_irqinfo
406 unsigned long cifirq_idx;
407 unsigned long cifirq_normal_idx;
408 unsigned long cifirq_abnormal_idx;
410 unsigned long dmairq_idx;
416 struct soc_camera_host soc_host;
418 /* RK2827x is only supposed to handle one camera on its Quick Capture
419 * interface. If anyone ever builds hardware to enable more than
420 * one camera, they will have to modify this driver too */
421 struct soc_camera_device *icd;
423 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
426 unsigned int last_fps;
427 unsigned long frame_interval;
430 unsigned int vipmem_phybase;
431 void __iomem *vipmem_virbase;
432 unsigned int vipmem_size;
433 unsigned int vipmem_bsize;
434 #if CAMERA_VIDEOBUF_ARM_ACCESS
435 struct rk29_camera_vbinfo *vbinfo;
436 unsigned int vbinfo_count;
440 int host_left; /*sensor output size ?*/
446 struct rk_cif_crop cropinfo;
447 struct rk_cif_irqinfo irqinfo;
449 struct rk29camera_platform_data *pdata;
450 struct resource *res;
451 struct list_head capture;
452 struct rk_camera_zoominfo zoominfo;
456 struct videobuf_buffer *active;
457 struct rk_camera_reg reginfo_suspend;
458 struct workqueue_struct *camera_wq;
459 struct rk_camera_work *camera_work;
460 struct list_head camera_work_queue;
461 spinlock_t camera_work_lock;
462 unsigned int camera_work_count;
463 struct rk_camera_timer fps_timer;
464 struct rk_camera_work camera_reinit_work;
466 rk29_camera_sensor_cb_s icd_cb;
467 struct rk_camera_frmivalinfo icd_frmival[2];
469 unsigned int reinit_times;
470 struct videobuf_queue *video_vq;
472 struct timeval first_tv;
477 static const struct v4l2_queryctrl rk_camera_controls[] =
480 .id = V4L2_CID_ZOOM_ABSOLUTE,
481 .type = V4L2_CTRL_TYPE_INTEGER,
482 .name = "DigitalZoom Control",
486 .default_value = 100,
490 static struct rk_cif_clk cif_clk[2];
492 static DEFINE_MUTEX(camera_lock);
493 static const char *rk_cam_driver_description = "RK_Camera";
495 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
496 static void rk_camera_capture_process(struct work_struct *work);
498 static void rk_camera_diffchips(const char *rockchip_name)
500 if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
502 CRU_PCLK_REG30 = 0xbc;
503 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
504 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7));
505 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
506 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
509 clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7));
510 CRU_CLKSEL29_CON = 0xb8;
511 cif0_clk_sel = ((0x1<<23)|(0x0<<7));
515 else if(strstr(rockchip_name,"3288"))
517 CRU_PCLK_REG30 = 0xd4;
518 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x1<<4));
519 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x0<<4));
520 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
521 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
529 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
531 void __iomem *reg = RK_CRU_VIRT + RK_CRU_SOFTRST_CON;
533 if(CHIP_NAME == 3126){
534 val = on ? 0x10001U << 14 : 0x10000U << 14;
535 }else if(CHIP_NAME == 3288){
536 val = on ? 0x10001U << 8 : 0x10000U << 8;
538 writel_relaxed(val, reg);
542 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
544 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
545 u32 RK_CRU_SOFTRST_CON = 0;
546 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
547 if(CHIP_NAME == 3126){
548 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
549 }else if(CHIP_NAME == 3288){
550 RK_CRU_SOFTRST_CON = RK3288_CRU_SOFTRSTS_CON(6);
553 if (only_rst == true) {
554 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
556 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
558 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
559 if (ctrl_reg & ENABLE_CAPTURE) {
560 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
562 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
563 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
564 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
565 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
566 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
567 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
568 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
569 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
571 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
573 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
575 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
576 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
577 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
578 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
579 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
580 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
581 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
582 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
583 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
590 * Videobuf operations
592 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
595 struct soc_camera_device *icd = vq->priv_data;
596 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
597 struct rk_camera_dev *pcdev = ici->priv;
599 struct rk_camera_work *wk;
601 struct soc_mbus_pixelfmt fmt;
603 int bytes_per_line_host;
604 fmt.packing = SOC_MBUS_PACKING_1_5X8;
606 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
609 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
610 icd->current_fmt->host_fmt);
611 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
612 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
614 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
615 bytes_per_line_host = pcdev->host_width*3;
617 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
618 icd->current_fmt->host_fmt);
619 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
621 if (bytes_per_line_host < 0)
622 return bytes_per_line_host;
624 /* planar capture requires Y, U and V buffers to be page aligned */
625 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
626 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
628 if (CAM_WORKQUEUE_IS_EN()) {
630 if (CAM_IPPWORK_IS_EN()) {
631 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
632 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
633 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
637 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
638 kfree(pcdev->camera_work);
639 pcdev->camera_work = NULL;
640 pcdev->camera_work_count = 0;
643 if (pcdev->camera_work == NULL) {
644 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
645 if (pcdev->camera_work == NULL) {
646 RKCAMERA_TR("kmalloc failed\n");
649 INIT_LIST_HEAD(&pcdev->camera_work_queue);
651 for (i=0; i<(*count); i++) {
653 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
656 pcdev->camera_work_count = (*count);
658 #if CAMERA_VIDEOBUF_ARM_ACCESS
659 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
660 kfree(pcdev->vbinfo);
661 pcdev->vbinfo = NULL;
662 pcdev->vbinfo_count = 0x00;
665 if (pcdev->vbinfo == NULL) {
666 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
667 if (pcdev->vbinfo == NULL) {
668 RKCAMERA_TR("vbinfo kmalloc fail\n");
671 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
672 pcdev->vbinfo_count = *count;
676 pcdev->video_vq = vq;
677 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
681 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
683 struct soc_camera_device *icd = vq->priv_data;
685 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
688 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
689 &buf->vb, buf->vb.baddr, buf->vb.bsize);
691 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
692 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
698 * This waits until this buffer is out of danger, i.e., until it is no
699 * longer in STATE_QUEUED or STATE_ACTIVE
701 videobuf_waiton(vq, &buf->vb, 0, 0);
702 videobuf_dma_contig_free(vq, &buf->vb);
703 /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
704 buf->vb.state = VIDEOBUF_NEEDS_INIT;
707 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
709 struct soc_camera_device *icd = vq->priv_data;
710 struct rk_camera_buffer *buf;
712 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
713 icd->current_fmt->host_fmt);
715 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
717 if ((bytes_per_line < 0) || (vb->boff == 0))
720 buf = container_of(vb, struct rk_camera_buffer, vb);
722 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
723 /* vb, vb->baddr, vb->bsize);*/ /*yzm*/
725 /* Added list head initialization on alloc */
726 WARN_ON(!list_empty(&vb->queue));
728 BUG_ON(NULL == icd->current_fmt);
730 if (buf->code != icd->current_fmt->code ||
731 vb->width != icd->user_width ||
732 vb->height != icd->user_height ||
733 vb->field != field) {
734 buf->code = icd->current_fmt->code;
735 vb->width = icd->user_width;
736 vb->height = icd->user_height;
738 vb->state = VIDEOBUF_NEEDS_INIT;
741 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
742 if (0 != vb->baddr && vb->bsize < vb->size) {
747 if (vb->state == VIDEOBUF_NEEDS_INIT) {
748 ret = videobuf_iolock(vq, vb, NULL);
752 vb->state = VIDEOBUF_PREPARED;
757 rk_videobuf_free(vq, buf);
762 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
764 unsigned int y_addr,uv_addr;
765 struct rk_camera_dev *pcdev = rk_pcdev;
767 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
771 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
772 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
773 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
774 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
775 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
776 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
781 uv_addr = y_addr + vb->width * vb->height;
783 #if defined(CONFIG_ARCH_RK3188)
784 rk_camera_cif_reset(pcdev,false);
786 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
787 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
788 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
789 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
790 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
793 /* Locking: Caller holds q->irqlock */
794 static void rk_videobuf_queue(struct videobuf_queue *vq,
795 struct videobuf_buffer *vb)
797 struct soc_camera_device *icd = vq->priv_data;
798 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
799 struct rk_camera_dev *pcdev = ici->priv;
800 #if CAMERA_VIDEOBUF_ARM_ACCESS
801 struct rk29_camera_vbinfo *vb_info;
805 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
807 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
808 vb, vb->baddr, vb->bsize); */ /*yzm*/
810 vb->state = VIDEOBUF_QUEUED;
811 if (list_empty(&pcdev->capture)) {
812 list_add_tail(&vb->queue, &pcdev->capture);
814 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
815 list_add_tail(&vb->queue, &pcdev->capture);
817 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
819 #if CAMERA_VIDEOBUF_ARM_ACCESS
821 vb_info = pcdev->vbinfo+vb->i;
822 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
823 if (vb_info->vir_addr) {
824 iounmap(vb_info->vir_addr);
825 release_mem_region(vb_info->phy_addr, vb_info->size);
826 vb_info->vir_addr = NULL;
827 vb_info->phy_addr = 0x00;
828 vb_info->size = 0x00;
831 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
832 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
835 if (vb_info->vir_addr) {
836 vb_info->size = vb->bsize;
837 vb_info->phy_addr = vb->boff;
839 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
844 if (!pcdev->active) {
846 rk_videobuf_capture(vb,pcdev);
847 if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
848 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
853 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
854 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
857 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
861 case V4L2_PIX_FMT_YUV420:
862 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.*/
863 case V4L2_PIX_FMT_YUYV:
865 *ippfmt = RK_FORMAT_YCbCr_420_SP;
868 case V4L2_PIX_FMT_YVU420:
869 case V4L2_PIX_FMT_VYUY:
870 case V4L2_PIX_FMT_YVYU:
872 *ippfmt = RK_FORMAT_YCrCb_420_SP;
875 case V4L2_PIX_FMT_RGB565:
877 *ippfmt = RK_FORMAT_RGB_565;
880 case V4L2_PIX_FMT_RGB24:
882 *ippfmt = RK_FORMAT_RGB_888;
886 goto rk_pixfmt2rgafmt_err;
890 rk_pixfmt2rgafmt_err:
894 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
895 static int rk_camera_scale_crop_pp(struct work_struct *work){
896 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
897 struct videobuf_buffer *vb = camera_work->vb;
898 struct rk_camera_dev *pcdev = camera_work->pcdev;
900 unsigned long int flags;
908 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
909 extern rga_service_info rga_service;
910 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
911 extern void rga_service_session_clear(rga_session *session);
912 static int rk_camera_scale_crop_rga(struct work_struct *work){
913 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
914 struct videobuf_buffer *vb = camera_work->vb;
915 struct rk_camera_dev *pcdev = camera_work->pcdev;
917 unsigned long int flags;
923 const struct soc_mbus_pixelfmt *fmt;
926 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
933 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
935 static int rk_camera_scale_crop_ipp(struct work_struct *work)
941 static void rk_camera_capture_process(struct work_struct *work)
943 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
944 struct videobuf_buffer *vb = camera_work->vb;
945 struct rk_camera_dev *pcdev = camera_work->pcdev;
946 /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code; */
947 unsigned long flags = 0;
950 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
953 if (atomic_read(&pcdev->stop_cif)==true) {
955 goto rk_camera_capture_process_end;
958 if (!CAM_WORKQUEUE_IS_EN()) {
960 goto rk_camera_capture_process_end;
963 down(&pcdev->zoominfo.sem);
964 if (pcdev->icd_cb.scale_crop_cb){
965 err = (pcdev->icd_cb.scale_crop_cb)(work);
967 up(&pcdev->zoominfo.sem);
969 if (pcdev->icd_cb.sensor_cb)
970 (pcdev->icd_cb.sensor_cb)(vb);
972 rk_camera_capture_process_end:
974 vb->state = VIDEOBUF_ERROR;
976 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
977 vb->state = VIDEOBUF_DONE;
981 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
982 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
983 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
984 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
988 static void rk_camera_cifrest_delay(struct work_struct *work)
990 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
991 struct rk_camera_dev *pcdev = camera_work->pcdev;
992 unsigned long flags = 0;
994 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
998 rk_camera_cif_reset(pcdev,false);
1000 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1001 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1002 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1004 spin_lock_irqsave(&pcdev->lock,flags);
1005 if (atomic_read(&pcdev->stop_cif) == false) {
1006 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
1007 RKCAMERA_DG2("After reset cif, enable capture again!\n");
1009 spin_unlock_irqrestore(&pcdev->lock,flags);
1013 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
1015 struct rk_camera_dev *pcdev = data;
1016 struct rk_camera_work *wk;
1017 unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
1019 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1022 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1024 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1025 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
1026 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
1028 pcdev->irqinfo.cifirq_idx++;
1029 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1030 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1031 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1032 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1034 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1037 if(reg_cifctrl & ENABLE_CAPTURE) {
1038 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1041 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1042 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1043 if (!list_empty(&pcdev->camera_work_queue)) {
1044 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1045 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1046 list_del_init(&wk->queue);
1047 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1049 queue_work(pcdev->camera_wq, &(wk->work));
1057 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1059 struct rk_camera_dev *pcdev = data;
1060 struct videobuf_buffer *vb;
1061 struct rk_camera_work *wk;
1063 unsigned long reg_cifctrl;
1065 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1068 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1069 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1070 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { //frame 0 ready yzm
1071 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1073 pcdev->irqinfo.dmairq_idx++;
1074 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1075 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1080 do_gettimeofday(&pcdev->first_tv);
1085 if (pcdev->frame_inval>0) {
1086 pcdev->frame_inval--;
1087 rk_videobuf_capture(pcdev->active,pcdev);
1089 } else if (pcdev->frame_inval) {
1090 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1091 pcdev->frame_inval = 0;
1094 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1095 do_gettimeofday(&tv);
1096 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1097 /(RK30_CAM_FRAME_MEASURE-1);
1102 printk("no acticve buffer!!!\n");
1106 /* ddl@rock-chips.com : this vb may be deleted from queue */
1107 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1108 list_del_init(&vb->queue);
1110 pcdev->active = NULL;
1111 if (!list_empty(&pcdev->capture)) {
1112 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1113 if (pcdev->active) {
1114 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1115 rk_videobuf_capture(pcdev->active,pcdev);
1118 if (pcdev->active == NULL) {
1119 RKCAMERA_DG1("video_buf queue is empty!\n");
1122 do_gettimeofday(&vb->ts);
1123 if (CAM_WORKQUEUE_IS_EN()) {
1124 if (!list_empty(&pcdev->camera_work_queue)) {
1125 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1126 list_del_init(&wk->queue);
1127 INIT_WORK(&(wk->work), rk_camera_capture_process);
1130 queue_work(pcdev->camera_wq, &(wk->work));
1133 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1134 vb->state = VIDEOBUF_DONE;
1142 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1143 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1147 static irqreturn_t rk_camera_irq(int irq, void *data)
1149 struct rk_camera_dev *pcdev = data;
1150 unsigned long reg_intstat;
1153 spin_lock(&pcdev->lock);
1155 if(atomic_read(&pcdev->stop_cif) == true) {
1156 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
1160 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1161 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%lx\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1162 if (reg_intstat & 0x0200)
1163 rk_camera_cifirq(irq,data);
1165 if (reg_intstat & 0x01)
1166 rk_camera_dmairq(irq,data);
1169 spin_unlock(&pcdev->lock);
1174 static void rk_videobuf_release(struct videobuf_queue *vq,
1175 struct videobuf_buffer *vb)
1177 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1178 struct soc_camera_device *icd = vq->priv_data;
1179 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1180 struct rk_camera_dev *pcdev = ici->priv;
1181 #if CAMERA_VIDEOBUF_ARM_ACCESS
1182 struct rk29_camera_vbinfo *vb_info =NULL;
1187 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1190 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1191 vb, vb->baddr, vb->bsize);
1195 case VIDEOBUF_ACTIVE:
1196 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1198 case VIDEOBUF_QUEUED:
1199 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1201 case VIDEOBUF_PREPARED:
1202 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1205 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1210 flush_workqueue(pcdev->camera_wq);
1212 rk_videobuf_free(vq, buf);
1214 #if CAMERA_VIDEOBUF_ARM_ACCESS
1215 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1216 vb_info = pcdev->vbinfo + vb->i;
1218 if (vb_info->vir_addr) {
1219 iounmap(vb_info->vir_addr);
1220 release_mem_region(vb_info->phy_addr, vb_info->size);
1221 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1228 static struct videobuf_queue_ops rk_videobuf_ops =
1230 .buf_setup = rk_videobuf_setup,
1231 .buf_prepare = rk_videobuf_prepare,
1232 .buf_queue = rk_videobuf_queue,
1233 .buf_release = rk_videobuf_release,
1236 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1237 struct soc_camera_device *icd)
1239 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1240 struct rk_camera_dev *pcdev = ici->priv;
1242 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1245 /* We must pass NULL as dev pointer, then all pci_* dma operations
1246 * transform to normal dma_* ones. */
1247 videobuf_queue_dma_contig_init(q,
1249 ici->v4l2_dev.dev, &pcdev->lock,
1250 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1252 sizeof(struct rk_camera_buffer),
1253 icd,&(ici->host_lock) );
1256 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1259 struct rk_cif_clk *clk;
1261 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1264 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1265 if ((cif<0)||(cif>1)) {
1266 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1268 goto rk_camera_clk_ctrl_end;
1271 clk = &cif_clk[cif];
1273 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1274 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1276 goto rk_camera_clk_ctrl_end;
1279 //spin_lock(&clk->lock);
1280 if (on && !clk->on) {
1281 clk_prepare_enable(clk->pd_cif); /*yzm*/
1282 clk_prepare_enable(clk->aclk_cif);
1283 clk_prepare_enable(clk->hclk_cif);
1284 clk_prepare_enable(clk->cif_clk_in);
1285 clk_prepare_enable(clk->cif_clk_out);
1286 clk_set_rate(clk->cif_clk_out,clk_rate);
1288 } else if (!on && clk->on) {
1289 clk_set_rate(clk->cif_clk_out,36000000);/*yzm :just for close clk which base on XIN24M */
1291 clk_disable_unprepare(clk->aclk_cif);
1292 clk_disable_unprepare(clk->hclk_cif);
1293 clk_disable_unprepare(clk->cif_clk_in);
1294 if(CHIP_NAME == 3126){
1295 write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
1296 write_cru_reg(CRU_CLK_OUT, 0x00800080);
1298 clk_disable_unprepare(clk->cif_clk_out);
1299 clk_disable_unprepare(clk->pd_cif);
1303 //spin_unlock(&clk->lock);
1304 rk_camera_clk_ctrl_end:
1307 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1310 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1313 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1315 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1316 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1320 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1323 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1325 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1331 /* The following two functions absolutely depend on the fact, that
1332 * there can be only one camera on RK28 quick capture interface */
1333 static int rk_camera_add_device(struct soc_camera_device *icd)
1335 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1336 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1337 struct device *control = to_soc_camera_control(icd);
1338 struct v4l2_subdev *sd;
1339 int ret,i,icd_catch;
1340 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1341 struct v4l2_cropcap cropcap;
1342 struct v4l2_mbus_framefmt mf;
1343 const struct soc_camera_format_xlate *xlate = NULL;
1345 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1348 mutex_lock(&camera_lock);
1355 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1357 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1358 pcdev->active = NULL;
1360 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1361 pcdev->zoominfo.zoom_rate = 100;
1362 pcdev->fps_timer.istarted = false;
1364 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1365 * if app havn't dequeue all videobuf before close camera device;
1367 INIT_LIST_HEAD(&pcdev->capture);
1369 ret = rk_camera_activate(pcdev,icd);
1372 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1373 if (control) { //TRUE in open ,FALSE in kernel start
1374 sd = dev_get_drvdata(control);
1375 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1377 ret = v4l2_subdev_call(sd,core, init, 0);
1381 /* call generic_sensor_ioctl*/
1382 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1383 /* call generic_sensor_cropcap*/
1384 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1385 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1387 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1390 mf.field = V4L2_FIELD_NONE;
1391 mf.code = xlate->code;
1392 mf.reserved[6] = 0xfefe5a5a;
1393 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1395 pcdev->cropinfo.bounds.left = 0;
1396 pcdev->cropinfo.bounds.top = 0;
1397 pcdev->cropinfo.bounds.width = mf.width;
1398 pcdev->cropinfo.bounds.height = mf.height;
1402 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1404 pcdev->icd_init = 0;
1407 for (i=0; i<2; i++) {
1408 if (pcdev->icd_frmival[i].icd == icd)
1410 if (pcdev->icd_frmival[i].icd == NULL) {
1411 pcdev->icd_frmival[i].icd = icd;
1415 if (icd_catch == 0) {
1416 fival_list = pcdev->icd_frmival[0].fival_list;
1417 fival_nxt = fival_list;
1418 while(fival_nxt != NULL) {
1419 fival_nxt = fival_list->nxt;
1421 fival_list = fival_nxt;
1423 pcdev->icd_frmival[0].icd = icd;
1424 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1427 mutex_unlock(&camera_lock);
1431 static void rk_camera_remove_device(struct soc_camera_device *icd)
1433 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1434 struct rk_camera_dev *pcdev = ici->priv;
1435 /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
1436 #if CAMERA_VIDEOBUF_ARM_ACCESS
1437 struct rk29_camera_vbinfo *vb_info;
1441 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1444 mutex_lock(&camera_lock);
1445 BUG_ON(icd != pcdev->icd);
1447 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1449 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1450 stream may be turn on again before close device, if suspend and resume happened. */
1451 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1452 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1453 rk_camera_s_stream(icd,0);
1455 /* move DEACTIVATE into generic_sensor_s_power*/
1456 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
1457 /* if stream off is not been executed,timer is running.*/
1458 if(pcdev->fps_timer.istarted){
1459 hrtimer_cancel(&pcdev->fps_timer.timer);
1460 pcdev->fps_timer.istarted = false;
1462 flush_work(&(pcdev->camera_reinit_work.work));
1463 flush_workqueue((pcdev->camera_wq));
1465 if (pcdev->camera_work) {
1466 kfree(pcdev->camera_work);
1467 pcdev->camera_work = NULL;
1468 pcdev->camera_work_count = 0;
1469 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1471 rk_camera_deactivate(pcdev);
1472 #if CAMERA_VIDEOBUF_ARM_ACCESS
1473 if (pcdev->vbinfo) {
1474 vb_info = pcdev->vbinfo;
1475 for (i=0; i<pcdev->vbinfo_count; i++) {
1476 if (vb_info->vir_addr) {
1477 iounmap(vb_info->vir_addr);
1478 release_mem_region(vb_info->phy_addr, vb_info->size);
1479 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1483 kfree(pcdev->vbinfo);
1484 pcdev->vbinfo = NULL;
1485 pcdev->vbinfo_count = 0;
1488 pcdev->active = NULL;
1490 pcdev->icd_cb.sensor_cb = NULL;
1491 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1492 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1493 * if app havn't dequeue all videobuf before close camera device;
1495 INIT_LIST_HEAD(&pcdev->capture);
1497 mutex_unlock(&camera_lock);
1501 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1503 unsigned long bus_flags, camera_flags, common_flags = 0;
1504 unsigned int cif_for = 0;
1505 const struct soc_mbus_pixelfmt *fmt;
1507 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /*yzm*/
1508 struct rk_camera_dev *pcdev = ici->priv;
1510 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1513 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1517 bus_flags = RK_CAM_BUS_PARAM;
1518 /* If requested data width is supported by the platform, use it */
1519 switch (fmt->bits_per_sample) {
1521 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1525 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1529 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1535 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1536 if (icd->ops->query_bus_param)
1537 camera_flags = icd->ops->query_bus_param(icd);
1541 /**************yzm************
1542 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1543 if (!common_flags) {
1545 goto RK_CAMERA_SET_BUS_PARAM_END;
1548 /***************yzm************end*/
1551 common_flags = camera_flags;
1552 ret = icd->ops->set_bus_param(icd, common_flags);
1554 goto RK_CAMERA_SET_BUS_PARAM_END;
1556 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1558 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1560 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1562 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1566 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1568 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1572 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1573 cif_for |= HSY_LOW_ACTIVE;
1575 cif_for &= ~HSY_LOW_ACTIVE;
1577 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1578 cif_for |= VSY_HIGH_ACTIVE;
1580 cif_for &= ~VSY_HIGH_ACTIVE;
1583 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1584 //vip_ctrl_val |= ENABLE_CAPTURE;
1585 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1586 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1588 RK_CAMERA_SET_BUS_PARAM_END:
1590 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1594 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1596 /* unsigned long bus_flags, camera_flags;*/
1599 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1600 /**********yzm***********
1602 bus_flags = RK_CAM_BUS_PARAM;
1603 if (icd->ops->query_bus_param) {
1604 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1608 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1611 dev_warn(icd->dev.parent,
1612 "Flags incompatible: camera %lx, host %lx\n",
1613 camera_flags, bus_flags);
1616 *///************yzm **************end
1621 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1623 .fourcc = V4L2_PIX_FMT_NV12,
1624 .name = "YUV420 NV12",
1625 .bits_per_sample = 8,
1626 .packing = SOC_MBUS_PACKING_1_5X8,
1627 .order = SOC_MBUS_ORDER_LE,
1629 .fourcc = V4L2_PIX_FMT_NV16,
1630 .name = "YUV422 NV16",
1631 .bits_per_sample = 8,
1632 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1633 .order = SOC_MBUS_ORDER_LE,
1635 .fourcc = V4L2_PIX_FMT_NV21,
1636 .name = "YUV420 NV21",
1637 .bits_per_sample = 8,
1638 .packing = SOC_MBUS_PACKING_1_5X8,
1639 .order = SOC_MBUS_ORDER_LE,
1641 .fourcc = V4L2_PIX_FMT_NV61,
1642 .name = "YUV422 NV61",
1643 .bits_per_sample = 8,
1644 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1645 .order = SOC_MBUS_ORDER_LE,
1647 .fourcc = V4L2_PIX_FMT_RGB565,
1649 .bits_per_sample = 8,
1650 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1651 .order = SOC_MBUS_ORDER_LE,
1653 .fourcc = V4L2_PIX_FMT_RGB24,
1655 .bits_per_sample = 8,
1656 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1657 .order = SOC_MBUS_ORDER_LE,
1662 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1664 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1665 struct rk_camera_dev *pcdev = ici->priv;
1666 unsigned int cif_fs = 0,cif_crop = 0;
1667 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;
1669 const struct soc_mbus_pixelfmt *fmt;
1670 fmt = soc_mbus_get_fmtdesc(icd_code);
1672 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1675 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1676 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1677 host_pixfmt = V4L2_PIX_FMT_NV12;
1678 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1679 host_pixfmt = V4L2_PIX_FMT_NV21;
1681 switch (host_pixfmt)
1683 case V4L2_PIX_FMT_NV16:
1684 cif_fmt_val &= ~YUV_OUTPUT_422;
1685 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1686 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1687 pcdev->pixfmt = host_pixfmt;
1689 case V4L2_PIX_FMT_NV61:
1690 cif_fmt_val &= ~YUV_OUTPUT_422;
1691 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1692 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1693 pcdev->pixfmt = host_pixfmt;
1695 case V4L2_PIX_FMT_NV12:
1696 cif_fmt_val |= YUV_OUTPUT_420;
1697 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1698 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1699 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1700 pcdev->pixfmt = host_pixfmt;
1702 case V4L2_PIX_FMT_NV21:
1703 cif_fmt_val |= YUV_OUTPUT_420;
1704 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1705 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1706 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1707 pcdev->pixfmt = host_pixfmt;
1709 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1710 cif_fmt_val |= YUV_OUTPUT_422;
1715 case V4L2_MBUS_FMT_UYVY8_2X8:
1716 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1718 case V4L2_MBUS_FMT_YUYV8_2X8:
1719 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1721 case V4L2_MBUS_FMT_YVYU8_2X8:
1722 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1724 case V4L2_MBUS_FMT_VYUY8_2X8:
1725 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1728 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1733 rk_camera_cif_reset(pcdev,true);
1735 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1736 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1738 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 */
1740 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1741 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1742 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1744 } else{ /* this is one frame mode*/
1745 cif_crop = (rect->left + (rect->top <<16));
1746 cif_fs = (rect->width + (rect->height <<16));
1749 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1750 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1751 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1752 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1754 /*MUST bypass scale */
1755 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1756 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);
1760 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1761 struct soc_camera_format_xlate *xlate)
1763 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1764 struct device *dev = icd->parent;/*yzm*/
1765 int formats = 0, ret;
1766 enum v4l2_mbus_pixelcode code;
1767 const struct soc_mbus_pixelfmt *fmt;
1769 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1772 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); /*call generic_sensor_enum_fmt()*/
1774 /* No more formats */
1777 fmt = soc_mbus_get_fmtdesc(code);
1779 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1783 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1788 case V4L2_MBUS_FMT_UYVY8_2X8:
1789 case V4L2_MBUS_FMT_YUYV8_2X8:
1790 case V4L2_MBUS_FMT_YVYU8_2X8:
1791 case V4L2_MBUS_FMT_VYUY8_2X8:
1794 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1797 xlate->host_fmt = &rk_camera_formats[0];
1800 dev_dbg(dev, "Providing format %s using code %d\n",
1801 rk_camera_formats[0].name,code);
1806 xlate->host_fmt = &rk_camera_formats[1];
1809 dev_dbg(dev, "Providing format %s using code %d\n",
1810 rk_camera_formats[1].name,code);
1815 xlate->host_fmt = &rk_camera_formats[2];
1818 dev_dbg(dev, "Providing format %s using code %d\n",
1819 rk_camera_formats[2].name,code);
1824 xlate->host_fmt = &rk_camera_formats[3];
1827 dev_dbg(dev, "Providing format %s using code %d\n",
1828 rk_camera_formats[3].name,code);
1834 xlate->host_fmt = &rk_camera_formats[4];
1837 dev_dbg(dev, "Providing format %s using code %d\n",
1838 rk_camera_formats[4].name,code);
1842 xlate->host_fmt = &rk_camera_formats[5];
1845 dev_dbg(dev, "Providing format %s using code %d\n",
1846 rk_camera_formats[5].name,code);
1858 static void rk_camera_put_formats(struct soc_camera_device *icd)
1861 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1865 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1867 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1870 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1872 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1875 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1876 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1880 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1882 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1883 struct rk_camera_dev *pcdev = ici->priv;
1885 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1888 spin_lock(&pcdev->cropinfo.lock);
1889 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1890 spin_unlock(&pcdev->cropinfo.lock);
1894 static int rk_camera_set_crop(struct soc_camera_device *icd,
1895 const struct v4l2_crop *crop)
1897 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1898 struct rk_camera_dev *pcdev = ici->priv;
1900 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1903 spin_lock(&pcdev->cropinfo.lock);
1904 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1905 spin_unlock(&pcdev->cropinfo.lock);
1908 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1912 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1915 if (f->fmt.pix.priv == 0xfefe5a5a) {
1919 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1921 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1923 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1925 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1927 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1929 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1934 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1937 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1938 struct v4l2_format *f)
1940 struct device *dev = icd->parent;/*yzm*/
1941 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1942 const struct soc_camera_format_xlate *xlate = NULL;
1943 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1944 struct rk_camera_dev *pcdev = ici->priv;
1945 struct v4l2_pix_format *pix = &f->fmt.pix;
1946 struct v4l2_mbus_framefmt mf;
1947 struct v4l2_rect rect;
1948 int ret,usr_w,usr_h,sensor_w,sensor_h;
1950 int ratio, bounds_aspect;
1952 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1956 usr_h = pix->height;
1958 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
1959 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1961 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1963 goto RK_CAMERA_SET_FMT_END;
1966 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1967 if (pcdev->icd_init == 0) {
1968 v4l2_subdev_call(sd,core, init, 0); /*call generic_sensor_init()*/
1969 pcdev->icd_init = 1;
1970 return 0; /*directly return !!!!!!*/
1972 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1973 if (stream_on & ENABLE_CAPTURE)
1974 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1976 mf.width = pix->width;
1977 mf.height = pix->height;
1978 mf.field = pix->field;
1979 mf.colorspace = pix->colorspace;
1980 mf.code = xlate->code;
1981 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
1984 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); /*generic_sensor_s_fmt*/
1985 if (mf.code != xlate->code)
1988 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
1989 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
1990 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
1991 if ((mf.width*10/mf.height) != bounds_aspect) {
1992 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
1993 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
1995 mf.width = pcdev->cropinfo.bounds.width/4;
1996 mf.height = pcdev->cropinfo.bounds.height/4;
1998 mf.field = pix->field;
1999 mf.colorspace = pix->colorspace;
2000 mf.code = xlate->code;
2001 mf.reserved[0] = pix->priv;
2004 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2005 if (mf.code != xlate->code)
2010 sensor_w = mf.width;
2011 sensor_h = mf.height;
2013 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
2016 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
2019 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2021 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2022 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2024 goto RK_CAMERA_SET_FMT_END;
2026 if (unlikely((usr_w <16)||(usr_h < 16))) {
2027 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2029 goto RK_CAMERA_SET_FMT_END;
2032 spin_lock(&pcdev->cropinfo.lock);
2033 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2034 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2035 /*Scale + Crop center is for keep aspect ratio unchange*/
2036 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2037 pcdev->host_width = ratio*usr_w/10;
2038 pcdev->host_height = ratio*usr_h/10;
2039 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2040 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2042 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2043 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2045 /*Scale + crop(user define)*/
2046 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2047 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2048 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2049 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2052 pcdev->host_left &= (~0x01);
2053 pcdev->host_top &= (~0x01);
2055 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2056 /*Crop Center for cif can work , then scale*/
2057 pcdev->host_width = mf.width;
2058 pcdev->host_height = mf.height;
2059 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2060 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2062 /*Crop center for cif can work + crop(user define), then scale */
2063 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2064 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2065 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2066 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2069 pcdev->host_left &= (~0x01);
2070 pcdev->host_top &= (~0x01);
2072 spin_unlock(&pcdev->cropinfo.lock);
2074 spin_lock(&pcdev->cropinfo.lock);
2075 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2076 pcdev->host_width = mf.width;
2077 pcdev->host_height = mf.height;
2078 pcdev->host_left = 0;
2079 pcdev->host_top = 0;
2081 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2082 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2083 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2084 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2086 spin_unlock(&pcdev->cropinfo.lock);
2091 rect.width = pcdev->host_width;
2092 rect.height = pcdev->host_height;
2093 rect.left = pcdev->host_left;
2094 rect.top = pcdev->host_top;
2096 down(&pcdev->zoominfo.sem);
2097 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2098 pcdev->zoominfo.a.c.left = 0;
2099 pcdev->zoominfo.a.c.top = 0;
2100 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2101 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2102 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2103 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2104 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2105 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2106 /*recalculate the CIF width & height*/
2107 rect.width = pcdev->zoominfo.a.c.width ;
2108 rect.height = pcdev->zoominfo.a.c.height;
2109 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2110 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2112 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2113 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2114 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2115 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2116 /*now digital zoom use ipp to do crop and scale*/
2117 if(pcdev->zoominfo.zoom_rate != 100){
2118 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2119 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2121 pcdev->zoominfo.a.c.left = 0;
2122 pcdev->zoominfo.a.c.top = 0;
2124 pcdev->zoominfo.vir_width = pcdev->host_width;
2125 pcdev->zoominfo.vir_height = pcdev->host_height;
2127 up(&pcdev->zoominfo.sem);
2129 /* ddl@rock-chips.com: IPP work limit check */
2130 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2131 if (usr_w > 0x7f0) {
2132 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2133 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));
2135 goto RK_CAMERA_SET_FMT_END;
2138 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2139 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2141 goto RK_CAMERA_SET_FMT_END;
2146 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,
2147 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2148 sensor_w,sensor_h,mf.width,mf.height,
2149 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2150 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2151 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2152 pix->width, pix->height);
2154 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2156 if (CAM_IPPWORK_IS_EN()) {
2157 BUG_ON(pcdev->vipmem_phybase == 0);
2160 pix->height = usr_h;
2161 pix->field = mf.field;
2162 pix->colorspace = mf.colorspace;
2163 icd->current_fmt = xlate;
2164 pcdev->icd_width = mf.width;
2165 pcdev->icd_height = mf.height;
2168 RK_CAMERA_SET_FMT_END:
2169 if (stream_on & ENABLE_CAPTURE)
2170 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2172 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2176 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2177 struct v4l2_format *f)
2179 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2180 struct rk_camera_dev *pcdev = ici->priv;
2181 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2182 const struct soc_camera_format_xlate *xlate;
2183 struct v4l2_pix_format *pix = &f->fmt.pix;
2184 __u32 pixfmt = pix->pixelformat;
2185 int ret,usr_w,usr_h,i;
2186 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2187 bool vipmem_is_overflow = false;
2188 struct v4l2_mbus_framefmt mf;
2189 int bytes_per_line_host;
2192 usr_h = pix->height;
2194 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2196 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2198 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2199 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
2200 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2202 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2203 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2204 for (i = 0; i < icd->num_user_formats; i++)
2205 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2206 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2207 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2208 icd->user_formats[i].host_fmt->name);
2209 goto RK_CAMERA_TRY_FMT_END;
2211 /* limit to rk29 hardware capabilities */
2212 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2213 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2214 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2216 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2218 if (pix->bytesperline < 0)
2219 return pix->bytesperline;
2221 /* limit to sensor capabilities */
2222 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2223 mf.width = pix->width;
2224 mf.height = pix->height;
2225 mf.field = pix->field;
2226 mf.colorspace = pix->colorspace;
2227 mf.code = xlate->code;
2228 /* ddl@rock-chips.com : It is query max resolution only. */
2229 if ((usr_w == 10000) && (usr_h == 10000)) {
2230 mf.reserved[6] = 0xfefe5a5a;
2232 /* call generic_sensor_try_fmt()*/
2233 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2235 goto RK_CAMERA_TRY_FMT_END;
2237 /*query resolution.*/
2238 if((usr_w == 10000) && (usr_h == 10000)) {
2239 pix->width = mf.width;
2240 pix->height = mf.height;
2241 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2242 goto RK_CAMERA_TRY_FMT_END;
2244 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2247 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2248 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2250 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2252 /* Assume preview buffer minimum is 4 */
2253 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2255 if (vipmem_is_overflow == false) {
2257 pix->height = usr_h;
2259 /*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*/
2260 pix->width = mf.width;
2261 pix->height = mf.height;
2263 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2265 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2266 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2267 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2268 pix->width = mf.width;
2269 pix->height = mf.height;
2275 pix->colorspace = mf.colorspace;
2278 case V4L2_FIELD_ANY:
2279 case V4L2_FIELD_NONE:
2280 pix->field = V4L2_FIELD_NONE;
2283 /* TODO: support interlaced at least in pass-through mode */
2284 dev_err(icd->parent, "Field type %d unsupported.\n",
2286 goto RK_CAMERA_TRY_FMT_END;
2289 RK_CAMERA_TRY_FMT_END:
2291 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2295 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2296 struct v4l2_requestbuffers *p)
2300 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2303 /* This is for locking debugging only. I removed spinlocks and now I
2304 * check whether .prepare is ever called on a linked buffer, or whether
2305 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2306 * it hadn't triggered */
2307 for (i = 0; i < p->count; i++) {
2308 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2309 struct rk_camera_buffer, vb);
2311 INIT_LIST_HEAD(&buf->vb.queue);
2317 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2319 struct soc_camera_device *icd = file->private_data;
2320 struct rk_camera_buffer *buf;
2322 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2325 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2328 poll_wait(file, &buf->vb.done, pt);
2330 if (buf->vb.state == VIDEOBUF_DONE ||
2331 buf->vb.state == VIDEOBUF_ERROR)
2332 return POLLIN|POLLRDNORM;
2337 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2338 * 10 5 1 3 3 3 + 5 < 32
2341 static int rk_camera_querycap(struct soc_camera_host *ici,
2342 struct v4l2_capability *cap)
2344 struct rk_camera_dev *pcdev = ici->priv;
2345 struct rkcamera_platform_data *new_camera;
2346 char orientation[5];
2350 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2353 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2354 memset(orientation,0x00,sizeof(orientation));
2357 new_camera = pcdev->pdata->register_dev_new;
2358 while(new_camera != NULL){
2359 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2360 sprintf(orientation,"-%d",new_camera->orientation);
2361 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2363 new_camera = new_camera->next_camera;
2366 if (orientation[0] != '-') {
2367 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2368 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2369 strcat(cap->card,"-270");
2371 strcat(cap->card,"-90");
2373 strcat(cap->card,orientation);
2376 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2377 cap->version = RK_CAM_VERSION_CODE;
2378 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2379 cap->reserved[0] = pcdev->pdata->iommu_enabled;
2380 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2384 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2386 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2387 struct rk_camera_dev *pcdev = ici->priv;
2388 struct v4l2_subdev *sd;
2391 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2394 mutex_lock(&camera_lock);
2395 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2396 rk_camera_s_stream(icd, 0);
2397 sd = soc_camera_to_subdev(icd);
2398 v4l2_subdev_call(sd, video, s_stream, 0);
2399 ret = icd->ops->suspend(icd, state);
2401 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2402 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2403 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2404 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2405 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2406 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2407 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2409 pcdev->reginfo_suspend.Inval = Reg_Validate;
2410 rk_camera_deactivate(pcdev);
2412 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2414 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2416 mutex_unlock(&camera_lock);
2420 static int rk_camera_resume(struct soc_camera_device *icd)
2422 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2423 struct rk_camera_dev *pcdev = ici->priv;
2424 struct v4l2_subdev *sd;
2427 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2430 mutex_lock(&camera_lock);
2431 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2432 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2433 rk_camera_activate(pcdev, icd);
2434 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2435 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2436 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2437 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2438 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2439 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2440 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2441 rk_videobuf_capture(pcdev->active,pcdev);
2442 rk_camera_s_stream(icd, 1);
2443 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2445 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2446 goto rk_camera_resume_end;
2449 ret = icd->ops->resume(icd);
2450 sd = soc_camera_to_subdev(icd);
2451 v4l2_subdev_call(sd, video, s_stream, 1);
2453 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2455 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2458 rk_camera_resume_end:
2459 mutex_unlock(&camera_lock);
2463 static void rk_camera_reinit_work(struct work_struct *work)
2465 struct v4l2_subdev *sd;
2466 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2467 struct rk_camera_dev *pcdev = camera_work->pcdev;
2468 /*struct soc_camera_link *tmp_soc_cam_link;*/
2469 struct v4l2_mbus_framefmt mf;
2471 unsigned long flags = 0;
2474 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2477 if(pcdev->icd == NULL)
2479 sd = soc_camera_to_subdev(pcdev->icd);
2480 /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2483 RKCAMERA_TR("CIF_CIF_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2484 RKCAMERA_TR("CIF_CIF_INTEN = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2485 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2486 RKCAMERA_TR("CIF_CIF_FOR = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2487 RKCAMERA_TR("CIF_CIF_CROP = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2488 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2489 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2490 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%lx\n",read_cru_reg(CRU_PCLK_REG30));
2491 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2493 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2494 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2495 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2496 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2497 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2498 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2499 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2500 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2501 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2504 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2505 if (pcdev->reinit_times == 1) {
2506 if (ctrl & ENABLE_CAPTURE) {
2507 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2508 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2509 rk_camera_cif_reset(pcdev,false);
2512 v4l2_subdev_call(sd,core, init, 0);
2514 mf.width = pcdev->icd_width;
2515 mf.height = pcdev->icd_height;
2516 mf.field = V4L2_FIELD_NONE;
2517 mf.code = pcdev->icd->current_fmt->code;
2518 mf.reserved[0] = 0x5a5afefe;
2521 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2523 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2524 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2525 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2526 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2527 rk_camera_cif_reset(pcdev,false);
2528 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2533 atomic_set(&pcdev->stop_cif,true);
2534 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2535 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2537 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2538 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2539 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2540 if (NULL == pcdev->video_vq->bufs[index])
2543 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2544 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2545 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2546 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2547 printk("wake up video buffer index = %d !!!\n",index);
2550 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2552 RKCAMERA_TR("video queue has somthing wrong !!\n");
2555 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2557 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2559 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2560 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2561 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2563 /*static unsigned int last_fps = 0;*/
2564 /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
2565 /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2567 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2569 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2570 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2571 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2572 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2573 pcdev->camera_reinit_work.pcdev = pcdev;
2574 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2575 pcdev->reinit_times++;
2576 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2577 } else if(!pcdev->timer_get_fps) {
2578 pcdev->timer_get_fps = true;
2579 for (i=0; i<2; i++) {
2580 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2581 fival_nxt = pcdev->icd_frmival[i].fival_list;
2586 fival_pre = fival_nxt;
2587 while (fival_nxt != NULL) {
2589 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
2590 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2591 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2592 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2593 fival_nxt->fival.discrete.numerator);
2595 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2596 && (fival_nxt->fival.height == pcdev->icd->user_height)
2597 && (fival_nxt->fival.width == pcdev->icd->user_width))
2598 || (fival_nxt->fival.discrete.denominator == 0)) {
2600 if (fival_nxt->fival.discrete.denominator == 0) {
2601 fival_nxt->fival.index = 0;
2602 fival_nxt->fival.width = pcdev->icd->user_width;
2603 fival_nxt->fival.height= pcdev->icd->user_height;
2604 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2605 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2606 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2607 |(pcdev->icd_height);
2608 fival_nxt->fival.discrete.numerator = 1000000;
2609 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2612 fival_rec = fival_nxt;
2614 fival_pre = fival_nxt;
2615 fival_nxt = fival_nxt->nxt;
2618 if ((rec_flag == 0) && fival_pre) {
2619 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2620 if (fival_pre->nxt != NULL) {
2621 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2622 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2623 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2624 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2626 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2627 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2628 |(pcdev->icd_height);
2629 fival_pre->nxt->fival.discrete.numerator = 1000000;
2630 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2632 fival_rec = fival_pre->nxt;
2637 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2638 pcdev->reinit_times = 0;
2640 pcdev->last_fps = pcdev->fps ;
2641 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2642 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2643 /*return HRTIMER_NORESTART;*/
2644 if(pcdev->reinit_times >=2)
2645 return HRTIMER_NORESTART;
2647 return HRTIMER_RESTART;
2649 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2651 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2652 struct rk_camera_dev *pcdev = ici->priv;
2655 unsigned long flags;
2657 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2659 WARN_ON(pcdev->icd != icd);
2661 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2664 pcdev->last_fps = 0;
2665 pcdev->frame_interval = 0;
2666 hrtimer_cancel(&(pcdev->fps_timer.timer));
2667 pcdev->fps_timer.pcdev = pcdev;
2668 pcdev->timer_get_fps = false;
2669 pcdev->reinit_times = 0;
2671 spin_lock_irqsave(&pcdev->lock,flags);
2672 atomic_set(&pcdev->stop_cif,false);
2673 pcdev->irqinfo.cifirq_idx = 0;
2674 pcdev->irqinfo.cifirq_normal_idx = 0;
2675 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2676 pcdev->irqinfo.dmairq_idx = 0;
2678 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2679 cif_ctrl_val |= ENABLE_CAPTURE;
2680 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2681 spin_unlock_irqrestore(&pcdev->lock,flags);
2682 printk("%s:stream enable CIF_CIF_CTRL 0x%lx\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2683 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2684 pcdev->fps_timer.istarted = true;
2686 /*cancel timer before stop cif*/
2687 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2688 pcdev->fps_timer.istarted = false;
2689 flush_work(&(pcdev->camera_reinit_work.work));
2691 cif_ctrl_val &= ~ENABLE_CAPTURE;
2692 spin_lock_irqsave(&pcdev->lock, flags);
2693 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2694 atomic_set(&pcdev->stop_cif,true);
2695 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2696 spin_unlock_irqrestore(&pcdev->lock, flags);
2697 flush_workqueue((pcdev->camera_wq));
2700 /*must be reinit,or will be somthing wrong in irq process.*/
2701 if(enable == false) {
2702 pcdev->active = NULL;
2703 INIT_LIST_HEAD(&pcdev->capture);
2705 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%lx\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2708 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2710 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2711 struct rk_camera_dev *pcdev = ici->priv;
2712 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2713 struct rk_camera_frmivalenum *fival_list = NULL;
2714 struct v4l2_frmivalenum *fival_head = NULL;
2715 struct rkcamera_platform_data *new_camera;
2716 int i,ret = 0,index;
2717 const struct soc_camera_format_xlate *xlate;
2718 struct v4l2_mbus_framefmt mf;
2721 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2723 index = fival->index & 0x00ffffff;
2724 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2725 for (i=0; i<2; i++) {
2726 if (pcdev->icd_frmival[i].icd == icd) {
2727 fival_list = pcdev->icd_frmival[i].fival_list;
2731 if (fival_list != NULL) {
2733 while (fival_list != NULL) {
2734 if ((fival->pixel_format == fival_list->fival.pixel_format)
2735 && (fival->height == fival_list->fival.height)
2736 && (fival->width == fival_list->fival.width)) {
2741 fival_list = fival_list->nxt;
2744 if ((i==index) && (fival_list != NULL)) {
2745 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2750 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2757 while (fival_head->width && fival_head->height) {
2758 if ((fival->pixel_format == fival_head->pixel_format)
2759 && (fival->height == fival_head->height)
2760 && (fival->width == fival_head->width)) {
2769 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2770 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2772 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2773 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2774 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2775 mf.width = fival->width;
2776 mf.height = fival->height;
2777 mf.code = xlate->code;
2779 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2781 fival->reserved[1] = (mf.width<<16)|(mf.height);
2783 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2784 fival->width, fival->height,
2785 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2786 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2787 fival->discrete.denominator,fival->discrete.numerator);
2790 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2791 fival->width,fival->height,
2792 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2793 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2796 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2797 fival->width,fival->height,
2798 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2799 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2802 goto rk_camera_enum_frameintervals_end;
2806 new_camera = pcdev->pdata->register_dev_new;
2807 while(new_camera != NULL){
2808 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2812 new_camera = new_camera->next_camera;
2816 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2817 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2820 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2821 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2822 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2823 mf.width = fival->width;
2824 mf.height = fival->height;
2825 mf.code = xlate->code;
2827 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2829 fival->discrete.numerator= 1000;
2830 fival->discrete.denominator = 15000;
2831 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2832 fival->reserved[1] = (mf.width<<16)|(mf.height);
2836 rk_camera_enum_frameintervals_end:
2840 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2841 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2844 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2845 struct rk_camera_dev *pcdev = ici->priv;
2847 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2851 unsigned long tmp_cifctrl;
2854 /*change the crop and scale parameters*/
2857 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2858 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2859 a.c.width = pcdev->host_width*100/zoom_rate;
2860 a.c.width &= ~CROP_ALIGN_BYTES;
2861 a.c.height = pcdev->host_height*100/zoom_rate;
2862 a.c.height &= ~CROP_ALIGN_BYTES;
2863 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2864 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2865 atomic_set(&pcdev->stop_cif,true);
2866 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2867 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2868 hrtimer_cancel(&(pcdev->fps_timer.timer));
2869 flush_workqueue((pcdev->camera_wq));
2871 down(&pcdev->zoominfo.sem);
2872 pcdev->zoominfo.a.c.left = 0;
2873 pcdev->zoominfo.a.c.top = 0;
2874 pcdev->zoominfo.a.c.width = a.c.width;
2875 pcdev->zoominfo.a.c.height = a.c.height;
2876 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2877 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2878 pcdev->frame_inval = 1;
2879 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2880 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2881 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2882 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2884 rk_videobuf_capture(pcdev->active,pcdev);
2885 if(tmp_cifctrl & ENABLE_CAPTURE)
2886 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2887 up(&pcdev->zoominfo.sem);
2889 atomic_set(&pcdev->stop_cif,false);
2890 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2891 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 );
2893 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2894 a.c.width = pcdev->host_width*100/zoom_rate;
2895 a.c.width &= ~CROP_ALIGN_BYTES;
2896 a.c.height = pcdev->host_height*100/zoom_rate;
2897 a.c.height &= ~CROP_ALIGN_BYTES;
2898 a.c.left = (pcdev->host_width - a.c.width)>>1;
2899 a.c.top = (pcdev->host_height - a.c.height)>>1;
2901 down(&pcdev->zoominfo.sem);
2902 pcdev->zoominfo.a.c.height = a.c.height;
2903 pcdev->zoominfo.a.c.width = a.c.width;
2904 pcdev->zoominfo.a.c.top = a.c.top;
2905 pcdev->zoominfo.a.c.left = a.c.left;
2906 pcdev->zoominfo.vir_width = pcdev->host_width;
2907 pcdev->zoominfo.vir_height= pcdev->host_height;
2908 up(&pcdev->zoominfo.sem);
2910 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 );
2916 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2917 struct soc_camera_host_ops *ops, int id)
2921 for (i = 0; i < ops->num_controls; i++)
2922 if (ops->controls[i].id == id)
2923 return &ops->controls[i];
2929 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2930 struct v4l2_control *sctrl)
2932 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2933 const struct v4l2_queryctrl *qctrl;
2934 struct rk_camera_dev *pcdev = ici->priv;
2938 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2940 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2943 goto rk_camera_set_ctrl_end;
2948 case V4L2_CID_ZOOM_ABSOLUTE:
2950 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2952 goto rk_camera_set_ctrl_end;
2954 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2956 pcdev->zoominfo.zoom_rate = sctrl->value;
2958 goto rk_camera_set_ctrl_end;
2966 rk_camera_set_ctrl_end:
2970 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2972 .owner = THIS_MODULE,
2973 .add = rk_camera_add_device,
2974 .remove = rk_camera_remove_device,
2975 .suspend = rk_camera_suspend,
2976 .resume = rk_camera_resume,
2977 .enum_frameinervals = rk_camera_enum_frameintervals,
2978 .cropcap = rk_camera_cropcap,
2979 .set_crop = rk_camera_set_crop,
2980 .get_crop = rk_camera_get_crop,
2981 .get_formats = rk_camera_get_formats,
2982 .put_formats = rk_camera_put_formats,
2983 .set_fmt = rk_camera_set_fmt,
2984 .try_fmt = rk_camera_try_fmt,
2985 .init_videobuf = rk_camera_init_videobuf,
2986 .reqbufs = rk_camera_reqbufs,
2987 .poll = rk_camera_poll,
2988 .querycap = rk_camera_querycap,
2989 .set_bus_param = rk_camera_set_bus_param,
2990 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2991 .set_ctrl = rk_camera_set_ctrl,
2992 .controls = rk_camera_controls,
2993 .num_controls = ARRAY_SIZE(rk_camera_controls)
2996 /**********yzm***********/
2997 static int rk_camera_cif_iomux(struct device *dev)
3000 struct pinctrl *pinctrl;
3001 struct pinctrl_state *state;
3003 char state_str[20] = {0};
3005 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3006 strcpy(state_str,"cif_pin_all");
3008 if(CHIP_NAME == 3288){
3009 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
3014 pinctrl = devm_pinctrl_get(dev);
3015 if (IS_ERR(pinctrl)) {
3016 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
3019 state = pinctrl_lookup_state(pinctrl,
3022 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
3026 if (!IS_ERR(state)) {
3027 retval = pinctrl_select_state(pinctrl, state);
3030 "%s:could not set %s pins\n",__func__,state_str);
3038 /***********yzm***********/
3039 static int rk_camera_probe(struct platform_device *pdev)
3041 struct rk_camera_dev *pcdev;
3042 struct resource *res;
3043 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3046 struct rk_cif_clk *clk=NULL;
3047 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
3049 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3051 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3052 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3054 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3055 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3059 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3060 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3064 /***********yzm**********/
3065 rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3067 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3068 irq = platform_get_irq(pdev, 0);
3070 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3071 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3072 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3074 if (!res || irq < 0) {
3078 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3080 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3085 pcdev->zoominfo.zoom_rate = 100;
3086 pcdev->hostid = pdev->id; /* get host id*/
3087 #ifdef CONFIG_SOC_RK3028
3088 pcdev->chip_id = rk3028_version_val();
3090 pcdev->chip_id = -1;
3093 /***********yzm***********/
3095 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3097 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3098 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3099 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3100 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3101 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3102 //spin_lock_init(&cif_clk[0].lock);
3103 cif_clk[0].on = false;
3104 rk_camera_cif_iomux(dev_cif);/*yzm*/
3107 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only yzm*/
3108 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3109 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3110 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3111 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3112 //spin_lock_init(&cif_clk[1].lock);
3113 cif_clk[1].on = false;
3114 rk_camera_cif_iomux(dev_cif);/*yzm*/
3117 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3119 /***********yzm**********/
3120 dev_set_drvdata(&pdev->dev, pcdev);
3122 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3123 /*= rk_camera_platform_data */
3124 if (pcdev->pdata && pcdev->pdata->io_init) {
3126 pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
3128 if (pcdev->pdata->sensor_mclk == NULL)
3129 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3132 INIT_LIST_HEAD(&pcdev->capture);
3133 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3134 spin_lock_init(&pcdev->lock);
3135 spin_lock_init(&pcdev->camera_work_lock);
3137 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3138 spin_lock_init(&pcdev->cropinfo.lock);
3139 sema_init(&pcdev->zoominfo.sem,1);
3142 * Request the regions.
3145 if (!request_mem_region(res->start, res->end - res->start + 1,
3146 RK29_CAM_DRV_NAME)) {
3148 goto exit_reqmem_vip;
3150 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3151 if (pcdev->base == NULL) {
3152 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3154 goto exit_ioremap_vip;
3158 pcdev->irqinfo.irq = irq;
3159 pcdev->dev = &pdev->dev;
3161 /* config buffer address */
3164 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, IRQF_DISABLED | IRQF_SHARED , RK29_CAM_DRV_NAME,
3167 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3173 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3175 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3177 if (pcdev->camera_wq == NULL) {
3178 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3182 pcdev->camera_reinit_work.pcdev = pcdev;
3183 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3185 for (i=0; i<2; i++) {
3186 pcdev->icd_frmival[i].icd = NULL;
3187 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3190 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3191 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3192 pcdev->soc_host.priv = pcdev; /*to itself,csll in rk_camera_add_device*/
3193 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3194 pcdev->soc_host.nr = pdev->id;
3195 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3196 err = soc_camera_host_register(&pcdev->soc_host);
3200 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3203 pcdev->fps_timer.pcdev = pcdev;
3204 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3205 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3206 pcdev->icd_cb.sensor_cb = NULL;
3208 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3209 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3210 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3211 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3212 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3213 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3214 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3215 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3221 for (i=0; i<2; i++) {
3222 fival_list = pcdev->icd_frmival[i].fival_list;
3223 fival_nxt = fival_list;
3224 while(fival_nxt != NULL) {
3225 fival_nxt = fival_list->nxt;
3227 fival_list = fival_nxt;
3231 free_irq(pcdev->irqinfo.irq, pcdev);
3232 if (pcdev->camera_wq) {
3233 destroy_workqueue(pcdev->camera_wq);
3234 pcdev->camera_wq = NULL;
3237 iounmap(pcdev->base);
3239 release_mem_region(res->start, res->end - res->start + 1);
3243 clk_put(clk->pd_cif);
3245 clk_put(clk->aclk_cif);
3247 clk_put(clk->hclk_cif);
3248 if (clk->cif_clk_in)
3249 clk_put(clk->cif_clk_in);
3250 if (clk->cif_clk_out)
3251 clk_put(clk->cif_clk_out);
3260 static int __exit rk_camera_remove(struct platform_device *pdev)
3262 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3263 struct resource *res;
3264 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3267 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3270 free_irq(pcdev->irqinfo.irq, pcdev);
3272 if (pcdev->camera_wq) {
3273 destroy_workqueue(pcdev->camera_wq);
3274 pcdev->camera_wq = NULL;
3277 for (i=0; i<2; i++) {
3278 fival_list = pcdev->icd_frmival[i].fival_list;
3279 fival_nxt = fival_list;
3280 while(fival_nxt != NULL) {
3281 fival_nxt = fival_list->nxt;
3283 fival_list = fival_nxt;
3287 soc_camera_host_unregister(&pcdev->soc_host);
3290 iounmap((void __iomem*)pcdev->base);
3291 release_mem_region(res->start, res->end - res->start + 1);
3292 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3293 pcdev->pdata->io_deinit(0);
3294 pcdev->pdata->io_deinit(1);
3299 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3304 static struct platform_driver rk_camera_driver =
3307 .name = RK29_CAM_DRV_NAME, /*host */
3309 .probe = rk_camera_probe,
3310 .remove = (rk_camera_remove),
3313 static int rk_camera_init_async(void *unused)
3316 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3317 platform_driver_register(&rk_camera_driver);
3321 static int __init rk_camera_init(void)
3324 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3326 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3331 static void __exit rk_camera_exit(void)
3333 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3335 platform_driver_unregister(&rk_camera_driver);
3338 device_initcall_sync(rk_camera_init);
3339 module_exit(rk_camera_exit);
3341 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3342 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3343 MODULE_LICENSE("GPL");