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 ENANABLE_INVERT_PCLK_CIF0;
197 static u32 DISABLE_INVERT_PCLK_CIF0;
198 static u32 ENANABLE_INVERT_PCLK_CIF1;
199 static u32 DISABLE_INVERT_PCLK_CIF1;
201 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK_CRU_VIRT)
202 #define read_cru_reg(addr) __raw_readl(addr+RK_CRU_VIRT)
203 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
204 /*********yzm*********end*/
206 #if defined(CONFIG_ARCH_RK2928)
207 #define write_cru_reg(addr, val)
208 #define read_cru_reg(addr) 0
209 #define mask_cru_reg(addr, msk, val)
214 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
216 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
217 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
218 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
219 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
220 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
223 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
224 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
225 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
227 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
228 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
229 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
231 #define write_grf_reg(addr, val)
232 #define read_grf_reg(addr) 0
233 #define mask_grf_reg(addr, msk, val)
236 #define CAM_WORKQUEUE_IS_EN() (true)
237 #define CAM_IPPWORK_IS_EN() (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
239 #define IS_CIF0() (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
240 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
241 #define CROP_ALIGN_BYTES (0x03)
242 #define CIF_DO_CROP 0
243 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
244 #define CROP_ALIGN_BYTES (0x0f)
245 #define CIF_DO_CROP 0
246 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
247 #define CROP_ALIGN_BYTES (0x03)
248 #define CIF_DO_CROP 0
249 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
250 #define CROP_ALIGN_BYTES (0x0F)
251 #define CIF_DO_CROP 1
255 *v0.1.0 : this driver is 3.10 kernel driver;
256 copy and updata from v0.3.0x19;
259 1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
260 cause warning, so remove this spin lock .
262 1. rk3126 and rk3128 use different dts file.
264 1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
266 1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk
268 1. Improve the code to support all configuration.reset,af,flash...
270 1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
272 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0x6)
273 static int version = RK_CAM_VERSION_CODE;
274 module_param(version, int, S_IRUGO);
276 /* limit to rk29 hardware capabilities */
277 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
278 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
279 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
280 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
281 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
282 V4L2_MBUS_PCLK_SAMPLE_RISING |\
283 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
284 V4L2_MBUS_DATA_ACTIVE_HIGH |\
285 V4L2_MBUS_DATA_ACTIVE_LOW|\
286 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
287 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
289 #define RK_CAM_W_MIN 48
290 #define RK_CAM_H_MIN 32
291 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
292 #define RK_CAM_H_MAX 2764
293 #define RK_CAM_FRAME_INVAL_INIT 0
294 #define RK_CAM_FRAME_INVAL_DC 0 /* ddl@rock-chips.com : */
295 #define RK30_CAM_FRAME_MEASURE 5
298 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
299 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
300 /* buffer for one video frame */
301 struct rk_camera_buffer
303 /* common v4l buffer stuff -- must be first */
304 struct videobuf_buffer vb;
305 enum v4l2_mbus_pixelcode code;
308 enum rk_camera_reg_state
316 unsigned int cifCtrl;
317 unsigned int cifCrop;
319 unsigned int cifIntEn;
321 unsigned int cifVirWidth;
322 unsigned int cifScale;
323 /* unsigned int VipCrm;*/
324 enum rk_camera_reg_state Inval;
326 struct rk_camera_work
328 struct videobuf_buffer *vb;
329 struct rk_camera_dev *pcdev;
330 struct work_struct work;
331 struct list_head queue;
334 struct rk_camera_frmivalenum
336 struct v4l2_frmivalenum fival;
337 struct rk_camera_frmivalenum *nxt;
339 struct rk_camera_frmivalinfo
341 struct soc_camera_device *icd;
342 struct rk_camera_frmivalenum *fival_list;
344 struct rk_camera_zoominfo
346 struct semaphore sem;
352 #if CAMERA_VIDEOBUF_ARM_ACCESS
353 struct rk29_camera_vbinfo
355 unsigned int phy_addr;
356 void __iomem *vir_addr;
360 struct rk_camera_timer{
361 struct rk_camera_dev *pcdev;
362 struct hrtimer timer;
367 /************must modify start************/
369 struct clk *aclk_cif;
370 struct clk *hclk_cif;
371 struct clk *cif_clk_in;
372 struct clk *cif_clk_out;
373 /************must modify end************/
383 struct v4l2_rect bounds;
386 struct rk_cif_irqinfo
389 unsigned long cifirq_idx;
390 unsigned long cifirq_normal_idx;
391 unsigned long cifirq_abnormal_idx;
393 unsigned long dmairq_idx;
399 struct soc_camera_host soc_host;
401 /* RK2827x is only supposed to handle one camera on its Quick Capture
402 * interface. If anyone ever builds hardware to enable more than
403 * one camera, they will have to modify this driver too */
404 struct soc_camera_device *icd;
406 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
409 unsigned int last_fps;
410 unsigned long frame_interval;
413 unsigned int vipmem_phybase;
414 void __iomem *vipmem_virbase;
415 unsigned int vipmem_size;
416 unsigned int vipmem_bsize;
417 #if CAMERA_VIDEOBUF_ARM_ACCESS
418 struct rk29_camera_vbinfo *vbinfo;
419 unsigned int vbinfo_count;
423 int host_left; /*sensor output size ?*/
429 struct rk_cif_crop cropinfo;
430 struct rk_cif_irqinfo irqinfo;
432 struct rk29camera_platform_data *pdata;
433 struct resource *res;
434 struct list_head capture;
435 struct rk_camera_zoominfo zoominfo;
439 struct videobuf_buffer *active;
440 struct rk_camera_reg reginfo_suspend;
441 struct workqueue_struct *camera_wq;
442 struct rk_camera_work *camera_work;
443 struct list_head camera_work_queue;
444 spinlock_t camera_work_lock;
445 unsigned int camera_work_count;
446 struct rk_camera_timer fps_timer;
447 struct rk_camera_work camera_reinit_work;
449 rk29_camera_sensor_cb_s icd_cb;
450 struct rk_camera_frmivalinfo icd_frmival[2];
452 unsigned int reinit_times;
453 struct videobuf_queue *video_vq;
455 struct timeval first_tv;
460 static const struct v4l2_queryctrl rk_camera_controls[] =
463 .id = V4L2_CID_ZOOM_ABSOLUTE,
464 .type = V4L2_CTRL_TYPE_INTEGER,
465 .name = "DigitalZoom Control",
469 .default_value = 100,
473 static struct rk_cif_clk cif_clk[2];
475 static DEFINE_MUTEX(camera_lock);
476 static const char *rk_cam_driver_description = "RK_Camera";
478 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
479 static void rk_camera_capture_process(struct work_struct *work);
481 static void rk_camera_diffchips(const char *rockchip_name)
483 if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
485 CRU_PCLK_REG30 = 0xbc;
486 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
487 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7));
488 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
489 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
492 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
494 void __iomem *reg = RK_CRU_VIRT + RK_CRU_SOFTRST_CON;
495 u32 val = on ? 0x10001U << 14 : 0x10000U << 14;
496 writel_relaxed(val, reg);
500 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
502 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
503 u32 RK_CRU_SOFTRST_CON = 0;
504 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
505 if(strstr(pcdev->pdata->rockchip_name,"3128")||strstr(pcdev->pdata->rockchip_name,"3126"))
506 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
508 if (only_rst == true) {
509 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
511 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
513 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
514 if (ctrl_reg & ENABLE_CAPTURE) {
515 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
517 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
518 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
519 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
520 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
521 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
522 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
523 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
524 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
526 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
528 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
530 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
531 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
532 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
533 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
534 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
535 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
536 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
537 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
538 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
545 * Videobuf operations
547 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
550 struct soc_camera_device *icd = vq->priv_data;
551 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
552 struct rk_camera_dev *pcdev = ici->priv;
554 struct rk_camera_work *wk;
556 struct soc_mbus_pixelfmt fmt;
558 int bytes_per_line_host;
559 fmt.packing = SOC_MBUS_PACKING_1_5X8;
561 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
564 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
565 icd->current_fmt->host_fmt);
566 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
567 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
569 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
570 bytes_per_line_host = pcdev->host_width*3;
572 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
573 icd->current_fmt->host_fmt);
574 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
576 if (bytes_per_line_host < 0)
577 return bytes_per_line_host;
579 /* planar capture requires Y, U and V buffers to be page aligned */
580 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
581 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
583 if (CAM_WORKQUEUE_IS_EN()) {
585 if (CAM_IPPWORK_IS_EN()) {
586 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
587 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
588 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
592 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
593 kfree(pcdev->camera_work);
594 pcdev->camera_work = NULL;
595 pcdev->camera_work_count = 0;
598 if (pcdev->camera_work == NULL) {
599 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
600 if (pcdev->camera_work == NULL) {
601 RKCAMERA_TR("kmalloc failed\n");
604 INIT_LIST_HEAD(&pcdev->camera_work_queue);
606 for (i=0; i<(*count); i++) {
608 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
611 pcdev->camera_work_count = (*count);
613 #if CAMERA_VIDEOBUF_ARM_ACCESS
614 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
615 kfree(pcdev->vbinfo);
616 pcdev->vbinfo = NULL;
617 pcdev->vbinfo_count = 0x00;
620 if (pcdev->vbinfo == NULL) {
621 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
622 if (pcdev->vbinfo == NULL) {
623 RKCAMERA_TR("vbinfo kmalloc fail\n");
626 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
627 pcdev->vbinfo_count = *count;
631 pcdev->video_vq = vq;
632 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
636 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
638 struct soc_camera_device *icd = vq->priv_data;
640 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
643 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
644 &buf->vb, buf->vb.baddr, buf->vb.bsize);
646 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
647 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
653 * This waits until this buffer is out of danger, i.e., until it is no
654 * longer in STATE_QUEUED or STATE_ACTIVE
656 videobuf_waiton(vq, &buf->vb, 0, 0);
657 videobuf_dma_contig_free(vq, &buf->vb);
658 /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
659 buf->vb.state = VIDEOBUF_NEEDS_INIT;
662 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
664 struct soc_camera_device *icd = vq->priv_data;
665 struct rk_camera_buffer *buf;
667 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
668 icd->current_fmt->host_fmt);
670 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
672 if ((bytes_per_line < 0) || (vb->boff == 0))
675 buf = container_of(vb, struct rk_camera_buffer, vb);
677 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
678 /* vb, vb->baddr, vb->bsize);*/ /*yzm*/
680 /* Added list head initialization on alloc */
681 WARN_ON(!list_empty(&vb->queue));
683 BUG_ON(NULL == icd->current_fmt);
685 if (buf->code != icd->current_fmt->code ||
686 vb->width != icd->user_width ||
687 vb->height != icd->user_height ||
688 vb->field != field) {
689 buf->code = icd->current_fmt->code;
690 vb->width = icd->user_width;
691 vb->height = icd->user_height;
693 vb->state = VIDEOBUF_NEEDS_INIT;
696 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
697 if (0 != vb->baddr && vb->bsize < vb->size) {
702 if (vb->state == VIDEOBUF_NEEDS_INIT) {
703 ret = videobuf_iolock(vq, vb, NULL);
707 vb->state = VIDEOBUF_PREPARED;
712 rk_videobuf_free(vq, buf);
717 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
719 unsigned int y_addr,uv_addr;
720 struct rk_camera_dev *pcdev = rk_pcdev;
722 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
726 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
727 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
728 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
729 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
730 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
731 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
736 uv_addr = y_addr + vb->width * vb->height;
738 #if defined(CONFIG_ARCH_RK3188)
739 rk_camera_cif_reset(pcdev,false);
741 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
742 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
743 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
744 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
745 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
748 /* Locking: Caller holds q->irqlock */
749 static void rk_videobuf_queue(struct videobuf_queue *vq,
750 struct videobuf_buffer *vb)
752 struct soc_camera_device *icd = vq->priv_data;
753 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
754 struct rk_camera_dev *pcdev = ici->priv;
755 #if CAMERA_VIDEOBUF_ARM_ACCESS
756 struct rk29_camera_vbinfo *vb_info;
760 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
762 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
763 vb, vb->baddr, vb->bsize); */ /*yzm*/
765 vb->state = VIDEOBUF_QUEUED;
766 if (list_empty(&pcdev->capture)) {
767 list_add_tail(&vb->queue, &pcdev->capture);
769 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
770 list_add_tail(&vb->queue, &pcdev->capture);
772 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
774 #if CAMERA_VIDEOBUF_ARM_ACCESS
776 vb_info = pcdev->vbinfo+vb->i;
777 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
778 if (vb_info->vir_addr) {
779 iounmap(vb_info->vir_addr);
780 release_mem_region(vb_info->phy_addr, vb_info->size);
781 vb_info->vir_addr = NULL;
782 vb_info->phy_addr = 0x00;
783 vb_info->size = 0x00;
786 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
787 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
790 if (vb_info->vir_addr) {
791 vb_info->size = vb->bsize;
792 vb_info->phy_addr = vb->boff;
794 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
799 if (!pcdev->active) {
801 rk_videobuf_capture(vb,pcdev);
802 if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
803 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
808 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
809 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
812 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
816 case V4L2_PIX_FMT_YUV420:
817 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.*/
818 case V4L2_PIX_FMT_YUYV:
820 *ippfmt = RK_FORMAT_YCbCr_420_SP;
823 case V4L2_PIX_FMT_YVU420:
824 case V4L2_PIX_FMT_VYUY:
825 case V4L2_PIX_FMT_YVYU:
827 *ippfmt = RK_FORMAT_YCrCb_420_SP;
830 case V4L2_PIX_FMT_RGB565:
832 *ippfmt = RK_FORMAT_RGB_565;
835 case V4L2_PIX_FMT_RGB24:
837 *ippfmt = RK_FORMAT_RGB_888;
841 goto rk_pixfmt2rgafmt_err;
845 rk_pixfmt2rgafmt_err:
849 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
850 static int rk_camera_scale_crop_pp(struct work_struct *work){
851 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
852 struct videobuf_buffer *vb = camera_work->vb;
853 struct rk_camera_dev *pcdev = camera_work->pcdev;
855 unsigned long int flags;
863 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
864 extern rga_service_info rga_service;
865 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
866 extern void rga_service_session_clear(rga_session *session);
867 static int rk_camera_scale_crop_rga(struct work_struct *work){
868 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
869 struct videobuf_buffer *vb = camera_work->vb;
870 struct rk_camera_dev *pcdev = camera_work->pcdev;
872 unsigned long int flags;
878 const struct soc_mbus_pixelfmt *fmt;
881 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
888 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
890 static int rk_camera_scale_crop_ipp(struct work_struct *work)
896 static void rk_camera_capture_process(struct work_struct *work)
898 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
899 struct videobuf_buffer *vb = camera_work->vb;
900 struct rk_camera_dev *pcdev = camera_work->pcdev;
901 /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code; */
902 unsigned long flags = 0;
905 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
908 if (atomic_read(&pcdev->stop_cif)==true) {
910 goto rk_camera_capture_process_end;
913 if (!CAM_WORKQUEUE_IS_EN()) {
915 goto rk_camera_capture_process_end;
918 down(&pcdev->zoominfo.sem);
919 if (pcdev->icd_cb.scale_crop_cb){
920 err = (pcdev->icd_cb.scale_crop_cb)(work);
922 up(&pcdev->zoominfo.sem);
924 if (pcdev->icd_cb.sensor_cb)
925 (pcdev->icd_cb.sensor_cb)(vb);
927 rk_camera_capture_process_end:
929 vb->state = VIDEOBUF_ERROR;
931 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
932 vb->state = VIDEOBUF_DONE;
936 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
937 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
938 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
939 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
943 static void rk_camera_cifrest_delay(struct work_struct *work)
945 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
946 struct rk_camera_dev *pcdev = camera_work->pcdev;
947 unsigned long flags = 0;
949 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
953 rk_camera_cif_reset(pcdev,false);
955 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
956 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
957 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
959 spin_lock_irqsave(&pcdev->lock,flags);
960 if (atomic_read(&pcdev->stop_cif) == false) {
961 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
962 RKCAMERA_DG2("After reset cif, enable capture again!\n");
964 spin_unlock_irqrestore(&pcdev->lock,flags);
968 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
970 struct rk_camera_dev *pcdev = data;
971 struct rk_camera_work *wk;
972 unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
974 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
977 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
979 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
980 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
981 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
983 pcdev->irqinfo.cifirq_idx++;
984 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
985 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
986 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
987 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
989 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
992 if(reg_cifctrl & ENABLE_CAPTURE) {
993 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
996 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
997 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
998 if (!list_empty(&pcdev->camera_work_queue)) {
999 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1000 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1001 list_del_init(&wk->queue);
1002 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1004 queue_work(pcdev->camera_wq, &(wk->work));
1012 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1014 struct rk_camera_dev *pcdev = data;
1015 struct videobuf_buffer *vb;
1016 struct rk_camera_work *wk;
1018 unsigned long reg_cifctrl;
1020 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1023 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1024 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1025 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { //frame 0 ready yzm
1026 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1028 pcdev->irqinfo.dmairq_idx++;
1029 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1030 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1035 do_gettimeofday(&pcdev->first_tv);
1040 if (pcdev->frame_inval>0) {
1041 pcdev->frame_inval--;
1042 rk_videobuf_capture(pcdev->active,pcdev);
1044 } else if (pcdev->frame_inval) {
1045 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1046 pcdev->frame_inval = 0;
1049 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1050 do_gettimeofday(&tv);
1051 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1052 /(RK30_CAM_FRAME_MEASURE-1);
1057 printk("no acticve buffer!!!\n");
1061 /* ddl@rock-chips.com : this vb may be deleted from queue */
1062 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1063 list_del_init(&vb->queue);
1065 pcdev->active = NULL;
1066 if (!list_empty(&pcdev->capture)) {
1067 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1068 if (pcdev->active) {
1069 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1070 rk_videobuf_capture(pcdev->active,pcdev);
1073 if (pcdev->active == NULL) {
1074 RKCAMERA_DG1("video_buf queue is empty!\n");
1077 do_gettimeofday(&vb->ts);
1078 if (CAM_WORKQUEUE_IS_EN()) {
1079 if (!list_empty(&pcdev->camera_work_queue)) {
1080 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1081 list_del_init(&wk->queue);
1082 INIT_WORK(&(wk->work), rk_camera_capture_process);
1085 queue_work(pcdev->camera_wq, &(wk->work));
1088 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1089 vb->state = VIDEOBUF_DONE;
1097 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1098 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1102 static irqreturn_t rk_camera_irq(int irq, void *data)
1104 struct rk_camera_dev *pcdev = data;
1105 unsigned long reg_intstat;
1109 spin_lock(&pcdev->lock);
1111 if(atomic_read(&pcdev->stop_cif) == true) {
1112 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
1116 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1117 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%lx\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1118 if (reg_intstat & 0x0200)
1119 rk_camera_cifirq(irq,data);
1121 if (reg_intstat & 0x01)
1122 rk_camera_dmairq(irq,data);
1125 spin_unlock(&pcdev->lock);
1130 static void rk_videobuf_release(struct videobuf_queue *vq,
1131 struct videobuf_buffer *vb)
1133 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1134 struct soc_camera_device *icd = vq->priv_data;
1135 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1136 struct rk_camera_dev *pcdev = ici->priv;
1137 #if CAMERA_VIDEOBUF_ARM_ACCESS
1138 struct rk29_camera_vbinfo *vb_info =NULL;
1143 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1146 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1147 vb, vb->baddr, vb->bsize);
1151 case VIDEOBUF_ACTIVE:
1152 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1154 case VIDEOBUF_QUEUED:
1155 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1157 case VIDEOBUF_PREPARED:
1158 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1161 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1166 flush_workqueue(pcdev->camera_wq);
1168 rk_videobuf_free(vq, buf);
1170 #if CAMERA_VIDEOBUF_ARM_ACCESS
1171 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1172 vb_info = pcdev->vbinfo + vb->i;
1174 if (vb_info->vir_addr) {
1175 iounmap(vb_info->vir_addr);
1176 release_mem_region(vb_info->phy_addr, vb_info->size);
1177 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1184 static struct videobuf_queue_ops rk_videobuf_ops =
1186 .buf_setup = rk_videobuf_setup,
1187 .buf_prepare = rk_videobuf_prepare,
1188 .buf_queue = rk_videobuf_queue,
1189 .buf_release = rk_videobuf_release,
1192 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1193 struct soc_camera_device *icd)
1195 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1196 struct rk_camera_dev *pcdev = ici->priv;
1198 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1201 /* We must pass NULL as dev pointer, then all pci_* dma operations
1202 * transform to normal dma_* ones. */
1203 videobuf_queue_dma_contig_init(q,
1205 ici->v4l2_dev.dev, &pcdev->lock,
1206 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1208 sizeof(struct rk_camera_buffer),
1209 icd,&(ici->host_lock) );
1212 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1215 struct rk_cif_clk *clk;
1216 struct clk *cif_clk_out_div;
1218 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1221 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1222 if ((cif<0)||(cif>1)) {
1223 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1225 goto rk_camera_clk_ctrl_end;
1228 clk = &cif_clk[cif];
1230 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1231 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1233 goto rk_camera_clk_ctrl_end;
1236 //spin_lock(&clk->lock);
1237 if (on && !clk->on) {
1238 clk_prepare_enable(clk->pd_cif); /*yzm*/
1239 clk_prepare_enable(clk->aclk_cif);
1240 clk_prepare_enable(clk->hclk_cif);
1241 clk_prepare_enable(clk->cif_clk_in);
1242 clk_prepare_enable(clk->cif_clk_out);
1243 clk_set_rate(clk->cif_clk_out,clk_rate);
1245 } else if (!on && clk->on) {
1247 clk_disable_unprepare(clk->aclk_cif);
1248 clk_disable_unprepare(clk->hclk_cif);
1249 clk_disable_unprepare(clk->cif_clk_in);
1250 clk_disable_unprepare(clk->cif_clk_out);
1251 clk_disable_unprepare(clk->pd_cif);
1254 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
1256 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
1257 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
1258 cif_clk_out_div = clk_get(NULL, "cif_out_div");
1262 if(!IS_ERR_OR_NULL(cif_clk_out_div)) { /* ddl@rock-chips.com: v0.3.0x13 */
1263 err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
1264 clk_put(cif_clk_out_div);
1270 RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__);
1272 //spin_unlock(&clk->lock);
1273 rk_camera_clk_ctrl_end:
1276 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1279 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1282 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1284 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1285 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1289 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1292 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1294 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1300 /* The following two functions absolutely depend on the fact, that
1301 * there can be only one camera on RK28 quick capture interface */
1302 static int rk_camera_add_device(struct soc_camera_device *icd)
1304 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1305 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1306 struct device *control = to_soc_camera_control(icd);
1307 struct v4l2_subdev *sd;
1308 int ret,i,icd_catch;
1309 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1310 struct v4l2_cropcap cropcap;
1311 struct v4l2_mbus_framefmt mf;
1312 const struct soc_camera_format_xlate *xlate = NULL;
1314 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1317 mutex_lock(&camera_lock);
1324 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1326 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1327 pcdev->active = NULL;
1329 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1330 pcdev->zoominfo.zoom_rate = 100;
1331 pcdev->fps_timer.istarted = false;
1333 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1334 * if app havn't dequeue all videobuf before close camera device;
1336 INIT_LIST_HEAD(&pcdev->capture);
1338 ret = rk_camera_activate(pcdev,icd);
1341 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1342 if (control) { //TRUE in open ,FALSE in kernel start
1343 sd = dev_get_drvdata(control);
1344 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1346 ret = v4l2_subdev_call(sd,core, init, 0);
1350 /* call generic_sensor_ioctl*/
1351 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1352 /* call generic_sensor_cropcap*/
1353 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1354 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1356 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1359 mf.field = V4L2_FIELD_NONE;
1360 mf.code = xlate->code;
1361 mf.reserved[6] = 0xfefe5a5a;
1362 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1364 pcdev->cropinfo.bounds.left = 0;
1365 pcdev->cropinfo.bounds.top = 0;
1366 pcdev->cropinfo.bounds.width = mf.width;
1367 pcdev->cropinfo.bounds.height = mf.height;
1371 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1373 pcdev->icd_init = 0;
1376 for (i=0; i<2; i++) {
1377 if (pcdev->icd_frmival[i].icd == icd)
1379 if (pcdev->icd_frmival[i].icd == NULL) {
1380 pcdev->icd_frmival[i].icd = icd;
1384 if (icd_catch == 0) {
1385 fival_list = pcdev->icd_frmival[0].fival_list;
1386 fival_nxt = fival_list;
1387 while(fival_nxt != NULL) {
1388 fival_nxt = fival_list->nxt;
1390 fival_list = fival_nxt;
1392 pcdev->icd_frmival[0].icd = icd;
1393 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1396 mutex_unlock(&camera_lock);
1400 static void rk_camera_remove_device(struct soc_camera_device *icd)
1402 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1403 struct rk_camera_dev *pcdev = ici->priv;
1404 /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
1405 #if CAMERA_VIDEOBUF_ARM_ACCESS
1406 struct rk29_camera_vbinfo *vb_info;
1410 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1413 mutex_lock(&camera_lock);
1414 BUG_ON(icd != pcdev->icd);
1416 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1418 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1419 stream may be turn on again before close device, if suspend and resume happened. */
1420 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1421 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1422 rk_camera_s_stream(icd,0);
1424 /* move DEACTIVATE into generic_sensor_s_power*/
1425 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
1426 /* if stream off is not been executed,timer is running.*/
1427 if(pcdev->fps_timer.istarted){
1428 hrtimer_cancel(&pcdev->fps_timer.timer);
1429 pcdev->fps_timer.istarted = false;
1431 flush_work(&(pcdev->camera_reinit_work.work));
1432 flush_workqueue((pcdev->camera_wq));
1434 if (pcdev->camera_work) {
1435 kfree(pcdev->camera_work);
1436 pcdev->camera_work = NULL;
1437 pcdev->camera_work_count = 0;
1438 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1440 rk_camera_deactivate(pcdev);
1441 #if CAMERA_VIDEOBUF_ARM_ACCESS
1442 if (pcdev->vbinfo) {
1443 vb_info = pcdev->vbinfo;
1444 for (i=0; i<pcdev->vbinfo_count; i++) {
1445 if (vb_info->vir_addr) {
1446 iounmap(vb_info->vir_addr);
1447 release_mem_region(vb_info->phy_addr, vb_info->size);
1448 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1452 kfree(pcdev->vbinfo);
1453 pcdev->vbinfo = NULL;
1454 pcdev->vbinfo_count = 0;
1457 pcdev->active = NULL;
1459 pcdev->icd_cb.sensor_cb = NULL;
1460 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1461 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1462 * if app havn't dequeue all videobuf before close camera device;
1464 INIT_LIST_HEAD(&pcdev->capture);
1466 mutex_unlock(&camera_lock);
1470 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1472 unsigned long bus_flags, camera_flags, common_flags = 0;
1473 unsigned int cif_for = 0;
1474 const struct soc_mbus_pixelfmt *fmt;
1476 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /*yzm*/
1477 struct rk_camera_dev *pcdev = ici->priv;
1479 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1482 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1486 bus_flags = RK_CAM_BUS_PARAM;
1487 /* If requested data width is supported by the platform, use it */
1488 switch (fmt->bits_per_sample) {
1490 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1494 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1498 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1504 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1505 if (icd->ops->query_bus_param)
1506 camera_flags = icd->ops->query_bus_param(icd);
1510 /**************yzm************
1511 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1512 if (!common_flags) {
1514 goto RK_CAMERA_SET_BUS_PARAM_END;
1517 /***************yzm************end*/
1520 common_flags = camera_flags;
1521 ret = icd->ops->set_bus_param(icd, common_flags);
1523 goto RK_CAMERA_SET_BUS_PARAM_END;
1525 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1527 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1529 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1531 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1535 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1537 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1541 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1542 cif_for |= HSY_LOW_ACTIVE;
1544 cif_for &= ~HSY_LOW_ACTIVE;
1546 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1547 cif_for |= VSY_HIGH_ACTIVE;
1549 cif_for &= ~VSY_HIGH_ACTIVE;
1552 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1553 //vip_ctrl_val |= ENABLE_CAPTURE;
1554 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1555 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1557 RK_CAMERA_SET_BUS_PARAM_END:
1559 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1563 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1565 /* unsigned long bus_flags, camera_flags;*/
1568 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1569 /**********yzm***********
1571 bus_flags = RK_CAM_BUS_PARAM;
1572 if (icd->ops->query_bus_param) {
1573 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1577 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1580 dev_warn(icd->dev.parent,
1581 "Flags incompatible: camera %lx, host %lx\n",
1582 camera_flags, bus_flags);
1585 *///************yzm **************end
1590 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1592 .fourcc = V4L2_PIX_FMT_NV12,
1593 .name = "YUV420 NV12",
1594 .bits_per_sample = 8,
1595 .packing = SOC_MBUS_PACKING_1_5X8,
1596 .order = SOC_MBUS_ORDER_LE,
1598 .fourcc = V4L2_PIX_FMT_NV16,
1599 .name = "YUV422 NV16",
1600 .bits_per_sample = 8,
1601 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1602 .order = SOC_MBUS_ORDER_LE,
1604 .fourcc = V4L2_PIX_FMT_NV21,
1605 .name = "YUV420 NV21",
1606 .bits_per_sample = 8,
1607 .packing = SOC_MBUS_PACKING_1_5X8,
1608 .order = SOC_MBUS_ORDER_LE,
1610 .fourcc = V4L2_PIX_FMT_NV61,
1611 .name = "YUV422 NV61",
1612 .bits_per_sample = 8,
1613 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1614 .order = SOC_MBUS_ORDER_LE,
1616 .fourcc = V4L2_PIX_FMT_RGB565,
1618 .bits_per_sample = 8,
1619 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1620 .order = SOC_MBUS_ORDER_LE,
1622 .fourcc = V4L2_PIX_FMT_RGB24,
1624 .bits_per_sample = 8,
1625 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1626 .order = SOC_MBUS_ORDER_LE,
1631 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1633 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1634 struct rk_camera_dev *pcdev = ici->priv;
1635 unsigned int cif_fs = 0,cif_crop = 0;
1636 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;
1638 const struct soc_mbus_pixelfmt *fmt;
1639 fmt = soc_mbus_get_fmtdesc(icd_code);
1641 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1644 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1645 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1646 host_pixfmt = V4L2_PIX_FMT_NV12;
1647 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1648 host_pixfmt = V4L2_PIX_FMT_NV21;
1650 switch (host_pixfmt)
1652 case V4L2_PIX_FMT_NV16:
1653 cif_fmt_val &= ~YUV_OUTPUT_422;
1654 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1655 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1656 pcdev->pixfmt = host_pixfmt;
1658 case V4L2_PIX_FMT_NV61:
1659 cif_fmt_val &= ~YUV_OUTPUT_422;
1660 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1661 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1662 pcdev->pixfmt = host_pixfmt;
1664 case V4L2_PIX_FMT_NV12:
1665 cif_fmt_val |= YUV_OUTPUT_420;
1666 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1667 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1668 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1669 pcdev->pixfmt = host_pixfmt;
1671 case V4L2_PIX_FMT_NV21:
1672 cif_fmt_val |= YUV_OUTPUT_420;
1673 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1674 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1675 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1676 pcdev->pixfmt = host_pixfmt;
1678 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1679 cif_fmt_val |= YUV_OUTPUT_422;
1684 case V4L2_MBUS_FMT_UYVY8_2X8:
1685 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1687 case V4L2_MBUS_FMT_YUYV8_2X8:
1688 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1690 case V4L2_MBUS_FMT_YVYU8_2X8:
1691 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1693 case V4L2_MBUS_FMT_VYUY8_2X8:
1694 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1697 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1702 rk_camera_cif_reset(pcdev,true);
1704 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1705 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1707 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 */
1709 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1710 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1711 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1713 } else{ /* this is one frame mode*/
1714 cif_crop = (rect->left + (rect->top <<16));
1715 cif_fs = (rect->width + (rect->height <<16));
1718 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1719 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1720 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1721 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1723 /*MUST bypass scale */
1724 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1725 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);
1729 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1730 struct soc_camera_format_xlate *xlate)
1732 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1733 struct device *dev = icd->parent;/*yzm*/
1734 int formats = 0, ret;
1735 enum v4l2_mbus_pixelcode code;
1736 const struct soc_mbus_pixelfmt *fmt;
1738 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1741 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); /*call generic_sensor_enum_fmt()*/
1743 /* No more formats */
1746 fmt = soc_mbus_get_fmtdesc(code);
1748 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1752 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1757 case V4L2_MBUS_FMT_UYVY8_2X8:
1758 case V4L2_MBUS_FMT_YUYV8_2X8:
1759 case V4L2_MBUS_FMT_YVYU8_2X8:
1760 case V4L2_MBUS_FMT_VYUY8_2X8:
1763 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1766 xlate->host_fmt = &rk_camera_formats[0];
1769 dev_dbg(dev, "Providing format %s using code %d\n",
1770 rk_camera_formats[0].name,code);
1775 xlate->host_fmt = &rk_camera_formats[1];
1778 dev_dbg(dev, "Providing format %s using code %d\n",
1779 rk_camera_formats[1].name,code);
1784 xlate->host_fmt = &rk_camera_formats[2];
1787 dev_dbg(dev, "Providing format %s using code %d\n",
1788 rk_camera_formats[2].name,code);
1793 xlate->host_fmt = &rk_camera_formats[3];
1796 dev_dbg(dev, "Providing format %s using code %d\n",
1797 rk_camera_formats[3].name,code);
1803 xlate->host_fmt = &rk_camera_formats[4];
1806 dev_dbg(dev, "Providing format %s using code %d\n",
1807 rk_camera_formats[4].name,code);
1811 xlate->host_fmt = &rk_camera_formats[5];
1814 dev_dbg(dev, "Providing format %s using code %d\n",
1815 rk_camera_formats[5].name,code);
1827 static void rk_camera_put_formats(struct soc_camera_device *icd)
1830 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1834 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1836 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1839 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1841 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1844 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1845 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1849 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1851 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1852 struct rk_camera_dev *pcdev = ici->priv;
1854 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1857 spin_lock(&pcdev->cropinfo.lock);
1858 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1859 spin_unlock(&pcdev->cropinfo.lock);
1863 static int rk_camera_set_crop(struct soc_camera_device *icd,
1864 const struct v4l2_crop *crop)
1866 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1867 struct rk_camera_dev *pcdev = ici->priv;
1869 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1872 spin_lock(&pcdev->cropinfo.lock);
1873 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1874 spin_unlock(&pcdev->cropinfo.lock);
1877 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1881 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1884 if (f->fmt.pix.priv == 0xfefe5a5a) {
1888 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1890 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1892 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1894 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1896 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1898 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1903 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1906 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1907 struct v4l2_format *f)
1909 struct device *dev = icd->parent;/*yzm*/
1910 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1911 const struct soc_camera_format_xlate *xlate = NULL;
1912 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1913 struct rk_camera_dev *pcdev = ici->priv;
1914 struct v4l2_pix_format *pix = &f->fmt.pix;
1915 struct v4l2_mbus_framefmt mf;
1916 struct v4l2_rect rect;
1917 int ret,usr_w,usr_h,sensor_w,sensor_h;
1919 int ratio, bounds_aspect;
1921 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1925 usr_h = pix->height;
1927 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
1928 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1930 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1932 goto RK_CAMERA_SET_FMT_END;
1935 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1936 if (pcdev->icd_init == 0) {
1937 v4l2_subdev_call(sd,core, init, 0); /*call generic_sensor_init()*/
1938 pcdev->icd_init = 1;
1939 return 0; /*directly return !!!!!!*/
1941 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1942 if (stream_on & ENABLE_CAPTURE)
1943 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1945 mf.width = pix->width;
1946 mf.height = pix->height;
1947 mf.field = pix->field;
1948 mf.colorspace = pix->colorspace;
1949 mf.code = xlate->code;
1950 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
1953 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); /*generic_sensor_s_fmt*/
1954 if (mf.code != xlate->code)
1957 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
1958 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
1959 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
1960 if ((mf.width*10/mf.height) != bounds_aspect) {
1961 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
1962 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
1964 mf.width = pcdev->cropinfo.bounds.width/4;
1965 mf.height = pcdev->cropinfo.bounds.height/4;
1967 mf.field = pix->field;
1968 mf.colorspace = pix->colorspace;
1969 mf.code = xlate->code;
1970 mf.reserved[0] = pix->priv;
1973 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1974 if (mf.code != xlate->code)
1979 sensor_w = mf.width;
1980 sensor_h = mf.height;
1982 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
1985 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
1988 if ((mf.width != usr_w) || (mf.height != usr_h)) {
1990 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1991 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
1993 goto RK_CAMERA_SET_FMT_END;
1995 if (unlikely((usr_w <16)||(usr_h < 16))) {
1996 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1998 goto RK_CAMERA_SET_FMT_END;
2001 spin_lock(&pcdev->cropinfo.lock);
2002 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2003 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2004 /*Scale + Crop center is for keep aspect ratio unchange*/
2005 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2006 pcdev->host_width = ratio*usr_w/10;
2007 pcdev->host_height = ratio*usr_h/10;
2008 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2009 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2011 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2012 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2014 /*Scale + crop(user define)*/
2015 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2016 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2017 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2018 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2021 pcdev->host_left &= (~0x01);
2022 pcdev->host_top &= (~0x01);
2024 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2025 /*Crop Center for cif can work , then scale*/
2026 pcdev->host_width = mf.width;
2027 pcdev->host_height = mf.height;
2028 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2029 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2031 /*Crop center for cif can work + crop(user define), then scale */
2032 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2033 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2034 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2035 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2038 pcdev->host_left &= (~0x01);
2039 pcdev->host_top &= (~0x01);
2041 spin_unlock(&pcdev->cropinfo.lock);
2043 spin_lock(&pcdev->cropinfo.lock);
2044 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2045 pcdev->host_width = mf.width;
2046 pcdev->host_height = mf.height;
2047 pcdev->host_left = 0;
2048 pcdev->host_top = 0;
2050 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2051 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2052 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2053 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2055 spin_unlock(&pcdev->cropinfo.lock);
2060 rect.width = pcdev->host_width;
2061 rect.height = pcdev->host_height;
2062 rect.left = pcdev->host_left;
2063 rect.top = pcdev->host_top;
2065 down(&pcdev->zoominfo.sem);
2066 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2067 pcdev->zoominfo.a.c.left = 0;
2068 pcdev->zoominfo.a.c.top = 0;
2069 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2070 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2071 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2072 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2073 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2074 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2075 /*recalculate the CIF width & height*/
2076 rect.width = pcdev->zoominfo.a.c.width ;
2077 rect.height = pcdev->zoominfo.a.c.height;
2078 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2079 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2081 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2082 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2083 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2084 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2085 /*now digital zoom use ipp to do crop and scale*/
2086 if(pcdev->zoominfo.zoom_rate != 100){
2087 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2088 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2090 pcdev->zoominfo.a.c.left = 0;
2091 pcdev->zoominfo.a.c.top = 0;
2093 pcdev->zoominfo.vir_width = pcdev->host_width;
2094 pcdev->zoominfo.vir_height = pcdev->host_height;
2096 up(&pcdev->zoominfo.sem);
2098 /* ddl@rock-chips.com: IPP work limit check */
2099 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2100 if (usr_w > 0x7f0) {
2101 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2102 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));
2104 goto RK_CAMERA_SET_FMT_END;
2107 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2108 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2110 goto RK_CAMERA_SET_FMT_END;
2115 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,
2116 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2117 sensor_w,sensor_h,mf.width,mf.height,
2118 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2119 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2120 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2121 pix->width, pix->height);
2123 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2125 if (CAM_IPPWORK_IS_EN()) {
2126 BUG_ON(pcdev->vipmem_phybase == 0);
2129 pix->height = usr_h;
2130 pix->field = mf.field;
2131 pix->colorspace = mf.colorspace;
2132 icd->current_fmt = xlate;
2133 pcdev->icd_width = mf.width;
2134 pcdev->icd_height = mf.height;
2137 RK_CAMERA_SET_FMT_END:
2138 if (stream_on & ENABLE_CAPTURE)
2139 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2141 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2145 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2146 struct v4l2_format *f)
2148 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2149 struct rk_camera_dev *pcdev = ici->priv;
2150 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2151 const struct soc_camera_format_xlate *xlate;
2152 struct v4l2_pix_format *pix = &f->fmt.pix;
2153 __u32 pixfmt = pix->pixelformat;
2154 int ret,usr_w,usr_h,i;
2155 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2156 bool vipmem_is_overflow = false;
2157 struct v4l2_mbus_framefmt mf;
2158 int bytes_per_line_host;
2161 usr_h = pix->height;
2163 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2165 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2167 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2168 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
2169 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2171 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2172 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2173 for (i = 0; i < icd->num_user_formats; i++)
2174 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2175 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2176 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2177 icd->user_formats[i].host_fmt->name);
2178 goto RK_CAMERA_TRY_FMT_END;
2180 /* limit to rk29 hardware capabilities */
2181 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2182 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2183 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2185 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2187 if (pix->bytesperline < 0)
2188 return pix->bytesperline;
2190 /* limit to sensor capabilities */
2191 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2192 mf.width = pix->width;
2193 mf.height = pix->height;
2194 mf.field = pix->field;
2195 mf.colorspace = pix->colorspace;
2196 mf.code = xlate->code;
2197 /* ddl@rock-chips.com : It is query max resolution only. */
2198 if ((usr_w == 10000) && (usr_h == 10000)) {
2199 mf.reserved[6] = 0xfefe5a5a;
2201 /* call generic_sensor_try_fmt()*/
2202 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2204 goto RK_CAMERA_TRY_FMT_END;
2206 /*query resolution.*/
2207 if((usr_w == 10000) && (usr_h == 10000)) {
2208 pix->width = mf.width;
2209 pix->height = mf.height;
2210 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2211 goto RK_CAMERA_TRY_FMT_END;
2213 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2216 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2217 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2219 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2221 /* Assume preview buffer minimum is 4 */
2222 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2224 if (vipmem_is_overflow == false) {
2226 pix->height = usr_h;
2228 /*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*/
2229 pix->width = mf.width;
2230 pix->height = mf.height;
2232 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2234 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2235 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2236 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2237 pix->width = mf.width;
2238 pix->height = mf.height;
2244 pix->colorspace = mf.colorspace;
2247 case V4L2_FIELD_ANY:
2248 case V4L2_FIELD_NONE:
2249 pix->field = V4L2_FIELD_NONE;
2252 /* TODO: support interlaced at least in pass-through mode */
2253 dev_err(icd->parent, "Field type %d unsupported.\n",
2255 goto RK_CAMERA_TRY_FMT_END;
2258 RK_CAMERA_TRY_FMT_END:
2260 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2264 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2265 struct v4l2_requestbuffers *p)
2269 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2272 /* This is for locking debugging only. I removed spinlocks and now I
2273 * check whether .prepare is ever called on a linked buffer, or whether
2274 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2275 * it hadn't triggered */
2276 for (i = 0; i < p->count; i++) {
2277 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2278 struct rk_camera_buffer, vb);
2280 INIT_LIST_HEAD(&buf->vb.queue);
2286 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2288 struct soc_camera_device *icd = file->private_data;
2289 struct rk_camera_buffer *buf;
2291 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2294 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2297 poll_wait(file, &buf->vb.done, pt);
2299 if (buf->vb.state == VIDEOBUF_DONE ||
2300 buf->vb.state == VIDEOBUF_ERROR)
2301 return POLLIN|POLLRDNORM;
2306 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2307 * 10 5 1 3 3 3 + 5 < 32
2310 static int rk_camera_querycap(struct soc_camera_host *ici,
2311 struct v4l2_capability *cap)
2313 struct rk_camera_dev *pcdev = ici->priv;
2314 struct rkcamera_platform_data *new_camera;
2315 char orientation[5];
2319 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2322 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2323 memset(orientation,0x00,sizeof(orientation));
2326 new_camera = pcdev->pdata->register_dev_new;
2327 while(new_camera != NULL){
2328 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2329 sprintf(orientation,"-%d",new_camera->orientation);
2330 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2332 new_camera = new_camera->next_camera;
2335 if (orientation[0] != '-') {
2336 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2337 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2338 strcat(cap->card,"-270");
2340 strcat(cap->card,"-90");
2342 strcat(cap->card,orientation);
2345 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2346 cap->version = RK_CAM_VERSION_CODE;
2347 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2348 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2352 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2354 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2355 struct rk_camera_dev *pcdev = ici->priv;
2356 struct v4l2_subdev *sd;
2359 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2362 mutex_lock(&camera_lock);
2363 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2364 rk_camera_s_stream(icd, 0);
2365 sd = soc_camera_to_subdev(icd);
2366 v4l2_subdev_call(sd, video, s_stream, 0);
2367 ret = icd->ops->suspend(icd, state);
2369 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2370 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2371 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2372 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2373 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2374 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2375 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2377 pcdev->reginfo_suspend.Inval = Reg_Validate;
2378 rk_camera_deactivate(pcdev);
2380 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2382 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2384 mutex_unlock(&camera_lock);
2388 static int rk_camera_resume(struct soc_camera_device *icd)
2390 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2391 struct rk_camera_dev *pcdev = ici->priv;
2392 struct v4l2_subdev *sd;
2395 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2398 mutex_lock(&camera_lock);
2399 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2400 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2401 rk_camera_activate(pcdev, icd);
2402 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2403 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2404 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2405 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2406 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2407 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2408 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2409 rk_videobuf_capture(pcdev->active,pcdev);
2410 rk_camera_s_stream(icd, 1);
2411 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2413 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2414 goto rk_camera_resume_end;
2417 ret = icd->ops->resume(icd);
2418 sd = soc_camera_to_subdev(icd);
2419 v4l2_subdev_call(sd, video, s_stream, 1);
2421 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2423 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2426 rk_camera_resume_end:
2427 mutex_unlock(&camera_lock);
2431 static void rk_camera_reinit_work(struct work_struct *work)
2433 struct v4l2_subdev *sd;
2434 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2435 struct rk_camera_dev *pcdev = camera_work->pcdev;
2436 /*struct soc_camera_link *tmp_soc_cam_link;*/
2437 struct v4l2_mbus_framefmt mf;
2439 unsigned long flags = 0;
2442 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2445 if(pcdev->icd == NULL)
2447 sd = soc_camera_to_subdev(pcdev->icd);
2448 /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2451 RKCAMERA_TR("CIF_CIF_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2452 RKCAMERA_TR("CIF_CIF_INTEN = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2453 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2454 RKCAMERA_TR("CIF_CIF_FOR = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2455 RKCAMERA_TR("CIF_CIF_CROP = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2456 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2457 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2458 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%lx\n",read_cru_reg(CRU_PCLK_REG30));
2459 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2461 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2462 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2463 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2464 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2465 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2466 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2467 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2468 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2469 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2472 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2473 if (pcdev->reinit_times == 1) {
2474 if (ctrl & ENABLE_CAPTURE) {
2475 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2476 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2477 rk_camera_cif_reset(pcdev,false);
2480 v4l2_subdev_call(sd,core, init, 0);
2482 mf.width = pcdev->icd_width;
2483 mf.height = pcdev->icd_height;
2484 mf.field = V4L2_FIELD_NONE;
2485 mf.code = pcdev->icd->current_fmt->code;
2486 mf.reserved[0] = 0x5a5afefe;
2489 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2491 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2492 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2493 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2494 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2495 rk_camera_cif_reset(pcdev,false);
2496 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2501 atomic_set(&pcdev->stop_cif,true);
2502 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2503 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2505 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2506 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2507 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2508 if (NULL == pcdev->video_vq->bufs[index])
2511 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2512 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2513 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2514 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2515 printk("wake up video buffer index = %d !!!\n",index);
2518 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2520 RKCAMERA_TR("video queue has somthing wrong !!\n");
2523 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2525 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2527 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2528 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2529 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2531 /*static unsigned int last_fps = 0;*/
2532 /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
2533 /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2535 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2537 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2538 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2539 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2540 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2541 pcdev->camera_reinit_work.pcdev = pcdev;
2542 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2543 pcdev->reinit_times++;
2544 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2545 } else if(!pcdev->timer_get_fps) {
2546 pcdev->timer_get_fps = true;
2547 for (i=0; i<2; i++) {
2548 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2549 fival_nxt = pcdev->icd_frmival[i].fival_list;
2554 fival_pre = fival_nxt;
2555 while (fival_nxt != NULL) {
2557 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
2558 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2559 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2560 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2561 fival_nxt->fival.discrete.numerator);
2563 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2564 && (fival_nxt->fival.height == pcdev->icd->user_height)
2565 && (fival_nxt->fival.width == pcdev->icd->user_width))
2566 || (fival_nxt->fival.discrete.denominator == 0)) {
2568 if (fival_nxt->fival.discrete.denominator == 0) {
2569 fival_nxt->fival.index = 0;
2570 fival_nxt->fival.width = pcdev->icd->user_width;
2571 fival_nxt->fival.height= pcdev->icd->user_height;
2572 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2573 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2574 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2575 |(pcdev->icd_height);
2576 fival_nxt->fival.discrete.numerator = 1000000;
2577 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2580 fival_rec = fival_nxt;
2582 fival_pre = fival_nxt;
2583 fival_nxt = fival_nxt->nxt;
2586 if ((rec_flag == 0) && fival_pre) {
2587 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2588 if (fival_pre->nxt != NULL) {
2589 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2590 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2591 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2592 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2594 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2595 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2596 |(pcdev->icd_height);
2597 fival_pre->nxt->fival.discrete.numerator = 1000000;
2598 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2600 fival_rec = fival_pre->nxt;
2605 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2606 pcdev->reinit_times = 0;
2608 pcdev->last_fps = pcdev->fps ;
2609 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2610 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2611 /*return HRTIMER_NORESTART;*/
2612 if(pcdev->reinit_times >=2)
2613 return HRTIMER_NORESTART;
2615 return HRTIMER_RESTART;
2617 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2619 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2620 struct rk_camera_dev *pcdev = ici->priv;
2623 unsigned long flags;
2625 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2627 WARN_ON(pcdev->icd != icd);
2629 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2632 pcdev->last_fps = 0;
2633 pcdev->frame_interval = 0;
2634 hrtimer_cancel(&(pcdev->fps_timer.timer));
2635 pcdev->fps_timer.pcdev = pcdev;
2636 pcdev->timer_get_fps = false;
2637 pcdev->reinit_times = 0;
2639 spin_lock_irqsave(&pcdev->lock,flags);
2640 atomic_set(&pcdev->stop_cif,false);
2641 pcdev->irqinfo.cifirq_idx = 0;
2642 pcdev->irqinfo.cifirq_normal_idx = 0;
2643 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2644 pcdev->irqinfo.dmairq_idx = 0;
2646 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2647 cif_ctrl_val |= ENABLE_CAPTURE;
2648 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2649 spin_unlock_irqrestore(&pcdev->lock,flags);
2650 printk("%s:stream enable CIF_CIF_CTRL 0x%lx",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2651 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2652 pcdev->fps_timer.istarted = true;
2654 /*cancel timer before stop cif*/
2655 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2656 pcdev->fps_timer.istarted = false;
2657 flush_work(&(pcdev->camera_reinit_work.work));
2659 cif_ctrl_val &= ~ENABLE_CAPTURE;
2660 spin_lock_irqsave(&pcdev->lock, flags);
2661 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2662 atomic_set(&pcdev->stop_cif,true);
2663 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2664 spin_unlock_irqrestore(&pcdev->lock, flags);
2665 flush_workqueue((pcdev->camera_wq));
2668 /*must be reinit,or will be somthing wrong in irq process.*/
2669 if(enable == false) {
2670 pcdev->active = NULL;
2671 INIT_LIST_HEAD(&pcdev->capture);
2673 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%lx\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2676 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2678 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2679 struct rk_camera_dev *pcdev = ici->priv;
2680 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2681 struct rk_camera_frmivalenum *fival_list = NULL;
2682 struct v4l2_frmivalenum *fival_head = NULL;
2683 struct rkcamera_platform_data *new_camera;
2684 int i,ret = 0,index;
2685 const struct soc_camera_format_xlate *xlate;
2686 struct v4l2_mbus_framefmt mf;
2689 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2691 index = fival->index & 0x00ffffff;
2692 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2693 for (i=0; i<2; i++) {
2694 if (pcdev->icd_frmival[i].icd == icd) {
2695 fival_list = pcdev->icd_frmival[i].fival_list;
2699 if (fival_list != NULL) {
2701 while (fival_list != NULL) {
2702 if ((fival->pixel_format == fival_list->fival.pixel_format)
2703 && (fival->height == fival_list->fival.height)
2704 && (fival->width == fival_list->fival.width)) {
2709 fival_list = fival_list->nxt;
2712 if ((i==index) && (fival_list != NULL)) {
2713 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2718 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2725 while (fival_head->width && fival_head->height) {
2726 if ((fival->pixel_format == fival_head->pixel_format)
2727 && (fival->height == fival_head->height)
2728 && (fival->width == fival_head->width)) {
2737 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2738 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2740 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2741 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2742 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2743 mf.width = fival->width;
2744 mf.height = fival->height;
2745 mf.code = xlate->code;
2747 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2749 fival->reserved[1] = (mf.width<<16)|(mf.height);
2751 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2752 fival->width, fival->height,
2753 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2754 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2755 fival->discrete.denominator,fival->discrete.numerator);
2758 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2759 fival->width,fival->height,
2760 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2761 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2764 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2765 fival->width,fival->height,
2766 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2767 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2770 goto rk_camera_enum_frameintervals_end;
2774 new_camera = pcdev->pdata->register_dev_new;
2775 while(new_camera != NULL){
2776 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2780 new_camera = new_camera->next_camera;
2784 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2785 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2788 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2789 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2790 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2791 mf.width = fival->width;
2792 mf.height = fival->height;
2793 mf.code = xlate->code;
2795 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2797 fival->discrete.numerator= 1000;
2798 fival->discrete.denominator = 15000;
2799 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2800 fival->reserved[1] = (mf.width<<16)|(mf.height);
2804 rk_camera_enum_frameintervals_end:
2808 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2809 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2812 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2813 struct rk_camera_dev *pcdev = ici->priv;
2815 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2819 unsigned long tmp_cifctrl;
2822 /*change the crop and scale parameters*/
2825 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2826 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2827 a.c.width = pcdev->host_width*100/zoom_rate;
2828 a.c.width &= ~CROP_ALIGN_BYTES;
2829 a.c.height = pcdev->host_height*100/zoom_rate;
2830 a.c.height &= ~CROP_ALIGN_BYTES;
2831 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2832 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2833 atomic_set(&pcdev->stop_cif,true);
2834 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2835 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2836 hrtimer_cancel(&(pcdev->fps_timer.timer));
2837 flush_workqueue((pcdev->camera_wq));
2839 down(&pcdev->zoominfo.sem);
2840 pcdev->zoominfo.a.c.left = 0;
2841 pcdev->zoominfo.a.c.top = 0;
2842 pcdev->zoominfo.a.c.width = a.c.width;
2843 pcdev->zoominfo.a.c.height = a.c.height;
2844 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2845 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2846 pcdev->frame_inval = 1;
2847 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2848 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2849 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2850 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2852 rk_videobuf_capture(pcdev->active,pcdev);
2853 if(tmp_cifctrl & ENABLE_CAPTURE)
2854 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2855 up(&pcdev->zoominfo.sem);
2857 atomic_set(&pcdev->stop_cif,false);
2858 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2859 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 );
2861 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2862 a.c.width = pcdev->host_width*100/zoom_rate;
2863 a.c.width &= ~CROP_ALIGN_BYTES;
2864 a.c.height = pcdev->host_height*100/zoom_rate;
2865 a.c.height &= ~CROP_ALIGN_BYTES;
2866 a.c.left = (pcdev->host_width - a.c.width)>>1;
2867 a.c.top = (pcdev->host_height - a.c.height)>>1;
2869 down(&pcdev->zoominfo.sem);
2870 pcdev->zoominfo.a.c.height = a.c.height;
2871 pcdev->zoominfo.a.c.width = a.c.width;
2872 pcdev->zoominfo.a.c.top = a.c.top;
2873 pcdev->zoominfo.a.c.left = a.c.left;
2874 pcdev->zoominfo.vir_width = pcdev->host_width;
2875 pcdev->zoominfo.vir_height= pcdev->host_height;
2876 up(&pcdev->zoominfo.sem);
2878 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 );
2884 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2885 struct soc_camera_host_ops *ops, int id)
2889 for (i = 0; i < ops->num_controls; i++)
2890 if (ops->controls[i].id == id)
2891 return &ops->controls[i];
2897 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2898 struct v4l2_control *sctrl)
2900 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2901 const struct v4l2_queryctrl *qctrl;
2902 struct rk_camera_dev *pcdev = ici->priv;
2906 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2908 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2911 goto rk_camera_set_ctrl_end;
2916 case V4L2_CID_ZOOM_ABSOLUTE:
2918 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2920 goto rk_camera_set_ctrl_end;
2922 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2924 pcdev->zoominfo.zoom_rate = sctrl->value;
2926 goto rk_camera_set_ctrl_end;
2934 rk_camera_set_ctrl_end:
2938 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2940 .owner = THIS_MODULE,
2941 .add = rk_camera_add_device,
2942 .remove = rk_camera_remove_device,
2943 .suspend = rk_camera_suspend,
2944 .resume = rk_camera_resume,
2945 .enum_frameinervals = rk_camera_enum_frameintervals,
2946 .cropcap = rk_camera_cropcap,
2947 .set_crop = rk_camera_set_crop,
2948 .get_crop = rk_camera_get_crop,
2949 .get_formats = rk_camera_get_formats,
2950 .put_formats = rk_camera_put_formats,
2951 .set_fmt = rk_camera_set_fmt,
2952 .try_fmt = rk_camera_try_fmt,
2953 .init_videobuf = rk_camera_init_videobuf,
2954 .reqbufs = rk_camera_reqbufs,
2955 .poll = rk_camera_poll,
2956 .querycap = rk_camera_querycap,
2957 .set_bus_param = rk_camera_set_bus_param,
2958 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2959 .set_ctrl = rk_camera_set_ctrl,
2960 .controls = rk_camera_controls,
2961 .num_controls = ARRAY_SIZE(rk_camera_controls)
2964 /**********yzm***********/
2965 static int rk_camera_cif_iomux(struct device *dev)
2968 struct pinctrl *pinctrl;
2969 struct pinctrl_state *state;
2971 char state_str[20] = {0};
2973 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2974 strcpy(state_str,"cif_pin_jpe");
2976 /*__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);*/
2981 pinctrl = devm_pinctrl_get(dev);
2982 if (IS_ERR(pinctrl)) {
2983 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
2986 state = pinctrl_lookup_state(pinctrl,
2989 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
2993 if (!IS_ERR(state)) {
2994 retval = pinctrl_select_state(pinctrl, state);
2997 "%s:could not set %s pins\n",__func__,state_str);
3005 /***********yzm***********/
3006 static int rk_camera_probe(struct platform_device *pdev)
3008 struct rk_camera_dev *pcdev;
3009 struct resource *res;
3010 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3013 struct rk_cif_clk *clk=NULL;
3014 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
3016 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3018 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3019 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3021 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3022 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3026 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3027 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3031 /***********yzm**********/
3032 rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3034 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3035 irq = platform_get_irq(pdev, 0);
3037 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3038 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3039 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3041 if (!res || irq < 0) {
3045 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3047 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3052 pcdev->zoominfo.zoom_rate = 100;
3053 pcdev->hostid = pdev->id; /* get host id*/
3054 #ifdef CONFIG_SOC_RK3028
3055 pcdev->chip_id = rk3028_version_val();
3057 pcdev->chip_id = -1;
3060 /***********yzm***********/
3062 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3064 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3065 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3066 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3067 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3068 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3069 //spin_lock_init(&cif_clk[0].lock);
3070 cif_clk[0].on = false;
3071 rk_camera_cif_iomux(dev_cif);/*yzm*/
3074 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only yzm*/
3075 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3076 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3077 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3078 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3079 //spin_lock_init(&cif_clk[1].lock);
3080 cif_clk[1].on = false;
3081 rk_camera_cif_iomux(dev_cif);/*yzm*/
3084 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3086 /***********yzm**********/
3087 dev_set_drvdata(&pdev->dev, pcdev);
3089 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3090 /*= rk_camera_platform_data */
3091 if (pcdev->pdata && pcdev->pdata->io_init) {
3093 pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
3095 if (pcdev->pdata->sensor_mclk == NULL)
3096 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3099 INIT_LIST_HEAD(&pcdev->capture);
3100 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3101 spin_lock_init(&pcdev->lock);
3102 spin_lock_init(&pcdev->camera_work_lock);
3104 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3105 spin_lock_init(&pcdev->cropinfo.lock);
3106 sema_init(&pcdev->zoominfo.sem,1);
3109 * Request the regions.
3112 if (!request_mem_region(res->start, res->end - res->start + 1,
3113 RK29_CAM_DRV_NAME)) {
3115 goto exit_reqmem_vip;
3117 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3118 if (pcdev->base == NULL) {
3119 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3121 goto exit_ioremap_vip;
3125 pcdev->irqinfo.irq = irq;
3126 pcdev->dev = &pdev->dev;
3128 /* config buffer address */
3131 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3134 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3140 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3142 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3144 if (pcdev->camera_wq == NULL) {
3145 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3149 pcdev->camera_reinit_work.pcdev = pcdev;
3150 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3152 for (i=0; i<2; i++) {
3153 pcdev->icd_frmival[i].icd = NULL;
3154 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3157 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3158 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3159 pcdev->soc_host.priv = pcdev; /*to itself,csll in rk_camera_add_device*/
3160 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3161 pcdev->soc_host.nr = pdev->id;
3162 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3163 err = soc_camera_host_register(&pcdev->soc_host);
3167 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3170 pcdev->fps_timer.pcdev = pcdev;
3171 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3172 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3173 pcdev->icd_cb.sensor_cb = NULL;
3175 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3176 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3177 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3178 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3179 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3180 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3181 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3182 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3188 for (i=0; i<2; i++) {
3189 fival_list = pcdev->icd_frmival[i].fival_list;
3190 fival_nxt = fival_list;
3191 while(fival_nxt != NULL) {
3192 fival_nxt = fival_list->nxt;
3194 fival_list = fival_nxt;
3198 free_irq(pcdev->irqinfo.irq, pcdev);
3199 if (pcdev->camera_wq) {
3200 destroy_workqueue(pcdev->camera_wq);
3201 pcdev->camera_wq = NULL;
3204 iounmap(pcdev->base);
3206 release_mem_region(res->start, res->end - res->start + 1);
3210 clk_put(clk->pd_cif);
3212 clk_put(clk->aclk_cif);
3214 clk_put(clk->hclk_cif);
3215 if (clk->cif_clk_in)
3216 clk_put(clk->cif_clk_in);
3217 if (clk->cif_clk_out)
3218 clk_put(clk->cif_clk_out);
3227 static int __exit rk_camera_remove(struct platform_device *pdev)
3229 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3230 struct resource *res;
3231 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3234 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3237 free_irq(pcdev->irqinfo.irq, pcdev);
3239 if (pcdev->camera_wq) {
3240 destroy_workqueue(pcdev->camera_wq);
3241 pcdev->camera_wq = NULL;
3244 for (i=0; i<2; i++) {
3245 fival_list = pcdev->icd_frmival[i].fival_list;
3246 fival_nxt = fival_list;
3247 while(fival_nxt != NULL) {
3248 fival_nxt = fival_list->nxt;
3250 fival_list = fival_nxt;
3254 soc_camera_host_unregister(&pcdev->soc_host);
3257 iounmap((void __iomem*)pcdev->base);
3258 release_mem_region(res->start, res->end - res->start + 1);
3259 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3260 pcdev->pdata->io_deinit(0);
3261 pcdev->pdata->io_deinit(1);
3266 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3271 static struct platform_driver rk_camera_driver =
3274 .name = RK29_CAM_DRV_NAME, /*host */
3276 .probe = rk_camera_probe,
3277 .remove = (rk_camera_remove),
3280 static int rk_camera_init_async(void *unused)
3283 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3284 platform_driver_register(&rk_camera_driver);
3288 static int __init rk_camera_init(void)
3291 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3293 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3298 static void __exit rk_camera_exit(void)
3300 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3302 platform_driver_unregister(&rk_camera_driver);
3305 device_initcall_sync(rk_camera_init);
3306 module_exit(rk_camera_exit);
3308 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3309 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3310 MODULE_LICENSE("GPL");