isp10: rockchip: v0.1.6
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / rk-isp10 / cif_isp10_v4l2.c
1 /*
2  *************************************************************************
3  * Rockchip driver for CIF ISP 1.0
4  * (Based on Intel driver for sofiaxxx)
5  *
6  * Copyright (C) 2015 Intel Mobile Communications GmbH
7  * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
8  *
9  *
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  *************************************************************************
15  */
16
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>
26 #include <linux/of.h>
27 #include <media/v4l2-controls_rockchip.h>
28 #include <linux/pm_runtime.h>
29 #include <linux/pagemap.h>
30 #include <linux/slab.h>
31
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
36
37 #define SP_DEV 0
38 #define MP_DEV 1
39 #define DMA_DEV 2
40 #define ISP_DEV 3
41
42 /* One structure per open file handle */
43 struct cif_isp10_v4l2_fh {
44         enum cif_isp10_stream_id stream_id;
45         struct v4l2_fh fh;
46 };
47
48 /* One structure per video node */
49 struct cif_isp10_v4l2_node {
50         struct videobuf_queue buf_queue;
51         struct video_device vdev;
52         int users;
53         struct cif_isp10_v4l2_fh *owner;
54 };
55
56 /* One structure per device */
57 struct cif_isp10_v4l2_device {
58         struct cif_isp10_v4l2_node node[4];
59 };
60
61 /* spinlock define */
62 spinlock_t iowrite32_verify_lock;
63
64 static struct cif_isp10_v4l2_fh *to_fh(struct file *file)
65 {
66         if (!file || !file->private_data)
67                 return NULL;
68
69         return container_of(file->private_data, struct cif_isp10_v4l2_fh, fh);
70 }
71
72 static struct cif_isp10_v4l2_node *to_node(struct cif_isp10_v4l2_fh *fh)
73 {
74         struct video_device *vdev = fh ? fh->fh.vdev : NULL;
75
76         if (!fh || !vdev)
77                 return NULL;
78
79         return container_of(vdev, struct cif_isp10_v4l2_node, vdev);
80 }
81
82 static struct videobuf_queue *to_videobuf_queue(
83         struct file *file)
84 {
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;
89
90         if (unlikely(!vdev)) {
91                 cif_isp10_pltfrm_pr_err(NULL,
92                         "vdev is NULL\n");
93                 WARN_ON(1);
94         }
95         q = &node->buf_queue;
96         if (unlikely(!q)) {
97                 cif_isp10_pltfrm_pr_err(NULL,
98                         "buffer queue is NULL\n");
99                 WARN_ON(1);
100         }
101
102         return q;
103 }
104
105 static enum cif_isp10_stream_id to_stream_id(
106         struct file *file)
107 {
108         struct cif_isp10_v4l2_fh *fh;
109
110         if (unlikely(!file)) {
111                 cif_isp10_pltfrm_pr_err(NULL,
112                         "NULL file handle\n");
113                 WARN_ON(1);
114         }
115         fh = to_fh(file);
116         if (unlikely(!fh)) {
117                 cif_isp10_pltfrm_pr_err(NULL,
118                         "fh is NULL\n");
119                 WARN_ON(1);
120         }
121
122         return fh->stream_id;
123 }
124
125 static struct cif_isp10_device *to_cif_isp10_device(
126         struct videobuf_queue *queue)
127 {
128         return queue->priv_data;
129 }
130
131 static enum cif_isp10_stream_id to_cif_isp10_stream_id(
132         struct videobuf_queue *queue)
133 {
134         struct cif_isp10_v4l2_node *node =
135                 container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
136         struct video_device *vdev =
137                 &node->vdev;
138
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;
145
146         cif_isp10_pltfrm_pr_err(NULL,
147                 "unsupported/unknown device name %s\n", vdev->name);
148         return -EINVAL;
149 }
150
151 static const char *cif_isp10_v4l2_buf_type_string(
152         enum v4l2_buf_type buf_type)
153 {
154         switch (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";
161         default:
162                 break;
163         }
164         return "UNKNOWN/UNSUPPORTED";
165 }
166
167 const char *cif_isp10_v4l2_pix_fmt_string(
168         int pix_fmt)
169 {
170         switch (pix_fmt) {
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:
182                 return "V4L2-BGR24";
183         case V4L2_PIX_FMT_RGB24:
184                 return "V4L2-RGB24";
185         case V4L2_PIX_FMT_BGR32:
186                 return "V4L2-BGR32";
187         case V4L2_PIX_FMT_RGB32:
188                 return "V4L2-RGB32";
189         case V4L2_PIX_FMT_GREY:
190                 return "V4L2-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:
196                 return "V4L2-YUYV";
197         case V4L2_PIX_FMT_UYVY:
198                 return "V4L2-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:
204                 return "V4L2-Y41P";
205         case V4L2_PIX_FMT_NV12:
206                 return "V4L2-NV12";
207         case V4L2_PIX_FMT_NV21:
208                 return "V4L2-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:
214                 return "V4L2-YYUV";
215         case V4L2_PIX_FMT_HI240:
216                 return "V4L2-HI240";
217         case V4L2_PIX_FMT_WNVA:
218                 return "V4L2-WNVA";
219         case V4L2_PIX_FMT_NV16:
220                 return "V4L2-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:
226                 return "V4L2-JPEG";
227         case V4L2_PIX_FMT_SGRBG10:
228                 return "RAW-BAYER-10Bits";
229         case V4L2_PIX_FMT_SGRBG8:
230                 return "RAW-BAYER-8Bits";
231         }
232         return "UNKNOWN/UNSUPPORTED";
233 }
234
235 static int cif_isp10_v4l2_cid2cif_isp10_cid(u32 v4l2_cid)
236 {
237         switch (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;
252         case V4L2_CID_GAIN:
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;
264         case V4L2_CID_HFLIP:
265                 return CIF_ISP10_CID_HFLIP;
266         case V4L2_CID_VFLIP:
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;
272         default:
273                 cif_isp10_pltfrm_pr_err(NULL,
274                         "unknown/unsupported V4L2 CID 0x%x\n",
275                         v4l2_cid);
276                 break;
277         }
278         return -EINVAL;
279 }
280
281 static enum cif_isp10_image_effect cif_isp10_v4l2_colorfx2cif_isp10_ie(
282         u32 v4l2_colorfx)
283 {
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;
297         default:
298                 cif_isp10_pltfrm_pr_err(NULL,
299                         "unknown/unsupported V4L2 COLORFX %d\n",
300                         v4l2_colorfx);
301                 break;
302         }
303         return -EINVAL;
304 }
305
306 static enum cif_isp10_pix_fmt cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
307         u32 v4l2_pix_fmt, struct videobuf_queue *queue)
308 {
309 /*struct cif_isp10_v4l2_node *node =
310  *      container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
311  *      struct video_device *vdev =
312  *      &node->vdev;
313  */
314
315         switch (v4l2_pix_fmt) {
316         case V4L2_PIX_FMT_GREY:
317                 return CIF_YUV400;
318         case V4L2_PIX_FMT_YUV420:
319                 return CIF_YUV420P;
320         case V4L2_PIX_FMT_YVU420:
321                 return CIF_YVU420P;
322         case V4L2_PIX_FMT_NV12:
323                 return CIF_YUV420SP;
324         case V4L2_PIX_FMT_NV21:
325                 return CIF_YVU420SP;
326         case V4L2_PIX_FMT_YUYV:
327                 return CIF_YUV422I;
328         case V4L2_PIX_FMT_UYVY:
329                 return CIF_UYV422I;
330         case V4L2_PIX_FMT_YUV422P:
331                 return CIF_YUV422P;
332         case V4L2_PIX_FMT_NV16:
333                 return CIF_YUV422SP;
334         case V4L2_PIX_FMT_YUV444:
335                 return CIF_YUV444P;
336         case V4L2_PIX_FMT_NV24:
337                 return CIF_YUV444SP;
338         case V4L2_PIX_FMT_RGB565:
339                 return CIF_RGB565;
340         case V4L2_PIX_FMT_RGB24:
341                 return CIF_RGB888;
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:
367                 return CIF_JPEG;
368         default:
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;
376         }
377 }
378
379 static int cif_isp10_v4l2_register_video_device(
380         struct cif_isp10_device *dev,
381         struct video_device *vdev,
382         const char *name,
383         int qtype,
384         int major,
385         const struct v4l2_file_operations *fops,
386         const struct v4l2_ioctl_ops *ioctl_ops)
387 {
388         int ret;
389
390         vdev->release = video_device_release;
391         strlcpy(vdev->name, name, sizeof(vdev->name));
392         vdev->vfl_type = qtype;
393         vdev->fops = fops;
394         video_set_drvdata(vdev, dev);
395         vdev->minor = -1;
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;
400         else
401                 vdev->vfl_dir = VFL_DIR_RX;
402
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);
407                 goto err;
408         }
409
410         cif_isp10_pltfrm_pr_info(NULL,
411                 "video device video%d.%d (%s) successfully registered\n",
412                 major, vdev->minor, name);
413
414         return 0;
415 err:
416         video_device_release(vdev);
417         cif_isp10_pltfrm_pr_err(NULL,
418                 "failed with err %d\n", ret);
419         return ret;
420 }
421
422 static int cif_isp10_v4l2_streamon(
423         struct file *file,
424         void *priv,
425         enum v4l2_buf_type buf_type)
426 {
427         int ret;
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);
436
437         if (node->owner != fh)
438                 return -EBUSY;
439
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));
445
446         ret = videobuf_streamon(queue);
447         if (IS_ERR_VALUE(ret)) {
448                 cif_isp10_pltfrm_pr_err(dev->dev,
449                         "videobuf_streamon failed\n");
450                 goto err;
451         }
452
453         ret = cif_isp10_streamon(dev, stream_ids);
454         if (IS_ERR_VALUE(ret)) {
455                 videobuf_queue_cancel(queue);
456                 goto err;
457         }
458
459         return 0;
460 err:
461         (void)videobuf_mmap_free(queue);
462         cif_isp10_pltfrm_pr_err(dev->dev, "failed with error %d\n", ret);
463         return ret;
464 }
465
466 static int cif_isp10_v4l2_do_streamoff(
467         struct file *file)
468 {
469         int ret = 0;
470         int err;
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);
476
477         cif_isp10_pltfrm_pr_dbg(dev->dev, "%s\n",
478                 cif_isp10_v4l2_buf_type_string(queue->type));
479
480         if (node->owner != fh)
481                 return -EBUSY;
482
483         err = cif_isp10_streamoff(dev, stream_ids);
484         if (IS_ERR_VALUE(err))
485                 ret = -EFAULT;
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);
490                 ret = -EFAULT;
491         }
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);
496                 ret = -EFAULT;
497         }
498
499         if (IS_ERR_VALUE(ret))
500                 cif_isp10_pltfrm_pr_err(dev->dev,
501                         "failed with error %d\n", ret);
502
503         return ret;
504 }
505
506 static int cif_isp10_v4l2_streamoff(
507         struct file *file,
508         void *priv,
509         enum v4l2_buf_type buf_type)
510 {
511         int ret = cif_isp10_v4l2_do_streamoff(file);
512
513         if (IS_ERR_VALUE(ret))
514                 cif_isp10_pltfrm_pr_err(NULL,
515                         "failed with error %d\n", ret);
516
517         return ret;
518 }
519
520 static int cif_isp10_v4l2_qbuf(
521         struct file *file,
522         void *priv,
523         struct v4l2_buffer *buf)
524 {
525         int ret;
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);
529
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);
535
536         if (node->owner != fh)
537                 return -EBUSY;
538
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);
543         return ret;
544 }
545
546 static int cif_isp10_v4l2_dqbuf(
547         struct file *file,
548         void *priv,
549         struct v4l2_buffer *buf)
550 {
551         int ret;
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);
555
556         cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
557                 cif_isp10_v4l2_buf_type_string(queue->type));
558
559         if (node->owner != fh)
560                 return -EBUSY;
561
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);
566         else
567                 cif_isp10_pltfrm_pr_dbg(NULL,
568                         "dequeued buffer %d, size %d\n",
569                         buf->index, buf->length);
570         return ret;
571 }
572
573 static void cif_isp10_v4l2_buf_release(
574         struct videobuf_queue *queue,
575         struct videobuf_buffer *buf)
576 {
577         cif_isp10_pltfrm_pr_dbg(NULL,
578                 "%s\n",
579                 cif_isp10_v4l2_buf_type_string(queue->type));
580
581         if (in_interrupt())
582                 WARN_ON(1);
583
584         videobuf_dma_contig_free(queue, buf);
585
586         buf->state = VIDEOBUF_NEEDS_INIT;
587 }
588
589 static void cif_isp10_v4l2_buf_queue(
590         struct videobuf_queue *queue,
591         struct videobuf_buffer *buf)
592 {
593         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
594         enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
595
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);
600
601         if (!IS_ERR_VALUE(cif_isp10_qbuf(dev, strm, buf)))
602                 buf->state = VIDEOBUF_QUEUED;
603         else
604                 cif_isp10_pltfrm_pr_err(NULL, "failed\n");
605 }
606
607 static int cif_isp10_v4l2_buf_setup(
608         struct videobuf_queue *queue,
609         unsigned int *cnt,
610         unsigned int *size)
611 {
612         int ret;
613         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
614         enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
615
616         cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
617                 cif_isp10_v4l2_buf_type_string(queue->type),
618                 *cnt, *size);
619
620         ret = cif_isp10_calc_min_out_buff_size(
621                 dev, strm, size);
622         if (IS_ERR_VALUE(ret)) {
623                 cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
624                 return ret;
625         }
626
627         cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
628                 cif_isp10_v4l2_buf_type_string(queue->type),
629                 *cnt, *size);
630
631         return 0;
632 }
633
634 static int cif_isp10_v4l2_buf_prepare(
635         struct videobuf_queue *queue,
636         struct videobuf_buffer *buf,
637         enum v4l2_field field)
638 {
639         int ret;
640         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
641         enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
642         u32 size;
643
644         cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
645                 cif_isp10_v4l2_buf_type_string(queue->type));
646
647         ret = cif_isp10_calc_min_out_buff_size(
648                 dev, strm, &size);
649         if (IS_ERR_VALUE(ret))
650                 goto err;
651         buf->size = size;
652         if (strm == CIF_ISP10_STREAM_SP) {
653                 buf->width =
654                         dev->config.mi_config.sp.output.width;
655                 buf->height =
656                         dev->config.mi_config.sp.output.height;
657         } else if (strm == CIF_ISP10_STREAM_MP) {
658                 buf->width =
659                         dev->config.mi_config.mp.output.width;
660                 buf->height =
661                         dev->config.mi_config.mp.output.height;
662         } else if (strm == CIF_ISP10_STREAM_DMA) {
663                 buf->width =
664                         dev->config.mi_config.dma.output.width;
665                 buf->height =
666                         dev->config.mi_config.dma.output.height;
667         } else {
668                 cif_isp10_pltfrm_pr_err(NULL,
669                         "wrong buffer queue %d\n", queue->type);
670                 ret = -EINVAL;
671                 goto err;
672         }
673         buf->field = field;
674
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);
678
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);
684                         goto err;
685                 }
686         }
687         buf->state = VIDEOBUF_PREPARED;
688
689         return 0;
690 err:
691         cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
692         cif_isp10_v4l2_buf_release(queue, buf);
693         return ret;
694 }
695
696 static int cif_isp10_v4l2_reqbufs(
697         struct file *file,
698         void *priv,
699         struct v4l2_requestbuffers *req)
700 {
701         struct cif_isp10_v4l2_fh *fh = to_fh(file);
702         struct cif_isp10_v4l2_node *node = to_node(fh);
703         int ret;
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);
707
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),
712                 req->count);
713
714         if (node->owner && node->owner != fh)
715                 return -EBUSY;
716         node->owner = fh;
717
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);
722         }
723         cif_isp10_reqbufs(dev, strm, req);
724         return ret;
725 }
726
727 static int cif_isp10_v4l2_querybuf(
728         struct file *file,
729         void *priv,
730         struct v4l2_buffer *buf)
731 {
732         int ret;
733         struct videobuf_queue *queue = to_videobuf_queue(file);
734
735         cif_isp10_pltfrm_pr_dbg(NULL,
736                 "%s, index %d\n",
737                 cif_isp10_v4l2_buf_type_string(queue->type), buf->index);
738
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);
743
744         return ret;
745 }
746
747 static int cif_isp10_v4l2_s_ctrl(
748         struct file *file,
749         void *priv,
750         struct v4l2_control *vc)
751 {
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);
756         int val = vc->value;
757
758         if (IS_ERR_VALUE(id))
759                 return id;
760
761         switch (vc->id) {
762         case V4L2_CID_COLORFX:
763                 val = cif_isp10_v4l2_colorfx2cif_isp10_ie(val);
764                 break;
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;
772                 else
773                         val = -EINVAL;
774                 break;
775         default:
776                 break;
777         }
778
779         return cif_isp10_s_ctrl(dev, id, val);
780 }
781
782 static int cif_isp10_v4l2_s_fmt(
783         struct file *file,
784         void *priv,
785         struct v4l2_format *f)
786 {
787         int ret;
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;
793
794         cif_isp10_pltfrm_pr_dbg(NULL,
795                 "%s\n",
796                 cif_isp10_v4l2_buf_type_string(queue->type));
797
798         if (node->owner && node->owner != fh)
799                 return -EBUSY;
800
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,
809                 to_stream_id(file),
810                 &strm_fmt,
811                 f->fmt.pix.bytesperline);
812         if (IS_ERR_VALUE(ret))
813                 goto err;
814
815         return 0;
816 err:
817         cif_isp10_pltfrm_pr_err(NULL,
818                 "failed with error %d\n", ret);
819         return ret;
820 }
821
822 /* existence of this function is checked by V4L2 */
823 static int cif_isp10_v4l2_g_fmt(
824         struct file *file,
825         void *priv,
826         struct v4l2_format *f)
827 {
828         return -EFAULT;
829 }
830
831 static int cif_isp10_v4l2_s_input(
832         struct file *file,
833         void *priv,
834         unsigned int i)
835 {
836         int ret;
837         struct videobuf_queue *queue = to_videobuf_queue(file);
838         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
839
840         cif_isp10_pltfrm_pr_dbg(dev->dev, "setting input to %d\n", i);
841
842         ret = cif_isp10_s_input(dev, i);
843         if (IS_ERR_VALUE(ret))
844                 goto err;
845
846         return 0;
847 err:
848         cif_isp10_pltfrm_pr_err(NULL,
849                 "failed with error %d\n", ret);
850         return ret;
851 }
852
853 static int cif_isp10_v4l2_enum_framesizes(
854         struct file *file,
855         void *priv,
856         struct v4l2_frmsizeenum *fsize)
857 {
858         /* THIS FUNCTION IS UNDER CONSTRUCTION */
859         int ret;
860         struct videobuf_queue *queue = to_videobuf_queue(file);
861         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
862
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");
866                 ret = -ENODEV;
867                 goto err;
868         }
869
870         return -EINVAL;
871 err:
872         cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
873         return ret;
874 }
875
876 /* fops **********************************************************************/
877
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,
883 };
884
885 static int cif_isp10_v4l2_open(
886         struct file *file)
887 {
888         int ret;
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;
897
898         cif_isp10_pltfrm_pr_dbg(NULL,
899                 "video device video%d.%d (%s)\n",
900                 vdev->num, vdev->minor, vdev->name);
901
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;
912         } else {
913                 cif_isp10_pltfrm_pr_err(NULL,
914                         "invalid video device video%d.%d (%s)\n",
915                         vdev->num, vdev->minor, vdev->name);
916                 ret = -EINVAL;
917                 goto err;
918         }
919
920         fh = kzalloc(sizeof(*fh), GFP_KERNEL);
921         if (!fh) {
922                 cif_isp10_pltfrm_pr_err(NULL,
923                         "memory allocation failed\n");
924                 ret = -ENOMEM;
925                 goto err;
926         }
927         fh->stream_id = stream_id;
928
929         file->private_data = &fh->fh;
930         v4l2_fh_init(&fh->fh, vdev);
931         v4l2_fh_add(&fh->fh);
932
933         node = to_node(fh);
934         if (++node->users > 1)
935                 return 0;
936
937         /* First open of the device, so initialize everything */
938         node->owner = NULL;
939
940         videobuf_queue_dma_contig_init(
941                 to_videobuf_queue(file),
942                 &cif_isp10_qops,
943                 dev->dev,
944                 &dev->vbq_lock,
945                 buf_type,
946                 V4L2_FIELD_NONE,
947                 sizeof(struct videobuf_buffer),
948                 dev, NULL);
949
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);
954                 kfree(fh);
955                 node->users--;
956                 goto err;
957         }
958
959         return 0;
960 err:
961         cif_isp10_pltfrm_pr_err(NULL,
962                 "failed with error %d\n", ret);
963         return ret;
964 }
965
966 static int cif_isp10_v4l2_release(struct file *file)
967 {
968         int ret = 0;
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);
974
975         cif_isp10_pltfrm_pr_dbg(dev->dev, "%s\n",
976                 cif_isp10_v4l2_buf_type_string(queue->type));
977
978         if (node->users) {
979                 --node->users;
980         } else {
981                 cif_isp10_pltfrm_pr_warn(dev->dev,
982                         "number of users for this device is already 0\n");
983                 return 0;
984         }
985
986         if (!node->users) {
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");
991
992                 /* Last close, so uninitialize hardware */
993                 ret = cif_isp10_release(dev, stream_id);
994         }
995
996         if (node->owner == fh)
997                 node->owner = NULL;
998
999         v4l2_fh_del(&fh->fh);
1000         v4l2_fh_exit(&fh->fh);
1001         kfree(fh);
1002
1003         if (IS_ERR_VALUE(ret))
1004                 cif_isp10_pltfrm_pr_err(dev->dev,
1005                         "failed with error %d\n", ret);
1006         return ret;
1007 }
1008
1009 static unsigned int cif_isp10_v4l2_poll(
1010         struct file *file,
1011         struct poll_table_struct *wait)
1012 {
1013         struct cif_isp10_v4l2_fh *fh = to_fh(file);
1014         int ret = 0;
1015         struct videobuf_queue *queue = to_videobuf_queue(file);
1016         unsigned long req_events = poll_requested_events(wait);
1017
1018         cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
1019                 cif_isp10_v4l2_buf_type_string(queue->type));
1020
1021         if (v4l2_event_pending(&fh->fh))
1022                 ret = POLLPRI;
1023         else if (req_events & POLLPRI)
1024                 poll_wait(file, &fh->fh.wait, wait);
1025
1026         if (!(req_events & (POLLIN | POLLOUT | POLLRDNORM)))
1027                 return ret;
1028
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);
1033         }
1034         return ret;
1035 }
1036
1037 /*
1038  * VMA operations.
1039  */
1040 static void cif_isp10_v4l2_vm_open(struct vm_area_struct *vma)
1041 {
1042         struct cif_isp10_metadata_s *metadata =
1043                 (struct cif_isp10_metadata_s *)vma->vm_private_data;
1044
1045         metadata->vmas++;
1046 }
1047
1048 static void cif_isp10_v4l2_vm_close(struct vm_area_struct *vma)
1049 {
1050         struct cif_isp10_metadata_s *metadata =
1051                 (struct cif_isp10_metadata_s *)vma->vm_private_data;
1052
1053         metadata->vmas--;
1054 }
1055
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,
1059 };
1060
1061 int cif_isp10_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1062 {
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);
1066         int retval;
1067
1068         retval = cif_isp10_mmap(dev, strm, vma);
1069         if (retval < 0)
1070                 goto done;
1071
1072         vma->vm_ops          = &cif_isp10_vm_ops;
1073         vma->vm_flags       |= VM_DONTEXPAND | VM_DONTDUMP;
1074         cif_isp10_v4l2_vm_open(vma);
1075
1076 done:
1077         return retval;
1078 }
1079
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,
1085 #endif
1086         .release = cif_isp10_v4l2_release,
1087         .poll = cif_isp10_v4l2_poll,
1088         .mmap = cif_isp10_v4l2_mmap,
1089 };
1090
1091 /*TBD: clean up code below this line******************************************/
1092
1093 static int v4l2_querycap(struct file *file,
1094                          void *priv, struct v4l2_capability *cap)
1095 {
1096         int ret = 0;
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);
1101
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",
1106                 dev->dev_id);
1107
1108         if (stream_ids == CIF_ISP10_STREAM_SP)
1109                 cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
1110                         V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1111                         V4L2_CAP_STREAMING;
1112         else if (stream_ids == CIF_ISP10_STREAM_MP)
1113                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1114                         V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1115                         V4L2_CAP_STREAMING;
1116         else if (stream_ids == CIF_ISP10_STREAM_DMA)
1117                 cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE |
1118                         V4L2_CAP_VIDEO_M2M;
1119         cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
1120         cap->device_caps = V4L2_CAP_DEVICE_CAPS;
1121         return ret;
1122 }
1123
1124 static int cif_isp10_v4l2_subscribe_event(struct v4l2_fh *fh,
1125                                 const struct v4l2_event_subscription *sub)
1126 {
1127         if (sub->type != V4L2_EVENT_FRAME_SYNC)
1128                 return -EINVAL;
1129         return v4l2_event_subscribe(fh, sub, 16, NULL);
1130 }
1131
1132 static int cif_isp10_v4l2_unsubscribe_event(struct v4l2_fh *fh,
1133                                 const struct v4l2_event_subscription *sub)
1134 {
1135         return v4l2_event_unsubscribe(fh, sub);
1136 }
1137
1138 static void cif_isp10_v4l2_event(
1139         struct cif_isp10_device *dev,
1140         __u32 frame_sequence)
1141 {
1142         struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
1143                 (struct cif_isp10_v4l2_device *)dev->nodes;
1144         struct v4l2_event ev;
1145
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);
1150 }
1151
1152 static void cif_isp10_v4l2_requeue_bufs(
1153         struct cif_isp10_device *dev,
1154         enum cif_isp10_stream_id stream_id)
1155 {
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;
1160
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;
1167         else
1168                 WARN_ON(1);
1169
1170         dev = to_cif_isp10_device(q);
1171
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;
1180                         else
1181                                 cif_isp10_pltfrm_pr_err(NULL,
1182                                         "ERR: buf->state is: %d\n",
1183                                         buf->state);
1184                         spin_unlock(&dev->vbreq_lock);
1185                 } else {
1186                         cif_isp10_pltfrm_pr_err(NULL,
1187                                 "failed for buffer %d\n", buf->i);
1188                 }
1189         }
1190 }
1191
1192 static long v4l2_default_ioctl(struct file *file, void *fh,
1193                                bool valid_prio, unsigned int cmd, void *arg)
1194 {
1195         int ret = -EINVAL;
1196         struct videobuf_queue *queue = to_videobuf_queue(file);
1197         struct cif_isp10_device *dev = to_cif_isp10_device(queue);
1198
1199         if (!arg) {
1200                 cif_isp10_pltfrm_pr_err(dev->dev,
1201                         "NULL Pointer Violation from IOCTL arg:0x%lx\n",
1202                         (unsigned long)arg);
1203                 return ret;
1204         }
1205
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;
1209
1210                 ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
1211                         RK_VIDIOC_SENSOR_MODE_DATA, p_mode_data);
1212
1213                 if (ret < 0) {
1214                         cif_isp10_pltfrm_pr_err(dev->dev,
1215                                 "failed to get sensor mode data\n");
1216                         return ret;
1217                 }
1218
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;
1227
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;
1232
1233                 if (ret < 0) {
1234                         cif_isp10_pltfrm_pr_err(dev->dev,
1235                                 "failed to get isp input info\n");
1236                         return ret;
1237                 }
1238         } else if (cmd == RK_VIDIOC_CAMERA_MODULEINFO) {
1239                 struct camera_module_info_s *p_camera_module =
1240                 (struct camera_module_info_s *)arg;
1241
1242                 ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
1243                         RK_VIDIOC_CAMERA_MODULEINFO, p_camera_module);
1244
1245                 if (ret < 0) {
1246                         cif_isp10_pltfrm_pr_err(dev->dev,
1247                                 "failed to get camera module information\n");
1248                         return ret;
1249                 }
1250         }
1251
1252         return ret;
1253 }
1254
1255 static int v4l2_s_parm(
1256         struct file *file,
1257         void *priv,
1258         struct v4l2_streamparm *a)
1259 {
1260         return 0;
1261 }
1262
1263 static int v4l2_enum_input(struct file *file, void *priv,
1264                            struct v4l2_input *input)
1265 {
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;
1269
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);
1274                 return -EINVAL;
1275         }
1276
1277         inp_name = cif_isp10_g_input_name(dev, input->index);
1278         if (IS_ERR_OR_NULL(inp_name))
1279                 return -EINVAL;
1280
1281         input->type = V4L2_INPUT_TYPE_CAMERA;
1282         input->std = V4L2_STD_UNKNOWN;
1283         strncpy(input->name, inp_name, sizeof(input->name)-1);
1284
1285         return 0;
1286 }
1287
1288 /* ================================================================= */
1289
1290 static int mainpath_g_ctrl(
1291         struct file *file,
1292         void *priv,
1293         struct v4l2_control *vc)
1294 {
1295         int ret = -EINVAL;
1296
1297         switch (vc->id) {
1298         default:
1299                 return -EINVAL;
1300         }
1301         return ret;
1302 }
1303
1304 #ifdef NOT_YET
1305 static int mainpath_try_fmt_cap(struct v4l2_format *f)
1306 {
1307         int ifmt = 0;
1308         struct v4l2_pix_format *pix = &f->fmt.pix;
1309
1310         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
1311
1312         for (ifmt = 0; ifmt < get_cif_isp10_output_format_size(); ifmt++) {
1313                 if (pix->pixelformat ==
1314                 get_cif_isp10_output_format(ifmt)->fourcc)
1315                         break;
1316         }
1317
1318         if (ifmt == get_cif_isp10_output_format_size())
1319                 ifmt = 0;
1320
1321         pix->bytesperline = pix->width *
1322                 get_cif_isp10_output_format(ifmt)->depth / 8;
1323
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;
1338                 break;
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;
1345                 break;
1346         default:
1347                 WARN_ON(1);
1348                 break;
1349         }
1350
1351         return 0;
1352 }
1353 #endif
1354
1355 static int v4l2_enum_fmt_cap(struct file *file, void *fh,
1356                              struct v4l2_fmtdesc *f)
1357 {
1358         int ret = 0;
1359         int xgold_num_format = 0;
1360
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);
1365                 return -EINVAL;
1366         }
1367         strlcpy(f->description,
1368                 get_cif_isp10_output_format_desc(f->index)->description,
1369                         sizeof(f->description));
1370         f->pixelformat =
1371         get_cif_isp10_output_format_desc(f->index)->pixelformat;
1372         f->flags = get_cif_isp10_output_format_desc(f->index)->flags;
1373
1374         return ret;
1375 }
1376
1377 static int v4l2_g_ctrl(struct file *file, void *priv,
1378         struct v4l2_control *vc)
1379 {
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);
1384
1385         return cif_isp10_img_src_g_ctrl(dev->img_src,
1386                 id, &vc->value);
1387 }
1388
1389 static int v4l2_s_ext_ctrls(struct file *file, void *priv,
1390         struct v4l2_ext_controls *vc_ext)
1391 {
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);
1396         int ret = -EINVAL;
1397         unsigned int i;
1398
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.
1401          */
1402         cif_isp10_pltfrm_pr_dbg(dev->dev, "count %d\n",
1403                 vc_ext->count);
1404
1405         if (vc_ext->count == 0)
1406                 return ret;
1407
1408         ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
1409         if (!ctrl)
1410                 return -ENOMEM;
1411
1412         ctrls = kmalloc(vc_ext->count *
1413                 sizeof(struct cif_isp10_img_src_ctrl), GFP_KERNEL);
1414         if (!ctrls) {
1415                 kfree(ctrl);
1416                 return -ENOMEM;
1417         }
1418
1419         ctrl->cnt = vc_ext->count;
1420         /*current kernel version don't define
1421          *this member for struct v4l2_ext_control.
1422          */
1423         /*ctrl->class = vc_ext->ctrl_class;*/
1424         ctrl->ctrls = ctrls;
1425
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;
1429         }
1430
1431         ret = cif_isp10_s_exp(dev, ctrl);
1432         return ret;
1433 }
1434
1435 int cif_isp10_v4l2_cropcap(
1436         struct file *file,
1437         void *fh,
1438         struct v4l2_cropcap *a)
1439 {
1440         int ret = 0;
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;
1444         u32 h_offs, v_offs;
1445
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,
1451                         &h_offs, &v_offs);
1452
1453                 /* Get output size */
1454                 ret = cif_isp10_get_target_frm_size(dev,
1455                         &target_width, &target_height);
1456                 if (ret < 0) {
1457                         cif_isp10_pltfrm_pr_err(dev->dev,
1458                                 "failed to get target frame size\n");
1459                         return ret;
1460                 }
1461
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,
1468                         target_width,
1469                         target_height);
1470
1471                 /* This is the input to Bayer after input formatter cropping */
1472                 a->defrect.top = 0;
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;
1481
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,
1487                         &h_offs, &v_offs);
1488
1489                 /* Get output size */
1490                 ret = cif_isp10_get_target_frm_size(dev,
1491                         &target_width, &target_height);
1492                 if (ret < 0) {
1493                         cif_isp10_pltfrm_pr_err(dev->dev,
1494                                 "failed to get target frame size\n");
1495                         return ret;
1496                 }
1497
1498                 /* This is the input to Bayer after input formatter cropping */
1499                 a->defrect.top =
1500                         v_offs + dev->config.isp_config.input->defrect.top;
1501                 a->defrect.left =
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;
1505
1506                 a->bounds.top = 0;
1507                 a->bounds.left = 0;
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;
1511         } else {
1512                 cif_isp10_pltfrm_pr_err(dev->dev,
1513                         "invalid input\n");
1514         }
1515
1516         cif_isp10_pltfrm_pr_dbg(dev->dev,
1517                 "v4l2_cropcap: defrect(%d,%d,%d,%d) bounds(%d,%d,%d,%d)\n",
1518                 a->defrect.width,
1519                 a->defrect.height,
1520                 a->defrect.left,
1521                 a->defrect.top,
1522                 a->bounds.width,
1523                 a->bounds.height,
1524                 a->bounds.left,
1525                 a->bounds.top);
1526
1527         return ret;
1528 }
1529
1530 int cif_isp10_v4l2_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
1531 {
1532         return 0;
1533 }
1534
1535 /*
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.
1540  */
1541 int cif_isp10_v4l2_s_crop(
1542         struct file *file,
1543         void *fh,
1544         const struct v4l2_crop *a)
1545 {
1546         return 0;
1547 }
1548
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,
1570 };
1571
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,
1593 };
1594
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,
1607 };
1608
1609 static struct pltfrm_soc_cfg rk3288_cfg = {
1610         .name = CIF_ISP10_SOC_RK3288,
1611         .soc_cfg = pltfrm_rk3288_cfg,
1612 };
1613
1614 static struct pltfrm_soc_cfg rk3399_cfg = {
1615         .name = CIF_ISP10_SOC_RK3399,
1616         .soc_cfg = pltfrm_rk3399_cfg,
1617 };
1618
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},
1624         {},
1625 };
1626
1627 static unsigned int cif_isp10_v4l2_dev_cnt;
1628 static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
1629 {
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;
1634         int ret;
1635
1636         cif_isp10_pltfrm_pr_info(NULL, "probing...\n");
1637
1638         cif_isp10_v4l2_dev = devm_kzalloc(
1639                                 &pdev->dev,
1640                                 sizeof(struct cif_isp10_v4l2_device),
1641                                 GFP_KERNEL);
1642         if (IS_ERR_OR_NULL(cif_isp10_v4l2_dev)) {
1643                 ret = -ENOMEM;
1644                 goto err;
1645         }
1646
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)) {
1653                 ret = -ENODEV;
1654                 goto err;
1655         }
1656
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);
1663
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");
1668                 goto err;
1669         }
1670
1671         ret = cif_isp10_v4l2_register_video_device(
1672                 dev,
1673                 &cif_isp10_v4l2_dev->node[SP_DEV].vdev,
1674                 SP_VDEV_NAME,
1675                 V4L2_CAP_VIDEO_OVERLAY,
1676                 CIF_ISP10_V4L2_SP_DEV_MAJOR,
1677                 &cif_isp10_v4l2_fops,
1678                 &cif_isp10_v4l2_sp_ioctlops);
1679         if (ret)
1680                 goto err;
1681
1682         ret = register_cifisp_device(&dev->isp_dev,
1683                 &cif_isp10_v4l2_dev->node[ISP_DEV].vdev,
1684                 &dev->v4l2_dev,
1685                 dev->config.base_addr);
1686         if (ret)
1687                 goto err;
1688
1689         ret = cif_isp10_v4l2_register_video_device(
1690                 dev,
1691                 &cif_isp10_v4l2_dev->node[MP_DEV].vdev,
1692                 MP_VDEV_NAME,
1693                 V4L2_CAP_VIDEO_CAPTURE,
1694                 CIF_ISP10_V4L2_MP_DEV_MAJOR,
1695                 &cif_isp10_v4l2_fops,
1696                 &cif_isp10_v4l2_mp_ioctlops);
1697         if (ret)
1698                 goto err;
1699
1700         ret = cif_isp10_v4l2_register_video_device(
1701                 dev,
1702                 &cif_isp10_v4l2_dev->node[DMA_DEV].vdev,
1703                 DMA_VDEV_NAME,
1704                 V4L2_CAP_VIDEO_OUTPUT,
1705                 CIF_ISP10_V4L2_DMA_DEV_MAJOR,
1706                 &cif_isp10_v4l2_fops,
1707                 &cif_isp10_v4l2_dma_ioctlops);
1708         if (ret)
1709                 goto err;
1710
1711         pm_runtime_enable(&pdev->dev);
1712
1713         cif_isp10_v4l2_dev_cnt++;
1714         return 0;
1715 err:
1716         cif_isp10_destroy(dev);
1717         return ret;
1718 }
1719
1720 /* ======================================================================== */
1721
1722 static int cif_isp10_v4l2_drv_remove(struct platform_device *pdev)
1723 {
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;
1728
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");
1733
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);
1741
1742         cif_isp10_v4l2_dev_cnt--;
1743         return 0;
1744 }
1745
1746 static int cif_isp10_v4l2_drv_suspend(struct platform_device *pdev,
1747         pm_message_t state)
1748 {
1749         int ret = 0;
1750         struct cif_isp10_device *cif_isp10_dev =
1751                 (struct cif_isp10_device *)platform_get_drvdata(pdev);
1752
1753         cif_isp10_pltfrm_pr_dbg(cif_isp10_dev->dev, "\n");
1754
1755         ret = cif_isp10_suspend(cif_isp10_dev);
1756         if (IS_ERR_VALUE(ret))
1757                 goto err;
1758
1759         cif_isp10_pltfrm_pinctrl_set_state(&pdev->dev,
1760                 CIF_ISP10_PINCTRL_STATE_SLEEP);
1761
1762         return 0;
1763 err:
1764         cif_isp10_pltfrm_pr_err(cif_isp10_dev->dev,
1765                 "failed with error %d\n", ret);
1766         return ret;
1767 }
1768
1769 static int cif_isp10_v4l2_drv_resume(struct platform_device *pdev)
1770 {
1771         int ret = 0;
1772         struct cif_isp10_device *cif_isp10_dev =
1773                 (struct cif_isp10_device *)platform_get_drvdata(pdev);
1774
1775         cif_isp10_pltfrm_pr_dbg(cif_isp10_dev->dev, "\n");
1776
1777         if (!cif_isp10_dev->img_src) {
1778                 cif_isp10_pltfrm_pr_err(
1779                         cif_isp10_dev->dev,
1780                         "cif_isp10_dev img_src is null!\n");
1781                 goto err;
1782         }
1783
1784         ret = cif_isp10_resume(cif_isp10_dev);
1785         if (IS_ERR_VALUE(ret))
1786                 goto err;
1787
1788         cif_isp10_pltfrm_pinctrl_set_state(&pdev->dev,
1789                 CIF_ISP10_PINCTRL_STATE_DEFAULT);
1790
1791         return 0;
1792 err:
1793         cif_isp10_pltfrm_pr_err(cif_isp10_dev->dev,
1794                 "failed with error %d\n", ret);
1795         return ret;
1796 }
1797
1798 static int cif_isp10_runtime_suspend(struct device *dev)
1799 {
1800         cif_isp10_pltfrm_pr_dbg(dev, "\n");
1801         return cif_isp10_pltfrm_pm_set_state(dev, CIF_ISP10_PM_STATE_SUSPENDED);
1802 }
1803
1804 static int cif_isp10_runtime_resume(struct device *dev)
1805 {
1806         cif_isp10_pltfrm_pr_dbg(dev, "\n");
1807         return cif_isp10_pltfrm_pm_set_state(dev, CIF_ISP10_PM_STATE_SW_STNDBY);
1808 }
1809
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)
1813 };
1814
1815 static struct platform_driver cif_isp10_v4l2_plat_drv = {
1816         .driver = {
1817                 .name = DRIVER_NAME,
1818                 .of_match_table = of_match_ptr(cif_isp10_v4l2_of_match),
1819                 .pm = &cif_isp10_dev_pm_ops,
1820                    },
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,
1825 };
1826
1827 /* ======================================================================== */
1828 static int cif_isp10_v4l2_init(void)
1829 {
1830         int ret;
1831
1832         ret = platform_driver_register(&cif_isp10_v4l2_plat_drv);
1833         if (ret) {
1834                 cif_isp10_pltfrm_pr_err(NULL,
1835                         "cannot register platform driver, failed with %d\n",
1836                         ret);
1837                 return -ENODEV;
1838         }
1839
1840         return ret;
1841 }
1842
1843 /* ======================================================================== */
1844 static void __exit cif_isp10_v4l2_exit(void)
1845 {
1846         platform_driver_unregister(&cif_isp10_v4l2_plat_drv);
1847 }
1848
1849 device_initcall_sync(cif_isp10_v4l2_init);
1850 module_exit(cif_isp10_v4l2_exit);
1851
1852 MODULE_DESCRIPTION("V4L2 interface for CIF ISP10 driver");
1853 MODULE_AUTHOR("George");
1854 MODULE_LICENSE("GPL");