From 8ce0498cb28b9db1a134a72b10ef2278e41fa196 Mon Sep 17 00:00:00 2001 From: Lian Xu Date: Tue, 10 May 2022 19:29:30 +0800 Subject: [PATCH] media: i2c: sc230ai 120fps Change-Id: I3240f4321d5b6d7a20ced8d28b4cdc31f7e942fe Signed-off-by: Lian Xu --- drivers/media/i2c/sc230ai.c | 251 ++++++++++++++++++++++++++++++++++-- 1 file changed, 241 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/sc230ai.c b/drivers/media/i2c/sc230ai.c index 728e2369b98c..befea030fbe8 100644 --- a/drivers/media/i2c/sc230ai.c +++ b/drivers/media/i2c/sc230ai.c @@ -36,9 +36,14 @@ #define SC230AI_LANES 2 #define SC230AI_BITS_PER_SAMPLE 10 #define SC230AI_LINK_FREQ_185 92812500// 185.625Mbps +#define SC230AI_LINK_FREQ_371 185625000// 371.25Mbps #define PIXEL_RATE_WITH_185M_10BIT (SC230AI_LINK_FREQ_185 * 2 * \ SC230AI_LANES / SC230AI_BITS_PER_SAMPLE) + +#define PIXEL_RATE_WITH_371M_10BIT (SC230AI_LINK_FREQ_371 * 2 * \ + SC230AI_LANES / SC230AI_BITS_PER_SAMPLE) + #define SC230AI_XVCLK_FREQ 27000000 #define CHIP_ID 0xcb34 @@ -133,6 +138,8 @@ struct sc230ai_mode { u32 hts_def; u32 vts_def; u32 exp_def; + u32 mipi_freq_idx; + u32 bpp; const struct regval *reg_list; u32 hdr_mode; u32 vc[PAD_MAX]; @@ -157,6 +164,8 @@ struct sc230ai { struct v4l2_ctrl *digi_gain; struct v4l2_ctrl *hblank; struct v4l2_ctrl *vblank; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *link_freq; struct v4l2_ctrl *test_pattern; struct mutex mutex; bool streaming; @@ -342,7 +351,196 @@ static const struct regval sc230ai_linear_10_1920x1080_regs[] = { {0x5aff, 0x2c}, {0x36e9, 0x20}, {0x37f9, 0x57}, - {0x0100, 0x01}, + {REG_NULL, 0x00}, +}; + +static const struct regval sc230ai_linear_10_640x480_regs[] = { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x36e9, 0x80}, + {0x37f9, 0x80}, + {0x301f, 0x2d}, + {0x3200, 0x00}, + {0x3201, 0x00}, + {0x3202, 0x00}, + {0x3203, 0x3c}, + {0x3204, 0x07}, + {0x3205, 0x87}, + {0x3206, 0x04}, + {0x3207, 0x03}, + {0x3208, 0x02}, + {0x3209, 0x80}, + {0x320a, 0x01}, + {0x320b, 0xe0}, + {0x320e, 0x02}, + {0x320f, 0x32}, + {0x3210, 0x00}, + {0x3211, 0xa2}, + {0x3212, 0x00}, + {0x3213, 0x02}, + {0x3215, 0x31}, + {0x3220, 0x01}, + {0x3301, 0x09}, + {0x3304, 0x50}, + {0x3306, 0x48}, + {0x3308, 0x18}, + {0x3309, 0x68}, + {0x330a, 0x00}, + {0x330b, 0xc0}, + {0x331e, 0x41}, + {0x331f, 0x59}, + {0x3333, 0x10}, + {0x3334, 0x40}, + {0x335d, 0x60}, + {0x335e, 0x06}, + {0x335f, 0x08}, + {0x3364, 0x5e}, + {0x337c, 0x02}, + {0x337d, 0x0a}, + {0x3390, 0x01}, + {0x3391, 0x0b}, + {0x3392, 0x0f}, + {0x3393, 0x0c}, + {0x3394, 0x0d}, + {0x3395, 0x60}, + {0x3396, 0x48}, + {0x3397, 0x49}, + {0x3398, 0x4f}, + {0x3399, 0x0a}, + {0x339a, 0x0f}, + {0x339b, 0x14}, + {0x339c, 0x60}, + {0x33a2, 0x04}, + {0x33af, 0x40}, + {0x33b1, 0x80}, + {0x33b3, 0x40}, + {0x33b9, 0x0a}, + {0x33f9, 0x70}, + {0x33fb, 0x90}, + {0x33fc, 0x4b}, + {0x33fd, 0x5f}, + {0x349f, 0x03}, + {0x34a6, 0x4b}, + {0x34a7, 0x4f}, + {0x34a8, 0x30}, + {0x34a9, 0x20}, + {0x34aa, 0x00}, + {0x34ab, 0xe0}, + {0x34ac, 0x01}, + {0x34ad, 0x00}, + {0x34f8, 0x5f}, + {0x34f9, 0x10}, + {0x3630, 0xc0}, + {0x3633, 0x44}, + {0x3637, 0x29}, + {0x363b, 0x20}, + {0x3670, 0x09}, + {0x3674, 0xb0}, + {0x3675, 0x80}, + {0x3676, 0x88}, + {0x367c, 0x40}, + {0x367d, 0x49}, + {0x3690, 0x44}, + {0x3691, 0x44}, + {0x3692, 0x54}, + {0x369c, 0x49}, + {0x369d, 0x4f}, + {0x36ae, 0x4b}, + {0x36af, 0x4f}, + {0x36b0, 0x87}, + {0x36b1, 0x9b}, + {0x36b2, 0xb7}, + {0x36d0, 0x01}, + {0x36ea, 0x0b}, + {0x36eb, 0x04}, + {0x36ec, 0x1c}, + {0x36ed, 0x24}, + {0x370f, 0x01}, + {0x3722, 0x17}, + {0x3728, 0x90}, + {0x37b0, 0x17}, + {0x37b1, 0x17}, + {0x37b2, 0x97}, + {0x37b3, 0x4b}, + {0x37b4, 0x4f}, + {0x37fa, 0x0b}, + {0x37fb, 0x24}, + {0x37fc, 0x10}, + {0x37fd, 0x22}, + {0x3901, 0x02}, + {0x3902, 0xc5}, + {0x3904, 0x04}, + {0x3907, 0x00}, + {0x3908, 0x41}, + {0x3909, 0x00}, + {0x390a, 0x00}, + {0x391f, 0x04}, + {0x3933, 0x84}, + {0x3934, 0x02}, + {0x3940, 0x62}, + {0x3941, 0x00}, + {0x3942, 0x04}, + {0x3943, 0x03}, + {0x3e00, 0x00}, + {0x3e01, 0x45}, + {0x3e02, 0xb0}, + {0x440e, 0x02}, + {0x450d, 0x11}, + {0x4819, 0x05}, + {0x481b, 0x03}, + {0x481d, 0x0a}, + {0x481f, 0x02}, + {0x4821, 0x08}, + {0x4823, 0x03}, + {0x4825, 0x02}, + {0x4827, 0x03}, + {0x4829, 0x04}, + {0x5000, 0x46}, + {0x5010, 0x01}, + {0x5787, 0x08}, + {0x5788, 0x03}, + {0x5789, 0x00}, + {0x578a, 0x10}, + {0x578b, 0x08}, + {0x578c, 0x00}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x10}, + {0x5794, 0x08}, + {0x5795, 0x00}, + {0x5799, 0x06}, + {0x57ad, 0x00}, + {0x5900, 0xf1}, + {0x5901, 0x04}, + {0x5ae0, 0xfe}, + {0x5ae1, 0x40}, + {0x5ae2, 0x3f}, + {0x5ae3, 0x38}, + {0x5ae4, 0x28}, + {0x5ae5, 0x3f}, + {0x5ae6, 0x38}, + {0x5ae7, 0x28}, + {0x5ae8, 0x3f}, + {0x5ae9, 0x3c}, + {0x5aea, 0x2c}, + {0x5aeb, 0x3f}, + {0x5aec, 0x3c}, + {0x5aed, 0x2c}, + {0x5af4, 0x3f}, + {0x5af5, 0x38}, + {0x5af6, 0x28}, + {0x5af7, 0x3f}, + {0x5af8, 0x38}, + {0x5af9, 0x28}, + {0x5afa, 0x3f}, + {0x5afb, 0x3c}, + {0x5afc, 0x2c}, + {0x5afd, 0x3f}, + {0x5afe, 0x3c}, + {0x5aff, 0x2c}, + {0x36e9, 0x20}, + {0x37f9, 0x24}, {REG_NULL, 0x00}, }; @@ -360,12 +558,31 @@ static const struct sc230ai_mode supported_modes[] = { .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, .reg_list = sc230ai_linear_10_1920x1080_regs, .hdr_mode = NO_HDR, + .bpp = 10, + .mipi_freq_idx = 0, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + }, { + .width = 640, + .height = 480, + .max_fps = { + .numerator = 10000, + .denominator = 1200000, + }, + .exp_def = 0x0232 - 9, + .hts_def = 0x96 * 8, + .vts_def = 0x0232, + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .reg_list = sc230ai_linear_10_640x480_regs, + .hdr_mode = NO_HDR, + .bpp = 10, + .mipi_freq_idx = 1, .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, }, }; static const s64 link_freq_menu_items[] = { - SC230AI_LINK_FREQ_185 + SC230AI_LINK_FREQ_185, + SC230AI_LINK_FREQ_371 }; static const char * const sc230ai_test_pattern_menu[] = { @@ -554,6 +771,7 @@ static int sc230ai_set_fmt(struct v4l2_subdev *sd, struct sc230ai *sc230ai = to_sc230ai(sd); const struct sc230ai_mode *mode; s64 h_blank, vblank_def; + u64 pixel_rate = 0; mutex_lock(&sc230ai->mutex); @@ -578,6 +796,11 @@ static int sc230ai_set_fmt(struct v4l2_subdev *sd, __v4l2_ctrl_modify_range(sc230ai->vblank, vblank_def, SC230AI_VTS_MAX - mode->height, 1, vblank_def); + + __v4l2_ctrl_s_ctrl(sc230ai->link_freq, mode->mipi_freq_idx); + pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / + mode->bpp * 2 * SC230AI_LANES; + __v4l2_ctrl_s_ctrl_int64(sc230ai->pixel_rate, pixel_rate); } mutex_unlock(&sc230ai->mutex); @@ -636,7 +859,7 @@ static int sc230ai_enum_frame_sizes(struct v4l2_subdev *sd, if (fse->index >= ARRAY_SIZE(supported_modes)) return -EINVAL; - if (fse->code != supported_modes[0].bus_fmt) + if (fse->code != supported_modes[fse->index].bus_fmt) return -EINVAL; fse->min_width = supported_modes[fse->index].width; @@ -1276,8 +1499,8 @@ static int sc230ai_initialize_controls(struct sc230ai *sc230ai) { const struct sc230ai_mode *mode; struct v4l2_ctrl_handler *handler; - struct v4l2_ctrl *ctrl; s64 exposure_max, vblank_def; + u64 dst_pixel_rate = 0; u32 h_blank; int ret; @@ -1288,13 +1511,21 @@ static int sc230ai_initialize_controls(struct sc230ai *sc230ai) return ret; handler->lock = &sc230ai->mutex; - ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, - 0, 0, link_freq_menu_items); - if (ctrl) - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + sc230ai->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(link_freq_menu_items) - 1, 0, + link_freq_menu_items); + __v4l2_ctrl_s_ctrl(sc230ai->link_freq, mode->mipi_freq_idx); - v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, - 0, PIXEL_RATE_WITH_185M_10BIT, 1, PIXEL_RATE_WITH_185M_10BIT); + if (mode->mipi_freq_idx == 0) + dst_pixel_rate = PIXEL_RATE_WITH_185M_10BIT; + else if (mode->mipi_freq_idx == 1) + dst_pixel_rate = PIXEL_RATE_WITH_371M_10BIT; + + sc230ai->pixel_rate = v4l2_ctrl_new_std(handler, NULL, + V4L2_CID_PIXEL_RATE, 0, + PIXEL_RATE_WITH_371M_10BIT, + 1, dst_pixel_rate); h_blank = mode->hts_def - mode->width; sc230ai->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,