@@ -2034,7 +2034,7 @@ static int raw_output_format_match_input(u32 input, u32 output)
return -EINVAL;
}
-static u32 get_pixel_depth(u32 pixelformat)
+u32 atomisp_get_pixel_depth(u32 pixelformat)
{
switch (pixelformat) {
case V4L2_PIX_FMT_YUV420:
@@ -4816,15 +4816,6 @@ int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
return 0;
}
-int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f)
-{
- struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
-
- f->fmt.pix = pipe->pix;
-
- return 0;
-}
-
static void __atomisp_update_stream_env(struct atomisp_sub_device *asd,
u16 stream_index, struct atomisp_input_stream_info *stream_info)
{
@@ -4973,7 +4964,7 @@ atomisp_try_fmt_file(struct atomisp_device *isp, struct v4l2_format *f)
return -EINVAL;
}
- depth = get_pixel_depth(pixelformat);
+ depth = atomisp_get_pixel_depth(pixelformat);
if (field == V4L2_FIELD_ANY) {
field = V4L2_FIELD_NONE;
@@ -266,8 +266,6 @@ int atomisp_compare_grid(struct atomisp_sub_device *asd,
int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
struct atomisp_sensor_mode_data *config);
-int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f);
-
/* This function looks up the closest available resolution. */
int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
bool *res_overflow);
@@ -341,6 +339,8 @@ enum atomisp_metadata_type
atomisp_get_metadata_type(struct atomisp_sub_device *asd,
enum ia_css_pipe_id pipe_id);
+u32 atomisp_get_pixel_depth(u32 pixelformat);
+
/* Function for HAL to inject a fake event to wake up poll thread */
int atomisp_inject_a_fake_event(struct atomisp_sub_device *asd, int *event);
@@ -838,15 +838,53 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
static int atomisp_g_fmt_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE
+ };
struct video_device *vdev = video_devdata(file);
struct atomisp_device *isp = video_get_drvdata(vdev);
-
+ struct v4l2_fmtdesc fmtdesc = { 0 };
+ struct atomisp_video_pipe *pipe;
+ struct atomisp_sub_device *asd;
+ struct v4l2_subdev *camera;
+ u32 depth;
int ret;
rt_mutex_lock(&isp->mutex);
- ret = atomisp_get_fmt(vdev, f);
+ pipe = atomisp_to_video_pipe(vdev);
rt_mutex_unlock(&isp->mutex);
- return ret;
+
+ f->fmt.pix = pipe->pix;
+ if (!f->fmt.pix.width) {
+ asd = atomisp_to_video_pipe(vdev)->asd;
+ if (!asd)
+ return -EINVAL;
+
+ camera = isp->inputs[asd->input_curr].camera;
+ if(!camera)
+ return -EINVAL;
+
+ ret = atomisp_enum_fmt_cap(file, fh, &fmtdesc);
+ if (ret)
+ return ret;
+
+ rt_mutex_lock(&isp->mutex);
+ ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
+ pad, get_fmt, NULL, &fmt);
+ rt_mutex_unlock(&isp->mutex);
+ if (ret)
+ return ret;
+
+ v4l2_fill_pix_format(&f->fmt.pix, &fmt.format);
+
+ f->fmt.pix.pixelformat = fmtdesc.pixelformat;
+ }
+
+ depth = atomisp_get_pixel_depth(f->fmt.pix.pixelformat);
+ f->fmt.pix.bytesperline = (f->fmt.pix.width * depth) >> 3;
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+ return 0;
}
static int atomisp_g_fmt_file(struct file *file, void *fh,
The current logic only initializes pipe->pix after setting up a pipeline - e. g. after start streaming. While it makes sense to get the format of the pipeline, when it is set, this breaks support for generic applications, as they rely on getting the current sensor format (which is usually the highest resolution format). So, implement a call to the sensor's get_fmt, when this is called before setting up a pipeline. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> --- .../staging/media/atomisp/pci/atomisp_cmd.c | 13 +----- .../staging/media/atomisp/pci/atomisp_cmd.h | 4 +- .../staging/media/atomisp/pci/atomisp_ioctl.c | 44 +++++++++++++++++-- 3 files changed, 45 insertions(+), 16 deletions(-)