1 /************yzm************
2 #if (defined(CONFIG_ARCH_RK2928) ||\
3 defined(CONFIG_ARCH_RK30) ||\
4 defined(CONFIG_ARCH_RK3188) ||\
5 defined(CONFIG_ARCH_RK3026))
7 #include <linux/init.h>
8 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include <linux/slab.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/errno.h>
15 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
18 #include <linux/moduleparam.h>
19 #include <linux/time.h>
20 #include <linux/clk.h>
21 #include <linux/version.h>
22 #include <linux/device.h>
23 #include <linux/platform_device.h>
24 #include <linux/mutex.h>
25 #include <linux/videodev2.h>
26 #include <linux/kthread.h>
28 #include <media/v4l2-common.h>
29 #include <media/v4l2-dev.h>
30 #include <media/videobuf-dma-contig.h>
31 #include <media/soc_camera.h>
32 #include <media/soc_mediabus.h>
33 #include <media/videobuf-core.h>
34 #include <linux/rockchip/iomap.h>
36 #include "../../video/rockchip/rga/rga.h"
37 #include "../../../arch/arm/mach-rockchip/rk30_camera.h"/*yzm*/
38 #include <linux/rockchip/cru.h>
42 #include <plat/efuse.h>
43 #if (defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026))
44 #include <mach/rk2928_camera.h>
47 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
50 #include <asm/cacheflush.h>
52 #include <linux/of_address.h>
53 #include <linux/of_platform.h>
54 #include <linux/of_fdt.h>
55 #include <media/soc_camera.h>
56 #include <media/camsys_head.h>
58 #include <linux/of_irq.h>
61 module_param(debug, int, S_IRUGO|S_IWUSR);
63 #define CAMMODULE_NAME "rk_cam_cif"
65 #define wprintk(level, fmt, arg...) do { \
67 printk(KERN_WARNING "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
69 #define dprintk(level, fmt, arg...) do { \
71 printk(KERN_DEBUG "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
73 #define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
74 #define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
75 #define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
76 #define debug_printk(format, ...) dprintk(3, format, ## __VA_ARGS__)
78 #define RK30_CRU_BASE 0x00 /*yzm*/
81 #define CIF_CIF_CTRL 0x00
82 #define CIF_CIF_INTEN 0x04
83 #define CIF_CIF_INTSTAT 0x08
84 #define CIF_CIF_FOR 0x0c
85 #define CIF_CIF_LINE_NUM_ADDR 0x10
86 #define CIF_CIF_FRM0_ADDR_Y 0x14
87 #define CIF_CIF_FRM0_ADDR_UV 0x18
88 #define CIF_CIF_FRM1_ADDR_Y 0x1c
89 #define CIF_CIF_FRM1_ADDR_UV 0x20
90 #define CIF_CIF_VIR_LINE_WIDTH 0x24
91 #define CIF_CIF_SET_SIZE 0x28
92 #define CIF_CIF_SCM_ADDR_Y 0x2c
93 #define CIF_CIF_SCM_ADDR_U 0x30
94 #define CIF_CIF_SCM_ADDR_V 0x34
95 #define CIF_CIF_WB_UP_FILTER 0x38
96 #define CIF_CIF_WB_LOW_FILTER 0x3c
97 #define CIF_CIF_WBC_CNT 0x40
98 #define CIF_CIF_CROP 0x44
99 #define CIF_CIF_SCL_CTRL 0x48
100 #define CIF_CIF_SCL_DST 0x4c
101 #define CIF_CIF_SCL_FCT 0x50
102 #define CIF_CIF_SCL_VALID_NUM 0x54
103 #define CIF_CIF_LINE_LOOP_CTR 0x58
104 #define CIF_CIF_FRAME_STATUS 0x60
105 #define CIF_CIF_CUR_DST 0x64
106 #define CIF_CIF_LAST_LINE 0x68
107 #define CIF_CIF_LAST_PIX 0x6c
109 /*The key register bit descrition*/
110 /* CIF_CTRL Reg , ignore SCM,WBC,ISP,*/
111 #define DISABLE_CAPTURE (0x00<<0)
112 #define ENABLE_CAPTURE (0x01<<0)
113 #define MODE_ONEFRAME (0x00<<1)
114 #define MODE_PINGPONG (0x01<<1)
115 #define MODE_LINELOOP (0x02<<1)
116 #define AXI_BURST_16 (0x0F << 12)
119 #define FRAME_END_EN (0x01<<1)
120 #define BUS_ERR_EN (0x01<<6)
121 #define SCL_ERR_EN (0x01<<7)
124 #define VSY_HIGH_ACTIVE (0x01<<0)
125 #define VSY_LOW_ACTIVE (0x00<<0)
126 #define HSY_LOW_ACTIVE (0x01<<1)
127 #define HSY_HIGH_ACTIVE (0x00<<1)
128 #define INPUT_MODE_YUV (0x00<<2)
129 #define INPUT_MODE_PAL (0x02<<2)
130 #define INPUT_MODE_NTSC (0x03<<2)
131 #define INPUT_MODE_RAW (0x04<<2)
132 #define INPUT_MODE_JPEG (0x05<<2)
133 #define INPUT_MODE_MIPI (0x06<<2)
134 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
135 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
136 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
137 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
138 #define YUV_INPUT_422 (0x00<<7)
139 #define YUV_INPUT_420 (0x01<<7)
140 #define INPUT_420_ORDER_EVEN (0x00<<8)
141 #define INPUT_420_ORDER_ODD (0x01<<8)
142 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
143 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
144 #define RAW_DATA_WIDTH_8 (0x00<<11)
145 #define RAW_DATA_WIDTH_10 (0x01<<11)
146 #define RAW_DATA_WIDTH_12 (0x02<<11)
147 #define YUV_OUTPUT_422 (0x00<<16)
148 #define YUV_OUTPUT_420 (0x01<<16)
149 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
150 #define OUTPUT_420_ORDER_ODD (0x01<<17)
151 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
152 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
153 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
154 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
157 #define ENABLE_SCL_DOWN (0x01<<0)
158 #define DISABLE_SCL_DOWN (0x00<<0)
159 #define ENABLE_SCL_UP (0x01<<1)
160 #define DISABLE_SCL_UP (0x00<<1)
161 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
162 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
163 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
164 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
165 #define ENABLE_32BIT_BYPASS (0x01<<6)
166 #define DISABLE_32BIT_BYPASS (0x00<<6)
169 #define MIN(x,y) ((x<y) ? x: y)
170 #define MAX(x,y) ((x>y) ? x: y)
171 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
172 #define RK_SENSOR_48MHZ 48
174 #define __raw_readl(p) (*(unsigned long *)(p))
175 #define __raw_writel(v,p) (*(unsigned long *)(p) = (v))
177 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
178 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
179 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
181 /*********yzm***********/
182 /*#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)*/
184 #define CRU_PCLK_REG30 0xbc
185 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
186 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
187 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
188 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
190 #define CRU_CIF_RST_REG30 0x128
191 #define MASK_RST_CIF0 (0x01 << 30)
192 #define MASK_RST_CIF1 (0x01 << 31)
193 #define RQUEST_RST_CIF0 (0x01 << 14)
194 #define RQUEST_RST_CIF1 (0x01 << 15)
196 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
197 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
198 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
201 #if defined(CONFIG_ARCH_RK3026)
203 #define CRU_PCLK_REG30 0xbc
204 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<23)|(0x1<<7))
205 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<23)|(0x0<<7))
206 #define ENANABLE_INVERT_PCLK_CIF1 ENANABLE_INVERT_PCLK_CIF0
207 #define DISABLE_INVERT_PCLK_CIF1 DISABLE_INVERT_PCLK_CIF0
209 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
210 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
211 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
214 #if defined(CONFIG_ARCH_RK2928)
215 #define write_cru_reg(addr, val)
216 #define read_cru_reg(addr) 0
217 #define mask_cru_reg(addr, msk, val)
221 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
222 /*GRF_IO_CON3 0x100*/
223 #define CIF_DRIVER_STRENGTH_2MA (0x00 << 12)
224 #define CIF_DRIVER_STRENGTH_4MA (0x01 << 12)
225 #define CIF_DRIVER_STRENGTH_8MA (0x02 << 12)
226 #define CIF_DRIVER_STRENGTH_12MA (0x03 << 12)
227 #define CIF_DRIVER_STRENGTH_MASK (0x03 << 28)
229 /*GRF_IO_CON4 0x104*/
230 #define CIF_CLKOUT_AMP_3V3 (0x00 << 10)
231 #define CIF_CLKOUT_AMP_1V8 (0x01 << 10)
232 #define CIF_CLKOUT_AMP_MASK (0x01 << 26)
234 #define write_grf_reg(addr, val) __raw_writel(val, addr+RK30_GRF_BASE)
235 #define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
236 #define mask_grf_reg(addr, msk, val) write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
238 #define write_grf_reg(addr, val)
239 #define read_grf_reg(addr) 0
240 #define mask_grf_reg(addr, msk, val)
243 #define CAM_WORKQUEUE_IS_EN() (false)/*(true)*/
244 #define CAM_IPPWORK_IS_EN() (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
246 #define IS_CIF0() (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
247 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
248 #define CROP_ALIGN_BYTES (0x03)
249 #define CIF_DO_CROP 0
250 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
251 #define CROP_ALIGN_BYTES (0x0f)
252 #define CIF_DO_CROP 0
253 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
254 #define CROP_ALIGN_BYTES (0x03)
255 #define CIF_DO_CROP 0
256 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
257 #define CROP_ALIGN_BYTES (0x0F)
258 #define CIF_DO_CROP 1
262 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x15)
263 static int version = RK_CAM_VERSION_CODE;
264 module_param(version, int, S_IRUGO);
266 /* limit to rk29 hardware capabilities */
267 #define RK_CAM_BUS_PARAM (V4L2_MBUS_MASTER |\
268 V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
269 V4L2_MBUS_HSYNC_ACTIVE_LOW |\
270 V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
271 V4L2_MBUS_VSYNC_ACTIVE_LOW |\
272 V4L2_MBUS_PCLK_SAMPLE_RISING |\
273 V4L2_MBUS_PCLK_SAMPLE_FALLING|\
274 V4L2_MBUS_DATA_ACTIVE_HIGH |\
275 V4L2_MBUS_DATA_ACTIVE_LOW|\
276 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
277 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
279 #define RK_CAM_W_MIN 48
280 #define RK_CAM_H_MIN 32
281 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
282 #define RK_CAM_H_MAX 2764
283 #define RK_CAM_FRAME_INVAL_INIT 3
284 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
285 #define RK30_CAM_FRAME_MEASURE 5
288 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
289 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
290 /* buffer for one video frame */
291 struct rk_camera_buffer
293 /* common v4l buffer stuff -- must be first */
294 struct videobuf_buffer vb;
295 enum v4l2_mbus_pixelcode code;
298 enum rk_camera_reg_state
306 unsigned int cifCtrl;
307 unsigned int cifCrop;
309 unsigned int cifIntEn;
311 unsigned int cifVirWidth;
312 unsigned int cifScale;
313 /* unsigned int VipCrm;*/
314 enum rk_camera_reg_state Inval;
316 struct rk_camera_work
318 struct videobuf_buffer *vb;
319 struct rk_camera_dev *pcdev;
320 struct work_struct work;
321 struct list_head queue;
324 struct rk_camera_frmivalenum
326 struct v4l2_frmivalenum fival;
327 struct rk_camera_frmivalenum *nxt;
329 struct rk_camera_frmivalinfo
331 struct soc_camera_device *icd;
332 struct rk_camera_frmivalenum *fival_list;
334 struct rk_camera_zoominfo
336 struct semaphore sem;
342 #if CAMERA_VIDEOBUF_ARM_ACCESS
343 struct rk29_camera_vbinfo
345 unsigned int phy_addr;
346 void __iomem *vir_addr;
350 struct rk_camera_timer{
351 struct rk_camera_dev *pcdev;
352 struct hrtimer timer;
357 /************must modify start************/
359 struct clk *aclk_cif;
360 struct clk *hclk_cif;
361 struct clk *cif_clk_in;
362 struct clk *cif_clk_out;
363 /************must modify end************/
373 struct v4l2_rect bounds;
376 struct rk_cif_irqinfo
379 unsigned long cifirq_idx;
380 unsigned long cifirq_normal_idx;
381 unsigned long cifirq_abnormal_idx;
383 unsigned long dmairq_idx;
389 struct soc_camera_host soc_host;
391 /* RK2827x is only supposed to handle one camera on its Quick Capture
392 * interface. If anyone ever builds hardware to enable more than
393 * one camera, they will have to modify this driver too */
394 struct soc_camera_device *icd;
396 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
399 unsigned int last_fps;
400 unsigned long frame_interval;
403 unsigned int vipmem_phybase;
404 void __iomem *vipmem_virbase;
405 unsigned int vipmem_size;
406 unsigned int vipmem_bsize;
407 #if CAMERA_VIDEOBUF_ARM_ACCESS
408 struct rk29_camera_vbinfo *vbinfo;
409 unsigned int vbinfo_count;
413 int host_left; /*sensor output size ?*/
419 struct rk_cif_crop cropinfo;
420 struct rk_cif_irqinfo irqinfo;
422 struct rk29camera_platform_data *pdata;
423 struct resource *res;
424 struct list_head capture;
425 struct rk_camera_zoominfo zoominfo;
429 struct videobuf_buffer *active;
430 struct rk_camera_reg reginfo_suspend;
431 struct workqueue_struct *camera_wq;
432 struct rk_camera_work *camera_work;
433 struct list_head camera_work_queue;
434 spinlock_t camera_work_lock;
435 unsigned int camera_work_count;
436 struct rk_camera_timer fps_timer;
437 struct rk_camera_work camera_reinit_work;
439 rk29_camera_sensor_cb_s icd_cb;
440 struct rk_camera_frmivalinfo icd_frmival[2];
442 unsigned int reinit_times;
443 struct videobuf_queue *video_vq;
445 struct timeval first_tv;
450 static const struct v4l2_queryctrl rk_camera_controls[] =
453 .id = V4L2_CID_ZOOM_ABSOLUTE,
454 .type = V4L2_CTRL_TYPE_INTEGER,
455 .name = "DigitalZoom Control",
459 .default_value = 100,
463 static struct rk_cif_clk cif_clk[2];
465 static DEFINE_MUTEX(camera_lock);
466 static const char *rk_cam_driver_description = "RK_Camera";
468 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
469 static void rk_camera_capture_process(struct work_struct *work);
470 /*static int rk_camera_scale_crop_arm(struct work_struct *work);*/
472 static inline void rk3128_cru_set_soft_reset(u32 idx, bool on)
474 void __iomem *reg = RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(6);
475 u32 val = on ? 0x10001U << 14 : 0x10000U << 14;
476 writel_relaxed(val, reg);
480 static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
482 int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
484 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
486 if (only_rst == true) {
487 rk3128_cru_set_soft_reset(0, true);
489 rk3128_cru_set_soft_reset(0, false);
491 ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
492 if (ctrl_reg & ENABLE_CAPTURE) {
493 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
495 crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
496 set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
497 inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
498 for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
499 vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
500 scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
501 y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
502 uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
504 rk3128_cru_set_soft_reset(0, true);
506 rk3128_cru_set_soft_reset(0, false);
508 write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
509 write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
510 write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
511 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
512 write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
513 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
514 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
515 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */
516 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
523 * Videobuf operations
525 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
528 struct soc_camera_device *icd = vq->priv_data;
529 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
530 struct rk_camera_dev *pcdev = ici->priv;
532 struct rk_camera_work *wk;
534 struct soc_mbus_pixelfmt fmt;
536 int bytes_per_line_host;
537 fmt.packing = SOC_MBUS_PACKING_1_5X8;
539 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
542 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
543 icd->current_fmt->host_fmt);
544 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
545 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
547 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
548 bytes_per_line_host = pcdev->host_width*3;
550 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
551 icd->current_fmt->host_fmt);
552 /* dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);*/ /*yzm*/
554 if (bytes_per_line_host < 0)
555 return bytes_per_line_host;
557 /* planar capture requires Y, U and V buffers to be page aligned */
558 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
559 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
561 if (CAM_WORKQUEUE_IS_EN()) {
563 if (CAM_IPPWORK_IS_EN()) {
564 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
565 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
566 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
570 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
571 kfree(pcdev->camera_work);
572 pcdev->camera_work = NULL;
573 pcdev->camera_work_count = 0;
576 if (pcdev->camera_work == NULL) {
577 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
578 if (pcdev->camera_work == NULL) {
579 RKCAMERA_TR("kmalloc failed\n");
582 INIT_LIST_HEAD(&pcdev->camera_work_queue);
584 for (i=0; i<(*count); i++) {
586 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
589 pcdev->camera_work_count = (*count);
591 #if CAMERA_VIDEOBUF_ARM_ACCESS
592 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
593 kfree(pcdev->vbinfo);
594 pcdev->vbinfo = NULL;
595 pcdev->vbinfo_count = 0x00;
598 if (pcdev->vbinfo == NULL) {
599 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
600 if (pcdev->vbinfo == NULL) {
601 RKCAMERA_TR("vbinfo kmalloc fail\n");
604 memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
605 pcdev->vbinfo_count = *count;
609 pcdev->video_vq = vq;
610 RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
614 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
616 struct soc_camera_device *icd = vq->priv_data;
618 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
621 dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
622 &buf->vb, buf->vb.baddr, buf->vb.bsize);
624 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
625 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
631 * This waits until this buffer is out of danger, i.e., until it is no
632 * longer in STATE_QUEUED or STATE_ACTIVE
634 videobuf_waiton(vq, &buf->vb, 0, 0);
635 videobuf_dma_contig_free(vq, &buf->vb);
636 /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
637 buf->vb.state = VIDEOBUF_NEEDS_INIT;
640 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
642 struct soc_camera_device *icd = vq->priv_data;
643 struct rk_camera_buffer *buf;
645 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
646 icd->current_fmt->host_fmt);
648 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
650 if ((bytes_per_line < 0) || (vb->boff == 0))
653 buf = container_of(vb, struct rk_camera_buffer, vb);
655 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
656 /* vb, vb->baddr, vb->bsize);*/ /*yzm*/
658 /* Added list head initialization on alloc */
659 WARN_ON(!list_empty(&vb->queue));
661 BUG_ON(NULL == icd->current_fmt);
663 if (buf->code != icd->current_fmt->code ||
664 vb->width != icd->user_width ||
665 vb->height != icd->user_height ||
666 vb->field != field) {
667 buf->code = icd->current_fmt->code;
668 vb->width = icd->user_width;
669 vb->height = icd->user_height;
671 vb->state = VIDEOBUF_NEEDS_INIT;
674 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
675 if (0 != vb->baddr && vb->bsize < vb->size) {
680 if (vb->state == VIDEOBUF_NEEDS_INIT) {
681 ret = videobuf_iolock(vq, vb, NULL);
685 vb->state = VIDEOBUF_PREPARED;
690 rk_videobuf_free(vq, buf);
695 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
697 unsigned int y_addr,uv_addr;
698 struct rk_camera_dev *pcdev = rk_pcdev;
700 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
704 if (CAM_WORKQUEUE_IS_EN()) {
705 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
706 uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
707 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
708 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
709 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
714 uv_addr = y_addr + vb->width * vb->height;
716 #if defined(CONFIG_ARCH_RK3188)
717 rk_camera_cif_reset(pcdev,false);
719 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
720 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
721 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
722 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
723 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
726 /* Locking: Caller holds q->irqlock */
727 static void rk_videobuf_queue(struct videobuf_queue *vq,
728 struct videobuf_buffer *vb)
730 struct soc_camera_device *icd = vq->priv_data;
731 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
732 struct rk_camera_dev *pcdev = ici->priv;
733 #if CAMERA_VIDEOBUF_ARM_ACCESS
734 struct rk29_camera_vbinfo *vb_info;
738 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
740 /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
741 vb, vb->baddr, vb->bsize); */ /*yzm*/
743 vb->state = VIDEOBUF_QUEUED;
744 if (list_empty(&pcdev->capture)) {
745 list_add_tail(&vb->queue, &pcdev->capture);
747 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
748 list_add_tail(&vb->queue, &pcdev->capture);
750 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
752 #if CAMERA_VIDEOBUF_ARM_ACCESS
754 vb_info = pcdev->vbinfo+vb->i;
755 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
756 if (vb_info->vir_addr) {
757 iounmap(vb_info->vir_addr);
758 release_mem_region(vb_info->phy_addr, vb_info->size);
759 vb_info->vir_addr = NULL;
760 vb_info->phy_addr = 0x00;
761 vb_info->size = 0x00;
764 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
765 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
768 if (vb_info->vir_addr) {
769 vb_info->size = vb->bsize;
770 vb_info->phy_addr = vb->boff;
772 RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
777 if (!pcdev->active) {
779 rk_videobuf_capture(vb,pcdev);
780 if (atomic_read(&pcdev->stop_cif) == false) { /*ddl@rock-chips.com v0.3.0x13*/
781 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
786 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
787 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
790 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
794 case V4L2_PIX_FMT_YUV420:
795 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.*/
796 case V4L2_PIX_FMT_YUYV:
798 *ippfmt = RK_FORMAT_YCbCr_420_SP;
801 case V4L2_PIX_FMT_YVU420:
802 case V4L2_PIX_FMT_VYUY:
803 case V4L2_PIX_FMT_YVYU:
805 *ippfmt = RK_FORMAT_YCrCb_420_SP;
808 case V4L2_PIX_FMT_RGB565:
810 *ippfmt = RK_FORMAT_RGB_565;
813 case V4L2_PIX_FMT_RGB24:
815 *ippfmt = RK_FORMAT_RGB_888;
819 goto rk_pixfmt2rgafmt_err;
823 rk_pixfmt2rgafmt_err:
827 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
828 static int rk_camera_scale_crop_pp(struct work_struct *work){
829 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
830 struct videobuf_buffer *vb = camera_work->vb;
831 struct rk_camera_dev *pcdev = camera_work->pcdev;
833 unsigned long int flags;
841 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
842 extern rga_service_info rga_service;
843 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
844 extern void rga_service_session_clear(rga_session *session);
845 static int rk_camera_scale_crop_rga(struct work_struct *work){
846 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
847 struct videobuf_buffer *vb = camera_work->vb;
848 struct rk_camera_dev *pcdev = camera_work->pcdev;
850 unsigned long int flags;
856 const struct soc_mbus_pixelfmt *fmt;
859 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
866 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
868 static int rk_camera_scale_crop_ipp(struct work_struct *work)
874 static void rk_camera_capture_process(struct work_struct *work)
876 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
877 struct videobuf_buffer *vb = camera_work->vb;
878 struct rk_camera_dev *pcdev = camera_work->pcdev;
879 /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code; */
880 unsigned long flags = 0;
883 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
886 if (atomic_read(&pcdev->stop_cif)==true) {
888 goto rk_camera_capture_process_end;
891 if (!CAM_WORKQUEUE_IS_EN()) {
893 goto rk_camera_capture_process_end;
896 down(&pcdev->zoominfo.sem);
897 if (pcdev->icd_cb.scale_crop_cb){
898 err = (pcdev->icd_cb.scale_crop_cb)(work);
900 up(&pcdev->zoominfo.sem);
902 if (pcdev->icd_cb.sensor_cb)
903 (pcdev->icd_cb.sensor_cb)(vb);
905 rk_camera_capture_process_end:
907 vb->state = VIDEOBUF_ERROR;
909 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
910 vb->state = VIDEOBUF_DONE;
914 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
915 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
916 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
917 wake_up(&(camera_work->vb->done)); /* ddl@rock-chips.com : v0.3.9 */
921 static void rk_camera_cifrest_delay(struct work_struct *work)
923 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
924 struct rk_camera_dev *pcdev = camera_work->pcdev;
925 unsigned long flags = 0;
927 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
931 rk_camera_cif_reset(pcdev,false);
933 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
934 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
935 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
937 spin_lock_irqsave(&pcdev->lock,flags);
938 if (atomic_read(&pcdev->stop_cif) == false) {
939 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
940 RKCAMERA_DG2("After reset cif, enable capture again!\n");
942 spin_unlock_irqrestore(&pcdev->lock,flags);
946 static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
948 struct rk_camera_dev *pcdev = data;
949 struct rk_camera_work *wk;
950 unsigned int reg_cifctrl,reg_lastpix,reg_lastline;
952 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
955 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
957 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
958 reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
959 reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
961 pcdev->irqinfo.cifirq_idx++;
962 if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
963 pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
964 RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
965 reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
967 pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
970 if(reg_cifctrl & ENABLE_CAPTURE) {
971 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
974 if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
975 if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
976 if (!list_empty(&pcdev->camera_work_queue)) {
977 RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
978 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
979 list_del_init(&wk->queue);
980 INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
982 queue_work(pcdev->camera_wq, &(wk->work));
990 static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
992 struct rk_camera_dev *pcdev = data;
993 struct videobuf_buffer *vb;
994 struct rk_camera_work *wk;
996 unsigned long reg_cifctrl;
998 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1001 reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1002 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1003 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { //frame 0 ready yzm
1004 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1006 pcdev->irqinfo.dmairq_idx++;
1007 if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
1008 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);
1013 do_gettimeofday(&pcdev->first_tv);
1018 if (pcdev->frame_inval>0) {
1019 pcdev->frame_inval--;
1020 rk_videobuf_capture(pcdev->active,pcdev);
1022 } else if (pcdev->frame_inval) {
1023 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1024 pcdev->frame_inval = 0;
1027 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1028 do_gettimeofday(&tv);
1029 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1030 /(RK30_CAM_FRAME_MEASURE-1);
1035 printk("no acticve buffer!!!\n");
1039 /* ddl@rock-chips.com : this vb may be deleted from queue */
1040 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1041 list_del_init(&vb->queue);
1043 pcdev->active = NULL;
1044 if (!list_empty(&pcdev->capture)) {
1045 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1046 if (pcdev->active) {
1047 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1048 rk_videobuf_capture(pcdev->active,pcdev);
1051 if (pcdev->active == NULL) {
1052 RKCAMERA_DG1("video_buf queue is empty!\n");
1055 do_gettimeofday(&vb->ts);
1056 if (CAM_WORKQUEUE_IS_EN()) {
1057 if (!list_empty(&pcdev->camera_work_queue)) {
1058 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1059 list_del_init(&wk->queue);
1060 INIT_WORK(&(wk->work), rk_camera_capture_process);
1063 queue_work(pcdev->camera_wq, &(wk->work));
1066 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1067 vb->state = VIDEOBUF_DONE;
1075 if((reg_cifctrl & ENABLE_CAPTURE) == 0)
1076 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
1080 static irqreturn_t rk_camera_irq(int irq, void *data)
1082 struct rk_camera_dev *pcdev = data;
1083 unsigned long reg_intstat;
1087 spin_lock(&pcdev->lock);
1089 if(atomic_read(&pcdev->stop_cif) == true) {
1090 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
1094 reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1095 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%lx\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
1096 if (reg_intstat & 0x0200)
1097 rk_camera_cifirq(irq,data);
1099 if (reg_intstat & 0x01)
1100 rk_camera_dmairq(irq,data);
1103 spin_unlock(&pcdev->lock);
1108 static void rk_videobuf_release(struct videobuf_queue *vq,
1109 struct videobuf_buffer *vb)
1111 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1112 struct soc_camera_device *icd = vq->priv_data;
1113 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1114 struct rk_camera_dev *pcdev = ici->priv;
1115 #if CAMERA_VIDEOBUF_ARM_ACCESS
1116 struct rk29_camera_vbinfo *vb_info =NULL;
1121 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1124 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1125 vb, vb->baddr, vb->bsize);
1129 case VIDEOBUF_ACTIVE:
1130 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1132 case VIDEOBUF_QUEUED:
1133 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1135 case VIDEOBUF_PREPARED:
1136 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1139 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1144 flush_workqueue(pcdev->camera_wq);
1146 rk_videobuf_free(vq, buf);
1148 #if CAMERA_VIDEOBUF_ARM_ACCESS
1149 if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
1150 vb_info = pcdev->vbinfo + vb->i;
1152 if (vb_info->vir_addr) {
1153 iounmap(vb_info->vir_addr);
1154 release_mem_region(vb_info->phy_addr, vb_info->size);
1155 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1162 static struct videobuf_queue_ops rk_videobuf_ops =
1164 .buf_setup = rk_videobuf_setup,
1165 .buf_prepare = rk_videobuf_prepare,
1166 .buf_queue = rk_videobuf_queue,
1167 .buf_release = rk_videobuf_release,
1170 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1171 struct soc_camera_device *icd)
1173 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1174 struct rk_camera_dev *pcdev = ici->priv;
1176 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1179 /* We must pass NULL as dev pointer, then all pci_* dma operations
1180 * transform to normal dma_* ones. */
1181 videobuf_queue_dma_contig_init(q,
1183 ici->v4l2_dev.dev, &pcdev->lock,
1184 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1186 sizeof(struct rk_camera_buffer),
1187 icd,&(ici->host_lock) );
1190 static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
1193 struct rk_cif_clk *clk;
1194 struct clk *cif_clk_out_div;
1196 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1199 cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
1200 if ((cif<0)||(cif>1)) {
1201 RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
1203 goto rk_camera_clk_ctrl_end;
1206 clk = &cif_clk[cif];
1208 if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
1209 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1211 goto rk_camera_clk_ctrl_end;
1214 spin_lock(&clk->lock);
1215 if (on && !clk->on) {
1216 clk_prepare_enable(clk->pd_cif); /*yzm*/
1217 clk_prepare_enable(clk->aclk_cif);
1218 clk_prepare_enable(clk->hclk_cif);
1219 clk_prepare_enable(clk->cif_clk_in);
1220 clk_prepare_enable(clk->cif_clk_out);
1221 clk_set_rate(clk->cif_clk_out,clk_rate);
1223 } else if (!on && clk->on) {
1224 clk_disable_unprepare(clk->aclk_cif);
1225 clk_disable_unprepare(clk->hclk_cif);
1226 clk_disable_unprepare(clk->cif_clk_in);
1227 clk_disable_unprepare(clk->cif_clk_out);
1228 clk_disable_unprepare(clk->pd_cif);
1231 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
1233 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
1234 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
1235 cif_clk_out_div = clk_get(NULL, "cif_out_div");
1239 if(!IS_ERR_OR_NULL(cif_clk_out_div)) { /* ddl@rock-chips.com: v0.3.0x13 */
1240 err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
1241 clk_put(cif_clk_out_div);
1247 RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__);
1249 spin_unlock(&clk->lock);
1250 rk_camera_clk_ctrl_end:
1253 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1256 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1259 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1261 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1262 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1266 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1269 * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
1271 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1277 /* The following two functions absolutely depend on the fact, that
1278 * there can be only one camera on RK28 quick capture interface */
1279 static int rk_camera_add_device(struct soc_camera_device *icd)
1281 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1282 struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/
1283 struct device *control = to_soc_camera_control(icd);
1284 struct v4l2_subdev *sd;
1285 int ret,i,icd_catch;
1286 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1287 struct v4l2_cropcap cropcap;
1288 struct v4l2_mbus_framefmt mf;
1289 const struct soc_camera_format_xlate *xlate = NULL;
1291 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1294 mutex_lock(&camera_lock);
1301 RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1303 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1304 pcdev->active = NULL;
1306 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1307 pcdev->zoominfo.zoom_rate = 100;
1308 pcdev->fps_timer.istarted = false;
1310 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1311 * if app havn't dequeue all videobuf before close camera device;
1313 INIT_LIST_HEAD(&pcdev->capture);
1315 ret = rk_camera_activate(pcdev,icd);
1318 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1319 if (control) { //TRUE in open ,FALSE in kernel start
1320 sd = dev_get_drvdata(control);
1321 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1323 ret = v4l2_subdev_call(sd,core, init, 0);
1327 /* call generic_sensor_ioctl*/
1328 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1329 /* call generic_sensor_cropcap*/
1330 if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
1331 memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
1333 xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12);
1336 mf.field = V4L2_FIELD_NONE;
1337 mf.code = xlate->code;
1338 mf.reserved[6] = 0xfefe5a5a;
1339 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1341 pcdev->cropinfo.bounds.left = 0;
1342 pcdev->cropinfo.bounds.top = 0;
1343 pcdev->cropinfo.bounds.width = mf.width;
1344 pcdev->cropinfo.bounds.height = mf.height;
1348 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1350 pcdev->icd_init = 0;
1353 for (i=0; i<2; i++) {
1354 if (pcdev->icd_frmival[i].icd == icd)
1356 if (pcdev->icd_frmival[i].icd == NULL) {
1357 pcdev->icd_frmival[i].icd = icd;
1361 if (icd_catch == 0) {
1362 fival_list = pcdev->icd_frmival[0].fival_list;
1363 fival_nxt = fival_list;
1364 while(fival_nxt != NULL) {
1365 fival_nxt = fival_list->nxt;
1367 fival_list = fival_nxt;
1369 pcdev->icd_frmival[0].icd = icd;
1370 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1373 mutex_unlock(&camera_lock);
1377 static void rk_camera_remove_device(struct soc_camera_device *icd)
1379 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1380 struct rk_camera_dev *pcdev = ici->priv;
1381 /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
1382 #if CAMERA_VIDEOBUF_ARM_ACCESS
1383 struct rk29_camera_vbinfo *vb_info;
1387 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1390 mutex_lock(&camera_lock);
1391 BUG_ON(icd != pcdev->icd);
1393 RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
1395 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1396 stream may be turn on again before close device, if suspend and resume happened. */
1397 /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
1398 if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) { /* ddl@rock-chips.com: v0.3.0x15*/
1399 rk_camera_s_stream(icd,0);
1401 /* move DEACTIVATE into generic_sensor_s_power*/
1402 /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
1403 /* if stream off is not been executed,timer is running.*/
1404 if(pcdev->fps_timer.istarted){
1405 hrtimer_cancel(&pcdev->fps_timer.timer);
1406 pcdev->fps_timer.istarted = false;
1408 flush_work(&(pcdev->camera_reinit_work.work));
1409 flush_workqueue((pcdev->camera_wq));
1411 if (pcdev->camera_work) {
1412 kfree(pcdev->camera_work);
1413 pcdev->camera_work = NULL;
1414 pcdev->camera_work_count = 0;
1415 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1417 rk_camera_deactivate(pcdev);
1418 #if CAMERA_VIDEOBUF_ARM_ACCESS
1419 if (pcdev->vbinfo) {
1420 vb_info = pcdev->vbinfo;
1421 for (i=0; i<pcdev->vbinfo_count; i++) {
1422 if (vb_info->vir_addr) {
1423 iounmap(vb_info->vir_addr);
1424 release_mem_region(vb_info->phy_addr, vb_info->size);
1425 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1429 kfree(pcdev->vbinfo);
1430 pcdev->vbinfo = NULL;
1431 pcdev->vbinfo_count = 0;
1434 pcdev->active = NULL;
1436 pcdev->icd_cb.sensor_cb = NULL;
1437 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1438 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1439 * if app havn't dequeue all videobuf before close camera device;
1441 INIT_LIST_HEAD(&pcdev->capture);
1443 mutex_unlock(&camera_lock);
1447 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1449 unsigned long bus_flags, camera_flags, common_flags = 0;
1450 /*unsigned int cif_for = 0;*/
1451 const struct soc_mbus_pixelfmt *fmt;
1453 /*struct soc_camera_host *ici = to_soc_camera_host(icd->parent);*/ /*yzm*/
1454 /*struct rk_camera_dev *pcdev = ici->priv;*/
1457 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1460 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1464 bus_flags = RK_CAM_BUS_PARAM;
1465 /* If requested data width is supported by the platform, use it */
1466 switch (fmt->bits_per_sample) {
1468 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1472 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1476 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1482 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1483 if (icd->ops->query_bus_param)
1484 camera_flags = icd->ops->query_bus_param(icd);
1488 /**************yzm************
1489 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1490 if (!common_flags) {
1492 goto RK_CAMERA_SET_BUS_PARAM_END;
1495 /***************yzm************end*/
1496 ret = icd->ops->set_bus_param(icd, common_flags);
1498 goto RK_CAMERA_SET_BUS_PARAM_END;
1500 cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1502 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1504 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1506 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1510 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1512 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1515 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
1516 cif_for |= HSY_LOW_ACTIVE;
1518 cif_for &= ~HSY_LOW_ACTIVE;
1520 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
1521 cif_for |= VSY_HIGH_ACTIVE;
1523 cif_for &= ~VSY_HIGH_ACTIVE;
1526 // ddl@rock-chips.com : Don't enable capture here, enable in stream_on
1527 //vip_ctrl_val |= ENABLE_CAPTURE;
1528 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
1529 RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
1531 RK_CAMERA_SET_BUS_PARAM_END:
1533 RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
1537 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1539 /* unsigned long bus_flags, camera_flags;*/
1542 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
1543 /**********yzm***********
1545 bus_flags = RK_CAM_BUS_PARAM;
1546 if (icd->ops->query_bus_param) {
1547 camera_flags = icd->ops->query_bus_param(icd); //generic_sensor_query_bus_param()
1551 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1554 dev_warn(icd->dev.parent,
1555 "Flags incompatible: camera %lx, host %lx\n",
1556 camera_flags, bus_flags);
1559 *///************yzm **************end
1564 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1566 .fourcc = V4L2_PIX_FMT_NV12,
1567 .name = "YUV420 NV12",
1568 .bits_per_sample = 8,
1569 .packing = SOC_MBUS_PACKING_1_5X8,
1570 .order = SOC_MBUS_ORDER_LE,
1572 .fourcc = V4L2_PIX_FMT_NV16,
1573 .name = "YUV422 NV16",
1574 .bits_per_sample = 8,
1575 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1576 .order = SOC_MBUS_ORDER_LE,
1578 .fourcc = V4L2_PIX_FMT_NV21,
1579 .name = "YUV420 NV21",
1580 .bits_per_sample = 8,
1581 .packing = SOC_MBUS_PACKING_1_5X8,
1582 .order = SOC_MBUS_ORDER_LE,
1584 .fourcc = V4L2_PIX_FMT_NV61,
1585 .name = "YUV422 NV61",
1586 .bits_per_sample = 8,
1587 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1588 .order = SOC_MBUS_ORDER_LE,
1590 .fourcc = V4L2_PIX_FMT_RGB565,
1592 .bits_per_sample = 8,
1593 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1594 .order = SOC_MBUS_ORDER_LE,
1596 .fourcc = V4L2_PIX_FMT_RGB24,
1598 .bits_per_sample = 8,
1599 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1600 .order = SOC_MBUS_ORDER_LE,
1605 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1607 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1608 struct rk_camera_dev *pcdev = ici->priv;
1609 unsigned int cif_fs = 0,cif_crop = 0;
1610 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;
1612 const struct soc_mbus_pixelfmt *fmt;
1613 fmt = soc_mbus_get_fmtdesc(icd_code);
1615 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1618 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1619 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1620 host_pixfmt = V4L2_PIX_FMT_NV12;
1621 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1622 host_pixfmt = V4L2_PIX_FMT_NV21;
1624 switch (host_pixfmt)
1626 case V4L2_PIX_FMT_NV16:
1627 cif_fmt_val &= ~YUV_OUTPUT_422;
1628 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1629 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1630 pcdev->pixfmt = host_pixfmt;
1632 case V4L2_PIX_FMT_NV61:
1633 cif_fmt_val &= ~YUV_OUTPUT_422;
1634 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1635 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1636 pcdev->pixfmt = host_pixfmt;
1638 case V4L2_PIX_FMT_NV12:
1639 cif_fmt_val |= YUV_OUTPUT_420;
1640 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1641 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1642 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1643 pcdev->pixfmt = host_pixfmt;
1645 case V4L2_PIX_FMT_NV21:
1646 cif_fmt_val |= YUV_OUTPUT_420;
1647 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1648 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1649 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1650 pcdev->pixfmt = host_pixfmt;
1652 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1653 cif_fmt_val |= YUV_OUTPUT_422;
1658 case V4L2_MBUS_FMT_UYVY8_2X8:
1659 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1661 case V4L2_MBUS_FMT_YUYV8_2X8:
1662 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1664 case V4L2_MBUS_FMT_YVYU8_2X8:
1665 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1667 case V4L2_MBUS_FMT_VYUY8_2X8:
1668 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1671 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1676 rk_camera_cif_reset(pcdev,true);
1678 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1679 //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
1681 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 */
1683 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1684 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1685 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1687 } else{ /* this is one frame mode*/
1688 cif_crop = (rect->left+ (rect->top<<16));
1689 cif_fs = ((rect->width ) + (rect->height<<16));
1692 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1693 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1694 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1695 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1697 /*MUST bypass scale */
1698 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1699 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);
1703 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1704 struct soc_camera_format_xlate *xlate)
1706 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1707 struct device *dev = icd->parent;/*yzm*/
1708 int formats = 0, ret;
1709 enum v4l2_mbus_pixelcode code;
1710 const struct soc_mbus_pixelfmt *fmt;
1712 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1715 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); /*call generic_sensor_enum_fmt()*/
1717 /* No more formats */
1720 fmt = soc_mbus_get_fmtdesc(code);
1722 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1726 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1731 case V4L2_MBUS_FMT_UYVY8_2X8:
1732 case V4L2_MBUS_FMT_YUYV8_2X8:
1733 case V4L2_MBUS_FMT_YVYU8_2X8:
1734 case V4L2_MBUS_FMT_VYUY8_2X8:
1737 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1740 xlate->host_fmt = &rk_camera_formats[0];
1743 dev_dbg(dev, "Providing format %s using code %d\n",
1744 rk_camera_formats[0].name,code);
1749 xlate->host_fmt = &rk_camera_formats[1];
1752 dev_dbg(dev, "Providing format %s using code %d\n",
1753 rk_camera_formats[1].name,code);
1758 xlate->host_fmt = &rk_camera_formats[2];
1761 dev_dbg(dev, "Providing format %s using code %d\n",
1762 rk_camera_formats[2].name,code);
1767 xlate->host_fmt = &rk_camera_formats[3];
1770 dev_dbg(dev, "Providing format %s using code %d\n",
1771 rk_camera_formats[3].name,code);
1777 xlate->host_fmt = &rk_camera_formats[4];
1780 dev_dbg(dev, "Providing format %s using code %d\n",
1781 rk_camera_formats[4].name,code);
1785 xlate->host_fmt = &rk_camera_formats[5];
1788 dev_dbg(dev, "Providing format %s using code %d\n",
1789 rk_camera_formats[5].name,code);
1801 static void rk_camera_put_formats(struct soc_camera_device *icd)
1804 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1808 static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
1810 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1813 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1815 ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
1818 /* ddl@rock-chips.com: driver decide the cropping rectangle */
1819 memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
1823 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
1825 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1826 struct rk_camera_dev *pcdev = ici->priv;
1828 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1831 spin_lock(&pcdev->cropinfo.lock);
1832 memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
1833 spin_unlock(&pcdev->cropinfo.lock);
1837 static int rk_camera_set_crop(struct soc_camera_device *icd,
1838 const struct v4l2_crop *crop)
1840 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1841 struct rk_camera_dev *pcdev = ici->priv;
1843 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1846 spin_lock(&pcdev->cropinfo.lock);
1847 memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
1848 spin_unlock(&pcdev->cropinfo.lock);
1851 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1855 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1858 if (f->fmt.pix.priv == 0xfefe5a5a) {
1862 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1864 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1866 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1868 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1870 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1872 } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
1877 RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
1880 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1881 struct v4l2_format *f)
1883 struct device *dev = icd->parent;/*yzm*/
1884 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1885 const struct soc_camera_format_xlate *xlate = NULL;
1886 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
1887 struct rk_camera_dev *pcdev = ici->priv;
1888 struct v4l2_pix_format *pix = &f->fmt.pix;
1889 struct v4l2_mbus_framefmt mf;
1890 struct v4l2_rect rect;
1891 int ret,usr_w,usr_h,sensor_w,sensor_h;
1893 int ratio, bounds_aspect;
1895 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
1899 usr_h = pix->height;
1901 RKCAMERA_DG1("enter width:%d height:%d\n",usr_w,usr_h);
1902 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1904 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1906 goto RK_CAMERA_SET_FMT_END;
1909 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1910 if (pcdev->icd_init == 0) {
1911 v4l2_subdev_call(sd,core, init, 0); /*call generic_sensor_init()*/
1912 pcdev->icd_init = 1;
1913 return 0; /*directly return !!!!!!*/
1915 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1916 if (stream_on & ENABLE_CAPTURE)
1917 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1919 mf.width = pix->width;
1920 mf.height = pix->height;
1921 mf.field = pix->field;
1922 mf.colorspace = pix->colorspace;
1923 mf.code = xlate->code;
1924 mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */
1927 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); /*generic_sensor_s_fmt*/
1928 if (mf.code != xlate->code)
1931 if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) &&
1932 (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
1933 bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
1934 if ((mf.width*10/mf.height) != bounds_aspect) {
1935 RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
1936 usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
1938 mf.width = pcdev->cropinfo.bounds.width/4;
1939 mf.height = pcdev->cropinfo.bounds.height/4;
1941 mf.field = pix->field;
1942 mf.colorspace = pix->colorspace;
1943 mf.code = xlate->code;
1944 mf.reserved[0] = pix->priv;
1947 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1948 if (mf.code != xlate->code)
1953 sensor_w = mf.width;
1954 sensor_h = mf.height;
1956 ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); /* 4 align*/
1959 ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); /* 2 align*/
1962 if ((mf.width != usr_w) || (mf.height != usr_h)) {
1964 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1965 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
1967 goto RK_CAMERA_SET_FMT_END;
1969 if (unlikely((usr_w <16)||(usr_h < 16))) {
1970 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1972 goto RK_CAMERA_SET_FMT_END;
1975 spin_lock(&pcdev->cropinfo.lock);
1976 if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {
1977 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
1978 /*Scale + Crop center is for keep aspect ratio unchange*/
1979 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
1980 pcdev->host_width = ratio*usr_w/10;
1981 pcdev->host_height = ratio*usr_h/10;
1982 pcdev->host_width &= ~CROP_ALIGN_BYTES;
1983 pcdev->host_height &= ~CROP_ALIGN_BYTES;
1985 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
1986 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
1988 /*Scale + crop(user define)*/
1989 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
1990 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
1991 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
1992 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
1995 pcdev->host_left &= (~0x01);
1996 pcdev->host_top &= (~0x01);
1998 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
1999 /*Crop Center for cif can work , then scale*/
2000 pcdev->host_width = mf.width;
2001 pcdev->host_height = mf.height;
2002 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
2003 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
2005 /*Crop center for cif can work + crop(user define), then scale */
2006 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2007 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2008 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
2009 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1);
2012 pcdev->host_left &= (~0x01);
2013 pcdev->host_top &= (~0x01);
2015 spin_unlock(&pcdev->cropinfo.lock);
2017 spin_lock(&pcdev->cropinfo.lock);
2018 if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
2019 pcdev->host_width = mf.width;
2020 pcdev->host_height = mf.height;
2021 pcdev->host_left = 0;
2022 pcdev->host_top = 0;
2024 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
2025 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
2026 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
2027 pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height);
2029 spin_unlock(&pcdev->cropinfo.lock);
2034 rect.width = pcdev->host_width;
2035 rect.height = pcdev->host_height;
2036 rect.left = pcdev->host_left;
2037 rect.top = pcdev->host_top;
2039 down(&pcdev->zoominfo.sem);
2040 #if CIF_DO_CROP /* this crop is only for digital zoom*/
2041 pcdev->zoominfo.a.c.left = 0;
2042 pcdev->zoominfo.a.c.top = 0;
2043 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2044 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2045 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2046 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2047 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2048 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2049 /*recalculate the CIF width & height*/
2050 rect.width = pcdev->zoominfo.a.c.width ;
2051 rect.height = pcdev->zoominfo.a.c.height;
2052 rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
2053 rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01);
2055 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2056 pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
2057 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2058 pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
2059 /*now digital zoom use ipp to do crop and scale*/
2060 if(pcdev->zoominfo.zoom_rate != 100){
2061 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2062 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2064 pcdev->zoominfo.a.c.left = 0;
2065 pcdev->zoominfo.a.c.top = 0;
2067 pcdev->zoominfo.vir_width = pcdev->host_width;
2068 pcdev->zoominfo.vir_height = pcdev->host_height;
2070 up(&pcdev->zoominfo.sem);
2072 /* ddl@rock-chips.com: IPP work limit check */
2073 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2074 if (usr_w > 0x7f0) {
2075 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2076 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));
2078 goto RK_CAMERA_SET_FMT_END;
2081 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2082 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2084 goto RK_CAMERA_SET_FMT_END;
2089 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,
2090 pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
2091 sensor_w,sensor_h,mf.width,mf.height,
2092 pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
2093 pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height,
2094 pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2095 pix->width, pix->height);
2097 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2099 if (CAM_IPPWORK_IS_EN()) {
2100 BUG_ON(pcdev->vipmem_phybase == 0);
2103 pix->height = usr_h;
2104 pix->field = mf.field;
2105 pix->colorspace = mf.colorspace;
2106 icd->current_fmt = xlate;
2107 pcdev->icd_width = mf.width;
2108 pcdev->icd_height = mf.height;
2111 RK_CAMERA_SET_FMT_END:
2112 if (stream_on & ENABLE_CAPTURE)
2113 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2115 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2119 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2120 struct v4l2_format *f)
2122 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2123 struct rk_camera_dev *pcdev = ici->priv;
2124 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2125 const struct soc_camera_format_xlate *xlate;
2126 struct v4l2_pix_format *pix = &f->fmt.pix;
2127 __u32 pixfmt = pix->pixelformat;
2128 int ret,usr_w,usr_h,i;
2129 bool is_capture = rk_camera_fmt_capturechk(f); /* testing f is in line with the already set*/
2130 bool vipmem_is_overflow = false;
2131 struct v4l2_mbus_framefmt mf;
2132 int bytes_per_line_host;
2135 usr_h = pix->height;
2137 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2139 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2141 /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
2142 dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
2143 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2145 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2146 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2147 for (i = 0; i < icd->num_user_formats; i++)
2148 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2149 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2150 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2151 icd->user_formats[i].host_fmt->name);
2152 goto RK_CAMERA_TRY_FMT_END;
2154 /* limit to rk29 hardware capabilities */
2155 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2156 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2157 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2159 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2161 if (pix->bytesperline < 0)
2162 return pix->bytesperline;
2164 /* limit to sensor capabilities */
2165 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2166 mf.width = pix->width;
2167 mf.height = pix->height;
2168 mf.field = pix->field;
2169 mf.colorspace = pix->colorspace;
2170 mf.code = xlate->code;
2171 /* ddl@rock-chips.com : It is query max resolution only. */
2172 if ((usr_w == 10000) && (usr_h == 10000)) {
2173 mf.reserved[6] = 0xfefe5a5a;
2175 /* call generic_sensor_try_fmt()*/
2176 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2178 goto RK_CAMERA_TRY_FMT_END;
2180 /*query resolution.*/
2181 if((usr_w == 10000) && (usr_h == 10000)) {
2182 pix->width = mf.width;
2183 pix->height = mf.height;
2184 RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
2185 goto RK_CAMERA_TRY_FMT_END;
2187 RKCAMERA_DG1("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
2190 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2191 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2193 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2195 /* Assume preview buffer minimum is 4 */
2196 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2198 if (vipmem_is_overflow == false) {
2200 pix->height = usr_h;
2202 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
2203 pix->width = mf.width;
2204 pix->height = mf.height;
2206 /* ddl@rock-chips.com: Invalidate these code, because sensor need interpolate */
2208 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2209 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2210 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2211 pix->width = mf.width;
2212 pix->height = mf.height;
2218 pix->colorspace = mf.colorspace;
2221 case V4L2_FIELD_ANY:
2222 case V4L2_FIELD_NONE:
2223 pix->field = V4L2_FIELD_NONE;
2226 /* TODO: support interlaced at least in pass-through mode */
2227 dev_err(icd->parent, "Field type %d unsupported.\n",
2229 goto RK_CAMERA_TRY_FMT_END;
2232 RK_CAMERA_TRY_FMT_END:
2234 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2238 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2239 struct v4l2_requestbuffers *p)
2243 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2246 /* This is for locking debugging only. I removed spinlocks and now I
2247 * check whether .prepare is ever called on a linked buffer, or whether
2248 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2249 * it hadn't triggered */
2250 for (i = 0; i < p->count; i++) {
2251 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2252 struct rk_camera_buffer, vb);
2254 INIT_LIST_HEAD(&buf->vb.queue);
2260 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2262 struct soc_camera_device *icd = file->private_data;
2263 struct rk_camera_buffer *buf;
2265 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2268 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2271 poll_wait(file, &buf->vb.done, pt);
2273 if (buf->vb.state == VIDEOBUF_DONE ||
2274 buf->vb.state == VIDEOBUF_ERROR)
2275 return POLLIN|POLLRDNORM;
2280 *card: sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
2281 * 10 5 1 3 3 3 + 5 < 32
2284 static int rk_camera_querycap(struct soc_camera_host *ici,
2285 struct v4l2_capability *cap)
2287 struct rk_camera_dev *pcdev = ici->priv;
2288 struct rkcamera_platform_data *new_camera;
2289 char orientation[5];
2293 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2296 strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
2297 memset(orientation,0x00,sizeof(orientation));
2300 new_camera = pcdev->pdata->register_dev_new;
2301 while(new_camera != NULL){
2302 if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
2303 sprintf(orientation,"-%d",new_camera->orientation);
2304 sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
2306 new_camera = new_camera->next_camera;
2309 if (orientation[0] != '-') {
2310 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2311 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2312 strcat(cap->card,"-270");
2314 strcat(cap->card,"-90");
2316 strcat(cap->card,orientation);
2319 strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */
2320 cap->version = RK_CAM_VERSION_CODE;
2321 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2322 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2326 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2328 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2329 struct rk_camera_dev *pcdev = ici->priv;
2330 struct v4l2_subdev *sd;
2333 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2336 mutex_lock(&camera_lock);
2337 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2338 rk_camera_s_stream(icd, 0);
2339 sd = soc_camera_to_subdev(icd);
2340 v4l2_subdev_call(sd, video, s_stream, 0);
2341 ret = icd->ops->suspend(icd, state);
2343 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2344 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2345 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2346 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2347 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2348 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2349 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2351 pcdev->reginfo_suspend.Inval = Reg_Validate;
2352 rk_camera_deactivate(pcdev);
2354 RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
2356 RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2358 mutex_unlock(&camera_lock);
2362 static int rk_camera_resume(struct soc_camera_device *icd)
2364 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2365 struct rk_camera_dev *pcdev = ici->priv;
2366 struct v4l2_subdev *sd;
2369 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2372 mutex_lock(&camera_lock);
2373 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2374 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2375 rk_camera_activate(pcdev, icd);
2376 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2377 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2378 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2379 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2380 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2381 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2382 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2383 rk_videobuf_capture(pcdev->active,pcdev);
2384 rk_camera_s_stream(icd, 1);
2385 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2387 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2388 goto rk_camera_resume_end;
2391 ret = icd->ops->resume(icd);
2392 sd = soc_camera_to_subdev(icd);
2393 v4l2_subdev_call(sd, video, s_stream, 1);
2395 RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
2397 RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2400 rk_camera_resume_end:
2401 mutex_unlock(&camera_lock);
2405 static void rk_camera_reinit_work(struct work_struct *work)
2407 struct v4l2_subdev *sd;
2408 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2409 struct rk_camera_dev *pcdev = camera_work->pcdev;
2410 /*struct soc_camera_link *tmp_soc_cam_link;*/
2411 struct v4l2_mbus_framefmt mf;
2413 unsigned long flags = 0;
2416 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2419 if(pcdev->icd == NULL)
2421 sd = soc_camera_to_subdev(pcdev->icd);
2422 /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2425 RKCAMERA_TR("CIF_CIF_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2426 RKCAMERA_TR("CIF_CIF_INTEN = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2427 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2428 RKCAMERA_TR("CIF_CIF_FOR = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2429 RKCAMERA_TR("CIF_CIF_CROP = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2430 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2431 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2432 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%lx\n",read_cru_reg(CRU_PCLK_REG30));
2433 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2435 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2436 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2437 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2438 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2439 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2440 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2441 RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
2442 RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
2443 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2446 ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/
2447 if (pcdev->reinit_times == 1) {
2448 if (ctrl & ENABLE_CAPTURE) {
2449 RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
2450 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2451 rk_camera_cif_reset(pcdev,false);
2454 v4l2_subdev_call(sd,core, init, 0);
2456 mf.width = pcdev->icd_width;
2457 mf.height = pcdev->icd_height;
2458 mf.field = V4L2_FIELD_NONE;
2459 mf.code = pcdev->icd->current_fmt->code;
2460 mf.reserved[0] = 0x5a5afefe;
2463 v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
2465 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2466 } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) {
2467 RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
2468 pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
2469 rk_camera_cif_reset(pcdev,false);
2470 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
2475 atomic_set(&pcdev->stop_cif,true);
2476 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2477 RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
2479 if(pcdev->video_vq && pcdev->video_vq->irqlock){
2480 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2481 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2482 if (NULL == pcdev->video_vq->bufs[index])
2485 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
2486 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2487 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2488 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2489 printk("wake up video buffer index = %d !!!\n",index);
2492 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2494 RKCAMERA_TR("video queue has somthing wrong !!\n");
2497 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2499 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2501 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2502 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2503 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2505 /*static unsigned int last_fps = 0;*/
2506 /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
2507 /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
2509 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2511 RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2512 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2513 RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
2514 pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
2515 pcdev->camera_reinit_work.pcdev = pcdev;
2516 /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
2517 pcdev->reinit_times++;
2518 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2519 } else if(!pcdev->timer_get_fps) {
2520 pcdev->timer_get_fps = true;
2521 for (i=0; i<2; i++) {
2522 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2523 fival_nxt = pcdev->icd_frmival[i].fival_list;
2528 fival_pre = fival_nxt;
2529 while (fival_nxt != NULL) {
2531 RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
2532 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2533 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2534 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2535 fival_nxt->fival.discrete.numerator);
2537 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2538 && (fival_nxt->fival.height == pcdev->icd->user_height)
2539 && (fival_nxt->fival.width == pcdev->icd->user_width))
2540 || (fival_nxt->fival.discrete.denominator == 0)) {
2542 if (fival_nxt->fival.discrete.denominator == 0) {
2543 fival_nxt->fival.index = 0;
2544 fival_nxt->fival.width = pcdev->icd->user_width;
2545 fival_nxt->fival.height= pcdev->icd->user_height;
2546 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2547 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2548 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2549 |(pcdev->icd_height);
2550 fival_nxt->fival.discrete.numerator = 1000000;
2551 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2554 fival_rec = fival_nxt;
2556 fival_pre = fival_nxt;
2557 fival_nxt = fival_nxt->nxt;
2560 if ((rec_flag == 0) && fival_pre) {
2561 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2562 if (fival_pre->nxt != NULL) {
2563 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2564 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2565 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2566 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2568 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2569 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2570 |(pcdev->icd_height);
2571 fival_pre->nxt->fival.discrete.numerator = 1000000;
2572 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2574 fival_rec = fival_pre->nxt;
2579 if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times)) /*ddl@rock-chips.com v0.3.0x13*/
2580 pcdev->reinit_times = 0;
2582 pcdev->last_fps = pcdev->fps ;
2583 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2584 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2585 /*return HRTIMER_NORESTART;*/
2586 if(pcdev->reinit_times >=2)
2587 return HRTIMER_NORESTART;
2589 return HRTIMER_RESTART;
2591 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2593 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2594 struct rk_camera_dev *pcdev = ici->priv;
2597 unsigned long flags;
2599 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2601 WARN_ON(pcdev->icd != icd);
2603 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2606 pcdev->last_fps = 0;
2607 pcdev->frame_interval = 0;
2608 hrtimer_cancel(&(pcdev->fps_timer.timer));
2609 pcdev->fps_timer.pcdev = pcdev;
2610 pcdev->timer_get_fps = false;
2611 pcdev->reinit_times = 0;
2613 spin_lock_irqsave(&pcdev->lock,flags);
2614 atomic_set(&pcdev->stop_cif,false);
2615 pcdev->irqinfo.cifirq_idx = 0;
2616 pcdev->irqinfo.cifirq_normal_idx = 0;
2617 pcdev->irqinfo.cifirq_abnormal_idx = 0;
2618 pcdev->irqinfo.dmairq_idx = 0;
2620 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); /*capture complete interrupt enable*/
2621 cif_ctrl_val |= ENABLE_CAPTURE;
2622 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2623 spin_unlock_irqrestore(&pcdev->lock,flags);
2624 printk("%s:stream enable CIF_CIF_CTRL 0x%lx",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2625 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2626 pcdev->fps_timer.istarted = true;
2628 /*cancel timer before stop cif*/
2629 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2630 pcdev->fps_timer.istarted = false;
2631 flush_work(&(pcdev->camera_reinit_work.work));
2633 cif_ctrl_val &= ~ENABLE_CAPTURE;
2634 spin_lock_irqsave(&pcdev->lock, flags);
2635 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2636 atomic_set(&pcdev->stop_cif,true);
2637 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0);
2638 spin_unlock_irqrestore(&pcdev->lock, flags);
2639 flush_workqueue((pcdev->camera_wq));
2641 /*must be reinit,or will be somthing wrong in irq process.*/
2642 if(enable == false) {
2643 pcdev->active = NULL;
2644 INIT_LIST_HEAD(&pcdev->capture);
2646 RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%lx\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2649 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2651 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2652 struct rk_camera_dev *pcdev = ici->priv;
2653 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2654 struct rk_camera_frmivalenum *fival_list = NULL;
2655 struct v4l2_frmivalenum *fival_head = NULL;
2656 struct rkcamera_platform_data *new_camera;
2657 int i,ret = 0,index;
2658 const struct soc_camera_format_xlate *xlate;
2659 struct v4l2_mbus_framefmt mf;
2662 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2664 index = fival->index & 0x00ffffff;
2665 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2666 for (i=0; i<2; i++) {
2667 if (pcdev->icd_frmival[i].icd == icd) {
2668 fival_list = pcdev->icd_frmival[i].fival_list;
2672 if (fival_list != NULL) {
2674 while (fival_list != NULL) {
2675 if ((fival->pixel_format == fival_list->fival.pixel_format)
2676 && (fival->height == fival_list->fival.height)
2677 && (fival->width == fival_list->fival.width)) {
2682 fival_list = fival_list->nxt;
2685 if ((i==index) && (fival_list != NULL)) {
2686 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2691 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2698 while (fival_head->width && fival_head->height) {
2699 if ((fival->pixel_format == fival_head->pixel_format)
2700 && (fival->height == fival_head->height)
2701 && (fival->width == fival_head->width)) {
2710 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2711 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2713 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2714 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2715 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2716 mf.width = fival->width;
2717 mf.height = fival->height;
2718 mf.code = xlate->code;
2720 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2722 fival->reserved[1] = (mf.width<<16)|(mf.height);
2724 RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2725 fival->width, fival->height,
2726 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2727 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2728 fival->discrete.denominator,fival->discrete.numerator);
2731 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2732 fival->width,fival->height,
2733 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2734 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2737 RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2738 fival->width,fival->height,
2739 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2740 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2743 goto rk_camera_enum_frameintervals_end;
2747 new_camera = pcdev->pdata->register_dev_new;
2748 while(new_camera != NULL){
2749 if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
2753 new_camera = new_camera->next_camera;
2757 printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
2758 __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
2761 pixfmt = fival->pixel_format; /* ddl@rock-chips.com: v0.3.9 */
2762 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2763 memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
2764 mf.width = fival->width;
2765 mf.height = fival->height;
2766 mf.code = xlate->code;
2768 v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2770 fival->discrete.numerator= 1000;
2771 fival->discrete.denominator = 15000;
2772 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
2773 fival->reserved[1] = (mf.width<<16)|(mf.height);
2777 rk_camera_enum_frameintervals_end:
2781 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2782 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2785 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2786 struct rk_camera_dev *pcdev = ici->priv;
2788 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2792 unsigned long tmp_cifctrl;
2795 /*change the crop and scale parameters*/
2798 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2799 /*a.c.width = pcdev->host_width*100/zoom_rate;*/
2800 a.c.width = pcdev->host_width*100/zoom_rate;
2801 a.c.width &= ~CROP_ALIGN_BYTES;
2802 a.c.height = pcdev->host_height*100/zoom_rate;
2803 a.c.height &= ~CROP_ALIGN_BYTES;
2804 a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
2805 a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
2806 atomic_set(&pcdev->stop_cif,true);
2807 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2808 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
2809 hrtimer_cancel(&(pcdev->fps_timer.timer));
2810 flush_workqueue((pcdev->camera_wq));
2812 down(&pcdev->zoominfo.sem);
2813 pcdev->zoominfo.a.c.left = 0;
2814 pcdev->zoominfo.a.c.top = 0;
2815 pcdev->zoominfo.a.c.width = a.c.width;
2816 pcdev->zoominfo.a.c.height = a.c.height;
2817 pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
2818 pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
2819 pcdev->frame_inval = 1;
2820 write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
2821 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
2822 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
2823 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
2825 rk_videobuf_capture(pcdev->active,pcdev);
2826 if(tmp_cifctrl & ENABLE_CAPTURE)
2827 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
2828 up(&pcdev->zoominfo.sem);
2830 atomic_set(&pcdev->stop_cif,false);
2831 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2832 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 );
2834 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2835 a.c.width = pcdev->host_width*100/zoom_rate;
2836 a.c.width &= ~CROP_ALIGN_BYTES;
2837 a.c.height = pcdev->host_height*100/zoom_rate;
2838 a.c.height &= ~CROP_ALIGN_BYTES;
2839 a.c.left = (pcdev->host_width - a.c.width)>>1;
2840 a.c.top = (pcdev->host_height - a.c.height)>>1;
2842 down(&pcdev->zoominfo.sem);
2843 pcdev->zoominfo.a.c.height = a.c.height;
2844 pcdev->zoominfo.a.c.width = a.c.width;
2845 pcdev->zoominfo.a.c.top = a.c.top;
2846 pcdev->zoominfo.a.c.left = a.c.left;
2847 pcdev->zoominfo.vir_width = pcdev->host_width;
2848 pcdev->zoominfo.vir_height= pcdev->host_height;
2849 up(&pcdev->zoominfo.sem);
2851 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 );
2857 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2858 struct soc_camera_host_ops *ops, int id)
2860 /************yzm************
2862 for (i = 0; i < ops->num_controls; i++)
2863 if (ops->controls[i].id == id)
2864 return &ops->controls[i];
2865 **************yzm*********/
2870 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2871 struct v4l2_control *sctrl)
2873 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
2874 const struct v4l2_queryctrl *qctrl;
2875 struct rk_camera_dev *pcdev = ici->priv;
2879 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
2881 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2884 goto rk_camera_set_ctrl_end;
2889 case V4L2_CID_ZOOM_ABSOLUTE:
2891 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2893 goto rk_camera_set_ctrl_end;
2895 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2897 pcdev->zoominfo.zoom_rate = sctrl->value;
2899 goto rk_camera_set_ctrl_end;
2907 rk_camera_set_ctrl_end:
2911 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2913 .owner = THIS_MODULE,
2914 .add = rk_camera_add_device,
2915 .remove = rk_camera_remove_device,
2916 .suspend = rk_camera_suspend,
2917 .resume = rk_camera_resume,
2918 .enum_frameinervals = rk_camera_enum_frameintervals,
2919 .cropcap = rk_camera_cropcap,
2920 .set_crop = rk_camera_set_crop,
2921 .get_crop = rk_camera_get_crop,
2922 .get_formats = rk_camera_get_formats,
2923 .put_formats = rk_camera_put_formats,
2924 .set_fmt = rk_camera_set_fmt,
2925 .try_fmt = rk_camera_try_fmt,
2926 .init_videobuf = rk_camera_init_videobuf,
2927 .reqbufs = rk_camera_reqbufs,
2928 .poll = rk_camera_poll,
2929 .querycap = rk_camera_querycap,
2930 .set_bus_param = rk_camera_set_bus_param,
2931 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2932 .set_ctrl = rk_camera_set_ctrl,
2933 .controls = rk_camera_controls,
2934 .num_controls = ARRAY_SIZE(rk_camera_controls)
2937 /**********yzm***********/
2938 static int rk_camera_cif_iomux(struct device *dev)
2941 struct pinctrl *pinctrl;
2942 struct pinctrl_state *state;
2944 char state_str[20] = {0};
2946 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2947 strcpy(state_str,"cif_pin_jpe");
2949 /*__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);*/
2954 pinctrl = devm_pinctrl_get(dev);
2955 if (IS_ERR(pinctrl)) {
2956 printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
2959 state = pinctrl_lookup_state(pinctrl,
2962 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
2966 if (!IS_ERR(state)) {
2967 retval = pinctrl_select_state(pinctrl, state);
2970 "%s:could not set %s pins\n",__func__,state_str);
2978 /***********yzm***********/
2979 static int rk_camera_probe(struct platform_device *pdev)
2981 struct rk_camera_dev *pcdev;
2982 struct resource *res;
2983 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
2986 struct rk_cif_clk *clk=NULL;
2987 struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
2988 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
2990 RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2991 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
2993 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
2994 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
2998 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
2999 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
3003 /***********yzm**********/
3004 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3005 irq = platform_get_irq(pdev, 0);
3007 /* irq = irq_of_parse_and_map(dev_cif->of_node, 0);
3008 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
3009 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
3011 if (!res || irq < 0) {
3015 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
3017 dev_err(&pdev->dev, "Could not allocate pcdev\n");
3022 pcdev->zoominfo.zoom_rate = 100;
3023 pcdev->hostid = pdev->id; /* get host id*/
3024 #ifdef CONFIG_SOC_RK3028
3025 pcdev->chip_id = rk3028_version_val();
3027 pcdev->chip_id = -1;
3030 /***********yzm***********/
3032 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
3034 cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
3035 cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3036 cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3037 cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3038 cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3039 spin_lock_init(&cif_clk[0].lock);
3040 cif_clk[0].on = false;
3041 rk_camera_cif_iomux(dev_cif);/*yzm*/
3044 cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only yzm*/
3045 cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
3046 cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
3047 cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
3048 cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
3049 spin_lock_init(&cif_clk[1].lock);
3050 cif_clk[1].on = false;
3051 rk_camera_cif_iomux(dev_cif);/*yzm*/
3054 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3056 /***********yzm**********/
3057 dev_set_drvdata(&pdev->dev, pcdev);
3059 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
3060 /*= rk_camera_platform_data */
3061 if (pcdev->pdata && pcdev->pdata->io_init) {
3063 pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
3065 if (pcdev->pdata->sensor_mclk == NULL)
3066 pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
3069 INIT_LIST_HEAD(&pcdev->capture);
3070 INIT_LIST_HEAD(&pcdev->camera_work_queue);
3071 spin_lock_init(&pcdev->lock);
3072 spin_lock_init(&pcdev->camera_work_lock);
3074 memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect));
3075 spin_lock_init(&pcdev->cropinfo.lock);
3076 sema_init(&pcdev->zoominfo.sem,1);
3079 * Request the regions.
3082 if (!request_mem_region(res->start, res->end - res->start + 1,
3083 RK29_CAM_DRV_NAME)) {
3085 goto exit_reqmem_vip;
3087 pcdev->base = ioremap(res->start, res->end - res->start + 1);
3088 if (pcdev->base == NULL) {
3089 dev_err(pcdev->dev, "ioremap() of registers failed\n");
3091 goto exit_ioremap_vip;
3095 pcdev->irqinfo.irq = irq;
3096 pcdev->dev = &pdev->dev;
3098 /* config buffer address */
3101 err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
3104 dev_err(pcdev->dev, "Camera interrupt register failed \n");
3110 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
3112 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
3114 if (pcdev->camera_wq == NULL) {
3115 RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
3119 pcdev->camera_reinit_work.pcdev = pcdev;
3120 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
3122 for (i=0; i<2; i++) {
3123 pcdev->icd_frmival[i].icd = NULL;
3124 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
3127 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
3128 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
3129 pcdev->soc_host.priv = pcdev; /*to itself,csll in rk_camera_add_device*/
3130 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
3131 pcdev->soc_host.nr = pdev->id;
3132 debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
3133 err = soc_camera_host_register(&pcdev->soc_host);
3137 RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
3140 pcdev->fps_timer.pcdev = pcdev;
3141 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3142 pcdev->fps_timer.timer.function = rk_camera_fps_func;
3143 pcdev->icd_cb.sensor_cb = NULL;
3145 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
3146 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
3147 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
3148 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
3149 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
3150 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
3151 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
3152 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
3158 for (i=0; i<2; i++) {
3159 fival_list = pcdev->icd_frmival[i].fival_list;
3160 fival_nxt = fival_list;
3161 while(fival_nxt != NULL) {
3162 fival_nxt = fival_list->nxt;
3164 fival_list = fival_nxt;
3168 free_irq(pcdev->irqinfo.irq, pcdev);
3169 if (pcdev->camera_wq) {
3170 destroy_workqueue(pcdev->camera_wq);
3171 pcdev->camera_wq = NULL;
3174 iounmap(pcdev->base);
3176 release_mem_region(res->start, res->end - res->start + 1);
3180 clk_put(clk->pd_cif);
3182 clk_put(clk->aclk_cif);
3184 clk_put(clk->hclk_cif);
3185 if (clk->cif_clk_in)
3186 clk_put(clk->cif_clk_in);
3187 if (clk->cif_clk_out)
3188 clk_put(clk->cif_clk_out);
3197 static int __exit rk_camera_remove(struct platform_device *pdev)
3199 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3200 struct resource *res;
3201 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3204 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3207 free_irq(pcdev->irqinfo.irq, pcdev);
3209 if (pcdev->camera_wq) {
3210 destroy_workqueue(pcdev->camera_wq);
3211 pcdev->camera_wq = NULL;
3214 for (i=0; i<2; i++) {
3215 fival_list = pcdev->icd_frmival[i].fival_list;
3216 fival_nxt = fival_list;
3217 while(fival_nxt != NULL) {
3218 fival_nxt = fival_list->nxt;
3220 fival_list = fival_nxt;
3224 soc_camera_host_unregister(&pcdev->soc_host);
3227 iounmap((void __iomem*)pcdev->base);
3228 release_mem_region(res->start, res->end - res->start + 1);
3229 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3230 pcdev->pdata->io_deinit(0);
3231 pcdev->pdata->io_deinit(1);
3236 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3241 static struct platform_driver rk_camera_driver =
3244 .name = RK29_CAM_DRV_NAME, /*host */
3246 .probe = rk_camera_probe,
3247 .remove = (rk_camera_remove),
3250 static int rk_camera_init_async(void *unused)
3253 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3255 platform_driver_register(&rk_camera_driver);
3259 static int __init rk_camera_init(void)
3262 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
3264 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3269 static void __exit rk_camera_exit(void)
3271 debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
3273 platform_driver_unregister(&rk_camera_driver);
3276 device_initcall_sync(rk_camera_init);
3277 module_exit(rk_camera_exit);
3279 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3280 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3281 MODULE_LICENSE("GPL");