| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Xilinx Video DMA |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> |
|---|
| 8 | 9 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | 10 | */ |
|---|
| 14 | 11 | |
|---|
| 15 | 12 | #include <linux/dma/xilinx_dma.h> |
|---|
| .. | .. |
|---|
| 494 | 491 | struct v4l2_fh *vfh = file->private_data; |
|---|
| 495 | 492 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); |
|---|
| 496 | 493 | |
|---|
| 497 | | - cap->device_caps = V4L2_CAP_STREAMING; |
|---|
| 494 | + cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING | |
|---|
| 495 | + V4L2_CAP_DEVICE_CAPS; |
|---|
| 498 | 496 | |
|---|
| 499 | | - if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
|---|
| 500 | | - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
|---|
| 501 | | - else |
|---|
| 502 | | - cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT; |
|---|
| 503 | | - |
|---|
| 504 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
|---|
| 505 | | - | dma->xdev->v4l2_caps; |
|---|
| 506 | | - |
|---|
| 507 | | - strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); |
|---|
| 508 | | - strlcpy(cap->card, dma->video.name, sizeof(cap->card)); |
|---|
| 509 | | - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u", |
|---|
| 510 | | - dma->xdev->dev->of_node->name, dma->port); |
|---|
| 497 | + strscpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); |
|---|
| 498 | + strscpy(cap->card, dma->video.name, sizeof(cap->card)); |
|---|
| 499 | + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%pOFn:%u", |
|---|
| 500 | + dma->xdev->dev->of_node, dma->port); |
|---|
| 511 | 501 | |
|---|
| 512 | 502 | return 0; |
|---|
| 513 | 503 | } |
|---|
| .. | .. |
|---|
| 527 | 517 | return -EINVAL; |
|---|
| 528 | 518 | |
|---|
| 529 | 519 | f->pixelformat = dma->format.pixelformat; |
|---|
| 530 | | - strlcpy(f->description, dma->fmtinfo->description, |
|---|
| 531 | | - sizeof(f->description)); |
|---|
| 532 | 520 | |
|---|
| 533 | 521 | return 0; |
|---|
| 534 | 522 | } |
|---|
| .. | .. |
|---|
| 693 | 681 | dma->video.fops = &xvip_dma_fops; |
|---|
| 694 | 682 | dma->video.v4l2_dev = &xdev->v4l2_dev; |
|---|
| 695 | 683 | dma->video.queue = &dma->queue; |
|---|
| 696 | | - snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u", |
|---|
| 697 | | - xdev->dev->of_node->name, |
|---|
| 684 | + snprintf(dma->video.name, sizeof(dma->video.name), "%pOFn %s %u", |
|---|
| 685 | + xdev->dev->of_node, |
|---|
| 698 | 686 | type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input", |
|---|
| 699 | 687 | port); |
|---|
| 700 | | - dma->video.vfl_type = VFL_TYPE_GRABBER; |
|---|
| 688 | + dma->video.vfl_type = VFL_TYPE_VIDEO; |
|---|
| 701 | 689 | dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE |
|---|
| 702 | 690 | ? VFL_DIR_RX : VFL_DIR_TX; |
|---|
| 703 | 691 | dma->video.release = video_device_release_empty; |
|---|
| 704 | 692 | dma->video.ioctl_ops = &xvip_dma_ioctl_ops; |
|---|
| 705 | 693 | dma->video.lock = &dma->lock; |
|---|
| 694 | + dma->video.device_caps = V4L2_CAP_STREAMING; |
|---|
| 695 | + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
|---|
| 696 | + dma->video.device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
|---|
| 697 | + else |
|---|
| 698 | + dma->video.device_caps |= V4L2_CAP_VIDEO_OUTPUT; |
|---|
| 706 | 699 | |
|---|
| 707 | 700 | video_set_drvdata(&dma->video, dma); |
|---|
| 708 | 701 | |
|---|
| .. | .. |
|---|
| 732 | 725 | |
|---|
| 733 | 726 | /* ... and the DMA channel. */ |
|---|
| 734 | 727 | snprintf(name, sizeof(name), "port%u", port); |
|---|
| 735 | | - dma->dma = dma_request_slave_channel(dma->xdev->dev, name); |
|---|
| 736 | | - if (dma->dma == NULL) { |
|---|
| 737 | | - dev_err(dma->xdev->dev, "no VDMA channel found\n"); |
|---|
| 738 | | - ret = -ENODEV; |
|---|
| 728 | + dma->dma = dma_request_chan(dma->xdev->dev, name); |
|---|
| 729 | + if (IS_ERR(dma->dma)) { |
|---|
| 730 | + ret = PTR_ERR(dma->dma); |
|---|
| 731 | + if (ret != -EPROBE_DEFER) |
|---|
| 732 | + dev_err(dma->xdev->dev, "no VDMA channel found\n"); |
|---|
| 739 | 733 | goto error; |
|---|
| 740 | 734 | } |
|---|
| 741 | 735 | |
|---|
| 742 | 736 | dma->align = 1 << dma->dma->device->copy_align; |
|---|
| 743 | 737 | |
|---|
| 744 | | - ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1); |
|---|
| 738 | + ret = video_register_device(&dma->video, VFL_TYPE_VIDEO, -1); |
|---|
| 745 | 739 | if (ret < 0) { |
|---|
| 746 | 740 | dev_err(dma->xdev->dev, "failed to register video device\n"); |
|---|
| 747 | 741 | goto error; |
|---|
| .. | .. |
|---|
| 759 | 753 | if (video_is_registered(&dma->video)) |
|---|
| 760 | 754 | video_unregister_device(&dma->video); |
|---|
| 761 | 755 | |
|---|
| 762 | | - if (dma->dma) |
|---|
| 756 | + if (!IS_ERR_OR_NULL(dma->dma)) |
|---|
| 763 | 757 | dma_release_channel(dma->dma); |
|---|
| 764 | 758 | |
|---|
| 765 | 759 | media_entity_cleanup(&dma->video.entity); |
|---|