Commit bc374e17 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

media: rkisp1: Create link from sensor to ISP at notifier bound time



Links from sensors to the ISP can be created as sensors are bound. Move
the link creation from rkisp1_create_links() to the bound notifier, and
clean up the rkisp1_create_links() function while at it.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarDafna Hirschfeld <dafna@fastmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent af2dabab
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ struct rkisp1_info {
 *				of the v4l2-async API
 *
 * @asd:		async_subdev variable for the sensor
 * @index:		index of the sensor (counting sensor found in DT)
 * @lanes:		number of lanes
 * @mbus_type:		type of bus (currently only CSI2 is supported)
 * @mbus_flags:		media bus (V4L2_MBUS_*) flags
@@ -125,6 +126,7 @@ struct rkisp1_info {
 */
struct rkisp1_sensor_async {
	struct v4l2_async_subdev asd;
	unsigned int index;
	unsigned int lanes;
	enum v4l2_mbus_type mbus_type;
	unsigned int mbus_flags;
+38 −49
Original line number Diff line number Diff line
@@ -111,72 +111,46 @@ struct rkisp1_isr_data {

static int rkisp1_create_links(struct rkisp1_device *rkisp1)
{
	struct media_entity *source, *sink;
	unsigned int flags, source_pad;
	struct v4l2_subdev *sd;
	unsigned int i;
	int ret;

	/* sensor links */
	flags = MEDIA_LNK_FL_ENABLED;
	list_for_each_entry(sd, &rkisp1->v4l2_dev.subdevs, list) {
		if (sd == &rkisp1->isp.sd ||
		    sd == &rkisp1->resizer_devs[RKISP1_MAINPATH].sd ||
		    sd == &rkisp1->resizer_devs[RKISP1_SELFPATH].sd)
			continue;

		ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
						  MEDIA_PAD_FL_SOURCE);
		if (ret < 0) {
			dev_err(rkisp1->dev, "failed to find src pad for %s\n",
				sd->name);
			return ret;
		}
		source_pad = ret;

		ret = media_create_pad_link(&sd->entity, source_pad,
					    &rkisp1->isp.sd.entity,
					    RKISP1_ISP_PAD_SINK_VIDEO,
					    flags);
		if (ret)
			return ret;

		flags = 0;
	}

	flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;

	/* create ISP->RSZ->CAP links */
	for (i = 0; i < 2; i++) {
		source = &rkisp1->isp.sd.entity;
		sink = &rkisp1->resizer_devs[i].sd.entity;
		ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_VIDEO,
					    sink, RKISP1_RSZ_PAD_SINK,
		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;

		source = sink;
		sink = &rkisp1->capture_devs[i].vnode.vdev.entity;
		ret = media_create_pad_link(source, RKISP1_RSZ_PAD_SRC,
					    sink, 0, flags);
		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 */
	source = &rkisp1->params.vnode.vdev.entity;
	sink = &rkisp1->isp.sd.entity;
	ret = media_create_pad_link(source, 0, sink,
				    RKISP1_ISP_PAD_SINK_PARAMS, flags);
	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;

	/* 3A stats links */
	source = &rkisp1->isp.sd.entity;
	sink = &rkisp1->stats.vnode.vdev.entity;
	return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
				     sink, 0, flags);
	return media_create_pad_link(&rkisp1->isp.sd.entity,
				     RKISP1_ISP_PAD_SOURCE_STATS,
				     &rkisp1->stats.vnode.vdev.entity, 0,
				     MEDIA_LNK_FL_ENABLED |
				     MEDIA_LNK_FL_IMMUTABLE);
}

static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
@@ -187,6 +161,7 @@ static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
		container_of(notifier, struct rkisp1_device, notifier);
	struct rkisp1_sensor_async *s_asd =
		container_of(asd, struct rkisp1_sensor_async, asd);
	int source_pad;

	s_asd->pixel_rate_ctrl = v4l2_ctrl_find(sd->ctrl_handler,
						V4L2_CID_PIXEL_RATE);
@@ -206,7 +181,19 @@ static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,

	phy_init(s_asd->dphy);

	return 0;
	/* Create the link to the sensor. */
	source_pad = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
						 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;
	}

	return 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);
}

static void rkisp1_subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
@@ -248,6 +235,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
{
	struct v4l2_async_notifier *ntf = &rkisp1->notifier;
	unsigned int next_id = 0;
	unsigned int index = 0;
	int ret;

	v4l2_async_nf_init(ntf);
@@ -277,6 +265,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
			goto err_parse;
		}

		rk_asd->index = index++;
		rk_asd->mbus_type = vep.bus_type;
		rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
		rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;