Lines Matching +full:fimc +full:- +full:is
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-ioctl.h>
23 #include <media/v4l2-mem2mem.h>
24 #include <media/v4l2-rect.h>
25 #include <media/videobuf2-v4l2.h>
26 #include <media/videobuf2-dma-contig.h>
29 #include "fimc-core.h"
30 #include "fimc-reg.h"
31 #include "media-dev.h"
33 static int fimc_capture_hw_init(struct fimc_dev *fimc) in fimc_capture_hw_init() argument
35 struct fimc_source_info *si = &fimc->vid_cap.source_config; in fimc_capture_hw_init()
36 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_capture_hw_init()
40 if (ctx == NULL || ctx->s_frame.fmt == NULL) in fimc_capture_hw_init()
41 return -EINVAL; in fimc_capture_hw_init()
43 if (si->fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) { in fimc_capture_hw_init()
44 ret = fimc_hw_camblk_cfg_writeback(fimc); in fimc_capture_hw_init()
49 spin_lock_irqsave(&fimc->slock, flags); in fimc_capture_hw_init()
50 fimc_prepare_dma_offset(ctx, &ctx->d_frame); in fimc_capture_hw_init()
53 fimc_hw_set_camera_polarity(fimc, si); in fimc_capture_hw_init()
54 fimc_hw_set_camera_type(fimc, si); in fimc_capture_hw_init()
55 fimc_hw_set_camera_source(fimc, si); in fimc_capture_hw_init()
56 fimc_hw_set_camera_offset(fimc, &ctx->s_frame); in fimc_capture_hw_init()
68 if (fimc->drv_data->alpha_color) in fimc_capture_hw_init()
70 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state); in fimc_capture_hw_init()
72 spin_unlock_irqrestore(&fimc->slock, flags); in fimc_capture_hw_init()
77 * Reinitialize the driver so it is ready to start the streaming again.
78 * Set fimc->state to indicate stream off and the hardware shut down state.
79 * If not suspending (@suspend is false), return any buffers to videobuf2.
81 * can be re-spun when the device is being resumed. Also perform FIMC
84 static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) in fimc_capture_state_cleanup() argument
86 struct fimc_vid_cap *cap = &fimc->vid_cap; in fimc_capture_state_cleanup()
91 spin_lock_irqsave(&fimc->slock, flags); in fimc_capture_state_cleanup()
92 streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM); in fimc_capture_state_cleanup()
94 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT | in fimc_capture_state_cleanup()
97 fimc->state |= (1 << ST_CAPT_SUSPENDED); in fimc_capture_state_cleanup()
99 fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED); in fimc_capture_state_cleanup()
102 while (!suspend && !list_empty(&cap->pending_buf_q)) { in fimc_capture_state_cleanup()
104 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in fimc_capture_state_cleanup()
107 while (!list_empty(&cap->active_buf_q)) { in fimc_capture_state_cleanup()
112 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in fimc_capture_state_cleanup()
115 fimc_hw_reset(fimc); in fimc_capture_state_cleanup()
116 cap->buf_index = 0; in fimc_capture_state_cleanup()
118 spin_unlock_irqrestore(&fimc->slock, flags); in fimc_capture_state_cleanup()
121 return fimc_pipeline_call(&cap->ve, set_stream, 0); in fimc_capture_state_cleanup()
126 static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend) in fimc_stop_capture() argument
130 if (!fimc_capture_active(fimc)) in fimc_stop_capture()
133 spin_lock_irqsave(&fimc->slock, flags); in fimc_stop_capture()
134 set_bit(ST_CAPT_SHUT, &fimc->state); in fimc_stop_capture()
135 fimc_deactivate_capture(fimc); in fimc_stop_capture()
136 spin_unlock_irqrestore(&fimc->slock, flags); in fimc_stop_capture()
138 wait_event_timeout(fimc->irq_queue, in fimc_stop_capture()
139 !test_bit(ST_CAPT_SHUT, &fimc->state), in fimc_stop_capture()
142 return fimc_capture_state_cleanup(fimc, suspend); in fimc_stop_capture()
146 * fimc_capture_config_update - apply the camera interface configuration
147 * @ctx: FIMC capture context
149 * To be called from within the interrupt handler with fimc.slock
155 struct fimc_dev *fimc = ctx->fimc_dev; in fimc_capture_config_update() local
158 fimc_hw_set_camera_offset(fimc, &ctx->s_frame); in fimc_capture_config_update()
169 fimc_prepare_dma_offset(ctx, &ctx->d_frame); in fimc_capture_config_update()
171 if (fimc->drv_data->alpha_color) in fimc_capture_config_update()
174 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state); in fimc_capture_config_update()
178 void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf) in fimc_capture_irq_handler() argument
180 struct fimc_vid_cap *cap = &fimc->vid_cap; in fimc_capture_irq_handler()
181 struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe); in fimc_capture_irq_handler()
182 struct v4l2_subdev *csis = p->subdevs[IDX_CSIS]; in fimc_capture_irq_handler()
183 const struct fimc_frame *f = &cap->ctx->d_frame; in fimc_capture_irq_handler()
186 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { in fimc_capture_irq_handler()
187 wake_up(&fimc->irq_queue); in fimc_capture_irq_handler()
191 if (!list_empty(&cap->active_buf_q) && in fimc_capture_irq_handler()
192 test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) { in fimc_capture_irq_handler()
195 v_buf->vb.vb2_buf.timestamp = ktime_get_ns(); in fimc_capture_irq_handler()
196 v_buf->vb.sequence = cap->frame_count++; in fimc_capture_irq_handler()
198 vb2_buffer_done(&v_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in fimc_capture_irq_handler()
201 if (!list_empty(&cap->pending_buf_q)) { in fimc_capture_irq_handler()
204 fimc_hw_set_output_addr(fimc, &v_buf->addr, cap->buf_index); in fimc_capture_irq_handler()
205 v_buf->index = cap->buf_index; in fimc_capture_irq_handler()
211 fimc_hw_get_frame_index(fimc), v_buf->index); in fimc_capture_irq_handler()
213 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) in fimc_capture_irq_handler()
214 cap->buf_index = 0; in fimc_capture_irq_handler()
217 * Set up a buffer at MIPI-CSIS if current image format in fimc_capture_irq_handler()
220 if (f->fmt->mdataplanes && !list_empty(&cap->active_buf_q)) { in fimc_capture_irq_handler()
221 unsigned int plane = ffs(f->fmt->mdataplanes) - 1; in fimc_capture_irq_handler()
222 unsigned int size = f->payload[plane]; in fimc_capture_irq_handler()
223 s32 index = fimc_hw_get_frame_index(fimc); in fimc_capture_irq_handler()
226 list_for_each_entry(v_buf, &cap->active_buf_q, list) { in fimc_capture_irq_handler()
227 if (v_buf->index != index) in fimc_capture_irq_handler()
229 vaddr = vb2_plane_vaddr(&v_buf->vb.vb2_buf, plane); in fimc_capture_irq_handler()
236 if (cap->active_buf_cnt == 0) { in fimc_capture_irq_handler()
238 clear_bit(ST_CAPT_RUN, &fimc->state); in fimc_capture_irq_handler()
240 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) in fimc_capture_irq_handler()
241 cap->buf_index = 0; in fimc_capture_irq_handler()
243 set_bit(ST_CAPT_RUN, &fimc->state); in fimc_capture_irq_handler()
246 if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state)) in fimc_capture_irq_handler()
247 fimc_capture_config_update(cap->ctx); in fimc_capture_irq_handler()
249 if (cap->active_buf_cnt == 1) { in fimc_capture_irq_handler()
250 fimc_deactivate_capture(fimc); in fimc_capture_irq_handler()
251 clear_bit(ST_CAPT_STREAM, &fimc->state); in fimc_capture_irq_handler()
255 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt); in fimc_capture_irq_handler()
261 struct fimc_ctx *ctx = q->drv_priv; in start_streaming()
262 struct fimc_dev *fimc = ctx->fimc_dev; in start_streaming() local
263 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; in start_streaming()
267 vid_cap->frame_count = 0; in start_streaming()
269 ret = fimc_capture_hw_init(fimc); in start_streaming()
271 fimc_capture_state_cleanup(fimc, false); in start_streaming()
275 set_bit(ST_CAPT_PEND, &fimc->state); in start_streaming()
277 min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1; in start_streaming()
279 if (vid_cap->active_buf_cnt >= min_bufs && in start_streaming()
280 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) { in start_streaming()
283 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) in start_streaming()
284 return fimc_pipeline_call(&vid_cap->ve, set_stream, 1); in start_streaming()
292 struct fimc_ctx *ctx = q->drv_priv; in stop_streaming()
293 struct fimc_dev *fimc = ctx->fimc_dev; in stop_streaming() local
295 if (!fimc_capture_active(fimc)) in stop_streaming()
298 fimc_stop_capture(fimc, false); in stop_streaming()
301 int fimc_capture_suspend(struct fimc_dev *fimc) in fimc_capture_suspend() argument
303 bool suspend = fimc_capture_busy(fimc); in fimc_capture_suspend()
305 int ret = fimc_stop_capture(fimc, suspend); in fimc_capture_suspend()
308 return fimc_pipeline_call(&fimc->vid_cap.ve, close); in fimc_capture_suspend()
313 int fimc_capture_resume(struct fimc_dev *fimc) in fimc_capture_resume() argument
315 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; in fimc_capture_resume()
316 struct exynos_video_entity *ve = &vid_cap->ve; in fimc_capture_resume()
320 if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state)) in fimc_capture_resume()
323 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); in fimc_capture_resume()
324 vid_cap->buf_index = 0; in fimc_capture_resume()
325 fimc_pipeline_call(ve, open, &ve->vdev.entity, false); in fimc_capture_resume()
326 fimc_capture_hw_init(fimc); in fimc_capture_resume()
328 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); in fimc_capture_resume()
330 for (i = 0; i < vid_cap->reqbufs_count; i++) { in fimc_capture_resume()
331 if (list_empty(&vid_cap->pending_buf_q)) in fimc_capture_resume()
334 buffer_queue(&buf->vb.vb2_buf); in fimc_capture_resume()
344 struct fimc_ctx *ctx = vq->drv_priv; in queue_setup()
345 const struct fimc_frame *frame = &ctx->d_frame; in queue_setup()
346 const struct fimc_fmt *fmt = frame->fmt; in queue_setup()
347 unsigned long wh = frame->f_width * frame->f_height; in queue_setup()
351 return -EINVAL; in queue_setup()
354 if (*num_planes != fmt->memplanes) in queue_setup()
355 return -EINVAL; in queue_setup()
357 if (sizes[i] < (wh * fmt->depth[i]) / 8) in queue_setup()
358 return -EINVAL; in queue_setup()
362 *num_planes = fmt->memplanes; in queue_setup()
364 for (i = 0; i < fmt->memplanes; i++) { in queue_setup()
365 unsigned int size = (wh * fmt->depth[i]) / 8; in queue_setup()
367 if (fimc_fmt_is_user_defined(fmt->color)) in queue_setup()
368 sizes[i] = frame->payload[i]; in queue_setup()
370 sizes[i] = max_t(u32, size, frame->payload[i]); in queue_setup()
378 struct vb2_queue *vq = vb->vb2_queue; in buffer_prepare()
379 struct fimc_ctx *ctx = vq->drv_priv; in buffer_prepare()
382 if (ctx->d_frame.fmt == NULL) in buffer_prepare()
383 return -EINVAL; in buffer_prepare()
385 for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) { in buffer_prepare()
386 unsigned long size = ctx->d_frame.payload[i]; in buffer_prepare()
389 v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev, in buffer_prepare()
392 return -EINVAL; in buffer_prepare()
405 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in buffer_queue()
406 struct fimc_dev *fimc = ctx->fimc_dev; in buffer_queue() local
407 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; in buffer_queue()
408 struct exynos_video_entity *ve = &vid_cap->ve; in buffer_queue()
412 spin_lock_irqsave(&fimc->slock, flags); in buffer_queue()
413 fimc_prepare_addr(ctx, &buf->vb.vb2_buf, &ctx->d_frame, &buf->addr); in buffer_queue()
415 if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) && in buffer_queue()
416 !test_bit(ST_CAPT_STREAM, &fimc->state) && in buffer_queue()
417 vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) { in buffer_queue()
419 int buf_id = (vid_cap->reqbufs_count == 1) ? -1 : in buffer_queue()
420 vid_cap->buf_index; in buffer_queue()
422 fimc_hw_set_output_addr(fimc, &buf->addr, buf_id); in buffer_queue()
423 buf->index = vid_cap->buf_index; in buffer_queue()
426 if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS) in buffer_queue()
427 vid_cap->buf_index = 0; in buffer_queue()
432 min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1; in buffer_queue()
435 if (vb2_is_streaming(&vid_cap->vbq) && in buffer_queue()
436 vid_cap->active_buf_cnt >= min_bufs && in buffer_queue()
437 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) { in buffer_queue()
441 spin_unlock_irqrestore(&fimc->slock, flags); in buffer_queue()
443 if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) in buffer_queue()
448 v4l2_err(&ve->vdev, "stream on failed: %d\n", ret); in buffer_queue()
451 spin_unlock_irqrestore(&fimc->slock, flags); in buffer_queue()
464 static int fimc_capture_set_default_format(struct fimc_dev *fimc);
468 struct fimc_dev *fimc = video_drvdata(file); in fimc_capture_open() local
469 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_capture_open()
470 struct exynos_video_entity *ve = &vc->ve; in fimc_capture_open()
471 int ret = -EBUSY; in fimc_capture_open()
473 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); in fimc_capture_open()
475 mutex_lock(&fimc->lock); in fimc_capture_open()
477 if (fimc_m2m_active(fimc)) in fimc_capture_open()
480 set_bit(ST_CAPT_BUSY, &fimc->state); in fimc_capture_open()
481 ret = pm_runtime_resume_and_get(&fimc->pdev->dev); in fimc_capture_open()
487 pm_runtime_put_sync(&fimc->pdev->dev); in fimc_capture_open()
494 ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true); in fimc_capture_open()
497 ve->vdev.entity.use_count++; in fimc_capture_open()
502 ret = fimc_capture_set_default_format(fimc); in fimc_capture_open()
505 clear_bit(ST_CAPT_BUSY, &fimc->state); in fimc_capture_open()
506 pm_runtime_put_sync(&fimc->pdev->dev); in fimc_capture_open()
511 mutex_unlock(&fimc->lock); in fimc_capture_open()
517 struct fimc_dev *fimc = video_drvdata(file); in fimc_capture_release() local
518 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_capture_release()
522 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); in fimc_capture_release()
524 mutex_lock(&fimc->lock); in fimc_capture_release()
526 if (close && vc->streaming) { in fimc_capture_release()
527 video_device_pipeline_stop(&vc->ve.vdev); in fimc_capture_release()
528 vc->streaming = false; in fimc_capture_release()
534 clear_bit(ST_CAPT_BUSY, &fimc->state); in fimc_capture_release()
535 fimc_pipeline_call(&vc->ve, close); in fimc_capture_release()
536 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); in fimc_capture_release()
538 fimc_md_graph_lock(&vc->ve); in fimc_capture_release()
539 vc->ve.vdev.entity.use_count--; in fimc_capture_release()
540 fimc_md_graph_unlock(&vc->ve); in fimc_capture_release()
543 pm_runtime_put_sync(&fimc->pdev->dev); in fimc_capture_release()
544 mutex_unlock(&fimc->lock); in fimc_capture_release()
566 bool rotation = ctx->rotation == 90 || ctx->rotation == 270; in fimc_capture_try_format()
567 struct fimc_dev *fimc = ctx->fimc_dev; in fimc_capture_try_format() local
568 const struct fimc_variant *var = fimc->variant; in fimc_capture_try_format()
569 const struct fimc_pix_limit *pl = var->pix_limit; in fimc_capture_try_format()
570 const struct fimc_frame *dst = &ctx->d_frame; in fimc_capture_try_format()
575 /* Conversion from/to JPEG or User Defined format is not supported */ in fimc_capture_try_format()
576 if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE && in fimc_capture_try_format()
577 fimc_fmt_is_user_defined(ctx->s_frame.fmt->color)) in fimc_capture_try_format()
578 *code = ctx->s_frame.fmt->mbus_code; in fimc_capture_try_format()
591 *code = ffmt->mbus_code; in fimc_capture_try_format()
593 *fourcc = ffmt->fourcc; in fimc_capture_try_format()
596 max_w = fimc_fmt_is_user_defined(ffmt->color) ? in fimc_capture_try_format()
597 pl->scaler_dis_w : pl->scaler_en_w; in fimc_capture_try_format()
602 fimc_fmt_is_user_defined(ffmt->color) ? in fimc_capture_try_format()
608 if (fimc_fmt_is_user_defined(ffmt->color)) { in fimc_capture_try_format()
609 *width = ctx->s_frame.f_width; in fimc_capture_try_format()
610 *height = ctx->s_frame.f_height; in fimc_capture_try_format()
614 max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; in fimc_capture_try_format()
615 if (ctx->state & FIMC_COMPOSE) { in fimc_capture_try_format()
616 min_w = dst->offs_h + dst->width; in fimc_capture_try_format()
617 min_h = dst->offs_v + dst->height; in fimc_capture_try_format()
619 min_w = var->min_out_pixsize; in fimc_capture_try_format()
620 min_h = var->min_out_pixsize; in fimc_capture_try_format()
622 if (var->min_vsize_align == 1 && !rotation) in fimc_capture_try_format()
623 align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; in fimc_capture_try_format()
627 ffs(var->min_out_pixsize) - 1, in fimc_capture_try_format()
634 dst->f_width, dst->f_height); in fimc_capture_try_format()
643 bool rotate = ctx->rotation == 90 || ctx->rotation == 270; in fimc_capture_try_selection()
644 struct fimc_dev *fimc = ctx->fimc_dev; in fimc_capture_try_selection() local
645 const struct fimc_variant *var = fimc->variant; in fimc_capture_try_selection()
646 const struct fimc_pix_limit *pl = var->pix_limit; in fimc_capture_try_selection()
647 const struct fimc_frame *sink = &ctx->s_frame; in fimc_capture_try_selection()
652 /* In JPEG transparent transfer mode cropping is not supported */ in fimc_capture_try_selection()
653 if (fimc_fmt_is_user_defined(ctx->d_frame.fmt->color)) { in fimc_capture_try_selection()
654 r->width = sink->f_width; in fimc_capture_try_selection()
655 r->height = sink->f_height; in fimc_capture_try_selection()
656 r->left = r->top = 0; in fimc_capture_try_selection()
660 u32 tmp_min_h = ffs(sink->width) - 3; in fimc_capture_try_selection()
661 u32 tmp_min_v = ffs(sink->height) - 1; in fimc_capture_try_selection()
663 if (ctx->rotation != 90 && ctx->rotation != 270) in fimc_capture_try_selection()
667 min_sz = var->min_out_pixsize; in fimc_capture_try_selection()
669 u32 depth = fimc_get_format_depth(sink->fmt); in fimc_capture_try_selection()
671 min_sz = var->min_inp_pixsize; in fimc_capture_try_selection()
677 * - it must fit in the sink pad format rectangle (f_width/f_height); in fimc_capture_try_selection()
678 * - maximum downscaling ratio is 64; in fimc_capture_try_selection()
679 * - maximum crop size depends if the rotator is used or not; in fimc_capture_try_selection()
680 * - the sink pad format width/height must be 4 multiple of the in fimc_capture_try_selection()
682 * the prescaler ratio is returned by fimc_get_scaler_factor(). in fimc_capture_try_selection()
685 rotate ? pl->out_rot_en_w : pl->out_rot_dis_w, in fimc_capture_try_selection()
686 rotate ? sink->f_height : sink->f_width); in fimc_capture_try_selection()
687 max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height); in fimc_capture_try_selection()
690 min_w = min_t(u32, max_w, sink->f_width / max_sc_h); in fimc_capture_try_selection()
691 min_h = min_t(u32, max_h, sink->f_height / max_sc_v); in fimc_capture_try_selection()
697 v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1, in fimc_capture_try_selection()
698 &r->height, min_h, max_h, align_h, in fimc_capture_try_selection()
700 /* Adjust left/top if crop/compose rectangle is out of bounds */ in fimc_capture_try_selection()
701 r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width); in fimc_capture_try_selection()
702 r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height); in fimc_capture_try_selection()
703 r->left = round_down(r->left, var->hor_offs_align); in fimc_capture_try_selection()
706 target, r->left, r->top, r->width, r->height, in fimc_capture_try_selection()
707 sink->f_width, sink->f_height); in fimc_capture_try_selection()
716 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_querycap() local
718 __fimc_vidioc_querycap(&fimc->pdev->dev, cap); in fimc_cap_querycap()
728 f->index); in fimc_cap_enum_fmt()
730 return -EINVAL; in fimc_cap_enum_fmt()
731 f->pixelformat = fmt->fourcc; in fimc_cap_enum_fmt()
737 struct media_pad *pad = &me->pads[0]; in fimc_pipeline_get_head()
739 while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) { in fimc_pipeline_get_head()
743 me = pad->entity; in fimc_pipeline_get_head()
744 pad = &me->pads[0]; in fimc_pipeline_get_head()
751 * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
753 * @ctx: FIMC capture context
755 * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
763 struct fimc_dev *fimc = ctx->fimc_dev; in fimc_pipeline_try_format() local
764 struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe); in fimc_pipeline_try_format()
765 struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; in fimc_pipeline_try_format()
778 return -EINVAL; in fimc_pipeline_try_format()
782 me = fimc_pipeline_get_head(&sd->entity); in fimc_pipeline_try_format()
785 ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL, in fimc_pipeline_try_format()
789 * Notify user-space if common pixel code for in fimc_pipeline_try_format()
792 return -EINVAL; in fimc_pipeline_try_format()
794 mf->code = tfmt->code = ffmt->mbus_code; in fimc_pipeline_try_format()
797 while (me != &fimc->vid_cap.subdev.entity) { in fimc_pipeline_try_format()
805 if (me->pads[0].flags & MEDIA_PAD_FL_SINK) { in fimc_pipeline_try_format()
806 sfmt.pad = me->num_pads - 1; in fimc_pipeline_try_format()
807 mf->code = tfmt->code; in fimc_pipeline_try_format()
814 pad = media_pad_remote_pad_first(&me->pads[sfmt.pad]); in fimc_pipeline_try_format()
816 return -EINVAL; in fimc_pipeline_try_format()
817 me = pad->entity; in fimc_pipeline_try_format()
820 if (mf->code != tfmt->code) in fimc_pipeline_try_format()
823 fcc = ffmt->fourcc; in fimc_pipeline_try_format()
824 tfmt->width = mf->width; in fimc_pipeline_try_format()
825 tfmt->height = mf->height; in fimc_pipeline_try_format()
826 ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height, in fimc_pipeline_try_format()
828 ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height, in fimc_pipeline_try_format()
830 if (ffmt && ffmt->mbus_code) in fimc_pipeline_try_format()
831 mf->code = ffmt->mbus_code; in fimc_pipeline_try_format()
832 if (mf->width != tfmt->width || mf->height != tfmt->height) in fimc_pipeline_try_format()
834 tfmt->code = mf->code; in fimc_pipeline_try_format()
846 * fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
852 * This function is used by this driver only for compressed/blob data formats.
865 pad = sensor->entity.num_pads - 1; in fimc_get_sensor_frame_desc()
875 return -EINVAL; in fimc_get_sensor_frame_desc()
881 v4l2_err(sensor->v4l2_dev, "Unsupported buffer size: %u\n", in fimc_get_sensor_frame_desc()
884 return -EINVAL; in fimc_get_sensor_frame_desc()
893 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_g_fmt_mplane() local
895 __fimc_get_format(&fimc->vid_cap.ctx->d_frame, f); in fimc_cap_g_fmt_mplane()
900 * Try or set format on the fimc.X.capture video node and additionally
901 * on the whole pipeline if @try is false.
904 static int __video_try_or_set_format(struct fimc_dev *fimc, in __video_try_or_set_format() argument
909 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; in __video_try_or_set_format()
910 struct fimc_vid_cap *vc = &fimc->vid_cap; in __video_try_or_set_format()
911 struct exynos_video_entity *ve = &vc->ve; in __video_try_or_set_format()
912 struct fimc_ctx *ctx = vc->ctx; in __video_try_or_set_format()
916 /* Pre-configure format at the camera input interface, for JPEG only */ in __video_try_or_set_format()
917 if (fimc_jpeg_fourcc(pix->pixelformat)) { in __video_try_or_set_format()
918 fimc_capture_try_format(ctx, &pix->width, &pix->height, in __video_try_or_set_format()
919 NULL, &pix->pixelformat, in __video_try_or_set_format()
922 width = pix->width; in __video_try_or_set_format()
923 height = pix->height; in __video_try_or_set_format()
925 ctx->s_frame.f_width = pix->width; in __video_try_or_set_format()
926 ctx->s_frame.f_height = pix->height; in __video_try_or_set_format()
931 *out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height, in __video_try_or_set_format()
932 NULL, &pix->pixelformat, in __video_try_or_set_format()
935 return -EINVAL; in __video_try_or_set_format()
938 if (try && fimc_jpeg_fourcc(pix->pixelformat)) { in __video_try_or_set_format()
939 pix->width = width; in __video_try_or_set_format()
940 pix->height = height; in __video_try_or_set_format()
944 if (!vc->user_subdev_api) { in __video_try_or_set_format()
948 mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt; in __video_try_or_set_format()
950 mf->code = (*out_fmt)->mbus_code; in __video_try_or_set_format()
951 mf->width = pix->width; in __video_try_or_set_format()
952 mf->height = pix->height; in __video_try_or_set_format()
961 pix->width = mf->width; in __video_try_or_set_format()
962 pix->height = mf->height; in __video_try_or_set_format()
965 fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix); in __video_try_or_set_format()
967 if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) { in __video_try_or_set_format()
972 sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR); in __video_try_or_set_format()
974 fimc_get_sensor_frame_desc(sensor, pix->plane_fmt, in __video_try_or_set_format()
975 (*out_fmt)->memplanes, try); in __video_try_or_set_format()
977 ret = -EPIPE; in __video_try_or_set_format()
988 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_try_fmt_mplane() local
991 return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt); in fimc_cap_try_fmt_mplane()
999 ctx->scaler.enabled = !jpeg; in fimc_capture_mark_jpeg_xfer()
1003 set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state); in fimc_capture_mark_jpeg_xfer()
1005 clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state); in fimc_capture_mark_jpeg_xfer()
1008 static int __fimc_capture_set_format(struct fimc_dev *fimc, in __fimc_capture_set_format() argument
1011 struct fimc_vid_cap *vc = &fimc->vid_cap; in __fimc_capture_set_format()
1012 struct fimc_ctx *ctx = vc->ctx; in __fimc_capture_set_format()
1013 const struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; in __fimc_capture_set_format()
1014 struct fimc_frame *ff = &ctx->d_frame; in __fimc_capture_set_format()
1018 if (vb2_is_busy(&fimc->vid_cap.vbq)) in __fimc_capture_set_format()
1019 return -EBUSY; in __fimc_capture_set_format()
1021 ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt); in __fimc_capture_set_format()
1028 for (i = 0; i < ff->fmt->memplanes; i++) { in __fimc_capture_set_format()
1029 ff->bytesperline[i] = pix->plane_fmt[i].bytesperline; in __fimc_capture_set_format()
1030 ff->payload[i] = pix->plane_fmt[i].sizeimage; in __fimc_capture_set_format()
1033 set_frame_bounds(ff, pix->width, pix->height); in __fimc_capture_set_format()
1035 if (!(ctx->state & FIMC_COMPOSE)) in __fimc_capture_set_format()
1036 set_frame_crop(ff, 0, 0, pix->width, pix->height); in __fimc_capture_set_format()
1038 fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color); in __fimc_capture_set_format()
1041 if (!vc->user_subdev_api) { in __fimc_capture_set_format()
1042 ctx->s_frame.fmt = inp_fmt; in __fimc_capture_set_format()
1043 set_frame_bounds(&ctx->s_frame, pix->width, pix->height); in __fimc_capture_set_format()
1044 set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height); in __fimc_capture_set_format()
1053 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_s_fmt_mplane() local
1055 return __fimc_capture_set_format(fimc, f); in fimc_cap_s_fmt_mplane()
1061 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_enum_input() local
1062 struct exynos_video_entity *ve = &fimc->vid_cap.ve; in fimc_cap_enum_input()
1065 if (i->index != 0) in fimc_cap_enum_input()
1066 return -EINVAL; in fimc_cap_enum_input()
1068 i->type = V4L2_INPUT_TYPE_CAMERA; in fimc_cap_enum_input()
1070 sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR); in fimc_cap_enum_input()
1074 strscpy(i->name, sd->name, sizeof(i->name)); in fimc_cap_enum_input()
1081 return i == 0 ? i : -EINVAL; in fimc_cap_s_input()
1091 * fimc_pipeline_validate - check for formats inconsistencies
1093 * @fimc: the FIMC device this context applies to
1095 * Return 0 if all formats match or -EPIPE otherwise.
1097 static int fimc_pipeline_validate(struct fimc_dev *fimc) in fimc_pipeline_validate() argument
1105 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_pipeline_validate()
1106 struct v4l2_subdev *sd = &vc->subdev; in fimc_pipeline_validate()
1107 struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe); in fimc_pipeline_validate()
1114 * to it. We stop if there is no sink pad in current entity or in fimc_pipeline_validate()
1115 * it is not linked to any other remote entity. in fimc_pipeline_validate()
1119 for (i = 0; i < sd->entity.num_pads; i++) { in fimc_pipeline_validate()
1120 struct media_pad *p = &sd->entity.pads[i]; in fimc_pipeline_validate()
1122 if (p->flags & MEDIA_PAD_FL_SINK) { in fimc_pipeline_validate()
1130 if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity)) in fimc_pipeline_validate()
1133 /* Don't call FIMC subdev operation to avoid nested locking */ in fimc_pipeline_validate()
1134 if (sd == &vc->subdev) { in fimc_pipeline_validate()
1135 const struct fimc_frame *ff = &vc->ctx->s_frame; in fimc_pipeline_validate()
1136 sink_fmt.format.width = ff->f_width; in fimc_pipeline_validate()
1137 sink_fmt.format.height = ff->f_height; in fimc_pipeline_validate()
1138 sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0; in fimc_pipeline_validate()
1140 sink_fmt.pad = sink_pad->index; in fimc_pipeline_validate()
1142 if (ret < 0 && ret != -ENOIOCTLCMD) in fimc_pipeline_validate()
1143 return -EPIPE; in fimc_pipeline_validate()
1147 sd = media_entity_to_v4l2_subdev(src_pad->entity); in fimc_pipeline_validate()
1148 src_fmt.pad = src_pad->index; in fimc_pipeline_validate()
1150 if (ret < 0 && ret != -ENOIOCTLCMD) in fimc_pipeline_validate()
1151 return -EPIPE; in fimc_pipeline_validate()
1156 return -EPIPE; in fimc_pipeline_validate()
1158 if (sd == p->subdevs[IDX_SENSOR] && in fimc_pipeline_validate()
1161 const struct fimc_frame *frame = &vc->ctx->d_frame; in fimc_pipeline_validate()
1165 frame->fmt->memplanes, in fimc_pipeline_validate()
1168 return -EPIPE; in fimc_pipeline_validate()
1170 for (i = 0; i < frame->fmt->memplanes; i++) in fimc_pipeline_validate()
1171 if (frame->payload[i] < plane_fmt[i].sizeimage) in fimc_pipeline_validate()
1172 return -EPIPE; in fimc_pipeline_validate()
1181 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_streamon() local
1182 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_cap_streamon()
1187 if (fimc_capture_active(fimc)) in fimc_cap_streamon()
1188 return -EBUSY; in fimc_cap_streamon()
1190 ret = video_device_pipeline_start(&vc->ve.vdev, &vc->ve.pipe->mp); in fimc_cap_streamon()
1194 sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR); in fimc_cap_streamon()
1199 ret = -EPIPE; in fimc_cap_streamon()
1204 * sensor or other data source, e.g. FIMC-IS. in fimc_cap_streamon()
1206 vc->source_config = *si; in fimc_cap_streamon()
1208 if (vc->input == GRP_ID_FIMC_IS) in fimc_cap_streamon()
1209 vc->source_config.fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK; in fimc_cap_streamon()
1211 if (vc->user_subdev_api) { in fimc_cap_streamon()
1212 ret = fimc_pipeline_validate(fimc); in fimc_cap_streamon()
1219 vc->streaming = true; in fimc_cap_streamon()
1224 video_device_pipeline_stop(&vc->ve.vdev); in fimc_cap_streamon()
1231 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_streamoff() local
1232 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_cap_streamoff()
1239 if (vc->streaming) { in fimc_cap_streamoff()
1240 video_device_pipeline_stop(&vc->ve.vdev); in fimc_cap_streamoff()
1241 vc->streaming = false; in fimc_cap_streamoff()
1250 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_reqbufs() local
1256 fimc->vid_cap.reqbufs_count = reqbufs->count; in fimc_cap_reqbufs()
1264 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_g_selection() local
1265 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_cap_g_selection()
1266 const struct fimc_frame *f = &ctx->s_frame; in fimc_cap_g_selection()
1268 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in fimc_cap_g_selection()
1269 return -EINVAL; in fimc_cap_g_selection()
1271 switch (s->target) { in fimc_cap_g_selection()
1274 f = &ctx->d_frame; in fimc_cap_g_selection()
1278 s->r.left = 0; in fimc_cap_g_selection()
1279 s->r.top = 0; in fimc_cap_g_selection()
1280 s->r.width = f->o_width; in fimc_cap_g_selection()
1281 s->r.height = f->o_height; in fimc_cap_g_selection()
1285 f = &ctx->d_frame; in fimc_cap_g_selection()
1288 s->r.left = f->offs_h; in fimc_cap_g_selection()
1289 s->r.top = f->offs_v; in fimc_cap_g_selection()
1290 s->r.width = f->width; in fimc_cap_g_selection()
1291 s->r.height = f->height; in fimc_cap_g_selection()
1295 return -EINVAL; in fimc_cap_g_selection()
1301 struct fimc_dev *fimc = video_drvdata(file); in fimc_cap_s_selection() local
1302 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_cap_s_selection()
1303 struct v4l2_rect rect = s->r; in fimc_cap_s_selection()
1307 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in fimc_cap_s_selection()
1308 return -EINVAL; in fimc_cap_s_selection()
1310 if (s->target == V4L2_SEL_TGT_COMPOSE) in fimc_cap_s_selection()
1311 f = &ctx->d_frame; in fimc_cap_s_selection()
1312 else if (s->target == V4L2_SEL_TGT_CROP) in fimc_cap_s_selection()
1313 f = &ctx->s_frame; in fimc_cap_s_selection()
1315 return -EINVAL; in fimc_cap_s_selection()
1317 fimc_capture_try_selection(ctx, &rect, s->target); in fimc_cap_s_selection()
1319 if (s->flags & V4L2_SEL_FLAG_LE && in fimc_cap_s_selection()
1320 !v4l2_rect_enclosed(&rect, &s->r)) in fimc_cap_s_selection()
1321 return -ERANGE; in fimc_cap_s_selection()
1323 if (s->flags & V4L2_SEL_FLAG_GE && in fimc_cap_s_selection()
1324 !v4l2_rect_enclosed(&s->r, &rect)) in fimc_cap_s_selection()
1325 return -ERANGE; in fimc_cap_s_selection()
1327 s->r = rect; in fimc_cap_s_selection()
1328 spin_lock_irqsave(&fimc->slock, flags); in fimc_cap_s_selection()
1329 set_frame_crop(f, s->r.left, s->r.top, s->r.width, in fimc_cap_s_selection()
1330 s->r.height); in fimc_cap_s_selection()
1331 spin_unlock_irqrestore(&fimc->slock, flags); in fimc_cap_s_selection()
1333 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); in fimc_cap_s_selection()
1370 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_link_setup() local
1371 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_link_setup()
1374 if (!is_media_entity_v4l2_subdev(remote->entity)) in fimc_link_setup()
1375 return -EINVAL; in fimc_link_setup()
1377 if (WARN_ON(fimc == NULL)) in fimc_link_setup()
1380 dbg("%s --> %s, flags: 0x%x. input: 0x%x", in fimc_link_setup()
1381 local->entity->name, remote->entity->name, flags, in fimc_link_setup()
1382 fimc->vid_cap.input); in fimc_link_setup()
1385 fimc->vid_cap.input = 0; in fimc_link_setup()
1389 if (vc->input != 0) in fimc_link_setup()
1390 return -EBUSY; in fimc_link_setup()
1392 vc->input = sd->grp_id; in fimc_link_setup()
1394 if (vc->user_subdev_api) in fimc_link_setup()
1398 sensor = fimc_find_remote_sensor(&vc->subdev.entity); in fimc_link_setup()
1402 return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler, in fimc_link_setup()
1403 sensor->ctrl_handler, NULL, true); in fimc_link_setup()
1411 * fimc_sensor_notify - v4l2_device notification from a sensor subdev
1417 * mode. If there is only a single VSYNC generated by the sensor at the
1418 * beginning of a frame transmission, FIMC does not issue the LastIrq
1419 * (end of frame) interrupt. And this notification is used to complete the
1420 * frame capture and returning a buffer to user-space. Subdev drivers should
1429 struct fimc_dev *fimc; in fimc_sensor_notify() local
1436 fmd = entity_to_fimc_mdev(&sd->entity); in fimc_sensor_notify()
1438 spin_lock_irqsave(&fmd->slock, flags); in fimc_sensor_notify()
1440 fimc = si ? source_to_sensor_info(si)->host : NULL; in fimc_sensor_notify()
1442 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY && in fimc_sensor_notify()
1443 test_bit(ST_CAPT_PEND, &fimc->state)) { in fimc_sensor_notify()
1445 spin_lock_irqsave(&fimc->slock, irq_flags); in fimc_sensor_notify()
1446 if (!list_empty(&fimc->vid_cap.active_buf_q)) { in fimc_sensor_notify()
1447 buf = list_entry(fimc->vid_cap.active_buf_q.next, in fimc_sensor_notify()
1449 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, in fimc_sensor_notify()
1452 fimc_capture_irq_handler(fimc, 1); in fimc_sensor_notify()
1453 fimc_deactivate_capture(fimc); in fimc_sensor_notify()
1454 spin_unlock_irqrestore(&fimc->slock, irq_flags); in fimc_sensor_notify()
1456 spin_unlock_irqrestore(&fmd->slock, flags); in fimc_sensor_notify()
1465 fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index); in fimc_subdev_enum_mbus_code()
1467 return -EINVAL; in fimc_subdev_enum_mbus_code()
1468 code->code = fmt->mbus_code; in fimc_subdev_enum_mbus_code()
1476 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_subdev_get_fmt() local
1477 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_subdev_get_fmt()
1478 const struct fimc_frame *ff = &ctx->s_frame; in fimc_subdev_get_fmt()
1481 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in fimc_subdev_get_fmt()
1482 mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); in fimc_subdev_get_fmt()
1483 fmt->format = *mf; in fimc_subdev_get_fmt()
1487 mf = &fmt->format; in fimc_subdev_get_fmt()
1488 mutex_lock(&fimc->lock); in fimc_subdev_get_fmt()
1490 switch (fmt->pad) { in fimc_subdev_get_fmt()
1492 if (!WARN_ON(ff->fmt == NULL)) in fimc_subdev_get_fmt()
1493 mf->code = ff->fmt->mbus_code; in fimc_subdev_get_fmt()
1495 mf->width = ff->width; in fimc_subdev_get_fmt()
1496 mf->height = ff->height; in fimc_subdev_get_fmt()
1499 *mf = fimc->vid_cap.wb_fmt; in fimc_subdev_get_fmt()
1503 *mf = fimc->vid_cap.ci_fmt; in fimc_subdev_get_fmt()
1507 mutex_unlock(&fimc->lock); in fimc_subdev_get_fmt()
1508 mf->colorspace = V4L2_COLORSPACE_JPEG; in fimc_subdev_get_fmt()
1517 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_subdev_set_fmt() local
1518 struct v4l2_mbus_framefmt *mf = &fmt->format; in fimc_subdev_set_fmt()
1519 struct fimc_vid_cap *vc = &fimc->vid_cap; in fimc_subdev_set_fmt()
1520 struct fimc_ctx *ctx = vc->ctx; in fimc_subdev_set_fmt()
1525 fmt->pad, mf->code, mf->width, mf->height); in fimc_subdev_set_fmt()
1527 if (fmt->pad == FIMC_SD_PAD_SOURCE && vb2_is_busy(&vc->vbq)) in fimc_subdev_set_fmt()
1528 return -EBUSY; in fimc_subdev_set_fmt()
1530 mutex_lock(&fimc->lock); in fimc_subdev_set_fmt()
1531 ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height, in fimc_subdev_set_fmt()
1532 &mf->code, NULL, fmt->pad); in fimc_subdev_set_fmt()
1533 mutex_unlock(&fimc->lock); in fimc_subdev_set_fmt()
1534 mf->colorspace = V4L2_COLORSPACE_JPEG; in fimc_subdev_set_fmt()
1536 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in fimc_subdev_set_fmt()
1537 mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); in fimc_subdev_set_fmt()
1538 *mf = fmt->format; in fimc_subdev_set_fmt()
1543 return -EINVAL; in fimc_subdev_set_fmt()
1548 fimc_capture_mark_jpeg_xfer(ctx, ffmt->color); in fimc_subdev_set_fmt()
1549 if (fmt->pad == FIMC_SD_PAD_SOURCE) { in fimc_subdev_set_fmt()
1550 ff = &ctx->d_frame; in fimc_subdev_set_fmt()
1552 mf->width = ctx->s_frame.width; in fimc_subdev_set_fmt()
1553 mf->height = ctx->s_frame.height; in fimc_subdev_set_fmt()
1555 ff = &ctx->s_frame; in fimc_subdev_set_fmt()
1558 mutex_lock(&fimc->lock); in fimc_subdev_set_fmt()
1559 set_frame_bounds(ff, mf->width, mf->height); in fimc_subdev_set_fmt()
1561 if (fmt->pad == FIMC_SD_PAD_SINK_FIFO) in fimc_subdev_set_fmt()
1562 vc->wb_fmt = *mf; in fimc_subdev_set_fmt()
1563 else if (fmt->pad == FIMC_SD_PAD_SINK_CAM) in fimc_subdev_set_fmt()
1564 vc->ci_fmt = *mf; in fimc_subdev_set_fmt()
1566 ff->fmt = ffmt; in fimc_subdev_set_fmt()
1569 if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE))) in fimc_subdev_set_fmt()
1570 set_frame_crop(ff, 0, 0, mf->width, mf->height); in fimc_subdev_set_fmt()
1572 if (fmt->pad != FIMC_SD_PAD_SOURCE) in fimc_subdev_set_fmt()
1573 ctx->state &= ~FIMC_COMPOSE; in fimc_subdev_set_fmt()
1575 mutex_unlock(&fimc->lock); in fimc_subdev_set_fmt()
1583 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_subdev_get_selection() local
1584 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_subdev_get_selection()
1585 const struct fimc_frame *f = &ctx->s_frame; in fimc_subdev_get_selection()
1586 struct v4l2_rect *r = &sel->r; in fimc_subdev_get_selection()
1589 if (sel->pad == FIMC_SD_PAD_SOURCE) in fimc_subdev_get_selection()
1590 return -EINVAL; in fimc_subdev_get_selection()
1592 mutex_lock(&fimc->lock); in fimc_subdev_get_selection()
1594 switch (sel->target) { in fimc_subdev_get_selection()
1596 f = &ctx->d_frame; in fimc_subdev_get_selection()
1599 r->width = f->o_width; in fimc_subdev_get_selection()
1600 r->height = f->o_height; in fimc_subdev_get_selection()
1601 r->left = 0; in fimc_subdev_get_selection()
1602 r->top = 0; in fimc_subdev_get_selection()
1603 mutex_unlock(&fimc->lock); in fimc_subdev_get_selection()
1607 try_sel = v4l2_subdev_state_get_crop(sd_state, sel->pad); in fimc_subdev_get_selection()
1610 try_sel = v4l2_subdev_state_get_compose(sd_state, sel->pad); in fimc_subdev_get_selection()
1611 f = &ctx->d_frame; in fimc_subdev_get_selection()
1614 mutex_unlock(&fimc->lock); in fimc_subdev_get_selection()
1615 return -EINVAL; in fimc_subdev_get_selection()
1618 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { in fimc_subdev_get_selection()
1619 sel->r = *try_sel; in fimc_subdev_get_selection()
1621 r->left = f->offs_h; in fimc_subdev_get_selection()
1622 r->top = f->offs_v; in fimc_subdev_get_selection()
1623 r->width = f->width; in fimc_subdev_get_selection()
1624 r->height = f->height; in fimc_subdev_get_selection()
1628 sel->pad, r->left, r->top, r->width, r->height, in fimc_subdev_get_selection()
1629 f->f_width, f->f_height); in fimc_subdev_get_selection()
1631 mutex_unlock(&fimc->lock); in fimc_subdev_get_selection()
1639 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_subdev_set_selection() local
1640 struct fimc_ctx *ctx = fimc->vid_cap.ctx; in fimc_subdev_set_selection()
1641 struct fimc_frame *f = &ctx->s_frame; in fimc_subdev_set_selection()
1642 struct v4l2_rect *r = &sel->r; in fimc_subdev_set_selection()
1646 if (sel->pad == FIMC_SD_PAD_SOURCE) in fimc_subdev_set_selection()
1647 return -EINVAL; in fimc_subdev_set_selection()
1649 mutex_lock(&fimc->lock); in fimc_subdev_set_selection()
1652 switch (sel->target) { in fimc_subdev_set_selection()
1654 try_sel = v4l2_subdev_state_get_crop(sd_state, sel->pad); in fimc_subdev_set_selection()
1657 try_sel = v4l2_subdev_state_get_compose(sd_state, sel->pad); in fimc_subdev_set_selection()
1658 f = &ctx->d_frame; in fimc_subdev_set_selection()
1661 mutex_unlock(&fimc->lock); in fimc_subdev_set_selection()
1662 return -EINVAL; in fimc_subdev_set_selection()
1665 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { in fimc_subdev_set_selection()
1666 *try_sel = sel->r; in fimc_subdev_set_selection()
1668 spin_lock_irqsave(&fimc->slock, flags); in fimc_subdev_set_selection()
1669 set_frame_crop(f, r->left, r->top, r->width, r->height); in fimc_subdev_set_selection()
1670 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); in fimc_subdev_set_selection()
1671 if (sel->target == V4L2_SEL_TGT_COMPOSE) in fimc_subdev_set_selection()
1672 ctx->state |= FIMC_COMPOSE; in fimc_subdev_set_selection()
1673 spin_unlock_irqrestore(&fimc->slock, flags); in fimc_subdev_set_selection()
1676 dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top, in fimc_subdev_set_selection()
1677 r->width, r->height); in fimc_subdev_set_selection()
1679 mutex_unlock(&fimc->lock); in fimc_subdev_set_selection()
1696 static int fimc_capture_set_default_format(struct fimc_dev *fimc) in fimc_capture_set_default_format() argument
1709 return __fimc_capture_set_format(fimc, &fmt); in fimc_capture_set_default_format()
1712 /* fimc->lock must be already initialized */
1713 static int fimc_register_capture_device(struct fimc_dev *fimc, in fimc_register_capture_device() argument
1716 struct video_device *vfd = &fimc->vid_cap.ve.vdev; in fimc_register_capture_device()
1717 struct vb2_queue *q = &fimc->vid_cap.vbq; in fimc_register_capture_device()
1721 int ret = -ENOMEM; in fimc_register_capture_device()
1725 return -ENOMEM; in fimc_register_capture_device()
1727 ctx->fimc_dev = fimc; in fimc_register_capture_device()
1728 ctx->in_path = FIMC_IO_CAMERA; in fimc_register_capture_device()
1729 ctx->out_path = FIMC_IO_DMA; in fimc_register_capture_device()
1730 ctx->state = FIMC_CTX_CAP; in fimc_register_capture_device()
1731 ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); in fimc_register_capture_device()
1732 ctx->d_frame.fmt = ctx->s_frame.fmt; in fimc_register_capture_device()
1735 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id); in fimc_register_capture_device()
1737 vfd->fops = &fimc_capture_fops; in fimc_register_capture_device()
1738 vfd->ioctl_ops = &fimc_capture_ioctl_ops; in fimc_register_capture_device()
1739 vfd->v4l2_dev = v4l2_dev; in fimc_register_capture_device()
1740 vfd->minor = -1; in fimc_register_capture_device()
1741 vfd->release = video_device_release_empty; in fimc_register_capture_device()
1742 vfd->queue = q; in fimc_register_capture_device()
1743 vfd->lock = &fimc->lock; in fimc_register_capture_device()
1744 vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE; in fimc_register_capture_device()
1746 video_set_drvdata(vfd, fimc); in fimc_register_capture_device()
1747 vid_cap = &fimc->vid_cap; in fimc_register_capture_device()
1748 vid_cap->active_buf_cnt = 0; in fimc_register_capture_device()
1749 vid_cap->reqbufs_count = 0; in fimc_register_capture_device()
1750 vid_cap->ctx = ctx; in fimc_register_capture_device()
1752 INIT_LIST_HEAD(&vid_cap->pending_buf_q); in fimc_register_capture_device()
1753 INIT_LIST_HEAD(&vid_cap->active_buf_q); in fimc_register_capture_device()
1756 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in fimc_register_capture_device()
1757 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in fimc_register_capture_device()
1758 q->drv_priv = ctx; in fimc_register_capture_device()
1759 q->ops = &fimc_capture_qops; in fimc_register_capture_device()
1760 q->mem_ops = &vb2_dma_contig_memops; in fimc_register_capture_device()
1761 q->buf_struct_size = sizeof(struct fimc_vid_buffer); in fimc_register_capture_device()
1762 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in fimc_register_capture_device()
1763 q->lock = &fimc->lock; in fimc_register_capture_device()
1764 q->dev = &fimc->pdev->dev; in fimc_register_capture_device()
1772 vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH; in fimc_register_capture_device()
1773 vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT; in fimc_register_capture_device()
1774 vid_cap->ci_fmt.code = fmt->mbus_code; in fimc_register_capture_device()
1776 ctx->s_frame.width = FIMC_DEFAULT_WIDTH; in fimc_register_capture_device()
1777 ctx->s_frame.height = FIMC_DEFAULT_HEIGHT; in fimc_register_capture_device()
1778 ctx->s_frame.fmt = fmt; in fimc_register_capture_device()
1781 vid_cap->wb_fmt = vid_cap->ci_fmt; in fimc_register_capture_device()
1782 vid_cap->wb_fmt.code = fmt->mbus_code; in fimc_register_capture_device()
1784 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; in fimc_register_capture_device()
1785 vfd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER; in fimc_register_capture_device()
1786 ret = media_entity_pads_init(&vfd->entity, 1, &vid_cap->vd_pad); in fimc_register_capture_device()
1794 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); in fimc_register_capture_device()
1799 vfd->name, video_device_node_name(vfd)); in fimc_register_capture_device()
1801 vfd->ctrl_handler = &ctx->ctrls.handler; in fimc_register_capture_device()
1807 media_entity_cleanup(&vfd->entity); in fimc_register_capture_device()
1815 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_capture_subdev_registered() local
1818 if (fimc == NULL) in fimc_capture_subdev_registered()
1819 return -ENXIO; in fimc_capture_subdev_registered()
1821 ret = fimc_register_m2m_device(fimc, sd->v4l2_dev); in fimc_capture_subdev_registered()
1825 fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd); in fimc_capture_subdev_registered()
1827 ret = fimc_register_capture_device(fimc, sd->v4l2_dev); in fimc_capture_subdev_registered()
1829 fimc_unregister_m2m_device(fimc); in fimc_capture_subdev_registered()
1830 fimc->vid_cap.ve.pipe = NULL; in fimc_capture_subdev_registered()
1838 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); in fimc_capture_subdev_unregistered() local
1841 if (fimc == NULL) in fimc_capture_subdev_unregistered()
1844 mutex_lock(&fimc->lock); in fimc_capture_subdev_unregistered()
1846 fimc_unregister_m2m_device(fimc); in fimc_capture_subdev_unregistered()
1847 vdev = &fimc->vid_cap.ve.vdev; in fimc_capture_subdev_unregistered()
1851 media_entity_cleanup(&vdev->entity); in fimc_capture_subdev_unregistered()
1852 fimc_ctrls_delete(fimc->vid_cap.ctx); in fimc_capture_subdev_unregistered()
1853 fimc->vid_cap.ve.pipe = NULL; in fimc_capture_subdev_unregistered()
1855 kfree(fimc->vid_cap.ctx); in fimc_capture_subdev_unregistered()
1856 fimc->vid_cap.ctx = NULL; in fimc_capture_subdev_unregistered()
1858 mutex_unlock(&fimc->lock); in fimc_capture_subdev_unregistered()
1866 int fimc_initialize_capture_subdev(struct fimc_dev *fimc) in fimc_initialize_capture_subdev() argument
1868 struct v4l2_subdev *sd = &fimc->vid_cap.subdev; in fimc_initialize_capture_subdev()
1872 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in fimc_initialize_capture_subdev()
1873 snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->id); in fimc_initialize_capture_subdev()
1875 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK; in fimc_initialize_capture_subdev()
1876 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK; in fimc_initialize_capture_subdev()
1877 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in fimc_initialize_capture_subdev()
1878 ret = media_entity_pads_init(&sd->entity, FIMC_SD_PADS_NUM, in fimc_initialize_capture_subdev()
1879 fimc->vid_cap.sd_pads); in fimc_initialize_capture_subdev()
1883 sd->entity.ops = &fimc_sd_media_ops; in fimc_initialize_capture_subdev()
1884 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER; in fimc_initialize_capture_subdev()
1885 sd->internal_ops = &fimc_capture_sd_internal_ops; in fimc_initialize_capture_subdev()
1886 v4l2_set_subdevdata(sd, fimc); in fimc_initialize_capture_subdev()
1890 void fimc_unregister_capture_subdev(struct fimc_dev *fimc) in fimc_unregister_capture_subdev() argument
1892 struct v4l2_subdev *sd = &fimc->vid_cap.subdev; in fimc_unregister_capture_subdev()
1895 media_entity_cleanup(&sd->entity); in fimc_unregister_capture_subdev()