Ejemplo n.º 1
0
static int fimc_md_link_notify(struct media_pad *source,
			       struct media_pad *sink, u32 flags)
{
	struct fimc_lite *fimc_lite = NULL;
	struct fimc_dev *fimc = NULL;
	struct fimc_pipeline *pipeline;
	struct v4l2_subdev *sd;
	int ret = 0;

	if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
		return 0;

	sd = media_entity_to_v4l2_subdev(sink->entity);

	switch (sd->grp_id) {
	case FLITE_GROUP_ID:
		fimc_lite = v4l2_get_subdevdata(sd);
		pipeline = &fimc_lite->pipeline;
		break;
	case FIMC_GROUP_ID:
		fimc = v4l2_get_subdevdata(sd);
		pipeline = &fimc->pipeline;
		break;
	default:
		return 0;
	}

	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
		ret = __fimc_pipeline_close(pipeline);
		pipeline->subdevs[IDX_SENSOR] = NULL;
		pipeline->subdevs[IDX_CSIS] = NULL;

		if (fimc) {
			mutex_lock(&fimc->lock);
			fimc_ctrls_delete(fimc->vid_cap.ctx);
			mutex_unlock(&fimc->lock);
		}
		return ret;
	}
	/*
	 * Link activation. Enable power of pipeline elements only if the
	 * pipeline is already in use, i.e. its video node is opened.
	 * Recreate the controls destroyed during the link deactivation.
	 */
	if (fimc) {
		mutex_lock(&fimc->lock);
		if (fimc->vid_cap.refcnt > 0) {
			ret = __fimc_pipeline_open(pipeline,
						   source->entity, true);
		if (!ret)
			ret = fimc_capture_ctrls_create(fimc);
		}
		mutex_unlock(&fimc->lock);
	} else {
		mutex_lock(&fimc_lite->lock);
		ret = __fimc_pipeline_open(pipeline, source->entity, true);
		mutex_unlock(&fimc_lite->lock);
	}
	return ret ? -EPIPE : ret;
}
static int fimc_md_link_notify(struct media_pad *source,
			       struct media_pad *sink, u32 flags)
{
	struct v4l2_subdev *sd;
	struct fimc_dev *fimc;
	int ret = 0;

	if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
		return 0;

	sd = media_entity_to_v4l2_subdev(sink->entity);
	fimc = v4l2_get_subdevdata(sd);

	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
		ret = __fimc_pipeline_shutdown(fimc);
		fimc->pipeline.sensor = NULL;
		fimc->pipeline.csis = NULL;

		mutex_lock(&fimc->lock);
		fimc_ctrls_delete(fimc->vid_cap.ctx);
		mutex_unlock(&fimc->lock);
		return ret;
	}
	mutex_lock(&fimc->lock);
	if (fimc->vid_cap.refcnt > 0) {
		ret = __fimc_pipeline_initialize(fimc, source->entity, true);
		if (!ret)
			ret = fimc_capture_ctrls_create(fimc);
	}
	mutex_unlock(&fimc->lock);

	return ret ? -EPIPE : ret;
}
Ejemplo n.º 3
0
static int fimc_capture_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret = -EBUSY;

	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	if (fimc_m2m_active(fimc))
		goto unlock;

	set_bit(ST_CAPT_BUSY, &fimc->state);
	ret = pm_runtime_get_sync(&fimc->pdev->dev);
	if (ret < 0)
		goto unlock;

	ret = v4l2_fh_open(file);
	if (ret) {
		pm_runtime_put(&fimc->pdev->dev);
		goto unlock;
	}

	if (++fimc->vid_cap.refcnt == 1) {
		ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
					 &fimc->vid_cap.vfd.entity, true);

		if (!ret && !fimc->vid_cap.user_subdev_api)
			ret = fimc_capture_set_default_format(fimc);

		if (!ret)
			ret = fimc_capture_ctrls_create(fimc);

		if (ret < 0) {
			clear_bit(ST_CAPT_BUSY, &fimc->state);
			pm_runtime_put_sync(&fimc->pdev->dev);
			fimc->vid_cap.refcnt--;
			v4l2_fh_release(file);
		}
	}
unlock:
	mutex_unlock(&fimc->lock);
	return ret;
}
static int fimc_md_link_notify(struct media_pad *source,
			       struct media_pad *sink, u32 flags)
{
	struct v4l2_subdev *sd;
	struct fimc_dev *fimc;
	int ret = 0;

	if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
		return 0;

	sd = media_entity_to_v4l2_subdev(sink->entity);
	fimc = v4l2_get_subdevdata(sd);

	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
		ret = __fimc_pipeline_shutdown(fimc);
		fimc->pipeline.sensor = NULL;
		fimc->pipeline.csis = NULL;

		mutex_lock(&fimc->lock);
		fimc_ctrls_delete(fimc->vid_cap.ctx);
		mutex_unlock(&fimc->lock);
		return ret;
	}
	/*
	 * Link activation. Enable power of pipeline elements only if the
	 * pipeline is already in use, i.e. its video node is opened.
	 * Recreate the controls destroyed during the link deactivation.
	 */
	mutex_lock(&fimc->lock);
	if (fimc->vid_cap.refcnt > 0) {
		ret = __fimc_pipeline_initialize(fimc, source->entity, true);
		if (!ret)
			ret = fimc_capture_ctrls_create(fimc);
	}
	mutex_unlock(&fimc->lock);

	return ret ? -EPIPE : ret;
}
Ejemplo n.º 5
0
static int fimc_capture_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret = v4l2_fh_open(file);

	if (ret)
		return ret;

	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);

	/* Return if the corresponding video mem2mem node is already opened. */
	if (fimc_m2m_active(fimc))
		return -EBUSY;

	set_bit(ST_CAPT_BUSY, &fimc->state);
	pm_runtime_get_sync(&fimc->pdev->dev);

	if (++fimc->vid_cap.refcnt == 1) {
		ret = fimc_pipeline_initialize(fimc,
			       &fimc->vid_cap.vfd->entity, true);
		if (ret < 0) {
			dev_err(&fimc->pdev->dev,
				"Video pipeline initialization failed\n");
			pm_runtime_put_sync(&fimc->pdev->dev);
			fimc->vid_cap.refcnt--;
			v4l2_fh_release(file);
			clear_bit(ST_CAPT_BUSY, &fimc->state);
			return ret;
		}
		ret = fimc_capture_ctrls_create(fimc);

		if (!ret && !fimc->vid_cap.user_subdev_api)
			ret = fimc_capture_set_default_format(fimc);
	}
	return ret;
}