2 * V4L2 Driver for RK28 camera host
4 * Copyright (C) 2006, Sascha Hauer, Pengutronix
5 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31)
13 #include <linux/init.h>
14 #include <linux/module.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/errno.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
24 #include <linux/moduleparam.h>
25 #include <linux/time.h>
26 #include <linux/clk.h>
27 #include <linux/version.h>
28 #include <linux/device.h>
29 #include <linux/platform_device.h>
30 #include <linux/mutex.h>
31 #include <linux/videodev2.h>
32 #include <linux/kthread.h>
33 #include <mach/iomux.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-dev.h>
36 #include <media/videobuf-dma-contig.h>
37 #include <media/soc_camera.h>
38 #include <media/soc_mediabus.h>
41 #include <plat/vpu_service.h>
42 #include "../../video/rockchip/rga/rga.h"
43 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31)
44 #include <mach/rk30_camera.h>
49 #if defined(CONFIG_ARCH_RK2928)
50 #include <mach/rk2928_camera.h>
51 #include "../../video/rockchip/rga/rga.h"
53 #include <asm/cacheflush.h>
55 module_param(debug, int, S_IRUGO|S_IWUSR);
57 #define dprintk(level, fmt, arg...) do { \
59 printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
61 #define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
62 #define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
65 #define CIF_CIF_CTRL 0x00
66 #define CIF_CIF_INTEN 0x04
67 #define CIF_CIF_INTSTAT 0x08
68 #define CIF_CIF_FOR 0x0c
69 #define CIF_CIF_LINE_NUM_ADDR 0x10
70 #define CIF_CIF_FRM0_ADDR_Y 0x14
71 #define CIF_CIF_FRM0_ADDR_UV 0x18
72 #define CIF_CIF_FRM1_ADDR_Y 0x1c
73 #define CIF_CIF_FRM1_ADDR_UV 0x20
74 #define CIF_CIF_VIR_LINE_WIDTH 0x24
75 #define CIF_CIF_SET_SIZE 0x28
76 #define CIF_CIF_SCM_ADDR_Y 0x2c
77 #define CIF_CIF_SCM_ADDR_U 0x30
78 #define CIF_CIF_SCM_ADDR_V 0x34
79 #define CIF_CIF_WB_UP_FILTER 0x38
80 #define CIF_CIF_WB_LOW_FILTER 0x3c
81 #define CIF_CIF_WBC_CNT 0x40
82 #define CIF_CIF_CROP 0x44
83 #define CIF_CIF_SCL_CTRL 0x48
84 #define CIF_CIF_SCL_DST 0x4c
85 #define CIF_CIF_SCL_FCT 0x50
86 #define CIF_CIF_SCL_VALID_NUM 0x54
87 #define CIF_CIF_LINE_LOOP_CTR 0x58
88 #define CIF_CIF_FRAME_STATUS 0x60
89 #define CIF_CIF_CUR_DST 0x64
90 #define CIF_CIF_LAST_LINE 0x68
91 #define CIF_CIF_LAST_PIX 0x6c
93 //The key register bit descrition
94 // CIF_CTRL Reg , ignore SCM,WBC,ISP,
95 #define DISABLE_CAPTURE (0x00<<0)
96 #define ENABLE_CAPTURE (0x01<<0)
97 #define MODE_ONEFRAME (0x00<<1)
98 #define MODE_PINGPONG (0x01<<1)
99 #define MODE_LINELOOP (0x02<<1)
100 #define AXI_BURST_16 (0x0F << 12)
103 #define FRAME_END_EN (0x01<<1)
104 #define BUS_ERR_EN (0x01<<6)
105 #define SCL_ERR_EN (0x01<<7)
108 #define VSY_HIGH_ACTIVE (0x01<<0)
109 #define VSY_LOW_ACTIVE (0x00<<0)
110 #define HSY_LOW_ACTIVE (0x01<<1)
111 #define HSY_HIGH_ACTIVE (0x00<<1)
112 #define INPUT_MODE_YUV (0x00<<2)
113 #define INPUT_MODE_PAL (0x02<<2)
114 #define INPUT_MODE_NTSC (0x03<<2)
115 #define INPUT_MODE_RAW (0x04<<2)
116 #define INPUT_MODE_JPEG (0x05<<2)
117 #define INPUT_MODE_MIPI (0x06<<2)
118 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
119 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
120 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
121 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
122 #define YUV_INPUT_422 (0x00<<7)
123 #define YUV_INPUT_420 (0x01<<7)
124 #define INPUT_420_ORDER_EVEN (0x00<<8)
125 #define INPUT_420_ORDER_ODD (0x01<<8)
126 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
127 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
128 #define RAW_DATA_WIDTH_8 (0x00<<11)
129 #define RAW_DATA_WIDTH_10 (0x01<<11)
130 #define RAW_DATA_WIDTH_12 (0x02<<11)
131 #define YUV_OUTPUT_422 (0x00<<16)
132 #define YUV_OUTPUT_420 (0x01<<16)
133 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
134 #define OUTPUT_420_ORDER_ODD (0x01<<17)
135 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
136 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
137 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
138 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
141 #define ENABLE_SCL_DOWN (0x01<<0)
142 #define DISABLE_SCL_DOWN (0x00<<0)
143 #define ENABLE_SCL_UP (0x01<<1)
144 #define DISABLE_SCL_UP (0x00<<1)
145 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
146 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
147 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
148 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
149 #define ENABLE_32BIT_BYPASS (0x01<<6)
150 #define DISABLE_32BIT_BYPASS (0x00<<6)
152 #if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31))
154 #define CRU_PCLK_REG30 0xbc
155 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
156 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
157 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
158 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
160 #define CRU_CIF_RST_REG30 0x128
161 #define MASK_RST_CIF0 (0x01 << 30)
162 #define MASK_RST_CIF1 (0x01 << 31)
163 #define RQUEST_RST_CIF0 (0x01 << 14)
164 #define RQUEST_RST_CIF1 (0x01 << 15)
167 #define MIN(x,y) ((x<y) ? x: y)
168 #define MAX(x,y) ((x>y) ? x: y)
169 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
170 #define RK_SENSOR_48MHZ 48
172 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
173 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
174 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
176 #if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31))
177 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
178 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
179 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
182 #if defined(CONFIG_ARCH_RK2928)
183 #define write_cru_reg(addr, val)
184 #define read_cru_reg(addr) 0
185 #define mask_cru_reg(addr, msk, val)
189 //when work_with_ipp is not enabled,CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF is not defined.something wrong with it
190 #ifdef CONFIG_VIDEO_RK29_WORK_IPP//CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
191 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
192 #define CAM_WORKQUEUE_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
193 || (pcdev->icd_cb.sensor_cb))
194 #define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))
196 #define CAM_WORKQUEUE_IS_EN() (true)
197 #define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
199 #else //CONFIG_VIDEO_RK29_WORK_IPP
200 #define CAM_WORKQUEUE_IS_EN() (false)
201 #define CAM_IPPWORK_IS_EN() (false)
204 #define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
207 * Driver Version Note
209 *v0.0.x : this driver is 2.6.32 kernel driver;
210 *v0.1.x : this driver is 3.0.8 kernel driver;
212 *v0.x.1 : this driver first support rk2918;
213 *v0.x.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420
214 * and V4L2_PIX_FMT_YUV422P;
215 *v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
216 *v0.x.4 : this driver support digital zoom;
217 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
218 *v0.x.6 : this driver improve test framerate method;
219 *v0.x.7 : digital zoom use the ipp to do scale and crop , otherwise ipp just do the scale. Something wrong with digital zoom if
220 we do crop with cif and do scale with ipp , we will fix this next version.
221 *v0.x.8 : temp version,reinit capture list when setup video buf.
222 *v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version.
223 2. flush workqueue when releas buffer
224 *v0.x.a: 1. reset cif and wake up vb when cif have't receive data in a fixed time(now setted as 2 secs) so that app can
226 2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
227 3. when front and back camera are the same sensor,and one has the flash ,other is not,flash can't work corrrectly ,fix it
228 4. add menu configs for convineuent to customize sensor series
229 *v0.x.b: specify the version is NOT sure stable.
230 *v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
231 2. irq process is splitted to two step.
232 *v0.x.e: fix bugs of early suspend when display_pd is closed.
233 *v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
234 *v0.x.11: fix struct rk_camera_work may be reentrant
235 *v0.x.13: add scale by arm,rga and pp.
237 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0x11)
239 /* limit to rk29 hardware capabilities */
240 #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
241 SOCAM_HSYNC_ACTIVE_HIGH |\
242 SOCAM_HSYNC_ACTIVE_LOW |\
243 SOCAM_VSYNC_ACTIVE_HIGH |\
244 SOCAM_VSYNC_ACTIVE_LOW |\
245 SOCAM_PCLK_SAMPLE_RISING |\
246 SOCAM_PCLK_SAMPLE_FALLING|\
247 SOCAM_DATA_ACTIVE_HIGH |\
248 SOCAM_DATA_ACTIVE_LOW|\
249 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
250 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
252 #define RK_CAM_W_MIN 48
253 #define RK_CAM_H_MIN 32
254 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
255 #define RK_CAM_H_MAX 2764
256 #define RK_CAM_FRAME_INVAL_INIT 3
257 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
258 #define RK30_CAM_FRAME_MEASURE 5
259 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
260 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
262 /* buffer for one video frame */
263 struct rk_camera_buffer
265 /* common v4l buffer stuff -- must be first */
266 struct videobuf_buffer vb;
267 enum v4l2_mbus_pixelcode code;
270 enum rk_camera_reg_state
278 unsigned int cifCtrl;
279 unsigned int cifCrop;
281 unsigned int cifIntEn;
283 unsigned int cifVirWidth;
284 unsigned int cifScale;
285 // unsigned int VipCrm;
286 enum rk_camera_reg_state Inval;
288 struct rk_camera_work
290 struct videobuf_buffer *vb;
291 struct rk_camera_dev *pcdev;
292 struct work_struct work;
293 struct list_head queue;
296 struct rk_camera_frmivalenum
298 struct v4l2_frmivalenum fival;
299 struct rk_camera_frmivalenum *nxt;
301 struct rk_camera_frmivalinfo
303 struct soc_camera_device *icd;
304 struct rk_camera_frmivalenum *fival_list;
306 struct rk_camera_zoominfo
308 struct semaphore sem;
314 #if CAMERA_VIDEOBUF_ARM_ACCESS
315 struct rk29_camera_vbinfo
317 unsigned int phy_addr;
318 void __iomem *vir_addr;
322 struct rk_camera_timer{
323 struct rk_camera_dev *pcdev;
324 struct hrtimer timer;
329 struct soc_camera_host soc_host;
331 /* RK2827x is only supposed to handle one camera on its Quick Capture
332 * interface. If anyone ever builds hardware to enable more than
333 * one camera, they will have to modify this driver too */
334 struct soc_camera_device *icd;
336 //************must modify start************/
338 struct clk *aclk_cif;
339 struct clk *hclk_cif;
340 struct clk *cif_clk_in;
341 struct clk *cif_clk_out;
342 //************must modify end************/
344 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
347 unsigned int last_fps;
348 unsigned long frame_interval;
351 unsigned int vipmem_phybase;
352 void __iomem *vipmem_virbase;
353 unsigned int vipmem_size;
354 unsigned int vipmem_bsize;
355 #if CAMERA_VIDEOBUF_ARM_ACCESS
356 struct rk29_camera_vbinfo *vbinfo;
357 unsigned int vbinfo_count;
361 int host_left; //sensor output size ?
367 struct rk29camera_platform_data *pdata;
368 struct resource *res;
369 struct list_head capture;
370 struct rk_camera_zoominfo zoominfo;
374 struct videobuf_buffer *active;
375 struct rk_camera_reg reginfo_suspend;
376 struct workqueue_struct *camera_wq;
377 struct rk_camera_work *camera_work;
378 struct list_head camera_work_queue;
379 spinlock_t camera_work_lock;
380 unsigned int camera_work_count;
381 struct rk_camera_timer fps_timer;
382 struct rk_camera_work camera_reinit_work;
384 rk29_camera_sensor_cb_s icd_cb;
385 struct rk_camera_frmivalinfo icd_frmival[2];
386 // atomic_t to_process_frames;
388 unsigned int reinit_times;
389 struct videobuf_queue *video_vq;
391 struct timeval first_tv;
394 static const struct v4l2_queryctrl rk_camera_controls[] =
396 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
398 .id = V4L2_CID_ZOOM_ABSOLUTE,
399 .type = V4L2_CTRL_TYPE_INTEGER,
400 .name = "DigitalZoom Control",
404 .default_value = 100,
409 static DEFINE_MUTEX(camera_lock);
410 static const char *rk_cam_driver_description = "RK_Camera";
412 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
413 static void rk_camera_capture_process(struct work_struct *work);
417 * Videobuf operations
419 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
422 struct soc_camera_device *icd = vq->priv_data;
423 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
424 struct rk_camera_dev *pcdev = ici->priv;
426 struct rk_camera_work *wk;
428 struct soc_mbus_pixelfmt fmt;
430 int bytes_per_line_host;
431 fmt.packing = SOC_MBUS_PACKING_1_5X8;
433 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
434 icd->current_fmt->host_fmt);
435 if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB565)
436 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
438 else if(icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB24)
439 bytes_per_line_host = pcdev->host_width*3;
441 bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
442 icd->current_fmt->host_fmt);
443 printk("user code = %d,packing = %d",icd->current_fmt->code,fmt.packing);
444 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
446 if (bytes_per_line_host < 0)
447 return bytes_per_line_host;
449 /* planar capture requires Y, U and V buffers to be page aligned */
450 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
451 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
453 if (CAM_WORKQUEUE_IS_EN()) {
454 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
455 if (CAM_IPPWORK_IS_EN())
458 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
459 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
460 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
463 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
464 kfree(pcdev->camera_work);
465 pcdev->camera_work = NULL;
466 pcdev->camera_work_count = 0;
469 if (pcdev->camera_work == NULL) {
470 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
471 if (pcdev->camera_work == NULL) {
472 RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
475 INIT_LIST_HEAD(&pcdev->camera_work_queue);
477 for (i=0; i<(*count); i++) {
479 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
482 pcdev->camera_work_count = (*count);
484 #if CAMERA_VIDEOBUF_ARM_ACCESS
485 if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
486 kfree(pcdev->vbinfo);
487 pcdev->vbinfo = NULL;
488 pcdev->vbinfo_count = 0x00;
491 if (pcdev->vbinfo == NULL) {
492 pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
493 if (pcdev->vbinfo == NULL) {
494 RKCAMERA_TR("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
497 pcdev->vbinfo_count = *count;
501 pcdev->video_vq = vq;
502 RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
506 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
508 struct soc_camera_device *icd = vq->priv_data;
510 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
511 &buf->vb, buf->vb.baddr, buf->vb.bsize);
513 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
514 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
520 * This waits until this buffer is out of danger, i.e., until it is no
521 * longer in STATE_QUEUED or STATE_ACTIVE
523 //videobuf_waiton(vq, &buf->vb, 0, 0);
524 videobuf_dma_contig_free(vq, &buf->vb);
525 dev_dbg(&icd->dev, "%s freed\n", __func__);
526 buf->vb.state = VIDEOBUF_NEEDS_INIT;
529 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
531 struct soc_camera_device *icd = vq->priv_data;
532 struct rk_camera_buffer *buf;
534 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
535 icd->current_fmt->host_fmt);
536 if (bytes_per_line < 0)
537 return bytes_per_line;
539 buf = container_of(vb, struct rk_camera_buffer, vb);
541 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
542 vb, vb->baddr, vb->bsize);
544 /* Added list head initialization on alloc */
545 WARN_ON(!list_empty(&vb->queue));
547 BUG_ON(NULL == icd->current_fmt);
549 if (buf->code != icd->current_fmt->code ||
550 vb->width != icd->user_width ||
551 vb->height != icd->user_height ||
552 vb->field != field) {
553 buf->code = icd->current_fmt->code;
554 vb->width = icd->user_width;
555 vb->height = icd->user_height;
557 vb->state = VIDEOBUF_NEEDS_INIT;
560 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
561 if (0 != vb->baddr && vb->bsize < vb->size) {
566 if (vb->state == VIDEOBUF_NEEDS_INIT) {
567 ret = videobuf_iolock(vq, vb, NULL);
571 vb->state = VIDEOBUF_PREPARED;
576 rk_videobuf_free(vq, buf);
581 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
583 unsigned int y_addr,uv_addr;
584 struct rk_camera_dev *pcdev = rk_pcdev;
587 if (CAM_WORKQUEUE_IS_EN()) {
588 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
589 uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
590 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
591 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
592 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
597 uv_addr = y_addr + vb->width * vb->height;
599 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
600 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
601 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
602 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
603 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
606 /* Locking: Caller holds q->irqlock */
607 static void rk_videobuf_queue(struct videobuf_queue *vq,
608 struct videobuf_buffer *vb)
610 struct soc_camera_device *icd = vq->priv_data;
611 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
612 struct rk_camera_dev *pcdev = ici->priv;
613 struct rk29_camera_vbinfo *vb_info;
615 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
616 vb, vb->baddr, vb->bsize);
618 vb->state = VIDEOBUF_QUEUED;
619 if (list_empty(&pcdev->capture)) {
620 list_add_tail(&vb->queue, &pcdev->capture);
622 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
623 list_add_tail(&vb->queue, &pcdev->capture);
625 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
627 #if CAMERA_VIDEOBUF_ARM_ACCESS
629 vb_info = pcdev->vbinfo+vb->i;
630 if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
631 if (vb_info->vir_addr) {
632 iounmap(vb_info->vir_addr);
633 release_mem_region(vb_info->phy_addr, vb_info->size);
634 vb_info->vir_addr = NULL;
635 vb_info->phy_addr = 0x00;
636 vb_info->size = 0x00;
639 if (request_mem_region(vb->boff,vb->bsize,"rk_camera_vb")) {
640 vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
643 if (vb_info->vir_addr) {
644 vb_info->size = vb->bsize;
645 vb_info->phy_addr = vb->boff;
647 RKCAMERA_TR("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
652 if (!pcdev->active) {
654 rk_videobuf_capture(vb,pcdev);
657 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
661 case V4L2_PIX_FMT_NV16:
662 case V4L2_PIX_FMT_NV61:
664 *ippfmt = IPP_Y_CBCR_H2V1;
667 case V4L2_PIX_FMT_NV12:
668 case V4L2_PIX_FMT_NV21:
670 *ippfmt = IPP_Y_CBCR_H2V2;
674 goto rk_pixfmt2ippfmt_err;
678 rk_pixfmt2ippfmt_err:
682 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
686 case V4L2_PIX_FMT_YUV420:
687 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.
688 case V4L2_PIX_FMT_YUYV:
690 *ippfmt = RK_FORMAT_YCbCr_420_SP;
693 case V4L2_PIX_FMT_YVU420:
694 case V4L2_PIX_FMT_VYUY:
695 case V4L2_PIX_FMT_YVYU:
697 *ippfmt = RK_FORMAT_YCrCb_420_SP;
700 case V4L2_PIX_FMT_RGB565:
702 *ippfmt = RK_FORMAT_RGB_565;
705 case V4L2_PIX_FMT_RGB24:
707 *ippfmt = RK_FORMAT_RGB_888;
711 goto rk_pixfmt2rgafmt_err;
715 rk_pixfmt2rgafmt_err:
718 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
719 static int rk_camera_scale_crop_pp(struct work_struct *work){
720 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
721 struct videobuf_buffer *vb = camera_work->vb;
722 struct rk_camera_dev *pcdev = camera_work->pcdev;
724 unsigned long int flags;
730 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
732 memset(&init, 0, sizeof(init));
733 init.srcAddr = vipdata_base;
734 init.srcFormat = PP_IN_FORMAT_YUV420SEMI;
735 init.srcWidth = init.srcHStride = pcdev->zoominfo.vir_width;
736 init.srcHeight = init.srcVStride = pcdev->zoominfo.vir_height;
738 init.dstAddr = vb->boff;
739 init.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE;
740 init.dstWidth = init.dstHStride = pcdev->icd->user_width;
741 init.dstHeight = init.dstVStride = pcdev->icd->user_height;
743 printk("srcWidth = %d,srcHeight = %d,dstWidth = %d,dstHeight = %d\n",init.srcWidth,init.srcHeight,init.dstWidth,init.dstHeight);
745 ret = ppOpInit(&hnd, &init);
751 printk("can not create ppOp handle\n");
757 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
758 extern rga_service_info rga_service;
759 extern int rga_blit_sync(rga_session *session, struct rga_req *req);
760 extern void rga_service_session_clear(rga_session *session);
761 static int rk_camera_scale_crop_rga(struct work_struct *work){
762 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
763 struct videobuf_buffer *vb = camera_work->vb;
764 struct rk_camera_dev *pcdev = camera_work->pcdev;
766 unsigned long int flags;
772 const struct soc_mbus_pixelfmt *fmt;
774 fmt = soc_mbus_get_fmtdesc(pcdev->icd->current_fmt->code);
775 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
776 if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
777 && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
778 RKCAMERA_TR("RGA not support this format !\n");
781 if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
782 scale_times = MAX((pcdev->icd->user_width/0x800),(pcdev->icd->user_height/0x800));
787 session.pid = current->pid;
788 INIT_LIST_HEAD(&session.waiting);
789 INIT_LIST_HEAD(&session.running);
790 INIT_LIST_HEAD(&session.list_session);
791 init_waitqueue_head(&session.wait);
792 /* no need to protect */
793 list_add_tail(&session.list_session, &rga_service.session);
794 atomic_set(&session.task_running, 0);
795 atomic_set(&session.num_done, 0);
797 memset(&req,0,sizeof(struct rga_req));
798 req.src.act_w = pcdev->zoominfo.a.c.width/scale_times;
799 req.src.act_h = pcdev->zoominfo.a.c.height/scale_times;
801 req.src.vir_w = pcdev->zoominfo.vir_width;
802 req.src.vir_h =pcdev->zoominfo.vir_height;
803 req.src.yrgb_addr = vipdata_base;
804 req.src.uv_addr =vipdata_base + req.src.vir_w*req.src.vir_h;
805 req.src.v_addr = req.src.uv_addr ;
806 req.src.format =fmt->fourcc;
807 rk_pixfmt2rgafmt(fmt->fourcc,&req.src.format);
808 req.src.x_offset = pcdev->zoominfo.a.c.left;
809 req.src.y_offset = pcdev->zoominfo.a.c.top;
811 req.dst.act_w = pcdev->icd->user_width/scale_times;
812 req.dst.act_h = pcdev->icd->user_height/scale_times;
814 req.dst.vir_w = pcdev->icd->user_width;
815 req.dst.vir_h = pcdev->icd->user_height;
816 req.dst.x_offset = 0;
817 req.dst.y_offset = 0;
818 req.dst.yrgb_addr = vb->boff;
819 rk_pixfmt2rgafmt(pcdev->icd->current_fmt->host_fmt->fourcc,&req.dst.format);
821 req.clip.xmax = req.dst.vir_w-1;
823 req.clip.ymax = req.dst.vir_h -1;
830 req.mmu_info.mmu_en = 0;
832 for (h=0; h<scale_times; h++) {
833 for (w=0; w<scale_times; w++) {
836 req.src.yrgb_addr = vipdata_base;
837 req.src.uv_addr =vipdata_base +req.src.vir_w *req.src.vir_h ;
838 req.src.x_offset = pcdev->zoominfo.a.c.left+w*pcdev->zoominfo.a.c.width/scale_times;
839 req.src.y_offset = pcdev->zoominfo.a.c.top+h*pcdev->zoominfo.a.c.height/scale_times;
840 req.dst.x_offset = pcdev->icd->user_width*w/scale_times;
841 req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
842 req.dst.yrgb_addr = vb->boff ;
843 // RKCAMERA_TR("src.act_w = %d , src.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
844 // RKCAMERA_TR("dst.act_w = %d , dst.act_h = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
845 // RKCAMERA_TR("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
847 while(rga_times-- > 0) {
848 if (rga_blit_sync(&session, &req)){
849 RKCAMERA_TR("rga do erro,do again,rga_times = %d!\n",rga_times);
855 if (rga_times <= 0) {
856 spin_lock_irqsave(&pcdev->lock, flags);
857 vb->state = VIDEOBUF_NEEDS_INIT;
858 spin_unlock_irqrestore(&pcdev->lock, flags);
859 mutex_lock(&rga_service.lock);
860 list_del(&session.list_session);
861 rga_service_session_clear(&session);
862 mutex_unlock(&rga_service.lock);
868 mutex_lock(&rga_service.lock);
869 list_del(&session.list_session);
870 rga_service_session_clear(&session);
871 mutex_unlock(&rga_service.lock);
880 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
882 static int rk_camera_scale_crop_ipp(struct work_struct *work)
884 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
885 struct videobuf_buffer *vb = camera_work->vb;
886 struct rk_camera_dev *pcdev = camera_work->pcdev;
888 unsigned long int flags;
890 struct rk29_ipp_req ipp_req;
891 int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
896 * IPP Dest image resolution is 2047x1088, so scale operation break up some times
898 if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
899 scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));
904 memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
907 ipp_req.timeout = 3000;
908 ipp_req.flag = IPP_ROT_0;
909 ipp_req.store_clip_mode =1;
910 ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
911 ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
912 ipp_req.src_vir_w = pcdev->zoominfo.vir_width;
913 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
914 ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
915 ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
916 ipp_req.dst_vir_w = pcdev->icd->user_width;
917 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
918 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
919 src_y_size = pcdev->host_width*pcdev->host_height; //vipmem
920 dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
921 for (h=0; h<scale_times; h++) {
922 for (w=0; w<scale_times; w++) {
924 src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width
925 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
926 src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width/2
927 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
929 dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
930 dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
932 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
933 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
934 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
935 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
936 while(ipp_times-- > 0) {
937 if (ipp_blit_sync(&ipp_req)){
938 RKCAMERA_TR("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
944 if (ipp_times <= 0) {
945 spin_lock_irqsave(&pcdev->lock, flags);
946 vb->state = VIDEOBUF_NEEDS_INIT;
947 spin_unlock_irqrestore(&pcdev->lock, flags);
948 RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
949 RKCAMERA_TR("widx:%d hidx:%d ",w,h);
950 RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
951 RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
952 RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
953 RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
954 RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
955 RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
956 RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
957 RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
958 RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
969 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
970 static int rk_camera_scale_crop_arm(struct work_struct *work)
972 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
973 struct videobuf_buffer *vb = camera_work->vb;
974 struct rk_camera_dev *pcdev = camera_work->pcdev;
975 struct rk29_camera_vbinfo *vb_info;
976 unsigned char *psY,*pdY,*psUV,*pdUV;
977 unsigned char *src,*dst;
978 unsigned long src_phy,dst_phy;
979 int srcW,srcH,cropW,cropH,dstW,dstH;
980 long zoomindstxIntInv,zoomindstyIntInv;
982 long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
987 src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
988 src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
989 psUV = psY + pcdev->host_width*pcdev->host_height;
991 srcW = pcdev->zoominfo.vir_width;
992 srcH = pcdev->zoominfo.vir_height;
993 cropW = pcdev->zoominfo.a.c.width;
994 cropH = pcdev->zoominfo.a.c.height;
996 psY = psY + (srcW-cropW);
997 psUV = psUV + (srcW-cropW);
999 vb_info = pcdev->vbinfo+vb->i;
1000 dst_phy = vb_info->phy_addr;
1001 dst = pdY = (unsigned char*)vb_info->vir_addr;
1002 pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
1003 dstW = pcdev->icd->user_width;
1004 dstH = pcdev->icd->user_height;
1006 zoomindstxIntInv = ((unsigned long)cropW<<16)/dstW + 1;
1007 zoomindstyIntInv = ((unsigned long)cropH<<16)/dstH + 1;
1010 //for(y = 0; y<dstH - 1 ; y++ ) {
1011 for(y = 0; y<dstH; y++ ) {
1012 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1013 yCoeff01 = 0xffff - yCoeff00;
1014 sY = (y*zoomindstyIntInv >> 16);
1016 for(x = 0; x<dstW; x++ ) {
1017 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1018 xCoeff01 = 0xffff - xCoeff00;
1019 sX = (x*zoomindstxIntInv >> 16);
1021 a = psY[sY*srcW + sX];
1022 b = psY[sY*srcW + sX + 1];
1023 c = psY[(sY+1)*srcW + sX];
1024 d = psY[(sY+1)*srcW + sX + 1];
1026 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1027 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1028 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1041 //for(y = 0; y<dstH - 1 ; y++ ) {
1042 for(y = 0; y<dstH; y++ ) {
1043 yCoeff00 = (y*zoomindstyIntInv)&0xffff;
1044 yCoeff01 = 0xffff - yCoeff00;
1045 sY = (y*zoomindstyIntInv >> 16);
1047 for(x = 0; x<dstW; x++ ) {
1048 xCoeff00 = (x*zoomindstxIntInv)&0xffff;
1049 xCoeff01 = 0xffff - xCoeff00;
1050 sX = (x*zoomindstxIntInv >> 16);
1053 a = psUV[(sY*srcW + sX)*2];
1054 b = psUV[(sY*srcW + sX + 1)*2];
1055 c = psUV[((sY+1)*srcW + sX)*2];
1056 d = psUV[((sY+1)*srcW + sX + 1)*2];
1058 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1059 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1060 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1065 a = psUV[(sY*srcW + sX)*2 + 1];
1066 b = psUV[(sY*srcW + sX + 1)*2 + 1];
1067 c = psUV[((sY+1)*srcW + sX)*2 + 1];
1068 d = psUV[((sY+1)*srcW + sX + 1)*2 + 1];
1070 r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
1071 r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
1072 r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
1079 rk_camera_scale_crop_arm_end:
1081 dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
1082 outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
1084 dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
1085 outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
1090 static void rk_camera_capture_process(struct work_struct *work)
1092 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1093 struct videobuf_buffer *vb = camera_work->vb;
1094 struct rk_camera_dev *pcdev = camera_work->pcdev;
1095 //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;
1096 unsigned long flags = 0;
1099 if (!CAM_WORKQUEUE_IS_EN())
1100 goto rk_camera_capture_process_end;
1102 down(&pcdev->zoominfo.sem);
1103 if (pcdev->icd_cb.scale_crop_cb){
1104 err = (pcdev->icd_cb.scale_crop_cb)(work);
1106 up(&pcdev->zoominfo.sem);
1108 if (pcdev->icd_cb.sensor_cb)
1109 (pcdev->icd_cb.sensor_cb)(vb);
1111 rk_camera_capture_process_end:
1113 vb->state = VIDEOBUF_ERROR;
1115 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1116 vb->state = VIDEOBUF_DONE;
1120 wake_up(&(camera_work->vb->done));
1121 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
1122 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
1123 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
1126 static irqreturn_t rk_camera_irq(int irq, void *data)
1128 struct rk_camera_dev *pcdev = data;
1129 struct videobuf_buffer *vb;
1130 struct rk_camera_work *wk;
1132 unsigned long tmp_intstat;
1133 unsigned long tmp_cifctrl;
1135 tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
1136 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1137 if(pcdev->stop_cif == true)
1139 printk("cif has stopped by app,needn't to deal this irq\n");
1140 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
1143 if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/){//bit9 =1 ,bit0 = 0
1144 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
1145 if(tmp_cifctrl & ENABLE_CAPTURE)
1146 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
1150 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
1151 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
1152 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
1154 do_gettimeofday(&pcdev->first_tv);
1158 goto RK_CAMERA_IRQ_END;
1159 if (pcdev->frame_inval>0) {
1160 pcdev->frame_inval--;
1161 rk_videobuf_capture(pcdev->active,pcdev);
1162 goto RK_CAMERA_IRQ_END;
1163 } else if (pcdev->frame_inval) {
1164 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
1165 pcdev->frame_inval = 0;
1167 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
1168 do_gettimeofday(&tv);
1169 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
1170 /(RK30_CAM_FRAME_MEASURE-1);
1174 printk("no acticve buffer!!!\n");
1175 goto RK_CAMERA_IRQ_END;
1177 /* ddl@rock-chips.com : this vb may be deleted from queue */
1178 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1179 list_del_init(&vb->queue);
1181 pcdev->active = NULL;
1182 if (!list_empty(&pcdev->capture)) {
1183 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
1184 if (pcdev->active) {
1185 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
1186 rk_videobuf_capture(pcdev->active,pcdev);
1189 if (pcdev->active == NULL) {
1190 RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
1193 do_gettimeofday(&vb->ts);
1194 if (CAM_WORKQUEUE_IS_EN()) {
1195 if (!list_empty(&pcdev->camera_work_queue)) {
1196 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
1197 list_del_init(&wk->queue);
1198 INIT_WORK(&(wk->work), rk_camera_capture_process);
1201 queue_work(pcdev->camera_wq, &(wk->work));
1204 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
1205 vb->state = VIDEOBUF_DONE;
1214 if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
1215 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
1220 static void rk_videobuf_release(struct videobuf_queue *vq,
1221 struct videobuf_buffer *vb)
1223 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
1224 struct soc_camera_device *icd = vq->priv_data;
1225 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1226 struct rk_camera_dev *pcdev = ici->priv;
1227 struct rk29_camera_vbinfo *vb_info =NULL;
1229 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1230 vb, vb->baddr, vb->bsize);
1234 case VIDEOBUF_ACTIVE:
1235 dev_dbg(&icd->dev, "%s (active)\n", __func__);
1237 case VIDEOBUF_QUEUED:
1238 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
1240 case VIDEOBUF_PREPARED:
1241 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
1244 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
1248 if (vb == pcdev->active) {
1249 RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
1250 interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
1251 RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
1254 flush_workqueue(pcdev->camera_wq);
1255 #if CAMERA_VIDEOBUF_ARM_ACCESS
1256 if (pcdev->vbinfo) {
1257 vb_info = pcdev->vbinfo + vb->i;
1259 if (vb_info->vir_addr) {
1260 iounmap(vb_info->vir_addr);
1261 release_mem_region(vb_info->phy_addr, vb_info->size);
1262 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1267 rk_videobuf_free(vq, buf);
1270 static struct videobuf_queue_ops rk_videobuf_ops =
1272 .buf_setup = rk_videobuf_setup,
1273 .buf_prepare = rk_videobuf_prepare,
1274 .buf_queue = rk_videobuf_queue,
1275 .buf_release = rk_videobuf_release,
1278 static void rk_camera_init_videobuf(struct videobuf_queue *q,
1279 struct soc_camera_device *icd)
1281 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1282 struct rk_camera_dev *pcdev = ici->priv;
1284 /* We must pass NULL as dev pointer, then all pci_* dma operations
1285 * transform to normal dma_* ones. */
1286 videobuf_queue_dma_contig_init(q,
1288 ici->v4l2_dev.dev, &pcdev->lock,
1289 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1291 sizeof(struct rk_camera_buffer),
1292 icd,&icd->video_lock);
1294 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
1298 if(!pcdev->aclk_cif || !pcdev->hclk_cif || !pcdev->cif_clk_in || !pcdev->cif_clk_out){
1299 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
1301 goto RK_CAMERA_ACTIVE_ERR;
1304 clk_enable(pcdev->pd_cif);
1305 clk_enable(pcdev->aclk_cif);
1307 clk_enable(pcdev->hclk_cif);
1308 clk_enable(pcdev->cif_clk_in);
1310 //if (icd->ops->query_bus_param) /* ddl@rock-chips.com : Query Sensor's xclk */
1311 //sensor_bus_flags = icd->ops->query_bus_param(icd);
1312 clk_enable(pcdev->cif_clk_out);
1313 clk_set_rate(pcdev->cif_clk_out,RK_SENSOR_24MHZ);
1316 //soft reset the registers
1317 #if 0 //has somthing wrong when suspend and resume now
1319 printk("before set cru register reset cif0 0x%x\n\n",read_cru_reg(CRU_CIF_RST_REG30));
1322 printk("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
1323 printk("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
1324 printk("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
1325 printk("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
1326 printk("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
1327 printk("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
1328 printk("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
1329 printk("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
1330 printk("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
1332 printk("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
1333 printk("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
1334 printk("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
1335 printk("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
1336 printk("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
1337 printk("CIF_CIF_FRAME_STATUS = 0X%x\n\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
1341 write_cru_reg(CRU_CIF_RST_REG30,(/*read_cru_reg(CRU_CIF_RST_REG30)|*/MASK_RST_CIF0|RQUEST_RST_CIF0 ));
1342 printk("set cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1343 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1345 printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
1347 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1348 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1351 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1352 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
1353 RKCAMERA_DG("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
1355 RK_CAMERA_ACTIVE_ERR:
1359 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
1361 clk_disable(pcdev->aclk_cif);
1363 clk_disable(pcdev->hclk_cif);
1364 clk_disable(pcdev->cif_clk_in);
1366 clk_disable(pcdev->cif_clk_out);
1367 clk_enable(pcdev->cif_clk_out);
1368 clk_set_rate(pcdev->cif_clk_out,48*1000*1000);
1369 clk_disable(pcdev->cif_clk_out);
1371 clk_disable(pcdev->pd_cif);
1375 /* The following two functions absolutely depend on the fact, that
1376 * there can be only one camera on RK28 quick capture interface */
1377 static int rk_camera_add_device(struct soc_camera_device *icd)
1379 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1380 struct rk_camera_dev *pcdev = ici->priv;
1381 struct device *control = to_soc_camera_control(icd);
1382 struct v4l2_subdev *sd;
1383 int ret,i,icd_catch;
1384 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
1386 mutex_lock(&camera_lock);
1393 dev_info(&icd->dev, "RK Camera driver attached to camera%d(%s)\n",
1394 icd->devnum,dev_name(icd->pdev));
1396 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1397 pcdev->active = NULL;
1399 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1400 pcdev->zoominfo.zoom_rate = 100;
1401 pcdev->fps_timer.istarted = false;
1403 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1404 * if app havn't dequeue all videobuf before close camera device;
1406 INIT_LIST_HEAD(&pcdev->capture);
1408 ret = rk_camera_activate(pcdev,icd);
1411 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
1413 sd = dev_get_drvdata(control);
1414 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
1416 ret = v4l2_subdev_call(sd,core, init, 0);
1420 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
1423 pcdev->icd_init = 0;
1426 for (i=0; i<2; i++) {
1427 if (pcdev->icd_frmival[i].icd == icd)
1429 if (pcdev->icd_frmival[i].icd == NULL) {
1430 pcdev->icd_frmival[i].icd = icd;
1434 if (icd_catch == 0) {
1435 fival_list = pcdev->icd_frmival[0].fival_list;
1436 fival_nxt = fival_list;
1437 while(fival_nxt != NULL) {
1438 fival_nxt = fival_list->nxt;
1440 fival_list = fival_nxt;
1442 pcdev->icd_frmival[0].icd = icd;
1443 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
1446 mutex_unlock(&camera_lock);
1450 static void rk_camera_remove_device(struct soc_camera_device *icd)
1452 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1453 struct rk_camera_dev *pcdev = ici->priv;
1454 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1455 struct rk29_camera_vbinfo *vb_info;
1458 mutex_lock(&camera_lock);
1459 BUG_ON(icd != pcdev->icd);
1461 dev_info(&icd->dev, "RK Camera driver detached from camera%d(%s)\n",
1462 icd->devnum,dev_name(icd->pdev));
1464 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1465 stream may be turn on again before close device, if suspend and resume happened. */
1466 if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
1467 rk_camera_s_stream(icd,0);
1470 //soft reset the registers
1471 #if 0 //has somthing wrong when suspend and resume now
1473 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF0|RQUEST_RST_CIF0 | (read_cru_reg(CRU_CIF_RST_REG30)));
1474 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1476 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1477 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1480 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
1481 //if stream off is not been executed,timer is running.
1482 if(pcdev->fps_timer.istarted){
1483 hrtimer_cancel(&pcdev->fps_timer.timer);
1484 pcdev->fps_timer.istarted = false;
1486 flush_work(&(pcdev->camera_reinit_work.work));
1487 flush_workqueue((pcdev->camera_wq));
1489 if (pcdev->camera_work) {
1490 kfree(pcdev->camera_work);
1491 pcdev->camera_work = NULL;
1492 pcdev->camera_work_count = 0;
1493 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1495 rk_camera_deactivate(pcdev);
1496 #if CAMERA_VIDEOBUF_ARM_ACCESS
1497 if (pcdev->vbinfo) {
1498 vb_info = pcdev->vbinfo;
1499 for (i=0; i<pcdev->vbinfo_count; i++) {
1500 if (vb_info->vir_addr) {
1501 iounmap(vb_info->vir_addr);
1502 release_mem_region(vb_info->phy_addr, vb_info->size);
1503 memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
1507 kfree(pcdev->vbinfo);
1508 pcdev->vbinfo = NULL;
1509 pcdev->vbinfo_count = 0;
1512 pcdev->active = NULL;
1514 pcdev->icd_cb.sensor_cb = NULL;
1515 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1516 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1517 * if app havn't dequeue all videobuf before close camera device;
1519 INIT_LIST_HEAD(&pcdev->capture);
1521 mutex_unlock(&camera_lock);
1522 RKCAMERA_DG("%s exit\n",__FUNCTION__);
1526 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1528 unsigned long bus_flags, camera_flags, common_flags;
1529 unsigned int cif_ctrl_val = 0;
1530 const struct soc_mbus_pixelfmt *fmt;
1532 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1533 struct rk_camera_dev *pcdev = ici->priv;
1534 RKCAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
1536 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1540 bus_flags = RK_CAM_BUS_PARAM;
1541 /* If requested data width is supported by the platform, use it */
1542 switch (fmt->bits_per_sample) {
1544 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1548 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1552 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1559 if (icd->ops->query_bus_param)
1560 camera_flags = icd->ops->query_bus_param(icd);
1564 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1565 if (!common_flags) {
1567 goto RK_CAMERA_SET_BUS_PARAM_END;
1570 ret = icd->ops->set_bus_param(icd, common_flags);
1572 goto RK_CAMERA_SET_BUS_PARAM_END;
1574 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1575 RKCAMERA_DG("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
1576 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1578 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1579 RKCAMERA_DG("enable cif0 pclk invert\n");
1581 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1582 RKCAMERA_DG("enable cif1 pclk invert\n");
1586 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1587 RKCAMERA_DG("diable cif0 pclk invert\n");
1589 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1590 RKCAMERA_DG("diable cif1 pclk invert\n");
1593 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
1594 cif_ctrl_val |= HSY_LOW_ACTIVE;
1596 cif_ctrl_val &= ~HSY_LOW_ACTIVE;
1598 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1599 cif_ctrl_val |= VSY_HIGH_ACTIVE;
1601 cif_ctrl_val &= ~VSY_HIGH_ACTIVE;
1604 /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1605 //vip_ctrl_val |= ENABLE_CAPTURE;
1606 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
1607 RKCAMERA_DG("%s..ctrl:0x%x CIF_CIF_FOR=%x \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1609 RK_CAMERA_SET_BUS_PARAM_END:
1611 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1615 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1617 unsigned long bus_flags, camera_flags;
1620 bus_flags = RK_CAM_BUS_PARAM;
1621 if (icd->ops->query_bus_param) {
1622 camera_flags = icd->ops->query_bus_param(icd);
1626 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1629 dev_warn(icd->dev.parent,
1630 "Flags incompatible: camera %lx, host %lx\n",
1631 camera_flags, bus_flags);
1635 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1637 .fourcc = V4L2_PIX_FMT_NV12,
1638 .name = "YUV420 NV12",
1639 .bits_per_sample = 8,
1640 .packing = SOC_MBUS_PACKING_1_5X8,
1641 .order = SOC_MBUS_ORDER_LE,
1643 .fourcc = V4L2_PIX_FMT_NV16,
1644 .name = "YUV422 NV16",
1645 .bits_per_sample = 8,
1646 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1647 .order = SOC_MBUS_ORDER_LE,
1649 .fourcc = V4L2_PIX_FMT_NV21,
1650 .name = "YUV420 NV21",
1651 .bits_per_sample = 8,
1652 .packing = SOC_MBUS_PACKING_1_5X8,
1653 .order = SOC_MBUS_ORDER_LE,
1655 .fourcc = V4L2_PIX_FMT_NV61,
1656 .name = "YUV422 NV61",
1657 .bits_per_sample = 8,
1658 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1659 .order = SOC_MBUS_ORDER_LE,
1661 .fourcc = V4L2_PIX_FMT_RGB565,
1663 .bits_per_sample = 8,
1664 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1665 .order = SOC_MBUS_ORDER_LE,
1667 .fourcc = V4L2_PIX_FMT_RGB24,
1669 .bits_per_sample = 8,
1670 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1671 .order = SOC_MBUS_ORDER_LE,
1675 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1677 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1678 struct rk_camera_dev *pcdev = ici->priv;
1679 unsigned int cif_fs = 0,cif_crop = 0;
1680 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;
1682 const struct soc_mbus_pixelfmt *fmt;
1683 fmt = soc_mbus_get_fmtdesc(icd_code);
1685 if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
1686 if(fmt->fourcc == V4L2_PIX_FMT_NV12)
1687 host_pixfmt = V4L2_PIX_FMT_NV12;
1688 else if(fmt->fourcc == V4L2_PIX_FMT_NV21)
1689 host_pixfmt = V4L2_PIX_FMT_NV21;
1691 switch (host_pixfmt)
1693 case V4L2_PIX_FMT_NV16:
1694 cif_fmt_val &= ~YUV_OUTPUT_422;
1695 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1696 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1697 pcdev->pixfmt = host_pixfmt;
1699 case V4L2_PIX_FMT_NV61:
1700 cif_fmt_val &= ~YUV_OUTPUT_422;
1701 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1702 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1703 pcdev->pixfmt = host_pixfmt;
1705 case V4L2_PIX_FMT_NV12:
1706 cif_fmt_val |= YUV_OUTPUT_420;
1707 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1708 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1709 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1710 pcdev->pixfmt = host_pixfmt;
1712 case V4L2_PIX_FMT_NV21:
1713 cif_fmt_val |= YUV_OUTPUT_420;
1714 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1715 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1716 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1717 pcdev->pixfmt = host_pixfmt;
1719 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1720 cif_fmt_val |= YUV_OUTPUT_422;
1725 case V4L2_MBUS_FMT_UYVY8_2X8:
1726 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1728 case V4L2_MBUS_FMT_YUYV8_2X8:
1729 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1731 case V4L2_MBUS_FMT_YVYU8_2X8:
1732 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1734 case V4L2_MBUS_FMT_VYUY8_2X8:
1735 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1738 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1743 #ifdef CONFIG_ARCH_RK30
1746 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1747 cru_set_soft_reset(SOFT_RST_CIF0, true);
1749 cru_set_soft_reset(SOFT_RST_CIF0, false);
1750 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1753 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1754 cru_set_soft_reset(SOFT_RST_CIF1, true);
1756 cru_set_soft_reset(SOFT_RST_CIF1, false);
1757 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1761 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1762 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable
1764 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 */
1766 // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */
1767 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1768 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1769 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1771 } else{ // this is one frame mode
1772 cif_crop = (rect->left+ (rect->top<<16));
1773 cif_fs = ((rect->width ) + (rect->height<<16));
1775 RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__);
1777 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1778 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1779 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1780 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1783 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1784 RKCAMERA_DG("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1788 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1789 struct soc_camera_format_xlate *xlate)
1791 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1792 struct device *dev = icd->dev.parent;
1793 int formats = 0, ret;
1794 enum v4l2_mbus_pixelcode code;
1795 const struct soc_mbus_pixelfmt *fmt;
1797 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1799 /* No more formats */
1802 fmt = soc_mbus_get_fmtdesc(code);
1804 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1808 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1813 case V4L2_MBUS_FMT_UYVY8_2X8:
1814 case V4L2_MBUS_FMT_YUYV8_2X8:
1815 case V4L2_MBUS_FMT_YVYU8_2X8:
1816 case V4L2_MBUS_FMT_VYUY8_2X8:
1817 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
1820 xlate->host_fmt = &rk_camera_formats[0];
1823 dev_dbg(dev, "Providing format %s using code %d\n",
1824 rk_camera_formats[0].name,code);
1829 xlate->host_fmt = &rk_camera_formats[1];
1832 dev_dbg(dev, "Providing format %s using code %d\n",
1833 rk_camera_formats[1].name,code);
1838 xlate->host_fmt = &rk_camera_formats[2];
1841 dev_dbg(dev, "Providing format %s using code %d\n",
1842 rk_camera_formats[2].name,code);
1847 xlate->host_fmt = &rk_camera_formats[3];
1850 dev_dbg(dev, "Providing format %s using code %d\n",
1851 rk_camera_formats[3].name,code);
1857 xlate->host_fmt = &rk_camera_formats[4];
1860 dev_dbg(dev, "Providing format %s using code %d\n",
1861 rk_camera_formats[4].name,code);
1865 xlate->host_fmt = &rk_camera_formats[5];
1868 dev_dbg(dev, "Providing format %s using code %d\n",
1869 rk_camera_formats[5].name,code);
1880 static void rk_camera_put_formats(struct soc_camera_device *icd)
1885 static int rk_camera_set_crop(struct soc_camera_device *icd,
1886 struct v4l2_crop *a)
1888 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1889 struct v4l2_mbus_framefmt mf;
1890 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1893 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1897 if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) {
1899 mf.width = a->c.left + a->c.width;
1900 mf.height = a->c.top + a->c.height;
1902 v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
1903 &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
1904 fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
1906 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1911 rk_camera_setup_format(icd, fourcc, mf.code, &a->c);
1913 icd->user_width = mf.width;
1914 icd->user_height = mf.height;
1919 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1920 struct v4l2_format *f)
1922 struct device *dev = icd->dev.parent;
1923 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1924 const struct soc_camera_format_xlate *xlate = NULL;
1925 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
1926 struct rk_camera_dev *pcdev = ici->priv;
1927 struct v4l2_pix_format *pix = &f->fmt.pix;
1928 struct v4l2_mbus_framefmt mf;
1929 struct v4l2_rect rect;
1930 int ret,usr_w,usr_h;
1934 usr_h = pix->height;
1935 RKCAMERA_TR("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
1936 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1938 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1940 goto RK_CAMERA_SET_FMT_END;
1943 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1944 if (pcdev->icd_init == 0) {
1945 v4l2_subdev_call(sd,core, init, 0);
1946 pcdev->icd_init = 1;
1948 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1949 if (stream_on & ENABLE_CAPTURE)
1950 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1952 mf.width = pix->width;
1953 mf.height = pix->height;
1954 mf.field = pix->field;
1955 mf.colorspace = pix->colorspace;
1956 mf.code = xlate->code;
1957 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1958 if (mf.code != xlate->code)
1960 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1961 if ((mf.width != usr_w) || (mf.height != usr_h)) {
1963 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1964 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
1966 goto RK_CAMERA_SET_FMT_END;
1968 if (unlikely((usr_w <16)||(usr_h < 16))) {
1969 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1971 goto RK_CAMERA_SET_FMT_END;
1974 if((mf.width*10/mf.height) != (usr_w*10/usr_h)){
1975 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
1976 pcdev->host_width = ratio*usr_w/10;
1977 pcdev->host_height = ratio*usr_h/10;
1978 //for ipp ,need 4 bit alligned.
1979 pcdev->host_width &= ~0x03;
1980 pcdev->host_height &= ~0x03;
1981 RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
1983 else{ // needn't crop ,just scaled by ipp
1984 pcdev->host_width = mf.width;
1985 pcdev->host_height = mf.height;
1989 pcdev->host_width = usr_w;
1990 pcdev->host_height = usr_h;
1993 //according to crop and scale capability to change , here just cropt to user needed
1994 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1995 RKCAMERA_TR("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
1997 goto RK_CAMERA_SET_FMT_END;
1999 if (unlikely((usr_w <16)||(usr_h < 16))) {
2000 RKCAMERA_TR("Senor invalid destination resolution(%dx%d)\n",usr_w,usr_h);
2002 goto RK_CAMERA_SET_FMT_END;
2004 pcdev->host_width = usr_w;
2005 pcdev->host_height = usr_h;
2009 RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__,
2010 pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h);
2011 rect.width = pcdev->host_width;
2012 rect.height = pcdev->host_height;
2013 rect.left = ((mf.width-pcdev->host_width )>>1)&(~0x01);
2014 rect.top = ((mf.height-pcdev->host_height)>>1)&(~0x01);
2015 pcdev->host_left = rect.left;
2016 pcdev->host_top = rect.top;
2018 down(&pcdev->zoominfo.sem);
2019 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
2020 pcdev->zoominfo.a.c.width &= ~0x03;
2021 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
2022 pcdev->zoominfo.a.c.height &= ~0x03;
2023 //now digital zoom use ipp to do crop and scale
2024 if(pcdev->zoominfo.zoom_rate != 100){
2025 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
2026 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
2029 pcdev->zoominfo.a.c.left = 0;
2030 pcdev->zoominfo.a.c.top = 0;
2032 pcdev->zoominfo.vir_width = pcdev->host_width;
2033 up(&pcdev->zoominfo.sem);
2035 /* ddl@rock-chips.com: IPP work limit check */
2036 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
2037 if (usr_w > 0x7f0) {
2038 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
2039 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));
2041 goto RK_CAMERA_SET_FMT_END;
2044 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
2045 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
2047 goto RK_CAMERA_SET_FMT_END;
2051 RKCAMERA_DG("%s..%s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
2052 rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
2053 pix->width, pix->height);
2054 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
2056 if (CAM_IPPWORK_IS_EN()) {
2057 BUG_ON(pcdev->vipmem_phybase == 0);
2060 pix->height = usr_h;
2061 pix->field = mf.field;
2062 pix->colorspace = mf.colorspace;
2063 icd->current_fmt = xlate;
2064 pcdev->icd_width = mf.width;
2065 pcdev->icd_height = mf.height;
2068 RK_CAMERA_SET_FMT_END:
2069 if (stream_on & ENABLE_CAPTURE)
2070 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
2072 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2075 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
2079 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
2081 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
2083 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
2085 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
2087 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
2092 RKCAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
2095 static int rk_camera_try_fmt(struct soc_camera_device *icd,
2096 struct v4l2_format *f)
2098 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2099 struct rk_camera_dev *pcdev = ici->priv;
2100 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
2101 const struct soc_camera_format_xlate *xlate;
2102 struct v4l2_pix_format *pix = &f->fmt.pix;
2103 __u32 pixfmt = pix->pixelformat;
2104 int ret,usr_w,usr_h,i;
2105 bool is_capture = rk_camera_fmt_capturechk(f);
2106 bool vipmem_is_overflow = false;
2107 struct v4l2_mbus_framefmt mf;
2108 int bytes_per_line_host;
2111 usr_h = pix->height;
2112 RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
2114 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
2116 dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
2117 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
2119 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
2120 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
2121 for (i = 0; i < icd->num_user_formats; i++)
2122 RKCAMERA_TR("(%c%c%c%c)-%s\n",
2123 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
2124 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
2125 icd->user_formats[i].host_fmt->name);
2126 goto RK_CAMERA_TRY_FMT_END;
2128 /* limit to rk29 hardware capabilities */
2129 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
2130 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
2131 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
2133 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
2135 if (pix->bytesperline < 0)
2136 return pix->bytesperline;
2138 /* limit to sensor capabilities */
2139 mf.width = pix->width;
2140 mf.height = pix->height;
2141 mf.field = pix->field;
2142 mf.colorspace = pix->colorspace;
2143 mf.code = xlate->code;
2145 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
2147 goto RK_CAMERA_TRY_FMT_END;
2148 RKCAMERA_DG("%s mf.width:%d mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
2149 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2150 if ((mf.width != usr_w) || (mf.height != usr_h)) {
2151 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
2153 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
2155 /* Assume preview buffer minimum is 4 */
2156 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
2158 if (vipmem_is_overflow == false) {
2160 pix->height = usr_h;
2162 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
2163 pix->width = mf.width;
2164 pix->height = mf.height;
2167 if ((mf.width < usr_w) || (mf.height < usr_h)) {
2168 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
2169 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
2170 pix->width = mf.width;
2171 pix->height = mf.height;
2176 //need to change according to crop and scale capablicity
2177 if ((mf.width > usr_w) && (mf.height > usr_h)) {
2179 pix->height = usr_h;
2180 } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
2181 RKCAMERA_TR("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
2182 pix->width = mf.width;
2183 pix->height = mf.height;
2186 pix->colorspace = mf.colorspace;
2189 case V4L2_FIELD_ANY:
2190 case V4L2_FIELD_NONE:
2191 pix->field = V4L2_FIELD_NONE;
2194 /* TODO: support interlaced at least in pass-through mode */
2195 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
2197 goto RK_CAMERA_TRY_FMT_END;
2200 RK_CAMERA_TRY_FMT_END:
2202 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
2206 static int rk_camera_reqbufs(struct soc_camera_device *icd,
2207 struct v4l2_requestbuffers *p)
2211 /* This is for locking debugging only. I removed spinlocks and now I
2212 * check whether .prepare is ever called on a linked buffer, or whether
2213 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
2214 * it hadn't triggered */
2215 for (i = 0; i < p->count; i++) {
2216 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
2217 struct rk_camera_buffer, vb);
2219 INIT_LIST_HEAD(&buf->vb.queue);
2225 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
2227 struct soc_camera_device *icd = file->private_data;
2228 struct rk_camera_buffer *buf;
2230 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
2233 poll_wait(file, &buf->vb.done, pt);
2235 if (buf->vb.state == VIDEOBUF_DONE ||
2236 buf->vb.state == VIDEOBUF_ERROR)
2237 return POLLIN|POLLRDNORM;
2242 static int rk_camera_querycap(struct soc_camera_host *ici,
2243 struct v4l2_capability *cap)
2245 struct rk_camera_dev *pcdev = ici->priv;
2246 char orientation[5];
2249 strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
2250 memset(orientation,0x00,sizeof(orientation));
2251 for (i=0; i<RK_CAM_NUM;i++) {
2252 if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
2253 sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
2257 if (orientation[0] != '-') {
2258 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
2259 if (strstr(dev_name(pcdev->icd->pdev),"front"))
2260 strcat(cap->card,"-270");
2262 strcat(cap->card,"-90");
2264 strcat(cap->card,orientation);
2266 cap->version = RK_CAM_VERSION_CODE;
2267 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2271 static void rk_camera_store_register(struct rk_camera_dev *pcdev)
2273 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2274 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2275 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2276 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2277 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2278 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2279 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2281 static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
2283 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2284 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2285 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2286 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2287 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2288 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2289 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2291 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
2293 struct soc_camera_host *ici =
2294 to_soc_camera_host(icd->dev.parent);
2295 struct rk_camera_dev *pcdev = ici->priv;
2296 struct v4l2_subdev *sd;
2299 mutex_lock(&camera_lock);
2300 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
2301 rk_camera_s_stream(icd, 0);
2302 sd = soc_camera_to_subdev(icd);
2303 v4l2_subdev_call(sd, video, s_stream, 0);
2304 ret = icd->ops->suspend(icd, state);
2306 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2307 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
2308 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
2309 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
2310 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
2311 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
2312 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
2314 pcdev->reginfo_suspend.Inval = Reg_Validate;
2315 rk_camera_deactivate(pcdev);
2317 RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__);
2319 RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
2321 mutex_unlock(&camera_lock);
2325 static int rk_camera_resume(struct soc_camera_device *icd)
2327 struct soc_camera_host *ici =
2328 to_soc_camera_host(icd->dev.parent);
2329 struct rk_camera_dev *pcdev = ici->priv;
2330 struct v4l2_subdev *sd;
2333 mutex_lock(&camera_lock);
2334 if ((pcdev->icd == icd) && (icd->ops->resume)) {
2335 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
2336 rk_camera_activate(pcdev, icd);
2337 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
2338 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
2339 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
2340 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
2341 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
2342 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
2343 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
2344 rk_videobuf_capture(pcdev->active,pcdev);
2345 rk_camera_s_stream(icd, 1);
2346 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
2348 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
2349 goto rk_camera_resume_end;
2352 ret = icd->ops->resume(icd);
2353 sd = soc_camera_to_subdev(icd);
2354 v4l2_subdev_call(sd, video, s_stream, 1);
2356 RKCAMERA_DG("%s Enter success\n",__FUNCTION__);
2358 RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
2361 rk_camera_resume_end:
2362 mutex_unlock(&camera_lock);
2366 static void rk_camera_reinit_work(struct work_struct *work)
2368 struct v4l2_subdev *sd;
2369 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
2370 struct rk_camera_dev *pcdev = camera_work->pcdev;
2371 struct soc_camera_link *tmp_soc_cam_link;
2373 unsigned long flags = 0;
2374 if(pcdev->icd == NULL)
2376 sd = soc_camera_to_subdev(pcdev->icd);
2377 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2380 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2381 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
2382 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
2383 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
2384 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
2385 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
2386 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
2387 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
2388 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
2390 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
2391 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
2392 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
2393 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
2394 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
2395 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
2398 pcdev->stop_cif = true;
2399 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
2400 RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
2402 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
2403 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
2404 if (NULL == pcdev->video_vq->bufs[index])
2407 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
2409 list_del_init(&pcdev->video_vq->bufs[index]->queue);
2410 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
2411 wake_up_all(&pcdev->video_vq->bufs[index]->done);
2412 printk("wake up video buffer index = %d !!!\n",index);
2415 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
2417 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
2419 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
2421 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
2422 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
2423 struct rk_camera_dev *pcdev = fps_timer->pcdev;
2425 // static unsigned int last_fps = 0;
2426 struct soc_camera_link *tmp_soc_cam_link;
2427 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
2429 RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
2430 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
2431 RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
2432 pcdev->camera_reinit_work.pcdev = pcdev;
2433 //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2434 pcdev->reinit_times++;
2435 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
2436 } else if(!pcdev->timer_get_fps) {
2437 pcdev->timer_get_fps = true;
2438 for (i=0; i<2; i++) {
2439 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
2440 fival_nxt = pcdev->icd_frmival[i].fival_list;
2445 fival_pre = fival_nxt;
2446 while (fival_nxt != NULL) {
2448 RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
2449 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
2450 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
2451 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
2452 fival_nxt->fival.discrete.numerator);
2454 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
2455 && (fival_nxt->fival.height == pcdev->icd->user_height)
2456 && (fival_nxt->fival.width == pcdev->icd->user_width))
2457 || (fival_nxt->fival.discrete.denominator == 0)) {
2459 if (fival_nxt->fival.discrete.denominator == 0) {
2460 fival_nxt->fival.index = 0;
2461 fival_nxt->fival.width = pcdev->icd->user_width;
2462 fival_nxt->fival.height= pcdev->icd->user_height;
2463 fival_nxt->fival.pixel_format = pcdev->pixfmt;
2464 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
2465 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2466 |(pcdev->icd_height);
2467 fival_nxt->fival.discrete.numerator = 1000000;
2468 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2471 fival_rec = fival_nxt;
2473 fival_pre = fival_nxt;
2474 fival_nxt = fival_nxt->nxt;
2477 if ((rec_flag == 0) && fival_pre) {
2478 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
2479 if (fival_pre->nxt != NULL) {
2480 fival_pre->nxt->fival.index = fival_pre->fival.index++;
2481 fival_pre->nxt->fival.width = pcdev->icd->user_width;
2482 fival_pre->nxt->fival.height= pcdev->icd->user_height;
2483 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
2485 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
2486 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
2487 |(pcdev->icd_height);
2488 fival_pre->nxt->fival.discrete.numerator = 1000000;
2489 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
2491 fival_rec = fival_pre->nxt;
2495 pcdev->last_fps = pcdev->fps ;
2496 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
2497 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
2498 //return HRTIMER_NORESTART;
2499 if(pcdev->reinit_times >=2)
2500 return HRTIMER_NORESTART;
2502 return HRTIMER_RESTART;
2504 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
2506 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2507 struct rk_camera_dev *pcdev = ici->priv;
2510 unsigned long flags;
2512 WARN_ON(pcdev->icd != icd);
2514 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2517 pcdev->last_fps = 0;
2518 pcdev->frame_interval = 0;
2519 hrtimer_cancel(&(pcdev->fps_timer.timer));
2520 pcdev->fps_timer.pcdev = pcdev;
2521 pcdev->timer_get_fps = false;
2522 pcdev->reinit_times = 0;
2523 pcdev->stop_cif = false;
2524 // hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2525 cif_ctrl_val |= ENABLE_CAPTURE;
2526 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2527 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2528 pcdev->fps_timer.istarted = true;
2530 //cancel timer before stop cif
2531 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2532 pcdev->fps_timer.istarted = false;
2533 flush_work(&(pcdev->camera_reinit_work.work));
2535 cif_ctrl_val &= ~ENABLE_CAPTURE;
2536 spin_lock_irqsave(&pcdev->lock, flags);
2537 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2538 pcdev->stop_cif = true;
2539 spin_unlock_irqrestore(&pcdev->lock, flags);
2540 flush_workqueue((pcdev->camera_wq));
2541 RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
2543 //must be reinit,or will be somthing wrong in irq process.
2544 if(enable == false){
2545 pcdev->active = NULL;
2546 INIT_LIST_HEAD(&pcdev->capture);
2548 RKCAMERA_DG("%s.. enable : 0x%x , CIF_CIF_CTRL = 0x%x\n", __FUNCTION__, enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2551 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2553 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2554 struct rk_camera_dev *pcdev = ici->priv;
2555 struct rk_camera_frmivalenum *fival_list = NULL;
2556 struct v4l2_frmivalenum *fival_head = NULL;
2557 int i,ret = 0,index;
2559 index = fival->index & 0x00ffffff;
2560 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2561 for (i=0; i<2; i++) {
2562 if (pcdev->icd_frmival[i].icd == icd) {
2563 fival_list = pcdev->icd_frmival[i].fival_list;
2567 if (fival_list != NULL) {
2569 while (fival_list != NULL) {
2570 if ((fival->pixel_format == fival_list->fival.pixel_format)
2571 && (fival->height == fival_list->fival.height)
2572 && (fival->width == fival_list->fival.width)) {
2577 fival_list = fival_list->nxt;
2580 if ((i==index) && (fival_list != NULL)) {
2581 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2586 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2591 for (i=0; i<RK_CAM_NUM; i++) {
2592 if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
2593 fival_head = pcdev->pdata->info[i].fival;
2597 if (fival_head == NULL) {
2598 RKCAMERA_TR("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
2600 goto rk_camera_enum_frameintervals_end;
2604 while (fival_head->width && fival_head->height) {
2605 if ((fival->pixel_format == fival_head->pixel_format)
2606 && (fival->height == fival_head->height)
2607 && (fival->width == fival_head->width)) {
2616 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2617 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2618 RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2619 fival->width, fival->height,
2620 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2621 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2622 fival->discrete.denominator,fival->discrete.numerator);
2625 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2626 fival->width,fival->height,
2627 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2628 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2631 RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2632 fival->width,fival->height,
2633 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2634 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2639 rk_camera_enum_frameintervals_end:
2643 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2644 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2645 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2648 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2649 struct rk_camera_dev *pcdev = ici->priv;
2652 //change the crop and scale parameters
2653 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2654 a.c.width = pcdev->host_width*100/zoom_rate;
2656 a.c.height = pcdev->host_height*100/zoom_rate;
2657 a.c.height &= ~0x03;
2658 a.c.left = (pcdev->host_width - a.c.width)>>1;
2659 a.c.top = (pcdev->host_height - a.c.height)>>1;
2660 down(&pcdev->zoominfo.sem);
2661 pcdev->zoominfo.a.c.height = a.c.height;
2662 pcdev->zoominfo.a.c.width = a.c.width;
2663 pcdev->zoominfo.a.c.top = a.c.top;
2664 pcdev->zoominfo.a.c.left = a.c.left;
2665 pcdev->zoominfo.vir_width = pcdev->host_width;
2666 up(&pcdev->zoominfo.sem);
2667 RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
2672 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2673 struct soc_camera_host_ops *ops, int id)
2677 for (i = 0; i < ops->num_controls; i++)
2678 if (ops->controls[i].id == id)
2679 return &ops->controls[i];
2685 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2686 struct v4l2_control *sctrl)
2689 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2690 const struct v4l2_queryctrl *qctrl;
2691 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2692 struct rk_camera_dev *pcdev = ici->priv;
2696 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2699 goto rk_camera_set_ctrl_end;
2704 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2705 case V4L2_CID_ZOOM_ABSOLUTE:
2707 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2709 goto rk_camera_set_ctrl_end;
2711 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2713 pcdev->zoominfo.zoom_rate = sctrl->value;
2715 goto rk_camera_set_ctrl_end;
2724 rk_camera_set_ctrl_end:
2728 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2730 .owner = THIS_MODULE,
2731 .add = rk_camera_add_device,
2732 .remove = rk_camera_remove_device,
2733 .suspend = rk_camera_suspend,
2734 .resume = rk_camera_resume,
2735 .enum_frameinervals = rk_camera_enum_frameintervals,
2736 .set_crop = rk_camera_set_crop,
2737 .get_formats = rk_camera_get_formats,
2738 .put_formats = rk_camera_put_formats,
2739 .set_fmt = rk_camera_set_fmt,
2740 .try_fmt = rk_camera_try_fmt,
2741 .init_videobuf = rk_camera_init_videobuf,
2742 .reqbufs = rk_camera_reqbufs,
2743 .poll = rk_camera_poll,
2744 .querycap = rk_camera_querycap,
2745 .set_bus_param = rk_camera_set_bus_param,
2746 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2747 .set_ctrl = rk_camera_set_ctrl,
2748 .controls = rk_camera_controls,
2749 .num_controls = ARRAY_SIZE(rk_camera_controls)
2752 static void rk_camera_cif_iomux(int cif_index)
2754 #ifdef CONFIG_ARCH_RK30
2757 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
2760 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
2761 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
2762 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
2763 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
2764 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
2765 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
2766 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
2767 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
2769 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
2770 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
2771 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
2772 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
2773 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
2774 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
2775 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
2776 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
2779 printk("cif index is erro!!!\n");
2786 static int rk_camera_probe(struct platform_device *pdev)
2788 struct rk_camera_dev *pcdev;
2789 struct resource *res;
2790 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
2794 RKCAMERA_DG("%s(%d) Enter..\n",__FUNCTION__,__LINE__);
2796 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
2797 RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
2801 if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
2802 RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
2806 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2807 irq = platform_get_irq(pdev, 0);
2808 if (!res || irq < 0) {
2812 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
2814 dev_err(&pdev->dev, "Could not allocate pcdev\n");
2819 pcdev->zoominfo.zoom_rate = 100;
2820 pcdev->hostid = pdev->id;
2821 /*config output clk*/ // must modify start
2823 pcdev->pd_cif = clk_get(NULL, "pd_cif0");
2824 pcdev->aclk_cif = clk_get(NULL, "aclk_cif0");
2825 pcdev->hclk_cif = clk_get(NULL, "hclk_cif0");
2826 pcdev->cif_clk_in = clk_get(NULL, "cif0_in");
2827 pcdev->cif_clk_out = clk_get(NULL, "cif0_out");
2828 rk_camera_cif_iomux(0);
2830 pcdev->pd_cif = clk_get(NULL, "pd_cif1");
2831 pcdev->aclk_cif = clk_get(NULL, "aclk_cif1");
2832 pcdev->hclk_cif = clk_get(NULL, "hclk_cif1");
2833 pcdev->cif_clk_in = clk_get(NULL, "cif1_in");
2834 pcdev->cif_clk_out = clk_get(NULL, "cif1_out");
2836 rk_camera_cif_iomux(1);
2839 if(IS_ERR(pcdev->pd_cif) || IS_ERR(pcdev->aclk_cif) || IS_ERR(pcdev->hclk_cif) || IS_ERR(pcdev->cif_clk_in) || IS_ERR(pcdev->cif_clk_out)){
2840 RKCAMERA_TR(KERN_ERR "%s(%d): failed to get cif clock source\n",__FUNCTION__,__LINE__);
2842 goto exit_reqmem_vip;
2845 dev_set_drvdata(&pdev->dev, pcdev);
2847 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
2849 if (pcdev->pdata && pcdev->pdata->io_init) {
2850 pcdev->pdata->io_init();
2852 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2853 if (pcdev->pdata && IS_CIF0()) {
2854 pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
2855 pcdev->vipmem_size = pcdev->pdata->meminfo.size;
2857 if (!request_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size,"rk29_vipmem")) {
2859 goto exit_ioremap_vipmem;
2861 pcdev->vipmem_virbase = ioremap_cached(pcdev->vipmem_phybase,pcdev->vipmem_size);
2862 if (pcdev->vipmem_virbase == NULL) {
2863 dev_err(pcdev->dev, "ioremap() of vip internal memory(Ex:IPP process/raw process) failed\n");
2865 goto exit_ioremap_vipmem;
2867 RKCAMERA_TR("%s(%d): Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
2868 } else if (pcdev->pdata) {
2869 pcdev->vipmem_phybase = pcdev->pdata->meminfo_cif1.start;
2870 pcdev->vipmem_size = pcdev->pdata->meminfo_cif1.size;
2872 if (!request_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size,"rk29_vipmem")) {
2874 goto exit_ioremap_vipmem;
2876 pcdev->vipmem_virbase = ioremap_cached(pcdev->vipmem_phybase,pcdev->vipmem_size);
2877 if (pcdev->vipmem_virbase == NULL) {
2878 dev_err(pcdev->dev, "ioremap() of vip internal memory(Ex:IPP process/raw process) failed\n");
2880 goto exit_ioremap_vipmem;
2882 RKCAMERA_TR("%s(%d): Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
2884 RKCAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
2885 pcdev->vipmem_phybase = 0;
2886 pcdev->vipmem_size = 0;
2887 pcdev->vipmem_virbase = 0;
2890 INIT_LIST_HEAD(&pcdev->capture);
2891 INIT_LIST_HEAD(&pcdev->camera_work_queue);
2892 spin_lock_init(&pcdev->lock);
2893 spin_lock_init(&pcdev->camera_work_lock);
2894 sema_init(&pcdev->zoominfo.sem,1);
2897 * Request the regions.
2900 if (!request_mem_region(res->start, res->end - res->start + 1,
2901 RK29_CAM_DRV_NAME)) {
2903 goto exit_reqmem_vip;
2905 pcdev->base = ioremap(res->start, res->end - res->start + 1);
2906 if (pcdev->base == NULL) {
2907 dev_err(pcdev->dev, "ioremap() of registers failed\n");
2909 goto exit_ioremap_vip;
2914 pcdev->dev = &pdev->dev;
2916 /* config buffer address */
2919 err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
2922 dev_err(pcdev->dev, "Camera interrupt register failed \n");
2927 //#ifdef CONFIG_VIDEO_RK29_WORK_IPP
2929 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
2931 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
2933 if (pcdev->camera_wq == NULL)
2937 pcdev->camera_reinit_work.pcdev = pcdev;
2938 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2940 for (i=0; i<2; i++) {
2941 pcdev->icd_frmival[i].icd = NULL;
2942 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
2945 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
2946 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
2947 pcdev->soc_host.priv = pcdev;
2948 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
2949 pcdev->soc_host.nr = pdev->id;
2951 err = soc_camera_host_register(&pcdev->soc_host);
2954 pcdev->fps_timer.pcdev = pcdev;
2955 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2956 pcdev->fps_timer.timer.function = rk_camera_fps_func;
2957 pcdev->icd_cb.sensor_cb = NULL;
2959 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
2960 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
2961 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
2962 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
2963 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
2964 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_rga;
2965 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
2966 pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp;
2968 RKCAMERA_DG("%s(%d) Exit \n",__FUNCTION__,__LINE__);
2973 for (i=0; i<2; i++) {
2974 fival_list = pcdev->icd_frmival[i].fival_list;
2975 fival_nxt = fival_list;
2976 while(fival_nxt != NULL) {
2977 fival_nxt = fival_list->nxt;
2979 fival_list = fival_nxt;
2983 free_irq(pcdev->irq, pcdev);
2984 if (pcdev->camera_wq) {
2985 destroy_workqueue(pcdev->camera_wq);
2986 pcdev->camera_wq = NULL;
2989 iounmap(pcdev->base);
2991 release_mem_region(res->start, res->end - res->start + 1);
2992 exit_ioremap_vipmem:
2993 if (pcdev->vipmem_virbase)
2994 iounmap(pcdev->vipmem_virbase);
2995 release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
2998 pcdev->aclk_cif = NULL;
3000 pcdev->hclk_cif = NULL;
3001 if(pcdev->cif_clk_in)
3002 pcdev->cif_clk_in = NULL;
3003 if(pcdev->cif_clk_out)
3004 pcdev->cif_clk_out = NULL;
3013 static int __devexit rk_camera_remove(struct platform_device *pdev)
3015 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
3016 struct resource *res;
3017 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
3020 free_irq(pcdev->irq, pcdev);
3022 if (pcdev->camera_wq) {
3023 destroy_workqueue(pcdev->camera_wq);
3024 pcdev->camera_wq = NULL;
3027 for (i=0; i<2; i++) {
3028 fival_list = pcdev->icd_frmival[i].fival_list;
3029 fival_nxt = fival_list;
3030 while(fival_nxt != NULL) {
3031 fival_nxt = fival_list->nxt;
3033 fival_list = fival_nxt;
3037 soc_camera_host_unregister(&pcdev->soc_host);
3040 release_mem_region(res->start, res->end - res->start + 1);
3041 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
3042 pcdev->pdata->io_deinit(0);
3043 pcdev->pdata->io_deinit(1);
3048 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
3053 static struct platform_driver rk_camera_driver =
3056 .name = RK29_CAM_DRV_NAME,
3058 .probe = rk_camera_probe,
3059 .remove = __devexit_p(rk_camera_remove),
3062 static int rk_camera_init_async(void *unused)
3064 RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
3065 platform_driver_register(&rk_camera_driver);
3069 static int __devinit rk_camera_init(void)
3071 RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
3072 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
3076 static void __exit rk_camera_exit(void)
3078 platform_driver_unregister(&rk_camera_driver);
3081 device_initcall_sync(rk_camera_init);
3082 module_exit(rk_camera_exit);
3084 MODULE_DESCRIPTION("RKSoc Camera Host driver");
3085 MODULE_AUTHOR("ddl <ddl@rock-chips>");
3086 MODULE_LICENSE("GPL");