diff options
| author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-04-20 17:57:25 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-20 08:17:11 -0400 |
| commit | 693f5c40825e91632478624bf0366e6ebf862a25 (patch) | |
| tree | 3c948517fbdbffdde66c2b076a187aa31ca07100 | |
| parent | 97d974226575227ebafdf3ab009f0212d8a7e223 (diff) | |
[media] s5p-fimc: Use v4l2_subdev internal ops to register video nodes
In order to be able to select only FIMC-LITE support, which is added
with subsequent patches, the regular FIMC support is now contained
only in fimc-core.c, fimc-m2m.c and fimc-capture.c files. The graph
and pipeline management is now solely handled in fimc-mdevice.[ch].
This means the FIMC driver can now be excluded with Kconfig option,
leaving only FIMC-LITE and allowing this driver to be reused in SoCs
that have only FIMC-LITE and no regular FIMC IP.
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>
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 142 | ||||
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 13 | ||||
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 7 | ||||
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-m2m.c | 17 | ||||
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-mdevice.c | 89 | ||||
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-mdevice.h | 1 |
6 files changed, 138 insertions, 131 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 0051d8161c6c..b45da2780213 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
| @@ -993,7 +993,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) | |||
| 993 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) | 993 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) |
| 994 | break; | 994 | break; |
| 995 | /* Don't call FIMC subdev operation to avoid nested locking */ | 995 | /* Don't call FIMC subdev operation to avoid nested locking */ |
| 996 | if (sd == fimc->vid_cap.subdev) { | 996 | if (sd == &fimc->vid_cap.subdev) { |
| 997 | struct fimc_frame *ff = &vid_cap->ctx->s_frame; | 997 | struct fimc_frame *ff = &vid_cap->ctx->s_frame; |
| 998 | sink_fmt.format.width = ff->f_width; | 998 | sink_fmt.format.width = ff->f_width; |
| 999 | sink_fmt.format.height = ff->f_height; | 999 | sink_fmt.format.height = ff->f_height; |
| @@ -1489,53 +1489,6 @@ static struct v4l2_subdev_ops fimc_subdev_ops = { | |||
| 1489 | .pad = &fimc_subdev_pad_ops, | 1489 | .pad = &fimc_subdev_pad_ops, |
| 1490 | }; | 1490 | }; |
| 1491 | 1491 | ||
| 1492 | static int fimc_create_capture_subdev(struct fimc_dev *fimc, | ||
| 1493 | struct v4l2_device *v4l2_dev) | ||
| 1494 | { | ||
| 1495 | struct v4l2_subdev *sd; | ||
| 1496 | int ret; | ||
| 1497 | |||
| 1498 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | ||
| 1499 | if (!sd) | ||
| 1500 | return -ENOMEM; | ||
| 1501 | |||
| 1502 | v4l2_subdev_init(sd, &fimc_subdev_ops); | ||
| 1503 | sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
| 1504 | snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id); | ||
| 1505 | |||
| 1506 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; | ||
| 1507 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; | ||
| 1508 | ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, | ||
| 1509 | fimc->vid_cap.sd_pads, 0); | ||
| 1510 | if (ret) | ||
| 1511 | goto me_err; | ||
| 1512 | ret = v4l2_device_register_subdev(v4l2_dev, sd); | ||
| 1513 | if (ret) | ||
| 1514 | goto sd_err; | ||
| 1515 | |||
| 1516 | fimc->vid_cap.subdev = sd; | ||
| 1517 | v4l2_set_subdevdata(sd, fimc); | ||
| 1518 | sd->entity.ops = &fimc_sd_media_ops; | ||
| 1519 | return 0; | ||
| 1520 | sd_err: | ||
| 1521 | media_entity_cleanup(&sd->entity); | ||
| 1522 | me_err: | ||
| 1523 | kfree(sd); | ||
| 1524 | return ret; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | static void fimc_destroy_capture_subdev(struct fimc_dev *fimc) | ||
| 1528 | { | ||
| 1529 | struct v4l2_subdev *sd = fimc->vid_cap.subdev; | ||
| 1530 | |||
| 1531 | if (!sd) | ||
| 1532 | return; | ||
| 1533 | media_entity_cleanup(&sd->entity); | ||
| 1534 | v4l2_device_unregister_subdev(sd); | ||
| 1535 | kfree(sd); | ||
| 1536 | fimc->vid_cap.subdev = NULL; | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | /* Set default format at the sensor and host interface */ | 1492 | /* Set default format at the sensor and host interface */ |
| 1540 | static int fimc_capture_set_default_format(struct fimc_dev *fimc) | 1493 | static int fimc_capture_set_default_format(struct fimc_dev *fimc) |
| 1541 | { | 1494 | { |
| @@ -1554,7 +1507,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc) | |||
| 1554 | } | 1507 | } |
| 1555 | 1508 | ||
| 1556 | /* fimc->lock must be already initialized */ | 1509 | /* fimc->lock must be already initialized */ |
| 1557 | int fimc_register_capture_device(struct fimc_dev *fimc, | 1510 | static int fimc_register_capture_device(struct fimc_dev *fimc, |
| 1558 | struct v4l2_device *v4l2_dev) | 1511 | struct v4l2_device *v4l2_dev) |
| 1559 | { | 1512 | { |
| 1560 | struct video_device *vfd; | 1513 | struct video_device *vfd; |
| @@ -1572,7 +1525,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
| 1572 | ctx->out_path = FIMC_DMA; | 1525 | ctx->out_path = FIMC_DMA; |
| 1573 | ctx->state = FIMC_CTX_CAP; | 1526 | ctx->state = FIMC_CTX_CAP; |
| 1574 | ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); | 1527 | ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); |
| 1575 | ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); | 1528 | ctx->d_frame.fmt = ctx->s_frame.fmt; |
| 1576 | 1529 | ||
| 1577 | vfd = video_device_alloc(); | 1530 | vfd = video_device_alloc(); |
| 1578 | if (!vfd) { | 1531 | if (!vfd) { |
| @@ -1580,8 +1533,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
| 1580 | goto err_vd_alloc; | 1533 | goto err_vd_alloc; |
| 1581 | } | 1534 | } |
| 1582 | 1535 | ||
| 1583 | snprintf(vfd->name, sizeof(vfd->name), "%s.capture", | 1536 | snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id); |
| 1584 | dev_name(&fimc->pdev->dev)); | ||
| 1585 | 1537 | ||
| 1586 | vfd->fops = &fimc_capture_fops; | 1538 | vfd->fops = &fimc_capture_fops; |
| 1587 | vfd->ioctl_ops = &fimc_capture_ioctl_ops; | 1539 | vfd->ioctl_ops = &fimc_capture_ioctl_ops; |
| @@ -1616,18 +1568,22 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
| 1616 | 1568 | ||
| 1617 | vb2_queue_init(q); | 1569 | vb2_queue_init(q); |
| 1618 | 1570 | ||
| 1619 | fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK; | 1571 | vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; |
| 1620 | ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0); | 1572 | ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); |
| 1621 | if (ret) | 1573 | if (ret) |
| 1622 | goto err_ent; | 1574 | goto err_ent; |
| 1623 | ret = fimc_create_capture_subdev(fimc, v4l2_dev); | 1575 | |
| 1576 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | ||
| 1624 | if (ret) | 1577 | if (ret) |
| 1625 | goto err_sd_reg; | 1578 | goto err_vd; |
| 1579 | |||
| 1580 | v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", | ||
| 1581 | vfd->name, video_device_node_name(vfd)); | ||
| 1626 | 1582 | ||
| 1627 | vfd->ctrl_handler = &ctx->ctrl_handler; | 1583 | vfd->ctrl_handler = &ctx->ctrl_handler; |
| 1628 | return 0; | 1584 | return 0; |
| 1629 | 1585 | ||
| 1630 | err_sd_reg: | 1586 | err_vd: |
| 1631 | media_entity_cleanup(&vfd->entity); | 1587 | media_entity_cleanup(&vfd->entity); |
| 1632 | err_ent: | 1588 | err_ent: |
| 1633 | video_device_release(vfd); | 1589 | video_device_release(vfd); |
| @@ -1636,17 +1592,73 @@ err_vd_alloc: | |||
| 1636 | return ret; | 1592 | return ret; |
| 1637 | } | 1593 | } |
| 1638 | 1594 | ||
| 1639 | void fimc_unregister_capture_device(struct fimc_dev *fimc) | 1595 | static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) |
| 1640 | { | 1596 | { |
| 1641 | struct video_device *vfd = fimc->vid_cap.vfd; | 1597 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
| 1598 | int ret; | ||
| 1642 | 1599 | ||
| 1643 | if (vfd) { | 1600 | ret = fimc_register_m2m_device(fimc, sd->v4l2_dev); |
| 1644 | media_entity_cleanup(&vfd->entity); | 1601 | if (ret) |
| 1645 | /* Can also be called if video device was | 1602 | return ret; |
| 1646 | not registered */ | 1603 | |
| 1647 | video_unregister_device(vfd); | 1604 | ret = fimc_register_capture_device(fimc, sd->v4l2_dev); |
| 1605 | if (ret) | ||
| 1606 | fimc_unregister_m2m_device(fimc); | ||
| 1607 | |||
| 1608 | return ret; | ||
| 1609 | } | ||
| 1610 | |||
| 1611 | static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) | ||
| 1612 | { | ||
| 1613 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | ||
| 1614 | |||
| 1615 | if (fimc == NULL) | ||
| 1616 | return; | ||
