From 2e04b093d986e8e821d78a671b8302654d4e8784 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 15 May 2024 12:43:15 +0100 Subject: [PATCH 1/5] media: imx290: Add module parameter to allow selection of HCG mode The sensor has Low Conversion Gain (HCG) and High Conversion Gain (HCG) modes, with the supposedly the HCG mode having better noise performance at high gains. As this parameter changes the gain range of the sensor, it isn't possible to make this an automatic property, and there is no suitable V4L2 control to set it, so just add it as a module parameter. Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx290.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 6dacd38ae947a1..c685dbe2d34270 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,9 @@ #define IMX290_WINMODE_720P (1 << 4) #define IMX290_WINMODE_CROP (4 << 4) #define IMX290_FR_FDG_SEL CCI_REG8(0x3009) +#define IMX290_FDG_HCG BIT(4) +#define IMX290_FRSEL_60FPS BIT(0) +#define IMX290_FDG_LCG 0 #define IMX290_BLKLEVEL CCI_REG16_LE(0x300a) #define IMX290_GAIN CCI_REG8(0x3014) #define IMX290_VMAX CCI_REG24_LE(0x3018) @@ -162,6 +166,10 @@ #define IMX290_NUM_SUPPLIES 3 +static bool hcg_mode; +module_param(hcg_mode, bool, 0664); +MODULE_PARM_DESC(hcg_mode, "Enable HCG mode"); + enum imx290_colour_variant { IMX290_VARIANT_COLOUR, IMX290_VARIANT_MONO, @@ -649,7 +657,8 @@ static int imx290_set_data_lanes(struct imx290 *imx290) &ret); cci_write(imx290->regmap, IMX290_CSI_LANE_MODE, imx290->nlanes - 1, &ret); - cci_write(imx290->regmap, IMX290_FR_FDG_SEL, 0x01, &ret); + cci_write(imx290->regmap, IMX290_FR_FDG_SEL, IMX290_FRSEL_60FPS | + (hcg_mode ? IMX290_FDG_HCG : IMX290_FDG_LCG), &ret); return ret; } From c43d48755fb3d40a0c1877063716a961ffa552f8 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 17 Jan 2024 16:29:37 +0000 Subject: [PATCH 2/5] media: i2c: imx290: Limit analogue gain according to module The imx327 only supports up to 29.4dB of analogue gain, vs the imx290 going up to 30dB. Both are in 0.3dB steps. As we now have model specific config, fix this mismatch, and delete the comment referencing it. Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx290.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index c685dbe2d34270..21b14f18c629a0 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -186,6 +186,7 @@ struct imx290_model_info { enum imx290_colour_variant colour_variant; const struct cci_reg_sequence *init_regs; size_t init_regs_num; + unsigned int max_analog_gain; const char *name; }; @@ -887,14 +888,10 @@ static int imx290_ctrl_init(struct imx290 *imx290) * up to 72.0dB (240) add further digital gain. Limit the range to * analog gain only, support for digital gain can be added separately * if needed. - * - * The IMX327 and IMX462 are largely compatible with the IMX290, but - * have an analog gain range of 0.0dB to 29.4dB and 42dB of digital - * gain. When support for those sensors gets added to the driver, the - * gain control should be adjusted accordingly. */ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); + V4L2_CID_ANALOGUE_GAIN, 0, + imx290->model->max_analog_gain, 1, 0); /* * Correct range will be determined through imx290_ctrl_update setting @@ -1445,18 +1442,21 @@ static const struct imx290_model_info imx290_models[] = { .colour_variant = IMX290_VARIANT_COLOUR, .init_regs = imx290_global_init_settings_290, .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290), + .max_analog_gain = 100, .name = "imx290", }, [IMX290_MODEL_IMX290LLR] = { .colour_variant = IMX290_VARIANT_MONO, .init_regs = imx290_global_init_settings_290, .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290), + .max_analog_gain = 100, .name = "imx290", }, [IMX290_MODEL_IMX327LQR] = { .colour_variant = IMX290_VARIANT_COLOUR, .init_regs = imx290_global_init_settings_327, .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327), + .max_analog_gain = 98, .name = "imx327", }, }; From 4419cdd279f3b11fc9c42cd4282c1b7137874230 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 12 Nov 2024 14:13:31 +0000 Subject: [PATCH 3/5] media: dt-bindings: media: i2c: Add IMX462 to the IMX290 binding IMX462 is the successor to IMX290, which is supportable by the existing IMX290 driver via a new compatible string. Signed-off-by: Dave Stevenson --- Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml index a531badc16c98b..cf8f33041f84c5 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml @@ -30,6 +30,8 @@ properties: - sony,imx290lqr # Colour - sony,imx290llr # Monochrome - sony,imx327lqr # Colour + - sony,imx462lqr # Colour + - sony,imx462llr # Monochrome - const: sony,imx290 deprecated: true From ef11ee9597cf5e9de5951597a2a1a7ba7f321019 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 12 Nov 2024 14:10:00 +0000 Subject: [PATCH 4/5] media: i2c: imx290: Add configuration for IMX462 IMX462 is the successor to IMX290, and wants very minor changes to the register setup. Add the relevant configuration to support it. Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx290.c | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 21b14f18c629a0..bbd1d7d20b60a7 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -180,6 +180,8 @@ enum imx290_model { IMX290_MODEL_IMX290LQR, IMX290_MODEL_IMX290LLR, IMX290_MODEL_IMX327LQR, + IMX290_MODEL_IMX462LQR, + IMX290_MODEL_IMX462LLR, }; struct imx290_model_info { @@ -326,6 +328,50 @@ static const struct cci_reg_sequence imx290_global_init_settings_290[] = { { CCI_REG8(0x33b3), 0x04 }, }; +static const struct cci_reg_sequence imx290_global_init_settings_462[] = { + { CCI_REG8(0x300f), 0x00 }, + { CCI_REG8(0x3010), 0x21 }, + { CCI_REG8(0x3011), 0x02 }, + { CCI_REG8(0x3016), 0x09 }, + { CCI_REG8(0x3070), 0x02 }, + { CCI_REG8(0x3071), 0x11 }, + { CCI_REG8(0x309b), 0x10 }, + { CCI_REG8(0x309c), 0x22 }, + { CCI_REG8(0x30a2), 0x02 }, + { CCI_REG8(0x30a6), 0x20 }, + { CCI_REG8(0x30a8), 0x20 }, + { CCI_REG8(0x30aa), 0x20 }, + { CCI_REG8(0x30ac), 0x20 }, + { CCI_REG8(0x30b0), 0x43 }, + { CCI_REG8(0x3119), 0x9e }, + { CCI_REG8(0x311c), 0x1e }, + { CCI_REG8(0x311e), 0x08 }, + { CCI_REG8(0x3128), 0x05 }, + { CCI_REG8(0x313d), 0x83 }, + { CCI_REG8(0x3150), 0x03 }, + { CCI_REG8(0x317e), 0x00 }, + { CCI_REG8(0x32b8), 0x50 }, + { CCI_REG8(0x32b9), 0x10 }, + { CCI_REG8(0x32ba), 0x00 }, + { CCI_REG8(0x32bb), 0x04 }, + { CCI_REG8(0x32c8), 0x50 }, + { CCI_REG8(0x32c9), 0x10 }, + { CCI_REG8(0x32ca), 0x00 }, + { CCI_REG8(0x32cb), 0x04 }, + { CCI_REG8(0x332c), 0xd3 }, + { CCI_REG8(0x332d), 0x10 }, + { CCI_REG8(0x332e), 0x0d }, + { CCI_REG8(0x3358), 0x06 }, + { CCI_REG8(0x3359), 0xe1 }, + { CCI_REG8(0x335a), 0x11 }, + { CCI_REG8(0x3360), 0x1e }, + { CCI_REG8(0x3361), 0x61 }, + { CCI_REG8(0x3362), 0x10 }, + { CCI_REG8(0x33b0), 0x50 }, + { CCI_REG8(0x33b2), 0x1a }, + { CCI_REG8(0x33b3), 0x04 }, +}; + #define IMX290_NUM_CLK_REGS 2 static const struct cci_reg_sequence xclk_regs[][IMX290_NUM_CLK_REGS] = { [IMX290_CLK_37_125] = { @@ -1459,6 +1505,20 @@ static const struct imx290_model_info imx290_models[] = { .max_analog_gain = 98, .name = "imx327", }, + [IMX290_MODEL_IMX462LQR] = { + .colour_variant = IMX290_VARIANT_COLOUR, + .init_regs = imx290_global_init_settings_462, + .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_462), + .max_analog_gain = 98, + .name = "imx462", + }, + [IMX290_MODEL_IMX462LLR] = { + .colour_variant = IMX290_VARIANT_MONO, + .init_regs = imx290_global_init_settings_462, + .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_462), + .max_analog_gain = 98, + .name = "imx462", + }, }; static int imx290_parse_dt(struct imx290 *imx290) @@ -1654,6 +1714,12 @@ static const struct of_device_id imx290_of_match[] = { }, { .compatible = "sony,imx327lqr", .data = &imx290_models[IMX290_MODEL_IMX327LQR], + }, { + .compatible = "sony,imx462lqr", + .data = &imx290_models[IMX290_MODEL_IMX462LQR], + }, { + .compatible = "sony,imx462llr", + .data = &imx290_models[IMX290_MODEL_IMX462LLR], }, { /* sentinel */ }, }; From ac4cf8eeff7e4e36da52a01faf1df055564a5c34 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 12 Nov 2024 14:15:30 +0000 Subject: [PATCH 5/5] dtoverlays: Switch imx462 overlay to use the new compatible Now that imx462 has a separate compatible string, make use of it. Signed-off-by: Dave Stevenson --- arch/arm/boot/dts/overlays/imx462-overlay.dts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/overlays/imx462-overlay.dts b/arch/arm/boot/dts/overlays/imx462-overlay.dts index c4d7aabe2efed5..6e4c5aaddff5e9 100644 --- a/arch/arm/boot/dts/overlays/imx462-overlay.dts +++ b/arch/arm/boot/dts/overlays/imx462-overlay.dts @@ -1,9 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Definitions for IMX462 camera module on VC I2C bus -// IMX462 is the successor to IMX290. The drivers currently don't support -// any additional feature of IMX462, so use the IMX290 compatible strings -// for now. +// IMX462 is the successor to IMX290. /dts-v1/; /plugin/; @@ -17,19 +15,17 @@ // Fragment numbers deliberately high to avoid conflicts with the // included imx290_327 overlay file. - //IMX462 is not defined in the bindings, so use IMX290 for now. - fragment@101 { target = <&cam_node>; __overlay__ { - compatible = "sony,imx290lqr"; + compatible = "sony,imx462lqr"; }; }; fragment@102 { target = <&cam_node>; __dormant__ { - compatible = "sony,imx290llr"; + compatible = "sony,imx462llr"; }; };