Beispiel #1
0
static int rvin_graph_notify_complete(struct v4l2_async_notifier *notifier)
{
	struct rvin_dev *vin = notifier_to_vin(notifier);
	int ret;

	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
	if (ret < 0) {
		vin_err(vin, "Failed to register subdev nodes\n");
		return ret;
	}

	if (!rvin_mbus_supported(vin)) {
		vin_err(vin, "No supported mediabus format found\n");
		return -EINVAL;
	}

	return rvin_v4l2_probe(vin);
}
Beispiel #2
0
static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
{
	struct rvin_dev *vin = notifier_to_vin(notifier);
	int ret;

	/* Verify subdevices mbus format */
	if (!rvin_mbus_supported(&vin->digital)) {
		vin_err(vin, "Unsupported media bus format for %s\n",
			vin->digital.subdev->name);
		return -EINVAL;
	}

	vin_dbg(vin, "Found media bus format for %s: %d\n",
		vin->digital.subdev->name, vin->digital.code);

	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
	if (ret < 0) {
		vin_err(vin, "Failed to register subdev nodes\n");
		return ret;
	}

	return rvin_v4l2_probe(vin);
}
static int atomisp_register_entities(struct atomisp_device *isp)
{
	int ret = 0;
	unsigned int i;

	isp->media_dev.dev = isp->dev;

	strlcpy(isp->media_dev.model, "Intel Atom ISP",
		sizeof(isp->media_dev.model));

	ret = media_device_register(&isp->media_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev, "%s: Media device registration "
			 "failed (%d)\n", __func__, ret);
		return ret;
	}

	isp->v4l2_dev.mdev = &isp->media_dev;
	ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"%s: V4L2 device registration failed (%d)\n",
			__func__, ret);
		goto v4l2_device_failed;
	}

	ret = atomisp_subdev_probe(isp);
	if (ret < 0)
		goto csi_and_subdev_probe_failed;

	/* Register internal entities */
	for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
		ret = atomisp_mipi_csi2_register_entities(&isp->csi2_port[i],
								&isp->v4l2_dev);
		if (ret == 0)
			continue;

		/* error case */
		v4l2_err(&atomisp_dev,
			"failed to register the CSI port: %d\n", i);
		/* deregister all registered CSI ports */
		while (i--)
			atomisp_mipi_csi2_unregister_entities(
							&isp->csi2_port[i]);

		goto csi_and_subdev_probe_failed;
	}

	ret =
	atomisp_file_input_register_entities(&isp->file_dev, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"atomisp_file_input_register_entities\n");
		goto file_input_register_failed;
	}

	ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev, "atomisp_tpg_register_entities\n");
		goto tpg_register_failed;
	}

	for (i = 0; i < isp->num_of_streams; i++) {
		ret =
		atomisp_subdev_register_entities(&isp->isp_subdev[i],
						 &isp->v4l2_dev);
		if (ret < 0) {
			v4l2_err(&atomisp_dev,
				"atomisp_subdev_register_entities fail\n");
			goto subdev_register_failed;
		}
	}

	for (i = 0; i < isp->input_cnt; i++) {
		if (isp->inputs[i].port >= ATOMISP_CAMERA_NR_PORTS) {
			v4l2_err(&atomisp_dev,
					"isp->inputs port %d not supported\n",
					isp->inputs[i].port);
			ret = -EINVAL;
			goto link_failed;
		}

		ret = media_entity_create_link(
			&isp->inputs[i].camera->entity, 0,
			&isp->csi2_port[isp->inputs[i].port].subdev.entity,
			CSI2_PAD_SINK,
			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
		if (ret < 0) {
			dev_err(isp->dev,
				"link create from sensor to csi-2 receiver failed\n");
			goto link_failed;
		}
	}

	v4l2_dbg(1, dbg_level, &atomisp_dev,
		"FILE_INPUT enable, camera_cnt: %d\n", isp->input_cnt);
	isp->inputs[isp->input_cnt].type = FILE_INPUT;
	isp->inputs[isp->input_cnt].port = -1;
	isp->inputs[isp->input_cnt].shading_table = NULL;
	isp->inputs[isp->input_cnt].morph_table = NULL;
	isp->inputs[isp->input_cnt++].camera = &isp->file_dev.sd;

	if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) {
		v4l2_dbg(1, dbg_level, &atomisp_dev,
			"TPG detected, camera_cnt: %d\n", isp->input_cnt);
		isp->inputs[isp->input_cnt].type = TEST_PATTERN;
		isp->inputs[isp->input_cnt].port = -1;
		isp->inputs[isp->input_cnt].shading_table = NULL;
		isp->inputs[isp->input_cnt].morph_table = NULL;
		isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd;
	} else {
		v4l2_warn(&atomisp_dev,
			"too many atomisp inputs, TPG ignored.\n");
	}

	ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
	if (ret < 0)
		goto link_failed;

	return ret;

link_failed:
	for (i = 0; i < isp->num_of_streams; i++)
		atomisp_subdev_unregister_entities(&isp->isp_subdev[i]);
subdev_register_failed:
	while (i--)
		atomisp_subdev_unregister_entities(&isp->isp_subdev[i]);
	atomisp_tpg_unregister_entities(&isp->tpg);
tpg_register_failed:
	atomisp_file_input_unregister_entities(&isp->file_dev);
file_input_register_failed:
	for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++)
		atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]);
csi_and_subdev_probe_failed:
	v4l2_device_unregister(&isp->v4l2_dev);
v4l2_device_failed:
	media_device_unregister(&isp->media_dev);
	return ret;
}
Beispiel #4
0
static int s3c_camif_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct s3c_camif_plat_data *pdata = dev->platform_data;
	struct s3c_camif_drvdata *drvdata;
	struct camif_dev *camif;
	struct resource *mres;
	int ret = 0;

	camif = devm_kzalloc(dev, sizeof(*camif), GFP_KERNEL);
	if (!camif)
		return -ENOMEM;

	spin_lock_init(&camif->slock);
	mutex_init(&camif->lock);

	camif->dev = dev;

	if (!pdata || !pdata->gpio_get || !pdata->gpio_put) {
		dev_err(dev, "wrong platform data\n");
		return -EINVAL;
	}

	camif->pdata = *pdata;
	drvdata = (void *)platform_get_device_id(pdev)->driver_data;
	camif->variant = drvdata->variant;

	mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	camif->io_base = devm_ioremap_resource(dev, mres);
	if (IS_ERR(camif->io_base))
		return PTR_ERR(camif->io_base);

	ret = camif_request_irqs(pdev, camif);
	if (ret < 0)
		return ret;

	ret = pdata->gpio_get();
	if (ret < 0)
		return ret;

	ret = s3c_camif_create_subdev(camif);
	if (ret < 0)
		goto err_sd;

	ret = camif_clk_get(camif);
	if (ret < 0)
		goto err_clk;

	platform_set_drvdata(pdev, camif);
	clk_set_rate(camif->clock[CLK_CAM],
			camif->pdata.sensor.clock_frequency);

	dev_info(dev, "sensor clock frequency: %lu\n",
		 clk_get_rate(camif->clock[CLK_CAM]));
	/*
	 * Set initial pixel format, resolution and crop rectangle.
	 * Must be done before a sensor subdev is registered as some
	 * settings are overrode with values from sensor subdev.
	 */
	s3c_camif_set_defaults(camif);

	pm_runtime_enable(dev);

	ret = pm_runtime_get_sync(dev);
	if (ret < 0)
		goto err_pm;

	/* Initialize contiguous memory allocator */
	camif->alloc_ctx = vb2_dma_contig_init_ctx(dev);
	if (IS_ERR(camif->alloc_ctx)) {
		ret = PTR_ERR(camif->alloc_ctx);
		goto err_alloc;
	}

	ret = camif_media_dev_init(camif);
	if (ret < 0)
		goto err_mdev;

	ret = camif_register_sensor(camif);
	if (ret < 0)
		goto err_sens;

	ret = v4l2_device_register_subdev(&camif->v4l2_dev, &camif->subdev);
	if (ret < 0)
		goto err_sens;

	ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev);
	if (ret < 0)
		goto err_sens;

	ret = camif_register_video_nodes(camif);
	if (ret < 0)
		goto err_sens;

	ret = camif_create_media_links(camif);
	if (ret < 0)
		goto err_sens;

	ret = media_device_register(&camif->media_dev);
	if (ret < 0)
		goto err_sens;

	pm_runtime_put(dev);
	return 0;

err_sens:
	v4l2_device_unregister(&camif->v4l2_dev);
	media_device_unregister(&camif->media_dev);
	media_device_cleanup(&camif->media_dev);
	camif_unregister_media_entities(camif);
err_mdev:
	vb2_dma_contig_cleanup_ctx(camif->alloc_ctx);
err_alloc:
	pm_runtime_put(dev);
	pm_runtime_disable(dev);
err_pm:
	camif_clk_put(camif);
err_clk:
	s3c_camif_unregister_subdev(camif);
err_sd:
	pdata->gpio_put();
	return ret;
}
static int atomisp_register_entities(struct atomisp_device *isp)
{
	int ret = 0;
	int i = 0;
	struct v4l2_subdev *subdev = NULL;
	struct media_entity *input = NULL;
	unsigned int flags;
	unsigned int pad;

	isp->media_dev.dev = isp->dev;

	strlcpy(isp->media_dev.model, "Intel Atom ISP",
		sizeof(isp->media_dev.model));

	ret = media_device_register(&isp->media_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev, "%s: Media device registration "
			 "failed (%d)\n", __func__, ret);
		return ret;
	}

	isp->v4l2_dev.mdev = &isp->media_dev;
	ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"%s: V4L2 device registration failed (%d)\n",
			__func__, ret);
		goto v4l2_device_failed;
	}

	/*
	 * fixing me!
	 * not sub device exists on
	 * mrfld vp
	 */
	if (!IS_MRFLD) {
		ret = atomisp_subdev_probe(isp);
		if (ret < 0)
			goto lane4_and_subdev_probe_failed;
	}

	/* Register internal entities */
	ret =
	atomisp_mipi_csi2_register_entities(&isp->csi2_4p, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"atomisp_mipi_csi2_register_entities 4p\n");
		goto lane4_and_subdev_probe_failed;
	}

	ret =
	atomisp_mipi_csi2_register_entities(&isp->csi2_1p, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"atomisp_mipi_csi2_register_entities 1p\n");
		goto lane1_failed;
	}

	ret =
	atomisp_file_input_register_entities(&isp->file_dev, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"atomisp_file_input_register_entities\n");
		goto file_input_register_failed;
	}

	ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev, "atomisp_tpg_register_entities\n");
		goto tpg_register_failed;
	}

	ret =
	atomisp_subdev_register_entities(&isp->isp_subdev, &isp->v4l2_dev);
	if (ret < 0) {
		v4l2_err(&atomisp_dev,
			"atomisp_subdev_register_entities fail\n");
		goto subdev_register_failed;
	}

	for (i = 0; i < isp->input_cnt; i++) {
		subdev = isp->inputs[i].camera;
		switch (isp->inputs[i].port) {
		case ATOMISP_CAMERA_PORT_PRIMARY:
			input = &isp->csi2_4p.subdev.entity;
			pad = CSI2_PAD_SINK;
			flags = 0;
			break;
		case ATOMISP_CAMERA_PORT_SECONDARY:
			input = &isp->csi2_1p.subdev.entity;
			pad = CSI2_PAD_SINK;
			flags = 0;
			break;
		default:
			v4l2_dbg(1, dbg_level, &atomisp_dev,
				  "isp->inputs type not supported\n");
			break;
		}
		ret = media_entity_create_link(&subdev->entity, 0,
			input, pad, flags);
		if (ret < 0) {
			v4l2_err(&atomisp_dev,
				"snr to mipi csi link failed\n");
			goto link_failed;
		}
	}

	v4l2_dbg(1, dbg_level, &atomisp_dev,
		"FILE_INPUT enable, camera_cnt: %d\n", isp->input_cnt);
	isp->inputs[isp->input_cnt].type = FILE_INPUT;
	isp->inputs[isp->input_cnt].port = -1;
	isp->inputs[isp->input_cnt].shading_table = NULL;
	isp->inputs[isp->input_cnt].morph_table = NULL;
	isp->inputs[isp->input_cnt++].camera = &isp->file_dev.sd;

	if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) {
		v4l2_dbg(1, dbg_level, &atomisp_dev,
			"TPG detected, camera_cnt: %d\n", isp->input_cnt);
		isp->inputs[isp->input_cnt].type = TEST_PATTERN;
		isp->inputs[isp->input_cnt].port = -1;
		isp->inputs[isp->input_cnt].shading_table = NULL;
		isp->inputs[isp->input_cnt].morph_table = NULL;
		isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd;
	} else {
		v4l2_warn(&atomisp_dev,
			"too many atomisp inputs, TPG ignored.\n");
	}

	ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
	if (ret < 0)
		goto link_failed;

	return ret;

link_failed:
	atomisp_subdev_unregister_entities(&isp->isp_subdev);
subdev_register_failed:
	atomisp_tpg_unregister_entities(&isp->tpg);
tpg_register_failed:
	atomisp_file_input_unregister_entities(&isp->file_dev);
file_input_register_failed:
	atomisp_mipi_csi2_unregister_entities(&isp->csi2_1p);
lane1_failed:
	atomisp_mipi_csi2_unregister_entities(&isp->csi2_4p);
lane4_and_subdev_probe_failed:
	v4l2_device_unregister(&isp->v4l2_dev);
v4l2_device_failed:
	media_device_unregister(&isp->media_dev);
	return ret;
}
static int __devinit fimc_md_probe(struct platform_device *pdev)
{
	struct v4l2_device *v4l2_dev;
	struct fimc_md *fmd;
	int ret;

	fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
	if (!fmd)
		return -ENOMEM;

	spin_lock_init(&fmd->slock);
	fmd->pdev = pdev;

	strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
		sizeof(fmd->media_dev.model));
	fmd->media_dev.link_notify = fimc_md_link_notify;
	fmd->media_dev.dev = &pdev->dev;

	v4l2_dev = &fmd->v4l2_dev;
	v4l2_dev->mdev = &fmd->media_dev;
	v4l2_dev->notify = fimc_sensor_notify;
	snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
		 dev_name(&pdev->dev));

	ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
	if (ret < 0) {
		v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
		return ret;
	}
	ret = media_device_register(&fmd->media_dev);
	if (ret < 0) {
		v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
		goto err2;
	}
	ret = fimc_md_get_clocks(fmd);
	if (ret)
		goto err3;

	fmd->user_subdev_api = false;
	ret = fimc_md_register_platform_entities(fmd);
	if (ret)
		goto err3;

	if (pdev->dev.platform_data) {
		ret = fimc_md_register_sensor_entities(fmd);
		if (ret)
			goto err3;
	}
	ret = fimc_md_create_links(fmd);
	if (ret)
		goto err3;
	ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
	if (ret)
		goto err3;
	ret = fimc_md_register_video_nodes(fmd);
	if (ret)
		goto err3;

	ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
	if (!ret) {
		platform_set_drvdata(pdev, fmd);
		return 0;
	}
err3:
	media_device_unregister(&fmd->media_dev);
	fimc_md_put_clocks(fmd);
	fimc_md_unregister_entities(fmd);
err2:
	v4l2_device_unregister(&fmd->v4l2_dev);
	return ret;
}
Beispiel #7
0
static int unicam_register_entities(struct unicam_device *unicam)
{
	struct unicam_platform_data *pdata = unicam->pdata;
	struct unicam_v4l2_subdevs_groups *subdevs;
	int ret, i;

	/* media device registration */
	unicam->media_dev.dev = unicam->dev;
	strlcpy(unicam->media_dev.model, "Broadcom Kona Unicam",
			sizeof(unicam->media_dev.model));
	unicam->media_dev.hw_revision = unicam->revision;
	unicam->media_dev.link_notify = unicam_pipeline_link_notify;
	ret = media_device_register(&unicam->media_dev);
	if (ret < 0) {
		dev_err(unicam->dev, "media device registration failed (%d)\n",
				ret);
		return ret;

	}

	/* v4l2 device registration */
	unicam->v4l2_dev.mdev = &unicam->media_dev;
	ret = v4l2_device_register(unicam->dev, &unicam->v4l2_dev);
	if (ret < 0) {
		dev_err(unicam->dev, "V4L2 device registration failed (%d)\n",
				ret);
		goto done;
	}

	/* now register all enitites */
	ret = kona_unicam_csi2_register_entities(&unicam->csi2a,
			&unicam->v4l2_dev);
	if (ret < 0) {
		dev_err(unicam->dev, "failed to register csi2a entities (%d)\n",
				ret);
		goto done;
	}

	/* now register external entities */
	for (i = 0; i < pdata->num_subdevs; i++) {
		struct v4l2_subdev *sensor;
		struct media_entity *input;
		unsigned int pad;

		subdevs = &pdata->subdevs[i];

		sensor = unicam_register_subdev_group(unicam,
				subdevs->i2c_info);
		if (sensor == NULL)
			continue;

		sensor->host_priv = subdevs;

		/*
		 * connect the sensor to the correct interface module.
		 * we only have one receiver here
		 */
		switch (subdevs->interface) {
		case UNICAM_INTERFACE_CSI2_PHY1:
			input = &unicam->csi2a.subdev.entity;
			pad = CSI2_PAD_SINK;
			break;

		default:
			dev_err(unicam->dev, "invalid interface type %u\n",
					subdevs->interface);
			goto done;
		}

		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
				0);

		if (ret < 0)
			goto done;
	};

	ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev);

done:
	if (ret < 0)
		unicam_unregister_entities(unicam);

	return ret;
}
Beispiel #8
0
static int fimc_md_probe(struct platform_device *pdev)
{
	struct s5p_platform_fimc *pdata = pdev->dev.platform_data;
	struct v4l2_device *v4l2_dev;
	struct fimc_md *fmd;
	int ret;

	fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
	if (!fmd)
		return -ENOMEM;

	spin_lock_init(&fmd->slock);
	fmd->pdev = pdev;

	strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
		sizeof(fmd->media_dev.model));
	fmd->media_dev.link_notify = fimc_md_link_notify;
	fmd->media_dev.dev = &pdev->dev;

	v4l2_dev = &fmd->v4l2_dev;
	v4l2_dev->mdev = &fmd->media_dev;
	v4l2_dev->notify = fimc_sensor_notify;
	snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
		 dev_name(&pdev->dev));

	ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
	if (ret < 0) {
		v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
		return ret;
	}
	ret = media_device_register(&fmd->media_dev);
	if (ret < 0) {
		v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
		goto err_md;
	}
	ret = fimc_md_get_clocks(fmd, pdata);
	if (ret)
		goto err_clk;

	fmd->user_subdev_api = true;

	/* Protect the media graph while we're registering entities */
	mutex_lock(&fmd->media_dev.graph_mutex);

	ret = fimc_md_register_platform_entities(fmd);
	if (ret)
		goto err_unlock;

	if (pdata) {
		ret = fimc_md_register_sensor_entities(fmd);
		if (ret)
			goto err_unlock;
	}
	ret = fimc_md_create_links(fmd);
	if (ret)
		goto err_unlock;
	ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
	if (ret)
		goto err_unlock;

	ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
	if (ret)
		goto err_unlock;

	platform_set_drvdata(pdev, fmd);
	mutex_unlock(&fmd->media_dev.graph_mutex);
	return 0;

err_unlock:
	mutex_unlock(&fmd->media_dev.graph_mutex);
err_clk:
	media_device_unregister(&fmd->media_dev);
	fimc_md_put_clocks(fmd);
	fimc_md_unregister_entities(fmd);
err_md:
	v4l2_device_unregister(&fmd->v4l2_dev);
	return ret;
}
Beispiel #9
0
static int iss_register_entities(struct iss_device *iss)
{
	struct iss_platform_data *pdata = iss->pdata;
	struct iss_v4l2_subdevs_group *subdevs;
	int ret;

	iss->media_dev.dev = iss->dev;
	strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
		sizeof(iss->media_dev.model));
	iss->media_dev.hw_revision = iss->revision;
	iss->media_dev.link_notify = iss_pipeline_link_notify;
	ret = media_device_register(&iss->media_dev);
	if (ret < 0) {
		dev_err(iss->dev, "Media device registration failed (%d)\n",
			ret);
		return ret;
	}

	iss->v4l2_dev.mdev = &iss->media_dev;
	ret = v4l2_device_register(iss->dev, &iss->v4l2_dev);
	if (ret < 0) {
		dev_err(iss->dev, "V4L2 device registration failed (%d)\n",
			ret);
		goto done;
	}

	/* Register internal entities */
	ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev);
	if (ret < 0)
		goto done;

	ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev);
	if (ret < 0)
		goto done;

	ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev);
	if (ret < 0)
		goto done;

	ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev);
	if (ret < 0)
		goto done;

	ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev);
	if (ret < 0)
		goto done;

	/* Register external entities */
	for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
		struct v4l2_subdev *sensor;
		struct media_entity *input;
		unsigned int flags;
		unsigned int pad;

		sensor = iss_register_subdev_group(iss, subdevs->subdevs);
		if (!sensor)
			continue;

		sensor->host_priv = subdevs;

		/* Connect the sensor to the correct interface module.
		 * CSI2a receiver through CSIPHY1, or
		 * CSI2b receiver through CSIPHY2
		 */
		switch (subdevs->interface) {
		case ISS_INTERFACE_CSI2A_PHY1:
			input = &iss->csi2a.subdev.entity;
			pad = CSI2_PAD_SINK;
			flags = MEDIA_LNK_FL_IMMUTABLE
			      | MEDIA_LNK_FL_ENABLED;
			break;

		case ISS_INTERFACE_CSI2B_PHY2:
			input = &iss->csi2b.subdev.entity;
			pad = CSI2_PAD_SINK;
			flags = MEDIA_LNK_FL_IMMUTABLE
			      | MEDIA_LNK_FL_ENABLED;
			break;

		default:
			dev_err(iss->dev, "invalid interface type %u\n",
				subdevs->interface);
			ret = -EINVAL;
			goto done;
		}

		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
					       flags);
		if (ret < 0)
			goto done;
	}

	ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev);

done:
	if (ret < 0)
		iss_unregister_entities(iss);

	return ret;
}
Beispiel #10
0
static int __devinit nxp_v4l2_probe(struct platform_device *pdev)
{
    struct v4l2_device *v4l2_dev;
    struct nxp_v4l2 *nxp_v4l2;
    struct nxp_v4l2_platformdata *pdata;
#ifdef CONFIG_VIDEO_NXP_CAPTURE
    struct nxp_capture_platformdata *capture_pdata;
    struct nxp_capture *capture;
    int i;
#endif
#ifdef CONFIG_NXP_M2M_SCALER
    struct nxp_scaler *scaler;
#endif

#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
		struct nxp_loopback_sensor *loopback_sensor = NULL;
#endif

    int ret;

    pr_debug("%s entered\n", __func__);

    pdata = pdev->dev.platform_data;
    if (!pdata) {
        dev_err(&pdev->dev, "can't get platformdata\n");
        return -EINVAL;
    }

    nxp_v4l2 = kzalloc(sizeof(*nxp_v4l2), GFP_KERNEL);
    if (!nxp_v4l2) {
        pr_err("%s error: fail to kzalloc(size %d)\n", __func__, sizeof(struct nxp_v4l2));
        return -ENOMEM;
    }

    nxp_v4l2->pdev = pdev;
    nxp_v4l2->pdata = pdata;

    snprintf(nxp_v4l2->media_dev.model, sizeof(nxp_v4l2->media_dev.model), "%s",
            dev_name(&pdev->dev));

    nxp_v4l2->media_dev.dev = &pdev->dev;

    v4l2_dev       = &nxp_v4l2->v4l2_dev;
    v4l2_dev->mdev = &nxp_v4l2->media_dev;
    snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
            dev_name(&pdev->dev));

    /* alloc context : use uncached area */
    nxp_v4l2->alloc_ctx =
        vb2_ion_create_context(&pdev->dev, SZ_4K, VB2ION_CTX_UNCACHED);
    if (!nxp_v4l2->alloc_ctx) {
        pr_err("%s: failed to ion alloc context\n", __func__);
        ret = -ENOMEM;
        goto err_alloc_ctx;
    }

    ret = v4l2_device_register(&pdev->dev, &nxp_v4l2->v4l2_dev);
    if (ret < 0) {
        pr_err("%s: failed to register v4l2_device: %d\n", __func__, ret);
        goto err_v4l2_reg;
    }

    ret = media_device_register(&nxp_v4l2->media_dev);
    if (ret < 0) {
        pr_err("%s: failed to register media_device: %d\n", __func__, ret);
        goto err_media_reg;
    }

    __me = nxp_v4l2;

#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
		loopback_sensor =	create_nxp_loopback_sensor(pdata->captures);
		if (!loopback_sensor) {
				pr_err("%s: failed to create_nxp_loopback_sensor()\n", __func__);
				ret = -EINVAL;
				goto err_loopback_sensor_create;
		}

		ret = register_nxp_loopback_sensor(loopback_sensor);
		if (ret < 0) {
				pr_err("%s: failed to register_nxp_loopback_sensor()\n", __func__);
				goto err_loopback_sensor_create;
		}

    nxp_v4l2->loopback_sensor = loopback_sensor;
#endif

#ifdef CONFIG_VIDEO_NXP_CAPTURE
    /* capture */
    for (capture_pdata = pdata->captures, i = 0;
            capture_pdata->sensor;
            capture_pdata++, i++) {
        /* TODO : psw0523 test for module index problem !!! */
        /* capture = create_nxp_capture(i, capture_pdata); */
        capture = create_nxp_capture(i, capture_pdata->module, capture_pdata);
        if (!capture) {
            pr_err("%s: failed to %dth create_nxp_capture()\n", __func__, i);
            ret = -EINVAL;
            goto err_capture_create;
        }

        ret = register_nxp_capture(capture);
        if (ret < 0) {
            pr_err("%s: failed to %dth register_nxp_capture()\n", __func__, i);
            goto err_capture_create;
        }

        nxp_v4l2->capture[i] = capture;
    }
#endif

#ifdef CONFIG_NXP_M2M_SCALER
    /* m2m */
    scaler = create_nxp_scaler();
    if (!scaler) {
        pr_err("%s: failed to create_nxp_scaler()\n", __func__);
        ret = -ENOMEM;
#ifdef CONFIG_VIDEO_NXP_CAPTURE
        goto err_capture_create;
#else
        goto err_media_reg;
#endif
    }

    ret = register_nxp_scaler(scaler);
    if (ret < 0) {
        pr_err("%s: failed to nxp_scaler_register()\n", __func__);
        goto err_register_scaler;
    }
    nxp_v4l2->scaler = scaler;
#endif

#ifdef CONFIG_VIDEO_NXP_OUT
    /* out */
    nxp_v4l2->out = create_nxp_out(pdata->out);
    if (!nxp_v4l2->out) {
        pr_err("%s: failed to create_nxp_out()\n", __func__);
        goto err_create_out;
    }

    ret = register_nxp_out(nxp_v4l2->out);
    if (ret < 0) {
        pr_err("%s: failed to register_nxp_out()\n", __func__);
        goto err_register_out;
    }
#endif

    ret = v4l2_device_register_subdev_nodes(&nxp_v4l2->v4l2_dev);
    if (ret < 0) {
        pr_err("%s: failed to v4l2_device_register_subdev_nodes()\n", __func__);
        goto err_register_out_subdev;
    }

    platform_set_drvdata(pdev, nxp_v4l2);
   // printk("%s success!!!\n", __func__);

    return 0;

err_register_out_subdev:
#ifdef CONFIG_VIDEO_NXP_OUT
    unregister_nxp_out(nxp_v4l2->out);
err_register_out:
    release_nxp_out(nxp_v4l2->out);
err_create_out:
#endif
#ifdef CONFIG_NXP_M2M_SCALER
    unregister_nxp_scaler(scaler);
err_register_scaler:
    release_nxp_scaler(scaler);
#endif
#ifdef CONFIG_VIDEO_NXP_CAPTURE
err_capture_create:
    for (i = 0; i < NXP_MAX_CAPTURE_NUM; ++i) {
        capture = nxp_v4l2->capture[i];
        if (capture) {
            unregister_nxp_capture(capture);
            release_nxp_capture(capture);
        }
    }
    media_device_unregister(&nxp_v4l2->media_dev);
#endif
#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
err_loopback_sensor_create:
		if( loopback_sensor )
		{
			unregister_nxp_loopback_sensor(loopback_sensor);
    	release_nxp_loopback_sensor(loopback_sensor);
		}
#endif

err_media_reg:
    v4l2_device_unregister(&nxp_v4l2->v4l2_dev);
err_v4l2_reg:
    vb2_ion_destroy_context(nxp_v4l2->alloc_ctx);
err_alloc_ctx:
    kfree(nxp_v4l2);
    __me = NULL;
    return ret;
}