Ejemplo n.º 1
0
static int
__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
{
    struct v4l2_subdev_format fmt;
    struct v4l2_subdev *subdev;
    u32 pad;
    int ret;

    subdev = isp_video_remote_subdev(video, &pad);
    if (subdev == NULL)
        return -EINVAL;

    mutex_lock(&video->mutex);

    fmt.pad = pad;
    fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
    if (ret == -ENOIOCTLCMD)
        ret = -EINVAL;

    mutex_unlock(&video->mutex);

    if (ret)
        return ret;

    format->type = video->type;
    return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
}
Ejemplo n.º 2
0
static int
isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
{
	struct isp_video *video = video_drvdata(file);
	struct v4l2_mbus_framefmt fmt;
	struct v4l2_subdev *subdev;
	u32 pad;
	int ret;

	if (format->type != video->type)
		return -EINVAL;

	subdev = isp_video_remote_subdev(video, &pad);
	if (subdev == NULL)
		return -EINVAL;

	isp_video_pix_to_mbus(&format->fmt.pix, &fmt);

	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, pad, &fmt,
			       V4L2_SUBDEV_FORMAT_ACTIVE);
	if (ret)
		return ret == -ENOIOCTLCMD ? -EINVAL : ret;

	isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
	return 0;
}
Ejemplo n.º 3
0
static int
isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
{
	struct isp_video_fh *vfh = to_isp_video_fh(fh);
	struct isp_video *video = video_drvdata(file);
	struct v4l2_mbus_framefmt fmt;

	if (format->type != video->type)
		return -EINVAL;

	mutex_lock(&video->mutex);

	/* Fill the bytesperline and sizeimage fields by converting to media bus
	 * format and back to pixel format.
	 */
	isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
	isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);

	vfh->format = *format;

	mutex_unlock(&video->mutex);
	return 0;
}
Ejemplo n.º 4
0
static int isp_video_open(struct file *file)
{
	struct isp_video *video = video_drvdata(file);
	struct isp_video_fh *handle;
	struct media_entity_pad *pad;
	int ret = 0;

	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
	if (handle == NULL)
		return -ENOMEM;

	v4l2_fh_init(&handle->vfh, &video->video);
	v4l2_fh_add(&handle->vfh);

	/* If this is the first user, initialise the pipeline. */
	if (atomic_inc_return(&video->users) == 1) {
		if (isp_get(video->isp) == NULL) {
			ret = -EBUSY;
			goto done;
		}
	}

	isp_video_queue_init(&handle->queue, video->type, &isp_video_queue_ops,
			     video->isp->dev, sizeof(struct isp_buffer));

	memset(&handle->format, 0, sizeof(handle->format));
	handle->format.type = video->type;
	handle->timeperframe.denominator = 1;

	/* If a subdev is linked to this dev, then initialize the
	   format to match the subdev. */
	pad = media_entity_remote_pad(&video->pad);
	if(pad && pad->entity->type == MEDIA_ENTITY_TYPE_SUBDEV) {
		struct v4l2_subdev *subdev;
		struct v4l2_mbus_framefmt fmt_source;
		struct v4l2_subdev_frame_interval fi;
		int err;
		subdev = media_entity_to_v4l2_subdev(pad->entity);
		err = v4l2_subdev_call(subdev, pad, get_fmt, NULL, pad->index,
				       &fmt_source, V4L2_SUBDEV_FORMAT_ACTIVE);
		if(err >= 0) {
			isp_video_mbus_to_pix(video, &fmt_source, &(handle->format.fmt.pix));
			handle->format.fmt.pix.width = fmt_source.width;
			handle->format.fmt.pix.height= fmt_source.height;
		}

		err = __find_timeperframe(pad, subdev, &fi, 0);
		if(err >= 0) {
			handle->timeperframe.numerator = fi.interval.numerator;
			handle->timeperframe.denominator = fi.interval.denominator;
		}
	}

	handle->video = video;
	file->private_data = &handle->vfh;

done:
	if (ret < 0) {
		v4l2_fh_del(&handle->vfh);
		atomic_dec(&video->users);
		kfree(handle);
	}

	return ret;
}