static int unicam_camera_set_fmt(struct soc_camera_device *icd,
				 struct v4l2_format *f)
{
	struct device *dev = icd->dev.parent;
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct unicam_camera_dev *unicam_dev = ici->priv;
	const struct soc_camera_format_xlate *xlate = NULL;
	struct v4l2_pix_format *pix = &f->fmt.pix;
	struct v4l2_mbus_framefmt mf;
	int ret;
	u32 skip_frames = 0;

	dprintk("-enter");
	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
	if (!xlate) {
		dev_warn(dev, "Format %x not found\n", pix->pixelformat);
		return -EINVAL;
	}

	mf.width = pix->width;
	mf.height = pix->height;
	mf.field = pix->field;
	mf.colorspace = pix->colorspace;
	mf.code = xlate->code;

	ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);

	if (mf.code != xlate->code)
		return -EINVAL;

	if (ret < 0) {
		dev_warn(dev, "Failed to configure for format %x\n",
			 pix->pixelformat);
		return ret;
	}
	/*TODO limit here any maximum size */

	ret = v4l2_subdev_call(sd, sensor, g_skip_frames, &skip_frames);
	if (ret < 0) {
		dev_warn(dev,
			 "sensor driver doesn't implement g_skip_frames operation\n");
		dev_warn(dev, "assuming zero skip frames\n");
		skip_frames = 0;
		ret = 0;
	}

	unicam_dev->skip_frames = skip_frames;

	pix->width = mf.width;
	pix->height = mf.height;
	pix->field = mf.field;
	pix->colorspace = mf.colorspace;
	icd->current_fmt = xlate;
	iprintk("format set to %c%c%c%c res=%dx%d success=%d",
		pixfmtstr(pix->pixelformat), pix->width, pix->height, ret);
	dprintk("-exit");
	return ret;
}
static int unicam_camera_try_fmt(struct soc_camera_device *icd,
				 struct v4l2_format *f)
{
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
	const struct soc_camera_format_xlate *xlate;
	struct v4l2_pix_format *pix = &f->fmt.pix;
	struct v4l2_mbus_framefmt mf;
	struct v4l2_format thumb_fmt;
	struct v4l2_pix_format *thumb_pix;
	__u32 pixfmt = pix->pixelformat;
	int thumb=0;
	int ret;

	pr_debug("-enter");
	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
	if (!xlate) {
		dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
		return -EINVAL;
	}

	pix->sizeimage = pix->height * pix->bytesperline;

	/* limit to sensor capabilities */
	mf.width = pix->width;
	mf.height = pix->height;
	mf.field = pix->field;
	mf.colorspace = pix->colorspace;
	mf.code = xlate->code;

	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
	if (ret < 0)
		return ret;

	pix->width = mf.width;
	pix->height = mf.height;
	pix->colorspace = mf.colorspace;

	switch (mf.field) {
	case V4L2_FIELD_ANY:
	case V4L2_FIELD_NONE:
		pix->field = V4L2_FIELD_NONE;
		break;
	default:
		dev_err(icd->dev.parent, "Field type %d unsupported.\n",
			mf.field);
		return -EINVAL;
	}

	/* what format can unicam support */
	switch (mf.code) {
	case V4L2_MBUS_FMT_JPEG_1X8:
		/* check here if thumbnail is supported
		and check thumbnail format */
		ret =
		    v4l2_subdev_call(sd, core, ioctl, VIDIOC_THUMB_SUPPORTED,
				     (void *)&thumb);
		if ((!ret) && thumb) {
			ret =
			    v4l2_subdev_call(sd, core, ioctl,
					     VIDIOC_THUMB_G_FMT,
					     (void *)&thumb_fmt);
			if (ret < 0) {
				dev_err(icd->dev.parent,
					"sensor driver should report thumbnail format\n");
				return -EINVAL;
			}
			thumb_pix = &thumb_fmt.fmt.pix;
			switch (thumb_pix->pixelformat) {
			case V4L2_PIX_FMT_YUYV:
			case V4L2_PIX_FMT_UYVY:
				pr_debug
				    ("sensor supports thumbnail %c%c%c%c format",
				     pixfmtstr(thumb_pix->pixelformat));
				break;
			default:
				dev_err(icd->dev.parent,
					"sensor thumbnail format %c%c%c%c not supported\n",
					pixfmtstr(thumb_pix->pixelformat));
				return -EINVAL;
			}
		} else
			pr_debug
			    ("sensor doesnot support thumbnail (thumb=%d, ret=%d)\n",
			     thumb, ret);

	case V4L2_MBUS_FMT_YUYV8_2X8:
	case V4L2_MBUS_FMT_UYVY8_2X8:
		/* Above formats are supported */
		break;
	default:
		dev_err(icd->dev.parent, "Sensor format code %d unsupported.\n",
			mf.code);
		return -EINVAL;
	}

	pr_debug("trying format=%c%c%c%c res=%dx%d success=%d",
		pixfmtstr(pixfmt), mf.width, mf.height, ret);
	pr_debug("-exit");
	return ret;
}