mbox series

[0/5] Improvements to IMX290 CMOS driver

Message ID 20191129190541.30315-1-manivannan.sadhasivam@linaro.org
Headers show
Series Improvements to IMX290 CMOS driver | expand

Message

Manivannan Sadhasivam Nov. 29, 2019, 7:05 p.m. UTC
Hello,

This patchset adds improvements to the existing IMX290 CMOS driver from
Sony. The major changes are adding 2 lane support, test pattern generation,
RAW12 mode support and configurable link frequency & pixel rate.

The link frequency & pixel rate combinations depend on various factors like
lane count, resolution and image format as per the datasheet.

Thanks,
Mani

Manivannan Sadhasivam (5):
  media: i2c: imx290: Add support for 2 data lanes
  media: i2c: imx290: Add support for test pattern generation
  media: i2c: imx290: Add RAW12 mode support
  media: i2c: imx290: Add support to enumerate all frame sizes
  media: i2c: imx290: Add configurable link frequency and pixel rate

 drivers/media/i2c/imx290.c | 328 +++++++++++++++++++++++++++++++------
 1 file changed, 277 insertions(+), 51 deletions(-)

-- 
2.17.1

Comments

Fabio Estevam Nov. 29, 2019, 7:49 p.m. UTC | #1
Hi Manivannan,

On Fri, Nov 29, 2019 at 4:07 PM Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:
               }
> +

> +               imx290->bpp = 10;

> +

> +               break;

> +       case MEDIA_BUS_FMT_SRGGB12_1X12:

> +               ret = imx290_set_register_array(imx290, imx290_12bit_settings,

> +                                               ARRAY_SIZE(

> +                                                       imx290_12bit_settings));


Could you please write the ARRAY_SIZE and its parameter in the same line?

It would improve readability.

Thanks
Manivannan Sadhasivam Dec. 15, 2019, 5:46 p.m. UTC | #2
Hi Sakari,

On Tue, Dec 03, 2019 at 10:54:17AM +0200, Sakari Ailus wrote:
> Hi Manivannan,

> 

> On Sat, Nov 30, 2019 at 12:35:39AM +0530, Manivannan Sadhasivam wrote:

> > IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and

> > 12 bit formats. Since the driver already supports RAW10 mode, let's add

> > the missing RAW12 mode as well.

> > 

> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

> > ---

> >  drivers/media/i2c/imx290.c | 32 ++++++++++++++++++++++++++++++++

> >  1 file changed, 32 insertions(+)

> > 

> > diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c

> > index e218c959a729..d5bb3a59ac46 100644

> > --- a/drivers/media/i2c/imx290.c

> > +++ b/drivers/media/i2c/imx290.c

> > @@ -75,6 +75,7 @@ struct imx290 {

> >  	struct clk *xclk;

> >  	struct regmap *regmap;

> >  	int nlanes;

> > +	u8 bpp;

> >  

> >  	struct v4l2_subdev sd;

> >  	struct v4l2_fwnode_endpoint ep;

> > @@ -98,6 +99,7 @@ struct imx290_pixfmt {

> >  

> >  static const struct imx290_pixfmt imx290_formats[] = {

> >  	{ MEDIA_BUS_FMT_SRGGB10_1X10 },

> > +	{ MEDIA_BUS_FMT_SRGGB12_1X12 },

> >  };

> >  

> >  static const struct regmap_config imx290_regmap_config = {

> > @@ -265,6 +267,18 @@ static const struct imx290_regval imx290_10bit_settings[] = {

> >  	{ 0x300b, 0x00},

> >  };

> >  

> > +static const struct imx290_regval imx290_12bit_settings[] = {

> > +	{ 0x3005, 0x01 },

> > +	{ 0x3046, 0x01 },

> > +	{ 0x3129, 0x00 },

> > +	{ 0x317c, 0x00 },

> > +	{ 0x31ec, 0x0e },

> > +	{ 0x3441, 0x0c },

> > +	{ 0x3442, 0x0c },

> > +	{ 0x300a, 0xf0 },

> > +	{ 0x300b, 0x00 },

> > +};

> > +

> >  /* supported link frequencies */

> >  static const s64 imx290_link_freq[] = {

> >  	IMX290_DEFAULT_LINK_FREQ,

> > @@ -550,6 +564,21 @@ static int imx290_write_current_format(struct imx290 *imx290,

> >  			dev_err(imx290->dev, "Could not set format registers\n");

> >  			return ret;

> >  		}

> > +

> > +		imx290->bpp = 10;

> > +

> > +		break;

> > +	case MEDIA_BUS_FMT_SRGGB12_1X12:

> > +		ret = imx290_set_register_array(imx290, imx290_12bit_settings,

> > +						ARRAY_SIZE(

> > +							imx290_12bit_settings));

> > +		if (ret < 0) {

> > +			dev_err(imx290->dev, "Could not set format registers\n");

> > +			return ret;

> > +		}

> > +

> > +		imx290->bpp = 12;

> > +

> >  		break;

> >  	default:

> >  		dev_err(imx290->dev, "Unknown pixel format\n");

> > @@ -910,6 +939,9 @@ static int imx290_probe(struct i2c_client *client)

> >  		goto free_err;

> >  	}

> >  

> > +	/* Default bits per pixel value */

> > +	imx290->bpp = 10;

> 

> Where is the format being initialised at the moment? Nowhere?

> 

> If that is the case, I think it should be fixed before this patch.

> 


Sorry, I don't quite understand what you're suggesting here. The bpp
is initialised because that's the default bit value at power up and
this value is being used below in imx290_calc_pixel_rate(). I'm not sure
why we need to initialise the format before set_fmt!

Thanks,
Mani

> > +

> >  	mutex_init(&imx290->lock);

> >  

> >  	v4l2_ctrl_handler_init(&imx290->ctrls, 4);

> 

> -- 

> Kind regards,

> 

> Sakari Ailus
Manivannan Sadhasivam Dec. 16, 2019, 4:04 a.m. UTC | #3
On Sun, Dec 15, 2019 at 03:52:37PM -0800, karthik poduval wrote:
> What if someone adds RAW8 or RAW14 formats in future the enum frame sizes

> code doesn't have to be patched again if written using a loop on formats

> array.

> 


Please don't top post :)

IMX290 only supports RAW10 and RAW12 formats. And I don't think this driver
can handle any other CMOS sensors from Sony, so looping over imx290_formats
seems unnecessary to me.

Thanks,
Mani

> On Sun, Dec 15, 2019, 9:49 AM Manivannan Sadhasivam <

> manivannan.sadhasivam@linaro.org> wrote:

> 

> > Hi Sakari,

> >

> > On Tue, Dec 03, 2019 at 10:56:04AM +0200, Sakari Ailus wrote:

> > > On Sat, Nov 30, 2019 at 12:35:40AM +0530, Manivannan Sadhasivam wrote:

> > > > Add support to enumerate all frame sizes supported by IMX290. This is

> > > > required for using with userspace tools such as libcamera.

> > > >

> > > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org

> > >

> > > > ---

> > > >  drivers/media/i2c/imx290.c | 20 ++++++++++++++++++++

> > > >  1 file changed, 20 insertions(+)

> > > >

> > > > diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c

> > > > index d5bb3a59ac46..f26c4a0ee0a0 100644

> > > > --- a/drivers/media/i2c/imx290.c

> > > > +++ b/drivers/media/i2c/imx290.c

> > > > @@ -468,6 +468,25 @@ static int imx290_enum_mbus_code(struct

> > v4l2_subdev *sd,

> > > >     return 0;

> > > >  }

> > > >

> > > > +static int imx290_enum_frame_size(struct v4l2_subdev *subdev,

> > > > +                             struct v4l2_subdev_pad_config *cfg,

> > > > +                             struct v4l2_subdev_frame_size_enum *fse)

> > > > +{

> > > > +   if ((fse->code != imx290_formats[0].code) &&

> > > > +       (fse->code != imx290_formats[1].code))

> > >

> > > Please use a loop over imx290_formats instead.

> > >

> >

> > May I know why? What benefit does it provide over current method?

> >

> > Thanks,

> > Mani

> >

> > > > +           return -EINVAL;

> > > > +

> > > > +   if (fse->index >= ARRAY_SIZE(imx290_modes))

> > > > +           return -EINVAL;

> > > > +

> > > > +   fse->min_width = imx290_modes[fse->index].width;

> > > > +   fse->max_width = imx290_modes[fse->index].width;

> > > > +   fse->min_height = imx290_modes[fse->index].height;

> > > > +   fse->max_height = imx290_modes[fse->index].height;

> > > > +

> > > > +   return 0;

> > > > +}

> > > > +

> > > >  static int imx290_get_fmt(struct v4l2_subdev *sd,

> > > >                       struct v4l2_subdev_pad_config *cfg,

> > > >                       struct v4l2_subdev_format *fmt)

> > > > @@ -820,6 +839,7 @@ static const struct v4l2_subdev_video_ops

> > imx290_video_ops = {

> > > >  static const struct v4l2_subdev_pad_ops imx290_pad_ops = {

> > > >     .init_cfg = imx290_entity_init_cfg,

> > > >     .enum_mbus_code = imx290_enum_mbus_code,

> > > > +   .enum_frame_size = imx290_enum_frame_size,

> > > >     .get_fmt = imx290_get_fmt,

> > > >     .set_fmt = imx290_set_fmt,

> > > >  };

> > >

> > > --

> > > Regards,

> > >

> > > Sakari Ailus

> >