12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/errno.h>
18 #include <linux/device.h>
20 #include <linux/list.h>
21 #include <linux/slab.h>
23 #include <linux/videodev2.h>
34 static int fimc_capture_hw_init(
struct fimc_dev *fimc)
72 spin_unlock_irqrestore(&fimc->
slock, flags);
84 static int fimc_capture_state_cleanup(
struct fimc_dev *fimc,
bool suspend)
103 buf = fimc_pending_queue_pop(cap);
108 buf = fimc_active_queue_pop(cap);
110 fimc_pending_queue_add(cap, buf);
118 spin_unlock_irqrestore(&fimc->
slock, flags);
127 static int fimc_stop_capture(
struct fimc_dev *fimc,
bool suspend)
131 if (!fimc_capture_active(fimc))
137 spin_unlock_irqrestore(&fimc->
slock, flags);
143 return fimc_capture_state_cleanup(fimc, suspend);
153 static int fimc_capture_config_update(
struct fimc_ctx *ctx)
196 v_buf = fimc_active_queue_pop(cap);
198 tv = &v_buf->
vb.v4l2_buf.timestamp;
208 v_buf = fimc_pending_queue_pop(cap);
213 fimc_active_queue_add(cap, v_buf);
215 dbg(
"next frame: %d, done frame: %d",
232 if (v_buf->
index != index)
252 fimc_capture_config_update(cap->
ctx);
259 dbg(
"frame: %d, active_buf_cnt: %d",
274 ret = fimc_capture_hw_init(fimc);
276 fimc_capture_state_cleanup(fimc,
false);
282 min_bufs = fimc->
vid_cap.reqbufs_count > 1 ? 2 : 1;
296 static int stop_streaming(
struct vb2_queue *q)
301 if (!fimc_capture_active(fimc))
304 return fimc_stop_capture(fimc,
false);
311 int ret = fimc_stop_capture(fimc, suspend);
317 static void buffer_queue(
struct vb2_buffer *vb);
328 INIT_LIST_HEAD(&fimc->
vid_cap.active_buf_q);
331 &vid_cap->
vfd.entity,
false);
332 fimc_capture_hw_init(fimc);
339 buf = fimc_pending_queue_pop(vid_cap);
340 buffer_queue(&buf->
vb);
347 unsigned int *num_buffers,
unsigned int *
num_planes,
348 unsigned int sizes[],
void *allocators[])
380 allocators[
i] = ctx->
fimc_dev->alloc_ctx;
386 static int buffer_prepare(
struct vb2_buffer *vb)
395 for (i = 0; i < ctx->
d_frame.fmt->memplanes; i++) {
396 unsigned long size = ctx->
d_frame.payload[
i];
398 if (vb2_plane_size(vb, i) < size) {
400 "User buffer too small (%ld < %ld)\n",
401 vb2_plane_size(vb, i), size);
404 vb2_set_plane_payload(vb, i, size);
410 static void buffer_queue(
struct vb2_buffer *vb)
432 fimc_active_queue_add(vid_cap, buf);
437 fimc_pending_queue_add(vid_cap, buf);
443 if (vb2_is_streaming(&vid_cap->
vbq) &&
447 spin_unlock_irqrestore(&fimc->
slock, flags);
454 spin_unlock_irqrestore(&fimc->
slock, flags);
457 static void fimc_lock(
struct vb2_queue *vq)
459 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
463 static void fimc_unlock(
struct vb2_queue *vq)
465 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
469 static struct vb2_ops fimc_capture_qops = {
471 .buf_prepare = buffer_prepare,
472 .buf_queue = buffer_queue,
473 .wait_prepare = fimc_unlock,
474 .wait_finish = fimc_lock,
493 if (vid_cap->
ctx->ctrls.ready)
504 static int fimc_capture_set_default_format(
struct fimc_dev *fimc);
506 static int fimc_capture_open(
struct file *
file)
508 struct fimc_dev *fimc = video_drvdata(file);
520 ret = pm_runtime_get_sync(&fimc->
pdev->dev);
526 pm_runtime_put(&fimc->
pdev->dev);
530 if (++fimc->
vid_cap.refcnt == 1) {
532 &fimc->
vid_cap.vfd.entity,
true);
534 if (!ret && !fimc->
vid_cap.user_subdev_api)
535 ret = fimc_capture_set_default_format(fimc);
542 pm_runtime_put_sync(&fimc->
pdev->dev);
552 static int fimc_capture_close(
struct file *file)
554 struct fimc_dev *fimc = video_drvdata(file);
561 if (--fimc->
vid_cap.refcnt == 0) {
563 fimc_stop_capture(fimc,
false);
568 pm_runtime_put(&fimc->
pdev->dev);
570 if (fimc->
vid_cap.refcnt == 0) {
581 static unsigned int fimc_capture_poll(
struct file *file,
584 struct fimc_dev *fimc = video_drvdata(file);
596 static int fimc_capture_mmap(
struct file *file,
struct vm_area_struct *vma)
598 struct fimc_dev *fimc = video_drvdata(file);
612 .open = fimc_capture_open,
613 .release = fimc_capture_close,
614 .poll = fimc_capture_poll,
616 .mmap = fimc_capture_mmap,
632 u32 depth, min_w, max_w, min_h, align_h = 3;
639 *code = ctx->
s_frame.fmt->mbus_code;
667 *height = ctx->
s_frame.f_height;
682 depth = fimc_get_format_depth(ffmt);
687 64/(
ALIGN(depth, 8)));
689 dbg(
"pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
690 pad, code ? *code : 0, *width, *height,
696 static void fimc_capture_try_selection(
struct fimc_ctx *ctx,
705 u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
706 u32 align_sz = 0, align_h = 4;
707 u32 max_sc_h, max_sc_v;
723 u32 depth = fimc_get_format_depth(sink->
fmt);
724 align_sz = 64/
ALIGN(depth, 8);
726 min_w = min_h = min_sz;
727 max_sc_h = max_sc_v = 1;
747 swap(max_sc_h, max_sc_v);
752 &r->
height, min_h, max_h, align_h,
759 dbg(
"target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
767 static int fimc_vidioc_querycap_capture(
struct file *file,
void *
priv,
770 struct fimc_dev *fimc = video_drvdata(file);
780 static int fimc_cap_enum_fmt_mplane(
struct file *file,
void *
priv,
804 static int fimc_pipeline_try_format(
struct fimc_ctx *ctx,
805 struct v4l2_mbus_framefmt *tfmt,
813 struct v4l2_mbus_framefmt *mf = &sfmt.
format;
820 memset(&sfmt, 0,
sizeof(sfmt));
839 if (mf->code != tfmt->code) {
843 if (mf->width != tfmt->width || mf->height != tfmt->height) {
845 tfmt->width = mf->width;
846 tfmt->height = mf->height;
847 ffmt = fimc_capture_try_format(ctx,
848 &tfmt->width, &tfmt->height,
852 if (mf->width != tfmt->width ||
853 mf->height != tfmt->height)
855 tfmt->code = mf->code;
860 if (mf->code == tfmt->code &&
861 mf->width == tfmt->width && mf->height == tfmt->height)
869 dbg(
"code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
881 static int fimc_get_sensor_frame_desc(
struct v4l2_subdev *sensor,
883 unsigned int num_planes,
bool try)
899 if (num_planes !=
fd.num_entries)
915 static int fimc_cap_g_fmt_mplane(
struct file *file,
void *fh,
918 struct fimc_dev *fimc = video_drvdata(file);
924 static int fimc_cap_try_fmt_mplane(
struct file *file,
void *
fh,
928 struct fimc_dev *fimc = video_drvdata(file);
930 struct v4l2_mbus_framefmt mf;
934 fimc_capture_try_format(ctx, &pix->
width, &pix->
height,
940 ffmt = fimc_capture_try_format(ctx, &pix->
width, &pix->
height,
946 if (!fimc->
vid_cap.user_subdev_api) {
947 mf.width = pix->
width;
950 fimc_md_graph_lock(fimc);
951 fimc_pipeline_try_format(ctx, &mf, &ffmt,
false);
952 fimc_md_graph_unlock(fimc);
953 pix->
width = mf.width;
968 static void fimc_capture_mark_jpeg_xfer(
struct fimc_ctx *ctx,
973 ctx->
scaler.enabled = !jpeg;
986 struct v4l2_mbus_framefmt *mf = &fimc->
vid_cap.mf;
991 if (vb2_is_busy(&fimc->
vid_cap.vbq))
996 fimc_capture_try_format(ctx, &pix->
width, &pix->
height,
1003 ff->
fmt = fimc_capture_try_format(ctx, &pix->
width, &pix->
height,
1013 if (!fimc->
vid_cap.user_subdev_api) {
1014 mf->code = ff->
fmt->mbus_code;
1015 mf->width = pix->
width;
1016 mf->height = pix->
height;
1018 fimc_md_graph_lock(fimc);
1019 ret = fimc_pipeline_try_format(ctx, mf, &s_fmt,
true);
1020 fimc_md_graph_unlock(fimc);
1023 pix->
width = mf->width;
1024 pix->
height = mf->height;
1037 for (i = 0; i < ff->
fmt->memplanes; i++)
1043 set_frame_crop(ff, 0, 0, pix->
width, pix->
height);
1045 fimc_capture_mark_jpeg_xfer(ctx, ff->
fmt->color);
1048 if (!fimc->
vid_cap.user_subdev_api) {
1057 static int fimc_cap_s_fmt_mplane(
struct file *file,
void *priv,
1060 struct fimc_dev *fimc = video_drvdata(file);
1062 return fimc_capture_set_format(fimc, f);
1065 static int fimc_cap_enum_input(
struct file *file,
void *priv,
1068 struct fimc_dev *fimc = video_drvdata(file);
1080 static int fimc_cap_s_input(
struct file *file,
void *priv,
unsigned int i)
1082 return i == 0 ? i : -
EINVAL;
1085 static int fimc_cap_g_input(
struct file *file,
void *priv,
unsigned int *i)
1097 static int fimc_pipeline_validate(
struct fimc_dev *fimc)
1114 pad = &sd->entity.pads[0];
1118 if (sd == &fimc->
vid_cap.subdev) {
1120 sink_fmt.format.width = ff->
f_width;
1121 sink_fmt.format.height = ff->
f_height;
1122 sink_fmt.format.code = ff->
fmt ? ff->
fmt->mbus_code : 0;
1124 sink_fmt.pad = pad->
index;
1137 src_fmt.pad = pad->
index;
1143 if (src_fmt.format.width != sink_fmt.format.width ||
1144 src_fmt.format.height != sink_fmt.format.height ||
1145 src_fmt.format.code != sink_fmt.format.code)
1149 fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
1154 ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
1155 frame->
fmt->memplanes,
1160 for (i = 0; i < frame->
fmt->memplanes; i++)
1168 static int fimc_cap_streamon(
struct file *file,
void *priv,
1171 struct fimc_dev *fimc = video_drvdata(file);
1176 if (fimc_capture_active(fimc))
1183 if (fimc->
vid_cap.user_subdev_api) {
1184 ret = fimc_pipeline_validate(fimc);
1193 static int fimc_cap_streamoff(
struct file *file,
void *priv,
1196 struct fimc_dev *fimc = video_drvdata(file);
1206 static int fimc_cap_reqbufs(
struct file *file,
void *priv,
1209 struct fimc_dev *fimc = video_drvdata(file);
1217 static int fimc_cap_querybuf(
struct file *file,
void *priv,
1220 struct fimc_dev *fimc = video_drvdata(file);
1225 static int fimc_cap_qbuf(
struct file *file,
void *priv,
1228 struct fimc_dev *fimc = video_drvdata(file);
1233 static int fimc_cap_dqbuf(
struct file *file,
void *priv,
1236 struct fimc_dev *fimc = video_drvdata(file);
1241 static int fimc_cap_create_bufs(
struct file *file,
void *priv,
1244 struct fimc_dev *fimc = video_drvdata(file);
1249 static int fimc_cap_prepare_buf(
struct file *file,
void *priv,
1252 struct fimc_dev *fimc = video_drvdata(file);
1257 static int fimc_cap_g_selection(
struct file *file,
void *fh,
1260 struct fimc_dev *fimc = video_drvdata(file);
1305 static int fimc_cap_s_selection(
struct file *file,
void *fh,
1308 struct fimc_dev *fimc = video_drvdata(file);
1312 unsigned long flags;
1324 fimc_capture_try_selection(ctx, &rect, s->
target);
1327 !enclosed_rectangle(&rect, &s->
r))
1331 !enclosed_rectangle(&s->
r, &rect))
1336 set_frame_crop(f, s->
r.left, s->
r.top, s->
r.width,
1338 spin_unlock_irqrestore(&fimc->
slock, flags);
1345 .vidioc_querycap = fimc_vidioc_querycap_capture,
1347 .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane,
1348 .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
1349 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
1350 .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
1352 .vidioc_reqbufs = fimc_cap_reqbufs,
1353 .vidioc_querybuf = fimc_cap_querybuf,
1355 .vidioc_qbuf = fimc_cap_qbuf,
1356 .vidioc_dqbuf = fimc_cap_dqbuf,
1358 .vidioc_prepare_buf = fimc_cap_prepare_buf,
1359 .vidioc_create_bufs = fimc_cap_create_bufs,
1361 .vidioc_streamon = fimc_cap_streamon,
1362 .vidioc_streamoff = fimc_cap_streamoff,
1364 .vidioc_g_selection = fimc_cap_g_selection,
1365 .vidioc_s_selection = fimc_cap_s_selection,
1367 .vidioc_enum_input = fimc_cap_enum_input,
1368 .vidioc_s_input = fimc_cap_s_input,
1369 .vidioc_g_input = fimc_cap_g_input,
1373 static int fimc_link_setup(
struct media_entity *entity,
1378 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1386 dbg(
"%s --> %s, flags: 0x%x. input: 0x%x",
1402 .link_setup = fimc_link_setup,
1425 unsigned long flags;
1430 sensor = v4l2_get_subdev_hostdata(sd);
1431 fmd = entity_to_fimc_mdev(&sd->entity);
1434 fimc = sensor ? sensor->
host :
NULL;
1438 unsigned long irq_flags;
1440 if (!list_empty(&fimc->
vid_cap.active_buf_q)) {
1443 vb2_set_plane_payload(&buf->
vb, 0, *((
u32 *)arg));
1447 spin_unlock_irqrestore(&fimc->
slock, irq_flags);
1449 spin_unlock_irqrestore(&fmd->
slock, flags);
1452 static int fimc_subdev_enum_mbus_code(
struct v4l2_subdev *sd,
1454 struct v4l2_subdev_mbus_code_enum *code)
1465 static int fimc_subdev_get_fmt(
struct v4l2_subdev *sd,
1469 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1471 struct v4l2_mbus_framefmt *mf;
1475 mf = v4l2_subdev_get_try_format(fh, fmt->
pad);
1486 mf->code = ctx->
s_frame.fmt->mbus_code;
1494 static int fimc_subdev_set_fmt(
struct v4l2_subdev *sd,
1498 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1499 struct v4l2_mbus_framefmt *mf = &fmt->
format;
1504 dbg(
"pad%d: code: 0x%x, %dx%d",
1505 fmt->
pad, mf->code, mf->width, mf->height);
1508 vb2_is_busy(&fimc->
vid_cap.vbq))
1512 ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
1518 mf = v4l2_subdev_get_try_format(fh, fmt->
pad);
1525 fimc_capture_mark_jpeg_xfer(ctx, ffmt->
color);
1531 set_frame_bounds(ff, mf->
width, mf->height);
1537 set_frame_crop(ff, 0, 0, mf->
width, mf->height);
1545 static int fimc_subdev_get_selection(
struct v4l2_subdev *sd,
1547 struct v4l2_subdev_selection *
sel)
1549 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1560 switch (sel->target) {
1572 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1575 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1592 dbg(
"target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
1600 static int fimc_subdev_set_selection(
struct v4l2_subdev *sd,
1602 struct v4l2_subdev_selection *sel)
1604 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1609 unsigned long flags;
1617 switch (sel->target) {
1629 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1632 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1646 spin_unlock_irqrestore(&fimc->
slock, flags);
1651 dbg(
"target %#x: (%d,%d)/%dx%d", sel->target, r->
left, r->
top,
1659 .enum_mbus_code = fimc_subdev_enum_mbus_code,
1660 .get_selection = fimc_subdev_get_selection,
1661 .set_selection = fimc_subdev_set_selection,
1662 .get_fmt = fimc_subdev_get_fmt,
1663 .set_fmt = fimc_subdev_set_fmt,
1667 .pad = &fimc_subdev_pad_ops,
1671 static int fimc_capture_set_default_format(
struct fimc_dev *fimc)
1684 return fimc_capture_set_format(fimc, &fmt);
1688 static int fimc_register_capture_device(
struct fimc_dev *fimc,
1708 memset(vfd, 0,
sizeof(*vfd));
1711 vfd->
fops = &fimc_capture_fops;
1712 vfd->
ioctl_ops = &fimc_capture_ioctl_ops;
1718 video_set_drvdata(vfd, fimc);
1730 memset(q, 0,
sizeof(*q));
1734 q->
ops = &fimc_capture_qops;
1751 v4l2_info(v4l2_dev,
"Registered %s as /dev/%s\n",
1752 vfd->
name, video_device_node_name(vfd));
1764 static int fimc_capture_subdev_registered(
struct v4l2_subdev *sd)
1766 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1778 ret = fimc_register_capture_device(fimc, sd->
v4l2_dev);
1787 static void fimc_capture_subdev_unregistered(
struct v4l2_subdev *sd)
1789 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1796 if (video_is_registered(&fimc->
vid_cap.vfd)) {
1806 .registered = fimc_capture_subdev_registered,
1807 .unregistered = fimc_capture_subdev_unregistered,
1826 sd->entity.
ops = &fimc_sd_media_ops;
1828 v4l2_set_subdevdata(sd, fimc);
1838 v4l2_set_subdevdata(sd,
NULL);