Example #1
0
static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
		struct soc_camera_device *icd, struct v4l2_subdev *sd,
		struct v4l2_mbus_framefmt *mf,
		const struct soc_camera_format_xlate *xlate)
{
	s32 bytes_per_line;
	int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf);

	if (ret < 0) {
		dev_err(dev, "%s: s_mbus_fmt failed\n", __func__);
		return ret;
	}

	if (mf->code != xlate->code) {
		dev_err(dev, "%s: unexpected pixel code change\n", __func__);
		return -EINVAL;
	}

	bytes_per_line = soc_mbus_bytes_per_line(mf->width, xlate->host_fmt);
	if (bytes_per_line < 0) {
		dev_err(dev, "%s: soc_mbus_bytes_per_line() failed\n",
				__func__);
		return bytes_per_line;
	}

	if (!is_dma_aligned(bytes_per_line, mf->height, pcdev->vb_mode)) {
		dev_err(dev, "%s: resulting geometry %ux%u not DMA aligned\n",
				__func__, mf->width, mf->height);
		return -EINVAL;
	}
	return 0;
}
Example #2
0
static int omap1_cam_set_crop(struct soc_camera_device *icd,
			       const struct v4l2_crop *crop)
{
	const struct v4l2_rect *rect = &crop->c;
	const struct soc_camera_format_xlate *xlate = icd->current_fmt;
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
	struct device *dev = icd->parent;
	struct soc_camera_host *ici = to_soc_camera_host(dev);
	struct omap1_cam_dev *pcdev = ici->priv;
	struct v4l2_subdev_format fmt = {
		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
	};
	struct v4l2_mbus_framefmt *mf = &fmt.format;
	int ret;

	ret = subdev_call_with_sense(pcdev, dev, icd, sd, video, s_crop, crop);
	if (ret < 0) {
		dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__,
			 rect->width, rect->height, rect->left, rect->top);
		return ret;
	}

	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
	if (ret < 0) {
		dev_warn(dev, "%s: failed to fetch current format\n", __func__);
		return ret;
	}

	ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode,
			false);
	if (ret < 0) {
		dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
				__func__, mf->width, mf->height,
				xlate->host_fmt->name);
		return ret;
	}

	if (!ret) {
		/* sensor returned geometry not DMA aligned, trying to fix */
		ret = set_format(pcdev, dev, icd, sd, &fmt, xlate);
		if (ret < 0) {
			dev_err(dev, "%s: failed to set format\n", __func__);
			return ret;
		}
	}

	icd->user_width	 = mf->width;
	icd->user_height = mf->height;

	return 0;
}