1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <asm/cacheflush.h>
17#include <linux/clk.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/pagemap.h>
21#include <linux/scatterlist.h>
22#include <linux/sched.h>
23#include <linux/slab.h>
24#include <linux/vmalloc.h>
25
26#include <media/v4l2-dev.h>
27#include <media/v4l2-ioctl.h>
28#include <media/v4l2-mc.h>
29#include <media/videobuf2-dma-contig.h>
30
31#include "ispvideo.h"
32#include "isp.h"
33
34
35
36
37
38
39
40
41
42
43static struct isp_format_info formats[] = {
44 { MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8,
45 MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8,
46 V4L2_PIX_FMT_GREY, 8, 1, },
47 { MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y10_1X10,
48 MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y8_1X8,
49 V4L2_PIX_FMT_Y10, 10, 2, },
50 { MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y10_1X10,
51 MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y8_1X8,
52 V4L2_PIX_FMT_Y12, 12, 2, },
53 { MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8,
54 MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8,
55 V4L2_PIX_FMT_SBGGR8, 8, 1, },
56 { MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,
57 MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,
58 V4L2_PIX_FMT_SGBRG8, 8, 1, },
59 { MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8,
60 MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8,
61 V4L2_PIX_FMT_SGRBG8, 8, 1, },
62 { MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,
63 MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,
64 V4L2_PIX_FMT_SRGGB8, 8, 1, },
65 { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
66 MEDIA_BUS_FMT_SBGGR10_1X10, 0,
67 V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, },
68 { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
69 MEDIA_BUS_FMT_SGBRG10_1X10, 0,
70 V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, },
71 { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
72 MEDIA_BUS_FMT_SGRBG10_1X10, 0,
73 V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, },
74 { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
75 MEDIA_BUS_FMT_SRGGB10_1X10, 0,
76 V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, },
77 { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10,
78 MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR8_1X8,
79 V4L2_PIX_FMT_SBGGR10, 10, 2, },
80 { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10,
81 MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG8_1X8,
82 V4L2_PIX_FMT_SGBRG10, 10, 2, },
83 { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10,
84 MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG8_1X8,
85 V4L2_PIX_FMT_SGRBG10, 10, 2, },
86 { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10,
87 MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB8_1X8,
88 V4L2_PIX_FMT_SRGGB10, 10, 2, },
89 { MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR10_1X10,
90 MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR8_1X8,
91 V4L2_PIX_FMT_SBGGR12, 12, 2, },
92 { MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG10_1X10,
93 MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG8_1X8,
94 V4L2_PIX_FMT_SGBRG12, 12, 2, },
95 { MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG10_1X10,
96 MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG8_1X8,
97 V4L2_PIX_FMT_SGRBG12, 12, 2, },
98 { MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10,
99 MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB8_1X8,
100 V4L2_PIX_FMT_SRGGB12, 12, 2, },
101 { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16,
102 MEDIA_BUS_FMT_UYVY8_1X16, 0,
103 V4L2_PIX_FMT_UYVY, 16, 2, },
104 { MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1X16,
105 MEDIA_BUS_FMT_YUYV8_1X16, 0,
106 V4L2_PIX_FMT_YUYV, 16, 2, },
107 { MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_UYVY8_2X8,
108 MEDIA_BUS_FMT_UYVY8_2X8, 0,
109 V4L2_PIX_FMT_UYVY, 8, 2, },
110 { MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_YUYV8_2X8,
111 MEDIA_BUS_FMT_YUYV8_2X8, 0,
112 V4L2_PIX_FMT_YUYV, 8, 2, },
113
114
115
116 { 0, }
117};
118
119const struct isp_format_info *omap3isp_video_format_info(u32 code)
120{
121 unsigned int i;
122
123 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
124 if (formats[i].code == code)
125 return &formats[i];
126 }
127
128 return NULL;
129}
130
131
132
133
134
135
136
137
138
139
140
141
142
143static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
144 const struct v4l2_mbus_framefmt *mbus,
145 struct v4l2_pix_format *pix)
146{
147 unsigned int bpl = pix->bytesperline;
148 unsigned int min_bpl;
149 unsigned int i;
150
151 memset(pix, 0, sizeof(*pix));
152 pix->width = mbus->width;
153 pix->height = mbus->height;
154
155 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
156 if (formats[i].code == mbus->code)
157 break;
158 }
159
160 if (WARN_ON(i == ARRAY_SIZE(formats)))
161 return 0;
162
163 min_bpl = pix->width * formats[i].bpp;
164
165
166
167
168
169 if (video->bpl_max)
170 bpl = clamp(bpl, min_bpl, video->bpl_max);
171 else
172 bpl = min_bpl;
173
174 if (!video->bpl_zero_padding || bpl != min_bpl)
175 bpl = ALIGN(bpl, video->bpl_alignment);
176
177 pix->pixelformat = formats[i].pixelformat;
178 pix->bytesperline = bpl;
179 pix->sizeimage = pix->bytesperline * pix->height;
180 pix->colorspace = mbus->colorspace;
181 pix->field = mbus->field;
182
183 return bpl - min_bpl;
184}
185
186static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
187 struct v4l2_mbus_framefmt *mbus)
188{
189 unsigned int i;
190
191 memset(mbus, 0, sizeof(*mbus));
192 mbus->width = pix->width;
193 mbus->height = pix->height;
194
195
196
197
198 for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
199 if (formats[i].pixelformat == pix->pixelformat)
200 break;
201 }
202
203 mbus->code = formats[i].code;
204 mbus->colorspace = pix->colorspace;
205 mbus->field = pix->field;
206}
207
208static struct v4l2_subdev *
209isp_video_remote_subdev(struct isp_video *video, u32 *pad)
210{
211 struct media_pad *remote;
212
213 remote = media_entity_remote_pad(&video->pad);
214
215 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
216 return NULL;
217
218 if (pad)
219 *pad = remote->index;
220
221 return media_entity_to_v4l2_subdev(remote->entity);
222}
223
224
225static int isp_video_get_graph_data(struct isp_video *video,
226 struct isp_pipeline *pipe)
227{
228 struct media_graph graph;
229 struct media_entity *entity = &video->video.entity;
230 struct media_device *mdev = entity->graph_obj.mdev;
231 struct isp_video *far_end = NULL;
232 int ret;
233
234 mutex_lock(&mdev->graph_mutex);
235 ret = media_graph_walk_init(&graph, mdev);
236 if (ret) {
237 mutex_unlock(&mdev->graph_mutex);
238 return ret;
239 }
240
241 media_graph_walk_start(&graph, entity);
242
243 while ((entity = media_graph_walk_next(&graph))) {
244 struct isp_video *__video;
245
246 media_entity_enum_set(&pipe->ent_enum, entity);
247
248 if (far_end != NULL)
249 continue;
250
251 if (entity == &video->video.entity)
252 continue;
253
254 if (!is_media_entity_v4l2_video_device(entity))
255 continue;
256
257 __video = to_isp_video(media_entity_to_video_device(entity));
258 if (__video->type != video->type)
259 far_end = __video;
260 }
261
262 mutex_unlock(&mdev->graph_mutex);
263
264 media_graph_walk_cleanup(&graph);
265
266 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
267 pipe->input = far_end;
268 pipe->output = video;
269 } else {
270 if (far_end == NULL)
271 return -EPIPE;
272
273 pipe->input = video;
274 pipe->output = far_end;
275 }
276
277 return 0;
278}
279
280static int
281__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
282{
283 struct v4l2_subdev_format fmt;
284 struct v4l2_subdev *subdev;
285 u32 pad;
286 int ret;
287
288 subdev = isp_video_remote_subdev(video, &pad);
289 if (subdev == NULL)
290 return -EINVAL;
291
292 fmt.pad = pad;
293 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
294
295 mutex_lock(&video->mutex);
296 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
297 mutex_unlock(&video->mutex);
298
299 if (ret)
300 return ret;
301
302 format->type = video->type;
303 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
304}
305
306static int
307isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
308{
309 struct v4l2_format format;
310 int ret;
311
312 memcpy(&format, &vfh->format, sizeof(format));
313 ret = __isp_video_get_format(video, &format);
314 if (ret < 0)
315 return ret;
316
317 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
318 vfh->format.fmt.pix.height != format.fmt.pix.height ||
319 vfh->format.fmt.pix.width != format.fmt.pix.width ||
320 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
321 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage ||
322 vfh->format.fmt.pix.field != format.fmt.pix.field)
323 return -EINVAL;
324
325 return 0;
326}
327
328
329
330
331
332static int isp_video_queue_setup(struct vb2_queue *queue,
333 unsigned int *count, unsigned int *num_planes,
334 unsigned int sizes[], struct device *alloc_devs[])
335{
336 struct isp_video_fh *vfh = vb2_get_drv_priv(queue);
337 struct isp_video *video = vfh->video;
338
339 *num_planes = 1;
340
341 sizes[0] = vfh->format.fmt.pix.sizeimage;
342 if (sizes[0] == 0)
343 return -EINVAL;
344
345 *count = min(*count, video->capture_mem / PAGE_ALIGN(sizes[0]));
346
347 return 0;
348}
349
350static int isp_video_buffer_prepare(struct vb2_buffer *buf)
351{
352 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(buf);
353 struct isp_video_fh *vfh = vb2_get_drv_priv(buf->vb2_queue);
354 struct isp_buffer *buffer = to_isp_buffer(vbuf);
355 struct isp_video *video = vfh->video;
356 dma_addr_t addr;
357
358
359
360
361
362
363
364 if (unlikely(video->error))
365 return -EIO;
366
367 addr = vb2_dma_contig_plane_dma_addr(buf, 0);
368 if (!IS_ALIGNED(addr, 32)) {
369 dev_dbg(video->isp->dev,
370 "Buffer address must be aligned to 32 bytes boundary.\n");
371 return -EINVAL;
372 }
373
374 vb2_set_plane_payload(&buffer->vb.vb2_buf, 0,
375 vfh->format.fmt.pix.sizeimage);
376 buffer->dma = addr;
377
378 return 0;
379}
380
381
382
383
384
385
386
387
388
389
390static void isp_video_buffer_queue(struct vb2_buffer *buf)
391{
392 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(buf);
393 struct isp_video_fh *vfh = vb2_get_drv_priv(buf->vb2_queue);
394 struct isp_buffer *buffer = to_isp_buffer(vbuf);
395 struct isp_video *video = vfh->video;
396 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
397 enum isp_pipeline_state state;
398 unsigned long flags;
399 unsigned int empty;
400 unsigned int start;
401
402 spin_lock_irqsave(&video->irqlock, flags);
403
404 if (unlikely(video->error)) {
405 vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_ERROR);
406 spin_unlock_irqrestore(&video->irqlock, flags);
407 return;
408 }
409
410 empty = list_empty(&video->dmaqueue);
411 list_add_tail(&buffer->irqlist, &video->dmaqueue);
412
413 spin_unlock_irqrestore(&video->irqlock, flags);
414
415 if (empty) {
416 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
417 state = ISP_PIPELINE_QUEUE_OUTPUT;
418 else
419 state = ISP_PIPELINE_QUEUE_INPUT;
420
421 spin_lock_irqsave(&pipe->lock, flags);
422 pipe->state |= state;
423 video->ops->queue(video, buffer);
424 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
425
426 start = isp_pipeline_ready(pipe);
427 if (start)
428 pipe->state |= ISP_PIPELINE_STREAM;
429 spin_unlock_irqrestore(&pipe->lock, flags);
430
431 if (start)
432 omap3isp_pipeline_set_stream(pipe,
433 ISP_PIPELINE_STREAM_SINGLESHOT);
434 }
435}
436
437
438
439
440
441
442
443
444
445
446
447
448static void omap3isp_video_return_buffers(struct isp_video *video,
449 enum vb2_buffer_state state)
450{
451 while (!list_empty(&video->dmaqueue)) {
452 struct isp_buffer *buf;
453
454 buf = list_first_entry(&video->dmaqueue,
455 struct isp_buffer, irqlist);
456 list_del(&buf->irqlist);
457 vb2_buffer_done(&buf->vb.vb2_buf, state);
458 }
459}
460
461static int isp_video_start_streaming(struct vb2_queue *queue,
462 unsigned int count)
463{
464 struct isp_video_fh *vfh = vb2_get_drv_priv(queue);
465 struct isp_video *video = vfh->video;
466 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
467 unsigned long flags;
468 int ret;
469
470
471
472
473
474 if (pipe->input)
475 return 0;
476
477 ret = omap3isp_pipeline_set_stream(pipe,
478 ISP_PIPELINE_STREAM_CONTINUOUS);
479 if (ret < 0) {
480 spin_lock_irqsave(&video->irqlock, flags);
481 omap3isp_video_return_buffers(video, VB2_BUF_STATE_QUEUED);
482 spin_unlock_irqrestore(&video->irqlock, flags);
483 return ret;
484 }
485
486 spin_lock_irqsave(&video->irqlock, flags);
487 if (list_empty(&video->dmaqueue))
488 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
489 spin_unlock_irqrestore(&video->irqlock, flags);
490
491 return 0;
492}
493
494static const struct vb2_ops isp_video_queue_ops = {
495 .queue_setup = isp_video_queue_setup,
496 .buf_prepare = isp_video_buffer_prepare,
497 .buf_queue = isp_video_buffer_queue,
498 .start_streaming = isp_video_start_streaming,
499};
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
518{
519 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
520 enum vb2_buffer_state vb_state;
521 struct isp_buffer *buf;
522 unsigned long flags;
523
524 spin_lock_irqsave(&video->irqlock, flags);
525 if (WARN_ON(list_empty(&video->dmaqueue))) {
526 spin_unlock_irqrestore(&video->irqlock, flags);
527 return NULL;
528 }
529
530 buf = list_first_entry(&video->dmaqueue, struct isp_buffer,
531 irqlist);
532 list_del(&buf->irqlist);
533 spin_unlock_irqrestore(&video->irqlock, flags);
534
535 buf->vb.vb2_buf.timestamp = ktime_get_ns();
536
537
538
539
540
541
542
543 if (video == pipe->output && !pipe->do_propagation)
544 buf->vb.sequence =
545 atomic_inc_return(&pipe->frame_number);
546 else
547 buf->vb.sequence = atomic_read(&pipe->frame_number);
548
549 if (pipe->field != V4L2_FIELD_NONE)
550 buf->vb.sequence /= 2;
551
552 buf->vb.field = pipe->field;
553
554
555 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
556 vb_state = VB2_BUF_STATE_ERROR;
557 pipe->error = false;
558 } else {
559 vb_state = VB2_BUF_STATE_DONE;
560 }
561
562 vb2_buffer_done(&buf->vb.vb2_buf, vb_state);
563
564 spin_lock_irqsave(&video->irqlock, flags);
565
566 if (list_empty(&video->dmaqueue)) {
567 enum isp_pipeline_state state;
568
569 spin_unlock_irqrestore(&video->irqlock, flags);
570
571 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
572 state = ISP_PIPELINE_QUEUE_OUTPUT
573 | ISP_PIPELINE_STREAM;
574 else
575 state = ISP_PIPELINE_QUEUE_INPUT
576 | ISP_PIPELINE_STREAM;
577
578 spin_lock_irqsave(&pipe->lock, flags);
579 pipe->state &= ~state;
580 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
581 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
582 spin_unlock_irqrestore(&pipe->lock, flags);
583 return NULL;
584 }
585
586 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
587 spin_lock(&pipe->lock);
588 pipe->state &= ~ISP_PIPELINE_STREAM;
589 spin_unlock(&pipe->lock);
590 }
591
592 buf = list_first_entry(&video->dmaqueue, struct isp_buffer,
593 irqlist);
594
595 spin_unlock_irqrestore(&video->irqlock, flags);
596
597 return buf;
598}
599
600
601
602
603
604
605
606
607void omap3isp_video_cancel_stream(struct isp_video *video)
608{
609 unsigned long flags;
610
611 spin_lock_irqsave(&video->irqlock, flags);
612 omap3isp_video_return_buffers(video, VB2_BUF_STATE_ERROR);
613 video->error = true;
614 spin_unlock_irqrestore(&video->irqlock, flags);
615}
616
617
618
619
620
621
622
623
624
625
626
627void omap3isp_video_resume(struct isp_video *video, int continuous)
628{
629 struct isp_buffer *buf = NULL;
630
631 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
632 mutex_lock(&video->queue_lock);
633 vb2_discard_done(video->queue);
634 mutex_unlock(&video->queue_lock);
635 }
636
637 if (!list_empty(&video->dmaqueue)) {
638 buf = list_first_entry(&video->dmaqueue,
639 struct isp_buffer, irqlist);
640 video->ops->queue(video, buf);
641 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
642 } else {
643 if (continuous)
644 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
645 }
646}
647
648
649
650
651
652static int
653isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
654{
655 struct isp_video *video = video_drvdata(file);
656
657 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
658 strlcpy(cap->card, video->video.name, sizeof(cap->card));
659 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
660
661 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
662 | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
663
664 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
665 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
666 else
667 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
668
669 return 0;
670}
671
672static int
673isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
674{
675 struct isp_video_fh *vfh = to_isp_video_fh(fh);
676 struct isp_video *video = video_drvdata(file);
677
678 if (format->type != video->type)
679 return -EINVAL;
680
681 mutex_lock(&video->mutex);
682 *format = vfh->format;
683 mutex_unlock(&video->mutex);
684
685 return 0;
686}
687
688static int
689isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
690{
691 struct isp_video_fh *vfh = to_isp_video_fh(fh);
692 struct isp_video *video = video_drvdata(file);
693 struct v4l2_mbus_framefmt fmt;
694
695 if (format->type != video->type)
696 return -EINVAL;
697
698
699 switch (format->fmt.pix.field) {
700 case V4L2_FIELD_NONE:
701
702 break;
703 case V4L2_FIELD_ALTERNATE:
704
705 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
706 format->fmt.pix.field = V4L2_FIELD_NONE;
707 break;
708 case V4L2_FIELD_INTERLACED:
709
710
711
712
713 format->fmt.pix.field = V4L2_FIELD_INTERLACED_TB;
714
715 case V4L2_FIELD_INTERLACED_TB:
716 case V4L2_FIELD_INTERLACED_BT:
717
718 if (video != &video->isp->isp_ccdc.video_out)
719 format->fmt.pix.field = V4L2_FIELD_NONE;
720 break;
721 case V4L2_FIELD_TOP:
722 case V4L2_FIELD_BOTTOM:
723 case V4L2_FIELD_SEQ_TB:
724 case V4L2_FIELD_SEQ_BT:
725 default:
726
727
728
729 format->fmt.pix.field = V4L2_FIELD_NONE;
730 break;
731 }
732
733
734
735
736 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
737 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
738
739 mutex_lock(&video->mutex);
740 vfh->format = *format;
741 mutex_unlock(&video->mutex);
742
743 return 0;
744}
745
746static int
747isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
748{
749 struct isp_video *video = video_drvdata(file);
750 struct v4l2_subdev_format fmt;
751 struct v4l2_subdev *subdev;
752 u32 pad;
753 int ret;
754
755 if (format->type != video->type)
756 return -EINVAL;
757
758 subdev = isp_video_remote_subdev(video, &pad);
759 if (subdev == NULL)
760 return -EINVAL;
761
762 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
763
764 fmt.pad = pad;
765 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
766 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
767 if (ret)
768 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
769
770 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
771 return 0;
772}
773
774static int
775isp_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel)
776{
777 struct isp_video *video = video_drvdata(file);
778 struct v4l2_subdev_format format;
779 struct v4l2_subdev *subdev;
780 struct v4l2_subdev_selection sdsel = {
781 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
782 .target = sel->target,
783 };
784 u32 pad;
785 int ret;
786
787 switch (sel->target) {
788 case V4L2_SEL_TGT_CROP:
789 case V4L2_SEL_TGT_CROP_BOUNDS:
790 case V4L2_SEL_TGT_CROP_DEFAULT:
791 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
792 return -EINVAL;
793 break;
794 case V4L2_SEL_TGT_COMPOSE:
795 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
796 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
797 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
798 return -EINVAL;
799 break;
800 default:
801 return -EINVAL;
802 }
803 subdev = isp_video_remote_subdev(video, &pad);
804 if (subdev == NULL)
805 return -EINVAL;
806
807
808
809
810 sdsel.pad = pad;
811 ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel);
812 if (!ret)
813 sel->r = sdsel.r;
814 if (ret != -ENOIOCTLCMD)
815 return ret;
816
817 format.pad = pad;
818 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
819 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
820 if (ret < 0)
821 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
822
823 sel->r.left = 0;
824 sel->r.top = 0;
825 sel->r.width = format.format.width;
826 sel->r.height = format.format.height;
827
828 return 0;
829}
830
831static int
832isp_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel)
833{
834 struct isp_video *video = video_drvdata(file);
835 struct v4l2_subdev *subdev;
836 struct v4l2_subdev_selection sdsel = {
837 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
838 .target = sel->target,
839 .flags = sel->flags,
840 .r = sel->r,
841 };
842 u32 pad;
843 int ret;
844
845 switch (sel->target) {
846 case V4L2_SEL_TGT_CROP:
847 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
848 return -EINVAL;
849 break;
850 case V4L2_SEL_TGT_COMPOSE:
851 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
852 return -EINVAL;
853 break;
854 default:
855 return -EINVAL;
856 }
857 subdev = isp_video_remote_subdev(video, &pad);
858 if (subdev == NULL)
859 return -EINVAL;
860
861 sdsel.pad = pad;
862 mutex_lock(&video->mutex);
863 ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel);
864 mutex_unlock(&video->mutex);
865 if (!ret)
866 sel->r = sdsel.r;
867
868 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
869}
870
871static int
872isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
873{
874 struct isp_video_fh *vfh = to_isp_video_fh(fh);
875 struct isp_video *video = video_drvdata(file);
876
877 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
878 video->type != a->type)
879 return -EINVAL;
880
881 memset(a, 0, sizeof(*a));
882 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
883 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
884 a->parm.output.timeperframe = vfh->timeperframe;
885
886 return 0;
887}
888
889static int
890isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
891{
892 struct isp_video_fh *vfh = to_isp_video_fh(fh);
893 struct isp_video *video = video_drvdata(file);
894
895 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
896 video->type != a->type)
897 return -EINVAL;
898
899 if (a->parm.output.timeperframe.denominator == 0)
900 a->parm.output.timeperframe.denominator = 1;
901
902 vfh->timeperframe = a->parm.output.timeperframe;
903
904 return 0;
905}
906
907static int
908isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
909{
910 struct isp_video_fh *vfh = to_isp_video_fh(fh);
911 struct isp_video *video = video_drvdata(file);
912 int ret;
913
914 mutex_lock(&video->queue_lock);
915 ret = vb2_reqbufs(&vfh->queue, rb);
916 mutex_unlock(&video->queue_lock);
917
918 return ret;
919}
920
921static int
922isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
923{
924 struct isp_video_fh *vfh = to_isp_video_fh(fh);
925 struct isp_video *video = video_drvdata(file);
926 int ret;
927
928 mutex_lock(&video->queue_lock);
929 ret = vb2_querybuf(&vfh->queue, b);
930 mutex_unlock(&video->queue_lock);
931
932 return ret;
933}
934
935static int
936isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
937{
938 struct isp_video_fh *vfh = to_isp_video_fh(fh);
939 struct isp_video *video = video_drvdata(file);
940 int ret;
941
942 mutex_lock(&video->queue_lock);
943 ret = vb2_qbuf(&vfh->queue, b);
944 mutex_unlock(&video->queue_lock);
945
946 return ret;
947}
948
949static int
950isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
951{
952 struct isp_video_fh *vfh = to_isp_video_fh(fh);
953 struct isp_video *video = video_drvdata(file);
954 int ret;
955
956 mutex_lock(&video->queue_lock);
957 ret = vb2_dqbuf(&vfh->queue, b, file->f_flags & O_NONBLOCK);
958 mutex_unlock(&video->queue_lock);
959
960 return ret;
961}
962
963static int isp_video_check_external_subdevs(struct isp_video *video,
964 struct isp_pipeline *pipe)
965{
966 struct isp_device *isp = video->isp;
967 struct media_entity *ents[] = {
968 &isp->isp_csi2a.subdev.entity,
969 &isp->isp_csi2c.subdev.entity,
970 &isp->isp_ccp2.subdev.entity,
971 &isp->isp_ccdc.subdev.entity
972 };
973 struct media_pad *source_pad;
974 struct media_entity *source = NULL;
975 struct media_entity *sink;
976 struct v4l2_subdev_format fmt;
977 struct v4l2_ext_controls ctrls;
978 struct v4l2_ext_control ctrl;
979 unsigned int i;
980 int ret;
981
982
983 if (pipe->input != NULL)
984 return 0;
985
986 for (i = 0; i < ARRAY_SIZE(ents); i++) {
987
988 if (!media_entity_enum_test(&pipe->ent_enum, ents[i]))
989 continue;
990
991
992 source_pad = media_entity_remote_pad(&ents[i]->pads[0]);
993 if (source_pad == NULL)
994 continue;
995
996 source = source_pad->entity;
997 sink = ents[i];
998 break;
999 }
1000
1001 if (!source) {
1002 dev_warn(isp->dev, "can't find source, failing now\n");
1003 return -EINVAL;
1004 }
1005
1006 if (!is_media_entity_v4l2_subdev(source))
1007 return 0;
1008
1009 pipe->external = media_entity_to_v4l2_subdev(source);
1010
1011 fmt.pad = source_pad->index;
1012 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1013 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
1014 pad, get_fmt, NULL, &fmt);
1015 if (unlikely(ret < 0)) {
1016 dev_warn(isp->dev, "get_fmt returned null!\n");
1017 return ret;
1018 }
1019
1020 pipe->external_width =
1021 omap3isp_video_format_info(fmt.format.code)->width;
1022
1023 memset(&ctrls, 0, sizeof(ctrls));
1024 memset(&ctrl, 0, sizeof(ctrl));
1025
1026 ctrl.id = V4L2_CID_PIXEL_RATE;
1027
1028 ctrls.count = 1;
1029 ctrls.controls = &ctrl;
1030
1031 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
1032 if (ret < 0) {
1033 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
1034 pipe->external->name);
1035 return ret;
1036 }
1037
1038 pipe->external_rate = ctrl.value64;
1039
1040 if (media_entity_enum_test(&pipe->ent_enum,
1041 &isp->isp_ccdc.subdev.entity)) {
1042 unsigned int rate = UINT_MAX;
1043
1044
1045
1046
1047 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
1048 if (pipe->external_rate > rate)
1049 return -ENOSPC;
1050 }
1051
1052 return 0;
1053}
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086static int
1087isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1088{
1089 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1090 struct isp_video *video = video_drvdata(file);
1091 enum isp_pipeline_state state;
1092 struct isp_pipeline *pipe;
1093 unsigned long flags;
1094 int ret;
1095
1096 if (type != video->type)
1097 return -EINVAL;
1098
1099 mutex_lock(&video->stream_lock);
1100
1101
1102
1103
1104 pipe = video->video.entity.pipe
1105 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
1106
1107 ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev);
1108 if (ret)
1109 goto err_enum_init;
1110
1111
1112 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1113 pipe->max_rate = pipe->l3_ick;
1114
1115 ret = media_pipeline_start(&video->video.entity, &pipe->pipe);
1116 if (ret < 0)
1117 goto err_pipeline_start;
1118
1119
1120
1121
1122 ret = isp_video_check_format(video, vfh);
1123 if (ret < 0)
1124 goto err_check_format;
1125
1126 video->bpl_padding = ret;
1127 video->bpl_value = vfh->format.fmt.pix.bytesperline;
1128
1129 ret = isp_video_get_graph_data(video, pipe);
1130 if (ret < 0)
1131 goto err_check_format;
1132
1133 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1134 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
1135 else
1136 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
1137
1138 ret = isp_video_check_external_subdevs(video, pipe);
1139 if (ret < 0)
1140 goto err_check_format;
1141
1142 pipe->error = false;
1143
1144 spin_lock_irqsave(&pipe->lock, flags);
1145 pipe->state &= ~ISP_PIPELINE_STREAM;
1146 pipe->state |= state;
1147 spin_unlock_irqrestore(&pipe->lock, flags);
1148
1149
1150
1151
1152
1153 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1154 pipe->max_timeperframe = vfh->timeperframe;
1155
1156 video->queue = &vfh->queue;
1157 INIT_LIST_HEAD(&video->dmaqueue);
1158 atomic_set(&pipe->frame_number, -1);
1159 pipe->field = vfh->format.fmt.pix.field;
1160
1161 mutex_lock(&video->queue_lock);
1162 ret = vb2_streamon(&vfh->queue, type);
1163 mutex_unlock(&video->queue_lock);
1164 if (ret < 0)
1165 goto err_check_format;
1166
1167 mutex_unlock(&video->stream_lock);
1168
1169 return 0;
1170
1171err_check_format:
1172 media_pipeline_stop(&video->video.entity);
1173err_pipeline_start:
1174
1175
1176
1177
1178
1179
1180
1181
1182 INIT_LIST_HEAD(&video->dmaqueue);
1183 video->queue = NULL;
1184
1185 media_entity_enum_cleanup(&pipe->ent_enum);
1186
1187err_enum_init:
1188 mutex_unlock(&video->stream_lock);
1189
1190 return ret;
1191}
1192
1193static int
1194isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1195{
1196 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1197 struct isp_video *video = video_drvdata(file);
1198 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
1199 enum isp_pipeline_state state;
1200 unsigned int streaming;
1201 unsigned long flags;
1202
1203 if (type != video->type)
1204 return -EINVAL;
1205
1206 mutex_lock(&video->stream_lock);
1207
1208
1209 mutex_lock(&video->queue_lock);
1210 streaming = vb2_is_streaming(&vfh->queue);
1211 mutex_unlock(&video->queue_lock);
1212
1213 if (!streaming)
1214 goto done;
1215
1216
1217 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1218 state = ISP_PIPELINE_STREAM_OUTPUT
1219 | ISP_PIPELINE_QUEUE_OUTPUT;
1220 else
1221 state = ISP_PIPELINE_STREAM_INPUT
1222 | ISP_PIPELINE_QUEUE_INPUT;
1223
1224 spin_lock_irqsave(&pipe->lock, flags);
1225 pipe->state &= ~state;
1226 spin_unlock_irqrestore(&pipe->lock, flags);
1227
1228
1229 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1230 omap3isp_video_cancel_stream(video);
1231
1232 mutex_lock(&video->queue_lock);
1233 vb2_streamoff(&vfh->queue, type);
1234 mutex_unlock(&video->queue_lock);
1235 video->queue = NULL;
1236 video->error = false;
1237
1238
1239 media_pipeline_stop(&video->video.entity);
1240
1241 media_entity_enum_cleanup(&pipe->ent_enum);
1242
1243done:
1244 mutex_unlock(&video->stream_lock);
1245 return 0;
1246}
1247
1248static int
1249isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1250{
1251 if (input->index > 0)
1252 return -EINVAL;
1253
1254 strlcpy(input->name, "camera", sizeof(input->name));
1255 input->type = V4L2_INPUT_TYPE_CAMERA;
1256
1257 return 0;
1258}
1259
1260static int
1261isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1262{
1263 *input = 0;
1264
1265 return 0;
1266}
1267
1268static int
1269isp_video_s_input(struct file *file, void *fh, unsigned int input)
1270{
1271 return input == 0 ? 0 : -EINVAL;
1272}
1273
1274static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1275 .vidioc_querycap = isp_video_querycap,
1276 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1277 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1278 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1279 .vidioc_g_fmt_vid_out = isp_video_get_format,
1280 .vidioc_s_fmt_vid_out = isp_video_set_format,
1281 .vidioc_try_fmt_vid_out = isp_video_try_format,
1282 .vidioc_g_selection = isp_video_get_selection,
1283 .vidioc_s_selection = isp_video_set_selection,
1284 .vidioc_g_parm = isp_video_get_param,
1285 .vidioc_s_parm = isp_video_set_param,
1286 .vidioc_reqbufs = isp_video_reqbufs,
1287 .vidioc_querybuf = isp_video_querybuf,
1288 .vidioc_qbuf = isp_video_qbuf,
1289 .vidioc_dqbuf = isp_video_dqbuf,
1290 .vidioc_streamon = isp_video_streamon,
1291 .vidioc_streamoff = isp_video_streamoff,
1292 .vidioc_enum_input = isp_video_enum_input,
1293 .vidioc_g_input = isp_video_g_input,
1294 .vidioc_s_input = isp_video_s_input,
1295};
1296
1297
1298
1299
1300
1301static int isp_video_open(struct file *file)
1302{
1303 struct isp_video *video = video_drvdata(file);
1304 struct isp_video_fh *handle;
1305 struct vb2_queue *queue;
1306 int ret = 0;
1307
1308 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1309 if (handle == NULL)
1310 return -ENOMEM;
1311
1312 v4l2_fh_init(&handle->vfh, &video->video);
1313 v4l2_fh_add(&handle->vfh);
1314
1315
1316 if (omap3isp_get(video->isp) == NULL) {
1317 ret = -EBUSY;
1318 goto done;
1319 }
1320
1321 ret = v4l2_pipeline_pm_use(&video->video.entity, 1);
1322 if (ret < 0) {
1323 omap3isp_put(video->isp);
1324 goto done;
1325 }
1326
1327 queue = &handle->queue;
1328 queue->type = video->type;
1329 queue->io_modes = VB2_MMAP | VB2_USERPTR;
1330 queue->drv_priv = handle;
1331 queue->ops = &isp_video_queue_ops;
1332 queue->mem_ops = &vb2_dma_contig_memops;
1333 queue->buf_struct_size = sizeof(struct isp_buffer);
1334 queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1335 queue->dev = video->isp->dev;
1336
1337 ret = vb2_queue_init(&handle->queue);
1338 if (ret < 0) {
1339 omap3isp_put(video->isp);
1340 goto done;
1341 }
1342
1343 memset(&handle->format, 0, sizeof(handle->format));
1344 handle->format.type = video->type;
1345 handle->timeperframe.denominator = 1;
1346
1347 handle->video = video;
1348 file->private_data = &handle->vfh;
1349
1350done:
1351 if (ret < 0) {
1352 v4l2_fh_del(&handle->vfh);
1353 v4l2_fh_exit(&handle->vfh);
1354 kfree(handle);
1355 }
1356
1357 return ret;
1358}
1359
1360static int isp_video_release(struct file *file)
1361{
1362 struct isp_video *video = video_drvdata(file);
1363 struct v4l2_fh *vfh = file->private_data;
1364 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1365
1366
1367 isp_video_streamoff(file, vfh, video->type);
1368
1369 mutex_lock(&video->queue_lock);
1370 vb2_queue_release(&handle->queue);
1371 mutex_unlock(&video->queue_lock);
1372
1373 v4l2_pipeline_pm_use(&video->video.entity, 0);
1374
1375
1376 v4l2_fh_del(vfh);
1377 v4l2_fh_exit(vfh);
1378 kfree(handle);
1379 file->private_data = NULL;
1380
1381 omap3isp_put(video->isp);
1382
1383 return 0;
1384}
1385
1386static __poll_t isp_video_poll(struct file *file, poll_table *wait)
1387{
1388 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1389 struct isp_video *video = video_drvdata(file);
1390 __poll_t ret;
1391
1392 mutex_lock(&video->queue_lock);
1393 ret = vb2_poll(&vfh->queue, file, wait);
1394 mutex_unlock(&video->queue_lock);
1395
1396 return ret;
1397}
1398
1399static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1400{
1401 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1402
1403 return vb2_mmap(&vfh->queue, vma);
1404}
1405
1406static const struct v4l2_file_operations isp_video_fops = {
1407 .owner = THIS_MODULE,
1408 .unlocked_ioctl = video_ioctl2,
1409 .open = isp_video_open,
1410 .release = isp_video_release,
1411 .poll = isp_video_poll,
1412 .mmap = isp_video_mmap,
1413};
1414
1415
1416
1417
1418
1419static const struct isp_video_operations isp_video_dummy_ops = {
1420};
1421
1422int omap3isp_video_init(struct isp_video *video, const char *name)
1423{
1424 const char *direction;
1425 int ret;
1426
1427 switch (video->type) {
1428 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1429 direction = "output";
1430 video->pad.flags = MEDIA_PAD_FL_SINK
1431 | MEDIA_PAD_FL_MUST_CONNECT;
1432 break;
1433 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1434 direction = "input";
1435 video->pad.flags = MEDIA_PAD_FL_SOURCE
1436 | MEDIA_PAD_FL_MUST_CONNECT;
1437 video->video.vfl_dir = VFL_DIR_TX;
1438 break;
1439
1440 default:
1441 return -EINVAL;
1442 }
1443
1444 ret = media_entity_pads_init(&video->video.entity, 1, &video->pad);
1445 if (ret < 0)
1446 return ret;
1447
1448 mutex_init(&video->mutex);
1449 atomic_set(&video->active, 0);
1450
1451 spin_lock_init(&video->pipe.lock);
1452 mutex_init(&video->stream_lock);
1453 mutex_init(&video->queue_lock);
1454 spin_lock_init(&video->irqlock);
1455
1456
1457 if (video->ops == NULL)
1458 video->ops = &isp_video_dummy_ops;
1459
1460 video->video.fops = &isp_video_fops;
1461 snprintf(video->video.name, sizeof(video->video.name),
1462 "OMAP3 ISP %s %s", name, direction);
1463 video->video.vfl_type = VFL_TYPE_GRABBER;
1464 video->video.release = video_device_release_empty;
1465 video->video.ioctl_ops = &isp_video_ioctl_ops;
1466 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1467
1468 video_set_drvdata(&video->video, video);
1469
1470 return 0;
1471}
1472
1473void omap3isp_video_cleanup(struct isp_video *video)
1474{
1475 media_entity_cleanup(&video->video.entity);
1476 mutex_destroy(&video->queue_lock);
1477 mutex_destroy(&video->stream_lock);
1478 mutex_destroy(&video->mutex);
1479}
1480
1481int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1482{
1483 int ret;
1484
1485 video->video.v4l2_dev = vdev;
1486
1487 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1488 if (ret < 0)
1489 dev_err(video->isp->dev,
1490 "%s: could not register video device (%d)\n",
1491 __func__, ret);
1492
1493 return ret;
1494}
1495
1496void omap3isp_video_unregister(struct isp_video *video)
1497{
1498 if (video_is_registered(&video->video))
1499 video_unregister_device(&video->video);
1500}
1501