public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver
@ 2024-10-28 19:06 Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Add a v4l2 subdevice driver for the Omnivision OX05B1S RGB-IR sensor

The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an active array size
of 2592 x 1944.
    
The following features are supported for OX05B1S:
- Manual exposure an gain control support
- vblank/hblank control support
- Supported resolution:
   - 2592 x 1944 @ 30fps (SGRBG10)

Support for another sensor, OS08A20, is added as a separate patch, using another compatible.
For OS08a20, HDR mode control is supported, with one HDR mode: staggered HDR with 2 exposures on separate virtual channels.
Supported resolutions:
   - 1920 x 1080 @ 60fps (SBGGR10, no HDR)
   - 1920 x 1080 @ 30fps (SBGGR10, HDR)
   - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
   - 3840 x 2160 @ 15fps (SBGGR10, HDR)
   - 3840 x 2160 @ 15fps (SBGGR12, HDR)
   - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
   - 3840 x 2160 @ 30fps (SBGGR10, no HDR)

The driver was tested on upstream 6.12-rc1 on imx8mp-evk, but also on nxp tree based on 6.11-rc7 on imx95-19x19-evk.

The results of v4l2-compliance test:

root@imx8mpevk:/unit_tests# ./v4l2-compliance -d /dev/video0
v4l2-compliance 1.29.0-5251, 64 bits, 64-bit time_t
v4l2-compliance SHA: 2e7492386e6e 2024-10-03 13:49:10

Compliance test for mxc-isi device /dev/video0:

Driver Info:
	Driver name      : mxc-isi
	Card type        : mxc-isi-cap
	Bus info         : platform:32e00000.isi
	Driver version   : 6.12.0
	Capabilities     : 0xa4201000
		Video Capture Multiplanar
		I/O MC
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x24201000
		Video Capture Multiplanar
		I/O MC
		Streaming
		Extended Pix Format
Media Driver Info:
	Driver name      : mxc-isi
	Model            : FSL Capture Media Device
	Serial           : 
	Bus info         : platform:32e00000.isi
	Media version    : 6.12.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 6.12.0
Interface Info:
	ID               : 0x0300000c
	Type             : V4L Video
Entity Info:
	ID               : 0x0000000a (10)
	Name             : mxc_isi.0.capture
	Function         : V4L2 I/O
	Pad 0x0100000b   : 0: Sink
	  Link 0x0200000e: from remote pad 0x1000009 of entity 'mxc_isi.0' (Video Pixel Formatter): Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video0 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Input 0):
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 4 Private Controls: 0

Format ioctls (Input 0):
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK (Not Supported)
	test Scaling: OK

Codec ioctls (Input 0):
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test CREATE_BUFS maximum buffers: OK
	test VIDIOC_REMOVE_BUFS: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)
	test blocking wait: OK

Total for mxc-isi device /dev/video0: 49, Succeeded: 49, Failed: 0, Warnings: 0


Mirela Rabulea (5):
  dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  media: ox05b1s: Add omnivision OX05B1S raw sensor driver
  MAINTAINERS: Add entry for OX05B1S sensor driver
  dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20
  media: ox05b1s: Add support for Omnivision OS08A20 raw sensor

 .../bindings/media/i2c/ovti,ox05b1s.yaml      |  110 ++
 MAINTAINERS                                   |   10 +
 drivers/media/i2c/Kconfig                     |    1 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/ox05b1s/Kconfig             |   10 +
 drivers/media/i2c/ox05b1s/Makefile            |    2 +
 .../media/i2c/ox05b1s/os08a20_regs_1080p.h    |  201 +++
 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h   |  209 +++
 .../media/i2c/ox05b1s/os08a20_regs_4k_hdr.h   |  199 +++
 drivers/media/i2c/ox05b1s/ox05b1s_mipi.c      | 1145 ++++++++++++++++
 drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h  | 1160 +++++++++++++++++
 11 files changed, 3048 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
 create mode 100644 drivers/media/i2c/ox05b1s/Kconfig
 create mode 100644 drivers/media/i2c/ox05b1s/Makefile
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
 create mode 100644 drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
 create mode 100644 drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
@ 2024-10-28 19:06 ` Mirela Rabulea
  2024-10-29  6:14   ` Krzysztof Kozlowski
  2024-10-29 11:44   ` Bryan O'Donoghue
  2024-10-28 19:06 ` [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw " Mirela Rabulea
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Add bindings for OX05B1S sensor driver

Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
 .../bindings/media/i2c/ovti,ox05b1s.yaml      | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
new file mode 100644
index 000000000000..d47e1950f24d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2024, NXP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ovti,ox05b1s.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Omnivision OX05B1S Image Sensor
+
+maintainers:
+  - Mirela Rabulea <mirela.rabulea@nxp.com>
+
+description: |-
+  The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an active array size
+  of 2592 x 1944. It is programmable through I2C interface.
+  The sensor output is available via CSI-2 serial data output.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ovti,ox05b1s
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    description: Input clock (24 MHz)
+    items:
+      - const: csi_mclk
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clock-parents:
+    maxItems: 1
+
+  assigned-clock-rates:
+    maxItems: 1
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the XSHUTDOWN pin. Active low.
+    maxItems: 1
+
+  orientation: true
+  rotation: true
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+    description: MIPI CSI-2 transmitter port
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            anyOf:
+              - items:
+                  - const: 1
+                  - const: 2
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+        required:
+          - data-lanes
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        ox05b1s: ox05b1s@36 {
+            compatible = "ovti,ox05b1s";
+            reg = <0x36>;
+            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;
+            orientation = <2>;
+            rotation = <0>;
+            status = "okay";
+
+            port {
+                ox05b1s_mipi_0_ep: endpoint {
+                    remote-endpoint = <&mipi_csi0_ep>;
+                    data-lanes = <1 2 3 4>;
+                };
+            };
+        };
+    };
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw sensor driver
  2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
@ 2024-10-28 19:06 ` Mirela Rabulea
  2024-10-29  6:17   ` Krzysztof Kozlowski
  2024-10-28 19:06 ` [PATCH 3/5] MAINTAINERS: Add entry for OX05B1S " Mirela Rabulea
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Add a v4l2 subdevice driver for the Omnivision OX05B1S RGB-IR sensor.

The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an
active array size of 2592 x 1944.

The following features are supported for OX05B1S:
- Manual exposure an gain control support
- vblank/hblank control support
- Supported resolution: 2592 x 1944 @ 30fps (SGRBG10)

Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
 drivers/media/i2c/Kconfig                    |    1 +
 drivers/media/i2c/Makefile                   |    1 +
 drivers/media/i2c/ox05b1s/Kconfig            |   10 +
 drivers/media/i2c/ox05b1s/Makefile           |    2 +
 drivers/media/i2c/ox05b1s/ox05b1s_mipi.c     |  956 +++++++++++++++
 drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h | 1160 ++++++++++++++++++
 6 files changed, 2130 insertions(+)
 create mode 100644 drivers/media/i2c/ox05b1s/Kconfig
 create mode 100644 drivers/media/i2c/ox05b1s/Makefile
 create mode 100644 drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
 create mode 100644 drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 8ba096b8ebca..5cda062c0463 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -700,6 +700,7 @@ config VIDEO_VGXY61
 
 source "drivers/media/i2c/ccs/Kconfig"
 source "drivers/media/i2c/et8ek8/Kconfig"
+source "drivers/media/i2c/ox05b1s/Kconfig"
 
 endif
 
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index fbb988bd067a..028eb08e648c 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -114,6 +114,7 @@ obj-$(CONFIG_VIDEO_OV9282) += ov9282.o
 obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
+obj-$(CONFIG_VIDEO_OX05B1S) += ox05b1s/
 obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o
 obj-$(CONFIG_VIDEO_RDACM21) += rdacm21.o
 obj-$(CONFIG_VIDEO_RJ54N1) += rj54n1cb0c.o
diff --git a/drivers/media/i2c/ox05b1s/Kconfig b/drivers/media/i2c/ox05b1s/Kconfig
new file mode 100644
index 000000000000..48fcd04b20d5
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/Kconfig
@@ -0,0 +1,10 @@
+config VIDEO_OX05B1S
+	tristate "OmniVision raw sensor support OX05B1S"
+	depends on OF
+	depends on GPIOLIB
+	select REGMAP_I2C
+	help
+	  This is a Video4Linux2 sensor driver for the Omnivision OX05B1S RGB-IR sensor.
+	  This is a 1/2.5-Inch CMOS image sensor with an active array size of 2592 x 1944.
+	  It is programmable through I2C interface.
+	  The output is on MIPI CSI-2 interface.
diff --git a/drivers/media/i2c/ox05b1s/Makefile b/drivers/media/i2c/ox05b1s/Makefile
new file mode 100644
index 000000000000..8b57974fd1b5
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/Makefile
@@ -0,0 +1,2 @@
+ox05b1s-objs := ox05b1s_mipi.o
+obj-$(CONFIG_VIDEO_OX05B1S) += ox05b1s_mipi.o
diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
new file mode 100644
index 000000000000..5b9c069af19b
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
@@ -0,0 +1,956 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * A V4L2 driver for Omnivision OX05B1S RGB-IR camera.
+ * Copyright (C) 2024, NXP
+ *
+ * Inspired from Sony imx219, imx290, imx214 and imx334 camera drivers
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <media/mipi-csi2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OX05B1S_SENS_PAD_SOURCE	0
+#define OX05B1S_SENS_PADS_NUM	1
+
+#define OX05B1S_REG_SW_STB 0x0100
+#define OX05B1S_REG_SW_RST 0x0103
+#define OX05B1S_REG_CHIP_ID_23_16 0x300a
+#define OX05B1S_REG_CHIP_ID_15_8 0x300b
+#define OX05B1S_REG_CHIP_ID_7_0 0x300c
+#define OX05B1S_REG_TIMING_HTS_H 0x380c
+#define OX05B1S_REG_TIMING_HTS_L 0x380d
+#define OX05B1S_REG_TIMING_VTS_H 0x380e
+#define OX05B1S_REG_TIMING_VTS_L 0x380f
+#define OX05B1S_REG_EXPOSURE_H 0x3501
+#define OX05B1S_REG_EXPOSURE_L 0x3502
+#define OX05B1S_REG_GAIN_H 0x3508
+#define OX05B1S_REG_GAIN_L 0x3509
+
+#define client_to_ox05b1s(client)\
+	container_of(i2c_get_clientdata(client), struct ox05b1s, subdev)
+
+#define OX05B1S_MAX_SIZES 4
+struct ox05b1s_sizes {
+	u32	code;
+	u32	sizes_count;
+	u32	sizes[OX05B1S_MAX_SIZES][2];
+};
+
+struct ox05b1s_plat_data {
+	char				name[20];
+	u32				chip_id;
+	u32				native_width;
+	u32				native_height;
+	u32				active_top;
+	u32				active_left;
+	u32				active_width;
+	u32				active_height;
+	const struct ox05b1s_mode	*supported_modes;
+	u32				supported_modes_count;
+	u32				default_mode_index;
+	const struct ox05b1s_sizes	*supported_codes;
+	u32				supported_codes_count;
+};
+
+struct ox05b1s_ctrls {
+	struct v4l2_ctrl_handler handler;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *gain;
+	struct v4l2_ctrl *exposure;
+};
+
+struct ox05b1s_reg {
+	u32 addr;
+	u32 data;
+};
+
+#include "ox05b1s_regs_5mp.h"
+
+struct ox05b1s_mode {
+	u32 index;
+	u32 width;
+	u32 height;
+	u32 code;
+	u32 bpp;
+	u32 vts; /* default VTS */
+	u32 hts; /* default HTS */
+	u32 exp; /* max exposure */
+	bool h_bin; /* horizontal binning */
+	u32 fps;
+	struct ox05b1s_reg *reg_data;
+	u32 reg_data_count;
+};
+
+struct ox05b1s {
+	struct i2c_client *i2c_client;
+	struct regmap *regmap;
+	struct gpio_desc *rst_gpio;
+	struct clk *sensor_clk;
+	const struct ox05b1s_plat_data *model;
+	struct v4l2_subdev subdev;
+	struct media_pad pads[OX05B1S_SENS_PADS_NUM];
+	const struct ox05b1s_mode *mode;
+	struct mutex lock; /* sensor lock */
+	u32 stream_status;
+	struct ox05b1s_ctrls ctrls;
+};
+
+static struct ox05b1s_mode ox05b1s_supported_modes[] = {
+	{
+		.index		= 0,
+		.width		= 2592,
+		.height		= 1944,
+		.code		= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.bpp		= 10,
+		.vts		= 0x850,
+		.hts		= 0x2f0,
+		.exp		= 0x850 - 8,
+		.h_bin		= false,
+		.fps		= 30,
+		.reg_data	= ovx5b_init_setting_2592x1944,
+		.reg_data_count	= ARRAY_SIZE(ovx5b_init_setting_2592x1944),
+	},
+};
+
+/* keep in sync with ox05b1s_supported_modes*/
+static const struct ox05b1s_sizes ox05b1s_supported_codes[] = {
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.sizes_count = 1,
+		.sizes = { {2592, 1944} }
+	},
+};
+
+static const struct regmap_config ox05b1s_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int ox05b1s_power_on(struct ox05b1s *sensor)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	int ret = 0;
+
+	/* get out of powerdown and reset */
+	gpiod_set_value_cansleep(sensor->rst_gpio, 0);
+
+	ret = clk_prepare_enable(sensor->sensor_clk);
+	if (ret < 0)
+		dev_err(dev, "Enable sensor clk fail ret=%d\n", ret);
+
+	/* with XVCLK@24MHz, t2 = 6ms required delay for ox05b1s before first SCCB transaction */
+	fsleep(6000);
+
+	return ret;
+}
+
+static int ox05b1s_power_off(struct ox05b1s *sensor)
+{
+	gpiod_set_value_cansleep(sensor->rst_gpio, 1);
+
+	if (!sensor->sensor_clk)
+		return 0;
+
+	/* XVCLK must be active for 512 cycles (0.34 ms at 24MHz) after last SCCB transaction */
+	fsleep(350);
+	clk_disable_unprepare(sensor->sensor_clk);
+
+	return 0;
+}
+
+static int ox05b1s_runtime_suspend(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+
+	return ox05b1s_power_off(sensor);
+}
+
+static int ox05b1s_runtime_resume(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+
+	return ox05b1s_power_on(sensor);
+}
+
+static int ox05b1s_write_reg(struct ox05b1s *sensor, u16 reg, u8 val)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	int ret = 0;
+
+	ret = regmap_write(sensor->regmap, reg, val);
+	if (ret < 0)
+		dev_err(dev, "Failed to write reg addr 0x%04x with 0x%02x\n", reg, val);
+
+	return ret;
+}
+
+static int ox05b1s_read_reg(struct ox05b1s *sensor, u16 reg, u8 *val)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	int ret = 0;
+
+	ret = regmap_raw_read(sensor->regmap, reg, val, 1);
+	if (ret)
+		dev_err(dev, "Read reg error: reg=%x, val=%x\n", reg, *val);
+
+	return ret;
+}
+
+#define OX05B1S_MAX_REG_BULK 16
+static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
+				   struct ox05b1s_reg *reg_array,
+				   u32 size)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	struct ox05b1s_reg *table = reg_array;
+	u8 vals[OX05B1S_MAX_REG_BULK];
+	int i, j;
+	int ret;
+
+	for (j = 0; j < size; j++) {
+		table = &reg_array[j];
+		for (i = 0; i < OX05B1S_MAX_REG_BULK; i++) {
+			if (table[i].addr != (table[0].addr + i))
+				break;
+			vals[i] = table[i].data;
+		}
+		ret = regmap_bulk_write(sensor->regmap, table->addr, vals, i);
+		if (ret) {
+			dev_err(dev, "Failed to write reg addr=%x, count %d\n", table->addr, i);
+			return ret;
+		}
+		j += i - 1;
+	}
+
+	return 0;
+}
+
+static int ox05b1s_set_hts(struct ox05b1s *sensor, u32 hts)
+{
+	u8 values[2] = { (u8)(hts >> 8) & 0xff, (u8)(hts & 0xff) };
+
+	return regmap_bulk_write(sensor->regmap, OX05B1S_REG_TIMING_HTS_H, values, 2);
+}
+
+static int ox05b1s_set_vts(struct ox05b1s *sensor, u32 vts)
+{
+	u8 values[2] = { (u8)(vts >> 8) & 0xff, (u8)(vts & 0xff) };
+
+	return regmap_bulk_write(sensor->regmap, OX05B1S_REG_TIMING_VTS_H, values, 2);
+}
+
+static int ox05b1s_set_exp(struct ox05b1s *sensor, u32 exp)
+{
+	u8 values[2] = { (u8)(exp >> 8) & 0xff, (u8)(exp & 0xff) };
+
+	return regmap_bulk_write(sensor->regmap, OX05B1S_REG_EXPOSURE_H, values, 2);
+}
+
+static int ox05b1s_set_analog_gain(struct ox05b1s *sensor, u32 again)
+{
+	u8 values[2] = { (u8)(again >> 8) & 0xff, (u8)(again & 0xff) };
+
+	/* real gain */
+	return regmap_bulk_write(sensor->regmap, OX05B1S_REG_GAIN_H, values, 2);
+}
+
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct ox05b1s,
+			     ctrls.handler)->subdev;
+}
+
+static int ox05b1s_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	u32 w = sensor->mode->width;
+	u32 h = sensor->mode->height;
+	int ret = 0;
+
+	/* apply V4L2 controls values only if power is already up */
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	/* s_ctrl holds sensor lock */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		ret = ox05b1s_set_vts(sensor, h + ctrl->val);
+		break;
+	case V4L2_CID_HBLANK:
+		if (sensor->mode->h_bin)
+			ret = ox05b1s_set_hts(sensor, w + ctrl->val);
+		else
+			ret = ox05b1s_set_hts(sensor, (w + ctrl->val) / 2);
+		break;
+	case V4L2_CID_PIXEL_RATE:
+		/* Read-only, but we adjust it based on mode. */
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = ox05b1s_set_analog_gain(sensor, ctrl->val);
+		break;
+	case V4L2_CID_EXPOSURE:
+		ret = ox05b1s_set_exp(sensor, ctrl->val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ox05b1s_ctrl_ops = {
+	.s_ctrl = ox05b1s_s_ctrl,
+};
+
+/*
+ * MIPI CSI-2 link frequencies.
+ * link_freq = (pixel_rate * bpp) / (2 * data_lanes)
+ */
+static const s64 ox05b1s_csi2_link_freqs[] = {
+	200000000,
+};
+
+/* Link freq for default mode: 1080p RAW10, 4 data lanes 800 Mbps/lane. */
+#define OX05B1S_DEFAULT_LINK_FREQ	0
+
+static int ox05b1s_init_controls(struct ox05b1s *sensor)
+{
+	const struct v4l2_ctrl_ops *ops = &ox05b1s_ctrl_ops;
+	struct ox05b1s_ctrls *ctrls = &sensor->ctrls;
+	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+	struct device *dev = &sensor->i2c_client->dev;
+	struct v4l2_fwnode_device_properties props;
+	int ret;
+
+	v4l2_ctrl_handler_init(hdl, 7);
+
+	/* we can use our own mutex for the ctrl lock */
+	hdl->lock = &sensor->lock;
+
+	/* Clock related controls */
+	ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops,
+						  V4L2_CID_LINK_FREQ,
+						  ARRAY_SIZE(ox05b1s_csi2_link_freqs) - 1,
+						  OX05B1S_DEFAULT_LINK_FREQ,
+						  ox05b1s_csi2_link_freqs);
+
+	/* mode dependent, actual range set in ox05b1s_update_controls */
+	ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
+					      0, 0, 1, 0);
+
+	ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK,
+					  0, 0, 1, 0);
+
+	ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK,
+					  0, 0, 1, 0);
+
+	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+					    0, 0, 1, 0);
+
+	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
+					0, 0xFFFF, 1, 0x80);
+
+	if (hdl->error) {
+		ret = hdl->error;
+		goto free_ctrls;
+	}
+
+	ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	ret = v4l2_fwnode_device_parse(dev, &props);
+	if (ret)
+		goto free_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &props);
+	if (ret)
+		goto free_ctrls;
+
+	sensor->subdev.ctrl_handler = hdl;
+	return 0;
+
+free_ctrls:
+	dev_err(dev, "Failed to init controls\n");
+	v4l2_ctrl_handler_free(hdl);
+	return ret;
+}
+
+static int ox05b1s_apply_current_mode(struct ox05b1s *sensor);
+
+static int ox05b1s_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	int ret = 0;
+
+	if (enable) {
+		ret = pm_runtime_resume_and_get(&client->dev);
+		if (ret < 0)
+			return ret;
+		ret = ox05b1s_apply_current_mode(sensor);
+		if (!ret)
+			ret = ox05b1s_write_reg(sensor, OX05B1S_REG_SW_STB, 0x01);
+	} else {
+		ret = ox05b1s_write_reg(sensor, OX05B1S_REG_SW_STB, 0x00);
+	}
+
+	sensor->stream_status = enable;
+
+	if (!enable || ret) {
+		pm_runtime_mark_last_busy(&sensor->i2c_client->dev);
+		pm_runtime_put_autosuspend(&client->dev);
+	}
+
+	return 0;
+}
+
+static void ox05b1s_update_pad_format(struct ox05b1s *sensor,
+				      const struct ox05b1s_mode *mode,
+				      struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->code = mode->code;
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = V4L2_COLORSPACE_RAW;
+	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int ox05b1s_init_state(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	struct v4l2_mbus_framefmt *format;
+
+	/* Initialize the format. */
+	format = v4l2_subdev_state_get_format(state, 0);
+	ox05b1s_update_pad_format(sensor, &sensor->model->supported_modes[0], format);
+
+	return 0;
+}
+
+static int ox05b1s_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+
+	if (code->index >= sensor->model->supported_codes_count)
+		return -EINVAL;
+
+	code->code = sensor->model->supported_codes[code->index].code;
+
+	return 0;
+}
+
+static int ox05b1s_enum_frame_size(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *sd_state,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	const struct ox05b1s_sizes *frame_sizes = NULL;
+	int i;
+
+	if (fse->pad != 0)
+		return -EINVAL;
+
+	for (i = 0; i < sensor->model->supported_codes_count; i++) {
+		if (sensor->model->supported_codes[i].code == fse->code) {
+			frame_sizes = &sensor->model->supported_codes[i];
+			break;
+		}
+	}
+
+	if (!frame_sizes || fse->index >= frame_sizes->sizes_count)
+		return -EINVAL;
+
+	fse->min_width = frame_sizes->sizes[fse->index][0];
+	fse->max_width = fse->min_width;
+	fse->min_height = frame_sizes->sizes[fse->index][1];
+	fse->max_height = fse->min_height;
+
+	return 0;
+}
+
+/* Update control ranges based on current streaming mode, needs sensor lock */
+static int ox05b1s_update_controls(struct ox05b1s *sensor)
+{
+	int ret;
+	struct device *dev = &sensor->i2c_client->dev;
+	u32 hts = sensor->mode->hts;
+	u32 hblank;
+	u32 vts = sensor->mode->vts;
+	u32 vblank = vts - sensor->mode->height;
+	u32 fps = sensor->mode->fps;
+	u64 pixel_rate = (sensor->mode->h_bin) ? hts * vts * fps : 2 * hts * vts * fps;
+	u32 min_exp = 8;
+	u32 max_exp = vts - 8;
+
+	ret = __v4l2_ctrl_modify_range(sensor->ctrls.pixel_rate, pixel_rate,
+				       pixel_rate, 1, pixel_rate);
+	if (ret) {
+		dev_err(dev, "Modify range for ctrl: pixel_rate %llu-%llu failed\n",
+			pixel_rate, pixel_rate);
+		goto out;
+	}
+
+	if (sensor->mode->h_bin)
+		hblank = hts - sensor->mode->width;
+	else
+		hblank = 2 * hts - sensor->mode->width;
+
+	ret = __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank,
+				       1, hblank);
+	if (ret) {
+		dev_err(dev, "Modify range for ctrl: hblank %u-%u failed\n",
+			hblank, hblank);
+		goto out;
+	}
+	__v4l2_ctrl_s_ctrl(sensor->ctrls.hblank, sensor->ctrls.hblank->default_value);
+
+	ret = __v4l2_ctrl_modify_range(sensor->ctrls.vblank, 0, vblank * 4,
+				       1, vblank);
+	if (ret) {
+		dev_err(dev, "Modify range for ctrl: vblank %u-%u failed\n",
+			vblank, vblank);
+		goto out;
+	}
+	__v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, sensor->ctrls.vblank->default_value);
+
+	ret = __v4l2_ctrl_modify_range(sensor->ctrls.exposure, min_exp, max_exp,
+				       1, max_exp / 2);
+	if (ret) {
+		dev_err(dev, "Modify range for ctrl: exposure %u-%u failed\n",
+			min_exp, max_exp);
+		goto out;
+	}
+	__v4l2_ctrl_s_ctrl(sensor->ctrls.exposure, sensor->ctrls.exposure->default_value);
+
+out:
+	return ret;
+}
+
+/* needs sensor lock and power on */
+static int ox05b1s_apply_current_mode(struct ox05b1s *sensor)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	struct ox05b1s_reg *reg_data = NULL;
+	int ret = 0;
+
+	ox05b1s_write_reg(sensor, OX05B1S_REG_SW_RST, 0x01);
+
+	reg_data = sensor->mode->reg_data;
+	ret = ox05b1s_write_reg_array(sensor, reg_data,
+				      sensor->mode->reg_data_count);
+	if (ret)
+		goto out;
+
+	/* setup handler will write actual controls into sensor registers */
+	ret =  __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+
+out:
+	if (ret < 0)
+		dev_err(dev, "Failed to apply mode %dx%d,bpp=%d\n", sensor->mode->width,
+			sensor->mode->height, sensor->mode->bpp);
+
+	return ret;
+}
+
+/* similar with v4l2_find_nearest_size but filter for mbus code, needs sensor lock */
+static const struct ox05b1s_mode *ox05b1s_nearest_size(const struct ox05b1s_mode *supported_modes,
+						       u32 supported_modes_count,
+						       struct v4l2_subdev_format *fmt)
+{
+	u32 error, min_error = U32_MAX;
+	const struct ox05b1s_mode *best = NULL;
+	unsigned int i;
+
+	if (!supported_modes)
+		return NULL;
+
+	for (i = 0; i < supported_modes_count; i++) {
+		const u32 w = supported_modes[i].width;
+		const u32 h = supported_modes[i].height;
+
+		if (supported_modes[i].code != fmt->format.code)
+			continue;
+
+		error = abs(w - fmt->format.width) + abs(h - fmt->format.height);
+		if (error > min_error)
+			continue;
+
+		min_error = error;
+		best = &supported_modes[i];
+		if (!error)
+			break;
+	}
+
+	return best;
+}
+
+/* get a valid mbus code for the model, either the requested one or the default one */
+static u32 ox05b1s_find_code(const struct ox05b1s_plat_data *model, u32 code)
+{
+	u32 found_code = 0;
+	unsigned int i;
+
+	for (i = 0; i < model->supported_codes_count; i++) {
+		if (model->supported_codes[i].code == code) {
+			found_code = code;
+			break;
+		}
+	}
+
+	if (!found_code)
+		found_code = model->supported_codes[model->default_mode_index].code;
+
+	return found_code;
+}
+
+static int ox05b1s_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *state,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	struct device *dev = &sensor->i2c_client->dev;
+	struct v4l2_mbus_framefmt *format;
+	const struct ox05b1s_mode *mode;
+
+	/* if no matching mbus code is found, use the one from the default mode */
+	fmt->format.code = ox05b1s_find_code(sensor->model, fmt->format.code);
+	mode = ox05b1s_nearest_size(sensor->model->supported_modes,
+				    sensor->model->supported_modes_count, fmt);
+
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		format = v4l2_subdev_state_get_format(state, 0);
+		*format = fmt->format;
+		return 0;
+	}
+
+	sensor->mode = mode;
+
+	/* update controls that depend on current mode */
+	ox05b1s_update_controls(sensor);
+
+	dev_dbg(dev, "Set mode index=%d, %d x %d, code=0x%x\n", sensor->mode->index,
+		fmt->format.width, fmt->format.height, fmt->format.code);
+
+	return 0;
+}
+
+static u8 ox05b1s_code2dt(const u32 code)
+{
+	switch (code) {
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+		return MIPI_CSI2_DT_RAW10;
+	default:
+		return MIPI_CSI2_DT_RAW10;
+	}
+}
+
+static int ox05b1s_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				  struct v4l2_mbus_frame_desc *fd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+	fd->num_entries = 1;
+
+	/* get sensor current code*/
+	mutex_lock(&sensor->lock);
+	fd->entry[0].pixelcode = sensor->mode->code;
+	mutex_unlock(&sensor->lock);
+
+	fd->entry[0].bus.csi2.vc = 0;
+	fd->entry[0].bus.csi2.dt = ox05b1s_code2dt(fd->entry[0].pixelcode);
+
+	return 0;
+}
+
+static int ox05b1s_get_selection(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_selection *sel)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = sensor->model->native_width;
+		sel->r.height = sensor->model->native_height;
+		return 0;
+	case V4L2_SEL_TGT_CROP:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		sel->r.top = sensor->model->active_top;
+		sel->r.left = sensor->model->active_left;
+		sel->r.width = sensor->model->active_width;
+		sel->r.height = sensor->model->active_height;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static const struct v4l2_subdev_video_ops ox05b1s_subdev_video_ops = {
+	.s_stream = ox05b1s_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ox05b1s_subdev_pad_ops = {
+	.set_fmt		= ox05b1s_set_fmt,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.get_frame_desc		= ox05b1s_get_frame_desc,
+	.enum_mbus_code		= ox05b1s_enum_mbus_code,
+	.enum_frame_size	= ox05b1s_enum_frame_size,
+	.get_selection		= ox05b1s_get_selection,
+};
+
+static const struct v4l2_subdev_ops ox05b1s_subdev_ops = {
+	.video = &ox05b1s_subdev_video_ops,
+	.pad   = &ox05b1s_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops ox05b1s_internal_ops = {
+	.init_state = ox05b1s_init_state,
+};
+
+static void ox05b1s_get_gpios(struct ox05b1s *sensor)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+
+	sensor->rst_gpio = devm_gpiod_get_optional(dev, "reset",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->rst_gpio))
+		dev_warn(dev, "No sensor reset pin available");
+}
+
+static int ox05b1s_read_chip_id(struct ox05b1s *sensor)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	u32 chip_id = 0;
+	u8 reg_val = 0;
+	char *camera_name;
+	int ret = 0;
+
+	ret = ox05b1s_read_reg(sensor, OX05B1S_REG_CHIP_ID_23_16, &reg_val);
+	chip_id |= reg_val << 16;
+	ret |= ox05b1s_read_reg(sensor, OX05B1S_REG_CHIP_ID_15_8, &reg_val);
+	chip_id |= reg_val << 8;
+	ret |= ox05b1s_read_reg(sensor, OX05B1S_REG_CHIP_ID_7_0, &reg_val);
+	chip_id |= reg_val;
+	if (ret) {
+		dev_err(dev, "Camera chip_id read error\n");
+		return -ENODEV;
+	}
+
+	switch (chip_id) {
+	case 0x580542:
+		camera_name = "ox05b1s";
+		break;
+	default:
+		camera_name = "unknown";
+		break;
+	}
+
+	if (chip_id == sensor->model->chip_id) {
+		dev_info(dev, "Camera %s detected, chip_id=%x\n", camera_name, chip_id);
+	} else {
+		dev_err(dev, "Detected %s camera (chip_id=%x), but expected %s (chip_id=%x)\n",
+			camera_name, chip_id, sensor->model->name, sensor->model->chip_id);
+		ret = -ENODEV;
+	}
+
+	return ret;
+}
+
+static int ox05b1s_probe(struct i2c_client *client)
+{
+	int retval;
+	struct device *dev = &client->dev;
+	struct v4l2_subdev *sd;
+	struct ox05b1s *sensor;
+
+	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+	if (!sensor)
+		return -ENOMEM;
+
+	sensor->regmap = devm_regmap_init_i2c(client, &ox05b1s_regmap_config);
+	if (IS_ERR(sensor->regmap)) {
+		dev_err(dev, "Failed to allocate sensor register map\n");
+		return PTR_ERR(sensor->regmap);
+	}
+
+	sensor->i2c_client = client;
+
+	sensor->model = of_device_get_match_data(dev);
+
+	ox05b1s_get_gpios(sensor);
+
+	sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
+	if (IS_ERR(sensor->sensor_clk)) {
+		sensor->sensor_clk = NULL;
+		dev_warn(dev, "Sensor csi_mclk is missing, using oscillator from sensor module\n");
+	}
+
+	sd = &sensor->subdev;
+	v4l2_i2c_subdev_init(sd, client, &ox05b1s_subdev_ops);
+	sd->internal_ops = &ox05b1s_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	sd->dev = &client->dev;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	sensor->pads[OX05B1S_SENS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	retval = media_entity_pads_init(&sd->entity, OX05B1S_SENS_PADS_NUM,
+					sensor->pads);
+	if (retval)
+		goto probe_out;
+
+	mutex_init(&sensor->lock);
+
+	retval = ox05b1s_init_controls(sensor);
+	if (retval)
+		goto probe_err_entity_cleanup;
+
+	/* power on manually */
+	retval = ox05b1s_power_on(sensor);
+	if (retval) {
+		dev_err(dev, "Failed to power on\n");
+		goto probe_err_free_ctrls;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_enable(dev);
+
+	retval = ox05b1s_read_chip_id(sensor);
+	if (retval)
+		goto probe_err_pm_runtime;
+
+	v4l2_i2c_subdev_set_name(sd, client, sensor->model->name, NULL);
+
+	/* Centrally managed subdev active state */
+	sd->state_lock = &sensor->lock;
+	retval = v4l2_subdev_init_finalize(sd);
+	if (retval < 0) {
+		dev_err(dev, "Subdev init error: %d\n", retval);
+		goto probe_err_pm_runtime;
+	}
+
+	retval = v4l2_async_register_subdev_sensor(sd);
+	if (retval < 0) {
+		dev_err(&client->dev, "Async register failed, ret=%d\n", retval);
+		goto probe_err_subdev_cleanup;
+	}
+
+	sensor->mode = &sensor->model->supported_modes[0];
+	ox05b1s_update_controls(sensor);
+
+	pm_runtime_set_autosuspend_delay(dev, 1000);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return 0;
+
+probe_err_subdev_cleanup:
+	v4l2_subdev_cleanup(sd);
+probe_err_pm_runtime:
+	pm_runtime_put_noidle(dev);
+	pm_runtime_disable(dev);
+	ox05b1s_runtime_suspend(dev);
+probe_err_free_ctrls:
+	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+probe_err_entity_cleanup:
+	media_entity_cleanup(&sd->entity);
+probe_out:
+	return retval;
+}
+
+static void ox05b1s_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ox05b1s *sensor = client_to_ox05b1s(client);
+	struct device *dev = &client->dev;
+
+	pm_runtime_disable(dev);
+	if (!pm_runtime_status_suspended(dev))
+		ox05b1s_runtime_suspend(dev);
+	pm_runtime_set_suspended(dev);
+	v4l2_async_unregister_subdev(sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+	mutex_destroy(&sensor->lock);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(ox05b1s_pm_ops, ox05b1s_runtime_suspend,
+				 ox05b1s_runtime_resume, NULL);
+
+static const struct ox05b1s_plat_data ox05b1s_data = {
+	.name			= "ox05b1s",
+	.chip_id		= 0x580542,
+	.native_width		= 2608, /* 8 dummy + 2592 active pixels + 8 dummy */
+	.native_height		= 1960, /* 8 dummy + 1944 active lines + 8 dummy */
+	.active_top		= 8,
+	.active_left		= 8,
+	.active_width		= 2592,
+	.active_height		= 1944,
+	.supported_modes	= ox05b1s_supported_modes,
+	.supported_modes_count	= ARRAY_SIZE(ox05b1s_supported_modes),
+	.default_mode_index	= 0,
+	.supported_codes	= ox05b1s_supported_codes,
+	.supported_codes_count	= ARRAY_SIZE(ox05b1s_supported_codes),
+};
+
+static const struct of_device_id ox05b1s_of_match[] = {
+	{
+		.compatible = "ovti,ox05b1s",
+		.data = &ox05b1s_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ox05b1s_of_match);
+
+static struct i2c_driver ox05b1s_i2c_driver = {
+	.driver = {
+		.name  = "ox05b1s",
+		.pm = pm_ptr(&ox05b1s_pm_ops),
+		.of_match_table	= ox05b1s_of_match,
+	},
+	.probe	= ox05b1s_probe,
+	.remove = ox05b1s_remove,
+};
+
+module_i2c_driver(ox05b1s_i2c_driver);
+MODULE_DESCRIPTION("Omnivision OX05B1S MIPI Camera Subdev Driver");
+MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h b/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h
new file mode 100644
index 000000000000..3c34724c1d7e
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h
@@ -0,0 +1,1160 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A register configuration for Omnivision OX05B1S raw camera, 2592 x 1944 @30fps BGGR10
+ * Copyright (C) 2024, NXP
+ * Copyright (C) 2024, Omnivision
+ *
+ */
+#ifndef _OX05B1S_REGS_2592x1944_H_
+#define _OX05B1S_REGS_2592x1944_H_
+
+/* 2592X1944_30FPS_FULL_RGBIr 2592 1944 */
+static struct ox05b1s_reg ovx5b_init_setting_2592x1944[] = {
+	{0x0100, 0x00},
+	{0x0107, 0x01}, /* reserved */
+	{0x0104, 0x00},
+	{0x0301, 0x1a},
+	{0x0304, 0x01},
+	{0x0305, 0xe0},
+	{0x0306, 0x04},
+	{0x0307, 0x02}, /* reset 0x01 */
+	{0x0321, 0x03},
+	{0x0324, 0x01},
+	{0x0325, 0x80},
+	{0x0341, 0x03},
+	{0x0344, 0x01},
+	{0x0345, 0xb0},
+	{0x0347, 0x07},
+	{0x034a, 0x05}, /* reset 0x03 */
+	{0x034b, 0x06},
+	{0x0360, 0x80}, /* PLL_CTRL_REG60 bit7 mipi_enable */
+	{0x0400, 0xe8},
+	{0x0401, 0x00},
+	{0x0402, 0x2b},
+	{0x0403, 0x32},
+	{0x0404, 0x3a},
+	{0x0405, 0x00},
+	{0x0406, 0x0c},
+	{0x0407, 0xe8},
+	{0x0408, 0x00},
+	{0x0409, 0x2b},
+	{0x040a, 0x32},
+	{0x040b, 0x5c}, /* reset 0x30 */
+	{0x040c, 0xcd}, /* reset 0x00 */
+	{0x040d, 0x0c},
+	{0x040e, 0xe7},
+	{0x040f, 0xff},
+	{0x0410, 0x2b},
+	{0x0411, 0x32},
+	{0x0412, 0x33},
+	{0x0413, 0x8f},
+	{0x0414, 0x0c},
+	{0x2000, 0x04},
+	{0x2805, 0xff},
+	{0x2806, 0x0f},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x10},
+	{0x3004, 0x00},
+	{0x3009, 0x2e},
+	{0x3010, 0x41}, /* SC_CMMN_REG10 mipi_lane_num = 4, phy_mode = 1 */
+	{0x3015, 0xf0},
+	{0x3016, 0xf0},
+	{0x3017, 0xf0},
+	{0x3018, 0xf0}, /* SC_CMMN_REG18 */
+	{0x301a, 0x78},
+	{0x301b, 0xb4},
+	{0x301f, 0xe9},
+	{0x3024, 0x80},
+	{0x3039, 0x00},
+	{0x3044, 0x70},
+	{0x3101, 0x32},
+	{0x3182, 0x10},
+	{0x3187, 0xff},
+	{0x320a, 0x00},
+	{0x320b, 0x00},
+	{0x320c, 0x00},
+	{0x320d, 0x00},
+	{0x320e, 0x00},
+	{0x320f, 0x00},
+	{0x3211, 0x61},
+	{0x3212, 0x00},
+	{0x3215, 0xcc},
+	{0x3218, 0x06},
+	{0x3219, 0x08},
+	{0x3251, 0x00},
+	{0x3252, 0xe4},
+	{0x3253, 0x00},
+	{0x3304, 0x11},
+	{0x3305, 0x00},
+	{0x3306, 0x01},
+	{0x3307, 0x00},
+	{0x3308, 0x02},
+	{0x3309, 0x00},
+	{0x330a, 0x02},
+	{0x330b, 0x00},
+	{0x330c, 0x02},
+	{0x330d, 0x00},
+	{0x330e, 0x02},
+	{0x330f, 0x00},
+	{0x3310, 0x02},
+	{0x3311, 0x00},
+	{0x3312, 0x02},
+	{0x3313, 0x00},
+	{0x3314, 0x02},
+	{0x3315, 0x00},
+	{0x3316, 0x02},
+	{0x3317, 0x11},
+	{0x3400, 0x0c},
+	{0x3421, 0x00},
+	{0x3422, 0x00},
+	{0x3423, 0x00},
+	{0x3424, 0x00},
+	{0x3425, 0x00},
+	{0x3426, 0x00},
+	{0x3427, 0x00},
+	{0x3428, 0x00},
+	{0x3429, 0x40},
+	{0x342a, 0x55},
+	{0x342b, 0x05},
+	{0x342c, 0x00},
+	{0x342d, 0x00},
+	{0x342e, 0x00},
+	{0x3500, 0x00},
+	{0x3501, 0x00},
+	{0x3502, 0x08},
+	{0x3503, 0xa8},
+	{0x3504, 0x08},
+	{0x3505, 0x00},
+	{0x3506, 0x00},
+	{0x3507, 0x00},
+	{0x3508, 0x01},
+	{0x3509, 0x00},
+	{0x350a, 0x01},
+	{0x350b, 0x00},
+	{0x350c, 0x00},
+	{0x3541, 0x00},
+	{0x3542, 0x08},
+	{0x3603, 0x65},
+	{0x3604, 0x24},
+	{0x3608, 0x08},
+	{0x3610, 0x00},
+	{0x3612, 0x00},
+	{0x3619, 0x09},
+	{0x361a, 0x27},
+	{0x3620, 0x40},
+	{0x3622, 0x15},
+	{0x3623, 0x0e},
+	{0x3624, 0x1f},
+	{0x3625, 0x1f},
+	{0x362a, 0x01}, /* ANA_REG2A mipi_pk_0 */
+	{0x362b, 0x00}, /* ANA_REG2B mipi_pk_1 */
+	{0x3633, 0x88},
+	{0x3634, 0x86},
+	{0x3636, 0x80},
+	{0x3638, 0x3b},
+	{0x363a, 0x00},
+	{0x363b, 0x22},
+	{0x363c, 0x07},
+	{0x363d, 0x11},
+	{0x363e, 0x21},
+	{0x363f, 0x24},
+	{0x3640, 0xd3},
+	{0x3641, 0x00},
+	{0x3650, 0xe4},
+	{0x3651, 0x80},
+	{0x3652, 0xff},
+	{0x3653, 0x00},
+	{0x3654, 0x05},
+	{0x3655, 0xf8},
+	{0x3656, 0x00},
+	{0x3660, 0x00},
+	{0x3664, 0x00},
+	{0x366a, 0x80},
+	{0x366b, 0x00},
+	{0x3670, 0x00},
+	{0x3674, 0x00},
+	{0x367b, 0x50},
+	{0x3684, 0x6d},
+	{0x3685, 0x6d},
+	{0x3686, 0x6d},
+	{0x3687, 0x6d},
+	{0x368c, 0x07},
+	{0x368d, 0x07},
+	{0x368e, 0x07},
+	{0x368f, 0x00},
+	{0x3690, 0x04},
+	{0x3691, 0x04},
+	{0x3692, 0x04},
+	{0x3693, 0x04},
+	{0x3698, 0x00},
+	{0x369e, 0x1f},
+	{0x369f, 0x19},
+	{0x36a0, 0x05},
+	{0x36a2, 0x16},
+	{0x36a3, 0x03},
+	{0x36a4, 0x07},
+	{0x36a5, 0x24},
+	{0x36a6, 0x00},
+	{0x36a7, 0x80},
+	{0x36e3, 0x09},
+	{0x3700, 0x07},
+	{0x3701, 0x1b},
+	{0x3702, 0x0a},
+	{0x3703, 0x21},
+	{0x3704, 0x19},
+	{0x3705, 0x07},
+	{0x3706, 0x36},
+	{0x370a, 0x1c},
+	{0x370b, 0x02},
+	{0x370c, 0x00},
+	{0x370d, 0x6e},
+	{0x370f, 0x80},
+	{0x3710, 0x10},
+	{0x3712, 0x09},
+	{0x3714, 0x42},
+	{0x3715, 0x00},
+	{0x3716, 0x02},
+	{0x3717, 0xa2},
+	{0x3718, 0x41},
+	{0x371a, 0x80},
+	{0x371b, 0x0a},
+	{0x371c, 0x0a},
+	{0x371d, 0x08},
+	{0x371e, 0x01},
+	{0x371f, 0x20},
+	{0x3720, 0x0e},
+	{0x3721, 0x22},
+	{0x3722, 0x0c},
+	{0x3727, 0x84},
+	{0x3728, 0x03},
+	{0x3729, 0x64},
+	{0x372a, 0x0c},
+	{0x372b, 0x14},
+	{0x372d, 0x50},
+	{0x372e, 0x14},
+	{0x3731, 0x11},
+	{0x3732, 0x24},
+	{0x3733, 0x00},
+	{0x3734, 0x00},
+	{0x3735, 0x12},
+	{0x3736, 0x00},
+	{0x373b, 0x0b},
+	{0x373c, 0x14},
+	{0x373f, 0x3e},
+	{0x3740, 0x12},
+	{0x3741, 0x12},
+	{0x3753, 0x80},
+	{0x3754, 0x01},
+	{0x3756, 0x11},
+	{0x375c, 0x0f},
+	{0x375d, 0x35},
+	{0x375e, 0x0f},
+	{0x375f, 0x37},
+	{0x3760, 0x0f},
+	{0x3761, 0x27},
+	{0x3762, 0x3f},
+	{0x3763, 0x5d},
+	{0x3764, 0x01},
+	{0x3765, 0x17},
+	{0x3766, 0x02},
+	{0x3768, 0x52},
+	{0x376a, 0x30},
+	{0x376b, 0x02},
+	{0x376c, 0x08},
+	{0x376d, 0x2a},
+	{0x376e, 0x00},
+	{0x376f, 0x18},
+	{0x3770, 0x2c},
+	{0x3771, 0x0c},
+	{0x3772, 0x71},
+	{0x3776, 0xc0},
+	{0x3778, 0x00},
+	{0x3779, 0x80},
+	{0x377a, 0x00},
+	{0x377d, 0x14},
+	{0x377e, 0x0c},
+	{0x379c, 0x25},
+	{0x379f, 0x00},
+	{0x37a3, 0x40},
+	{0x37a4, 0x03},
+	{0x37a5, 0x10},
+	{0x37a6, 0x02},
+	{0x37a7, 0x0e},
+	{0x37a9, 0x00},
+	{0x37aa, 0x08},
+	{0x37ab, 0x08},
+	{0x37ac, 0x36},
+	{0x37ad, 0x40},
+	{0x37b0, 0x48},
+	{0x37d0, 0x00},
+	{0x37d1, 0x0b},
+	{0x37d2, 0x0c},
+	{0x37d3, 0x10},
+	{0x37d4, 0x10},
+	{0x37d5, 0x10},
+	{0x37d8, 0x0e},
+	{0x37d9, 0x0e},
+	{0x37da, 0x3c},
+	{0x37db, 0x52},
+	{0x37dc, 0x50},
+	{0x37dd, 0x00},
+	{0x37de, 0x55},
+	{0x37df, 0x7d},
+	{0x37e5, 0x88},
+	{0x37e7, 0x68},
+	{0x37e8, 0x07},
+	{0x37f0, 0x00},
+	{0x37f1, 0x0e},
+	{0x37f2, 0x35},
+	{0x37f3, 0x14},
+	{0x37f4, 0x0c},
+	{0x37f5, 0x14},
+	{0x37f6, 0x0c},
+	{0x37f7, 0x35},
+	{0x37f8, 0x35},
+	{0x37f9, 0x37},
+	{0x37fa, 0x37},
+	{0x37fb, 0x37},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x2f},
+	{0x3806, 0x07},
+	{0x3807, 0xa7},
+	{0x3808, 0x0a}, /* width 2592 = 0xa20 */
+	{0x3809, 0x20}, /* width */
+	{0x380a, 0x07}, /* height 1944 = 0x798 */
+	{0x380b, 0x98}, /* height */
+	{0x380c, 0x02},
+	{0x380d, 0xf0},
+	{0x380e, 0x08},
+	{0x380f, 0x50},
+	{0x3810, 0x00},
+	{0x3811, 0x08},
+	{0x3812, 0x00},
+	{0x3813, 0x08},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3820, 0x40},
+	{0x3821, 0x04}, /* TIMING_CTRL_REG21 bit[2] = mirror */
+	{0x3822, 0x10},
+	{0x3823, 0x00},
+	{0x3826, 0x00},
+	{0x3827, 0x00},
+	{0x382b, 0x03},
+	{0x382c, 0x0c},
+	{0x382d, 0x15},
+	{0x382e, 0x01},
+	{0x3830, 0x00},
+	{0x3838, 0x00},
+	{0x383b, 0x00},
+	{0x3840, 0x00},
+	{0x384a, 0xa2},
+	{0x3858, 0x00},
+	{0x3859, 0x00},
+	{0x3860, 0x00},
+	{0x3861, 0x00},
+	{0x3866, 0x10},
+	{0x3867, 0x07},
+	{0x3868, 0x01},
+	{0x3869, 0x01},
+	{0x386a, 0x01},
+	{0x386b, 0x01},
+	{0x386c, 0x46},
+	{0x386d, 0x08},
+	{0x386e, 0x7b},
+	{0x3871, 0x01},
+	{0x3872, 0x01},
+	{0x3873, 0x01},
+	{0x3874, 0x01},
+	{0x3880, 0x00},
+	{0x3881, 0x00},
+	{0x3882, 0x00},
+	{0x3883, 0x00},
+	{0x3884, 0x00},
+	{0x3885, 0x00},
+	{0x3886, 0x00},
+	{0x3887, 0x00},
+	{0x3888, 0x00},
+	{0x3889, 0x00},
+	{0x3900, 0x13},
+	{0x3901, 0x19},
+	{0x3902, 0x05},
+	{0x3903, 0x00},
+	{0x3904, 0x00},
+	{0x3908, 0x00},
+	{0x3909, 0x18},
+	{0x390a, 0x00},
+	{0x390b, 0x11},
+	{0x390c, 0x15},
+	{0x390d, 0x84},
+	{0x390f, 0x88},
+	{0x3910, 0x00},
+	{0x3911, 0x00},
+	{0x3912, 0x03},
+	{0x3913, 0x62},
+	{0x3914, 0x00},
+	{0x3915, 0x06},
+	{0x3916, 0x0c},
+	{0x3917, 0x81},
+	{0x3918, 0xc8},
+	{0x3919, 0x94},
+	{0x391a, 0x17},
+	{0x391b, 0x05},
+	{0x391c, 0x81},
+	{0x391d, 0x05},
+	{0x391e, 0x81},
+	{0x391f, 0x05},
+	{0x3920, 0x81},
+	{0x3921, 0x14},
+	{0x3922, 0x0b},
+	{0x3929, 0x00},
+	{0x392a, 0x00},
+	{0x392b, 0xc8},
+	{0x392c, 0x81},
+	{0x392f, 0x00},
+	{0x3930, 0x00},
+	{0x3931, 0x00},
+	{0x3932, 0x00},
+	{0x3933, 0x00},
+	{0x3934, 0x1b},
+	{0x3935, 0xc0},
+	{0x3936, 0x1c},
+	{0x3937, 0x21},
+	{0x3938, 0x0d},
+	{0x3939, 0x92},
+	{0x393a, 0x85},
+	{0x393b, 0x8a},
+	{0x393c, 0x06},
+	{0x393d, 0x8b},
+	{0x393e, 0x0f},
+	{0x393f, 0x14},
+	{0x3940, 0x0f},
+	{0x3941, 0x14},
+	{0x3945, 0xc0},
+	{0x3946, 0x05},
+	{0x3947, 0xc0},
+	{0x3948, 0x01},
+	{0x3949, 0x00},
+	{0x394a, 0x00},
+	{0x394b, 0x0b},
+	{0x394c, 0x0c},
+	{0x394d, 0x0b},
+	{0x394e, 0x09},
+	{0x3951, 0xc7},
+	{0x3952, 0x0f},
+	{0x3953, 0x0f},
+	{0x3954, 0x0f},
+	{0x3955, 0x00},
+	{0x3956, 0x27},
+	{0x3957, 0x27},
+	{0x3958, 0x27},
+	{0x3959, 0x01},
+	{0x395a, 0x02},
+	{0x395b, 0x14},
+	{0x395c, 0x36},
+	{0x395e, 0xc0},
+	{0x3964, 0x55},
+	{0x3965, 0x55},
+	{0x3966, 0x88},
+	{0x3967, 0x88},
+	{0x3968, 0x66},
+	{0x3969, 0x66},
+	{0x396d, 0x80},
+	{0x396e, 0xff},
+	{0x396f, 0x10},
+	{0x3970, 0x80},
+	{0x3971, 0x80},
+	{0x3972, 0x00},
+	{0x397a, 0x55},
+	{0x397b, 0x10},
+	{0x397c, 0x10},
+	{0x397d, 0x10},
+	{0x397e, 0x10},
+	{0x3980, 0xfc},
+	{0x3981, 0xfc},
+	{0x3982, 0x66},
+	{0x3983, 0xfc},
+	{0x3984, 0xfc},
+	{0x3985, 0x66},
+	{0x3986, 0x00},
+	{0x3987, 0x00},
+	{0x3988, 0x00},
+	{0x3989, 0x00},
+	{0x398a, 0x00},
+	{0x398b, 0x00},
+	{0x398c, 0x00},
+	{0x398d, 0x00},
+	{0x398e, 0x00},
+	{0x398f, 0x00},
+	{0x3990, 0x00},
+	{0x3991, 0x00},
+	{0x3992, 0x00},
+	{0x3993, 0x00},
+	{0x3994, 0x00},
+	{0x3995, 0x00},
+	{0x3996, 0x00},
+	{0x3997, 0x0f},
+	{0x3998, 0x0c},
+	{0x3999, 0x0c},
+	{0x399a, 0x0c},
+	{0x399b, 0xf0},
+	{0x399c, 0x14},
+	{0x399d, 0x0d},
+	{0x399e, 0x00},
+	{0x399f, 0x0c},
+	{0x39a0, 0x0c},
+	{0x39a1, 0x0c},
+	{0x39a2, 0x00},
+	{0x39a3, 0x0f},
+	{0x39a4, 0x0c},
+	{0x39a5, 0x0c},
+	{0x39a6, 0x0c},
+	{0x39a7, 0x0c},
+	{0x39a8, 0x0f},
+	{0x39a9, 0xff},
+	{0x39aa, 0xbf},
+	{0x39ab, 0x3f},
+	{0x39ac, 0x7e},
+	{0x39ad, 0xff},
+	{0x39ae, 0x00},
+	{0x39af, 0x00},
+	{0x39b0, 0x00},
+	{0x39b1, 0x00},
+	{0x39b2, 0x00},
+	{0x39b3, 0x00},
+	{0x39b4, 0x00},
+	{0x39b5, 0x00},
+	{0x39b6, 0x00},
+	{0x39b7, 0x00},
+	{0x39b8, 0x00},
+	{0x39b9, 0x00},
+	{0x39ba, 0x00},
+	{0x39bb, 0x00},
+	{0x39bc, 0x00},
+	{0x39c2, 0x00},
+	{0x39c3, 0x00},
+	{0x39c4, 0x00},
+	{0x39c5, 0x00},
+	{0x39c7, 0x00},
+	{0x39c8, 0x00},
+	{0x39c9, 0x00},
+	{0x39ca, 0x01},
+	{0x39cb, 0x00},
+	{0x39cc, 0x85},
+	{0x39cd, 0x09},
+	{0x39cf, 0x04},
+	{0x39d0, 0x85},
+	{0x39d1, 0x09},
+	{0x39d2, 0x04},
+	{0x39d4, 0x02},
+	{0x39d5, 0x0e},
+	{0x39db, 0x00},
+	{0x39dc, 0x01},
+	{0x39dd, 0x0c},
+	{0x39e5, 0xff},
+	{0x39e6, 0xff},
+	{0x39fa, 0x38},
+	{0x39fb, 0x07},
+	{0x39ff, 0x00},
+	{0x3a05, 0x00},
+	{0x3a06, 0x07},
+	{0x3a07, 0x0d},
+	{0x3a08, 0x08},
+	{0x3a09, 0xb2},
+	{0x3a0a, 0x0a},
+	{0x3a0b, 0x3c},
+	{0x3a0c, 0x0b},
+	{0x3a0d, 0xe1},
+	{0x3a0e, 0x03},
+	{0x3a0f, 0x85},
+	{0x3a10, 0x0b},
+	{0x3a11, 0xff},
+	{0x3a12, 0x00},
+	{0x3a13, 0x01},
+	{0x3a14, 0x0c},
+	{0x3a15, 0x04},
+	{0x3a17, 0x09},
+	{0x3a18, 0x20},
+	{0x3a19, 0x09},
+	{0x3a1a, 0x9d},
+	{0x3a1b, 0x09},
+	{0x3a1e, 0x34},
+	{0x3a1f, 0x09},
+	{0x3a20, 0x89},
+	{0x3a21, 0x09},
+	{0x3a48, 0xbe},
+	{0x3a52, 0x00},
+	{0x3a53, 0x01},
+	{0x3a54, 0x0c},
+	{0x3a55, 0x04},
+	{0x3a58, 0x0c},
+	{0x3a59, 0x04},
+	{0x3a5a, 0x01},
+	{0x3a5b, 0x00},
+	{0x3a5c, 0x01},
+	{0x3a5d, 0xe8},
+	{0x3a62, 0x03},
+	{0x3a63, 0x86},
+	{0x3a64, 0x0b},
+	{0x3a65, 0xbe},
+	{0x3a6a, 0xdc},
+	{0x3a6b, 0x0b},
+	{0x3a6c, 0x1a},
+	{0x3a6d, 0x06},
+	{0x3a6e, 0x01},
+	{0x3a6f, 0x04},
+	{0x3a70, 0xdc},
+	{0x3a71, 0x0b},
+	{0x3a83, 0x10},
+	{0x3a84, 0x00},
+	{0x3a85, 0x08},
+	{0x3a87, 0x00},
+	{0x3a88, 0x6b},
+	{0x3a89, 0x01},
+	{0x3a8a, 0x53},
+	{0x3a8f, 0x00},
+	{0x3a90, 0x00},
+	{0x3a91, 0x00},
+	{0x3a92, 0x00},
+	{0x3a93, 0x60},
+	{0x3a94, 0xea},
+	{0x3a98, 0x00},
+	{0x3a99, 0x31},
+	{0x3a9a, 0x01},
+	{0x3a9b, 0x04},
+	{0x3a9c, 0xdc},
+	{0x3a9d, 0x0b},
+	{0x3aa4, 0x0f},
+	{0x3aad, 0x00},
+	{0x3aae, 0x3e},
+	{0x3aaf, 0x02},
+	{0x3ab0, 0x77},
+	{0x3ab2, 0x00},
+	{0x3ab3, 0x08},
+	{0x3ab6, 0x0b},
+	{0x3ab7, 0xff},
+	{0x3aba, 0x0b},
+	{0x3abb, 0xfa},
+	{0x3abd, 0x05},
+	{0x3abe, 0x09},
+	{0x3abf, 0x1e},
+	{0x3ac0, 0x00},
+	{0x3ac1, 0x63},
+	{0x3ac2, 0x01},
+	{0x3ac3, 0x55},
+	{0x3ac8, 0x00},
+	{0x3ac9, 0x2a},
+	{0x3aca, 0x01},
+	{0x3acb, 0x36},
+	{0x3acc, 0x00},
+	{0x3acd, 0x6f},
+	{0x3ad0, 0x00},
+	{0x3ad1, 0x79},
+	{0x3ad2, 0x02},
+	{0x3ad3, 0x59},
+	{0x3ad4, 0x06},
+	{0x3ad5, 0x5a},
+	{0x3ad6, 0x08},
+	{0x3ad7, 0x3a},
+	{0x3ad8, 0x00},
+	{0x3ad9, 0x79},
+	{0x3ada, 0x02},
+	{0x3adb, 0x59},
+	{0x3adc, 0x09},
+	{0x3add, 0x89},
+	{0x3ade, 0x0b},
+	{0x3adf, 0x69},
+	{0x3ae0, 0x03},
+	{0x3ae1, 0xc1},
+	{0x3ae2, 0x0b},
+	{0x3ae3, 0xaf},
+	{0x3ae4, 0x00},
+	{0x3ae5, 0x3e},
+	{0x3ae6, 0x02},
+	{0x3ae7, 0x77},
+	{0x3ae8, 0x00},
+	{0x3aea, 0x0b},
+	{0x3aeb, 0xbe},
+	{0x3aee, 0x08},
+	{0x3aef, 0x80},
+	{0x3af0, 0x09},
+	{0x3af1, 0x70},
+	{0x3af2, 0x08},
+	{0x3af3, 0x94},
+	{0x3af4, 0x09},
+	{0x3af5, 0x5c},
+	{0x3af6, 0x03},
+	{0x3af7, 0x85},
+	{0x3af8, 0x08},
+	{0x3af9, 0x80},
+	{0x3afa, 0x0b},
+	{0x3afb, 0xaf},
+	{0x3afc, 0x01},
+	{0x3afd, 0x5a},
+	{0x3b1e, 0x00},
+	{0x3b20, 0xa5},
+	{0x3b21, 0x00},
+	{0x3b22, 0x00},
+	{0x3b23, 0x00},
+	{0x3b24, 0x05},
+	{0x3b25, 0x00},
+	{0x3b26, 0x00},
+	{0x3b27, 0x00},
+	{0x3b28, 0x1a},
+	{0x3b2f, 0x40},
+	{0x3b40, 0x08},
+	{0x3b41, 0x70},
+	{0x3b42, 0x05},
+	{0x3b43, 0xf0},
+	{0x3b44, 0x01},
+	{0x3b45, 0x54},
+	{0x3b46, 0x01},
+	{0x3b47, 0x54},
+	{0x3b56, 0x08},
+	{0x3b80, 0x00},
+	{0x3b81, 0x00},
+	{0x3b82, 0x64},
+	{0x3b83, 0x00},
+	{0x3b84, 0x00},
+	{0x3b85, 0x64},
+	{0x3b9d, 0x61},
+	{0x3ba8, 0x38},
+	{0x3c11, 0x33},
+	{0x3c12, 0x3d},
+	{0x3c13, 0x00},
+	{0x3c14, 0xbe},
+	{0x3c15, 0x0b},
+	{0x3c16, 0xa8},
+	{0x3c17, 0x03},
+	{0x3c18, 0x9c},
+	{0x3c19, 0x0b},
+	{0x3c1a, 0x0f},
+	{0x3c1b, 0x97},
+	{0x3c1c, 0x00},
+	{0x3c1d, 0x3c},
+	{0x3c1e, 0x02},
+	{0x3c1f, 0x78},
+	{0x3c20, 0x06},
+	{0x3c21, 0x80},
+	{0x3c22, 0x08},
+	{0x3c23, 0x0f},
+	{0x3c24, 0x97},
+	{0x3c25, 0x00},
+	{0x3c26, 0x3c},
+	{0x3c27, 0x02},
+	{0x3c28, 0xa7},
+	{0x3c29, 0x09},
+	{0x3c2a, 0xaf},
+	{0x3c2b, 0x0b},
+	{0x3c2c, 0x38},
+	{0x3c2d, 0xf9},
+	{0x3c2e, 0x0b},
+	{0x3c2f, 0xfd},
+	{0x3c30, 0x05},
+	{0x3c35, 0x8c},
+	{0x3c3e, 0xc3},
+	{0x3c43, 0xcb},
+	{0x3c44, 0x00},
+	{0x3c45, 0xff},
+	{0x3c46, 0x0b},
+	{0x3c48, 0x3b},
+	{0x3c49, 0x40},
+	{0x3c4a, 0x00},
+	{0x3c4b, 0x5b},
+	{0x3c4c, 0x02},
+	{0x3c4d, 0x02},
+	{0x3c4e, 0x00},
+	{0x3c4f, 0x04},
+	{0x3c50, 0x0c},
+	{0x3c51, 0x00},
+	{0x3c52, 0x3b},
+	{0x3c53, 0x3a},
+	{0x3c54, 0x07},
+	{0x3c55, 0x9e},
+	{0x3c56, 0x07},
+	{0x3c57, 0x9e},
+	{0x3c58, 0x07},
+	{0x3c59, 0xe8},
+	{0x3c5a, 0x03},
+	{0x3c5b, 0x33},
+	{0x3c5c, 0xa8},
+	{0x3c5d, 0x07},
+	{0x3c5e, 0xd0},
+	{0x3c5f, 0x07},
+	{0x3c60, 0x32},
+	{0x3c61, 0x00},
+	{0x3c62, 0xd0},
+	{0x3c63, 0x07},
+	{0x3c64, 0x80},
+	{0x3c65, 0x80},
+	{0x3c66, 0x3f},
+	{0x3c67, 0x01},
+	{0x3c68, 0x00},
+	{0x3c69, 0xd0},
+	{0x3c6a, 0x07},
+	{0x3c6b, 0x01},
+	{0x3c6c, 0x00},
+	{0x3c6d, 0xcd},
+	{0x3c6e, 0x07},
+	{0x3c6f, 0xd1},
+	{0x3c70, 0x07},
+	{0x3c71, 0x01},
+	{0x3c72, 0x00},
+	{0x3c73, 0xc3},
+	{0x3c74, 0x01},
+	{0x3c75, 0x00},
+	{0x3c76, 0xcd},
+	{0x3c77, 0x07},
+	{0x3c78, 0xea},
+	{0x3c79, 0x03},
+	{0x3c7a, 0xcd},
+	{0x3c7b, 0x07},
+	{0x3c7c, 0x08},
+	{0x3c7d, 0x06},
+	{0x3c7e, 0x03},
+	{0x3c85, 0x3a},
+	{0x3c86, 0x08},
+	{0x3c87, 0x69},
+	{0x3c88, 0x0b},
+	{0x3c8f, 0xb2},
+	{0x3c90, 0x08},
+	{0x3c91, 0xe1},
+	{0x3c92, 0x0b},
+	{0x3c93, 0x06},
+	{0x3c94, 0x03},
+	{0x3c9b, 0x35},
+	{0x3c9c, 0x08},
+	{0x3c9d, 0x64},
+	{0x3c9e, 0x0b},
+	{0x3ca5, 0xb7},
+	{0x3ca6, 0x08},
+	{0x3ca7, 0xe6},
+	{0x3ca8, 0x0b},
+	{0x3ca9, 0x83},
+	{0x3caa, 0x3c},
+	{0x3cab, 0x01},
+	{0x3cac, 0x00},
+	{0x3cad, 0x9e},
+	{0x3cae, 0x07},
+	{0x3caf, 0x85},
+	{0x3cb0, 0x03},
+	{0x3cb1, 0xbc},
+	{0x3cb2, 0x0b},
+	{0x3cb7, 0x3c},
+	{0x3cb8, 0x01},
+	{0x3cb9, 0x00},
+	{0x3cba, 0xbc},
+	{0x3cbb, 0x07},
+	{0x3cbc, 0xa3},
+	{0x3cbd, 0x03},
+	{0x3cbe, 0x9e},
+	{0x3cbf, 0x0b},
+	{0x3cc4, 0x66},
+	{0x3cc5, 0xe6},
+	{0x3cc6, 0x99},
+	{0x3cc7, 0xe9},
+	{0x3cc8, 0x33},
+	{0x3cc9, 0x03},
+	{0x3cca, 0x33},
+	{0x3ccb, 0x03},
+	{0x3cce, 0x66},
+	{0x3ccf, 0x66},
+	{0x3cd0, 0x00},
+	{0x3cd1, 0x04},
+	{0x3cd2, 0xf4},
+	{0x3cd3, 0xb7},
+	{0x3cd4, 0x03},
+	{0x3cd5, 0x10},
+	{0x3cd6, 0x06},
+	{0x3cd7, 0x30},
+	{0x3cd8, 0x08},
+	{0x3cd9, 0x5f},
+	{0x3cda, 0x0b},
+	{0x3cdd, 0x88},
+	{0x3cde, 0x88},
+	{0x3cdf, 0x08},
+	{0x3ce0, 0x00},
+	{0x3ce1, 0x00},
+	{0x3ce3, 0x00},
+	{0x3ce4, 0x00},
+	{0x3ce5, 0x00},
+	{0x3ce6, 0x00},
+	{0x3ce7, 0x00},
+	{0x3ce8, 0x00},
+	{0x3ce9, 0x00},
+	{0x3cea, 0x00},
+	{0x3ceb, 0x00},
+	{0x3cec, 0x00},
+	{0x3ced, 0x00},
+	{0x3cee, 0x00},
+	{0x3cef, 0x85},
+	{0x3cf0, 0x03},
+	{0x3cf1, 0xaf},
+	{0x3cf2, 0x0b},
+	{0x3cf3, 0x03},
+	{0x3cf4, 0x2c},
+	{0x3cf5, 0x00},
+	{0x3cf6, 0x42},
+	{0x3cf7, 0x00},
+	{0x3cf8, 0x03},
+	{0x3cf9, 0x2c},
+	{0x3cfa, 0x00},
+	{0x3cfb, 0x42},
+	{0x3cfc, 0x00},
+	{0x3cfd, 0x03},
+	{0x3cfe, 0x01},
+	{0x3d81, 0x00},
+	{0x3e94, 0x0f},
+	{0x3e95, 0x5f},
+	{0x3e96, 0x02},
+	{0x3e97, 0x3c},
+	{0x3e98, 0x00},
+	{0x3e9f, 0x00},
+	{0x3f00, 0x00},
+	{0x3f05, 0x03},
+	{0x3f07, 0x01},
+	{0x3f08, 0x55},
+	{0x3f09, 0x25},
+	{0x3f0a, 0x35},
+	{0x3f0b, 0x20},
+	{0x3f11, 0x05},
+	{0x3f12, 0x05},
+	{0x3f40, 0x00},
+	{0x3f41, 0x03},
+	{0x3f43, 0x10},
+	{0x3f44, 0x02},
+	{0x3f45, 0xe6},
+	{0x4000, 0xf9},
+	{0x4001, 0x2b},
+	{0x4008, 0x04},
+	{0x4009, 0x1b},
+	{0x400a, 0x03},
+	{0x400e, 0x10},
+	{0x4010, 0x04},
+	{0x4011, 0xf7},
+	{0x4032, 0x3e},
+	{0x4033, 0x02},
+	{0x4050, 0x02},
+	{0x4051, 0x0d},
+	{0x40b0, 0x0f},
+	{0x40f9, 0x00},
+	{0x4200, 0x00},
+	{0x4204, 0x00},
+	{0x4205, 0x00},
+	{0x4206, 0x00},
+	{0x4207, 0x00},
+	{0x4208, 0x00},
+	{0x4244, 0x00},
+	{0x4300, 0x00},
+	{0x4301, 0xff},
+	{0x4302, 0xf0},
+	{0x4303, 0x00},
+	{0x4304, 0xff},
+	{0x4305, 0xf0},
+	{0x4306, 0x00},
+	{0x4307, 0x06},
+	{0x4308, 0x00},
+	{0x430a, 0x90}, /* reset 0x10 emb_dt */
+	{0x430b, 0x11},
+	{0x4310, 0x00},
+	{0x4316, 0x00},
+	{0x431c, 0x00},
+	{0x431e, 0x00},
+	{0x431f, 0x0a},
+	{0x4320, 0x20},
+	{0x4410, 0x08},
+	{0x4433, 0x08},
+	{0x4434, 0xf8},
+	{0x4508, 0x80},
+	{0x4509, 0x10},
+	{0x450b, 0x83},
+	{0x4511, 0x00},
+	{0x4580, 0x09},
+	{0x4587, 0x00},
+	{0x458c, 0x00},
+	{0x4640, 0x00},
+	{0x4641, 0xc1},
+	{0x4642, 0x00},
+	{0x4643, 0x00},
+	{0x4649, 0x00},
+	{0x4681, 0x04},
+	{0x4682, 0x10},
+	{0x4683, 0xa0},
+	{0x4698, 0x07},
+	{0x4699, 0xf0},
+	{0x4700, 0xe0},
+	{0x4710, 0x00},
+	{0x4718, 0x04},
+	{0x4802, 0x00}, /* MIPI_CORE_REG00 */
+	{0x481b, 0x3c}, /* MIPI_CORE_REG1B */
+	{0x4837, 0x19}, /* MIPI_CORE_REG37 pclk_period[7:0] */
+	{0x4860, 0x00},
+	{0x4883, 0x00},
+	{0x4884, 0x09},
+	{0x4885, 0x80},
+	{0x4886, 0x00},
+	{0x4888, 0x10},
+	{0x488b, 0x00},
+	{0x488c, 0x10},
+	{0x4980, 0x03},
+	{0x4981, 0x06},
+	{0x4984, 0x00},
+	{0x4985, 0x00},
+	{0x4a14, 0x04},
+	{0x4b01, 0x44},
+	{0x4b03, 0x80},
+	{0x4d06, 0xc8},
+	{0x4d09, 0xdf},
+	{0x4d12, 0x80},
+	{0x4d15, 0x7d},
+	{0x4d34, 0x7d},
+	{0x4d3c, 0x7d},
+	{0x4d5a, 0x14},
+	{0x4e03, 0x06},
+	{0x4e04, 0xb9},
+	{0x4e05, 0x08},
+	{0x4e06, 0x36},
+	{0x4e07, 0x04},
+	{0x4e08, 0x52},
+	{0x4e09, 0x05},
+	{0x4e0a, 0x47},
+	{0x4e0b, 0x02},
+	{0x4e0c, 0xe2},
+	{0x4e0d, 0x03},
+	{0x4e0e, 0x85},
+	{0x4e18, 0xf3},
+	{0x4e19, 0x0f},
+	{0x4e1b, 0x08},
+	{0x4e1c, 0x04},
+	{0x4f00, 0x7f},
+	{0x4f01, 0xff},
+	{0x4f03, 0x00},
+	{0x4f04, 0x18},
+	{0x4f05, 0x13},
+	{0x5000, 0x6e},
+	{0x5001, 0x00},
+	{0x500a, 0x00},
+	{0x5080, 0x00},
+	{0x5081, 0x00},
+	{0x5082, 0x00},
+	{0x5083, 0x00},
+	{0x5100, 0x00},
+	{0x5103, 0x00},
+	{0x5180, 0x70},
+	{0x5181, 0x70},
+	{0x5182, 0x73},
+	{0x5183, 0xff},
+	{0x5240, 0x73},
+	{0x5249, 0x06},
+	{0x524a, 0x44},
+	{0x524b, 0x44},
+	{0x524c, 0x44},
+	{0x524e, 0x66},
+	{0x524f, 0x06},
+	{0x5250, 0x00},
+	{0x5281, 0x18},
+	{0x5282, 0x08},
+	{0x5283, 0x08},
+	{0x5284, 0x18},
+	{0x5285, 0x18},
+	{0x5286, 0x08},
+	{0x5287, 0x08},
+	{0x5288, 0x18},
+	{0x5289, 0x2d},
+	{0x6000, 0x40},
+	{0x6001, 0x40},
+	{0x6002, 0x00},
+	{0x6003, 0x00},
+	{0x6004, 0x00},
+	{0x6005, 0x00},
+	{0x6006, 0x00},
+	{0x6007, 0x00},
+	{0x6008, 0x00},
+	{0x6009, 0x00},
+	{0x600a, 0x00},
+	{0x600b, 0x00},
+	{0x600c, 0x02},
+	{0x600d, 0x00},
+	{0x600e, 0x04},
+	{0x600f, 0x00},
+	{0x6010, 0x06},
+	{0x6011, 0x00},
+	{0x6012, 0x00},
+	{0x6013, 0x00},
+	{0x6014, 0x02},
+	{0x6015, 0x00},
+	{0x6016, 0x04},
+	{0x6017, 0x00},
+	{0x6018, 0x06},
+	{0x6019, 0x00},
+	{0x601a, 0x01},
+	{0x601b, 0x00},
+	{0x601c, 0x01},
+	{0x601d, 0x00},
+	{0x601e, 0x01},
+	{0x601f, 0x00},
+	{0x6020, 0x01},
+	{0x6021, 0x00},
+	{0x6022, 0x01},
+	{0x6023, 0x00},
+	{0x6024, 0x01},
+	{0x6025, 0x00},
+	{0x6026, 0x01},
+	{0x6027, 0x00},
+	{0x6028, 0x01},
+	{0x6029, 0x00},
+
+	{0x3501, 0x08},
+	{0x3502, 0x32},
+
+	/* PLL 6G */
+	{0x0307, 0x01}, /* pll1_divm */
+	{0x304a, 0x03},
+	{0x4837, 0x10}, /* MIPI_CORE_REG37 pclk_period[7:0] */
+
+	/* Ficosa specific */
+	{0x3503, 0xa8}, /* AEC enable */
+	{0x3501, 0x00}, /* AEC expusure time 0x3501, 0x3502 */
+	{0x3502, 0x40},
+	{0x3508, 0x01}, /* AEC gain 0x3508, 0x3509 */
+	{0x3509, 0x00},
+	{0x3002, 0x6f}, /* I/O */ /* SC_CMMN_REG02 io_pad_oen[7:0] */
+	{0x3005, 0x6a}, /* SC_CMMN_REG05 io_pad_out[7:0] */
+	{0x3008, 0x6a}, /* SC_CMMN_REG08 io_pad_sel[7:0] */
+	{0x3b20, 0xff}, /* Strobe */ /* STOBE_REG20 stobe_pattern[7:0] */
+	{0x3a9f, 0x08}, /* GLOBAL_SHUTTER_REG9F */
+	{0x3aa0, 0x00}, /* GLOBAL_SHUTTER_REGA0 */
+	{0x3aa1, 0x00}, /* GLOBAL_SHUTTER_REGA1 */
+	{0x3b21, 0x00},
+	{0x3b22, 0x00},
+	{0x3b23, 0x00},
+	{0x3b24, 0x00},
+	{0x3b25, 0x00},
+	{0x3b26, 0x00},
+	{0x3b27, 0x00},
+	{0x3b28, 0x10},
+	{0x3b2f, 0x4a},
+	{0x3b2d, 0x01},
+	{0x3b2e, 0x78},
+	{0x3b1e, 0x01},
+	{0x3b1f, 0x05},
+
+	{0x4e04, 0x06},
+	{0x4e04, 0xee},
+	{0x4e05, 0x08},
+	{0x4e06, 0x88},
+	{0x4e07, 0x04},
+	{0x4e08, 0x0d},
+	{0x4e09, 0x09},
+	{0x4e0a, 0xae},
+	{0x4e0b, 0x02},
+	{0x4e0c, 0x44},
+	{0x4e0d, 0x03},
+	{0x4e0e, 0x55},
+};
+
+#endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 3/5] MAINTAINERS: Add entry for OX05B1S sensor driver
  2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw " Mirela Rabulea
@ 2024-10-28 19:06 ` Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20 Mirela Rabulea
  2024-10-28 19:06 ` [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor Mirela Rabulea
  4 siblings, 0 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Add maintainer for Omnivision OX05B1S sensor driver.

Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a77770cd96b8..8372ab4999da 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17259,6 +17259,16 @@ S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
 F:	drivers/media/i2c/ov9734.c
 
+OMNIVISION OX05B1S SENSOR DRIVER
+M:	Mirela Rabulea <mirela.rabulea@nxp.com>
+R:	Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+R:	Robert Chiras <robert.chiras@oss.nxp.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
+F:	drivers/media/i2c/ox05b1s/*
+
 ONBOARD USB HUB DRIVER
 M:	Matthias Kaehlcke <mka@chromium.org>
 L:	linux-usb@vger.kernel.org
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20
  2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
                   ` (2 preceding siblings ...)
  2024-10-28 19:06 ` [PATCH 3/5] MAINTAINERS: Add entry for OX05B1S " Mirela Rabulea
@ 2024-10-28 19:06 ` Mirela Rabulea
  2024-10-29  6:17   ` Krzysztof Kozlowski
  2024-10-28 19:06 ` [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor Mirela Rabulea
  4 siblings, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Add another compatible for OS08A20 sensor.

Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
 Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
index d47e1950f24d..a645c34dcc22 100644
--- a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
@@ -20,6 +20,7 @@ properties:
     items:
       - enum:
           - ovti,ox05b1s
+          - ovti,os08a20
 
   reg:
     maxItems: 1
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor
  2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
                   ` (3 preceding siblings ...)
  2024-10-28 19:06 ` [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20 Mirela Rabulea
@ 2024-10-28 19:06 ` Mirela Rabulea
  2024-11-01 12:08   ` Sakari Ailus
  4 siblings, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-28 19:06 UTC (permalink / raw)
  To: mchehab, sakari.ailus, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

This is an 8 megapixel raw10/raw12 sensor with HDR capabilities.
HDR mode control is supported, with one hdr mode: staggered HDR with
2 exposures on separate virtual channels.
Supported resolutions:
   - 1920 x 1080 @ 60fps (SBGGR10, no HDR)
   - 1920 x 1080 @ 30fps (SBGGR10, HDR)
   - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
   - 3840 x 2160 @ 15fps (SBGGR10, HDR)
   - 3840 x 2160 @ 15fps (SBGGR12, HDR)
   - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
   - 3840 x 2160 @ 30fps (SBGGR10, no HDR)

Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
 .../media/i2c/ox05b1s/os08a20_regs_1080p.h    | 201 +++++++++++++++++
 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h   | 209 ++++++++++++++++++
 .../media/i2c/ox05b1s/os08a20_regs_4k_hdr.h   | 199 +++++++++++++++++
 drivers/media/i2c/ox05b1s/ox05b1s_mipi.c      | 189 ++++++++++++++++
 4 files changed, 798 insertions(+)
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
 create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h

diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
new file mode 100644
index 000000000000..ab9977c56a10
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A register configuration for Omnivision OS08A20 raw camera, 1920 x 1080 @60fps BGGR10
+ * Copyright (C) 2024, NXP
+ * Copyright (C) 2024, Omnivision
+ * Copyright (C) 2024, Verisilicon
+ *
+ */
+#ifndef _OS08A20_REGS_1080P_H_
+#define _OS08A20_REGS_1080P_H_
+
+static struct ox05b1s_reg os08a20_init_setting_1080p[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x0303, 0x01},
+	{0x0304, 0x00}, /* PLL_CTRL_04 (default 0x00) */
+	{0x0305, 0x2d}, /* PLL_CTRL_05 (default 0x3c) */
+	{0x0306, 0x00},
+	{0x0308, 0x03},
+	{0x0309, 0x04},
+	{0x0325, 0x45}, /* PLL_CTRL_25 (default 0x3c) */
+	{0x0327, 0x05}, /* PLL_CTRL_27 (default 0x07) */
+	{0x0328, 0x02}, /* PLL_CTRL_28 (default 0x07) */
+	{0x032a, 0x02}, /* PLL_CTRL_2a (default 0x00) */
+	{0x300f, 0x11},
+	{0x3010, 0x01},
+	{0x3011, 0x04},
+	{0x3012, 0x41},
+	{0x3016, 0xf0},
+	{0x301e, 0x98},
+	{0x3031, 0xa9},
+	{0x3103, 0x92},
+	{0x3104, 0x01},
+	{0x3106, 0x10},
+	{0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
+	{0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
+	{0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
+	{0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
+	{0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
+	{0x340c, 0xff},
+	{0x340d, 0xff},
+	{0x031e, 0x09},
+	{0x3501, 0x04}, /* Long exposure */
+	{0x3502, 0x62}, /* Long exposure */
+	{0x3505, 0x83},
+	{0x3508, 0x00}, /* Long gain */
+	{0x3509, 0x80}, /* Long gain */
+	{0x350a, 0x04},
+	{0x350b, 0x00},
+	{0x350c, 0x00},
+	{0x350d, 0x80},
+	{0x350e, 0x04},
+	{0x350f, 0x00},
+	{0x3600, 0x09}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
+	{0x3603, 0x2c},
+	{0x3605, 0x50},
+	{0x3609, 0xb5},
+	{0x3610, 0x39},
+	{0x360c, 0x01},
+	{0x3628, 0xa4},
+	{0x362d, 0x10},
+	{0x3660, 0x43}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
+	{0x3662, 0x00},
+	{0x3663, 0x28},
+	{0x3664, 0x0d},
+	{0x366a, 0x38},
+	{0x366b, 0xa0},
+	{0x366d, 0x00},
+	{0x366e, 0x00},
+	{0x3680, 0x00},
+	{0x36c0, 0x00},
+	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x373b, 0x02},
+	{0x373c, 0x02},
+	{0x3736, 0x02},
+	{0x3737, 0x02},
+	{0x3705, 0x00},
+	{0x3706, 0x39},
+	{0x370a, 0x00},
+	{0x370b, 0x98},
+	{0x3709, 0x49},
+	{0x3714, 0x22},  /* Sensor timing control registers 0x3700-0x37ff */
+	{0x371c, 0x00},
+	{0x371d, 0x08},
+	{0x3740, 0x1b},
+	{0x3741, 0x04},
+	{0x375e, 0x0b},
+	{0x3760, 0x10},
+	{0x3776, 0x10},
+	{0x3781, 0x02},
+	{0x3782, 0x04},
+	{0x3783, 0x02},
+	{0x3784, 0x08},
+	{0x3785, 0x08},
+	{0x3788, 0x01},
+	{0x3789, 0x01},
+	{0x3797, 0x04},
+	{0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x0c},
+	{0x3804, 0x0e},
+	{0x3805, 0xff},
+	{0x3806, 0x08},
+	{0x3807, 0x6f},
+	{0x3808, 0x07}, /* X output size (default 0x07) */
+	{0x3809, 0x80}, /* X output size (default 0x80) */
+	{0x380a, 0x04}, /* Y output size (default 0x04) */
+	{0x380b, 0x38}, /* Y output size (default 0x38) */
+	{0x380c, 0x07}, /* HTS[15:8], total horizontal timing size */
+	{0x380d, 0x90}, /* HTS[7:0],  total horizontal timing size */
+	{0x380e, 0x04}, /* VTS[15:8], total vertical timing (default 0x04) */
+	{0x380f, 0xa4}, /* VTS[7:0],  total vertical timing (default 0xA0) */
+	{0x3813, 0x08}, /* ISP_Y_WIN ISP vertical windowing offset */
+	{0x3814, 0x03}, /* X INC ODD (default 0x01) */
+	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
+	{0x3816, 0x03}, /* Y INC ODD (default 0x01) */
+	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
+	{0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
+	{0x3820, 0x01}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
+	{0x3821, 0x05}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
+	{0x3823, 0x08},
+	{0x3826, 0x00},
+	{0x3827, 0x08},
+	{0x382d, 0x08},
+	{0x3832, 0x02},
+	{0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
+	{0x383c, 0x48},
+	{0x383d, 0xff},
+	{0x3d85, 0x0b},
+	{0x3d84, 0x40},
+	{0x3d8c, 0x63},
+	{0x3d8d, 0xd7},
+	{0x4000, 0xf8},
+	{0x4001, 0x2b},
+	{0x4004, 0x00},
+	{0x4005, 0x40},
+	{0x400a, 0x01},
+	{0x400f, 0xa0},
+	{0x4010, 0x12},
+	{0x4018, 0x00},
+	{0x4008, 0x02},
+	{0x4009, 0x05}, /* BLC CTRL09 (default 0x0f) bl_end */
+	{0x401a, 0x58},
+	{0x4050, 0x00},
+	{0x4051, 0x01},
+	{0x4028, 0x2f},
+	{0x4052, 0x00},
+	{0x4053, 0x80},
+	{0x4054, 0x00},
+	{0x4055, 0x80},
+	{0x4056, 0x00},
+	{0x4057, 0x80},
+	{0x4058, 0x00},
+	{0x4059, 0x80},
+	{0x430b, 0xff},
+	{0x430c, 0xff},
+	{0x430d, 0x00},
+	{0x430e, 0x00},
+	{0x4501, 0x98}, /* R1 (default 0x18) bit[4:2]=not used */
+	{0x4502, 0x00},
+	{0x4643, 0x00},
+	{0x4640, 0x01},
+	{0x4641, 0x04},
+	{0x4800, 0x64},
+	{0x4809, 0x2b},
+	{0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
+	{0x4817, 0x04},
+	{0x4833, 0x18},
+	{0x4837, 0x16}, /* PCLK PERIOD (default 0x08) */
+	{0x483b, 0x00},
+	{0x484b, 0x03},
+	{0x4850, 0x7c},
+	{0x4852, 0x06},
+	{0x4856, 0x58},
+	{0x4857, 0xaa},
+	{0x4862, 0x0a},
+	{0x4869, 0x18},
+	{0x486a, 0xaa},
+	{0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
+	{0x486f, 0x55},
+	{0x4875, 0xf0},
+	{0x5000, 0x89},
+	{0x5001, 0x42},
+	{0x5004, 0x40},
+	{0x5005, 0x00},
+	{0x5180, 0x00},
+	{0x5181, 0x10},
+	{0x580b, 0x03},
+	{0x4d00, 0x03},
+	{0x4d01, 0xc9},
+	{0x4d02, 0xbc},
+	{0x4d03, 0xc6},
+	{0x4d04, 0x4a},
+	{0x4d05, 0x25},
+	{0x4700, 0x2b},
+	{0x4e00, 0x2b},
+};
+
+#endif
diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
new file mode 100644
index 000000000000..f3d5f0fe1b61
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR12
+ * Copyright (C) 2024, NXP
+ * Copyright (C) 2024, Omnivision
+ * Copyright (C) 2024, Verisilicon
+ *
+ */
+
+#ifndef _OS08A20_REGS_4K_H_
+#define _OS08A20_REGS_4K_H_
+
+static struct ox05b1s_reg os08a20_init_setting_4k[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x0303, 0x01},
+	{0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
+	{0x0306, 0x00},
+	{0x0308, 0x03},
+	{0x0309, 0x04},
+	{0x0325, 0x47}, /* PLL_CTRL_25 (default 0x3c) */
+	{0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
+	{0x300f, 0x11},
+	{0x3010, 0x01},
+	{0x3011, 0x04},
+	{0x3012, 0x41},
+	{0x3016, 0xf0},
+	{0x301e, 0x98},
+	{0x3031, 0xa9},
+	{0x3103, 0x92},
+	{0x3104, 0x01},
+	{0x3106, 0x10},
+	{0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
+	{0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
+	{0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
+	{0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
+	{0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
+	{0x340c, 0xff},
+	{0x340d, 0xff},
+	{0x031e, 0x0a},
+	{0x3501, 0x08}, /* Long exposure */
+	{0x3502, 0xe5}, /* Long exposure */
+	{0x3505, 0x83},
+	{0x3508, 0x00}, /* Long gain */
+	{0x3509, 0x80}, /* Long gain */
+	{0x350a, 0x04},
+	{0x350b, 0x00},
+	{0x350c, 0x00},
+	{0x350d, 0x80},
+	{0x350e, 0x04},
+	{0x350f, 0x00},
+	{0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
+	{0x3603, 0x2c},
+	{0x3605, 0x50},
+	{0x3609, 0xdb},
+	{0x3610, 0x39},
+	{0x360c, 0x01},
+	{0x3628, 0xa4},
+	{0x362d, 0x10},
+	{0x3660, 0xd3}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
+	{0x3662, 0x00},
+	{0x3663, 0x28},
+	{0x3664, 0x0d},
+	{0x366a, 0x38},
+	{0x366b, 0xa0},
+	{0x366d, 0x00},
+	{0x366e, 0x00},
+	{0x3680, 0x00},
+	{0x36c0, 0x00},
+	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x373b, 0x02},
+	{0x373c, 0x02},
+	{0x3736, 0x02},
+	{0x3737, 0x02},
+	{0x3705, 0x00},
+	{0x3706, 0x72},
+	{0x370a, 0x01},
+	{0x370b, 0x30},
+	{0x3709, 0x48},
+	{0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x371c, 0x00},
+	{0x371d, 0x08},
+	{0x3740, 0x1b},
+	{0x3741, 0x04},
+	{0x375e, 0x0b},
+	{0x3760, 0x10},
+	{0x3776, 0x10},
+	{0x3781, 0x02},
+	{0x3782, 0x04},
+	{0x3783, 0x02},
+	{0x3784, 0x08},
+	{0x3785, 0x08},
+	{0x3788, 0x01},
+	{0x3789, 0x01},
+	{0x3797, 0x04},
+	{0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x0c},
+	{0x3804, 0x0e},
+	{0x3805, 0xff},
+	{0x3806, 0x08},
+	{0x3807, 0x6f},
+	{0x3808, 0x0f}, /* X output size (default 0x07) */
+	{0x3809, 0x00}, /* X output size (default 0x80) */
+	{0x380a, 0x08}, /* Y output size (default 0x04) */
+	{0x380b, 0x70}, /* Y output size (default 0x38) */
+	{0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
+	{0x380d, 0x14}, /* HTS[7:0],  total horizontal timing size */
+	{0x380e, 0x08}, /* VTS[15:8], total vertical timing (default 0x04) */
+	{0x380f, 0xf0}, /* VTS[7:0],  total vertical timing (default 0xA0) */
+	{0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
+	{0x3814, 0x01}, /* X INC ODD (default 0x01) */
+	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
+	{0x3816, 0x01}, /* Y INC ODD (default 0x01) */
+	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
+	{0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
+	{0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
+	{0x3821, 0x04}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
+	{0x3823, 0x08},
+	{0x3826, 0x00},
+	{0x3827, 0x08},
+	{0x382d, 0x08},
+	{0x3832, 0x02},
+	{0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
+	{0x383c, 0x48},
+	{0x383d, 0xff},
+	{0x3d85, 0x0b},
+	{0x3d84, 0x40},
+	{0x3d8c, 0x63},
+	{0x3d8d, 0xd7},
+	{0x4000, 0xf8},
+	{0x4001, 0x2b},
+	{0x4004, 0x00},
+	{0x4005, 0x40},
+	{0x400a, 0x01},
+	{0x400f, 0xa0},
+	{0x4010, 0x12},
+	{0x4018, 0x00},
+	{0x4008, 0x02},
+	{0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
+	{0x401a, 0x58},
+	{0x4050, 0x00},
+	{0x4051, 0x01},
+	{0x4028, 0x2f},
+	{0x4052, 0x00},
+	{0x4053, 0x80},
+	{0x4054, 0x00},
+	{0x4055, 0x80},
+	{0x4056, 0x00},
+	{0x4057, 0x80},
+	{0x4058, 0x00},
+	{0x4059, 0x80},
+	{0x430b, 0xff},
+	{0x430c, 0xff},
+	{0x430d, 0x00},
+	{0x430e, 0x00},
+	{0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
+	{0x4502, 0x00},
+	{0x4600, 0x00},
+	{0x4601, 0x20},
+	{0x4603, 0x01},
+	{0x4643, 0x00},
+	{0x4640, 0x01},
+	{0x4641, 0x04},
+	{0x4800, 0x64},
+	{0x4809, 0x2b},
+	{0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
+	{0x4817, 0x04},
+	{0x4833, 0x18},
+	{0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
+	{0x483b, 0x00},
+	{0x484b, 0x03},
+	{0x4850, 0x7c},
+	{0x4852, 0x06},
+	{0x4856, 0x58},
+	{0x4857, 0xaa},
+	{0x4862, 0x0a},
+	{0x4869, 0x18},
+	{0x486a, 0xaa},
+	{0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
+	{0x486f, 0x55},
+	{0x4875, 0xf0},
+	{0x5000, 0x89},
+	{0x5001, 0x42},
+	{0x5004, 0x40},
+	{0x5005, 0x00},
+	{0x5180, 0x00},
+	{0x5181, 0x10},
+	{0x580b, 0x03},
+	{0x4d00, 0x03},
+	{0x4d01, 0xc9},
+	{0x4d02, 0xbc},
+	{0x4d03, 0xc6},
+	{0x4d04, 0x4a},
+	{0x4d05, 0x25},
+	{0x4700, 0x2b},
+	{0x4e00, 0x2b},
+	{0x3501, 0x09}, /* Long exposure */
+	{0x3502, 0x01}, /* Long exposure */
+	{0x4028, 0x4f},
+	{0x4029, 0x1f},
+	{0x402a, 0x7f},
+	{0x402b, 0x01},
+	{0x0100, 0x01},
+};
+
+#endif
diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
new file mode 100644
index 000000000000..2ae79ebae436
--- /dev/null
+++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR10 HDR
+ * Copyright (C) 2024, NXP
+ * Copyright (C) 2024, Omnivision
+ * Copyright (C) 2024, Verisilicon
+ *
+ */
+
+#ifndef _OS08A20_REGS_4K_HDR_H_
+#define _OS08A20_REGS_4K_HDR_H_
+
+static struct ox05b1s_reg os08a20_init_setting_4k_hdr[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x0303, 0x01},
+	{0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
+	{0x0306, 0x00},
+	{0x0308, 0x03},
+	{0x0309, 0x04},
+	{0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
+	{0x300f, 0x11},
+	{0x3010, 0x01},
+	{0x3011, 0x04},
+	{0x3012, 0x41},
+	{0x3016, 0xf0},
+	{0x301e, 0x98},
+	{0x3031, 0xa9},
+	{0x3103, 0x92},
+	{0x3104, 0x01},
+	{0x3106, 0x10},
+	{0x340c, 0xff},
+	{0x340d, 0xff},
+	{0x031e, 0x09},
+	{0x3501, 0x08}, /* Long exposure */
+	{0x3502, 0xe5}, /* Long exposure */
+	{0x3505, 0x83},
+	{0x3508, 0x00}, /* Long gain */
+	{0x3509, 0x80}, /* Long gain */
+	{0x350a, 0x04},
+	{0x350b, 0x00},
+	{0x350c, 0x00},
+	{0x350d, 0x80},
+	{0x350e, 0x04},
+	{0x350f, 0x00},
+	{0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
+	{0x3603, 0x2c},
+	{0x3605, 0x50},
+	{0x3609, 0xb5},
+	{0x3610, 0x39},
+	{0x360c, 0x01},
+	{0x3628, 0xa4},
+	{0x362d, 0x10},
+	{0x3660, 0x42}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
+	{0x3661, 0x07}, /* CORE1 (default 0x06) bit[0]=stg_hdr_align_en */
+	{0x3662, 0x00},
+	{0x3663, 0x28},
+	{0x3664, 0x0d},
+	{0x366a, 0x38},
+	{0x366b, 0xa0},
+	{0x366d, 0x00},
+	{0x366e, 0x00},
+	{0x3680, 0x00},
+	{0x36c0, 0x00},
+	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x373b, 0x02},
+	{0x373c, 0x02},
+	{0x3736, 0x02},
+	{0x3737, 0x02},
+	{0x3705, 0x00},
+	{0x3706, 0x39},
+	{0x370a, 0x00},
+	{0x370b, 0x98},
+	{0x3709, 0x49},
+	{0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x371c, 0x00},
+	{0x371d, 0x08},
+	{0x3740, 0x1b},
+	{0x3741, 0x04},
+	{0x375e, 0x0b},
+	{0x3760, 0x10},
+	{0x3776, 0x10},
+	{0x3781, 0x02},
+	{0x3782, 0x04},
+	{0x3783, 0x02},
+	{0x3784, 0x08},
+	{0x3785, 0x08},
+	{0x3788, 0x01},
+	{0x3789, 0x01},
+	{0x3797, 0x04},
+	{0x3762, 0x11}, /* Sensor timing control registers 0x3700-0x37ff */
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x0c},
+	{0x3804, 0x0e},
+	{0x3805, 0xff},
+	{0x3806, 0x08},
+	{0x3807, 0x6f},
+	{0x3808, 0x0f}, /* X output size (default 0x07) */
+	{0x3809, 0x00}, /* X output size (default 0x80) */
+	{0x380a, 0x08}, /* Y output size (default 0x04) */
+	{0x380b, 0x70}, /* Y output size (default 0x38) */
+	{0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
+	{0x380d, 0x18}, /* HTS[7:0],  total horizontal timing size */
+	{0x380e, 0x09}, /* VTS[15:8], total vertical timing (default 0x04) */
+	{0x380f, 0x0a}, /* VTS[7:0],  total vertical timing (default 0xA0) */
+	{0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
+	{0x3814, 0x01}, /* X INC ODD (default 0x01) */
+	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
+	{0x3816, 0x01}, /* Y INC ODD (default 0x01) */
+	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
+	{0x381c, 0x08}, /* BLC_NUM_OPTION (default 0x0e) */
+	{0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
+	{0x3821, 0x24}, /* FORMAT2 bit[5]=stagger hdr en, bit[2]=mirror */
+	{0x3823, 0x08},
+	{0x3826, 0x00},
+	{0x3827, 0x08},
+	{0x382d, 0x08},
+	{0x3832, 0x02},
+	{0x3833, 0x01}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
+	{0x383c, 0x48},
+	{0x383d, 0xff},
+	{0x3d85, 0x0b},
+	{0x3d84, 0x40},
+	{0x3d8c, 0x63},
+	{0x3d8d, 0xd7},
+	{0x4000, 0xf8},
+	{0x4001, 0x2b},
+	{0x4004, 0x00},
+	{0x4005, 0x40},
+	{0x400a, 0x01},
+	{0x400f, 0xa0},
+	{0x4010, 0x12},
+	{0x4018, 0x00},
+	{0x4008, 0x02},
+	{0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
+	{0x401a, 0x58},
+	{0x4050, 0x00},
+	{0x4051, 0x01},
+	{0x4028, 0x2f},
+	{0x4052, 0x00},
+	{0x4053, 0x80},
+	{0x4054, 0x00},
+	{0x4055, 0x80},
+	{0x4056, 0x00},
+	{0x4057, 0x80},
+	{0x4058, 0x00},
+	{0x4059, 0x80},
+	{0x430b, 0xff},
+	{0x430c, 0xff},
+	{0x430d, 0x00},
+	{0x430e, 0x00},
+	{0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
+	{0x4502, 0x00},
+	{0x4643, 0x00},
+	{0x4640, 0x01},
+	{0x4641, 0x04},
+	{0x4800, 0x64},
+	{0x4809, 0x2b},
+	{0x4813, 0x98}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
+	{0x4817, 0x04},
+	{0x4833, 0x18},
+	{0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
+	{0x483b, 0x00},
+	{0x484b, 0x03},
+	{0x4850, 0x7c},
+	{0x4852, 0x06},
+	{0x4856, 0x58},
+	{0x4857, 0xaa},
+	{0x4862, 0x0a},
+	{0x4869, 0x18},
+	{0x486a, 0xaa},
+	{0x486e, 0x07}, /* MIPI CTRL 6E (default 0x03) */
+	{0x486f, 0x55},
+	{0x4875, 0xf0},
+	{0x5000, 0x89},
+	{0x5001, 0x42},
+	{0x5004, 0x40},
+	{0x5005, 0x00},
+	{0x5180, 0x00},
+	{0x5181, 0x10},
+	{0x580b, 0x03},
+	{0x4d00, 0x03},
+	{0x4d01, 0xc9},
+	{0x4d02, 0xbc},
+	{0x4d03, 0xc6},
+	{0x4d04, 0x4a},
+	{0x4d05, 0x25},
+	{0x4700, 0x2b},
+	{0x4e00, 0x2b},
+	{0x3501, 0x08}, /* Long exposure */
+	{0x3502, 0xe1}, /* Long exposure */
+	{0x3511, 0x00}, /* Short exposure */
+	{0x3512, 0x20}, /* Short exposure */
+	{0x3833, 0x01},
+};
+
+#endif
diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
index 5b9c069af19b..15559265d8f0 100644
--- a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
+++ b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
@@ -42,6 +42,7 @@ struct ox05b1s_sizes {
 	u32	sizes[OX05B1S_MAX_SIZES][2];
 };
 
+struct ox05b1s;
 struct ox05b1s_plat_data {
 	char				name[20];
 	u32				chip_id;
@@ -56,6 +57,9 @@ struct ox05b1s_plat_data {
 	u32				default_mode_index;
 	const struct ox05b1s_sizes	*supported_codes;
 	u32				supported_codes_count;
+	const char * const		*hdr_modes;
+	u32				hdr_modes_count;
+	int (*set_hdr_mode)(struct ox05b1s *sensor, u32 hdr_mode);
 };
 
 struct ox05b1s_ctrls {
@@ -66,6 +70,7 @@ struct ox05b1s_ctrls {
 	struct v4l2_ctrl *vblank;
 	struct v4l2_ctrl *gain;
 	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *hdr_mode;
 };
 
 struct ox05b1s_reg {
@@ -73,6 +78,9 @@ struct ox05b1s_reg {
 	u32 data;
 };
 
+#include "os08a20_regs_1080p.h"
+#include "os08a20_regs_4k.h"
+#include "os08a20_regs_4k_hdr.h"
 #include "ox05b1s_regs_5mp.h"
 
 struct ox05b1s_mode {
@@ -104,6 +112,68 @@ struct ox05b1s {
 	struct ox05b1s_ctrls ctrls;
 };
 
+static struct ox05b1s_mode os08a20_supported_modes[] = {
+	{
+		/* 1080p BGGR10, no hdr, 60fps */
+		.index		= 0,
+		.width		= 1920,
+		.height		= 1080,
+		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.bpp		= 10,
+		.vts		= 0x4a4,
+		.hts		= 0x790,
+		.exp		= 0x4a4 - 8,
+		.h_bin		= true,
+		.fps		= 60,
+		.reg_data	= os08a20_init_setting_1080p,
+		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_1080p),
+	},
+	{
+		/* 4k BGGR10, staggered hdr VC0/VC1, 15fps */
+		.index		= 1,
+		.width		= 3840,
+		.height		= 2160,
+		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.bpp		= 10,
+		.vts		= 0x90a,
+		.hts		= 0x818,
+		.exp		= 0x90a - 8,
+		.h_bin		= false,
+		.fps		= 15,
+		.reg_data	= os08a20_init_setting_4k_hdr,
+		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_4k_hdr),
+	},
+	{
+		/* 4k BGGR12, no hdr, 30fps */
+		.index		= 2,
+		.width		= 3840,
+		.height		= 2160,
+		.code		= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.bpp		= 12,
+		.vts		= 0x8f0,
+		.hts		= 0x814,
+		.exp		= 0x8f0 - 8,
+		.h_bin		= false,
+		.fps		= 30,
+		.reg_data	= os08a20_init_setting_4k,
+		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_4k),
+	},
+};
+
+/* keep in sync with os08a20_supported_modes*/
+static const struct ox05b1s_sizes os08a20_supported_codes[] = {
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.sizes_count = 2,
+		.sizes = { {1920, 1080}, {3840, 2160} }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.sizes_count = 1,
+		.sizes = { {3840, 2160} }
+	},
+};
+
 static struct ox05b1s_mode ox05b1s_supported_modes[] = {
 	{
 		.index		= 0,
@@ -210,6 +280,18 @@ static int ox05b1s_read_reg(struct ox05b1s *sensor, u16 reg, u8 *val)
 	return ret;
 }
 
+static int ox05b1s_update_bits(struct ox05b1s *sensor, u16 reg, unsigned int mask, u8 val)
+{
+	struct device *dev = &sensor->i2c_client->dev;
+	int ret = 0;
+
+	ret = regmap_update_bits(sensor->regmap, reg, mask, val);
+	if (ret < 0)
+		dev_err(dev, "Failed to update reg addr 0x%04x with 0x%02x\n", reg, val);
+
+	return ret;
+}
+
 #define OX05B1S_MAX_REG_BULK 16
 static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
 				   struct ox05b1s_reg *reg_array,
@@ -239,6 +321,67 @@ static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
 	return 0;
 }
 
+static const char * const os08a20_hdr_modes[] = {
+	"NO HDR",		/* No HDR, single exposure */
+	"HDR Staggered",	/* Staggered HDR mode, 2 exposures on separate virtual channels */
+};
+
+#define OS08A20_REG_CORE1		0x3661
+#define OS08A20_STG_HDR_ALIGN_EN	BIT(0)
+
+#define OS08A20_REG_FORMAT2		0x3821
+#define OS08A20_STG_HDR_EN		BIT(5)
+
+#define OS08A20_REG_MIPI_CTRL_13	0x4813
+#define OS08A20_MISTERY_BIT3		BIT(3)
+
+#define OS08A20_REG_MIPI_CTRL_6E	0x486e
+#define OS08A20_MIPI_VC_ENABLE		BIT(2)
+
+static int os08a20_enable_staggered_hdr(struct ox05b1s *sensor)
+{
+	int ret = 0;
+
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN,
+				   OS08A20_STG_HDR_ALIGN_EN);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN,
+				   OS08A20_STG_HDR_EN);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3,
+				   OS08A20_MISTERY_BIT3);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE,
+				   OS08A20_MIPI_VC_ENABLE);
+	if (ret)
+		ret = -EIO;
+
+	return ret;
+}
+
+static int os08a20_disable_staggered_hdr(struct ox05b1s *sensor)
+{
+	int ret = 0;
+
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN, 0);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN, 0);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3, 0);
+	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE, 0);
+	if (ret)
+		ret = -EIO;
+
+	return ret;
+}
+
+static int os08a20_set_hdr_mode(struct ox05b1s *sensor, u32 hdr_mode)
+{
+	switch (hdr_mode) {
+	case 0:
+		return os08a20_disable_staggered_hdr(sensor);
+	case 1:
+		return os08a20_enable_staggered_hdr(sensor);
+	default:
+		return -EINVAL;
+	}
+}
+
 static int ox05b1s_set_hts(struct ox05b1s *sensor, u32 hts)
 {
 	u8 values[2] = { (u8)(hts >> 8) & 0xff, (u8)(hts & 0xff) };
@@ -307,6 +450,12 @@ static int ox05b1s_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE:
 		ret = ox05b1s_set_exp(sensor, ctrl->val);
 		break;
+	case V4L2_CID_HDR_SENSOR_MODE:
+		if (sensor->model->set_hdr_mode)
+			ret = sensor->model->set_hdr_mode(sensor, ctrl->val);
+		else
+			ret = -EINVAL;
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -369,6 +518,13 @@ static int ox05b1s_init_controls(struct ox05b1s *sensor)
 	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
 					0, 0xFFFF, 1, 0x80);
 
+	if (sensor->model->hdr_modes)
+		ctrls->hdr_mode = v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_HDR_SENSOR_MODE,
+							       sensor->model->hdr_modes_count - 1,
+								0, 0, sensor->model->hdr_modes);
+	else
+		ctrls->hdr_mode = NULL;
+
 	if (hdl->error) {
 		ret = hdl->error;
 		goto free_ctrls;
@@ -670,7 +826,10 @@ static u8 ox05b1s_code2dt(const u32 code)
 {
 	switch (code) {
 	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
 		return MIPI_CSI2_DT_RAW10;
+	case MEDIA_BUS_FMT_SBGGR12_1X12:
+		return MIPI_CSI2_DT_RAW12;
 	default:
 		return MIPI_CSI2_DT_RAW10;
 	}
@@ -775,6 +934,9 @@ static int ox05b1s_read_chip_id(struct ox05b1s *sensor)
 	}
 
 	switch (chip_id) {
+	case 0x530841:
+		camera_name = "os08a20";
+		break;
 	case 0x580542:
 		camera_name = "ox05b1s";
 		break;
@@ -915,6 +1077,26 @@ static void ox05b1s_remove(struct i2c_client *client)
 static DEFINE_RUNTIME_DEV_PM_OPS(ox05b1s_pm_ops, ox05b1s_runtime_suspend,
 				 ox05b1s_runtime_resume, NULL);
 
+static const struct ox05b1s_plat_data os08a20_data = {
+	.name			= "os08a20",
+	.chip_id		= 0x530841,
+	.native_width		= 3872, /* 16 dummy + 3840 active pixels + 16 dummy */
+	.native_height		= 2192, /* 16 dummy + 2160 active lines + 16 dummy */
+	.active_top		= 16,
+	.active_left		= 16,
+	.active_width		= 3840,
+	.active_height		= 2160,
+	.supported_modes	= os08a20_supported_modes,
+	.supported_modes_count	= ARRAY_SIZE(os08a20_supported_modes),
+	.default_mode_index	= 0,
+	.supported_codes	= os08a20_supported_codes,
+	.supported_codes_count	= ARRAY_SIZE(os08a20_supported_codes),
+	.hdr_modes		= os08a20_hdr_modes,
+	.hdr_modes_count	= ARRAY_SIZE(os08a20_hdr_modes),
+	.set_hdr_mode		= os08a20_set_hdr_mode,
+
+};
+
 static const struct ox05b1s_plat_data ox05b1s_data = {
 	.name			= "ox05b1s",
 	.chip_id		= 0x580542,
@@ -929,9 +1111,16 @@ static const struct ox05b1s_plat_data ox05b1s_data = {
 	.default_mode_index	= 0,
 	.supported_codes	= ox05b1s_supported_codes,
 	.supported_codes_count	= ARRAY_SIZE(ox05b1s_supported_codes),
+	.hdr_modes		= NULL,
+	.hdr_modes_count	= 0,
+	.set_hdr_mode		= NULL,
 };
 
 static const struct of_device_id ox05b1s_of_match[] = {
+	{
+		.compatible = "ovti,os08a20",
+		.data = &os08a20_data,
+	},
 	{
 		.compatible = "ovti,ox05b1s",
 		.data = &ox05b1s_data,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
@ 2024-10-29  6:14   ` Krzysztof Kozlowski
  2024-10-29 12:10     ` Laurent Pinchart
  2024-10-29 13:36     ` [EXT] " Mirela Rabulea
  2024-10-29 11:44   ` Bryan O'Donoghue
  1 sibling, 2 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29  6:14 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 28/10/2024 20:06, Mirela Rabulea wrote:
> Add bindings for OX05B1S sensor driver
> 
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>

<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.

Please kindly resend and include all necessary To/Cc entries.
</form letter>

Binding also looks very different than all other devices, so re-write it
starting from EXISTING GOOD bindings. Not some downstream stuff.

A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18

A nit, subject: drop second/last "driver". Bindings are for hardware,
not drivers.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw sensor driver
  2024-10-28 19:06 ` [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw " Mirela Rabulea
@ 2024-10-29  6:17   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29  6:17 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 28/10/2024 20:06, Mirela Rabulea wrote:
> Add a v4l2 subdevice driver for the Omnivision OX05B1S RGB-IR sensor.
> 
> The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an
> active array size of 2592 x 1944.
> 
> The following features are supported for OX05B1S:
> - Manual exposure an gain control support
> - vblank/hblank control support
> - Supported resolution: 2592 x 1944 @ 30fps (SGRBG10)

...

> +
> +static const struct v4l2_subdev_ops ox05b1s_subdev_ops = {
> +	.video = &ox05b1s_subdev_video_ops,
> +	.pad   = &ox05b1s_subdev_pad_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops ox05b1s_internal_ops = {
> +	.init_state = ox05b1s_init_state,
> +};
> +
> +static void ox05b1s_get_gpios(struct ox05b1s *sensor)
> +{
> +	struct device *dev = &sensor->i2c_client->dev;
> +
> +	sensor->rst_gpio = devm_gpiod_get_optional(dev, "reset",
> +						   GPIOD_OUT_HIGH);
> +	if (IS_ERR(sensor->rst_gpio))
> +		dev_warn(dev, "No sensor reset pin available");

Same comment as for clock further.

> +}
> +

...

> +static int ox05b1s_probe(struct i2c_client *client)
> +{
> +	int retval;
> +	struct device *dev = &client->dev;
> +	struct v4l2_subdev *sd;
> +	struct ox05b1s *sensor;
> +
> +	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
> +	if (!sensor)
> +		return -ENOMEM;
> +
> +	sensor->regmap = devm_regmap_init_i2c(client, &ox05b1s_regmap_config);
> +	if (IS_ERR(sensor->regmap)) {
> +		dev_err(dev, "Failed to allocate sensor register map\n");

Allocation errors never result with error msg. Unless you meant
something else than allocation, but then syntax is return dev_err_probe.

> +		return PTR_ERR(sensor->regmap);
> +	}
> +
> +	sensor->i2c_client = client;
> +
> +	sensor->model = of_device_get_match_data(dev);
> +
> +	ox05b1s_get_gpios(sensor);
> +
> +	sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
> +	if (IS_ERR(sensor->sensor_clk)) {
> +		sensor->sensor_clk = NULL;
> +		dev_warn(dev, "Sensor csi_mclk is missing, using oscillator from sensor module\n");

Nope, syntax is return dev_err_probe. Why would you warn on probe deferral?

> +	}
> +


...

> +
> +module_i2c_driver(ox05b1s_i2c_driver);
> +MODULE_DESCRIPTION("Omnivision OX05B1S MIPI Camera Subdev Driver");
> +MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h b/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h
> new file mode 100644
> index 000000000000..3c34724c1d7e
> --- /dev/null
> +++ b/drivers/media/i2c/ox05b1s/ox05b1s_regs_5mp.h
> @@ -0,0 +1,1160 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * A register configuration for Omnivision OX05B1S raw camera, 2592 x 1944 @30fps BGGR10
> + * Copyright (C) 2024, NXP
> + * Copyright (C) 2024, Omnivision
> + *
> + */
> +#ifndef _OX05B1S_REGS_2592x1944_H_
> +#define _OX05B1S_REGS_2592x1944_H_
> +
> +/* 2592X1944_30FPS_FULL_RGBIr 2592 1944 */
> +static struct ox05b1s_reg ovx5b_init_setting_2592x1944[] = {

How this could be in the header? Why do you need multiple of copies of
it? No, move to the driver.



Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20
  2024-10-28 19:06 ` [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20 Mirela Rabulea
@ 2024-10-29  6:17   ` Krzysztof Kozlowski
  2024-10-29 14:02     ` [EXT] " Mirela Rabulea
  0 siblings, 1 reply; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29  6:17 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 28/10/2024 20:06, Mirela Rabulea wrote:
> Add another compatible for OS08A20 sensor.
> 
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> ---
>  Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml | 1 +

This is part of the original binding. Submit complete binding in one patch.

A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18

<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.

Please kindly resend and include all necessary To/Cc entries.
</form letter>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
  2024-10-29  6:14   ` Krzysztof Kozlowski
@ 2024-10-29 11:44   ` Bryan O'Donoghue
  2024-10-29 11:57     ` Laurent Pinchart
  1 sibling, 1 reply; 28+ messages in thread
From: Bryan O'Donoghue @ 2024-10-29 11:44 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 28/10/2024 19:06, Mirela Rabulea wrote:
> Add bindings for OX05B1S sensor driver
> 
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> ---
>   .../bindings/media/i2c/ovti,ox05b1s.yaml      | 109 ++++++++++++++++++
>   1 file changed, 109 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> new file mode 100644
> index 000000000000..d47e1950f24d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> @@ -0,0 +1,109 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright (C) 2024, NXP
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/ovti,ox05b1s.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Omnivision OX05B1S Image Sensor
> +
> +maintainers:
> +  - Mirela Rabulea <mirela.rabulea@nxp.com>
> +
> +description: |-
> +  The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an active array size
> +  of 2592 x 1944. It is programmable through I2C interface.
> +  The sensor output is available via CSI-2 serial data output.
> +

You should add

+allOf:
+  - $ref: /schemas/media/video-interface-devices.yaml#

> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - ovti,ox05b1s
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    description: Input clock (24 MHz)
> +    items:
> +      - const: csi_mclk
> +
> +  assigned-clocks:
> +    maxItems: 1
> +
> +  assigned-clock-parents:
> +    maxItems: 1
> +
> +  assigned-clock-rates:
> +    maxItems: 1
> +

assigned-clock* should be dropped.

https://lore.kernel.org/all/20241025-b4-linux-next-202041004-i2c-media-yaml-fixes-v2-1-1b4535174a5a@linaro.org/

> +
> +  orientation: true
> +  rotation: true

I think you can drop both of these too.

> +
> +  port:
> +    $ref: /schemas/graph.yaml#/$defs/port-base
> +    additionalProperties: false
> +    description: MIPI CSI-2 transmitter port
> +
> +    properties:
> +      endpoint:
> +        $ref: /schemas/media/video-interfaces.yaml#
> +        unevaluatedProperties: false
> +
> +        properties:
> +          data-lanes:
> +            anyOf:
> +              - items:
> +                  - const: 1
> +                  - const: 2
> +              - items:
> +                  - const: 1
> +                  - const: 2
> +                  - const: 3
> +                  - const: 4
> +        required:
> +          - data-lanes
> +
> +    required:
> +      - endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - port
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        ox05b1s: ox05b1s@36 {
> +            compatible = "ovti,ox05b1s";
> +            reg = <0x36>;
> +            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;
> +            orientation = <2>;
> +            rotation = <0>;
> +            status = "okay";

You should include assigned-clock* here in the example.

> +
> +            port {
> +                ox05b1s_mipi_0_ep: endpoint {
> +                    remote-endpoint = <&mipi_csi0_ep>;
> +                    data-lanes = <1 2 3 4>;
> +                };
> +            };
> +        };
> +    };
> +...

---
bod

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 11:44   ` Bryan O'Donoghue
@ 2024-10-29 11:57     ` Laurent Pinchart
  2024-10-29 12:00       ` Bryan O'Donoghue
  2024-10-30  6:02       ` Mirela Rabulea
  0 siblings, 2 replies; 28+ messages in thread
From: Laurent Pinchart @ 2024-10-29 11:57 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On Tue, Oct 29, 2024 at 11:44:33AM +0000, Bryan O'Donoghue wrote:
> On 28/10/2024 19:06, Mirela Rabulea wrote:
> > Add bindings for OX05B1S sensor driver
> > 
> > Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> > ---
> >   .../bindings/media/i2c/ovti,ox05b1s.yaml      | 109 ++++++++++++++++++
> >   1 file changed, 109 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> > new file mode 100644
> > index 000000000000..d47e1950f24d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml
> > @@ -0,0 +1,109 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +# Copyright (C) 2024, NXP
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/i2c/ovti,ox05b1s.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Omnivision OX05B1S Image Sensor
> > +
> > +maintainers:
> > +  - Mirela Rabulea <mirela.rabulea@nxp.com>
> > +
> > +description: |-
> > +  The Omnivision OX05B1S is a 1/2.5-Inch CMOS image sensor with an active array size

Reflow to 80 columns.

> > +  of 2592 x 1944. It is programmable through I2C interface.
> > +  The sensor output is available via CSI-2 serial data output.
> > +
> 
> You should add
> 
> +allOf:
> +  - $ref: /schemas/media/video-interface-devices.yaml#
> 
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - ovti,ox05b1s
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  clock-names:
> > +    description: Input clock (24 MHz)
> > +    items:
> > +      - const: csi_mclk

If there's a single clock you can drop the name.

How about regulators ?

> > +
> > +  assigned-clocks:
> > +    maxItems: 1
> > +
> > +  assigned-clock-parents:
> > +    maxItems: 1
> > +
> > +  assigned-clock-rates:
> > +    maxItems: 1
> > +
> 
> assigned-clock* should be dropped.
> 
> https://lore.kernel.org/all/20241025-b4-linux-next-202041004-i2c-media-yaml-fixes-v2-1-1b4535174a5a@linaro.org/

Agreed.

> > +
> > +  orientation: true
> > +  rotation: true
> 
> I think you can drop both of these too.

Aren't they needed given that the binding ends with

additionalProperties: false

?

> > +
> > +  port:
> > +    $ref: /schemas/graph.yaml#/$defs/port-base
> > +    additionalProperties: false
> > +    description: MIPI CSI-2 transmitter port
> > +
> > +    properties:
> > +      endpoint:
> > +        $ref: /schemas/media/video-interfaces.yaml#
> > +        unevaluatedProperties: false
> > +
> > +        properties:
> > +          data-lanes:
> > +            anyOf:
> > +              - items:
> > +                  - const: 1
> > +                  - const: 2
> > +              - items:
> > +                  - const: 1
> > +                  - const: 2
> > +                  - const: 3
> > +                  - const: 4
> > +        required:
> > +          - data-lanes
> > +
> > +    required:
> > +      - endpoint
> > +
> > +required:
> > +  - compatible
> > +  - reg

The device requires a clock, shouldn't the clocks property be required ?

> > +  - port
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +
> > +    i2c {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        ox05b1s: ox05b1s@36 {
> > +            compatible = "ovti,ox05b1s";
> > +            reg = <0x36>;
> > +            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;

This isn't specified in the bindings. Does the example validate ?

> > +            orientation = <2>;
> > +            rotation = <0>;
> > +            status = "okay";
> 
> You should include assigned-clock* here in the example.

Is that mandatory ? I'd rather omit it, I think it only adds noise.

> > +
> > +            port {
> > +                ox05b1s_mipi_0_ep: endpoint {
> > +                    remote-endpoint = <&mipi_csi0_ep>;
> > +                    data-lanes = <1 2 3 4>;
> > +                };
> > +            };
> > +        };
> > +    };
> > +...

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 11:57     ` Laurent Pinchart
@ 2024-10-29 12:00       ` Bryan O'Donoghue
  2024-10-30  6:08         ` [EXT] " Mirela Rabulea
  2024-10-30  6:02       ` Mirela Rabulea
  1 sibling, 1 reply; 28+ messages in thread
From: Bryan O'Donoghue @ 2024-10-29 12:00 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On 29/10/2024 11:57, Laurent Pinchart wrote:
> Aren't they needed given that the binding ends with
> 
> additionalProperties: false

Yes.

Might be nice to have

unevaluatedProperties: false and just rely on the top level

$ref: /schemas/media/video-interface-devices.yaml#

Seems redundant to me to keep specifying these properties over and over 
again.

---
bod

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29  6:14   ` Krzysztof Kozlowski
@ 2024-10-29 12:10     ` Laurent Pinchart
  2024-10-29 12:15       ` Krzysztof Kozlowski
  2024-10-29 13:36     ` [EXT] " Mirela Rabulea
  1 sibling, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2024-10-29 12:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
> On 28/10/2024 20:06, Mirela Rabulea wrote:
> > Add bindings for OX05B1S sensor driver
> > 
> > Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> 
> <form letter>
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
> 
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline) or work on fork of kernel
> (don't, instead use mainline). Just use b4 and everything should be
> fine, although remember about `b4 prep --auto-to-cc` if you added new
> patches to the patchset.
> 
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time.
> 
> Please kindly resend and include all necessary To/Cc entries.
> </form letter>
> 
> Binding also looks very different than all other devices, so re-write it
> starting from EXISTING GOOD bindings. Not some downstream stuff.

Krzysztof, please point to a good example when making this kind of
comment.

> A nit, subject: drop second/last, redundant "bindings". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
> 
> A nit, subject: drop second/last "driver". Bindings are for hardware,
> not drivers.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:10     ` Laurent Pinchart
@ 2024-10-29 12:15       ` Krzysztof Kozlowski
  2024-10-29 12:21         ` Laurent Pinchart
  0 siblings, 1 reply; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29 12:15 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On 29/10/2024 13:10, Laurent Pinchart wrote:
> On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
>> On 28/10/2024 20:06, Mirela Rabulea wrote:
>>> Add bindings for OX05B1S sensor driver
>>>
>>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>>
>> <form letter>
>> Please use scripts/get_maintainers.pl to get a list of necessary people
>> and lists to CC. It might happen, that command when run on an older
>> kernel, gives you outdated entries. Therefore please be sure you base
>> your patches on recent Linux kernel.
>>
>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>> people, so fix your workflow. Tools might also fail if you work on some
>> ancient tree (don't, instead use mainline) or work on fork of kernel
>> (don't, instead use mainline). Just use b4 and everything should be
>> fine, although remember about `b4 prep --auto-to-cc` if you added new
>> patches to the patchset.
>>
>> You missed at least devicetree list (maybe more), so this won't be
>> tested by automated tooling. Performing review on untested code might be
>> a waste of time.
>>
>> Please kindly resend and include all necessary To/Cc entries.
>> </form letter>
>>
>> Binding also looks very different than all other devices, so re-write it
>> starting from EXISTING GOOD bindings. Not some downstream stuff.
> 
> Krzysztof, please point to a good example when making this kind of
> comment.

Anything recently added. Git log tells which files were recently added.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:15       ` Krzysztof Kozlowski
@ 2024-10-29 12:21         ` Laurent Pinchart
  2024-10-29 12:28           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2024-10-29 12:21 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On Tue, Oct 29, 2024 at 01:15:46PM +0100, Krzysztof Kozlowski wrote:
> On 29/10/2024 13:10, Laurent Pinchart wrote:
> > On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
> >> On 28/10/2024 20:06, Mirela Rabulea wrote:
> >>> Add bindings for OX05B1S sensor driver
> >>>
> >>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> >>
> >> <form letter>
> >> Please use scripts/get_maintainers.pl to get a list of necessary people
> >> and lists to CC. It might happen, that command when run on an older
> >> kernel, gives you outdated entries. Therefore please be sure you base
> >> your patches on recent Linux kernel.
> >>
> >> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> >> people, so fix your workflow. Tools might also fail if you work on some
> >> ancient tree (don't, instead use mainline) or work on fork of kernel
> >> (don't, instead use mainline). Just use b4 and everything should be
> >> fine, although remember about `b4 prep --auto-to-cc` if you added new
> >> patches to the patchset.
> >>
> >> You missed at least devicetree list (maybe more), so this won't be
> >> tested by automated tooling. Performing review on untested code might be
> >> a waste of time.
> >>
> >> Please kindly resend and include all necessary To/Cc entries.
> >> </form letter>
> >>
> >> Binding also looks very different than all other devices, so re-write it
> >> starting from EXISTING GOOD bindings. Not some downstream stuff.
> > 
> > Krzysztof, please point to a good example when making this kind of
> > comment.
> 
> Anything recently added. Git log tells which files were recently added.

If the review comment is a copy&paste (given that you review lots of
bindings and constantly have to repeat the same things, that would make
sense), expanding it with that information for future reviews could help
patch authors. Thanks for considering it, it would be much appreciated.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:21         ` Laurent Pinchart
@ 2024-10-29 12:28           ` Krzysztof Kozlowski
  2024-10-29 12:46             ` Laurent Pinchart
  0 siblings, 1 reply; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29 12:28 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

On 29/10/2024 13:21, Laurent Pinchart wrote:
> On Tue, Oct 29, 2024 at 01:15:46PM +0100, Krzysztof Kozlowski wrote:
>> On 29/10/2024 13:10, Laurent Pinchart wrote:
>>> On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
>>>> On 28/10/2024 20:06, Mirela Rabulea wrote:
>>>>> Add bindings for OX05B1S sensor driver
>>>>>
>>>>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>>>>
>>>> <form letter>
>>>> Please use scripts/get_maintainers.pl to get a list of necessary people
>>>> and lists to CC. It might happen, that command when run on an older
>>>> kernel, gives you outdated entries. Therefore please be sure you base
>>>> your patches on recent Linux kernel.
>>>>
>>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>>>> people, so fix your workflow. Tools might also fail if you work on some
>>>> ancient tree (don't, instead use mainline) or work on fork of kernel
>>>> (don't, instead use mainline). Just use b4 and everything should be
>>>> fine, although remember about `b4 prep --auto-to-cc` if you added new
>>>> patches to the patchset.
>>>>
>>>> You missed at least devicetree list (maybe more), so this won't be
>>>> tested by automated tooling. Performing review on untested code might be
>>>> a waste of time.
>>>>
>>>> Please kindly resend and include all necessary To/Cc entries.
>>>> </form letter>
>>>>
>>>> Binding also looks very different than all other devices, so re-write it
>>>> starting from EXISTING GOOD bindings. Not some downstream stuff.
>>>
>>> Krzysztof, please point to a good example when making this kind of
>>> comment.
>>
>> Anything recently added. Git log tells which files were recently added.
> 
> If the review comment is a copy&paste (given that you review lots of
> bindings and constantly have to repeat the same things, that would make
> sense), expanding it with that information for future reviews could help
> patch authors. Thanks for considering it, it would be much appreciated.

Sorry, but that's not the point. You do not take 10 yo, unmaintained
driver and use it as template for your new one. Instead you rather take
something recent or something which you know is correct. Same with bindings.

NXP is not a small company which does not know how to use Linux or how
to upstream stuff. This is not individual's contribution, where one does
not have colleagues or 3 billions USD of revenue behind, to be able to
get some internal help prior sending something downstream.

They can spend something out of these 3 billions of revenue or 700
millions of net income to hire you guys or any other open-source
company, if basics of upstreaming are unknown.

That's the comment I was giving about NXP since a year. Some things
around SoC improved, some things from this unit of NXP here did not
change at all.

So again, it's not about me giving them more things. They will keep
ignoring it over and over, because that's how big companies sometimes
behave. You know, community people work for free, right?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:28           ` Krzysztof Kozlowski
@ 2024-10-29 12:46             ` Laurent Pinchart
  2024-10-29 12:47               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2024-10-29 12:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan, devicetree

(CC'ing the devicetree mailing list)

On Tue, Oct 29, 2024 at 01:28:51PM +0100, Krzysztof Kozlowski wrote:
> On 29/10/2024 13:21, Laurent Pinchart wrote:
> > On Tue, Oct 29, 2024 at 01:15:46PM +0100, Krzysztof Kozlowski wrote:
> >> On 29/10/2024 13:10, Laurent Pinchart wrote:
> >>> On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
> >>>> On 28/10/2024 20:06, Mirela Rabulea wrote:
> >>>>> Add bindings for OX05B1S sensor driver
> >>>>>
> >>>>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> >>>>
> >>>> <form letter>
> >>>> Please use scripts/get_maintainers.pl to get a list of necessary people
> >>>> and lists to CC. It might happen, that command when run on an older
> >>>> kernel, gives you outdated entries. Therefore please be sure you base
> >>>> your patches on recent Linux kernel.
> >>>>
> >>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> >>>> people, so fix your workflow. Tools might also fail if you work on some
> >>>> ancient tree (don't, instead use mainline) or work on fork of kernel
> >>>> (don't, instead use mainline). Just use b4 and everything should be
> >>>> fine, although remember about `b4 prep --auto-to-cc` if you added new
> >>>> patches to the patchset.
> >>>>
> >>>> You missed at least devicetree list (maybe more), so this won't be
> >>>> tested by automated tooling. Performing review on untested code might be
> >>>> a waste of time.
> >>>>
> >>>> Please kindly resend and include all necessary To/Cc entries.
> >>>> </form letter>
> >>>>
> >>>> Binding also looks very different than all other devices, so re-write it
> >>>> starting from EXISTING GOOD bindings. Not some downstream stuff.
> >>>
> >>> Krzysztof, please point to a good example when making this kind of
> >>> comment.
> >>
> >> Anything recently added. Git log tells which files were recently added.
> > 
> > If the review comment is a copy&paste (given that you review lots of
> > bindings and constantly have to repeat the same things, that would make
> > sense), expanding it with that information for future reviews could help
> > patch authors. Thanks for considering it, it would be much appreciated.
> 
> Sorry, but that's not the point. You do not take 10 yo, unmaintained
> driver and use it as template for your new one. Instead you rather take
> something recent or something which you know is correct. Same with bindings.

I wouldn't know for sure which driver or binding was used as a starting
point. My point was unrelated to this particular patch series. I think
that including clear information in ready-made answers will help
everybody. It will tell the submitters what they need to know, it will
avoid this kind of conversation being repeated, and it could even in the
end increase the quality of submissions. Even better, it won't cost
anything to add it to answer templates.

> NXP is not a small company which does not know how to use Linux or how
> to upstream stuff. This is not individual's contribution, where one does
> not have colleagues or 3 billions USD of revenue behind, to be able to
> get some internal help prior sending something downstream.
> 
> They can spend something out of these 3 billions of revenue or 700
> millions of net income to hire you guys or any other open-source
> company, if basics of upstreaming are unknown.
>
> That's the comment I was giving about NXP since a year. Some things
> around SoC improved, some things from this unit of NXP here did not
> change at all.

If I were on the receiving end of this, as an individual developer, I
would consider it very patronizing and insulting. Treating the authors
of contributions you don't consider as good enough in such a harsh way
will not improve the situation, and will drive people away. You may be
frustrated by some companies, but this kind of comment will not help.
Please soften your tone towards individual developers, they're not
punching balls on which to dump frustration and anger. Firm and polite
will work better than lashing out.

> So again, it's not about me giving them more things. They will keep
> ignoring it over and over, because that's how big companies sometimes
> behave. You know, community people work for free, right?

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:46             ` Laurent Pinchart
@ 2024-10-29 12:47               ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29 12:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan, devicetree

On 29/10/2024 13:46, Laurent Pinchart wrote:
> (CC'ing the devicetree mailing list)
> 
> On Tue, Oct 29, 2024 at 01:28:51PM +0100, Krzysztof Kozlowski wrote:
>> On 29/10/2024 13:21, Laurent Pinchart wrote:
>>> On Tue, Oct 29, 2024 at 01:15:46PM +0100, Krzysztof Kozlowski wrote:
>>>> On 29/10/2024 13:10, Laurent Pinchart wrote:
>>>>> On Tue, Oct 29, 2024 at 07:14:28AM +0100, Krzysztof Kozlowski wrote:
>>>>>> On 28/10/2024 20:06, Mirela Rabulea wrote:
>>>>>>> Add bindings for OX05B1S sensor driver
>>>>>>>
>>>>>>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>>>>>>
>>>>>> <form letter>
>>>>>> Please use scripts/get_maintainers.pl to get a list of necessary people
>>>>>> and lists to CC. It might happen, that command when run on an older
>>>>>> kernel, gives you outdated entries. Therefore please be sure you base
>>>>>> your patches on recent Linux kernel.
>>>>>>
>>>>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>>>>>> people, so fix your workflow. Tools might also fail if you work on some
>>>>>> ancient tree (don't, instead use mainline) or work on fork of kernel
>>>>>> (don't, instead use mainline). Just use b4 and everything should be
>>>>>> fine, although remember about `b4 prep --auto-to-cc` if you added new
>>>>>> patches to the patchset.
>>>>>>
>>>>>> You missed at least devicetree list (maybe more), so this won't be
>>>>>> tested by automated tooling. Performing review on untested code might be
>>>>>> a waste of time.
>>>>>>
>>>>>> Please kindly resend and include all necessary To/Cc entries.
>>>>>> </form letter>
>>>>>>
>>>>>> Binding also looks very different than all other devices, so re-write it
>>>>>> starting from EXISTING GOOD bindings. Not some downstream stuff.
>>>>>
>>>>> Krzysztof, please point to a good example when making this kind of
>>>>> comment.
>>>>
>>>> Anything recently added. Git log tells which files were recently added.
>>>
>>> If the review comment is a copy&paste (given that you review lots of
>>> bindings and constantly have to repeat the same things, that would make
>>> sense), expanding it with that information for future reviews could help
>>> patch authors. Thanks for considering it, it would be much appreciated.
>>
>> Sorry, but that's not the point. You do not take 10 yo, unmaintained
>> driver and use it as template for your new one. Instead you rather take
>> something recent or something which you know is correct. Same with bindings.
> 
> I wouldn't know for sure which driver or binding was used as a starting
> point. My point was unrelated to this particular patch series. I think
> that including clear information in ready-made answers will help
> everybody. It will tell the submitters what they need to know, it will
> avoid this kind of conversation being repeated, and it could even in the
> end increase the quality of submissions. Even better, it won't cost
> anything to add it to answer templates.
> 
>> NXP is not a small company which does not know how to use Linux or how
>> to upstream stuff. This is not individual's contribution, where one does
>> not have colleagues or 3 billions USD of revenue behind, to be able to
>> get some internal help prior sending something downstream.
>>
>> They can spend something out of these 3 billions of revenue or 700
>> millions of net income to hire you guys or any other open-source
>> company, if basics of upstreaming are unknown.
>>
>> That's the comment I was giving about NXP since a year. Some things
>> around SoC improved, some things from this unit of NXP here did not
>> change at all.
> 
> If I were on the receiving end of this, as an individual developer, I
> would consider it very patronizing and insulting. Treating the authors
> of contributions you don't consider as good enough in such a harsh way
> will not improve the situation, and will drive people away. You may be
> frustrated by some companies, but this kind of comment will not help.
> Please soften your tone towards individual developers, they're not
> punching balls on which to dump frustration and anger. Firm and polite
> will work better than lashing out.

I would be very happy to tell it to the managers, decision makers and
CEOs, but they avoid me. :/

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29  6:14   ` Krzysztof Kozlowski
  2024-10-29 12:10     ` Laurent Pinchart
@ 2024-10-29 13:36     ` Mirela Rabulea
  2024-10-29 13:49       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-29 13:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

Hi Krzysztof,

thanks for feedback.

On 29.10.2024 08:14, Krzysztof Kozlowski wrote:
> On 28/10/2024 20:06, Mirela Rabulea wrote:
>> Add bindings for OX05B1S sensor driver
>>
>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> <form letter>
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
>
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline) or work on fork of kernel
> (don't, instead use mainline). Just use b4 and everything should be
> fine, although remember about `b4 prep --auto-to-cc` if you added new
> patches to the patchset.
>
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time.
My bad, I ran get_maintainer.pl on the driver, but forgot to do so for 
the bindings. I will resend to extended audience, once I will also 
address the feedback from all reviewers.
>
> Please kindly resend and include all necessary To/Cc entries.
> </form letter>
>
> Binding also looks very different than all other devices, so re-write it
> starting from EXISTING GOOD bindings. Not some downstream stuff.
Would this be a good example? 
Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
>
> A nit, subject: drop second/last, redundant "bindings". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
>
> A nit, subject: drop second/last "driver". Bindings are for hardware,
> not drivers.

I will rephrase it to:

dt-bindings: media: i2c: Add OX05B1S sensor

Add bindings for OX05B1S sensor.

Thanks,

Mirela

>
> Best regards,
> Krzysztof
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 13:36     ` [EXT] " Mirela Rabulea
@ 2024-10-29 13:49       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29 13:49 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 29/10/2024 14:36, Mirela Rabulea wrote:
>>
>> Binding also looks very different than all other devices, so re-write it
>> starting from EXISTING GOOD bindings. Not some downstream stuff.
> Would this be a good example? 
> Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml

Yes, looks good.

>>
>> A nit, subject: drop second/last, redundant "bindings". The
>> "dt-bindings" prefix is already stating that these are bindings.
>> See also:
>> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
>>
>> A nit, subject: drop second/last "driver". Bindings are for hardware,
>> not drivers.
> 

Please correct the example so it matches coding style. Just compare how
your DTS and imx DTS look like.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20
  2024-10-29  6:17   ` Krzysztof Kozlowski
@ 2024-10-29 14:02     ` Mirela Rabulea
  2024-10-29 16:46       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-29 14:02 UTC (permalink / raw)
  To: Krzysztof Kozlowski, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan


On 29.10.2024 08:17, Krzysztof Kozlowski wrote:
> On 28/10/2024 20:06, Mirela Rabulea wrote:
>> Add another compatible for OS08A20 sensor.
>>
>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>> ---
>>   Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml | 1 +
> This is part of the original binding. Submit complete binding in one patch.

Hi Krzysztof,

Should I squash this patch into #1?

I sent the patch #1, #2 and #3 for the OX05B1S sensor, and patches #4 
and #5 as additions for another sensor, OS08A20.

Thanks,

Mirela



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20
  2024-10-29 14:02     ` [EXT] " Mirela Rabulea
@ 2024-10-29 16:46       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2024-10-29 16:46 UTC (permalink / raw)
  To: Mirela Rabulea, mchehab, sakari.ailus, hverkuil-cisco,
	laurent.pinchart+renesas, laurentiu.palcu, robert.chiras
  Cc: linux-media, linux-kernel, LnxRevLi, kieran.bingham, hdegoede,
	dave.stevenson, mike.rudenko, alain.volmat, julien.vuillaumier,
	alice.yuan

On 29/10/2024 15:02, Mirela Rabulea wrote:
> 
> On 29.10.2024 08:17, Krzysztof Kozlowski wrote:
>> On 28/10/2024 20:06, Mirela Rabulea wrote:
>>> Add another compatible for OS08A20 sensor.
>>>
>>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>>> ---
>>>   Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.yaml | 1 +
>> This is part of the original binding. Submit complete binding in one patch.
> 
> Hi Krzysztof,
> 
> Should I squash this patch into #1?

Yes, please. Splitting initial binding into such small chunks is not
necessary.

> 
> I sent the patch #1, #2 and #3 for the OX05B1S sensor, and patches #4 
> and #5 as additions for another sensor, OS08A20.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 11:57     ` Laurent Pinchart
  2024-10-29 12:00       ` Bryan O'Donoghue
@ 2024-10-30  6:02       ` Mirela Rabulea
  2024-11-04 14:25         ` Laurent Pinchart
  1 sibling, 1 reply; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-30  6:02 UTC (permalink / raw)
  To: Laurent Pinchart, Bryan O'Donoghue
  Cc: mchehab, sakari.ailus, hverkuil-cisco, laurentiu.palcu,
	robert.chiras, linux-media, linux-kernel, LnxRevLi,
	kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hi Laurent,

thanks for feedback.

On 29.10.2024 13:57, Laurent Pinchart wrote:
>>> +
>>> +  orientation: true
>>> +  rotation: true
>> I think you can drop both of these too.
> Aren't they needed given that the binding ends with
>
> additionalProperties: false
>
> ?
I added orientation & rotation properties in order to support 
orientation and rotation controls, libcamera warns about those (optional 
requirements last time I checked).
>>> +
>>> +required:
>>> +  - compatible
>>> +  - reg
> The device requires a clock, shouldn't the clocks property be required ?

I intentionally left the clock optional, because NXP has a converter 
board which supports both ox05b1s and os08a20 sensor, and the converter 
board has an oscillator, and we are using that, not the SOC clock.

Here is how the module looks like for os08a20 for imx8mp:

https://docs.nxp.com/bundle/AN13712/page/topics/os08a20_sensor_module.html

There's a newer revision for the converter board for imx95, sorry but I 
do not have a link for that.

For imx8mp, we used in the past the clock from the SOC, then switched to 
the external clock (from the converter board).

I think Omnivision has their own module.

So, I thought leaving the clock as optional allows for more flexibility.

>
>>> +  - port
>>> +
>>> +additionalProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    #include <dt-bindings/gpio/gpio.h>
>>> +
>>> +    i2c {
>>> +        #address-cells = <1>;
>>> +        #size-cells = <0>;
>>> +
>>> +        ox05b1s: ox05b1s@36 {
>>> +            compatible = "ovti,ox05b1s";
>>> +            reg = <0x36>;
>>> +            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;
> This isn't specified in the bindings. Does the example validate ?

Apparently yes, I mean dt_binding_check passed:

$ rm Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb

$ make dt_binding_check DT_CHECKER_FLAGS=-m 
DT_SCHEMA_FILES=ovti,ox05b1s.yaml
   DTC [C] 
Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb

I have dtschema-2024.10.dev6+g12c3cd5.


The "reset-gpios" is described in this binding, as the GPIO connected to 
the XSHUTDOWN pin.

The <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW> is what works for imx95 
("nxp,pcal6408"), for imx8mp this works:

reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;


Thanks,

Mirela


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-29 12:00       ` Bryan O'Donoghue
@ 2024-10-30  6:08         ` Mirela Rabulea
  0 siblings, 0 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-10-30  6:08 UTC (permalink / raw)
  To: Bryan O'Donoghue, Laurent Pinchart
  Cc: mchehab, sakari.ailus, hverkuil-cisco, laurentiu.palcu,
	robert.chiras, linux-media, linux-kernel, LnxRevLi,
	kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hi Bryan,

thanks for feedback.

On 29.10.2024 14:00, Bryan O'Donoghue wrote:
>
> On 29/10/2024 11:57, Laurent Pinchart wrote:
>> Aren't they needed given that the binding ends with
>>
>> additionalProperties: false
>
> Yes.
>
> Might be nice to have
>
> unevaluatedProperties: false and just rely on the top level
>
> $ref: /schemas/media/video-interface-devices.yaml#
>
> Seems redundant to me to keep specifying these properties over and over
> again.
>
> ---
> bod


I'm not sure I understand all the implications of unevaluatedProperties: 
false.

Does this mean that I will have to add false for properties from 
video-interface-devices.yaml which should, maybe, not be allowed 
(lens-focus, flash-leds)?


Thanks,

Mirela



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor
  2024-10-28 19:06 ` [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor Mirela Rabulea
@ 2024-11-01 12:08   ` Sakari Ailus
  2024-11-04 13:21     ` [EXT] " Mirela Rabulea
  0 siblings, 1 reply; 28+ messages in thread
From: Sakari Ailus @ 2024-11-01 12:08 UTC (permalink / raw)
  To: Mirela Rabulea
  Cc: mchehab, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hi Mirela,

Thanks set the set.

On Mon, Oct 28, 2024 at 09:06:28PM +0200, Mirela Rabulea wrote:
> This is an 8 megapixel raw10/raw12 sensor with HDR capabilities.
> HDR mode control is supported, with one hdr mode: staggered HDR with
> 2 exposures on separate virtual channels.

The patch still declares just one via get_frame_desc (as there are no
changes). I think we need more documentation on this, including sensor
specific documentation on the HDR mode as the interfaces don't provide it
all. There's Documentation/userspace-api/media/drivers/st-vgxy61.rst that
describes the existing usage of the control. We need more than this,
however, as staggered HDR is more complicated, requiring processing on
receiver side.

Neither I'm sure the control is enough as an interface to configure this.

> Supported resolutions:
>    - 1920 x 1080 @ 60fps (SBGGR10, no HDR)
>    - 1920 x 1080 @ 30fps (SBGGR10, HDR)
>    - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
>    - 3840 x 2160 @ 15fps (SBGGR10, HDR)
>    - 3840 x 2160 @ 15fps (SBGGR12, HDR)
>    - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
>    - 3840 x 2160 @ 30fps (SBGGR10, no HDR)
> 
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> ---
>  .../media/i2c/ox05b1s/os08a20_regs_1080p.h    | 201 +++++++++++++++++
>  drivers/media/i2c/ox05b1s/os08a20_regs_4k.h   | 209 ++++++++++++++++++
>  .../media/i2c/ox05b1s/os08a20_regs_4k_hdr.h   | 199 +++++++++++++++++
>  drivers/media/i2c/ox05b1s/ox05b1s_mipi.c      | 189 ++++++++++++++++
>  4 files changed, 798 insertions(+)
>  create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
>  create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
>  create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
> 
> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
> new file mode 100644
> index 000000000000..ab9977c56a10
> --- /dev/null
> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
> @@ -0,0 +1,201 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * A register configuration for Omnivision OS08A20 raw camera, 1920 x 1080 @60fps BGGR10

Over 80, please wrap.

> + * Copyright (C) 2024, NXP
> + * Copyright (C) 2024, Omnivision
> + * Copyright (C) 2024, Verisilicon
> + *
> + */
> +#ifndef _OS08A20_REGS_1080P_H_
> +#define _OS08A20_REGS_1080P_H_
> +
> +static struct ox05b1s_reg os08a20_init_setting_1080p[] = {
> +	{0x0100, 0x00},

Spaces inside braces.

Quite few of the register settings here are also shared with the other
modes. Wouldn't it make sense to refactor these into a single common list
and then mode related lists?

> +	{0x0103, 0x01},
> +	{0x0303, 0x01},
> +	{0x0304, 0x00}, /* PLL_CTRL_04 (default 0x00) */
> +	{0x0305, 0x2d}, /* PLL_CTRL_05 (default 0x3c) */
> +	{0x0306, 0x00},
> +	{0x0308, 0x03},
> +	{0x0309, 0x04},
> +	{0x0325, 0x45}, /* PLL_CTRL_25 (default 0x3c) */
> +	{0x0327, 0x05}, /* PLL_CTRL_27 (default 0x07) */
> +	{0x0328, 0x02}, /* PLL_CTRL_28 (default 0x07) */
> +	{0x032a, 0x02}, /* PLL_CTRL_2a (default 0x00) */
> +	{0x300f, 0x11},
> +	{0x3010, 0x01},
> +	{0x3011, 0x04},
> +	{0x3012, 0x41},
> +	{0x3016, 0xf0},
> +	{0x301e, 0x98},
> +	{0x3031, 0xa9},
> +	{0x3103, 0x92},
> +	{0x3104, 0x01},
> +	{0x3106, 0x10},
> +	{0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
> +	{0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
> +	{0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
> +	{0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
> +	{0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
> +	{0x340c, 0xff},
> +	{0x340d, 0xff},
> +	{0x031e, 0x09},
> +	{0x3501, 0x04}, /* Long exposure */
> +	{0x3502, 0x62}, /* Long exposure */
> +	{0x3505, 0x83},
> +	{0x3508, 0x00}, /* Long gain */
> +	{0x3509, 0x80}, /* Long gain */
> +	{0x350a, 0x04},
> +	{0x350b, 0x00},
> +	{0x350c, 0x00},
> +	{0x350d, 0x80},
> +	{0x350e, 0x04},
> +	{0x350f, 0x00},
> +	{0x3600, 0x09}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
> +	{0x3603, 0x2c},
> +	{0x3605, 0x50},
> +	{0x3609, 0xb5},
> +	{0x3610, 0x39},
> +	{0x360c, 0x01},
> +	{0x3628, 0xa4},
> +	{0x362d, 0x10},
> +	{0x3660, 0x43}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
> +	{0x3662, 0x00},
> +	{0x3663, 0x28},
> +	{0x3664, 0x0d},
> +	{0x366a, 0x38},
> +	{0x366b, 0xa0},
> +	{0x366d, 0x00},
> +	{0x366e, 0x00},
> +	{0x3680, 0x00},
> +	{0x36c0, 0x00},
> +	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x373b, 0x02},
> +	{0x373c, 0x02},
> +	{0x3736, 0x02},
> +	{0x3737, 0x02},
> +	{0x3705, 0x00},
> +	{0x3706, 0x39},
> +	{0x370a, 0x00},
> +	{0x370b, 0x98},
> +	{0x3709, 0x49},
> +	{0x3714, 0x22},  /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x371c, 0x00},
> +	{0x371d, 0x08},
> +	{0x3740, 0x1b},
> +	{0x3741, 0x04},
> +	{0x375e, 0x0b},
> +	{0x3760, 0x10},
> +	{0x3776, 0x10},
> +	{0x3781, 0x02},
> +	{0x3782, 0x04},
> +	{0x3783, 0x02},
> +	{0x3784, 0x08},
> +	{0x3785, 0x08},
> +	{0x3788, 0x01},
> +	{0x3789, 0x01},
> +	{0x3797, 0x04},
> +	{0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x3800, 0x00},
> +	{0x3801, 0x00},
> +	{0x3802, 0x00},
> +	{0x3803, 0x0c},
> +	{0x3804, 0x0e},
> +	{0x3805, 0xff},
> +	{0x3806, 0x08},
> +	{0x3807, 0x6f},
> +	{0x3808, 0x07}, /* X output size (default 0x07) */
> +	{0x3809, 0x80}, /* X output size (default 0x80) */
> +	{0x380a, 0x04}, /* Y output size (default 0x04) */
> +	{0x380b, 0x38}, /* Y output size (default 0x38) */
> +	{0x380c, 0x07}, /* HTS[15:8], total horizontal timing size */
> +	{0x380d, 0x90}, /* HTS[7:0],  total horizontal timing size */
> +	{0x380e, 0x04}, /* VTS[15:8], total vertical timing (default 0x04) */
> +	{0x380f, 0xa4}, /* VTS[7:0],  total vertical timing (default 0xA0) */
> +	{0x3813, 0x08}, /* ISP_Y_WIN ISP vertical windowing offset */
> +	{0x3814, 0x03}, /* X INC ODD (default 0x01) */
> +	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
> +	{0x3816, 0x03}, /* Y INC ODD (default 0x01) */
> +	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
> +	{0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
> +	{0x3820, 0x01}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
> +	{0x3821, 0x05}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
> +	{0x3823, 0x08},
> +	{0x3826, 0x00},
> +	{0x3827, 0x08},
> +	{0x382d, 0x08},
> +	{0x3832, 0x02},
> +	{0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
> +	{0x383c, 0x48},
> +	{0x383d, 0xff},
> +	{0x3d85, 0x0b},
> +	{0x3d84, 0x40},
> +	{0x3d8c, 0x63},
> +	{0x3d8d, 0xd7},
> +	{0x4000, 0xf8},
> +	{0x4001, 0x2b},
> +	{0x4004, 0x00},
> +	{0x4005, 0x40},
> +	{0x400a, 0x01},
> +	{0x400f, 0xa0},
> +	{0x4010, 0x12},
> +	{0x4018, 0x00},
> +	{0x4008, 0x02},
> +	{0x4009, 0x05}, /* BLC CTRL09 (default 0x0f) bl_end */
> +	{0x401a, 0x58},
> +	{0x4050, 0x00},
> +	{0x4051, 0x01},
> +	{0x4028, 0x2f},
> +	{0x4052, 0x00},
> +	{0x4053, 0x80},
> +	{0x4054, 0x00},
> +	{0x4055, 0x80},
> +	{0x4056, 0x00},
> +	{0x4057, 0x80},
> +	{0x4058, 0x00},
> +	{0x4059, 0x80},
> +	{0x430b, 0xff},
> +	{0x430c, 0xff},
> +	{0x430d, 0x00},
> +	{0x430e, 0x00},
> +	{0x4501, 0x98}, /* R1 (default 0x18) bit[4:2]=not used */
> +	{0x4502, 0x00},
> +	{0x4643, 0x00},
> +	{0x4640, 0x01},
> +	{0x4641, 0x04},
> +	{0x4800, 0x64},
> +	{0x4809, 0x2b},
> +	{0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
> +	{0x4817, 0x04},
> +	{0x4833, 0x18},
> +	{0x4837, 0x16}, /* PCLK PERIOD (default 0x08) */
> +	{0x483b, 0x00},
> +	{0x484b, 0x03},
> +	{0x4850, 0x7c},
> +	{0x4852, 0x06},
> +	{0x4856, 0x58},
> +	{0x4857, 0xaa},
> +	{0x4862, 0x0a},
> +	{0x4869, 0x18},
> +	{0x486a, 0xaa},
> +	{0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
> +	{0x486f, 0x55},
> +	{0x4875, 0xf0},
> +	{0x5000, 0x89},
> +	{0x5001, 0x42},
> +	{0x5004, 0x40},
> +	{0x5005, 0x00},
> +	{0x5180, 0x00},
> +	{0x5181, 0x10},
> +	{0x580b, 0x03},
> +	{0x4d00, 0x03},
> +	{0x4d01, 0xc9},
> +	{0x4d02, 0xbc},
> +	{0x4d03, 0xc6},
> +	{0x4d04, 0x4a},
> +	{0x4d05, 0x25},
> +	{0x4700, 0x2b},
> +	{0x4e00, 0x2b},
> +};
> +
> +#endif
> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
> new file mode 100644
> index 000000000000..f3d5f0fe1b61
> --- /dev/null
> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
> @@ -0,0 +1,209 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR12

Ditto.

> + * Copyright (C) 2024, NXP
> + * Copyright (C) 2024, Omnivision
> + * Copyright (C) 2024, Verisilicon
> + *
> + */
> +
> +#ifndef _OS08A20_REGS_4K_H_
> +#define _OS08A20_REGS_4K_H_
> +
> +static struct ox05b1s_reg os08a20_init_setting_4k[] = {
> +	{0x0100, 0x00},
> +	{0x0103, 0x01},
> +	{0x0303, 0x01},
> +	{0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
> +	{0x0306, 0x00},
> +	{0x0308, 0x03},
> +	{0x0309, 0x04},
> +	{0x0325, 0x47}, /* PLL_CTRL_25 (default 0x3c) */
> +	{0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
> +	{0x300f, 0x11},
> +	{0x3010, 0x01},
> +	{0x3011, 0x04},
> +	{0x3012, 0x41},
> +	{0x3016, 0xf0},
> +	{0x301e, 0x98},
> +	{0x3031, 0xa9},
> +	{0x3103, 0x92},
> +	{0x3104, 0x01},
> +	{0x3106, 0x10},
> +	{0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
> +	{0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
> +	{0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
> +	{0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
> +	{0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
> +	{0x340c, 0xff},
> +	{0x340d, 0xff},
> +	{0x031e, 0x0a},
> +	{0x3501, 0x08}, /* Long exposure */
> +	{0x3502, 0xe5}, /* Long exposure */
> +	{0x3505, 0x83},
> +	{0x3508, 0x00}, /* Long gain */
> +	{0x3509, 0x80}, /* Long gain */
> +	{0x350a, 0x04},
> +	{0x350b, 0x00},
> +	{0x350c, 0x00},
> +	{0x350d, 0x80},
> +	{0x350e, 0x04},
> +	{0x350f, 0x00},
> +	{0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
> +	{0x3603, 0x2c},
> +	{0x3605, 0x50},
> +	{0x3609, 0xdb},
> +	{0x3610, 0x39},
> +	{0x360c, 0x01},
> +	{0x3628, 0xa4},
> +	{0x362d, 0x10},
> +	{0x3660, 0xd3}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
> +	{0x3662, 0x00},
> +	{0x3663, 0x28},
> +	{0x3664, 0x0d},
> +	{0x366a, 0x38},
> +	{0x366b, 0xa0},
> +	{0x366d, 0x00},
> +	{0x366e, 0x00},
> +	{0x3680, 0x00},
> +	{0x36c0, 0x00},
> +	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x373b, 0x02},
> +	{0x373c, 0x02},
> +	{0x3736, 0x02},
> +	{0x3737, 0x02},
> +	{0x3705, 0x00},
> +	{0x3706, 0x72},
> +	{0x370a, 0x01},
> +	{0x370b, 0x30},
> +	{0x3709, 0x48},
> +	{0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x371c, 0x00},
> +	{0x371d, 0x08},
> +	{0x3740, 0x1b},
> +	{0x3741, 0x04},
> +	{0x375e, 0x0b},
> +	{0x3760, 0x10},
> +	{0x3776, 0x10},
> +	{0x3781, 0x02},
> +	{0x3782, 0x04},
> +	{0x3783, 0x02},
> +	{0x3784, 0x08},
> +	{0x3785, 0x08},
> +	{0x3788, 0x01},
> +	{0x3789, 0x01},
> +	{0x3797, 0x04},
> +	{0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x3800, 0x00},
> +	{0x3801, 0x00},
> +	{0x3802, 0x00},
> +	{0x3803, 0x0c},
> +	{0x3804, 0x0e},
> +	{0x3805, 0xff},
> +	{0x3806, 0x08},
> +	{0x3807, 0x6f},
> +	{0x3808, 0x0f}, /* X output size (default 0x07) */
> +	{0x3809, 0x00}, /* X output size (default 0x80) */
> +	{0x380a, 0x08}, /* Y output size (default 0x04) */
> +	{0x380b, 0x70}, /* Y output size (default 0x38) */
> +	{0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
> +	{0x380d, 0x14}, /* HTS[7:0],  total horizontal timing size */
> +	{0x380e, 0x08}, /* VTS[15:8], total vertical timing (default 0x04) */
> +	{0x380f, 0xf0}, /* VTS[7:0],  total vertical timing (default 0xA0) */
> +	{0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
> +	{0x3814, 0x01}, /* X INC ODD (default 0x01) */
> +	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
> +	{0x3816, 0x01}, /* Y INC ODD (default 0x01) */
> +	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
> +	{0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
> +	{0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
> +	{0x3821, 0x04}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
> +	{0x3823, 0x08},
> +	{0x3826, 0x00},
> +	{0x3827, 0x08},
> +	{0x382d, 0x08},
> +	{0x3832, 0x02},
> +	{0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
> +	{0x383c, 0x48},
> +	{0x383d, 0xff},
> +	{0x3d85, 0x0b},
> +	{0x3d84, 0x40},
> +	{0x3d8c, 0x63},
> +	{0x3d8d, 0xd7},
> +	{0x4000, 0xf8},
> +	{0x4001, 0x2b},
> +	{0x4004, 0x00},
> +	{0x4005, 0x40},
> +	{0x400a, 0x01},
> +	{0x400f, 0xa0},
> +	{0x4010, 0x12},
> +	{0x4018, 0x00},
> +	{0x4008, 0x02},
> +	{0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
> +	{0x401a, 0x58},
> +	{0x4050, 0x00},
> +	{0x4051, 0x01},
> +	{0x4028, 0x2f},
> +	{0x4052, 0x00},
> +	{0x4053, 0x80},
> +	{0x4054, 0x00},
> +	{0x4055, 0x80},
> +	{0x4056, 0x00},
> +	{0x4057, 0x80},
> +	{0x4058, 0x00},
> +	{0x4059, 0x80},
> +	{0x430b, 0xff},
> +	{0x430c, 0xff},
> +	{0x430d, 0x00},
> +	{0x430e, 0x00},
> +	{0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
> +	{0x4502, 0x00},
> +	{0x4600, 0x00},
> +	{0x4601, 0x20},
> +	{0x4603, 0x01},
> +	{0x4643, 0x00},
> +	{0x4640, 0x01},
> +	{0x4641, 0x04},
> +	{0x4800, 0x64},
> +	{0x4809, 0x2b},
> +	{0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
> +	{0x4817, 0x04},
> +	{0x4833, 0x18},
> +	{0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
> +	{0x483b, 0x00},
> +	{0x484b, 0x03},
> +	{0x4850, 0x7c},
> +	{0x4852, 0x06},
> +	{0x4856, 0x58},
> +	{0x4857, 0xaa},
> +	{0x4862, 0x0a},
> +	{0x4869, 0x18},
> +	{0x486a, 0xaa},
> +	{0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
> +	{0x486f, 0x55},
> +	{0x4875, 0xf0},
> +	{0x5000, 0x89},
> +	{0x5001, 0x42},
> +	{0x5004, 0x40},
> +	{0x5005, 0x00},
> +	{0x5180, 0x00},
> +	{0x5181, 0x10},
> +	{0x580b, 0x03},
> +	{0x4d00, 0x03},
> +	{0x4d01, 0xc9},
> +	{0x4d02, 0xbc},
> +	{0x4d03, 0xc6},
> +	{0x4d04, 0x4a},
> +	{0x4d05, 0x25},
> +	{0x4700, 0x2b},
> +	{0x4e00, 0x2b},
> +	{0x3501, 0x09}, /* Long exposure */
> +	{0x3502, 0x01}, /* Long exposure */
> +	{0x4028, 0x4f},
> +	{0x4029, 0x1f},
> +	{0x402a, 0x7f},
> +	{0x402b, 0x01},
> +	{0x0100, 0x01},
> +};
> +
> +#endif
> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
> new file mode 100644
> index 000000000000..2ae79ebae436
> --- /dev/null
> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
> @@ -0,0 +1,199 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR10 HDR

Ditto.

> + * Copyright (C) 2024, NXP
> + * Copyright (C) 2024, Omnivision
> + * Copyright (C) 2024, Verisilicon
> + *
> + */
> +
> +#ifndef _OS08A20_REGS_4K_HDR_H_
> +#define _OS08A20_REGS_4K_HDR_H_
> +
> +static struct ox05b1s_reg os08a20_init_setting_4k_hdr[] = {
> +	{0x0100, 0x00},
> +	{0x0103, 0x01},
> +	{0x0303, 0x01},
> +	{0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
> +	{0x0306, 0x00},
> +	{0x0308, 0x03},
> +	{0x0309, 0x04},
> +	{0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
> +	{0x300f, 0x11},
> +	{0x3010, 0x01},
> +	{0x3011, 0x04},
> +	{0x3012, 0x41},
> +	{0x3016, 0xf0},
> +	{0x301e, 0x98},
> +	{0x3031, 0xa9},
> +	{0x3103, 0x92},
> +	{0x3104, 0x01},
> +	{0x3106, 0x10},
> +	{0x340c, 0xff},
> +	{0x340d, 0xff},
> +	{0x031e, 0x09},
> +	{0x3501, 0x08}, /* Long exposure */
> +	{0x3502, 0xe5}, /* Long exposure */
> +	{0x3505, 0x83},
> +	{0x3508, 0x00}, /* Long gain */
> +	{0x3509, 0x80}, /* Long gain */
> +	{0x350a, 0x04},
> +	{0x350b, 0x00},
> +	{0x350c, 0x00},
> +	{0x350d, 0x80},
> +	{0x350e, 0x04},
> +	{0x350f, 0x00},
> +	{0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
> +	{0x3603, 0x2c},
> +	{0x3605, 0x50},
> +	{0x3609, 0xb5},
> +	{0x3610, 0x39},
> +	{0x360c, 0x01},
> +	{0x3628, 0xa4},
> +	{0x362d, 0x10},
> +	{0x3660, 0x42}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
> +	{0x3661, 0x07}, /* CORE1 (default 0x06) bit[0]=stg_hdr_align_en */
> +	{0x3662, 0x00},
> +	{0x3663, 0x28},
> +	{0x3664, 0x0d},
> +	{0x366a, 0x38},
> +	{0x366b, 0xa0},
> +	{0x366d, 0x00},
> +	{0x366e, 0x00},
> +	{0x3680, 0x00},
> +	{0x36c0, 0x00},
> +	{0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x373b, 0x02},
> +	{0x373c, 0x02},
> +	{0x3736, 0x02},
> +	{0x3737, 0x02},
> +	{0x3705, 0x00},
> +	{0x3706, 0x39},
> +	{0x370a, 0x00},
> +	{0x370b, 0x98},
> +	{0x3709, 0x49},
> +	{0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x371c, 0x00},
> +	{0x371d, 0x08},
> +	{0x3740, 0x1b},
> +	{0x3741, 0x04},
> +	{0x375e, 0x0b},
> +	{0x3760, 0x10},
> +	{0x3776, 0x10},
> +	{0x3781, 0x02},
> +	{0x3782, 0x04},
> +	{0x3783, 0x02},
> +	{0x3784, 0x08},
> +	{0x3785, 0x08},
> +	{0x3788, 0x01},
> +	{0x3789, 0x01},
> +	{0x3797, 0x04},
> +	{0x3762, 0x11}, /* Sensor timing control registers 0x3700-0x37ff */
> +	{0x3800, 0x00},
> +	{0x3801, 0x00},
> +	{0x3802, 0x00},
> +	{0x3803, 0x0c},
> +	{0x3804, 0x0e},
> +	{0x3805, 0xff},
> +	{0x3806, 0x08},
> +	{0x3807, 0x6f},
> +	{0x3808, 0x0f}, /* X output size (default 0x07) */
> +	{0x3809, 0x00}, /* X output size (default 0x80) */
> +	{0x380a, 0x08}, /* Y output size (default 0x04) */
> +	{0x380b, 0x70}, /* Y output size (default 0x38) */
> +	{0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
> +	{0x380d, 0x18}, /* HTS[7:0],  total horizontal timing size */
> +	{0x380e, 0x09}, /* VTS[15:8], total vertical timing (default 0x04) */
> +	{0x380f, 0x0a}, /* VTS[7:0],  total vertical timing (default 0xA0) */
> +	{0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
> +	{0x3814, 0x01}, /* X INC ODD (default 0x01) */
> +	{0x3815, 0x01}, /* X INC EVEN (default 0x01) */
> +	{0x3816, 0x01}, /* Y INC ODD (default 0x01) */
> +	{0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
> +	{0x381c, 0x08}, /* BLC_NUM_OPTION (default 0x0e) */
> +	{0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
> +	{0x3821, 0x24}, /* FORMAT2 bit[5]=stagger hdr en, bit[2]=mirror */
> +	{0x3823, 0x08},
> +	{0x3826, 0x00},
> +	{0x3827, 0x08},
> +	{0x382d, 0x08},
> +	{0x3832, 0x02},
> +	{0x3833, 0x01}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
> +	{0x383c, 0x48},
> +	{0x383d, 0xff},
> +	{0x3d85, 0x0b},
> +	{0x3d84, 0x40},
> +	{0x3d8c, 0x63},
> +	{0x3d8d, 0xd7},
> +	{0x4000, 0xf8},
> +	{0x4001, 0x2b},
> +	{0x4004, 0x00},
> +	{0x4005, 0x40},
> +	{0x400a, 0x01},
> +	{0x400f, 0xa0},
> +	{0x4010, 0x12},
> +	{0x4018, 0x00},
> +	{0x4008, 0x02},
> +	{0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
> +	{0x401a, 0x58},
> +	{0x4050, 0x00},
> +	{0x4051, 0x01},
> +	{0x4028, 0x2f},
> +	{0x4052, 0x00},
> +	{0x4053, 0x80},
> +	{0x4054, 0x00},
> +	{0x4055, 0x80},
> +	{0x4056, 0x00},
> +	{0x4057, 0x80},
> +	{0x4058, 0x00},
> +	{0x4059, 0x80},
> +	{0x430b, 0xff},
> +	{0x430c, 0xff},
> +	{0x430d, 0x00},
> +	{0x430e, 0x00},
> +	{0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
> +	{0x4502, 0x00},
> +	{0x4643, 0x00},
> +	{0x4640, 0x01},
> +	{0x4641, 0x04},
> +	{0x4800, 0x64},
> +	{0x4809, 0x2b},
> +	{0x4813, 0x98}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
> +	{0x4817, 0x04},
> +	{0x4833, 0x18},
> +	{0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
> +	{0x483b, 0x00},
> +	{0x484b, 0x03},
> +	{0x4850, 0x7c},
> +	{0x4852, 0x06},
> +	{0x4856, 0x58},
> +	{0x4857, 0xaa},
> +	{0x4862, 0x0a},
> +	{0x4869, 0x18},
> +	{0x486a, 0xaa},
> +	{0x486e, 0x07}, /* MIPI CTRL 6E (default 0x03) */
> +	{0x486f, 0x55},
> +	{0x4875, 0xf0},
> +	{0x5000, 0x89},
> +	{0x5001, 0x42},
> +	{0x5004, 0x40},
> +	{0x5005, 0x00},
> +	{0x5180, 0x00},
> +	{0x5181, 0x10},
> +	{0x580b, 0x03},
> +	{0x4d00, 0x03},
> +	{0x4d01, 0xc9},
> +	{0x4d02, 0xbc},
> +	{0x4d03, 0xc6},
> +	{0x4d04, 0x4a},
> +	{0x4d05, 0x25},
> +	{0x4700, 0x2b},
> +	{0x4e00, 0x2b},
> +	{0x3501, 0x08}, /* Long exposure */
> +	{0x3502, 0xe1}, /* Long exposure */
> +	{0x3511, 0x00}, /* Short exposure */
> +	{0x3512, 0x20}, /* Short exposure */
> +	{0x3833, 0x01},
> +};
> +
> +#endif
> diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
> index 5b9c069af19b..15559265d8f0 100644
> --- a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
> +++ b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
> @@ -42,6 +42,7 @@ struct ox05b1s_sizes {
>  	u32	sizes[OX05B1S_MAX_SIZES][2];
>  };
>  
> +struct ox05b1s;
>  struct ox05b1s_plat_data {
>  	char				name[20];
>  	u32				chip_id;
> @@ -56,6 +57,9 @@ struct ox05b1s_plat_data {
>  	u32				default_mode_index;
>  	const struct ox05b1s_sizes	*supported_codes;
>  	u32				supported_codes_count;
> +	const char * const		*hdr_modes;
> +	u32				hdr_modes_count;
> +	int (*set_hdr_mode)(struct ox05b1s *sensor, u32 hdr_mode);
>  };
>  
>  struct ox05b1s_ctrls {
> @@ -66,6 +70,7 @@ struct ox05b1s_ctrls {
>  	struct v4l2_ctrl *vblank;
>  	struct v4l2_ctrl *gain;
>  	struct v4l2_ctrl *exposure;
> +	struct v4l2_ctrl *hdr_mode;
>  };
>  
>  struct ox05b1s_reg {
> @@ -73,6 +78,9 @@ struct ox05b1s_reg {
>  	u32 data;
>  };
>  
> +#include "os08a20_regs_1080p.h"
> +#include "os08a20_regs_4k.h"
> +#include "os08a20_regs_4k_hdr.h"
>  #include "ox05b1s_regs_5mp.h"
>  
>  struct ox05b1s_mode {
> @@ -104,6 +112,68 @@ struct ox05b1s {
>  	struct ox05b1s_ctrls ctrls;
>  };
>  
> +static struct ox05b1s_mode os08a20_supported_modes[] = {
> +	{
> +		/* 1080p BGGR10, no hdr, 60fps */
> +		.index		= 0,
> +		.width		= 1920,
> +		.height		= 1080,
> +		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.bpp		= 10,
> +		.vts		= 0x4a4,
> +		.hts		= 0x790,
> +		.exp		= 0x4a4 - 8,
> +		.h_bin		= true,
> +		.fps		= 60,
> +		.reg_data	= os08a20_init_setting_1080p,
> +		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_1080p),
> +	},
> +	{

These fit on the same line.

> +		/* 4k BGGR10, staggered hdr VC0/VC1, 15fps */
> +		.index		= 1,
> +		.width		= 3840,
> +		.height		= 2160,
> +		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.bpp		= 10,
> +		.vts		= 0x90a,
> +		.hts		= 0x818,
> +		.exp		= 0x90a - 8,
> +		.h_bin		= false,
> +		.fps		= 15,
> +		.reg_data	= os08a20_init_setting_4k_hdr,
> +		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_4k_hdr),
> +	},
> +	{
> +		/* 4k BGGR12, no hdr, 30fps */
> +		.index		= 2,
> +		.width		= 3840,
> +		.height		= 2160,
> +		.code		= MEDIA_BUS_FMT_SBGGR12_1X12,
> +		.bpp		= 12,
> +		.vts		= 0x8f0,
> +		.hts		= 0x814,
> +		.exp		= 0x8f0 - 8,
> +		.h_bin		= false,
> +		.fps		= 30,
> +		.reg_data	= os08a20_init_setting_4k,
> +		.reg_data_count	= ARRAY_SIZE(os08a20_init_setting_4k),
> +	},
> +};
> +
> +/* keep in sync with os08a20_supported_modes*/
> +static const struct ox05b1s_sizes os08a20_supported_codes[] = {
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.sizes_count = 2,

This doesn't seem like very nice to maintain. :-(

Could you make sizes a pointer instead?

> +		.sizes = { {1920, 1080}, {3840, 2160} }

Spaces inside braces, please.

> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
> +		.sizes_count = 1,
> +		.sizes = { {3840, 2160} }
> +	},
> +};
> +
>  static struct ox05b1s_mode ox05b1s_supported_modes[] = {
>  	{
>  		.index		= 0,
> @@ -210,6 +280,18 @@ static int ox05b1s_read_reg(struct ox05b1s *sensor, u16 reg, u8 *val)
>  	return ret;
>  }
>  
> +static int ox05b1s_update_bits(struct ox05b1s *sensor, u16 reg, unsigned int mask, u8 val)
> +{
> +	struct device *dev = &sensor->i2c_client->dev;
> +	int ret = 0;

The initialisation is redundant.

> +
> +	ret = regmap_update_bits(sensor->regmap, reg, mask, val);
> +	if (ret < 0)
> +		dev_err(dev, "Failed to update reg addr 0x%04x with 0x%02x\n", reg, val);
> +
> +	return ret;
> +}
> +
>  #define OX05B1S_MAX_REG_BULK 16
>  static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
>  				   struct ox05b1s_reg *reg_array,
> @@ -239,6 +321,67 @@ static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
>  	return 0;
>  }
>  
> +static const char * const os08a20_hdr_modes[] = {
> +	"NO HDR",		/* No HDR, single exposure */
> +	"HDR Staggered",	/* Staggered HDR mode, 2 exposures on separate virtual channels */
> +};
> +
> +#define OS08A20_REG_CORE1		0x3661
> +#define OS08A20_STG_HDR_ALIGN_EN	BIT(0)
> +
> +#define OS08A20_REG_FORMAT2		0x3821
> +#define OS08A20_STG_HDR_EN		BIT(5)
> +
> +#define OS08A20_REG_MIPI_CTRL_13	0x4813
> +#define OS08A20_MISTERY_BIT3		BIT(3)
> +
> +#define OS08A20_REG_MIPI_CTRL_6E	0x486e
> +#define OS08A20_MIPI_VC_ENABLE		BIT(2)
> +
> +static int os08a20_enable_staggered_hdr(struct ox05b1s *sensor)
> +{
> +	int ret = 0;
> +
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN,
> +				   OS08A20_STG_HDR_ALIGN_EN);

How about returning the actual error code to the caller?

Also this requires reading the registers over I²C that is slow. If it's not
during streaming it should be fine though.

I'd probably make this a loop.

> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN,
> +				   OS08A20_STG_HDR_EN);
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3,
> +				   OS08A20_MISTERY_BIT3);
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE,
> +				   OS08A20_MIPI_VC_ENABLE);
> +	if (ret)
> +		ret = -EIO;
> +
> +	return ret;
> +}
> +
> +static int os08a20_disable_staggered_hdr(struct ox05b1s *sensor)
> +{
> +	int ret = 0;
> +
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN, 0);
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN, 0);
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3, 0);
> +	ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE, 0);
> +	if (ret)
> +		ret = -EIO;
> +
> +	return ret;
> +}
> +
> +static int os08a20_set_hdr_mode(struct ox05b1s *sensor, u32 hdr_mode)
> +{
> +	switch (hdr_mode) {
> +	case 0:
> +		return os08a20_disable_staggered_hdr(sensor);
> +	case 1:
> +		return os08a20_enable_staggered_hdr(sensor);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static int ox05b1s_set_hts(struct ox05b1s *sensor, u32 hts)
>  {
>  	u8 values[2] = { (u8)(hts >> 8) & 0xff, (u8)(hts & 0xff) };
> @@ -307,6 +450,12 @@ static int ox05b1s_s_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE:
>  		ret = ox05b1s_set_exp(sensor, ctrl->val);
>  		break;
> +	case V4L2_CID_HDR_SENSOR_MODE:
> +		if (sensor->model->set_hdr_mode)
> +			ret = sensor->model->set_hdr_mode(sensor, ctrl->val);
> +		else
> +			ret = -EINVAL;
> +		break;
>  	default:
>  		ret = -EINVAL;
>  		break;
> @@ -369,6 +518,13 @@ static int ox05b1s_init_controls(struct ox05b1s *sensor)
>  	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
>  					0, 0xFFFF, 1, 0x80);
>  
> +	if (sensor->model->hdr_modes)
> +		ctrls->hdr_mode = v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_HDR_SENSOR_MODE,
> +							       sensor->model->hdr_modes_count - 1,
> +								0, 0, sensor->model->hdr_modes);
> +	else
> +		ctrls->hdr_mode = NULL;
> +
>  	if (hdl->error) {
>  		ret = hdl->error;
>  		goto free_ctrls;
> @@ -670,7 +826,10 @@ static u8 ox05b1s_code2dt(const u32 code)
>  {
>  	switch (code) {
>  	case MEDIA_BUS_FMT_SGRBG10_1X10:
> +	case MEDIA_BUS_FMT_SBGGR10_1X10:
>  		return MIPI_CSI2_DT_RAW10;
> +	case MEDIA_BUS_FMT_SBGGR12_1X12:
> +		return MIPI_CSI2_DT_RAW12;
>  	default:
>  		return MIPI_CSI2_DT_RAW10;
>  	}
> @@ -775,6 +934,9 @@ static int ox05b1s_read_chip_id(struct ox05b1s *sensor)
>  	}
>  
>  	switch (chip_id) {
> +	case 0x530841:
> +		camera_name = "os08a20";
> +		break;
>  	case 0x580542:
>  		camera_name = "ox05b1s";
>  		break;
> @@ -915,6 +1077,26 @@ static void ox05b1s_remove(struct i2c_client *client)
>  static DEFINE_RUNTIME_DEV_PM_OPS(ox05b1s_pm_ops, ox05b1s_runtime_suspend,
>  				 ox05b1s_runtime_resume, NULL);
>  
> +static const struct ox05b1s_plat_data os08a20_data = {
> +	.name			= "os08a20",
> +	.chip_id		= 0x530841,
> +	.native_width		= 3872, /* 16 dummy + 3840 active pixels + 16 dummy */
> +	.native_height		= 2192, /* 16 dummy + 2160 active lines + 16 dummy */
> +	.active_top		= 16,
> +	.active_left		= 16,
> +	.active_width		= 3840,
> +	.active_height		= 2160,
> +	.supported_modes	= os08a20_supported_modes,
> +	.supported_modes_count	= ARRAY_SIZE(os08a20_supported_modes),
> +	.default_mode_index	= 0,
> +	.supported_codes	= os08a20_supported_codes,
> +	.supported_codes_count	= ARRAY_SIZE(os08a20_supported_codes),
> +	.hdr_modes		= os08a20_hdr_modes,
> +	.hdr_modes_count	= ARRAY_SIZE(os08a20_hdr_modes),
> +	.set_hdr_mode		= os08a20_set_hdr_mode,
> +
> +};
> +
>  static const struct ox05b1s_plat_data ox05b1s_data = {
>  	.name			= "ox05b1s",
>  	.chip_id		= 0x580542,
> @@ -929,9 +1111,16 @@ static const struct ox05b1s_plat_data ox05b1s_data = {
>  	.default_mode_index	= 0,
>  	.supported_codes	= ox05b1s_supported_codes,
>  	.supported_codes_count	= ARRAY_SIZE(ox05b1s_supported_codes),
> +	.hdr_modes		= NULL,
> +	.hdr_modes_count	= 0,
> +	.set_hdr_mode		= NULL,
>  };
>  
>  static const struct of_device_id ox05b1s_of_match[] = {
> +	{
> +		.compatible = "ovti,os08a20",
> +		.data = &os08a20_data,
> +	},
>  	{
>  		.compatible = "ovti,ox05b1s",
>  		.data = &ox05b1s_data,

-- 
Kind regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor
  2024-11-01 12:08   ` Sakari Ailus
@ 2024-11-04 13:21     ` Mirela Rabulea
  0 siblings, 0 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-11-04 13:21 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: mchehab, hverkuil-cisco, laurent.pinchart+renesas,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hi Sakari,

thanks a lot for feedback.

On 01.11.2024 14:08, Sakari Ailus wrote:
> Hi Mirela,
>
> Thanks set the set.
>
> On Mon, Oct 28, 2024 at 09:06:28PM +0200, Mirela Rabulea wrote:
>> This is an 8 megapixel raw10/raw12 sensor with HDR capabilities.
>> HDR mode control is supported, with one hdr mode: staggered HDR with
>> 2 exposures on separate virtual channels.
> The patch still declares just one via get_frame_desc (as there are no
> changes). I think we need more documentation on this, including sensor
> specific documentation on the HDR mode as the interfaces don't provide it
> all. There's Documentation/userspace-api/media/drivers/st-vgxy61.rst that
> describes the existing usage of the control. We need more than this,
> however, as staggered HDR is more complicated, requiring processing on
> receiver side.
>
> Neither I'm sure the control is enough as an interface to configure this.

Indeed, when HDR is enabled, the sensor sends data on 2 VCs, but only 
the VC0 makes it further, as you noticed, it is hard-coded in 
get_frame_desc.

I did experiment with both exposures, sent as 2 separate streams, and 
the 2 VCs, each of them assigned to one stream, with get_frame_desc 
modified for 2 entries.

I did capture successfully the 2 exposures as 2 streams, however, I got 
stuck on a clean implementation for streams & routes, here are some of 
my questions on the subject:

https://www.spinics.net/lists/linux-media/msg262705.html

I would much appreciate any thoughts or comments on that.

In the meantime, while the internal pads support settles, I could add 
some comment in the code, to document the current limitation?

Do you know, is the HDR merge for ST VGXY61 done inside the sensor? For 
os08a20, it is not, it will be merged in the ISP. There are other HDR 
modes available for the os08a20, but we only experimented the staggered 
hdr on 2 virtual channels, and I think it's unlikely that we will add 
other modes.

The other HDR modes for os08a20 are:

1) sequential HDR, can be achieved by using context switching, further 
documentation missing from the datasheet: frame1 long, frame2 medium, 
frame3 short, frame4 long, frame5 medium, frame6 short,...

2) staggered HDR (long and short exposure frames overlap each other); 
there are 2 possible output modes:

2a) first staggered mode, uses MIPI channel to differentiate different 
exposure frames (this is what is enabled in this driver)

2b) second output mode (the new staggered HDR mode) with dummy lines, 
where no VC is needed (did not experiment with it, and I also do not see 
any specific documentation on it)

The datasheet I have seems to be confidential for NXP, and it is thin on 
the subject.

The other sensor, ox05b1s does not have HDR capabilities, but it can 
operate in a context-switching mode and output on 2 virtual channels 
also, on one channel frames optimized for the RGB component, on the 
other channel  frames optimized for the IR component, each one consuming 
half the fps. We did experiment with this mode, in a similar manner with 
the os08a20 staggered HDR, however, the current mode used in this driver 
for ox05b1s is with the RGB-IR together on a single VC.

Please let me know your further recommendation.

>
>> Supported resolutions:
>>     - 1920 x 1080 @ 60fps (SBGGR10, no HDR)
>>     - 1920 x 1080 @ 30fps (SBGGR10, HDR)
>>     - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
>>     - 3840 x 2160 @ 15fps (SBGGR10, HDR)
>>     - 3840 x 2160 @ 15fps (SBGGR12, HDR)
>>     - 3840 x 2160 @ 30fps (SBGGR12, no HDR)
>>     - 3840 x 2160 @ 30fps (SBGGR10, no HDR)
>>
>> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
>> ---
>>   .../media/i2c/ox05b1s/os08a20_regs_1080p.h    | 201 +++++++++++++++++
>>   drivers/media/i2c/ox05b1s/os08a20_regs_4k.h   | 209 ++++++++++++++++++
>>   .../media/i2c/ox05b1s/os08a20_regs_4k_hdr.h   | 199 +++++++++++++++++
>>   drivers/media/i2c/ox05b1s/ox05b1s_mipi.c      | 189 ++++++++++++++++
>>   4 files changed, 798 insertions(+)
>>   create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
>>   create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
>>   create mode 100644 drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
>>
>> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
>> new file mode 100644
>> index 000000000000..ab9977c56a10
>> --- /dev/null
>> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_1080p.h
>> @@ -0,0 +1,201 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * A register configuration for Omnivision OS08A20 raw camera, 1920 x 1080 @60fps BGGR10
> Over 80, please wrap.
>
>> + * Copyright (C) 2024, NXP
>> + * Copyright (C) 2024, Omnivision
>> + * Copyright (C) 2024, Verisilicon
>> + *
>> + */
>> +#ifndef _OS08A20_REGS_1080P_H_
>> +#define _OS08A20_REGS_1080P_H_
>> +
>> +static struct ox05b1s_reg os08a20_init_setting_1080p[] = {
>> +     {0x0100, 0x00},
> Spaces inside braces.
>
> Quite few of the register settings here are also shared with the other
> modes. Wouldn't it make sense to refactor these into a single common list
> and then mode related lists?
I'll see what can be done.
>
>> +     {0x0103, 0x01},
>> +     {0x0303, 0x01},
>> +     {0x0304, 0x00}, /* PLL_CTRL_04 (default 0x00) */
>> +     {0x0305, 0x2d}, /* PLL_CTRL_05 (default 0x3c) */
>> +     {0x0306, 0x00},
>> +     {0x0308, 0x03},
>> +     {0x0309, 0x04},
>> +     {0x0325, 0x45}, /* PLL_CTRL_25 (default 0x3c) */
>> +     {0x0327, 0x05}, /* PLL_CTRL_27 (default 0x07) */
>> +     {0x0328, 0x02}, /* PLL_CTRL_28 (default 0x07) */
>> +     {0x032a, 0x02}, /* PLL_CTRL_2a (default 0x00) */
>> +     {0x300f, 0x11},
>> +     {0x3010, 0x01},
>> +     {0x3011, 0x04},
>> +     {0x3012, 0x41},
>> +     {0x3016, 0xf0},
>> +     {0x301e, 0x98},
>> +     {0x3031, 0xa9},
>> +     {0x3103, 0x92},
>> +     {0x3104, 0x01},
>> +     {0x3106, 0x10},
>> +     {0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
>> +     {0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
>> +     {0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
>> +     {0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
>> +     {0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
>> +     {0x340c, 0xff},
>> +     {0x340d, 0xff},
>> +     {0x031e, 0x09},
>> +     {0x3501, 0x04}, /* Long exposure */
>> +     {0x3502, 0x62}, /* Long exposure */
>> +     {0x3505, 0x83},
>> +     {0x3508, 0x00}, /* Long gain */
>> +     {0x3509, 0x80}, /* Long gain */
>> +     {0x350a, 0x04},
>> +     {0x350b, 0x00},
>> +     {0x350c, 0x00},
>> +     {0x350d, 0x80},
>> +     {0x350e, 0x04},
>> +     {0x350f, 0x00},
>> +     {0x3600, 0x09}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
>> +     {0x3603, 0x2c},
>> +     {0x3605, 0x50},
>> +     {0x3609, 0xb5},
>> +     {0x3610, 0x39},
>> +     {0x360c, 0x01},
>> +     {0x3628, 0xa4},
>> +     {0x362d, 0x10},
>> +     {0x3660, 0x43}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
>> +     {0x3662, 0x00},
>> +     {0x3663, 0x28},
>> +     {0x3664, 0x0d},
>> +     {0x366a, 0x38},
>> +     {0x366b, 0xa0},
>> +     {0x366d, 0x00},
>> +     {0x366e, 0x00},
>> +     {0x3680, 0x00},
>> +     {0x36c0, 0x00},
>> +     {0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x373b, 0x02},
>> +     {0x373c, 0x02},
>> +     {0x3736, 0x02},
>> +     {0x3737, 0x02},
>> +     {0x3705, 0x00},
>> +     {0x3706, 0x39},
>> +     {0x370a, 0x00},
>> +     {0x370b, 0x98},
>> +     {0x3709, 0x49},
>> +     {0x3714, 0x22},  /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x371c, 0x00},
>> +     {0x371d, 0x08},
>> +     {0x3740, 0x1b},
>> +     {0x3741, 0x04},
>> +     {0x375e, 0x0b},
>> +     {0x3760, 0x10},
>> +     {0x3776, 0x10},
>> +     {0x3781, 0x02},
>> +     {0x3782, 0x04},
>> +     {0x3783, 0x02},
>> +     {0x3784, 0x08},
>> +     {0x3785, 0x08},
>> +     {0x3788, 0x01},
>> +     {0x3789, 0x01},
>> +     {0x3797, 0x04},
>> +     {0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x3800, 0x00},
>> +     {0x3801, 0x00},
>> +     {0x3802, 0x00},
>> +     {0x3803, 0x0c},
>> +     {0x3804, 0x0e},
>> +     {0x3805, 0xff},
>> +     {0x3806, 0x08},
>> +     {0x3807, 0x6f},
>> +     {0x3808, 0x07}, /* X output size (default 0x07) */
>> +     {0x3809, 0x80}, /* X output size (default 0x80) */
>> +     {0x380a, 0x04}, /* Y output size (default 0x04) */
>> +     {0x380b, 0x38}, /* Y output size (default 0x38) */
>> +     {0x380c, 0x07}, /* HTS[15:8], total horizontal timing size */
>> +     {0x380d, 0x90}, /* HTS[7:0],  total horizontal timing size */
>> +     {0x380e, 0x04}, /* VTS[15:8], total vertical timing (default 0x04) */
>> +     {0x380f, 0xa4}, /* VTS[7:0],  total vertical timing (default 0xA0) */
>> +     {0x3813, 0x08}, /* ISP_Y_WIN ISP vertical windowing offset */
>> +     {0x3814, 0x03}, /* X INC ODD (default 0x01) */
>> +     {0x3815, 0x01}, /* X INC EVEN (default 0x01) */
>> +     {0x3816, 0x03}, /* Y INC ODD (default 0x01) */
>> +     {0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
>> +     {0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
>> +     {0x3820, 0x01}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
>> +     {0x3821, 0x05}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
>> +     {0x3823, 0x08},
>> +     {0x3826, 0x00},
>> +     {0x3827, 0x08},
>> +     {0x382d, 0x08},
>> +     {0x3832, 0x02},
>> +     {0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
>> +     {0x383c, 0x48},
>> +     {0x383d, 0xff},
>> +     {0x3d85, 0x0b},
>> +     {0x3d84, 0x40},
>> +     {0x3d8c, 0x63},
>> +     {0x3d8d, 0xd7},
>> +     {0x4000, 0xf8},
>> +     {0x4001, 0x2b},
>> +     {0x4004, 0x00},
>> +     {0x4005, 0x40},
>> +     {0x400a, 0x01},
>> +     {0x400f, 0xa0},
>> +     {0x4010, 0x12},
>> +     {0x4018, 0x00},
>> +     {0x4008, 0x02},
>> +     {0x4009, 0x05}, /* BLC CTRL09 (default 0x0f) bl_end */
>> +     {0x401a, 0x58},
>> +     {0x4050, 0x00},
>> +     {0x4051, 0x01},
>> +     {0x4028, 0x2f},
>> +     {0x4052, 0x00},
>> +     {0x4053, 0x80},
>> +     {0x4054, 0x00},
>> +     {0x4055, 0x80},
>> +     {0x4056, 0x00},
>> +     {0x4057, 0x80},
>> +     {0x4058, 0x00},
>> +     {0x4059, 0x80},
>> +     {0x430b, 0xff},
>> +     {0x430c, 0xff},
>> +     {0x430d, 0x00},
>> +     {0x430e, 0x00},
>> +     {0x4501, 0x98}, /* R1 (default 0x18) bit[4:2]=not used */
>> +     {0x4502, 0x00},
>> +     {0x4643, 0x00},
>> +     {0x4640, 0x01},
>> +     {0x4641, 0x04},
>> +     {0x4800, 0x64},
>> +     {0x4809, 0x2b},
>> +     {0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
>> +     {0x4817, 0x04},
>> +     {0x4833, 0x18},
>> +     {0x4837, 0x16}, /* PCLK PERIOD (default 0x08) */
>> +     {0x483b, 0x00},
>> +     {0x484b, 0x03},
>> +     {0x4850, 0x7c},
>> +     {0x4852, 0x06},
>> +     {0x4856, 0x58},
>> +     {0x4857, 0xaa},
>> +     {0x4862, 0x0a},
>> +     {0x4869, 0x18},
>> +     {0x486a, 0xaa},
>> +     {0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
>> +     {0x486f, 0x55},
>> +     {0x4875, 0xf0},
>> +     {0x5000, 0x89},
>> +     {0x5001, 0x42},
>> +     {0x5004, 0x40},
>> +     {0x5005, 0x00},
>> +     {0x5180, 0x00},
>> +     {0x5181, 0x10},
>> +     {0x580b, 0x03},
>> +     {0x4d00, 0x03},
>> +     {0x4d01, 0xc9},
>> +     {0x4d02, 0xbc},
>> +     {0x4d03, 0xc6},
>> +     {0x4d04, 0x4a},
>> +     {0x4d05, 0x25},
>> +     {0x4700, 0x2b},
>> +     {0x4e00, 0x2b},
>> +};
>> +
>> +#endif
>> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
>> new file mode 100644
>> index 000000000000..f3d5f0fe1b61
>> --- /dev/null
>> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k.h
>> @@ -0,0 +1,209 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR12
> Ditto.
>
>> + * Copyright (C) 2024, NXP
>> + * Copyright (C) 2024, Omnivision
>> + * Copyright (C) 2024, Verisilicon
>> + *
>> + */
>> +
>> +#ifndef _OS08A20_REGS_4K_H_
>> +#define _OS08A20_REGS_4K_H_
>> +
>> +static struct ox05b1s_reg os08a20_init_setting_4k[] = {
>> +     {0x0100, 0x00},
>> +     {0x0103, 0x01},
>> +     {0x0303, 0x01},
>> +     {0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
>> +     {0x0306, 0x00},
>> +     {0x0308, 0x03},
>> +     {0x0309, 0x04},
>> +     {0x0325, 0x47}, /* PLL_CTRL_25 (default 0x3c) */
>> +     {0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
>> +     {0x300f, 0x11},
>> +     {0x3010, 0x01},
>> +     {0x3011, 0x04},
>> +     {0x3012, 0x41},
>> +     {0x3016, 0xf0},
>> +     {0x301e, 0x98},
>> +     {0x3031, 0xa9},
>> +     {0x3103, 0x92},
>> +     {0x3104, 0x01},
>> +     {0x3106, 0x10},
>> +     {0x3400, 0x04}, /* PSV CTRL (default 0x00) bit[2]=r_psv_mode_en */
>> +     {0x3025, 0x03}, /* PSV MODE OPT (default 0x02) not used */
>> +     {0x3425, 0x01}, /* R ASP PD SEL bit[1:0]=stream blanking */
>> +     {0x3428, 0x01}, /* R ASP PD SEL bit[1:0]=bpg1 N-pump1 bypass to AGND */
>> +     {0x3408, 0x03}, /* CTRL08 (default 0x01) bit[3:0]=r_clk_winp_off */
>> +     {0x340c, 0xff},
>> +     {0x340d, 0xff},
>> +     {0x031e, 0x0a},
>> +     {0x3501, 0x08}, /* Long exposure */
>> +     {0x3502, 0xe5}, /* Long exposure */
>> +     {0x3505, 0x83},
>> +     {0x3508, 0x00}, /* Long gain */
>> +     {0x3509, 0x80}, /* Long gain */
>> +     {0x350a, 0x04},
>> +     {0x350b, 0x00},
>> +     {0x350c, 0x00},
>> +     {0x350d, 0x80},
>> +     {0x350e, 0x04},
>> +     {0x350f, 0x00},
>> +     {0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
>> +     {0x3603, 0x2c},
>> +     {0x3605, 0x50},
>> +     {0x3609, 0xdb},
>> +     {0x3610, 0x39},
>> +     {0x360c, 0x01},
>> +     {0x3628, 0xa4},
>> +     {0x362d, 0x10},
>> +     {0x3660, 0xd3}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
>> +     {0x3662, 0x00},
>> +     {0x3663, 0x28},
>> +     {0x3664, 0x0d},
>> +     {0x366a, 0x38},
>> +     {0x366b, 0xa0},
>> +     {0x366d, 0x00},
>> +     {0x366e, 0x00},
>> +     {0x3680, 0x00},
>> +     {0x36c0, 0x00},
>> +     {0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x373b, 0x02},
>> +     {0x373c, 0x02},
>> +     {0x3736, 0x02},
>> +     {0x3737, 0x02},
>> +     {0x3705, 0x00},
>> +     {0x3706, 0x72},
>> +     {0x370a, 0x01},
>> +     {0x370b, 0x30},
>> +     {0x3709, 0x48},
>> +     {0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x371c, 0x00},
>> +     {0x371d, 0x08},
>> +     {0x3740, 0x1b},
>> +     {0x3741, 0x04},
>> +     {0x375e, 0x0b},
>> +     {0x3760, 0x10},
>> +     {0x3776, 0x10},
>> +     {0x3781, 0x02},
>> +     {0x3782, 0x04},
>> +     {0x3783, 0x02},
>> +     {0x3784, 0x08},
>> +     {0x3785, 0x08},
>> +     {0x3788, 0x01},
>> +     {0x3789, 0x01},
>> +     {0x3797, 0x04},
>> +     {0x3762, 0x11},  /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x3800, 0x00},
>> +     {0x3801, 0x00},
>> +     {0x3802, 0x00},
>> +     {0x3803, 0x0c},
>> +     {0x3804, 0x0e},
>> +     {0x3805, 0xff},
>> +     {0x3806, 0x08},
>> +     {0x3807, 0x6f},
>> +     {0x3808, 0x0f}, /* X output size (default 0x07) */
>> +     {0x3809, 0x00}, /* X output size (default 0x80) */
>> +     {0x380a, 0x08}, /* Y output size (default 0x04) */
>> +     {0x380b, 0x70}, /* Y output size (default 0x38) */
>> +     {0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
>> +     {0x380d, 0x14}, /* HTS[7:0],  total horizontal timing size */
>> +     {0x380e, 0x08}, /* VTS[15:8], total vertical timing (default 0x04) */
>> +     {0x380f, 0xf0}, /* VTS[7:0],  total vertical timing (default 0xA0) */
>> +     {0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
>> +     {0x3814, 0x01}, /* X INC ODD (default 0x01) */
>> +     {0x3815, 0x01}, /* X INC EVEN (default 0x01) */
>> +     {0x3816, 0x01}, /* Y INC ODD (default 0x01) */
>> +     {0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
>> +     {0x381c, 0x00}, /* BLC_NUM_OPTION (default 0x0e) */
>> +     {0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
>> +     {0x3821, 0x04}, /* FORMAT2 bit[2]=mirror, bit[0]=horizontal bining */
>> +     {0x3823, 0x08},
>> +     {0x3826, 0x00},
>> +     {0x3827, 0x08},
>> +     {0x382d, 0x08},
>> +     {0x3832, 0x02},
>> +     {0x3833, 0x00}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
>> +     {0x383c, 0x48},
>> +     {0x383d, 0xff},
>> +     {0x3d85, 0x0b},
>> +     {0x3d84, 0x40},
>> +     {0x3d8c, 0x63},
>> +     {0x3d8d, 0xd7},
>> +     {0x4000, 0xf8},
>> +     {0x4001, 0x2b},
>> +     {0x4004, 0x00},
>> +     {0x4005, 0x40},
>> +     {0x400a, 0x01},
>> +     {0x400f, 0xa0},
>> +     {0x4010, 0x12},
>> +     {0x4018, 0x00},
>> +     {0x4008, 0x02},
>> +     {0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
>> +     {0x401a, 0x58},
>> +     {0x4050, 0x00},
>> +     {0x4051, 0x01},
>> +     {0x4028, 0x2f},
>> +     {0x4052, 0x00},
>> +     {0x4053, 0x80},
>> +     {0x4054, 0x00},
>> +     {0x4055, 0x80},
>> +     {0x4056, 0x00},
>> +     {0x4057, 0x80},
>> +     {0x4058, 0x00},
>> +     {0x4059, 0x80},
>> +     {0x430b, 0xff},
>> +     {0x430c, 0xff},
>> +     {0x430d, 0x00},
>> +     {0x430e, 0x00},
>> +     {0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
>> +     {0x4502, 0x00},
>> +     {0x4600, 0x00},
>> +     {0x4601, 0x20},
>> +     {0x4603, 0x01},
>> +     {0x4643, 0x00},
>> +     {0x4640, 0x01},
>> +     {0x4641, 0x04},
>> +     {0x4800, 0x64},
>> +     {0x4809, 0x2b},
>> +     {0x4813, 0x90}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
>> +     {0x4817, 0x04},
>> +     {0x4833, 0x18},
>> +     {0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
>> +     {0x483b, 0x00},
>> +     {0x484b, 0x03},
>> +     {0x4850, 0x7c},
>> +     {0x4852, 0x06},
>> +     {0x4856, 0x58},
>> +     {0x4857, 0xaa},
>> +     {0x4862, 0x0a},
>> +     {0x4869, 0x18},
>> +     {0x486a, 0xaa},
>> +     {0x486e, 0x03}, /* MIPI CTRL 6E (default 0x03) */
>> +     {0x486f, 0x55},
>> +     {0x4875, 0xf0},
>> +     {0x5000, 0x89},
>> +     {0x5001, 0x42},
>> +     {0x5004, 0x40},
>> +     {0x5005, 0x00},
>> +     {0x5180, 0x00},
>> +     {0x5181, 0x10},
>> +     {0x580b, 0x03},
>> +     {0x4d00, 0x03},
>> +     {0x4d01, 0xc9},
>> +     {0x4d02, 0xbc},
>> +     {0x4d03, 0xc6},
>> +     {0x4d04, 0x4a},
>> +     {0x4d05, 0x25},
>> +     {0x4700, 0x2b},
>> +     {0x4e00, 0x2b},
>> +     {0x3501, 0x09}, /* Long exposure */
>> +     {0x3502, 0x01}, /* Long exposure */
>> +     {0x4028, 0x4f},
>> +     {0x4029, 0x1f},
>> +     {0x402a, 0x7f},
>> +     {0x402b, 0x01},
>> +     {0x0100, 0x01},
>> +};
>> +
>> +#endif
>> diff --git a/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
>> new file mode 100644
>> index 000000000000..2ae79ebae436
>> --- /dev/null
>> +++ b/drivers/media/i2c/ox05b1s/os08a20_regs_4k_hdr.h
>> @@ -0,0 +1,199 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * A register configuration for Omnivision OS08A20 raw camera, 3840 x 2160 @30fps BGGR10 HDR
> Ditto.
>
>> + * Copyright (C) 2024, NXP
>> + * Copyright (C) 2024, Omnivision
>> + * Copyright (C) 2024, Verisilicon
>> + *
>> + */
>> +
>> +#ifndef _OS08A20_REGS_4K_HDR_H_
>> +#define _OS08A20_REGS_4K_HDR_H_
>> +
>> +static struct ox05b1s_reg os08a20_init_setting_4k_hdr[] = {
>> +     {0x0100, 0x00},
>> +     {0x0103, 0x01},
>> +     {0x0303, 0x01},
>> +     {0x0305, 0x3c}, /* PLL_CTRL_05 (default 0x3c) */
>> +     {0x0306, 0x00},
>> +     {0x0308, 0x03},
>> +     {0x0309, 0x04},
>> +     {0x032a, 0x00}, /* PLL_CTRL_2a (default 0x00) */
>> +     {0x300f, 0x11},
>> +     {0x3010, 0x01},
>> +     {0x3011, 0x04},
>> +     {0x3012, 0x41},
>> +     {0x3016, 0xf0},
>> +     {0x301e, 0x98},
>> +     {0x3031, 0xa9},
>> +     {0x3103, 0x92},
>> +     {0x3104, 0x01},
>> +     {0x3106, 0x10},
>> +     {0x340c, 0xff},
>> +     {0x340d, 0xff},
>> +     {0x031e, 0x09},
>> +     {0x3501, 0x08}, /* Long exposure */
>> +     {0x3502, 0xe5}, /* Long exposure */
>> +     {0x3505, 0x83},
>> +     {0x3508, 0x00}, /* Long gain */
>> +     {0x3509, 0x80}, /* Long gain */
>> +     {0x350a, 0x04},
>> +     {0x350b, 0x00},
>> +     {0x350c, 0x00},
>> +     {0x350d, 0x80},
>> +     {0x350e, 0x04},
>> +     {0x350f, 0x00},
>> +     {0x3600, 0x00}, /* CORE0 bit[0]=stg_hdr_align_en, bit[3]=new_stgr_hdr_en */
>> +     {0x3603, 0x2c},
>> +     {0x3605, 0x50},
>> +     {0x3609, 0xb5},
>> +     {0x3610, 0x39},
>> +     {0x360c, 0x01},
>> +     {0x3628, 0xa4},
>> +     {0x362d, 0x10},
>> +     {0x3660, 0x42}, /* CORE0 bit[0]=rip_sof_vifo_en, bit[1]=stg_hdr_long_en debug mode */
>> +     {0x3661, 0x07}, /* CORE1 (default 0x06) bit[0]=stg_hdr_align_en */
>> +     {0x3662, 0x00},
>> +     {0x3663, 0x28},
>> +     {0x3664, 0x0d},
>> +     {0x366a, 0x38},
>> +     {0x366b, 0xa0},
>> +     {0x366d, 0x00},
>> +     {0x366e, 0x00},
>> +     {0x3680, 0x00},
>> +     {0x36c0, 0x00},
>> +     {0x3701, 0x02}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x373b, 0x02},
>> +     {0x373c, 0x02},
>> +     {0x3736, 0x02},
>> +     {0x3737, 0x02},
>> +     {0x3705, 0x00},
>> +     {0x3706, 0x39},
>> +     {0x370a, 0x00},
>> +     {0x370b, 0x98},
>> +     {0x3709, 0x49},
>> +     {0x3714, 0x21}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x371c, 0x00},
>> +     {0x371d, 0x08},
>> +     {0x3740, 0x1b},
>> +     {0x3741, 0x04},
>> +     {0x375e, 0x0b},
>> +     {0x3760, 0x10},
>> +     {0x3776, 0x10},
>> +     {0x3781, 0x02},
>> +     {0x3782, 0x04},
>> +     {0x3783, 0x02},
>> +     {0x3784, 0x08},
>> +     {0x3785, 0x08},
>> +     {0x3788, 0x01},
>> +     {0x3789, 0x01},
>> +     {0x3797, 0x04},
>> +     {0x3762, 0x11}, /* Sensor timing control registers 0x3700-0x37ff */
>> +     {0x3800, 0x00},
>> +     {0x3801, 0x00},
>> +     {0x3802, 0x00},
>> +     {0x3803, 0x0c},
>> +     {0x3804, 0x0e},
>> +     {0x3805, 0xff},
>> +     {0x3806, 0x08},
>> +     {0x3807, 0x6f},
>> +     {0x3808, 0x0f}, /* X output size (default 0x07) */
>> +     {0x3809, 0x00}, /* X output size (default 0x80) */
>> +     {0x380a, 0x08}, /* Y output size (default 0x04) */
>> +     {0x380b, 0x70}, /* Y output size (default 0x38) */
>> +     {0x380c, 0x08}, /* HTS[15:8], total horizontal timing size */
>> +     {0x380d, 0x18}, /* HTS[7:0],  total horizontal timing size */
>> +     {0x380e, 0x09}, /* VTS[15:8], total vertical timing (default 0x04) */
>> +     {0x380f, 0x0a}, /* VTS[7:0],  total vertical timing (default 0xA0) */
>> +     {0x3813, 0x10}, /* ISP_Y_WIN ISP vertical windowing offset */
>> +     {0x3814, 0x01}, /* X INC ODD (default 0x01) */
>> +     {0x3815, 0x01}, /* X INC EVEN (default 0x01) */
>> +     {0x3816, 0x01}, /* Y INC ODD (default 0x01) */
>> +     {0x3817, 0x01}, /* Y INC EVEN (default 0x01) */
>> +     {0x381c, 0x08}, /* BLC_NUM_OPTION (default 0x0e) */
>> +     {0x3820, 0x00}, /* FORMAT1 (default 0x80) bit[0]=vertical bining */
>> +     {0x3821, 0x24}, /* FORMAT2 bit[5]=stagger hdr en, bit[2]=mirror */
>> +     {0x3823, 0x08},
>> +     {0x3826, 0x00},
>> +     {0x3827, 0x08},
>> +     {0x382d, 0x08},
>> +     {0x3832, 0x02},
>> +     {0x3833, 0x01}, /* REG33 (bit[0]=r_stg_hdr_grp_wr_opt, bit[2]=r_stg_grphold_nomask) */
>> +     {0x383c, 0x48},
>> +     {0x383d, 0xff},
>> +     {0x3d85, 0x0b},
>> +     {0x3d84, 0x40},
>> +     {0x3d8c, 0x63},
>> +     {0x3d8d, 0xd7},
>> +     {0x4000, 0xf8},
>> +     {0x4001, 0x2b},
>> +     {0x4004, 0x00},
>> +     {0x4005, 0x40},
>> +     {0x400a, 0x01},
>> +     {0x400f, 0xa0},
>> +     {0x4010, 0x12},
>> +     {0x4018, 0x00},
>> +     {0x4008, 0x02},
>> +     {0x4009, 0x0d}, /* BLC CTRL09 (default 0x0f) bl_end */
>> +     {0x401a, 0x58},
>> +     {0x4050, 0x00},
>> +     {0x4051, 0x01},
>> +     {0x4028, 0x2f},
>> +     {0x4052, 0x00},
>> +     {0x4053, 0x80},
>> +     {0x4054, 0x00},
>> +     {0x4055, 0x80},
>> +     {0x4056, 0x00},
>> +     {0x4057, 0x80},
>> +     {0x4058, 0x00},
>> +     {0x4059, 0x80},
>> +     {0x430b, 0xff},
>> +     {0x430c, 0xff},
>> +     {0x430d, 0x00},
>> +     {0x430e, 0x00},
>> +     {0x4501, 0x18}, /* R1 (default 0x18) bit[4:2]=not used */
>> +     {0x4502, 0x00},
>> +     {0x4643, 0x00},
>> +     {0x4640, 0x01},
>> +     {0x4641, 0x04},
>> +     {0x4800, 0x64},
>> +     {0x4809, 0x2b},
>> +     {0x4813, 0x98}, /* MIPI CTRL 13 (bit[5:4]=VC1=1, bit[7:6]=VC2=2) */
>> +     {0x4817, 0x04},
>> +     {0x4833, 0x18},
>> +     {0x4837, 0x10}, /* PCLK PERIOD (default 0x08) */
>> +     {0x483b, 0x00},
>> +     {0x484b, 0x03},
>> +     {0x4850, 0x7c},
>> +     {0x4852, 0x06},
>> +     {0x4856, 0x58},
>> +     {0x4857, 0xaa},
>> +     {0x4862, 0x0a},
>> +     {0x4869, 0x18},
>> +     {0x486a, 0xaa},
>> +     {0x486e, 0x07}, /* MIPI CTRL 6E (default 0x03) */
>> +     {0x486f, 0x55},
>> +     {0x4875, 0xf0},
>> +     {0x5000, 0x89},
>> +     {0x5001, 0x42},
>> +     {0x5004, 0x40},
>> +     {0x5005, 0x00},
>> +     {0x5180, 0x00},
>> +     {0x5181, 0x10},
>> +     {0x580b, 0x03},
>> +     {0x4d00, 0x03},
>> +     {0x4d01, 0xc9},
>> +     {0x4d02, 0xbc},
>> +     {0x4d03, 0xc6},
>> +     {0x4d04, 0x4a},
>> +     {0x4d05, 0x25},
>> +     {0x4700, 0x2b},
>> +     {0x4e00, 0x2b},
>> +     {0x3501, 0x08}, /* Long exposure */
>> +     {0x3502, 0xe1}, /* Long exposure */
>> +     {0x3511, 0x00}, /* Short exposure */
>> +     {0x3512, 0x20}, /* Short exposure */
>> +     {0x3833, 0x01},
>> +};
>> +
>> +#endif
>> diff --git a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
>> index 5b9c069af19b..15559265d8f0 100644
>> --- a/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
>> +++ b/drivers/media/i2c/ox05b1s/ox05b1s_mipi.c
>> @@ -42,6 +42,7 @@ struct ox05b1s_sizes {
>>        u32     sizes[OX05B1S_MAX_SIZES][2];
>>   };
>>
>> +struct ox05b1s;
>>   struct ox05b1s_plat_data {
>>        char                            name[20];
>>        u32                             chip_id;
>> @@ -56,6 +57,9 @@ struct ox05b1s_plat_data {
>>        u32                             default_mode_index;
>>        const struct ox05b1s_sizes      *supported_codes;
>>        u32                             supported_codes_count;
>> +     const char * const              *hdr_modes;
>> +     u32                             hdr_modes_count;
>> +     int (*set_hdr_mode)(struct ox05b1s *sensor, u32 hdr_mode);
>>   };
>>
>>   struct ox05b1s_ctrls {
>> @@ -66,6 +70,7 @@ struct ox05b1s_ctrls {
>>        struct v4l2_ctrl *vblank;
>>        struct v4l2_ctrl *gain;
>>        struct v4l2_ctrl *exposure;
>> +     struct v4l2_ctrl *hdr_mode;
>>   };
>>
>>   struct ox05b1s_reg {
>> @@ -73,6 +78,9 @@ struct ox05b1s_reg {
>>        u32 data;
>>   };
>>
>> +#include "os08a20_regs_1080p.h"
>> +#include "os08a20_regs_4k.h"
>> +#include "os08a20_regs_4k_hdr.h"
>>   #include "ox05b1s_regs_5mp.h"
>>
>>   struct ox05b1s_mode {
>> @@ -104,6 +112,68 @@ struct ox05b1s {
>>        struct ox05b1s_ctrls ctrls;
>>   };
>>
>> +static struct ox05b1s_mode os08a20_supported_modes[] = {
>> +     {
>> +             /* 1080p BGGR10, no hdr, 60fps */
>> +             .index          = 0,
>> +             .width          = 1920,
>> +             .height         = 1080,
>> +             .code           = MEDIA_BUS_FMT_SBGGR10_1X10,
>> +             .bpp            = 10,
>> +             .vts            = 0x4a4,
>> +             .hts            = 0x790,
>> +             .exp            = 0x4a4 - 8,
>> +             .h_bin          = true,
>> +             .fps            = 60,
>> +             .reg_data       = os08a20_init_setting_1080p,
>> +             .reg_data_count = ARRAY_SIZE(os08a20_init_setting_1080p),
>> +     },
>> +     {
> These fit on the same line.
>
>> +             /* 4k BGGR10, staggered hdr VC0/VC1, 15fps */
>> +             .index          = 1,
>> +             .width          = 3840,
>> +             .height         = 2160,
>> +             .code           = MEDIA_BUS_FMT_SBGGR10_1X10,
>> +             .bpp            = 10,
>> +             .vts            = 0x90a,
>> +             .hts            = 0x818,
>> +             .exp            = 0x90a - 8,
>> +             .h_bin          = false,
>> +             .fps            = 15,
>> +             .reg_data       = os08a20_init_setting_4k_hdr,
>> +             .reg_data_count = ARRAY_SIZE(os08a20_init_setting_4k_hdr),
>> +     },
>> +     {
>> +             /* 4k BGGR12, no hdr, 30fps */
>> +             .index          = 2,
>> +             .width          = 3840,
>> +             .height         = 2160,
>> +             .code           = MEDIA_BUS_FMT_SBGGR12_1X12,
>> +             .bpp            = 12,
>> +             .vts            = 0x8f0,
>> +             .hts            = 0x814,
>> +             .exp            = 0x8f0 - 8,
>> +             .h_bin          = false,
>> +             .fps            = 30,
>> +             .reg_data       = os08a20_init_setting_4k,
>> +             .reg_data_count = ARRAY_SIZE(os08a20_init_setting_4k),
>> +     },
>> +};
>> +
>> +/* keep in sync with os08a20_supported_modes*/
>> +static const struct ox05b1s_sizes os08a20_supported_codes[] = {
>> +     {
>> +             .code = MEDIA_BUS_FMT_SBGGR10_1X10,
>> +             .sizes_count = 2,
> This doesn't seem like very nice to maintain. :-(
>
> Could you make sizes a pointer instead?
I'll check it.
>
>> +             .sizes = { {1920, 1080}, {3840, 2160} }
> Spaces inside braces, please.
>
>> +     },
>> +     {
>> +             .code = MEDIA_BUS_FMT_SBGGR12_1X12,
>> +             .sizes_count = 1,
>> +             .sizes = { {3840, 2160} }
>> +     },
>> +};
>> +
>>   static struct ox05b1s_mode ox05b1s_supported_modes[] = {
>>        {
>>                .index          = 0,
>> @@ -210,6 +280,18 @@ static int ox05b1s_read_reg(struct ox05b1s *sensor, u16 reg, u8 *val)
>>        return ret;
>>   }
>>
>> +static int ox05b1s_update_bits(struct ox05b1s *sensor, u16 reg, unsigned int mask, u8 val)
>> +{
>> +     struct device *dev = &sensor->i2c_client->dev;
>> +     int ret = 0;
> The initialisation is redundant.
>
>> +
>> +     ret = regmap_update_bits(sensor->regmap, reg, mask, val);
>> +     if (ret < 0)
>> +             dev_err(dev, "Failed to update reg addr 0x%04x with 0x%02x\n", reg, val);
>> +
>> +     return ret;
>> +}
>> +
>>   #define OX05B1S_MAX_REG_BULK 16
>>   static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
>>                                   struct ox05b1s_reg *reg_array,
>> @@ -239,6 +321,67 @@ static int ox05b1s_write_reg_array(struct ox05b1s *sensor,
>>        return 0;
>>   }
>>
>> +static const char * const os08a20_hdr_modes[] = {
>> +     "NO HDR",               /* No HDR, single exposure */
>> +     "HDR Staggered",        /* Staggered HDR mode, 2 exposures on separate virtual channels */
>> +};
>> +
>> +#define OS08A20_REG_CORE1            0x3661
>> +#define OS08A20_STG_HDR_ALIGN_EN     BIT(0)
>> +
>> +#define OS08A20_REG_FORMAT2          0x3821
>> +#define OS08A20_STG_HDR_EN           BIT(5)
>> +
>> +#define OS08A20_REG_MIPI_CTRL_13     0x4813
>> +#define OS08A20_MISTERY_BIT3         BIT(3)
>> +
>> +#define OS08A20_REG_MIPI_CTRL_6E     0x486e
>> +#define OS08A20_MIPI_VC_ENABLE               BIT(2)
>> +
>> +static int os08a20_enable_staggered_hdr(struct ox05b1s *sensor)
>> +{
>> +     int ret = 0;
>> +
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN,
>> +                                OS08A20_STG_HDR_ALIGN_EN);
> How about returning the actual error code to the caller?
Although unlikely, we could get different error codes from 
ox05b1s_update_bits calls, so, for safety, returned -EIO.
> Also this requires reading the registers over I²C that is slow. If it's not
> during streaming it should be fine though.
Yes, this is not meant to be done during streaming, but in the initial 
phase only.
>
> I'd probably make this a loop.

Will check.

For your other comments, I will address them in the next version, thanks.

Regards,

Mirela

>
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN,
>> +                                OS08A20_STG_HDR_EN);
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3,
>> +                                OS08A20_MISTERY_BIT3);
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE,
>> +                                OS08A20_MIPI_VC_ENABLE);
>> +     if (ret)
>> +             ret = -EIO;
>> +
>> +     return ret;
>> +}
>> +
>> +static int os08a20_disable_staggered_hdr(struct ox05b1s *sensor)
>> +{
>> +     int ret = 0;
>> +
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_CORE1, OS08A20_STG_HDR_ALIGN_EN, 0);
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_FORMAT2, OS08A20_STG_HDR_EN, 0);
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_13, OS08A20_MISTERY_BIT3, 0);
>> +     ret |= ox05b1s_update_bits(sensor, OS08A20_REG_MIPI_CTRL_6E, OS08A20_MIPI_VC_ENABLE, 0);
>> +     if (ret)
>> +             ret = -EIO;
>> +
>> +     return ret;
>> +}
>> +
>> +static int os08a20_set_hdr_mode(struct ox05b1s *sensor, u32 hdr_mode)
>> +{
>> +     switch (hdr_mode) {
>> +     case 0:
>> +             return os08a20_disable_staggered_hdr(sensor);
>> +     case 1:
>> +             return os08a20_enable_staggered_hdr(sensor);
>> +     default:
>> +             return -EINVAL;
>> +     }
>> +}
>> +
>>   static int ox05b1s_set_hts(struct ox05b1s *sensor, u32 hts)
>>   {
>>        u8 values[2] = { (u8)(hts >> 8) & 0xff, (u8)(hts & 0xff) };
>> @@ -307,6 +450,12 @@ static int ox05b1s_s_ctrl(struct v4l2_ctrl *ctrl)
>>        case V4L2_CID_EXPOSURE:
>>                ret = ox05b1s_set_exp(sensor, ctrl->val);
>>                break;
>> +     case V4L2_CID_HDR_SENSOR_MODE:
>> +             if (sensor->model->set_hdr_mode)
>> +                     ret = sensor->model->set_hdr_mode(sensor, ctrl->val);
>> +             else
>> +                     ret = -EINVAL;
>> +             break;
>>        default:
>>                ret = -EINVAL;
>>                break;
>> @@ -369,6 +518,13 @@ static int ox05b1s_init_controls(struct ox05b1s *sensor)
>>        ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
>>                                        0, 0xFFFF, 1, 0x80);
>>
>> +     if (sensor->model->hdr_modes)
>> +             ctrls->hdr_mode = v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_HDR_SENSOR_MODE,
>> +                                                            sensor->model->hdr_modes_count - 1,
>> +                                                             0, 0, sensor->model->hdr_modes);
>> +     else
>> +             ctrls->hdr_mode = NULL;
>> +
>>        if (hdl->error) {
>>                ret = hdl->error;
>>                goto free_ctrls;
>> @@ -670,7 +826,10 @@ static u8 ox05b1s_code2dt(const u32 code)
>>   {
>>        switch (code) {
>>        case MEDIA_BUS_FMT_SGRBG10_1X10:
>> +     case MEDIA_BUS_FMT_SBGGR10_1X10:
>>                return MIPI_CSI2_DT_RAW10;
>> +     case MEDIA_BUS_FMT_SBGGR12_1X12:
>> +             return MIPI_CSI2_DT_RAW12;
>>        default:
>>                return MIPI_CSI2_DT_RAW10;
>>        }
>> @@ -775,6 +934,9 @@ static int ox05b1s_read_chip_id(struct ox05b1s *sensor)
>>        }
>>
>>        switch (chip_id) {
>> +     case 0x530841:
>> +             camera_name = "os08a20";
>> +             break;
>>        case 0x580542:
>>                camera_name = "ox05b1s";
>>                break;
>> @@ -915,6 +1077,26 @@ static void ox05b1s_remove(struct i2c_client *client)
>>   static DEFINE_RUNTIME_DEV_PM_OPS(ox05b1s_pm_ops, ox05b1s_runtime_suspend,
>>                                 ox05b1s_runtime_resume, NULL);
>>
>> +static const struct ox05b1s_plat_data os08a20_data = {
>> +     .name                   = "os08a20",
>> +     .chip_id                = 0x530841,
>> +     .native_width           = 3872, /* 16 dummy + 3840 active pixels + 16 dummy */
>> +     .native_height          = 2192, /* 16 dummy + 2160 active lines + 16 dummy */
>> +     .active_top             = 16,
>> +     .active_left            = 16,
>> +     .active_width           = 3840,
>> +     .active_height          = 2160,
>> +     .supported_modes        = os08a20_supported_modes,
>> +     .supported_modes_count  = ARRAY_SIZE(os08a20_supported_modes),
>> +     .default_mode_index     = 0,
>> +     .supported_codes        = os08a20_supported_codes,
>> +     .supported_codes_count  = ARRAY_SIZE(os08a20_supported_codes),
>> +     .hdr_modes              = os08a20_hdr_modes,
>> +     .hdr_modes_count        = ARRAY_SIZE(os08a20_hdr_modes),
>> +     .set_hdr_mode           = os08a20_set_hdr_mode,
>> +
>> +};
>> +
>>   static const struct ox05b1s_plat_data ox05b1s_data = {
>>        .name                   = "ox05b1s",
>>        .chip_id                = 0x580542,
>> @@ -929,9 +1111,16 @@ static const struct ox05b1s_plat_data ox05b1s_data = {
>>        .default_mode_index     = 0,
>>        .supported_codes        = ox05b1s_supported_codes,
>>        .supported_codes_count  = ARRAY_SIZE(ox05b1s_supported_codes),
>> +     .hdr_modes              = NULL,
>> +     .hdr_modes_count        = 0,
>> +     .set_hdr_mode           = NULL,
>>   };
>>
>>   static const struct of_device_id ox05b1s_of_match[] = {
>> +     {
>> +             .compatible = "ovti,os08a20",
>> +             .data = &os08a20_data,
>> +     },
>>        {
>>                .compatible = "ovti,ox05b1s",
>>                .data = &ox05b1s_data,
> --
> Kind regards,
>
> Sakari Ailus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-10-30  6:02       ` Mirela Rabulea
@ 2024-11-04 14:25         ` Laurent Pinchart
  2024-11-26 16:10           ` Mirela Rabulea
  0 siblings, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2024-11-04 14:25 UTC (permalink / raw)
  To: Mirela Rabulea
  Cc: Bryan O'Donoghue, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hello Mirela,

On Wed, Oct 30, 2024 at 08:02:44AM +0200, Mirela Rabulea wrote:
> On 29.10.2024 13:57, Laurent Pinchart wrote:
> >>> +
> >>> +  orientation: true
> >>> +  rotation: true
> >>
> >> I think you can drop both of these too.
> >
> > Aren't they needed given that the binding ends with
> >
> > additionalProperties: false
> >
> > ?
>
> I added orientation & rotation properties in order to support 
> orientation and rotation controls, libcamera warns about those (optional 
> requirements last time I checked).

The orientation and rotation properties should certainly be specified in
DT sources. They are standardized in video-interface-devices.yaml which
Bryan pointed out you should reference. If you're not familiar yet with
with how the YAML schemas used for DT bindings reference core schemas,
now would be a good time to have a look at it :-)

In a nutshell, you'll find that all properties need to be properly
defined with appropriate constraints, and properties shared by multiple
devices have constraints defined in core schemas. Some are included
automatically and are applied based on property names, other need a
manual $ref. You can have a look at
https://github.com/devicetree-org/dt-schema.git to see core schemas that
get automatically selected, they specify "select: true". For example the
schemas defining the reg or clocks properties don't have to be manually
referenced.

Bryan's comment about dropping the orientation and rotation properties
was related to the fact that the video-interface-devices.yaml schema
defines them already. With "unevaluatedProperties: false", you won't
need to specify "orientation: true". With "additionalProperties: false",
you will. It's a good idea to learn about the difference between those
two and how they really work.

> >>> +
> >>> +required:
> >>> +  - compatible
> >>> +  - reg
> >
> > The device requires a clock, shouldn't the clocks property be required ?
> 
> I intentionally left the clock optional, because NXP has a converter 
> board which supports both ox05b1s and os08a20 sensor, and the converter 
> board has an oscillator, and we are using that, not the SOC clock.

That's fine, you can have a fixed clock node in DT to model that. DT
bindings describe the intrinsic needs of a particular device. If the
sensor requires a clock, I think it should be mandatory. If the sensor
itself could operate without an external clock (i.e. if it had an
internal oscillator) then the property could be optional.

> Here is how the module looks like for os08a20 for imx8mp:
> 
> https://docs.nxp.com/bundle/AN13712/page/topics/os08a20_sensor_module.html
> 
> There's a newer revision for the converter board for imx95, sorry but I 
> do not have a link for that.
> 
> For imx8mp, we used in the past the clock from the SOC, then switched to 
> the external clock (from the converter board).
> 
> I think Omnivision has their own module.
> 
> So, I thought leaving the clock as optional allows for more flexibility.
> 
> >>> +  - port
> >>> +
> >>> +additionalProperties: false
> >>> +
> >>> +examples:
> >>> +  - |
> >>> +    #include <dt-bindings/gpio/gpio.h>
> >>> +
> >>> +    i2c {
> >>> +        #address-cells = <1>;
> >>> +        #size-cells = <0>;
> >>> +
> >>> +        ox05b1s: ox05b1s@36 {
> >>> +            compatible = "ovti,ox05b1s";
> >>> +            reg = <0x36>;
> >>> +            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;
> >
> > This isn't specified in the bindings. Does the example validate ?
> 
> Apparently yes, I mean dt_binding_check passed:
> 
> $ rm Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb
> 
> $ make dt_binding_check DT_CHECKER_FLAGS=-m 
> DT_SCHEMA_FILES=ovti,ox05b1s.yaml
>    DTC [C] 
> Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb
> 
> I have dtschema-2024.10.dev6+g12c3cd5.
> 
> 
> The "reset-gpios" is described in this binding, as the GPIO connected to 
> the XSHUTDOWN pin.

Ah sorry, Bryan dropped that part from his reply, so I didn't notice it.

> The <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW> is what works for imx95 
> ("nxp,pcal6408"), for imx8mp this works:
> 
> reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Re: [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S sensor driver
  2024-11-04 14:25         ` Laurent Pinchart
@ 2024-11-26 16:10           ` Mirela Rabulea
  0 siblings, 0 replies; 28+ messages in thread
From: Mirela Rabulea @ 2024-11-26 16:10 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Bryan O'Donoghue, mchehab, sakari.ailus, hverkuil-cisco,
	laurentiu.palcu, robert.chiras, linux-media, linux-kernel,
	LnxRevLi, kieran.bingham, hdegoede, dave.stevenson, mike.rudenko,
	alain.volmat, julien.vuillaumier, alice.yuan

Hi Laurent,

On 04.11.2024 16:25, Laurent Pinchart wrote:
> Hello Mirela,
>
> On Wed, Oct 30, 2024 at 08:02:44AM +0200, Mirela Rabulea wrote:
>> On 29.10.2024 13:57, Laurent Pinchart wrote:
>>>>> +
>>>>> +  orientation: true
>>>>> +  rotation: true
>>>> I think you can drop both of these too.
>>> Aren't they needed given that the binding ends with
>>>
>>> additionalProperties: false
>>>
>>> ?
>> I added orientation & rotation properties in order to support
>> orientation and rotation controls, libcamera warns about those (optional
>> requirements last time I checked).
> The orientation and rotation properties should certainly be specified in
> DT sources. They are standardized in video-interface-devices.yaml which
> Bryan pointed out you should reference. If you're not familiar yet with
> with how the YAML schemas used for DT bindings reference core schemas,
> now would be a good time to have a look at it :-)
>
> In a nutshell, you'll find that all properties need to be properly
> defined with appropriate constraints, and properties shared by multiple
> devices have constraints defined in core schemas. Some are included
> automatically and are applied based on property names, other need a
> manual $ref. You can have a look at
> https://github.com/devicetree-org/dt-schema.git  to see core schemas that
> get automatically selected, they specify "select: true". For example the
> schemas defining the reg or clocks properties don't have to be manually
> referenced.
>
> Bryan's comment about dropping the orientation and rotation properties
> was related to the fact that the video-interface-devices.yaml schema
> defines them already. With "unevaluatedProperties: false", you won't
> need to specify "orientation: true". With "additionalProperties: false",
> you will. It's a good idea to learn about the difference between those
> two and how they really work.

Thanks for info :)

I just sent the v2, I added video-interface-devices.yaml.

>
>>>>> +
>>>>> +required:
>>>>> +  - compatible
>>>>> +  - reg
>>> The device requires a clock, shouldn't the clocks property be required ?
>> I intentionally left the clock optional, because NXP has a converter
>> board which supports both ox05b1s and os08a20 sensor, and the converter
>> board has an oscillator, and we are using that, not the SOC clock.
> That's fine, you can have a fixed clock node in DT to model that. DT
> bindings describe the intrinsic needs of a particular device. If the
> sensor requires a clock, I think it should be mandatory. If the sensor
> itself could operate without an external clock (i.e. if it had an
> internal oscillator) then the property could be optional.

Also, in v2, I added the clock as mandatory. Strictly from sensor's 
module point of view, it is mandatory (will use a fixed clock for nxp 
board). Also added regulators.

Again, thank you for feedback.


Regards,

Mirela

>
>> Here is how the module looks like for os08a20 for imx8mp:
>>
>> https://docs.nxp.com/bundle/AN13712/page/topics/os08a20_sensor_module.html
>>
>> There's a newer revision for the converter board for imx95, sorry but I
>> do not have a link for that.
>>
>> For imx8mp, we used in the past the clock from the SOC, then switched to
>> the external clock (from the converter board).
>>
>> I think Omnivision has their own module.
>>
>> So, I thought leaving the clock as optional allows for more flexibility.
>>
>>>>> +  - port
>>>>> +
>>>>> +additionalProperties: false
>>>>> +
>>>>> +examples:
>>>>> +  - |
>>>>> +    #include <dt-bindings/gpio/gpio.h>
>>>>> +
>>>>> +    i2c {
>>>>> +        #address-cells = <1>;
>>>>> +        #size-cells = <0>;
>>>>> +
>>>>> +        ox05b1s: ox05b1s@36 {
>>>>> +            compatible = "ovti,ox05b1s";
>>>>> +            reg = <0x36>;
>>>>> +            reset-gpios = <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW>;
>>> This isn't specified in the bindings. Does the example validate ?
>> Apparently yes, I mean dt_binding_check passed:
>>
>> $ rm Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb
>>
>> $ make dt_binding_check DT_CHECKER_FLAGS=-m
>> DT_SCHEMA_FILES=ovti,ox05b1s.yaml
>>     DTC [C]
>> Documentation/devicetree/bindings/media/i2c/ovti,ox05b1s.example.dtb
>>
>> I have dtschema-2024.10.dev6+g12c3cd5.
>>
>>
>> The "reset-gpios" is described in this binding, as the GPIO connected to
>> the XSHUTDOWN pin.
> Ah sorry, Bryan dropped that part from his reply, so I didn't notice it.
>
>> The <&i2c3_gpio_expander_20 2 GPIO_ACTIVE_LOW> is what works for imx95
>> ("nxp,pcal6408"), for imx8mp this works:
>>
>> reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
> --
> Regards,
>
> Laurent Pinchart

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2024-11-26 16:10 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-28 19:06 [PATCH 0/5] media: i2c: Add OX05B1S camera sensor driver Mirela Rabulea
2024-10-28 19:06 ` [PATCH 1/5] dt-bindings: media: i2c: Add bindings for OX05B1S " Mirela Rabulea
2024-10-29  6:14   ` Krzysztof Kozlowski
2024-10-29 12:10     ` Laurent Pinchart
2024-10-29 12:15       ` Krzysztof Kozlowski
2024-10-29 12:21         ` Laurent Pinchart
2024-10-29 12:28           ` Krzysztof Kozlowski
2024-10-29 12:46             ` Laurent Pinchart
2024-10-29 12:47               ` Krzysztof Kozlowski
2024-10-29 13:36     ` [EXT] " Mirela Rabulea
2024-10-29 13:49       ` Krzysztof Kozlowski
2024-10-29 11:44   ` Bryan O'Donoghue
2024-10-29 11:57     ` Laurent Pinchart
2024-10-29 12:00       ` Bryan O'Donoghue
2024-10-30  6:08         ` [EXT] " Mirela Rabulea
2024-10-30  6:02       ` Mirela Rabulea
2024-11-04 14:25         ` Laurent Pinchart
2024-11-26 16:10           ` Mirela Rabulea
2024-10-28 19:06 ` [PATCH 2/5] media: ox05b1s: Add omnivision OX05B1S raw " Mirela Rabulea
2024-10-29  6:17   ` Krzysztof Kozlowski
2024-10-28 19:06 ` [PATCH 3/5] MAINTAINERS: Add entry for OX05B1S " Mirela Rabulea
2024-10-28 19:06 ` [PATCH 4/5] dt-bindings: media: i2c: Update bindings for OX05B1S with OS08A20 Mirela Rabulea
2024-10-29  6:17   ` Krzysztof Kozlowski
2024-10-29 14:02     ` [EXT] " Mirela Rabulea
2024-10-29 16:46       ` Krzysztof Kozlowski
2024-10-28 19:06 ` [PATCH 5/5] media: ox05b1s: Add support for Omnivision OS08A20 raw sensor Mirela Rabulea
2024-11-01 12:08   ` Sakari Ailus
2024-11-04 13:21     ` [EXT] " Mirela Rabulea

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox