static int vivid_create_devnodes()

in test-drivers/vivid/vivid-core.c [1379:1720]


static int vivid_create_devnodes(struct platform_device *pdev,
				 struct vivid_dev *dev, int inst,
				 unsigned int cec_tx_bus_cnt,
				 v4l2_std_id tvnorms_cap,
				 v4l2_std_id tvnorms_out,
				 unsigned in_type_counter[4],
				 unsigned out_type_counter[4])
{
	struct video_device *vfd;
	int ret;

	if (dev->has_vid_cap) {
		vfd = &dev->vid_cap_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-vid-cap", inst);
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->vid_cap_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_vid_cap_q;
		vfd->tvnorms = tvnorms_cap;

		/*
		 * Provide a mutex to v4l2 core. It will be used to protect
		 * all fops and v4l2 ioctls.
		 */
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);

#ifdef CONFIG_MEDIA_CONTROLLER
		dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_cap_pad);
		if (ret)
			return ret;
#endif

#ifdef CONFIG_VIDEO_VIVID_CEC
		if (in_type_counter[HDMI]) {
			ret = cec_register_adapter(dev->cec_rx_adap, &pdev->dev);
			if (ret < 0) {
				cec_delete_adapter(dev->cec_rx_adap);
				dev->cec_rx_adap = NULL;
				return ret;
			}
			cec_s_phys_addr(dev->cec_rx_adap, 0, false);
			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n",
				  dev_name(&dev->cec_rx_adap->devnode.dev));
		}
#endif

		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_cap_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
					  video_device_node_name(vfd));
	}

	if (dev->has_vid_out) {
#ifdef CONFIG_VIDEO_VIVID_CEC
		int i;
#endif
		vfd = &dev->vid_out_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-vid-out", inst);
		vfd->vfl_dir = VFL_DIR_TX;
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->vid_out_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_vid_out_q;
		vfd->tvnorms = tvnorms_out;

		/*
		 * Provide a mutex to v4l2 core. It will be used to protect
		 * all fops and v4l2 ioctls.
		 */
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);

#ifdef CONFIG_MEDIA_CONTROLLER
		dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_out_pad);
		if (ret)
			return ret;
#endif

#ifdef CONFIG_VIDEO_VIVID_CEC
		for (i = 0; i < cec_tx_bus_cnt; i++) {
			ret = cec_register_adapter(dev->cec_tx_adap[i], &pdev->dev);
			if (ret < 0) {
				for (; i < cec_tx_bus_cnt; i++) {
					cec_delete_adapter(dev->cec_tx_adap[i]);
					dev->cec_tx_adap[i] = NULL;
				}
				return ret;
			}
			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",
				  dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);
			if (i < out_type_counter[HDMI])
				cec_s_phys_addr(dev->cec_tx_adap[i], (i + 1) << 12, false);
			else
				cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false);
		}
#endif

		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_out_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",
					  video_device_node_name(vfd));
	}

	if (dev->has_vbi_cap) {
		vfd = &dev->vbi_cap_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-vbi-cap", inst);
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->vbi_cap_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_vbi_cap_q;
		vfd->lock = &dev->mutex;
		vfd->tvnorms = tvnorms_cap;
		video_set_drvdata(vfd, dev);

#ifdef CONFIG_MEDIA_CONTROLLER
		dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_cap_pad);
		if (ret)
			return ret;
#endif

		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_cap_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s, supports %s VBI\n",
					  video_device_node_name(vfd),
					  (dev->has_raw_vbi_cap && dev->has_sliced_vbi_cap) ?
					  "raw and sliced" :
					  (dev->has_raw_vbi_cap ? "raw" : "sliced"));
	}

	if (dev->has_vbi_out) {
		vfd = &dev->vbi_out_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-vbi-out", inst);
		vfd->vfl_dir = VFL_DIR_TX;
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->vbi_out_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_vbi_out_q;
		vfd->lock = &dev->mutex;
		vfd->tvnorms = tvnorms_out;
		video_set_drvdata(vfd, dev);

#ifdef CONFIG_MEDIA_CONTROLLER
		dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_out_pad);
		if (ret)
			return ret;
#endif

		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_out_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s, supports %s VBI\n",
					  video_device_node_name(vfd),
					  (dev->has_raw_vbi_out && dev->has_sliced_vbi_out) ?
					  "raw and sliced" :
					  (dev->has_raw_vbi_out ? "raw" : "sliced"));
	}

	if (dev->has_sdr_cap) {
		vfd = &dev->sdr_cap_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-sdr-cap", inst);
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->sdr_cap_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_sdr_cap_q;
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);

#ifdef CONFIG_MEDIA_CONTROLLER
		dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
		ret = media_entity_pads_init(&vfd->entity, 1, &dev->sdr_cap_pad);
		if (ret)
			return ret;
#endif

		ret = video_register_device(vfd, VFL_TYPE_SDR, sdr_cap_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
					  video_device_node_name(vfd));
	}

	if (dev->has_radio_rx) {
		vfd = &dev->radio_rx_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-rad-rx", inst);
		vfd->fops = &vivid_radio_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->radio_rx_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);

		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_rx_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 receiver device registered as %s\n",
					  video_device_node_name(vfd));
	}

	if (dev->has_radio_tx) {
		vfd = &dev->radio_tx_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-rad-tx", inst);
		vfd->vfl_dir = VFL_DIR_TX;
		vfd->fops = &vivid_radio_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->radio_tx_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);

		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_tx_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev, "V4L2 transmitter device registered as %s\n",
					  video_device_node_name(vfd));
	}

	if (dev->has_meta_cap) {
		vfd = &dev->meta_cap_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-meta-cap", inst);
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->meta_cap_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_meta_cap_q;
		vfd->lock = &dev->mutex;
		vfd->tvnorms = tvnorms_cap;
		video_set_drvdata(vfd, dev);
#ifdef CONFIG_MEDIA_CONTROLLER
		dev->meta_cap_pad.flags = MEDIA_PAD_FL_SINK;
		ret = media_entity_pads_init(&vfd->entity, 1,
					     &dev->meta_cap_pad);
		if (ret)
			return ret;
#endif
		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
					    meta_cap_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev,
			  "V4L2 metadata capture device registered as %s\n",
			  video_device_node_name(vfd));
	}

	if (dev->has_meta_out) {
		vfd = &dev->meta_out_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-meta-out", inst);
		vfd->vfl_dir = VFL_DIR_TX;
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->meta_out_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_meta_out_q;
		vfd->lock = &dev->mutex;
		vfd->tvnorms = tvnorms_out;
		video_set_drvdata(vfd, dev);
#ifdef CONFIG_MEDIA_CONTROLLER
		dev->meta_out_pad.flags = MEDIA_PAD_FL_SOURCE;
		ret = media_entity_pads_init(&vfd->entity, 1,
					     &dev->meta_out_pad);
		if (ret)
			return ret;
#endif
		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
					    meta_out_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev,
			  "V4L2 metadata output device registered as %s\n",
			  video_device_node_name(vfd));
	}

	if (dev->has_touch_cap) {
		vfd = &dev->touch_cap_dev;
		snprintf(vfd->name, sizeof(vfd->name),
			 "vivid-%03d-touch-cap", inst);
		vfd->fops = &vivid_fops;
		vfd->ioctl_ops = &vivid_ioctl_ops;
		vfd->device_caps = dev->touch_cap_caps;
		vfd->release = video_device_release_empty;
		vfd->v4l2_dev = &dev->v4l2_dev;
		vfd->queue = &dev->vb_touch_cap_q;
		vfd->tvnorms = tvnorms_cap;
		vfd->lock = &dev->mutex;
		video_set_drvdata(vfd, dev);
#ifdef CONFIG_MEDIA_CONTROLLER
		dev->touch_cap_pad.flags = MEDIA_PAD_FL_SINK;
		ret = media_entity_pads_init(&vfd->entity, 1,
					     &dev->touch_cap_pad);
		if (ret)
			return ret;
#endif
		ret = video_register_device(vfd, VFL_TYPE_TOUCH,
					    touch_cap_nr[inst]);
		if (ret < 0)
			return ret;
		v4l2_info(&dev->v4l2_dev,
			  "V4L2 touch capture device registered as %s\n",
			  video_device_node_name(vfd));
	}

#ifdef CONFIG_MEDIA_CONTROLLER
	/* Register the media device */
	ret = media_device_register(&dev->mdev);
	if (ret) {
		dev_err(dev->mdev.dev,
			"media device register failed (err=%d)\n", ret);
		return ret;
	}
#endif
	return 0;
}