Re: [PATCH v2 09/13] media: i2c: imx214: Extract format and crop settings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi André

On Wed, Nov 20, 2024 at 9:07 PM André Apitzsch <git@xxxxxxxxxxx> wrote:
>
> Hi Ricardo,
>
> Am Mittwoch, dem 30.10.2024 um 13:10 +0100 schrieb Ricardo Ribalda
> Delgado:
> > Hi
> >
> > Aren't you changing the binning mode for 1920x1080  with this patch?
> > I think that could be considered an ABI change.
>
> Is the problem that the ABI changes or that it is not mentioned in the
> commit message?

I think it is a combination of both. There will be products out there
that after applying this change will get different frames using the
same configuration.

@Sakari Ailus  What do we usually do in these cases?

> >
> > Also, if we are not letting the user change the value, I do not see
> > much value in setting the cropping programmatically, I'd rather not
> > take this change.
>
> I assume the first "value" refers to "binning value", that cannot be
> changed by the user. Is it right, that .set_selection needs to be
> implemented to change that?

I believe set_selection is the correct way, yes. Sakari again to keep
me honest :)

>
> The different values are set programmatically to reduce the number of
> entries in the cci reg sequences to make it easier to add more modes
> later.

If it is not a huge rework: Can we start by having  the crop area
moved to imx214_mode and add all the binning logic to a different
patch?
It will be easier to discuss things that way.

>
> Regards,
> André
>
> >
> > On Mon, Oct 21, 2024 at 12:14 AM André Apitzsch via B4 Relay
> > <devnull+git.apitzsch.eu@xxxxxxxxxx> wrote:
> > >
> > > From: André Apitzsch <git@xxxxxxxxxxx>
> > >
> > > Remove format and crop settings from register sequences and set
> > > them
> > > programmatically.
> > >
> > > Signed-off-by: André Apitzsch <git@xxxxxxxxxxx>
> > > ---
> > >  drivers/media/i2c/imx214.c | 129
> > > ++++++++++++++++++++++++++++++++++-----------
> > >  1 file changed, 97 insertions(+), 32 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/imx214.c
> > > b/drivers/media/i2c/imx214.c
> > > index
> > > cb443d8bee6fe72dc9378b2c2d3caae09f8642c5..87a03e292e19ccd71f1b2dcee
> > > 3409826b2f5cb6f 100644
> > > --- a/drivers/media/i2c/imx214.c
> > > +++ b/drivers/media/i2c/imx214.c
> > > @@ -96,6 +96,9 @@
> > >  #define IMX214_REG_PREPLLCK_VT_DIV     CCI_REG8(0x0305)
> > >  #define IMX214_REG_PLL_VT_MPY          CCI_REG16(0x0306)
> > >  #define IMX214_REG_OPPXCK_DIV          CCI_REG8(0x0309)
> > > +#define IMX214_OPPXCK_DIV_COMP6                6
> > > +#define IMX214_OPPXCK_DIV_COMP8                8
> > > +#define IMX214_OPPXCK_DIV_RAW10                10
> > >  #define IMX214_REG_OPSYCK_DIV          CCI_REG8(0x030b)
> > >  #define IMX214_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
> > >  #define IMX214_PLL_SINGLE              0
> > > @@ -132,6 +135,9 @@
> > >  #define IMX214_BINNING_NONE            0
> > >  #define IMX214_BINNING_ENABLE          1
> > >  #define IMX214_REG_BINNING_TYPE                CCI_REG8(0x0901)
> > > +#define IMX214_BINNING_1X1             0
> > > +#define IMX214_BINNING_2X2             0x22
> > > +#define IMX214_BINNING_4X4             0x44
> > >  #define IMX214_REG_BINNING_WEIGHTING   CCI_REG8(0x0902)
> > >  #define IMX214_BINNING_AVERAGE         0x00
> > >  #define IMX214_BINNING_SUMMED          0x01
> > > @@ -211,36 +217,22 @@ static const struct cci_reg_sequence
> > > mode_4096x2304[] = {
> > >         { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
> > >         { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH
> > > },
> > >         { IMX214_REG_EXPOSURE_RATIO, 1 },
> > > -       { IMX214_REG_X_ADD_STA, 56 },
> > > -       { IMX214_REG_Y_ADD_STA, 408 },
> > > -       { IMX214_REG_X_ADD_END, 4151 },
> > > -       { IMX214_REG_Y_ADD_END, 2711 },
> > >         { IMX214_REG_X_EVEN_INC, 1 },
> > >         { IMX214_REG_X_ODD_INC, 1 },
> > >         { IMX214_REG_Y_EVEN_INC, 1 },
> > >         { IMX214_REG_Y_ODD_INC, 1 },
> > > -       { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE },
> > > -       { IMX214_REG_BINNING_TYPE, 0 },
> > >         { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE },
> > >         { CCI_REG8(0x3000), 0x35 },
> > >         { CCI_REG8(0x3054), 0x01 },
> > >         { CCI_REG8(0x305C), 0x11 },
> > >
> > > -       { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10
> > > },
> > > -       { IMX214_REG_X_OUTPUT_SIZE, 4096 },
> > > -       { IMX214_REG_Y_OUTPUT_SIZE, 2304 },
> > >         { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE },
> > >         { IMX214_REG_SCALE_M, 2 },
> > > -       { IMX214_REG_DIG_CROP_X_OFFSET, 0 },
> > > -       { IMX214_REG_DIG_CROP_Y_OFFSET, 0 },
> > > -       { IMX214_REG_DIG_CROP_WIDTH, 4096 },
> > > -       { IMX214_REG_DIG_CROP_HEIGHT, 2304 },
> > >
> > >         { IMX214_REG_VTPXCK_DIV, 5 },
> > >         { IMX214_REG_VTSYCK_DIV, 2 },
> > >         { IMX214_REG_PREPLLCK_VT_DIV, 3 },
> > >         { IMX214_REG_PLL_VT_MPY, 150 },
> > > -       { IMX214_REG_OPPXCK_DIV, 10 },
> > >         { IMX214_REG_OPSYCK_DIV, 1 },
> > >         { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
> > >
> > > @@ -281,36 +273,22 @@ static const struct cci_reg_sequence
> > > mode_1920x1080[] = {
> > >         { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
> > >         { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH
> > > },
> > >         { IMX214_REG_EXPOSURE_RATIO, 1 },
> > > -       { IMX214_REG_X_ADD_STA, 1144 },
> > > -       { IMX214_REG_Y_ADD_STA, 1020 },
> > > -       { IMX214_REG_X_ADD_END, 3063 },
> > > -       { IMX214_REG_Y_ADD_END, 2099 },
> > >         { IMX214_REG_X_EVEN_INC, 1 },
> > >         { IMX214_REG_X_ODD_INC, 1 },
> > >         { IMX214_REG_Y_EVEN_INC, 1 },
> > >         { IMX214_REG_Y_ODD_INC, 1 },
> > > -       { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE },
> > > -       { IMX214_REG_BINNING_TYPE, 0 },
> > >         { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE },
> > >         { CCI_REG8(0x3000), 0x35 },
> > >         { CCI_REG8(0x3054), 0x01 },
> > >         { CCI_REG8(0x305C), 0x11 },
> > >
> > > -       { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10
> > > },
> > > -       { IMX214_REG_X_OUTPUT_SIZE, 1920 },
> > > -       { IMX214_REG_Y_OUTPUT_SIZE, 1080 },
> > >         { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE },
> > >         { IMX214_REG_SCALE_M, 2 },
> > > -       { IMX214_REG_DIG_CROP_X_OFFSET, 0 },
> > > -       { IMX214_REG_DIG_CROP_Y_OFFSET, 0 },
> > > -       { IMX214_REG_DIG_CROP_WIDTH, 1920 },
> > > -       { IMX214_REG_DIG_CROP_HEIGHT, 1080 },
> > >
> > >         { IMX214_REG_VTPXCK_DIV, 5 },
> > >         { IMX214_REG_VTSYCK_DIV, 2 },
> > >         { IMX214_REG_PREPLLCK_VT_DIV, 3 },
> > >         { IMX214_REG_PLL_VT_MPY, 150 },
> > > -       { IMX214_REG_OPPXCK_DIV, 10 },
> > >         { IMX214_REG_OPSYCK_DIV, 1 },
> > >         { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
> > >
> > > @@ -623,6 +601,7 @@ static int imx214_set_format(struct v4l2_subdev
> > > *sd,
> > >         struct v4l2_mbus_framefmt *__format;
> > >         struct v4l2_rect *__crop;
> > >         const struct imx214_mode *mode;
> > > +       unsigned int bin_h, bin_v, bin;
> > >
> > >         mode = v4l2_find_nearest_size(imx214_modes,
> > >                                       ARRAY_SIZE(imx214_modes),
> > > width, height,
> > > @@ -637,9 +616,32 @@ static int imx214_set_format(struct
> > > v4l2_subdev *sd,
> > >
> > >         *__format = format->format;
> > >
> > > +       /*
> > > +        * Use binning to maximize the crop rectangle size, and
> > > centre it in the
> > > +        * sensor.
> > > +        */
> > > +       bin_h = IMX214_PIXEL_ARRAY_WIDTH / __format->width;
> > > +       bin_v = IMX214_PIXEL_ARRAY_HEIGHT / __format->height;
> > > +
> > > +       switch (min(bin_h, bin_v)) {
> > > +       case 1:
> > > +               bin = 1;
> > > +               break;
> > > +       case 2:
> > > +       case 3:
> > > +               bin = 2;
> > > +               break;
> > > +       case 4:
> > > +       default:
> > > +               bin = 4;
> > > +               break;
> > > +       }
> > > +
> > >         __crop = v4l2_subdev_state_get_crop(sd_state, 0);
> > > -       __crop->width = mode->width;
> > > -       __crop->height = mode->height;
> > > +       __crop->width = __format->width * bin;
> > > +       __crop->height = __format->height * bin;
> > > +       __crop->left = (IMX214_NATIVE_WIDTH - __crop->width) / 2;
> > > +       __crop->top = (IMX214_NATIVE_HEIGHT - __crop->height) / 2;
> > >
> > >         if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> > >                 int exposure_max;
> > > @@ -847,7 +849,62 @@ static int imx214_ctrls_init(struct imx214
> > > *imx214)
> > >         return 0;
> > >  };
> > >
> > > -static int imx214_start_streaming(struct imx214 *imx214)
> > > +static int imx214_set_framefmt(struct imx214 *imx214,
> > > +                              struct v4l2_subdev_state *state)
> > > +{
> > > +       const struct v4l2_mbus_framefmt *format;
> > > +       const struct v4l2_rect *crop;
> > > +       u64 bin_mode;
> > > +       u64 bin_type;
> > > +       int ret = 0;
> > > +
> > > +       format = v4l2_subdev_state_get_format(state, 0);
> > > +       crop = v4l2_subdev_state_get_crop(state, 0);
> > > +
> > > +       cci_write(imx214->regmap, IMX214_REG_X_ADD_STA,
> > > +                 crop->left - IMX214_PIXEL_ARRAY_LEFT, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_X_ADD_END,
> > > +                 crop->left - IMX214_PIXEL_ARRAY_LEFT + crop-
> > > >width - 1, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_Y_ADD_STA,
> > > +                 crop->top - IMX214_PIXEL_ARRAY_TOP, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_Y_ADD_END,
> > > +                 crop->top - IMX214_PIXEL_ARRAY_TOP + crop->height
> > > - 1, &ret);
> > > +
> > > +       /* Proper setting is required even if cropping is not used
> > > */
> > > +       cci_write(imx214->regmap, IMX214_REG_DIG_CROP_WIDTH, crop-
> > > >width, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_DIG_CROP_HEIGHT, crop-
> > > >height, &ret);
> > > +
> > > +       switch (crop->width / format->width) {
> > > +       case 1:
> > > +       default:
> > nit: It feels weird that default is not the last case.  Can you move
> > it to the bottom?
> > > +               bin_mode = IMX214_BINNING_NONE;
> > > +               bin_type = IMX214_BINNING_1X1;
> > > +               break;
> > > +       case 2:
> > > +               bin_mode = IMX214_BINNING_ENABLE;
> > > +               bin_type = IMX214_BINNING_2X2;
> > > +               break;
> > > +       case 4:
> > > +               bin_mode = IMX214_BINNING_ENABLE;
> > > +               bin_type = IMX214_BINNING_4X4;
> > > +               break;
> > > +       }
> > > +
> > > +       cci_write(imx214->regmap, IMX214_REG_BINNING_MODE,
> > > bin_mode, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_BINNING_TYPE,
> > > bin_type, &ret);
> > > +
> > > +       cci_write(imx214->regmap, IMX214_REG_X_OUTPUT_SIZE, format-
> > > >width, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_Y_OUTPUT_SIZE, format-
> > > >height, &ret);
> > > +
> > > +       cci_write(imx214->regmap, IMX214_REG_CSI_DATA_FORMAT,
> > > +                 IMX214_CSI_DATA_FORMAT_RAW10, &ret);
> > > +       cci_write(imx214->regmap, IMX214_REG_OPPXCK_DIV,
> > > IMX214_OPPXCK_DIV_RAW10, &ret);
> > > +
> > > +       return ret;
> > > +};
> > > +
> > > +static int imx214_start_streaming(struct imx214 *imx214,
> > > +                                 struct v4l2_subdev_state *state)
> > >  {
> > >         int ret;
> > >
> > > @@ -865,6 +922,14 @@ static int imx214_start_streaming(struct
> > > imx214 *imx214)
> > >                 return ret;
> > >         }
> > >
> > > +       /* Apply format and crop settings */
> > > +       ret = imx214_set_framefmt(imx214, state);
> > > +       if (ret) {
> > > +               dev_err(imx214->dev, "%s failed to set frame
> > > format: %d\n",
> > > +                       __func__, ret);
> > > +               return ret;
> > > +       }
> > > +
> > >         ret = cci_multi_reg_write(imx214->regmap, imx214->cur_mode-
> > > >reg_table,
> > >                                   imx214->cur_mode->num_of_regs,
> > > NULL);
> > >         if (ret < 0) {
> > > @@ -913,7 +978,7 @@ static int imx214_s_stream(struct v4l2_subdev
> > > *subdev, int enable)
> > >                         return ret;
> > >
> > >                 state =
> > > v4l2_subdev_lock_and_get_active_state(subdev);
> > > -               ret = imx214_start_streaming(imx214);
> > > +               ret = imx214_start_streaming(imx214, state);
> > >                 v4l2_subdev_unlock_state(state);
> > >                 if (ret < 0)
> > >                         goto err_rpm_put;
> > >
> > > --
> > > 2.47.0
> > >
> > >
>





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux