0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/of_platform.h>
0010 #include <media/v4l2-ctrls.h>
0011 #include <media/v4l2-device.h>
0012 #include <media/v4l2-fwnode.h>
0013 #include <media/v4l2-subdev.h>
0014 #include <media/videobuf2-dma-contig.h>
0015 #include <linux/of_graph.h>
0016 #include <video/imx-ipu-v3.h>
0017 #include "imx-media.h"
0018
0019 int imx_media_of_add_csi(struct imx_media_dev *imxmd,
0020 struct device_node *csi_np)
0021 {
0022 struct v4l2_async_subdev *asd;
0023 int ret = 0;
0024
0025 if (!of_device_is_available(csi_np)) {
0026 dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__,
0027 csi_np);
0028 return -ENODEV;
0029 }
0030
0031
0032 asd = v4l2_async_nf_add_fwnode(&imxmd->notifier,
0033 of_fwnode_handle(csi_np),
0034 struct v4l2_async_subdev);
0035 if (IS_ERR(asd)) {
0036 ret = PTR_ERR(asd);
0037 if (ret == -EEXIST)
0038 dev_dbg(imxmd->md.dev, "%s: already added %pOFn\n",
0039 __func__, csi_np);
0040 }
0041
0042 return ret;
0043 }
0044 EXPORT_SYMBOL_GPL(imx_media_of_add_csi);
0045
0046 int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
0047 struct device_node *np)
0048 {
0049 struct device_node *csi_np;
0050 int i, ret;
0051
0052 for (i = 0; ; i++) {
0053 csi_np = of_parse_phandle(np, "ports", i);
0054 if (!csi_np)
0055 break;
0056
0057 ret = imx_media_of_add_csi(imxmd, csi_np);
0058 if (ret) {
0059
0060 if (ret == -ENODEV || ret == -EEXIST) {
0061 of_node_put(csi_np);
0062 continue;
0063 }
0064
0065
0066 goto err_out;
0067 }
0068 }
0069
0070 return 0;
0071
0072 err_out:
0073 of_node_put(csi_np);
0074 return ret;
0075 }
0076 EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs);