Commit dca6b6d1 authored by Sergio Aguirre's avatar Sergio Aguirre Committed by Mauro Carvalho Chehab

[media] V4L: soc-camera: regression fix: calculate .sizeimage in soc_camera.c

A recent patch has given individual soc-camera host drivers a possibility
to calculate .sizeimage and .bytesperline pixel format fields internally,
however, some drivers relied on the core calculating these values for
them, following a default algorithm. This patch restores the default
calculation for such drivers.

Based on initial patch by Guennadi Liakhovetski, found here:

http://www.spinics.net/lists/linux-media/msg31282.html

Except that this covers try_fmt aswell.
Signed-off-by: default avatarSergio Aguirre <saaguirre@ti.com>
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0b84834a
...@@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, ...@@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
} }
EXPORT_SYMBOL(soc_camera_apply_sensor_flags); EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
((x) >> 24) & 0xff
static int soc_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_pix_format *pix = &f->fmt.pix;
int ret;
dev_dbg(&icd->dev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
pixfmtstr(pix->pixelformat), pix->width, pix->height);
pix->bytesperline = 0;
pix->sizeimage = 0;
ret = ici->ops->try_fmt(icd, f);
if (ret < 0)
return ret;
if (!pix->sizeimage) {
if (!pix->bytesperline) {
const struct soc_camera_format_xlate *xlate;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate)
return -EINVAL;
ret = soc_mbus_bytes_per_line(pix->width,
xlate->host_fmt);
if (ret > 0)
pix->bytesperline = ret;
}
if (pix->bytesperline)
pix->sizeimage = pix->bytesperline * pix->height;
}
return 0;
}
static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct soc_camera_device *icd = file->private_data; struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
WARN_ON(priv != file->private_data); WARN_ON(priv != file->private_data);
...@@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, ...@@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL; return -EINVAL;
/* limit format to hardware capabilities */ /* limit format to hardware capabilities */
return ici->ops->try_fmt(icd, f); return soc_camera_try_fmt(icd, f);
} }
static int soc_camera_enum_input(struct file *file, void *priv, static int soc_camera_enum_input(struct file *file, void *priv,
...@@ -362,9 +401,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) ...@@ -362,9 +401,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
icd->user_formats = NULL; icd->user_formats = NULL;
} }
#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
((x) >> 24) & 0xff
/* Called with .vb_lock held, or from the first open(2), see comment there */ /* Called with .vb_lock held, or from the first open(2), see comment there */
static int soc_camera_set_fmt(struct soc_camera_device *icd, static int soc_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
...@@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd, ...@@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
pixfmtstr(pix->pixelformat), pix->width, pix->height); pixfmtstr(pix->pixelformat), pix->width, pix->height);
/* We always call try_fmt() before set_fmt() or set_crop() */ /* We always call try_fmt() before set_fmt() or set_crop() */
ret = ici->ops->try_fmt(icd, f); ret = soc_camera_try_fmt(icd, f);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment