Lines Matching full:vin
3 * Driver for Renesas R-Car VIN
20 #include "rcar-vin.h"
87 const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, in rvin_format_from_pixel() argument
94 if (vin->info->model == RCAR_M1) in rvin_format_from_pixel()
102 if (!vin->info->nv12 || !(BIT(vin->id) & 0x3333)) in rvin_format_from_pixel()
116 static u32 rvin_format_bytesperline(struct rvin_dev *vin, in rvin_format_bytesperline() argument
122 fmt = rvin_format_from_pixel(vin, pix->pixelformat); in rvin_format_bytesperline()
155 static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) in rvin_format_align() argument
159 if (!rvin_format_from_pixel(vin, pix->pixelformat)) in rvin_format_align()
189 /* Limit to VIN capabilities */ in rvin_format_align()
190 v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, in rvin_format_align()
191 &pix->height, 4, vin->info->max_height, 2, 0); in rvin_format_align()
193 pix->bytesperline = rvin_format_bytesperline(vin, pix); in rvin_format_align()
196 vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n", in rvin_format_align()
204 static int rvin_reset_format(struct rvin_dev *vin) in rvin_reset_format() argument
208 .pad = vin->parallel->source_pad, in rvin_reset_format()
212 ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt); in rvin_reset_format()
216 v4l2_fill_pix_format(&vin->format, &fmt.format); in rvin_reset_format()
218 vin->src_rect.top = 0; in rvin_reset_format()
219 vin->src_rect.left = 0; in rvin_reset_format()
220 vin->src_rect.width = vin->format.width; in rvin_reset_format()
221 vin->src_rect.height = vin->format.height; in rvin_reset_format()
224 if (vin->format.field == V4L2_FIELD_ALTERNATE) { in rvin_reset_format()
225 vin->format.field = V4L2_FIELD_INTERLACED; in rvin_reset_format()
226 vin->format.height *= 2; in rvin_reset_format()
229 rvin_format_align(vin, &vin->format); in rvin_reset_format()
231 vin->crop = vin->src_rect; in rvin_reset_format()
233 vin->compose.top = 0; in rvin_reset_format()
234 vin->compose.left = 0; in rvin_reset_format()
235 vin->compose.width = vin->format.width; in rvin_reset_format()
236 vin->compose.height = vin->format.height; in rvin_reset_format()
241 static int rvin_try_format(struct rvin_dev *vin, u32 which, in rvin_try_format() argument
245 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_try_format()
249 .pad = vin->parallel->source_pad, in rvin_try_format()
259 if (!rvin_format_from_pixel(vin, pix->pixelformat)) in rvin_try_format()
262 v4l2_fill_mbus_format(&format.format, pix, vin->mbus_code); in rvin_try_format()
289 rvin_format_align(vin, pix); in rvin_try_format()
299 struct rvin_dev *vin = video_drvdata(file); in rvin_querycap() local
304 dev_name(vin->dev)); in rvin_querycap()
311 struct rvin_dev *vin = video_drvdata(file); in rvin_try_fmt_vid_cap() local
313 return rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix, NULL); in rvin_try_fmt_vid_cap()
319 struct rvin_dev *vin = video_drvdata(file); in rvin_s_fmt_vid_cap() local
323 if (vb2_is_busy(&vin->queue)) in rvin_s_fmt_vid_cap()
326 ret = rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix, in rvin_s_fmt_vid_cap()
331 vin->format = f->fmt.pix; in rvin_s_fmt_vid_cap()
335 fmt_rect.width = vin->format.width; in rvin_s_fmt_vid_cap()
336 fmt_rect.height = vin->format.height; in rvin_s_fmt_vid_cap()
338 v4l2_rect_map_inside(&vin->crop, &src_rect); in rvin_s_fmt_vid_cap()
339 v4l2_rect_map_inside(&vin->compose, &fmt_rect); in rvin_s_fmt_vid_cap()
340 vin->src_rect = src_rect; in rvin_s_fmt_vid_cap()
348 struct rvin_dev *vin = video_drvdata(file); in rvin_g_fmt_vid_cap() local
350 f->fmt.pix = vin->format; in rvin_g_fmt_vid_cap()
358 struct rvin_dev *vin = video_drvdata(file); in rvin_enum_fmt_vid_cap() local
365 * with VIN, so all supported YCbCr and RGB media bus codes can produce in rvin_enum_fmt_vid_cap()
407 if (rvin_format_from_pixel(vin, rvin_formats[i].fourcc)) in rvin_enum_fmt_vid_cap()
422 struct rvin_dev *vin = video_drvdata(file); in rvin_g_selection() local
431 s->r.width = vin->src_rect.width; in rvin_g_selection()
432 s->r.height = vin->src_rect.height; in rvin_g_selection()
435 s->r = vin->crop; in rvin_g_selection()
440 s->r.width = vin->format.width; in rvin_g_selection()
441 s->r.height = vin->format.height; in rvin_g_selection()
444 s->r = vin->compose; in rvin_g_selection()
456 struct rvin_dev *vin = video_drvdata(file); in rvin_s_selection() local
474 max_rect.width = vin->src_rect.width; in rvin_s_selection()
475 max_rect.height = vin->src_rect.height; in rvin_s_selection()
478 v4l_bound_align_image(&r.width, 6, vin->src_rect.width, 0, in rvin_s_selection()
479 &r.height, 2, vin->src_rect.height, 0, 0); in rvin_s_selection()
482 vin->src_rect.height - r.height); in rvin_s_selection()
483 r.left = clamp_t(s32, r.left, 0, vin->src_rect.width - r.width); in rvin_s_selection()
485 vin->crop = s->r = r; in rvin_s_selection()
487 vin_dbg(vin, "Cropped %dx%d@%d:%d of %dx%d\n", in rvin_s_selection()
489 vin->src_rect.width, vin->src_rect.height); in rvin_s_selection()
494 max_rect.width = vin->format.width; in rvin_s_selection()
495 max_rect.height = vin->format.height; in rvin_s_selection()
503 while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK) in rvin_s_selection()
506 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); in rvin_s_selection()
510 vin->compose = s->r = r; in rvin_s_selection()
512 vin_dbg(vin, "Compose %dx%d@%d:%d in %dx%d\n", in rvin_s_selection()
514 vin->format.width, vin->format.height); in rvin_s_selection()
521 rvin_crop_scale_comp(vin); in rvin_s_selection()
529 struct rvin_dev *vin = video_drvdata(file); in rvin_g_pixelaspect() local
530 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_g_pixelaspect()
541 struct rvin_dev *vin = video_drvdata(file); in rvin_enum_input() local
542 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_enum_input()
559 i->std = vin->vdev.tvnorms; in rvin_enum_input()
582 struct rvin_dev *vin = video_drvdata(file); in rvin_querystd() local
583 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_querystd()
590 struct rvin_dev *vin = video_drvdata(file); in rvin_s_std() local
593 ret = v4l2_subdev_call(vin_to_source(vin), video, s_std, a); in rvin_s_std()
597 vin->std = a; in rvin_s_std()
600 return rvin_reset_format(vin); in rvin_s_std()
605 struct rvin_dev *vin = video_drvdata(file); in rvin_g_std() local
607 if (v4l2_subdev_has_op(vin_to_source(vin), pad, dv_timings_cap)) in rvin_g_std()
610 *a = vin->std; in rvin_g_std()
628 struct rvin_dev *vin = video_drvdata(file); in rvin_enum_dv_timings() local
629 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_enum_dv_timings()
635 timings->pad = vin->parallel->sink_pad; in rvin_enum_dv_timings()
647 struct rvin_dev *vin = video_drvdata(file); in rvin_s_dv_timings() local
648 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_s_dv_timings()
656 return rvin_reset_format(vin); in rvin_s_dv_timings()
662 struct rvin_dev *vin = video_drvdata(file); in rvin_g_dv_timings() local
663 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_g_dv_timings()
671 struct rvin_dev *vin = video_drvdata(file); in rvin_query_dv_timings() local
672 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_query_dv_timings()
680 struct rvin_dev *vin = video_drvdata(file); in rvin_dv_timings_cap() local
681 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_dv_timings_cap()
687 cap->pad = vin->parallel->sink_pad; in rvin_dv_timings_cap()
698 struct rvin_dev *vin = video_drvdata(file); in rvin_g_edid() local
699 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_g_edid()
705 edid->pad = vin->parallel->sink_pad; in rvin_g_edid()
716 struct rvin_dev *vin = video_drvdata(file); in rvin_s_edid() local
717 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_s_edid()
723 edid->pad = vin->parallel->sink_pad; in rvin_s_edid()
780 static void rvin_mc_try_format(struct rvin_dev *vin, in rvin_mc_try_format() argument
795 rvin_format_align(vin, pix); in rvin_mc_try_format()
801 struct rvin_dev *vin = video_drvdata(file); in rvin_mc_try_fmt_vid_cap() local
803 rvin_mc_try_format(vin, &f->fmt.pix); in rvin_mc_try_fmt_vid_cap()
811 struct rvin_dev *vin = video_drvdata(file); in rvin_mc_s_fmt_vid_cap() local
813 if (vb2_is_busy(&vin->queue)) in rvin_mc_s_fmt_vid_cap()
816 rvin_mc_try_format(vin, &f->fmt.pix); in rvin_mc_s_fmt_vid_cap()
818 vin->format = f->fmt.pix; in rvin_mc_s_fmt_vid_cap()
820 vin->crop.top = 0; in rvin_mc_s_fmt_vid_cap()
821 vin->crop.left = 0; in rvin_mc_s_fmt_vid_cap()
822 vin->crop.width = vin->format.width; in rvin_mc_s_fmt_vid_cap()
823 vin->crop.height = vin->format.height; in rvin_mc_s_fmt_vid_cap()
824 vin->compose = vin->crop; in rvin_mc_s_fmt_vid_cap()
855 static int rvin_power_parallel(struct rvin_dev *vin, bool on) in rvin_power_parallel() argument
857 struct v4l2_subdev *sd = vin_to_source(vin); in rvin_power_parallel()
870 struct rvin_dev *vin = video_drvdata(file); in rvin_open() local
873 ret = pm_runtime_get_sync(vin->dev); in rvin_open()
875 pm_runtime_put_noidle(vin->dev); in rvin_open()
879 ret = mutex_lock_interruptible(&vin->lock); in rvin_open()
883 file->private_data = vin; in rvin_open()
889 if (vin->info->use_mc) in rvin_open()
890 ret = v4l2_pipeline_pm_get(&vin->vdev.entity); in rvin_open()
892 ret = rvin_power_parallel(vin, true); in rvin_open()
897 ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler); in rvin_open()
901 mutex_unlock(&vin->lock); in rvin_open()
905 if (vin->info->use_mc) in rvin_open()
906 v4l2_pipeline_pm_put(&vin->vdev.entity); in rvin_open()
908 rvin_power_parallel(vin, false); in rvin_open()
912 mutex_unlock(&vin->lock); in rvin_open()
914 pm_runtime_put(vin->dev); in rvin_open()
921 struct rvin_dev *vin = video_drvdata(file); in rvin_release() local
925 mutex_lock(&vin->lock); in rvin_release()
933 if (vin->info->use_mc) { in rvin_release()
934 v4l2_pipeline_pm_put(&vin->vdev.entity); in rvin_release()
937 rvin_power_parallel(vin, false); in rvin_release()
940 mutex_unlock(&vin->lock); in rvin_release()
942 pm_runtime_put(vin->dev); in rvin_release()
957 void rvin_v4l2_unregister(struct rvin_dev *vin) in rvin_v4l2_unregister() argument
959 if (!video_is_registered(&vin->vdev)) in rvin_v4l2_unregister()
962 v4l2_info(&vin->v4l2_dev, "Removing %s\n", in rvin_v4l2_unregister()
963 video_device_node_name(&vin->vdev)); in rvin_v4l2_unregister()
966 video_unregister_device(&vin->vdev); in rvin_v4l2_unregister()
972 struct rvin_dev *vin = in rvin_notify() local
977 v4l2_event_queue(&vin->vdev, arg); in rvin_notify()
984 int rvin_v4l2_register(struct rvin_dev *vin) in rvin_v4l2_register() argument
986 struct video_device *vdev = &vin->vdev; in rvin_v4l2_register()
989 vin->v4l2_dev.notify = rvin_notify; in rvin_v4l2_register()
992 vdev->v4l2_dev = &vin->v4l2_dev; in rvin_v4l2_register()
993 vdev->queue = &vin->queue; in rvin_v4l2_register()
994 snprintf(vdev->name, sizeof(vdev->name), "VIN%u output", vin->id); in rvin_v4l2_register()
996 vdev->lock = &vin->lock; in rvin_v4l2_register()
1002 vin->format.pixelformat = RVIN_DEFAULT_FORMAT; in rvin_v4l2_register()
1003 vin->format.width = RVIN_DEFAULT_WIDTH; in rvin_v4l2_register()
1004 vin->format.height = RVIN_DEFAULT_HEIGHT; in rvin_v4l2_register()
1005 vin->format.field = RVIN_DEFAULT_FIELD; in rvin_v4l2_register()
1006 vin->format.colorspace = RVIN_DEFAULT_COLORSPACE; in rvin_v4l2_register()
1008 if (vin->info->use_mc) { in rvin_v4l2_register()
1013 rvin_reset_format(vin); in rvin_v4l2_register()
1016 rvin_format_align(vin, &vin->format); in rvin_v4l2_register()
1018 ret = video_register_device(&vin->vdev, VFL_TYPE_VIDEO, -1); in rvin_v4l2_register()
1020 vin_err(vin, "Failed to register video device\n"); in rvin_v4l2_register()
1024 video_set_drvdata(&vin->vdev, vin); in rvin_v4l2_register()
1026 v4l2_info(&vin->v4l2_dev, "Device registered as %s\n", in rvin_v4l2_register()
1027 video_device_node_name(&vin->vdev)); in rvin_v4l2_register()