diff mbox series

[2/4] media: mt9m111: make VIDIOC_SUBDEV_G_FMT ioctl work with V4L2_SUBDEV_FORMAT_TRY

Message ID 1546103258-29025-3-git-send-email-akinobu.mita@gmail.com (mailing list archive)
State New, archived
Headers show
Series media: bugfixes for mt9m111 driver | expand

Commit Message

Akinobu Mita Dec. 29, 2018, 5:07 p.m. UTC
The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
is specified.

Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
 drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

Comments

Marco Felsch Dec. 31, 2018, 10:54 a.m. UTC | #1
On 18-12-30 02:07, Akinobu Mita wrote:
> The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
> V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
> is specified.
> 
> Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> ---
>  drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> index f0e47fd..acb4dee 100644
> --- a/drivers/media/i2c/mt9m111.c
> +++ b/drivers/media/i2c/mt9m111.c
> @@ -528,6 +528,16 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
>  	if (format->pad)
>  		return -EINVAL;
>  
> +	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API

This ifdef is made in the include/media/v4l2-subdev.h, so I would drop
it.

> +		mf = v4l2_subdev_get_try_format(sd, cfg, 0);

I would use format->pad instead of the static 0.

> +		format->format = *mf;

Is this correct? I tought v4l2_subdev_get_try_format() will return the
try_pad which we need to fill.

> +		return 0;
> +#else
> +		return -ENOTTY;

Return this error is not specified in the API-Doc.

> +#endif
> +	}
> +

If I understood it right, your patch should look like:

> +	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
> +		mf = v4l2_subdev_get_try_format(sd, cfg, format->pad);

Sakari please correct me if it's wrong.

>  	mf->width	= mt9m111->width;
>  	mf->height	= mt9m111->height;
>  	mf->code	= mt9m111->fmt->code;
> @@ -1090,6 +1100,26 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
>  	return 0;
>  }
>  
> +static int mt9m111_init_cfg(struct v4l2_subdev *sd,
> +			    struct v4l2_subdev_pad_config *cfg)

Is this related to the patch description? I would split this into a
seperate patch.

> +{
> +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> +	struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
> +	struct v4l2_mbus_framefmt *format =
> +		v4l2_subdev_get_try_format(sd, cfg, 0);
> +
> +	format->width	= mt9m111->width;
> +	format->height	= mt9m111->height;
> +	format->code	= mt9m111->fmt->code;
> +	format->colorspace	= mt9m111->fmt->colorspace;
> +	format->field	= V4L2_FIELD_NONE;
> +	format->ycbcr_enc	= V4L2_YCBCR_ENC_DEFAULT;
> +	format->quantization	= V4L2_QUANTIZATION_DEFAULT;
> +	format->xfer_func	= V4L2_XFER_FUNC_DEFAULT;
> +#endif
> +	return 0;
> +}
> +
>  static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
>  				struct v4l2_mbus_config *cfg)
>  {
> @@ -1115,6 +1145,7 @@ static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
>  };
>  
>  static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
> +	.init_cfg	= mt9m111_init_cfg,
>  	.enum_mbus_code = mt9m111_enum_mbus_code,
>  	.get_selection	= mt9m111_get_selection,
>  	.set_selection	= mt9m111_set_selection,
> -- 
> 2.7.4
> 
>
Akinobu Mita Dec. 31, 2018, 5:07 p.m. UTC | #2
2018年12月31日(月) 19:54 Marco Felsch <m.felsch@pengutronix.de>:
>
> On 18-12-30 02:07, Akinobu Mita wrote:
> > The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
> > V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
> > is specified.
> >
> > Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> > ---
> >  drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
> >  1 file changed, 31 insertions(+)
> >
> > diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> > index f0e47fd..acb4dee 100644
> > --- a/drivers/media/i2c/mt9m111.c
> > +++ b/drivers/media/i2c/mt9m111.c
> > @@ -528,6 +528,16 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
> >       if (format->pad)
> >               return -EINVAL;
> >
> > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
>
> This ifdef is made in the include/media/v4l2-subdev.h, so I would drop
> it.

I sent similar fix for ov2640 driver and kerel test robot reported
build test failure.  So I think this ifdef is necessary.

v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg137098.html
v2: https://www.mail-archive.com/linux-media@vger.kernel.org/msg141735.html

> > +             mf = v4l2_subdev_get_try_format(sd, cfg, 0);
>
> I would use format->pad instead of the static 0.

OK.

> > +             format->format = *mf;
>
> Is this correct? I tought v4l2_subdev_get_try_format() will return the
> try_pad which we need to fill.

I think this is correct.  Other sensor drivers are doing the same thing in
get_fmt() callback.

> > +             return 0;
> > +#else
> > +             return -ENOTTY;
>
> Return this error is not specified in the API-Doc.

I think this 'return -ENOTTY' is not reachable even if
CONFIG_VIDEO_V4L2_SUBDEV_API is not set, and can be replaced with any
return value.

> > +#endif
> > +     }
> > +
>
> If I understood it right, your patch should look like:
>
> > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY)
> > +             mf = v4l2_subdev_get_try_format(sd, cfg, format->pad);
>
> Sakari please correct me if it's wrong.
>
> >       mf->width       = mt9m111->width;
> >       mf->height      = mt9m111->height;
> >       mf->code        = mt9m111->fmt->code;
> > @@ -1090,6 +1100,26 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
> >       return 0;
> >  }
> >
> > +static int mt9m111_init_cfg(struct v4l2_subdev *sd,
> > +                         struct v4l2_subdev_pad_config *cfg)
>
> Is this related to the patch description? I would split this into a
> seperate patch.

The mt9m111_init_cfg() initializes the try format with default setting.
So this is required in case get_fmt() with V4L2_SUBDEV_FORMAT_TRY is
called before set_fmt() with V4L2_SUBDEV_FORMAT_TRY is called.

> > +{
> > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> > +     struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
> > +     struct v4l2_mbus_framefmt *format =
> > +             v4l2_subdev_get_try_format(sd, cfg, 0);
> > +
> > +     format->width   = mt9m111->width;
> > +     format->height  = mt9m111->height;
> > +     format->code    = mt9m111->fmt->code;
> > +     format->colorspace      = mt9m111->fmt->colorspace;
> > +     format->field   = V4L2_FIELD_NONE;
> > +     format->ycbcr_enc       = V4L2_YCBCR_ENC_DEFAULT;
> > +     format->quantization    = V4L2_QUANTIZATION_DEFAULT;
> > +     format->xfer_func       = V4L2_XFER_FUNC_DEFAULT;
> > +#endif
> > +     return 0;
> > +}
> > +
> >  static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
> >                               struct v4l2_mbus_config *cfg)
> >  {
> > @@ -1115,6 +1145,7 @@ static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
> >  };
> >
> >  static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
> > +     .init_cfg       = mt9m111_init_cfg,
> >       .enum_mbus_code = mt9m111_enum_mbus_code,
> >       .get_selection  = mt9m111_get_selection,
> >       .set_selection  = mt9m111_set_selection,
> > --
> > 2.7.4
> >
> >
Marco Felsch Jan. 3, 2019, 1:47 p.m. UTC | #3
On 19-01-01 02:07, Akinobu Mita wrote:
> 2018年12月31日(月) 19:54 Marco Felsch <m.felsch@pengutronix.de>:
> >
> > On 18-12-30 02:07, Akinobu Mita wrote:
> > > The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
> > > V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
> > > is specified.
> > >
> > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> > > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> > > ---
> > >  drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
> > >  1 file changed, 31 insertions(+)
> > >
> > > diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> > > index f0e47fd..acb4dee 100644
> > > --- a/drivers/media/i2c/mt9m111.c
> > > +++ b/drivers/media/i2c/mt9m111.c
> > > @@ -528,6 +528,16 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
> > >       if (format->pad)
> > >               return -EINVAL;
> > >
> > > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> >
> > This ifdef is made in the include/media/v4l2-subdev.h, so I would drop
> > it.
> 
> I sent similar fix for ov2640 driver and kerel test robot reported
> build test failure.  So I think this ifdef is necessary.
> 
> v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg137098.html
> v2: https://www.mail-archive.com/linux-media@vger.kernel.org/msg141735.html

You are absolutely true, sorry my mistake.. Unfortunately my patch [1] wasn't
applied which fixes it commonly. This patch will avoid the 2nd ifdef in
init_cfg() too.

[1] https://www.spinics.net/lists/linux-media/msg138940.html

> 
> > > +             mf = v4l2_subdev_get_try_format(sd, cfg, 0);
> >
> > I would use format->pad instead of the static 0.
> 
> OK.
> 
> > > +             format->format = *mf;
> >
> > Is this correct? I tought v4l2_subdev_get_try_format() will return the
> > try_pad which we need to fill.
> 
> I think this is correct.  Other sensor drivers are doing the same thing in
> get_fmt() callback.

Yes, you're right.

> > > +             return 0;
> > > +#else
> > > +             return -ENOTTY;
> >
> > Return this error is not specified in the API-Doc.
> 
> I think this 'return -ENOTTY' is not reachable even if
> CONFIG_VIDEO_V4L2_SUBDEV_API is not set, and can be replaced with any
> return value.

Sorry I didn't catched this. When it's not reachable why is it there and
why isn't it reachable? If the format->which = V4L2_SUBDEV_FORMAT_TRY
and we don't configure CONFIG_VIDEO_V4L2_SUBDEV_API, then this path will
be reached, or overlooked I something?

> 
> > > +#endif
> > > +     }
> > > +
> >
> > If I understood it right, your patch should look like:
> >
> > > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY)
> > > +             mf = v4l2_subdev_get_try_format(sd, cfg, format->pad);
> >
> > Sakari please correct me if it's wrong.
> >
> > >       mf->width       = mt9m111->width;
> > >       mf->height      = mt9m111->height;
> > >       mf->code        = mt9m111->fmt->code;
> > > @@ -1090,6 +1100,26 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
> > >       return 0;
> > >  }
> > >
> > > +static int mt9m111_init_cfg(struct v4l2_subdev *sd,
> > > +                         struct v4l2_subdev_pad_config *cfg)
> >
> > Is this related to the patch description? I would split this into a
> > seperate patch.
> 
> The mt9m111_init_cfg() initializes the try format with default setting.
> So this is required in case get_fmt() with V4L2_SUBDEV_FORMAT_TRY is
> called before set_fmt() with V4L2_SUBDEV_FORMAT_TRY is called.

Okay, I would split this but it's my personal opinion.

Kind regards,
Marco

> > > +{
> > > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> > > +     struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
> > > +     struct v4l2_mbus_framefmt *format =
> > > +             v4l2_subdev_get_try_format(sd, cfg, 0);
> > > +
> > > +     format->width   = mt9m111->width;
> > > +     format->height  = mt9m111->height;
> > > +     format->code    = mt9m111->fmt->code;
> > > +     format->colorspace      = mt9m111->fmt->colorspace;
> > > +     format->field   = V4L2_FIELD_NONE;
> > > +     format->ycbcr_enc       = V4L2_YCBCR_ENC_DEFAULT;
> > > +     format->quantization    = V4L2_QUANTIZATION_DEFAULT;
> > > +     format->xfer_func       = V4L2_XFER_FUNC_DEFAULT;
> > > +#endif
> > > +     return 0;
> > > +}
> > > +
> > >  static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
> > >                               struct v4l2_mbus_config *cfg)
> > >  {
> > > @@ -1115,6 +1145,7 @@ static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
> > >  };
> > >
> > >  static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
> > > +     .init_cfg       = mt9m111_init_cfg,
> > >       .enum_mbus_code = mt9m111_enum_mbus_code,
> > >       .get_selection  = mt9m111_get_selection,
> > >       .set_selection  = mt9m111_set_selection,
> > > --
> > > 2.7.4
> > >
> > >
>
Jacopo Mondi Jan. 4, 2019, 1:35 p.m. UTC | #4
Hello,
  sorry to jump in

On Thu, Jan 03, 2019 at 02:47:04PM +0100, Marco Felsch wrote:
> On 19-01-01 02:07, Akinobu Mita wrote:
> > 2018年12月31日(月) 19:54 Marco Felsch <m.felsch@pengutronix.de>:
> > >
> > > On 18-12-30 02:07, Akinobu Mita wrote:
> > > > The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
> > > > V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
> > > > is specified.
> > > >
> > > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> > > > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > > > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> > > > ---
> > > >  drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
> > > >  1 file changed, 31 insertions(+)
> > > >
> > > > diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> > > > index f0e47fd..acb4dee 100644
> > > > --- a/drivers/media/i2c/mt9m111.c
> > > > +++ b/drivers/media/i2c/mt9m111.c
> > > > @@ -528,6 +528,16 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
> > > >       if (format->pad)
> > > >               return -EINVAL;
> > > >
> > > > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> > >
> > > This ifdef is made in the include/media/v4l2-subdev.h, so I would drop
> > > it.
> >
> > I sent similar fix for ov2640 driver and kerel test robot reported
> > build test failure.  So I think this ifdef is necessary.
> >
> > v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg137098.html
> > v2: https://www.mail-archive.com/linux-media@vger.kernel.org/msg141735.html
>
> You are absolutely true, sorry my mistake.. Unfortunately my patch [1] wasn't
> applied which fixes it commonly. This patch will avoid the 2nd ifdef in
> init_cfg() too.
>
> [1] https://www.spinics.net/lists/linux-media/msg138940.html
>

There have been recents attempts to do the same, please see:
https://lkml.org/lkml/2018/11/28/1080
and Hans' attempt at
https://patchwork.kernel.org/patch/10717699/

Unfortunately seems like we're gonna live with those ifdefs

Thanks
  j
Akinobu Mita Jan. 5, 2019, 2:52 p.m. UTC | #5
2019年1月3日(木) 22:47 Marco Felsch <m.felsch@pengutronix.de>:
>
> On 19-01-01 02:07, Akinobu Mita wrote:
> > 2018年12月31日(月) 19:54 Marco Felsch <m.felsch@pengutronix.de>:
> > >
> > > On 18-12-30 02:07, Akinobu Mita wrote:
> > > > The VIDIOC_SUBDEV_G_FMT ioctl for this driver doesn't recognize
> > > > V4L2_SUBDEV_FORMAT_TRY and always works as if V4L2_SUBDEV_FORMAT_ACTIVE
> > > > is specified.
> > > >
> > > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> > > > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > > > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> > > > ---
> > > >  drivers/media/i2c/mt9m111.c | 31 +++++++++++++++++++++++++++++++
> > > >  1 file changed, 31 insertions(+)
> > > >
> > > > diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> > > > index f0e47fd..acb4dee 100644
> > > > --- a/drivers/media/i2c/mt9m111.c
> > > > +++ b/drivers/media/i2c/mt9m111.c
> > > > @@ -528,6 +528,16 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
> > > >       if (format->pad)
> > > >               return -EINVAL;
> > > >
> > > > +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > > +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
> > >
> > > This ifdef is made in the include/media/v4l2-subdev.h, so I would drop
> > > it.
> >
> > I sent similar fix for ov2640 driver and kerel test robot reported
> > build test failure.  So I think this ifdef is necessary.
> >
> > v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg137098.html
> > v2: https://www.mail-archive.com/linux-media@vger.kernel.org/msg141735.html
>
> You are absolutely true, sorry my mistake.. Unfortunately my patch [1] wasn't
> applied which fixes it commonly. This patch will avoid the 2nd ifdef in
> init_cfg() too.
>
> [1] https://www.spinics.net/lists/linux-media/msg138940.html
>
> >
> > > > +             mf = v4l2_subdev_get_try_format(sd, cfg, 0);
> > >
> > > I would use format->pad instead of the static 0.
> >
> > OK.
> >
> > > > +             format->format = *mf;
> > >
> > > Is this correct? I tought v4l2_subdev_get_try_format() will return the
> > > try_pad which we need to fill.
> >
> > I think this is correct.  Other sensor drivers are doing the same thing in
> > get_fmt() callback.
>
> Yes, you're right.
>
> > > > +             return 0;
> > > > +#else
> > > > +             return -ENOTTY;
> > >
> > > Return this error is not specified in the API-Doc.
> >
> > I think this 'return -ENOTTY' is not reachable even if
> > CONFIG_VIDEO_V4L2_SUBDEV_API is not set, and can be replaced with any
> > return value.
>
> Sorry I didn't catched this. When it's not reachable why is it there and
> why isn't it reachable? If the format->which = V4L2_SUBDEV_FORMAT_TRY
> and we don't configure CONFIG_VIDEO_V4L2_SUBDEV_API, then this path will
> be reached, or overlooked I something?

As far as I can see, when CONFIG_VIDEO_V4L2_SUBDEV_API is not defined,
the get_fmt() callback is always called with
'format->which == V4L2_SUBDEV_FORMAT_ACTIVE'.

There is only one call site that the get_fmt() is called with
'format->which == V4L2_SUBDEV_FORMAT_TRY' in
drivers/media/v4l2-core/v4l2-subdev.c: subdev_do_ioctl().
But the call site is enclosed by ifdef CONFIG_VIDEO_V4L2_SUBDEV_API.

So the hunk of the patch can be changed to:

        if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
                mf = v4l2_subdev_get_try_format(sd, cfg, format->pad);
                format->format = *mf;
                return 0;
#endif
        }
diff mbox series

Patch

diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index f0e47fd..acb4dee 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -528,6 +528,16 @@  static int mt9m111_get_fmt(struct v4l2_subdev *sd,
 	if (format->pad)
 		return -EINVAL;
 
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		mf = v4l2_subdev_get_try_format(sd, cfg, 0);
+		format->format = *mf;
+		return 0;
+#else
+		return -ENOTTY;
+#endif
+	}
+
 	mf->width	= mt9m111->width;
 	mf->height	= mt9m111->height;
 	mf->code	= mt9m111->fmt->code;
@@ -1090,6 +1100,26 @@  static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
 	return 0;
 }
 
+static int mt9m111_init_cfg(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg)
+{
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
+	struct v4l2_mbus_framefmt *format =
+		v4l2_subdev_get_try_format(sd, cfg, 0);
+
+	format->width	= mt9m111->width;
+	format->height	= mt9m111->height;
+	format->code	= mt9m111->fmt->code;
+	format->colorspace	= mt9m111->fmt->colorspace;
+	format->field	= V4L2_FIELD_NONE;
+	format->ycbcr_enc	= V4L2_YCBCR_ENC_DEFAULT;
+	format->quantization	= V4L2_QUANTIZATION_DEFAULT;
+	format->xfer_func	= V4L2_XFER_FUNC_DEFAULT;
+#endif
+	return 0;
+}
+
 static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
 				struct v4l2_mbus_config *cfg)
 {
@@ -1115,6 +1145,7 @@  static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
+	.init_cfg	= mt9m111_init_cfg,
 	.enum_mbus_code = mt9m111_enum_mbus_code,
 	.get_selection	= mt9m111_get_selection,
 	.set_selection	= mt9m111_set_selection,