summaryrefslogtreecommitdiff
path: root/drivers/media/pci/intel
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2023-10-16 10:38:43 +0300
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2023-11-22 10:56:34 +0100
commit3c9202e88ffad78f57a418bace2d25f7824a7e4b (patch)
treeaddafd1fcd25f5eb1685bcc4985f787d2cf6711d /drivers/media/pci/intel
parent096bc4f14956c9e963419b292fc28f0dd4e52908 (diff)
media: ivsc: csi: Check number of lanes on source, too
The IVSC has two CSI-2 ports, one receiver and one transmitter, for passing through the CSI-2 image data. Both have the same number of lanes and this information should be also present in firmware. Check this. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Tested-by: Wentong Wu <wentong.wu@intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'drivers/media/pci/intel')
-rw-r--r--drivers/media/pci/intel/ivsc/mei_csi.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c
index 3f507d0170f9..2ca52390541d 100644
--- a/drivers/media/pci/intel/ivsc/mei_csi.c
+++ b/drivers/media/pci/intel/ivsc/mei_csi.c
@@ -645,27 +645,49 @@ static int mei_csi_parse_firmware(struct mei_csi *csi)
};
struct device *dev = &csi->cldev->dev;
struct v4l2_async_connection *asd;
- struct fwnode_handle *ep;
+ struct fwnode_handle *sink_ep, *source_ep;
int ret;
- ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
- if (!ep) {
- dev_err(dev, "not connected to subdevice\n");
+ sink_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
+ if (!sink_ep) {
+ dev_err(dev, "can't obtain sink endpoint\n");
return -EINVAL;
}
v4l2_async_subdev_nf_init(&csi->notifier, &csi->subdev);
csi->notifier.ops = &mei_csi_notify_ops;
- ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
+ ret = v4l2_fwnode_endpoint_parse(sink_ep, &v4l2_ep);
if (ret) {
- dev_err(dev, "could not parse v4l2 endpoint\n");
+ dev_err(dev, "could not parse v4l2 sink endpoint\n");
goto out_nf_cleanup;
}
csi->nr_of_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
- asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
+ source_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 1, 0, 0);
+ if (!source_ep) {
+ ret = -ENOTCONN;
+ dev_err(dev, "can't obtain source endpoint\n");
+ goto out_nf_cleanup;
+ }
+
+ ret = v4l2_fwnode_endpoint_parse(source_ep, &v4l2_ep);
+ fwnode_handle_put(source_ep);
+ if (ret) {
+ dev_err(dev, "could not parse v4l2 source endpoint\n");
+ goto out_nf_cleanup;
+ }
+
+ if (csi->nr_of_lanes != v4l2_ep.bus.mipi_csi2.num_data_lanes) {
+ ret = -EINVAL;
+ dev_err(dev,
+ "the number of lanes does not match (%u vs. %u)\n",
+ csi->nr_of_lanes, v4l2_ep.bus.mipi_csi2.num_data_lanes);
+ goto out_nf_cleanup;
+ }
+
+ asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, sink_ep,
struct v4l2_async_connection);
if (IS_ERR(asd)) {
ret = PTR_ERR(asd);
@@ -676,13 +698,13 @@ static int mei_csi_parse_firmware(struct mei_csi *csi)
if (ret)
goto out_nf_cleanup;
- fwnode_handle_put(ep);
+ fwnode_handle_put(sink_ep);
return 0;
out_nf_cleanup:
v4l2_async_nf_cleanup(&csi->notifier);
- fwnode_handle_put(ep);
+ fwnode_handle_put(sink_ep);
return ret;
}