File Index
Files and directories
Sign in
FILE

imx-media-dev.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/media/imx/imx-media-dev.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC
  4 *
  5 * Copyright (c) 2016-2019 Mentor Graphics Inc.
  6 */
  7#include <linux/fs.h>
  8#include <linux/module.h>
  9#include <linux/platform_device.h>
 10#include <media/v4l2-async.h>
 11#include <media/v4l2-event.h>
 12#include <media/imx.h>
 13#include "imx-media.h"
 14
 15static inline struct imx_media_dev *notifier2dev(struct v4l2_async_notifier *n)
 16{
 17	return container_of(n, struct imx_media_dev, notifier);
 18}
 19
 20/* async subdev bound notifier */
 21static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
 22				  struct v4l2_subdev *sd,
 23				  struct v4l2_async_connection *asd)
 24{
 25	struct imx_media_dev *imxmd = notifier2dev(notifier);
 26	int ret;
 27
 28	if (sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) {
 29		/* register the IPU internal subdevs */
 30		ret = imx_media_register_ipu_internal_subdevs(imxmd, sd);
 31		if (ret)
 32			return ret;
 33	}
 34
 35	dev_dbg(imxmd->md.dev, "subdev %s bound\n", sd->name);
 36
 37	return 0;
 38}
 39
 40/* async subdev complete notifier */
 41static int imx6_media_probe_complete(struct v4l2_async_notifier *notifier)
 42{
 43	struct imx_media_dev *imxmd = notifier2dev(notifier);
 44	int ret;
 45
 46	/* call the imx5/6/7 common probe completion handler */
 47	ret = imx_media_probe_complete(notifier);
 48	if (ret)
 49		return ret;
 50
 51	mutex_lock(&imxmd->mutex);
 52
 53	imxmd->m2m_vdev = imx_media_csc_scaler_device_init(imxmd);
 54	if (IS_ERR(imxmd->m2m_vdev)) {
 55		ret = PTR_ERR(imxmd->m2m_vdev);
 56		imxmd->m2m_vdev = NULL;
 57		goto unlock;
 58	}
 59
 60	ret = imx_media_csc_scaler_device_register(imxmd->m2m_vdev);
 61unlock:
 62	mutex_unlock(&imxmd->mutex);
 63	return ret;
 64}
 65
 66/* async subdev complete notifier */
 67static const struct v4l2_async_notifier_operations imx_media_notifier_ops = {
 68	.bound = imx_media_subdev_bound,
 69	.complete = imx6_media_probe_complete,
 70};
 71
 72static int imx_media_probe(struct platform_device *pdev)
 73{
 74	struct device *dev = &pdev->dev;
 75	struct device_node *node = dev->of_node;
 76	struct imx_media_dev *imxmd;
 77	int ret;
 78
 79	imxmd = imx_media_dev_init(dev, NULL);
 80	if (IS_ERR(imxmd))
 81		return PTR_ERR(imxmd);
 82
 83	ret = imx_media_add_of_subdevs(imxmd, node);
 84	if (ret) {
 85		v4l2_err(&imxmd->v4l2_dev,
 86			 "add_of_subdevs failed with %d\n", ret);
 87		goto cleanup;
 88	}
 89
 90	ret = imx_media_dev_notifier_register(imxmd, &imx_media_notifier_ops);
 91	if (ret)
 92		goto cleanup;
 93
 94	return 0;
 95
 96cleanup:
 97	v4l2_async_nf_cleanup(&imxmd->notifier);
 98	v4l2_device_unregister(&imxmd->v4l2_dev);
 99	media_device_cleanup(&imxmd->md);
100
101	return ret;
102}
103
104static void imx_media_remove(struct platform_device *pdev)
105{
106	struct imx_media_dev *imxmd =
107		(struct imx_media_dev *)platform_get_drvdata(pdev);
108
109	v4l2_info(&imxmd->v4l2_dev, "Removing imx-media\n");
110
111	if (imxmd->m2m_vdev) {
112		imx_media_csc_scaler_device_unregister(imxmd->m2m_vdev);
113		imxmd->m2m_vdev = NULL;
114	}
115
116	v4l2_async_nf_unregister(&imxmd->notifier);
117	imx_media_unregister_ipu_internal_subdevs(imxmd);
118	v4l2_async_nf_cleanup(&imxmd->notifier);
119	media_device_unregister(&imxmd->md);
120	v4l2_device_unregister(&imxmd->v4l2_dev);
121	media_device_cleanup(&imxmd->md);
122}
123
124static const struct of_device_id imx_media_dt_ids[] = {
125	{ .compatible = "fsl,imx-capture-subsystem" },
126	{ /* sentinel */ }
127};
128MODULE_DEVICE_TABLE(of, imx_media_dt_ids);
129
130static struct platform_driver imx_media_pdrv = {
131	.probe		= imx_media_probe,
132	.remove		= imx_media_remove,
133	.driver		= {
134		.name	= "imx-media",
135		.of_match_table	= imx_media_dt_ids,
136	},
137};
138
139module_platform_driver(imx_media_pdrv);
140
141MODULE_DESCRIPTION("i.MX5/6 v4l2 media controller driver");
142MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
143MODULE_LICENSE("GPL");
~/ Read-only file preview.