* [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support
@ 2026-02-26 13:37 Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 1/6] media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe Vladimir Zapolskiy
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
The changeset updates Omnivision OG01A1B camera sensor driver by utilizing
shared V4L2 helpers and adds Y8 media bus support.
Vladimir Zapolskiy (6):
media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe
media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams
media: i2c: og01a1b: Change I2C interface controls to V4L2 CCI
media: i2c: og01a1b: Replace .open with .init_state internal ops
media: i2c: og01a1b: Use generic v4l2_subdev_get_fmt() to get format
media: i2c: og01a1b: Add support of 8-bit media bus format
drivers/media/i2c/Kconfig | 1 +
drivers/media/i2c/og01a1b.c | 895 +++++++++++++++++-------------------
2 files changed, 411 insertions(+), 485 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/6] media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 2/6] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Vladimir Zapolskiy
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
It's necessary to finalize the camera sensor subdevice initialization on
driver probe and clean V4L2 subdevice data up on error paths and driver
removal.
The change fixes a previously reported by v4l2-compliance issue of
the failed VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT test:
fail: v4l2-test-controls.cpp(1104): subscribe event for control 'User Controls' failed
Fixes: 472377febf84 ("media: Add a driver for the og01a1b camera sensor")
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/og01a1b.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index c7184de6251a..7b892b26203c 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -1042,6 +1042,7 @@ static void og01a1b_remove(struct i2c_client *client)
struct og01a1b *og01a1b = to_og01a1b(sd);
v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(&og01a1b->sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(og01a1b->dev);
@@ -1153,11 +1154,18 @@ static int og01a1b_probe(struct i2c_client *client)
goto probe_error_v4l2_ctrl_handler_free;
}
+ ret = v4l2_subdev_init_finalize(&og01a1b->sd);
+ if (ret < 0) {
+ dev_err_probe(og01a1b->dev, ret,
+ "failed to finalize subdevice init\n");
+ goto probe_error_media_entity_cleanup;
+ }
+
ret = v4l2_async_register_subdev_sensor(&og01a1b->sd);
if (ret < 0) {
dev_err(og01a1b->dev, "failed to register V4L2 subdev: %d",
ret);
- goto probe_error_media_entity_cleanup;
+ goto probe_error_v4l2_subdev_cleanup;
}
/* Enable runtime PM and turn off the device */
@@ -1167,6 +1175,9 @@ static int og01a1b_probe(struct i2c_client *client)
return 0;
+probe_error_v4l2_subdev_cleanup:
+ v4l2_subdev_cleanup(&og01a1b->sd);
+
probe_error_media_entity_cleanup:
media_entity_cleanup(&og01a1b->sd.entity);
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/6] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 1/6] media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 3/6] media: i2c: og01a1b: Change I2C interface controls to V4L2 CCI Vladimir Zapolskiy
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
The change allows to simplify the driver code, in particular the explicit
locking scheme for stream on/off or format update serialization can be
dropped in favour to the one provided by the V4L2 core internals.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/og01a1b.c | 88 ++++++++++++++-----------------------
1 file changed, 33 insertions(+), 55 deletions(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 7b892b26203c..ea4c4c7b3d64 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -442,9 +442,6 @@ struct og01a1b {
/* Current mode */
const struct og01a1b_mode *cur_mode;
-
- /* To serialize asynchronus callbacks */
- struct mutex mutex;
};
static u64 to_pixel_rate(u32 f_index)
@@ -616,7 +613,6 @@ static int og01a1b_init_controls(struct og01a1b *og01a1b)
if (ret)
return ret;
- ctrl_hdlr->lock = &og01a1b->mutex;
og01a1b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&og01a1b_ctrl_ops,
V4L2_CID_LINK_FREQ,
@@ -686,74 +682,66 @@ static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,
fmt->field = V4L2_FIELD_NONE;
}
-static int og01a1b_start_streaming(struct og01a1b *og01a1b)
+static int og01a1b_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct og01a1b *og01a1b = to_og01a1b(sd);
+ unsigned int link_freq_index = og01a1b->cur_mode->link_freq_index;
const struct og01a1b_reg_list *reg_list;
- int link_freq_index, ret;
+ int ret;
- link_freq_index = og01a1b->cur_mode->link_freq_index;
- reg_list = &link_freq_configs[link_freq_index].reg_list;
+ ret = pm_runtime_resume_and_get(og01a1b->dev);
+ if (ret)
+ return ret;
+ reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(og01a1b->dev, "failed to set plls");
- return ret;
+ dev_err(og01a1b->dev, "failed to set plls: %d\n", ret);
+ goto error;
}
reg_list = &og01a1b->cur_mode->reg_list;
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(og01a1b->dev, "failed to set mode");
+ dev_err(og01a1b->dev, "failed to set mode: %d\n", ret);
return ret;
}
ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
if (ret)
- return ret;
+ goto error;
ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
OG01A1B_REG_VALUE_08BIT,
OG01A1B_MODE_STREAMING);
if (ret) {
- dev_err(og01a1b->dev, "failed to set stream");
- return ret;
+ dev_err(og01a1b->dev, "failed to start streaming: %d\n", ret);
+ goto error;
}
return 0;
-}
-static void og01a1b_stop_streaming(struct og01a1b *og01a1b)
-{
- if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
- OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY))
- dev_err(og01a1b->dev, "failed to set stream");
+error:
+ pm_runtime_put_autosuspend(og01a1b->dev);
+
+ return ret;
}
-static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)
+static int og01a1b_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
struct og01a1b *og01a1b = to_og01a1b(sd);
- int ret = 0;
-
- mutex_lock(&og01a1b->mutex);
- if (enable) {
- ret = pm_runtime_resume_and_get(og01a1b->dev);
- if (ret) {
- mutex_unlock(&og01a1b->mutex);
- return ret;
- }
+ int ret;
- ret = og01a1b_start_streaming(og01a1b);
- if (ret) {
- enable = 0;
- og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(og01a1b->dev);
- }
- } else {
- og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(og01a1b->dev);
- }
+ ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
+ OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY);
+ if (ret)
+ dev_err(og01a1b->dev, "failed to stop streaming: %d\n", ret);
- mutex_unlock(&og01a1b->mutex);
+ pm_runtime_put_autosuspend(og01a1b->dev);
return ret;
}
@@ -771,7 +759,6 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
height, fmt->format.width,
fmt->format.height);
- mutex_lock(&og01a1b->mutex);
og01a1b_update_pad_format(mode, &fmt->format);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
@@ -794,8 +781,6 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
h_blank);
}
- mutex_unlock(&og01a1b->mutex);
-
return 0;
}
@@ -805,15 +790,12 @@ static int og01a1b_get_format(struct v4l2_subdev *sd,
{
struct og01a1b *og01a1b = to_og01a1b(sd);
- mutex_lock(&og01a1b->mutex);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format);
- mutex_unlock(&og01a1b->mutex);
-
return 0;
}
@@ -849,18 +831,14 @@ static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
- struct og01a1b *og01a1b = to_og01a1b(sd);
-
- mutex_lock(&og01a1b->mutex);
og01a1b_update_pad_format(&supported_modes[0],
v4l2_subdev_state_get_format(fh->state, 0));
- mutex_unlock(&og01a1b->mutex);
return 0;
}
static const struct v4l2_subdev_video_ops og01a1b_video_ops = {
- .s_stream = og01a1b_set_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
@@ -868,6 +846,8 @@ static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
.get_fmt = og01a1b_get_format,
.enum_mbus_code = og01a1b_enum_mbus_code,
.enum_frame_size = og01a1b_enum_frame_size,
+ .enable_streams = og01a1b_enable_streams,
+ .disable_streams = og01a1b_disable_streams,
};
static const struct v4l2_subdev_ops og01a1b_subdev_ops = {
@@ -1046,7 +1026,6 @@ static void og01a1b_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(og01a1b->dev);
- mutex_destroy(&og01a1b->mutex);
}
static int og01a1b_probe(struct i2c_client *client)
@@ -1135,7 +1114,6 @@ static int og01a1b_probe(struct i2c_client *client)
goto power_off;
}
- mutex_init(&og01a1b->mutex);
og01a1b->cur_mode = &supported_modes[0];
ret = og01a1b_init_controls(og01a1b);
if (ret) {
@@ -1143,6 +1121,7 @@ static int og01a1b_probe(struct i2c_client *client)
goto probe_error_v4l2_ctrl_handler_free;
}
+ og01a1b->sd.state_lock = og01a1b->ctrl_handler.lock;
og01a1b->sd.internal_ops = &og01a1b_internal_ops;
og01a1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
og01a1b->sd.entity.ops = &og01a1b_subdev_entity_ops;
@@ -1183,7 +1162,6 @@ static int og01a1b_probe(struct i2c_client *client)
probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler);
- mutex_destroy(&og01a1b->mutex);
power_off:
og01a1b_power_off(og01a1b->dev);
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/6] media: i2c: og01a1b: Change I2C interface controls to V4L2 CCI
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 1/6] media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 2/6] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 4/6] media: i2c: og01a1b: Replace .open with .init_state internal ops Vladimir Zapolskiy
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
Switch the sensor driver to utilize V4L2 CCI helper interfaces instead
of driver specific wrappers over I2C read/write functions.
The conversion change is intended to be non-function, Group Access
register macros were removed as unused ones.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/Kconfig | 1 +
drivers/media/i2c/og01a1b.c | 687 ++++++++++++++++--------------------
2 files changed, 305 insertions(+), 383 deletions(-)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 5eb1e0e0a87a..db0d32bec533 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -355,6 +355,7 @@ config VIDEO_MT9V111
config VIDEO_OG01A1B
tristate "OmniVision OG01A1B sensor support"
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the OmniVision
OG01A1B camera.
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index ea4c4c7b3d64..1f33a4e427ef 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -9,65 +9,54 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
-#include <linux/unaligned.h>
-
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
-#define OG01A1B_REG_VALUE_08BIT 1
-#define OG01A1B_REG_VALUE_16BIT 2
-#define OG01A1B_REG_VALUE_24BIT 3
-
#define OG01A1B_LINK_FREQ_500MHZ 500000000ULL
#define OG01A1B_SCLK 120000000LL
#define OG01A1B_MCLK 19200000
#define OG01A1B_DATA_LANES 2
#define OG01A1B_RGB_DEPTH 10
-#define OG01A1B_REG_CHIP_ID 0x300a
+#define OG01A1B_REG_CHIP_ID CCI_REG24(0x300a)
#define OG01A1B_CHIP_ID 0x470141
-#define OG01A1B_REG_MODE_SELECT 0x0100
+#define OG01A1B_REG_MODE_SELECT CCI_REG8(0x0100)
#define OG01A1B_MODE_STANDBY 0x00
#define OG01A1B_MODE_STREAMING 0x01
/* vertical-timings from sensor */
-#define OG01A1B_REG_VTS 0x380e
+#define OG01A1B_REG_VTS CCI_REG16(0x380e)
#define OG01A1B_VTS_120FPS 0x0498
#define OG01A1B_VTS_120FPS_MIN 0x0498
#define OG01A1B_VTS_MAX 0x7fff
/* horizontal-timings from sensor */
-#define OG01A1B_REG_HTS 0x380c
+#define OG01A1B_REG_HTS CCI_REG16(0x380c)
/* Exposure controls from sensor */
-#define OG01A1B_REG_EXPOSURE 0x3501
+#define OG01A1B_REG_EXPOSURE CCI_REG16(0x3501)
#define OG01A1B_EXPOSURE_MIN 1
#define OG01A1B_EXPOSURE_MAX_MARGIN 14
#define OG01A1B_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
-#define OG01A1B_REG_ANALOG_GAIN 0x3508
+#define OG01A1B_REG_ANALOG_GAIN CCI_REG16(0x3508)
#define OG01A1B_ANAL_GAIN_MIN 16
#define OG01A1B_ANAL_GAIN_MAX 248 /* Max = 15.5x */
#define OG01A1B_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
-#define OG01A1B_REG_DIG_GAIN 0x350a
+#define OG01A1B_REG_DIG_GAIN CCI_REG24(0x350a)
#define OG01A1B_DGTL_GAIN_MIN 1024
#define OG01A1B_DGTL_GAIN_MAX 16384 /* Max = 16x */
#define OG01A1B_DGTL_GAIN_STEP 1
#define OG01A1B_DGTL_GAIN_DEFAULT 1024
-/* Group Access */
-#define OG01A1B_REG_GROUP_ACCESS 0x3208
-#define OG01A1B_GROUP_HOLD_START 0x0
-#define OG01A1B_GROUP_HOLD_END 0x10
-#define OG01A1B_GROUP_HOLD_LAUNCH 0xa0
-
/* Test Pattern Control */
-#define OG01A1B_REG_TEST_PATTERN 0x5100
+#define OG01A1B_REG_TEST_PATTERN CCI_REG8(0x5100)
#define OG01A1B_TEST_PATTERN_ENABLE BIT(7)
#define OG01A1B_TEST_PATTERN_BAR_SHIFT 2
@@ -77,14 +66,9 @@ enum {
OG01A1B_LINK_FREQ_1000MBPS,
};
-struct og01a1b_reg {
- u16 address;
- u8 val;
-};
-
struct og01a1b_reg_list {
+ const struct cci_reg_sequence *regs;
u32 num_of_regs;
- const struct og01a1b_reg *regs;
};
struct og01a1b_link_freq_config {
@@ -114,275 +98,275 @@ struct og01a1b_mode {
const struct og01a1b_reg_list reg_list;
};
-static const struct og01a1b_reg mipi_data_rate_1000mbps[] = {
- {0x0103, 0x01},
- {0x0303, 0x02},
- {0x0304, 0x00},
- {0x0305, 0xd2},
- {0x0323, 0x02},
- {0x0324, 0x01},
- {0x0325, 0x77},
+static const struct cci_reg_sequence mipi_data_rate_1000mbps[] = {
+ { CCI_REG8(0x0103), 0x01 },
+ { CCI_REG8(0x0303), 0x02 },
+ { CCI_REG8(0x0304), 0x00 },
+ { CCI_REG8(0x0305), 0xd2 },
+ { CCI_REG8(0x0323), 0x02 },
+ { CCI_REG8(0x0324), 0x01 },
+ { CCI_REG8(0x0325), 0x77 },
};
-static const struct og01a1b_reg mode_1280x1024_regs[] = {
- {0x0300, 0x0a},
- {0x0301, 0x29},
- {0x0302, 0x31},
- {0x0303, 0x02},
- {0x0304, 0x00},
- {0x0305, 0xd2},
- {0x0306, 0x00},
- {0x0307, 0x01},
- {0x0308, 0x02},
- {0x0309, 0x00},
- {0x0310, 0x00},
- {0x0311, 0x00},
- {0x0312, 0x07},
- {0x0313, 0x00},
- {0x0314, 0x00},
- {0x0315, 0x00},
- {0x0320, 0x02},
- {0x0321, 0x01},
- {0x0322, 0x01},
- {0x0323, 0x02},
- {0x0324, 0x01},
- {0x0325, 0x77},
- {0x0326, 0xce},
- {0x0327, 0x04},
- {0x0329, 0x02},
- {0x032a, 0x04},
- {0x032b, 0x04},
- {0x032c, 0x02},
- {0x032d, 0x01},
- {0x032e, 0x00},
- {0x300d, 0x02},
- {0x300e, 0x04},
- {0x3021, 0x08},
- {0x301e, 0x03},
- {0x3103, 0x00},
- {0x3106, 0x08},
- {0x3107, 0x40},
- {0x3216, 0x01},
- {0x3217, 0x00},
- {0x3218, 0xc0},
- {0x3219, 0x55},
- {0x3500, 0x00},
- {0x3501, 0x04},
- {0x3502, 0x8a},
- {0x3506, 0x01},
- {0x3507, 0x72},
- {0x3508, 0x01},
- {0x3509, 0x00},
- {0x350a, 0x01},
- {0x350b, 0x00},
- {0x350c, 0x00},
- {0x3541, 0x00},
- {0x3542, 0x40},
- {0x3605, 0xe0},
- {0x3606, 0x41},
- {0x3614, 0x20},
- {0x3620, 0x0b},
- {0x3630, 0x07},
- {0x3636, 0xa0},
- {0x3637, 0xf9},
- {0x3638, 0x09},
- {0x3639, 0x38},
- {0x363f, 0x09},
- {0x3640, 0x17},
- {0x3662, 0x04},
- {0x3665, 0x80},
- {0x3670, 0x68},
- {0x3674, 0x00},
- {0x3677, 0x3f},
- {0x3679, 0x00},
- {0x369f, 0x19},
- {0x36a0, 0x03},
- {0x36a2, 0x19},
- {0x36a3, 0x03},
- {0x370d, 0x66},
- {0x370f, 0x00},
- {0x3710, 0x03},
- {0x3715, 0x03},
- {0x3716, 0x03},
- {0x3717, 0x06},
- {0x3733, 0x00},
- {0x3778, 0x00},
- {0x37a8, 0x0f},
- {0x37a9, 0x01},
- {0x37aa, 0x07},
- {0x37bd, 0x1c},
- {0x37c1, 0x2f},
- {0x37c3, 0x09},
- {0x37c8, 0x1d},
- {0x37ca, 0x30},
- {0x37df, 0x00},
- {0x3800, 0x00},
- {0x3801, 0x00},
- {0x3802, 0x00},
- {0x3803, 0x00},
- {0x3804, 0x05},
- {0x3805, 0x0f},
- {0x3806, 0x04},
- {0x3807, 0x0f},
- {0x3808, 0x05},
- {0x3809, 0x00},
- {0x380a, 0x04},
- {0x380b, 0x00},
- {0x380c, 0x03},
- {0x380d, 0x50},
- {0x380e, 0x04},
- {0x380f, 0x98},
- {0x3810, 0x00},
- {0x3811, 0x08},
- {0x3812, 0x00},
- {0x3813, 0x08},
- {0x3814, 0x11},
- {0x3815, 0x11},
- {0x3820, 0x40},
- {0x3821, 0x04},
- {0x3826, 0x00},
- {0x3827, 0x00},
- {0x382a, 0x08},
- {0x382b, 0x52},
- {0x382d, 0xba},
- {0x383d, 0x14},
- {0x384a, 0xa2},
- {0x3866, 0x0e},
- {0x3867, 0x07},
- {0x3884, 0x00},
- {0x3885, 0x08},
- {0x3893, 0x68},
- {0x3894, 0x2a},
- {0x3898, 0x00},
- {0x3899, 0x31},
- {0x389a, 0x04},
- {0x389b, 0x00},
- {0x389c, 0x0b},
- {0x389d, 0xad},
- {0x389f, 0x08},
- {0x38a0, 0x00},
- {0x38a1, 0x00},
- {0x38a8, 0x70},
- {0x38ac, 0xea},
- {0x38b2, 0x00},
- {0x38b3, 0x08},
- {0x38bc, 0x20},
- {0x38c4, 0x0c},
- {0x38c5, 0x3a},
- {0x38c7, 0x3a},
- {0x38e1, 0xc0},
- {0x38ec, 0x3c},
- {0x38f0, 0x09},
- {0x38f1, 0x6f},
- {0x38fe, 0x3c},
- {0x391e, 0x00},
- {0x391f, 0x00},
- {0x3920, 0xa5},
- {0x3921, 0x00},
- {0x3922, 0x00},
- {0x3923, 0x00},
- {0x3924, 0x05},
- {0x3925, 0x00},
- {0x3926, 0x00},
- {0x3927, 0x00},
- {0x3928, 0x1a},
- {0x3929, 0x01},
- {0x392a, 0xb4},
- {0x392b, 0x00},
- {0x392c, 0x10},
- {0x392f, 0x40},
- {0x4000, 0xcf},
- {0x4003, 0x40},
- {0x4008, 0x00},
- {0x4009, 0x07},
- {0x400a, 0x02},
- {0x400b, 0x54},
- {0x400c, 0x00},
- {0x400d, 0x07},
- {0x4010, 0xc0},
- {0x4012, 0x02},
- {0x4014, 0x04},
- {0x4015, 0x04},
- {0x4017, 0x02},
- {0x4042, 0x01},
- {0x4306, 0x04},
- {0x4307, 0x12},
- {0x4509, 0x00},
- {0x450b, 0x83},
- {0x4604, 0x68},
- {0x4608, 0x0a},
- {0x4700, 0x06},
- {0x4800, 0x64},
- {0x481b, 0x3c},
- {0x4825, 0x32},
- {0x4833, 0x18},
- {0x4837, 0x0f},
- {0x4850, 0x40},
- {0x4860, 0x00},
- {0x4861, 0xec},
- {0x4864, 0x00},
- {0x4883, 0x00},
- {0x4888, 0x90},
- {0x4889, 0x05},
- {0x488b, 0x04},
- {0x4f00, 0x04},
- {0x4f10, 0x04},
- {0x4f21, 0x01},
- {0x4f22, 0x40},
- {0x4f23, 0x44},
- {0x4f24, 0x51},
- {0x4f25, 0x41},
- {0x5000, 0x1f},
- {0x500a, 0x00},
- {0x5100, 0x00},
- {0x5111, 0x20},
- {0x3020, 0x20},
- {0x3613, 0x03},
- {0x38c9, 0x02},
- {0x5304, 0x01},
- {0x3620, 0x08},
- {0x3639, 0x58},
- {0x363a, 0x10},
- {0x3674, 0x04},
- {0x3780, 0xff},
- {0x3781, 0xff},
- {0x3782, 0x00},
- {0x3783, 0x01},
- {0x3798, 0xa3},
- {0x37aa, 0x10},
- {0x38a8, 0xf0},
- {0x38c4, 0x09},
- {0x38c5, 0xb0},
- {0x38df, 0x80},
- {0x38ff, 0x05},
- {0x4010, 0xf1},
- {0x4011, 0x70},
- {0x3667, 0x80},
- {0x4d00, 0x4a},
- {0x4d01, 0x18},
- {0x4d02, 0xbb},
- {0x4d03, 0xde},
- {0x4d04, 0x93},
- {0x4d05, 0xff},
- {0x4d09, 0x0a},
- {0x37aa, 0x16},
- {0x3606, 0x42},
- {0x3605, 0x00},
- {0x36a2, 0x17},
- {0x300d, 0x0a},
- {0x4d00, 0x4d},
- {0x4d01, 0x95},
- {0x3d8C, 0x70},
- {0x3d8d, 0xE9},
- {0x5300, 0x00},
- {0x5301, 0x10},
- {0x5302, 0x00},
- {0x5303, 0xE3},
- {0x3d88, 0x00},
- {0x3d89, 0x10},
- {0x3d8a, 0x00},
- {0x3d8b, 0xE3},
- {0x4f22, 0x00},
+static const struct cci_reg_sequence mode_1280x1024_regs[] = {
+ { CCI_REG8(0x0300), 0x0a },
+ { CCI_REG8(0x0301), 0x29 },
+ { CCI_REG8(0x0302), 0x31 },
+ { CCI_REG8(0x0303), 0x02 },
+ { CCI_REG8(0x0304), 0x00 },
+ { CCI_REG8(0x0305), 0xd2 },
+ { CCI_REG8(0x0306), 0x00 },
+ { CCI_REG8(0x0307), 0x01 },
+ { CCI_REG8(0x0308), 0x02 },
+ { CCI_REG8(0x0309), 0x00 },
+ { CCI_REG8(0x0310), 0x00 },
+ { CCI_REG8(0x0311), 0x00 },
+ { CCI_REG8(0x0312), 0x07 },
+ { CCI_REG8(0x0313), 0x00 },
+ { CCI_REG8(0x0314), 0x00 },
+ { CCI_REG8(0x0315), 0x00 },
+ { CCI_REG8(0x0320), 0x02 },
+ { CCI_REG8(0x0321), 0x01 },
+ { CCI_REG8(0x0322), 0x01 },
+ { CCI_REG8(0x0323), 0x02 },
+ { CCI_REG8(0x0324), 0x01 },
+ { CCI_REG8(0x0325), 0x77 },
+ { CCI_REG8(0x0326), 0xce },
+ { CCI_REG8(0x0327), 0x04 },
+ { CCI_REG8(0x0329), 0x02 },
+ { CCI_REG8(0x032a), 0x04 },
+ { CCI_REG8(0x032b), 0x04 },
+ { CCI_REG8(0x032c), 0x02 },
+ { CCI_REG8(0x032d), 0x01 },
+ { CCI_REG8(0x032e), 0x00 },
+ { CCI_REG8(0x300d), 0x02 },
+ { CCI_REG8(0x300e), 0x04 },
+ { CCI_REG8(0x3021), 0x08 },
+ { CCI_REG8(0x301e), 0x03 },
+ { CCI_REG8(0x3103), 0x00 },
+ { CCI_REG8(0x3106), 0x08 },
+ { CCI_REG8(0x3107), 0x40 },
+ { CCI_REG8(0x3216), 0x01 },
+ { CCI_REG8(0x3217), 0x00 },
+ { CCI_REG8(0x3218), 0xc0 },
+ { CCI_REG8(0x3219), 0x55 },
+ { CCI_REG8(0x3500), 0x00 },
+ { CCI_REG8(0x3501), 0x04 },
+ { CCI_REG8(0x3502), 0x8a },
+ { CCI_REG8(0x3506), 0x01 },
+ { CCI_REG8(0x3507), 0x72 },
+ { CCI_REG8(0x3508), 0x01 },
+ { CCI_REG8(0x3509), 0x00 },
+ { CCI_REG8(0x350a), 0x01 },
+ { CCI_REG8(0x350b), 0x00 },
+ { CCI_REG8(0x350c), 0x00 },
+ { CCI_REG8(0x3541), 0x00 },
+ { CCI_REG8(0x3542), 0x40 },
+ { CCI_REG8(0x3605), 0xe0 },
+ { CCI_REG8(0x3606), 0x41 },
+ { CCI_REG8(0x3614), 0x20 },
+ { CCI_REG8(0x3620), 0x0b },
+ { CCI_REG8(0x3630), 0x07 },
+ { CCI_REG8(0x3636), 0xa0 },
+ { CCI_REG8(0x3637), 0xf9 },
+ { CCI_REG8(0x3638), 0x09 },
+ { CCI_REG8(0x3639), 0x38 },
+ { CCI_REG8(0x363f), 0x09 },
+ { CCI_REG8(0x3640), 0x17 },
+ { CCI_REG8(0x3662), 0x04 },
+ { CCI_REG8(0x3665), 0x80 },
+ { CCI_REG8(0x3670), 0x68 },
+ { CCI_REG8(0x3674), 0x00 },
+ { CCI_REG8(0x3677), 0x3f },
+ { CCI_REG8(0x3679), 0x00 },
+ { CCI_REG8(0x369f), 0x19 },
+ { CCI_REG8(0x36a0), 0x03 },
+ { CCI_REG8(0x36a2), 0x19 },
+ { CCI_REG8(0x36a3), 0x03 },
+ { CCI_REG8(0x370d), 0x66 },
+ { CCI_REG8(0x370f), 0x00 },
+ { CCI_REG8(0x3710), 0x03 },
+ { CCI_REG8(0x3715), 0x03 },
+ { CCI_REG8(0x3716), 0x03 },
+ { CCI_REG8(0x3717), 0x06 },
+ { CCI_REG8(0x3733), 0x00 },
+ { CCI_REG8(0x3778), 0x00 },
+ { CCI_REG8(0x37a8), 0x0f },
+ { CCI_REG8(0x37a9), 0x01 },
+ { CCI_REG8(0x37aa), 0x07 },
+ { CCI_REG8(0x37bd), 0x1c },
+ { CCI_REG8(0x37c1), 0x2f },
+ { CCI_REG8(0x37c3), 0x09 },
+ { CCI_REG8(0x37c8), 0x1d },
+ { CCI_REG8(0x37ca), 0x30 },
+ { CCI_REG8(0x37df), 0x00 },
+ { CCI_REG8(0x3800), 0x00 },
+ { CCI_REG8(0x3801), 0x00 },
+ { CCI_REG8(0x3802), 0x00 },
+ { CCI_REG8(0x3803), 0x00 },
+ { CCI_REG8(0x3804), 0x05 },
+ { CCI_REG8(0x3805), 0x0f },
+ { CCI_REG8(0x3806), 0x04 },
+ { CCI_REG8(0x3807), 0x0f },
+ { CCI_REG8(0x3808), 0x05 },
+ { CCI_REG8(0x3809), 0x00 },
+ { CCI_REG8(0x380a), 0x04 },
+ { CCI_REG8(0x380b), 0x00 },
+ { CCI_REG8(0x380c), 0x03 },
+ { CCI_REG8(0x380d), 0x50 },
+ { CCI_REG8(0x380e), 0x04 },
+ { CCI_REG8(0x380f), 0x98 },
+ { CCI_REG8(0x3810), 0x00 },
+ { CCI_REG8(0x3811), 0x08 },
+ { CCI_REG8(0x3812), 0x00 },
+ { CCI_REG8(0x3813), 0x08 },
+ { CCI_REG8(0x3814), 0x11 },
+ { CCI_REG8(0x3815), 0x11 },
+ { CCI_REG8(0x3820), 0x40 },
+ { CCI_REG8(0x3821), 0x04 },
+ { CCI_REG8(0x3826), 0x00 },
+ { CCI_REG8(0x3827), 0x00 },
+ { CCI_REG8(0x382a), 0x08 },
+ { CCI_REG8(0x382b), 0x52 },
+ { CCI_REG8(0x382d), 0xba },
+ { CCI_REG8(0x383d), 0x14 },
+ { CCI_REG8(0x384a), 0xa2 },
+ { CCI_REG8(0x3866), 0x0e },
+ { CCI_REG8(0x3867), 0x07 },
+ { CCI_REG8(0x3884), 0x00 },
+ { CCI_REG8(0x3885), 0x08 },
+ { CCI_REG8(0x3893), 0x68 },
+ { CCI_REG8(0x3894), 0x2a },
+ { CCI_REG8(0x3898), 0x00 },
+ { CCI_REG8(0x3899), 0x31 },
+ { CCI_REG8(0x389a), 0x04 },
+ { CCI_REG8(0x389b), 0x00 },
+ { CCI_REG8(0x389c), 0x0b },
+ { CCI_REG8(0x389d), 0xad },
+ { CCI_REG8(0x389f), 0x08 },
+ { CCI_REG8(0x38a0), 0x00 },
+ { CCI_REG8(0x38a1), 0x00 },
+ { CCI_REG8(0x38a8), 0x70 },
+ { CCI_REG8(0x38ac), 0xea },
+ { CCI_REG8(0x38b2), 0x00 },
+ { CCI_REG8(0x38b3), 0x08 },
+ { CCI_REG8(0x38bc), 0x20 },
+ { CCI_REG8(0x38c4), 0x0c },
+ { CCI_REG8(0x38c5), 0x3a },
+ { CCI_REG8(0x38c7), 0x3a },
+ { CCI_REG8(0x38e1), 0xc0 },
+ { CCI_REG8(0x38ec), 0x3c },
+ { CCI_REG8(0x38f0), 0x09 },
+ { CCI_REG8(0x38f1), 0x6f },
+ { CCI_REG8(0x38fe), 0x3c },
+ { CCI_REG8(0x391e), 0x00 },
+ { CCI_REG8(0x391f), 0x00 },
+ { CCI_REG8(0x3920), 0xa5 },
+ { CCI_REG8(0x3921), 0x00 },
+ { CCI_REG8(0x3922), 0x00 },
+ { CCI_REG8(0x3923), 0x00 },
+ { CCI_REG8(0x3924), 0x05 },
+ { CCI_REG8(0x3925), 0x00 },
+ { CCI_REG8(0x3926), 0x00 },
+ { CCI_REG8(0x3927), 0x00 },
+ { CCI_REG8(0x3928), 0x1a },
+ { CCI_REG8(0x3929), 0x01 },
+ { CCI_REG8(0x392a), 0xb4 },
+ { CCI_REG8(0x392b), 0x00 },
+ { CCI_REG8(0x392c), 0x10 },
+ { CCI_REG8(0x392f), 0x40 },
+ { CCI_REG8(0x4000), 0xcf },
+ { CCI_REG8(0x4003), 0x40 },
+ { CCI_REG8(0x4008), 0x00 },
+ { CCI_REG8(0x4009), 0x07 },
+ { CCI_REG8(0x400a), 0x02 },
+ { CCI_REG8(0x400b), 0x54 },
+ { CCI_REG8(0x400c), 0x00 },
+ { CCI_REG8(0x400d), 0x07 },
+ { CCI_REG8(0x4010), 0xc0 },
+ { CCI_REG8(0x4012), 0x02 },
+ { CCI_REG8(0x4014), 0x04 },
+ { CCI_REG8(0x4015), 0x04 },
+ { CCI_REG8(0x4017), 0x02 },
+ { CCI_REG8(0x4042), 0x01 },
+ { CCI_REG8(0x4306), 0x04 },
+ { CCI_REG8(0x4307), 0x12 },
+ { CCI_REG8(0x4509), 0x00 },
+ { CCI_REG8(0x450b), 0x83 },
+ { CCI_REG8(0x4604), 0x68 },
+ { CCI_REG8(0x4608), 0x0a },
+ { CCI_REG8(0x4700), 0x06 },
+ { CCI_REG8(0x4800), 0x64 },
+ { CCI_REG8(0x481b), 0x3c },
+ { CCI_REG8(0x4825), 0x32 },
+ { CCI_REG8(0x4833), 0x18 },
+ { CCI_REG8(0x4837), 0x0f },
+ { CCI_REG8(0x4850), 0x40 },
+ { CCI_REG8(0x4860), 0x00 },
+ { CCI_REG8(0x4861), 0xec },
+ { CCI_REG8(0x4864), 0x00 },
+ { CCI_REG8(0x4883), 0x00 },
+ { CCI_REG8(0x4888), 0x90 },
+ { CCI_REG8(0x4889), 0x05 },
+ { CCI_REG8(0x488b), 0x04 },
+ { CCI_REG8(0x4f00), 0x04 },
+ { CCI_REG8(0x4f10), 0x04 },
+ { CCI_REG8(0x4f21), 0x01 },
+ { CCI_REG8(0x4f22), 0x40 },
+ { CCI_REG8(0x4f23), 0x44 },
+ { CCI_REG8(0x4f24), 0x51 },
+ { CCI_REG8(0x4f25), 0x41 },
+ { CCI_REG8(0x5000), 0x1f },
+ { CCI_REG8(0x500a), 0x00 },
+ { CCI_REG8(0x5100), 0x00 },
+ { CCI_REG8(0x5111), 0x20 },
+ { CCI_REG8(0x3020), 0x20 },
+ { CCI_REG8(0x3613), 0x03 },
+ { CCI_REG8(0x38c9), 0x02 },
+ { CCI_REG8(0x5304), 0x01 },
+ { CCI_REG8(0x3620), 0x08 },
+ { CCI_REG8(0x3639), 0x58 },
+ { CCI_REG8(0x363a), 0x10 },
+ { CCI_REG8(0x3674), 0x04 },
+ { CCI_REG8(0x3780), 0xff },
+ { CCI_REG8(0x3781), 0xff },
+ { CCI_REG8(0x3782), 0x00 },
+ { CCI_REG8(0x3783), 0x01 },
+ { CCI_REG8(0x3798), 0xa3 },
+ { CCI_REG8(0x37aa), 0x10 },
+ { CCI_REG8(0x38a8), 0xf0 },
+ { CCI_REG8(0x38c4), 0x09 },
+ { CCI_REG8(0x38c5), 0xb0 },
+ { CCI_REG8(0x38df), 0x80 },
+ { CCI_REG8(0x38ff), 0x05 },
+ { CCI_REG8(0x4010), 0xf1 },
+ { CCI_REG8(0x4011), 0x70 },
+ { CCI_REG8(0x3667), 0x80 },
+ { CCI_REG8(0x4d00), 0x4a },
+ { CCI_REG8(0x4d01), 0x18 },
+ { CCI_REG8(0x4d02), 0xbb },
+ { CCI_REG8(0x4d03), 0xde },
+ { CCI_REG8(0x4d04), 0x93 },
+ { CCI_REG8(0x4d05), 0xff },
+ { CCI_REG8(0x4d09), 0x0a },
+ { CCI_REG8(0x37aa), 0x16 },
+ { CCI_REG8(0x3606), 0x42 },
+ { CCI_REG8(0x3605), 0x00 },
+ { CCI_REG8(0x36a2), 0x17 },
+ { CCI_REG8(0x300d), 0x0a },
+ { CCI_REG8(0x4d00), 0x4d },
+ { CCI_REG8(0x4d01), 0x95 },
+ { CCI_REG8(0x3d8c), 0x70 },
+ { CCI_REG8(0x3d8d), 0xe9 },
+ { CCI_REG8(0x5300), 0x00 },
+ { CCI_REG8(0x5301), 0x10 },
+ { CCI_REG8(0x5302), 0x00 },
+ { CCI_REG8(0x5303), 0xe3 },
+ { CCI_REG8(0x3d88), 0x00 },
+ { CCI_REG8(0x3d89), 0x10 },
+ { CCI_REG8(0x3d8a), 0x00 },
+ { CCI_REG8(0x3d8b), 0xe3 },
+ { CCI_REG8(0x4f22), 0x00 },
};
static const char * const og01a1b_test_pattern_menu[] = {
@@ -423,6 +407,7 @@ static const struct og01a1b_mode supported_modes[] = {
struct og01a1b {
struct device *dev;
+ struct regmap *regmap;
struct clk *xvclk;
struct gpio_desc *reset_gpio;
struct regulator *avdd;
@@ -462,80 +447,14 @@ static u64 to_pixels_per_line(u32 hts, u32 f_index)
return ppl;
}
-static int og01a1b_read_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
- struct i2c_msg msgs[2];
- u8 addr_buf[2];
- u8 data_buf[4] = {0};
- int ret;
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, addr_buf);
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = sizeof(addr_buf);
- msgs[0].buf = addr_buf;
- msgs[1].addr = client->addr;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = len;
- msgs[1].buf = &data_buf[4 - len];
-
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs))
- return -EIO;
-
- *val = get_unaligned_be32(data_buf);
-
- return 0;
-}
-
-static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
- u8 buf[6];
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, buf);
- put_unaligned_be32(val << 8 * (4 - len), buf + 2);
- if (i2c_master_send(client, buf, len + 2) != len + 2)
- return -EIO;
-
- return 0;
-}
-
-static int og01a1b_write_reg_list(struct og01a1b *og01a1b,
- const struct og01a1b_reg_list *r_list)
-{
- unsigned int i;
- int ret;
-
- for (i = 0; i < r_list->num_of_regs; i++) {
- ret = og01a1b_write_reg(og01a1b, r_list->regs[i].address, 1,
- r_list->regs[i].val);
- if (ret) {
- dev_err_ratelimited(og01a1b->dev,
- "failed to write reg 0x%4.4x. error = %d",
- r_list->regs[i].address, ret);
- return ret;
- }
- }
-
- return 0;
-}
-
static int og01a1b_test_pattern(struct og01a1b *og01a1b, u32 pattern)
{
if (pattern)
pattern = (pattern - 1) << OG01A1B_TEST_PATTERN_BAR_SHIFT |
OG01A1B_TEST_PATTERN_ENABLE;
- return og01a1b_write_reg(og01a1b, OG01A1B_REG_TEST_PATTERN,
- OG01A1B_REG_VALUE_08BIT, pattern);
+ return cci_write(og01a1b->regmap, OG01A1B_REG_TEST_PATTERN,
+ pattern, NULL);
}
static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -562,26 +481,23 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_ANALOG_GAIN,
- OG01A1B_REG_VALUE_16BIT,
- ctrl->val << 4);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_ANALOG_GAIN,
+ ctrl->val << 4, NULL);
break;
case V4L2_CID_DIGITAL_GAIN:
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_DIG_GAIN,
- OG01A1B_REG_VALUE_24BIT,
- ctrl->val << 6);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_DIG_GAIN,
+ ctrl->val << 6, NULL);
break;
case V4L2_CID_EXPOSURE:
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_EXPOSURE,
- OG01A1B_REG_VALUE_16BIT, ctrl->val);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_EXPOSURE,
+ ctrl->val, NULL);
break;
case V4L2_CID_VBLANK:
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_VTS,
- OG01A1B_REG_VALUE_16BIT,
- og01a1b->cur_mode->height + ctrl->val);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_VTS,
+ og01a1b->cur_mode->height + ctrl->val, NULL);
break;
case V4L2_CID_TEST_PATTERN:
@@ -696,14 +612,16 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
return ret;
reg_list = &link_freq_configs[link_freq_index].reg_list;
- ret = og01a1b_write_reg_list(og01a1b, reg_list);
+ ret = cci_multi_reg_write(og01a1b->regmap, reg_list->regs,
+ reg_list->num_of_regs, NULL);
if (ret) {
dev_err(og01a1b->dev, "failed to set plls: %d\n", ret);
goto error;
}
reg_list = &og01a1b->cur_mode->reg_list;
- ret = og01a1b_write_reg_list(og01a1b, reg_list);
+ ret = cci_multi_reg_write(og01a1b->regmap, reg_list->regs,
+ reg_list->num_of_regs, NULL);
if (ret) {
dev_err(og01a1b->dev, "failed to set mode: %d\n", ret);
return ret;
@@ -713,9 +631,8 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
if (ret)
goto error;
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
- OG01A1B_REG_VALUE_08BIT,
- OG01A1B_MODE_STREAMING);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_MODE_SELECT,
+ OG01A1B_MODE_STREAMING, NULL);
if (ret) {
dev_err(og01a1b->dev, "failed to start streaming: %d\n", ret);
goto error;
@@ -736,8 +653,8 @@ static int og01a1b_disable_streams(struct v4l2_subdev *sd,
struct og01a1b *og01a1b = to_og01a1b(sd);
int ret;
- ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
- OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY);
+ ret = cci_write(og01a1b->regmap, OG01A1B_REG_MODE_SELECT,
+ OG01A1B_MODE_STANDBY, NULL);
if (ret)
dev_err(og01a1b->dev, "failed to stop streaming: %d\n", ret);
@@ -866,15 +783,14 @@ static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {
static int og01a1b_identify_module(struct og01a1b *og01a1b)
{
int ret;
- u32 val;
+ u64 val;
- ret = og01a1b_read_reg(og01a1b, OG01A1B_REG_CHIP_ID,
- OG01A1B_REG_VALUE_24BIT, &val);
+ ret = cci_read(og01a1b->regmap, OG01A1B_REG_CHIP_ID, &val, NULL);
if (ret)
return ret;
if (val != OG01A1B_CHIP_ID) {
- dev_err(og01a1b->dev, "chip id mismatch: %x!=%x",
+ dev_err(og01a1b->dev, "chip id mismatch: %x!=%llx",
OG01A1B_CHIP_ID, val);
return -ENXIO;
}
@@ -1042,6 +958,11 @@ static int og01a1b_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops);
+ og01a1b->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(og01a1b->regmap))
+ return dev_err_probe(og01a1b->dev, PTR_ERR(og01a1b->regmap),
+ "failed to init CCI\n");
+
og01a1b->xvclk = devm_v4l2_sensor_clk_get(og01a1b->dev, NULL);
if (IS_ERR(og01a1b->xvclk))
return dev_err_probe(og01a1b->dev, PTR_ERR(og01a1b->xvclk),
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/6] media: i2c: og01a1b: Replace .open with .init_state internal ops
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
` (2 preceding siblings ...)
2026-02-26 13:37 ` [PATCH 3/6] media: i2c: og01a1b: Change I2C interface controls to V4L2 CCI Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 5/6] media: i2c: og01a1b: Use generic v4l2_subdev_get_fmt() to get format Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format Vladimir Zapolskiy
5 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
Instead of wiping the camera sensor subdevice initial state on every
open() syscall it would be better to set the initial state just once.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/og01a1b.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 1f33a4e427ef..537218f6fa62 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -746,10 +746,21 @@ static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
return 0;
}
-static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+static int og01a1b_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
{
- og01a1b_update_pad_format(&supported_modes[0],
- v4l2_subdev_state_get_format(fh->state, 0));
+ struct og01a1b *og01a1b = to_og01a1b(sd);
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .pad = 0,
+ .format = {
+ .width = og01a1b->cur_mode->width,
+ .height = og01a1b->cur_mode->height,
+ .code = MEDIA_BUS_FMT_Y10_1X10,
+ },
+ };
+
+ og01a1b_set_format(sd, state, &fmt);
return 0;
}
@@ -777,7 +788,7 @@ static const struct media_entity_operations og01a1b_subdev_entity_ops = {
};
static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {
- .open = og01a1b_open,
+ .init_state = og01a1b_init_state,
};
static int og01a1b_identify_module(struct og01a1b *og01a1b)
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/6] media: i2c: og01a1b: Use generic v4l2_subdev_get_fmt() to get format
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
` (3 preceding siblings ...)
2026-02-26 13:37 ` [PATCH 4/6] media: i2c: og01a1b: Replace .open with .init_state internal ops Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format Vladimir Zapolskiy
5 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
The generic v4l2_subdev_get_fmt() helper function can be utilized to
get the setup device format instead of the custom one.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/og01a1b.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 537218f6fa62..58531ab8f87d 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -701,21 +701,6 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
return 0;
}
-static int og01a1b_get_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct og01a1b *og01a1b = to_og01a1b(sd);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
- fmt->format = *v4l2_subdev_state_get_format(sd_state,
- fmt->pad);
- else
- og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format);
-
- return 0;
-}
-
static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
@@ -771,7 +756,7 @@ static const struct v4l2_subdev_video_ops og01a1b_video_ops = {
static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
.set_fmt = og01a1b_set_format,
- .get_fmt = og01a1b_get_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.enum_mbus_code = og01a1b_enum_mbus_code,
.enum_frame_size = og01a1b_enum_frame_size,
.enable_streams = og01a1b_enable_streams,
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
` (4 preceding siblings ...)
2026-02-26 13:37 ` [PATCH 5/6] media: i2c: og01a1b: Use generic v4l2_subdev_get_fmt() to get format Vladimir Zapolskiy
@ 2026-02-26 13:37 ` Vladimir Zapolskiy
2026-03-09 11:55 ` Sakari Ailus
5 siblings, 1 reply; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-02-26 13:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil; +Cc: Shawn Tu, linux-media
Omnivision OG01A1B monochrome image sensor supports 8-bit and 10-bit
output formats, add support of 8-bit Y8 format to the driver.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
---
drivers/media/i2c/og01a1b.c | 97 ++++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 39 deletions(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 58531ab8f87d..0ccb03f05734 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -18,7 +18,6 @@
#define OG01A1B_SCLK 120000000LL
#define OG01A1B_MCLK 19200000
#define OG01A1B_DATA_LANES 2
-#define OG01A1B_RGB_DEPTH 10
#define OG01A1B_REG_CHIP_ID CCI_REG24(0x300a)
#define OG01A1B_CHIP_ID 0x470141
@@ -98,6 +97,11 @@ struct og01a1b_mode {
const struct og01a1b_reg_list reg_list;
};
+static const u32 og01a1b_mbus_formats[] = {
+ MEDIA_BUS_FMT_Y10_1X10,
+ MEDIA_BUS_FMT_Y8_1X8,
+};
+
static const struct cci_reg_sequence mipi_data_rate_1000mbps[] = {
{ CCI_REG8(0x0103), 0x01 },
{ CCI_REG8(0x0303), 0x02 },
@@ -173,7 +177,6 @@ static const struct cci_reg_sequence mode_1280x1024_regs[] = {
{ CCI_REG8(0x3639), 0x38 },
{ CCI_REG8(0x363f), 0x09 },
{ CCI_REG8(0x3640), 0x17 },
- { CCI_REG8(0x3662), 0x04 },
{ CCI_REG8(0x3665), 0x80 },
{ CCI_REG8(0x3670), 0x68 },
{ CCI_REG8(0x3674), 0x00 },
@@ -427,20 +430,23 @@ struct og01a1b {
/* Current mode */
const struct og01a1b_mode *cur_mode;
+
+ /* Selected media bus format output */
+ u32 code;
};
-static u64 to_pixel_rate(u32 f_index)
+static u64 to_pixel_rate(u32 f_index, u32 bpp)
{
u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OG01A1B_DATA_LANES;
- do_div(pixel_rate, OG01A1B_RGB_DEPTH);
+ do_div(pixel_rate, bpp);
return pixel_rate;
}
-static u64 to_pixels_per_line(u32 hts, u32 f_index)
+static u64 to_pixels_per_line(u32 hts, u32 f_index, u32 bpp)
{
- u64 ppl = hts * to_pixel_rate(f_index);
+ u64 ppl = hts * to_pixel_rate(f_index, bpp);
do_div(ppl, OG01A1B_SCLK);
@@ -522,6 +528,7 @@ static int og01a1b_init_controls(struct og01a1b *og01a1b)
{
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max, h_blank;
+ u32 bpp;
int ret;
ctrl_hdlr = &og01a1b->ctrl_handler;
@@ -538,13 +545,12 @@ static int og01a1b_init_controls(struct og01a1b *og01a1b)
if (og01a1b->link_freq)
og01a1b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ bpp = (og01a1b->code == MEDIA_BUS_FMT_Y10_1X10 ? 10 : 8);
og01a1b->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0,
- to_pixel_rate
- (OG01A1B_LINK_FREQ_1000MBPS),
- 1,
- to_pixel_rate
- (OG01A1B_LINK_FREQ_1000MBPS));
+ V4L2_CID_PIXEL_RATE, 0,
+ to_pixel_rate(OG01A1B_LINK_FREQ_1000MBPS, bpp),
+ 1,
+ to_pixel_rate(OG01A1B_LINK_FREQ_1000MBPS, bpp));
og01a1b->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
V4L2_CID_VBLANK,
og01a1b->cur_mode->vts_min -
@@ -554,7 +560,7 @@ static int og01a1b_init_controls(struct og01a1b *og01a1b)
og01a1b->cur_mode->vts_def -
og01a1b->cur_mode->height);
h_blank = to_pixels_per_line(og01a1b->cur_mode->hts,
- og01a1b->cur_mode->link_freq_index) -
+ og01a1b->cur_mode->link_freq_index, bpp) -
og01a1b->cur_mode->width;
og01a1b->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
V4L2_CID_HBLANK, h_blank, h_blank,
@@ -594,7 +600,6 @@ static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,
{
fmt->width = mode->width;
fmt->height = mode->height;
- fmt->code = MEDIA_BUS_FMT_Y10_1X10;
fmt->field = V4L2_FIELD_NONE;
}
@@ -627,6 +632,14 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
return ret;
}
+ ret = cci_write(og01a1b->regmap, CCI_REG8(0x3662),
+ (og01a1b->code == MEDIA_BUS_FMT_Y10_1X10 ? 0x4 : 0x6),
+ NULL);
+ if (ret) {
+ dev_err(og01a1b->dev, "failed to set output format: %d\n", ret);
+ return ret;
+ }
+
ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
if (ret)
goto error;
@@ -669,7 +682,7 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
{
struct og01a1b *og01a1b = to_og01a1b(sd);
const struct og01a1b_mode *mode;
- s32 vblank_def, h_blank;
+ s32 vblank_def, h_blank, bpp;
mode = v4l2_find_nearest_size(supported_modes,
ARRAY_SIZE(supported_modes), width,
@@ -677,26 +690,30 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
fmt->format.height);
og01a1b_update_pad_format(mode, &fmt->format);
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
- } else {
- og01a1b->cur_mode = mode;
- __v4l2_ctrl_s_ctrl(og01a1b->link_freq, mode->link_freq_index);
- __v4l2_ctrl_s_ctrl_int64(og01a1b->pixel_rate,
- to_pixel_rate(mode->link_freq_index));
-
- /* Update limits and set FPS to default */
- vblank_def = mode->vts_def - mode->height;
- __v4l2_ctrl_modify_range(og01a1b->vblank,
- mode->vts_min - mode->height,
- OG01A1B_VTS_MAX - mode->height, 1,
- vblank_def);
- __v4l2_ctrl_s_ctrl(og01a1b->vblank, vblank_def);
- h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
- mode->width;
- __v4l2_ctrl_modify_range(og01a1b->hblank, h_blank, h_blank, 1,
- h_blank);
- }
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+ goto set_format;
+
+ bpp = (fmt->format.code == MEDIA_BUS_FMT_Y10_1X10 ? 10 : 8);
+ __v4l2_ctrl_s_ctrl(og01a1b->link_freq, mode->link_freq_index);
+ __v4l2_ctrl_s_ctrl_int64(og01a1b->pixel_rate,
+ to_pixel_rate(mode->link_freq_index, bpp));
+
+ /* Update limits and set FPS to default */
+ vblank_def = mode->vts_def - mode->height;
+ __v4l2_ctrl_modify_range(og01a1b->vblank,
+ mode->vts_min - mode->height,
+ OG01A1B_VTS_MAX - mode->height, 1, vblank_def);
+ __v4l2_ctrl_s_ctrl(og01a1b->vblank, vblank_def);
+ h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index,
+ bpp) - mode->width;
+ __v4l2_ctrl_modify_range(og01a1b->hblank, h_blank, h_blank, 1, h_blank);
+
+ og01a1b->cur_mode = mode;
+ og01a1b->code = fmt->format.code;
+
+set_format:
+ *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
return 0;
}
@@ -705,10 +722,10 @@ static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
- if (code->index > 0)
+ if (code->index > ARRAY_SIZE(og01a1b_mbus_formats) - 1)
return -EINVAL;
- code->code = MEDIA_BUS_FMT_Y10_1X10;
+ code->code = og01a1b_mbus_formats[code->index];
return 0;
}
@@ -720,7 +737,8 @@ static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
+ if (fse->code != MEDIA_BUS_FMT_Y10_1X10 &&
+ fse->code != MEDIA_BUS_FMT_Y8_1X8)
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
@@ -741,7 +759,7 @@ static int og01a1b_init_state(struct v4l2_subdev *sd,
.format = {
.width = og01a1b->cur_mode->width,
.height = og01a1b->cur_mode->height,
- .code = MEDIA_BUS_FMT_Y10_1X10,
+ .code = og01a1b->code,
},
};
@@ -1032,6 +1050,7 @@ static int og01a1b_probe(struct i2c_client *client)
}
og01a1b->cur_mode = &supported_modes[0];
+ og01a1b->code = og01a1b_mbus_formats[0];
ret = og01a1b_init_controls(og01a1b);
if (ret) {
dev_err(og01a1b->dev, "failed to init controls: %d", ret);
--
2.49.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-02-26 13:37 ` [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format Vladimir Zapolskiy
@ 2026-03-09 11:55 ` Sakari Ailus
2026-03-09 21:56 ` Vladimir Zapolskiy
0 siblings, 1 reply; 12+ messages in thread
From: Sakari Ailus @ 2026-03-09 11:55 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Mauro Carvalho Chehab, Hans Verkuil, Shawn Tu, linux-media
Hi Vladimir,
Thanks for the set.
On Thu, Feb 26, 2026 at 03:37:39PM +0200, Vladimir Zapolskiy wrote:
> @@ -627,6 +632,14 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
> return ret;
> }
>
> + ret = cci_write(og01a1b->regmap, CCI_REG8(0x3662),
> + (og01a1b->code == MEDIA_BUS_FMT_Y10_1X10 ? 0x4 : 0x6),
Does this configuration have a human-readable name? It'd be nice to use
that instead of a plain numerical value.
> + NULL);
> + if (ret) {
> + dev_err(og01a1b->dev, "failed to set output format: %d\n", ret);
> + return ret;
> + }
> +
> ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
> if (ret)
> goto error;
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-03-09 11:55 ` Sakari Ailus
@ 2026-03-09 21:56 ` Vladimir Zapolskiy
2026-03-10 8:03 ` Sakari Ailus
2026-03-10 11:08 ` Sakari Ailus
0 siblings, 2 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-03-09 21:56 UTC (permalink / raw)
To: Sakari Ailus; +Cc: Mauro Carvalho Chehab, Hans Verkuil, Shawn Tu, linux-media
Hi Sakari,
thank you for your review.
On 3/9/26 13:55, Sakari Ailus wrote:
> Hi Vladimir,
>
> Thanks for the set.
>
> On Thu, Feb 26, 2026 at 03:37:39PM +0200, Vladimir Zapolskiy wrote:
>> @@ -627,6 +632,14 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
>> return ret;
>> }
>>
>> + ret = cci_write(og01a1b->regmap, CCI_REG8(0x3662),
>> + (og01a1b->code == MEDIA_BUS_FMT_Y10_1X10 ? 0x4 : 0x6),
>
> Does this configuration have a human-readable name? It'd be nice to use
> that instead of a plain numerical value.
>
If it has, it's not known to me, unfortunately, I cannot add a meaningful
symbol name here...
The 0x3662 register is one of many analog control registers, the upstream
OmniVision OV9282 sensor driver shares a hint that BIT(1) of the register
changes the media bus mode from Y10 to Y8, and due to my tests it's right
the same for this one OmniVision OG01A1B sensor, thus it allows me to add
Y8 support to the driver.
>> + NULL);
>> + if (ret) {
>> + dev_err(og01a1b->dev, "failed to set output format: %d\n", ret);
>> + return ret;
>> + }
>> +
>> ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
>> if (ret)
>> goto error;
>
--
Best wishes,
Vladimir
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-03-09 21:56 ` Vladimir Zapolskiy
@ 2026-03-10 8:03 ` Sakari Ailus
2026-03-10 11:08 ` Sakari Ailus
1 sibling, 0 replies; 12+ messages in thread
From: Sakari Ailus @ 2026-03-10 8:03 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Mauro Carvalho Chehab, Hans Verkuil, Shawn Tu, linux-media
Hi Vladimir,
On Mon, Mar 09, 2026 at 11:56:03PM +0200, Vladimir Zapolskiy wrote:
> Hi Sakari,
>
> thank you for your review.
>
> On 3/9/26 13:55, Sakari Ailus wrote:
> > Hi Vladimir,
> >
> > Thanks for the set.
> >
> > On Thu, Feb 26, 2026 at 03:37:39PM +0200, Vladimir Zapolskiy wrote:
> > > @@ -627,6 +632,14 @@ static int og01a1b_enable_streams(struct v4l2_subdev *sd,
> > > return ret;
> > > }
> > > + ret = cci_write(og01a1b->regmap, CCI_REG8(0x3662),
> > > + (og01a1b->code == MEDIA_BUS_FMT_Y10_1X10 ? 0x4 : 0x6),
> >
> > Does this configuration have a human-readable name? It'd be nice to use
> > that instead of a plain numerical value.
> >
>
> If it has, it's not known to me, unfortunately, I cannot add a meaningful
> symbol name here...
>
> The 0x3662 register is one of many analog control registers, the upstream
> OmniVision OV9282 sensor driver shares a hint that BIT(1) of the register
> changes the media bus mode from Y10 to Y8, and due to my tests it's right
> the same for this one OmniVision OG01A1B sensor, thus it allows me to add
> Y8 support to the driver.
Could you post a patch that adds a comment along the lines above? I'll take
this set now.
--
Kind regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-03-09 21:56 ` Vladimir Zapolskiy
2026-03-10 8:03 ` Sakari Ailus
@ 2026-03-10 11:08 ` Sakari Ailus
2026-03-10 13:12 ` Vladimir Zapolskiy
1 sibling, 1 reply; 12+ messages in thread
From: Sakari Ailus @ 2026-03-10 11:08 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Mauro Carvalho Chehab, Hans Verkuil, Shawn Tu, linux-media
On Mon, Mar 09, 2026 at 11:56:03PM +0200, Vladimir Zapolskiy wrote:
> Hi Sakari,
>
> thank you for your review.
I fixed a few issues on error path of enable_streams callback while
applying the set , no need to resend.
--
Sakari Ailus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format
2026-03-10 11:08 ` Sakari Ailus
@ 2026-03-10 13:12 ` Vladimir Zapolskiy
0 siblings, 0 replies; 12+ messages in thread
From: Vladimir Zapolskiy @ 2026-03-10 13:12 UTC (permalink / raw)
To: Sakari Ailus; +Cc: Mauro Carvalho Chehab, Hans Verkuil, Shawn Tu, linux-media
Hi Sakari,
On 3/10/26 13:08, Sakari Ailus wrote:
> On Mon, Mar 09, 2026 at 11:56:03PM +0200, Vladimir Zapolskiy wrote:
>> Hi Sakari,
>>
>> thank you for your review.
>
> I fixed a few issues on error path of enable_streams callback while
> applying the set , no need to resend.
>
I appreciate the review and improvements, thank you so much!
--
Best wishes,
Vladimir
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-03-10 13:12 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-26 13:37 [PATCH 0/6] media: i2c: og01a1b: Updates to the driver and 8-bit mode support Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 1/6] media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 2/6] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 3/6] media: i2c: og01a1b: Change I2C interface controls to V4L2 CCI Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 4/6] media: i2c: og01a1b: Replace .open with .init_state internal ops Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 5/6] media: i2c: og01a1b: Use generic v4l2_subdev_get_fmt() to get format Vladimir Zapolskiy
2026-02-26 13:37 ` [PATCH 6/6] media: i2c: og01a1b: Add support of 8-bit media bus format Vladimir Zapolskiy
2026-03-09 11:55 ` Sakari Ailus
2026-03-09 21:56 ` Vladimir Zapolskiy
2026-03-10 8:03 ` Sakari Ailus
2026-03-10 11:08 ` Sakari Ailus
2026-03-10 13:12 ` Vladimir Zapolskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox