From 6602d7e5d364c28c47b4765452147da3e82379e7 Mon Sep 17 00:00:00 2001 From: Lan Honglin Date: Tue, 10 Oct 2023 20:10:46 +0800 Subject: [PATCH] media: i2c: imx415: support 2lane Change-Id: Id1bc53d85bf84067ee10aca67eb0ad22a0b4b574 Signed-off-by: Lan Honglin --- drivers/media/i2c/imx415.c | 294 ++++++++++++++++++++++++++++++++----- 1 file changed, 260 insertions(+), 34 deletions(-) diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c index 0bd0431d3106..205a474aa11e 100644 --- a/drivers/media/i2c/imx415.c +++ b/drivers/media/i2c/imx415.c @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include "../platform/rockchip/isp/rkisp_tb_helper.h" #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08) @@ -64,11 +66,13 @@ #define MIPI_FREQ_297M 297000000 #define IMX415_4LANES 4 +#define IMX415_2LANES 2 #define IMX415_MAX_PIXEL_RATE (MIPI_FREQ_891M / 10 * 2 * IMX415_4LANES) #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode" #define IMX415_XVCLK_FREQ_37M 37125000 +#define IMX415_XVCLK_FREQ_27M 27000000 /* TODO: Get the real chip id from reg */ #define CHIP_ID 0xE0 @@ -142,6 +146,7 @@ #define IMX415_FLIP_REG 0x3030 #define REG_NULL 0xFFFF +#define REG_DELAY 0xFFFE #define IMX415_REG_VALUE_08BIT 1 #define IMX415_REG_VALUE_16BIT 2 @@ -194,6 +199,7 @@ struct imx415_mode { const struct regval *reg_list; u32 hdr_mode; u32 vc[PAD_MAX]; + u32 xvclk; }; struct imx415 { @@ -223,6 +229,7 @@ struct imx415 { bool is_thunderboot; bool is_thunderboot_ng; bool is_first_streamoff; + const struct imx415_mode *supported_modes; const struct imx415_mode *cur_mode; u32 module_index; u32 cfg_num; @@ -232,6 +239,7 @@ struct imx415 { u32 cur_vts; bool has_init_exp; struct preisp_hdrae_exp_s init_hdrae_exp; + struct v4l2_fwnode_endpoint bus_cfg; }; static struct rkmodule_csi_dphy_param dcphy_param = { @@ -745,6 +753,150 @@ static __maybe_unused const struct regval imx415_hdr2_12bit_1932x1096_891M_regs[ {REG_NULL, 0x00}, }; +/* + * Xclk 27Mhz + * 15fps + * CSI-2_2lane + * AD:12bit Output:12bit + * 891Mbps + * Master Mode + * Time 9.988ms Gain:6dB + * All-pixel + */ +static __maybe_unused const struct regval imx415_linear_12bit_3864x2192_891M_regs_2lane[] = { + {0x3008, 0x5D}, + {0x300A, 0x42}, + {0x3028, 0x98}, + {0x3029, 0x08}, + {0x3033, 0x05}, + {0x3050, 0x79}, + {0x3051, 0x07}, + {0x3090, 0x14}, + {0x30C1, 0x00}, + {0x3116, 0x23}, + {0x3118, 0xC6}, + {0x311A, 0xE7}, + {0x311E, 0x23}, + {0x32D4, 0x21}, + {0x32EC, 0xA1}, + {0x344C, 0x2B}, + {0x344D, 0x01}, + {0x344E, 0xED}, + {0x344F, 0x01}, + {0x3450, 0xF6}, + {0x3451, 0x02}, + {0x3452, 0x7F}, + {0x3453, 0x03}, + {0x358A, 0x04}, + {0x35A1, 0x02}, + {0x35EC, 0x27}, + {0x35EE, 0x8D}, + {0x35F0, 0x8D}, + {0x35F2, 0x29}, + {0x36BC, 0x0C}, + {0x36CC, 0x53}, + {0x36CD, 0x00}, + {0x36CE, 0x3C}, + {0x36D0, 0x8C}, + {0x36D1, 0x00}, + {0x36D2, 0x71}, + {0x36D4, 0x3C}, + {0x36D6, 0x53}, + {0x36D7, 0x00}, + {0x36D8, 0x71}, + {0x36DA, 0x8C}, + {0x36DB, 0x00}, + {0x3720, 0x00}, + {0x3724, 0x02}, + {0x3726, 0x02}, + {0x3732, 0x02}, + {0x3734, 0x03}, + {0x3736, 0x03}, + {0x3742, 0x03}, + {0x3862, 0xE0}, + {0x38CC, 0x30}, + {0x38CD, 0x2F}, + {0x395C, 0x0C}, + {0x39A4, 0x07}, + {0x39A8, 0x32}, + {0x39AA, 0x32}, + {0x39AC, 0x32}, + {0x39AE, 0x32}, + {0x39B0, 0x32}, + {0x39B2, 0x2F}, + {0x39B4, 0x2D}, + {0x39B6, 0x28}, + {0x39B8, 0x30}, + {0x39BA, 0x30}, + {0x39BC, 0x30}, + {0x39BE, 0x30}, + {0x39C0, 0x30}, + {0x39C2, 0x2E}, + {0x39C4, 0x2B}, + {0x39C6, 0x25}, + {0x3A42, 0xD1}, + {0x3A4C, 0x77}, + {0x3AE0, 0x02}, + {0x3AEC, 0x0C}, + {0x3B00, 0x2E}, + {0x3B06, 0x29}, + {0x3B98, 0x25}, + {0x3B99, 0x21}, + {0x3B9B, 0x13}, + {0x3B9C, 0x13}, + {0x3B9D, 0x13}, + {0x3B9E, 0x13}, + {0x3BA1, 0x00}, + {0x3BA2, 0x06}, + {0x3BA3, 0x0B}, + {0x3BA4, 0x10}, + {0x3BA5, 0x14}, + {0x3BA6, 0x18}, + {0x3BA7, 0x1A}, + {0x3BA8, 0x1A}, + {0x3BA9, 0x1A}, + {0x3BAC, 0xED}, + {0x3BAD, 0x01}, + {0x3BAE, 0xF6}, + {0x3BAF, 0x02}, + {0x3BB0, 0xA2}, + {0x3BB1, 0x03}, + {0x3BB2, 0xE0}, + {0x3BB3, 0x03}, + {0x3BB4, 0xE0}, + {0x3BB5, 0x03}, + {0x3BB6, 0xE0}, + {0x3BB7, 0x03}, + {0x3BB8, 0xE0}, + {0x3BBA, 0xE0}, + {0x3BBC, 0xDA}, + {0x3BBE, 0x88}, + {0x3BC0, 0x44}, + {0x3BC2, 0x7B}, + {0x3BC4, 0xA2}, + {0x3BC8, 0xBD}, + {0x3BCA, 0xBD}, + {0x4001, 0x01}, + {0x4004, 0xC0}, + {0x4005, 0x06}, + {0x400C, 0x00}, + {0x4018, 0x7F}, + {0x401A, 0x37}, + {0x401C, 0x37}, + {0x401E, 0xF7}, + {0x401F, 0x00}, + {0x4020, 0x3F}, + {0x4022, 0x6F}, + {0x4024, 0x3F}, + {0x4026, 0x5F}, + {0x4028, 0x2F}, + {0x4074, 0x01}, + {0x3002, 0x00}, + //{0x3000, 0x00}, + {REG_DELAY, 0x1E},//wait_ms(30) + {REG_NULL, 0x00}, +}; + /* * The width and height must be configured to be * the same as the current output resolution of the sensor. @@ -779,6 +931,7 @@ static const struct imx415_mode supported_modes[] = { .mipi_freq_idx = 1, .bpp = 10, .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10, @@ -804,6 +957,7 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1, .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10, @@ -829,6 +983,7 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10, @@ -854,6 +1009,7 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, }, { /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */ @@ -873,6 +1029,7 @@ static const struct imx415_mode supported_modes[] = { .mipi_freq_idx = 1, .bpp = 12, .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12, @@ -898,6 +1055,7 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1, .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12, @@ -923,6 +1081,7 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12, @@ -941,6 +1100,7 @@ static const struct imx415_mode supported_modes[] = { .mipi_freq_idx = 0, .bpp = 12, .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + .xvclk = IMX415_XVCLK_FREQ_37M, }, { .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12, @@ -966,6 +1126,30 @@ static const struct imx415_mode supported_modes[] = { .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1, .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2 + .xvclk = IMX415_XVCLK_FREQ_37M, + }, +}; + +static const struct imx415_mode supported_modes_2lane[] = { + { + /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */ + .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12, + .width = 3864, + .height = 2192, + .max_fps = { + .numerator = 10000, + .denominator = 150000, + }, + .exp_def = 0x08ca - 0x08, + .hts_def = 0x0898 * IMX415_2LANES * 2, + .vts_def = 0x08ca, + .global_reg_list = NULL, + .reg_list = imx415_linear_12bit_3864x2192_891M_regs_2lane, + .hdr_mode = NO_HDR, + .mipi_freq_idx = 1, + .bpp = 12, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + .xvclk = IMX415_XVCLK_FREQ_27M, }, }; @@ -1010,10 +1194,18 @@ static int imx415_write_array(struct i2c_client *client, { u32 i; int ret = 0; - + if (!regs) { + dev_err(&client->dev, "write reg array error\n"); + return ret; + } for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) { - ret = imx415_write_reg(client, regs[i].addr, - IMX415_REG_VALUE_08BIT, regs[i].val); + if (regs[i].addr == REG_DELAY) { + usleep_range(regs[i].val * 1000, regs[i].val * 1000 + 500); + dev_info(&client->dev, "write reg array, sleep %dms\n", regs[i].val); + } else { + ret = imx415_write_reg(client, regs[i].addr, + IMX415_REG_VALUE_08BIT, regs[i].val); + } } return ret; } @@ -1070,9 +1262,9 @@ imx415_find_best_fit(struct imx415 *imx415, struct v4l2_subdev_format *fmt) unsigned int i; for (i = 0; i < imx415->cfg_num; i++) { - dist = imx415_get_reso_dist(&supported_modes[i], framefmt); + dist = imx415_get_reso_dist(&imx415->supported_modes[i], framefmt); if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) && - supported_modes[i].bus_fmt == framefmt->code) { + imx415->supported_modes[i].bus_fmt == framefmt->code) { cur_best_fit_dist = dist; cur_best_fit = i; } @@ -1080,7 +1272,7 @@ imx415_find_best_fit(struct imx415 *imx415, struct v4l2_subdev_format *fmt) dev_info(&imx415->client->dev, "%s: cur_best_fit(%d)", __func__, cur_best_fit); - return &supported_modes[cur_best_fit]; + return &imx415->supported_modes[cur_best_fit]; } static int __imx415_power_on(struct imx415 *imx415); @@ -1094,8 +1286,8 @@ static void imx415_change_mode(struct imx415 *imx415, const struct imx415_mode * } imx415->cur_mode = mode; imx415->cur_vts = imx415->cur_mode->vts_def; - dev_dbg(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n", - mode->width, mode->height, mode->hdr_mode); + dev_info(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d, bpp: %d\n", + mode->width, mode->height, mode->hdr_mode, mode->bpp); } static int imx415_set_fmt(struct v4l2_subdev *sd, @@ -1106,6 +1298,7 @@ static int imx415_set_fmt(struct v4l2_subdev *sd, const struct imx415_mode *mode; s64 h_blank, vblank_def, vblank_min; u64 pixel_rate = 0; + u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes; mutex_lock(&imx415->mutex); @@ -1134,7 +1327,8 @@ static int imx415_set_fmt(struct v4l2_subdev *sd, 1, vblank_def); __v4l2_ctrl_s_ctrl(imx415->vblank, vblank_def); __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx); - pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES; + pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / + mode->bpp * 2 * lanes; __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate, pixel_rate); } @@ -1185,7 +1379,7 @@ static int imx415_enum_mbus_code(struct v4l2_subdev *sd, if (code->index >= imx415->cfg_num) return -EINVAL; - code->code = supported_modes[code->index].bus_fmt; + code->code = imx415->supported_modes[code->index].bus_fmt; return 0; } @@ -1199,13 +1393,13 @@ static int imx415_enum_frame_sizes(struct v4l2_subdev *sd, if (fse->index >= imx415->cfg_num) return -EINVAL; - if (fse->code != supported_modes[fse->index].bus_fmt) + if (fse->code != imx415->supported_modes[fse->index].bus_fmt) return -EINVAL; - fse->min_width = supported_modes[fse->index].width; - fse->max_width = supported_modes[fse->index].width; - fse->max_height = supported_modes[fse->index].height; - fse->min_height = supported_modes[fse->index].height; + fse->min_width = imx415->supported_modes[fse->index].width; + fse->max_width = imx415->supported_modes[fse->index].width; + fse->max_height = imx415->supported_modes[fse->index].height; + fse->min_height = imx415->supported_modes[fse->index].height; return 0; } @@ -1227,8 +1421,9 @@ static int imx415_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, struct imx415 *imx415 = to_imx415(sd); const struct imx415_mode *mode = imx415->cur_mode; u32 val = 0; + u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes; - val = 1 << (IMX415_4LANES - 1) | + val = 1 << (lanes - 1) | V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; if (mode->hdr_mode != NO_HDR) @@ -1687,6 +1882,7 @@ static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) const struct imx415_mode *mode; u64 pixel_rate = 0; struct rkmodule_csi_dphy_param *dphy_param; + u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes; switch (cmd) { case PREISP_CMD_SET_HDRAE_EXP: @@ -1708,10 +1904,11 @@ static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) w = imx415->cur_mode->width; h = imx415->cur_mode->height; for (i = 0; i < imx415->cfg_num; i++) { - if (w == supported_modes[i].width && - h == supported_modes[i].height && - supported_modes[i].hdr_mode == hdr->hdr_mode) { - imx415_change_mode(imx415, &supported_modes[i]); + if (w == imx415->supported_modes[i].width && + h == imx415->supported_modes[i].height && + imx415->supported_modes[i].hdr_mode == hdr->hdr_mode) { + dev_info(&imx415->client->dev, "set hdr cfg, set mode to %d\n", i); + imx415_change_mode(imx415, &imx415->supported_modes[i]); break; } } @@ -1741,7 +1938,8 @@ static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) IMX415_VTS_MAX - mode->height, 1, h); __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx); - pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES; + pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / + mode->bpp * 2 * lanes; __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate, pixel_rate); mutex_unlock(&imx415->mutex); @@ -2072,10 +2270,10 @@ int __imx415_power_on(struct imx415 *imx415) /* At least 1us between XCLR and clk */ /* fix power on timing if insmod this ko */ usleep_range(10 * 1000, 20 * 1000); - ret = clk_set_rate(imx415->xvclk, IMX415_XVCLK_FREQ_37M); + ret = clk_set_rate(imx415->xvclk, imx415->cur_mode->xvclk); if (ret < 0) dev_warn(dev, "Failed to set xvclk rate\n"); - if (clk_get_rate(imx415->xvclk) != IMX415_XVCLK_FREQ_37M) + if (clk_get_rate(imx415->xvclk) != imx415->cur_mode->xvclk) dev_warn(dev, "xvclk mismatched\n"); ret = clk_prepare_enable(imx415->xvclk); if (ret < 0) { @@ -2154,7 +2352,7 @@ static int imx415_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct imx415 *imx415 = to_imx415(sd); struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, 0); - const struct imx415_mode *def_mode = &supported_modes[0]; + const struct imx415_mode *def_mode = &imx415->supported_modes[0]; mutex_lock(&imx415->mutex); /* Initialize try_fmt */ @@ -2179,11 +2377,11 @@ static int imx415_enum_frame_interval(struct v4l2_subdev *sd, if (fie->index >= imx415->cfg_num) return -EINVAL; - fie->code = supported_modes[fie->index].bus_fmt; - fie->width = supported_modes[fie->index].width; - fie->height = supported_modes[fie->index].height; - fie->interval = supported_modes[fie->index].max_fps; - fie->reserved[0] = supported_modes[fie->index].hdr_mode; + fie->code = imx415->supported_modes[fie->index].bus_fmt; + fie->width = imx415->supported_modes[fie->index].width; + fie->height = imx415->supported_modes[fie->index].height; + fie->interval = imx415->supported_modes[fie->index].max_fps; + fie->reserved[0] = imx415->supported_modes[fie->index].hdr_mode; return 0; } @@ -2401,8 +2599,10 @@ static int imx415_initialize_controls(struct imx415 *imx415) struct v4l2_ctrl_handler *handler; s64 exposure_max, vblank_def; u64 pixel_rate; + u64 max_pixel_rate; u32 h_blank; int ret; + u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes; handler = &imx415->ctrl_handler; mode = imx415->cur_mode; @@ -2418,9 +2618,10 @@ static int imx415_initialize_controls(struct imx415 *imx415) v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx); /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ - pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES; + pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * lanes; + max_pixel_rate = MIPI_FREQ_891M / mode->bpp * 2 * lanes; imx415->pixel_rate = v4l2_ctrl_new_std(handler, NULL, - V4L2_CID_PIXEL_RATE, 0, IMX415_MAX_PIXEL_RATE, + V4L2_CID_PIXEL_RATE, 0, max_pixel_rate, 1, pixel_rate); h_blank = mode->hts_def - mode->width; @@ -2511,6 +2712,7 @@ static int imx415_probe(struct i2c_client *client, struct device_node *node = dev->of_node; struct imx415 *imx415; struct v4l2_subdev *sd; + struct device_node *endpoint; char facing[2]; int ret; u32 i, hdr_mode = 0; @@ -2542,11 +2744,35 @@ static int imx415_probe(struct i2c_client *client, hdr_mode = NO_HDR; dev_warn(dev, " Get hdr mode failed! no hdr default\n"); } + + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) { + dev_err(dev, "Failed to get endpoint\n"); + return -EINVAL; + } + + ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), + &imx415->bus_cfg); + of_node_put(endpoint); + if (ret) { + dev_err(dev, "Failed to get bus config\n"); + return -EINVAL; + } + imx415->client = client; - imx415->cfg_num = ARRAY_SIZE(supported_modes); + if (imx415->bus_cfg.bus.mipi_csi2.num_data_lanes == IMX415_4LANES) { + imx415->supported_modes = supported_modes; + imx415->cfg_num = ARRAY_SIZE(supported_modes); + } else { + imx415->supported_modes = supported_modes_2lane; + imx415->cfg_num = ARRAY_SIZE(supported_modes_2lane); + } + dev_info(dev, "detect imx415 lane %d\n", + imx415->bus_cfg.bus.mipi_csi2.num_data_lanes); + for (i = 0; i < imx415->cfg_num; i++) { - if (hdr_mode == supported_modes[i].hdr_mode) { - imx415->cur_mode = &supported_modes[i]; + if (hdr_mode == imx415->supported_modes[i].hdr_mode) { + imx415->cur_mode = &imx415->supported_modes[i]; break; } }