aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergio Aguirre <saaguirre@ti.com>2011-04-11 12:14:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-04 15:47:56 -0400
commitdca6b6d18fa4428c4539e45f7a43040e388ab99e (patch)
tree60023ee7652741d1706c1cec7cc336ac9bc19eb1
parent0b84834a5a9f5fe8f3760560ef8c5b1536d22bd1 (diff)
[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: Sergio Aguirre <saaguirre@ti.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/soc_camera.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 3973f9a94753..ddb4c091dedc 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
136} 136}
137EXPORT_SYMBOL(soc_camera_apply_sensor_flags); 137EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
138 138
139#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
140 ((x) >> 24) & 0xff
141
142static int soc_camera_try_fmt(struct soc_camera_device *icd,
143 struct v4l2_format *f)
144{
145 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
146 struct v4l2_pix_format *pix = &f->fmt.pix;
147 int ret;
148
149 dev_dbg(&icd->dev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
150 pixfmtstr(pix->pixelformat), pix->width, pix->height);
151
152 pix->bytesperline = 0;
153 pix->sizeimage = 0;
154
155 ret = ici->ops->try_fmt(icd, f);
156 if (ret < 0)
157 return ret;
158
159 if (!pix->sizeimage) {
160 if (!pix->bytesperline) {
161 const struct soc_camera_format_xlate *xlate;
162
163 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
164 if (!xlate)
165 return -EINVAL;
166
167 ret = soc_mbus_bytes_per_line(pix->width,
168 xlate->host_fmt);
169 if (ret > 0)
170 pix->bytesperline = ret;
171 }
172 if (pix->bytesperline)
173 pix->sizeimage = pix->bytesperline * pix->height;
174 }
175
176 return 0;
177}
178
139static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, 179static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
140 struct v4l2_format *f) 180 struct v4l2_format *f)
141{ 181{
142 struct soc_camera_device *icd = file->private_data; 182 struct soc_camera_device *icd = file->private_data;
143 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
144 183
145 WARN_ON(priv != file->private_data); 184 WARN_ON(priv != file->private_data);
146 185
@@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
149 return -EINVAL; 188 return -EINVAL;
150 189
151 /* limit format to hardware capabilities */ 190 /* limit format to hardware capabilities */
152 return ici->ops->try_fmt(icd, f); 191 return soc_camera_try_fmt(icd, f);
153} 192}
154 193
155static int soc_camera_enum_input(struct file *file, void *priv, 194static 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 icd->user_formats = NULL; 401 icd->user_formats = NULL;
363} 402}
364 403
365#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
366 ((x) >> 24) & 0xff
367
368/* Called with .vb_lock held, or from the first open(2), see comment there */ 404/* Called with .vb_lock held, or from the first open(2), see comment there */
369static int soc_camera_set_fmt(struct soc_camera_device *icd, 405static int soc_camera_set_fmt(struct soc_camera_device *icd,
370 struct v4l2_format *f) 406 struct v4l2_format *f)
@@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
377 pixfmtstr(pix->pixelformat), pix->width, pix->height); 413 pixfmtstr(pix->pixelformat), pix->width, pix->height);
378 414
379 /* We always call try_fmt() before set_fmt() or set_crop() */ 415 /* We always call try_fmt() before set_fmt() or set_crop() */
380 ret = ici->ops->try_fmt(icd, f); 416 ret = soc_camera_try_fmt(icd, f);
381 if (ret < 0) 417 if (ret < 0)
382 return ret; 418 return ret;
383 419