diff options
author | Sakari Ailus <sakari.ailus@linux.intel.com> | 2023-10-16 10:38:43 +0300 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2023-11-22 10:56:34 +0100 |
commit | 3c9202e88ffad78f57a418bace2d25f7824a7e4b (patch) | |
tree | addafd1fcd25f5eb1685bcc4985f787d2cf6711d /drivers/media/pci | |
parent | 096bc4f14956c9e963419b292fc28f0dd4e52908 (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')
-rw-r--r-- | drivers/media/pci/intel/ivsc/mei_csi.c | 40 |
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; } |