static int mxr_s_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct mxr_layer *layer = video_drvdata(file); const struct mxr_format *fmt; struct v4l2_pix_format_mplane *pix; struct mxr_device *mdev = layer->mdev; struct mxr_geometry *geo = &layer->geo; mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__); pix = &f->fmt.pix_mp; fmt = find_format_by_fourcc(layer, pix->pixelformat); if (fmt == NULL) { mxr_warn(mdev, "not recognized fourcc: %08x\n", pix->pixelformat); return -EINVAL; } layer->fmt = fmt; geo->src.full_width = pix->width; geo->src.width = pix->width; geo->src.full_height = pix->height; geo->src.height = pix->height; /* assure consistency of geometry */ mxr_layer_geo_fix(layer); mxr_dbg(mdev, "width=%u height=%u span=%u\n", geo->src.width, geo->src.height, geo->src.full_width); return 0; }
static int tv_graph_pipeline_stream(struct mxr_pipeline *pipe, int on) { struct mxr_device *mdev = pipe->layer->mdev; struct media_entity *me = &pipe->layer->vfd.entity; /* source pad of graphic layer entity */ struct media_pad *pad = &me->pads[0]; struct v4l2_subdev *sd; struct exynos_entity_data md_data; mxr_dbg(mdev, "%s TV graphic layer pipeline\n", on ? "start" : "stop"); /* find remote pad through enabled link */ pad = media_entity_remote_source(pad); if (pad == NULL) return -EPIPE; if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) mxr_warn(mdev, "cannot find remote pad\n"); sd = media_entity_to_v4l2_subdev(pad->entity); mxr_dbg(mdev, "s_stream of %s sub-device is called\n", sd->name); md_data.mxr_data_from = FROM_MXR_VD; v4l2_set_subdevdata(sd, &md_data); v4l2_subdev_call(sd, video, s_stream, on); return 0; }
static int buffer_fence_wait(struct mxr_device *mdev, struct mxr_buffer *buffer) { struct sync_fence *fence; int ret = 0; fence = buffer->vb.acquire_fence; if (!fence) return 0; ret = sync_fence_wait(fence, 1000); if (ret == -ETIME) { mxr_warn(mdev, "sync_fence_wait timeout"); ret = sync_fence_wait(fence, -1); } if (ret) mxr_warn(mdev, "sync_fence_wait error"); buffer->vb.acquire_fence = NULL; sync_fence_put(fence); return ret; }
int mxr_reg_wait4vsync(struct mxr_device *mdev) { int ret; clear_bit(MXR_EVENT_VSYNC, &mdev->event_flags); /* TODO: consider adding interruptible */ ret = wait_event_timeout(mdev->event_queue, test_bit(MXR_EVENT_VSYNC, &mdev->event_flags), msecs_to_jiffies(1000)); if (ret > 0) return 0; if (ret < 0) return ret; mxr_warn(mdev, "no vsync detected - timeout\n"); return -ETIME; }
int mxr_reg_wait4update(struct mxr_device *mdev) { ktime_t timestamp = mdev->vsync_timestamp; int ret; ret = wait_event_interruptible_timeout(mdev->vsync_wait, !ktime_equal(timestamp, mdev->vsync_timestamp) && !mxr_update_pending(mdev), msecs_to_jiffies(100)); if (ret > 0) return 0; if (ret < 0) return ret; mxr_warn(mdev, "no vsync detected - timeout\n"); return -ETIME; }
int mxr_hdmi_blank(struct mxr_device *mdev, int blank) { struct v4l2_control ctrl; int ret = 0; /* stop hdmi */ ctrl.id = V4L2_CID_TV_HDMI_STATUS; ret = v4l2_subdev_call(to_outsd(mdev), core, g_ctrl, &ctrl); if (ret) { mxr_err(mdev, "failed to get output %s status for stop\n", to_outsd(mdev)->name); return ret; } /* * HDMI should be turn off only when not in use. * 1. cable out * 2. suspend (V4L2_CID_TV_BLANK is called at suspend) */ if (ctrl.value != (HDMI_STREAMING | HPD_LOW) && !blank) mxr_warn(mdev, "invalid blank condition. ctrl(%#x), blank(%d)\n", ctrl.value, blank); ret = v4l2_subdev_call(to_outsd(mdev), video, s_stream, 0); if (ret) { mxr_err(mdev, "stopping stream failed for output %s\n", to_outsd(mdev)->name); return ret; } ret = v4l2_subdev_call(to_outsd(mdev), core, s_power, 0); if (ret) { mxr_err(mdev, "failed to put power for output %s\n", to_outsd(mdev)->name); return ret; } return ret; }
u32 mxr_irq_underrun_handle(struct mxr_device *mdev, u32 val) { if (val & MXR_INT_STATUS_MX0_VIDEO) { mxr_warn(mdev, "mixer0 video layer underrun occur\n"); val |= MXR_INT_STATUS_MX0_VIDEO; } else if (val & MXR_INT_STATUS_MX0_GRP0) { mxr_warn(mdev, "mixer0 graphic0 layer underrun occur\n"); val |= MXR_INT_STATUS_MX0_GRP0; } else if (val & MXR_INT_STATUS_MX0_GRP1) { mxr_warn(mdev, "mixer0 graphic1 layer underrun occur\n"); val |= MXR_INT_STATUS_MX0_GRP1; } else if (val & MXR_INT_STATUS_MX1_VIDEO) { mxr_warn(mdev, "mixer1 video layer underrun occur\n"); val |= MXR_INT_STATUS_MX1_VIDEO; } else if (val & MXR_INT_STATUS_MX1_GRP0) { mxr_warn(mdev, "mixer1 graphic0 layer underrun occur\n"); val |= MXR_INT_STATUS_MX1_GRP0; } else if (val & MXR_INT_STATUS_MX1_GRP1) { mxr_warn(mdev, "mixer1 graphic1 layer underrun occur\n"); val |= MXR_INT_STATUS_MX1_GRP1; } return val; }