Lines Matching +full:ts +full:- +full:attached
4 * Copyright (C) 2005-2010 Texas Instruments.
11 * Video-for-Linux (Version 2) camera capture driver for
20 * 20-APR-2006 Khasim Modified VRFB based Rotation,
24 * 4-DEC-2006 Jian Changed to support better memory management
26 * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
28 * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
40 #include <linux/dma-mapping.h>
43 #include <media/v4l2-device.h>
44 #include <media/v4l2-ioctl.h>
45 #include <media/v4l2-event.h>
81 MODULE_PARM_DESC(debug, "Debug level (0-1)");
99 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
105 /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
128 pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT, in omap_vout_try_format()
130 pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH); in omap_vout_try_format()
133 if (pix->pixelformat == omap_formats[ifmt].pixelformat) in omap_vout_try_format()
140 pix->pixelformat = omap_formats[ifmt].pixelformat; in omap_vout_try_format()
141 pix->field = V4L2_FIELD_NONE; in omap_vout_try_format()
143 switch (pix->pixelformat) { in omap_vout_try_format()
147 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
152 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
156 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
161 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
165 pix->bytesperline = pix->width * bpp; in omap_vout_try_format()
166 pix->sizeimage = pix->bytesperline * pix->height; in omap_vout_try_format()
195 ret = -EINVAL; in v4l2_rot_to_dss_rot()
203 struct v4l2_rect *crop = &vout->crop; in omap_vout_calculate_offset()
204 struct v4l2_pix_format *pix = &vout->pix; in omap_vout_calculate_offset()
205 int *cropped_offset = &vout->cropped_offset; in omap_vout_calculate_offset()
208 ovid = &vout->vid_info; in omap_vout_calculate_offset()
210 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_calculate_offset()
213 vout->line_length = line_length = pix->width; in omap_vout_calculate_offset()
215 if (V4L2_PIX_FMT_YUYV == pix->pixelformat || in omap_vout_calculate_offset()
216 V4L2_PIX_FMT_UYVY == pix->pixelformat) in omap_vout_calculate_offset()
218 else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) in omap_vout_calculate_offset()
220 else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) in omap_vout_calculate_offset()
223 vout->ps = ps; in omap_vout_calculate_offset()
226 crop->top + crop->left * ps; in omap_vout_calculate_offset()
229 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n", in omap_vout_calculate_offset()
230 __func__, vout->cropped_offset); in omap_vout_calculate_offset()
242 struct v4l2_pix_format *pix = &vout->pix; in video_mode_to_dss_mode()
245 ovid = &vout->vid_info; in video_mode_to_dss_mode()
246 ovl = ovid->overlays[0]; in video_mode_to_dss_mode()
248 switch (pix->pixelformat) { in video_mode_to_dss_mode()
262 mode = (ovl->id == OMAP_DSS_VIDEO1) ? in video_mode_to_dss_mode()
269 mode = -EINVAL; in video_mode_to_dss_mode()
286 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 && in omapvid_setup_overlay()
287 (outw != vout->pix.width || outh != vout->pix.height)) { in omapvid_setup_overlay()
288 ret = -EINVAL; in omapvid_setup_overlay()
292 vout->dss_mode = video_mode_to_dss_mode(vout); in omapvid_setup_overlay()
293 if (vout->dss_mode == -EINVAL) { in omapvid_setup_overlay()
294 ret = -EINVAL; in omapvid_setup_overlay()
302 cropheight = vout->crop.width; in omapvid_setup_overlay()
303 cropwidth = vout->crop.height; in omapvid_setup_overlay()
304 pixwidth = vout->pix.height; in omapvid_setup_overlay()
306 cropheight = vout->crop.height; in omapvid_setup_overlay()
307 cropwidth = vout->crop.width; in omapvid_setup_overlay()
308 pixwidth = vout->pix.width; in omapvid_setup_overlay()
311 ovl->get_overlay_info(ovl, &info); in omapvid_setup_overlay()
315 info.color_mode = vout->dss_mode; in omapvid_setup_overlay()
316 info.mirror = vout->mirror; in omapvid_setup_overlay()
321 info.global_alpha = vout->win.global_alpha; in omapvid_setup_overlay()
327 info.rotation = vout->rotation; in omapvid_setup_overlay()
332 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, in omapvid_setup_overlay()
336 ovl->is_enabled(ovl), &info.paddr, info.width, info.height, in omapvid_setup_overlay()
341 ret = ovl->set_overlay_info(ovl, &info); in omapvid_setup_overlay()
348 v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n"); in omapvid_setup_overlay()
362 struct omapvideo_info *ovid = &vout->vid_info; in omapvid_init()
364 win = &vout->win; in omapvid_init()
365 for (i = 0; i < ovid->num_overlays; i++) { in omapvid_init()
368 ovl = ovid->overlays[i]; in omapvid_init()
369 dssdev = ovl->get_device(ovl); in omapvid_init()
372 return -EINVAL; in omapvid_init()
374 timing = &dssdev->panel.timings; in omapvid_init()
376 outw = win->w.width; in omapvid_init()
377 outh = win->w.height; in omapvid_init()
378 switch (vout->rotation) { in omapvid_init()
384 posy = (timing->y_res - win->w.width) - win->w.left; in omapvid_init()
385 posx = win->w.top; in omapvid_init()
389 posx = (timing->x_res - win->w.width) - win->w.left; in omapvid_init()
390 posy = (timing->y_res - win->w.height) - win->w.top; in omapvid_init()
395 posy = win->w.left; in omapvid_init()
396 posx = (timing->x_res - win->w.height) - win->w.top; in omapvid_init()
400 posx = win->w.left; in omapvid_init()
401 posy = win->w.top; in omapvid_init()
413 v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n"); in omapvid_init()
424 struct omapvideo_info *ovid = &vout->vid_info; in omapvid_apply_changes()
426 for (i = 0; i < ovid->num_overlays; i++) { in omapvid_apply_changes()
429 ovl = ovid->overlays[i]; in omapvid_apply_changes()
430 dssdev = ovl->get_device(ovl); in omapvid_apply_changes()
432 return -EINVAL; in omapvid_apply_changes()
433 ovl->manager->apply(ovl->manager); in omapvid_apply_changes()
440 unsigned int irqstatus, u64 ts) in omapvid_handle_interlace_display() argument
444 if (vout->first_int) { in omapvid_handle_interlace_display()
445 vout->first_int = 0; in omapvid_handle_interlace_display()
456 vout->field_id ^= 1; in omapvid_handle_interlace_display()
457 if (fid != vout->field_id) { in omapvid_handle_interlace_display()
459 vout->field_id = fid; in omapvid_handle_interlace_display()
461 if (vout->cur_frm == vout->next_frm) in omapvid_handle_interlace_display()
464 vout->cur_frm->vbuf.vb2_buf.timestamp = ts; in omapvid_handle_interlace_display()
465 vout->cur_frm->vbuf.sequence = vout->sequence++; in omapvid_handle_interlace_display()
466 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); in omapvid_handle_interlace_display()
467 vout->cur_frm = vout->next_frm; in omapvid_handle_interlace_display()
469 if (list_empty(&vout->dma_queue) || in omapvid_handle_interlace_display()
470 (vout->cur_frm != vout->next_frm)) in omapvid_handle_interlace_display()
474 return vout->field_id; in omapvid_handle_interlace_display()
485 u64 ts; in omap_vout_isr() local
490 ovid = &vout->vid_info; in omap_vout_isr()
491 ovl = ovid->overlays[0]; in omap_vout_isr()
493 mgr_id = ovl->manager->id; in omap_vout_isr()
495 /* get the display device attached to the overlay */ in omap_vout_isr()
496 cur_display = ovl->get_device(ovl); in omap_vout_isr()
501 spin_lock(&vout->vbq_lock); in omap_vout_isr()
502 ts = ktime_get_ns(); in omap_vout_isr()
504 switch (cur_display->type) { in omap_vout_isr()
520 ts); in omap_vout_isr()
532 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { in omap_vout_isr()
533 vout->cur_frm->vbuf.vb2_buf.timestamp = ts; in omap_vout_isr()
534 vout->cur_frm->vbuf.sequence = vout->sequence++; in omap_vout_isr()
535 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); in omap_vout_isr()
536 vout->cur_frm = vout->next_frm; in omap_vout_isr()
539 vout->first_int = 0; in omap_vout_isr()
540 if (list_empty(&vout->dma_queue)) in omap_vout_isr()
543 vout->next_frm = list_entry(vout->dma_queue.next, in omap_vout_isr()
545 list_del(&vout->next_frm->queue); in omap_vout_isr()
547 addr = vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index] in omap_vout_isr()
548 + vout->cropped_offset; in omap_vout_isr()
564 spin_unlock(&vout->vbq_lock); in omap_vout_isr()
576 strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); in vidioc_querycap()
577 strscpy(cap->card, vout->vfd->name, sizeof(cap->card)); in vidioc_querycap()
578 snprintf(cap->bus_info, sizeof(cap->bus_info), in vidioc_querycap()
579 "platform:%s.%d", VOUT_NAME, vout->vid); in vidioc_querycap()
586 int index = fmt->index; in vidioc_enum_fmt_vid_out()
589 return -EINVAL; in vidioc_enum_fmt_vid_out()
591 fmt->flags = omap_formats[index].flags; in vidioc_enum_fmt_vid_out()
592 fmt->pixelformat = omap_formats[index].pixelformat; in vidioc_enum_fmt_vid_out()
602 f->fmt.pix = vout->pix; in vidioc_g_fmt_vid_out()
616 ovid = &vout->vid_info; in vidioc_try_fmt_vid_out()
617 ovl = ovid->overlays[0]; in vidioc_try_fmt_vid_out()
618 /* get the display device attached to the overlay */ in vidioc_try_fmt_vid_out()
619 dssdev = ovl->get_device(ovl); in vidioc_try_fmt_vid_out()
622 return -EINVAL; in vidioc_try_fmt_vid_out()
624 timing = &dssdev->panel.timings; in vidioc_try_fmt_vid_out()
626 vout->fbuf.fmt.height = timing->y_res; in vidioc_try_fmt_vid_out()
627 vout->fbuf.fmt.width = timing->x_res; in vidioc_try_fmt_vid_out()
629 omap_vout_try_format(&f->fmt.pix); in vidioc_try_fmt_vid_out()
643 if (vb2_is_busy(&vout->vq)) in vidioc_s_fmt_vid_out()
644 return -EBUSY; in vidioc_s_fmt_vid_out()
646 ovid = &vout->vid_info; in vidioc_s_fmt_vid_out()
647 ovl = ovid->overlays[0]; in vidioc_s_fmt_vid_out()
648 dssdev = ovl->get_device(ovl); in vidioc_s_fmt_vid_out()
650 /* get the display device attached to the overlay */ in vidioc_s_fmt_vid_out()
652 ret = -EINVAL; in vidioc_s_fmt_vid_out()
655 timing = &dssdev->panel.timings; in vidioc_s_fmt_vid_out()
657 /* We don't support RGB24-packed mode if vrfb rotation in vidioc_s_fmt_vid_out()
660 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { in vidioc_s_fmt_vid_out()
661 ret = -EINVAL; in vidioc_s_fmt_vid_out()
668 vout->fbuf.fmt.height = timing->x_res; in vidioc_s_fmt_vid_out()
669 vout->fbuf.fmt.width = timing->y_res; in vidioc_s_fmt_vid_out()
671 vout->fbuf.fmt.height = timing->y_res; in vidioc_s_fmt_vid_out()
672 vout->fbuf.fmt.width = timing->x_res; in vidioc_s_fmt_vid_out()
677 bpp = omap_vout_try_format(&f->fmt.pix); in vidioc_s_fmt_vid_out()
678 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp; in vidioc_s_fmt_vid_out()
681 vout->bpp = bpp; in vidioc_s_fmt_vid_out()
682 vout->pix = f->fmt.pix; in vidioc_s_fmt_vid_out()
683 vout->vrfb_bpp = 1; in vidioc_s_fmt_vid_out()
686 if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat || in vidioc_s_fmt_vid_out()
687 V4L2_PIX_FMT_UYVY == vout->pix.pixelformat) in vidioc_s_fmt_vid_out()
688 vout->vrfb_bpp = 2; in vidioc_s_fmt_vid_out()
691 omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win); in vidioc_s_fmt_vid_out()
706 struct v4l2_window *win = &f->fmt.win; in vidioc_try_fmt_vid_overlay()
708 ovid = &vout->vid_info; in vidioc_try_fmt_vid_overlay()
709 ovl = ovid->overlays[0]; in vidioc_try_fmt_vid_overlay()
711 ret = omap_vout_try_window(&vout->fbuf, win); in vidioc_try_fmt_vid_overlay()
713 if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)) in vidioc_try_fmt_vid_overlay()
714 win->global_alpha = 0; in vidioc_try_fmt_vid_overlay()
726 struct v4l2_window *win = &f->fmt.win; in vidioc_s_fmt_vid_overlay()
728 ovid = &vout->vid_info; in vidioc_s_fmt_vid_overlay()
729 ovl = ovid->overlays[0]; in vidioc_s_fmt_vid_overlay()
731 ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win); in vidioc_s_fmt_vid_overlay()
738 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) in vidioc_s_fmt_vid_overlay()
739 vout->win.global_alpha = win->global_alpha; in vidioc_s_fmt_vid_overlay()
741 win->global_alpha = 0; in vidioc_s_fmt_vid_overlay()
742 if (vout->fbuf.flags & (V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_s_fmt_vid_overlay()
747 if (vout->fbuf.flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) in vidioc_s_fmt_vid_overlay()
750 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fmt_vid_overlay()
751 ovl->manager->set_manager_info) { in vidioc_s_fmt_vid_overlay()
754 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fmt_vid_overlay()
757 info.trans_key = vout->win.chromakey; in vidioc_s_fmt_vid_overlay()
759 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fmt_vid_overlay()
760 return -EINVAL; in vidioc_s_fmt_vid_overlay()
772 struct v4l2_window *win = &f->fmt.win; in vidioc_g_fmt_vid_overlay()
774 ovid = &vout->vid_info; in vidioc_g_fmt_vid_overlay()
775 ovl = ovid->overlays[0]; in vidioc_g_fmt_vid_overlay()
777 win->w = vout->win.w; in vidioc_g_fmt_vid_overlay()
778 win->field = vout->win.field; in vidioc_g_fmt_vid_overlay()
779 win->chromakey = vout->win.chromakey; in vidioc_g_fmt_vid_overlay()
780 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) in vidioc_g_fmt_vid_overlay()
781 win->global_alpha = vout->win.global_alpha; in vidioc_g_fmt_vid_overlay()
783 win->global_alpha = 0; in vidioc_g_fmt_vid_overlay()
784 win->clips = NULL; in vidioc_g_fmt_vid_overlay()
785 win->clipcount = 0; in vidioc_g_fmt_vid_overlay()
786 win->bitmap = NULL; in vidioc_g_fmt_vid_overlay()
793 struct v4l2_pix_format *pix = &vout->pix; in vidioc_g_selection()
795 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_g_selection()
796 return -EINVAL; in vidioc_g_selection()
798 switch (sel->target) { in vidioc_g_selection()
800 sel->r = vout->crop; in vidioc_g_selection()
803 omap_vout_default_crop(&vout->pix, &vout->fbuf, &sel->r); in vidioc_g_selection()
807 sel->r.width = pix->width & ~1; in vidioc_g_selection()
808 sel->r.height = pix->height & ~1; in vidioc_g_selection()
811 return -EINVAL; in vidioc_g_selection()
818 int ret = -EINVAL; in vidioc_s_selection()
825 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_s_selection()
826 return -EINVAL; in vidioc_s_selection()
828 if (sel->target != V4L2_SEL_TGT_CROP) in vidioc_s_selection()
829 return -EINVAL; in vidioc_s_selection()
831 if (vb2_is_busy(&vout->vq)) in vidioc_s_selection()
832 return -EBUSY; in vidioc_s_selection()
834 ovid = &vout->vid_info; in vidioc_s_selection()
835 ovl = ovid->overlays[0]; in vidioc_s_selection()
836 /* get the display device attached to the overlay */ in vidioc_s_selection()
837 dssdev = ovl->get_device(ovl); in vidioc_s_selection()
840 ret = -EINVAL; in vidioc_s_selection()
844 timing = &dssdev->panel.timings; in vidioc_s_selection()
847 vout->fbuf.fmt.height = timing->x_res; in vidioc_s_selection()
848 vout->fbuf.fmt.width = timing->y_res; in vidioc_s_selection()
850 vout->fbuf.fmt.height = timing->y_res; in vidioc_s_selection()
851 vout->fbuf.fmt.width = timing->x_res; in vidioc_s_selection()
854 ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win, in vidioc_s_selection()
855 &vout->fbuf, &sel->r); in vidioc_s_selection()
864 container_of(ctrl->handler, struct omap_vout_device, ctrl_handler); in omap_vout_s_ctrl()
867 switch (ctrl->id) { in omap_vout_s_ctrl()
870 int rotation = ctrl->val; in omap_vout_s_ctrl()
872 ovid = &vout->vid_info; in omap_vout_s_ctrl()
874 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) { in omap_vout_s_ctrl()
875 ret = -ERANGE; in omap_vout_s_ctrl()
879 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { in omap_vout_s_ctrl()
880 ret = -EINVAL; in omap_vout_s_ctrl()
884 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation, in omap_vout_s_ctrl()
885 vout->mirror)) { in omap_vout_s_ctrl()
886 ret = -EINVAL; in omap_vout_s_ctrl()
894 unsigned int color = ctrl->val; in omap_vout_s_ctrl()
897 ovl = vout->vid_info.overlays[0]; in omap_vout_s_ctrl()
899 if (!ovl->manager || !ovl->manager->get_manager_info) { in omap_vout_s_ctrl()
900 ret = -EINVAL; in omap_vout_s_ctrl()
904 ovl->manager->get_manager_info(ovl->manager, &info); in omap_vout_s_ctrl()
906 if (ovl->manager->set_manager_info(ovl->manager, &info)) { in omap_vout_s_ctrl()
907 ret = -EINVAL; in omap_vout_s_ctrl()
915 unsigned int mirror = ctrl->val; in omap_vout_s_ctrl()
917 ovid = &vout->vid_info; in omap_vout_s_ctrl()
919 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) { in omap_vout_s_ctrl()
920 ret = -ERANGE; in omap_vout_s_ctrl()
924 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { in omap_vout_s_ctrl()
925 ret = -EINVAL; in omap_vout_s_ctrl()
928 vout->mirror = mirror; in omap_vout_s_ctrl()
932 return -EINVAL; in omap_vout_s_ctrl()
948 int size = vout->pix.sizeimage; in omap_vout_vb2_queue_setup()
951 *nbufs = VRFB_NUM_BUFS - q_num_bufs; in omap_vout_vb2_queue_setup()
953 return -EINVAL; in omap_vout_vb2_queue_setup()
957 return sizes[0] < size ? -EINVAL : 0; in omap_vout_vb2_queue_setup()
966 struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); in omap_vout_vb2_prepare()
967 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_prepare()
971 if (vb2_plane_size(vb, 0) < vout->pix.sizeimage) { in omap_vout_vb2_prepare()
972 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, in omap_vout_vb2_prepare()
974 __func__, vb2_plane_size(vb, 0), vout->pix.sizeimage); in omap_vout_vb2_prepare()
975 return -EINVAL; in omap_vout_vb2_prepare()
978 vb2_set_plane_payload(vb, 0, vout->pix.sizeimage); in omap_vout_vb2_prepare()
979 voutbuf->vbuf.field = V4L2_FIELD_NONE; in omap_vout_vb2_prepare()
981 vout->queued_buf_addr[vb->index] = buf_phy_addr; in omap_vout_vb2_prepare()
982 if (ovid->rotation_type == VOUT_ROT_VRFB) in omap_vout_vb2_prepare()
989 struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); in omap_vout_vb2_queue()
992 list_add_tail(&voutbuf->queue, &vout->dma_queue); in omap_vout_vb2_queue()
998 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_start_streaming()
1005 vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next, in omap_vout_vb2_start_streaming()
1008 list_del(&vout->cur_frm->queue); in omap_vout_vb2_start_streaming()
1010 vout->field_id = 0; in omap_vout_vb2_start_streaming()
1011 vout->first_int = 1; in omap_vout_vb2_start_streaming()
1012 vout->sequence = 0; in omap_vout_vb2_start_streaming()
1015 ret = -EINVAL; in omap_vout_vb2_start_streaming()
1018 if (ovid->rotation_type == VOUT_ROT_VRFB) in omap_vout_vb2_start_streaming()
1020 ret = -ENOMEM; in omap_vout_vb2_start_streaming()
1024 addr = vout->queued_buf_addr[vout->cur_frm->vbuf.vb2_buf.index] in omap_vout_vb2_start_streaming()
1025 + vout->cropped_offset; in omap_vout_vb2_start_streaming()
1033 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_start_streaming()
1043 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n"); in omap_vout_vb2_start_streaming()
1045 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_start_streaming()
1046 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_start_streaming()
1047 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_start_streaming()
1050 ret = ovl->enable(ovl); in omap_vout_vb2_start_streaming()
1063 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_start_streaming()
1064 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_start_streaming()
1065 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_start_streaming()
1068 ovl->disable(ovl); in omap_vout_vb2_start_streaming()
1072 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_start_streaming()
1076 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); in omap_vout_vb2_start_streaming()
1077 list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { in omap_vout_vb2_start_streaming()
1078 list_del(&buf->queue); in omap_vout_vb2_start_streaming()
1079 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); in omap_vout_vb2_start_streaming()
1087 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_stop_streaming()
1097 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_stop_streaming()
1098 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_stop_streaming()
1099 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_stop_streaming()
1102 ovl->disable(ovl); in omap_vout_vb2_stop_streaming()
1106 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_stop_streaming()
1109 if (vout->next_frm != vout->cur_frm) in omap_vout_vb2_stop_streaming()
1110 vb2_buffer_done(&vout->next_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1111 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1112 list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { in omap_vout_vb2_stop_streaming()
1113 list_del(&buf->queue); in omap_vout_vb2_stop_streaming()
1114 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1128 ovid = &vout->vid_info; in vidioc_s_fbuf()
1129 ovl = ovid->overlays[0]; in vidioc_s_fbuf()
1133 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) && in vidioc_s_fbuf()
1134 (a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) in vidioc_s_fbuf()
1135 return -EINVAL; in vidioc_s_fbuf()
1138 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) && in vidioc_s_fbuf()
1139 (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA)) in vidioc_s_fbuf()
1140 return -EINVAL; in vidioc_s_fbuf()
1142 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) { in vidioc_s_fbuf()
1143 vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_s_fbuf()
1146 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_s_fbuf()
1148 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) { in vidioc_s_fbuf()
1149 vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_s_fbuf()
1152 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_s_fbuf()
1154 if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_s_fbuf()
1159 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fbuf()
1160 ovl->manager->set_manager_info) { in vidioc_s_fbuf()
1162 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fbuf()
1165 info.trans_key = vout->win.chromakey; in vidioc_s_fbuf()
1167 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fbuf()
1168 return -EINVAL; in vidioc_s_fbuf()
1170 if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) { in vidioc_s_fbuf()
1171 vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_s_fbuf()
1174 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_s_fbuf()
1177 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fbuf()
1178 ovl->manager->set_manager_info) { in vidioc_s_fbuf()
1179 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fbuf()
1181 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) in vidioc_s_fbuf()
1183 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fbuf()
1184 return -EINVAL; in vidioc_s_fbuf()
1200 ovid = &vout->vid_info; in vidioc_g_fbuf()
1201 ovl = ovid->overlays[0]; in vidioc_g_fbuf()
1202 /* get the display device attached to the overlay */ in vidioc_g_fbuf()
1203 dssdev = ovl->get_device(ovl); in vidioc_g_fbuf()
1206 return -EINVAL; in vidioc_g_fbuf()
1208 timing = &dssdev->panel.timings; in vidioc_g_fbuf()
1210 vout->fbuf.fmt.height = timing->y_res; in vidioc_g_fbuf()
1211 vout->fbuf.fmt.width = timing->x_res; in vidioc_g_fbuf()
1212 a->fmt.field = V4L2_FIELD_NONE; in vidioc_g_fbuf()
1213 a->fmt.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_g_fbuf()
1214 a->fmt.pixelformat = V4L2_PIX_FMT_RGBA32; in vidioc_g_fbuf()
1215 a->fmt.height = vout->fbuf.fmt.height; in vidioc_g_fbuf()
1216 a->fmt.width = vout->fbuf.fmt.width; in vidioc_g_fbuf()
1217 a->fmt.bytesperline = vout->fbuf.fmt.width * 4; in vidioc_g_fbuf()
1218 a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline; in vidioc_g_fbuf()
1219 a->base = vout->fbuf.base; in vidioc_g_fbuf()
1221 a->flags = vout->fbuf.flags; in vidioc_g_fbuf()
1222 a->capability = vout->fbuf.capability; in vidioc_g_fbuf()
1223 a->flags &= ~(V4L2_FBUF_FLAG_SRC_CHROMAKEY | V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_g_fbuf()
1226 if (ovl->manager && ovl->manager->get_manager_info) { in vidioc_g_fbuf()
1227 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_g_fbuf()
1229 a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_g_fbuf()
1231 a->flags |= V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_g_fbuf()
1233 a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_g_fbuf()
1242 if (out->index) in vidioc_enum_output()
1243 return -EINVAL; in vidioc_enum_output()
1244 snprintf(out->name, sizeof(out->name), "Overlay"); in vidioc_enum_output()
1245 out->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; in vidioc_enum_output()
1257 return i ? -EINVAL : 0; in vidioc_s_output()
1313 struct omap_overlay *ovl = vout->vid_info.overlays[0]; in omap_vout_setup_video_data()
1314 struct omap_dss_device *display = ovl->get_device(ovl); in omap_vout_setup_video_data()
1320 pix = &vout->pix; in omap_vout_setup_video_data()
1323 pix->width = QQVGA_WIDTH; in omap_vout_setup_video_data()
1324 pix->height = QQVGA_HEIGHT; in omap_vout_setup_video_data()
1326 /* Default pixel format is RGB 5-6-5 */ in omap_vout_setup_video_data()
1327 pix->pixelformat = V4L2_PIX_FMT_RGB565; in omap_vout_setup_video_data()
1328 pix->field = V4L2_FIELD_NONE; in omap_vout_setup_video_data()
1329 pix->bytesperline = pix->width * 2; in omap_vout_setup_video_data()
1330 pix->sizeimage = pix->bytesperline * pix->height; in omap_vout_setup_video_data()
1331 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_setup_video_data()
1333 vout->bpp = RGB565_BPP; in omap_vout_setup_video_data()
1334 vout->fbuf.fmt.width = display->panel.timings.x_res; in omap_vout_setup_video_data()
1335 vout->fbuf.fmt.height = display->panel.timings.y_res; in omap_vout_setup_video_data()
1336 vout->cropped_offset = 0; in omap_vout_setup_video_data()
1339 vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY; in omap_vout_setup_video_data()
1340 vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA | in omap_vout_setup_video_data()
1343 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) { in omap_vout_setup_video_data()
1344 vout->win.global_alpha = 255; in omap_vout_setup_video_data()
1345 vout->fbuf.capability |= V4L2_FBUF_CAP_GLOBAL_ALPHA; in omap_vout_setup_video_data()
1346 vout->fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; in omap_vout_setup_video_data()
1348 vout->win.global_alpha = 0; in omap_vout_setup_video_data()
1350 vout->win.field = V4L2_FIELD_NONE; in omap_vout_setup_video_data()
1352 omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win); in omap_vout_setup_video_data()
1354 hdl = &vout->ctrl_handler; in omap_vout_setup_video_data()
1356 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) { in omap_vout_setup_video_data()
1364 if (hdl->error) in omap_vout_setup_video_data()
1365 return hdl->error; in omap_vout_setup_video_data()
1367 vout->rotation = 0; in omap_vout_setup_video_data()
1368 vout->mirror = false; in omap_vout_setup_video_data()
1369 INIT_LIST_HEAD(&vout->dma_queue); in omap_vout_setup_video_data()
1370 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) in omap_vout_setup_video_data()
1371 vout->vrfb_bpp = 2; in omap_vout_setup_video_data()
1374 vfd = vout->vfd = video_device_alloc(); in omap_vout_setup_video_data()
1380 return -ENOMEM; in omap_vout_setup_video_data()
1382 vfd->ctrl_handler = hdl; in omap_vout_setup_video_data()
1383 vfd->release = video_device_release; in omap_vout_setup_video_data()
1384 vfd->ioctl_ops = &vout_ioctl_ops; in omap_vout_setup_video_data()
1386 strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); in omap_vout_setup_video_data()
1388 vfd->fops = &omap_vout_fops; in omap_vout_setup_video_data()
1389 vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; in omap_vout_setup_video_data()
1390 vfd->vfl_dir = VFL_DIR_TX; in omap_vout_setup_video_data()
1391 vfd->minor = -1; in omap_vout_setup_video_data()
1392 vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | in omap_vout_setup_video_data()
1394 mutex_init(&vout->lock); in omap_vout_setup_video_data()
1396 vq = &vout->vq; in omap_vout_setup_video_data()
1397 vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in omap_vout_setup_video_data()
1398 vq->io_modes = VB2_MMAP | VB2_DMABUF; in omap_vout_setup_video_data()
1399 vq->drv_priv = vout; in omap_vout_setup_video_data()
1400 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in omap_vout_setup_video_data()
1401 vq->buf_struct_size = sizeof(struct omap_vout_buffer); in omap_vout_setup_video_data()
1402 vq->dev = vfd->v4l2_dev->dev; in omap_vout_setup_video_data()
1404 vq->ops = &omap_vout_vb2_ops; in omap_vout_setup_video_data()
1405 vq->mem_ops = &vb2_dma_contig_memops; in omap_vout_setup_video_data()
1406 vq->lock = &vout->lock; in omap_vout_setup_video_data()
1407 vq->min_queued_buffers = 1; in omap_vout_setup_video_data()
1408 vfd->queue = vq; in omap_vout_setup_video_data()
1429 vout = vid_dev->vouts[vid_num]; in omap_vout_setup_video_bufs()
1430 ovid = &vout->vid_info; in omap_vout_setup_video_bufs()
1432 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_setup_video_bufs()
1450 struct omap_overlay *ovl = vid_dev->overlays[0]; in omap_vout_create_video_devices()
1453 ovl->get_overlay_info(ovl, &info); in omap_vout_create_video_devices()
1455 for (k = 0; k < pdev->num_resources; k++) { in omap_vout_create_video_devices()
1459 dev_err(&pdev->dev, ": could not allocate memory\n"); in omap_vout_create_video_devices()
1460 return -ENOMEM; in omap_vout_create_video_devices()
1463 vout->vid = k; in omap_vout_create_video_devices()
1464 vid_dev->vouts[k] = vout; in omap_vout_create_video_devices()
1465 vout->vid_dev = vid_dev; in omap_vout_create_video_devices()
1467 if (pdev->num_resources == 1) in omap_vout_create_video_devices()
1468 vout->vid_info.overlays[0] = vid_dev->overlays[k + 2]; in omap_vout_create_video_devices()
1471 vout->vid_info.overlays[0] = vid_dev->overlays[k + 1]; in omap_vout_create_video_devices()
1472 vout->vid_info.num_overlays = 1; in omap_vout_create_video_devices()
1473 vout->vid_info.id = k + 1; in omap_vout_create_video_devices()
1474 spin_lock_init(&vout->vbq_lock); in omap_vout_create_video_devices()
1482 vout->fbuf.base = (void *)(uintptr_t)info.paddr; in omap_vout_create_video_devices()
1486 vout->vid_info.rotation_type = VOUT_ROT_VRFB; in omap_vout_create_video_devices()
1491 ret = -ENOMEM; in omap_vout_create_video_devices()
1499 ret = -ENOMEM; in omap_vout_create_video_devices()
1505 vfd = vout->vfd; in omap_vout_create_video_devices()
1506 if (video_register_device(vfd, VFL_TYPE_VIDEO, -1) < 0) { in omap_vout_create_video_devices()
1507 dev_err(&pdev->dev, in omap_vout_create_video_devices()
1509 vfd->minor = -1; in omap_vout_create_video_devices()
1510 ret = -ENODEV; in omap_vout_create_video_devices()
1515 dev_info(&pdev->dev, in omap_vout_create_video_devices()
1517 vfd->minor); in omap_vout_create_video_devices()
1518 if (k == (pdev->num_resources - 1)) in omap_vout_create_video_devices()
1523 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) in omap_vout_create_video_devices()
1532 return -ENODEV; in omap_vout_create_video_devices()
1543 vfd = vout->vfd; in omap_vout_cleanup_device()
1544 ovid = &vout->vid_info; in omap_vout_cleanup_device()
1560 v4l2_ctrl_handler_free(&vout->ctrl_handler); in omap_vout_cleanup_device()
1561 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_cleanup_device()
1566 if (vout->vrfb_static_allocation) in omap_vout_cleanup_device()
1581 for (k = 0; k < pdev->num_resources; k++) in omap_vout_remove()
1582 omap_vout_cleanup_device(vid_dev->vouts[k]); in omap_vout_remove()
1584 for (k = 0; k < vid_dev->num_displays; k++) { in omap_vout_remove()
1585 if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED) in omap_vout_remove()
1586 vid_dev->displays[k]->driver->disable(vid_dev->displays[k]); in omap_vout_remove()
1588 omap_dss_put_device(vid_dev->displays[k]); in omap_vout_remove()
1602 return -EPROBE_DEFER; in omap_vout_probe()
1606 dev_err(&pdev->dev, "failed to init dss\n"); in omap_vout_probe()
1610 if (pdev->num_resources == 0) { in omap_vout_probe()
1611 dev_err(&pdev->dev, "probed for an unknown device\n"); in omap_vout_probe()
1612 ret = -ENODEV; in omap_vout_probe()
1618 ret = -ENOMEM; in omap_vout_probe()
1622 vid_dev->num_displays = 0; in omap_vout_probe()
1626 if (!dssdev->driver) { in omap_vout_probe()
1627 dev_warn(&pdev->dev, "no driver for display: %s\n", in omap_vout_probe()
1628 dssdev->name); in omap_vout_probe()
1633 vid_dev->displays[vid_dev->num_displays++] = dssdev; in omap_vout_probe()
1636 if (vid_dev->num_displays == 0) { in omap_vout_probe()
1637 dev_err(&pdev->dev, "no displays\n"); in omap_vout_probe()
1638 ret = -EINVAL; in omap_vout_probe()
1642 vid_dev->num_overlays = omap_dss_get_num_overlays(); in omap_vout_probe()
1643 for (i = 0; i < vid_dev->num_overlays; i++) in omap_vout_probe()
1644 vid_dev->overlays[i] = omap_dss_get_overlay(i); in omap_vout_probe()
1646 vid_dev->num_managers = omap_dss_get_num_overlay_managers(); in omap_vout_probe()
1647 for (i = 0; i < vid_dev->num_managers; i++) in omap_vout_probe()
1648 vid_dev->managers[i] = omap_dss_get_overlay_manager(i); in omap_vout_probe()
1651 * Setup the Display attached to that overlays in omap_vout_probe()
1653 for (i = 1; i < vid_dev->num_overlays; i++) { in omap_vout_probe()
1655 dssdev = ovl->get_device(ovl); in omap_vout_probe()
1660 dev_warn(&pdev->dev, "cannot find display\n"); in omap_vout_probe()
1664 struct omap_dss_driver *dssdrv = def_display->driver; in omap_vout_probe()
1666 ret = dssdrv->enable(def_display); in omap_vout_probe()
1672 dev_warn(&pdev->dev, in omap_vout_probe()
1674 def_display->name); in omap_vout_probe()
1679 if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) { in omap_vout_probe()
1680 dev_err(&pdev->dev, "v4l2_device_register failed\n"); in omap_vout_probe()
1681 ret = -ENODEV; in omap_vout_probe()
1689 for (i = 0; i < vid_dev->num_displays; i++) { in omap_vout_probe()
1690 struct omap_dss_device *display = vid_dev->displays[i]; in omap_vout_probe()
1692 if (display->driver->update) in omap_vout_probe()
1693 display->driver->update(display, 0, 0, in omap_vout_probe()
1694 display->panel.timings.x_res, in omap_vout_probe()
1695 display->panel.timings.y_res); in omap_vout_probe()
1700 v4l2_device_unregister(&vid_dev->v4l2_dev); in omap_vout_probe()
1702 for (i = 1; i < vid_dev->num_overlays; i++) { in omap_vout_probe()
1705 dssdev = ovl->get_device(ovl); in omap_vout_probe()
1710 if (def_display && def_display->driver) in omap_vout_probe()
1711 def_display->driver->disable(def_display); in omap_vout_probe()
1731 return -EINVAL; in omap_vout_init()