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); }
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; }
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; }
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; }