diff options
author | Sergio Aguirre <saaguirre@ti.com> | 2011-04-11 12:14:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-04 15:47:56 -0400 |
commit | dca6b6d18fa4428c4539e45f7a43040e388ab99e (patch) | |
tree | 60023ee7652741d1706c1cec7cc336ac9bc19eb1 | |
parent | 0b84834a5a9f5fe8f3760560ef8c5b1536d22bd1 (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.c | 48 |
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 | } |
137 | EXPORT_SYMBOL(soc_camera_apply_sensor_flags); | 137 | EXPORT_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 | |||
142 | static 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 | |||
139 | static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, | 179 | static 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 | ||
155 | static int soc_camera_enum_input(struct file *file, void *priv, | 194 | 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 | 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 */ |
369 | static int soc_camera_set_fmt(struct soc_camera_device *icd, | 405 | static 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 | ||