diff options
| -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 | ||
