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"
32 #include <linux/rockchip/cru.h>
34 #include <asm/cacheflush.h>
36 #include <linux/of_address.h>
37 #include <linux/of_platform.h>
38 #include <linux/of_fdt.h>
39 #include <media/soc_camera.h>
40 #include <media/camsys_head.h>
42 #include <linux/of_irq.h>
45 module_param(debug, int, S_IRUGO|S_IWUSR);
47 #define CAMMODULE_NAME "rk_cam_cif"
49 #define wprintk(level, fmt, arg...) do { \
51 printk(KERN_ERR "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
53 #define dprintk(level, fmt, arg...) do { \
55 printk(KERN_ERR"%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
57 #define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
58 #define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
59 #define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
60 #define debug_printk(format, ...) dprintk(3, format, ## __VA_ARGS__)
63 #define CIF_CIF_CTRL 0x00
64 #define CIF_CIF_INTEN 0x04
65 #define CIF_CIF_INTSTAT 0x08
66 #define CIF_CIF_FOR 0x0c
67 #define CIF_CIF_LINE_NUM_ADDR 0x10
68 #define CIF_CIF_FRM0_ADDR_Y 0x14
69 #define CIF_CIF_FRM0_ADDR_UV 0x18
70 #define CIF_CIF_FRM1_ADDR_Y 0x1c
71 #define CIF_CIF_FRM1_ADDR_UV 0x20
72 #define CIF_CIF_VIR_LINE_WIDTH 0x24
73 #define CIF_CIF_SET_SIZE 0x28
74 #define CIF_CIF_SCM_ADDR_Y 0x2c
75 #define CIF_CIF_SCM_ADDR_U 0x30
76 #define CIF_CIF_SCM_ADDR_V 0x34
77 #define CIF_CIF_WB_UP_FILTER 0x38
78 #define CIF_CIF_WB_LOW_FILTER 0x3c
79 #define CIF_CIF_WBC_CNT 0x40
80 #define CIF_CIF_CROP 0x44
81 #define CIF_CIF_SCL_CTRL 0x48
82 #define CIF_CIF_SCL_DST 0x4c
83 #define CIF_CIF_SCL_FCT 0x50
84 #define CIF_CIF_SCL_VALID_NUM 0x54
85 #define CIF_CIF_LINE_LOOP_CTR 0x58
86 #define CIF_CIF_FRAME_STATUS 0x60
87 #define CIF_CIF_CUR_DST 0x64
88 #define CIF_CIF_LAST_LINE 0x68
89 #define CIF_CIF_LAST_PIX 0x6c
91 /*The key register bit descrition*/
92 /* CIF_CTRL Reg , ignore SCM,WBC,ISP,*/
93 #define DISABLE_CAPTURE (0x00<<0)
94 #define ENABLE_CAPTURE (0x01<<0)
95 #define MODE_ONEFRAME (0x00<<1)
96 #define MODE_PINGPONG (0x01<<1)
97 #define MODE_LINELOOP (0x02<<1)
98 #define AXI_BURST_16 (0x0F << 12)
101 #define FRAME_END_EN (0x01<<1)
102 #define BUS_ERR_EN (0x01<<6)
103 #define SCL_ERR_EN (0x01<<7)
106 #define VSY_HIGH_ACTIVE (0x01<<0)
107 #define VSY_LOW_ACTIVE (0x00<<0)
108 #define HSY_LOW_ACTIVE (0x01<<1)
109 #define HSY_HIGH_ACTIVE (0x00<<1)
110 #define INPUT_MODE_YUV (0x00<<2)
111 #define INPUT_MODE_PAL (0x02<<2)
112 #define INPUT_MODE_NTSC (0x03<<2)
113 #define INPUT_MODE_RAW (0x04<<2)
114 #define INPUT_MODE_JPEG (0x05<<2)
115 #define INPUT_MODE_MIPI (0x06<<2)
116 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
117 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
118 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
119 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
120 #define YUV_INPUT_422 (0x00<<7)
121 #define YUV_INPUT_420 (0x01<<7)
122 #define INPUT_420_ORDER_EVEN (0x00<<8)
123 #define INPUT_420_ORDER_ODD (0x01<<8)
124 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
125 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
126 #define RAW_DATA_WIDTH_8 (0x00<<11)
127 #define RAW_DATA_WIDTH_10 (0x01<<11)
128 #define RAW_DATA_WIDTH_12 (0x02<<11)
129 #define YUV_OUTPUT_422 (0x00<<16)
130 #define YUV_OUTPUT_420 (0x01<<16)
131 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
132 #define OUTPUT_420_ORDER_ODD (0x01<<17)
133 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
134 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
135 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
136 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
139 #define ENABLE_SCL_DOWN (0x01<<0)
140 #define DISABLE_SCL_DOWN (0x00<<0)
141 #define ENABLE_SCL_UP (0x01<<1)
142 #define DISABLE_SCL_UP (0x00<<1)
143 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
144 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
145 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
146 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
147 #define ENABLE_32BIT_BYPASS (0x01<<6)
148 #define DISABLE_32BIT_BYPASS (0x00<<6)
150 extern unsigned long rk_cif_grf_base;
151 extern unsigned long rk_cif_cru_base;
154 #define MIN(x,y) ((x<y) ? x: y)
155 #define MAX(x,y) ((x>y) ? x: y)
156 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
157 #define RK_SENSOR_48MHZ 48
159 #define __raw_readl(p) (*(unsigned int *)(p))
160 #define __raw_writel(v,p) (*(unsigned int *)(p) = (v))
162 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
163 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
164 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
167 static u32 CRU_PCLK_REG30;
168 static u32 CRU_CLK_OUT;
169 static u32 clk_cif_out_src_gate_en;
170 static u32 CRU_CLKSEL29_CON;
171 static u32 cif0_clk_sel;
172 static u32 ENANABLE_INVERT_PCLK_CIF0;
173 static u32 DISABLE_INVERT_PCLK_CIF0;
174 static u32 ENANABLE_INVERT_PCLK_CIF1;
175 static u32 DISABLE_INVERT_PCLK_CIF1;
176 static u32 CHIP_NAME;
178 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK_CRU_VIRT)
179 #define read_cru_reg(addr) __raw_readl(addr+RK_CRU_VIRT)
180 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
182 #define rk3368_write_cru_reg(addr, val) __raw_writel(val, addr+rk_cif_cru_base)
183 #define rk3368_read_cru_reg(addr) __raw_readl(addr+rk_cif_cru_base)
184 #define rk3368_mask_cru_reg(addr, msk, val) rk3368_write_cru_reg(addr,(val)|((~(msk))&rk3368_read_cru_reg(addr)))
186 #define CAM_WORKQUEUE_IS_EN() (true)
187 #define CAM_IPPWORK_IS_EN() (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
189 #define IS_CIF0() (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
190 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
191 #define CROP_ALIGN_BYTES (0x03)
192 #define CIF_DO_CROP 0
193 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
194 #define CROP_ALIGN_BYTES (0x0f)
195 #define CIF_DO_CROP 0
196 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
197 #define CROP_ALIGN_BYTES (0x03)
198 #define CIF_DO_CROP 0
199 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
200 #define CROP_ALIGN_BYTES (0x0F)
201 #define CIF_DO_CROP 1
205 *v0.1.0 : this driver is 3.10 kernel driver;
206 copy and updata from v0.3.0x19;
209 1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
210 cause warning, so remove this spin lock .
212 1. rk3126 and rk3128 use different dts file.
214 1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
216 1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk
218 1. Improve the code to support all configuration.reset,af,flash...
220 1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
222 1. Add power and powerdown controled by PMU.
224 1. Support front and rear camera support are the same.
226 1. Support pingpong mode.
227 2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0
228 3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
229 4. Support flash control when preview size == picture size
231 1. Support rk3288 cif driver
232 2. Query and upload iommu info
234 1. Vpu_service compatible has change ,fix it.
236 1. setting cif capture en bit can't stop cif really,reset cif instead.
238 1. use of_find_node_by_name to get vpu node instead of of_find_compatible_node
240 1. support focus mode.
242 1. focus mode have some bug,fix it.
246 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0)
247 static int version = RK_CAM_VERSION_CODE;
248 module_param(version, int, S_IRUGO);
250 /* limit to rk29 hardware capabilities */
251 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
252 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
253 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
254 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
255 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
256 V4L2_MBUS_PCLK_SAMPLE_RISING |\
257 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
258 V4L2_MBUS_DATA_ACTIVE_HIGH |\
259 V4L2_MBUS_DATA_ACTIVE_LOW|\
260 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
261 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
263 #define RK_CAM_W_MIN 48
264 #define RK_CAM_H_MIN 32
265 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
266 #define RK_CAM_H_MAX 2764
267 #define RK_CAM_FRAME_INVAL_INIT 0
268 #define RK_CAM_FRAME_INVAL_DC 0 /* ddl@rock-chips.com : */
269 #define RK30_CAM_FRAME_MEASURE 5
272 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
273 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
274 /* buffer for one video frame */
275 struct rk_camera_buffer
277 /* common v4l buffer stuff -- must be first */
278 struct videobuf_buffer vb;
279 enum v4l2_mbus_pixelcode code;
282 enum rk_camera_reg_state
290 unsigned int cifCtrl;
291 unsigned int cifCrop;
293 unsigned int cifIntEn;
295 unsigned int cifVirWidth;
296 unsigned int cifScale;
297 /* unsigned int VipCrm;*/
298 enum rk_camera_reg_state Inval;
300 struct rk_camera_work
302 struct videobuf_buffer *vb;
303 struct rk_camera_dev *pcdev;
304 struct work_struct work;
305 struct list_head queue;
308 struct rk_camera_frmivalenum
310 struct v4l2_frmivalenum fival;
311 struct rk_camera_frmivalenum *nxt;
313 struct rk_camera_frmivalinfo
315 struct soc_camera_device *icd;
316 struct rk_camera_frmivalenum *fival_list;
318 struct rk_camera_zoominfo
320 struct semaphore sem;
326 #if CAMERA_VIDEOBUF_ARM_ACCESS
327 struct rk29_camera_vbinfo
329 unsigned long phy_addr;
330 void __iomem *vir_addr;
334 struct rk_camera_timer{
335 struct rk_camera_dev *pcdev;
336 struct hrtimer timer;
341 /************must modify start************/
343 struct clk *aclk_cif;
344 struct clk *hclk_cif;
345 struct clk *cif_clk_in;
346 struct clk *cif_clk_out;
347 /************must modify end************/
357 struct v4l2_rect bounds;
360 struct rk_cif_irqinfo
363 unsigned long cifirq_idx;
364 unsigned long cifirq_normal_idx;
365 unsigned long cifirq_abnormal_idx;
367 unsigned long dmairq_idx;
373 struct soc_camera_host soc_host;
375 /* RK2827x is only supposed to handle one camera on its Quick Capture
376 * interface. If anyone ever builds hardware to enable more than
377 * one camera, they will have to modify this driver too */
378 struct soc_camera_device *icd;
380 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
383 unsigned int last_fps;
384 unsigned long frame_interval;
387 unsigned long vipmem_phybase;
388 void __iomem *vipmem_virbase;
389 unsigned int vipmem_size;
390 unsigned int vipmem_bsize;
391 #if CAMERA_VIDEOBUF_ARM_ACCESS
392 struct rk29_camera_vbinfo *vbinfo;
393 unsigned int vbinfo_count;
397 int host_left; /*sensor output size ?*/
403 struct rk_cif_crop cropinfo;
404 struct rk_cif_irqinfo irqinfo;
406 struct rk29camera_platform_data *pdata;
407 struct resource *res;
408 struct list_head capture;
409 struct rk_camera_zoominfo zoominfo;
413 struct videobuf_buffer *active;
414 struct rk_camera_reg reginfo_suspend;
415 struct workqueue_struct *camera_wq;
416 struct rk_camera_work *camera_work;
417 struct list_head camera_work_queue;
418 spinlock_t camera_work_lock;
419 unsigned int camera_work_count;
420 struct rk_camera_timer fps_timer;
421 struct rk_camera_work camera_reinit_work;
423 rk29_camera_sensor_cb_s icd_cb;
424 struct rk_camera_frmivalinfo icd_frmival[2];
426 unsigned int reinit_times;
427 struct videobuf_queue *video_vq;
429 wait_queue_head_t cif_stop_done;
430 volatile bool cif_stopped;
431 struct timeval first_tv;
436 static const struct v4l2_queryctrl rk_camera_controls[] =
439 .id = V4L2_CID_ZOOM_ABSOLUTE,
440 .type = V4L2_CTRL_TYPE_INTEGER,
441 .name = "DigitalZoom Control",
445 .default_value = 100,
449 static struct rk_cif_clk cif_clk[2];
451 static DEFINE_MUTEX(camera_lock);
452 static const char *rk_cam_driver_description = "RK_Camera";
454 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
455 static void rk_camera_capture_process(struct work_struct *work);
457 static void rk_camera_diffchips(const char *rockchip_name)
459 if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
461 CRU_PCLK_REG30 = 0xbc;
462 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
463 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7));
464 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
465 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
468 clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7));
469 CRU_CLKSEL29_CON = 0xb8;
470 cif0_clk_sel = ((0x1<<23)|(0x0<<7));
474 else if(strstr(rockchip_name,"3288"))
476 CRU_PCLK_REG30 = 0xd4;
477 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x1<<4));
478 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x0<<4));
479 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
480 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
485 else if(strstr(rockchip_name,"3368"))
487 CRU_PCLK_REG30 = 0x154;
488 ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x1<<13));
489 DISABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x0<<13));
490 ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
491 DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0;
493 //CRU_CLK_OUT = 0x16c;
497 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
502 if(CHIP_NAME == 3368)
503 reg = (void*)(rk_cif_cru_base + RK_CRU_SOFTRST_CON);
505 reg = (void*)(RK_CRU_VIRT + RK_CRU_SOFTRST_CON);
507 if(CHIP_NAME == 3126){
508 val = on ? 0x10001U << 14 : 0x10000U << 14;
509 }else if(CHIP_NAME == 3288){
510 val = on ? 0x10001U << 8 : 0x10000U << 8;
511 }else if(CHIP_NAME == 3368){
512 val = on ? 0x10001U << 8 : 0x10000U << 8;
514 writel_relaxed(val, reg);
518 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
520 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
521 u32 RK_CRU_SOFTRST_CON = 0;
522 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
523 if(CHIP_NAME == 3126){
524 RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
525 }else if(CHIP_NAME == 3288){
526 RK_CRU_SOFTRST_CON = RK3288_CRU_SOFTRSTS_CON(6);
527 }else if(CHIP_NAME == 3368){
528 RK_CRU_SOFTRST_CON = RK3368_CRU_SOFTRSTS_CON(6);
531 if (only_rst == true) {
532 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
534 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
536 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
537 if (ctrl_reg & ENABLE_CAPTURE) {
538 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
540 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
541 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
542 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
543 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
544 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
545 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
546 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
547 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
549 rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
551 rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
553 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
554 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
555 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
556 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
557 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
558 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
559 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
560 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
561 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
568 * Videobuf operations
570 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
573 struct soc_camera_device *icd = vq->priv_data;
574 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
575 struct rk_camera_dev *pcdev = ici->priv;
577 struct rk_camera_work *wk;
579 struct soc_mbus_pixelfmt fmt;
581 int bytes_per_line_host;
582 fmt.packing = SOC_MBUS_PACKING_1_5X8;
584 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
587 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
588 icd->current_fmt->host_fmt);
589 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
590 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
592 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
593 bytes_per_line_host = pcdev->host_width*3;
595 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
596 icd->current_fmt->host_fmt);
597 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
599 if (bytes_per_line_host < 0)
600 return bytes_per_line_host;
602 /* planar capture requires Y, U and V buffers to be page aligned */
603 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
604 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
606 if (CAM_WORKQUEUE_IS_EN()) {
608 if (CAM_IPPWORK_IS_EN()) {
609 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
610 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
611 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
615 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
616 kfree(pcdev->camera_work);
617 pcdev->camera_work = NULL;
618 pcdev->camera_work_count = 0;
621 if (pcdev->camera_work == NULL) {
622 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
623 if (pcdev->camera_work == NULL) {
624 RKCAMERA_TR("kmalloc failed\n");
627 INIT_LIST_HEAD(&pcdev->camera_work_queue);
629 for (i=0; i<(*count); i++) {
631 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
634 pcdev->camera_work_count = (*count);
636 #if CAMERA_VIDEOBUF_ARM_ACCESS
637 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
638 kfree(pcdev->vbinfo);
639 pcdev->vbinfo = NULL;
640 pcdev->vbinfo_count = 0x00;
643 if (pcdev->vbinfo == NULL) {
644 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
645 if (pcdev->vbinfo == NULL) {
646 RKCAMERA_TR("vbinfo kmalloc fail\n");
649 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
650 pcdev->vbinfo_count = *count;
654 pcdev->video_vq = vq;
655 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
659 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
661 struct soc_camera_device *icd = vq->priv_data;
663 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
666 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
667 &buf->vb, buf->vb.baddr, buf->vb.bsize);
669 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
670 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
676 * This waits until this buffer is out of danger, i.e., until it is no
677 * longer in STATE_QUEUED or STATE_ACTIVE
679 videobuf_waiton(vq, &buf->vb, 0, 0);
680 videobuf_dma_contig_free(vq, &buf->vb);
681 buf->vb.state = VIDEOBUF_NEEDS_INIT;
684 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
686 struct soc_camera_device *icd = vq->priv_data;
687 struct rk_camera_buffer *buf;
689 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
690 icd->current_fmt->host_fmt);
692 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
694 if ((bytes_per_line < 0) || (vb->boff == 0))
697 buf = container_of(vb, struct rk_camera_buffer, vb);
699 /* Added list head initialization on alloc */
700 WARN_ON(!list_empty(&vb->queue));
702 BUG_ON(NULL == icd->current_fmt);
704 if (buf->code != icd->current_fmt->code ||
705 vb->width != icd->user_width ||
706 vb->height != icd->user_height ||
707 vb->field != field) {
708 buf->code = icd->current_fmt->code;
709 vb->width = icd->user_width;
710 vb->height = icd->user_height;
712 vb->state = VIDEOBUF_NEEDS_INIT;
715 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
716 if (0 != vb->baddr && vb->bsize < vb->size) {
721 if (vb->state == VIDEOBUF_NEEDS_INIT) {
722 ret = videobuf_iolock(vq, vb, NULL);
726 vb->state = VIDEOBUF_PREPARED;
731 rk_videobuf_free(vq, buf);
736 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
738 unsigned long y_addr,uv_addr;
739 struct rk_camera_dev *pcdev = rk_pcdev;
741 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
745 if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
746 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
747 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
748 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
749 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
750 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
755 uv_addr = y_addr + vb->width * vb->height;
757 #if defined(CONFIG_ARCH_RK3188)
758 rk_camera_cif_reset(pcdev,false);
760 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
761 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
762 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
763 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
764 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
767 /* Locking: Caller holds q->irqlock */
768 static void rk_videobuf_queue(struct videobuf_queue *vq,
769 struct videobuf_buffer *vb)
771 struct soc_camera_device *icd = vq->priv_data;
772 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
773 struct rk_camera_dev *pcdev = ici->priv;
774 #if CAMERA_VIDEOBUF_ARM_ACCESS
775 struct rk29_camera_vbinfo *vb_info;
779 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
781 vb->state = VIDEOBUF_QUEUED;
782 if (list_empty(&pcdev->capture)) {
783 list_add_tail(&vb->queue, &pcdev->capture);
785 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
786 list_add_tail(&vb->queue, &pcdev->capture);
788 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
790 #if CAMERA_VIDEOBUF_ARM_ACCESS
792 vb_info = pcdev->vbinfo+vb->i;
793 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
794 if (vb_info->vir_addr) {
795 iounmap(vb_info->vir_addr);
796 release_mem_region(vb_info->phy_addr, vb_info->size);
797 vb_info->vir_addr = NULL;
798 vb_info->phy_addr = 0x00;
799 vb_info->size = 0x00;
802 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
803 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
806 if (vb_info->vir_addr) {
807 vb_info->size = vb->bsize;
808 vb_info->phy_addr = vb->boff;
810 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
815 if (!pcdev->active) {
817 rk_videobuf_capture(vb,pcdev);
818 if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13
819 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
824 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
825 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
828 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
832 case V4L2_PIX_FMT_YUV420:
833 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.*/
834 case V4L2_PIX_FMT_YUYV:
836 *ippfmt = RK_FORMAT_YCbCr_420_SP;
839 case V4L2_PIX_FMT_YVU420:
840 case V4L2_PIX_FMT_VYUY:
841 case V4L2_PIX_FMT_YVYU:
843 *ippfmt = RK_FORMAT_YCrCb_420_SP;
846 case V4L2_PIX_FMT_RGB565:
848 *ippfmt = RK_FORMAT_RGB_565;
851 case V4L2_PIX_FMT_RGB24:
853 *ippfmt = RK_FORMAT_RGB_888;
857 goto rk_pixfmt2rgafmt_err;
861 rk_pixfmt2rgafmt_err:
865 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
866 static int rk_camera_scale_crop_pp(struct work_struct *work){
867 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
868 struct videobuf_buffer *vb = camera_work->vb;
869 struct rk_camera_dev *pcdev = camera_work->pcdev;
871 unsigned long int flags;
879 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
880 extern rga_service_info rga_service;
881 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
882 extern void rga_service_session_clear(rga_session *session);
883 static int rk_camera_scale_crop_rga(struct work_struct *work){
884 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
885 struct videobuf_buffer *vb = camera_work->vb;
886 struct rk_camera_dev *pcdev = camera_work->pcdev;
888 unsigned long int flags;
894 const struct soc_mbus_pixelfmt *fmt;
897 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
904 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
906 static int rk_camera_scale_crop_ipp(struct work_struct *work)
912 static void rk_camera_capture_process(struct work_struct *work)
914 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
915 struct videobuf_buffer *vb = camera_work->vb;
916 struct rk_camera_dev *pcdev = camera_work->pcdev;
917 unsigned long flags = 0;
920 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
923 if (atomic_read(&pcdev->stop_cif)==true) {
925 goto rk_camera_capture_process_end;
928 if (!CAM_WORKQUEUE_IS_EN()) {
930 goto rk_camera_capture_process_end;
933 down(&pcdev->zoominfo.sem);
934 if (pcdev->icd_cb.scale_crop_cb){
935 err = (pcdev->icd_cb.scale_crop_cb)(work);
937 up(&pcdev->zoominfo.sem);
939 if (pcdev->icd_cb.sensor_cb)
940 (pcdev->icd_cb.sensor_cb)(vb);
942 rk_camera_capture_process_end:
944 vb->state = VIDEOBUF_ERROR;
946 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
947 vb->state = VIDEOBUF_DONE;
951 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
952 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
953 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
954 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
958 static void rk_camera_cifrest_delay(struct work_struct *work)
960 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
961 struct rk_camera_dev *pcdev = camera_work->pcdev;
962 unsigned long flags = 0;
964 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
968 rk_camera_cif_reset(pcdev,false);
970 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
971 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
972 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
974 spin_lock_irqsave(&pcdev->lock,flags);
975 if (atomic_read(&pcdev->stop_cif) == false) {
976 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
977 RKCAMERA_DG2("After reset cif, enable capture again!\n");
979 spin_unlock_irqrestore(&pcdev->lock,flags);
983 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
985 struct rk_camera_dev *pcdev = data;
986 struct rk_camera_work *wk;
987 unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
989 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
992 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
994 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
995 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
996 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
998 pcdev->irqinfo.cifirq_idx++;
999 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
1000 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
1001 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
1002 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
1004 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
1007 if(reg_cifctrl & ENABLE_CAPTURE) {
1008 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
1011 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
1012 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
1013 if (!list_empty(&pcdev->camera_work_queue)) {
1014 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
1015 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1016 list_del_init(&wk->queue);
1017 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
1019 queue_work(pcdev->camera_wq, &(wk->work));
1027 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
1029 struct rk_camera_dev *pcdev = data;
1030 struct videobuf_buffer *vb;
1031 struct rk_camera_work *wk;
1033 unsigned long reg_cifctrl;
1035 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1038 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1039 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1040 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { //frame 0 ready yzm
1041 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1043 pcdev->irqinfo.dmairq_idx++;
1044 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1045 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1050 do_gettimeofday(&pcdev->first_tv);
1055 if (pcdev->frame_inval>0) {
1056 pcdev->frame_inval--;
1057 rk_videobuf_capture(pcdev->active,pcdev);
1059 } else if (pcdev->frame_inval) {
1060 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1061 pcdev->frame_inval = 0;
1064 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1065 do_gettimeofday(&tv);
1066 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1067 /(RK30_CAM_FRAME_MEASURE-1);
1072 printk("no acticve buffer!!!\n");
1076 /* ddl@rock-chips.com : this vb may be deleted from queue */
1077 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1078 list_del_init(&vb->queue);
1080 pcdev->active = NULL;
1081 if (!list_empty(&pcdev->capture)) {
1082 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1083 if (pcdev->active) {
1084 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1085 rk_videobuf_capture(pcdev->active,pcdev);
1088 if (pcdev->active == NULL) {
1089 RKCAMERA_DG1("video_buf queue is empty!\n");
1092 do_gettimeofday(&vb->ts);
1093 if (CAM_WORKQUEUE_IS_EN()) {
1094 if (!list_empty(&pcdev->camera_work_queue)) {
1095 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1096 list_del_init(&wk->queue);
1097 INIT_WORK(&(wk->work), rk_camera_capture_process);
1100 queue_work(pcdev->camera_wq, &(wk->work));
1103 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1104 vb->state = VIDEOBUF_DONE;
1112 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1113 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1117 static irqreturn_t rk_camera_irq(int irq, void *data)
1119 struct rk_camera_dev *pcdev = data;
1120 unsigned int reg_intstat;
1122 //should set value in cif irq
1123 static int rec_stop_cif = 0;
1125 spin_lock(&pcdev->lock);
1128 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1129 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%x\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1130 if (reg_intstat & 0x0200){
1131 rk_camera_cifirq(irq,data);
1132 if(atomic_read(&pcdev->stop_cif))
1135 debug_printk("receive cif stop request, recevie cif irq,reg_intstat = 0x%x\n",reg_intstat);
1139 if (reg_intstat & 0x01){
1140 if(rec_stop_cif == 1){
1141 pcdev->cif_stopped = true;
1143 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
1144 //workaround: disabled capen can't stop cif really,so should reset instead.
1145 rk_camera_cif_reset(pcdev,false);
1146 debug_printk("receive cif stop request,recevie dma irq ,reg_intstat = 0x%x\n",reg_intstat);
1147 wake_up(&pcdev->cif_stop_done);
1149 rk_camera_dmairq(irq,data);
1153 spin_unlock(&pcdev->lock);
1158 static void rk_videobuf_release(struct videobuf_queue *vq,
1159 struct videobuf_buffer *vb)
1161 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1162 struct soc_camera_device *icd = vq->priv_data;
1163 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1164 struct rk_camera_dev *pcdev = ici->priv;
1165 #if CAMERA_VIDEOBUF_ARM_ACCESS
1166 struct rk29_camera_vbinfo *vb_info =NULL;
1171 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1174 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1175 vb, vb->baddr, vb->bsize);
1179 case VIDEOBUF_ACTIVE:
1180 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1182 case VIDEOBUF_QUEUED:
1183 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1185 case VIDEOBUF_PREPARED:
1186 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1189 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1194 flush_workqueue(pcdev->camera_wq);
1196 rk_videobuf_free(vq, buf);
1198 #if CAMERA_VIDEOBUF_ARM_ACCESS
1199 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1200 vb_info = pcdev->vbinfo + vb->i;
1202 if (vb_info->vir_addr) {
1203 iounmap(vb_info->vir_addr);
1204 release_mem_region(vb_info->phy_addr, vb_info->size);
1205 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1212 static struct videobuf_queue_ops rk_videobuf_ops =
1214 .buf_setup = rk_videobuf_setup,
1215 .buf_prepare = rk_videobuf_prepare,
1216 .buf_queue = rk_videobuf_queue,
1217 .buf_release = rk_videobuf_release,
1220 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1221 struct soc_camera_device *icd)
1223 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1224 struct rk_camera_dev *pcdev = ici->priv;
1226 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1229 /* We must pass NULL as dev pointer, then all pci_* dma operations
1230 * transform to normal dma_* ones. */
1231 videobuf_queue_dma_contig_init(q,
1233 ici->v4l2_dev.dev, &pcdev->lock,
1234 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1236 sizeof(struct rk_camera_buffer),
1237 icd,&(ici->host_lock) );
1240 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1243 struct rk_cif_clk *clk;
1245 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1248 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1249 if ((cif<0)||(cif>1)) {
1250 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1252 goto rk_camera_clk_ctrl_end;
1255 clk = &cif_clk[cif];
1257 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1258 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1260 goto rk_camera_clk_ctrl_end;
1263 //spin_lock(&clk->lock);
1264 if (on && !clk->on) {
1265 if(CHIP_NAME != 3368)
1266 clk_prepare_enable(clk->pd_cif);
1268 clk_prepare_enable(clk->aclk_cif);
1269 clk_prepare_enable(clk->hclk_cif);
1270 clk_prepare_enable(clk->cif_clk_in);
1271 clk_prepare_enable(clk->cif_clk_out);
1272 clk_set_rate(clk->cif_clk_out,clk_rate);
1274 } else if (!on && clk->on) {
1275 clk_set_rate(clk->cif_clk_out,36000000);/*just for close clk which base on XIN24M */
1276 clk_disable_unprepare(clk->aclk_cif);
1277 clk_disable_unprepare(clk->hclk_cif);
1278 clk_disable_unprepare(clk->cif_clk_in);
1279 if(CHIP_NAME == 3126){
1280 write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
1281 write_cru_reg(CRU_CLK_OUT, 0x00800080);
1283 clk_disable_unprepare(clk->cif_clk_out);
1284 if(CHIP_NAME != 3368)
1285 clk_disable_unprepare(clk->pd_cif);
1289 //spin_unlock(&clk->lock);
1290 rk_camera_clk_ctrl_end:
1293 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1296 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1299 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1301 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1302 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1306 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1309 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1311 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1317 /* The following two functions absolutely depend on the fact, that
1318 * there can be only one camera on RK28 quick capture interface */
1319 static int rk_camera_add_device(struct soc_camera_device *icd)
1321 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1322 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1323 struct device *control = to_soc_camera_control(icd);
1324 struct v4l2_subdev *sd;
1325 int ret,i,icd_catch;
1326 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1327 struct v4l2_cropcap cropcap;
1328 struct v4l2_mbus_framefmt mf;
1329 const struct soc_camera_format_xlate *xlate = NULL;
1331 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1334 mutex_lock(&camera_lock);
1341 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1343 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1344 pcdev->active = NULL;
1346 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1347 pcdev->zoominfo.zoom_rate = 100;
1348 pcdev->fps_timer.istarted = false;
1350 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1351 * if app havn't dequeue all videobuf before close camera device;
1353 INIT_LIST_HEAD(&pcdev->capture);
1355 ret = rk_camera_activate(pcdev,icd);
1358 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1359 if (control) { //TRUE in open ,FALSE in kernel start
1360 sd = dev_get_drvdata(control);
1361 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1363 ret = v4l2_subdev_call(sd,core, init, 0);
1367 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1368 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1369 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1371 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1374 mf.field = V4L2_FIELD_NONE;
1375 mf.code = xlate->code;
1376 mf.reserved[6] = 0xfefe5a5a;
1377 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1379 pcdev->cropinfo.bounds.left = 0;
1380 pcdev->cropinfo.bounds.top = 0;
1381 pcdev->cropinfo.bounds.width = mf.width;
1382 pcdev->cropinfo.bounds.height = mf.height;
1386 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1388 pcdev->icd_init = 0;
1391 for (i=0; i<2; i++) {
1392 if (pcdev->icd_frmival[i].icd == icd)
1394 if (pcdev->icd_frmival[i].icd == NULL) {
1395 pcdev->icd_frmival[i].icd = icd;
1399 if (icd_catch == 0) {
1400 fival_list = pcdev->icd_frmival[0].fival_list;
1401 fival_nxt = fival_list;
1402 while(fival_nxt != NULL) {
1403 fival_nxt = fival_list->nxt;
1405 fival_list = fival_nxt;
1407 pcdev->icd_frmival[0].icd = icd;
1408 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1411 mutex_unlock(&camera_lock);
1415 static void rk_camera_remove_device(struct soc_camera_device *icd)
1417 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1418 struct rk_camera_dev *pcdev = ici->priv;
1419 #if CAMERA_VIDEOBUF_ARM_ACCESS
1420 struct rk29_camera_vbinfo *vb_info;
1424 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1427 mutex_lock(&camera_lock);
1428 BUG_ON(icd != pcdev->icd);
1430 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1432 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1433 stream may be turn on again before close device, if suspend and resume happened. */
1434 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1435 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1436 rk_camera_s_stream(icd,0);
1438 /* move DEACTIVATE into generic_sensor_s_power*/
1439 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/
1440 /* if stream off is not been executed,timer is running.*/
1441 if(pcdev->fps_timer.istarted){
1442 hrtimer_cancel(&pcdev->fps_timer.timer);
1443 pcdev->fps_timer.istarted = false;
1445 flush_work(&(pcdev->camera_reinit_work.work));
1446 flush_workqueue((pcdev->camera_wq));
1448 if (pcdev->camera_work) {
1449 kfree(pcdev->camera_work);
1450 pcdev->camera_work = NULL;
1451 pcdev->camera_work_count = 0;
1452 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1454 rk_camera_deactivate(pcdev);
1455 #if CAMERA_VIDEOBUF_ARM_ACCESS
1456 if (pcdev->vbinfo) {
1457 vb_info = pcdev->vbinfo;
1458 for (i=0; i<pcdev->vbinfo_count; i++) {
1459 if (vb_info->vir_addr) {
1460 iounmap(vb_info->vir_addr);
1461 release_mem_region(vb_info->phy_addr, vb_info->size);
1462 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1466 kfree(pcdev->vbinfo);
1467 pcdev->vbinfo = NULL;
1468 pcdev->vbinfo_count = 0;
1471 pcdev->active = NULL;
1473 pcdev->icd_cb.sensor_cb = NULL;
1474 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1475 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1476 * if app havn't dequeue all videobuf before close camera device;
1478 INIT_LIST_HEAD(&pcdev->capture);
1480 mutex_unlock(&camera_lock);
1484 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1486 unsigned long bus_flags, camera_flags, common_flags = 0;
1487 unsigned int cif_for = 0;
1488 const struct soc_mbus_pixelfmt *fmt;
1490 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1491 struct rk_camera_dev *pcdev = ici->priv;
1493 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1496 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1500 bus_flags = RK_CAM_BUS_PARAM;
1501 /* If requested data width is supported by the platform, use it */
1502 switch (fmt->bits_per_sample) {
1504 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1508 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1512 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1518 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1519 if (icd->ops->query_bus_param)
1520 camera_flags = icd->ops->query_bus_param(icd);
1524 /**************yzm************
1525 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1526 if (!common_flags) {
1528 goto RK_CAMERA_SET_BUS_PARAM_END;
1531 /***************yzm************end*/
1534 common_flags = camera_flags;
1535 ret = icd->ops->set_bus_param(icd, common_flags);
1537 goto RK_CAMERA_SET_BUS_PARAM_END;
1539 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1541 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
1543 if(CHIP_NAME == 3368)
1544 rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1546 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1548 if(CHIP_NAME == 3368)
1549 rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1551 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1555 if(CHIP_NAME == 3368)
1556 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1558 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
1560 if(CHIP_NAME == 3368)
1561 rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1563 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1567 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1568 cif_for |= HSY_LOW_ACTIVE;
1570 cif_for &= ~HSY_LOW_ACTIVE;
1572 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1573 cif_for |= VSY_HIGH_ACTIVE;
1575 cif_for &= ~VSY_HIGH_ACTIVE;
1578 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1579 //vip_ctrl_val |= ENABLE_CAPTURE;
1580 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1581 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1583 RK_CAMERA_SET_BUS_PARAM_END:
1585 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1589 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1591 /* unsigned long bus_flags, camera_flags;*/
1594 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1595 /**********yzm***********
1597 bus_flags = RK_CAM_BUS_PARAM;
1598 if (icd->ops->query_bus_param) {
1599 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1603 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1606 dev_warn(icd->dev.parent,
1607 "Flags incompatible: camera %lx, host %lx\n",
1608 camera_flags, bus_flags);
1611 *///************yzm **************end
1616 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1618 .fourcc = V4L2_PIX_FMT_NV12,
1619 .name = "YUV420 NV12",
1620 .bits_per_sample = 8,
1621 .packing = SOC_MBUS_PACKING_1_5X8,
1622 .order = SOC_MBUS_ORDER_LE,
1624 .fourcc = V4L2_PIX_FMT_NV16,
1625 .name = "YUV422 NV16",
1626 .bits_per_sample = 8,
1627 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1628 .order = SOC_MBUS_ORDER_LE,
1630 .fourcc = V4L2_PIX_FMT_NV21,
1631 .name = "YUV420 NV21",
1632 .bits_per_sample = 8,
1633 .packing = SOC_MBUS_PACKING_1_5X8,
1634 .order = SOC_MBUS_ORDER_LE,
1636 .fourcc = V4L2_PIX_FMT_NV61,
1637 .name = "YUV422 NV61",
1638 .bits_per_sample = 8,
1639 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1640 .order = SOC_MBUS_ORDER_LE,
1642 .fourcc = V4L2_PIX_FMT_RGB565,
1644 .bits_per_sample = 8,
1645 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1646 .order = SOC_MBUS_ORDER_LE,
1648 .fourcc = V4L2_PIX_FMT_RGB24,
1650 .bits_per_sample = 8,
1651 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1652 .order = SOC_MBUS_ORDER_LE,
1657 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1659 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1660 struct rk_camera_dev *pcdev = ici->priv;
1661 unsigned int cif_fs = 0,cif_crop = 0;
1662 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;
1664 const struct soc_mbus_pixelfmt *fmt;
1665 fmt = soc_mbus_get_fmtdesc(icd_code);
1667 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1670 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1671 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1672 host_pixfmt = V4L2_PIX_FMT_NV12;
1673 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1674 host_pixfmt = V4L2_PIX_FMT_NV21;
1676 switch (host_pixfmt)
1678 case V4L2_PIX_FMT_NV16:
1679 cif_fmt_val &= ~YUV_OUTPUT_422;
1680 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1681 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1682 pcdev->pixfmt = host_pixfmt;
1684 case V4L2_PIX_FMT_NV61:
1685 cif_fmt_val &= ~YUV_OUTPUT_422;
1686 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1687 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1688 pcdev->pixfmt = host_pixfmt;
1690 case V4L2_PIX_FMT_NV12:
1691 cif_fmt_val |= YUV_OUTPUT_420;
1692 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1693 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1694 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1695 pcdev->pixfmt = host_pixfmt;
1697 case V4L2_PIX_FMT_NV21:
1698 cif_fmt_val |= YUV_OUTPUT_420;
1699 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1700 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1701 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1702 pcdev->pixfmt = host_pixfmt;
1704 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1705 cif_fmt_val |= YUV_OUTPUT_422;
1710 case V4L2_MBUS_FMT_UYVY8_2X8:
1711 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1713 case V4L2_MBUS_FMT_YUYV8_2X8:
1714 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1716 case V4L2_MBUS_FMT_YVYU8_2X8:
1717 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1719 case V4L2_MBUS_FMT_VYUY8_2X8:
1720 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1723 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1728 rk_camera_cif_reset(pcdev,true);
1730 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1731 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1733 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 */
1735 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1736 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1737 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1739 } else{ /* this is one frame mode*/
1740 cif_crop = (rect->left + (rect->top <<16));
1741 cif_fs = (rect->width + (rect->height <<16));
1744 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1745 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1746 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1747 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1749 /*MUST bypass scale */
1750 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1751 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);
1755 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1756 struct soc_camera_format_xlate *xlate)
1758 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1759 struct device *dev = icd->parent;
1760 int formats = 0, ret;
1761 enum v4l2_mbus_pixelcode code;
1762 const struct soc_mbus_pixelfmt *fmt;
1764 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1767 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1769 /* No more formats */
1772 fmt = soc_mbus_get_fmtdesc(code);
1774 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1778 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1783 case V4L2_MBUS_FMT_UYVY8_2X8:
1784 case V4L2_MBUS_FMT_YUYV8_2X8:
1785 case V4L2_MBUS_FMT_YVYU8_2X8:
1786 case V4L2_MBUS_FMT_VYUY8_2X8:
1789 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1792 xlate->host_fmt = &rk_camera_formats[0];
1795 dev_dbg(dev, "Providing format %s using code %d\n",
1796 rk_camera_formats[0].name,code);
1801 xlate->host_fmt = &rk_camera_formats[1];
1804 dev_dbg(dev, "Providing format %s using code %d\n",
1805 rk_camera_formats[1].name,code);
1810 xlate->host_fmt = &rk_camera_formats[2];
1813 dev_dbg(dev, "Providing format %s using code %d\n",
1814 rk_camera_formats[2].name,code);
1819 xlate->host_fmt = &rk_camera_formats[3];
1822 dev_dbg(dev, "Providing format %s using code %d\n",
1823 rk_camera_formats[3].name,code);
1829 xlate->host_fmt = &rk_camera_formats[4];
1832 dev_dbg(dev, "Providing format %s using code %d\n",
1833 rk_camera_formats[4].name,code);
1837 xlate->host_fmt = &rk_camera_formats[5];
1840 dev_dbg(dev, "Providing format %s using code %d\n",
1841 rk_camera_formats[5].name,code);
1853 static void rk_camera_put_formats(struct soc_camera_device *icd)
1856 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1860 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1862 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1865 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1867 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1870 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1871 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1875 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1877 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1878 struct rk_camera_dev *pcdev = ici->priv;
1880 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1883 spin_lock(&pcdev->cropinfo.lock);
1884 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1885 spin_unlock(&pcdev->cropinfo.lock);
1889 static int rk_camera_set_crop(struct soc_camera_device *icd,
1890 const struct v4l2_crop *crop)
1892 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1893 struct rk_camera_dev *pcdev = ici->priv;
1895 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1898 spin_lock(&pcdev->cropinfo.lock);
1899 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1900 spin_unlock(&pcdev->cropinfo.lock);
1903 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1907 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1910 if (f->fmt.pix.priv == 0xfefe5a5a) {
1914 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1916 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1918 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1920 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1922 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1924 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1929 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1932 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1933 struct v4l2_format *f)
1935 struct device *dev = icd->parent;
1936 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1937 const struct soc_camera_format_xlate *xlate = NULL;
1938 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1939 struct rk_camera_dev *pcdev = ici->priv;
1940 struct v4l2_pix_format *pix = &f->fmt.pix;
1941 struct v4l2_mbus_framefmt mf;
1942 struct v4l2_rect rect;
1943 int ret,usr_w,usr_h,sensor_w,sensor_h;
1945 int ratio, bounds_aspect;
1947 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1951 usr_h = pix->height;
1953 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
1954 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1956 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1958 goto RK_CAMERA_SET_FMT_END;
1961 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1962 if (pcdev->icd_init == 0) {
1963 v4l2_subdev_call(sd,core, init, 0);
1964 pcdev->icd_init = 1;
1967 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1968 if (stream_on & ENABLE_CAPTURE)
1969 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1971 mf.width = pix->width;
1972 mf.height = pix->height;
1973 mf.field = pix->field;
1974 mf.colorspace = pix->colorspace;
1975 mf.code = xlate->code;
1976 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
1979 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1980 if (mf.code != xlate->code)
1983 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
1984 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
1985 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
1986 if ((mf.width*10/mf.height) != bounds_aspect) {
1987 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
1988 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
1990 mf.width = pcdev->cropinfo.bounds.width/4;
1991 mf.height = pcdev->cropinfo.bounds.height/4;
1993 mf.field = pix->field;
1994 mf.colorspace = pix->colorspace;
1995 mf.code = xlate->code;
1996 mf.reserved[0] = pix->priv;
1999 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2000 if (mf.code != xlate->code)
2005 sensor_w = mf.width;
2006 sensor_h = mf.height;
2008 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
2011 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
2014 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2016 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
2017 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
2019 goto RK_CAMERA_SET_FMT_END;
2021 if (unlikely((usr_w <16)||(usr_h < 16))) {
2022 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2024 goto RK_CAMERA_SET_FMT_END;
2027 spin_lock(&pcdev->cropinfo.lock);
2028 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
2029 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2030 /*Scale + Crop center is for keep aspect ratio unchange*/
2031 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
2032 pcdev->host_width = ratio*usr_w/10;
2033 pcdev->host_height = ratio*usr_h/10;
2034 pcdev->host_width &= ~CROP_ALIGN_BYTES;
2035 pcdev->host_height &= ~CROP_ALIGN_BYTES;
2037 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
2038 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
2040 /*Scale + crop(user define)*/
2041 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2042 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2043 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2044 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2047 pcdev->host_left &= (~0x01);
2048 pcdev->host_top &= (~0x01);
2050 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2051 /*Crop Center for cif can work , then scale*/
2052 pcdev->host_width = mf.width;
2053 pcdev->host_height = mf.height;
2054 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2055 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2057 /*Crop center for cif can work + crop(user define), then scale */
2058 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2059 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2060 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2061 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2064 pcdev->host_left &= (~0x01);
2065 pcdev->host_top &= (~0x01);
2067 spin_unlock(&pcdev->cropinfo.lock);
2069 spin_lock(&pcdev->cropinfo.lock);
2070 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2071 pcdev->host_width = mf.width;
2072 pcdev->host_height = mf.height;
2073 pcdev->host_left = 0;
2074 pcdev->host_top = 0;
2076 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2077 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2078 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2079 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2081 spin_unlock(&pcdev->cropinfo.lock);
2086 rect.width = pcdev->host_width;
2087 rect.height = pcdev->host_height;
2088 rect.left = pcdev->host_left;
2089 rect.top = pcdev->host_top;
2091 down(&pcdev->zoominfo.sem);
2092 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2093 pcdev->zoominfo.a.c.left = 0;
2094 pcdev->zoominfo.a.c.top = 0;
2095 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2096 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2097 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2098 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2099 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2100 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2101 /*recalculate the CIF width & height*/
2102 rect.width = pcdev->zoominfo.a.c.width ;
2103 rect.height = pcdev->zoominfo.a.c.height;
2104 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2105 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2107 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2108 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2109 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2110 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2111 /*now digital zoom use ipp to do crop and scale*/
2112 if(pcdev->zoominfo.zoom_rate != 100){
2113 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2114 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2116 pcdev->zoominfo.a.c.left = 0;
2117 pcdev->zoominfo.a.c.top = 0;
2119 pcdev->zoominfo.vir_width = pcdev->host_width;
2120 pcdev->zoominfo.vir_height = pcdev->host_height;
2122 up(&pcdev->zoominfo.sem);
2124 /* ddl@rock-chips.com: IPP work limit check */
2125 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2126 if (usr_w > 0x7f0) {
2127 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2128 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));
2130 goto RK_CAMERA_SET_FMT_END;
2133 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2134 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2136 goto RK_CAMERA_SET_FMT_END;
2141 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,
2142 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2143 sensor_w,sensor_h,mf.width,mf.height,
2144 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2145 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2146 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2147 pix->width, pix->height);
2149 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2151 if (CAM_IPPWORK_IS_EN()) {
2152 BUG_ON(pcdev->vipmem_phybase == 0);
2155 pix->height = usr_h;
2156 pix->field = mf.field;
2157 pix->colorspace = mf.colorspace;
2158 icd->current_fmt = xlate;
2159 pcdev->icd_width = mf.width;
2160 pcdev->icd_height = mf.height;
2163 RK_CAMERA_SET_FMT_END:
2164 if (stream_on & ENABLE_CAPTURE)
2165 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2167 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2171 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2172 struct v4l2_format *f)
2174 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2175 struct rk_camera_dev *pcdev = ici->priv;
2176 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2177 const struct soc_camera_format_xlate *xlate;
2178 struct v4l2_pix_format *pix = &f->fmt.pix;
2179 __u32 pixfmt = pix->pixelformat;
2180 int ret,usr_w,usr_h,i;
2181 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2182 bool vipmem_is_overflow = false;
2183 struct v4l2_mbus_framefmt mf;
2184 int bytes_per_line_host;
2187 usr_h = pix->height;
2189 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2191 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2193 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2194 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2195 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2197 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2198 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2199 for (i = 0; i < icd->num_user_formats; i++)
2200 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2201 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2202 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2203 icd->user_formats[i].host_fmt->name);
2204 goto RK_CAMERA_TRY_FMT_END;
2206 /* limit to rk29 hardware capabilities */
2207 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2208 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2209 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2211 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2213 if (pix->bytesperline < 0)
2214 return pix->bytesperline;
2216 /* limit to sensor capabilities */
2217 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2218 mf.width = pix->width;
2219 mf.height = pix->height;
2220 mf.field = pix->field;
2221 mf.colorspace = pix->colorspace;
2222 mf.code = xlate->code;
2223 /* ddl@rock-chips.com : It is query max resolution only. */
2224 if ((usr_w == 10000) && (usr_h == 10000)) {
2225 mf.reserved[6] = 0xfefe5a5a;
2227 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2229 goto RK_CAMERA_TRY_FMT_END;
2231 /*query resolution.*/
2232 if((usr_w == 10000) && (usr_h == 10000)) {
2233 pix->width = mf.width;
2234 pix->height = mf.height;
2235 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2236 goto RK_CAMERA_TRY_FMT_END;
2238 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2241 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2242 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2244 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2246 /* Assume preview buffer minimum is 4 */
2247 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2249 if (vipmem_is_overflow == false) {
2251 pix->height = usr_h;
2253 /*RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);*/
2254 pix->width = mf.width;
2255 pix->height = mf.height;
2257 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2259 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2260 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2261 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2262 pix->width = mf.width;
2263 pix->height = mf.height;
2269 pix->colorspace = mf.colorspace;
2272 case V4L2_FIELD_ANY:
2273 case V4L2_FIELD_NONE:
2274 pix->field = V4L2_FIELD_NONE;
2277 /* TODO: support interlaced at least in pass-through mode */
2278 dev_err(icd->parent, "Field type %d unsupported.\n",
2280 goto RK_CAMERA_TRY_FMT_END;
2283 RK_CAMERA_TRY_FMT_END:
2285 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2289 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2290 struct v4l2_requestbuffers *p)
2294 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2297 /* This is for locking debugging only. I removed spinlocks and now I
2298 * check whether .prepare is ever called on a linked buffer, or whether
2299 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2300 * it hadn't triggered */
2301 for (i = 0; i < p->count; i++) {
2302 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2303 struct rk_camera_buffer, vb);
2305 INIT_LIST_HEAD(&buf->vb.queue);
2311 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2313 struct soc_camera_device *icd = file->private_data;
2314 struct rk_camera_buffer *buf;
2316 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2319 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2322 poll_wait(file, &buf->vb.done, pt);
2324 if (buf->vb.state == VIDEOBUF_DONE ||
2325 buf->vb.state == VIDEOBUF_ERROR)
2326 return POLLIN|POLLRDNORM;
2331 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2332 * 10 5 1 3 3 3 + 5 < 32
2335 static int rk_camera_querycap(struct soc_camera_host *ici,
2336 struct v4l2_capability *cap)
2338 struct rk_camera_dev *pcdev = ici->priv;
2339 struct rkcamera_platform_data *new_camera;
2340 char orientation[5];
2344 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2347 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2348 memset(orientation,0x00,sizeof(orientation));
2351 new_camera = pcdev->pdata->register_dev_new;
2352 while(new_camera != NULL){
2353 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2354 sprintf(orientation,"-%d",new_camera->orientation);
2355 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2357 new_camera = new_camera->next_camera;
2360 if (orientation[0] != '-') {
2361 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2362 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2363 strcat(cap->card,"-270");
2365 strcat(cap->card,"-90");
2367 strcat(cap->card,orientation);
2370 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2371 cap->version = RK_CAM_VERSION_CODE;
2372 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2373 cap->reserved[0] = pcdev->pdata->iommu_enabled;
2374 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2378 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2380 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2381 struct rk_camera_dev *pcdev = ici->priv;
2382 struct v4l2_subdev *sd;
2385 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2388 mutex_lock(&camera_lock);
2389 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2390 rk_camera_s_stream(icd, 0);
2391 sd = soc_camera_to_subdev(icd);
2392 v4l2_subdev_call(sd, video, s_stream, 0);
2393 ret = icd->ops->suspend(icd, state);
2395 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2396 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2397 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2398 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2399 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2400 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2401 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2403 pcdev->reginfo_suspend.Inval = Reg_Validate;
2404 rk_camera_deactivate(pcdev);
2406 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2408 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2410 mutex_unlock(&camera_lock);
2414 static int rk_camera_resume(struct soc_camera_device *icd)
2416 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2417 struct rk_camera_dev *pcdev = ici->priv;
2418 struct v4l2_subdev *sd;
2421 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2424 mutex_lock(&camera_lock);
2425 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2426 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2427 rk_camera_activate(pcdev, icd);
2428 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2429 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2430 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2431 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2432 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2433 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2434 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2435 rk_videobuf_capture(pcdev->active,pcdev);
2436 rk_camera_s_stream(icd, 1);
2437 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2439 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2440 goto rk_camera_resume_end;
2443 ret = icd->ops->resume(icd);
2444 sd = soc_camera_to_subdev(icd);
2445 v4l2_subdev_call(sd, video, s_stream, 1);
2447 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2449 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2452 rk_camera_resume_end:
2453 mutex_unlock(&camera_lock);
2457 static void rk_camera_reinit_work(struct work_struct *work)
2459 struct v4l2_subdev *sd;
2460 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2461 struct rk_camera_dev *pcdev = camera_work->pcdev;
2462 struct v4l2_mbus_framefmt mf;
2464 unsigned long flags = 0;
2467 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2470 if(pcdev->icd == NULL)
2472 sd = soc_camera_to_subdev(pcdev->icd);
2475 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2476 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2477 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2478 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2479 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2480 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2481 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2482 if(CHIP_NAME == 3368)
2483 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",rk3368_read_cru_reg(CRU_PCLK_REG30));
2485 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2486 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2488 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2489 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2490 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2491 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2492 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2493 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2494 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2495 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2496 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2499 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2500 if (pcdev->reinit_times == 1) {
2501 if (ctrl & ENABLE_CAPTURE) {
2502 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2503 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2504 rk_camera_cif_reset(pcdev,false);
2507 v4l2_subdev_call(sd,core, init, 0);
2509 mf.width = pcdev->icd_width;
2510 mf.height = pcdev->icd_height;
2511 mf.field = V4L2_FIELD_NONE;
2512 mf.code = pcdev->icd->current_fmt->code;
2513 mf.reserved[0] = 0x5a5afefe;
2516 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2518 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2519 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2520 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2521 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2522 rk_camera_cif_reset(pcdev,false);
2523 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2528 atomic_set(&pcdev->stop_cif,true);
2529 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2530 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2532 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2533 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2534 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2535 if (NULL == pcdev->video_vq->bufs[index])
2538 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2539 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2540 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2541 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2542 printk("wake up video buffer index = %d !!!\n",index);
2545 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2547 RKCAMERA_TR("video queue has somthing wrong !!\n");
2550 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2552 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2554 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2555 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2556 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2559 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2561 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2562 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2563 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2564 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2565 pcdev->camera_reinit_work.pcdev = pcdev;
2566 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2567 pcdev->reinit_times++;
2568 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2569 } else if(!pcdev->timer_get_fps) {
2570 pcdev->timer_get_fps = true;
2571 for (i=0; i<2; i++) {
2572 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2573 fival_nxt = pcdev->icd_frmival[i].fival_list;
2578 fival_pre = fival_nxt;
2579 while (fival_nxt != NULL) {
2581 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control),
2582 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2583 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2584 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2585 fival_nxt->fival.discrete.numerator);
2587 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2588 && (fival_nxt->fival.height == pcdev->icd->user_height)
2589 && (fival_nxt->fival.width == pcdev->icd->user_width))
2590 || (fival_nxt->fival.discrete.denominator == 0)) {
2592 if (fival_nxt->fival.discrete.denominator == 0) {
2593 fival_nxt->fival.index = 0;
2594 fival_nxt->fival.width = pcdev->icd->user_width;
2595 fival_nxt->fival.height= pcdev->icd->user_height;
2596 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2597 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2598 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2599 |(pcdev->icd_height);
2600 fival_nxt->fival.discrete.numerator = 1000000;
2601 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2604 fival_rec = fival_nxt;
2606 fival_pre = fival_nxt;
2607 fival_nxt = fival_nxt->nxt;
2610 if ((rec_flag == 0) && fival_pre) {
2611 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2612 if (fival_pre->nxt != NULL) {
2613 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2614 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2615 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2616 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2618 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2619 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2620 |(pcdev->icd_height);
2621 fival_pre->nxt->fival.discrete.numerator = 1000000;
2622 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2624 fival_rec = fival_pre->nxt;
2629 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2630 pcdev->reinit_times = 0;
2632 pcdev->last_fps = pcdev->fps ;
2633 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2634 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2635 /*return HRTIMER_NORESTART;*/
2636 if(pcdev->reinit_times >=2)
2637 return HRTIMER_NORESTART;
2639 return HRTIMER_RESTART;
2641 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2643 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2644 struct rk_camera_dev *pcdev = ici->priv;
2647 unsigned long flags;
2649 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2651 WARN_ON(pcdev->icd != icd);
2653 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2656 pcdev->last_fps = 0;
2657 pcdev->frame_interval = 0;
2658 hrtimer_cancel(&(pcdev->fps_timer.timer));
2659 pcdev->fps_timer.pcdev = pcdev;
2660 pcdev->timer_get_fps = false;
2661 pcdev->reinit_times = 0;
2663 spin_lock_irqsave(&pcdev->lock,flags);
2664 atomic_set(&pcdev->stop_cif,false);
2665 pcdev->cif_stopped = false;
2666 pcdev->irqinfo.cifirq_idx = 0;
2667 pcdev->irqinfo.cifirq_normal_idx = 0;
2668 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2669 pcdev->irqinfo.dmairq_idx = 0;
2671 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2672 cif_ctrl_val |= ENABLE_CAPTURE;
2673 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2674 spin_unlock_irqrestore(&pcdev->lock,flags);
2675 printk("%s:stream enable CIF_CIF_CTRL 0x%x\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2676 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2677 pcdev->fps_timer.istarted = true;
2679 /*cancel timer before stop cif*/
2680 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2681 pcdev->fps_timer.istarted = false;
2682 flush_work(&(pcdev->camera_reinit_work.work));
2684 cif_ctrl_val &= ~ENABLE_CAPTURE;
2685 spin_lock_irqsave(&pcdev->lock, flags);
2686 //write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2687 atomic_set(&pcdev->stop_cif,true);
2688 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2689 spin_unlock_irqrestore(&pcdev->lock, flags);
2691 init_waitqueue_head(&pcdev->cif_stop_done);
2692 if (wait_event_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(1000)) == 0) {
2693 RKCAMERA_TR("%s:%d, wait cif stop timeout!",__func__,__LINE__);
2694 pcdev->cif_stopped = true;
2697 flush_workqueue((pcdev->camera_wq));
2700 /*must be reinit,or will be somthing wrong in irq process.*/
2701 if(enable == false) {
2702 pcdev->active = NULL;
2703 INIT_LIST_HEAD(&pcdev->capture);
2705 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2708 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2710 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2711 struct rk_camera_dev *pcdev = ici->priv;
2712 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2713 struct rk_camera_frmivalenum *fival_list = NULL;
2714 struct v4l2_frmivalenum *fival_head = NULL;
2715 struct rkcamera_platform_data *new_camera;
2716 int i,ret = 0,index;
2717 const struct soc_camera_format_xlate *xlate;
2718 struct v4l2_mbus_framefmt mf;
2721 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2723 index = fival->index & 0x00ffffff;
2724 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2725 for (i=0; i<2; i++) {
2726 if (pcdev->icd_frmival[i].icd == icd) {
2727 fival_list = pcdev->icd_frmival[i].fival_list;
2731 if (fival_list != NULL) {
2733 while (fival_list != NULL) {
2734 if ((fival->pixel_format == fival_list->fival.pixel_format)
2735 && (fival->height == fival_list->fival.height)
2736 && (fival->width == fival_list->fival.width)) {
2741 fival_list = fival_list->nxt;
2744 if ((i==index) && (fival_list != NULL)) {
2745 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2750 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2757 while (fival_head->width && fival_head->height) {
2758 if ((fival->pixel_format == fival_head->pixel_format)
2759 && (fival->height == fival_head->height)
2760 && (fival->width == fival_head->width)) {
2769 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2770 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2772 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2773 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2774 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2775 mf.width = fival->width;
2776 mf.height = fival->height;
2777 mf.code = xlate->code;
2779 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2781 fival->reserved[1] = (mf.width<<16)|(mf.height);
2783 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2784 fival->width, fival->height,
2785 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2786 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2787 fival->discrete.denominator,fival->discrete.numerator);
2790 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2791 fival->width,fival->height,
2792 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2793 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2796 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2797 fival->width,fival->height,
2798 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2799 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2802 goto rk_camera_enum_frameintervals_end;
2806 new_camera = pcdev->pdata->register_dev_new;
2807 while(new_camera != NULL){
2808 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2812 new_camera = new_camera->next_camera;
2816 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2817 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2820 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2821 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2822 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2823 mf.width = fival->width;
2824 mf.height = fival->height;
2825 mf.code = xlate->code;
2827 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2829 fival->discrete.numerator= 1000;
2830 fival->discrete.denominator = 15000;
2831 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2832 fival->reserved[1] = (mf.width<<16)|(mf.height);
2836 rk_camera_enum_frameintervals_end:
2840 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2841 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2844 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2845 struct rk_camera_dev *pcdev = ici->priv;
2847 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2851 unsigned long tmp_cifctrl;
2854 /*change the crop and scale parameters*/
2857 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2858 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2859 a.c.width = pcdev->host_width*100/zoom_rate;
2860 a.c.width &= ~CROP_ALIGN_BYTES;
2861 a.c.height = pcdev->host_height*100/zoom_rate;
2862 a.c.height &= ~CROP_ALIGN_BYTES;
2863 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2864 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2865 atomic_set(&pcdev->stop_cif,true);
2866 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2867 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2868 hrtimer_cancel(&(pcdev->fps_timer.timer));
2869 flush_workqueue((pcdev->camera_wq));
2871 down(&pcdev->zoominfo.sem);
2872 pcdev->zoominfo.a.c.left = 0;
2873 pcdev->zoominfo.a.c.top = 0;
2874 pcdev->zoominfo.a.c.width = a.c.width;
2875 pcdev->zoominfo.a.c.height = a.c.height;
2876 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2877 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2878 pcdev->frame_inval = 1;
2879 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2880 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2881 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2882 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2884 rk_videobuf_capture(pcdev->active,pcdev);
2885 if(tmp_cifctrl & ENABLE_CAPTURE)
2886 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2887 up(&pcdev->zoominfo.sem);
2889 atomic_set(&pcdev->stop_cif,false);
2890 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2891 RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2893 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2894 a.c.width = pcdev->host_width*100/zoom_rate;
2895 a.c.width &= ~CROP_ALIGN_BYTES;
2896 a.c.height = pcdev->host_height*100/zoom_rate;
2897 a.c.height &= ~CROP_ALIGN_BYTES;
2898 a.c.left = (pcdev->host_width - a.c.width)>>1;
2899 a.c.top = (pcdev->host_height - a.c.height)>>1;
2901 down(&pcdev->zoominfo.sem);
2902 pcdev->zoominfo.a.c.height = a.c.height;
2903 pcdev->zoominfo.a.c.width = a.c.width;
2904 pcdev->zoominfo.a.c.top = a.c.top;
2905 pcdev->zoominfo.a.c.left = a.c.left;
2906 pcdev->zoominfo.vir_width = pcdev->host_width;
2907 pcdev->zoominfo.vir_height= pcdev->host_height;
2908 up(&pcdev->zoominfo.sem);
2910 RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2916 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2917 struct soc_camera_host_ops *ops, int id)
2921 for (i = 0; i < ops->num_controls; i++)
2922 if (ops->controls[i].id == id)
2923 return &ops->controls[i];
2929 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2930 struct v4l2_control *sctrl)
2932 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
2933 const struct v4l2_queryctrl *qctrl;
2934 struct rk_camera_dev *pcdev = ici->priv;
2938 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2940 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2943 goto rk_camera_set_ctrl_end;
2948 case V4L2_CID_ZOOM_ABSOLUTE:
2950 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2952 goto rk_camera_set_ctrl_end;
2954 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2956 pcdev->zoominfo.zoom_rate = sctrl->value;
2958 goto rk_camera_set_ctrl_end;
2966 rk_camera_set_ctrl_end:
2970 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2972 .owner = THIS_MODULE,
2973 .add = rk_camera_add_device,
2974 .remove = rk_camera_remove_device,
2975 .suspend = rk_camera_suspend,
2976 .resume = rk_camera_resume,
2977 .enum_frameinervals = rk_camera_enum_frameintervals,
2978 .cropcap = rk_camera_cropcap,
2979 .set_crop = rk_camera_set_crop,
2980 .get_crop = rk_camera_get_crop,
2981 .get_formats = rk_camera_get_formats,
2982 .put_formats = rk_camera_put_formats,
2983 .set_fmt = rk_camera_set_fmt,
2984 .try_fmt = rk_camera_try_fmt,
2985 .init_videobuf = rk_camera_init_videobuf,
2986 .reqbufs = rk_camera_reqbufs,
2987 .poll = rk_camera_poll,
2988 .querycap = rk_camera_querycap,
2989 .set_bus_param = rk_camera_set_bus_param,
2990 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2991 .set_ctrl = rk_camera_set_ctrl,
2992 .controls = rk_camera_controls,
2993 .num_controls = ARRAY_SIZE(rk_camera_controls)
2996 static int rk_camera_cif_iomux(struct device *dev)
2999 struct pinctrl *pinctrl;
3000 struct pinctrl_state *state;
3002 char state_str[20] = {0};
3004 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3005 strcpy(state_str,"cif_pin_all");
3007 if(CHIP_NAME == 3288){
3008 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
3009 }else if(CHIP_NAME == 3368){
3010 //__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0900);
3011 __raw_writel(((1<<1)|(1<<(1+16))),rk_cif_grf_base+0x0900);
3016 pinctrl = devm_pinctrl_get(dev);
3017 if (IS_ERR(pinctrl)) {
3018 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
3021 state = pinctrl_lookup_state(pinctrl,
3024 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
3028 if (!IS_ERR(state)) {
3029 retval = pinctrl_select_state(pinctrl, state);
3032 "%s:could not set %s pins\n",__func__,state_str);
3040 static int rk_camera_probe(struct platform_device *pdev)
3042 struct rk_camera_dev *pcdev;
3043 struct resource *res;
3044 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3047 struct rk_cif_clk *clk=NULL;
3048 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;
3050 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3052 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
3053 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
3055 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
3056 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
3060 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
3061 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3065 rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
3067 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3068 irq = platform_get_irq(pdev, 0);
3070 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3071 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3072 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3074 if (!res || irq < 0) {
3078 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3080 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3085 pcdev->zoominfo.zoom_rate = 100;
3086 pcdev->hostid = pdev->id; /* get host id*/
3087 #ifdef CONFIG_SOC_RK3028
3088 pcdev->chip_id = rk3028_version_val();
3090 pcdev->chip_id = -1;
3094 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3096 if(CHIP_NAME != 3368)
3097 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3099 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3100 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3101 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3102 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3103 //spin_lock_init(&cif_clk[0].lock);
3104 cif_clk[0].on = false;
3105 rk_camera_cif_iomux(dev_cif);
3108 if(CHIP_NAME != 3368)
3109 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only */
3111 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3112 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3113 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3114 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3115 //spin_lock_init(&cif_clk[1].lock);
3116 cif_clk[1].on = false;
3117 rk_camera_cif_iomux(dev_cif);
3120 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3122 dev_set_drvdata(&pdev->dev, pcdev);
3124 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3125 if (pcdev->pdata && pcdev->pdata->io_init) {
3127 pcdev->pdata->io_init();
3129 if (pcdev->pdata->sensor_mclk == NULL)
3130 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3133 INIT_LIST_HEAD(&pcdev->capture);
3134 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3135 spin_lock_init(&pcdev->lock);
3136 spin_lock_init(&pcdev->camera_work_lock);
3138 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3139 spin_lock_init(&pcdev->cropinfo.lock);
3140 sema_init(&pcdev->zoominfo.sem,1);
3143 * Request the regions.
3146 if (!request_mem_region(res->start, res->end - res->start + 1,
3147 RK29_CAM_DRV_NAME)) {
3149 goto exit_reqmem_vip;
3151 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3152 if (pcdev->base == NULL) {
3153 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3155 goto exit_ioremap_vip;
3159 pcdev->irqinfo.irq = irq;
3160 pcdev->dev = &pdev->dev;
3162 /* config buffer address */
3165 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, IRQF_DISABLED | IRQF_SHARED , RK29_CAM_DRV_NAME,
3168 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3174 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3176 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3178 if (pcdev->camera_wq == NULL) {
3179 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3183 pcdev->camera_reinit_work.pcdev = pcdev;
3184 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3186 for (i=0; i<2; i++) {
3187 pcdev->icd_frmival[i].icd = NULL;
3188 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3191 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3192 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3193 pcdev->soc_host.priv = pcdev;
3194 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3195 pcdev->soc_host.nr = pdev->id;
3196 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3197 err = soc_camera_host_register(&pcdev->soc_host);
3201 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3204 pcdev->fps_timer.pcdev = pcdev;
3205 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3206 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3207 pcdev->icd_cb.sensor_cb = NULL;
3209 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3210 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3211 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3212 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3213 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3214 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3215 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3216 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3222 for (i=0; i<2; i++) {
3223 fival_list = pcdev->icd_frmival[i].fival_list;
3224 fival_nxt = fival_list;
3225 while(fival_nxt != NULL) {
3226 fival_nxt = fival_list->nxt;
3228 fival_list = fival_nxt;
3232 free_irq(pcdev->irqinfo.irq, pcdev);
3233 if (pcdev->camera_wq) {
3234 destroy_workqueue(pcdev->camera_wq);
3235 pcdev->camera_wq = NULL;
3238 iounmap(pcdev->base);
3240 release_mem_region(res->start, res->end - res->start + 1);
3243 if(CHIP_NAME != 3368){
3245 clk_put(clk->pd_cif);
3248 clk_put(clk->aclk_cif);
3250 clk_put(clk->hclk_cif);
3251 if (clk->cif_clk_in)
3252 clk_put(clk->cif_clk_in);
3253 if (clk->cif_clk_out)
3254 clk_put(clk->cif_clk_out);
3263 static int rk_camera_remove(struct platform_device *pdev)
3265 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3266 struct resource *res;
3267 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3270 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3273 free_irq(pcdev->irqinfo.irq, pcdev);
3275 if (pcdev->camera_wq) {
3276 destroy_workqueue(pcdev->camera_wq);
3277 pcdev->camera_wq = NULL;
3280 for (i=0; i<2; i++) {
3281 fival_list = pcdev->icd_frmival[i].fival_list;
3282 fival_nxt = fival_list;
3283 while(fival_nxt != NULL) {
3284 fival_nxt = fival_list->nxt;
3286 fival_list = fival_nxt;
3290 soc_camera_host_unregister(&pcdev->soc_host);
3293 iounmap((void __iomem*)pcdev->base);
3294 release_mem_region(res->start, res->end - res->start + 1);
3295 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3296 pcdev->pdata->io_deinit(0);
3297 pcdev->pdata->io_deinit(1);
3302 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3307 static struct platform_driver rk_camera_driver =
3310 .name = RK29_CAM_DRV_NAME, /*host */
3312 .probe = rk_camera_probe,
3313 .remove = (rk_camera_remove),
3316 static int rk_camera_init_async(void *unused)
3319 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3320 platform_driver_register(&rk_camera_driver);
3324 static int __init rk_camera_init(void)
3327 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3329 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3334 static void __exit rk_camera_exit(void)
3336 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3338 platform_driver_unregister(&rk_camera_driver);
3341 device_initcall_sync(rk_camera_init);
3342 module_exit(rk_camera_exit);
3344 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3345 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3346 MODULE_LICENSE("GPL");