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;
}
Esempio n. 4
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}