Hi,

I'll drop this patch for now. The changes included are not needed to
make imx214 work with libcamera. And with [1] the patch might need a
rework anyway.

Best regards,
André

[1]
https://lore.kernel.org/linux-media/20241129095142.87196-1-sakari.ai...@linux.intel.com/

Am Montag, dem 21.10.2024 um 00:13 +0200 schrieb André Apitzsch via B4
Relay:
> From: André Apitzsch <g...@apitzsch.eu>
> 
> Remove format and crop settings from register sequences and set them
> programmatically.
> 
> Signed-off-by: André Apitzsch <g...@apitzsch.eu>
> ---
>  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..87a03e292e19ccd71f1b2dcee34
> 09826b2f5cb6f 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:
> +             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;
> 


Reply via email to