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 #ifdef CONFIG_ARCH_RK30
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 <mach/rk30_camera.h>
46 module_param(debug, int, S_IRUGO|S_IWUSR);
48 #define dprintk(level, fmt, arg...) do { \
50 printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
52 #define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
53 #define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
56 #define CIF_CIF_CTRL 0x00
57 #define CIF_CIF_INTEN 0x04
58 #define CIF_CIF_INTSTAT 0x08
59 #define CIF_CIF_FOR 0x0c
60 #define CIF_CIF_LINE_NUM_ADDR 0x10
61 #define CIF_CIF_FRM0_ADDR_Y 0x14
62 #define CIF_CIF_FRM0_ADDR_UV 0x18
63 #define CIF_CIF_FRM1_ADDR_Y 0x1c
64 #define CIF_CIF_FRM1_ADDR_UV 0x20
65 #define CIF_CIF_VIR_LINE_WIDTH 0x24
66 #define CIF_CIF_SET_SIZE 0x28
67 #define CIF_CIF_SCM_ADDR_Y 0x2c
68 #define CIF_CIF_SCM_ADDR_U 0x30
69 #define CIF_CIF_SCM_ADDR_V 0x34
70 #define CIF_CIF_WB_UP_FILTER 0x38
71 #define CIF_CIF_WB_LOW_FILTER 0x3c
72 #define CIF_CIF_WBC_CNT 0x40
73 #define CIF_CIF_CROP 0x44
74 #define CIF_CIF_SCL_CTRL 0x48
75 #define CIF_CIF_SCL_DST 0x4c
76 #define CIF_CIF_SCL_FCT 0x50
77 #define CIF_CIF_SCL_VALID_NUM 0x54
78 #define CIF_CIF_LINE_LOOP_CTR 0x58
79 #define CIF_CIF_FRAME_STATUS 0x60
80 #define CIF_CIF_CUR_DST 0x64
81 #define CIF_CIF_LAST_LINE 0x68
82 #define CIF_CIF_LAST_PIX 0x6c
84 //The key register bit descrition
85 // CIF_CTRL Reg , ignore SCM,WBC,ISP,
86 #define DISABLE_CAPTURE (0x00<<0)
87 #define ENABLE_CAPTURE (0x01<<0)
88 #define MODE_ONEFRAME (0x00<<1)
89 #define MODE_PINGPONG (0x01<<1)
90 #define MODE_LINELOOP (0x02<<1)
91 #define AXI_BURST_16 (0x0F << 12)
94 #define FRAME_END_EN (0x01<<1)
95 #define BUS_ERR_EN (0x01<<6)
96 #define SCL_ERR_EN (0x01<<7)
99 #define VSY_HIGH_ACTIVE (0x01<<0)
100 #define VSY_LOW_ACTIVE (0x00<<0)
101 #define HSY_LOW_ACTIVE (0x01<<1)
102 #define HSY_HIGH_ACTIVE (0x00<<1)
103 #define INPUT_MODE_YUV (0x00<<2)
104 #define INPUT_MODE_PAL (0x02<<2)
105 #define INPUT_MODE_NTSC (0x03<<2)
106 #define INPUT_MODE_RAW (0x04<<2)
107 #define INPUT_MODE_JPEG (0x05<<2)
108 #define INPUT_MODE_MIPI (0x06<<2)
109 #define YUV_INPUT_ORDER_UYVY(ori) (ori & (~(0x03<<5)))
110 #define YUV_INPUT_ORDER_YVYU(ori) ((ori & (~(0x01<<6)))|(0x01<<5))
111 #define YUV_INPUT_ORDER_VYUY(ori) ((ori & (~(0x01<<5))) | (0x1<<6))
112 #define YUV_INPUT_ORDER_YUYV(ori) (ori|(0x03<<5))
113 #define YUV_INPUT_422 (0x00<<7)
114 #define YUV_INPUT_420 (0x01<<7)
115 #define INPUT_420_ORDER_EVEN (0x00<<8)
116 #define INPUT_420_ORDER_ODD (0x01<<8)
117 #define CCIR_INPUT_ORDER_ODD (0x00<<9)
118 #define CCIR_INPUT_ORDER_EVEN (0x01<<9)
119 #define RAW_DATA_WIDTH_8 (0x00<<11)
120 #define RAW_DATA_WIDTH_10 (0x01<<11)
121 #define RAW_DATA_WIDTH_12 (0x02<<11)
122 #define YUV_OUTPUT_422 (0x00<<16)
123 #define YUV_OUTPUT_420 (0x01<<16)
124 #define OUTPUT_420_ORDER_EVEN (0x00<<17)
125 #define OUTPUT_420_ORDER_ODD (0x01<<17)
126 #define RAWD_DATA_LITTLE_ENDIAN (0x00<<18)
127 #define RAWD_DATA_BIG_ENDIAN (0x01<<18)
128 #define UV_STORAGE_ORDER_UVUV (0x00<<19)
129 #define UV_STORAGE_ORDER_VUVU (0x01<<19)
132 #define ENABLE_SCL_DOWN (0x01<<0)
133 #define DISABLE_SCL_DOWN (0x00<<0)
134 #define ENABLE_SCL_UP (0x01<<1)
135 #define DISABLE_SCL_UP (0x00<<1)
136 #define ENABLE_YUV_16BIT_BYPASS (0x01<<4)
137 #define DISABLE_YUV_16BIT_BYPASS (0x00<<4)
138 #define ENABLE_RAW_16BIT_BYPASS (0x01<<5)
139 #define DISABLE_RAW_16BIT_BYPASS (0x00<<5)
140 #define ENABLE_32BIT_BYPASS (0x01<<6)
141 #define DISABLE_32BIT_BYPASS (0x00<<6)
144 #define CRU_PCLK_REG30 0xbc
145 #define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8))
146 #define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8))
147 #define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12))
148 #define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12))
150 #define CRU_CIF_RST_REG30 0x128
151 #define MASK_RST_CIF0 (0x01 << 30)
152 #define MASK_RST_CIF1 (0x01 << 31)
153 #define RQUEST_RST_CIF0 (0x01 << 14)
154 #define RQUEST_RST_CIF1 (0x01 << 15)
156 #define MIN(x,y) ((x<y) ? x: y)
157 #define MAX(x,y) ((x>y) ? x: y)
158 #define RK_SENSOR_24MHZ 24*1000*1000 /* MHz */
159 #define RK_SENSOR_48MHZ 48
161 #define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base))
162 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
163 #define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
165 #define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE)
166 #define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
167 #define mask_cru_reg(addr, msk, val) write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
169 //when work_with_ipp is not enabled,CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF is not defined.something wrong with it
170 #ifdef CONFIG_VIDEO_RK29_WORK_IPP//CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
171 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
172 #define CAM_WORKQUEUE_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
173 || (pcdev->icd_cb.sensor_cb))
174 #define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))
176 #define CAM_WORKQUEUE_IS_EN() (true)
177 #define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
179 #else //CONFIG_VIDEO_RK29_WORK_IPP
180 #define CAM_WORKQUEUE_IS_EN() (false)
181 #define CAM_IPPWORK_IS_EN() (false)
184 #define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
187 * Driver Version Note
189 *v0.0.x : this driver is 2.6.32 kernel driver;
190 *v0.1.x : this driver is 3.0.8 kernel driver;
192 *v0.x.1 : this driver first support rk2918;
193 *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
194 * and V4L2_PIX_FMT_YUV422P;
195 *v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
196 *v0.x.4 : this driver support digital zoom;
197 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
198 *v0.x.6 : this driver improve test framerate method;
199 *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
200 we do crop with cif and do scale with ipp , we will fix this next version.
201 *v0.x.8 : temp version,reinit capture list when setup video buf.
202 *v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version.
203 2. flush workqueue when releas buffer
204 *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
206 2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
207 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
208 4. add menu configs for convineuent to customize sensor series
209 *v0.x.b: specify the version is NOT sure stable.
210 *v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
211 2. irq process is splitted to two step.
212 *v0.x.e: fix bugs of early suspend when display_pd is closed.
213 *v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function;
214 *v0.x.11: fix struct rk_camera_work may be reentrant
216 #define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0x11)
218 /* limit to rk29 hardware capabilities */
219 #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\
220 SOCAM_HSYNC_ACTIVE_HIGH |\
221 SOCAM_HSYNC_ACTIVE_LOW |\
222 SOCAM_VSYNC_ACTIVE_HIGH |\
223 SOCAM_VSYNC_ACTIVE_LOW |\
224 SOCAM_PCLK_SAMPLE_RISING |\
225 SOCAM_PCLK_SAMPLE_FALLING|\
226 SOCAM_DATA_ACTIVE_HIGH |\
227 SOCAM_DATA_ACTIVE_LOW|\
228 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
229 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
231 #define RK_CAM_W_MIN 48
232 #define RK_CAM_H_MIN 32
233 #define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */
234 #define RK_CAM_H_MAX 2764
235 #define RK_CAM_FRAME_INVAL_INIT 3
236 #define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */
237 #define RK30_CAM_FRAME_MEASURE 5
238 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
239 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
241 /* buffer for one video frame */
242 struct rk_camera_buffer
244 /* common v4l buffer stuff -- must be first */
245 struct videobuf_buffer vb;
246 enum v4l2_mbus_pixelcode code;
249 enum rk_camera_reg_state
257 unsigned int cifCtrl;
258 unsigned int cifCrop;
260 unsigned int cifIntEn;
262 unsigned int cifVirWidth;
263 unsigned int cifScale;
264 // unsigned int VipCrm;
265 enum rk_camera_reg_state Inval;
267 struct rk_camera_work
269 struct videobuf_buffer *vb;
270 struct rk_camera_dev *pcdev;
271 struct work_struct work;
272 struct list_head queue;
275 struct rk_camera_frmivalenum
277 struct v4l2_frmivalenum fival;
278 struct rk_camera_frmivalenum *nxt;
280 struct rk_camera_frmivalinfo
282 struct soc_camera_device *icd;
283 struct rk_camera_frmivalenum *fival_list;
285 struct rk_camera_zoominfo
287 struct semaphore sem;
292 struct rk_camera_timer{
293 struct rk_camera_dev *pcdev;
294 struct hrtimer timer;
299 struct soc_camera_host soc_host;
301 /* RK2827x is only supposed to handle one camera on its Quick Capture
302 * interface. If anyone ever builds hardware to enable more than
303 * one camera, they will have to modify this driver too */
304 struct soc_camera_device *icd;
306 //************must modify start************/
308 struct clk *aclk_cif;
309 struct clk *hclk_cif;
310 struct clk *cif_clk_in;
311 struct clk *cif_clk_out;
312 //************must modify end************/
314 int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */
317 unsigned int last_fps;
318 unsigned long frame_interval;
321 unsigned int vipmem_phybase;
322 unsigned int vipmem_size;
323 unsigned int vipmem_bsize;
325 int host_width; //croped size
327 int host_left; //sensor output size ?
333 struct rk29camera_platform_data *pdata;
334 struct resource *res;
335 struct list_head capture;
336 struct rk_camera_zoominfo zoominfo;
340 struct videobuf_buffer *active;
341 struct rk_camera_reg reginfo_suspend;
342 struct workqueue_struct *camera_wq;
343 struct rk_camera_work *camera_work;
344 struct list_head camera_work_queue;
345 spinlock_t camera_work_lock;
346 unsigned int camera_work_count;
347 struct rk_camera_timer fps_timer;
348 struct rk_camera_work camera_reinit_work;
350 rk29_camera_sensor_cb_s icd_cb;
351 struct rk_camera_frmivalinfo icd_frmival[2];
352 // atomic_t to_process_frames;
354 unsigned int reinit_times;
355 struct videobuf_queue *video_vq;
357 struct timeval first_tv;
360 static const struct v4l2_queryctrl rk_camera_controls[] =
362 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
364 .id = V4L2_CID_ZOOM_ABSOLUTE,
365 .type = V4L2_CTRL_TYPE_INTEGER,
366 .name = "DigitalZoom Control",
370 .default_value = 100,
375 static DEFINE_MUTEX(camera_lock);
376 static const char *rk_cam_driver_description = "RK_Camera";
378 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
379 static void rk_camera_capture_process(struct work_struct *work);
383 * Videobuf operations
385 static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
388 struct soc_camera_device *icd = vq->priv_data;
389 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
390 struct rk_camera_dev *pcdev = ici->priv;
391 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
392 icd->current_fmt->host_fmt);
393 int bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
394 icd->current_fmt->host_fmt);
396 struct rk_camera_work *wk;
398 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
400 if (bytes_per_line_host < 0)
401 return bytes_per_line_host;
403 /* planar capture requires Y, U and V buffers to be page aligned */
404 *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/
405 pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
407 if (CAM_WORKQUEUE_IS_EN()) {
408 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
409 if (CAM_IPPWORK_IS_EN())
412 BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
413 if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */
414 *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
417 if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
418 kfree(pcdev->camera_work);
419 pcdev->camera_work = NULL;
420 pcdev->camera_work_count = 0;
423 if (pcdev->camera_work == NULL) {
424 pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
425 if (pcdev->camera_work == NULL) {
426 RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
429 INIT_LIST_HEAD(&pcdev->camera_work_queue);
431 for (i=0; i<(*count); i++) {
433 list_add_tail(&wk->queue, &pcdev->camera_work_queue);
436 pcdev->camera_work_count = (*count);
440 pcdev->video_vq = vq;
441 RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
445 static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf)
447 struct soc_camera_device *icd = vq->priv_data;
449 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
450 &buf->vb, buf->vb.baddr, buf->vb.bsize);
452 /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
453 if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
459 * This waits until this buffer is out of danger, i.e., until it is no
460 * longer in STATE_QUEUED or STATE_ACTIVE
462 //videobuf_waiton(vq, &buf->vb, 0, 0);
463 videobuf_dma_contig_free(vq, &buf->vb);
464 dev_dbg(&icd->dev, "%s freed\n", __func__);
465 buf->vb.state = VIDEOBUF_NEEDS_INIT;
468 static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
470 struct soc_camera_device *icd = vq->priv_data;
471 struct rk_camera_buffer *buf;
473 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
474 icd->current_fmt->host_fmt);
475 if (bytes_per_line < 0)
476 return bytes_per_line;
478 buf = container_of(vb, struct rk_camera_buffer, vb);
480 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
481 vb, vb->baddr, vb->bsize);
483 /* Added list head initialization on alloc */
484 WARN_ON(!list_empty(&vb->queue));
486 BUG_ON(NULL == icd->current_fmt);
488 if (buf->code != icd->current_fmt->code ||
489 vb->width != icd->user_width ||
490 vb->height != icd->user_height ||
491 vb->field != field) {
492 buf->code = icd->current_fmt->code;
493 vb->width = icd->user_width;
494 vb->height = icd->user_height;
496 vb->state = VIDEOBUF_NEEDS_INIT;
499 vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */
500 if (0 != vb->baddr && vb->bsize < vb->size) {
505 if (vb->state == VIDEOBUF_NEEDS_INIT) {
506 ret = videobuf_iolock(vq, vb, NULL);
510 vb->state = VIDEOBUF_PREPARED;
515 rk_videobuf_free(vq, buf);
520 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev)
522 unsigned int y_addr,uv_addr;
523 struct rk_camera_dev *pcdev = rk_pcdev;
526 if (CAM_WORKQUEUE_IS_EN()) {
527 y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
528 uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
529 if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
530 RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
531 pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
536 uv_addr = y_addr + vb->width * vb->height;
538 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
539 write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
540 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
541 write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
542 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used
545 /* Locking: Caller holds q->irqlock */
546 static void rk_videobuf_queue(struct videobuf_queue *vq,
547 struct videobuf_buffer *vb)
549 struct soc_camera_device *icd = vq->priv_data;
550 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
551 struct rk_camera_dev *pcdev = ici->priv;
553 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
554 vb, vb->baddr, vb->bsize);
556 vb->state = VIDEOBUF_QUEUED;
557 if (list_empty(&pcdev->capture)) {
558 list_add_tail(&vb->queue, &pcdev->capture);
560 if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
561 list_add_tail(&vb->queue, &pcdev->capture);
563 BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
565 if (!pcdev->active) {
567 rk_videobuf_capture(vb,pcdev);
570 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
574 case V4L2_PIX_FMT_NV16:
575 case V4L2_PIX_FMT_NV61:
577 *ippfmt = IPP_Y_CBCR_H2V1;
580 case V4L2_PIX_FMT_NV12:
581 case V4L2_PIX_FMT_NV21:
583 *ippfmt = IPP_Y_CBCR_H2V2;
587 goto rk_pixfmt2ippfmt_err;
591 rk_pixfmt2ippfmt_err:
594 static void rk_camera_capture_process(struct work_struct *work)
596 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
597 struct videobuf_buffer *vb = camera_work->vb;
598 struct rk_camera_dev *pcdev = camera_work->pcdev;
599 struct rk29_ipp_req ipp_req;
600 unsigned long int flags;
601 int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
602 int scale_times,w,h,vipdata_base;
606 * IPP Dest image resolution is 2047x1088, so scale operation break up some times
608 if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
609 scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));
614 memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
617 down(&pcdev->zoominfo.sem);
618 ipp_req.timeout = 3000;
619 ipp_req.flag = IPP_ROT_0;
620 ipp_req.store_clip_mode =1;
621 ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
622 ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
623 ipp_req.src_vir_w = pcdev->zoominfo.vir_width;
624 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
625 ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
626 ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
627 ipp_req.dst_vir_w = pcdev->icd->user_width;
628 rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
629 vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
630 src_y_size = pcdev->host_width*pcdev->host_height; //vipmem
631 dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
632 for (h=0; h<scale_times; h++) {
633 for (w=0; w<scale_times; w++) {
635 src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width
636 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
637 src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width/2
638 + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
640 dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
641 dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
643 ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
644 ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
645 ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
646 ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
647 while(ipp_times-- > 0) {
648 if (ipp_blit_sync(&ipp_req)){
649 RKCAMERA_TR("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
655 if (ipp_times <= 0) {
656 spin_lock_irqsave(&pcdev->lock, flags);
657 vb->state = VIDEOBUF_NEEDS_INIT;
658 spin_unlock_irqrestore(&pcdev->lock, flags);
659 RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
660 RKCAMERA_TR("widx:%d hidx:%d ",w,h);
661 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);
662 RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
663 RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
664 RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
665 RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
666 RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
667 RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
668 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);
669 RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
676 if (pcdev->icd_cb.sensor_cb)
677 (pcdev->icd_cb.sensor_cb)(vb);
679 up(&pcdev->zoominfo.sem);
680 wake_up(&(camera_work->vb->done));
681 spin_lock_irqsave(&pcdev->camera_work_lock, flags);
682 list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
683 spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
686 static irqreturn_t rk_camera_irq(int irq, void *data)
688 struct rk_camera_dev *pcdev = data;
689 struct videobuf_buffer *vb;
690 struct rk_camera_work *wk;
692 unsigned long tmp_intstat;
693 unsigned long tmp_cifctrl;
695 tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
696 tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
697 if(pcdev->stop_cif == true)
699 printk("cif has stopped by app,needn't to deal this irq\n");
700 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
703 if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/){//bit9 =1 ,bit0 = 0
704 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200); /* clear vip interrupte single */
705 if(tmp_cifctrl & ENABLE_CAPTURE)
706 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
710 /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
711 if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) {
712 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01); /* clear vip interrupte single */
714 do_gettimeofday(&pcdev->first_tv);
718 goto RK_CAMERA_IRQ_END;
719 if (pcdev->frame_inval>0) {
720 pcdev->frame_inval--;
721 rk_videobuf_capture(pcdev->active,pcdev);
722 goto RK_CAMERA_IRQ_END;
723 } else if (pcdev->frame_inval) {
724 RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
725 pcdev->frame_inval = 0;
727 if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
728 do_gettimeofday(&tv);
729 pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
730 /(RK30_CAM_FRAME_MEASURE-1);
734 printk("no acticve buffer!!!\n");
735 goto RK_CAMERA_IRQ_END;
737 /* ddl@rock-chips.com : this vb may be deleted from queue */
738 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
739 list_del_init(&vb->queue);
741 pcdev->active = NULL;
742 if (!list_empty(&pcdev->capture)) {
743 pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
745 WARN_ON(pcdev->active->state != VIDEOBUF_QUEUED);
746 rk_videobuf_capture(pcdev->active,pcdev);
749 if (pcdev->active == NULL) {
750 RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
753 if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
754 vb->state = VIDEOBUF_DONE;
755 do_gettimeofday(&vb->ts);
758 if (CAM_WORKQUEUE_IS_EN()) {
759 if (!list_empty(&pcdev->camera_work_queue)) {
760 wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
761 list_del_init(&wk->queue);
762 INIT_WORK(&(wk->work), rk_camera_capture_process);
765 queue_work(pcdev->camera_wq, &(wk->work));
774 if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
775 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
780 static void rk_videobuf_release(struct videobuf_queue *vq,
781 struct videobuf_buffer *vb)
783 struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
784 struct soc_camera_device *icd = vq->priv_data;
785 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
786 struct rk_camera_dev *pcdev = ici->priv;
788 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
789 vb, vb->baddr, vb->bsize);
793 case VIDEOBUF_ACTIVE:
794 dev_dbg(&icd->dev, "%s (active)\n", __func__);
796 case VIDEOBUF_QUEUED:
797 dev_dbg(&icd->dev, "%s (queued)\n", __func__);
799 case VIDEOBUF_PREPARED:
800 dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
803 dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
808 flush_workqueue(pcdev->camera_wq);
811 if (vb == pcdev->active) {
812 RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
813 interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
814 flush_workqueue(pcdev->camera_wq);
815 RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
817 rk_videobuf_free(vq, buf);
820 static struct videobuf_queue_ops rk_videobuf_ops =
822 .buf_setup = rk_videobuf_setup,
823 .buf_prepare = rk_videobuf_prepare,
824 .buf_queue = rk_videobuf_queue,
825 .buf_release = rk_videobuf_release,
828 static void rk_camera_init_videobuf(struct videobuf_queue *q,
829 struct soc_camera_device *icd)
831 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
832 struct rk_camera_dev *pcdev = ici->priv;
834 /* We must pass NULL as dev pointer, then all pci_* dma operations
835 * transform to normal dma_* ones. */
836 videobuf_queue_dma_contig_init(q,
838 ici->v4l2_dev.dev, &pcdev->lock,
839 V4L2_BUF_TYPE_VIDEO_CAPTURE,
841 sizeof(struct rk_camera_buffer),
842 icd,&icd->video_lock);
844 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
848 if(!pcdev->aclk_cif || !pcdev->hclk_cif || !pcdev->cif_clk_in || !pcdev->cif_clk_out){
849 RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
851 goto RK_CAMERA_ACTIVE_ERR;
854 clk_enable(pcdev->pd_cif);
855 clk_enable(pcdev->aclk_cif);
857 clk_enable(pcdev->hclk_cif);
858 clk_enable(pcdev->cif_clk_in);
860 //if (icd->ops->query_bus_param) /* ddl@rock-chips.com : Query Sensor's xclk */
861 //sensor_bus_flags = icd->ops->query_bus_param(icd);
862 clk_enable(pcdev->cif_clk_out);
863 clk_set_rate(pcdev->cif_clk_out,RK_SENSOR_24MHZ);
866 //soft reset the registers
867 #if 0 //has somthing wrong when suspend and resume now
869 printk("before set cru register reset cif0 0x%x\n\n",read_cru_reg(CRU_CIF_RST_REG30));
872 printk("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
873 printk("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
874 printk("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
875 printk("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
876 printk("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
877 printk("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
878 printk("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
879 printk("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
880 printk("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
882 printk("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
883 printk("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
884 printk("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
885 printk("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
886 printk("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
887 printk("CIF_CIF_FRAME_STATUS = 0X%x\n\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
891 write_cru_reg(CRU_CIF_RST_REG30,(/*read_cru_reg(CRU_CIF_RST_REG30)|*/MASK_RST_CIF0|RQUEST_RST_CIF0 ));
892 printk("set cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
893 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
895 printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
897 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
898 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
901 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
902 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable
903 RKCAMERA_DG("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
905 RK_CAMERA_ACTIVE_ERR:
909 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
911 clk_disable(pcdev->aclk_cif);
913 clk_disable(pcdev->hclk_cif);
914 clk_disable(pcdev->cif_clk_in);
916 clk_disable(pcdev->cif_clk_out);
917 clk_enable(pcdev->cif_clk_out);
918 clk_set_rate(pcdev->cif_clk_out,48*1000*1000);
919 clk_disable(pcdev->cif_clk_out);
921 clk_disable(pcdev->pd_cif);
925 /* The following two functions absolutely depend on the fact, that
926 * there can be only one camera on RK28 quick capture interface */
927 static int rk_camera_add_device(struct soc_camera_device *icd)
929 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
930 struct rk_camera_dev *pcdev = ici->priv;
931 struct device *control = to_soc_camera_control(icd);
932 struct v4l2_subdev *sd;
934 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
936 mutex_lock(&camera_lock);
943 RKCAMERA_DG("RK Camera driver attached to %s\n",dev_name(icd->pdev));
945 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
946 pcdev->active = NULL;
948 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
949 pcdev->zoominfo.zoom_rate = 100;
950 pcdev->fps_timer.istarted = false;
952 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
953 * if app havn't dequeue all videobuf before close camera device;
955 INIT_LIST_HEAD(&pcdev->capture);
957 ret = rk_camera_activate(pcdev,icd);
960 /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */
962 sd = dev_get_drvdata(control);
963 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
965 ret = v4l2_subdev_call(sd,core, init, 0);
969 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
975 for (i=0; i<2; i++) {
976 if (pcdev->icd_frmival[i].icd == icd)
978 if (pcdev->icd_frmival[i].icd == NULL) {
979 pcdev->icd_frmival[i].icd = icd;
983 if (icd_catch == 0) {
984 fival_list = pcdev->icd_frmival[0].fival_list;
985 fival_nxt = fival_list;
986 while(fival_nxt != NULL) {
987 fival_nxt = fival_list->nxt;
989 fival_list = fival_nxt;
991 pcdev->icd_frmival[0].icd = icd;
992 pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
995 mutex_unlock(&camera_lock);
999 static void rk_camera_remove_device(struct soc_camera_device *icd)
1001 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1002 struct rk_camera_dev *pcdev = ici->priv;
1003 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1005 mutex_lock(&camera_lock);
1006 BUG_ON(icd != pcdev->icd);
1008 RKCAMERA_DG("RK Camera driver detached from %s\n",dev_name(icd->pdev));
1010 /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
1011 stream may be turn on again before close device, if suspend and resume happened. */
1012 if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
1013 rk_camera_s_stream(icd,0);
1016 //soft reset the registers
1017 #if 0 //has somthing wrong when suspend and resume now
1019 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF0|RQUEST_RST_CIF0 | (read_cru_reg(CRU_CIF_RST_REG30)));
1020 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
1022 write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
1023 write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
1026 v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
1027 //if stream off is not been executed,timer is running.
1028 if(pcdev->fps_timer.istarted){
1029 hrtimer_cancel(&pcdev->fps_timer.timer);
1030 pcdev->fps_timer.istarted = false;
1032 flush_work(&(pcdev->camera_reinit_work.work));
1033 flush_workqueue((pcdev->camera_wq));
1035 if (pcdev->camera_work) {
1036 kfree(pcdev->camera_work);
1037 pcdev->camera_work = NULL;
1038 pcdev->camera_work_count = 0;
1039 INIT_LIST_HEAD(&pcdev->camera_work_queue);
1041 rk_camera_deactivate(pcdev);
1042 pcdev->active = NULL;
1044 pcdev->icd_cb.sensor_cb = NULL;
1045 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1046 /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty,
1047 * if app havn't dequeue all videobuf before close camera device;
1049 INIT_LIST_HEAD(&pcdev->capture);
1051 mutex_unlock(&camera_lock);
1052 RKCAMERA_DG("%s exit\n",__FUNCTION__);
1056 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1058 unsigned long bus_flags, camera_flags, common_flags;
1059 unsigned int cif_ctrl_val = 0;
1060 const struct soc_mbus_pixelfmt *fmt;
1062 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1063 struct rk_camera_dev *pcdev = ici->priv;
1064 RKCAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
1066 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1070 bus_flags = RK_CAM_BUS_PARAM;
1071 /* If requested data width is supported by the platform, use it */
1072 switch (fmt->bits_per_sample) {
1074 if (!(bus_flags & SOCAM_DATAWIDTH_10))
1078 if (!(bus_flags & SOCAM_DATAWIDTH_9))
1082 if (!(bus_flags & SOCAM_DATAWIDTH_8))
1089 if (icd->ops->query_bus_param)
1090 camera_flags = icd->ops->query_bus_param(icd);
1094 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1095 if (!common_flags) {
1097 goto RK_CAMERA_SET_BUS_PARAM_END;
1100 ret = icd->ops->set_bus_param(icd, common_flags);
1102 goto RK_CAMERA_SET_BUS_PARAM_END;
1104 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
1105 RKCAMERA_DG("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
1106 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
1108 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
1109 RKCAMERA_DG("enable cif0 pclk invert\n");
1111 write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
1112 RKCAMERA_DG("enable cif1 pclk invert\n");
1116 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
1117 RKCAMERA_DG("diable cif0 pclk invert\n");
1119 write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
1120 RKCAMERA_DG("diable cif1 pclk invert\n");
1123 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
1124 cif_ctrl_val |= HSY_LOW_ACTIVE;
1126 cif_ctrl_val &= ~HSY_LOW_ACTIVE;
1128 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
1129 cif_ctrl_val |= VSY_HIGH_ACTIVE;
1131 cif_ctrl_val &= ~VSY_HIGH_ACTIVE;
1134 /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
1135 //vip_ctrl_val |= ENABLE_CAPTURE;
1136 write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
1137 RKCAMERA_DG("%s..ctrl:0x%x CIF_CIF_FOR=%x \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
1139 RK_CAMERA_SET_BUS_PARAM_END:
1141 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1145 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1147 unsigned long bus_flags, camera_flags;
1150 bus_flags = RK_CAM_BUS_PARAM;
1151 if (icd->ops->query_bus_param) {
1152 camera_flags = icd->ops->query_bus_param(icd);
1156 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
1159 dev_warn(icd->dev.parent,
1160 "Flags incompatible: camera %lx, host %lx\n",
1161 camera_flags, bus_flags);
1165 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
1167 .fourcc = V4L2_PIX_FMT_NV12,
1168 .name = "YUV420 NV12",
1169 .bits_per_sample = 8,
1170 .packing = SOC_MBUS_PACKING_1_5X8,
1171 .order = SOC_MBUS_ORDER_LE,
1173 .fourcc = V4L2_PIX_FMT_NV16,
1174 .name = "YUV422 NV16",
1175 .bits_per_sample = 8,
1176 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1177 .order = SOC_MBUS_ORDER_LE,
1179 .fourcc = V4L2_PIX_FMT_NV21,
1180 .name = "YUV420 NV21",
1181 .bits_per_sample = 8,
1182 .packing = SOC_MBUS_PACKING_1_5X8,
1183 .order = SOC_MBUS_ORDER_LE,
1185 .fourcc = V4L2_PIX_FMT_NV61,
1186 .name = "YUV422 NV61",
1187 .bits_per_sample = 8,
1188 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1189 .order = SOC_MBUS_ORDER_LE,
1193 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
1195 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1196 struct rk_camera_dev *pcdev = ici->priv;
1197 unsigned int cif_fs = 0,cif_crop = 0;
1198 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;
1199 switch (host_pixfmt)
1201 case V4L2_PIX_FMT_NV16:
1202 cif_fmt_val &= ~YUV_OUTPUT_422;
1203 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1204 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1205 pcdev->pixfmt = host_pixfmt;
1207 case V4L2_PIX_FMT_NV61:
1208 cif_fmt_val &= ~YUV_OUTPUT_422;
1209 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1210 pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC;
1211 pcdev->pixfmt = host_pixfmt;
1213 case V4L2_PIX_FMT_NV12:
1214 cif_fmt_val |= YUV_OUTPUT_420;
1215 cif_fmt_val &= ~UV_STORAGE_ORDER_UVUV;
1216 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1217 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1218 pcdev->pixfmt = host_pixfmt;
1220 case V4L2_PIX_FMT_NV21:
1221 cif_fmt_val |= YUV_OUTPUT_420;
1222 cif_fmt_val |= UV_STORAGE_ORDER_VUVU;
1223 if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT)
1224 pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
1225 pcdev->pixfmt = host_pixfmt;
1227 default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
1228 cif_fmt_val |= YUV_OUTPUT_422;
1233 case V4L2_MBUS_FMT_UYVY8_2X8:
1234 cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val);
1236 case V4L2_MBUS_FMT_YUYV8_2X8:
1237 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1239 case V4L2_MBUS_FMT_YVYU8_2X8:
1240 cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val);
1242 case V4L2_MBUS_FMT_VYUY8_2X8:
1243 cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val);
1246 cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
1253 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1254 cru_set_soft_reset(SOFT_RST_CIF0, true);
1256 cru_set_soft_reset(SOFT_RST_CIF0, false);
1257 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1260 // pmu_set_idle_request(IDLE_REQ_VIO, true);
1261 cru_set_soft_reset(SOFT_RST_CIF1, true);
1263 cru_set_soft_reset(SOFT_RST_CIF1, false);
1264 // pmu_set_idle_request(IDLE_REQ_VIO, false);
1267 write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */
1268 write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable
1269 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 */
1271 // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */
1272 write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
1273 if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
1274 ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
1276 } else{ // this is one frame mode
1277 cif_crop = (rect->left+ (rect->top<<16));
1278 cif_fs = ((rect->width ) + (rect->height<<16));
1280 RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__);
1282 write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
1283 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
1284 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
1285 write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
1288 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
1289 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));
1293 static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1294 struct soc_camera_format_xlate *xlate)
1296 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1297 struct device *dev = icd->dev.parent;
1298 int formats = 0, ret;
1299 enum v4l2_mbus_pixelcode code;
1300 const struct soc_mbus_pixelfmt *fmt;
1302 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1304 /* No more formats */
1307 fmt = soc_mbus_get_fmtdesc(code);
1309 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1313 ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample);
1318 case V4L2_MBUS_FMT_UYVY8_2X8:
1319 case V4L2_MBUS_FMT_YUYV8_2X8:
1320 case V4L2_MBUS_FMT_YVYU8_2X8:
1321 case V4L2_MBUS_FMT_VYUY8_2X8:
1324 xlate->host_fmt = &rk_camera_formats[0];
1327 dev_dbg(dev, "Providing format %s using code %d\n",
1328 rk_camera_formats[0].name,code);
1333 xlate->host_fmt = &rk_camera_formats[1];
1336 dev_dbg(dev, "Providing format %s using code %d\n",
1337 rk_camera_formats[1].name,code);
1342 xlate->host_fmt = &rk_camera_formats[2];
1345 dev_dbg(dev, "Providing format %s using code %d\n",
1346 rk_camera_formats[2].name,code);
1351 xlate->host_fmt = &rk_camera_formats[3];
1354 dev_dbg(dev, "Providing format %s using code %d\n",
1355 rk_camera_formats[3].name,code);
1365 static void rk_camera_put_formats(struct soc_camera_device *icd)
1370 static int rk_camera_set_crop(struct soc_camera_device *icd,
1371 struct v4l2_crop *a)
1373 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1374 struct v4l2_mbus_framefmt mf;
1375 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1378 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1382 if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) {
1384 mf.width = a->c.left + a->c.width;
1385 mf.height = a->c.top + a->c.height;
1387 v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
1388 &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
1389 fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
1391 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1396 rk_camera_setup_format(icd, fourcc, mf.code, &a->c);
1398 icd->user_width = mf.width;
1399 icd->user_height = mf.height;
1404 static int rk_camera_set_fmt(struct soc_camera_device *icd,
1405 struct v4l2_format *f)
1407 struct device *dev = icd->dev.parent;
1408 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1409 const struct soc_camera_format_xlate *xlate = NULL;
1410 struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
1411 struct rk_camera_dev *pcdev = ici->priv;
1412 struct v4l2_pix_format *pix = &f->fmt.pix;
1413 struct v4l2_mbus_framefmt mf;
1414 struct v4l2_rect rect;
1415 int ret,usr_w,usr_h;
1419 usr_h = pix->height;
1420 RKCAMERA_TR("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
1421 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1423 dev_err(dev, "Format %x not found\n", pix->pixelformat);
1425 goto RK_CAMERA_SET_FMT_END;
1428 /* ddl@rock-chips.com: sensor init code transmit in here after open */
1429 if (pcdev->icd_init == 0) {
1430 v4l2_subdev_call(sd,core, init, 0);
1431 pcdev->icd_init = 1;
1433 stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1434 if (stream_on & ENABLE_CAPTURE)
1435 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE)));
1437 mf.width = pix->width;
1438 mf.height = pix->height;
1439 mf.field = pix->field;
1440 mf.colorspace = pix->colorspace;
1441 mf.code = xlate->code;
1442 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1443 if (mf.code != xlate->code)
1445 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1446 if ((mf.width != usr_w) || (mf.height != usr_h)) {
1448 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1449 RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
1451 goto RK_CAMERA_SET_FMT_END;
1453 if (unlikely((usr_w <16)||(usr_h < 16))) {
1454 RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1456 goto RK_CAMERA_SET_FMT_END;
1459 if((mf.width*10/mf.height) != (usr_w*10/usr_h)){
1460 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
1461 pcdev->host_width = ratio*usr_w/10;
1462 pcdev->host_height = ratio*usr_h/10;
1463 //for ipp ,need 4 bit alligned.
1464 pcdev->host_width &= ~0x03;
1465 pcdev->host_height &= ~0x03;
1466 RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
1468 else{ // needn't crop ,just scaled by ipp
1469 pcdev->host_width = mf.width;
1470 pcdev->host_height = mf.height;
1474 pcdev->host_width = usr_w;
1475 pcdev->host_height = usr_h;
1478 //according to crop and scale capability to change , here just cropt to user needed
1479 if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
1480 RKCAMERA_TR("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
1482 goto RK_CAMERA_SET_FMT_END;
1484 if (unlikely((usr_w <16)||(usr_h < 16))) {
1485 RKCAMERA_TR("Senor invalid destination resolution(%dx%d)\n",usr_w,usr_h);
1487 goto RK_CAMERA_SET_FMT_END;
1489 pcdev->host_width = usr_w;
1490 pcdev->host_height = usr_h;
1494 RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__,
1495 pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h);
1496 rect.width = pcdev->host_width;
1497 rect.height = pcdev->host_height;
1498 rect.left = ((mf.width-pcdev->host_width )>>1)&(~0x01);
1499 rect.top = ((mf.height-pcdev->host_height)>>1)&(~0x01);
1500 pcdev->host_left = rect.left;
1501 pcdev->host_top = rect.top;
1503 down(&pcdev->zoominfo.sem);
1504 pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
1505 pcdev->zoominfo.a.c.width &= ~0x03;
1506 pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
1507 pcdev->zoominfo.a.c.height &= ~0x03;
1508 //now digital zoom use ipp to do crop and scale
1509 if(pcdev->zoominfo.zoom_rate != 100){
1510 pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
1511 pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
1514 pcdev->zoominfo.a.c.left = 0;
1515 pcdev->zoominfo.a.c.top = 0;
1517 pcdev->zoominfo.vir_width = pcdev->host_width;
1518 up(&pcdev->zoominfo.sem);
1520 /* ddl@rock-chips.com: IPP work limit check */
1521 if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
1522 if (usr_w > 0x7f0) {
1523 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
1524 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));
1526 goto RK_CAMERA_SET_FMT_END;
1529 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
1530 RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
1532 goto RK_CAMERA_SET_FMT_END;
1536 RKCAMERA_DG("%s..%s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
1537 rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
1538 pix->width, pix->height);
1539 rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect);
1541 if (CAM_IPPWORK_IS_EN()) {
1542 BUG_ON(pcdev->vipmem_phybase == 0);
1545 pix->height = usr_h;
1546 pix->field = mf.field;
1547 pix->colorspace = mf.colorspace;
1548 icd->current_fmt = xlate;
1549 pcdev->icd_width = mf.width;
1550 pcdev->icd_height = mf.height;
1553 RK_CAMERA_SET_FMT_END:
1554 if (stream_on & ENABLE_CAPTURE)
1555 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
1557 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1560 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
1564 if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
1566 } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
1568 } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
1570 } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
1572 } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
1577 RKCAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
1580 static int rk_camera_try_fmt(struct soc_camera_device *icd,
1581 struct v4l2_format *f)
1583 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1584 struct rk_camera_dev *pcdev = ici->priv;
1585 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1586 const struct soc_camera_format_xlate *xlate;
1587 struct v4l2_pix_format *pix = &f->fmt.pix;
1588 __u32 pixfmt = pix->pixelformat;
1589 int ret,usr_w,usr_h,i;
1590 bool is_capture = rk_camera_fmt_capturechk(f);
1591 bool vipmem_is_overflow = false;
1592 struct v4l2_mbus_framefmt mf;
1593 int bytes_per_line_host;
1596 usr_h = pix->height;
1597 RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h);
1599 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1601 dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
1602 (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
1604 RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
1605 (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
1606 for (i = 0; i < icd->num_user_formats; i++)
1607 RKCAMERA_TR("(%c%c%c%c)-%s\n",
1608 icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
1609 (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
1610 icd->user_formats[i].host_fmt->name);
1611 goto RK_CAMERA_TRY_FMT_END;
1613 /* limit to rk29 hardware capabilities */
1614 v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
1615 &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
1616 pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
1618 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1620 if (pix->bytesperline < 0)
1621 return pix->bytesperline;
1623 /* limit to sensor capabilities */
1624 mf.width = pix->width;
1625 mf.height = pix->height;
1626 mf.field = pix->field;
1627 mf.colorspace = pix->colorspace;
1628 mf.code = xlate->code;
1630 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1632 goto RK_CAMERA_TRY_FMT_END;
1633 RKCAMERA_DG("%s mf.width:%d mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
1634 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
1635 if ((mf.width != usr_w) || (mf.height != usr_h)) {
1636 bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt);
1638 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
1640 /* Assume preview buffer minimum is 4 */
1641 vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
1643 if (vipmem_is_overflow == false) {
1645 pix->height = usr_h;
1647 RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
1648 pix->width = mf.width;
1649 pix->height = mf.height;
1652 if ((mf.width < usr_w) || (mf.height < usr_h)) {
1653 if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
1654 RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
1655 pix->width = mf.width;
1656 pix->height = mf.height;
1661 //need to change according to crop and scale capablicity
1662 if ((mf.width > usr_w) && (mf.height > usr_h)) {
1664 pix->height = usr_h;
1665 } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
1666 RKCAMERA_TR("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
1667 pix->width = mf.width;
1668 pix->height = mf.height;
1671 pix->colorspace = mf.colorspace;
1674 case V4L2_FIELD_ANY:
1675 case V4L2_FIELD_NONE:
1676 pix->field = V4L2_FIELD_NONE;
1679 /* TODO: support interlaced at least in pass-through mode */
1680 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
1682 goto RK_CAMERA_TRY_FMT_END;
1685 RK_CAMERA_TRY_FMT_END:
1687 RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
1691 static int rk_camera_reqbufs(struct soc_camera_device *icd,
1692 struct v4l2_requestbuffers *p)
1696 /* This is for locking debugging only. I removed spinlocks and now I
1697 * check whether .prepare is ever called on a linked buffer, or whether
1698 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1699 * it hadn't triggered */
1700 for (i = 0; i < p->count; i++) {
1701 struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i],
1702 struct rk_camera_buffer, vb);
1704 INIT_LIST_HEAD(&buf->vb.queue);
1710 static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
1712 struct soc_camera_device *icd = file->private_data;
1713 struct rk_camera_buffer *buf;
1715 buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
1718 poll_wait(file, &buf->vb.done, pt);
1720 if (buf->vb.state == VIDEOBUF_DONE ||
1721 buf->vb.state == VIDEOBUF_ERROR)
1722 return POLLIN|POLLRDNORM;
1727 static int rk_camera_querycap(struct soc_camera_host *ici,
1728 struct v4l2_capability *cap)
1730 struct rk_camera_dev *pcdev = ici->priv;
1731 char orientation[5];
1734 strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
1735 memset(orientation,0x00,sizeof(orientation));
1736 for (i=0; i<RK_CAM_NUM;i++) {
1737 if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
1738 sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
1742 if (orientation[0] != '-') {
1743 RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
1744 if (strstr(dev_name(pcdev->icd->pdev),"front"))
1745 strcat(cap->card,"-270");
1747 strcat(cap->card,"-90");
1749 strcat(cap->card,orientation);
1751 cap->version = RK_CAM_VERSION_CODE;
1752 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1756 static void rk_camera_store_register(struct rk_camera_dev *pcdev)
1758 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1759 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
1760 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
1761 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
1762 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
1763 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
1764 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
1766 static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
1768 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
1769 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
1770 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
1771 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
1772 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
1773 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
1774 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
1776 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
1778 struct soc_camera_host *ici =
1779 to_soc_camera_host(icd->dev.parent);
1780 struct rk_camera_dev *pcdev = ici->priv;
1781 struct v4l2_subdev *sd;
1784 mutex_lock(&camera_lock);
1785 if ((pcdev->icd == icd) && (icd->ops->suspend)) {
1786 rk_camera_s_stream(icd, 0);
1787 sd = soc_camera_to_subdev(icd);
1788 v4l2_subdev_call(sd, video, s_stream, 0);
1789 ret = icd->ops->suspend(icd, state);
1791 pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
1792 pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
1793 pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
1794 pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
1795 pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
1796 pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
1797 pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
1799 pcdev->reginfo_suspend.Inval = Reg_Validate;
1800 rk_camera_deactivate(pcdev);
1802 RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__);
1804 RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
1806 mutex_unlock(&camera_lock);
1810 static int rk_camera_resume(struct soc_camera_device *icd)
1812 struct soc_camera_host *ici =
1813 to_soc_camera_host(icd->dev.parent);
1814 struct rk_camera_dev *pcdev = ici->priv;
1815 struct v4l2_subdev *sd;
1818 mutex_lock(&camera_lock);
1819 if ((pcdev->icd == icd) && (icd->ops->resume)) {
1820 if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
1821 rk_camera_activate(pcdev, icd);
1822 write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
1823 write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
1824 write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
1825 write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
1826 write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
1827 write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
1828 write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
1829 rk_videobuf_capture(pcdev->active,pcdev);
1830 rk_camera_s_stream(icd, 1);
1831 pcdev->reginfo_suspend.Inval = Reg_Invalidate;
1833 RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
1834 goto rk_camera_resume_end;
1837 ret = icd->ops->resume(icd);
1838 sd = soc_camera_to_subdev(icd);
1839 v4l2_subdev_call(sd, video, s_stream, 1);
1841 RKCAMERA_DG("%s Enter success\n",__FUNCTION__);
1843 RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
1846 rk_camera_resume_end:
1847 mutex_unlock(&camera_lock);
1851 static void rk_camera_reinit_work(struct work_struct *work)
1853 struct v4l2_subdev *sd;
1854 struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
1855 struct rk_camera_dev *pcdev = camera_work->pcdev;
1856 struct soc_camera_link *tmp_soc_cam_link;
1858 unsigned long flags = 0;
1859 if(pcdev->icd == NULL)
1861 sd = soc_camera_to_subdev(pcdev->icd);
1862 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
1865 RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
1866 RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
1867 RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
1868 RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
1869 RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
1870 RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
1871 RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
1872 RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
1873 RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
1875 RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
1876 RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
1877 RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
1878 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
1879 RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
1880 RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
1883 pcdev->stop_cif = true;
1884 write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
1885 RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
1887 spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
1888 for (index = 0; index < VIDEO_MAX_FRAME; index++) {
1889 if (NULL == pcdev->video_vq->bufs[index])
1892 if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
1894 list_del_init(&pcdev->video_vq->bufs[index]->queue);
1895 pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
1896 wake_up_all(&pcdev->video_vq->bufs[index]->done);
1897 printk("wake up video buffer index = %d !!!\n",index);
1900 spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags);
1902 RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
1904 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
1906 struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL;
1907 struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
1908 struct rk_camera_dev *pcdev = fps_timer->pcdev;
1910 // static unsigned int last_fps = 0;
1911 struct soc_camera_link *tmp_soc_cam_link;
1912 tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
1914 RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
1915 if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
1916 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);
1917 pcdev->camera_reinit_work.pcdev = pcdev;
1918 //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
1919 pcdev->reinit_times++;
1920 queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
1921 } else if(!pcdev->timer_get_fps) {
1922 pcdev->timer_get_fps = true;
1923 for (i=0; i<2; i++) {
1924 if (pcdev->icd == pcdev->icd_frmival[i].icd) {
1925 fival_nxt = pcdev->icd_frmival[i].fival_list;
1930 fival_pre = fival_nxt;
1931 while (fival_nxt != NULL) {
1933 RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
1934 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
1935 (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
1936 fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
1937 fival_nxt->fival.discrete.numerator);
1939 if (((fival_nxt->fival.pixel_format == pcdev->pixfmt)
1940 && (fival_nxt->fival.height == pcdev->icd->user_height)
1941 && (fival_nxt->fival.width == pcdev->icd->user_width))
1942 || (fival_nxt->fival.discrete.denominator == 0)) {
1944 if (fival_nxt->fival.discrete.denominator == 0) {
1945 fival_nxt->fival.index = 0;
1946 fival_nxt->fival.width = pcdev->icd->user_width;
1947 fival_nxt->fival.height= pcdev->icd->user_height;
1948 fival_nxt->fival.pixel_format = pcdev->pixfmt;
1949 fival_nxt->fival.discrete.denominator = pcdev->frame_interval;
1950 fival_nxt->fival.reserved[1] = (pcdev->icd_width<<16)
1951 |(pcdev->icd_height);
1952 fival_nxt->fival.discrete.numerator = 1000000;
1953 fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
1956 fival_rec = fival_nxt;
1958 fival_pre = fival_nxt;
1959 fival_nxt = fival_nxt->nxt;
1962 if ((rec_flag == 0) && fival_pre) {
1963 fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC);
1964 if (fival_pre->nxt != NULL) {
1965 fival_pre->nxt->fival.index = fival_pre->fival.index++;
1966 fival_pre->nxt->fival.width = pcdev->icd->user_width;
1967 fival_pre->nxt->fival.height= pcdev->icd->user_height;
1968 fival_pre->nxt->fival.pixel_format = pcdev->pixfmt;
1970 fival_pre->nxt->fival.discrete.denominator = pcdev->frame_interval;
1971 fival_pre->nxt->fival.reserved[1] = (pcdev->icd_width<<16)
1972 |(pcdev->icd_height);
1973 fival_pre->nxt->fival.discrete.numerator = 1000000;
1974 fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE;
1976 fival_rec = fival_pre->nxt;
1980 pcdev->last_fps = pcdev->fps ;
1981 pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
1982 pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
1983 //return HRTIMER_NORESTART;
1984 if(pcdev->reinit_times >=2)
1985 return HRTIMER_NORESTART;
1987 return HRTIMER_RESTART;
1989 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
1991 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1992 struct rk_camera_dev *pcdev = ici->priv;
1995 unsigned long flags;
1997 WARN_ON(pcdev->icd != icd);
1999 cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
2002 pcdev->last_fps = 0;
2003 pcdev->frame_interval = 0;
2004 hrtimer_cancel(&(pcdev->fps_timer.timer));
2005 pcdev->fps_timer.pcdev = pcdev;
2006 pcdev->timer_get_fps = false;
2007 pcdev->reinit_times = 0;
2008 pcdev->stop_cif = false;
2009 // hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2010 cif_ctrl_val |= ENABLE_CAPTURE;
2011 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2012 hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
2013 pcdev->fps_timer.istarted = true;
2015 //cancel timer before stop cif
2016 ret = hrtimer_cancel(&pcdev->fps_timer.timer);
2017 pcdev->fps_timer.istarted = false;
2018 flush_work(&(pcdev->camera_reinit_work.work));
2020 cif_ctrl_val &= ~ENABLE_CAPTURE;
2021 spin_lock_irqsave(&pcdev->lock, flags);
2022 write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
2023 pcdev->stop_cif = true;
2024 spin_unlock_irqrestore(&pcdev->lock, flags);
2025 flush_workqueue((pcdev->camera_wq));
2026 RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
2028 //must be reinit,or will be somthing wrong in irq process.
2029 if(enable == false){
2030 pcdev->active = NULL;
2031 INIT_LIST_HEAD(&pcdev->capture);
2033 RKCAMERA_DG("%s.. enable : 0x%x , CIF_CIF_CTRL = 0x%x\n", __FUNCTION__, enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
2036 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
2038 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2039 struct rk_camera_dev *pcdev = ici->priv;
2040 struct rk_camera_frmivalenum *fival_list = NULL;
2041 struct v4l2_frmivalenum *fival_head = NULL;
2042 int i,ret = 0,index;
2044 index = fival->index & 0x00ffffff;
2045 if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */
2046 for (i=0; i<2; i++) {
2047 if (pcdev->icd_frmival[i].icd == icd) {
2048 fival_list = pcdev->icd_frmival[i].fival_list;
2052 if (fival_list != NULL) {
2054 while (fival_list != NULL) {
2055 if ((fival->pixel_format == fival_list->fival.pixel_format)
2056 && (fival->height == fival_list->fival.height)
2057 && (fival->width == fival_list->fival.width)) {
2062 fival_list = fival_list->nxt;
2065 if ((i==index) && (fival_list != NULL)) {
2066 memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum));
2071 RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
2076 for (i=0; i<RK_CAM_NUM; i++) {
2077 if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
2078 fival_head = pcdev->pdata->info[i].fival;
2082 if (fival_head == NULL) {
2083 RKCAMERA_TR("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
2085 goto rk_camera_enum_frameintervals_end;
2089 while (fival_head->width && fival_head->height) {
2090 if ((fival->pixel_format == fival_head->pixel_format)
2091 && (fival->height == fival_head->height)
2092 && (fival->width == fival_head->width)) {
2101 if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
2102 memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
2103 RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
2104 fival->width, fival->height,
2105 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2106 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2107 fival->discrete.denominator,fival->discrete.numerator);
2110 RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2111 fival->width,fival->height,
2112 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2113 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2116 RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
2117 fival->width,fival->height,
2118 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
2119 (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
2124 rk_camera_enum_frameintervals_end:
2128 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2129 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
2130 const struct v4l2_queryctrl *qctrl, int zoom_rate)
2133 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2134 struct rk_camera_dev *pcdev = ici->priv;
2137 //change the crop and scale parameters
2138 a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2139 a.c.width = pcdev->host_width*100/zoom_rate;
2141 a.c.height = pcdev->host_height*100/zoom_rate;
2142 a.c.height &= ~0x03;
2143 a.c.left = (pcdev->host_width - a.c.width)>>1;
2144 a.c.top = (pcdev->host_height - a.c.height)>>1;
2145 down(&pcdev->zoominfo.sem);
2146 pcdev->zoominfo.a.c.height = a.c.height;
2147 pcdev->zoominfo.a.c.width = a.c.width;
2148 pcdev->zoominfo.a.c.top = a.c.top;
2149 pcdev->zoominfo.a.c.left = a.c.left;
2150 pcdev->zoominfo.vir_width = pcdev->host_width;
2151 up(&pcdev->zoominfo.sem);
2152 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 );
2157 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
2158 struct soc_camera_host_ops *ops, int id)
2162 for (i = 0; i < ops->num_controls; i++)
2163 if (ops->controls[i].id == id)
2164 return &ops->controls[i];
2170 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
2171 struct v4l2_control *sctrl)
2174 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
2175 const struct v4l2_queryctrl *qctrl;
2176 struct rk_camera_dev *pcdev = ici->priv;
2179 qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
2182 goto rk_camera_set_ctrl_end;
2187 #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
2188 case V4L2_CID_ZOOM_ABSOLUTE:
2190 if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
2192 goto rk_camera_set_ctrl_end;
2194 ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
2196 pcdev->zoominfo.zoom_rate = sctrl->value;
2198 goto rk_camera_set_ctrl_end;
2207 rk_camera_set_ctrl_end:
2211 static struct soc_camera_host_ops rk_soc_camera_host_ops =
2213 .owner = THIS_MODULE,
2214 .add = rk_camera_add_device,
2215 .remove = rk_camera_remove_device,
2216 .suspend = rk_camera_suspend,
2217 .resume = rk_camera_resume,
2218 .enum_frameinervals = rk_camera_enum_frameintervals,
2219 .set_crop = rk_camera_set_crop,
2220 .get_formats = rk_camera_get_formats,
2221 .put_formats = rk_camera_put_formats,
2222 .set_fmt = rk_camera_set_fmt,
2223 .try_fmt = rk_camera_try_fmt,
2224 .init_videobuf = rk_camera_init_videobuf,
2225 .reqbufs = rk_camera_reqbufs,
2226 .poll = rk_camera_poll,
2227 .querycap = rk_camera_querycap,
2228 .set_bus_param = rk_camera_set_bus_param,
2229 .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */
2230 .set_ctrl = rk_camera_set_ctrl,
2231 .controls = rk_camera_controls,
2232 .num_controls = ARRAY_SIZE(rk_camera_controls)
2235 static void rk_camera_cif_iomux(int cif_index)
2239 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
2242 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
2243 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
2244 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
2245 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
2246 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
2247 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
2248 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
2249 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
2251 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
2252 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
2253 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
2254 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
2255 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
2256 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
2257 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
2258 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
2261 printk("cif index is erro!!!\n");
2266 static int rk_camera_probe(struct platform_device *pdev)
2268 struct rk_camera_dev *pcdev;
2269 struct resource *res;
2270 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
2274 RKCAMERA_TR("RK30 Camera driver version: v%d.%d.%d\n",(RK_CAM_VERSION_CODE&0xff0000)>>16,
2275 (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff);
2277 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2278 irq = platform_get_irq(pdev, 0);
2279 if (!res || irq < 0) {
2283 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
2285 dev_err(&pdev->dev, "Could not allocate pcdev\n");
2290 pcdev->zoominfo.zoom_rate = 100;
2291 pcdev->hostid = pdev->id;
2292 /*config output clk*/ // must modify start
2294 pcdev->pd_cif = clk_get(NULL, "pd_cif0");
2295 pcdev->aclk_cif = clk_get(NULL, "aclk_cif0");
2296 pcdev->hclk_cif = clk_get(NULL, "hclk_cif0");
2297 pcdev->cif_clk_in = clk_get(NULL, "cif0_in");
2298 pcdev->cif_clk_out = clk_get(NULL, "cif0_out");
2299 rk_camera_cif_iomux(0);
2301 pcdev->pd_cif = clk_get(NULL, "pd_cif1");
2302 pcdev->aclk_cif = clk_get(NULL, "aclk_cif1");
2303 pcdev->hclk_cif = clk_get(NULL, "hclk_cif1");
2304 pcdev->cif_clk_in = clk_get(NULL, "cif1_in");
2305 pcdev->cif_clk_out = clk_get(NULL, "cif1_out");
2307 rk_camera_cif_iomux(1);
2310 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)){
2311 RKCAMERA_TR(KERN_ERR "%s(%d): failed to get cif clock source\n",__FUNCTION__,__LINE__);
2313 goto exit_reqmem_vip;
2316 dev_set_drvdata(&pdev->dev, pcdev);
2318 pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */
2320 if (pcdev->pdata && pcdev->pdata->io_init) {
2321 pcdev->pdata->io_init();
2323 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2324 if (pcdev->pdata && IS_CIF0()) {
2325 pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
2326 pcdev->vipmem_size = pcdev->pdata->meminfo.size;
2327 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);
2328 } else if (pcdev->pdata) {
2329 pcdev->vipmem_phybase = pcdev->pdata->meminfo_cif1.start;
2330 pcdev->vipmem_size = pcdev->pdata->meminfo_cif1.size;
2331 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);
2333 RKCAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
2334 pcdev->vipmem_phybase = 0;
2335 pcdev->vipmem_size = 0;
2338 INIT_LIST_HEAD(&pcdev->capture);
2339 INIT_LIST_HEAD(&pcdev->camera_work_queue);
2340 spin_lock_init(&pcdev->lock);
2341 spin_lock_init(&pcdev->camera_work_lock);
2342 sema_init(&pcdev->zoominfo.sem,1);
2345 * Request the regions.
2348 if (!request_mem_region(res->start, res->end - res->start + 1,
2349 RK29_CAM_DRV_NAME)) {
2351 goto exit_reqmem_vip;
2353 pcdev->base = ioremap(res->start, res->end - res->start + 1);
2354 if (pcdev->base == NULL) {
2355 dev_err(pcdev->dev, "ioremap() of registers failed\n");
2357 goto exit_ioremap_vip;
2362 pcdev->dev = &pdev->dev;
2364 /* config buffer address */
2367 err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
2370 dev_err(pcdev->dev, "Camera interrupt register failed \n");
2375 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
2377 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
2379 pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
2381 if (pcdev->camera_wq == NULL)
2385 pcdev->camera_reinit_work.pcdev = pcdev;
2386 INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
2388 for (i=0; i<2; i++) {
2389 pcdev->icd_frmival[i].icd = NULL;
2390 pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL);
2393 pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME;
2394 pcdev->soc_host.ops = &rk_soc_camera_host_ops;
2395 pcdev->soc_host.priv = pcdev;
2396 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
2397 pcdev->soc_host.nr = pdev->id;
2399 err = soc_camera_host_register(&pcdev->soc_host);
2402 pcdev->fps_timer.pcdev = pcdev;
2403 hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2404 pcdev->fps_timer.timer.function = rk_camera_fps_func;
2405 pcdev->icd_cb.sensor_cb = NULL;
2407 RKCAMERA_DG("%s(%d) Exit \n",__FUNCTION__,__LINE__);
2412 for (i=0; i<2; i++) {
2413 fival_list = pcdev->icd_frmival[i].fival_list;
2414 fival_nxt = fival_list;
2415 while(fival_nxt != NULL) {
2416 fival_nxt = fival_list->nxt;
2418 fival_list = fival_nxt;
2422 free_irq(pcdev->irq, pcdev);
2423 if (pcdev->camera_wq) {
2424 destroy_workqueue(pcdev->camera_wq);
2425 pcdev->camera_wq = NULL;
2428 iounmap(pcdev->base);
2430 release_mem_region(res->start, res->end - res->start + 1);
2434 pcdev->aclk_cif = NULL;
2436 pcdev->hclk_cif = NULL;
2437 if(pcdev->cif_clk_in)
2438 pcdev->cif_clk_in = NULL;
2439 if(pcdev->cif_clk_out)
2440 pcdev->cif_clk_out = NULL;
2449 static int __devexit rk_camera_remove(struct platform_device *pdev)
2451 struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
2452 struct resource *res;
2453 struct rk_camera_frmivalenum *fival_list,*fival_nxt;
2456 free_irq(pcdev->irq, pcdev);
2458 if (pcdev->camera_wq) {
2459 destroy_workqueue(pcdev->camera_wq);
2460 pcdev->camera_wq = NULL;
2463 for (i=0; i<2; i++) {
2464 fival_list = pcdev->icd_frmival[i].fival_list;
2465 fival_nxt = fival_list;
2466 while(fival_nxt != NULL) {
2467 fival_nxt = fival_list->nxt;
2469 fival_list = fival_nxt;
2473 soc_camera_host_unregister(&pcdev->soc_host);
2476 release_mem_region(res->start, res->end - res->start + 1);
2477 if (pcdev->pdata && pcdev->pdata->io_deinit) { /* ddl@rock-chips.com : Free IO in deinit function */
2478 pcdev->pdata->io_deinit(0);
2479 pcdev->pdata->io_deinit(1);
2484 dev_info(&pdev->dev, "RK28 Camera driver unloaded\n");
2489 static struct platform_driver rk_camera_driver =
2492 .name = RK29_CAM_DRV_NAME,
2494 .probe = rk_camera_probe,
2495 .remove = __devexit_p(rk_camera_remove),
2498 static int rk_camera_init_async(void *unused)
2500 RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
2501 platform_driver_register(&rk_camera_driver);
2505 static int __devinit rk_camera_init(void)
2507 RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
2508 kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
2512 static void __exit rk_camera_exit(void)
2514 platform_driver_unregister(&rk_camera_driver);
2517 device_initcall_sync(rk_camera_init);
2518 module_exit(rk_camera_exit);
2520 MODULE_DESCRIPTION("RKSoc Camera Host driver");
2521 MODULE_AUTHOR("ddl <ddl@rock-chips>");
2522 MODULE_LICENSE("GPL");