2 *************************************************************************
3 * Rockchip driver for CIF ISP 1.0
4 * (Based on Intel driver for sofiaxxx)
6 * Copyright (C) 2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *************************************************************************
17 #include <media/v4l2-common.h>
18 #include <media/v4l2-event.h>
19 #include <media/v4l2-fh.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/videobuf-dma-contig.h>
22 #include "cif_isp10.h"
23 #include "cif_isp10_regs.h"
24 #include "cif_isp10_version.h"
25 #include <linux/module.h>
27 #include <media/v4l2-controls_rockchip.h>
28 #include <linux/pm_runtime.h>
29 #include <linux/pagemap.h>
30 #include <linux/slab.h>
32 #define CIF_ISP10_V4L2_SP_DEV_MAJOR 0
33 #define CIF_ISP10_V4L2_ISP_DEV_MAJOR 1
34 #define CIF_ISP10_V4L2_MP_DEV_MAJOR 2
35 #define CIF_ISP10_V4L2_DMA_DEV_MAJOR 3
42 /* One structure per open file handle */
43 struct cif_isp10_v4l2_fh {
44 enum cif_isp10_stream_id stream_id;
48 /* One structure per video node */
49 struct cif_isp10_v4l2_node {
50 struct videobuf_queue buf_queue;
51 struct video_device vdev;
53 struct cif_isp10_v4l2_fh *owner;
56 /* One structure per device */
57 struct cif_isp10_v4l2_device {
58 struct cif_isp10_v4l2_node node[4];
62 spinlock_t iowrite32_verify_lock;
64 static struct cif_isp10_v4l2_fh *to_fh(struct file *file)
66 if (!file || !file->private_data)
69 return container_of(file->private_data, struct cif_isp10_v4l2_fh, fh);
72 static struct cif_isp10_v4l2_node *to_node(struct cif_isp10_v4l2_fh *fh)
74 struct video_device *vdev = fh ? fh->fh.vdev : NULL;
79 return container_of(vdev, struct cif_isp10_v4l2_node, vdev);
82 static struct videobuf_queue *to_videobuf_queue(
85 struct cif_isp10_v4l2_fh *fh = to_fh(file);
86 struct video_device *vdev = fh ? fh->fh.vdev : NULL;
87 struct cif_isp10_v4l2_node *node = to_node(fh);
88 struct videobuf_queue *q;
90 if (unlikely(!vdev)) {
91 cif_isp10_pltfrm_pr_err(NULL,
97 cif_isp10_pltfrm_pr_err(NULL,
98 "buffer queue is NULL\n");
105 static enum cif_isp10_stream_id to_stream_id(
108 struct cif_isp10_v4l2_fh *fh;
110 if (unlikely(!file)) {
111 cif_isp10_pltfrm_pr_err(NULL,
112 "NULL file handle\n");
117 cif_isp10_pltfrm_pr_err(NULL,
122 return fh->stream_id;
125 static struct cif_isp10_device *to_cif_isp10_device(
126 struct videobuf_queue *queue)
128 return queue->priv_data;
131 static enum cif_isp10_stream_id to_cif_isp10_stream_id(
132 struct videobuf_queue *queue)
134 struct cif_isp10_v4l2_node *node =
135 container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
136 struct video_device *vdev =
139 if (!strcmp(vdev->name, SP_VDEV_NAME))
140 return CIF_ISP10_STREAM_SP;
141 if (!strcmp(vdev->name, MP_VDEV_NAME))
142 return CIF_ISP10_STREAM_MP;
143 if (!strcmp(vdev->name, DMA_VDEV_NAME))
144 return CIF_ISP10_STREAM_DMA;
146 cif_isp10_pltfrm_pr_err(NULL,
147 "unsupported/unknown device name %s\n", vdev->name);
151 static const char *cif_isp10_v4l2_buf_type_string(
152 enum v4l2_buf_type buf_type)
155 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
156 return "VIDEO_CAPTURE";
157 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
158 return "VIDEO_OVERLAY";
159 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
160 return "VIDEO_OUTPUT";
164 return "UNKNOWN/UNSUPPORTED";
167 const char *cif_isp10_v4l2_pix_fmt_string(
171 case V4L2_PIX_FMT_RGB332:
172 return "V4L2-RGB332";
173 case V4L2_PIX_FMT_RGB555:
174 return "V4L2-RGB555";
175 case V4L2_PIX_FMT_RGB565:
176 return "V4L2-RGB565";
177 case V4L2_PIX_FMT_RGB555X:
178 return "V4L2-RGB555X";
179 case V4L2_PIX_FMT_RGB565X:
180 return "V4L2-RGB565X";
181 case V4L2_PIX_FMT_BGR24:
183 case V4L2_PIX_FMT_RGB24:
185 case V4L2_PIX_FMT_BGR32:
187 case V4L2_PIX_FMT_RGB32:
189 case V4L2_PIX_FMT_GREY:
191 case V4L2_PIX_FMT_YVU410:
192 return "V4L2-YVU410";
193 case V4L2_PIX_FMT_YVU420:
194 return "V4L2-YVU420";
195 case V4L2_PIX_FMT_YUYV:
197 case V4L2_PIX_FMT_UYVY:
199 case V4L2_PIX_FMT_YUV422P:
200 return "V4L2-YUV422P";
201 case V4L2_PIX_FMT_YUV411P:
202 return "V4L2-YUV411P";
203 case V4L2_PIX_FMT_Y41P:
205 case V4L2_PIX_FMT_NV12:
207 case V4L2_PIX_FMT_NV21:
209 case V4L2_PIX_FMT_YUV410:
210 return "V4L2-YUV410";
211 case V4L2_PIX_FMT_YUV420:
212 return "V4L2--YUV420";
213 case V4L2_PIX_FMT_YYUV:
215 case V4L2_PIX_FMT_HI240:
217 case V4L2_PIX_FMT_WNVA:
219 case V4L2_PIX_FMT_NV16:
221 case V4L2_PIX_FMT_YUV444:
222 return "V4L2-YUV444P";
223 case V4L2_PIX_FMT_NV24:
224 return "M5-YUV444SP";
225 case V4L2_PIX_FMT_JPEG:
227 case V4L2_PIX_FMT_SGRBG10:
228 return "RAW-BAYER-10Bits";
229 case V4L2_PIX_FMT_SGRBG8:
230 return "RAW-BAYER-8Bits";
232 return "UNKNOWN/UNSUPPORTED";
235 static int cif_isp10_v4l2_cid2cif_isp10_cid(u32 v4l2_cid)
238 case V4L2_CID_FLASH_LED_MODE:
239 return CIF_ISP10_CID_FLASH_MODE;
240 case V4L2_CID_AUTOGAIN:
241 return CIF_ISP10_CID_AUTO_GAIN;
242 case V4L2_EXPOSURE_AUTO:
243 return CIF_ISP10_CID_AUTO_EXPOSURE;
244 case V4L2_CID_AUTO_WHITE_BALANCE:
245 return CIF_ISP10_CID_AUTO_WHITE_BALANCE;
246 case V4L2_CID_BLACK_LEVEL:
247 return CIF_ISP10_CID_BLACK_LEVEL;
248 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
249 return CIF_ISP10_CID_WB_TEMPERATURE;
250 case V4L2_CID_EXPOSURE:
251 return CIF_ISP10_CID_EXPOSURE_TIME;
253 return CIF_ISP10_CID_ANALOG_GAIN;
254 case V4L2_CID_FOCUS_ABSOLUTE:
255 return CIF_ISP10_CID_FOCUS_ABSOLUTE;
256 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
257 return CIF_ISP10_CID_AUTO_N_PRESET_WHITE_BALANCE;
258 case V4L2_CID_SCENE_MODE:
259 return CIF_ISP10_CID_SCENE_MODE;
260 case V4L2_CID_COLORFX:
261 return CIF_ISP10_CID_IMAGE_EFFECT;
262 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
263 return CIF_ISP10_CID_JPEG_QUALITY;
265 return CIF_ISP10_CID_HFLIP;
267 return CIF_ISP10_CID_VFLIP;
268 case V4L2_CID_ISO_SENSITIVITY:
269 return CIF_ISP10_CID_ISO_SENSITIVITY;
270 case RK_V4L2_CID_AUTO_FPS:
271 return CIF_ISP10_CID_AUTO_FPS;
273 cif_isp10_pltfrm_pr_err(NULL,
274 "unknown/unsupported V4L2 CID 0x%x\n",
281 static enum cif_isp10_image_effect cif_isp10_v4l2_colorfx2cif_isp10_ie(
284 switch (v4l2_colorfx) {
285 case V4L2_COLORFX_SEPIA:
286 return CIF_ISP10_IE_SEPIA;
287 case V4L2_COLORFX_BW:
288 return CIF_ISP10_IE_BW;
289 case V4L2_COLORFX_NEGATIVE:
290 return CIF_ISP10_IE_NEGATIVE;
291 case V4L2_COLORFX_EMBOSS:
292 return CIF_ISP10_IE_EMBOSS;
293 case V4L2_COLORFX_SKETCH:
294 return CIF_ISP10_IE_SKETCH;
295 case V4L2_COLORFX_NONE:
296 return CIF_ISP10_IE_NONE;
298 cif_isp10_pltfrm_pr_err(NULL,
299 "unknown/unsupported V4L2 COLORFX %d\n",
306 static enum cif_isp10_pix_fmt cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
307 u32 v4l2_pix_fmt, struct videobuf_queue *queue)
309 /*struct cif_isp10_v4l2_node *node =
310 * container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
311 * struct video_device *vdev =
315 switch (v4l2_pix_fmt) {
316 case V4L2_PIX_FMT_GREY:
318 case V4L2_PIX_FMT_YUV420:
320 case V4L2_PIX_FMT_YVU420:
322 case V4L2_PIX_FMT_NV12:
324 case V4L2_PIX_FMT_NV21:
326 case V4L2_PIX_FMT_YUYV:
328 case V4L2_PIX_FMT_UYVY:
330 case V4L2_PIX_FMT_YUV422P:
332 case V4L2_PIX_FMT_NV16:
334 case V4L2_PIX_FMT_YUV444:
336 case V4L2_PIX_FMT_NV24:
338 case V4L2_PIX_FMT_RGB565:
340 case V4L2_PIX_FMT_RGB24:
342 case V4L2_PIX_FMT_SBGGR8:
343 return CIF_BAYER_SBGGR8;
344 case V4L2_PIX_FMT_SGBRG8:
345 return CIF_BAYER_SGBRG8;
346 case V4L2_PIX_FMT_SGRBG8:
347 return CIF_BAYER_SGRBG8;
348 case V4L2_PIX_FMT_SRGGB8:
349 return CIF_BAYER_SRGGB8;
350 case V4L2_PIX_FMT_SBGGR10:
351 return CIF_BAYER_SBGGR10;
352 case V4L2_PIX_FMT_SGBRG10:
353 return CIF_BAYER_SGBRG10;
354 case V4L2_PIX_FMT_SGRBG10:
355 return CIF_BAYER_SGRBG10;
356 case V4L2_PIX_FMT_SRGGB10:
357 return CIF_BAYER_SRGGB10;
358 case V4L2_PIX_FMT_SBGGR12:
359 return CIF_BAYER_SBGGR12;
360 case V4L2_PIX_FMT_SGBRG12:
361 return CIF_BAYER_SGBRG12;
362 case V4L2_PIX_FMT_SGRBG12:
363 return CIF_BAYER_SGRBG12;
364 case V4L2_PIX_FMT_SRGGB12:
365 return CIF_BAYER_SRGGB12;
366 case V4L2_PIX_FMT_JPEG:
369 cif_isp10_pltfrm_pr_err(NULL,
370 "unknown or unsupported V4L2 pixel format %c%c%c%c\n",
371 (u8)(v4l2_pix_fmt & 0xff),
372 (u8)((v4l2_pix_fmt >> 8) & 0xff),
373 (u8)((v4l2_pix_fmt >> 16) & 0xff),
374 (u8)((v4l2_pix_fmt >> 24) & 0xff));
375 return CIF_UNKNOWN_FORMAT;
379 static int cif_isp10_v4l2_register_video_device(
380 struct cif_isp10_device *dev,
381 struct video_device *vdev,
385 const struct v4l2_file_operations *fops,
386 const struct v4l2_ioctl_ops *ioctl_ops)
390 vdev->release = video_device_release;
391 strlcpy(vdev->name, name, sizeof(vdev->name));
392 vdev->vfl_type = qtype;
394 video_set_drvdata(vdev, dev);
396 vdev->ioctl_ops = ioctl_ops;
397 vdev->v4l2_dev = &dev->v4l2_dev;
398 if (qtype == V4L2_BUF_TYPE_VIDEO_OUTPUT)
399 vdev->vfl_dir = VFL_DIR_TX;
401 vdev->vfl_dir = VFL_DIR_RX;
403 ret = video_register_device(vdev, VFL_TYPE_GRABBER, major);
404 if (IS_ERR_VALUE(ret)) {
405 cif_isp10_pltfrm_pr_err(NULL,
406 "video_register_device failed with error %d\n", ret);
410 cif_isp10_pltfrm_pr_info(NULL,
411 "video device video%d.%d (%s) successfully registered\n",
412 major, vdev->minor, name);
416 video_device_release(vdev);
417 cif_isp10_pltfrm_pr_err(NULL,
418 "failed with err %d\n", ret);
422 static int cif_isp10_v4l2_streamon(
425 enum v4l2_buf_type buf_type)
428 struct videobuf_queue *queue = to_videobuf_queue(file);
429 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
430 static u32 streamon_cnt_sp;
431 static u32 streamon_cnt_mp;
432 static u32 streamon_cnt_dma;
433 struct cif_isp10_v4l2_fh *fh = to_fh(file);
434 struct cif_isp10_v4l2_node *node = to_node(fh);
435 u32 stream_ids = to_stream_id(file);
437 if (node->owner != fh)
440 cif_isp10_pltfrm_pr_dbg(dev->dev, "%s(%d)\n",
441 cif_isp10_v4l2_buf_type_string(queue->type),
442 (stream_ids & CIF_ISP10_STREAM_MP) ? ++streamon_cnt_mp :
443 ((stream_ids & CIF_ISP10_STREAM_SP) ? ++streamon_cnt_sp :
444 ++streamon_cnt_dma));
446 ret = videobuf_streamon(queue);
447 if (IS_ERR_VALUE(ret)) {
448 cif_isp10_pltfrm_pr_err(dev->dev,
449 "videobuf_streamon failed\n");
453 ret = cif_isp10_streamon(dev, stream_ids);
454 if (IS_ERR_VALUE(ret)) {
455 videobuf_queue_cancel(queue);
461 (void)videobuf_mmap_free(queue);
462 cif_isp10_pltfrm_pr_err(dev->dev, "failed with error %d\n", ret);
466 static int cif_isp10_v4l2_do_streamoff(
471 struct videobuf_queue *queue = to_videobuf_queue(file);
472 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
473 struct cif_isp10_v4l2_fh *fh = to_fh(file);
474 struct cif_isp10_v4l2_node *node = to_node(fh);
475 u32 stream_ids = to_stream_id(file);
477 cif_isp10_pltfrm_pr_dbg(dev->dev, "%s\n",
478 cif_isp10_v4l2_buf_type_string(queue->type));
480 if (node->owner != fh)
483 err = cif_isp10_streamoff(dev, stream_ids);
484 if (IS_ERR_VALUE(err))
486 err = videobuf_streamoff(queue);
487 if (IS_ERR_VALUE(err)) {
488 cif_isp10_pltfrm_pr_err(dev->dev,
489 "videobuf_streamoff failed with error %d\n", err);
492 err = videobuf_mmap_free(queue);
493 if (IS_ERR_VALUE(err)) {
494 cif_isp10_pltfrm_pr_err(dev->dev,
495 "videobuf_mmap_free failed with error %d\n", err);
499 if (IS_ERR_VALUE(ret))
500 cif_isp10_pltfrm_pr_err(dev->dev,
501 "failed with error %d\n", ret);
506 static int cif_isp10_v4l2_streamoff(
509 enum v4l2_buf_type buf_type)
511 int ret = cif_isp10_v4l2_do_streamoff(file);
513 if (IS_ERR_VALUE(ret))
514 cif_isp10_pltfrm_pr_err(NULL,
515 "failed with error %d\n", ret);
520 static int cif_isp10_v4l2_qbuf(
523 struct v4l2_buffer *buf)
526 struct videobuf_queue *queue = to_videobuf_queue(file);
527 struct cif_isp10_v4l2_fh *fh = to_fh(file);
528 struct cif_isp10_v4l2_node *node = to_node(fh);
530 cif_isp10_pltfrm_pr_dbg(NULL,
531 "%s buffer type %s, index %d, length %d\n",
532 cif_isp10_v4l2_buf_type_string(queue->type),
533 cif_isp10_v4l2_buf_type_string(buf->type),
534 buf->index, buf->length);
536 if (node->owner != fh)
539 ret = videobuf_qbuf(queue, buf);
540 if (IS_ERR_VALUE(ret))
541 cif_isp10_pltfrm_pr_err(NULL,
542 "videobuf_qbuf failed with error %d\n", ret);
546 static int cif_isp10_v4l2_dqbuf(
549 struct v4l2_buffer *buf)
552 struct videobuf_queue *queue = to_videobuf_queue(file);
553 struct cif_isp10_v4l2_fh *fh = to_fh(file);
554 struct cif_isp10_v4l2_node *node = to_node(fh);
556 cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
557 cif_isp10_v4l2_buf_type_string(queue->type));
559 if (node->owner != fh)
562 ret = videobuf_dqbuf(queue, buf, file->f_flags & O_NONBLOCK);
563 if (IS_ERR_VALUE(ret) && (ret != -EAGAIN))
564 cif_isp10_pltfrm_pr_err(NULL,
565 "videobuf_dqbuf failed with error %d\n", ret);
567 cif_isp10_pltfrm_pr_dbg(NULL,
568 "dequeued buffer %d, size %d\n",
569 buf->index, buf->length);
573 static void cif_isp10_v4l2_buf_release(
574 struct videobuf_queue *queue,
575 struct videobuf_buffer *buf)
577 cif_isp10_pltfrm_pr_dbg(NULL,
579 cif_isp10_v4l2_buf_type_string(queue->type));
584 videobuf_dma_contig_free(queue, buf);
586 buf->state = VIDEOBUF_NEEDS_INIT;
589 static void cif_isp10_v4l2_buf_queue(
590 struct videobuf_queue *queue,
591 struct videobuf_buffer *buf)
593 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
594 enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
596 cif_isp10_pltfrm_pr_dbg(NULL,
597 "%s %dx%d, size %lu, bytesperline %d\n",
598 cif_isp10_v4l2_buf_type_string(queue->type),
599 buf->width, buf->height, buf->size, buf->bytesperline);
601 if (!IS_ERR_VALUE(cif_isp10_qbuf(dev, strm, buf)))
602 buf->state = VIDEOBUF_QUEUED;
604 cif_isp10_pltfrm_pr_err(NULL, "failed\n");
607 static int cif_isp10_v4l2_buf_setup(
608 struct videobuf_queue *queue,
613 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
614 enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
616 cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
617 cif_isp10_v4l2_buf_type_string(queue->type),
620 ret = cif_isp10_calc_min_out_buff_size(
622 if (IS_ERR_VALUE(ret)) {
623 cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
627 cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
628 cif_isp10_v4l2_buf_type_string(queue->type),
634 static int cif_isp10_v4l2_buf_prepare(
635 struct videobuf_queue *queue,
636 struct videobuf_buffer *buf,
637 enum v4l2_field field)
640 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
641 enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
644 cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
645 cif_isp10_v4l2_buf_type_string(queue->type));
647 ret = cif_isp10_calc_min_out_buff_size(
649 if (IS_ERR_VALUE(ret))
652 if (strm == CIF_ISP10_STREAM_SP) {
654 dev->config.mi_config.sp.output.width;
656 dev->config.mi_config.sp.output.height;
657 } else if (strm == CIF_ISP10_STREAM_MP) {
659 dev->config.mi_config.mp.output.width;
661 dev->config.mi_config.mp.output.height;
662 } else if (strm == CIF_ISP10_STREAM_DMA) {
664 dev->config.mi_config.dma.output.width;
666 dev->config.mi_config.dma.output.height;
668 cif_isp10_pltfrm_pr_err(NULL,
669 "wrong buffer queue %d\n", queue->type);
675 cif_isp10_pltfrm_pr_dbg(NULL, "%s buffer prepared %dx%d, size %d\n",
676 cif_isp10_v4l2_buf_type_string(queue->type),
677 buf->width, buf->height, size);
679 if (buf->state == VIDEOBUF_NEEDS_INIT) {
680 ret = videobuf_iolock(queue, buf, NULL);
681 if (IS_ERR_VALUE(ret)) {
682 cif_isp10_pltfrm_pr_err(NULL,
683 "videobuf_iolock failed with error %d\n", ret);
687 buf->state = VIDEOBUF_PREPARED;
691 cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
692 cif_isp10_v4l2_buf_release(queue, buf);
696 static int cif_isp10_v4l2_reqbufs(
699 struct v4l2_requestbuffers *req)
701 struct cif_isp10_v4l2_fh *fh = to_fh(file);
702 struct cif_isp10_v4l2_node *node = to_node(fh);
704 struct videobuf_queue *queue = to_videobuf_queue(file);
705 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
706 enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
708 cif_isp10_pltfrm_pr_dbg(NULL,
709 "%s requested type %s, count %d\n",
710 cif_isp10_v4l2_buf_type_string(queue->type),
711 cif_isp10_v4l2_buf_type_string(req->type),
714 if (node->owner && node->owner != fh)
718 ret = videobuf_reqbufs(queue, req);
719 if (IS_ERR_VALUE(ret)) {
720 cif_isp10_pltfrm_pr_err(NULL,
721 "videobuf_reqbufs failed with error %d\n", ret);
723 cif_isp10_reqbufs(dev, strm, req);
727 static int cif_isp10_v4l2_querybuf(
730 struct v4l2_buffer *buf)
733 struct videobuf_queue *queue = to_videobuf_queue(file);
735 cif_isp10_pltfrm_pr_dbg(NULL,
737 cif_isp10_v4l2_buf_type_string(queue->type), buf->index);
739 ret = videobuf_querybuf(queue, buf);
740 if (IS_ERR_VALUE(ret))
741 cif_isp10_pltfrm_pr_err(NULL,
742 "videobuf_querybuf failed with error %d\n", ret);
747 static int cif_isp10_v4l2_s_ctrl(
750 struct v4l2_control *vc)
752 struct videobuf_queue *queue = to_videobuf_queue(file);
753 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
754 enum cif_isp10_cid id =
755 cif_isp10_v4l2_cid2cif_isp10_cid(vc->id);
758 if (IS_ERR_VALUE(id))
762 case V4L2_CID_COLORFX:
763 val = cif_isp10_v4l2_colorfx2cif_isp10_ie(val);
765 case V4L2_CID_FLASH_LED_MODE:
766 if (vc->value == V4L2_FLASH_LED_MODE_NONE)
767 val = CIF_ISP10_FLASH_MODE_OFF;
768 else if (vc->value == V4L2_FLASH_LED_MODE_FLASH)
769 val = CIF_ISP10_FLASH_MODE_FLASH;
770 else if (vc->value == V4L2_FLASH_LED_MODE_TORCH)
771 val = CIF_ISP10_FLASH_MODE_TORCH;
779 return cif_isp10_s_ctrl(dev, id, val);
782 static int cif_isp10_v4l2_s_fmt(
785 struct v4l2_format *f)
788 struct videobuf_queue *queue = to_videobuf_queue(file);
789 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
790 struct cif_isp10_v4l2_fh *fh = to_fh(file);
791 struct cif_isp10_v4l2_node *node = to_node(fh);
792 struct cif_isp10_strm_fmt strm_fmt;
794 cif_isp10_pltfrm_pr_dbg(NULL,
796 cif_isp10_v4l2_buf_type_string(queue->type));
798 if (node->owner && node->owner != fh)
801 strm_fmt.frm_fmt.pix_fmt =
802 cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
803 f->fmt.pix.pixelformat, queue);
804 strm_fmt.frm_fmt.width = f->fmt.pix.width;
805 strm_fmt.frm_fmt.height = f->fmt.pix.height;
806 /* strm_fmt.frm_fmt.quantization = f->fmt.pix.quantization; */
807 strm_fmt.frm_fmt.quantization = 0;
808 ret = cif_isp10_s_fmt(dev,
811 f->fmt.pix.bytesperline);
812 if (IS_ERR_VALUE(ret))
817 cif_isp10_pltfrm_pr_err(NULL,
818 "failed with error %d\n", ret);
822 /* existence of this function is checked by V4L2 */
823 static int cif_isp10_v4l2_g_fmt(
826 struct v4l2_format *f)
831 static int cif_isp10_v4l2_s_input(
837 struct videobuf_queue *queue = to_videobuf_queue(file);
838 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
840 cif_isp10_pltfrm_pr_dbg(dev->dev, "setting input to %d\n", i);
842 ret = cif_isp10_s_input(dev, i);
843 if (IS_ERR_VALUE(ret))
848 cif_isp10_pltfrm_pr_err(NULL,
849 "failed with error %d\n", ret);
853 static int cif_isp10_v4l2_enum_framesizes(
856 struct v4l2_frmsizeenum *fsize)
858 /* THIS FUNCTION IS UNDER CONSTRUCTION */
860 struct videobuf_queue *queue = to_videobuf_queue(file);
861 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
863 if (IS_ERR_OR_NULL(dev->img_src)) {
864 cif_isp10_pltfrm_pr_err(NULL,
865 "input has not yet been selected, cannot enumerate formats\n");
872 cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
876 /* fops **********************************************************************/
878 const struct videobuf_queue_ops cif_isp10_qops = {
879 .buf_setup = cif_isp10_v4l2_buf_setup,
880 .buf_prepare = cif_isp10_v4l2_buf_prepare,
881 .buf_queue = cif_isp10_v4l2_buf_queue,
882 .buf_release = cif_isp10_v4l2_buf_release,
885 static int cif_isp10_v4l2_open(
889 struct video_device *vdev = video_devdata(file);
890 struct cif_isp10_device *dev = video_get_drvdata(vdev);
891 struct cif_isp10_v4l2_fh *fh;
892 struct cif_isp10_v4l2_node *node;
893 enum v4l2_buf_type buf_type;
894 enum cif_isp10_stream_id stream_id;
895 struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
896 (struct cif_isp10_v4l2_device *)dev->nodes;
898 cif_isp10_pltfrm_pr_dbg(NULL,
899 "video device video%d.%d (%s)\n",
900 vdev->num, vdev->minor, vdev->name);
902 if (vdev->minor == cif_isp10_v4l2_dev->node[SP_DEV].vdev.minor) {
903 buf_type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
904 stream_id = CIF_ISP10_STREAM_SP;
905 } else if (vdev->minor == cif_isp10_v4l2_dev->node[MP_DEV].vdev.minor) {
906 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
907 stream_id = CIF_ISP10_STREAM_MP;
908 } else if (vdev->minor ==
909 cif_isp10_v4l2_dev->node[DMA_DEV].vdev.minor) {
910 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
911 stream_id = CIF_ISP10_STREAM_DMA;
913 cif_isp10_pltfrm_pr_err(NULL,
914 "invalid video device video%d.%d (%s)\n",
915 vdev->num, vdev->minor, vdev->name);
920 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
922 cif_isp10_pltfrm_pr_err(NULL,
923 "memory allocation failed\n");
927 fh->stream_id = stream_id;
929 file->private_data = &fh->fh;
930 v4l2_fh_init(&fh->fh, vdev);
931 v4l2_fh_add(&fh->fh);
934 if (++node->users > 1)
937 /* First open of the device, so initialize everything */
940 videobuf_queue_dma_contig_init(
941 to_videobuf_queue(file),
947 sizeof(struct videobuf_buffer),
950 ret = cif_isp10_init(dev, to_stream_id(file));
951 if (IS_ERR_VALUE(ret)) {
952 v4l2_fh_del(&fh->fh);
953 v4l2_fh_exit(&fh->fh);
961 cif_isp10_pltfrm_pr_err(NULL,
962 "failed with error %d\n", ret);
966 static int cif_isp10_v4l2_release(struct file *file)
969 struct videobuf_queue *queue = to_videobuf_queue(file);
970 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
971 struct cif_isp10_v4l2_fh *fh = to_fh(file);
972 struct cif_isp10_v4l2_node *node = to_node(fh);
973 enum cif_isp10_stream_id stream_id = to_stream_id(file);
975 cif_isp10_pltfrm_pr_dbg(dev->dev, "%s\n",
976 cif_isp10_v4l2_buf_type_string(queue->type));
981 cif_isp10_pltfrm_pr_warn(dev->dev,
982 "number of users for this device is already 0\n");
987 if (queue->streaming)
988 if (IS_ERR_VALUE(cif_isp10_v4l2_do_streamoff(file)))
989 cif_isp10_pltfrm_pr_warn(dev->dev,
990 "streamoff failed\n");
992 /* Last close, so uninitialize hardware */
993 ret = cif_isp10_release(dev, stream_id);
996 if (node->owner == fh)
999 v4l2_fh_del(&fh->fh);
1000 v4l2_fh_exit(&fh->fh);
1003 if (IS_ERR_VALUE(ret))
1004 cif_isp10_pltfrm_pr_err(dev->dev,
1005 "failed with error %d\n", ret);
1009 static unsigned int cif_isp10_v4l2_poll(
1011 struct poll_table_struct *wait)
1013 struct cif_isp10_v4l2_fh *fh = to_fh(file);
1015 struct videobuf_queue *queue = to_videobuf_queue(file);
1016 unsigned long req_events = poll_requested_events(wait);
1018 cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
1019 cif_isp10_v4l2_buf_type_string(queue->type));
1021 if (v4l2_event_pending(&fh->fh))
1023 else if (req_events & POLLPRI)
1024 poll_wait(file, &fh->fh.wait, wait);
1026 if (!(req_events & (POLLIN | POLLOUT | POLLRDNORM)))
1029 ret |= videobuf_poll_stream(file, queue, wait);
1030 if (ret & POLLERR) {
1031 cif_isp10_pltfrm_pr_err(NULL,
1032 "videobuf_poll_stream failed with error 0x%x\n", ret);
1040 static void cif_isp10_v4l2_vm_open(struct vm_area_struct *vma)
1042 struct cif_isp10_metadata_s *metadata =
1043 (struct cif_isp10_metadata_s *)vma->vm_private_data;
1048 static void cif_isp10_v4l2_vm_close(struct vm_area_struct *vma)
1050 struct cif_isp10_metadata_s *metadata =
1051 (struct cif_isp10_metadata_s *)vma->vm_private_data;
1056 static const struct vm_operations_struct cif_isp10_vm_ops = {
1057 .open = cif_isp10_v4l2_vm_open,
1058 .close = cif_isp10_v4l2_vm_close,
1061 int cif_isp10_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1063 struct videobuf_queue *queue = to_videobuf_queue(file);
1064 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1065 enum cif_isp10_stream_id strm = to_stream_id(file);
1068 retval = cif_isp10_mmap(dev, strm, vma);
1072 vma->vm_ops = &cif_isp10_vm_ops;
1073 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
1074 cif_isp10_v4l2_vm_open(vma);
1080 const struct v4l2_file_operations cif_isp10_v4l2_fops = {
1081 .open = cif_isp10_v4l2_open,
1082 .unlocked_ioctl = video_ioctl2,
1083 #ifdef CONFIG_COMPAT
1084 .compat_ioctl32 = video_ioctl2,
1086 .release = cif_isp10_v4l2_release,
1087 .poll = cif_isp10_v4l2_poll,
1088 .mmap = cif_isp10_v4l2_mmap,
1091 /*TBD: clean up code below this line******************************************/
1093 static int v4l2_querycap(struct file *file,
1094 void *priv, struct v4l2_capability *cap)
1097 struct videobuf_queue *queue = to_videobuf_queue(file);
1098 struct video_device *vdev = video_devdata(file);
1099 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1100 u32 stream_ids = to_stream_id(file);
1102 strcpy(cap->driver, DRIVER_NAME);
1103 strlcpy(cap->card, vdev->name, sizeof(cap->card));
1104 snprintf(cap->bus_info, sizeof(cap->bus_info),
1105 "platform:" DRIVER_NAME "-%03i",
1108 if (stream_ids == CIF_ISP10_STREAM_SP)
1109 cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
1110 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1112 else if (stream_ids == CIF_ISP10_STREAM_MP)
1113 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1114 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1116 else if (stream_ids == CIF_ISP10_STREAM_DMA)
1117 cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE |
1119 cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
1120 cap->device_caps = V4L2_CAP_DEVICE_CAPS;
1124 static int cif_isp10_v4l2_subscribe_event(struct v4l2_fh *fh,
1125 const struct v4l2_event_subscription *sub)
1127 if (sub->type != V4L2_EVENT_FRAME_SYNC)
1129 return v4l2_event_subscribe(fh, sub, 16, NULL);
1132 static int cif_isp10_v4l2_unsubscribe_event(struct v4l2_fh *fh,
1133 const struct v4l2_event_subscription *sub)
1135 return v4l2_event_unsubscribe(fh, sub);
1138 static void cif_isp10_v4l2_event(
1139 struct cif_isp10_device *dev,
1140 __u32 frame_sequence)
1142 struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
1143 (struct cif_isp10_v4l2_device *)dev->nodes;
1144 struct v4l2_event ev;
1146 memset(&ev, 0, sizeof(ev));
1147 ev.type = V4L2_EVENT_FRAME_SYNC;
1148 ev.u.frame_sync.frame_sequence = frame_sequence;
1149 v4l2_event_queue(&cif_isp10_v4l2_dev->node[SP_DEV].vdev, &ev);
1152 static void cif_isp10_v4l2_requeue_bufs(
1153 struct cif_isp10_device *dev,
1154 enum cif_isp10_stream_id stream_id)
1156 struct videobuf_buffer *buf;
1157 struct videobuf_queue *q = NULL;
1158 struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
1159 (struct cif_isp10_v4l2_device *)dev->nodes;
1161 if (stream_id == CIF_ISP10_STREAM_SP)
1162 q = &cif_isp10_v4l2_dev->node[SP_DEV].buf_queue;
1163 else if (stream_id == CIF_ISP10_STREAM_MP)
1164 q = &cif_isp10_v4l2_dev->node[MP_DEV].buf_queue;
1165 else if (stream_id == CIF_ISP10_STREAM_DMA)
1166 q = &cif_isp10_v4l2_dev->node[DMA_DEV].buf_queue;
1170 dev = to_cif_isp10_device(q);
1172 list_for_each_entry(buf, &q->stream, stream) {
1173 if (!IS_ERR_VALUE(cif_isp10_qbuf(
1174 to_cif_isp10_device(q), stream_id, buf))) {
1175 spin_lock(&dev->vbreq_lock);
1176 if ((buf->state == VIDEOBUF_QUEUED) ||
1177 (buf->state == VIDEOBUF_ACTIVE) ||
1178 (buf->state == VIDEOBUF_DONE))
1179 buf->state = VIDEOBUF_QUEUED;
1181 cif_isp10_pltfrm_pr_err(NULL,
1182 "ERR: buf->state is: %d\n",
1184 spin_unlock(&dev->vbreq_lock);
1186 cif_isp10_pltfrm_pr_err(NULL,
1187 "failed for buffer %d\n", buf->i);
1192 static long v4l2_default_ioctl(struct file *file, void *fh,
1193 bool valid_prio, unsigned int cmd, void *arg)
1196 struct videobuf_queue *queue = to_videobuf_queue(file);
1197 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1200 cif_isp10_pltfrm_pr_err(dev->dev,
1201 "NULL Pointer Violation from IOCTL arg:0x%lx\n",
1202 (unsigned long)arg);
1206 if (cmd == RK_VIDIOC_SENSOR_MODE_DATA) {
1207 struct isp_supplemental_sensor_mode_data *p_mode_data =
1208 (struct isp_supplemental_sensor_mode_data *)arg;
1210 ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
1211 RK_VIDIOC_SENSOR_MODE_DATA, p_mode_data);
1214 cif_isp10_pltfrm_pr_err(dev->dev,
1215 "failed to get sensor mode data\n");
1219 p_mode_data->isp_input_width =
1220 dev->config.isp_config.input->defrect.width;
1221 p_mode_data->isp_input_height =
1222 dev->config.isp_config.input->defrect.height;
1223 p_mode_data->isp_input_horizontal_start =
1224 dev->config.isp_config.input->defrect.left;
1225 p_mode_data->isp_input_vertical_start =
1226 dev->config.isp_config.input->defrect.top;
1228 p_mode_data->isp_output_width =
1229 dev->config.isp_config.output.width;
1230 p_mode_data->isp_output_height =
1231 dev->config.isp_config.output.height;
1234 cif_isp10_pltfrm_pr_err(dev->dev,
1235 "failed to get isp input info\n");
1238 } else if (cmd == RK_VIDIOC_CAMERA_MODULEINFO) {
1239 struct camera_module_info_s *p_camera_module =
1240 (struct camera_module_info_s *)arg;
1242 ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
1243 RK_VIDIOC_CAMERA_MODULEINFO, p_camera_module);
1246 cif_isp10_pltfrm_pr_err(dev->dev,
1247 "failed to get camera module information\n");
1255 static int v4l2_s_parm(
1258 struct v4l2_streamparm *a)
1263 static int v4l2_enum_input(struct file *file, void *priv,
1264 struct v4l2_input *input)
1266 struct videobuf_queue *queue = to_videobuf_queue(file);
1267 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1268 const char *inp_name;
1270 if ((queue->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
1271 (queue->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)) {
1272 cif_isp10_pltfrm_pr_err(NULL,
1273 "wrong buffer queue %d\n", queue->type);
1277 inp_name = cif_isp10_g_input_name(dev, input->index);
1278 if (IS_ERR_OR_NULL(inp_name))
1281 input->type = V4L2_INPUT_TYPE_CAMERA;
1282 input->std = V4L2_STD_UNKNOWN;
1283 strncpy(input->name, inp_name, sizeof(input->name)-1);
1288 /* ================================================================= */
1290 static int mainpath_g_ctrl(
1293 struct v4l2_control *vc)
1305 static int mainpath_try_fmt_cap(struct v4l2_format *f)
1308 struct v4l2_pix_format *pix = &f->fmt.pix;
1310 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
1312 for (ifmt = 0; ifmt < get_cif_isp10_output_format_size(); ifmt++) {
1313 if (pix->pixelformat ==
1314 get_cif_isp10_output_format(ifmt)->fourcc)
1318 if (ifmt == get_cif_isp10_output_format_size())
1321 pix->bytesperline = pix->width *
1322 get_cif_isp10_output_format(ifmt)->depth / 8;
1324 switch (pix->pixelformat) {
1325 case V4L2_PIX_FMT_YUYV:
1326 case V4L2_PIX_FMT_UYVY:
1327 case V4L2_PIX_FMT_YUV422P:
1328 case V4L2_PIX_FMT_NV16:
1329 case V4L2_PIX_FMT_YUV420:
1330 case V4L2_PIX_FMT_YVU420:
1331 case V4L2_PIX_FMT_NV12:
1332 case V4L2_PIX_FMT_NV21:
1333 case V4L2_PIX_FMT_GREY:
1334 case V4L2_PIX_FMT_YUV444:
1335 case V4L2_PIX_FMT_NV24:
1336 case V4L2_PIX_FMT_JPEG:
1337 pix->colorspace = V4L2_COLORSPACE_JPEG;
1339 case V4L2_PIX_FMT_RGB32:
1340 case V4L2_PIX_FMT_BGR32:
1341 case V4L2_PIX_FMT_RGB565:
1342 case V4L2_PIX_FMT_RGB565X:
1343 case V4L2_PIX_FMT_SGRBG10:
1344 pix->colorspace = V4L2_COLORSPACE_SRGB;
1355 static int v4l2_enum_fmt_cap(struct file *file, void *fh,
1356 struct v4l2_fmtdesc *f)
1359 int xgold_num_format = 0;
1361 xgold_num_format = get_cif_isp10_output_format_desc_size();
1362 if ((f->index >= xgold_num_format) ||
1363 (get_cif_isp10_output_format_desc(f->index)->pixelformat == 0)) {
1364 cif_isp10_pltfrm_pr_err(NULL, "index %d\n", f->index);
1367 strlcpy(f->description,
1368 get_cif_isp10_output_format_desc(f->index)->description,
1369 sizeof(f->description));
1371 get_cif_isp10_output_format_desc(f->index)->pixelformat;
1372 f->flags = get_cif_isp10_output_format_desc(f->index)->flags;
1377 static int v4l2_g_ctrl(struct file *file, void *priv,
1378 struct v4l2_control *vc)
1380 struct videobuf_queue *queue = to_videobuf_queue(file);
1381 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1382 enum cif_isp10_cid id =
1383 cif_isp10_v4l2_cid2cif_isp10_cid(vc->id);
1385 return cif_isp10_img_src_g_ctrl(dev->img_src,
1389 static int v4l2_s_ext_ctrls(struct file *file, void *priv,
1390 struct v4l2_ext_controls *vc_ext)
1392 struct cif_isp10_img_src_ctrl *ctrls;
1393 struct cif_isp10_img_src_ext_ctrl *ctrl;
1394 struct videobuf_queue *queue = to_videobuf_queue(file);
1395 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1399 /* The only use-case is gain and exposure to sensor. Thus no check if
1400 * this shall go to img_src or not as of now.
1402 cif_isp10_pltfrm_pr_dbg(dev->dev, "count %d\n",
1405 if (vc_ext->count == 0)
1408 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
1412 ctrls = kmalloc(vc_ext->count *
1413 sizeof(struct cif_isp10_img_src_ctrl), GFP_KERNEL);
1419 ctrl->cnt = vc_ext->count;
1420 /*current kernel version don't define
1421 *this member for struct v4l2_ext_control.
1423 /*ctrl->class = vc_ext->ctrl_class;*/
1424 ctrl->ctrls = ctrls;
1426 for (i = 0; i < vc_ext->count; i++) {
1427 ctrls[i].id = vc_ext->controls[i].id;
1428 ctrls[i].val = vc_ext->controls[i].value;
1431 ret = cif_isp10_s_exp(dev, ctrl);
1435 int cif_isp10_v4l2_cropcap(
1438 struct v4l2_cropcap *a)
1441 struct videobuf_queue *queue = to_videobuf_queue(file);
1442 struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1443 u32 target_width, target_height;
1446 if ((dev->config.input_sel == CIF_ISP10_INP_DMA) ||
1447 (dev->config.input_sel == CIF_ISP10_INP_DMA_IE)) {
1448 /* calculate cropping for aspect ratio */
1449 ret = cif_isp10_calc_isp_cropping(dev,
1450 &dev->isp_dev.input_width, &dev->isp_dev.input_height,
1453 /* Get output size */
1454 ret = cif_isp10_get_target_frm_size(dev,
1455 &target_width, &target_height);
1457 cif_isp10_pltfrm_pr_err(dev->dev,
1458 "failed to get target frame size\n");
1462 cif_isp10_pltfrm_pr_dbg(dev->dev,
1463 "CIF_IN_W=%d, CIF_IN_H=%d, ISP_IN_W=%d, ISP_IN_H=%d, target_width=%d, target_height=%d\n",
1464 dev->config.isp_config.input->width,
1465 dev->config.isp_config.input->height,
1466 dev->isp_dev.input_width,
1467 dev->isp_dev.input_height,
1471 /* This is the input to Bayer after input formatter cropping */
1473 a->defrect.left = 0;
1474 a->defrect.width = dev->isp_dev.input_width;
1475 a->defrect.height = dev->isp_dev.input_height;
1476 /* This is the minimum cropping window for the IS module */
1477 a->bounds.width = 2;
1478 a->bounds.height = 2;
1479 a->bounds.top = (a->defrect.height - a->bounds.height) / 2;
1480 a->bounds.left = (a->defrect.width - a->bounds.width) / 2;
1482 a->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
1483 } else if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
1484 /* calculate cropping for aspect ratio */
1485 ret = cif_isp10_calc_isp_cropping(dev,
1486 &dev->isp_dev.input_width, &dev->isp_dev.input_height,
1489 /* Get output size */
1490 ret = cif_isp10_get_target_frm_size(dev,
1491 &target_width, &target_height);
1493 cif_isp10_pltfrm_pr_err(dev->dev,
1494 "failed to get target frame size\n");
1498 /* This is the input to Bayer after input formatter cropping */
1500 v_offs + dev->config.isp_config.input->defrect.top;
1502 h_offs + dev->config.isp_config.input->defrect.left;
1503 a->defrect.width = dev->isp_dev.input_width;
1504 a->defrect.height = dev->isp_dev.input_height;
1508 a->bounds.width = dev->config.isp_config.input->width;
1509 a->bounds.height = dev->config.isp_config.input->height;
1510 a->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
1512 cif_isp10_pltfrm_pr_err(dev->dev,
1516 cif_isp10_pltfrm_pr_dbg(dev->dev,
1517 "v4l2_cropcap: defrect(%d,%d,%d,%d) bounds(%d,%d,%d,%d)\n",
1530 int cif_isp10_v4l2_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
1536 * This is a write only function, so the upper layer
1537 * will ignore the changes to 'a'. So don't use 'a' to pass
1538 * the actual cropping parameters, the upper layer
1539 * should call g_crop to get the actual window.
1541 int cif_isp10_v4l2_s_crop(
1544 const struct v4l2_crop *a)
1549 const struct v4l2_ioctl_ops cif_isp10_v4l2_sp_ioctlops = {
1550 .vidioc_reqbufs = cif_isp10_v4l2_reqbufs,
1551 .vidioc_querybuf = cif_isp10_v4l2_querybuf,
1552 .vidioc_qbuf = cif_isp10_v4l2_qbuf,
1553 .vidioc_dqbuf = cif_isp10_v4l2_dqbuf,
1554 .vidioc_streamon = cif_isp10_v4l2_streamon,
1555 .vidioc_streamoff = cif_isp10_v4l2_streamoff,
1556 .vidioc_s_input = cif_isp10_v4l2_s_input,
1557 .vidioc_enum_input = v4l2_enum_input,
1558 .vidioc_g_ctrl = v4l2_g_ctrl,
1559 .vidioc_s_ctrl = cif_isp10_v4l2_s_ctrl,
1560 .vidioc_s_fmt_vid_overlay = cif_isp10_v4l2_s_fmt,
1561 .vidioc_g_fmt_vid_overlay = cif_isp10_v4l2_g_fmt,
1562 .vidioc_s_ext_ctrls = v4l2_s_ext_ctrls,
1563 .vidioc_querycap = v4l2_querycap,
1564 .vidioc_cropcap = cif_isp10_v4l2_cropcap,
1565 .vidioc_s_crop = cif_isp10_v4l2_s_crop,
1566 .vidioc_g_crop = cif_isp10_v4l2_g_crop,
1567 .vidioc_subscribe_event = cif_isp10_v4l2_subscribe_event,
1568 .vidioc_unsubscribe_event = cif_isp10_v4l2_unsubscribe_event,
1569 .vidioc_default = v4l2_default_ioctl,
1572 const struct v4l2_ioctl_ops cif_isp10_v4l2_mp_ioctlops = {
1573 .vidioc_reqbufs = cif_isp10_v4l2_reqbufs,
1574 .vidioc_querybuf = cif_isp10_v4l2_querybuf,
1575 .vidioc_qbuf = cif_isp10_v4l2_qbuf,
1576 .vidioc_dqbuf = cif_isp10_v4l2_dqbuf,
1577 .vidioc_streamon = cif_isp10_v4l2_streamon,
1578 .vidioc_streamoff = cif_isp10_v4l2_streamoff,
1579 .vidioc_s_input = cif_isp10_v4l2_s_input,
1580 .vidioc_enum_input = v4l2_enum_input,
1581 .vidioc_g_ctrl = mainpath_g_ctrl,
1582 .vidioc_s_ctrl = cif_isp10_v4l2_s_ctrl,
1583 .vidioc_s_fmt_vid_cap = cif_isp10_v4l2_s_fmt,
1584 .vidioc_g_fmt_vid_cap = cif_isp10_v4l2_g_fmt,
1585 .vidioc_enum_fmt_vid_cap = v4l2_enum_fmt_cap,
1586 .vidioc_enum_framesizes = cif_isp10_v4l2_enum_framesizes,
1587 .vidioc_s_parm = v4l2_s_parm,
1588 .vidioc_querycap = v4l2_querycap,
1589 .vidioc_cropcap = cif_isp10_v4l2_cropcap,
1590 .vidioc_s_crop = cif_isp10_v4l2_s_crop,
1591 .vidioc_g_crop = cif_isp10_v4l2_g_crop,
1592 .vidioc_default = v4l2_default_ioctl,
1595 const struct v4l2_ioctl_ops cif_isp10_v4l2_dma_ioctlops = {
1596 .vidioc_reqbufs = cif_isp10_v4l2_reqbufs,
1597 .vidioc_querybuf = cif_isp10_v4l2_querybuf,
1598 .vidioc_qbuf = cif_isp10_v4l2_qbuf,
1599 .vidioc_dqbuf = cif_isp10_v4l2_dqbuf,
1600 .vidioc_streamon = cif_isp10_v4l2_streamon,
1601 .vidioc_streamoff = cif_isp10_v4l2_streamoff,
1602 .vidioc_s_fmt_vid_out = cif_isp10_v4l2_s_fmt,
1603 .vidioc_g_fmt_vid_out = cif_isp10_v4l2_g_fmt,
1604 .vidioc_cropcap = cif_isp10_v4l2_cropcap,
1605 .vidioc_s_crop = cif_isp10_v4l2_s_crop,
1606 .vidioc_g_crop = cif_isp10_v4l2_g_crop,
1609 static struct pltfrm_soc_cfg rk3288_cfg = {
1610 .name = CIF_ISP10_SOC_RK3288,
1611 .soc_cfg = pltfrm_rk3288_cfg,
1614 static struct pltfrm_soc_cfg rk3399_cfg = {
1615 .name = CIF_ISP10_SOC_RK3399,
1616 .soc_cfg = pltfrm_rk3399_cfg,
1619 static const struct of_device_id cif_isp10_v4l2_of_match[] = {
1620 {.compatible = "rockchip,rk3288-cif-isp",
1621 .data = (void *)&rk3288_cfg},
1622 {.compatible = "rockchip,rk3399-cif-isp",
1623 .data = (void *)&rk3399_cfg},
1627 static unsigned int cif_isp10_v4l2_dev_cnt;
1628 static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
1630 const struct of_device_id *match;
1631 struct device_node *node = pdev->dev.of_node;
1632 struct cif_isp10_device *dev = NULL;
1633 struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev;
1636 cif_isp10_pltfrm_pr_info(NULL, "probing...\n");
1638 cif_isp10_v4l2_dev = devm_kzalloc(
1640 sizeof(struct cif_isp10_v4l2_device),
1642 if (IS_ERR_OR_NULL(cif_isp10_v4l2_dev)) {
1647 match = of_match_node(cif_isp10_v4l2_of_match, node);
1648 dev = cif_isp10_create(&pdev->dev,
1649 cif_isp10_v4l2_event,
1650 cif_isp10_v4l2_requeue_bufs,
1651 (struct pltfrm_soc_cfg *)match->data);
1652 if (IS_ERR_OR_NULL(dev)) {
1657 dev->dev_id = cif_isp10_v4l2_dev_cnt;
1658 dev->isp_dev.dev_id = &dev->dev_id;
1659 dev->nodes = (void *)cif_isp10_v4l2_dev;
1660 spin_lock_init(&dev->vbq_lock);
1661 spin_lock_init(&dev->vbreq_lock);
1662 spin_lock_init(&iowrite32_verify_lock);
1664 ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
1665 if (IS_ERR_VALUE(ret)) {
1666 cif_isp10_pltfrm_pr_err(NULL,
1667 "V4L2 device registration failed\n");
1671 ret = cif_isp10_v4l2_register_video_device(
1673 &cif_isp10_v4l2_dev->node[SP_DEV].vdev,
1675 V4L2_CAP_VIDEO_OVERLAY,
1676 CIF_ISP10_V4L2_SP_DEV_MAJOR,
1677 &cif_isp10_v4l2_fops,
1678 &cif_isp10_v4l2_sp_ioctlops);
1682 ret = register_cifisp_device(&dev->isp_dev,
1683 &cif_isp10_v4l2_dev->node[ISP_DEV].vdev,
1685 dev->config.base_addr);
1689 ret = cif_isp10_v4l2_register_video_device(
1691 &cif_isp10_v4l2_dev->node[MP_DEV].vdev,
1693 V4L2_CAP_VIDEO_CAPTURE,
1694 CIF_ISP10_V4L2_MP_DEV_MAJOR,
1695 &cif_isp10_v4l2_fops,
1696 &cif_isp10_v4l2_mp_ioctlops);
1700 ret = cif_isp10_v4l2_register_video_device(
1702 &cif_isp10_v4l2_dev->node[DMA_DEV].vdev,
1704 V4L2_CAP_VIDEO_OUTPUT,
1705 CIF_ISP10_V4L2_DMA_DEV_MAJOR,
1706 &cif_isp10_v4l2_fops,
1707 &cif_isp10_v4l2_dma_ioctlops);
1711 pm_runtime_enable(&pdev->dev);
1713 cif_isp10_v4l2_dev_cnt++;
1716 cif_isp10_destroy(dev);
1720 /* ======================================================================== */
1722 static int cif_isp10_v4l2_drv_remove(struct platform_device *pdev)
1724 struct cif_isp10_device *cif_isp10_dev =
1725 (struct cif_isp10_device *)platform_get_drvdata(pdev);
1726 struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
1727 (struct cif_isp10_v4l2_device *)cif_isp10_dev->nodes;
1729 if (IS_ERR_VALUE(cif_isp10_release(cif_isp10_dev,
1730 CIF_ISP10_ALL_STREAMS)))
1731 cif_isp10_pltfrm_pr_warn(cif_isp10_dev->dev,
1732 "CIF power off failed\n");
1734 video_unregister_device(&cif_isp10_v4l2_dev->node[SP_DEV].vdev);
1735 video_unregister_device(&cif_isp10_v4l2_dev->node[MP_DEV].vdev);
1736 video_unregister_device(&cif_isp10_v4l2_dev->node[DMA_DEV].vdev);
1737 unregister_cifisp_device(&cif_isp10_v4l2_dev->node[ISP_DEV].vdev);
1738 v4l2_device_unregister(&cif_isp10_dev->v4l2_dev);
1739 cif_isp10_pltfrm_dev_release(&pdev->dev);
1740 cif_isp10_destroy(cif_isp10_dev);
1742 cif_isp10_v4l2_dev_cnt--;
1746 static int cif_isp10_v4l2_drv_suspend(struct platform_device *pdev,
1750 struct cif_isp10_device *cif_isp10_dev =
1751 (struct cif_isp10_device *)platform_get_drvdata(pdev);
1753 cif_isp10_pltfrm_pr_dbg(cif_isp10_dev->dev, "\n");
1755 ret = cif_isp10_suspend(cif_isp10_dev);
1756 if (IS_ERR_VALUE(ret))
1759 cif_isp10_pltfrm_pinctrl_set_state(&pdev->dev,
1760 CIF_ISP10_PINCTRL_STATE_SLEEP);
1764 cif_isp10_pltfrm_pr_err(cif_isp10_dev->dev,
1765 "failed with error %d\n", ret);
1769 static int cif_isp10_v4l2_drv_resume(struct platform_device *pdev)
1772 struct cif_isp10_device *cif_isp10_dev =
1773 (struct cif_isp10_device *)platform_get_drvdata(pdev);
1775 cif_isp10_pltfrm_pr_dbg(cif_isp10_dev->dev, "\n");
1777 if (!cif_isp10_dev->img_src) {
1778 cif_isp10_pltfrm_pr_err(
1780 "cif_isp10_dev img_src is null!\n");
1784 ret = cif_isp10_resume(cif_isp10_dev);
1785 if (IS_ERR_VALUE(ret))
1788 cif_isp10_pltfrm_pinctrl_set_state(&pdev->dev,
1789 CIF_ISP10_PINCTRL_STATE_DEFAULT);
1793 cif_isp10_pltfrm_pr_err(cif_isp10_dev->dev,
1794 "failed with error %d\n", ret);
1798 static int cif_isp10_runtime_suspend(struct device *dev)
1800 cif_isp10_pltfrm_pr_dbg(dev, "\n");
1801 return cif_isp10_pltfrm_pm_set_state(dev, CIF_ISP10_PM_STATE_SUSPENDED);
1804 static int cif_isp10_runtime_resume(struct device *dev)
1806 cif_isp10_pltfrm_pr_dbg(dev, "\n");
1807 return cif_isp10_pltfrm_pm_set_state(dev, CIF_ISP10_PM_STATE_SW_STNDBY);
1810 static const struct dev_pm_ops cif_isp10_dev_pm_ops = {
1811 SET_RUNTIME_PM_OPS(cif_isp10_runtime_suspend,
1812 cif_isp10_runtime_resume, NULL)
1815 static struct platform_driver cif_isp10_v4l2_plat_drv = {
1817 .name = DRIVER_NAME,
1818 .of_match_table = of_match_ptr(cif_isp10_v4l2_of_match),
1819 .pm = &cif_isp10_dev_pm_ops,
1821 .probe = cif_isp10_v4l2_drv_probe,
1822 .remove = cif_isp10_v4l2_drv_remove,
1823 .suspend = cif_isp10_v4l2_drv_suspend,
1824 .resume = cif_isp10_v4l2_drv_resume,
1827 /* ======================================================================== */
1828 static int cif_isp10_v4l2_init(void)
1832 ret = platform_driver_register(&cif_isp10_v4l2_plat_drv);
1834 cif_isp10_pltfrm_pr_err(NULL,
1835 "cannot register platform driver, failed with %d\n",
1843 /* ======================================================================== */
1844 static void __exit cif_isp10_v4l2_exit(void)
1846 platform_driver_unregister(&cif_isp10_v4l2_plat_drv);
1849 device_initcall_sync(cif_isp10_v4l2_init);
1850 module_exit(cif_isp10_v4l2_exit);
1852 MODULE_DESCRIPTION("V4L2 interface for CIF ISP10 driver");
1853 MODULE_AUTHOR("George");
1854 MODULE_LICENSE("GPL");