From 944d57f7390dd61585bfc3f763dc4fd44ddd2068 Mon Sep 17 00:00:00 2001 From: gechdcb Date: Thu, 24 Mar 2022 22:29:39 +0800 Subject: [PATCH] * imx290 : 1. Allow switch the HCG/LCG mode at runtime via module parameter. 2. Add a optional dtoverlay parameter to set the max gain as the maximum analogue gain of the imx290 and imx327 is slightly different --- drivers/media/i2c/imx290.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index a6f4ba5b93459d..dafbb676300e57 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,10 @@ enum imx290_clk_index { #define IMX290_PIXEL_ARRAY_WIDTH 1937U #define IMX290_PIXEL_ARRAY_HEIGHT 1097U +static bool hcgmode = false; +module_param(hcgmode, bool, 0664); +MODULE_PARM_DESC(hcgmode, "Enable HCG mode"); + static const char * const imx290_supply_name[] = { "vdda", "vddd", @@ -246,7 +251,6 @@ static const struct imx290_regval imx290_74_250mhz_clock_1080p[] = { static const struct imx290_regval imx290_1080p_common_settings[] = { /* mode settings */ - { IMX290_FR_FDG_SEL, 0x01 }, { 0x3007, 0x00 }, { 0x303a, 0x0c }, { 0x3414, 0x0a }, @@ -330,7 +334,6 @@ static const struct imx290_regval imx290_74_250mhz_clock_720p[] = { static const struct imx290_regval imx290_720p_common_settings[] = { /* mode settings */ - { IMX290_FR_FDG_SEL, 0x01 }, { 0x3007, 0x10 }, { 0x303a, 0x06 }, { 0x3414, 0x04 }, @@ -1071,6 +1074,12 @@ static int imx290_start_streaming(struct imx290 *imx290) } /* Apply default values of current mode */ + ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, hcgmode ? 0x11 : 0x01); + if (ret < 0) { + dev_err(imx290->dev, "Could not set current mode\n"); + return ret; + } + ret = imx290_set_register_array(imx290, imx290->current_mode->mode_data, imx290->current_mode->mode_data_size); @@ -1250,6 +1259,7 @@ static int imx290_probe(struct i2c_client *client) const struct imx290_mode *mode; struct imx290 *imx290; s64 fq; + u8 max_gain; int ret; imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); @@ -1332,6 +1342,16 @@ static int imx290_probe(struct i2c_client *client) goto free_err; } + max_gain = 100; + if (fwnode_property_present(dev_fwnode(dev), "max-gain")) { + ret = fwnode_property_read_u8(dev_fwnode(dev), "max-gain", + &max_gain); + if (ret) { + dev_err(dev, "Could not get max gain\n"); + goto free_err; + } + } + ret = clk_set_rate(imx290->xclk, imx290->xclk_freq); if (ret) { dev_err(dev, "Could not set xclk frequency\n"); @@ -1364,7 +1384,7 @@ static int imx290_probe(struct i2c_client *client) v4l2_ctrl_handler_init(&imx290->ctrls, 11); v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); + V4L2_CID_ANALOGUE_GAIN, 0, max_gain, 1, 0); mode = imx290->current_mode; imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,