source_pad = media_entity_get_fwnode_pad(&sd->entity, s_asd->source_ep,
MEDIA_PAD_FL_SOURCE); if (source_pad < 0) {
dev_err(rkisp1->dev, "failed to find source pad for %s\n",
sd->name); return source_pad;
}
if (s_asd->port == 0) return rkisp1_csi_link_sensor(rkisp1, sd, s_asd, source_pad);
ret = media_create_pad_link(&sd->entity, source_pad,
&rkisp1->isp.sd.entity,
RKISP1_ISP_PAD_SINK_VIDEO,
!s_asd->index ? MEDIA_LNK_FL_ENABLED : 0); if (ret) {
dev_err(rkisp1->dev, "failed to link source pad of %s\n",
sd->name); return ret;
}
/* Select the bus type based on the port. */
port = fwnode_get_parent(ep);
fwnode_property_read_u32(port, "reg", ®);
fwnode_handle_put(port);
switch (reg) { case 0: /* MIPI CSI-2 port */ if (!rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
dev_err(rkisp1->dev, "internal CSI must be available for port 0\n");
ret = -EINVAL; break;
}
vep.bus_type = V4L2_MBUS_CSI2_DPHY; break;
case 1: /* * Parallel port. The bus-type property in DT is * mandatory for port 1, it will be used to determine if * it's PARALLEL or BT656.
*/
vep.bus_type = V4L2_MBUS_UNKNOWN; break;
}
if (ret) break;
/* Parse the endpoint and validate the bus type. */
ret = v4l2_fwnode_endpoint_parse(ep, &vep); if (ret) {
dev_err(rkisp1->dev, "failed to parse endpoint %pfw\n",
ep); break;
}
if (vep.base.port == 1) { if (vep.bus_type != V4L2_MBUS_PARALLEL &&
vep.bus_type != V4L2_MBUS_BT656) {
dev_err(rkisp1->dev, "port 1 must be parallel or BT656\n");
ret = -EINVAL; break;
}
}
/* Add the async subdev to the notifier. */
source = fwnode_graph_get_remote_endpoint(ep); if (!source) {
dev_err(rkisp1->dev, "endpoint %pfw has no remote endpoint\n",
ep);
ret = -ENODEV; break;
}
rk_asd = v4l2_async_nf_add_fwnode(ntf, source, struct rkisp1_sensor_async); if (IS_ERR(rk_asd)) {
fwnode_handle_put(source);
ret = PTR_ERR(rk_asd); break;
}
rkisp1->irqs_enabled = false; /* Make sure the IRQ handler will see the above */
mb();
/* * Wait until any running IRQ handler has returned. The IRQ handler * may get called even after this (as it's a shared interrupt line) * but the 'irqs_enabled' flag will make the handler return immediately.
*/ for (unsignedint il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) { if (rkisp1->irqs[il] == -1) continue;
/* Skip if the irq line is the same as previous */ if (il == 0 || rkisp1->irqs[il - 1] != rkisp1->irqs[il])
synchronize_irq(rkisp1->irqs[il]);
}
if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) { /* Link the CSI receiver to the ISP. */
ret = media_create_pad_link(&rkisp1->csi.sd.entity,
RKISP1_CSI_PAD_SRC,
&rkisp1->isp.sd.entity,
RKISP1_ISP_PAD_SINK_VIDEO,
MEDIA_LNK_FL_ENABLED); if (ret) return ret;
}
/* create ISP->RSZ->CAP links */ for (i = 0; i < dev_count; i++) { struct media_entity *resizer =
&rkisp1->resizer_devs[i].sd.entity; struct media_entity *capture =
&rkisp1->capture_devs[i].vnode.vdev.entity;
ret = media_create_pad_link(&rkisp1->isp.sd.entity,
RKISP1_ISP_PAD_SOURCE_VIDEO,
resizer, RKISP1_RSZ_PAD_SINK,
MEDIA_LNK_FL_ENABLED); if (ret) return ret;
ret = media_create_pad_link(resizer, RKISP1_RSZ_PAD_SRC,
capture, 0,
MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE); if (ret) return ret;
}
/* params links */
ret = media_create_pad_link(&rkisp1->params.vnode.vdev.entity, 0,
&rkisp1->isp.sd.entity,
RKISP1_ISP_PAD_SINK_PARAMS,
MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE); if (ret) return ret;
/* * Call rkisp1_capture_isr() first to handle the frame that * potentially completed using the current frame_sequence number before * it is potentially incremented by rkisp1_isp_isr() in the vertical * sync.
*/
if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED)
ret = IRQ_HANDLED;
if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED)
ret = IRQ_HANDLED;
if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED)
ret = IRQ_HANDLED;
for (i = 0; i < info->clk_size; i++)
rkisp1->clks[i].id = info->clks[i];
ret = devm_clk_bulk_get(dev, info->clk_size, rkisp1->clks); if (ret) return ret;
rkisp1->clk_size = info->clk_size;
if (info->isp_ver == RKISP1_V_IMX8MP) { unsignedint id;
rkisp1->gasket = syscon_regmap_lookup_by_phandle_args(dev->of_node, "fsl,blk-ctrl",
1, &id); if (IS_ERR(rkisp1->gasket)) {
ret = PTR_ERR(rkisp1->gasket);
dev_err(dev, "failed to get gasket: %d\n", ret); return ret;
}
rkisp1->gasket_id = id;
}
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_resume_and_get(&pdev->dev); if (ret) goto err_pm_runtime_disable;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.