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; }
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; }