aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/s5p-fimc/fimc-capture.c
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-03-24 11:54:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-31 10:04:03 -0400
commit56fa1a6a6a7da91e7ece8b01b0ae8adb2926e434 (patch)
tree28d1c182eae5fa0fa2f0573390a593e895f664b4 /drivers/media/platform/s5p-fimc/fimc-capture.c
parent80f958f40d702ab322947f648bbd42174facf19d (diff)
[media] s5p-fimc: Change the driver directory name to exynos4-is
The s5p-fimc directory now contains drivers for multiple IP blocks found in multiple Samsung application processors. This includes FIMC (CAMIF), MIPI CSIS and FIMC LITE. FIMC-IS (Imaging Subsystem) driver is going to be put into same directory. Hence we rename it to exynos4-is as s5p-fimc was only relevant for early version of this driver, when it only supported FIMC IP block. The imaging subsystem drivers for Exynos4 SoC series and S5PV210 will be included in drivers/media/platform/exynos4-is directory, with some modules shared with exynos5 series, while the rest of exynos5 specific modules will find their home in drivers/media/platform/exynos5-is. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform/s5p-fimc/fimc-capture.c')
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c1887
1 files changed, 0 insertions, 1887 deletions
diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
deleted file mode 100644
index 1675d385d900..000000000000
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ /dev/null
@@ -1,1887 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
3 *
4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/errno.h>
16#include <linux/bug.h>
17#include <linux/interrupt.h>
18#include <linux/device.h>
19#include <linux/pm_runtime.h>
20#include <linux/list.h>
21#include <linux/slab.h>
22
23#include <linux/videodev2.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-ioctl.h>
26#include <media/v4l2-mem2mem.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "fimc-mdevice.h"
31#include "fimc-core.h"
32#include "fimc-reg.h"
33
34static int fimc_capture_hw_init(struct fimc_dev *fimc)
35{
36 struct fimc_source_info *si = &fimc->vid_cap.source_config;
37 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
38 int ret;
39 unsigned long flags;
40
41 if (ctx == NULL || ctx->s_frame.fmt == NULL)
42 return -EINVAL;
43
44 if (si->fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) {
45 ret = fimc_hw_camblk_cfg_writeback(fimc);
46 if (ret < 0)
47 return ret;
48 }
49
50 spin_lock_irqsave(&fimc->slock, flags);
51 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
52 fimc_set_yuv_order(ctx);
53
54 fimc_hw_set_camera_polarity(fimc, si);
55 fimc_hw_set_camera_type(fimc, si);
56 fimc_hw_set_camera_source(fimc, si);
57 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
58
59 ret = fimc_set_scaler_info(ctx);
60 if (!ret) {
61 fimc_hw_set_input_path(ctx);
62 fimc_hw_set_prescaler(ctx);
63 fimc_hw_set_mainscaler(ctx);
64 fimc_hw_set_target_format(ctx);
65 fimc_hw_set_rotation(ctx);
66 fimc_hw_set_effect(ctx);
67 fimc_hw_set_output_path(ctx);
68 fimc_hw_set_out_dma(ctx);
69 if (fimc->drv_data->alpha_color)
70 fimc_hw_set_rgb_alpha(ctx);
71 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
72 }
73 spin_unlock_irqrestore(&fimc->slock, flags);
74 return ret;
75}
76
77/*
78 * Reinitialize the driver so it is ready to start the streaming again.
79 * Set fimc->state to indicate stream off and the hardware shut down state.
80 * If not suspending (@suspend is false), return any buffers to videobuf2.
81 * Otherwise put any owned buffers onto the pending buffers queue, so they
82 * can be re-spun when the device is being resumed. Also perform FIMC
83 * software reset and disable streaming on the whole pipeline if required.
84 */
85static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
86{
87 struct fimc_vid_cap *cap = &fimc->vid_cap;
88 struct fimc_vid_buffer *buf;
89 unsigned long flags;
90 bool streaming;
91
92 spin_lock_irqsave(&fimc->slock, flags);
93 streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);
94
95 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
96 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
97 if (suspend)
98 fimc->state |= (1 << ST_CAPT_SUSPENDED);
99 else
100 fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
101
102 /* Release unused buffers */
103 while (!suspend && !list_empty(&cap->pending_buf_q)) {
104 buf = fimc_pending_queue_pop(cap);
105 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
106 }
107 /* If suspending put unused buffers onto pending queue */
108 while (!list_empty(&cap->active_buf_q)) {
109 buf = fimc_active_queue_pop(cap);
110 if (suspend)
111 fimc_pending_queue_add(cap, buf);
112 else
113 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
114 }
115
116 fimc_hw_reset(fimc);
117 cap->buf_index = 0;
118
119 spin_unlock_irqrestore(&fimc->slock, flags);
120
121 if (streaming)
122 return fimc_pipeline_call(fimc, set_stream,
123 &fimc->pipeline, 0);
124 else
125 return 0;
126}
127
128static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
129{
130 unsigned long flags;
131
132 if (!fimc_capture_active(fimc))
133 return 0;
134
135 spin_lock_irqsave(&fimc->slock, flags);
136 set_bit(ST_CAPT_SHUT, &fimc->state);
137 fimc_deactivate_capture(fimc);
138 spin_unlock_irqrestore(&fimc->slock, flags);
139
140 wait_event_timeout(fimc->irq_queue,
141 !test_bit(ST_CAPT_SHUT, &fimc->state),
142 (2*HZ/10)); /* 200 ms */
143
144 return fimc_capture_state_cleanup(fimc, suspend);
145}
146
147/**
148 * fimc_capture_config_update - apply the camera interface configuration
149 *
150 * To be called from within the interrupt handler with fimc.slock
151 * spinlock held. It updates the camera pixel crop, rotation and
152 * image flip in H/W.
153 */
154static int fimc_capture_config_update(struct fimc_ctx *ctx)
155{
156 struct fimc_dev *fimc = ctx->fimc_dev;
157 int ret;
158
159 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
160
161 ret = fimc_set_scaler_info(ctx);
162 if (ret)
163 return ret;
164
165 fimc_hw_set_prescaler(ctx);
166 fimc_hw_set_mainscaler(ctx);
167 fimc_hw_set_target_format(ctx);
168 fimc_hw_set_rotation(ctx);
169 fimc_hw_set_effect(ctx);
170 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
171 fimc_hw_set_out_dma(ctx);
172 if (fimc->drv_data->alpha_color)
173 fimc_hw_set_rgb_alpha(ctx);
174
175 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
176 return ret;
177}
178
179void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
180{
181 struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
182 struct fimc_vid_cap *cap = &fimc->vid_cap;
183 struct fimc_frame *f = &cap->ctx->d_frame;
184 struct fimc_vid_buffer *v_buf;
185 struct timeval *tv;
186 struct timespec ts;
187
188 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
189 wake_up(&fimc->irq_queue);
190 goto done;
191 }
192
193 if (!list_empty(&cap->active_buf_q) &&
194 test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
195 ktime_get_real_ts(&ts);
196
197 v_buf = fimc_active_queue_pop(cap);
198
199 tv = &v_buf->vb.v4l2_buf.timestamp;
200 tv->tv_sec = ts.tv_sec;
201 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
202 v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
203
204 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
205 }
206
207 if (!list_empty(&cap->pending_buf_q)) {
208
209 v_buf = fimc_pending_queue_pop(cap);
210 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
211 v_buf->index = cap->buf_index;
212
213 /* Move the buffer to the capture active queue */
214 fimc_active_queue_add(cap, v_buf);
215
216 dbg("next frame: %d, done frame: %d",
217 fimc_hw_get_frame_index(fimc), v_buf->index);
218
219 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
220 cap->buf_index = 0;
221 }
222 /*
223 * Set up a buffer at MIPI-CSIS if current image format
224 * requires the frame embedded data capture.
225 */
226 if (f->fmt->mdataplanes && !list_empty(&cap->active_buf_q)) {
227 unsigned int plane = ffs(f->fmt->mdataplanes) - 1;
228 unsigned int size = f->payload[plane];
229 s32 index = fimc_hw_get_frame_index(fimc);
230 void *vaddr;
231
232 list_for_each_entry(v_buf, &cap->active_buf_q, list) {
233 if (v_buf->index != index)
234 continue;
235 vaddr = vb2_plane_vaddr(&v_buf->vb, plane);
236 v4l2_subdev_call(csis, video, s_rx_buffer,
237 vaddr, &size);
238 break;
239 }
240 }
241
242 if (cap->active_buf_cnt == 0) {
243 if (deq_buf)
244 clear_bit(ST_CAPT_RUN, &fimc->state);
245
246 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
247 cap->buf_index = 0;
248 } else {
249 set_bit(ST_CAPT_RUN, &fimc->state);
250 }
251
252 if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
253 fimc_capture_config_update(cap->ctx);
254done:
255 if (cap->active_buf_cnt == 1) {
256 fimc_deactivate_capture(fimc);
257 clear_bit(ST_CAPT_STREAM, &fimc->state);
258 }
259
260 dbg("frame: %d, active_buf_cnt: %d",
261 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
262}
263
264
265static int start_streaming(struct vb2_queue *q, unsigned int count)
266{
267 struct fimc_ctx *ctx = q->drv_priv;
268 struct fimc_dev *fimc = ctx->fimc_dev;
269 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
270 int min_bufs;
271 int ret;
272
273 vid_cap->frame_count = 0;
274
275 ret = fimc_capture_hw_init(fimc);
276 if (ret) {
277 fimc_capture_state_cleanup(fimc, false);
278 return ret;
279 }
280
281 set_bit(ST_CAPT_PEND, &fimc->state);
282
283 min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
284
285 if (vid_cap->active_buf_cnt >= min_bufs &&
286 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
287 fimc_activate_capture(ctx);
288
289 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
290 return fimc_pipeline_call(fimc, set_stream,
291 &fimc->pipeline, 1);
292 }
293
294 return 0;
295}
296
297static int stop_streaming(struct vb2_queue *q)
298{
299 struct fimc_ctx *ctx = q->drv_priv;
300 struct fimc_dev *fimc = ctx->fimc_dev;
301
302 if (!fimc_capture_active(fimc))
303 return -EINVAL;
304
305 return fimc_stop_capture(fimc, false);
306}
307
308int fimc_capture_suspend(struct fimc_dev *fimc)
309{
310 bool suspend = fimc_capture_busy(fimc);
311
312 int ret = fimc_stop_capture(fimc, suspend);
313 if (ret)
314 return ret;
315 return fimc_pipeline_call(fimc, close, &fimc->pipeline);
316}
317
318static void buffer_queue(struct vb2_buffer *vb);
319
320int fimc_capture_resume(struct fimc_dev *fimc)
321{
322 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
323 struct fimc_vid_buffer *buf;
324 int i;
325
326 if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state))
327 return 0;
328
329 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
330 vid_cap->buf_index = 0;
331 fimc_pipeline_call(fimc, open, &fimc->pipeline,
332 &vid_cap->vfd.entity, false);
333 fimc_capture_hw_init(fimc);
334
335 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
336
337 for (i = 0; i < vid_cap->reqbufs_count; i++) {
338 if (list_empty(&vid_cap->pending_buf_q))
339 break;
340 buf = fimc_pending_queue_pop(vid_cap);
341 buffer_queue(&buf->vb);
342 }
343 return 0;
344
345}
346
347static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
348 unsigned int *num_buffers, unsigned int *num_planes,
349 unsigned int sizes[], void *allocators[])
350{
351 const struct v4l2_pix_format_mplane *pixm = NULL;
352 struct fimc_ctx *ctx = vq->drv_priv;
353 struct fimc_frame *frame = &ctx->d_frame;
354 struct fimc_fmt *fmt = frame->fmt;
355 unsigned long wh;
356 int i;
357
358 if (pfmt) {
359 pixm = &pfmt->fmt.pix_mp;
360 fmt = fimc_find_format(&pixm->pixelformat, NULL,
361 FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
362 wh = pixm->width * pixm->height;
363 } else {
364 wh = frame->f_width * frame->f_height;
365 }
366
367 if (fmt == NULL)
368 return -EINVAL;
369
370 *num_planes = fmt->memplanes;
371
372 for (i = 0; i < fmt->memplanes; i++) {
373 unsigned int size = (wh * fmt->depth[i]) / 8;
374 if (pixm)
375 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
376 else if (fimc_fmt_is_user_defined(fmt->color))
377 sizes[i] = frame->payload[i];
378 else
379 sizes[i] = max_t(u32, size, frame->payload[i]);
380
381 allocators[i] = ctx->fimc_dev->alloc_ctx;
382 }
383
384 return 0;
385}
386
387static int buffer_prepare(struct vb2_buffer *vb)
388{
389 struct vb2_queue *vq = vb->vb2_queue;
390 struct fimc_ctx *ctx = vq->drv_priv;
391 int i;
392
393 if (ctx->d_frame.fmt == NULL)
394 return -EINVAL;
395
396 for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
397 unsigned long size = ctx->d_frame.payload[i];
398
399 if (vb2_plane_size(vb, i) < size) {
400 v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
401 "User buffer too small (%ld < %ld)\n",
402 vb2_plane_size(vb, i), size);
403 return -EINVAL;
404 }
405 vb2_set_plane_payload(vb, i, size);
406 }
407
408 return 0;
409}
410
411static void buffer_queue(struct vb2_buffer *vb)
412{
413 struct fimc_vid_buffer *buf
414 = container_of(vb, struct fimc_vid_buffer, vb);
415 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
416 struct fimc_dev *fimc = ctx->fimc_dev;
417 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
418 unsigned long flags;
419 int min_bufs;
420
421 spin_lock_irqsave(&fimc->slock, flags);
422 fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
423
424 if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
425 !test_bit(ST_CAPT_STREAM, &fimc->state) &&
426 vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
427 /* Setup the buffer directly for processing. */
428 int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
429 vid_cap->buf_index;
430
431 fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
432 buf->index = vid_cap->buf_index;
433 fimc_active_queue_add(vid_cap, buf);
434
435 if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
436 vid_cap->buf_index = 0;
437 } else {
438 fimc_pending_queue_add(vid_cap, buf);
439 }
440
441 min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
442
443
444 if (vb2_is_streaming(&vid_cap->vbq) &&
445 vid_cap->active_buf_cnt >= min_bufs &&
446 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
447 int ret;
448
449 fimc_activate_capture(ctx);
450 spin_unlock_irqrestore(&fimc->slock, flags);
451
452 if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
453 return;
454
455 ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
456 if (ret < 0)
457 v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret);
458 return;
459 }
460 spin_unlock_irqrestore(&fimc->slock, flags);
461}
462
463static struct vb2_ops fimc_capture_qops = {
464 .queue_setup = queue_setup,
465 .buf_prepare = buffer_prepare,
466 .buf_queue = buffer_queue,
467 .wait_prepare = vb2_ops_wait_prepare,
468 .wait_finish = vb2_ops_wait_finish,
469 .start_streaming = start_streaming,
470 .stop_streaming = stop_streaming,
471};
472
473/**
474 * fimc_capture_ctrls_create - initialize the control handler
475 * Initialize the capture video node control handler and fill it
476 * with the FIMC controls. Inherit any sensor's controls if the
477 * 'user_subdev_api' flag is false (default behaviour).
478 * This function need to be called with the graph mutex held.
479 */
480int fimc_capture_ctrls_create(struct fimc_dev *fimc)
481{
482 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
483 struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
484 int ret;
485
486 if (WARN_ON(vid_cap->ctx == NULL))
487 return -ENXIO;
488 if (vid_cap->ctx->ctrls.ready)
489 return 0;
490
491 ret = fimc_ctrls_create(vid_cap->ctx);
492
493 if (ret || vid_cap->user_subdev_api || !sensor ||
494 !vid_cap->ctx->ctrls.ready)
495 return ret;
496
497 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
498 sensor->ctrl_handler, NULL);
499}
500
501static int fimc_capture_set_default_format(struct fimc_dev *fimc);
502
503static int fimc_capture_open(struct file *file)
504{
505 struct fimc_dev *fimc = video_drvdata(file);
506 int ret = -EBUSY;
507
508 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
509
510 fimc_md_graph_lock(fimc);
511 mutex_lock(&fimc->lock);
512
513 if (fimc_m2m_active(fimc))
514 goto unlock;
515
516 set_bit(ST_CAPT_BUSY, &fimc->state);
517 ret = pm_runtime_get_sync(&fimc->pdev->dev);
518 if (ret < 0)
519 goto unlock;
520
521 ret = v4l2_fh_open(file);
522 if (ret) {
523 pm_runtime_put(&fimc->pdev->dev);
524 goto unlock;
525 }
526
527 if (v4l2_fh_is_singular_file(file)) {
528 ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
529 &fimc->vid_cap.vfd.entity, true);
530
531 if (!ret && !fimc->vid_cap.user_subdev_api)
532 ret = fimc_capture_set_default_format(fimc);
533
534 if (!ret)
535 ret = fimc_capture_ctrls_create(fimc);
536
537 if (ret < 0) {
538 clear_bit(ST_CAPT_BUSY, &fimc->state);
539 pm_runtime_put_sync(&fimc->pdev->dev);
540 v4l2_fh_release(file);
541 } else {
542 fimc->vid_cap.refcnt++;
543 }
544 }
545unlock:
546 mutex_unlock(&fimc->lock);
547 fimc_md_graph_unlock(fimc);
548 return ret;
549}
550
551static int fimc_capture_release(struct file *file)
552{
553 struct fimc_dev *fimc = video_drvdata(file);
554 int ret;
555
556 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
557
558 mutex_lock(&fimc->lock);
559
560 if (v4l2_fh_is_singular_file(file)) {
561 clear_bit(ST_CAPT_BUSY, &fimc->state);
562 fimc_stop_capture(fimc, false);
563 fimc_pipeline_call(fimc, close, &fimc->pipeline);
564 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
565 fimc->vid_cap.refcnt--;
566 }
567
568 pm_runtime_put(&fimc->pdev->dev);
569
570 if (v4l2_fh_is_singular_file(file))
571 fimc_ctrls_delete(fimc->vid_cap.ctx);
572
573 ret = vb2_fop_release(file);
574 mutex_unlock(&fimc->lock);
575
576 return ret;
577}
578
579static const struct v4l2_file_operations fimc_capture_fops = {
580 .owner = THIS_MODULE,
581 .open = fimc_capture_open,
582 .release = fimc_capture_release,
583 .poll = vb2_fop_poll,
584 .unlocked_ioctl = video_ioctl2,
585 .mmap = vb2_fop_mmap,
586};
587
588/*
589 * Format and crop negotiation helpers
590 */
591
592static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
593 u32 *width, u32 *height,
594 u32 *code, u32 *fourcc, int pad)
595{
596 bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
597 struct fimc_dev *fimc = ctx->fimc_dev;
598 const struct fimc_variant *var = fimc->variant;
599 const struct fimc_pix_limit *pl = var->pix_limit;
600 struct fimc_frame *dst = &ctx->d_frame;
601 u32 depth, min_w, max_w, min_h, align_h = 3;
602 u32 mask = FMT_FLAGS_CAM;
603 struct fimc_fmt *ffmt;
604
605 /* Conversion from/to JPEG or User Defined format is not supported */
606 if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
607 fimc_fmt_is_user_defined(ctx->s_frame.fmt->color))
608 *code = ctx->s_frame.fmt->mbus_code;
609
610 if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad == FIMC_SD_PAD_SOURCE)
611 mask |= FMT_FLAGS_M2M;
612
613 if (pad == FIMC_SD_PAD_SINK_FIFO)
614 mask = FMT_FLAGS_WRITEBACK;
615
616 ffmt = fimc_find_format(fourcc, code, mask, 0);
617 if (WARN_ON(!ffmt))
618 return NULL;
619
620 if (code)
621 *code = ffmt->mbus_code;
622 if (fourcc)
623 *fourcc = ffmt->fourcc;
624
625 if (pad != FIMC_SD_PAD_SOURCE) {
626 max_w = fimc_fmt_is_user_defined(ffmt->color) ?
627 pl->scaler_dis_w : pl->scaler_en_w;
628 /* Apply the camera input interface pixel constraints */
629 v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
630 height, max_t(u32, *height, 32),
631 FIMC_CAMIF_MAX_HEIGHT,
632 fimc_fmt_is_user_defined(ffmt->color) ?
633 3 : 1,
634 0);
635 return ffmt;
636 }
637 /* Can't scale or crop in transparent (JPEG) transfer mode */
638 if (fimc_fmt_is_user_defined(ffmt->color)) {
639 *width = ctx->s_frame.f_width;
640 *height = ctx->s_frame.f_height;
641 return ffmt;
642 }
643 /* Apply the scaler and the output DMA constraints */
644 max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
645 if (ctx->state & FIMC_COMPOSE) {
646 min_w = dst->offs_h + dst->width;
647 min_h = dst->offs_v + dst->height;
648 } else {
649 min_w = var->min_out_pixsize;
650 min_h = var->min_out_pixsize;
651 }
652 if (var->min_vsize_align == 1 && !rotation)
653 align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
654
655 depth = fimc_get_format_depth(ffmt);
656 v4l_bound_align_image(width, min_w, max_w,
657 ffs(var->min_out_pixsize) - 1,
658 height, min_h, FIMC_CAMIF_MAX_HEIGHT,
659 align_h,
660 64/(ALIGN(depth, 8)));
661
662 dbg("pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
663 pad, code ? *code : 0, *width, *height,
664 dst->f_width, dst->f_height);
665
666 return ffmt;
667}
668
669static void fimc_capture_try_selection(struct fimc_ctx *ctx,
670 struct v4l2_rect *r,
671 int target)
672{
673 bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
674 struct fimc_dev *fimc = ctx->fimc_dev;
675 const struct fimc_variant *var = fimc->variant;
676 const struct fimc_pix_limit *pl = var->pix_limit;
677 struct fimc_frame *sink = &ctx->s_frame;
678 u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
679 u32 align_sz = 0, align_h = 4;
680 u32 max_sc_h, max_sc_v;
681
682 /* In JPEG transparent transfer mode cropping is not supported */
683 if (fimc_fmt_is_user_defined(ctx->d_frame.fmt->color)) {
684 r->width = sink->f_width;
685 r->height = sink->f_height;
686 r->left = r->top = 0;
687 return;
688 }
689 if (target == V4L2_SEL_TGT_COMPOSE) {
690 if (ctx->rotation != 90 && ctx->rotation != 270)
691 align_h = 1;
692 max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
693 max_sc_v = min(SCALER_MAX_VRATIO, 1 << (ffs(sink->height) - 1));
694 min_sz = var->min_out_pixsize;
695 } else {
696 u32 depth = fimc_get_format_depth(sink->fmt);
697 align_sz = 64/ALIGN(depth, 8);
698 min_sz = var->min_inp_pixsize;
699 min_w = min_h = min_sz;
700 max_sc_h = max_sc_v = 1;
701 }
702 /*
703 * For the compose rectangle the following constraints must be met:
704 * - it must fit in the sink pad format rectangle (f_width/f_height);
705 * - maximum downscaling ratio is 64;
706 * - maximum crop size depends if the rotator is used or not;
707 * - the sink pad format width/height must be 4 multiple of the
708 * prescaler ratios determined by sink pad size and source pad crop,
709 * the prescaler ratio is returned by fimc_get_scaler_factor().
710 */
711 max_w = min_t(u32,
712 rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
713 rotate ? sink->f_height : sink->f_width);
714 max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
715
716 if (target == V4L2_SEL_TGT_COMPOSE) {
717 min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
718 min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
719 if (rotate) {
720 swap(max_sc_h, max_sc_v);
721 swap(min_w, min_h);
722 }
723 }
724 v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
725 &r->height, min_h, max_h, align_h,
726 align_sz);
727 /* Adjust left/top if crop/compose rectangle is out of bounds */
728 r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
729 r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
730 r->left = round_down(r->left, var->hor_offs_align);
731
732 dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
733 target, r->left, r->top, r->width, r->height,
734 sink->f_width, sink->f_height);
735}
736
737/*
738 * The video node ioctl operations
739 */
740static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
741 struct v4l2_capability *cap)
742{
743 struct fimc_dev *fimc = video_drvdata(file);
744
745 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
746 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
747 cap->bus_info[0] = 0;
748 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
749
750 return 0;
751}
752
753static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
754 struct v4l2_fmtdesc *f)
755{
756 struct fimc_fmt *fmt;
757
758 fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
759 f->index);
760 if (!fmt)
761 return -EINVAL;
762 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
763 f->pixelformat = fmt->fourcc;
764 if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8)
765 f->flags |= V4L2_FMT_FLAG_COMPRESSED;
766 return 0;
767}
768
769static struct media_entity *fimc_pipeline_get_head(struct media_entity *me)
770{
771 struct media_pad *pad = &me->pads[0];
772
773 while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
774 pad = media_entity_remote_source(pad);
775 if (!pad)
776 break;
777 me = pad->entity;
778 pad = &me->pads[0];
779 }
780
781 return me;
782}
783
784/**
785 * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
786 * elements
787 * @ctx: FIMC capture context
788 * @tfmt: media bus format to try/set on subdevs
789 * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
790 * @set: true to set format on subdevs, false to try only
791 */
792static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
793 struct v4l2_mbus_framefmt *tfmt,
794 struct fimc_fmt **fmt_id,
795 bool set)
796{
797 struct fimc_dev *fimc = ctx->fimc_dev;
798 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
799 struct v4l2_subdev_format sfmt;
800 struct v4l2_mbus_framefmt *mf = &sfmt.format;
801 struct media_entity *me;
802 struct fimc_fmt *ffmt;
803 struct media_pad *pad;
804 int ret, i = 1;
805 u32 fcc;
806
807 if (WARN_ON(!sd || !tfmt))
808 return -EINVAL;
809
810 memset(&sfmt, 0, sizeof(sfmt));
811 sfmt.format = *tfmt;
812 sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
813
814 me = fimc_pipeline_get_head(&sd->entity);
815
816 while (1) {
817 ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
818 FMT_FLAGS_CAM, i++);
819 if (ffmt == NULL) {
820 /*
821 * Notify user-space if common pixel code for
822 * host and sensor does not exist.
823 */
824 return -EINVAL;
825 }
826 mf->code = tfmt->code = ffmt->mbus_code;
827
828 /* set format on all pipeline subdevs */
829 while (me != &fimc->vid_cap.subdev.entity) {
830 sd = media_entity_to_v4l2_subdev(me);
831
832 sfmt.pad = 0;
833 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
834 if (ret)
835 return ret;
836
837 if (me->pads[0].flags & MEDIA_PAD_FL_SINK) {
838 sfmt.pad = me->num_pads - 1;
839 mf->code = tfmt->code;
840 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL,
841 &sfmt);
842 if (ret)
843 return ret;
844 }
845
846 pad = media_entity_remote_source(&me->pads[sfmt.pad]);
847 if (!pad)
848 return -EINVAL;
849 me = pad->entity;
850 }
851
852 if (mf->code != tfmt->code)
853 continue;
854
855 fcc = ffmt->fourcc;
856 tfmt->width = mf->width;
857 tfmt->height = mf->height;
858 ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
859 NULL, &fcc, FIMC_SD_PAD_SINK_CAM);
860 ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
861 NULL, &fcc, FIMC_SD_PAD_SOURCE);
862 if (ffmt && ffmt->mbus_code)
863 mf->code = ffmt->mbus_code;
864 if (mf->width != tfmt->width || mf->height != tfmt->height)
865 continue;
866 tfmt->code = mf->code;
867 break;
868 }
869
870 if (fmt_id && ffmt)
871 *fmt_id = ffmt;
872 *tfmt = *mf;
873
874 return 0;
875}
876
877/**
878 * fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
879 * @sensor: pointer to the sensor subdev
880 * @plane_fmt: provides plane sizes corresponding to the frame layout entries
881 * @try: true to set the frame parameters, false to query only
882 *
883 * This function is used by this driver only for compressed/blob data formats.
884 */
885static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
886 struct v4l2_plane_pix_format *plane_fmt,
887 unsigned int num_planes, bool try)
888{
889 struct v4l2_mbus_frame_desc fd;
890 int i, ret;
891 int pad;
892
893 for (i = 0; i < num_planes; i++)
894 fd.entry[i].length = plane_fmt[i].sizeimage;
895
896 pad = sensor->entity.num_pads - 1;
897 if (try)
898 ret = v4l2_subdev_call(sensor, pad, set_frame_desc, pad, &fd);
899 else
900 ret = v4l2_subdev_call(sensor, pad, get_frame_desc, pad, &fd);
901
902 if (ret < 0)
903 return ret;
904
905 if (num_planes != fd.num_entries)
906 return -EINVAL;
907
908 for (i = 0; i < num_planes; i++)
909 plane_fmt[i].sizeimage = fd.entry[i].length;
910
911 if (fd.entry[0].length > FIMC_MAX_JPEG_BUF_SIZE) {
912 v4l2_err(sensor->v4l2_dev, "Unsupported buffer size: %u\n",
913 fd.entry[0].length);
914
915 return -EINVAL;
916 }
917
918 return 0;
919}
920
921static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
922 struct v4l2_format *f)
923{
924 struct fimc_dev *fimc = video_drvdata(file);
925
926 __fimc_get_format(&fimc->vid_cap.ctx->d_frame, f);
927 return 0;
928}
929
930static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
931 struct v4l2_format *f)
932{
933 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
934 struct fimc_dev *fimc = video_drvdata(file);
935 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
936 struct v4l2_mbus_framefmt mf;
937 struct fimc_fmt *ffmt = NULL;
938 int ret = 0;
939
940 fimc_md_graph_lock(fimc);
941 mutex_lock(&fimc->lock);
942
943 if (fimc_jpeg_fourcc(pix->pixelformat)) {
944 fimc_capture_try_format(ctx, &pix->width, &pix->height,
945 NULL, &pix->pixelformat,
946 FIMC_SD_PAD_SINK_CAM);
947 ctx->s_frame.f_width = pix->width;
948 ctx->s_frame.f_height = pix->height;
949 }
950 ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
951 NULL, &pix->pixelformat,
952 FIMC_SD_PAD_SOURCE);
953 if (!ffmt) {
954 ret = -EINVAL;
955 goto unlock;
956 }
957
958 if (!fimc->vid_cap.user_subdev_api) {
959 mf.width = pix->width;
960 mf.height = pix->height;
961 mf.code = ffmt->mbus_code;
962 fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
963 pix->width = mf.width;
964 pix->height = mf.height;
965 if (ffmt)
966 pix->pixelformat = ffmt->fourcc;
967 }
968
969 fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
970
971 if (ffmt->flags & FMT_FLAGS_COMPRESSED)
972 fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
973 pix->plane_fmt, ffmt->memplanes, true);
974unlock:
975 mutex_unlock(&fimc->lock);
976 fimc_md_graph_unlock(fimc);
977
978 return ret;
979}
980
981static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
982 enum fimc_color_fmt color)
983{
984 bool jpeg = fimc_fmt_is_user_defined(color);
985
986 ctx->scaler.enabled = !jpeg;
987 fimc_ctrls_activate(ctx, !jpeg);
988
989 if (jpeg)
990 set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
991 else
992 clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
993}
994
995static int __fimc_capture_set_format(struct fimc_dev *fimc,
996 struct v4l2_format *f)
997{
998 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
999 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1000 struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
1001 struct fimc_frame *ff = &ctx->d_frame;
1002 struct fimc_fmt *s_fmt = NULL;
1003 int ret, i;
1004
1005 if (vb2_is_busy(&fimc->vid_cap.vbq))
1006 return -EBUSY;
1007
1008 /* Pre-configure format at camera interface input, for JPEG only */
1009 if (fimc_jpeg_fourcc(pix->pixelformat)) {
1010 fimc_capture_try_format(ctx, &pix->width, &pix->height,
1011 NULL, &pix->pixelformat,
1012 FIMC_SD_PAD_SINK_CAM);
1013 ctx->s_frame.f_width = pix->width;
1014 ctx->s_frame.f_height = pix->height;
1015 }
1016 /* Try the format at the scaler and the DMA output */
1017 ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
1018 NULL, &pix->pixelformat,
1019 FIMC_SD_PAD_SOURCE);
1020 if (!ff->fmt)
1021 return -EINVAL;
1022
1023 /* Update RGB Alpha control state and value range */
1024 fimc_alpha_ctrl_update(ctx);
1025
1026 /* Try to match format at the host and the sensor */
1027 if (!fimc->vid_cap.user_subdev_api) {
1028 mf->code = ff->fmt->mbus_code;
1029 mf->width = pix->width;
1030 mf->height = pix->height;
1031 ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
1032 if (ret)
1033 return ret;
1034
1035 pix->width = mf->width;
1036 pix->height = mf->height;
1037 }
1038
1039 fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
1040
1041 if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
1042 ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
1043 pix->plane_fmt, ff->fmt->memplanes,
1044 true);
1045 if (ret < 0)
1046 return ret;
1047 }
1048
1049 for (i = 0; i < ff->fmt->memplanes; i++) {
1050 ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
1051 ff->payload[i] = pix->plane_fmt[i].sizeimage;
1052 }
1053
1054 set_frame_bounds(ff, pix->width, pix->height);
1055 /* Reset the composition rectangle if not yet configured */
1056 if (!(ctx->state & FIMC_COMPOSE))
1057 set_frame_crop(ff, 0, 0, pix->width, pix->height);
1058
1059 fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
1060
1061 /* Reset cropping and set format at the camera interface input */
1062 if (!fimc->vid_cap.user_subdev_api) {
1063 ctx->s_frame.fmt = s_fmt;
1064 set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
1065 set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
1066 }
1067
1068 return ret;
1069}
1070
1071static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
1072 struct v4l2_format *f)
1073{
1074 struct fimc_dev *fimc = video_drvdata(file);
1075 int ret;
1076
1077 fimc_md_graph_lock(fimc);
1078 mutex_lock(&fimc->lock);
1079 /*
1080 * The graph is walked within __fimc_capture_set_format() to set
1081 * the format at subdevs thus the graph mutex needs to be held at
1082 * this point and acquired before the video mutex, to avoid AB-BA
1083 * deadlock when fimc_md_link_notify() is called by other thread.
1084 * Ideally the graph walking and setting format at the whole pipeline
1085 * should be removed from this driver and handled in userspace only.
1086 */
1087 ret = __fimc_capture_set_format(fimc, f);
1088
1089 mutex_unlock(&fimc->lock);
1090 fimc_md_graph_unlock(fimc);
1091 return ret;
1092}
1093
1094static int fimc_cap_enum_input(struct file *file, void *priv,
1095 struct v4l2_input *i)
1096{
1097 struct fimc_dev *fimc = video_drvdata(file);
1098 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
1099
1100 if (i->index != 0)
1101 return -EINVAL;
1102
1103 i->type = V4L2_INPUT_TYPE_CAMERA;
1104 if (sd)
1105 strlcpy(i->name, sd->name, sizeof(i->name));
1106 return 0;
1107}
1108
1109static int fimc_cap_s_input(struct file *file, void *priv, unsigned int i)
1110{
1111 return i == 0 ? i : -EINVAL;
1112}
1113
1114static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
1115{
1116 *i = 0;
1117 return 0;
1118}
1119
1120/**
1121 * fimc_pipeline_validate - check for formats inconsistencies
1122 * between source and sink pad of each link
1123 *
1124 * Return 0 if all formats match or -EPIPE otherwise.
1125 */
1126static int fimc_pipeline_validate(struct fimc_dev *fimc)
1127{
1128 struct v4l2_subdev_format sink_fmt, src_fmt;
1129 struct fimc_vid_cap *vc = &fimc->vid_cap;
1130 struct v4l2_subdev *sd = &vc->subdev;
1131 struct media_pad *sink_pad, *src_pad;
1132 int i, ret;
1133
1134 while (1) {
1135 /*
1136 * Find current entity sink pad and any remote sink pad linked
1137 * to it. We stop if there is no sink pad in current entity or
1138 * it is not linked to any other remote entity.
1139 */
1140 src_pad = NULL;
1141
1142 for (i = 0; i < sd->entity.num_pads; i++) {
1143 struct media_pad *p = &sd->entity.pads[i];
1144
1145 if (p->flags & MEDIA_PAD_FL_SINK) {
1146 sink_pad = p;
1147 src_pad = media_entity_remote_source(sink_pad);
1148 if (src_pad)
1149 break;
1150 }
1151 }
1152
1153 if (src_pad == NULL ||
1154 media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
1155 break;
1156
1157 /* Don't call FIMC subdev operation to avoid nested locking */
1158 if (sd == &vc->subdev) {
1159 struct fimc_frame *ff = &vc->ctx->s_frame;
1160 sink_fmt.format.width = ff->f_width;
1161 sink_fmt.format.height = ff->f_height;
1162 sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
1163 } else {
1164 sink_fmt.pad = sink_pad->index;
1165 sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1166 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
1167 if (ret < 0 && ret != -ENOIOCTLCMD)
1168 return -EPIPE;
1169 }
1170
1171 /* Retrieve format at the source pad */
1172 sd = media_entity_to_v4l2_subdev(src_pad->entity);
1173 src_fmt.pad = src_pad->index;
1174 src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1175 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
1176 if (ret < 0 && ret != -ENOIOCTLCMD)
1177 return -EPIPE;
1178
1179 if (src_fmt.format.width != sink_fmt.format.width ||
1180 src_fmt.format.height != sink_fmt.format.height ||
1181 src_fmt.format.code != sink_fmt.format.code)
1182 return -EPIPE;
1183
1184 if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
1185 fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
1186 struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
1187 struct fimc_frame *frame = &vc->ctx->d_frame;
1188 unsigned int i;
1189
1190 ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
1191 frame->fmt->memplanes,
1192 false);
1193 if (ret < 0)
1194 return -EPIPE;
1195
1196 for (i = 0; i < frame->fmt->memplanes; i++)
1197 if (frame->payload[i] < plane_fmt[i].sizeimage)
1198 return -EPIPE;
1199 }
1200 }
1201 return 0;
1202}
1203
1204static int fimc_cap_streamon(struct file *file, void *priv,
1205 enum v4l2_buf_type type)
1206{
1207 struct fimc_dev *fimc = video_drvdata(file);
1208 struct fimc_pipeline *p = &fimc->pipeline;
1209 struct fimc_vid_cap *vc = &fimc->vid_cap;
1210 struct media_entity *entity = &vc->vfd.entity;
1211 struct fimc_source_info *si = NULL;
1212 struct v4l2_subdev *sd;
1213 int ret;
1214
1215 if (fimc_capture_active(fimc))
1216 return -EBUSY;
1217
1218 ret = media_entity_pipeline_start(entity, p->m_pipeline);
1219 if (ret < 0)
1220 return ret;
1221
1222 sd = p->subdevs[IDX_SENSOR];
1223 if (sd)
1224 si = v4l2_get_subdev_hostdata(sd);
1225
1226 if (si == NULL) {
1227 ret = -EPIPE;
1228 goto err_p_stop;
1229 }
1230 /*
1231 * Save configuration data related to currently attached image
1232 * sensor or other data source, e.g. FIMC-IS.
1233 */
1234 vc->source_config = *si;
1235
1236 if (vc->input == GRP_ID_FIMC_IS)
1237 vc->source_config.fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
1238
1239 if (vc->user_subdev_api) {
1240 ret = fimc_pipeline_validate(fimc);
1241 if (ret < 0)
1242 goto err_p_stop;
1243 }
1244
1245 ret = vb2_ioctl_streamon(file, priv, type);
1246 if (!ret)
1247 return ret;
1248
1249err_p_stop:
1250 media_entity_pipeline_stop(entity);
1251 return ret;
1252}
1253
1254static int fimc_cap_streamoff(struct file *file, void *priv,
1255 enum v4l2_buf_type type)
1256{
1257 struct fimc_dev *fimc = video_drvdata(file);
1258 int ret;
1259
1260 ret = vb2_ioctl_streamoff(file, priv, type);
1261
1262 if (ret == 0)
1263 media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
1264
1265 return ret;
1266}
1267
1268static int fimc_cap_reqbufs(struct file *file, void *priv,
1269 struct v4l2_requestbuffers *reqbufs)
1270{
1271 struct fimc_dev *fimc = video_drvdata(file);
1272 int ret;
1273
1274 ret = vb2_ioctl_reqbufs(file, priv, reqbufs);
1275
1276 if (!ret)
1277 fimc->vid_cap.reqbufs_count = reqbufs->count;
1278
1279 return ret;
1280}
1281
1282static int fimc_cap_g_selection(struct file *file, void *fh,
1283 struct v4l2_selection *s)
1284{
1285 struct fimc_dev *fimc = video_drvdata(file);
1286 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1287 struct fimc_frame *f = &ctx->s_frame;
1288
1289 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1290 return -EINVAL;
1291
1292 switch (s->target) {
1293 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1294 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1295 f = &ctx->d_frame;
1296 case V4L2_SEL_TGT_CROP_BOUNDS:
1297 case V4L2_SEL_TGT_CROP_DEFAULT:
1298 s->r.left = 0;
1299 s->r.top = 0;
1300 s->r.width = f->o_width;
1301 s->r.height = f->o_height;
1302 return 0;
1303
1304 case V4L2_SEL_TGT_COMPOSE:
1305 f = &ctx->d_frame;
1306 case V4L2_SEL_TGT_CROP:
1307 s->r.left = f->offs_h;
1308 s->r.top = f->offs_v;
1309 s->r.width = f->width;
1310 s->r.height = f->height;
1311 return 0;
1312 }
1313
1314 return -EINVAL;
1315}
1316
1317/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1318static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1319{
1320 if (a->left < b->left || a->top < b->top)
1321 return 0;
1322 if (a->left + a->width > b->left + b->width)
1323 return 0;
1324 if (a->top + a->height > b->top + b->height)
1325 return 0;
1326
1327 return 1;
1328}
1329
1330static int fimc_cap_s_selection(struct file *file, void *fh,
1331 struct v4l2_selection *s)
1332{
1333 struct fimc_dev *fimc = video_drvdata(file);
1334 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1335 struct v4l2_rect rect = s->r;
1336 struct fimc_frame *f;
1337 unsigned long flags;
1338
1339 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1340 return -EINVAL;
1341
1342 if (s->target == V4L2_SEL_TGT_COMPOSE)
1343 f = &ctx->d_frame;
1344 else if (s->target == V4L2_SEL_TGT_CROP)
1345 f = &ctx->s_frame;
1346 else
1347 return -EINVAL;
1348
1349 fimc_capture_try_selection(ctx, &rect, s->target);
1350
1351 if (s->flags & V4L2_SEL_FLAG_LE &&
1352 !enclosed_rectangle(&rect, &s->r))
1353 return -ERANGE;
1354
1355 if (s->flags & V4L2_SEL_FLAG_GE &&
1356 !enclosed_rectangle(&s->r, &rect))
1357 return -ERANGE;
1358
1359 s->r = rect;
1360 spin_lock_irqsave(&fimc->slock, flags);
1361 set_frame_crop(f, s->r.left, s->r.top, s->r.width,
1362 s->r.height);
1363 spin_unlock_irqrestore(&fimc->slock, flags);
1364
1365 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1366 return 0;
1367}
1368
1369static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
1370 .vidioc_querycap = fimc_vidioc_querycap_capture,
1371
1372 .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane,
1373 .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
1374 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
1375 .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
1376
1377 .vidioc_reqbufs = fimc_cap_reqbufs,
1378 .vidioc_querybuf = vb2_ioctl_querybuf,
1379 .vidioc_qbuf = vb2_ioctl_qbuf,
1380 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1381 .vidioc_expbuf = vb2_ioctl_expbuf,
1382 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1383 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1384
1385 .vidioc_streamon = fimc_cap_streamon,
1386 .vidioc_streamoff = fimc_cap_streamoff,
1387
1388 .vidioc_g_selection = fimc_cap_g_selection,
1389 .vidioc_s_selection = fimc_cap_s_selection,
1390
1391 .vidioc_enum_input = fimc_cap_enum_input,
1392 .vidioc_s_input = fimc_cap_s_input,
1393 .vidioc_g_input = fimc_cap_g_input,
1394};
1395
1396/* Capture subdev media entity operations */
1397static int fimc_link_setup(struct media_entity *entity,
1398 const struct media_pad *local,
1399 const struct media_pad *remote, u32 flags)
1400{
1401 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1402 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1403
1404 if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
1405 return -EINVAL;
1406
1407 if (WARN_ON(fimc == NULL))
1408 return 0;
1409
1410 dbg("%s --> %s, flags: 0x%x. input: 0x%x",
1411 local->entity->name, remote->entity->name, flags,
1412 fimc->vid_cap.input);
1413
1414 if (flags & MEDIA_LNK_FL_ENABLED) {
1415 if (fimc->vid_cap.input != 0)
1416 return -EBUSY;
1417 fimc->vid_cap.input = sd->grp_id;
1418 return 0;
1419 }
1420
1421 fimc->vid_cap.input = 0;
1422 return 0;
1423}
1424
1425static const struct media_entity_operations fimc_sd_media_ops = {
1426 .link_setup = fimc_link_setup,
1427};
1428
1429/**
1430 * fimc_sensor_notify - v4l2_device notification from a sensor subdev
1431 * @sd: pointer to a subdev generating the notification
1432 * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
1433 * @arg: pointer to an u32 type integer that stores the frame payload value
1434 *
1435 * The End Of Frame notification sent by sensor subdev in its still capture
1436 * mode. If there is only a single VSYNC generated by the sensor at the
1437 * beginning of a frame transmission, FIMC does not issue the LastIrq
1438 * (end of frame) interrupt. And this notification is used to complete the
1439 * frame capture and returning a buffer to user-space. Subdev drivers should
1440 * call this notification from their last 'End of frame capture' interrupt.
1441 */
1442void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1443 void *arg)
1444{
1445 struct fimc_sensor_info *sensor;
1446 struct fimc_vid_buffer *buf;
1447 struct fimc_md *fmd;
1448 struct fimc_dev *fimc;
1449 unsigned long flags;
1450
1451 if (sd == NULL)
1452 return;
1453
1454 sensor = v4l2_get_subdev_hostdata(sd);
1455 fmd = entity_to_fimc_mdev(&sd->entity);
1456
1457 spin_lock_irqsave(&fmd->slock, flags);
1458 fimc = sensor ? sensor->host : NULL;
1459
1460 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
1461 test_bit(ST_CAPT_PEND, &fimc->state)) {
1462 unsigned long irq_flags;
1463 spin_lock_irqsave(&fimc->slock, irq_flags);
1464 if (!list_empty(&fimc->vid_cap.active_buf_q)) {
1465 buf = list_entry(fimc->vid_cap.active_buf_q.next,
1466 struct fimc_vid_buffer, list);
1467 vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
1468 }
1469 fimc_capture_irq_handler(fimc, 1);
1470 fimc_deactivate_capture(fimc);
1471 spin_unlock_irqrestore(&fimc->slock, irq_flags);
1472 }
1473 spin_unlock_irqrestore(&fmd->slock, flags);
1474}
1475
1476static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1477 struct v4l2_subdev_fh *fh,
1478 struct v4l2_subdev_mbus_code_enum *code)
1479{
1480 struct fimc_fmt *fmt;
1481
1482 fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
1483 if (!fmt)
1484 return -EINVAL;
1485 code->code = fmt->mbus_code;
1486 return 0;
1487}
1488
1489static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
1490 struct v4l2_subdev_fh *fh,
1491 struct v4l2_subdev_format *fmt)
1492{
1493 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1494 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1495 struct fimc_frame *ff = &ctx->s_frame;
1496 struct v4l2_mbus_framefmt *mf;
1497
1498 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1499 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1500 fmt->format = *mf;
1501 return 0;
1502 }
1503
1504 mf = &fmt->format;
1505 mutex_lock(&fimc->lock);
1506
1507 switch (fmt->pad) {
1508 case FIMC_SD_PAD_SOURCE:
1509 if (!WARN_ON(ff->fmt == NULL))
1510 mf->code = ff->fmt->mbus_code;
1511 /* Sink pads crop rectangle size */
1512 mf->width = ff->width;
1513 mf->height = ff->height;
1514 break;
1515 case FIMC_SD_PAD_SINK_FIFO:
1516 *mf = fimc->vid_cap.wb_fmt;
1517 break;
1518 case FIMC_SD_PAD_SINK_CAM:
1519 default:
1520 *mf = fimc->vid_cap.ci_fmt;
1521 break;
1522 }
1523
1524 mutex_unlock(&fimc->lock);
1525 mf->colorspace = V4L2_COLORSPACE_JPEG;
1526
1527 return 0;
1528}
1529
1530static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1531 struct v4l2_subdev_fh *fh,
1532 struct v4l2_subdev_format *fmt)
1533{
1534 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1535 struct v4l2_mbus_framefmt *mf = &fmt->format;
1536 struct fimc_vid_cap *vc = &fimc->vid_cap;
1537 struct fimc_ctx *ctx = vc->ctx;
1538 struct fimc_frame *ff;
1539 struct fimc_fmt *ffmt;
1540
1541 dbg("pad%d: code: 0x%x, %dx%d",
1542 fmt->pad, mf->code, mf->width, mf->height);
1543
1544 if (fmt->pad == FIMC_SD_PAD_SOURCE && vb2_is_busy(&vc->vbq))
1545 return -EBUSY;
1546
1547 mutex_lock(&fimc->lock);
1548 ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
1549 &mf->code, NULL, fmt->pad);
1550 mutex_unlock(&fimc->lock);
1551 mf->colorspace = V4L2_COLORSPACE_JPEG;
1552
1553 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1554 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1555 *mf = fmt->format;
1556 return 0;
1557 }
1558 /* There must be a bug in the driver if this happens */
1559 if (WARN_ON(ffmt == NULL))
1560 return -EINVAL;
1561
1562 /* Update RGB Alpha control state and value range */
1563 fimc_alpha_ctrl_update(ctx);
1564
1565 fimc_capture_mark_jpeg_xfer(ctx, ffmt->color);
1566 if (fmt->pad == FIMC_SD_PAD_SOURCE) {
1567 ff = &ctx->d_frame;
1568 /* Sink pads crop rectangle size */
1569 mf->width = ctx->s_frame.width;
1570 mf->height = ctx->s_frame.height;
1571 } else {
1572 ff = &ctx->s_frame;
1573 }
1574
1575 mutex_lock(&fimc->lock);
1576 set_frame_bounds(ff, mf->width, mf->height);
1577
1578 if (fmt->pad == FIMC_SD_PAD_SINK_FIFO)
1579 vc->wb_fmt = *mf;
1580 else if (fmt->pad == FIMC_SD_PAD_SINK_CAM)
1581 vc->ci_fmt = *mf;
1582
1583 ff->fmt = ffmt;
1584
1585 /* Reset the crop rectangle if required. */
1586 if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE)))
1587 set_frame_crop(ff, 0, 0, mf->width, mf->height);
1588
1589 if (fmt->pad != FIMC_SD_PAD_SOURCE)
1590 ctx->state &= ~FIMC_COMPOSE;
1591
1592 mutex_unlock(&fimc->lock);
1593 return 0;
1594}
1595
1596static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1597 struct v4l2_subdev_fh *fh,
1598 struct v4l2_subdev_selection *sel)
1599{
1600 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1601 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1602 struct fimc_frame *f = &ctx->s_frame;
1603 struct v4l2_rect *r = &sel->r;
1604 struct v4l2_rect *try_sel;
1605
1606 if (sel->pad == FIMC_SD_PAD_SOURCE)
1607 return -EINVAL;
1608
1609 mutex_lock(&fimc->lock);
1610
1611 switch (sel->target) {
1612 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1613 f = &ctx->d_frame;
1614 case V4L2_SEL_TGT_CROP_BOUNDS:
1615 r->width = f->o_width;
1616 r->height = f->o_height;
1617 r->left = 0;
1618 r->top = 0;
1619 mutex_unlock(&fimc->lock);
1620 return 0;
1621
1622 case V4L2_SEL_TGT_CROP:
1623 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1624 break;
1625 case V4L2_SEL_TGT_COMPOSE:
1626 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1627 f = &ctx->d_frame;
1628 break;
1629 default:
1630 mutex_unlock(&fimc->lock);
1631 return -EINVAL;
1632 }
1633
1634 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1635 sel->r = *try_sel;
1636 } else {
1637 r->left = f->offs_h;
1638 r->top = f->offs_v;
1639 r->width = f->width;
1640 r->height = f->height;
1641 }
1642
1643 dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
1644 sel->pad, r->left, r->top, r->width, r->height,
1645 f->f_width, f->f_height);
1646
1647 mutex_unlock(&fimc->lock);
1648 return 0;
1649}
1650
1651static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
1652 struct v4l2_subdev_fh *fh,
1653 struct v4l2_subdev_selection *sel)
1654{
1655 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1656 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1657 struct fimc_frame *f = &ctx->s_frame;
1658 struct v4l2_rect *r = &sel->r;
1659 struct v4l2_rect *try_sel;
1660 unsigned long flags;
1661
1662 if (sel->pad == FIMC_SD_PAD_SOURCE)
1663 return -EINVAL;
1664
1665 mutex_lock(&fimc->lock);
1666 fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP);
1667
1668 switch (sel->target) {
1669 case V4L2_SEL_TGT_CROP:
1670 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1671 break;
1672 case V4L2_SEL_TGT_COMPOSE:
1673 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1674 f = &ctx->d_frame;
1675 break;
1676 default:
1677 mutex_unlock(&fimc->lock);
1678 return -EINVAL;
1679 }
1680
1681 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1682 *try_sel = sel->r;
1683 } else {
1684 spin_lock_irqsave(&fimc->slock, flags);
1685 set_frame_crop(f, r->left, r->top, r->width, r->height);
1686 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1687 if (sel->target == V4L2_SEL_TGT_COMPOSE)
1688 ctx->state |= FIMC_COMPOSE;
1689 spin_unlock_irqrestore(&fimc->slock, flags);
1690 }
1691
1692 dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top,
1693 r->width, r->height);
1694
1695 mutex_unlock(&fimc->lock);
1696 return 0;
1697}
1698
1699static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
1700 .enum_mbus_code = fimc_subdev_enum_mbus_code,
1701 .get_selection = fimc_subdev_get_selection,
1702 .set_selection = fimc_subdev_set_selection,
1703 .get_fmt = fimc_subdev_get_fmt,
1704 .set_fmt = fimc_subdev_set_fmt,
1705};
1706
1707static struct v4l2_subdev_ops fimc_subdev_ops = {
1708 .pad = &fimc_subdev_pad_ops,
1709};
1710
1711/* Set default format at the sensor and host interface */
1712static int fimc_capture_set_default_format(struct fimc_dev *fimc)
1713{
1714 struct v4l2_format fmt = {
1715 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1716 .fmt.pix_mp = {
1717 .width = 640,
1718 .height = 480,
1719 .pixelformat = V4L2_PIX_FMT_YUYV,
1720 .field = V4L2_FIELD_NONE,
1721 .colorspace = V4L2_COLORSPACE_JPEG,
1722 },
1723 };
1724
1725 return __fimc_capture_set_format(fimc, &fmt);
1726}
1727
1728/* fimc->lock must be already initialized */
1729static int fimc_register_capture_device(struct fimc_dev *fimc,
1730 struct v4l2_device *v4l2_dev)
1731{
1732 struct video_device *vfd = &fimc->vid_cap.vfd;
1733 struct vb2_queue *q = &fimc->vid_cap.vbq;
1734 struct fimc_ctx *ctx;
1735 struct fimc_vid_cap *vid_cap;
1736 int ret = -ENOMEM;
1737
1738 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1739 if (!ctx)
1740 return -ENOMEM;
1741
1742 ctx->fimc_dev = fimc;
1743 ctx->in_path = FIMC_IO_CAMERA;
1744 ctx->out_path = FIMC_IO_DMA;
1745 ctx->state = FIMC_CTX_CAP;
1746 ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
1747 ctx->d_frame.fmt = ctx->s_frame.fmt;
1748
1749 memset(vfd, 0, sizeof(*vfd));
1750 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
1751
1752 vfd->fops = &fimc_capture_fops;
1753 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
1754 vfd->v4l2_dev = v4l2_dev;
1755 vfd->minor = -1;
1756 vfd->release = video_device_release_empty;
1757 vfd->queue = q;
1758 vfd->lock = &fimc->lock;
1759
1760 video_set_drvdata(vfd, fimc);
1761 vid_cap = &fimc->vid_cap;
1762 vid_cap->active_buf_cnt = 0;
1763 vid_cap->reqbufs_count = 0;
1764 vid_cap->ctx = ctx;
1765
1766 INIT_LIST_HEAD(&vid_cap->pending_buf_q);
1767 INIT_LIST_HEAD(&vid_cap->active_buf_q);
1768
1769 memset(q, 0, sizeof(*q));
1770 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1771 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1772 q->drv_priv = ctx;
1773 q->ops = &fimc_capture_qops;
1774 q->mem_ops = &vb2_dma_contig_memops;
1775 q->buf_struct_size = sizeof(struct fimc_vid_buffer);
1776 q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1777 q->lock = &fimc->lock;
1778
1779 ret = vb2_queue_init(q);
1780 if (ret)
1781 goto err_ent;
1782
1783 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
1784 ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
1785 if (ret)
1786 goto err_ent;
1787 /*
1788 * For proper order of acquiring/releasing the video
1789 * and the graph mutex.
1790 */
1791 v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
1792 v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
1793
1794 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1795 if (ret)
1796 goto err_vd;
1797
1798 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
1799 vfd->name, video_device_node_name(vfd));
1800
1801 vfd->ctrl_handler = &ctx->ctrls.handler;
1802 return 0;
1803
1804err_vd:
1805 media_entity_cleanup(&vfd->entity);
1806err_ent:
1807 kfree(ctx);
1808 return ret;
1809}
1810
1811static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
1812{
1813 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1814 int ret;
1815
1816 if (fimc == NULL)
1817 return -ENXIO;
1818
1819 ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
1820 if (ret)
1821 return ret;
1822
1823 fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
1824
1825 ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
1826 if (ret) {
1827 fimc_unregister_m2m_device(fimc);
1828 fimc->pipeline_ops = NULL;
1829 }
1830
1831 return ret;
1832}
1833
1834static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
1835{
1836 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1837
1838 if (fimc == NULL)
1839 return;
1840
1841 fimc_unregister_m2m_device(fimc);
1842
1843 if (video_is_registered(&fimc->vid_cap.vfd)) {
1844 video_unregister_device(&fimc->vid_cap.vfd);
1845 media_entity_cleanup(&fimc->vid_cap.vfd.entity);
1846 fimc->pipeline_ops = NULL;
1847 }
1848 kfree(fimc->vid_cap.ctx);
1849 fimc->vid_cap.ctx = NULL;
1850}
1851
1852static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
1853 .registered = fimc_capture_subdev_registered,
1854 .unregistered = fimc_capture_subdev_unregistered,
1855};
1856
1857int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
1858{
1859 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1860 int ret;
1861
1862 v4l2_subdev_init(sd, &fimc_subdev_ops);
1863 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1864 snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->id);
1865
1866 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK;
1867 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
1868 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1869 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1870 fimc->vid_cap.sd_pads, 0);
1871 if (ret)
1872 return ret;
1873
1874 sd->entity.ops = &fimc_sd_media_ops;
1875 sd->internal_ops = &fimc_capture_sd_internal_ops;
1876 v4l2_set_subdevdata(sd, fimc);
1877 return 0;
1878}
1879
1880void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
1881{
1882 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1883
1884 v4l2_device_unregister_subdev(sd);
1885 media_entity_cleanup(&sd->entity);
1886 v4l2_set_subdevdata(sd, NULL);
1887}