Thread (6 messages) 6 messages, 3 authors, 2025-08-22

Re: [PATCH 2/2] media: i2c: Add OmniVision OG0VE1B camera sensor

From: Tarang Raval <hidden>
Date: 2025-08-21 06:52:08
Also in: linux-media

Hi Vladimir,
OmniVision OG0VE1B is a monochrome image sensor, which produces frames in
8/10-bit raw output format and supports 640x480, 400x400, 200x200 and
100x100 output image resolution modes.

Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
 MAINTAINERS                 |   8 +
 drivers/media/i2c/Kconfig   |  10 +
 drivers/media/i2c/Makefile  |   1 +
 drivers/media/i2c/og0ve1b.c | 858 ++++++++++++++++++++++++++++++++++++
 4 files changed, 877 insertions(+)
 create mode 100644 drivers/media/i2c/og0ve1b.c
...
+static const struct cci_reg_sequence og0ve1b_640x480_120fps_mode[] = {
+       { CCI_REG8(0x30a0), 0x02 },
+       { CCI_REG8(0x30a1), 0x00 },
+       { CCI_REG8(0x30a2), 0x48 },
+       { CCI_REG8(0x30a3), 0x34 },
+       { CCI_REG8(0x30a4), 0xf7 },
+       { CCI_REG8(0x30a5), 0x00 },
+       { CCI_REG8(0x3082), 0x32 },
+       { CCI_REG8(0x3083), 0x01 },
+       { CCI_REG8(0x301c), 0xf0 },
+       { CCI_REG8(0x301e), 0x0b },
+       { CCI_REG8(0x3106), 0x10 },
+       { CCI_REG8(0x3708), 0x77 },
+       { CCI_REG8(0x3709), 0xf8 },
+       { CCI_REG8(0x3717), 0x00 },
+       { CCI_REG8(0x3782), 0x00 },
+       { CCI_REG8(0x3783), 0x47 },
+       { CCI_REG8(0x37a2), 0x00 },
+       { CCI_REG8(0x3503), 0x07 },
+       { CCI_REG8(0x3509), 0x10 },
+       { CCI_REG8(0x3600), 0x83 },
+       { CCI_REG8(0x3601), 0x21 },
+       { CCI_REG8(0x3602), 0xf1 },
+       { CCI_REG8(0x360a), 0x18 },
+       { CCI_REG8(0x360e), 0xb3 },
+       { CCI_REG8(0x3613), 0x20 },
+       { CCI_REG8(0x366a), 0x78 },
+       { CCI_REG8(0x3706), 0x63 },
+       { CCI_REG8(0x3713), 0x00 },
+       { CCI_REG8(0x3716), 0xb0 },
+       { CCI_REG8(0x37a1), 0x38 },
+       { CCI_REG8(0x3800), 0x00 },
+       { CCI_REG8(0x3801), 0x04 },
+       { CCI_REG8(0x3802), 0x00 },
+       { CCI_REG8(0x3803), 0x04 },
+       { CCI_REG8(0x3804), 0x02 },
+       { CCI_REG8(0x3805), 0x8b },
+       { CCI_REG8(0x3806), 0x01 },
+       { CCI_REG8(0x3807), 0xeb },
+       { CCI_REG8(0x3808), 0x02 },     /* output width */
+       { CCI_REG8(0x3809), 0x80 },
+       { CCI_REG8(0x380a), 0x01 },     /* output height */
+       { CCI_REG8(0x380b), 0xe0 },
+       { CCI_REG8(0x380c), 0x03 },     /* horizontal timing size */
+       { CCI_REG8(0x380d), 0x18 },
+       { CCI_REG8(0x380e), 0x02 },     /* vertical timing size */
Do you have the datasheet for this sensor?

If so, it would be better to divide this array into two parts.
Currently, all of these registers are not related to the mode.
One part should be for common registers, and the other for 
mode-related registers. 
+       { CCI_REG8(0x380f), 0x38 },
+       { CCI_REG8(0x3811), 0x04 },
+       { CCI_REG8(0x3813), 0x04 },
+       { CCI_REG8(0x3814), 0x11 },
+       { CCI_REG8(0x3815), 0x11 },
+       { CCI_REG8(0x3820), 0x00 },
+       { CCI_REG8(0x3821), 0x00 },
+       { CCI_REG8(0x3823), 0x04 },
+       { CCI_REG8(0x382a), 0x00 },
+       { CCI_REG8(0x382b), 0x03 },
+       { CCI_REG8(0x3840), 0x00 },
+       { CCI_REG8(0x389e), 0x00 },
+       { CCI_REG8(0x3c05), 0x08 },
+       { CCI_REG8(0x3c26), 0x02 },
+       { CCI_REG8(0x3c27), 0xc0 },
+       { CCI_REG8(0x3c28), 0x00 },
+       { CCI_REG8(0x3c29), 0x40 },
+       { CCI_REG8(0x3c2c), 0x00 },
+       { CCI_REG8(0x3c2d), 0x50 },
+       { CCI_REG8(0x3c2e), 0x02 },
+       { CCI_REG8(0x3c2f), 0x66 },
+       { CCI_REG8(0x3c33), 0x08 },
+       { CCI_REG8(0x3c35), 0x00 },
+       { CCI_REG8(0x3c36), 0x00 },
+       { CCI_REG8(0x3c37), 0x00 },
+       { CCI_REG8(0x3f52), 0x9b },
+       { CCI_REG8(0x4001), 0x42 },
+       { CCI_REG8(0x4004), 0x08 },
+       { CCI_REG8(0x4005), 0x00 },
+       { CCI_REG8(0x4007), 0x28 },
+       { CCI_REG8(0x4009), 0x40 },
+       { CCI_REG8(0x4307), 0x30 },
+       { CCI_REG8(0x4500), 0x80 },
+       { CCI_REG8(0x4501), 0x02 },
+       { CCI_REG8(0x4502), 0x47 },
+       { CCI_REG8(0x4504), 0x7f },
+       { CCI_REG8(0x4601), 0x48 },
+       { CCI_REG8(0x4800), 0x64 },
+       { CCI_REG8(0x4801), 0x0f },
+       { CCI_REG8(0x4806), 0x2f },
+       { CCI_REG8(0x4819), 0xaa },
+       { CCI_REG8(0x4823), 0x3e },
+       { CCI_REG8(0x5000), 0x85 },
+       { CCI_REG8(0x5e00), 0x0c },
+       { CCI_REG8(0x3899), 0x09 },
+       { CCI_REG8(0x4f00), 0x64 },
+       { CCI_REG8(0x4f02), 0x0a },
+       { CCI_REG8(0x4f05), 0x0e },
+       { CCI_REG8(0x4f06), 0x11 },
+       { CCI_REG8(0x4f08), 0x0b },
+       { CCI_REG8(0x4f0a), 0xc4 },
+       { CCI_REG8(0x4f20), 0x1f },
+       { CCI_REG8(0x4f25), 0x10 },
+       { CCI_REG8(0x3016), 0x10 },
+       { CCI_REG8(0x3017), 0x00 },
+       { CCI_REG8(0x3018), 0x00 },
+       { CCI_REG8(0x3019), 0x00 },
+       { CCI_REG8(0x301a), 0x00 },
+       { CCI_REG8(0x301b), 0x00 },
+       { CCI_REG8(0x301c), 0x72 },
+       { CCI_REG8(0x3037), 0x40 },
+       { CCI_REG8(0x4f2c), 0x00 },
+       { CCI_REG8(0x4f21), 0x00 },
+       { CCI_REG8(0x4f23), 0x00 },
+       { CCI_REG8(0x4f2a), 0x00 },
+       { CCI_REG8(0x3665), 0xe7 },
+       { CCI_REG8(0x3668), 0x48 },
+       { CCI_REG8(0x3671), 0x3c },
+       { CCI_REG8(0x389a), 0x02 },
+       { CCI_REG8(0x389b), 0x00 },
+       { CCI_REG8(0x303c), 0xa0 },
+       { CCI_REG8(0x300f), 0xf0 },
+       { CCI_REG8(0x304b), 0x0f },
+       { CCI_REG8(0x3662), 0x24 },
+       { CCI_REG8(0x3006), 0x40 },
+       { CCI_REG8(0x4f26), 0x45 },
+       { CCI_REG8(0x3607), 0x34 },
+       { CCI_REG8(0x3608), 0x01 },
+       { CCI_REG8(0x360a), 0x0c },
+       { CCI_REG8(0x360b), 0x86 },
+       { CCI_REG8(0x360c), 0xcc },
+       { CCI_REG8(0x3013), 0x00 },
+       { CCI_REG8(0x3083), 0x02 },
+       { CCI_REG8(0x3084), 0x12 },
+       { CCI_REG8(0x4601), 0x38 },
+       { CCI_REG8(0x366f), 0x3a },
+       { CCI_REG8(0x3713), 0x19 },
+       { CCI_REG8(0x37a2), 0x00 },
+       { CCI_REG8(0x3f43), 0x27 },
+       { CCI_REG8(0x3f45), 0x27 },
+       { CCI_REG8(0x3f47), 0x32 },
+       { CCI_REG8(0x3f49), 0x3e },
+       { CCI_REG8(0x3f4b), 0x20 },
+       { CCI_REG8(0x3f4d), 0x30 },
+       { CCI_REG8(0x4300), 0x3f },
+       { CCI_REG8(0x4009), 0x10 },
+       { CCI_REG8(0x3f02), 0x68 },
+       { CCI_REG8(0x3700), 0x8c },
+       { CCI_REG8(0x370b), 0x7e },
+       { CCI_REG8(0x3f47), 0x35 },
+};
...
+static int og0ve1b_probe(struct i2c_client *client)
+{
+       struct og0ve1b *og0ve1b;
+       unsigned long freq;
+       int ret;
+
+       og0ve1b = devm_kzalloc(&client->dev, sizeof(*og0ve1b), GFP_KERNEL);
+       if (!og0ve1b)
+               return -ENOMEM;
+
+       og0ve1b->dev = &client->dev;
+
+       v4l2_i2c_subdev_init(&og0ve1b->sd, client, &og0ve1b_subdev_ops);
+       og0ve1b->sd.dev = og0ve1b->dev;
This seems unnecessary; drop this line.
 
+
+       og0ve1b->regmap = devm_cci_regmap_init_i2c(client, 16);
+       if (IS_ERR(og0ve1b->regmap))
+               return dev_err_probe(og0ve1b->dev, PTR_ERR(og0ve1b->regmap),
+                                    "failed to init CCI\n");
+
+       og0ve1b->xvclk = devm_v4l2_sensor_clk_get(og0ve1b->dev, NULL);
+       if (IS_ERR(og0ve1b->xvclk))
+               return dev_err_probe(og0ve1b->dev, PTR_ERR(og0ve1b->xvclk),
+                                    "failed to get XVCLK clock\n");
+
+       freq = clk_get_rate(og0ve1b->xvclk);
+       if (freq && freq != OG0VE1B_MCLK_FREQ_24MHZ)
+               return dev_err_probe(og0ve1b->dev, -EINVAL,
+                                    "XVCLK clock frequency %lu is not supported\n",
+                                    freq);
...
+static const struct dev_pm_ops og0ve1b_pm_ops = {
+       SET_RUNTIME_PM_OPS(og0ve1b_power_off, og0ve1b_power_on, NULL)
+};
+
+static const struct of_device_id og0ve1b_of_match[] = {
+       { .compatible = "ovti,og0ve1b" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, og0ve1b_of_match);
+
+static struct i2c_driver og0ve1b_i2c_driver = {
+       .driver = {
+               .name = "og0ve1b",
+               .pm = &og0ve1b_pm_ops,
+               .of_match_table = og0ve1b_of_match,
+       },
+       .probe = og0ve1b_probe,
+       .remove = og0ve1b_remove,
+};
+
+module_i2c_driver(og0ve1b_i2c_driver);
+
+MODULE_AUTHOR("Vladimir Zapolskiy [off-list ref]");
+MODULE_DESCRIPTION("OmniVision OG0VE1B sensor driver");
+MODULE_LICENSE("GPL");
--
2.49.0
Best Regards,
Tarang
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help