drivers/media/platform/ti/cal/cal.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/ti/cal/cal.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/ti/cal/cal.c
Extension
.c
Size
34079 bytes
Lines
1364
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cal_v4l2_async_subdev {
	struct v4l2_async_connection asd; /* Must be first */
	struct cal_camerarx *phy;
};

static inline struct cal_v4l2_async_subdev *
to_cal_asd(struct v4l2_async_connection *asd)
{
	return container_of(asd, struct cal_v4l2_async_subdev, asd);
}

static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
				    struct v4l2_subdev *subdev,
				    struct v4l2_async_connection *asd)
{
	struct cal_camerarx *phy = to_cal_asd(asd)->phy;
	int pad;
	int ret;

	if (phy->source) {
		phy_info(phy, "Rejecting subdev %s (Already set!!)",
			 subdev->name);
		return 0;
	}

	phy_dbg(1, phy, "Using source %s for capture\n", subdev->name);

	pad = media_entity_get_fwnode_pad(&subdev->entity,
					  of_fwnode_handle(phy->source_ep_node),
					  MEDIA_PAD_FL_SOURCE);
	if (pad < 0) {
		phy_err(phy, "Source %s has no connected source pad\n",
			subdev->name);
		return pad;
	}

	ret = media_create_pad_link(&subdev->entity, pad,
				    &phy->subdev.entity, CAL_CAMERARX_PAD_SINK,
				    MEDIA_LNK_FL_IMMUTABLE |
				    MEDIA_LNK_FL_ENABLED);
	if (ret) {
		phy_err(phy, "Failed to create media link for source %s\n",
			subdev->name);
		return ret;
	}

	phy->source = subdev;
	phy->source_pad = pad;

	return 0;
}

static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier)
{
	struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
	unsigned int i;
	int ret;

	for (i = 0; i < cal->num_contexts; ++i) {
		ret = cal_ctx_v4l2_register(cal->ctx[i]);
		if (ret)
			goto err_ctx_unreg;
	}

	if (!cal_mc_api)
		return 0;

	ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
	if (ret)
		goto err_ctx_unreg;

	return 0;

err_ctx_unreg:
	for (; i > 0; --i) {
		if (!cal->ctx[i - 1])
			continue;

		cal_ctx_v4l2_unregister(cal->ctx[i - 1]);
	}

	return ret;
}

static const struct v4l2_async_notifier_operations cal_async_notifier_ops = {
	.bound = cal_async_notifier_bound,
	.complete = cal_async_notifier_complete,
};

static int cal_async_notifier_register(struct cal_dev *cal)

Annotation

Implementation Notes