Linux Media Controller development
 help / color / mirror / Atom feed
* [PATCH v3 0/3] media: i2c: Add imx576 camera sensor driver
@ 2026-08-06 12:02 Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 1/3] dt-bindings: media: i2c: Add imx576 sensor Himanshu Bhavani
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-06 12:02 UTC (permalink / raw)
  To: sakari.ailus
  Cc: Himanshu Bhavani, Hardevsinh Palaniya, Mauro Carvalho Chehab,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Hans Verkuil, Vladimir Zapolskiy, Hans de Goede,
	Elgin Perumbilly, Xiaolei Wang, Laurent Pinchart, Kate Hsuan,
	Walter Werner Schneider, Bartosz Golaszewski, Jai Luthra,
	linux-media, devicetree, linux-kernel, linux-arm-msm

The following features are supported:
- Manual exposure an gain control support.
- vblank/hblank control support.
- Supported resolution: 5760 x 4312 30fps (SRGGB10)

This series depends on the SM6350 CAMSS support series
https://lore.kernel.org/linux-arm-msm/20260216-sm6350-camss-v4-0-b9df35f87edb@fairphone.com/

The driver has been tested on the mainline v7.0-rc6 kernel on the Fairphone 4 running postmarketOS.

fairphone-fp4:~$ v4l2-compliance -d /dev/v4l-subdev21
v4l2-compliance 1.32.0, 64 bits, 64-bit time_t

Compliance test for device /dev/v4l-subdev21:

Driver Info:
	Driver version   : 7.0.0
	Capabilities     : 0x00000000
	Client Capabilities: 0x0000000000000002
interval-uses-which
Required ioctls:
	test VIDIOC_SUDBEV_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/v4l-subdev21 open: OK
	test VIDIOC_SUBDEV_QUERYCAP: OK
	test for unlimited opens: OK

Debug ioctls:
	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 (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 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:
	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: 12 Private Controls: 0

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

Codec ioctls:
	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:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
	test CREATE_BUFS maximum buffers: OK
	test VIDIOC_REMOVE_BUFS: OK
	test VIDIOC_EXPBUF: OK (Not Supported)
	test Requests: OK (Not Supported)
	test blocking wait: OK (Not Supported)

Total for device /dev/v4l-subdev21: 46, Succeeded: 46, Failed: 0, Warnings: 0


V2 -> V3

In Patch 1/3
- Added required endpoint

In Patch 2/3
- Change the capturing to full active-area of 5760x4312, up to 30fps.
- Replace mode table with imx576_program_window().
- Added DT-configurable link frequency with PLL parameters.

In Patch 3/3
- Replace the hardcoded orientation <0> with <MEDIA_ORIENTATION_FRONT>.


V1 -> V2

In Patch 1/3
- Rename regulator supplies to (vana, vdig, vif).

In Patch 2/3
- Rename link_freq array to avoid confusion with the link_freq control.
- Use IMX576_EXPOSURE_STEP in exposure control range update.
- Make cci_write() error handling consistent.
- Return imx576_set_pad_format() result instead of return 0.
- Initialize link_freq_index before creating the link frequency control.
- Replace dev_err() with dev_err_probe().
- Remove redundant comment.

In Patch 3/3
- Added the remaining supplies CSIPHYs (0-3).
- Add comment for camera orientation property.
- Move cam_mclk1_default{..} pinctrl definition to SoC SM6350 dtsi.


Hardevsinh Palaniya (2):
  dt-bindings: media: i2c: Add imx576 sensor
  arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera
    support

Himanshu Bhavani (1):
  media: i2c: add imx576 image sensor driver

 .../bindings/media/i2c/sony,imx576.yaml       |  114 ++
 MAINTAINERS                                   |    8 +
 arch/arm64/boot/dts/qcom/sm6350.dtsi          |    7 +
 .../boot/dts/qcom/sm7225-fairphone-fp4.dts    |   54 +-
 drivers/media/i2c/Kconfig                     |   10 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/imx576.c                    | 1054 +++++++++++++++++
 7 files changed, 1247 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml
 create mode 100644 drivers/media/i2c/imx576.c

--
2.34.1


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

* [PATCH v3 1/3] dt-bindings: media: i2c: Add imx576 sensor
  2026-08-06 12:02 [PATCH v3 0/3] media: i2c: Add imx576 camera sensor driver Himanshu Bhavani
@ 2026-08-06 12:02 ` Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 2/3] media: i2c: add imx576 image sensor driver Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support Himanshu Bhavani
  2 siblings, 0 replies; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-06 12:02 UTC (permalink / raw)
  To: sakari.ailus
  Cc: Hardevsinh Palaniya, Himanshu Bhavani, Krzysztof Kozlowski,
	Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Konrad Dybcio, Hans Verkuil,
	Vladimir Zapolskiy, Hans de Goede, Mehdi Djait, Elgin Perumbilly,
	Xiaolei Wang, Kate Hsuan, Walter Werner Schneider,
	Laurent Pinchart, Bartosz Golaszewski, Miguel Vadillo, Jai Luthra,
	linux-media, devicetree, linux-kernel, linux-arm-msm

From: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>

Add bindings for Sony IMX576 sensor

Signed-off-by: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
 .../bindings/media/i2c/sony,imx576.yaml       | 114 ++++++++++++++++++
 MAINTAINERS                                   |   7 ++
 2 files changed, 121 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml
new file mode 100644
index 000000000000..c82efd17eb7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx576.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony IMX576 Image Sensor
+
+maintainers:
+  - Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
+
+description:
+  IMX576 sensor is a Sony CMOS active pixel digital image sensor with an active
+  array size of 5760(H) × 4312(V). It is programmable through an I2C interface.
+  Image data is transmitted through MIPI CSI-2. It supports RAW10/RAW8, COMP8
+  output formats.
+
+allOf:
+  - $ref: /schemas/media/video-interface-devices.yaml#
+
+properties:
+  compatible:
+    const: sony,imx576
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: INCLK clock
+
+  vana-supply:
+    description: Analog Supply Voltage (2.8v)
+
+  vdig-supply:
+    description: Digital Supply Voltage (1.05v)
+
+  vif-supply:
+    description: Interface Supply Voltage (1.8v)
+
+  reset-gpios:
+    maxItems: 1
+    description: Reset Pin GPIO Control (active low)
+
+  port:
+    description: MIPI CSI-2 transmitter port
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            oneOf:
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+              - items:
+                  - const: 1
+                  - const: 2
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - vana-supply
+  - vif-supply
+  - vdig-supply
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera-sensor@10 {
+            compatible = "sony,imx576";
+            reg = <0x10>;
+            clocks = <&imx576_clk>;
+            reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+
+            vana-supply = <&vreg_l3p>;
+            vif-supply = <&vreg_l6p>;
+            vdig-supply = <&vreg_32m_cam_dvdd_1p05>;
+
+            orientation = <0>;
+            rotation = <90>;
+
+            port {
+                cam_out: endpoint {
+                   remote-endpoint = <&csiphy3_ep>;
+                   data-lanes = <1 2 3 4>;
+                   link-frequencies = /bits/ 64 <1017000000>;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index e95fc6f2ddc6..faf5753be337 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25437,6 +25437,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml
 F:	drivers/media/i2c/imx678.c

+SONY IMX576 SENSOR DRIVER
+M:	Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
+M:	Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml
+
 SONY MEMORYSTICK SUBSYSTEM
 M:	Maxim Levitsky <maximlevitsky@gmail.com>
 M:	Alex Dubov <oakad@yahoo.com>
--
2.34.1


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

* [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-06 12:02 [PATCH v3 0/3] media: i2c: Add imx576 camera sensor driver Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 1/3] dt-bindings: media: i2c: Add imx576 sensor Himanshu Bhavani
@ 2026-08-06 12:02 ` Himanshu Bhavani
  2026-08-07  7:00   ` Jai Luthra
  2026-08-06 12:02 ` [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support Himanshu Bhavani
  2 siblings, 1 reply; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-06 12:02 UTC (permalink / raw)
  To: sakari.ailus
  Cc: Himanshu Bhavani, Hardevsinh Palaniya, Mauro Carvalho Chehab,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Hans Verkuil, Hans de Goede, Vladimir Zapolskiy,
	Mehdi Djait, Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	Jai Luthra, linux-media, devicetree, linux-kernel, linux-arm-msm

Add a v4l2 subdevice driver for the Sony imx576 sensor.

The Sony IMX576 image sensor with an active
array size of 5760 x 4312

The following features are supported:
- Manual exposure an gain control support
- vblank/hblank control support
- Supported resolution: 5760 x 4312 30fps (SRGGB10)

Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
---
 MAINTAINERS                |    1 +
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/imx576.c | 1054 ++++++++++++++++++++++++++++++++++++
 4 files changed, 1066 insertions(+)
 create mode 100644 drivers/media/i2c/imx576.c

diff --git a/MAINTAINERS b/MAINTAINERS
index faf5753be337..81f25c74be8b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25443,6 +25443,7 @@ M:	Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/i2c/sony,imx576.yaml
+F:	drivers/media/i2c/imx576.c

 SONY MEMORYSTICK SUBSYSTEM
 M:	Maxim Levitsky <maximlevitsky@gmail.com>
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index fc2954098eaf..05d1e69c2f33 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -288,6 +288,16 @@ config VIDEO_IMX415
 	  To compile this driver as a module, choose M here: the
 	  module will be called imx415.

+config VIDEO_IMX576
+        tristate "Sony IMX576 sensor support"
+        select V4L2_CCI_I2C
+        help
+          This is a Video4Linux2 sensor driver for the Sony
+          IMX576 camera.
+
+          To compile this driver as a module, choose M here: the
+          module will be called imx576.
+
 config VIDEO_MAX9271_LIB
 	tristate

diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index d04bd5724552..57cf6a169441 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_VIDEO_IMX412) += imx412.o
 obj-$(CONFIG_VIDEO_IMX415) += imx415.o
 obj-$(CONFIG_VIDEO_IMX678) += imx678.o
 obj-$(CONFIG_VIDEO_IMX471) += imx471.o
+obj-$(CONFIG_VIDEO_IMX576) += imx576.o
 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
diff --git a/drivers/media/i2c/imx576.c b/drivers/media/i2c/imx576.c
new file mode 100644
index 000000000000..24ed60ffe234
--- /dev/null
+++ b/drivers/media/i2c/imx576.c
@@ -0,0 +1,1054 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * V4L2 Support for the IMX576
+ *
+ * Copyright (C) 2026 Silicon Signals Pvt. Ltd.
+ *
+ * Copyright (C) 2024 Luca Weiss <luca.weiss@fairphone.com>
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device/devres.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/units.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mediabus.h>
+
+#define IMX576_INCLK_RATE		(24 * HZ_PER_MHZ)
+
+#define IMX576_REG_CHIP_ID		CCI_REG16(0x0016)
+#define IMX576_CHIP_ID			0x0576
+
+#define IMX576_REG_MODE_SELECT		CCI_REG8(0x0100)
+#define IMX576_MODE_STANDBY		0x00
+#define IMX576_MODE_STREAMING		0x01
+
+#define IMX576_REG_HOLD			CCI_REG8(0x0104)
+
+#define IMX576_REG_EXPOSURE		CCI_REG16(0x0202)
+#define IMX576_EXPOSURE_MIN		8
+#define IMX576_EXPOSURE_OFFSET		22
+#define IMX576_EXPOSURE_STEP		1
+#define IMX576_EXPOSURE_DEFAULT		0x0648
+
+#define IMX576_REG_ANALOG_GAIN		CCI_REG16(0x0204)
+#define IMX576_ANA_GAIN_MIN		0
+#define IMX576_ANA_GAIN_MAX		978
+#define IMX576_ANA_GAIN_STEP		1
+#define IMX576_ANA_GAIN_DEFAULT		0
+
+#define IMX576_REG_IVT_PXCK_DIV		CCI_REG8(0x0301)
+#define IMX576_REG_IVT_SYCK_DIV		CCI_REG8(0x0303)
+#define IMX576_REG_IVT_PREPLLCK_DIV	CCI_REG8(0x0305)
+#define IMX576_REG_IVT_PLL_MPY		CCI_REG16(0x0306)
+#define IMX576_REG_IOP_SYCK_DIV		CCI_REG8(0x030b)
+#define IMX576_REG_IOP_PREPLLCK_DIV	CCI_REG8(0x030d)
+#define IMX576_REG_IOP_PLL_MPY		CCI_REG16(0x030e)
+#define IMX576_REG_PLL_MULT_DRIV	CCI_REG8(0x0310)
+
+#define IMX576_REG_FRM_LENGTH_LINES	CCI_REG16(0x0340)
+#define IMX576_REG_LINE_LENGTH_PCK	CCI_REG16(0x0342)
+#define IMX576_LINE_LENGTH		6144
+#define IMX576_VBLANK_DEF		4387
+
+/* FIXME: Exact VBLANK limit unknown (no datasheet). */
+#define IMX576_VBLANK_MAX		32420
+
+#define IMX576_REG_X_ADD_STA		CCI_REG16(0x0344)
+#define IMX576_REG_Y_ADD_STA		CCI_REG16(0x0346)
+#define IMX576_REG_X_ADD_END		CCI_REG16(0x0348)
+#define IMX576_REG_Y_ADD_END		CCI_REG16(0x034a)
+#define IMX576_REG_X_OUTPUT_SIZE	CCI_REG16(0x034c)
+#define IMX576_REG_Y_OUTPUT_SIZE	CCI_REG16(0x034e)
+
+#define IMX576_REG_DIG_CROP_X_OFFSET	CCI_REG16(0x0408)
+#define IMX576_REG_DIG_CROP_Y_OFFSET	CCI_REG16(0x040a)
+#define IMX576_REG_DIG_CROP_WIDTH	CCI_REG16(0x040c)
+#define IMX576_REG_DIG_CROP_HEIGHT	CCI_REG16(0x040e)
+
+#define IMX576_REG_BINNING_MODE		CCI_REG8(0x0900)
+#define IMX576_REG_BINNING_TYPE		CCI_REG8(0x0901)
+#define IMX576_REG_BINNING_WEIGHT	CCI_REG8(0x0902)
+
+#define IMX576_PIXEL_RATE		813600000
+#define IMX576_NUM_DATA_LANES		4
+
+/* IMX576 native and active pixel array size */
+static const struct v4l2_rect imx576_native_area = {
+	.top = 0,
+	.left = 0,
+	.width = 5792,
+	.height = 4464,
+};
+
+static const struct v4l2_rect imx576_active_area = {
+	.top = 136,
+	.left = 16,
+	.width = 5760,
+	.height = 4312,
+};
+
+static const char * const imx576_supply_names[] = {
+	"vana",		/* Analog Power */
+	"vif",		/* Interface Power */
+	"vdig",		/* Digital Power */
+};
+
+static const struct cci_reg_sequence imx576_common_regs[] = {
+	{ CCI_REG8(0x0136), 0x18 },
+	{ CCI_REG8(0x0137), 0x00 },
+	{ CCI_REG8(0x3c7e), 0x05 },
+	{ CCI_REG8(0x3c7f), 0x07 },
+	{ CCI_REG8(0x380d), 0x80 },
+	{ CCI_REG8(0x3c00), 0x1a },
+	{ CCI_REG8(0x3c01), 0x1a },
+	{ CCI_REG8(0x3c02), 0x1a },
+	{ CCI_REG8(0x3c03), 0x1a },
+	{ CCI_REG8(0x3c04), 0x1a },
+	{ CCI_REG8(0x3c05), 0x01 },
+	{ CCI_REG8(0x3c08), 0xff },
+	{ CCI_REG8(0x3c09), 0xff },
+	{ CCI_REG8(0x3c0a), 0x01 },
+	{ CCI_REG8(0x3c0d), 0xff },
+	{ CCI_REG8(0x3c0e), 0xff },
+	{ CCI_REG8(0x3c0f), 0x20 },
+	{ CCI_REG8(0x3f89), 0x01 },
+	{ CCI_REG8(0x4b8e), 0x18 },
+	{ CCI_REG8(0x4b8f), 0x10 },
+	{ CCI_REG8(0x4ba8), 0x08 },
+	{ CCI_REG8(0x4baa), 0x08 },
+	{ CCI_REG8(0x4bab), 0x08 },
+	{ CCI_REG8(0x4bc9), 0x10 },
+	{ CCI_REG8(0x5511), 0x01 },
+	{ CCI_REG8(0x560b), 0x5b },
+	{ CCI_REG8(0x56a7), 0x60 },
+	{ CCI_REG8(0x5b3b), 0x60 },
+	{ CCI_REG8(0x5ba7), 0x60 },
+	{ CCI_REG8(0x6002), 0x00 },
+	{ CCI_REG8(0x6014), 0x01 },
+	{ CCI_REG8(0x6118), 0x0a },
+	{ CCI_REG8(0x6122), 0x0a },
+	{ CCI_REG8(0x6128), 0x0a },
+	{ CCI_REG8(0x6132), 0x0a },
+	{ CCI_REG8(0x6138), 0x0a },
+	{ CCI_REG8(0x6142), 0x0a },
+	{ CCI_REG8(0x6148), 0x0a },
+	{ CCI_REG8(0x6152), 0x0a },
+	{ CCI_REG8(0x617b), 0x04 },
+	{ CCI_REG8(0x617e), 0x04 },
+	{ CCI_REG8(0x6187), 0x04 },
+	{ CCI_REG8(0x618a), 0x04 },
+	{ CCI_REG8(0x6193), 0x04 },
+	{ CCI_REG8(0x6196), 0x04 },
+	{ CCI_REG8(0x619f), 0x04 },
+	{ CCI_REG8(0x61a2), 0x04 },
+	{ CCI_REG8(0x61ab), 0x04 },
+	{ CCI_REG8(0x61ae), 0x04 },
+	{ CCI_REG8(0x61b7), 0x04 },
+	{ CCI_REG8(0x61ba), 0x04 },
+	{ CCI_REG8(0x61c3), 0x04 },
+	{ CCI_REG8(0x61c6), 0x04 },
+	{ CCI_REG8(0x61cf), 0x04 },
+	{ CCI_REG8(0x61d2), 0x04 },
+	{ CCI_REG8(0x61db), 0x04 },
+	{ CCI_REG8(0x61de), 0x04 },
+	{ CCI_REG8(0x61e7), 0x04 },
+	{ CCI_REG8(0x61ea), 0x04 },
+	{ CCI_REG8(0x61f3), 0x04 },
+	{ CCI_REG8(0x61f6), 0x04 },
+	{ CCI_REG8(0x61ff), 0x04 },
+	{ CCI_REG8(0x6202), 0x04 },
+	{ CCI_REG8(0x620b), 0x04 },
+	{ CCI_REG8(0x620e), 0x04 },
+	{ CCI_REG8(0x6217), 0x04 },
+	{ CCI_REG8(0x621a), 0x04 },
+	{ CCI_REG8(0x6223), 0x04 },
+	{ CCI_REG8(0x6226), 0x04 },
+	{ CCI_REG8(0x6b0b), 0x02 },
+	{ CCI_REG8(0x6b0c), 0x01 },
+	{ CCI_REG8(0x6b0d), 0x05 },
+	{ CCI_REG8(0x6b0f), 0x04 },
+	{ CCI_REG8(0x6b10), 0x02 },
+	{ CCI_REG8(0x6b11), 0x06 },
+	{ CCI_REG8(0x6b12), 0x03 },
+	{ CCI_REG8(0x6b13), 0x07 },
+	{ CCI_REG8(0x6b14), 0x0d },
+	{ CCI_REG8(0x6b15), 0x09 },
+	{ CCI_REG8(0x6b16), 0x0c },
+	{ CCI_REG8(0x6b17), 0x08 },
+	{ CCI_REG8(0x6b18), 0x0e },
+	{ CCI_REG8(0x6b19), 0x0a },
+	{ CCI_REG8(0x6b1a), 0x0f },
+	{ CCI_REG8(0x6b1b), 0x0b },
+	{ CCI_REG8(0x6b1c), 0x01 },
+	{ CCI_REG8(0x6b1d), 0x05 },
+	{ CCI_REG8(0x6b1f), 0x04 },
+	{ CCI_REG8(0x6b20), 0x02 },
+	{ CCI_REG8(0x6b21), 0x06 },
+	{ CCI_REG8(0x6b22), 0x03 },
+	{ CCI_REG8(0x6b23), 0x07 },
+	{ CCI_REG8(0x6b24), 0x0d },
+	{ CCI_REG8(0x6b25), 0x09 },
+	{ CCI_REG8(0x6b26), 0x0c },
+	{ CCI_REG8(0x6b27), 0x08 },
+	{ CCI_REG8(0x6b28), 0x0e },
+	{ CCI_REG8(0x6b29), 0x0a },
+	{ CCI_REG8(0x6b2a), 0x0f },
+	{ CCI_REG8(0x6b2b), 0x0b },
+	{ CCI_REG8(0x7948), 0x01 },
+	{ CCI_REG8(0x7949), 0x06 },
+	{ CCI_REG8(0x794b), 0x04 },
+	{ CCI_REG8(0x794c), 0x04 },
+	{ CCI_REG8(0x794d), 0x3a },
+	{ CCI_REG8(0x7951), 0x00 },
+	{ CCI_REG8(0x7952), 0x01 },
+	{ CCI_REG8(0x7955), 0x00 },
+	{ CCI_REG8(0x9004), 0x10 },
+	{ CCI_REG8(0x9200), 0xa0 },
+	{ CCI_REG8(0x9201), 0xa7 },
+	{ CCI_REG8(0x9202), 0xa0 },
+	{ CCI_REG8(0x9203), 0xaa },
+	{ CCI_REG8(0x9204), 0xa0 },
+	{ CCI_REG8(0x9205), 0xad },
+	{ CCI_REG8(0x9206), 0xa0 },
+	{ CCI_REG8(0x9207), 0xb0 },
+	{ CCI_REG8(0x9208), 0xa0 },
+	{ CCI_REG8(0x9209), 0xb3 },
+	{ CCI_REG8(0x920a), 0xb7 },
+	{ CCI_REG8(0x920b), 0x34 },
+	{ CCI_REG8(0x920c), 0xb7 },
+	{ CCI_REG8(0x920d), 0x36 },
+	{ CCI_REG8(0x920e), 0xb7 },
+	{ CCI_REG8(0x920f), 0x37 },
+	{ CCI_REG8(0x9210), 0xb7 },
+	{ CCI_REG8(0x9211), 0x38 },
+	{ CCI_REG8(0x9212), 0xb7 },
+	{ CCI_REG8(0x9213), 0x39 },
+	{ CCI_REG8(0x9214), 0xb7 },
+	{ CCI_REG8(0x9215), 0x3a },
+	{ CCI_REG8(0x9216), 0xb7 },
+	{ CCI_REG8(0x9217), 0x3c },
+	{ CCI_REG8(0x9218), 0xb7 },
+	{ CCI_REG8(0x9219), 0x3d },
+	{ CCI_REG8(0x921a), 0xb7 },
+	{ CCI_REG8(0x921b), 0x3e },
+	{ CCI_REG8(0x921c), 0xb7 },
+	{ CCI_REG8(0x921d), 0x3f },
+	{ CCI_REG8(0x921e), 0x7f },
+	{ CCI_REG8(0x921f), 0x77 },
+	{ CCI_REG8(0x99af), 0x0f },
+	{ CCI_REG8(0x99b0), 0x0f },
+	{ CCI_REG8(0x99b1), 0x0f },
+	{ CCI_REG8(0x99b2), 0x0f },
+	{ CCI_REG8(0x99b3), 0x0f },
+	{ CCI_REG8(0x99e1), 0x0f },
+	{ CCI_REG8(0x99e2), 0x0f },
+	{ CCI_REG8(0x99e3), 0x0f },
+	{ CCI_REG8(0x99e4), 0x0f },
+	{ CCI_REG8(0x99e5), 0x0f },
+	{ CCI_REG8(0x99e6), 0x0f },
+	{ CCI_REG8(0x99e7), 0x0f },
+	{ CCI_REG8(0x99e8), 0x0f },
+	{ CCI_REG8(0x99e9), 0x0f },
+	{ CCI_REG8(0x99ea), 0x0f },
+	{ CCI_REG8(0xe286), 0x31 },
+	{ CCI_REG8(0xe2a6), 0x32 },
+	{ CCI_REG8(0xe2c6), 0x33 },
+	{ CCI_REG8(0x4038), 0x00 },
+	{ CCI_REG8(0x9856), 0xa0 },
+	{ CCI_REG8(0x9857), 0x78 },
+	{ CCI_REG8(0x9858), 0x64 },
+	{ CCI_REG8(0x986e), 0x64 },
+	{ CCI_REG8(0x9870), 0x3c },
+	{ CCI_REG8(0x993a), 0x0e },
+	{ CCI_REG8(0x993b), 0x0e },
+	{ CCI_REG8(0x9953), 0x08 },
+	{ CCI_REG8(0x9954), 0x08 },
+	{ CCI_REG8(0x996b), 0x0f },
+	{ CCI_REG8(0x996d), 0x0f },
+	{ CCI_REG8(0x996f), 0x0f },
+	{ CCI_REG8(0x998e), 0x0f },
+	{ CCI_REG8(0xa101), 0x01 },
+	{ CCI_REG8(0xa103), 0x01 },
+	{ CCI_REG8(0xa105), 0x01 },
+	{ CCI_REG8(0xa107), 0x01 },
+	{ CCI_REG8(0xa109), 0x01 },
+	{ CCI_REG8(0xa10b), 0x01 },
+	{ CCI_REG8(0xa10d), 0x01 },
+	{ CCI_REG8(0xa10f), 0x01 },
+	{ CCI_REG8(0xa111), 0x01 },
+	{ CCI_REG8(0xa113), 0x01 },
+	{ CCI_REG8(0xa115), 0x01 },
+	{ CCI_REG8(0xa117), 0x01 },
+	{ CCI_REG8(0xa119), 0x01 },
+	{ CCI_REG8(0xa11b), 0x01 },
+	{ CCI_REG8(0xa11d), 0x01 },
+	{ CCI_REG8(0xaa58), 0x00 },
+	{ CCI_REG8(0xaa59), 0x01 },
+	{ CCI_REG8(0xab03), 0x10 },
+	{ CCI_REG8(0xab04), 0x10 },
+	{ CCI_REG8(0xab05), 0x10 },
+	{ CCI_REG8(0xad6a), 0x03 },
+	{ CCI_REG8(0xad6b), 0xff },
+	{ CCI_REG8(0xad77), 0x00 },
+	{ CCI_REG8(0xad82), 0x03 },
+	{ CCI_REG8(0xad83), 0xff },
+	{ CCI_REG8(0xae06), 0x04 },
+	{ CCI_REG8(0xae07), 0x16 },
+	{ CCI_REG8(0xae08), 0xff },
+	{ CCI_REG8(0xae09), 0x04 },
+	{ CCI_REG8(0xae0a), 0x16 },
+	{ CCI_REG8(0xae0b), 0xff },
+	{ CCI_REG8(0xaf01), 0x04 },
+	{ CCI_REG8(0xaf03), 0x0a },
+	{ CCI_REG8(0xaf05), 0x18 },
+	{ CCI_REG8(0xb048), 0x0a },
+	{ CCI_REG8(0x0112), 0x0a },
+	{ CCI_REG8(0x0113), 0x0a },
+	{ CCI_REG8(0x0114), 0x03 },
+	{ CCI_REG8(0x0342), 0x18 },
+	{ CCI_REG8(0x0343), 0x00 },
+	{ CCI_REG8(0x0220), 0x00 },
+	{ CCI_REG8(0x3140), 0x00 },
+	{ CCI_REG8(0x3246), 0x01 },
+	{ CCI_REG8(0x3247), 0x01 },
+	{ CCI_REG8(0x0401), 0x00 },
+	{ CCI_REG8(0x0404), 0x00 },
+	{ CCI_REG8(0x0405), 0x10 },
+	{ IMX576_REG_IVT_PXCK_DIV, 0x05 },
+	{ IMX576_REG_IVT_SYCK_DIV, 0x02 },
+	{ IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
+	{ IMX576_REG_IVT_PLL_MPY, 0x0154 },
+	{ IMX576_REG_IOP_SYCK_DIV, 0x01 },
+	{ IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
+	{ IMX576_REG_PLL_MULT_DRIV, 0x01 },
+	{ CCI_REG8(0x0b06), 0x01 },
+	{ CCI_REG8(0x3620), 0x01 },
+	{ CCI_REG8(0x3f0c), 0x00 },
+};
+
+struct imx576 {
+	struct device *dev;
+	struct regmap *regmap;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct gpio_desc *reset_gpio;
+	struct clk *inclk;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(imx576_supply_names)];
+
+	/* V4L2 Controls */
+	struct v4l2_ctrl_handler handler;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *gain;
+
+	u32 link_freq_index;
+
+	unsigned long link_freq_bitmap;
+};
+
+struct imx576_reg_list {
+	u32 num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+enum {
+	IMX576_LINK_FREQ_1017MHZ,
+};
+
+static const s64 link_freqs[] = {
+	[IMX576_LINK_FREQ_1017MHZ] = 1017000000,
+};
+
+static const struct cci_reg_sequence link_1017Mhz_regs[] = {
+	{ IMX576_REG_IOP_PLL_MPY, 0x0153 },
+};
+
+static const struct imx576_reg_list link_freq_regs[] = {
+	[IMX576_LINK_FREQ_1017MHZ] = {
+		.regs = link_1017Mhz_regs,
+		.num_of_regs = ARRAY_SIZE(link_1017Mhz_regs)
+	},
+};
+
+static const u32 imx576_mbus_codes[] = {
+	MEDIA_BUS_FMT_SRGGB10_1X10,
+};
+
+static inline struct imx576 *to_imx576(struct v4l2_subdev *sd)
+{
+	return container_of_const(sd, struct imx576, sd);
+}
+
+static int imx576_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct imx576 *imx576 = container_of_const(ctrl->handler,
+						   struct imx576, handler);
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	int ret = 0;
+
+	state = v4l2_subdev_get_locked_active_state(&imx576->sd);
+	fmt = v4l2_subdev_state_get_format(state, 0);
+
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Honour the VBLANK limits when setting exposure */
+		ret = __v4l2_ctrl_modify_range(imx576->exposure,
+					       IMX576_EXPOSURE_MIN,
+					       fmt->height + ctrl->val -
+					       IMX576_EXPOSURE_OFFSET,
+					       IMX576_EXPOSURE_STEP,
+					       IMX576_EXPOSURE_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	if (pm_runtime_get_if_active(imx576->dev) == 0)
+		return 0;
+
+	cci_write(imx576->regmap, IMX576_REG_HOLD, 1, &ret);
+
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK: {
+		u64 vmax = fmt->height + ctrl->val;
+
+		cci_write(imx576->regmap, IMX576_REG_FRM_LENGTH_LINES, vmax, &ret);
+		break;
+	}
+	case V4L2_CID_EXPOSURE:
+		cci_write(imx576->regmap, IMX576_REG_EXPOSURE, ctrl->val, &ret);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		cci_write(imx576->regmap, IMX576_REG_ANALOG_GAIN,
+			  ctrl->val, &ret);
+		break;
+	default:
+		dev_err(imx576->dev, "Invalid control %d\n", ctrl->id);
+		ret = -EINVAL;
+		break;
+	}
+
+	cci_write(imx576->regmap, IMX576_REG_HOLD, 0, &ret);
+
+	pm_runtime_put(imx576->dev);
+
+	return ret;
+}
+
+static int imx576_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(imx576_mbus_codes))
+		return -EINVAL;
+
+	code->code = imx576_mbus_codes[code->index];
+
+	return 0;
+}
+
+static int imx576_set_pad_format(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_format *fmt)
+{
+	struct imx576 *imx576 = to_imx576(sd);
+	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *crop;
+	int ret;
+
+	fmt->format.width = imx576_active_area.width;
+	fmt->format.height = imx576_active_area.height;
+	fmt->format.code = imx576_mbus_codes[0];
+	fmt->format.field = V4L2_FIELD_NONE;
+	fmt->format.colorspace = V4L2_COLORSPACE_RAW;
+	fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
+	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
+
+	format = v4l2_subdev_state_get_format(sd_state, 0);
+
+	*format = fmt->format;
+
+	crop = v4l2_subdev_state_get_crop(sd_state, 0);
+	*crop = imx576_active_area;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		u32 vblank_def = IMX576_VBLANK_DEF - imx576_active_area.height;
+
+		ret = __v4l2_ctrl_modify_range(imx576->vblank, vblank_def,
+					       IMX576_VBLANK_MAX, 1, vblank_def);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int imx576_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *sd_state,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r = imx576_native_area;
+		return 0;
+	case V4L2_SEL_TGT_CROP: {
+		struct v4l2_rect *crop;
+
+		crop = v4l2_subdev_state_get_crop(sd_state, sel->pad);
+		sel->r = *crop;
+
+		return 0;
+	}
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		sel->r = imx576_active_area;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int imx576_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fsize)
+{
+	if (fsize->index > 0)
+		return -EINVAL;
+
+	if (fsize->code != imx576_mbus_codes[0])
+		return -EINVAL;
+
+	fsize->min_width = imx576_active_area.width;
+	fsize->max_width = fsize->min_width;
+	fsize->min_height = imx576_active_area.height;
+	fsize->max_height = fsize->min_height;
+
+	return 0;
+}
+
+static int imx576_program_window(struct imx576 *imx576,
+				 struct v4l2_subdev_state *state)
+{
+	const struct v4l2_rect *crop;
+	const struct v4l2_mbus_framefmt *format;
+	int ret = 0;
+	s32 x_start, y_start;
+
+	crop = v4l2_subdev_state_get_crop(state, 0);
+	format = v4l2_subdev_state_get_format(state, 0);
+
+	/* Line length */
+	cci_write(imx576->regmap, IMX576_REG_LINE_LENGTH_PCK, IMX576_LINE_LENGTH,
+		  &ret);
+
+	/* Imaging area */
+	x_start = crop->left - imx576_active_area.left;
+	y_start = crop->top - imx576_active_area.top;
+	cci_write(imx576->regmap, IMX576_REG_X_ADD_STA, x_start, &ret);
+	cci_write(imx576->regmap, IMX576_REG_Y_ADD_STA, y_start, &ret);
+	cci_write(imx576->regmap, IMX576_REG_X_ADD_END, x_start + crop->width - 1,
+		  &ret);
+	cci_write(imx576->regmap, IMX576_REG_Y_ADD_END, y_start + crop->height - 1,
+		  &ret);
+
+	/* Binning */
+	cci_write(imx576->regmap, IMX576_REG_BINNING_MODE, 0x00, &ret);
+	cci_write(imx576->regmap, IMX576_REG_BINNING_TYPE, 0x11, &ret);
+	cci_write(imx576->regmap, IMX576_REG_BINNING_WEIGHT, 0x0a, &ret);
+
+	/* Digital crop */
+	cci_write(imx576->regmap, IMX576_REG_DIG_CROP_X_OFFSET, 0, &ret);
+	cci_write(imx576->regmap, IMX576_REG_DIG_CROP_Y_OFFSET, 0, &ret);
+	cci_write(imx576->regmap, IMX576_REG_DIG_CROP_WIDTH, format->width, &ret);
+	cci_write(imx576->regmap, IMX576_REG_DIG_CROP_HEIGHT, format->height, &ret);
+
+	/* Output size */
+	cci_write(imx576->regmap, IMX576_REG_X_OUTPUT_SIZE, format->width, &ret);
+	cci_write(imx576->regmap, IMX576_REG_Y_OUTPUT_SIZE, format->height, &ret);
+
+	return ret;
+}
+
+static int imx576_enable_streams(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state,
+				 u32 pad, u64 streams_mask)
+{
+	const struct imx576_reg_list *link_freq_reg;
+	struct imx576 *imx576 = to_imx576(sd);
+	int ret;
+
+	ret = pm_runtime_resume_and_get(imx576->dev);
+	if (ret < 0)
+		return ret;
+
+	/* Write common registers */
+	ret = cci_multi_reg_write(imx576->regmap, imx576_common_regs,
+				  ARRAY_SIZE(imx576_common_regs), NULL);
+	if (ret) {
+		dev_err(imx576->dev, "failed to write common registers\n");
+		goto err_rpm_put;
+	}
+
+	/* Program window registers */
+	ret = imx576_program_window(imx576, state);
+	if (ret) {
+		dev_err(imx576->dev, "failed to program window\n");
+		goto err_rpm_put;
+	}
+
+	/* Set link frequency registers */
+	link_freq_reg = &link_freq_regs[__ffs(imx576->link_freq_bitmap)];
+	cci_multi_reg_write(imx576->regmap, link_freq_reg->regs,
+			    link_freq_reg->num_of_regs, &ret);
+	if (ret) {
+		dev_err(imx576->dev, "failed to set link frequency registers\n");
+		goto err_rpm_put;
+	}
+
+	/* Apply customized user controls */
+	ret =  __v4l2_ctrl_handler_setup(imx576->sd.ctrl_handler);
+	if (ret) {
+		dev_err(imx576->dev, "fail to setup handler\n");
+		goto err_rpm_put;
+	}
+
+	/* T7: delay before sending stream command */
+	usleep_range(8000, 9000);
+
+	/* Start streaming */
+	ret = cci_write(imx576->regmap, IMX576_REG_MODE_SELECT,
+			IMX576_MODE_STREAMING, NULL);
+	if (ret) {
+		dev_err(imx576->dev, "fail to start streaming\n");
+		goto err_rpm_put;
+	}
+
+	return 0;
+
+err_rpm_put:
+	pm_runtime_put(imx576->dev);
+
+	return ret;
+}
+
+static int imx576_disable_streams(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state,
+				  u32 pad, u64 streams_mask)
+{
+	struct imx576 *imx576 = to_imx576(sd);
+	int ret;
+
+	ret = cci_write(imx576->regmap, IMX576_REG_MODE_SELECT,
+			IMX576_MODE_STANDBY, NULL);
+	if (ret)
+		dev_err(imx576->dev, "failed to set stream off\n");
+
+	pm_runtime_put(imx576->dev);
+
+	return 0;
+}
+
+static int imx576_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *sd_state)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_TRY,
+		.pad = 0,
+		.format = {
+			.code = imx576_mbus_codes[0],
+			.width = imx576_active_area.width,
+			.height = imx576_active_area.height,
+		},
+	};
+
+	return imx576_set_pad_format(sd, sd_state, &fmt);
+}
+
+static const struct v4l2_subdev_video_ops imx576_video_ops = {
+	.s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops imx576_pad_ops = {
+	.enum_mbus_code = imx576_enum_mbus_code,
+	.enum_frame_size = imx576_enum_frame_size,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = imx576_set_pad_format,
+	.get_selection = imx576_get_selection,
+	.enable_streams = imx576_enable_streams,
+	.disable_streams = imx576_disable_streams,
+};
+
+static const struct v4l2_subdev_internal_ops imx576_internal_ops = {
+	.init_state = imx576_init_state,
+};
+
+static const struct v4l2_subdev_ops imx576_subdev_ops = {
+	.video = &imx576_video_ops,
+	.pad = &imx576_pad_ops,
+};
+
+static const struct v4l2_ctrl_ops imx576_ctrl_ops = {
+	.s_ctrl = imx576_set_ctrl,
+};
+
+static int imx576_detect(struct imx576 *imx576)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(imx576->regmap, IMX576_REG_CHIP_ID, &val, NULL);
+	if (ret)
+		return dev_err_probe(imx576->dev, ret,
+				     "failed to read chip id %x\n",
+				     IMX576_CHIP_ID);
+
+	if (val != IMX576_CHIP_ID)
+		return dev_err_probe(imx576->dev, -EIO,
+				     "chip id mismatch: %x!=%llx\n",
+				     IMX576_CHIP_ID, val);
+
+	return 0;
+}
+
+static int imx576_power_on(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct imx576 *imx576 = to_imx576(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(imx576_supply_names),
+				    imx576->supplies);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable regulators\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(imx576->inclk);
+	if (ret) {
+		dev_err(imx576->dev, "fail to enable inclk\n");
+		goto err_regulator_off;
+	}
+
+	gpiod_set_value_cansleep(imx576->reset_gpio, 0);
+
+	/* T6: Wait for internal init before CCI access */
+	usleep_range(1000, 1200);
+
+	return 0;
+
+err_regulator_off:
+	regulator_bulk_disable(ARRAY_SIZE(imx576_supply_names),
+			       imx576->supplies);
+
+	return ret;
+}
+
+static int imx576_power_off(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct imx576 *imx576 = to_imx576(sd);
+
+	clk_disable_unprepare(imx576->inclk);
+
+	gpiod_set_value_cansleep(imx576->reset_gpio, 1);
+
+	regulator_bulk_disable(ARRAY_SIZE(imx576_supply_names),
+			       imx576->supplies);
+
+	return 0;
+}
+
+static int imx576_parse_endpoint(struct imx576 *imx576)
+{
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	struct fwnode_handle *ep;
+	int ret;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(imx576->dev), 0, 0, 0);
+	if (!ep)
+		return dev_err_probe(imx576->dev, -ENXIO,
+				     "Failed to get next endpoint\n");
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+	fwnode_handle_put(ep);
+	if (ret)
+		return ret;
+
+	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX576_NUM_DATA_LANES) {
+		ret = dev_err_probe(imx576->dev, -EINVAL,
+				    "only 4 data lanes are supported\n");
+		goto error_out;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(imx576->dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       link_freqs, ARRAY_SIZE(link_freqs),
+				       &imx576->link_freq_bitmap);
+	if (ret) {
+		ret = dev_err_probe(imx576->dev, -EINVAL,
+				    "only 1017MHz frequency is available\n");
+		goto error_out;
+	}
+
+	imx576->link_freq_index = __ffs(imx576->link_freq_bitmap);
+
+error_out:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+
+	return ret;
+}
+
+static int imx576_init_controls(struct imx576 *imx576)
+{
+	struct v4l2_fwnode_device_properties props;
+	u64 vblank_def, hblank_def;
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	u32 lpfr;
+	int ret;
+
+	ret = v4l2_fwnode_device_parse(imx576->dev, &props);
+	if (ret)
+		return ret;
+
+	ctrl_hdlr = &imx576->handler;
+	v4l2_ctrl_handler_init(ctrl_hdlr, 8);
+
+	vblank_def = IMX576_VBLANK_DEF - imx576_active_area.height;
+	lpfr = vblank_def + imx576_active_area.height;
+	imx576->exposure = v4l2_ctrl_new_std(ctrl_hdlr,
+					     &imx576_ctrl_ops,
+					     V4L2_CID_EXPOSURE,
+					     IMX576_EXPOSURE_MIN,
+					     lpfr - IMX576_EXPOSURE_OFFSET,
+					     IMX576_EXPOSURE_STEP,
+					     IMX576_EXPOSURE_DEFAULT);
+
+	imx576->gain = v4l2_ctrl_new_std(ctrl_hdlr, &imx576_ctrl_ops,
+					 V4L2_CID_ANALOGUE_GAIN,
+					 IMX576_ANA_GAIN_MIN,
+					 IMX576_ANA_GAIN_MAX,
+					 IMX576_ANA_GAIN_STEP,
+					 IMX576_ANA_GAIN_DEFAULT);
+
+	imx576->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx576_ctrl_ops,
+					   V4L2_CID_VBLANK, vblank_def,
+					   IMX576_VBLANK_MAX, 1,
+					   vblank_def);
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &imx576_ctrl_ops, V4L2_CID_PIXEL_RATE,
+			  IMX576_PIXEL_RATE, IMX576_PIXEL_RATE, 1, IMX576_PIXEL_RATE);
+
+	imx576->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx576_ctrl_ops,
+						   V4L2_CID_LINK_FREQ,
+						   ARRAY_SIZE(link_freqs) - 1,
+						   imx576->link_freq_index,
+						   link_freqs);
+
+	hblank_def =  IMX576_LINE_LENGTH - imx576_active_area.width;
+	imx576->hblank = v4l2_ctrl_new_std(ctrl_hdlr,
+					   &imx576_ctrl_ops,
+					   V4L2_CID_HBLANK,
+					   hblank_def,
+					   hblank_def,
+					   1, hblank_def);
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx576_ctrl_ops, &props);
+	if (ret)
+		goto err_handler_free;
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		goto err_handler_free;
+	}
+
+	imx576->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	imx576->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	imx576->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+
+err_handler_free:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static int imx576_probe(struct i2c_client *client)
+{
+	struct imx576 *imx576;
+	unsigned int inclk_freq;
+	int ret;
+
+	imx576 = devm_kzalloc(&client->dev, sizeof(*imx576), GFP_KERNEL);
+	if (!imx576)
+		return -ENOMEM;
+
+	imx576->dev = &client->dev;
+
+	/* Initialize subdev */
+	v4l2_i2c_subdev_init(&imx576->sd, client, &imx576_subdev_ops);
+	imx576->sd.internal_ops = &imx576_internal_ops;
+
+	imx576->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(imx576->regmap))
+		return dev_err_probe(imx576->dev, PTR_ERR(imx576->regmap),
+				     "failed to initialize CCI\n");
+
+	ret = imx576_parse_endpoint(imx576);
+	if (ret)
+		return dev_err_probe(imx576->dev, ret,
+				     "failed to parse endpoint configuration\n");
+
+	/* Get sensor input clock */
+	imx576->inclk = devm_v4l2_sensor_clk_get(imx576->dev, NULL);
+	if (IS_ERR(imx576->inclk))
+		return dev_err_probe(imx576->dev, PTR_ERR(imx576->inclk),
+				     "failed to get inclk\n");
+
+	inclk_freq = clk_get_rate(imx576->inclk);
+	if (inclk_freq != IMX576_INCLK_RATE)
+		return dev_err_probe(imx576->dev, -EINVAL,
+				     "inclk frequency not supported: %u Hz\n",
+				     inclk_freq);
+
+	for (unsigned int i = 0; i < ARRAY_SIZE(imx576_supply_names); i++)
+		imx576->supplies[i].supply = imx576_supply_names[i];
+
+	ret = devm_regulator_bulk_get(imx576->dev,
+				      ARRAY_SIZE(imx576_supply_names),
+				      imx576->supplies);
+	if (ret)
+		return dev_err_probe(imx576->dev, ret,
+				     "failed to get regulators\n");
+
+	imx576->reset_gpio = devm_gpiod_get_optional(imx576->dev, "reset",
+						     GPIOD_OUT_HIGH);
+	if (IS_ERR(imx576->reset_gpio))
+		return dev_err_probe(imx576->dev, PTR_ERR(imx576->reset_gpio),
+				     "failed to get reset GPIO\n");
+
+	ret = imx576_power_on(imx576->dev);
+	if (ret)
+		return ret;
+
+	ret = imx576_detect(imx576);
+	if (ret)
+		goto error_power_off;
+
+	ret = imx576_init_controls(imx576);
+	if (ret) {
+		dev_err_probe(imx576->dev, ret, "failed to init controls");
+		goto error_power_off;
+	}
+
+	/* Initialize subdev */
+	imx576->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	imx576->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	imx576->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_pads_init(&imx576->sd.entity, 1, &imx576->pad);
+	if (ret) {
+		dev_err_probe(imx576->dev, ret, "failed to init entity pads");
+		goto error_handler_free;
+	}
+
+	imx576->sd.state_lock = imx576->handler.lock;
+	ret = v4l2_subdev_init_finalize(&imx576->sd);
+	if (ret < 0) {
+		dev_err_probe(imx576->dev, ret, "subdev init error\n");
+		goto error_media_entity;
+	}
+
+	pm_runtime_set_active(imx576->dev);
+	pm_runtime_enable(imx576->dev);
+
+	ret = v4l2_async_register_subdev_sensor(&imx576->sd);
+	if (ret < 0) {
+		dev_err_probe(imx576->dev, ret,
+			      "failed to register imx576 sub-device\n");
+		goto error_subdev_cleanup;
+	}
+
+	pm_runtime_idle(imx576->dev);
+
+	return 0;
+
+error_subdev_cleanup:
+	v4l2_subdev_cleanup(&imx576->sd);
+	pm_runtime_disable(imx576->dev);
+	pm_runtime_set_suspended(imx576->dev);
+
+error_media_entity:
+	media_entity_cleanup(&imx576->sd.entity);
+
+error_handler_free:
+	v4l2_ctrl_handler_free(imx576->sd.ctrl_handler);
+
+error_power_off:
+	imx576_power_off(imx576->dev);
+
+	return ret;
+}
+
+static void imx576_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx576 *imx576 = to_imx576(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_subdev_cleanup(&imx576->sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_ctrl_handler_free(imx576->sd.ctrl_handler);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev)) {
+		imx576_power_off(&client->dev);
+		pm_runtime_set_suspended(&client->dev);
+	}
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx576_pm_ops,
+				 imx576_power_off, imx576_power_on, NULL);
+
+static const struct of_device_id imx576_of_match[] = {
+	{ .compatible = "sony,imx576" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx576_of_match);
+
+static struct i2c_driver imx576_driver = {
+	.driver = {
+		.name = "imx576",
+		.pm = &imx576_pm_ops,
+		.of_match_table = imx576_of_match,
+	},
+	.probe = imx576_probe,
+	.remove = imx576_remove,
+};
+module_i2c_driver(imx576_driver);
+
+MODULE_DESCRIPTION("IMX576 Camera Sensor Driver");
+MODULE_AUTHOR("Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>");
+MODULE_AUTHOR("Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>");
+MODULE_LICENSE("GPL");
--
2.34.1


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

* [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support
  2026-08-06 12:02 [PATCH v3 0/3] media: i2c: Add imx576 camera sensor driver Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 1/3] dt-bindings: media: i2c: Add imx576 sensor Himanshu Bhavani
  2026-08-06 12:02 ` [PATCH v3 2/3] media: i2c: add imx576 image sensor driver Himanshu Bhavani
@ 2026-08-06 12:02 ` Himanshu Bhavani
  2026-08-07  6:55   ` Jai Luthra
  2026-08-24  9:46   ` Konrad Dybcio
  2 siblings, 2 replies; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-06 12:02 UTC (permalink / raw)
  To: sakari.ailus
  Cc: Hardevsinh Palaniya, Himanshu Bhavani, Mauro Carvalho Chehab,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Hans Verkuil, Vladimir Zapolskiy, Hans de Goede,
	Tarang Raval, Elgin Perumbilly, Kate Hsuan, Xiaolei Wang,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	Mehdi Djait, Miguel Vadillo, linux-media, devicetree,
	linux-kernel, linux-arm-msm

From: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>

Add device tree support for the Sony IMX576 front camera
sensor and connect it to CAMSS via CSIPHY3.

Signed-off-by: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
---
 arch/arm64/boot/dts/qcom/sm6350.dtsi          |  7 +++
 .../boot/dts/qcom/sm7225-fairphone-fp4.dts    | 54 ++++++++++++++++++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
index 9ecd17e0b6a0..5db18f6c1be6 100644
--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -2926,6 +2926,13 @@ cci2_sleep: cci2-sleep-state {
 				bias-pull-down;
 			};
 
+			cam_mclk1_default: cam-mclk1-default-state {
+				pins = "gpio30";
+				function = "cam_mclk1";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
 			sdc2_off_state: sdc2-off-state {
 				clk-pins {
 					pins = "sdc2_clk";
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index 711a120753ad..452fc649ddb3 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -17,6 +17,8 @@
 #include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/media/video-interfaces.h>
+#include <dt-bindings/media/video-interface-devices.h>
 #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include <dt-bindings/sound/qcom,q6asm.h>
@@ -547,6 +549,29 @@ vreg_bob: bob {
 	};
 };
 
+&camss {
+	vdd-csiphy0-0p9-supply = <&vreg_l18a>;
+	vdd-csiphy0-1p25-supply = <&vreg_l22a>;
+	vdd-csiphy1-0p9-supply = <&vreg_l18a>;
+	vdd-csiphy1-1p25-supply = <&vreg_l22a>;
+	vdd-csiphy2-0p9-supply = <&vreg_l18a>;
+	vdd-csiphy2-1p25-supply = <&vreg_l22a>;
+	vdd-csiphy3-0p9-supply = <&vreg_l18a>;
+	vdd-csiphy3-1p25-supply = <&vreg_l22a>;
+
+	status = "okay";
+
+	ports {
+		port@3 {
+			csiphy3_ep: endpoint {
+				data-lanes = <0 1 2 3>;
+				bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+				remote-endpoint = <&camera_imx576_ep>;
+			};
+		};
+	};
+};
+
 &cci0 {
 	status = "okay";
 };
@@ -581,7 +606,34 @@ &cci1 {
 };
 
 &cci1_i2c0 {
-	/* Front cam (Sony IMX576) @ 0x10 */
+	camera@10 {
+		compatible = "sony,imx576";
+		reg = <0x10>;
+
+		vana-supply = <&vreg_l3p>;
+		vif-supply = <&vreg_l6p>;
+		vdig-supply = <&vreg_32m_cam_dvdd_1p05>;
+
+		clocks = <&camcc CAMCC_MCLK1_CLK>;
+		assigned-clocks = <&camcc CAMCC_MCLK1_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+		pinctrl-0 = <&cam_mclk1_default>;
+		pinctrl-names = "default";
+
+		orientation = <MEDIA_ORIENTATION_FRONT>;
+		rotation = <90>;
+
+		port {
+			camera_imx576_ep: endpoint {
+				data-lanes = <1 2 3 4>;
+				bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+				link-frequencies = /bits/ 64 <1017000000>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
 
 	eeprom@50 {
 		compatible = "giantec,gt24p64a", "atmel,24c64";
-- 
2.34.1


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

* Re: [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support
  2026-08-06 12:02 ` [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support Himanshu Bhavani
@ 2026-08-07  6:55   ` Jai Luthra
  2026-08-11  9:16     ` Himanshu Bhavani
  2026-08-24  9:46   ` Konrad Dybcio
  1 sibling, 1 reply; 12+ messages in thread
From: Jai Luthra @ 2026-08-07  6:55 UTC (permalink / raw)
  To: Himanshu Bhavani, sakari.ailus
  Cc: Hardevsinh Palaniya, Himanshu Bhavani, Mauro Carvalho Chehab,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Hans Verkuil, Vladimir Zapolskiy, Hans de Goede,
	Tarang Raval, Elgin Perumbilly, Kate Hsuan, Xiaolei Wang,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	Mehdi Djait, Miguel Vadillo, linux-media, devicetree,
	linux-kernel

Hi Himanshu,

Quoting Himanshu Bhavani (2026-08-06 17:32:09)
> From: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
> 
> Add device tree support for the Sony IMX576 front camera
> sensor and connect it to CAMSS via CSIPHY3.
> 
> Signed-off-by: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>

It's best to keep the DT series (which go through the arm tree) separate
from the one adding the driver and bindings (which go through media tree).

Moreover, I believe DT changes can't be merged until the bindings land in
mainline (or at least the linux-next tree)

Thanks,
    Jai

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

* Re: [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-06 12:02 ` [PATCH v3 2/3] media: i2c: add imx576 image sensor driver Himanshu Bhavani
@ 2026-08-07  7:00   ` Jai Luthra
  2026-08-11  9:14     ` Himanshu Bhavani
  0 siblings, 1 reply; 12+ messages in thread
From: Jai Luthra @ 2026-08-07  7:00 UTC (permalink / raw)
  To: Himanshu Bhavani, sakari.ailus
  Cc: Himanshu Bhavani, Hardevsinh Palaniya, Mauro Carvalho Chehab,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Hans Verkuil, Hans de Goede, Vladimir Zapolskiy,
	Mehdi Djait, Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	linux-media, devicetree, linux-kernel, linux-arm-msm

Hi Himanshu,

Thanks for the patch.

Not a full review, but just a few comments on the PLL programming.

Quoting Himanshu Bhavani (2026-08-06 17:32:08)
> Add a v4l2 subdevice driver for the Sony imx576 sensor.
> 
> The Sony IMX576 image sensor with an active
> array size of 5760 x 4312
> 
> The following features are supported:
> - Manual exposure an gain control support
> - vblank/hblank control support
> - Supported resolution: 5760 x 4312 30fps (SRGGB10)
> 
> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>

[...]

> +#define IMX576_INCLK_RATE              (24 * HZ_PER_MHZ)
> +
> +#define IMX576_REG_CHIP_ID             CCI_REG16(0x0016)
> +#define IMX576_CHIP_ID                 0x0576
> +
> +#define IMX576_REG_MODE_SELECT         CCI_REG8(0x0100)
> +#define IMX576_MODE_STANDBY            0x00
> +#define IMX576_MODE_STREAMING          0x01
> +
> +#define IMX576_REG_HOLD                        CCI_REG8(0x0104)
> +
> +#define IMX576_REG_EXPOSURE            CCI_REG16(0x0202)
> +#define IMX576_EXPOSURE_MIN            8
> +#define IMX576_EXPOSURE_OFFSET         22
> +#define IMX576_EXPOSURE_STEP           1
> +#define IMX576_EXPOSURE_DEFAULT                0x0648
> +
> +#define IMX576_REG_ANALOG_GAIN         CCI_REG16(0x0204)
> +#define IMX576_ANA_GAIN_MIN            0
> +#define IMX576_ANA_GAIN_MAX            978
> +#define IMX576_ANA_GAIN_STEP           1
> +#define IMX576_ANA_GAIN_DEFAULT                0
> +
> +#define IMX576_REG_IVT_PXCK_DIV                CCI_REG8(0x0301)
> +#define IMX576_REG_IVT_SYCK_DIV                CCI_REG8(0x0303)
> +#define IMX576_REG_IVT_PREPLLCK_DIV    CCI_REG8(0x0305)
> +#define IMX576_REG_IVT_PLL_MPY         CCI_REG16(0x0306)
> +#define IMX576_REG_IOP_SYCK_DIV                CCI_REG8(0x030b)
> +#define IMX576_REG_IOP_PREPLLCK_DIV    CCI_REG8(0x030d)
> +#define IMX576_REG_IOP_PLL_MPY         CCI_REG16(0x030e)
> +#define IMX576_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
> +
> +#define IMX576_REG_FRM_LENGTH_LINES    CCI_REG16(0x0340)
> +#define IMX576_REG_LINE_LENGTH_PCK     CCI_REG16(0x0342)
> +#define IMX576_LINE_LENGTH             6144
> +#define IMX576_VBLANK_DEF              4387
> +
> +/* FIXME: Exact VBLANK limit unknown (no datasheet). */
> +#define IMX576_VBLANK_MAX              32420
> +
> +#define IMX576_REG_X_ADD_STA           CCI_REG16(0x0344)
> +#define IMX576_REG_Y_ADD_STA           CCI_REG16(0x0346)
> +#define IMX576_REG_X_ADD_END           CCI_REG16(0x0348)
> +#define IMX576_REG_Y_ADD_END           CCI_REG16(0x034a)
> +#define IMX576_REG_X_OUTPUT_SIZE       CCI_REG16(0x034c)
> +#define IMX576_REG_Y_OUTPUT_SIZE       CCI_REG16(0x034e)
> +
> +#define IMX576_REG_DIG_CROP_X_OFFSET   CCI_REG16(0x0408)
> +#define IMX576_REG_DIG_CROP_Y_OFFSET   CCI_REG16(0x040a)
> +#define IMX576_REG_DIG_CROP_WIDTH      CCI_REG16(0x040c)
> +#define IMX576_REG_DIG_CROP_HEIGHT     CCI_REG16(0x040e)

This sensor's registers seem quite similar to the MIPI CCS specification.

Please check if the sensor is CCS compatible. Even if it is not, I think
the PLL programming is compatible, so you can use the helpers from
ccs-pll.c.

> +
> +#define IMX576_REG_BINNING_MODE                CCI_REG8(0x0900)
> +#define IMX576_REG_BINNING_TYPE                CCI_REG8(0x0901)
> +#define IMX576_REG_BINNING_WEIGHT      CCI_REG8(0x0902)
> +
> +#define IMX576_PIXEL_RATE              813600000
> +#define IMX576_NUM_DATA_LANES          4
> +
> +/* IMX576 native and active pixel array size */
> +static const struct v4l2_rect imx576_native_area = {
> +       .top = 0,
> +       .left = 0,
> +       .width = 5792,
> +       .height = 4464,
> +};
> +
> +static const struct v4l2_rect imx576_active_area = {
> +       .top = 136,
> +       .left = 16,
> +       .width = 5760,
> +       .height = 4312,
> +};
> +
> +static const char * const imx576_supply_names[] = {
> +       "vana",         /* Analog Power */
> +       "vif",          /* Interface Power */
> +       "vdig",         /* Digital Power */
> +};
> +
> +static const struct cci_reg_sequence imx576_common_regs[] = {

[...]

> +       { IMX576_REG_IVT_PXCK_DIV, 0x05 },
> +       { IMX576_REG_IVT_SYCK_DIV, 0x02 },
> +       { IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
> +       { IMX576_REG_IVT_PLL_MPY, 0x0154 },
> +       { IMX576_REG_IOP_SYCK_DIV, 0x01 },
> +       { IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
> +       { IMX576_REG_PLL_MULT_DRIV, 0x01 },

I think when Laurent asked to make the PLL configurable for different link
frequencies, he meant deriving these and the OP_PLL_MPY value instead of
hardcoding all of them and only supporting one link freq.

> +       { CCI_REG8(0x0b06), 0x01 },
> +       { CCI_REG8(0x3620), 0x01 },
> +       { CCI_REG8(0x3f0c), 0x00 },
> +};
> +

Thanks,
    Jai

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

* Re: [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-07  7:00   ` Jai Luthra
@ 2026-08-11  9:14     ` Himanshu Bhavani
  2026-08-12  6:16       ` Jai Luthra
  0 siblings, 1 reply; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-11  9:14 UTC (permalink / raw)
  To: Jai Luthra, sakari.ailus@linux.intel.com
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Hans de Goede, Vladimir Zapolskiy, Mehdi Djait,
	Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org

Hi Jai,

>Hi Himanshu,
>
>Thanks for the patch.
>
>Not a full review, but just a few comments on the PLL programming.
>
>Quoting Himanshu Bhavani (2026-08-06 17:32:08)
>> Add a v4l2 subdevice driver for the Sony imx576 sensor.
>>
>> The Sony IMX576 image sensor with an active
>> array size of 5760 x 4312
>>
>> The following features are supported:
>> - Manual exposure an gain control support
>> - vblank/hblank control support
>> - Supported resolution: 5760 x 4312 30fps (SRGGB10)
>>
>> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
>
>[...]
>
>> +#define IMX576_INCLK_RATE              (24 * HZ_PER_MHZ)
>> +
>> +#define IMX576_REG_CHIP_ID             CCI_REG16(0x0016)
>> +#define IMX576_CHIP_ID                 0x0576
>> +
>> +#define IMX576_REG_MODE_SELECT         CCI_REG8(0x0100)
>> +#define IMX576_MODE_STANDBY            0x00
>> +#define IMX576_MODE_STREAMING          0x01
>> +
>> +#define IMX576_REG_HOLD                        CCI_REG8(0x0104)
>> +
>> +#define IMX576_REG_EXPOSURE            CCI_REG16(0x0202)
>> +#define IMX576_EXPOSURE_MIN            8
>> +#define IMX576_EXPOSURE_OFFSET         22
>> +#define IMX576_EXPOSURE_STEP           1
>> +#define IMX576_EXPOSURE_DEFAULT                0x0648
>> +
>> +#define IMX576_REG_ANALOG_GAIN         CCI_REG16(0x0204)
>> +#define IMX576_ANA_GAIN_MIN            0
>> +#define IMX576_ANA_GAIN_MAX            978
>> +#define IMX576_ANA_GAIN_STEP           1
>> +#define IMX576_ANA_GAIN_DEFAULT                0
>> +
>> +#define IMX576_REG_IVT_PXCK_DIV                CCI_REG8(0x0301)
>> +#define IMX576_REG_IVT_SYCK_DIV                CCI_REG8(0x0303)
>> +#define IMX576_REG_IVT_PREPLLCK_DIV    CCI_REG8(0x0305)
>> +#define IMX576_REG_IVT_PLL_MPY         CCI_REG16(0x0306)
>> +#define IMX576_REG_IOP_SYCK_DIV                CCI_REG8(0x030b)
>> +#define IMX576_REG_IOP_PREPLLCK_DIV    CCI_REG8(0x030d)
>> +#define IMX576_REG_IOP_PLL_MPY         CCI_REG16(0x030e)
>> +#define IMX576_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
>> +
>> +#define IMX576_REG_FRM_LENGTH_LINES    CCI_REG16(0x0340)
>> +#define IMX576_REG_LINE_LENGTH_PCK     CCI_REG16(0x0342)
>> +#define IMX576_LINE_LENGTH             6144
>> +#define IMX576_VBLANK_DEF              4387
>> +
>> +/* FIXME: Exact VBLANK limit unknown (no datasheet). */
>> +#define IMX576_VBLANK_MAX              32420
>> +
>> +#define IMX576_REG_X_ADD_STA           CCI_REG16(0x0344)
>> +#define IMX576_REG_Y_ADD_STA           CCI_REG16(0x0346)
>> +#define IMX576_REG_X_ADD_END           CCI_REG16(0x0348)
>> +#define IMX576_REG_Y_ADD_END           CCI_REG16(0x034a)
>> +#define IMX576_REG_X_OUTPUT_SIZE       CCI_REG16(0x034c)
>> +#define IMX576_REG_Y_OUTPUT_SIZE       CCI_REG16(0x034e)
>> +
>> +#define IMX576_REG_DIG_CROP_X_OFFSET   CCI_REG16(0x0408)
>> +#define IMX576_REG_DIG_CROP_Y_OFFSET   CCI_REG16(0x040a)
>> +#define IMX576_REG_DIG_CROP_WIDTH      CCI_REG16(0x040c)
>> +#define IMX576_REG_DIG_CROP_HEIGHT     CCI_REG16(0x040e)
>
>This sensor's registers seem quite similar to the MIPI CCS specification.

Yes, you are right some registers seems to be similar I will address it.


>Please check if the sensor is CCS compatible. Even if it is not, I think
>the PLL programming is compatible, so you can use the helpers from
>ccs-pll.c.

Most PLL values are derived from the limited IMX576 datasheet information available.

For the unknown values, I referred to out of tree driver and validated and assumed them based on the PLL configuration.

Should I proceed with the PLL programming as it is, or drop the PLL approach and retain only the CCS-supported registers?

static const struct ccs_pll_limits imx576_pll_limits = {
	.min_ext_clk_freq_hz = 6000000,
	.max_ext_clk_freq_hz = 27000000,

	.vt_fr = {
		/* Confirmed values as per datasheet */

		.min_pre_pll_clk_div = 1,
		.max_pre_pll_clk_div = 4,
		.min_pll_ip_clk_freq_hz = 6000000,
		.max_pll_ip_clk_freq_hz = 12000000,
		.min_pll_multiplier = 87,
		.max_pll_multiplier = 350,
		.min_pll_op_clk_freq_hz = 1050000000,
		.max_pll_op_clk_freq_hz = 2100000000,
	},

	.vt_bk = {
		/* here the sys_clk_div (IVT_SYCK_DIV -> 0303) value as per out of tree driver they are using div as 2 or 4  */

		.min_sys_clk_div = 2,
		.max_sys_clk_div = 4,
		.min_sys_clk_freq_hz = 262500000,
		.max_sys_clk_freq_hz = 1050000000,

		/* pix_clk_div also being used as an Fixed to 5 */
		.min_pix_clk_div = 5,
		.max_pix_clk_div = 5,
		.min_pix_clk_freq_hz = 52500000,
		.max_pix_clk_freq_hz = 210000000,
	},
	.op_fr = {

		/* Confirmed values as per datasheet */

		.min_pre_pll_clk_div = 1,
		.max_pre_pll_clk_div = 15,
		.min_pll_ip_clk_freq_hz = 6000000,
		.max_pll_ip_clk_freq_hz = 12000000,
		.min_pll_multiplier = 47,
		.max_pll_multiplier = 2300,
		.min_pll_op_clk_freq_hz = 1250000000,
		.max_pll_op_clk_freq_hz = 2300000000,
	},
	.op_bk = {

		 /* Similarly here also (OP_SYS_CLK_DIV -> 030b) value being used is 1,2,4 in out of tree driver
		  * But as per ccs-limits { CCS_R_MAX_OP_SYS_CLK_DIV = 2 }
		  */

		.min_sys_clk_div = 1,
		.max_sys_clk_div = 2,
		.min_sys_clk_freq_hz = 625000000,
		.max_sys_clk_freq_hz = 2300000000,

		/* (RAW8 and RAW10) */
		.min_pix_clk_div = 8,
		.max_pix_clk_div = 10,
		.min_pix_clk_freq_hz = 62500000,
		.max_pix_clk_freq_hz = 2300000000,
	},

>> +
>> +#define IMX576_REG_BINNING_MODE                CCI_REG8(0x0900)
>> +#define IMX576_REG_BINNING_TYPE                CCI_REG8(0x0901)
>> +#define IMX576_REG_BINNING_WEIGHT      CCI_REG8(0x0902)
>> +
>> +#define IMX576_PIXEL_RATE              813600000
>> +#define IMX576_NUM_DATA_LANES          4
>> +
>> +/* IMX576 native and active pixel array size */
>> +static const struct v4l2_rect imx576_native_area = {
>> +       .top = 0,
>> +       .left = 0,
>> +       .width = 5792,
>> +       .height = 4464,
>> +};
>> +
>> +static const struct v4l2_rect imx576_active_area = {
>> +       .top = 136,
>> +       .left = 16,
>> +       .width = 5760,
>> +       .height = 4312,
>> +};
>> +
>> +static const char * const imx576_supply_names[] = {
>> +       "vana",         /* Analog Power */
>> +       "vif",          /* Interface Power */
>> +       "vdig",         /* Digital Power */
>> +};
>> +
>> +static const struct cci_reg_sequence imx576_common_regs[] = {
>
>[...]
>
>> +       { IMX576_REG_IVT_PXCK_DIV, 0x05 },
>> +       { IMX576_REG_IVT_SYCK_DIV, 0x02 },
>> +       { IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
>> +       { IMX576_REG_IVT_PLL_MPY, 0x0154 },
>> +       { IMX576_REG_IOP_SYCK_DIV, 0x01 },
>> +       { IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
>> +       { IMX576_REG_PLL_MULT_DRIV, 0x01 },
>
>I think when Laurent asked to make the PLL configurable for different link
>frequencies, he meant deriving these and the OP_PLL_MPY value instead of
>hardcoding all of them and only supporting one link freq.
>> +       { CCI_REG8(0x0b06), 0x01 },
>> +       { CCI_REG8(0x3620), 0x01 },
>> +       { CCI_REG8(0x3f0c), 0x00 },
>> +};
>> +
>
>Thanks,
>    Jai


Best Regards,
Himanshu

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

* Re: [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support
  2026-08-07  6:55   ` Jai Luthra
@ 2026-08-11  9:16     ` Himanshu Bhavani
  0 siblings, 0 replies; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-11  9:16 UTC (permalink / raw)
  To: Jai Luthra, sakari.ailus@linux.intel.com
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Vladimir Zapolskiy, Hans de Goede, Tarang Raval,
	Elgin Perumbilly, Kate Hsuan, Xiaolei Wang,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	Mehdi Djait, Miguel Vadillo, linux-media@vger.kernel.org,
	devicetree@vger.kernel.org, LKML, linux-arm-msm@vger.kernel.org

Hi Jai,

>Hi Himanshu,
>
>Quoting Himanshu Bhavani (2026-08-06 17:32:09)
>> From: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
>>
>> Add device tree support for the Sony IMX576 front camera
>> sensor and connect it to CAMSS via CSIPHY3.
>>
>> Signed-off-by: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
>> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
>
>It's best to keep the DT series (which go through the arm tree) separate
>from the one adding the driver and bindings (which go through media tree).
>
>Moreover, I believe DT changes can't be merged until the bindings land in
>mainline (or at least the linux-next tree)
>
>Thanks,
>    Jai

Thanks, understood. We’ll submit the DT changes separately after the bindings
land in mainline.

Best Regards,
Himanshu

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

* Re: [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-11  9:14     ` Himanshu Bhavani
@ 2026-08-12  6:16       ` Jai Luthra
  2026-08-14 11:35         ` Himanshu Bhavani
  0 siblings, 1 reply; 12+ messages in thread
From: Jai Luthra @ 2026-08-12  6:16 UTC (permalink / raw)
  To: sakari.ailus@linux.intel.com, Himanshu Bhavani
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Hans de Goede, Vladimir Zapolskiy, Mehdi Djait,
	Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	"linux-arm-msm@vger.kernel.org" <linux-ar 

Hi Himanshu,

Quoting Himanshu Bhavani (2026-08-11 14:44:12)
> Hi Jai,
> 
> >Hi Himanshu,
> >
> >Thanks for the patch.
> >
> >Not a full review, but just a few comments on the PLL programming.
> >
> >Quoting Himanshu Bhavani (2026-08-06 17:32:08)
> >> Add a v4l2 subdevice driver for the Sony imx576 sensor.
> >>
> >> The Sony IMX576 image sensor with an active
> >> array size of 5760 x 4312
> >>
> >> The following features are supported:
> >> - Manual exposure an gain control support
> >> - vblank/hblank control support
> >> - Supported resolution: 5760 x 4312 30fps (SRGGB10)
> >>
> >> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
> >
> >[...]
> >
> >> +#define IMX576_INCLK_RATE              (24 * HZ_PER_MHZ)
> >> +
> >> +#define IMX576_REG_CHIP_ID             CCI_REG16(0x0016)
> >> +#define IMX576_CHIP_ID                 0x0576
> >> +
> >> +#define IMX576_REG_MODE_SELECT         CCI_REG8(0x0100)
> >> +#define IMX576_MODE_STANDBY            0x00
> >> +#define IMX576_MODE_STREAMING          0x01
> >> +
> >> +#define IMX576_REG_HOLD                        CCI_REG8(0x0104)
> >> +
> >> +#define IMX576_REG_EXPOSURE            CCI_REG16(0x0202)
> >> +#define IMX576_EXPOSURE_MIN            8
> >> +#define IMX576_EXPOSURE_OFFSET         22
> >> +#define IMX576_EXPOSURE_STEP           1
> >> +#define IMX576_EXPOSURE_DEFAULT                0x0648
> >> +
> >> +#define IMX576_REG_ANALOG_GAIN         CCI_REG16(0x0204)
> >> +#define IMX576_ANA_GAIN_MIN            0
> >> +#define IMX576_ANA_GAIN_MAX            978
> >> +#define IMX576_ANA_GAIN_STEP           1
> >> +#define IMX576_ANA_GAIN_DEFAULT                0
> >> +
> >> +#define IMX576_REG_IVT_PXCK_DIV                CCI_REG8(0x0301)
> >> +#define IMX576_REG_IVT_SYCK_DIV                CCI_REG8(0x0303)
> >> +#define IMX576_REG_IVT_PREPLLCK_DIV    CCI_REG8(0x0305)
> >> +#define IMX576_REG_IVT_PLL_MPY         CCI_REG16(0x0306)
> >> +#define IMX576_REG_IOP_SYCK_DIV                CCI_REG8(0x030b)
> >> +#define IMX576_REG_IOP_PREPLLCK_DIV    CCI_REG8(0x030d)
> >> +#define IMX576_REG_IOP_PLL_MPY         CCI_REG16(0x030e)
> >> +#define IMX576_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
> >> +
> >> +#define IMX576_REG_FRM_LENGTH_LINES    CCI_REG16(0x0340)
> >> +#define IMX576_REG_LINE_LENGTH_PCK     CCI_REG16(0x0342)
> >> +#define IMX576_LINE_LENGTH             6144
> >> +#define IMX576_VBLANK_DEF              4387
> >> +
> >> +/* FIXME: Exact VBLANK limit unknown (no datasheet). */
> >> +#define IMX576_VBLANK_MAX              32420
> >> +
> >> +#define IMX576_REG_X_ADD_STA           CCI_REG16(0x0344)
> >> +#define IMX576_REG_Y_ADD_STA           CCI_REG16(0x0346)
> >> +#define IMX576_REG_X_ADD_END           CCI_REG16(0x0348)
> >> +#define IMX576_REG_Y_ADD_END           CCI_REG16(0x034a)
> >> +#define IMX576_REG_X_OUTPUT_SIZE       CCI_REG16(0x034c)
> >> +#define IMX576_REG_Y_OUTPUT_SIZE       CCI_REG16(0x034e)
> >> +
> >> +#define IMX576_REG_DIG_CROP_X_OFFSET   CCI_REG16(0x0408)
> >> +#define IMX576_REG_DIG_CROP_Y_OFFSET   CCI_REG16(0x040a)
> >> +#define IMX576_REG_DIG_CROP_WIDTH      CCI_REG16(0x040c)
> >> +#define IMX576_REG_DIG_CROP_HEIGHT     CCI_REG16(0x040e)
> >
> >This sensor's registers seem quite similar to the MIPI CCS specification.
> 
> Yes, you are right some registers seems to be similar I will address it.
> 

That's good to know. Did you check if the sensor itself advertises itself
as compliant to a particular version of the CCS standard? You can read the
below register:

#define CCS_R_MIPI_CCS_VERSION					CCI_REG8(0x0007)

In general it might help to take a dump of all the CCS registers to see if
the ranges given in datasheet match what the sensor's registers say.

> 
> >Please check if the sensor is CCS compatible. Even if it is not, I think
> >the PLL programming is compatible, so you can use the helpers from
> >ccs-pll.c.
> 
> Most PLL values are derived from the limited IMX576 datasheet information
> available.
> 
> For the unknown values, I referred to out of tree driver and validated
> and assumed them based on the PLL configuration.
> 
> Should I proceed with the PLL programming as it is, or drop the PLL
> approach and retain only the CCS-supported registers?
> 

I'm not sure I fully understand your question.

If you can support more than 1 link frequency using the ccs_pll_calculate()
helper, then my suggestion would be to do that, even if it's just 2
well-tested frequencies today.

That leaves the driver in much better shape for future (for use with a
different input clock or frequency). At least that's what I have done for
my IMX708 series, which was similar to this sensor.

Thanks,
    Jai

> static const struct ccs_pll_limits imx576_pll_limits = {
>         .min_ext_clk_freq_hz = 6000000,
>         .max_ext_clk_freq_hz = 27000000,
> 
>         .vt_fr = {
>                 /* Confirmed values as per datasheet */
> 
>                 .min_pre_pll_clk_div = 1,
>                 .max_pre_pll_clk_div = 4,
>                 .min_pll_ip_clk_freq_hz = 6000000,
>                 .max_pll_ip_clk_freq_hz = 12000000,
>                 .min_pll_multiplier = 87,
>                 .max_pll_multiplier = 350,
>                 .min_pll_op_clk_freq_hz = 1050000000,
>                 .max_pll_op_clk_freq_hz = 2100000000,
>         },
> 
>         .vt_bk = {
>                 /* here the sys_clk_div (IVT_SYCK_DIV -> 0303) value as per out of tree driver they are using div as 2 or 4  */
> 
>                 .min_sys_clk_div = 2,
>                 .max_sys_clk_div = 4,
>                 .min_sys_clk_freq_hz = 262500000,
>                 .max_sys_clk_freq_hz = 1050000000,
> 
>                 /* pix_clk_div also being used as an Fixed to 5 */
>                 .min_pix_clk_div = 5,
>                 .max_pix_clk_div = 5,
>                 .min_pix_clk_freq_hz = 52500000,
>                 .max_pix_clk_freq_hz = 210000000,
>         },
>         .op_fr = {
> 
>                 /* Confirmed values as per datasheet */
> 
>                 .min_pre_pll_clk_div = 1,
>                 .max_pre_pll_clk_div = 15,
>                 .min_pll_ip_clk_freq_hz = 6000000,
>                 .max_pll_ip_clk_freq_hz = 12000000,
>                 .min_pll_multiplier = 47,
>                 .max_pll_multiplier = 2300,
>                 .min_pll_op_clk_freq_hz = 1250000000,
>                 .max_pll_op_clk_freq_hz = 2300000000,
>         },
>         .op_bk = {
> 
>                  /* Similarly here also (OP_SYS_CLK_DIV -> 030b) value being used is 1,2,4 in out of tree driver
>                   * But as per ccs-limits { CCS_R_MAX_OP_SYS_CLK_DIV = 2 }
>                   */
> 
>                 .min_sys_clk_div = 1,
>                 .max_sys_clk_div = 2,
>                 .min_sys_clk_freq_hz = 625000000,
>                 .max_sys_clk_freq_hz = 2300000000,
> 
>                 /* (RAW8 and RAW10) */
>                 .min_pix_clk_div = 8,
>                 .max_pix_clk_div = 10,
>                 .min_pix_clk_freq_hz = 62500000,
>                 .max_pix_clk_freq_hz = 2300000000,
>         },
> 
> >> +
> >> +#define IMX576_REG_BINNING_MODE                CCI_REG8(0x0900)
> >> +#define IMX576_REG_BINNING_TYPE                CCI_REG8(0x0901)
> >> +#define IMX576_REG_BINNING_WEIGHT      CCI_REG8(0x0902)
> >> +
> >> +#define IMX576_PIXEL_RATE              813600000
> >> +#define IMX576_NUM_DATA_LANES          4
> >> +
> >> +/* IMX576 native and active pixel array size */
> >> +static const struct v4l2_rect imx576_native_area = {
> >> +       .top = 0,
> >> +       .left = 0,
> >> +       .width = 5792,
> >> +       .height = 4464,
> >> +};
> >> +
> >> +static const struct v4l2_rect imx576_active_area = {
> >> +       .top = 136,
> >> +       .left = 16,
> >> +       .width = 5760,
> >> +       .height = 4312,
> >> +};
> >> +
> >> +static const char * const imx576_supply_names[] = {
> >> +       "vana",         /* Analog Power */
> >> +       "vif",          /* Interface Power */
> >> +       "vdig",         /* Digital Power */
> >> +};
> >> +
> >> +static const struct cci_reg_sequence imx576_common_regs[] = {
> >
> >[...]
> >
> >> +       { IMX576_REG_IVT_PXCK_DIV, 0x05 },
> >> +       { IMX576_REG_IVT_SYCK_DIV, 0x02 },
> >> +       { IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
> >> +       { IMX576_REG_IVT_PLL_MPY, 0x0154 },
> >> +       { IMX576_REG_IOP_SYCK_DIV, 0x01 },
> >> +       { IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
> >> +       { IMX576_REG_PLL_MULT_DRIV, 0x01 },
> >
> >I think when Laurent asked to make the PLL configurable for different link
> >frequencies, he meant deriving these and the OP_PLL_MPY value instead of
> >hardcoding all of them and only supporting one link freq.
> >> +       { CCI_REG8(0x0b06), 0x01 },
> >> +       { CCI_REG8(0x3620), 0x01 },
> >> +       { CCI_REG8(0x3f0c), 0x00 },
> >> +};
> >> +
> >
> >Thanks,
> >    Jai
> 
> 
> Best Regards,
> Himanshu

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

* Re: [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-12  6:16       ` Jai Luthra
@ 2026-08-14 11:35         ` Himanshu Bhavani
  2026-08-14 12:52           ` Jai Luthra
  0 siblings, 1 reply; 12+ messages in thread
From: Himanshu Bhavani @ 2026-08-14 11:35 UTC (permalink / raw)
  To: Jai Luthra, sakari.ailus@linux.intel.com
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Hans de Goede, Vladimir Zapolskiy, Mehdi Djait,
	Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org

Hi Jai,

>Hi Himanshu,
>
> Quoting Himanshu Bhavani (2026-08-11 14:44:12)
> > Hi Jai,
> >
> > >Hi Himanshu,
> > >
> > >Thanks for the patch.
> > >
> > >Not a full review, but just a few comments on the PLL programming.
> > >
> > >Quoting Himanshu Bhavani (2026-08-06 17:32:08)
> > >> Add a v4l2 subdevice driver for the Sony imx576 sensor.
> > >>
> > >> The Sony IMX576 image sensor with an active
> > >> array size of 5760 x 4312
> > >>
> > >> The following features are supported:
> > >> - Manual exposure an gain control support
> > >> - vblank/hblank control support
> > >> - Supported resolution: 5760 x 4312 30fps (SRGGB10)
> > >>
> > >> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
> > >
> > >[...]
> > >
> > >> +#define IMX576_INCLK_RATE              (24 * HZ_PER_MHZ)
> > >> +
> > >> +#define IMX576_REG_CHIP_ID             CCI_REG16(0x0016)
> > >> +#define IMX576_CHIP_ID                 0x0576
> > >> +
> > >> +#define IMX576_REG_MODE_SELECT         CCI_REG8(0x0100)
> > >> +#define IMX576_MODE_STANDBY            0x00
> > >> +#define IMX576_MODE_STREAMING          0x01
> > >> +
> > >> +#define IMX576_REG_HOLD                        CCI_REG8(0x0104)
> > >> +
> > >> +#define IMX576_REG_EXPOSURE            CCI_REG16(0x0202)
> > >> +#define IMX576_EXPOSURE_MIN            8
> > >> +#define IMX576_EXPOSURE_OFFSET         22
> > >> +#define IMX576_EXPOSURE_STEP           1
> > >> +#define IMX576_EXPOSURE_DEFAULT                0x0648
> > >> +
> > >> +#define IMX576_REG_ANALOG_GAIN         CCI_REG16(0x0204)
> > >> +#define IMX576_ANA_GAIN_MIN            0
> > >> +#define IMX576_ANA_GAIN_MAX            978
> > >> +#define IMX576_ANA_GAIN_STEP           1
> > >> +#define IMX576_ANA_GAIN_DEFAULT                0
> > >> +
> > >> +#define IMX576_REG_IVT_PXCK_DIV                CCI_REG8(0x0301)
> > >> +#define IMX576_REG_IVT_SYCK_DIV                CCI_REG8(0x0303)
> > >> +#define IMX576_REG_IVT_PREPLLCK_DIV    CCI_REG8(0x0305)
> > >> +#define IMX576_REG_IVT_PLL_MPY         CCI_REG16(0x0306)
> > >> +#define IMX576_REG_IOP_SYCK_DIV                CCI_REG8(0x030b)
> > >> +#define IMX576_REG_IOP_PREPLLCK_DIV    CCI_REG8(0x030d)
> > >> +#define IMX576_REG_IOP_PLL_MPY         CCI_REG16(0x030e)
> > >> +#define IMX576_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
> > >> +
> > >> +#define IMX576_REG_FRM_LENGTH_LINES    CCI_REG16(0x0340)
> > >> +#define IMX576_REG_LINE_LENGTH_PCK     CCI_REG16(0x0342)
> > >> +#define IMX576_LINE_LENGTH             6144
> > >> +#define IMX576_VBLANK_DEF              4387
> > >> +
> > >> +/* FIXME: Exact VBLANK limit unknown (no datasheet). */
> > >> +#define IMX576_VBLANK_MAX              32420
> > >> +
> > >> +#define IMX576_REG_X_ADD_STA           CCI_REG16(0x0344)
> > >> +#define IMX576_REG_Y_ADD_STA           CCI_REG16(0x0346)
> > >> +#define IMX576_REG_X_ADD_END           CCI_REG16(0x0348)
> > >> +#define IMX576_REG_Y_ADD_END           CCI_REG16(0x034a)
> > >> +#define IMX576_REG_X_OUTPUT_SIZE       CCI_REG16(0x034c)
> > >> +#define IMX576_REG_Y_OUTPUT_SIZE       CCI_REG16(0x034e)
> > >> +
> > >> +#define IMX576_REG_DIG_CROP_X_OFFSET   CCI_REG16(0x0408)
> > >> +#define IMX576_REG_DIG_CROP_Y_OFFSET   CCI_REG16(0x040a)
> > >> +#define IMX576_REG_DIG_CROP_WIDTH      CCI_REG16(0x040c)
> > >> +#define IMX576_REG_DIG_CROP_HEIGHT     CCI_REG16(0x040e)
> > >
> > >This sensor's registers seem quite similar to the MIPI CCS specification.
> >
> > Yes, you are right some registers seems to be similar I will address it.
> >
>
> That's good to know. Did you check if the sensor itself advertises itself
> as compliant to a particular version of the CCS standard? You can read the
> below register:
>
> #define CCS_R_MIPI_CCS_VERSION					CCI_REG8(0x0007)
>
> In general it might help to take a dump of all the CCS registers to see if
> the ranges given in datasheet match what the sensor's registers say.
>

I tried reading CCS_R_MIPI_CCS_VERSION (CCI_REG8(0x0007)), but it returned 0x00.
it is expected to return either CCS_MIPI_CCS_VERSION_V1_0 or CCS_MIPI_CCS_VERSION_V1_1 ?

I have shared you the minimal datasheet in personal,

Could you please clarify how you verified the IMX708 ? Is 0x0007 documented as the MIPI CCS Version register?


Because I tried applyig the imx576_pll_limits{..} PLL calculation and updating the corresponding registers, streaming works fine to me.
readback those pll related registers confirms they are set as expected by the ccs-pll.c calculation.

> >
> > >Please check if the sensor is CCS compatible. Even if it is not, I think
> > >the PLL programming is compatible, so you can use the helpers from
> > >ccs-pll.c.
> >
> > Most PLL values are derived from the limited IMX576 datasheet information
> > available.
> >
> > For the unknown values, I referred to out of tree driver and validated
> > and assumed them based on the PLL configuration.
> >
> > Should I proceed with the PLL programming as it is, or drop the PLL
> > approach and retain only the CCS-supported registers?
> >
>
> I'm not sure I fully understand your question.
>
> If you can support more than 1 link frequency using the ccs_pll_calculate()
> helper, then my suggestion would be to do that, even if it's just 2
> well-tested frequencies today.
>
> That leaves the driver in much better shape for future (for use with a
> different input clock or frequency). At least that's what I have done for
> my IMX708 series, which was similar to this sensor.
>
> Thanks,
>     Jai
>
> > static const struct ccs_pll_limits imx576_pll_limits = {
> >         .min_ext_clk_freq_hz = 6000000,
> >         .max_ext_clk_freq_hz = 27000000,
> >
> >         .vt_fr = {
> >                 /* Confirmed values as per datasheet */
> >
> >                 .min_pre_pll_clk_div = 1,
> >                 .max_pre_pll_clk_div = 4,
> >                 .min_pll_ip_clk_freq_hz = 6000000,
> >                 .max_pll_ip_clk_freq_hz = 12000000,
> >                 .min_pll_multiplier = 87,
> >                 .max_pll_multiplier = 350,
> >                 .min_pll_op_clk_freq_hz = 1050000000,
> >                 .max_pll_op_clk_freq_hz = 2100000000,
> >         },
> >
> >         .vt_bk = {
> >                 /* here the sys_clk_div (IVT_SYCK_DIV -> 0303) value as per out of tree driver they are using div as 2 or 4  */
> >
> >                 .min_sys_clk_div = 2,
> >                 .max_sys_clk_div = 4,
> >                 .min_sys_clk_freq_hz = 262500000,
> >                 .max_sys_clk_freq_hz = 1050000000,
> >
> >                 /* pix_clk_div also being used as an Fixed to 5 */
> >                 .min_pix_clk_div = 5,
> >                 .max_pix_clk_div = 5,
> >                 .min_pix_clk_freq_hz = 52500000,
> >                 .max_pix_clk_freq_hz = 210000000,
> >         },
> >         .op_fr = {
> >
> >                 /* Confirmed values as per datasheet */
> >
> >                 .min_pre_pll_clk_div = 1,
> >                 .max_pre_pll_clk_div = 15,
> >                 .min_pll_ip_clk_freq_hz = 6000000,
> >                 .max_pll_ip_clk_freq_hz = 12000000,
> >                 .min_pll_multiplier = 47,
> >                 .max_pll_multiplier = 2300,
> >                 .min_pll_op_clk_freq_hz = 1250000000,
> >                 .max_pll_op_clk_freq_hz = 2300000000,
> >         },
> >         .op_bk = {
> >
> >                  /* Similarly here also (OP_SYS_CLK_DIV -> 030b) value being used is 1,2,4 in out of tree driver
> >                   * But as per ccs-limits { CCS_R_MAX_OP_SYS_CLK_DIV = 2 }
> >                   */
> >
> >                 .min_sys_clk_div = 1,
> >                 .max_sys_clk_div = 2,
> >                 .min_sys_clk_freq_hz = 625000000,
> >                 .max_sys_clk_freq_hz = 2300000000,
> >
> >                 /* (RAW8 and RAW10) */
> >                 .min_pix_clk_div = 8,
> >                 .max_pix_clk_div = 10,
> >                 .min_pix_clk_freq_hz = 62500000,
> >                 .max_pix_clk_freq_hz = 2300000000,
> >         },
> >
> > >> +
> > >> +#define IMX576_REG_BINNING_MODE                CCI_REG8(0x0900)
> > >> +#define IMX576_REG_BINNING_TYPE                CCI_REG8(0x0901)
> > >> +#define IMX576_REG_BINNING_WEIGHT      CCI_REG8(0x0902)
> > >> +
> > >> +#define IMX576_PIXEL_RATE              813600000
> > >> +#define IMX576_NUM_DATA_LANES          4
> > >> +
> > >> +/* IMX576 native and active pixel array size */
> > >> +static const struct v4l2_rect imx576_native_area = {
> > >> +       .top = 0,
> > >> +       .left = 0,
> > >> +       .width = 5792,
> > >> +       .height = 4464,
> > >> +};
> > >> +
> > >> +static const struct v4l2_rect imx576_active_area = {
> > >> +       .top = 136,
> > >> +       .left = 16,
> > >> +       .width = 5760,
> > >> +       .height = 4312,
> > >> +};
> > >> +
> > >> +static const char * const imx576_supply_names[] = {
> > >> +       "vana",         /* Analog Power */
> > >> +       "vif",          /* Interface Power */
> > >> +       "vdig",         /* Digital Power */
> > >> +};
> > >> +
> > >> +static const struct cci_reg_sequence imx576_common_regs[] = {
> > >
> > >[...]
> > >
> > >> +       { IMX576_REG_IVT_PXCK_DIV, 0x05 },
> > >> +       { IMX576_REG_IVT_SYCK_DIV, 0x02 },
> > >> +       { IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
> > >> +       { IMX576_REG_IVT_PLL_MPY, 0x0154 },
> > >> +       { IMX576_REG_IOP_SYCK_DIV, 0x01 },
> > >> +       { IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
> > >> +       { IMX576_REG_PLL_MULT_DRIV, 0x01 },
> > >
> > >I think when Laurent asked to make the PLL configurable for different link
> > >frequencies, he meant deriving these and the OP_PLL_MPY value instead of
> > >hardcoding all of them and only supporting one link freq.
> > >> +       { CCI_REG8(0x0b06), 0x01 },
> > >> +       { CCI_REG8(0x3620), 0x01 },
> > >> +       { CCI_REG8(0x3f0c), 0x00 },
> > >> +};
> > >> +
> > >
> > >Thanks,
> > >    Jai
> >
> >
> > Best Regards,
> > Himanshu

Best Regards,
Himanshu

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

* Re: [PATCH v3 2/3] media: i2c: add imx576 image sensor driver
  2026-08-14 11:35         ` Himanshu Bhavani
@ 2026-08-14 12:52           ` Jai Luthra
  0 siblings, 0 replies; 12+ messages in thread
From: Jai Luthra @ 2026-08-14 12:52 UTC (permalink / raw)
  To: sakari.ailus@linux.intel.com, Himanshu Bhavani
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Hans de Goede, Vladimir Zapolskiy, Mehdi Djait,
	Elgin Perumbilly, Xiaolei Wang, Kate Hsuan,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	"linux-arm-msm@vger.kernel.org" <linux-ar 

Quoting Himanshu Bhavani (2026-08-14 17:05:12)
> Hi Jai,
> 
> >Hi Himanshu,
> >
> > Quoting Himanshu Bhavani (2026-08-11 14:44:12)
> > > Hi Jai,
> > >
> > > >Hi Himanshu,
> > > >
> > > >Thanks for the patch.
> > > >
> > > >Not a full review, but just a few comments on the PLL programming.
> > > >
> > > >Quoting Himanshu Bhavani (2026-08-06 17:32:08)
> > > >> Add a v4l2 subdevice driver for the Sony imx576 sensor.
> > > >>
> > > >> The Sony IMX576 image sensor with an active
> > > >> array size of 5760 x 4312
> > > >>
> > > >> The following features are supported:
> > > >> - Manual exposure an gain control support
> > > >> - vblank/hblank control support
> > > >> - Supported resolution: 5760 x 4312 30fps (SRGGB10)
> > > >>
> > > >> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
> > > >
> > > >[...]
> > > >
> > > >> +#define IMX576_INCLK_RATE              (24 * HZ_PER_MHZ)
> > > >> +
> > > >> +#define IMX576_REG_CHIP_ID             CCI_REG16(0x0016)
> > > >> +#define IMX576_CHIP_ID                 0x0576
> > > >> +
> > > >> +#define IMX576_REG_MODE_SELECT         CCI_REG8(0x0100)
> > > >> +#define IMX576_MODE_STANDBY            0x00
> > > >> +#define IMX576_MODE_STREAMING          0x01
> > > >> +
> > > >> +#define IMX576_REG_HOLD                        CCI_REG8(0x0104)
> > > >> +
> > > >> +#define IMX576_REG_EXPOSURE            CCI_REG16(0x0202)
> > > >> +#define IMX576_EXPOSURE_MIN            8
> > > >> +#define IMX576_EXPOSURE_OFFSET         22
> > > >> +#define IMX576_EXPOSURE_STEP           1
> > > >> +#define IMX576_EXPOSURE_DEFAULT                0x0648
> > > >> +
> > > >> +#define IMX576_REG_ANALOG_GAIN         CCI_REG16(0x0204)
> > > >> +#define IMX576_ANA_GAIN_MIN            0
> > > >> +#define IMX576_ANA_GAIN_MAX            978
> > > >> +#define IMX576_ANA_GAIN_STEP           1
> > > >> +#define IMX576_ANA_GAIN_DEFAULT                0
> > > >> +
> > > >> +#define IMX576_REG_IVT_PXCK_DIV                CCI_REG8(0x0301)
> > > >> +#define IMX576_REG_IVT_SYCK_DIV                CCI_REG8(0x0303)
> > > >> +#define IMX576_REG_IVT_PREPLLCK_DIV    CCI_REG8(0x0305)
> > > >> +#define IMX576_REG_IVT_PLL_MPY         CCI_REG16(0x0306)
> > > >> +#define IMX576_REG_IOP_SYCK_DIV                CCI_REG8(0x030b)
> > > >> +#define IMX576_REG_IOP_PREPLLCK_DIV    CCI_REG8(0x030d)
> > > >> +#define IMX576_REG_IOP_PLL_MPY         CCI_REG16(0x030e)
> > > >> +#define IMX576_REG_PLL_MULT_DRIV       CCI_REG8(0x0310)
> > > >> +
> > > >> +#define IMX576_REG_FRM_LENGTH_LINES    CCI_REG16(0x0340)
> > > >> +#define IMX576_REG_LINE_LENGTH_PCK     CCI_REG16(0x0342)
> > > >> +#define IMX576_LINE_LENGTH             6144
> > > >> +#define IMX576_VBLANK_DEF              4387
> > > >> +
> > > >> +/* FIXME: Exact VBLANK limit unknown (no datasheet). */
> > > >> +#define IMX576_VBLANK_MAX              32420
> > > >> +
> > > >> +#define IMX576_REG_X_ADD_STA           CCI_REG16(0x0344)
> > > >> +#define IMX576_REG_Y_ADD_STA           CCI_REG16(0x0346)
> > > >> +#define IMX576_REG_X_ADD_END           CCI_REG16(0x0348)
> > > >> +#define IMX576_REG_Y_ADD_END           CCI_REG16(0x034a)
> > > >> +#define IMX576_REG_X_OUTPUT_SIZE       CCI_REG16(0x034c)
> > > >> +#define IMX576_REG_Y_OUTPUT_SIZE       CCI_REG16(0x034e)
> > > >> +
> > > >> +#define IMX576_REG_DIG_CROP_X_OFFSET   CCI_REG16(0x0408)
> > > >> +#define IMX576_REG_DIG_CROP_Y_OFFSET   CCI_REG16(0x040a)
> > > >> +#define IMX576_REG_DIG_CROP_WIDTH      CCI_REG16(0x040c)
> > > >> +#define IMX576_REG_DIG_CROP_HEIGHT     CCI_REG16(0x040e)
> > > >
> > > >This sensor's registers seem quite similar to the MIPI CCS specification.
> > >
> > > Yes, you are right some registers seems to be similar I will address it.
> > >
> >
> > That's good to know. Did you check if the sensor itself advertises itself
> > as compliant to a particular version of the CCS standard? You can read the
> > below register:
> >
> > #define CCS_R_MIPI_CCS_VERSION                                        CCI_REG8(0x0007)
> >
> > In general it might help to take a dump of all the CCS registers to see if
> > the ranges given in datasheet match what the sensor's registers say.
> >
> 
> I tried reading CCS_R_MIPI_CCS_VERSION (CCI_REG8(0x0007)), but it
> returned 0x00.
> it is expected to return either CCS_MIPI_CCS_VERSION_V1_0 or
> CCS_MIPI_CCS_VERSION_V1_1 ?
> 

Not necessarily, it's the same as IMX708 which also returned 0x00.

I interpreted this to mean the sensor isn't compliant to the CCS
specification v1.0 or v1.1.

It supports the same register layout, but some features might make it
incompatible with the spec.

> I have shared you the minimal datasheet in personal,
> 
> Could you please clarify how you verified the IMX708 ? Is 0x0007
> documented as the MIPI CCS Version register?

It wasn't documented for IMX708 either. But dumping all CCS registers
(present in ccs-regs.h) worked for IMX708. I also ended up reusing the
register definitions by including ccs-regs.h in my driver, rather than
re-defining all macros.

> 
> 
> Because I tried applyig the imx576_pll_limits{..} PLL calculation and
> updating the corresponding registers, streaming works fine to me.
> readback those pll related registers confirms they are set as expected by
> the ccs-pll.c calculation.
> 

That's good, I would suggest going forward with this rather than hardcoded
values.

Thanks,
    Jai

> > >
> > > >Please check if the sensor is CCS compatible. Even if it is not, I think
> > > >the PLL programming is compatible, so you can use the helpers from
> > > >ccs-pll.c.
> > >
> > > Most PLL values are derived from the limited IMX576 datasheet information
> > > available.
> > >
> > > For the unknown values, I referred to out of tree driver and validated
> > > and assumed them based on the PLL configuration.
> > >
> > > Should I proceed with the PLL programming as it is, or drop the PLL
> > > approach and retain only the CCS-supported registers?
> > >
> >
> > I'm not sure I fully understand your question.
> >
> > If you can support more than 1 link frequency using the ccs_pll_calculate()
> > helper, then my suggestion would be to do that, even if it's just 2
> > well-tested frequencies today.
> >
> > That leaves the driver in much better shape for future (for use with a
> > different input clock or frequency). At least that's what I have done for
> > my IMX708 series, which was similar to this sensor.
> >
> > Thanks,
> >     Jai
> >
> > > static const struct ccs_pll_limits imx576_pll_limits = {
> > >         .min_ext_clk_freq_hz = 6000000,
> > >         .max_ext_clk_freq_hz = 27000000,
> > >
> > >         .vt_fr = {
> > >                 /* Confirmed values as per datasheet */
> > >
> > >                 .min_pre_pll_clk_div = 1,
> > >                 .max_pre_pll_clk_div = 4,
> > >                 .min_pll_ip_clk_freq_hz = 6000000,
> > >                 .max_pll_ip_clk_freq_hz = 12000000,
> > >                 .min_pll_multiplier = 87,
> > >                 .max_pll_multiplier = 350,
> > >                 .min_pll_op_clk_freq_hz = 1050000000,
> > >                 .max_pll_op_clk_freq_hz = 2100000000,
> > >         },
> > >
> > >         .vt_bk = {
> > >                 /* here the sys_clk_div (IVT_SYCK_DIV -> 0303) value as per out of tree driver they are using div as 2 or 4  */
> > >
> > >                 .min_sys_clk_div = 2,
> > >                 .max_sys_clk_div = 4,
> > >                 .min_sys_clk_freq_hz = 262500000,
> > >                 .max_sys_clk_freq_hz = 1050000000,
> > >
> > >                 /* pix_clk_div also being used as an Fixed to 5 */
> > >                 .min_pix_clk_div = 5,
> > >                 .max_pix_clk_div = 5,
> > >                 .min_pix_clk_freq_hz = 52500000,
> > >                 .max_pix_clk_freq_hz = 210000000,
> > >         },
> > >         .op_fr = {
> > >
> > >                 /* Confirmed values as per datasheet */
> > >
> > >                 .min_pre_pll_clk_div = 1,
> > >                 .max_pre_pll_clk_div = 15,
> > >                 .min_pll_ip_clk_freq_hz = 6000000,
> > >                 .max_pll_ip_clk_freq_hz = 12000000,
> > >                 .min_pll_multiplier = 47,
> > >                 .max_pll_multiplier = 2300,
> > >                 .min_pll_op_clk_freq_hz = 1250000000,
> > >                 .max_pll_op_clk_freq_hz = 2300000000,
> > >         },
> > >         .op_bk = {
> > >
> > >                  /* Similarly here also (OP_SYS_CLK_DIV -> 030b) value being used is 1,2,4 in out of tree driver
> > >                   * But as per ccs-limits { CCS_R_MAX_OP_SYS_CLK_DIV = 2 }
> > >                   */
> > >
> > >                 .min_sys_clk_div = 1,
> > >                 .max_sys_clk_div = 2,
> > >                 .min_sys_clk_freq_hz = 625000000,
> > >                 .max_sys_clk_freq_hz = 2300000000,
> > >
> > >                 /* (RAW8 and RAW10) */
> > >                 .min_pix_clk_div = 8,
> > >                 .max_pix_clk_div = 10,
> > >                 .min_pix_clk_freq_hz = 62500000,
> > >                 .max_pix_clk_freq_hz = 2300000000,
> > >         },
> > >
> > > >> +
> > > >> +#define IMX576_REG_BINNING_MODE                CCI_REG8(0x0900)
> > > >> +#define IMX576_REG_BINNING_TYPE                CCI_REG8(0x0901)
> > > >> +#define IMX576_REG_BINNING_WEIGHT      CCI_REG8(0x0902)
> > > >> +
> > > >> +#define IMX576_PIXEL_RATE              813600000
> > > >> +#define IMX576_NUM_DATA_LANES          4
> > > >> +
> > > >> +/* IMX576 native and active pixel array size */
> > > >> +static const struct v4l2_rect imx576_native_area = {
> > > >> +       .top = 0,
> > > >> +       .left = 0,
> > > >> +       .width = 5792,
> > > >> +       .height = 4464,
> > > >> +};
> > > >> +
> > > >> +static const struct v4l2_rect imx576_active_area = {
> > > >> +       .top = 136,
> > > >> +       .left = 16,
> > > >> +       .width = 5760,
> > > >> +       .height = 4312,
> > > >> +};
> > > >> +
> > > >> +static const char * const imx576_supply_names[] = {
> > > >> +       "vana",         /* Analog Power */
> > > >> +       "vif",          /* Interface Power */
> > > >> +       "vdig",         /* Digital Power */
> > > >> +};
> > > >> +
> > > >> +static const struct cci_reg_sequence imx576_common_regs[] = {
> > > >
> > > >[...]
> > > >
> > > >> +       { IMX576_REG_IVT_PXCK_DIV, 0x05 },
> > > >> +       { IMX576_REG_IVT_SYCK_DIV, 0x02 },
> > > >> +       { IMX576_REG_IVT_PREPLLCK_DIV, 0x04 },
> > > >> +       { IMX576_REG_IVT_PLL_MPY, 0x0154 },
> > > >> +       { IMX576_REG_IOP_SYCK_DIV, 0x01 },
> > > >> +       { IMX576_REG_IOP_PREPLLCK_DIV, 0x04 },
> > > >> +       { IMX576_REG_PLL_MULT_DRIV, 0x01 },
> > > >
> > > >I think when Laurent asked to make the PLL configurable for different link
> > > >frequencies, he meant deriving these and the OP_PLL_MPY value instead of
> > > >hardcoding all of them and only supporting one link freq.
> > > >> +       { CCI_REG8(0x0b06), 0x01 },
> > > >> +       { CCI_REG8(0x3620), 0x01 },
> > > >> +       { CCI_REG8(0x3f0c), 0x00 },
> > > >> +};
> > > >> +
> > > >
> > > >Thanks,
> > > >    Jai
> > >
> > >
> > > Best Regards,
> > > Himanshu
> 
> Best Regards,
> Himanshu

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

* Re: [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support
  2026-08-06 12:02 ` [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support Himanshu Bhavani
  2026-08-07  6:55   ` Jai Luthra
@ 2026-08-24  9:46   ` Konrad Dybcio
  1 sibling, 0 replies; 12+ messages in thread
From: Konrad Dybcio @ 2026-08-24  9:46 UTC (permalink / raw)
  To: Himanshu Bhavani, sakari.ailus
  Cc: Hardevsinh Palaniya, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Hans Verkuil, Vladimir Zapolskiy, Hans de Goede, Tarang Raval,
	Elgin Perumbilly, Kate Hsuan, Xiaolei Wang,
	Walter Werner Schneider, Laurent Pinchart, Bartosz Golaszewski,
	Mehdi Djait, Miguel Vadillo, linux-media, devicetree,
	linux-kernel, linux-arm-msm

On 8/6/26 2:02 PM, Himanshu Bhavani wrote:
> From: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
> 
> Add device tree support for the Sony IMX576 front camera
> sensor and connect it to CAMSS via CSIPHY3.
> 
> Signed-off-by: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
> Signed-off-by: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

end of thread, other threads:[~2026-08-24  9:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06 12:02 [PATCH v3 0/3] media: i2c: Add imx576 camera sensor driver Himanshu Bhavani
2026-08-06 12:02 ` [PATCH v3 1/3] dt-bindings: media: i2c: Add imx576 sensor Himanshu Bhavani
2026-08-06 12:02 ` [PATCH v3 2/3] media: i2c: add imx576 image sensor driver Himanshu Bhavani
2026-08-07  7:00   ` Jai Luthra
2026-08-11  9:14     ` Himanshu Bhavani
2026-08-12  6:16       ` Jai Luthra
2026-08-14 11:35         ` Himanshu Bhavani
2026-08-14 12:52           ` Jai Luthra
2026-08-06 12:02 ` [PATCH v3 3/3] arm64: dts: qcom: sm7225-fairphone-fp4: Add Sony IMX576 front camera support Himanshu Bhavani
2026-08-07  6:55   ` Jai Luthra
2026-08-11  9:16     ` Himanshu Bhavani
2026-08-24  9:46   ` Konrad Dybcio

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