All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
@ 2022-11-25 15:31 Petko Manolov
  2022-11-25 15:31 ` [PATCH v1 1/5] DT bindings for imx492 Petko Manolov
                   ` (5 more replies)
  0 siblings, 6 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

This patch adds dt-bindings documentation, driver source, etc for Sony imx492
image sensor.

imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
digital output makes it possible to output the signals with high definition for
moving pictures. It is programmable through I2C interface. The I2C client
address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
through MIPI CSI-2.

Petko Manolov (5):
  DT bindings for imx492
  media: i2c: imx492: driver's header
  media: i2c: imx492: driver's source
  media: i2c: add imx492 config entry
  media: i2c: add imx492 entry for make

 .../bindings/media/i2c/sony,imx492.yaml       |  101 ++
 drivers/media/i2c/Kconfig                     |   14 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/imx492.c                    | 1092 +++++++++++++++++
 drivers/media/i2c/imx492.h                    |  555 +++++++++
 5 files changed, 1763 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
 create mode 100644 drivers/media/i2c/imx492.c
 create mode 100644 drivers/media/i2c/imx492.h

-- 
2.30.2


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

* [PATCH v1 1/5] DT bindings for imx492
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
@ 2022-11-25 15:31 ` Petko Manolov
  2022-11-28  4:37   ` Laurent Pinchart
  2022-11-25 15:31 ` [PATCH v1 2/5] media: i2c: imx492: driver's header Petko Manolov
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Here goes the DT bindings file.

Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
---
 .../bindings/media/i2c/sony,imx492.yaml       | 101 ++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
new file mode 100644
index 000000000000..f4feef17c677
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx492.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony imx492 Sensor
+
+maintainers:
+  - Petko Manolov <petko.manolov@konsulko.com>
+
+description:
+
+  imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
+  monochrome square pixel array and approximately 47.08 M effective pixels.
+  12-bit digital output makes it possible to output the signals with high
+  definition for moving pictures. It is programmable through I2C interface. The
+  I2C client address can be either 0x10 or 0x1a depending on SLASEL pin. Image
+  data is sent through MIPI CSI-2.
+
+properties:
+  compatible:
+    const: sony,imx492
+  reg:
+    description: I2C address
+    maxItems: 1
+
+  assigned-clocks: true
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+
+  clocks:
+    description: Clock frequency 6MHz, 12MHz, 18MHz and 24MHz
+    maxItems: 1
+
+  dovdd-supply:
+    description: Interface power supply.
+
+  avdd-supply:
+    description: Analog power supply.
+
+  dvdd-supply:
+    description: Digital power supply.
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the XCLR pin, if any.
+    maxItems: 1
+
+  port:
+    additionalProperties: false
+    $ref: /schemas/graph.yaml#/$defs/port-base
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes: true
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera@10 {
+            compatible = "sony,imx492";
+            reg = <0x10>;
+            clocks = <&imx492_clk>;
+
+            assigned-clocks = <&imx492_clk>;
+            assigned-clock-parents = <&imx492_clk_parent>;
+            assigned-clock-rates = <24000000>;
+
+            port {
+                imx492: endpoint {
+                    remote-endpoint = <&cam>;
+                    data-lanes = <1 2 3 4>;
+                    link-frequencies = /bits/ 64 <600000000>;
+                };
+            };
+        };
+    };
+...
-- 
2.30.2


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

* [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
  2022-11-25 15:31 ` [PATCH v1 1/5] DT bindings for imx492 Petko Manolov
@ 2022-11-25 15:31 ` Petko Manolov
  2022-11-28  4:40   ` Laurent Pinchart
  2022-11-28 12:47   ` Kieran Bingham
  2022-11-25 15:31 ` [PATCH v1 3/5] media: i2c: imx492: driver's source Petko Manolov
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

The header.  For the moment only two modes are supported.

Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
---
 drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
 1 file changed, 555 insertions(+)
 create mode 100644 drivers/media/i2c/imx492.h

diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
new file mode 100644
index 000000000000..301fd66c77d5
--- /dev/null
+++ b/drivers/media/i2c/imx492.h
@@ -0,0 +1,555 @@
+#ifndef	__imx492_h__
+#define	__imx492_h__
+
+struct imx492_reg {
+	u16 address;
+	u8 val;
+};
+
+static const struct imx492_reg mode_17to9_regs[] = {
+	{ 0x3033, 0x30 },
+	{ 0x303c, 0x01 },
+	{ 0x31e8, 0xa0 },
+	{ 0x31f4, 0x01 },
+	{ 0x31e9, 0x00 },
+	{ 0x3122, 0x02 },
+	{ 0x3129, 0x90 },
+	{ 0x312a, 0x02 },
+	{ 0x311f, 0x00 },
+	{ 0x3123, 0x00 },
+	{ 0x3124, 0x00 },
+	{ 0x3125, 0x01 },
+	{ 0x3127, 0x02 },
+	{ 0x312d, 0x02 },
+	{ 0x3000, 0x12 },
+	{ 0x310b, 0x00 },
+	{ 0x3004, 0x1c },
+	{ 0x3005, 0x06 },
+	{ 0x3006, 0x00 },
+	{ 0x3007, 0xa7 },
+	{ 0x3047, 0x02 },
+	{ 0x304e, 0x0b },
+	{ 0x304f, 0x2a },
+	{ 0x3052, 0xee },
+	{ 0x3062, 0x25 },
+	{ 0x3064, 0x78 },
+	{ 0x3065, 0x33 },
+	{ 0x3066, 0x64 },
+	{ 0x3067, 0x71 },
+	{ 0x307e, 0x07 },
+	{ 0x3081, 0x00 },
+	{ 0x3088, 0x75 },
+	{ 0x308a, 0x09 },
+	{ 0x308c, 0x61 },
+	{ 0x30ef, 0x01 },
+	{ 0x3146, 0x00 },
+	{ 0x31f5, 0x01 },
+	{ 0x3234, 0x32 },
+	{ 0x3248, 0xbc },
+	{ 0x3250, 0xbc },
+	{ 0x3258, 0xbc },
+	{ 0x3260, 0xbc },
+	{ 0x3274, 0x13 },
+	{ 0x3276, 0x00 },
+	{ 0x3277, 0x00 },
+	{ 0x327c, 0x13 },
+	{ 0x327e, 0x00 },
+	{ 0x327f, 0x00 },
+	{ 0x3284, 0x13 },
+	{ 0x3286, 0x00 },
+	{ 0x3287, 0x00 },
+	{ 0x328c, 0x13 },
+	{ 0x328e, 0x00 },
+	{ 0x328f, 0x00 },
+	{ 0x32ae, 0x00 },
+	{ 0x32af, 0x00 },
+	{ 0x32ca, 0x5a },
+	{ 0x332c, 0x00 },
+	{ 0x332f, 0x00 },
+	{ 0x334a, 0x00 },
+	{ 0x334c, 0x01 },
+	{ 0x3352, 0x50 },
+	{ 0x3356, 0x4f },
+	{ 0x335a, 0x79 },
+	{ 0x335e, 0x56 },
+	{ 0x3360, 0x6a },
+	{ 0x336a, 0x56 },
+	{ 0x33d6, 0x79 },
+	{ 0x340c, 0x6e },
+	{ 0x3448, 0x7e },
+	{ 0x348e, 0x6f },
+	{ 0x3492, 0x11 },
+	{ 0x34c4, 0x5a },
+	{ 0x3506, 0x56 },
+	{ 0x350c, 0x56 },
+	{ 0x350e, 0x58 },
+	{ 0x353d, 0x10 },
+	{ 0x3549, 0x04 },
+	{ 0x355d, 0x03 },
+	{ 0x355e, 0x03 },
+	{ 0x3574, 0x56 },
+	{ 0x357f, 0x0c },
+	{ 0x3580, 0x0a },
+	{ 0x3581, 0x08 },
+	{ 0x3583, 0x72 },
+	{ 0x3587, 0x01 },
+	{ 0x35b6, 0x00 },
+	{ 0x35b8, 0x00 },
+	{ 0x35d0, 0x5e },
+	{ 0x35d4, 0x63 },
+	{ 0x366a, 0x04 },
+	{ 0x366b, 0x04 },
+	{ 0x366c, 0x00 },
+	{ 0x366d, 0x00 },
+	{ 0x366e, 0x00 },
+	{ 0x366f, 0x00 },
+	{ 0x3670, 0x00 },
+	{ 0x3671, 0x05 },
+	{ 0x3676, 0x83 },
+	{ 0x3677, 0x03 },
+	{ 0x3678, 0x00 },
+	{ 0x3679, 0x04 },
+	{ 0x367a, 0x2c },
+	{ 0x367b, 0x05 },
+	{ 0x367d, 0x06 },
+	{ 0x367e, 0xff },
+	{ 0x367f, 0x06 },
+	{ 0x3680, 0x4b },
+	{ 0x3688, 0x05 },
+	{ 0x3690, 0x27 },
+	{ 0x3692, 0x65 },
+	{ 0x3694, 0x4f },
+	{ 0x3696, 0xa1 },
+	{ 0x36bc, 0x00 },
+	{ 0x371c, 0x02 },
+	{ 0x372f, 0x3c },
+	{ 0x3730, 0x01 },
+	{ 0x3732, 0xb8 },
+	{ 0x3734, 0x4a },
+	{ 0x3736, 0x57 },
+	{ 0x3738, 0x4d },
+	{ 0x3744, 0x0f },
+	{ 0x375b, 0x01 },
+	{ 0x382b, 0x68 },
+	{ 0x38b3, 0x00 },
+	{ 0x3910, 0x90 },
+	{ 0x3911, 0x70 },
+	{ 0x3912, 0x92 },
+	{ 0x3913, 0x24 },
+	{ 0x3914, 0x93 },
+	{ 0x3915, 0x0b },
+	{ 0x3916, 0x01 },
+	{ 0x3918, 0x04 },
+	{ 0x391c, 0x90 },
+	{ 0x391d, 0x05 },
+	{ 0x3920, 0x96 },
+	{ 0x3921, 0x06 },
+	{ 0x3a2a, 0x01 },
+	{ 0x3a7a, 0x01 },
+	{ 0x3a7b, 0x01 },
+	{ 0x3acb, 0x06 },
+	{ 0x3c08, 0x3f },
+	{ 0x3c0c, 0x1b },
+	{ 0x3e80, 0x14 },
+	{ 0x3e82, 0x30 },
+	{ 0x3e84, 0x0c },
+	{ 0x3e85, 0x06 },
+	{ 0x3e86, 0xfc },
+	{ 0x3e87, 0x10 },
+	{ 0x3e88, 0x03 },
+	{ 0x3e89, 0xfe },
+	{ 0x3e8a, 0x01 },
+	{ 0x3e8b, 0x06 },
+	{ 0x3e8e, 0x03 },
+	{ 0x3e8f, 0xfe },
+	{ 0x3e90, 0x01 },
+	{ 0x3e91, 0x06 },
+	{ 0x3e94, 0x33 },
+	{ 0x3e95, 0x01 },
+	{ 0x3e96, 0x19 },
+	{ 0x3e98, 0x30 },
+	{ 0x3e9a, 0x11 },
+	{ 0x3e9b, 0x06 },
+	{ 0x3e9c, 0xfc },
+	{ 0x3e9d, 0x10 },
+	{ 0x3e9e, 0xfe },
+	{ 0x3e9f, 0x03 },
+	{ 0x3ea0, 0x06 },
+	{ 0x3ea3, 0x01 },
+	{ 0x3ea4, 0xfe },
+	{ 0x3ea5, 0x03 },
+	{ 0x3ea6, 0x06 },
+	{ 0x3ea9, 0x33 },
+	{ 0x3eaa, 0x00 },
+	{ 0x3eab, 0x08 },
+	{ 0x3eac, 0x08 },
+	{ 0x3ead, 0x01 },
+	{ 0x3eae, 0x08 },
+	{ 0x3eaf, 0x08 },
+	{ 0x3eb0, 0x00 },
+	{ 0x3eb1, 0x10 },
+	{ 0x3eb2, 0x10 },
+	{ 0x3eb3, 0x01 },
+	{ 0x3eb4, 0x10 },
+	{ 0x3eb5, 0x10 },
+	{ 0x3eb6, 0x00 },
+	{ 0x3eb7, 0x00 },
+	{ 0x3eb8, 0x00 },
+	{ 0x3eb9, 0x00 },
+	{ 0x3eba, 0x00 },
+	{ 0x3ebb, 0x00 },
+	{ 0x3ec0, 0x54 },
+	{ 0x3ecc, 0x04 },
+	{ 0x3ecd, 0x04 },
+	{ 0x3ed0, 0xf0 },
+	{ 0x3ed1, 0x20 },
+	{ 0x3ed2, 0x0b },
+	{ 0x3ed3, 0x04 },
+	{ 0x3ed5, 0x13 },
+	{ 0x3ed6, 0x00 },
+	{ 0x3ed9, 0x0f },
+	{ 0x3ee4, 0x02 },
+	{ 0x3ee5, 0x02 },
+	{ 0x3ee7, 0x00 },
+	{ 0x3ef6, 0x00 },
+	{ 0x3ef8, 0x10 },
+	{ 0x3efa, 0x00 },
+	{ 0x3efc, 0x10 },
+	{ 0x3134, 0xa7 },
+	{ 0x3135, 0x00 },
+	{ 0x3136, 0x9f },
+	{ 0x3137, 0x00 },
+	{ 0x3138, 0x6f },
+	{ 0x3139, 0x00 },
+	{ 0x313a, 0x5f },
+	{ 0x313b, 0x00 },
+	{ 0x313c, 0x5f },
+	{ 0x313d, 0x00 },
+	{ 0x313e, 0x7f },
+	{ 0x313f, 0x01 },
+	{ 0x3140, 0x6f },
+	{ 0x3141, 0x00 },
+	{ 0x3142, 0x4f },
+	{ 0x3143, 0x00 },
+	{ 0x300e, 0x00 },
+	{ 0x300f, 0x00 },
+	{ 0x302c, 0x0c },
+	{ 0x302d, 0x00 },
+	{ 0x3034, 0x01 },
+	{ 0x3035, 0x01 },
+	{ 0x3036, 0x64 },
+	{ 0x3037, 0x00 },
+	{ 0x3038, 0xc8 },
+	{ 0x3039, 0x00 },
+	{ 0x3084, 0x4e },
+	{ 0x3085, 0x04 },
+	{ 0x3086, 0x4e },
+	{ 0x3087, 0x04 },
+	{ 0x30a9, 0xe0 },
+	{ 0x30aa, 0x2e },
+	{ 0x30ab, 0x00 },
+	{ 0x30ac, 0x48 },
+	{ 0x30ad, 0x0d },
+	{ 0x30e2, 0x00 },
+	{ 0x312f, 0x20 },
+	{ 0x3130, 0x1c },
+	{ 0x3131, 0x11 },
+	{ 0x3132, 0xfc },
+	{ 0x3133, 0x10 },
+	{ 0x3a54, 0xf0 },
+	{ 0x3a55, 0x20 },
+	{ 0x3a43, 0x01 },
+	{ 0x3a3b, 0x00 },
+	{ 0x3042, 0x32 },
+	{ 0x3092, 0x00 },
+	{ 0x30dd, 0x00 },
+	{ 0x30de, 0x00 },
+	{ 0x30df, 0x00 },
+	{ 0x30e0, 0x00 },
+	{ 0x30e1, 0x00 },
+	{ 0x332c, 0x00 },
+	{ 0x332d, 0x00 },
+	{ 0x334a, 0x00 },
+	{ 0x334b, 0x00 },
+	{ 0x35b6, 0x00 },
+	{ 0x35b7, 0x00 },
+	{ 0x35b8, 0x00 },
+	{ 0x35b9, 0x00 },
+	{ 0x36bc, 0x00 },
+	{ 0x36bd, 0x00 },
+};
+
+static const struct imx492_reg mode_all_regs[] = {
+	{ 0x3033, 0x30 },
+	{ 0x303c, 0x01 },
+	{ 0x31e8, 0xa0 },
+	{ 0x31f4, 0x01 },
+	{ 0x31e9, 0x00 },
+	{ 0x3122, 0x02 },
+	{ 0x3129, 0x90 },
+	{ 0x312a, 0x02 },
+	{ 0x311f, 0x00 },
+	{ 0x3123, 0x00 },
+	{ 0x3124, 0x00 },
+	{ 0x3125, 0x01 },
+	{ 0x3127, 0x02 },
+	{ 0x312d, 0x02 },
+	{ 0x3000, 0x12 },
+	{ 0x310b, 0x00 },
+	{ 0x3004, 0x1c },
+	{ 0x3005, 0x06 },
+	{ 0x3006, 0x00 },
+	{ 0x3007, 0xa7 },
+	{ 0x3047, 0x02 },
+	{ 0x304e, 0x0b },
+	{ 0x304f, 0x2a },
+	{ 0x3052, 0xee },
+	{ 0x3062, 0x25 },
+	{ 0x3064, 0x78 },
+	{ 0x3065, 0x33 },
+	{ 0x3066, 0x64 },
+	{ 0x3067, 0x71 },
+	{ 0x307e, 0x07 },
+	{ 0x3081, 0x00 },
+	{ 0x3088, 0x75 },
+	{ 0x308a, 0x09 },
+	{ 0x308c, 0x61 },
+	{ 0x30ef, 0x01 },
+	{ 0x3146, 0x00 },
+	{ 0x31f5, 0x01 },
+	{ 0x3234, 0x32 },
+	{ 0x3248, 0xbc },
+	{ 0x3250, 0xbc },
+	{ 0x3258, 0xbc },
+	{ 0x3260, 0xbc },
+	{ 0x3274, 0x13 },
+	{ 0x3276, 0x00 },
+	{ 0x3277, 0x00 },
+	{ 0x327c, 0x13 },
+	{ 0x327e, 0x00 },
+	{ 0x327f, 0x00 },
+	{ 0x3284, 0x13 },
+	{ 0x3286, 0x00 },
+	{ 0x3287, 0x00 },
+	{ 0x328c, 0x13 },
+	{ 0x328e, 0x00 },
+	{ 0x328f, 0x00 },
+	{ 0x32ae, 0x00 },
+	{ 0x32af, 0x00 },
+	{ 0x32ca, 0x5a },
+	{ 0x332c, 0x00 },
+	{ 0x332f, 0x00 },
+	{ 0x334a, 0x00 },
+	{ 0x334c, 0x01 },
+	{ 0x3352, 0x50 },
+	{ 0x3356, 0x4f },
+	{ 0x335a, 0x79 },
+	{ 0x335e, 0x56 },
+	{ 0x3360, 0x6a },
+	{ 0x336a, 0x56 },
+	{ 0x33d6, 0x79 },
+	{ 0x340c, 0x6e },
+	{ 0x3448, 0x7e },
+	{ 0x348e, 0x6f },
+	{ 0x3492, 0x11 },
+	{ 0x34c4, 0x5a },
+	{ 0x3506, 0x56 },
+	{ 0x350c, 0x56 },
+	{ 0x350e, 0x58 },
+	{ 0x353d, 0x10 },
+	{ 0x3549, 0x04 },
+	{ 0x355d, 0x03 },
+	{ 0x355e, 0x03 },
+	{ 0x3574, 0x56 },
+	{ 0x357f, 0x0c },
+	{ 0x3580, 0x0a },
+	{ 0x3581, 0x08 },
+	{ 0x3583, 0x72 },
+	{ 0x3587, 0x01 },
+	{ 0x35b6, 0x00 },
+	{ 0x35b8, 0x00 },
+	{ 0x35d0, 0x5e },
+	{ 0x35d4, 0x63 },
+	{ 0x366a, 0x04 },
+	{ 0x366b, 0x04 },
+	{ 0x366c, 0x00 },
+	{ 0x366d, 0x00 },
+	{ 0x366e, 0x00 },
+	{ 0x366f, 0x00 },
+	{ 0x3670, 0x00 },
+	{ 0x3671, 0x05 },
+	{ 0x3676, 0x83 },
+	{ 0x3677, 0x03 },
+	{ 0x3678, 0x00 },
+	{ 0x3679, 0x04 },
+	{ 0x367a, 0x2c },
+	{ 0x367b, 0x05 },
+	{ 0x367d, 0x06 },
+	{ 0x367e, 0xff },
+	{ 0x367f, 0x06 },
+	{ 0x3680, 0x4b },
+	{ 0x3688, 0x05 },
+	{ 0x3690, 0x27 },
+	{ 0x3692, 0x65 },
+	{ 0x3694, 0x4f },
+	{ 0x3696, 0xa1 },
+	{ 0x36bc, 0x00 },
+	{ 0x371c, 0x02 },
+	{ 0x372f, 0x3c },
+	{ 0x3730, 0x01 },
+	{ 0x3732, 0xb8 },
+	{ 0x3734, 0x4a },
+	{ 0x3736, 0x57 },
+	{ 0x3738, 0x4d },
+	{ 0x3744, 0x0f },
+	{ 0x375b, 0x01 },
+	{ 0x382b, 0x68 },
+	{ 0x38b3, 0x00 },
+	{ 0x3910, 0x90 },
+	{ 0x3911, 0x70 },
+	{ 0x3912, 0x92 },
+	{ 0x3913, 0x24 },
+	{ 0x3914, 0x93 },
+	{ 0x3915, 0x0b },
+	{ 0x3916, 0x01 },
+	{ 0x3918, 0x04 },
+	{ 0x391c, 0x90 },
+	{ 0x391d, 0x05 },
+	{ 0x3920, 0x96 },
+	{ 0x3921, 0x06 },
+	{ 0x3a2a, 0x01 },
+	{ 0x3a7a, 0x01 },
+	{ 0x3a7b, 0x01 },
+	{ 0x3acb, 0x06 },
+	{ 0x3c08, 0x3f },
+	{ 0x3c0c, 0x1b },
+	{ 0x3e80, 0x14 },
+	{ 0x3e82, 0x30 },
+	{ 0x3e84, 0x0c },
+	{ 0x3e85, 0x06 },
+	{ 0x3e86, 0xfc },
+	{ 0x3e87, 0x10 },
+	{ 0x3e88, 0x03 },
+	{ 0x3e89, 0xfe },
+	{ 0x3e8a, 0x01 },
+	{ 0x3e8b, 0x06 },
+	{ 0x3e8e, 0x03 },
+	{ 0x3e8f, 0xfe },
+	{ 0x3e90, 0x01 },
+	{ 0x3e91, 0x06 },
+	{ 0x3e94, 0x33 },
+	{ 0x3e95, 0x01 },
+	{ 0x3e96, 0x19 },
+	{ 0x3e98, 0x30 },
+	{ 0x3e9a, 0x11 },
+	{ 0x3e9b, 0x06 },
+	{ 0x3e9c, 0xfc },
+	{ 0x3e9d, 0x10 },
+	{ 0x3e9e, 0xfe },
+	{ 0x3e9f, 0x03 },
+	{ 0x3ea0, 0x06 },
+	{ 0x3ea3, 0x01 },
+	{ 0x3ea4, 0xfe },
+	{ 0x3ea5, 0x03 },
+	{ 0x3ea6, 0x06 },
+	{ 0x3ea9, 0x33 },
+	{ 0x3eaa, 0x00 },
+	{ 0x3eab, 0x08 },
+	{ 0x3eac, 0x08 },
+	{ 0x3ead, 0x01 },
+	{ 0x3eae, 0x08 },
+	{ 0x3eaf, 0x08 },
+	{ 0x3eb0, 0x00 },
+	{ 0x3eb1, 0x10 },
+	{ 0x3eb2, 0x10 },
+	{ 0x3eb3, 0x01 },
+	{ 0x3eb4, 0x10 },
+	{ 0x3eb5, 0x10 },
+	{ 0x3eb6, 0x00 },
+	{ 0x3eb7, 0x00 },
+	{ 0x3eb8, 0x00 },
+	{ 0x3eb9, 0x00 },
+	{ 0x3eba, 0x00 },
+	{ 0x3ebb, 0x00 },
+	{ 0x3ec0, 0x54 },
+	{ 0x3ecc, 0x04 },
+	{ 0x3ecd, 0x04 },
+	{ 0x3ed0, 0xf0 },
+	{ 0x3ed1, 0x20 },
+	{ 0x3ed2, 0x0b },
+	{ 0x3ed3, 0x04 },
+	{ 0x3ed5, 0x13 },
+	{ 0x3ed6, 0x00 },
+	{ 0x3ed9, 0x0f },
+	{ 0x3ee4, 0x02 },
+	{ 0x3ee5, 0x02 },
+	{ 0x3ee7, 0x00 },
+	{ 0x3ef6, 0x00 },
+	{ 0x3ef8, 0x10 },
+	{ 0x3efa, 0x00 },
+	{ 0x3efc, 0x10 },
+	{ 0x3134, 0xa7 },
+	{ 0x3135, 0x00 },
+	{ 0x3136, 0x9f },
+	{ 0x3137, 0x00 },
+	{ 0x3138, 0x6f },
+	{ 0x3139, 0x00 },
+	{ 0x313a, 0x5f },
+	{ 0x313b, 0x00 },
+	{ 0x313c, 0x5f },
+	{ 0x313d, 0x00 },
+	{ 0x313e, 0x7f },
+	{ 0x313f, 0x01 },
+	{ 0x3140, 0x6f },
+	{ 0x3141, 0x00 },
+	{ 0x3142, 0x4f },
+	{ 0x3143, 0x00 },
+	{ 0x300e, 0x00 },
+	{ 0x300f, 0x00 },
+	{ 0x302c, 0x0c },
+	{ 0x302d, 0x00 },
+	{ 0x3034, 0x01 },
+	{ 0x3035, 0x01 },
+	{ 0x3036, 0x64 },
+	{ 0x3037, 0x00 },
+	{ 0x3038, 0xc8 },
+	{ 0x3039, 0x00 },
+	{ 0x3084, 0x4e },
+	{ 0x3085, 0x04 },
+	{ 0x3086, 0x4e },
+	{ 0x3087, 0x04 },
+	{ 0x30a9, 0xe0 },
+	{ 0x30aa, 0x2e },
+	{ 0x30ab, 0x00 },
+	{ 0x30ac, 0x48 },
+	{ 0x30ad, 0x0d },
+	{ 0x30e2, 0x00 },
+	{ 0x312f, 0x20 },
+	{ 0x3130, 0x1c },
+	{ 0x3131, 0x11 },
+	{ 0x3132, 0xfc },
+	{ 0x3133, 0x10 },
+	{ 0x3a54, 0xf0 },
+	{ 0x3a55, 0x20 },
+	{ 0x3a43, 0x01 },
+	{ 0x3a3b, 0x00 },
+	{ 0x3042, 0x32 },
+	{ 0x3092, 0x00 },
+	{ 0x30dd, 0x00 },
+	{ 0x30de, 0x00 },
+	{ 0x30df, 0x00 },
+	{ 0x30e0, 0x00 },
+	{ 0x30e1, 0x00 },
+	{ 0x332c, 0x00 },
+	{ 0x332d, 0x00 },
+	{ 0x334a, 0x00 },
+	{ 0x334b, 0x00 },
+	{ 0x35b6, 0x00 },
+	{ 0x35b7, 0x00 },
+	{ 0x35b8, 0x00 },
+	{ 0x35b9, 0x00 },
+	{ 0x36bc, 0x00 },
+	{ 0x36bd, 0x00 },
+};
+
+#endif /* __imx492_h__ */
-- 
2.30.2


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

* [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
  2022-11-25 15:31 ` [PATCH v1 1/5] DT bindings for imx492 Petko Manolov
  2022-11-25 15:31 ` [PATCH v1 2/5] media: i2c: imx492: driver's header Petko Manolov
@ 2022-11-25 15:31 ` Petko Manolov
  2022-11-28  5:16   ` Laurent Pinchart
  2022-11-28 12:58   ` Kieran Bingham
  2022-11-25 15:31 ` [PATCH v1 4/5] media: i2c: add imx492 config entry Petko Manolov
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
digital output makes it possible to output the signals with high definition for
moving pictures. It is programmable through I2C interface. The I2C client
address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
through MIPI CSI-2.

Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
---
 drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
 1 file changed, 1092 insertions(+)
 create mode 100644 drivers/media/i2c/imx492.c

diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
new file mode 100644
index 000000000000..0713256b4b63
--- /dev/null
+++ b/drivers/media/i2c/imx492.c
@@ -0,0 +1,1092 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Sony imx492 Camera Sensor Driver (based on imx412.c source);
+ *
+ * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
+ */
+
+#include <asm/unaligned.h>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#include "imx492.h"
+
+/* Streaming Mode */
+#define IMX492_REG_MODE_SELECT	0x3000
+
+/* Chip ID */
+#define IMX492_ID		0x13
+
+/* Analog gain control */
+#define IMX492_REG_AGAIN	0x300a
+#define IMX492_AGAIN_MIN	0
+#define IMX492_AGAIN_MAX	978
+#define IMX492_AGAIN_STEP	1
+#define IMX492_AGAIN_DEFAULT	0
+
+/* Group hold register */
+#define IMX492_REG_HOLD		0x302b
+#define	IMX492_REG_XMSTA	0x3033
+#define	IMX492_REG_SYSCLKEN	0x35e5
+
+/* CSI2 HW configuration */
+#define IMX492_LINK_FREQ	745000000
+#define IMX492_NUM_DATA_LANES	4
+
+#define IMX492_REG_MIN		0x3000
+#define IMX492_REG_MAX		0xffff
+
+/* *** */
+
+#define IMX492_REG_STANDBY	IMX492_REG_MODE_SELECT
+#define IMX492_BIT_STANDBY	0x01
+#define IMX492_BIT_STBLOGIC	0x02
+#define IMX492_BIT_STBDV	0x10
+
+#define IMX492_MODE_STANDBY	(IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
+#define IMX492_MODE_STREAMING	0x00
+
+#define IMX492_REG_TESTPTRN	0x303A
+#define IMX492_BIT_CLKEN	0x01
+#define IMX492_BIT_TESTPTRN	0x10
+#define IMX492_BITS_TPTRN_ON	(IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
+#define IMX492_BITS_TPTRN_OFF	0x00
+
+#define IMX492_REG_TESTPATSEL	0x303B
+#define IMX492_BIT_TPAT00	0x00
+#define IMX492_BIT_TPAT01	0x01
+#define IMX492_BIT_TPAT02	0x02
+#define IMX492_BIT_TPAT03	0x03
+#define IMX492_BIT_TPAT0A	0x0A
+#define IMX492_BIT_TPAT0B	0x0B
+
+#define IMX492_EXPOSURE_MIN		8
+#define IMX492_EXPOSURE_OFFSET		22
+#define IMX492_EXPOSURE_STEP		1
+#define IMX492_EXPOSURE_DEFAULT		0x0648
+
+#define	DEFAULT_FPS		6
+
+/**
+ * struct imx492_reg_list - imx492 sensor register list
+ * @num_of_regs: Number of registers in the list
+ * @regs: Pointer to register list
+ */
+struct imx492_reg_list {
+	u32 num_of_regs;
+	const struct imx492_reg *regs;
+};
+
+/**
+ * struct imx492_mode - imx492 sensor mode structure
+ * @width: Frame width
+ * @height: Frame height
+ * @code: Format code
+ * @hblank: Horizontal blanking in lines
+ * @vblank: Vertical blanking in lines
+ * @vblank_min: Minimum vertical blanking in lines
+ * @vblank_max: Maximum vertical blanking in lines
+ * @pclk: Sensor pixel clock
+ * @link_freq_idx: Link frequency index
+ * @reg_list: Register list for sensor mode
+ */
+struct imx492_mode {
+	u32 width;
+	u32 height;
+	u32 code;
+	u32 hblank;
+	u32 hblank_min;
+	u32 hblank_max;
+	u32 vblank;
+	u32 vblank_min;
+	u32 vblank_max;
+	u64 pclk;
+	u32 link_freq_idx;
+	struct imx492_reg_list reg_list;
+};
+
+/**
+ * struct imx492 - imx492 sensor device structure
+ * @dev: Pointer to generic device
+ * @client: Pointer to i2c client
+ * @sd: V4L2 sub-device
+ * @pad: Media pad. Only one pad supported
+ * @reset_gpio: Sensor reset gpio
+ * @reset_gpio: Sensor power gpio
+ * @inclk: Sensor input clock
+ * @supplies: Regulator supplies
+ * @ctrl_handler: V4L2 control handler
+ * @link_freq_ctrl: Pointer to link frequency control
+ * @pclk_ctrl: Pointer to pixel clock control
+ * @hblank_ctrl: Pointer to horizontal blanking control
+ * @vblank_ctrl: Pointer to vertical blanking control
+ * @exp_ctrl: Pointer to exposure control
+ * @again_ctrl: Pointer to analog gain control
+ * @vblank: Vertical blanking in lines
+ * @cur_mode: Pointer to current selected sensor mode
+ * @mutex: Mutex for serializing sensor controls
+ * @streaming: Flag indicating streaming state
+ */
+struct imx492 {
+	struct device *dev;
+	struct i2c_client *client;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct v4l2_captureparm scap;
+	struct gpio_desc *reset_gpio;
+	struct gpio_desc *power_gpio;
+	struct gpio_desc *oscen_gpio;
+	struct clk *inclk;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *link_freq_ctrl;
+	struct v4l2_ctrl *pclk_ctrl;
+	struct v4l2_ctrl *hblank_ctrl;
+	struct v4l2_ctrl *vblank_ctrl;
+	struct v4l2_ctrl *exp_ctrl;
+	struct v4l2_ctrl *again_ctrl;
+	const struct imx492_mode *cur_mode;
+	struct mutex mutex;
+	u32 tpatt;
+	u32 vblank;
+	bool streaming;
+};
+
+static const s64 link_freq[] = {
+	IMX492_LINK_FREQ,
+};
+
+
+/* Supported sensor mode configurations */
+static const struct imx492_mode supported_modes[] = {
+	{
+		.width = 8192,
+		.height = 4320,
+		.hblank = 1108,
+		.hblank_min = 1102,
+		.hblank_max = 32768,
+		.vblank = 5728,
+		.vblank_min = 4428,
+		.vblank_max = 32768,
+		.pclk = 745000000,
+		.link_freq_idx = 0,
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_17to9_regs),
+			.regs = mode_17to9_regs,
+		},
+	}, {
+		.width = 8192,
+		.height = 5556,
+		.hblank = 1108,
+		.hblank_min = 1102,
+		.hblank_max = 32768,
+		.vblank = 5728,
+		.vblank_min = 4428,
+		.vblank_max = 32768,
+		.pclk = 745000000,
+		.link_freq_idx = 0,
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_all_regs),
+			.regs = mode_all_regs,
+		},
+	},
+};
+
+static const char * const imx492_test_pattern_menu[] = {
+	"Disabled",
+	"Solid black",
+	"Solid white",
+	"Solid dark grey",
+	"Solid light gray",
+	"None",
+	"None",
+	"None",
+	"None",
+	"None",
+	"None",
+	"Vertical color bars",
+	"Horizontal color bars",
+};
+
+/**
+ * to_imx492() - imx492 V4L2 sub-device to imx492 device.
+ * @subdev: pointer to imx492 V4L2 sub-device
+ *
+ * Return: pointer to imx492 device
+ */
+static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct imx492, sd);
+}
+
+/**
+ * imx492_read_reg() - Read registers.
+ * @imx492: pointer to imx492 device
+ * @reg: register address
+ * @len: length of bytes to read. Max supported bytes is 4
+ * @val: pointer to register value to be filled.
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
+	struct i2c_msg msgs[2] = {0};
+	u8 addr_buf[2] = {0};
+	u8 data_buf[4] = {0};
+	int ret;
+
+	if (WARN_ON(len > 4))
+		return -EINVAL;
+
+	put_unaligned_be16(reg, addr_buf);
+
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = ARRAY_SIZE(addr_buf);
+	msgs[0].buf = addr_buf;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_buf[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = get_unaligned_be32(data_buf);
+
+	return 0;
+}
+
+/**
+ * imx492_write_reg() - Write register
+ * @imx492: pointer to imx492 device
+ * @reg: register address
+ * @len: length of bytes. Max supported bytes is 4
+ * @val: register value
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
+	u8 buf[6] = {0};
+
+	if (WARN_ON(len > 4))
+		return -EINVAL;
+
+	put_unaligned_be16(reg, buf);
+	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+/**
+ * imx492_write_regs() - Write a list of registers
+ * @imx492: pointer to imx492 device
+ * @regs: list of registers to be written
+ * @len: length of registers array
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_write_regs(struct imx492 *imx492,
+			     const struct imx492_reg *regs, u32 len)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < len; i++) {
+		ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
+{
+	/* for now this is the only format we support */
+	return MEDIA_BUS_FMT_SGBRG12_1X12;
+}
+
+/**
+ * imx492_update_controls() - Update control ranges based on streaming mode
+ * @imx492: pointer to imx492 device
+ * @mode: pointer to imx492_mode sensor mode
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_update_controls(struct imx492 *imx492,
+				  const struct imx492_mode *mode)
+{
+	int ret;
+
+	ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
+	if (ret)
+		return ret;
+
+	ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
+	if (ret)
+		return ret;
+
+	return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
+					mode->vblank_max, 1, mode->vblank);
+}
+
+/**
+ * imx492_update_exp_gain() - Set updated exposure and gain
+ * @imx492: pointer to imx492 device
+ * @exposure: updated exposure value
+ * @gain: updated analog gain value
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
+{
+	u32 lpfr, shutter;
+	int ret;
+
+	lpfr = imx492->vblank + imx492->cur_mode->height;
+	shutter = lpfr - exposure;
+
+	ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
+	if (ret)
+		return ret;
+
+	ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
+
+	return ret;
+}
+
+/**
+ * imx492_set_ctrl() - Set subdevice control
+ * @ctrl: pointer to v4l2_ctrl structure
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct imx492 *imx492 =
+		container_of(ctrl->handler, struct imx492, ctrl_handler);
+	u32 analog_gain;
+	u32 exposure;
+	int ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		imx492->vblank = imx492->vblank_ctrl->val;
+
+		ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
+					       IMX492_EXPOSURE_MIN,
+					       imx492->vblank +
+					       imx492->cur_mode->height -
+					       IMX492_EXPOSURE_OFFSET,
+					       1, IMX492_EXPOSURE_DEFAULT);
+		break;
+	case V4L2_CID_EXPOSURE:
+		/* Set controls only if sensor is in power on state */
+		if (!pm_runtime_get_if_in_use(imx492->dev))
+			return 0;
+		exposure = ctrl->val;
+		analog_gain = imx492->again_ctrl->val;
+		ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
+		pm_runtime_put(imx492->dev);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		if (ctrl->val) {
+			imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
+			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
+		} else {
+			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
+		}
+		ret = 0;
+		break;
+	default:
+		dev_err(imx492->dev, "Invalid control %d", ctrl->id);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/* V4l2 subdevice control ops*/
+static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
+	.s_ctrl = imx492_set_ctrl,
+};
+
+/**
+ * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
+ * @sd: pointer to imx492 V4L2 sub-device structure
+ * @sd_state: V4L2 sub-device configuration
+ * @code: V4L2 sub-device code enumeration need to be filled
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_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(supported_modes))
+		return -EINVAL;
+
+	code->code = supported_modes[code->index].code;
+
+	return 0;
+}
+
+/**
+ * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
+ * @sd: pointer to imx492 V4L2 sub-device structure
+ * @sd_state: V4L2 sub-device configuration
+ * @fsize: V4L2 sub-device size enumeration need to be filled
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fsize)
+{
+	if (fsize->index > ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fsize->code != supported_modes[fsize->index].code)
+		return -EINVAL;
+
+	fsize->max_width = supported_modes[fsize->index].width;
+	fsize->min_width = fsize->max_width;
+	fsize->max_height = supported_modes[fsize->index].height;
+	fsize->min_height = fsize->max_height;
+
+	return 0;
+}
+
+/**
+n * imx492_fill_pad_format() - Fill subdevice pad format
+ *                            from selected sensor mode
+ * @imx492: pointer to imx492 device
+ * @mode: pointer to imx492_mode sensor mode
+ * @fmt: V4L2 sub-device format need to be filled
+ */
+static void imx492_fill_pad_format(struct imx492 *imx492,
+				   const struct imx492_mode *mode,
+				   struct v4l2_subdev_format *fmt)
+{
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.code = mode->code;
+	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;
+}
+
+/**
+ * imx492_get_pad_format() - Get subdevice pad format
+ * @sd: pointer to imx492 V4L2 sub-device structure
+ * @sd_state: V4L2 sub-device configuration
+ * @fmt: V4L2 sub-device format need to be set
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_get_pad_format(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_format *fmt)
+{
+	struct imx492 *imx492 = to_imx492(sd);
+
+	mutex_lock(&imx492->mutex);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		struct v4l2_mbus_framefmt *framefmt;
+
+		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
+		fmt->format = *framefmt;
+	} else {
+		imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
+	}
+
+	mutex_unlock(&imx492->mutex);
+
+	return 0;
+}
+
+/**
+ * imx492_set_pad_format() - Set subdevice pad format
+ * @sd: pointer to imx492 V4L2 sub-device structure
+ * @sd_state: V4L2 sub-device configuration
+ * @fmt: V4L2 sub-device format need to be set
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_set_pad_format(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_format *fmt)
+{
+	struct imx492 *imx492 = to_imx492(sd);
+	const struct imx492_mode *mode;
+	int ret = 0;
+
+	mutex_lock(&imx492->mutex);
+
+	fmt->format.code = imx492_get_format_code(imx492, 0);
+	mode = v4l2_find_nearest_size(supported_modes,
+					ARRAY_SIZE(supported_modes),
+					width, height,
+					fmt->format.width, fmt->format.height);
+	imx492_fill_pad_format(imx492, mode, fmt);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		struct v4l2_mbus_framefmt *framefmt;
+
+		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
+		*framefmt = fmt->format;
+	} else {
+		ret = imx492_update_controls(imx492, mode);
+		if (!ret)
+			imx492->cur_mode = mode;
+	}
+
+	mutex_unlock(&imx492->mutex);
+
+	return ret;
+}
+
+/**
+ * imx492_init_pad_cfg() - Initialize sub-device pad configuration
+ * @sd: pointer to imx492 V4L2 sub-device structure
+ * @sd_state: V4L2 sub-device configuration
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *sd_state)
+{
+	struct imx492 *imx492 = to_imx492(sd);
+	struct v4l2_subdev_format fmt = { 0 };
+
+	fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
+	imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
+
+	return imx492_set_pad_format(sd, sd_state, &fmt);
+}
+
+/**
+ * imx492_start_streaming() - Start sensor stream
+ * @imx492: pointer to imx492 device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_start_streaming(struct imx492 *imx492)
+{
+	const struct imx492_reg_list *reg_list;
+	int ret;
+
+	/* Write sensor mode registers */
+	reg_list = &imx492->cur_mode->reg_list;
+	ret = imx492_write_regs(imx492, reg_list->regs,
+				reg_list->num_of_regs);
+	if (ret) {
+		dev_err(imx492->dev, "fail to write initial registers");
+		return ret;
+	}
+
+	/* Setup handler will write actual exposure and gain */
+	ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
+	if (ret) {
+		dev_err(imx492->dev, "fail to setup handler");
+		return ret;
+	}
+
+	/* 1st stabilization period */
+	usleep_range(10000, 11000);
+	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
+	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
+	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
+	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
+
+	/* 2nd stabilization period */
+	usleep_range(7000, 8000);
+
+	/* Start streaming */
+	ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
+
+	if (ret) {
+		dev_err(imx492->dev, "fail to start streaming");
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * imx492_stop_streaming() - Stop sensor stream
+ * @imx492: pointer to imx492 device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static void imx492_stop_streaming(struct imx492 *imx492)
+{
+	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
+	imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
+}
+
+/**
+ * imx492_set_stream() - Enable sensor streaming
+ * @sd: pointer to imx492 subdevice
+ * @enable: set to enable sensor streaming
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct imx492 *imx492 = to_imx492(sd);
+	int ret;
+
+	mutex_lock(&imx492->mutex);
+
+	if (imx492->streaming == enable) {
+		mutex_unlock(&imx492->mutex);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_resume_and_get(imx492->dev);
+		if (ret)
+			goto error_unlock;
+		ret = imx492_start_streaming(imx492);
+		if (ret)
+			goto error_power_off;
+	} else {
+		imx492_stop_streaming(imx492);
+		pm_runtime_put(imx492->dev);
+	}
+
+	imx492->streaming = enable;
+
+	mutex_unlock(&imx492->mutex);
+
+	return 0;
+
+error_power_off:
+	pm_runtime_put(imx492->dev);
+error_unlock:
+	mutex_unlock(&imx492->mutex);
+
+	return ret;
+}
+
+/**
+ * imx492_detect() - Detect imx492 sensor
+ * @imx492: pointer to imx492 device
+ *
+ * Return: 0 if successful, -EIO if sensor id does not match
+ */
+static int imx492_detect(struct imx492 *imx492)
+{
+	int ret;
+	u32 val;
+
+	ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);
+	if (ret)
+		return ret;
+
+	if (val != IMX492_ID) {
+		dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+/**
+ * imx492_parse_hw_config() - Parse HW configuration and check if supported
+ * @imx492: pointer to imx492 device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_parse_hw_config(struct imx492 *imx492)
+{
+	struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY
+	};
+	struct fwnode_handle *ep;
+	unsigned int i;
+	int ret;
+
+	if (!fwnode)
+		return -ENXIO;
+
+	imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
+	if (IS_ERR(imx492->power_gpio)) {
+		dev_err(imx492->dev, "failed to get power gpio %ld",
+			PTR_ERR(imx492->power_gpio));
+		return PTR_ERR(imx492->power_gpio);
+	}
+
+	imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
+	if (IS_ERR(imx492->oscen_gpio)) {
+		dev_err(imx492->dev, "failed to get oscen gpio %ld",
+			PTR_ERR(imx492->oscen_gpio));
+		return PTR_ERR(imx492->oscen_gpio);
+	}
+
+	imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(imx492->reset_gpio)) {
+		dev_err(imx492->dev, "failed to get reset gpio %ld",
+			PTR_ERR(imx492->reset_gpio));
+		return PTR_ERR(imx492->reset_gpio);
+	}
+
+	if (gpiod_direction_output(imx492->power_gpio, 1) ||
+	    gpiod_direction_output(imx492->oscen_gpio, 1) ||
+	    gpiod_direction_output(imx492->reset_gpio, 0)) {
+		dev_err(imx492->dev, "failed to change gpio direction");
+		return -EINVAL;
+	}
+
+	/* Get sensor input clock */
+	imx492->inclk = devm_clk_get(imx492->dev, NULL);
+	if (IS_ERR(imx492->inclk)) {
+		dev_err(imx492->dev, "could not get inclk");
+		return PTR_ERR(imx492->inclk);
+	}
+
+	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+	if (!ep) {
+		dev_err(imx492->dev, "next endpoint?");
+		return -ENXIO;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+	fwnode_handle_put(ep);
+	if (ret) {
+		dev_err(imx492->dev, "endpoint alloc parse");
+		return ret;
+	}
+
+	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
+		dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
+			bus_cfg.bus.mipi_csi2.num_data_lanes);
+		ret = -EINVAL;
+		goto done_endpoint_free;
+	}
+
+	if (!bus_cfg.nr_of_link_frequencies) {
+		dev_err(imx492->dev, "no link frequencies defined");
+		ret = -EINVAL;
+		goto done_endpoint_free;
+	}
+
+	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
+		if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
+			goto done_endpoint_free;
+	}
+
+	ret = -EINVAL;
+
+done_endpoint_free:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+
+	return ret;
+}
+
+/* V4l2 subdevice ops */
+static const struct v4l2_subdev_video_ops imx492_video_ops = {
+	.s_stream = imx492_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
+	.init_cfg = imx492_init_pad_cfg,
+	.enum_mbus_code = imx492_enum_mbus_code,
+	.enum_frame_size = imx492_enum_frame_size,
+	.get_fmt = imx492_get_pad_format,
+	.set_fmt = imx492_set_pad_format,
+};
+
+static const struct v4l2_subdev_ops imx492_subdev_ops = {
+	.video = &imx492_video_ops,
+	.pad = &imx492_pad_ops,
+};
+
+/**
+ * imx492_power_on() - Sensor power on sequence
+ * @dev: pointer to i2c device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_power_on(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct imx492 *imx492 = to_imx492(sd);
+
+	gpiod_set_value_cansleep(imx492->power_gpio, 1);
+	msleep(1);
+	gpiod_set_value_cansleep(imx492->reset_gpio, 1);
+	msleep(1);
+	gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
+	msleep(1);
+
+	return 0;
+}
+
+/**
+ * imx492_power_off() - Sensor power off sequence
+ * @dev: pointer to i2c device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_power_off(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct imx492 *imx492 = to_imx492(sd);
+
+	gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
+	gpiod_set_value_cansleep(imx492->reset_gpio, 0);
+	gpiod_set_value_cansleep(imx492->power_gpio, 0);
+
+	return 0;
+}
+
+/**
+ * imx492_init_controls() - Initialize sensor subdevice controls
+ * @imx492: pointer to imx492 device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_init_controls(struct imx492 *imx492)
+{
+	struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
+	const struct imx492_mode *mode = imx492->cur_mode;
+	u32 lpfr;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
+	if (ret)
+		return ret;
+
+	/* Serialize controls with sensor device */
+	ctrl_hdlr->lock = &imx492->mutex;
+	/* Initialize exposure and gain */
+	lpfr = mode->vblank + mode->height;
+	imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
+					     &imx492_ctrl_ops,
+					     V4L2_CID_EXPOSURE,
+					     IMX492_EXPOSURE_MIN,
+					     lpfr - IMX492_EXPOSURE_OFFSET,
+					     IMX492_EXPOSURE_STEP,
+					     IMX492_EXPOSURE_DEFAULT);
+
+	imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
+					       &imx492_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN,
+					       IMX492_AGAIN_MIN,
+					       IMX492_AGAIN_MAX,
+					       IMX492_AGAIN_STEP,
+					       IMX492_AGAIN_DEFAULT);
+
+	v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
+
+	imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
+						&imx492_ctrl_ops,
+						V4L2_CID_VBLANK,
+						mode->vblank_min,
+						mode->vblank_max,
+						1, mode->vblank);
+	/* Read only controls */
+	imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
+						&imx492_ctrl_ops,
+						V4L2_CID_HBLANK,
+						mode->hblank_min,
+						mode->hblank_max,
+						1, mode->hblank);
+	if (imx492->hblank_ctrl)
+		imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
+					      &imx492_ctrl_ops,
+					      V4L2_CID_PIXEL_RATE,
+					      mode->pclk, mode->pclk,
+					      1, mode->pclk);
+
+	imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
+							&imx492_ctrl_ops,
+							V4L2_CID_LINK_FREQ,
+							ARRAY_SIZE(link_freq) -
+							1,
+							mode->link_freq_idx,
+							link_freq);
+	if (imx492->link_freq_ctrl)
+		imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(imx492_test_pattern_menu) - 1,
+				     0, 0, imx492_test_pattern_menu);
+
+	if (ctrl_hdlr->error) {
+		dev_err(imx492->dev, "control init failed: %d",	ctrl_hdlr->error);
+		v4l2_ctrl_handler_free(ctrl_hdlr);
+		return ctrl_hdlr->error;
+	}
+
+	imx492->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+}
+
+/**
+ * imx492_probe() - I2C client device binding
+ * @client: pointer to i2c client device
+ *
+ * Return: 0 if successful, error code otherwise.
+ */
+static int imx492_probe(struct i2c_client *client)
+{
+	struct imx492 *imx492;
+	int ret;
+
+	imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
+	if (!imx492)
+		return -ENOMEM;
+
+	imx492->dev = &client->dev;
+
+	/* Initialize subdev */
+	v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
+
+	ret = imx492_parse_hw_config(imx492);
+	if (ret) {
+		dev_err(imx492->dev, "HW configuration is not supported");
+		return ret;
+	}
+
+	mutex_init(&imx492->mutex);
+
+	ret = imx492_power_on(imx492->dev);
+	if (ret) {
+		dev_err(imx492->dev, "failed to power-on the sensor");
+		goto error_mutex_destroy;
+	}
+
+	/* Check module identity */
+	ret = imx492_detect(imx492);
+	if (ret) {
+		dev_err(imx492->dev, "failed to find sensor: %d", ret);
+		goto error_power_off;
+	}
+
+	/* Set default mode to max resolution */
+	imx492->cur_mode = &supported_modes[0];
+	imx492->vblank = imx492->cur_mode->vblank;
+
+	ret = imx492_init_controls(imx492);
+	if (ret) {
+		dev_err(imx492->dev, "failed to init controls: %d", ret);
+		goto error_power_off;
+	}
+
+	/* Initialize subdev */
+	imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+	imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
+	imx492->scap.capturemode = 0;
+	imx492->scap.timeperframe.denominator = DEFAULT_FPS;
+	imx492->scap.timeperframe.numerator = 1;
+
+	/* Initialize source pad */
+	imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
+	if (ret) {
+		dev_err(imx492->dev, "failed to init entity pads: %d", ret);
+		goto error_handler_free;
+	}
+
+	ret = v4l2_async_register_subdev(&imx492->sd);
+	if (ret < 0) {
+		dev_err(imx492->dev, "failed to register async subdev: %d", ret);
+		goto error_media_entity;
+	}
+
+	pm_runtime_set_active(imx492->dev);
+	pm_runtime_enable(imx492->dev);
+	pm_runtime_idle(imx492->dev);
+
+	return 0;
+
+error_media_entity:
+	media_entity_cleanup(&imx492->sd.entity);
+error_handler_free:
+	v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
+error_power_off:
+	imx492_power_off(imx492->dev);
+error_mutex_destroy:
+	mutex_destroy(&imx492->mutex);
+
+	return ret;
+}
+
+/**
+ * imx492_remove() - I2C client device unbinding
+ * @client: pointer to I2C client device
+ */
+static void imx492_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx492 *imx492 = to_imx492(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_ctrl_handler_free(sd->ctrl_handler);
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		imx492_power_off(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	mutex_destroy(&imx492->mutex);
+}
+
+static const struct dev_pm_ops imx492_pm_ops = {
+	SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
+};
+
+static const struct of_device_id imx492_of_match[] = {
+	{ .compatible = "sony,imx492_mipi" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, imx492_of_match);
+
+static struct i2c_driver imx492_driver = {
+	.probe_new = imx492_probe,
+	.remove = imx492_remove,
+	.driver = {
+		.name = "imx492",
+		.pm = &imx492_pm_ops,
+		.of_match_table = imx492_of_match,
+	},
+};
+
+module_i2c_driver(imx492_driver);
+
+MODULE_DESCRIPTION("Sony imx492 sensor driver");
+MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
+MODULE_LICENSE("GPL");
-- 
2.30.2


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

* [PATCH v1 4/5] media: i2c: add imx492 config entry
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
                   ` (2 preceding siblings ...)
  2022-11-25 15:31 ` [PATCH v1 3/5] media: i2c: imx492: driver's source Petko Manolov
@ 2022-11-25 15:31 ` Petko Manolov
  2022-11-25 15:31 ` [PATCH v1 5/5] media: i2c: add imx492 entry for make Petko Manolov
  2022-11-28 12:45 ` [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Kieran Bingham
  5 siblings, 0 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Adds the Kconfig entry right after it's sibling.

Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
---
 drivers/media/i2c/Kconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 49c1c27afdc1..db69725d2f9a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -228,6 +228,20 @@ config VIDEO_IMX412
 	  To compile this driver as a module, choose M here: the
 	  module will be called imx412.
 
+config VIDEO_IMX492
+	tristate "Sony IMX492 sensor support"
+	depends on OF_GPIO
+	depends on I2C && VIDEO_DEV
+	select VIDEO_V4L2_SUBDEV_API
+	select MEDIA_CONTROLLER
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the Sony
+	  IMX492 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called imx492.
+
 config VIDEO_MAX9271_LIB
 	tristate
 
-- 
2.30.2


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

* [PATCH v1 5/5] media: i2c: add imx492 entry for make
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
                   ` (3 preceding siblings ...)
  2022-11-25 15:31 ` [PATCH v1 4/5] media: i2c: add imx492 config entry Petko Manolov
@ 2022-11-25 15:31 ` Petko Manolov
  2022-11-25 19:48   ` kernel test robot
  2022-11-28 12:45 ` [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Kieran Bingham
  5 siblings, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-25 15:31 UTC (permalink / raw)
  To: linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Make sure the driver gets compiled in case it is selected in Kconfig.

Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
---
 drivers/media/i2c/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index ba28a8f8a07f..8cdad7e25e5e 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_IMX334) += imx334.o
 obj-$(CONFIG_VIDEO_IMX335) += imx335.o
 obj-$(CONFIG_VIDEO_IMX355) += imx355.o
 obj-$(CONFIG_VIDEO_IMX412) += imx412.o
+obj-$(CONFIG_VIDEO_IMX492) += imx492.o
 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
-- 
2.30.2


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

* Re: [PATCH v1 5/5] media: i2c: add imx492 entry for make
  2022-11-25 15:31 ` [PATCH v1 5/5] media: i2c: add imx492 entry for make Petko Manolov
@ 2022-11-25 19:48   ` kernel test robot
  0 siblings, 0 replies; 28+ messages in thread
From: kernel test robot @ 2022-11-25 19:48 UTC (permalink / raw)
  To: Petko Manolov, linux-media
  Cc: oe-kbuild-all, laurent.pinchart, sakari.ailus, Petko Manolov

[-- Attachment #1: Type: text/plain, Size: 14349 bytes --]

Hi Petko,

I love your patch! Perhaps something to improve:

[auto build test WARNING on media-tree/master]
[also build test WARNING on sailus-media-tree/streams linus/master v6.1-rc6 next-20221125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Petko-Manolov/Adds-media-driver-for-Sony-IMX492-sensor/20221125-233206
base:   git://linuxtv.org/media_tree.git master
patch link:    https://lore.kernel.org/r/20221125153120.541298-6-petko.manolov%40konsulko.com
patch subject: [PATCH v1 5/5] media: i2c: add imx492 entry for make
config: sh-allmodconfig
compiler: sh4-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/18ef413f6501ce8e80e9b8d4b141a32eb5efb610
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Petko-Manolov/Adds-media-driver-for-Sony-IMX492-sensor/20221125-233206
        git checkout 18ef413f6501ce8e80e9b8d4b141a32eb5efb610
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sh SHELL=/bin/bash drivers/media/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/media/i2c/imx492.c: In function 'imx492_update_exp_gain':
>> drivers/media/i2c/imx492.c:363:19: warning: variable 'shutter' set but not used [-Wunused-but-set-variable]
     363 |         u32 lpfr, shutter;
         |                   ^~~~~~~
--
   drivers/media/i2c/imx492.c:115: warning: Function parameter or member 'hblank_min' not described in 'imx492_mode'
   drivers/media/i2c/imx492.c:115: warning: Function parameter or member 'hblank_max' not described in 'imx492_mode'
   drivers/media/i2c/imx492.c:161: warning: Function parameter or member 'scap' not described in 'imx492'
   drivers/media/i2c/imx492.c:161: warning: Function parameter or member 'power_gpio' not described in 'imx492'
   drivers/media/i2c/imx492.c:161: warning: Function parameter or member 'oscen_gpio' not described in 'imx492'
   drivers/media/i2c/imx492.c:161: warning: Function parameter or member 'tpatt' not described in 'imx492'
>> drivers/media/i2c/imx492.c:481: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
   n * imx492_fill_pad_format() - Fill subdevice pad format

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for COMMON_CLK
   Depends on [n]: !HAVE_LEGACY_CLK [=y]
   Selected by [m]:
   - VIDEO_TC358746 [=m] && MEDIA_SUPPORT [=m] && VIDEO_DEV [=m] && PM [=y] && I2C [=m]


vim +/shutter +363 drivers/media/i2c/imx492.c

4da35cf18851012 Petko Manolov 2022-11-25  352  
4da35cf18851012 Petko Manolov 2022-11-25  353  /**
4da35cf18851012 Petko Manolov 2022-11-25  354   * imx492_update_exp_gain() - Set updated exposure and gain
4da35cf18851012 Petko Manolov 2022-11-25  355   * @imx492: pointer to imx492 device
4da35cf18851012 Petko Manolov 2022-11-25  356   * @exposure: updated exposure value
4da35cf18851012 Petko Manolov 2022-11-25  357   * @gain: updated analog gain value
4da35cf18851012 Petko Manolov 2022-11-25  358   *
4da35cf18851012 Petko Manolov 2022-11-25  359   * Return: 0 if successful, error code otherwise.
4da35cf18851012 Petko Manolov 2022-11-25  360   */
4da35cf18851012 Petko Manolov 2022-11-25  361  static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
4da35cf18851012 Petko Manolov 2022-11-25  362  {
4da35cf18851012 Petko Manolov 2022-11-25 @363  	u32 lpfr, shutter;
4da35cf18851012 Petko Manolov 2022-11-25  364  	int ret;
4da35cf18851012 Petko Manolov 2022-11-25  365  
4da35cf18851012 Petko Manolov 2022-11-25  366  	lpfr = imx492->vblank + imx492->cur_mode->height;
4da35cf18851012 Petko Manolov 2022-11-25  367  	shutter = lpfr - exposure;
4da35cf18851012 Petko Manolov 2022-11-25  368  
4da35cf18851012 Petko Manolov 2022-11-25  369  	ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
4da35cf18851012 Petko Manolov 2022-11-25  370  	if (ret)
4da35cf18851012 Petko Manolov 2022-11-25  371  		return ret;
4da35cf18851012 Petko Manolov 2022-11-25  372  
4da35cf18851012 Petko Manolov 2022-11-25  373  	ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
4da35cf18851012 Petko Manolov 2022-11-25  374  
4da35cf18851012 Petko Manolov 2022-11-25  375  	return ret;
4da35cf18851012 Petko Manolov 2022-11-25  376  }
4da35cf18851012 Petko Manolov 2022-11-25  377  
4da35cf18851012 Petko Manolov 2022-11-25  378  /**
4da35cf18851012 Petko Manolov 2022-11-25  379   * imx492_set_ctrl() - Set subdevice control
4da35cf18851012 Petko Manolov 2022-11-25  380   * @ctrl: pointer to v4l2_ctrl structure
4da35cf18851012 Petko Manolov 2022-11-25  381   *
4da35cf18851012 Petko Manolov 2022-11-25  382   * Return: 0 if successful, error code otherwise.
4da35cf18851012 Petko Manolov 2022-11-25  383   */
4da35cf18851012 Petko Manolov 2022-11-25  384  static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
4da35cf18851012 Petko Manolov 2022-11-25  385  {
4da35cf18851012 Petko Manolov 2022-11-25  386  	struct imx492 *imx492 =
4da35cf18851012 Petko Manolov 2022-11-25  387  		container_of(ctrl->handler, struct imx492, ctrl_handler);
4da35cf18851012 Petko Manolov 2022-11-25  388  	u32 analog_gain;
4da35cf18851012 Petko Manolov 2022-11-25  389  	u32 exposure;
4da35cf18851012 Petko Manolov 2022-11-25  390  	int ret;
4da35cf18851012 Petko Manolov 2022-11-25  391  
4da35cf18851012 Petko Manolov 2022-11-25  392  	switch (ctrl->id) {
4da35cf18851012 Petko Manolov 2022-11-25  393  	case V4L2_CID_VBLANK:
4da35cf18851012 Petko Manolov 2022-11-25  394  		imx492->vblank = imx492->vblank_ctrl->val;
4da35cf18851012 Petko Manolov 2022-11-25  395  
4da35cf18851012 Petko Manolov 2022-11-25  396  		ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
4da35cf18851012 Petko Manolov 2022-11-25  397  					       IMX492_EXPOSURE_MIN,
4da35cf18851012 Petko Manolov 2022-11-25  398  					       imx492->vblank +
4da35cf18851012 Petko Manolov 2022-11-25  399  					       imx492->cur_mode->height -
4da35cf18851012 Petko Manolov 2022-11-25  400  					       IMX492_EXPOSURE_OFFSET,
4da35cf18851012 Petko Manolov 2022-11-25  401  					       1, IMX492_EXPOSURE_DEFAULT);
4da35cf18851012 Petko Manolov 2022-11-25  402  		break;
4da35cf18851012 Petko Manolov 2022-11-25  403  	case V4L2_CID_EXPOSURE:
4da35cf18851012 Petko Manolov 2022-11-25  404  		/* Set controls only if sensor is in power on state */
4da35cf18851012 Petko Manolov 2022-11-25  405  		if (!pm_runtime_get_if_in_use(imx492->dev))
4da35cf18851012 Petko Manolov 2022-11-25  406  			return 0;
4da35cf18851012 Petko Manolov 2022-11-25  407  		exposure = ctrl->val;
4da35cf18851012 Petko Manolov 2022-11-25  408  		analog_gain = imx492->again_ctrl->val;
4da35cf18851012 Petko Manolov 2022-11-25  409  		ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
4da35cf18851012 Petko Manolov 2022-11-25  410  		pm_runtime_put(imx492->dev);
4da35cf18851012 Petko Manolov 2022-11-25  411  		break;
4da35cf18851012 Petko Manolov 2022-11-25  412  	case V4L2_CID_TEST_PATTERN:
4da35cf18851012 Petko Manolov 2022-11-25  413  		if (ctrl->val) {
4da35cf18851012 Petko Manolov 2022-11-25  414  			imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
4da35cf18851012 Petko Manolov 2022-11-25  415  			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
4da35cf18851012 Petko Manolov 2022-11-25  416  		} else {
4da35cf18851012 Petko Manolov 2022-11-25  417  			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
4da35cf18851012 Petko Manolov 2022-11-25  418  		}
4da35cf18851012 Petko Manolov 2022-11-25  419  		ret = 0;
4da35cf18851012 Petko Manolov 2022-11-25  420  		break;
4da35cf18851012 Petko Manolov 2022-11-25  421  	default:
4da35cf18851012 Petko Manolov 2022-11-25  422  		dev_err(imx492->dev, "Invalid control %d", ctrl->id);
4da35cf18851012 Petko Manolov 2022-11-25  423  		ret = -EINVAL;
4da35cf18851012 Petko Manolov 2022-11-25  424  	}
4da35cf18851012 Petko Manolov 2022-11-25  425  
4da35cf18851012 Petko Manolov 2022-11-25  426  	return ret;
4da35cf18851012 Petko Manolov 2022-11-25  427  }
4da35cf18851012 Petko Manolov 2022-11-25  428  
4da35cf18851012 Petko Manolov 2022-11-25  429  /* V4l2 subdevice control ops*/
4da35cf18851012 Petko Manolov 2022-11-25  430  static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
4da35cf18851012 Petko Manolov 2022-11-25  431  	.s_ctrl = imx492_set_ctrl,
4da35cf18851012 Petko Manolov 2022-11-25  432  };
4da35cf18851012 Petko Manolov 2022-11-25  433  
4da35cf18851012 Petko Manolov 2022-11-25  434  /**
4da35cf18851012 Petko Manolov 2022-11-25  435   * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
4da35cf18851012 Petko Manolov 2022-11-25  436   * @sd: pointer to imx492 V4L2 sub-device structure
4da35cf18851012 Petko Manolov 2022-11-25  437   * @sd_state: V4L2 sub-device configuration
4da35cf18851012 Petko Manolov 2022-11-25  438   * @code: V4L2 sub-device code enumeration need to be filled
4da35cf18851012 Petko Manolov 2022-11-25  439   *
4da35cf18851012 Petko Manolov 2022-11-25  440   * Return: 0 if successful, error code otherwise.
4da35cf18851012 Petko Manolov 2022-11-25  441   */
4da35cf18851012 Petko Manolov 2022-11-25  442  static int imx492_enum_mbus_code(struct v4l2_subdev *sd,
4da35cf18851012 Petko Manolov 2022-11-25  443  				 struct v4l2_subdev_state *sd_state,
4da35cf18851012 Petko Manolov 2022-11-25  444  				 struct v4l2_subdev_mbus_code_enum *code)
4da35cf18851012 Petko Manolov 2022-11-25  445  {
4da35cf18851012 Petko Manolov 2022-11-25  446  	if (code->index > ARRAY_SIZE(supported_modes))
4da35cf18851012 Petko Manolov 2022-11-25  447  		return -EINVAL;
4da35cf18851012 Petko Manolov 2022-11-25  448  
4da35cf18851012 Petko Manolov 2022-11-25  449  	code->code = supported_modes[code->index].code;
4da35cf18851012 Petko Manolov 2022-11-25  450  
4da35cf18851012 Petko Manolov 2022-11-25  451  	return 0;
4da35cf18851012 Petko Manolov 2022-11-25  452  }
4da35cf18851012 Petko Manolov 2022-11-25  453  
4da35cf18851012 Petko Manolov 2022-11-25  454  /**
4da35cf18851012 Petko Manolov 2022-11-25  455   * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
4da35cf18851012 Petko Manolov 2022-11-25  456   * @sd: pointer to imx492 V4L2 sub-device structure
4da35cf18851012 Petko Manolov 2022-11-25  457   * @sd_state: V4L2 sub-device configuration
4da35cf18851012 Petko Manolov 2022-11-25  458   * @fsize: V4L2 sub-device size enumeration need to be filled
4da35cf18851012 Petko Manolov 2022-11-25  459   *
4da35cf18851012 Petko Manolov 2022-11-25  460   * Return: 0 if successful, error code otherwise.
4da35cf18851012 Petko Manolov 2022-11-25  461   */
4da35cf18851012 Petko Manolov 2022-11-25  462  static int imx492_enum_frame_size(struct v4l2_subdev *sd,
4da35cf18851012 Petko Manolov 2022-11-25  463  				  struct v4l2_subdev_state *sd_state,
4da35cf18851012 Petko Manolov 2022-11-25  464  				  struct v4l2_subdev_frame_size_enum *fsize)
4da35cf18851012 Petko Manolov 2022-11-25  465  {
4da35cf18851012 Petko Manolov 2022-11-25  466  	if (fsize->index > ARRAY_SIZE(supported_modes))
4da35cf18851012 Petko Manolov 2022-11-25  467  		return -EINVAL;
4da35cf18851012 Petko Manolov 2022-11-25  468  
4da35cf18851012 Petko Manolov 2022-11-25  469  	if (fsize->code != supported_modes[fsize->index].code)
4da35cf18851012 Petko Manolov 2022-11-25  470  		return -EINVAL;
4da35cf18851012 Petko Manolov 2022-11-25  471  
4da35cf18851012 Petko Manolov 2022-11-25  472  	fsize->max_width = supported_modes[fsize->index].width;
4da35cf18851012 Petko Manolov 2022-11-25  473  	fsize->min_width = fsize->max_width;
4da35cf18851012 Petko Manolov 2022-11-25  474  	fsize->max_height = supported_modes[fsize->index].height;
4da35cf18851012 Petko Manolov 2022-11-25  475  	fsize->min_height = fsize->max_height;
4da35cf18851012 Petko Manolov 2022-11-25  476  
4da35cf18851012 Petko Manolov 2022-11-25  477  	return 0;
4da35cf18851012 Petko Manolov 2022-11-25  478  }
4da35cf18851012 Petko Manolov 2022-11-25  479  
4da35cf18851012 Petko Manolov 2022-11-25  480  /**
4da35cf18851012 Petko Manolov 2022-11-25 @481  n * imx492_fill_pad_format() - Fill subdevice pad format
4da35cf18851012 Petko Manolov 2022-11-25  482   *                            from selected sensor mode
4da35cf18851012 Petko Manolov 2022-11-25  483   * @imx492: pointer to imx492 device
4da35cf18851012 Petko Manolov 2022-11-25  484   * @mode: pointer to imx492_mode sensor mode
4da35cf18851012 Petko Manolov 2022-11-25  485   * @fmt: V4L2 sub-device format need to be filled
4da35cf18851012 Petko Manolov 2022-11-25  486   */
4da35cf18851012 Petko Manolov 2022-11-25  487  static void imx492_fill_pad_format(struct imx492 *imx492,
4da35cf18851012 Petko Manolov 2022-11-25  488  				   const struct imx492_mode *mode,
4da35cf18851012 Petko Manolov 2022-11-25  489  				   struct v4l2_subdev_format *fmt)
4da35cf18851012 Petko Manolov 2022-11-25  490  {
4da35cf18851012 Petko Manolov 2022-11-25  491  	fmt->format.width = mode->width;
4da35cf18851012 Petko Manolov 2022-11-25  492  	fmt->format.height = mode->height;
4da35cf18851012 Petko Manolov 2022-11-25  493  	fmt->format.code = mode->code;
4da35cf18851012 Petko Manolov 2022-11-25  494  	fmt->format.field = V4L2_FIELD_NONE;
4da35cf18851012 Petko Manolov 2022-11-25  495  	fmt->format.colorspace = V4L2_COLORSPACE_RAW;
4da35cf18851012 Petko Manolov 2022-11-25  496  	fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
4da35cf18851012 Petko Manolov 2022-11-25  497  	fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
4da35cf18851012 Petko Manolov 2022-11-25  498  	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
4da35cf18851012 Petko Manolov 2022-11-25  499  }
4da35cf18851012 Petko Manolov 2022-11-25  500  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

[-- Attachment #2: config --]
[-- Type: text/plain, Size: 260839 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/sh 6.1.0-rc4 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="sh4-linux-gcc (GCC) 12.1.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=120100
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23800
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23800
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_WATCH_QUEUE=y
CONFIG_USELIB=y
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_INJECTION=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_SIM=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_IRQ_DEBUGFS=y
# end of IRQ subsystem

CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_TIME_KUNIT_TEST=m

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem

CONFIG_BPF=y

#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_USERMODE_DRIVER=y
# end of BPF subsystem

CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_COUNT=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=y
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
CONFIG_RCU_EXPERT=y
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_FORCE_TASKS_RCU=y
CONFIG_TASKS_RCU=y
CONFIG_FORCE_TASKS_RUDE_RCU=y
CONFIG_TASKS_RUDE_RCU=y
CONFIG_FORCE_TASKS_TRACE_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_TASKS_TRACE_RCU_READ_MB=y
# end of RCU Subsystem

CONFIG_BUILD_BIN2C=y
CONFIG_IKCONFIG=m
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=m
CONFIG_LOG_BUF_SHIFT=17
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_PRINTK_INDEX=y
CONFIG_GENERIC_SCHED_CLOCK=y

#
# Scheduler features
#
# end of Scheduler features

CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_CGROUPS=y
CONFIG_PAGE_COUNTER=y
CONFIG_CGROUP_FAVOR_DYNMODS=y
CONFIG_MEMCG=y
CONFIG_MEMCG_KMEM=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
CONFIG_CGROUP_DEBUG=y
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_RD_ZSTD=y
CONFIG_BOOT_CONFIG=y
CONFIG_BOOT_CONFIG_EMBED=y
CONFIG_BOOT_CONFIG_EMBED_FILE=""
CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_HAVE_UID16=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_KCMP=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PC104=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_DEBUG_PERF_USE_VMALLOC=y
# end of Kernel Performance Events And Counters

CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
# end of General setup

CONFIG_SUPERH=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_NO_IOPORT_MAP=y
CONFIG_PGTABLE_LEVELS=2

#
# System type
#
CONFIG_CPU_SH2=y
CONFIG_CPU_SUBTYPE_SH7619=y
# CONFIG_CPU_SUBTYPE_J2 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
# CONFIG_CPU_SUBTYPE_SH7263 is not set
# CONFIG_CPU_SUBTYPE_SH7264 is not set
# CONFIG_CPU_SUBTYPE_SH7269 is not set
# CONFIG_CPU_SUBTYPE_MXG is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
# CONFIG_CPU_SUBTYPE_SH7710 is not set
# CONFIG_CPU_SUBTYPE_SH7712 is not set
# CONFIG_CPU_SUBTYPE_SH7720 is not set
# CONFIG_CPU_SUBTYPE_SH7721 is not set
# CONFIG_CPU_SUBTYPE_SH7750 is not set
# CONFIG_CPU_SUBTYPE_SH7091 is not set
# CONFIG_CPU_SUBTYPE_SH7750R is not set
# CONFIG_CPU_SUBTYPE_SH7750S is not set
# CONFIG_CPU_SUBTYPE_SH7751 is not set
# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7734 is not set
# CONFIG_CPU_SUBTYPE_SH7757 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set

#
# Memory management options
#
CONFIG_PAGE_OFFSET=0x00000000
CONFIG_ARCH_FORCE_MAX_ORDER=14
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x04000000
CONFIG_32BIT=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
# end of Memory management options

#
# Cache configuration
#
# CONFIG_CACHE_WRITEBACK is not set
CONFIG_CACHE_WRITETHROUGH=y
# CONFIG_CACHE_OFF is not set
# end of Cache configuration

#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU_EMU=y
# end of Processor features

#
# Board support
#
CONFIG_SOLUTION_ENGINE=y
CONFIG_SH_CUSTOM_CLK=y
CONFIG_SH_7619_SOLUTION_ENGINE=y
# end of Board support

#
# Timer and clock configuration
#
CONFIG_SH_PCLK_FREQ=31250000
CONFIG_SH_CLK_CPG=y
CONFIG_SH_CLK_CPG_LEGACY=y
# end of Timer and clock configuration

#
# CPU Frequency scaling
#

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m

#
# CPU frequency scaling drivers
#
CONFIG_CPUFREQ_DT=m
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_SH_CPU_FREQ=m
CONFIG_QORIQ_CPUFREQ=m
# end of CPU Frequency scaling
# end of CPU Frequency scaling

#
# DMA support
#
# end of DMA support

#
# Companion Chips
#
# end of Companion Chips

#
# Additional SuperH Device Drivers
#
CONFIG_HEARTBEAT=y
CONFIG_PUSH_SWITCH=m
# end of Additional SuperH Device Drivers
# end of System type

#
# Kernel features
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
CONFIG_CRASH_DUMP=y
CONFIG_PHYSICAL_START=0x08000000
CONFIG_GUSA=y

#
# SuperH / SH-Mobile Driver Options
#
CONFIG_SH_INTC=y

#
# Interrupt controller options
#
CONFIG_INTC_USERIMASK=y
CONFIG_INTC_MAPPING_DEBUG=y
# end of SuperH / SH-Mobile Driver Options
# end of Kernel features

#
# Boot options
#
CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00800000
CONFIG_ENTRY_OFFSET=0x00001000
CONFIG_CMDLINE_OVERWRITE=y
# CONFIG_CMDLINE_EXTEND is not set
CONFIG_CMDLINE="console=ttySC1,115200"
# end of Boot options

#
# Bus options
#
# end of Bus options

#
# Power management options (EXPERIMENTAL)
#
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_DPM_WATCHDOG=y
CONFIG_DPM_WATCHDOG_TIMEOUT=120
CONFIG_PM_CLK=y
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_PM_GENERIC_DOMAINS_OF=y

#
# CPU Idle
#
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_GOV_TEO=y
# end of CPU Idle
# end of Power management options (EXPERIMENTAL)

#
# General architecture-dependent options
#
CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
CONFIG_SECCOMP_CACHE_DEBUG=y
CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_LTO_NONE=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_ISA_BUS_API=y
CONFIG_OLD_SIGSUSPEND=y
CONFIG_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_NO_EFFICIENT_FFS=y
CONFIG_LOCK_EVENT_COUNTS=y

#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
CONFIG_MODULE_SIG_SHA1=y
# CONFIG_MODULE_SIG_SHA224 is not set
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
# CONFIG_MODULE_SIG_SHA512 is not set
CONFIG_MODULE_SIG_HASH="sha1"
CONFIG_MODULE_COMPRESS_NONE=y
# CONFIG_MODULE_COMPRESS_GZIP is not set
# CONFIG_MODULE_COMPRESS_XZ is not set
# CONFIG_MODULE_COMPRESS_ZSTD is not set
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
CONFIG_MODPROBE_PATH="/sbin/modprobe"
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
CONFIG_BLK_RQ_ALLOC_TIME=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_ICQ=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_INTEGRITY_T10=m
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_DEV_THROTTLING_LOW=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_DEBUG_FS_ZONED=y
CONFIG_BLK_SED_OPAL=y
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_AIX_PARTITION=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_CMDLINE_PARTITION=y
# end of Partition Types

CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BLOCK_HOLDER_DEPRECATED=y
CONFIG_BLK_MQ_STACKING=y

#
# IO Schedulers
#
CONFIG_MQ_IOSCHED_DEADLINE=y
CONFIG_MQ_IOSCHED_KYBER=m
CONFIG_IOSCHED_BFQ=m
CONFIG_BFQ_GROUP_IOSCHED=y
CONFIG_BFQ_CGROUP_DEBUG=y
# end of IO Schedulers

CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_FREEZER=y

#
# Executable file formats
#
CONFIG_BINFMT_ELF_FDPIC=y
CONFIG_ELFCORE=y
CONFIG_BINFMT_SCRIPT=m
CONFIG_ARCH_HAS_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT_OLD=y
CONFIG_BINFMT_ZFLAT=y
CONFIG_BINFMT_MISC=m
CONFIG_COREDUMP=y
# end of Executable file formats

#
# Memory Management options
#

#
# SLAB allocator options
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_SLAB_MERGE_DEFAULT=y
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SLUB_STATS=y
# end of SLAB allocator options

CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
CONFIG_COMPAT_BRK=y
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_MEMORY_BALLOON=y
CONFIG_PAGE_REPORTING=y
CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
CONFIG_NEED_PER_CPU_KM=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
CONFIG_GUP_TEST=y
CONFIG_ARCH_HAS_PTE_SPECIAL=y

#
# Data Access Monitoring
#
CONFIG_DAMON=y
CONFIG_DAMON_SYSFS=y
# end of Data Access Monitoring
# end of Memory Management options

CONFIG_NET=y
CONFIG_NET_INGRESS=y
CONFIG_NET_EGRESS=y
CONFIG_NET_REDIRECT=y
CONFIG_SKB_EXTENSIONS=y

#
# Networking options
#
CONFIG_PACKET=m
CONFIG_PACKET_DIAG=m
CONFIG_UNIX=m
CONFIG_UNIX_SCM=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=m
CONFIG_TLS=m
CONFIG_TLS_DEVICE=y
CONFIG_TLS_TOE=y
CONFIG_XFRM=y
CONFIG_XFRM_OFFLOAD=y
CONFIG_XFRM_ALGO=m
CONFIG_XFRM_USER=m
CONFIG_XFRM_INTERFACE=m
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_AH=m
CONFIG_XFRM_ESP=m
CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=m
CONFIG_NET_KEY_MIGRATE=y
CONFIG_XFRM_ESPINTCP=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_ROUTE_CLASSID=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IP_TUNNEL=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE_COMMON=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=m
CONFIG_NET_UDP_TUNNEL=m
CONFIG_NET_FOU=m
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_ESP_OFFLOAD=m
CONFIG_INET_ESPINTCP=y
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_INET_UDP_DIAG=m
CONFIG_INET_RAW_DIAG=m
CONFIG_INET_DIAG_DESTROY=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=m
CONFIG_TCP_CONG_CUBIC=m
CONFIG_TCP_CONG_WESTWOOD=m
CONFIG_TCP_CONG_HTCP=m
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_VEGAS=m
CONFIG_TCP_CONG_NV=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_CONG_DCTCP=m
CONFIG_TCP_CONG_CDG=m
CONFIG_TCP_CONG_BBR=m
CONFIG_DEFAULT_RENO=y
CONFIG_DEFAULT_TCP_CONG="reno"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=m
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_ESP_OFFLOAD=m
CONFIG_INET6_ESPINTCP=y
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_MIP6=m
CONFIG_IPV6_ILA=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_GRE=m
CONFIG_IPV6_FOU=m
CONFIG_IPV6_FOU_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
CONFIG_IPV6_RPL_LWTUNNEL=y
CONFIG_IPV6_IOAM6_LWTUNNEL=y
CONFIG_NETLABEL=y
CONFIG_MPTCP=y
CONFIG_INET_MPTCP_DIAG=m
CONFIG_MPTCP_KUNIT_TEST=m
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=m

#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_EGRESS=y
CONFIG_NETFILTER_SKIP_EGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
CONFIG_NETFILTER_NETLINK_HOOK=m
CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_OSF=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_LOG_SYSLOG=m
CONFIG_NETFILTER_CONNCOUNT=m
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_LABELS=y
CONFIG_NF_CT_PROTO_DCCP=y
CONFIG_NF_CT_PROTO_GRE=y
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_NF_CT_PROTO_UDPLITE=y
CONFIG_NF_CONNTRACK_AMANDA=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_H323=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_BROADCAST=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_SNMP=m
CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NF_CT_NETLINK_HELPER=m
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_NAT=m
CONFIG_NF_NAT_AMANDA=m
CONFIG_NF_NAT_FTP=m
CONFIG_NF_NAT_IRC=m
CONFIG_NF_NAT_SIP=m
CONFIG_NF_NAT_TFTP=m
CONFIG_NF_NAT_REDIRECT=y
CONFIG_NF_NAT_MASQUERADE=y
CONFIG_NETFILTER_SYNPROXY=m
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
CONFIG_NFT_OBJREF=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_REJECT_INET=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB=m
CONFIG_NFT_FIB_INET=m
CONFIG_NFT_XFRM=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_TPROXY=m
CONFIG_NFT_SYNPROXY=m
CONFIG_NF_DUP_NETDEV=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_FWD_NETDEV=m
CONFIG_NFT_FIB_NETDEV=m
CONFIG_NFT_REJECT_NETDEV=m
CONFIG_NF_FLOW_TABLE_INET=m
CONFIG_NF_FLOW_TABLE=m
CONFIG_NF_FLOW_TABLE_PROCFS=y
CONFIG_NETFILTER_XTABLES=m

#
# Xtables combined modules
#
CONFIG_NETFILTER_XT_MARK=m
CONFIG_NETFILTER_XT_CONNMARK=m
CONFIG_NETFILTER_XT_SET=m

#
# Xtables targets
#
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_HL=m
CONFIG_NETFILTER_XT_TARGET_HMARK=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LED=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_NAT=m
CONFIG_NETFILTER_XT_TARGET_NETMAP=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
CONFIG_NETFILTER_XT_TARGET_RATEEST=m
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
CONFIG_NETFILTER_XT_TARGET_TEE=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m

#
# Xtables matches
#
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_CPU=m
CONFIG_NETFILTER_XT_MATCH_DCCP=m
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ECN=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_HL=m
CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_L2TP=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_NFACCT=m
CONFIG_NETFILTER_XT_MATCH_OSF=m
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
CONFIG_NETFILTER_XT_MATCH_SCTP=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
# end of Core Netfilter Configuration

CONFIG_IP_SET=m
CONFIG_IP_SET_MAX=256
CONFIG_IP_SET_BITMAP_IP=m
CONFIG_IP_SET_BITMAP_IPMAC=m
CONFIG_IP_SET_BITMAP_PORT=m
CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPMARK=m
CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_IPMAC=m
CONFIG_IP_SET_HASH_MAC=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12

#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y

#
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_FO=m
CONFIG_IP_VS_OVF=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_MH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_TWOS=m

#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8

#
# IPVS MH scheduler
#
CONFIG_IP_VS_MH_TAB_INDEX=12

#
# IPVS application helper
#
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=m

#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=m
CONFIG_NF_SOCKET_IPV4=m
CONFIG_NF_TPROXY_IPV4=m
CONFIG_NF_TABLES_IPV4=y
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_DUP_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_NF_REJECT_IPV4=m
CONFIG_NF_NAT_SNMP_BASIC=m
CONFIG_NF_NAT_PPTP=m
CONFIG_NF_NAT_H323=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_SYNPROXY=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
# end of IP: Netfilter Configuration

#
# IPv6: Netfilter Configuration
#
CONFIG_NF_SOCKET_IPV6=m
CONFIG_NF_TPROXY_IPV6=m
CONFIG_NF_TABLES_IPV6=y
CONFIG_NFT_REJECT_IPV6=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
CONFIG_NF_DUP_IPV6=m
CONFIG_NF_REJECT_IPV6=m
CONFIG_NF_LOG_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RPFILTER=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_SRH=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_TARGET_SYNPROXY=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
# end of IPv6: Netfilter Configuration

CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_META=m
CONFIG_NFT_BRIDGE_REJECT=m
CONFIG_NF_CONNTRACK_BRIDGE=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_BPFILTER=y
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m

#
# DCCP CCIDs Configuration
#
CONFIG_IP_DCCP_CCID2_DEBUG=y
CONFIG_IP_DCCP_CCID3=y
CONFIG_IP_DCCP_CCID3_DEBUG=y
CONFIG_IP_DCCP_TFRC_LIB=y
CONFIG_IP_DCCP_TFRC_DEBUG=y
# end of DCCP CCIDs Configuration

#
# DCCP Kernel Hacking
#
CONFIG_IP_DCCP_DEBUG=y
# end of DCCP Kernel Hacking

CONFIG_IP_SCTP=m
CONFIG_SCTP_DBG_OBJCNT=y
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_SCTP_COOKIE_HMAC_MD5=y
CONFIG_SCTP_COOKIE_HMAC_SHA1=y
CONFIG_INET_SCTP_DIAG=m
CONFIG_RDS=m
CONFIG_RDS_TCP=m
CONFIG_RDS_DEBUG=y
CONFIG_TIPC=m
CONFIG_TIPC_MEDIA_UDP=y
CONFIG_TIPC_CRYPTO=y
CONFIG_TIPC_DIAG=m
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
CONFIG_ATM_CLIP_NO_ICMP=y
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
CONFIG_ATM_BR2684_IPFILTER=y
CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=m
CONFIG_L2TP_ETH=m
CONFIG_STP=m
CONFIG_GARP=m
CONFIG_MRP=m
CONFIG_BRIDGE=m
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_NET_DSA=m
CONFIG_NET_DSA_TAG_AR9331=m
CONFIG_NET_DSA_TAG_BRCM_COMMON=m
CONFIG_NET_DSA_TAG_BRCM=m
CONFIG_NET_DSA_TAG_BRCM_LEGACY=m
CONFIG_NET_DSA_TAG_BRCM_PREPEND=m
CONFIG_NET_DSA_TAG_HELLCREEK=m
CONFIG_NET_DSA_TAG_GSWIP=m
CONFIG_NET_DSA_TAG_DSA_COMMON=m
CONFIG_NET_DSA_TAG_DSA=m
CONFIG_NET_DSA_TAG_EDSA=m
CONFIG_NET_DSA_TAG_MTK=m
CONFIG_NET_DSA_TAG_KSZ=m
CONFIG_NET_DSA_TAG_OCELOT=m
CONFIG_NET_DSA_TAG_OCELOT_8021Q=m
CONFIG_NET_DSA_TAG_QCA=m
CONFIG_NET_DSA_TAG_RTL4_A=m
CONFIG_NET_DSA_TAG_RTL8_4=m
CONFIG_NET_DSA_TAG_RZN1_A5PSW=m
CONFIG_NET_DSA_TAG_LAN9303=m
CONFIG_NET_DSA_TAG_SJA1105=m
CONFIG_NET_DSA_TAG_TRAILER=m
CONFIG_NET_DSA_TAG_XRS700X=m
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_LLC=m
CONFIG_LLC2=m
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_X25=m
CONFIG_LAPB=m
CONFIG_PHONET=m
CONFIG_6LOWPAN=m
CONFIG_6LOWPAN_DEBUGFS=y
CONFIG_6LOWPAN_NHC=m
CONFIG_6LOWPAN_NHC_DEST=m
CONFIG_6LOWPAN_NHC_FRAGMENT=m
CONFIG_6LOWPAN_NHC_HOP=m
CONFIG_6LOWPAN_NHC_IPV6=m
CONFIG_6LOWPAN_NHC_MOBILITY=m
CONFIG_6LOWPAN_NHC_ROUTING=m
CONFIG_6LOWPAN_NHC_UDP=m
CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
CONFIG_6LOWPAN_GHC_UDP=m
CONFIG_6LOWPAN_GHC_ICMPV6=m
CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_IEEE802154=m
CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y
CONFIG_IEEE802154_SOCKET=m
CONFIG_IEEE802154_6LOWPAN=m
CONFIG_MAC802154=m
CONFIG_NET_SCHED=y

#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_ATM=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFB=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_CBS=m
CONFIG_NET_SCH_ETF=m
CONFIG_NET_SCH_TAPRIO=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_SKBPRIO=m
CONFIG_NET_SCH_CHOKE=m
CONFIG_NET_SCH_QFQ=m
CONFIG_NET_SCH_CODEL=m
CONFIG_NET_SCH_FQ_CODEL=m
CONFIG_NET_SCH_CAKE=m
CONFIG_NET_SCH_FQ=m
CONFIG_NET_SCH_HHF=m
CONFIG_NET_SCH_PIE=m
CONFIG_NET_SCH_FQ_PIE=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_SCH_PLUG=m
CONFIG_NET_SCH_ETS=m
CONFIG_NET_SCH_DEFAULT=y
# CONFIG_DEFAULT_FQ is not set
# CONFIG_DEFAULT_CODEL is not set
# CONFIG_DEFAULT_FQ_CODEL is not set
# CONFIG_DEFAULT_FQ_PIE is not set
# CONFIG_DEFAULT_SFQ is not set
CONFIG_DEFAULT_PFIFO_FAST=y
CONFIG_DEFAULT_NET_SCH="pfifo_fast"

#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_FLOWER=m
CONFIG_NET_CLS_MATCHALL=m
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=m
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
CONFIG_NET_EMATCH_CANID=m
CONFIG_NET_EMATCH_IPSET=m
CONFIG_NET_EMATCH_IPT=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_SAMPLE=m
CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_MPLS=m
CONFIG_NET_ACT_VLAN=m
CONFIG_NET_ACT_BPF=m
CONFIG_NET_ACT_CONNMARK=m
CONFIG_NET_ACT_CTINFO=m
CONFIG_NET_ACT_SKBMOD=m
CONFIG_NET_ACT_IFE=m
CONFIG_NET_ACT_TUNNEL_KEY=m
CONFIG_NET_ACT_CT=m
CONFIG_NET_ACT_GATE=m
CONFIG_NET_IFE_SKBMARK=m
CONFIG_NET_IFE_SKBPRIO=m
CONFIG_NET_IFE_SKBTCINDEX=m
CONFIG_NET_TC_SKB_EXT=y
CONFIG_NET_SCH_FIFO=y
CONFIG_DCB=y
CONFIG_DNS_RESOLVER=m
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_BATMAN_V=y
CONFIG_BATMAN_ADV_BLA=y
CONFIG_BATMAN_ADV_DAT=y
CONFIG_BATMAN_ADV_NC=y
CONFIG_BATMAN_ADV_MCAST=y
CONFIG_BATMAN_ADV_DEBUG=y
CONFIG_BATMAN_ADV_TRACING=y
CONFIG_OPENVSWITCH=m
CONFIG_OPENVSWITCH_GRE=m
CONFIG_OPENVSWITCH_VXLAN=m
CONFIG_OPENVSWITCH_GENEVE=m
CONFIG_VSOCKETS=m
CONFIG_VSOCKETS_DIAG=m
CONFIG_VSOCKETS_LOOPBACK=m
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS_COMMON=m
CONFIG_NETLINK_DIAG=m
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
CONFIG_NET_NSH=m
CONFIG_HSR=m
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_QRTR=m
CONFIG_QRTR_SMD=m
CONFIG_QRTR_TUN=m
CONFIG_QRTR_MHI=m
CONFIG_NET_NCSI=y
CONFIG_NCSI_OEM_CMD_GET_MAC=y
CONFIG_NCSI_OEM_CMD_KEEP_PHY=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_HWBM=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_BPF_STREAM_PARSER=y

#
# Network testing
#
CONFIG_NET_PKTGEN=m
CONFIG_NET_DROP_MONITOR=m
# end of Network testing
# end of Networking options

CONFIG_HAMRADIO=y

#
# Packet Radio protocols
#
CONFIG_AX25=m
CONFIG_AX25_DAMA_SLAVE=y
CONFIG_NETROM=m
CONFIG_ROSE=m

#
# AX.25 network device drivers
#
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
CONFIG_BAYCOM_SER_FDX=m
CONFIG_BAYCOM_SER_HDX=m
CONFIG_BAYCOM_PAR=m
CONFIG_BAYCOM_EPP=m
CONFIG_YAM=m
# end of AX.25 network device drivers

CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
CONFIG_CAN_GW=m
CONFIG_CAN_J1939=m
CONFIG_CAN_ISOTP=m
CONFIG_BT=m
CONFIG_BT_BREDR=y
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_CMTP=m
CONFIG_BT_HIDP=m
CONFIG_BT_HS=y
CONFIG_BT_LE=y
CONFIG_BT_6LOWPAN=m
CONFIG_BT_LEDS=y
CONFIG_BT_MSFTEXT=y
CONFIG_BT_AOSPEXT=y
CONFIG_BT_DEBUGFS=y
CONFIG_BT_SELFTEST=y
CONFIG_BT_SELFTEST_ECDH=y
CONFIG_BT_SELFTEST_SMP=y

#
# Bluetooth device drivers
#
CONFIG_BT_INTEL=m
CONFIG_BT_BCM=m
CONFIG_BT_RTL=m
CONFIG_BT_QCA=m
CONFIG_BT_MTK=m
CONFIG_BT_HCIBTUSB=m
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
CONFIG_BT_HCIBTUSB_BCM=y
CONFIG_BT_HCIBTUSB_MTK=y
CONFIG_BT_HCIBTUSB_RTL=y
CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_NOKIA=m
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
CONFIG_BT_HCIUART_INTEL=y
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIDTL1=m
CONFIG_BT_HCIBT3C=m
CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_ATH3K=m
CONFIG_BT_MTKSDIO=m
CONFIG_BT_MTKUART=m
CONFIG_BT_QCOMSMD=m
CONFIG_BT_HCIRSI=m
CONFIG_BT_VIRTIO=m
# end of Bluetooth device drivers

CONFIG_AF_RXRPC=m
CONFIG_AF_RXRPC_IPV6=y
CONFIG_AF_RXRPC_INJECT_LOSS=y
CONFIG_AF_RXRPC_DEBUG=y
CONFIG_RXKAD=y
CONFIG_AF_KCM=m
CONFIG_STREAM_PARSER=y
CONFIG_MCTP=y
CONFIG_MCTP_FLOWS=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_CFG80211_DEVELOPER_WARNINGS=y
CONFIG_CFG80211_CERTIFICATION_ONUS=y
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
CONFIG_CFG80211_EXTRA_REGDB_KEYDIR=""
CONFIG_CFG80211_REG_CELLULAR_HINTS=y
CONFIG_CFG80211_REG_RELAX_NO_IR=y
CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_DEBUGFS=y
CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
CONFIG_CFG80211_WEXT_EXPORT=y
CONFIG_LIB80211=m
CONFIG_LIB80211_CRYPT_WEP=m
CONFIG_LIB80211_CRYPT_CCMP=m
CONFIG_LIB80211_CRYPT_TKIP=m
CONFIG_LIB80211_DEBUG=y
CONFIG_MAC80211=m
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_MESSAGE_TRACING=y
CONFIG_MAC80211_DEBUG_MENU=y
CONFIG_MAC80211_NOINLINE=y
CONFIG_MAC80211_VERBOSE_DEBUG=y
CONFIG_MAC80211_MLME_DEBUG=y
CONFIG_MAC80211_STA_DEBUG=y
CONFIG_MAC80211_HT_DEBUG=y
CONFIG_MAC80211_OCB_DEBUG=y
CONFIG_MAC80211_IBSS_DEBUG=y
CONFIG_MAC80211_PS_DEBUG=y
CONFIG_MAC80211_MPL_DEBUG=y
CONFIG_MAC80211_MPATH_DEBUG=y
CONFIG_MAC80211_MHWMP_DEBUG=y
CONFIG_MAC80211_MESH_SYNC_DEBUG=y
CONFIG_MAC80211_MESH_CSA_DEBUG=y
CONFIG_MAC80211_MESH_PS_DEBUG=y
CONFIG_MAC80211_TDLS_DEBUG=y
CONFIG_MAC80211_DEBUG_COUNTERS=y
CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
CONFIG_RFKILL=m
CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
CONFIG_RFKILL_GPIO=m
CONFIG_NET_9P=m
CONFIG_NET_9P_FD=m
CONFIG_NET_9P_VIRTIO=m
CONFIG_NET_9P_DEBUG=y
CONFIG_CAIF=m
CONFIG_CAIF_DEBUG=y
CONFIG_CAIF_NETDEV=m
CONFIG_CAIF_USB=m
CONFIG_CEPH_LIB=m
CONFIG_CEPH_LIB_PRETTYDEBUG=y
CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
CONFIG_NFC=m
CONFIG_NFC_DIGITAL=m
CONFIG_NFC_NCI=m
CONFIG_NFC_NCI_SPI=m
CONFIG_NFC_NCI_UART=m
CONFIG_NFC_HCI=m
CONFIG_NFC_SHDLC=y

#
# Near Field Communication (NFC) devices
#
CONFIG_NFC_TRF7970A=m
CONFIG_NFC_SIM=m
CONFIG_NFC_PORT100=m
CONFIG_NFC_VIRTUAL_NCI=m
CONFIG_NFC_FDP=m
CONFIG_NFC_FDP_I2C=m
CONFIG_NFC_PN544=m
CONFIG_NFC_PN544_I2C=m
CONFIG_NFC_PN533=m
CONFIG_NFC_PN533_USB=m
CONFIG_NFC_PN533_I2C=m
CONFIG_NFC_PN532_UART=m
CONFIG_NFC_MICROREAD=m
CONFIG_NFC_MICROREAD_I2C=m
CONFIG_NFC_MRVL=m
CONFIG_NFC_MRVL_USB=m
CONFIG_NFC_MRVL_UART=m
CONFIG_NFC_MRVL_I2C=m
CONFIG_NFC_MRVL_SPI=m
CONFIG_NFC_ST21NFCA=m
CONFIG_NFC_ST21NFCA_I2C=m
CONFIG_NFC_ST_NCI=m
CONFIG_NFC_ST_NCI_I2C=m
CONFIG_NFC_ST_NCI_SPI=m
CONFIG_NFC_NXP_NCI=m
CONFIG_NFC_NXP_NCI_I2C=m
CONFIG_NFC_S3FWRN5=m
CONFIG_NFC_S3FWRN5_I2C=m
CONFIG_NFC_S3FWRN82_UART=m
CONFIG_NFC_ST95HF=m
# end of Near Field Communication (NFC) devices

CONFIG_PSAMPLE=m
CONFIG_NET_IFE=m
CONFIG_LWTUNNEL=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_DST_CACHE=y
CONFIG_GRO_CELLS=y
CONFIG_SOCK_VALIDATE_XMIT=y
CONFIG_NET_SELFTESTS=m
CONFIG_NET_SOCK_MSG=y
CONFIG_NET_DEVLINK=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_POOL_STATS=y
CONFIG_FAILOVER=m
CONFIG_ETHTOOL_NETLINK=y
CONFIG_NETDEV_ADDR_LIST_TEST=m

#
# Device Drivers
#
CONFIG_PCCARD=m
CONFIG_PCMCIA=m
CONFIG_PCMCIA_LOAD_CIS=y

#
# PC-card bridges
#

#
# Generic Driver Options
#
CONFIG_AUXILIARY_BUS=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DEVTMPFS_SAFE=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y

#
# Firmware loader
#
CONFIG_FW_LOADER=m
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_FW_LOADER_COMPRESS=y
CONFIG_FW_LOADER_COMPRESS_XZ=y
CONFIG_FW_LOADER_COMPRESS_ZSTD=y
CONFIG_FW_UPLOAD=y
# end of Firmware loader

CONFIG_WANT_DEV_COREDUMP=y
CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_DEV_COREDUMP=y
CONFIG_DEBUG_DRIVER=y
CONFIG_DEBUG_DEVRES=y
CONFIG_DEBUG_TEST_DRIVER_REMOVE=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
CONFIG_SOC_BUS=y
CONFIG_REGMAP=y
CONFIG_REGMAP_AC97=m
CONFIG_REGMAP_I2C=m
CONFIG_REGMAP_SLIMBUS=m
CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_SPMI=m
CONFIG_REGMAP_W1=m
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_REGMAP_SOUNDWIRE=m
CONFIG_REGMAP_SOUNDWIRE_MBQ=m
CONFIG_REGMAP_SCCB=m
CONFIG_REGMAP_I3C=m
CONFIG_REGMAP_SPI_AVMM=m
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMA_FENCE_TRACE=y
# end of Generic Driver Options

#
# Bus devices
#
CONFIG_ARM_INTEGRATOR_LM=y
CONFIG_BT1_APB=y
CONFIG_BT1_AXI=y
CONFIG_MOXTET=m
CONFIG_HISILICON_LPC=y
CONFIG_INTEL_IXP4XX_EB=y
CONFIG_QCOM_EBI2=y
CONFIG_MHI_BUS=m
CONFIG_MHI_BUS_DEBUG=y
CONFIG_MHI_BUS_EP=m
# end of Bus devices

CONFIG_CONNECTOR=m

#
# Firmware Drivers
#

#
# ARM System Control and Management Interface Protocol
#
CONFIG_ARM_SCMI_PROTOCOL=m
CONFIG_ARM_SCMI_HAVE_TRANSPORT=y
CONFIG_ARM_SCMI_HAVE_SHMEM=y
CONFIG_ARM_SCMI_HAVE_MSG=y
CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE=y
CONFIG_ARM_SCMI_POWER_DOMAIN=m
CONFIG_ARM_SCMI_POWER_CONTROL=m
# end of ARM System Control and Management Interface Protocol

CONFIG_ARM_SCPI_PROTOCOL=m
CONFIG_ARM_SCPI_POWER_DOMAIN=m
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_MTK_ADSP_IPC=m
CONFIG_QCOM_SCM=m
CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT=y
CONFIG_BCM47XX_NVRAM=y
CONFIG_BCM47XX_SPROM=y
CONFIG_TEE_BNXT_FW=m
CONFIG_CS_DSP=m
CONFIG_GOOGLE_FIRMWARE=y
CONFIG_GOOGLE_COREBOOT_TABLE=m
CONFIG_GOOGLE_MEMCONSOLE=m
CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT=m
CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=m
CONFIG_GOOGLE_VPD=m
CONFIG_IMX_DSP=m
CONFIG_IMX_SCU=y
CONFIG_IMX_SCU_PD=y

#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers

CONFIG_GNSS=m
CONFIG_GNSS_SERIAL=m
CONFIG_GNSS_MTK_SERIAL=m
CONFIG_GNSS_SIRF_SERIAL=m
CONFIG_GNSS_UBX_SERIAL=m
CONFIG_GNSS_USB=m
CONFIG_MTD=m
CONFIG_MTD_TESTS=m

#
# Partition parsers
#
CONFIG_MTD_AR7_PARTS=m
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_BRCM_U_BOOT=m
CONFIG_MTD_CMDLINE_PARTS=m
CONFIG_MTD_OF_PARTS=m
CONFIG_MTD_OF_PARTS_BCM4908=y
CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
CONFIG_MTD_PARSER_IMAGETAG=m
CONFIG_MTD_PARSER_TRX=m
CONFIG_MTD_SHARPSL_PARTS=m
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_QCOMSMEM_PARTS=m
# end of Partition parsers

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m

#
# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
#
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_SM_FTL=m
CONFIG_MTD_OOPS=m
CONFIG_MTD_PSTORE=m
CONFIG_MTD_PARTITIONED_MASTER=y

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=m
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_GEN_PROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_MTD_MAP_BANK_WIDTH_8=y
CONFIG_MTD_MAP_BANK_WIDTH_16=y
CONFIG_MTD_MAP_BANK_WIDTH_32=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_I8=y
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_CFI_UTIL=m
CONFIG_MTD_RAM=m
CONFIG_MTD_ROM=m
CONFIG_MTD_ABSENT=m
# end of RAM/ROM/Flash chip drivers

#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_PHYSMAP_BT1_ROM=y
CONFIG_MTD_PHYSMAP_VERSATILE=y
CONFIG_MTD_PHYSMAP_GEMINI=y
CONFIG_MTD_PHYSMAP_GPIO_ADDR=y
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
CONFIG_MTD_TS5500=m
CONFIG_MTD_SOLUTIONENGINE=m
CONFIG_MTD_PCMCIA=m
CONFIG_MTD_PCMCIA_ANONYMOUS=y
CONFIG_MTD_PLATRAM=m
# end of Mapping drivers for chip access

#
# Self-contained MTD device drivers
#
CONFIG_MTD_DATAFLASH=m
CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
CONFIG_MTD_DATAFLASH_OTP=y
CONFIG_MTD_MCHP23K256=m
CONFIG_MTD_MCHP48L640=m
CONFIG_MTD_SPEAR_SMI=m
CONFIG_MTD_SST25L=m
CONFIG_MTD_SLRAM=m
CONFIG_MTD_PHRAM=m
CONFIG_MTD_MTDRAM=m
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTD_BLOCK2MTD=m

#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOCG3=m
CONFIG_BCH_CONST_M=14
CONFIG_BCH_CONST_T=4
# end of Self-contained MTD device drivers

#
# NAND
#
CONFIG_MTD_NAND_CORE=m
CONFIG_MTD_ONENAND=m
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=m
CONFIG_MTD_ONENAND_SAMSUNG=m
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_RAW_NAND=m

#
# Raw/parallel NAND flash controllers
#
CONFIG_MTD_NAND_AMS_DELTA=m
CONFIG_MTD_NAND_OMAP2=m
CONFIG_MTD_NAND_OMAP_BCH=y
CONFIG_MTD_NAND_OMAP_BCH_BUILD=m
CONFIG_MTD_NAND_SHARPSL=m
CONFIG_MTD_NAND_ATMEL=m
CONFIG_MTD_NAND_MARVELL=m
CONFIG_MTD_NAND_SLC_LPC32XX=m
CONFIG_MTD_NAND_MLC_LPC32XX=m
CONFIG_MTD_NAND_BRCMNAND=m
CONFIG_MTD_NAND_BRCMNAND_BCM63XX=m
CONFIG_MTD_NAND_BRCMNAND_BCMBCA=m
CONFIG_MTD_NAND_BRCMNAND_BRCMSTB=m
CONFIG_MTD_NAND_BRCMNAND_IPROC=m
CONFIG_MTD_NAND_OXNAS=m
CONFIG_MTD_NAND_FSL_IFC=m
CONFIG_MTD_NAND_VF610_NFC=m
CONFIG_MTD_NAND_MXC=m
CONFIG_MTD_NAND_SH_FLCTL=m
CONFIG_MTD_NAND_DAVINCI=m
CONFIG_MTD_NAND_TXX9NDFMC=m
CONFIG_MTD_NAND_JZ4780=m
CONFIG_MTD_NAND_INGENIC_ECC=y
CONFIG_MTD_NAND_JZ4740_ECC=m
CONFIG_MTD_NAND_JZ4725B_BCH=m
CONFIG_MTD_NAND_JZ4780_BCH=m
CONFIG_MTD_NAND_FSMC=m
CONFIG_MTD_NAND_SUNXI=m
CONFIG_MTD_NAND_HISI504=m
CONFIG_MTD_NAND_QCOM=m
CONFIG_MTD_NAND_MTK=m
CONFIG_MTD_NAND_MXIC=m
CONFIG_MTD_NAND_TEGRA=m
CONFIG_MTD_NAND_STM32_FMC2=m
CONFIG_MTD_NAND_MESON=m
CONFIG_MTD_NAND_GPIO=m
CONFIG_MTD_NAND_PLATFORM=m
CONFIG_MTD_NAND_CADENCE=m
CONFIG_MTD_NAND_INTEL_LGM=m
CONFIG_MTD_NAND_RENESAS=m

#
# Misc
#
CONFIG_MTD_NAND_NANDSIM=m
CONFIG_MTD_NAND_DISKONCHIP=m
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_SPI_NAND=m

#
# ECC engine support
#
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
CONFIG_MTD_NAND_ECC_SW_BCH=y
CONFIG_MTD_NAND_ECC_MXIC=y
CONFIG_MTD_NAND_ECC_MEDIATEK=m
# end of ECC engine support
# end of NAND

#
# LPDDR & LPDDR2 PCM memory drivers
#
CONFIG_MTD_LPDDR=m
CONFIG_MTD_QINFO_PROBE=m
# end of LPDDR & LPDDR2 PCM memory drivers

CONFIG_MTD_SPI_NOR=m
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
CONFIG_SPI_HISI_SFC=m
CONFIG_SPI_NXP_SPIFI=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_FASTMAP=y
CONFIG_MTD_UBI_GLUEBI=m
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_HYPERBUS=m
CONFIG_HBMC_AM654=m
CONFIG_DTC=y
CONFIG_OF=y
CONFIG_OF_UNITTEST=y
CONFIG_OF_ALL_DTBS=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OF_RESOLVE=y
CONFIG_OF_OVERLAY=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_PC_SUPERIO=y
CONFIG_PARPORT_PC_PCMCIA=m
CONFIG_PARPORT_AX88796=m
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_NULL_BLK=m
CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION=y
CONFIG_CDROM=m
CONFIG_PARIDE=m

#
# Parallel IDE high-level drivers
#
CONFIG_PARIDE_PD=m
CONFIG_PARIDE_PCD=m
CONFIG_PARIDE_PF=m
CONFIG_PARIDE_PT=m
CONFIG_PARIDE_PG=m

#
# Parallel IDE protocol modules
#
CONFIG_PARIDE_ATEN=m
CONFIG_PARIDE_BPCK=m
CONFIG_PARIDE_BPCK6=m
CONFIG_PARIDE_COMM=m
CONFIG_PARIDE_DSTR=m
CONFIG_PARIDE_FIT2=m
CONFIG_PARIDE_FIT3=m
CONFIG_PARIDE_EPAT=m
CONFIG_PARIDE_EPATC8=y
CONFIG_PARIDE_EPIA=m
CONFIG_PARIDE_FRIQ=m
CONFIG_PARIDE_FRPW=m
CONFIG_PARIDE_KBIC=m
CONFIG_PARIDE_KTTI=m
CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_BLK_DEV_DRBD=m
CONFIG_DRBD_FAULT_INJECTION=y
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
CONFIG_CDROM_PKTCDVD_WCACHE=y
CONFIG_ATA_OVER_ETH=m
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_UBLK=m

#
# NVME Support
#
CONFIG_NVME_COMMON=m
CONFIG_NVME_CORE=m
CONFIG_NVME_MULTIPATH=y
CONFIG_NVME_VERBOSE_ERRORS=y
CONFIG_NVME_HWMON=y
CONFIG_NVME_FABRICS=m
CONFIG_NVME_TCP=m
CONFIG_NVME_AUTH=y
CONFIG_NVME_APPLE=m
CONFIG_NVME_TARGET=m
CONFIG_NVME_TARGET_PASSTHRU=y
CONFIG_NVME_TARGET_LOOP=m
CONFIG_NVME_TARGET_TCP=m
CONFIG_NVME_TARGET_AUTH=y
# end of NVME Support

#
# Misc devices
#
CONFIG_SENSORS_LIS3LV02D=m
CONFIG_AD525X_DPOT=m
CONFIG_AD525X_DPOT_I2C=m
CONFIG_AD525X_DPOT_SPI=m
CONFIG_DUMMY_IRQ=m
CONFIG_ICS932S401=m
CONFIG_ATMEL_SSC=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_GEHC_ACHC=m
CONFIG_HI6421V600_IRQ=m
CONFIG_QCOM_COINCELL=m
CONFIG_QCOM_FASTRPC=m
CONFIG_APDS9802ALS=m
CONFIG_ISL29003=m
CONFIG_ISL29020=m
CONFIG_SENSORS_TSL2550=m
CONFIG_SENSORS_BH1770=m
CONFIG_SENSORS_APDS990X=m
CONFIG_HMC6352=m
CONFIG_DS1682=m
CONFIG_LATTICE_ECP3_CONFIG=m
CONFIG_SRAM=y
CONFIG_XILINX_SDFEC=m
CONFIG_MISC_RTSX=m
CONFIG_HISI_HIKEY_USB=m
CONFIG_OPEN_DICE=m
CONFIG_VCPU_STALL_DETECTOR=m
CONFIG_C2PORT=m

#
# EEPROM support
#
CONFIG_EEPROM_AT24=m
CONFIG_EEPROM_AT25=m
CONFIG_EEPROM_LEGACY=m
CONFIG_EEPROM_MAX6875=m
CONFIG_EEPROM_93CX6=m
CONFIG_EEPROM_93XX46=m
CONFIG_EEPROM_IDT_89HPESX=m
CONFIG_EEPROM_EE1004=m
# end of EEPROM support

#
# Texas Instruments shared transport line discipline
#
CONFIG_TI_ST=m
# end of Texas Instruments shared transport line discipline

CONFIG_SENSORS_LIS3_SPI=m
CONFIG_SENSORS_LIS3_I2C=m

#
# Altera FPGA firmware download module (requires I2C)
#
CONFIG_ALTERA_STAPL=m
CONFIG_ECHO=m
CONFIG_MISC_RTSX_USB=m
CONFIG_UACCE=m
CONFIG_PVPANIC=y
CONFIG_PVPANIC_MMIO=m
# end of Misc devices

#
# SCSI device support
#
CONFIG_SCSI_MOD=m
CONFIG_RAID_ATTRS=m
CONFIG_SCSI_COMMON=m
CONFIG_SCSI=m
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
CONFIG_BLK_DEV_BSG=y
CONFIG_CHR_DEV_SCH=m
CONFIG_SCSI_ENCLOSURE=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=m
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SAS_ATTRS=m
CONFIG_SCSI_SAS_LIBSAS=m
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SRP_ATTRS=m
# end of SCSI Transports

CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_SCSI_HISI_SAS=m
CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
CONFIG_SCSI_FDOMAIN=m
CONFIG_SCSI_PPA=m
CONFIG_SCSI_IMM=m
CONFIG_SCSI_IZIP_EPP16=y
CONFIG_SCSI_IZIP_SLOW_CTR=y
CONFIG_SCSI_DEBUG=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_PCMCIA_AHA152X=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_PCMCIA_NINJA_SCSI=m
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
# end of SCSI device support

CONFIG_HAVE_PATA_PLATFORM=y
CONFIG_ATA=m
CONFIG_SATA_HOST=y
CONFIG_PATA_TIMINGS=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_FORCE=y
CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y

#
# SFF controllers with custom DMA interface
#

#
# PIO-only SFF controllers
#
CONFIG_PATA_IXP4XX_CF=m
CONFIG_PATA_PCMCIA=m
CONFIG_PATA_PLATFORM=m
CONFIG_PATA_OF_PLATFORM=m
CONFIG_PATA_SAMSUNG_CF=m

#
# Generic fallback / legacy drivers
#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_MD_CLUSTER=m
CONFIG_BCACHE=m
CONFIG_BCACHE_DEBUG=y
CONFIG_BCACHE_CLOSURES_DEBUG=y
CONFIG_BCACHE_ASYNC_REGISTRATION=y
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=m
CONFIG_DM_DEBUG=y
CONFIG_DM_BUFIO=m
CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING=y
CONFIG_DM_DEBUG_BLOCK_STACK_TRACING=y
CONFIG_DM_BIO_PRISON=m
CONFIG_DM_PERSISTENT_DATA=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
CONFIG_DM_WRITECACHE=m
CONFIG_DM_EBS=m
CONFIG_DM_ERA=m
CONFIG_DM_CLONE=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_MULTIPATH_HST=m
CONFIG_DM_MULTIPATH_IOA=m
CONFIG_DM_DELAY=m
CONFIG_DM_DUST=m
CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=m
CONFIG_DM_VERITY=m
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y
CONFIG_DM_VERITY_FEC=y
CONFIG_DM_SWITCH=m
CONFIG_DM_LOG_WRITES=m
CONFIG_DM_INTEGRITY=m
CONFIG_DM_ZONED=m
CONFIG_DM_AUDIT=y
CONFIG_TARGET_CORE=m
CONFIG_TCM_IBLOCK=m
CONFIG_TCM_FILEIO=m
CONFIG_TCM_PSCSI=m
CONFIG_LOOPBACK_TARGET=m
CONFIG_TCM_FC=m
CONFIG_ISCSI_TARGET=m
CONFIG_SBP_TARGET=m

#
# IEEE 1394 (FireWire) support
#
CONFIG_FIREWIRE=m
CONFIG_FIREWIRE_SBP2=m
CONFIG_FIREWIRE_NET=m
# end of IEEE 1394 (FireWire) support

CONFIG_NETDEVICES=y
CONFIG_MII=m
CONFIG_NET_CORE=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_WIREGUARD=m
CONFIG_WIREGUARD_DEBUG=y
CONFIG_EQUALIZER=m
CONFIG_IFB=m
CONFIG_NET_TEAM=m
CONFIG_NET_TEAM_MODE_BROADCAST=m
CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
CONFIG_NET_TEAM_MODE_RANDOM=m
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
CONFIG_NET_TEAM_MODE_LOADBALANCE=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_IPVLAN_L3S=y
CONFIG_IPVLAN=m
CONFIG_IPVTAP=m
CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
CONFIG_AMT=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_TUN=m
CONFIG_TAP=m
CONFIG_TUN_VNET_CROSS_LE=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=m
CONFIG_NLMON=m
CONFIG_NET_VRF=m
CONFIG_VSOCKMON=m
CONFIG_MHI_NET=m
CONFIG_ARCNET=m
CONFIG_ARCNET_1201=m
CONFIG_ARCNET_1051=m
CONFIG_ARCNET_RAW=m
CONFIG_ARCNET_CAP=m
CONFIG_ARCNET_COM90xx=m
CONFIG_ARCNET_COM90xxIO=m
CONFIG_ARCNET_RIM_I=m
CONFIG_ARCNET_COM20020=m
CONFIG_ARCNET_COM20020_CS=m
CONFIG_ATM_DRIVERS=y
CONFIG_ATM_DUMMY=m
CONFIG_ATM_TCP=m
CONFIG_CAIF_DRIVERS=y
CONFIG_CAIF_TTY=m

#
# Distributed Switch Architecture drivers
#
CONFIG_B53=m
CONFIG_B53_SPI_DRIVER=m
CONFIG_B53_MDIO_DRIVER=m
CONFIG_B53_MMAP_DRIVER=m
CONFIG_B53_SRAB_DRIVER=m
CONFIG_B53_SERDES=m
CONFIG_NET_DSA_BCM_SF2=m
CONFIG_NET_DSA_LOOP=m
CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m
CONFIG_NET_DSA_LANTIQ_GSWIP=m
CONFIG_NET_DSA_MT7530=m
CONFIG_NET_DSA_MV88E6060=m
CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m
CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m
CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m
CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m
CONFIG_NET_DSA_MV88E6XXX=m
CONFIG_NET_DSA_MV88E6XXX_PTP=y
CONFIG_NET_DSA_MSCC_SEVILLE=m
CONFIG_NET_DSA_AR9331=m
CONFIG_NET_DSA_QCA8K=m
CONFIG_NET_DSA_SJA1105=m
CONFIG_NET_DSA_SJA1105_PTP=y
CONFIG_NET_DSA_SJA1105_TAS=y
CONFIG_NET_DSA_SJA1105_VL=y
CONFIG_NET_DSA_XRS700X=m
CONFIG_NET_DSA_XRS700X_I2C=m
CONFIG_NET_DSA_XRS700X_MDIO=m
CONFIG_NET_DSA_REALTEK=m
CONFIG_NET_DSA_REALTEK_MDIO=m
CONFIG_NET_DSA_REALTEK_SMI=m
CONFIG_NET_DSA_REALTEK_RTL8365MB=m
CONFIG_NET_DSA_REALTEK_RTL8366RB=m
CONFIG_NET_DSA_SMSC_LAN9303=m
CONFIG_NET_DSA_SMSC_LAN9303_I2C=m
CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m
CONFIG_NET_DSA_VITESSE_VSC73XX=m
CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=m
CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m
# end of Distributed Switch Architecture drivers

CONFIG_ETHERNET=y
CONFIG_MDIO=m
CONFIG_NET_VENDOR_3COM=y
CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_3C589=m
CONFIG_NET_VENDOR_ACTIONS=y
CONFIG_OWL_EMAC=m
CONFIG_NET_VENDOR_ALACRITECH=y
CONFIG_NET_VENDOR_AMAZON=y
CONFIG_NET_VENDOR_AMD=y
CONFIG_PCMCIA_NMCLAN=m
CONFIG_AMD_XGBE=m
CONFIG_AMD_XGBE_DCB=y
CONFIG_NET_XGENE=m
CONFIG_NET_XGENE_V2=m
CONFIG_NET_VENDOR_AQUANTIA=y
CONFIG_NET_VENDOR_ARC=y
CONFIG_ARC_EMAC_CORE=m
CONFIG_ARC_EMAC=m
CONFIG_EMAC_ROCKCHIP=m
CONFIG_NET_VENDOR_ASIX=y
CONFIG_SPI_AX88796C=m
CONFIG_SPI_AX88796C_COMPRESSION=y
CONFIG_NET_VENDOR_CADENCE=y
CONFIG_NET_CALXEDA_XGMAC=m
CONFIG_NET_VENDOR_CAVIUM=y
CONFIG_NET_VENDOR_CIRRUS=y
CONFIG_CS89x0=m
CONFIG_CS89x0_PLATFORM=m
CONFIG_EP93XX_ETH=m
CONFIG_NET_VENDOR_CORTINA=y
CONFIG_GEMINI_ETHERNET=m
CONFIG_NET_VENDOR_DAVICOM=y
CONFIG_DM9000=m
CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
CONFIG_DM9051=m
CONFIG_DNET=m
CONFIG_NET_VENDOR_ENGLEDER=y
CONFIG_NET_VENDOR_EZCHIP=y
CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=m
CONFIG_NET_VENDOR_FARADAY=y
CONFIG_FTMAC100=m
CONFIG_FTGMAC100=m
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FEC=m
CONFIG_FSL_FMAN=m
CONFIG_FSL_PQ_MDIO=m
CONFIG_FSL_XGMAC_MDIO=m
CONFIG_FSL_DPAA2_SWITCH=m
CONFIG_FSL_ENETC_IERB=m
CONFIG_NET_VENDOR_FUJITSU=y
CONFIG_PCMCIA_FMVJ18X=m
CONFIG_NET_VENDOR_FUNGIBLE=y
CONFIG_NET_VENDOR_GOOGLE=y
CONFIG_NET_VENDOR_HISILICON=y
CONFIG_HIX5HD2_GMAC=m
CONFIG_HISI_FEMAC=m
CONFIG_HIP04_ETH=m
CONFIG_HI13X1_GMAC=y
CONFIG_HNS_MDIO=m
CONFIG_HNS=m
CONFIG_HNS_DSAF=m
CONFIG_HNS_ENET=m
CONFIG_NET_VENDOR_HUAWEI=y
CONFIG_NET_VENDOR_I825XX=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_NET_VENDOR_WANGXUN=y
CONFIG_KORINA=m
CONFIG_NET_VENDOR_ADI=y
CONFIG_ADIN1110=m
CONFIG_NET_VENDOR_LITEX=y
CONFIG_LITEX_LITEETH=m
CONFIG_NET_VENDOR_MARVELL=y
CONFIG_MV643XX_ETH=m
CONFIG_MVMDIO=m
CONFIG_MVNETA_BM_ENABLE=m
CONFIG_MVNETA=m
CONFIG_MVNETA_BM=m
CONFIG_MVPP2=m
CONFIG_MVPP2_PTP=y
CONFIG_PXA168_ETH=m
CONFIG_PRESTERA=m
CONFIG_NET_VENDOR_MEDIATEK=y
CONFIG_NET_MEDIATEK_SOC_WED=y
CONFIG_NET_MEDIATEK_SOC=m
CONFIG_NET_MEDIATEK_STAR_EMAC=m
CONFIG_NET_VENDOR_MELLANOX=y
CONFIG_MLXSW_CORE=m
CONFIG_MLXSW_CORE_HWMON=y
CONFIG_MLXSW_CORE_THERMAL=y
CONFIG_MLXSW_I2C=m
CONFIG_MLXSW_MINIMAL=m
CONFIG_MLXFW=m
CONFIG_MLXBF_GIGE=m
CONFIG_NET_VENDOR_MICREL=y
CONFIG_KS8851=m
CONFIG_KS8851_MLL=m
CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_ENC28J60=m
CONFIG_ENC28J60_WRITEVERIFY=y
CONFIG_ENCX24J600=m
CONFIG_LAN966X_SWITCH=m
CONFIG_SPARX5_SWITCH=m
CONFIG_NET_VENDOR_MICROSEMI=y
CONFIG_MSCC_OCELOT_SWITCH_LIB=m
CONFIG_MSCC_OCELOT_SWITCH=m
CONFIG_NET_VENDOR_MICROSOFT=y
CONFIG_NET_VENDOR_NI=y
CONFIG_NET_VENDOR_NATSEMI=y
CONFIG_NET_VENDOR_NETRONOME=y
CONFIG_NET_VENDOR_8390=y
CONFIG_PCMCIA_AXNET=m
CONFIG_AX88796=m
CONFIG_AX88796_93CX6=y
CONFIG_PCMCIA_PCNET=m
CONFIG_STNIC=m
CONFIG_LPC_ENET=m
CONFIG_NET_VENDOR_PENSANDO=y
CONFIG_NET_VENDOR_QUALCOMM=y
CONFIG_QCA7000=m
CONFIG_QCA7000_SPI=m
CONFIG_QCA7000_UART=m
CONFIG_RMNET=m
CONFIG_NET_VENDOR_RENESAS=y
CONFIG_SH_ETH=m
CONFIG_RAVB=m
CONFIG_NET_VENDOR_ROCKER=y
CONFIG_NET_VENDOR_SAMSUNG=y
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SOLARFLARE=y
CONFIG_NET_VENDOR_SMSC=y
CONFIG_SMC91X=m
CONFIG_PCMCIA_SMC91C92=m
CONFIG_SMC911X=m
CONFIG_SMSC911X=m
CONFIG_NET_VENDOR_SOCIONEXT=y
CONFIG_SNI_AVE=m
CONFIG_SNI_NETSEC=m
CONFIG_NET_VENDOR_STMICRO=y
CONFIG_NET_VENDOR_SUNPLUS=y
CONFIG_SP7021_EMAC=m
CONFIG_NET_VENDOR_SYNOPSYS=y
CONFIG_NET_VENDOR_VERTEXCOM=y
CONFIG_MSE102X=m
CONFIG_NET_VENDOR_VIA=y
CONFIG_NET_VENDOR_WIZNET=y
CONFIG_WIZNET_W5100=m
CONFIG_WIZNET_W5300=m
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not set
CONFIG_WIZNET_BUS_ANY=y
CONFIG_WIZNET_W5100_SPI=m
CONFIG_NET_VENDOR_XILINX=y
CONFIG_XILINX_EMACLITE=m
CONFIG_XILINX_AXI_EMAC=m
CONFIG_XILINX_LL_TEMAC=m
CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_QCOM_IPA=m
CONFIG_PHYLINK=m
CONFIG_PHYLIB=m
CONFIG_SWPHY=y
CONFIG_LED_TRIGGER_PHY=y
CONFIG_FIXED_PHY=m
CONFIG_SFP=m

#
# MII PHY device drivers
#
CONFIG_AMD_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_ADIN_PHY=m
CONFIG_ADIN1100_PHY=m
CONFIG_AQUANTIA_PHY=m
CONFIG_AX88796B_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_BCM54140_PHY=m
CONFIG_BCM63XX_PHY=m
CONFIG_BCM7XXX_PHY=m
CONFIG_BCM84881_PHY=m
CONFIG_BCM87XX_PHY=m
CONFIG_BCM_CYGNUS_PHY=m
CONFIG_BCM_NET_PHYLIB=m
CONFIG_BCM_NET_PHYPTP=m
CONFIG_CICADA_PHY=m
CONFIG_CORTINA_PHY=m
CONFIG_DAVICOM_PHY=m
CONFIG_ICPLUS_PHY=m
CONFIG_LXT_PHY=m
CONFIG_INTEL_XWAY_PHY=m
CONFIG_LSI_ET1011C_PHY=m
CONFIG_MARVELL_PHY=m
CONFIG_MARVELL_10G_PHY=m
CONFIG_MARVELL_88X2222_PHY=m
CONFIG_MAXLINEAR_GPHY=m
CONFIG_MEDIATEK_GE_PHY=m
CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
CONFIG_NXP_C45_TJA11XX_PHY=m
CONFIG_NXP_TJA11XX_PHY=m
CONFIG_AT803X_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_REALTEK_PHY=m
CONFIG_RENESAS_PHY=m
CONFIG_ROCKCHIP_PHY=m
CONFIG_SMSC_PHY=m
CONFIG_STE10XP=m
CONFIG_TERANETICS_PHY=m
CONFIG_DP83822_PHY=m
CONFIG_DP83TC811_PHY=m
CONFIG_DP83848_PHY=m
CONFIG_DP83867_PHY=m
CONFIG_DP83869_PHY=m
CONFIG_DP83TD510_PHY=m
CONFIG_VITESSE_PHY=m
CONFIG_XILINX_GMII2RGMII=m
CONFIG_MICREL_KS8995MA=m
CONFIG_PSE_CONTROLLER=y
CONFIG_PSE_REGULATOR=m
CONFIG_CAN_DEV=m
CONFIG_CAN_VCAN=m
CONFIG_CAN_VXCAN=m
CONFIG_CAN_NETLINK=y
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_RX_OFFLOAD=y
CONFIG_CAN_AT91=m
CONFIG_CAN_CAN327=m
CONFIG_CAN_FLEXCAN=m
CONFIG_CAN_SLCAN=m
CONFIG_CAN_SUN4I=m
CONFIG_CAN_XILINXCAN=m
CONFIG_CAN_C_CAN=m
CONFIG_CAN_C_CAN_PLATFORM=m
CONFIG_CAN_CC770=m
CONFIG_CAN_CC770_ISA=m
CONFIG_CAN_CC770_PLATFORM=m
CONFIG_CAN_CTUCANFD=m
CONFIG_CAN_CTUCANFD_PLATFORM=m
CONFIG_CAN_IFI_CANFD=m
CONFIG_CAN_M_CAN=m
CONFIG_CAN_M_CAN_PLATFORM=m
CONFIG_CAN_M_CAN_TCAN4X5X=m
CONFIG_CAN_RCAR=m
CONFIG_CAN_RCAR_CANFD=m
CONFIG_CAN_SJA1000=m
CONFIG_CAN_EMS_PCMCIA=m
CONFIG_CAN_SJA1000_ISA=m
CONFIG_CAN_SJA1000_PLATFORM=m
CONFIG_CAN_SOFTING=m
CONFIG_CAN_SOFTING_CS=m

#
# CAN SPI interfaces
#
CONFIG_CAN_HI311X=m
CONFIG_CAN_MCP251X=m
CONFIG_CAN_MCP251XFD=m
CONFIG_CAN_MCP251XFD_SANITY=y
# end of CAN SPI interfaces

#
# CAN USB interfaces
#
CONFIG_CAN_8DEV_USB=m
CONFIG_CAN_EMS_USB=m
CONFIG_CAN_ESD_USB=m
CONFIG_CAN_ETAS_ES58X=m
CONFIG_CAN_GS_USB=m
CONFIG_CAN_KVASER_USB=m
CONFIG_CAN_MCBA_USB=m
CONFIG_CAN_PEAK_USB=m
CONFIG_CAN_UCAN=m
# end of CAN USB interfaces

CONFIG_CAN_DEBUG_DEVICES=y

#
# MCTP Device Drivers
#
CONFIG_MCTP_SERIAL=m
CONFIG_MCTP_TRANSPORT_I2C=m
# end of MCTP Device Drivers

CONFIG_MDIO_DEVICE=m
CONFIG_MDIO_BUS=m
CONFIG_FWNODE_MDIO=m
CONFIG_OF_MDIO=m
CONFIG_MDIO_DEVRES=m
CONFIG_MDIO_SUN4I=m
CONFIG_MDIO_XGENE=m
CONFIG_MDIO_ASPEED=m
CONFIG_MDIO_BITBANG=m
CONFIG_MDIO_BCM_IPROC=m
CONFIG_MDIO_BCM_UNIMAC=m
CONFIG_MDIO_CAVIUM=m
CONFIG_MDIO_GPIO=m
CONFIG_MDIO_HISI_FEMAC=m
CONFIG_MDIO_I2C=m
CONFIG_MDIO_MVUSB=m
CONFIG_MDIO_MSCC_MIIM=m
CONFIG_MDIO_MOXART=m
CONFIG_MDIO_OCTEON=m
CONFIG_MDIO_IPQ4019=m
CONFIG_MDIO_IPQ8064=m

#
# MDIO Multiplexers
#
CONFIG_MDIO_BUS_MUX=m
CONFIG_MDIO_BUS_MUX_MESON_G12A=m
CONFIG_MDIO_BUS_MUX_BCM6368=m
CONFIG_MDIO_BUS_MUX_BCM_IPROC=m
CONFIG_MDIO_BUS_MUX_GPIO=m
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
CONFIG_MDIO_BUS_MUX_MMIOREG=m

#
# PCS device drivers
#
CONFIG_PCS_XPCS=m
CONFIG_PCS_LYNX=m
CONFIG_PCS_RZN1_MIIC=m
# end of PCS device drivers

CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOATM=m
CONFIG_PPPOE=m
CONFIG_PPTP=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_SLIP=m
CONFIG_SLHC=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y

#
# Host-side USB support is needed for USB Network Adapter support
#
CONFIG_USB_NET_DRIVERS=m
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_AX88179_178A=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_EEM=m
CONFIG_USB_NET_CDC_NCM=m
CONFIG_USB_NET_HUAWEI_CDC_NCM=m
CONFIG_USB_NET_CDC_MBIM=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SR9700=m
CONFIG_USB_NET_SR9800=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET_ENABLE=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
CONFIG_USB_NET_CX82310_ETH=m
CONFIG_USB_NET_KALMIA=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_HSO=m
CONFIG_USB_NET_INT51X1=m
CONFIG_USB_CDC_PHONET=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
CONFIG_USB_VL600=m
CONFIG_USB_NET_CH9200=m
CONFIG_USB_NET_AQC111=m
CONFIG_USB_RTL8153_ECM=m
CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y
CONFIG_ATH_COMMON=m
CONFIG_WLAN_VENDOR_ATH=y
CONFIG_ATH_DEBUG=y
CONFIG_ATH_TRACEPOINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y
CONFIG_ATH9K_HW=m
CONFIG_ATH9K_COMMON=m
CONFIG_ATH9K_COMMON_DEBUG=y
CONFIG_ATH9K_BTCOEX_SUPPORT=y
CONFIG_ATH9K_HTC=m
CONFIG_ATH9K_HTC_DEBUGFS=y
CONFIG_ATH9K_COMMON_SPECTRAL=y
CONFIG_CARL9170=m
CONFIG_CARL9170_LEDS=y
CONFIG_CARL9170_DEBUGFS=y
CONFIG_CARL9170_WPC=y
CONFIG_CARL9170_HWRNG=y
CONFIG_ATH6KL=m
CONFIG_ATH6KL_SDIO=m
CONFIG_ATH6KL_USB=m
CONFIG_ATH6KL_DEBUG=y
CONFIG_ATH6KL_TRACING=y
CONFIG_ATH6KL_REGDOMAIN=y
CONFIG_AR5523=m
CONFIG_WLAN_VENDOR_ATMEL=y
CONFIG_ATMEL=m
CONFIG_PCMCIA_ATMEL=m
CONFIG_AT76C50X_USB=m
CONFIG_WLAN_VENDOR_BROADCOM=y
CONFIG_BRCMUTIL=m
CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_PROTO_BCDC=y
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_USB=y
CONFIG_BRCM_TRACING=y
CONFIG_BRCMDBG=y
CONFIG_WLAN_VENDOR_CISCO=y
CONFIG_AIRO_CS=m
CONFIG_WLAN_VENDOR_INTEL=y
CONFIG_WLAN_VENDOR_INTERSIL=y
CONFIG_HOSTAP=m
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_HOSTAP_CS=m
CONFIG_HERMES=m
CONFIG_HERMES_PRISM=y
CONFIG_HERMES_CACHE_FW_ON_INIT=y
CONFIG_ORINOCO_USB=m
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
CONFIG_P54_SPI=m
CONFIG_P54_SPI_DEFAULT_EEPROM=y
CONFIG_P54_LEDS=y
CONFIG_WLAN_VENDOR_MARVELL=y
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_SPI=m
CONFIG_LIBERTAS_DEBUG=y
CONFIG_LIBERTAS_MESH=y
CONFIG_LIBERTAS_THINFIRM=m
CONFIG_LIBERTAS_THINFIRM_DEBUG=y
CONFIG_LIBERTAS_THINFIRM_USB=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_USB=m
CONFIG_WLAN_VENDOR_MEDIATEK=y
CONFIG_MT7601U=m
CONFIG_MT76_CORE=m
CONFIG_MT76_LEDS=y
CONFIG_MT76_USB=m
CONFIG_MT76_SDIO=m
CONFIG_MT76x02_LIB=m
CONFIG_MT76x02_USB=m
CONFIG_MT76_CONNAC_LIB=m
CONFIG_MT76x0_COMMON=m
CONFIG_MT76x0U=m
CONFIG_MT76x2_COMMON=m
CONFIG_MT76x2U=m
CONFIG_MT7615_COMMON=m
CONFIG_MT7663_USB_SDIO_COMMON=m
CONFIG_MT7663U=m
CONFIG_MT7663S=m
CONFIG_MT7921_COMMON=m
CONFIG_MT7921S=m
CONFIG_MT7921U=m
CONFIG_WLAN_VENDOR_MICROCHIP=y
CONFIG_WILC1000=m
CONFIG_WILC1000_SDIO=m
CONFIG_WILC1000_SPI=m
CONFIG_WILC1000_HW_OOB_INTR=y
CONFIG_WLAN_VENDOR_PURELIFI=y
CONFIG_PLFXLC=m
CONFIG_WLAN_VENDOR_RALINK=y
CONFIG_WLAN_VENDOR_REALTEK=y
CONFIG_RTL8187=m
CONFIG_RTL8187_LEDS=y
CONFIG_RTL_CARDS=m
CONFIG_RTL8192CU=m
CONFIG_RTLWIFI=m
CONFIG_RTLWIFI_USB=m
CONFIG_RTLWIFI_DEBUG=y
CONFIG_RTL8192C_COMMON=m
CONFIG_RTL8XXXU=m
CONFIG_RTL8XXXU_UNTESTED=y
CONFIG_RTW88=m
CONFIG_RTW89=m
CONFIG_WLAN_VENDOR_RSI=y
CONFIG_RSI_91X=m
CONFIG_RSI_DEBUGFS=y
CONFIG_RSI_SDIO=m
CONFIG_RSI_USB=m
CONFIG_RSI_COEX=y
CONFIG_WLAN_VENDOR_SILABS=y
CONFIG_WFX=m
CONFIG_WLAN_VENDOR_ST=y
CONFIG_CW1200=m
CONFIG_CW1200_WLAN_SDIO=m
CONFIG_CW1200_WLAN_SPI=m
CONFIG_WLAN_VENDOR_TI=y
CONFIG_WL1251=m
CONFIG_WL1251_SPI=m
CONFIG_WL1251_SDIO=m
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE=m
CONFIG_WLCORE_SPI=m
CONFIG_WLCORE_SDIO=m
CONFIG_WILINK_PLATFORM_DATA=y
CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_USB_ZD1201=m
CONFIG_ZD1211RW=m
CONFIG_ZD1211RW_DEBUG=y
CONFIG_WLAN_VENDOR_QUANTENNA=y
CONFIG_PCMCIA_RAYCS=m
CONFIG_PCMCIA_WL3501=m
CONFIG_MAC80211_HWSIM=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_VIRT_WIFI=m
CONFIG_WAN=y
CONFIG_HDLC=m
CONFIG_HDLC_RAW=m
CONFIG_HDLC_RAW_ETH=m
CONFIG_HDLC_CISCO=m
CONFIG_HDLC_FR=m
CONFIG_HDLC_PPP=m
CONFIG_HDLC_X25=m
CONFIG_FSL_UCC_HDLC=m
CONFIG_SLIC_DS26522=m
CONFIG_LAPBETHER=m
CONFIG_IEEE802154_DRIVERS=m
CONFIG_IEEE802154_FAKELB=m
CONFIG_IEEE802154_AT86RF230=m
CONFIG_IEEE802154_MRF24J40=m
CONFIG_IEEE802154_CC2520=m
CONFIG_IEEE802154_ATUSB=m
CONFIG_IEEE802154_ADF7242=m
CONFIG_IEEE802154_CA8210=m
CONFIG_IEEE802154_CA8210_DEBUGFS=y
CONFIG_IEEE802154_MCR20A=m
CONFIG_IEEE802154_HWSIM=m

#
# Wireless WAN
#
CONFIG_WWAN=m
CONFIG_WWAN_DEBUGFS=y
CONFIG_WWAN_HWSIM=m
CONFIG_MHI_WWAN_CTRL=m
CONFIG_MHI_WWAN_MBIM=m
CONFIG_QCOM_BAM_DMUX=m
CONFIG_RPMSG_WWAN_CTRL=m
# end of Wireless WAN

CONFIG_NETDEVSIM=m
CONFIG_NET_FAILOVER=m
CONFIG_ISDN=y
CONFIG_ISDN_CAPI=y
CONFIG_CAPI_TRACE=y
CONFIG_ISDN_CAPI_MIDDLEWARE=y
CONFIG_MISDN=m
CONFIG_MISDN_DSP=m
CONFIG_MISDN_L1OIP=m

#
# mISDN hardware drivers
#
CONFIG_MISDN_HFCUSB=m

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_LEDS=m
CONFIG_INPUT_FF_MEMLESS=m
CONFIG_INPUT_SPARSEKMAP=m
CONFIG_INPUT_MATRIXKMAP=m
CONFIG_INPUT_VIVALDIFMAP=m

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_EVBUG=m

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_ADP5588=m
CONFIG_KEYBOARD_ADP5589=m
CONFIG_KEYBOARD_ATKBD=m
CONFIG_KEYBOARD_QT1050=m
CONFIG_KEYBOARD_QT1070=m
CONFIG_KEYBOARD_QT2160=m
CONFIG_KEYBOARD_CLPS711X=m
CONFIG_KEYBOARD_DLINK_DIR685=m
CONFIG_KEYBOARD_LKKBD=m
CONFIG_KEYBOARD_EP93XX=m
CONFIG_KEYBOARD_GPIO=m
CONFIG_KEYBOARD_GPIO_POLLED=m
CONFIG_KEYBOARD_TCA6416=m
CONFIG_KEYBOARD_TCA8418=m
CONFIG_KEYBOARD_MATRIX=m
CONFIG_KEYBOARD_LM8323=m
CONFIG_KEYBOARD_LM8333=m
CONFIG_KEYBOARD_MAX7359=m
CONFIG_KEYBOARD_MCS=m
CONFIG_KEYBOARD_MPR121=m
CONFIG_KEYBOARD_SNVS_PWRKEY=m
CONFIG_KEYBOARD_IMX=m
CONFIG_KEYBOARD_IMX_SC_KEY=m
CONFIG_KEYBOARD_NEWTON=m
CONFIG_KEYBOARD_OPENCORES=m
CONFIG_KEYBOARD_PINEPHONE=m
CONFIG_KEYBOARD_PMIC8XXX=m
CONFIG_KEYBOARD_SAMSUNG=m
CONFIG_KEYBOARD_GOLDFISH_EVENTS=m
CONFIG_KEYBOARD_STOWAWAY=m
CONFIG_KEYBOARD_ST_KEYSCAN=m
CONFIG_KEYBOARD_SUNKBD=m
CONFIG_KEYBOARD_SH_KEYSC=m
CONFIG_KEYBOARD_STMPE=m
CONFIG_KEYBOARD_IQS62X=m
CONFIG_KEYBOARD_OMAP4=m
CONFIG_KEYBOARD_TM2_TOUCHKEY=m
CONFIG_KEYBOARD_XTKBD=m
CONFIG_KEYBOARD_CROS_EC=m
CONFIG_KEYBOARD_CAP11XX=m
CONFIG_KEYBOARD_BCM=m
CONFIG_KEYBOARD_MT6779=m
CONFIG_KEYBOARD_MTK_PMIC=m
CONFIG_KEYBOARD_CYPRESS_SF=m
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_BYD=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_ELANTECH_SMBUS=y
CONFIG_MOUSE_PS2_SENTELIC=y
CONFIG_MOUSE_PS2_TOUCHKIT=y
CONFIG_MOUSE_PS2_FOCALTECH=y
CONFIG_MOUSE_PS2_SMBUS=y
CONFIG_MOUSE_SERIAL=m
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_CYAPA=m
CONFIG_MOUSE_ELAN_I2C=m
CONFIG_MOUSE_ELAN_I2C_I2C=y
CONFIG_MOUSE_ELAN_I2C_SMBUS=y
CONFIG_MOUSE_VSXXXAA=m
CONFIG_MOUSE_GPIO=m
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_MOUSE_SYNAPTICS_USB=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=m
CONFIG_JOYSTICK_A3D=m
CONFIG_JOYSTICK_ADC=m
CONFIG_JOYSTICK_ADI=m
CONFIG_JOYSTICK_COBRA=m
CONFIG_JOYSTICK_GF2K=m
CONFIG_JOYSTICK_GRIP=m
CONFIG_JOYSTICK_GRIP_MP=m
CONFIG_JOYSTICK_GUILLEMOT=m
CONFIG_JOYSTICK_INTERACT=m
CONFIG_JOYSTICK_SIDEWINDER=m
CONFIG_JOYSTICK_TMDC=m
CONFIG_JOYSTICK_IFORCE=m
CONFIG_JOYSTICK_IFORCE_USB=m
CONFIG_JOYSTICK_IFORCE_232=m
CONFIG_JOYSTICK_WARRIOR=m
CONFIG_JOYSTICK_MAGELLAN=m
CONFIG_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
CONFIG_JOYSTICK_TWIDJOY=m
CONFIG_JOYSTICK_ZHENHUA=m
CONFIG_JOYSTICK_DB9=m
CONFIG_JOYSTICK_GAMECON=m
CONFIG_JOYSTICK_TURBOGRAFX=m
CONFIG_JOYSTICK_AS5011=m
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_JOYSTICK_XPAD=m
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_JOYSTICK_WALKERA0701=m
CONFIG_JOYSTICK_PSXPAD_SPI=m
CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
CONFIG_JOYSTICK_PXRC=m
CONFIG_JOYSTICK_QWIIC=m
CONFIG_JOYSTICK_FSIA6B=m
CONFIG_JOYSTICK_SENSEHAT=m
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=m
CONFIG_TABLET_USB_AIPTEK=m
CONFIG_TABLET_USB_HANWANG=m
CONFIG_TABLET_USB_KBTAB=m
CONFIG_TABLET_USB_PEGASUS=m
CONFIG_TABLET_SERIAL_WACOM4=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_AD7877=m
CONFIG_TOUCHSCREEN_AD7879=m
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_AD7879_SPI=m
CONFIG_TOUCHSCREEN_ADC=m
CONFIG_TOUCHSCREEN_AR1021_I2C=m
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y
CONFIG_TOUCHSCREEN_AUO_PIXCIR=m
CONFIG_TOUCHSCREEN_BU21013=m
CONFIG_TOUCHSCREEN_BU21029=m
CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m
CONFIG_TOUCHSCREEN_CY8CTMA140=m
CONFIG_TOUCHSCREEN_CY8CTMG110=m
CONFIG_TOUCHSCREEN_CYTTSP_CORE=m
CONFIG_TOUCHSCREEN_CYTTSP_I2C=m
CONFIG_TOUCHSCREEN_CYTTSP_SPI=m
CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m
CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m
CONFIG_TOUCHSCREEN_CYTTSP4_SPI=m
CONFIG_TOUCHSCREEN_DA9052=m
CONFIG_TOUCHSCREEN_DYNAPRO=m
CONFIG_TOUCHSCREEN_HAMPSHIRE=m
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_TOUCHSCREEN_EGALAX=m
CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m
CONFIG_TOUCHSCREEN_EXC3000=m
CONFIG_TOUCHSCREEN_FUJITSU=m
CONFIG_TOUCHSCREEN_GOODIX=m
CONFIG_TOUCHSCREEN_HIDEEP=m
CONFIG_TOUCHSCREEN_HYCON_HY46XX=m
CONFIG_TOUCHSCREEN_ILI210X=m
CONFIG_TOUCHSCREEN_ILITEK=m
CONFIG_TOUCHSCREEN_IPROC=m
CONFIG_TOUCHSCREEN_S6SY761=m
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_EKTF2127=m
CONFIG_TOUCHSCREEN_ELAN=m
CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_WACOM_W8001=m
CONFIG_TOUCHSCREEN_WACOM_I2C=m
CONFIG_TOUCHSCREEN_MAX11801=m
CONFIG_TOUCHSCREEN_MCS5000=m
CONFIG_TOUCHSCREEN_MMS114=m
CONFIG_TOUCHSCREEN_MELFAS_MIP4=m
CONFIG_TOUCHSCREEN_MSG2638=m
CONFIG_TOUCHSCREEN_MTOUCH=m
CONFIG_TOUCHSCREEN_IMAGIS=m
CONFIG_TOUCHSCREEN_IMX6UL_TSC=m
CONFIG_TOUCHSCREEN_INEXIO=m
CONFIG_TOUCHSCREEN_MK712=m
CONFIG_TOUCHSCREEN_PENMOUNT=m
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
CONFIG_TOUCHSCREEN_RASPBERRYPI_FW=m
CONFIG_TOUCHSCREEN_MIGOR=m
CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
CONFIG_TOUCHSCREEN_TOUCHWIN=m
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
CONFIG_TOUCHSCREEN_UCB1400=m
CONFIG_TOUCHSCREEN_PIXCIR=m
CONFIG_TOUCHSCREEN_WDT87XX_I2C=m
CONFIG_TOUCHSCREEN_WM831X=m
CONFIG_TOUCHSCREEN_WM97XX=m
CONFIG_TOUCHSCREEN_WM9705=y
CONFIG_TOUCHSCREEN_WM9712=y
CONFIG_TOUCHSCREEN_WM9713=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
CONFIG_TOUCHSCREEN_MXS_LRADC=m
CONFIG_TOUCHSCREEN_MX25=m
CONFIG_TOUCHSCREEN_MC13783=m
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
CONFIG_TOUCHSCREEN_TOUCHIT213=m
CONFIG_TOUCHSCREEN_TS4800=m
CONFIG_TOUCHSCREEN_TSC_SERIO=m
CONFIG_TOUCHSCREEN_TSC200X_CORE=m
CONFIG_TOUCHSCREEN_TSC2004=m
CONFIG_TOUCHSCREEN_TSC2005=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_TOUCHSCREEN_TSC2007_IIO=y
CONFIG_TOUCHSCREEN_PCAP=m
CONFIG_TOUCHSCREEN_RM_TS=m
CONFIG_TOUCHSCREEN_SILEAD=m
CONFIG_TOUCHSCREEN_SIS_I2C=m
CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_STMFTS=m
CONFIG_TOUCHSCREEN_STMPE=m
CONFIG_TOUCHSCREEN_SUN4I=m
CONFIG_TOUCHSCREEN_SURFACE3_SPI=m
CONFIG_TOUCHSCREEN_SX8654=m
CONFIG_TOUCHSCREEN_TPS6507X=m
CONFIG_TOUCHSCREEN_ZET6223=m
CONFIG_TOUCHSCREEN_ZFORCE=m
CONFIG_TOUCHSCREEN_COLIBRI_VF50=m
CONFIG_TOUCHSCREEN_ROHM_BU21023=m
CONFIG_TOUCHSCREEN_IQS5XX=m
CONFIG_TOUCHSCREEN_ZINITIX=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_88PM80X_ONKEY=m
CONFIG_INPUT_AD714X=m
CONFIG_INPUT_AD714X_I2C=m
CONFIG_INPUT_AD714X_SPI=m
CONFIG_INPUT_ARIEL_PWRBUTTON=m
CONFIG_INPUT_ARIZONA_HAPTICS=m
CONFIG_INPUT_ATC260X_ONKEY=m
CONFIG_INPUT_ATMEL_CAPTOUCH=m
CONFIG_INPUT_BMA150=m
CONFIG_INPUT_E3X0_BUTTON=m
CONFIG_INPUT_PM8941_PWRKEY=m
CONFIG_INPUT_PM8XXX_VIBRATOR=m
CONFIG_INPUT_PMIC8XXX_PWRKEY=m
CONFIG_INPUT_MAX77650_ONKEY=m
CONFIG_INPUT_MAX77693_HAPTIC=m
CONFIG_INPUT_MC13783_PWRBUTTON=m
CONFIG_INPUT_MMA8450=m
CONFIG_INPUT_GPIO_BEEPER=m
CONFIG_INPUT_GPIO_DECODER=m
CONFIG_INPUT_GPIO_VIBRA=m
CONFIG_INPUT_CPCAP_PWRBUTTON=m
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_KEYSPAN_REMOTE=m
CONFIG_INPUT_KXTJ9=m
CONFIG_INPUT_POWERMATE=m
CONFIG_INPUT_YEALINK=m
CONFIG_INPUT_CM109=m
CONFIG_INPUT_REGULATOR_HAPTIC=m
CONFIG_INPUT_RETU_PWRBUTTON=m
CONFIG_INPUT_TPS65218_PWRBUTTON=m
CONFIG_INPUT_AXP20X_PEK=m
CONFIG_INPUT_UINPUT=m
CONFIG_INPUT_PCF50633_PMU=m
CONFIG_INPUT_PCF8574=m
CONFIG_INPUT_PWM_BEEPER=m
CONFIG_INPUT_PWM_VIBRA=m
CONFIG_INPUT_RK805_PWRKEY=m
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
CONFIG_INPUT_DA7280_HAPTICS=m
CONFIG_INPUT_DA9052_ONKEY=m
CONFIG_INPUT_DA9063_ONKEY=m
CONFIG_INPUT_WM831X_ON=m
CONFIG_INPUT_PCAP=m
CONFIG_INPUT_ADXL34X=m
CONFIG_INPUT_ADXL34X_I2C=m
CONFIG_INPUT_ADXL34X_SPI=m
CONFIG_INPUT_IBM_PANEL=m
CONFIG_INPUT_IMS_PCU=m
CONFIG_INPUT_IQS269A=m
CONFIG_INPUT_IQS626A=m
CONFIG_INPUT_IQS7222=m
CONFIG_INPUT_CMA3000=m
CONFIG_INPUT_CMA3000_I2C=m
CONFIG_INPUT_DRV260X_HAPTICS=m
CONFIG_INPUT_DRV2665_HAPTICS=m
CONFIG_INPUT_DRV2667_HAPTICS=m
CONFIG_INPUT_HISI_POWERKEY=m
CONFIG_INPUT_RAVE_SP_PWRBUTTON=m
CONFIG_INPUT_SC27XX_VIBRA=m
CONFIG_INPUT_RT5120_PWRKEY=m
CONFIG_RMI4_CORE=m
CONFIG_RMI4_I2C=m
CONFIG_RMI4_SPI=m
CONFIG_RMI4_SMB=m
CONFIG_RMI4_F03=y
CONFIG_RMI4_F03_SERIO=m
CONFIG_RMI4_2D_SENSOR=y
CONFIG_RMI4_F11=y
CONFIG_RMI4_F12=y
CONFIG_RMI4_F30=y
CONFIG_RMI4_F34=y
CONFIG_RMI4_F3A=y
CONFIG_RMI4_F54=y
CONFIG_RMI4_F55=y

#
# Hardware I/O ports
#
CONFIG_SERIO=m
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_PARKBD=m
CONFIG_SERIO_LIBPS2=m
CONFIG_SERIO_RAW=m
CONFIG_SERIO_ALTERA_PS2=m
CONFIG_SERIO_PS2MULT=m
CONFIG_SERIO_ARC_PS2=m
CONFIG_SERIO_APBPS2=m
CONFIG_SERIO_OLPC_APSP=m
CONFIG_SERIO_SUN4I_PS2=m
CONFIG_SERIO_GPIO_PS2=m
CONFIG_USERIO=m
CONFIG_GAMEPORT=m
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
# end of Hardware I/O ports
# end of Input device support

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LDISC_AUTOLOAD=y

#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=m
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_16550A_VARIANTS=y
CONFIG_SERIAL_8250_FINTEK=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_MEN_MCB=m
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_ASPEED_VUART=m
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_DWLIB=y
CONFIG_SERIAL_8250_BCM2835AUX=m
CONFIG_SERIAL_8250_DW=m
CONFIG_SERIAL_8250_EM=m
CONFIG_SERIAL_8250_IOC3=m
CONFIG_SERIAL_8250_RT288X=y
CONFIG_SERIAL_8250_OMAP=m
CONFIG_SERIAL_8250_LPC18XX=m
CONFIG_SERIAL_8250_MT6577=m
CONFIG_SERIAL_8250_UNIPHIER=m
CONFIG_SERIAL_8250_INGENIC=m
CONFIG_SERIAL_8250_PXA=m
CONFIG_SERIAL_8250_TEGRA=m
CONFIG_SERIAL_8250_BCM7271=m
CONFIG_SERIAL_OF_PLATFORM=m

#
# Non-8250 serial port support
#
CONFIG_SERIAL_AMBA_PL010=m
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_SERIAL_ATMEL_PDC=y
CONFIG_SERIAL_ATMEL_TTYAT=y
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_SERIAL_MESON=m
CONFIG_SERIAL_MESON_CONSOLE=y
CONFIG_SERIAL_CLPS711X=m
CONFIG_SERIAL_SAMSUNG=m
CONFIG_SERIAL_SAMSUNG_UARTS_4=y
CONFIG_SERIAL_SAMSUNG_UARTS=4
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_TEGRA=m
CONFIG_SERIAL_TEGRA_TCU=m
CONFIG_SERIAL_MAX3100=m
CONFIG_SERIAL_MAX310X=m
CONFIG_SERIAL_IMX=m
CONFIG_SERIAL_IMX_CONSOLE=m
CONFIG_SERIAL_IMX_EARLYCON=y
CONFIG_SERIAL_UARTLITE=m
CONFIG_SERIAL_UARTLITE_NR_UARTS=1
CONFIG_SERIAL_SH_SCI=m
CONFIG_SERIAL_SH_SCI_NR_UARTS=10
CONFIG_SERIAL_HS_LPC32XX=m
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_MSM=m
CONFIG_SERIAL_QCOM_GENI=m
CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
CONFIG_SERIAL_VT8500=y
CONFIG_SERIAL_VT8500_CONSOLE=y
CONFIG_SERIAL_OMAP=m
CONFIG_SERIAL_SIFIVE=m
CONFIG_SERIAL_LANTIQ=m
CONFIG_SERIAL_QE=m
CONFIG_SERIAL_SCCNXP=m
CONFIG_SERIAL_SC16IS7XX_CORE=m
CONFIG_SERIAL_SC16IS7XX=m
CONFIG_SERIAL_SC16IS7XX_I2C=y
CONFIG_SERIAL_SC16IS7XX_SPI=y
CONFIG_SERIAL_TIMBERDALE=m
CONFIG_SERIAL_BCM63XX=m
CONFIG_SERIAL_ALTERA_JTAGUART=m
CONFIG_SERIAL_ALTERA_UART=m
CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
CONFIG_SERIAL_MXS_AUART=m
CONFIG_SERIAL_XILINX_PS_UART=m
CONFIG_SERIAL_MPS2_UART_CONSOLE=y
CONFIG_SERIAL_MPS2_UART=y
CONFIG_SERIAL_ARC=m
CONFIG_SERIAL_ARC_NR_PORTS=1
CONFIG_SERIAL_FSL_LINFLEXUART=m
CONFIG_SERIAL_CONEXANT_DIGICOLOR=m
CONFIG_SERIAL_ST_ASC=m
CONFIG_SERIAL_MEN_Z135=m
CONFIG_SERIAL_SPRD=m
CONFIG_SERIAL_STM32=m
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_MVEBU_CONSOLE=y
CONFIG_SERIAL_OWL=m
CONFIG_SERIAL_RDA=y
CONFIG_SERIAL_RDA_CONSOLE=y
CONFIG_SERIAL_MILBEAUT_USIO=m
CONFIG_SERIAL_MILBEAUT_USIO_PORTS=4
CONFIG_SERIAL_LITEUART=m
CONFIG_SERIAL_LITEUART_MAX_PORTS=1
CONFIG_SERIAL_SUNPLUS=m
CONFIG_SERIAL_SUNPLUS_CONSOLE=y
# end of Serial drivers

CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_N_HDLC=m
CONFIG_N_GSM=m
CONFIG_NULL_TTY=m
CONFIG_HVC_DRIVER=y
CONFIG_RPMSG_TTY=m
CONFIG_SERIAL_DEV_BUS=m
CONFIG_TTY_PRINTK=m
CONFIG_TTY_PRINTK_LEVEL=6
CONFIG_PRINTER=m
CONFIG_LP_CONSOLE=y
CONFIG_PPDEV=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_IPMI_HANDLER=m
CONFIG_IPMI_PLAT_DATA=y
CONFIG_IPMI_PANIC_EVENT=y
CONFIG_IPMI_PANIC_STRING=y
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_IPMI_SSIF=m
CONFIG_IPMI_IPMB=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
CONFIG_IPMI_KCS_BMC=m
CONFIG_ASPEED_KCS_IPMI_BMC=m
CONFIG_NPCM7XX_KCS_IPMI_BMC=m
CONFIG_IPMI_KCS_BMC_CDEV_IPMI=m
CONFIG_IPMI_KCS_BMC_SERIO=m
CONFIG_ASPEED_BT_IPMI_BMC=m
CONFIG_IPMB_DEVICE_INTERFACE=m
CONFIG_HW_RANDOM=m
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_HW_RANDOM_ATMEL=m
CONFIG_HW_RANDOM_BA431=m
CONFIG_HW_RANDOM_BCM2835=m
CONFIG_HW_RANDOM_IPROC_RNG200=m
CONFIG_HW_RANDOM_IXP4XX=m
CONFIG_HW_RANDOM_OMAP=m
CONFIG_HW_RANDOM_OMAP3_ROM=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_HW_RANDOM_IMX_RNGC=m
CONFIG_HW_RANDOM_NOMADIK=m
CONFIG_HW_RANDOM_STM32=m
CONFIG_HW_RANDOM_POLARFIRE_SOC=m
CONFIG_HW_RANDOM_MESON=m
CONFIG_HW_RANDOM_MTK=m
CONFIG_HW_RANDOM_EXYNOS=m
CONFIG_HW_RANDOM_NPCM=m
CONFIG_HW_RANDOM_KEYSTONE=m
CONFIG_HW_RANDOM_CCTRNG=m
CONFIG_HW_RANDOM_XIPHERA=m

#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=m
CONFIG_CARDMAN_4000=m
CONFIG_CARDMAN_4040=m
CONFIG_SCR24X=m
CONFIG_IPWIRELESS=m
# end of PCMCIA character devices

CONFIG_DEVMEM=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_CORE=m
CONFIG_TCG_TIS=m
CONFIG_TCG_TIS_SPI=m
CONFIG_TCG_TIS_SPI_CR50=y
CONFIG_TCG_TIS_I2C=m
CONFIG_TCG_TIS_SYNQUACER=m
CONFIG_TCG_TIS_I2C_CR50=m
CONFIG_TCG_TIS_I2C_ATMEL=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_TCG_TIS_I2C_NUVOTON=m
CONFIG_TCG_VTPM_PROXY=m
CONFIG_TCG_TIS_ST33ZP24=m
CONFIG_TCG_TIS_ST33ZP24_I2C=m
CONFIG_TCG_TIS_ST33ZP24_SPI=m
CONFIG_XILLYBUS_CLASS=m
CONFIG_XILLYBUS=m
CONFIG_XILLYUSB=m
CONFIG_RANDOM_TRUST_CPU=y
CONFIG_RANDOM_TRUST_BOOTLOADER=y
# end of Character devices

#
# I2C support
#
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_MUX=m

#
# Multiplexer I2C Chip support
#
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_GPIO=m
CONFIG_I2C_MUX_GPMUX=m
CONFIG_I2C_MUX_LTC4306=m
CONFIG_I2C_MUX_PCA9541=m
CONFIG_I2C_MUX_PCA954x=m
CONFIG_I2C_MUX_PINCTRL=m
CONFIG_I2C_MUX_REG=m
CONFIG_I2C_DEMUX_PINCTRL=m
CONFIG_I2C_MUX_MLXCPLD=m
# end of Multiplexer I2C Chip support

CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=m
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOPCA=m

#
# I2C Hardware Bus support
#
CONFIG_I2C_HIX5HD2=m

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_ALTERA=m
CONFIG_I2C_ASPEED=m
CONFIG_I2C_AT91=m
CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL=m
CONFIG_I2C_AXXIA=m
CONFIG_I2C_BCM2835=m
CONFIG_I2C_BCM_IPROC=m
CONFIG_I2C_BCM_KONA=m
CONFIG_I2C_BRCMSTB=m
CONFIG_I2C_CADENCE=m
CONFIG_I2C_CBUS_GPIO=m
CONFIG_I2C_DAVINCI=m
CONFIG_I2C_DESIGNWARE_CORE=m
CONFIG_I2C_DESIGNWARE_SLAVE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=m
CONFIG_I2C_DIGICOLOR=m
CONFIG_I2C_EMEV2=m
CONFIG_I2C_EXYNOS5=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_GPIO_FAULT_INJECTOR=y
CONFIG_I2C_HIGHLANDER=m
CONFIG_I2C_HISI=m
CONFIG_I2C_IMG=m
CONFIG_I2C_IMX=m
CONFIG_I2C_IMX_LPI2C=m
CONFIG_I2C_IOP3XX=m
CONFIG_I2C_JZ4780=m
CONFIG_I2C_KEMPLD=m
CONFIG_I2C_LPC2K=m
CONFIG_I2C_MESON=m
CONFIG_I2C_MICROCHIP_CORE=m
CONFIG_I2C_MT65XX=m
CONFIG_I2C_MT7621=m
CONFIG_I2C_MV64XXX=m
CONFIG_I2C_MXS=m
CONFIG_I2C_NPCM=m
CONFIG_I2C_OCORES=m
CONFIG_I2C_OMAP=m
CONFIG_I2C_OWL=m
CONFIG_I2C_APPLE=m
CONFIG_I2C_PCA_PLATFORM=m
CONFIG_I2C_PNX=m
CONFIG_I2C_PXA=m
CONFIG_I2C_PXA_SLAVE=y
CONFIG_I2C_QCOM_CCI=m
CONFIG_I2C_QCOM_GENI=m
CONFIG_I2C_QUP=m
CONFIG_I2C_RIIC=m
CONFIG_I2C_RK3X=m
CONFIG_I2C_RZV2M=m
CONFIG_I2C_S3C2410=m
CONFIG_I2C_SH_MOBILE=m
CONFIG_I2C_SIMTEC=m
CONFIG_I2C_ST=m
CONFIG_I2C_STM32F4=m
CONFIG_I2C_STM32F7=m
CONFIG_I2C_SUN6I_P2WI=m
CONFIG_I2C_SYNQUACER=m
CONFIG_I2C_TEGRA=m
CONFIG_I2C_TEGRA_BPMP=m
CONFIG_I2C_UNIPHIER=m
CONFIG_I2C_UNIPHIER_F=m
CONFIG_I2C_VERSATILE=m
CONFIG_I2C_WMT=m
CONFIG_I2C_XILINX=m
CONFIG_I2C_XLP9XX=m
CONFIG_I2C_RCAR=m

#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_DIOLAN_U2C=m
CONFIG_I2C_DLN2=m
CONFIG_I2C_CP2615=m
CONFIG_I2C_PARPORT=m
CONFIG_I2C_ROBOTFUZZ_OSIF=m
CONFIG_I2C_TAOS_EVM=m
CONFIG_I2C_TINY_USB=m
CONFIG_I2C_VIPERBOARD=m

#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_MLXCPLD=m
CONFIG_I2C_CROS_EC_TUNNEL=m
CONFIG_I2C_FSI=m
CONFIG_I2C_VIRTIO=m
# end of I2C Hardware Bus support

CONFIG_I2C_STUB=m
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=m
CONFIG_I2C_SLAVE_TESTUNIT=m
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
# end of I2C support

CONFIG_I3C=m
CONFIG_CDNS_I3C_MASTER=m
CONFIG_DW_I3C_MASTER=m
CONFIG_SVC_I3C_MASTER=m
CONFIG_MIPI_I3C_HCI=m
CONFIG_SPI=y
CONFIG_SPI_DEBUG=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y

#
# SPI Master Controller Drivers
#
CONFIG_SPI_ALTERA=m
CONFIG_SPI_ALTERA_CORE=m
CONFIG_SPI_ALTERA_DFL=m
CONFIG_SPI_AR934X=m
CONFIG_SPI_ATH79=m
CONFIG_SPI_ARMADA_3700=m
CONFIG_SPI_ASPEED_SMC=m
CONFIG_SPI_ATMEL=m
CONFIG_SPI_AT91_USART=m
CONFIG_SPI_ATMEL_QUADSPI=m
CONFIG_SPI_AXI_SPI_ENGINE=m
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
CONFIG_SPI_BCM63XX=m
CONFIG_SPI_BCM63XX_HSSPI=m
CONFIG_SPI_BCM_QSPI=m
CONFIG_SPI_BITBANG=m
CONFIG_SPI_BUTTERFLY=m
CONFIG_SPI_CADENCE=m
CONFIG_SPI_CADENCE_QUADSPI=m
CONFIG_SPI_CADENCE_XSPI=m
CONFIG_SPI_CLPS711X=m
CONFIG_SPI_DESIGNWARE=m
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_MMIO=m
CONFIG_SPI_DW_BT1=m
CONFIG_SPI_DW_BT1_DIRMAP=y
CONFIG_SPI_DLN2=m
CONFIG_SPI_EP93XX=m
CONFIG_SPI_FSI=m
CONFIG_SPI_FSL_LPSPI=m
CONFIG_SPI_FSL_QUADSPI=m
CONFIG_SPI_GXP=m
CONFIG_SPI_HISI_KUNPENG=m
CONFIG_SPI_HISI_SFC_V3XX=m
CONFIG_SPI_NXP_FLEXSPI=m
CONFIG_SPI_GPIO=m
CONFIG_SPI_IMG_SPFI=m
CONFIG_SPI_IMX=m
CONFIG_SPI_INGENIC=m
CONFIG_SPI_INTEL=m
CONFIG_SPI_INTEL_PLATFORM=m
CONFIG_SPI_JCORE=m
CONFIG_SPI_LM70_LLP=m
CONFIG_SPI_LP8841_RTC=m
CONFIG_SPI_FSL_LIB=m
CONFIG_SPI_FSL_SPI=m
CONFIG_SPI_FSL_DSPI=m
CONFIG_SPI_MESON_SPICC=m
CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_MICROCHIP_CORE=m
CONFIG_SPI_MICROCHIP_CORE_QSPI=m
CONFIG_SPI_MT65XX=m
CONFIG_SPI_MT7621=m
CONFIG_SPI_MTK_NOR=m
CONFIG_SPI_MTK_SNFI=m
CONFIG_SPI_NPCM_FIU=m
CONFIG_SPI_NPCM_PSPI=m
CONFIG_SPI_LANTIQ_SSC=m
CONFIG_SPI_OC_TINY=m
CONFIG_SPI_OMAP24XX=m
CONFIG_SPI_TI_QSPI=m
CONFIG_SPI_OMAP_100K=m
CONFIG_SPI_ORION=m
CONFIG_SPI_PIC32=m
CONFIG_SPI_PIC32_SQI=m
CONFIG_SPI_PXA2XX=m
CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_RPCIF=m
CONFIG_SPI_RSPI=m
CONFIG_SPI_QUP=m
CONFIG_SPI_QCOM_GENI=m
CONFIG_SPI_S3C64XX=m
CONFIG_SPI_SC18IS602=m
CONFIG_SPI_SH_MSIOF=m
CONFIG_SPI_SH=m
CONFIG_SPI_SH_SCI=m
CONFIG_SPI_SH_HSPI=m
CONFIG_SPI_SIFIVE=m
CONFIG_SPI_SLAVE_MT27XX=m
CONFIG_SPI_SPRD=m
CONFIG_SPI_SPRD_ADI=m
CONFIG_SPI_STM32=m
CONFIG_SPI_STM32_QSPI=m
CONFIG_SPI_ST_SSC4=m
CONFIG_SPI_SUN4I=m
CONFIG_SPI_SUN6I=m
CONFIG_SPI_SUNPLUS_SP7021=m
CONFIG_SPI_SYNQUACER=m
CONFIG_SPI_MXIC=m
CONFIG_SPI_TEGRA210_QUAD=m
CONFIG_SPI_TEGRA114=m
CONFIG_SPI_TEGRA20_SFLASH=m
CONFIG_SPI_TEGRA20_SLINK=m
CONFIG_SPI_UNIPHIER=m
CONFIG_SPI_XCOMM=m
CONFIG_SPI_XILINX=m
CONFIG_SPI_XLP=m
CONFIG_SPI_XTENSA_XTFPGA=m
CONFIG_SPI_ZYNQ_QSPI=m
CONFIG_SPI_ZYNQMP_GQSPI=m
CONFIG_SPI_AMD=m

#
# SPI Multiplexer support
#
CONFIG_SPI_MUX=m

#
# SPI Protocol Masters
#
CONFIG_SPI_SPIDEV=m
CONFIG_SPI_LOOPBACK_TEST=m
CONFIG_SPI_TLE62X0=m
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=m
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m
CONFIG_SPI_DYNAMIC=y
CONFIG_SPMI=m
CONFIG_SPMI_HISI3670=m
CONFIG_SPMI_MSM_PMIC_ARB=m
CONFIG_SPMI_MTK_PMIF=m
CONFIG_HSI=m
CONFIG_HSI_BOARDINFO=y

#
# HSI controllers
#

#
# HSI clients
#
CONFIG_HSI_CHAR=m
CONFIG_PPS=m
CONFIG_PPS_DEBUG=y

#
# PPS clients support
#
CONFIG_PPS_CLIENT_KTIMER=m
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PPS_CLIENT_PARPORT=m
CONFIG_PPS_CLIENT_GPIO=m

#
# PPS generators support
#

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=m
CONFIG_PTP_1588_CLOCK_OPTIONAL=m
CONFIG_PTP_1588_CLOCK_DTE=m
CONFIG_PTP_1588_CLOCK_QORIQ=m
CONFIG_DP83640_PHY=m
CONFIG_PTP_1588_CLOCK_INES=m
CONFIG_PTP_1588_CLOCK_IDT82P33=m
CONFIG_PTP_1588_CLOCK_IDTCM=m
# end of PTP clock support

CONFIG_PINCTRL=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_PINMUX=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_PINCONF=y
CONFIG_GENERIC_PINCONF=y
CONFIG_DEBUG_PINCTRL=y
CONFIG_PINCTRL_AMD=y
CONFIG_PINCTRL_AT91PIO4=y
CONFIG_PINCTRL_AXP209=m
CONFIG_PINCTRL_BM1880=y
CONFIG_PINCTRL_CY8C95X0=m
CONFIG_PINCTRL_DA850_PUPD=m
CONFIG_PINCTRL_DA9062=m
CONFIG_PINCTRL_EQUILIBRIUM=m
CONFIG_PINCTRL_INGENIC=y
CONFIG_PINCTRL_LPC18XX=y
CONFIG_PINCTRL_MCP23S08_I2C=m
CONFIG_PINCTRL_MCP23S08_SPI=m
CONFIG_PINCTRL_MCP23S08=m
CONFIG_PINCTRL_MICROCHIP_SGPIO=m
CONFIG_PINCTRL_OCELOT=m
CONFIG_PINCTRL_PISTACHIO=y
CONFIG_PINCTRL_RK805=m
CONFIG_PINCTRL_ROCKCHIP=m
CONFIG_PINCTRL_SINGLE=m
CONFIG_PINCTRL_STMFX=m
CONFIG_PINCTRL_OWL=y
CONFIG_PINCTRL_S500=y
CONFIG_PINCTRL_S700=y
CONFIG_PINCTRL_S900=y
CONFIG_PINCTRL_ASPEED=y
CONFIG_PINCTRL_ASPEED_G4=y
CONFIG_PINCTRL_ASPEED_G5=y
CONFIG_PINCTRL_ASPEED_G6=y
CONFIG_PINCTRL_BCM281XX=y
CONFIG_PINCTRL_BCM2835=m
CONFIG_PINCTRL_BCM4908=m
CONFIG_PINCTRL_BCM63XX=y
CONFIG_PINCTRL_BCM6318=y
CONFIG_PINCTRL_BCM6328=y
CONFIG_PINCTRL_BCM6358=y
CONFIG_PINCTRL_BCM6362=y
CONFIG_PINCTRL_BCM6368=y
CONFIG_PINCTRL_BCM63268=y
CONFIG_PINCTRL_IPROC_GPIO=y
CONFIG_PINCTRL_CYGNUS_MUX=y
CONFIG_PINCTRL_NS=y
CONFIG_PINCTRL_NSP_GPIO=y
CONFIG_PINCTRL_NS2_MUX=y
CONFIG_PINCTRL_NSP_MUX=y
CONFIG_PINCTRL_BERLIN=y
CONFIG_PINCTRL_AS370=y
CONFIG_PINCTRL_BERLIN_BG4CT=y
CONFIG_PINCTRL_MADERA=m
CONFIG_PINCTRL_CS47L15=y
CONFIG_PINCTRL_CS47L35=y
CONFIG_PINCTRL_CS47L85=y
CONFIG_PINCTRL_CS47L90=y
CONFIG_PINCTRL_CS47L92=y
CONFIG_PINCTRL_IMX=m
CONFIG_PINCTRL_IMX8MM=m
CONFIG_PINCTRL_IMX8MN=m
CONFIG_PINCTRL_IMX8MP=m
CONFIG_PINCTRL_IMX8MQ=m

#
# Intel pinctrl drivers
#
# end of Intel pinctrl drivers

#
# MediaTek pinctrl drivers
#
CONFIG_EINT_MTK=y
CONFIG_PINCTRL_MTK=y
CONFIG_PINCTRL_MTK_V2=y
CONFIG_PINCTRL_MTK_MOORE=y
CONFIG_PINCTRL_MTK_PARIS=y
CONFIG_PINCTRL_MT2701=y
CONFIG_PINCTRL_MT7623=y
CONFIG_PINCTRL_MT7629=y
CONFIG_PINCTRL_MT8135=y
CONFIG_PINCTRL_MT8127=y
CONFIG_PINCTRL_MT2712=y
CONFIG_PINCTRL_MT6765=m
CONFIG_PINCTRL_MT6779=m
CONFIG_PINCTRL_MT6795=y
CONFIG_PINCTRL_MT6797=y
CONFIG_PINCTRL_MT7622=y
CONFIG_PINCTRL_MT7986=y
CONFIG_PINCTRL_MT8167=y
CONFIG_PINCTRL_MT8173=y
CONFIG_PINCTRL_MT8183=y
CONFIG_PINCTRL_MT8186=y
CONFIG_PINCTRL_MT8188=y
CONFIG_PINCTRL_MT8192=y
CONFIG_PINCTRL_MT8195=y
CONFIG_PINCTRL_MT8365=y
CONFIG_PINCTRL_MT8516=y
CONFIG_PINCTRL_MT6397=y
# end of MediaTek pinctrl drivers

CONFIG_PINCTRL_MESON=m
CONFIG_PINCTRL_WPCM450=m
CONFIG_PINCTRL_NPCM7XX=y
CONFIG_PINCTRL_PXA=y
CONFIG_PINCTRL_PXA25X=m
CONFIG_PINCTRL_PXA27X=m
CONFIG_PINCTRL_MSM=m
CONFIG_PINCTRL_APQ8064=m
CONFIG_PINCTRL_APQ8084=m
CONFIG_PINCTRL_IPQ4019=m
CONFIG_PINCTRL_IPQ8064=m
CONFIG_PINCTRL_IPQ8074=m
CONFIG_PINCTRL_IPQ6018=m
CONFIG_PINCTRL_MSM8226=m
CONFIG_PINCTRL_MSM8660=m
CONFIG_PINCTRL_MSM8960=m
CONFIG_PINCTRL_MDM9607=m
CONFIG_PINCTRL_MDM9615=m
CONFIG_PINCTRL_MSM8X74=m
CONFIG_PINCTRL_MSM8909=m
CONFIG_PINCTRL_MSM8916=m
CONFIG_PINCTRL_MSM8953=m
CONFIG_PINCTRL_MSM8976=m
CONFIG_PINCTRL_MSM8994=m
CONFIG_PINCTRL_MSM8996=m
CONFIG_PINCTRL_MSM8998=m
CONFIG_PINCTRL_QCM2290=m
CONFIG_PINCTRL_QCS404=m
CONFIG_PINCTRL_QCOM_SPMI_PMIC=m
CONFIG_PINCTRL_QCOM_SSBI_PMIC=m
CONFIG_PINCTRL_SC7180=m
CONFIG_PINCTRL_SC7280=m
CONFIG_PINCTRL_SC7280_LPASS_LPI=m
CONFIG_PINCTRL_SC8180X=m
CONFIG_PINCTRL_SC8280XP=m
CONFIG_PINCTRL_SDM660=m
CONFIG_PINCTRL_SDM845=m
CONFIG_PINCTRL_SDX55=m
CONFIG_PINCTRL_SM6115=m
CONFIG_PINCTRL_SM6125=m
CONFIG_PINCTRL_SM6350=m
CONFIG_PINCTRL_SM6375=m
CONFIG_PINCTRL_SDX65=m
CONFIG_PINCTRL_SM8150=m
CONFIG_PINCTRL_SM8250=m
CONFIG_PINCTRL_SM8250_LPASS_LPI=m
CONFIG_PINCTRL_SM8350=m
CONFIG_PINCTRL_SM8450=m
CONFIG_PINCTRL_SM8450_LPASS_LPI=m
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
CONFIG_PINCTRL_LPASS_LPI=m

#
# Renesas pinctrl drivers
#
CONFIG_PINCTRL_RENESAS=y
CONFIG_PINCTRL_SH_PFC=y
CONFIG_PINCTRL_SH_PFC_GPIO=y
CONFIG_PINCTRL_SH_FUNC_GPIO=y
CONFIG_PINCTRL_PFC_EMEV2=y
CONFIG_PINCTRL_PFC_R8A77995=y
CONFIG_PINCTRL_PFC_R8A7794=y
CONFIG_PINCTRL_PFC_R8A77990=y
CONFIG_PINCTRL_PFC_R8A7779=y
CONFIG_PINCTRL_PFC_R8A7790=y
CONFIG_PINCTRL_PFC_R8A77950=y
CONFIG_PINCTRL_PFC_R8A77951=y
CONFIG_PINCTRL_PFC_R8A7778=y
CONFIG_PINCTRL_PFC_R8A7793=y
CONFIG_PINCTRL_PFC_R8A7791=y
CONFIG_PINCTRL_PFC_R8A77965=y
CONFIG_PINCTRL_PFC_R8A77960=y
CONFIG_PINCTRL_PFC_R8A77961=y
CONFIG_PINCTRL_PFC_R8A779F0=y
CONFIG_PINCTRL_PFC_R8A7792=y
CONFIG_PINCTRL_PFC_R8A77980=y
CONFIG_PINCTRL_PFC_R8A77970=y
CONFIG_PINCTRL_PFC_R8A779A0=y
CONFIG_PINCTRL_PFC_R8A779G0=y
CONFIG_PINCTRL_PFC_R8A7740=y
CONFIG_PINCTRL_PFC_R8A73A4=y
CONFIG_PINCTRL_RZA1=y
CONFIG_PINCTRL_RZA2=y
CONFIG_PINCTRL_RZG2L=y
CONFIG_PINCTRL_PFC_R8A77470=y
CONFIG_PINCTRL_PFC_R8A7745=y
CONFIG_PINCTRL_PFC_R8A7742=y
CONFIG_PINCTRL_PFC_R8A7743=y
CONFIG_PINCTRL_PFC_R8A7744=y
CONFIG_PINCTRL_PFC_R8A774C0=y
CONFIG_PINCTRL_PFC_R8A774E1=y
CONFIG_PINCTRL_PFC_R8A774A1=y
CONFIG_PINCTRL_PFC_R8A774B1=y
CONFIG_PINCTRL_RZN1=y
CONFIG_PINCTRL_RZV2M=y
CONFIG_PINCTRL_PFC_SH7203=y
CONFIG_PINCTRL_PFC_SH7264=y
CONFIG_PINCTRL_PFC_SH7269=y
CONFIG_PINCTRL_PFC_SH7720=y
CONFIG_PINCTRL_PFC_SH7722=y
CONFIG_PINCTRL_PFC_SH7734=y
CONFIG_PINCTRL_PFC_SH7757=y
CONFIG_PINCTRL_PFC_SH7785=y
CONFIG_PINCTRL_PFC_SH7786=y
CONFIG_PINCTRL_PFC_SH73A0=y
CONFIG_PINCTRL_PFC_SH7723=y
CONFIG_PINCTRL_PFC_SH7724=y
CONFIG_PINCTRL_PFC_SHX3=y
# end of Renesas pinctrl drivers

CONFIG_PINCTRL_SAMSUNG=y
CONFIG_PINCTRL_EXYNOS=y
CONFIG_PINCTRL_EXYNOS_ARM=y
CONFIG_PINCTRL_EXYNOS_ARM64=y
CONFIG_PINCTRL_S3C24XX=y
CONFIG_PINCTRL_S3C64XX=y
CONFIG_PINCTRL_SPRD=m
CONFIG_PINCTRL_SPRD_SC9860=m
CONFIG_PINCTRL_STARFIVE_JH7100=m
CONFIG_PINCTRL_STM32=y
CONFIG_PINCTRL_STM32F429=y
CONFIG_PINCTRL_STM32F469=y
CONFIG_PINCTRL_STM32F746=y
CONFIG_PINCTRL_STM32F769=y
CONFIG_PINCTRL_STM32H743=y
CONFIG_PINCTRL_STM32MP135=y
CONFIG_PINCTRL_STM32MP157=y
CONFIG_PINCTRL_TI_IODELAY=m
CONFIG_PINCTRL_UNIPHIER=y
CONFIG_PINCTRL_UNIPHIER_LD4=y
CONFIG_PINCTRL_UNIPHIER_PRO4=y
CONFIG_PINCTRL_UNIPHIER_SLD8=y
CONFIG_PINCTRL_UNIPHIER_PRO5=y
CONFIG_PINCTRL_UNIPHIER_PXS2=y
CONFIG_PINCTRL_UNIPHIER_LD6B=y
CONFIG_PINCTRL_UNIPHIER_LD11=y
CONFIG_PINCTRL_UNIPHIER_LD20=y
CONFIG_PINCTRL_UNIPHIER_PXS3=y
CONFIG_PINCTRL_UNIPHIER_NX1=y
CONFIG_PINCTRL_VISCONTI=y
CONFIG_PINCTRL_TMPV7700=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=512
CONFIG_OF_GPIO=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_CDEV_V1=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_REGMAP=y
CONFIG_GPIO_MAX730X=m

#
# Memory mapped GPIO drivers
#
CONFIG_GPIO_74XX_MMIO=m
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_ASPEED=m
CONFIG_GPIO_ASPEED_SGPIO=y
CONFIG_GPIO_ATH79=m
CONFIG_GPIO_RASPBERRYPI_EXP=m
CONFIG_GPIO_BCM_KONA=y
CONFIG_GPIO_BCM_XGS_IPROC=m
CONFIG_GPIO_BRCMSTB=m
CONFIG_GPIO_CADENCE=m
CONFIG_GPIO_CLPS711X=m
CONFIG_GPIO_DWAPB=m
CONFIG_GPIO_EIC_SPRD=m
CONFIG_GPIO_EM=m
CONFIG_GPIO_FTGPIO010=y
CONFIG_GPIO_GENERIC_PLATFORM=m
CONFIG_GPIO_GRGPIO=m
CONFIG_GPIO_HISI=m
CONFIG_GPIO_HLWD=m
CONFIG_GPIO_IMX_SCU=y
CONFIG_GPIO_IOP=m
CONFIG_GPIO_LOGICVC=m
CONFIG_GPIO_LPC18XX=m
CONFIG_GPIO_LPC32XX=m
CONFIG_GPIO_MB86S7X=m
CONFIG_GPIO_MENZ127=m
CONFIG_GPIO_MPC8XXX=y
CONFIG_GPIO_MT7621=y
CONFIG_GPIO_MXC=m
CONFIG_GPIO_MXS=y
CONFIG_GPIO_PMIC_EIC_SPRD=m
CONFIG_GPIO_PXA=y
CONFIG_GPIO_RCAR=m
CONFIG_GPIO_RDA=y
CONFIG_GPIO_ROCKCHIP=m
CONFIG_GPIO_SAMA5D2_PIOBU=m
CONFIG_GPIO_SIFIVE=y
CONFIG_GPIO_SIOX=m
CONFIG_GPIO_SNPS_CREG=y
CONFIG_GPIO_SPRD=m
CONFIG_GPIO_STP_XWAY=y
CONFIG_GPIO_SYSCON=m
CONFIG_GPIO_TEGRA=m
CONFIG_GPIO_TEGRA186=m
CONFIG_GPIO_TS4800=m
CONFIG_GPIO_UNIPHIER=m
CONFIG_GPIO_VISCONTI=m
CONFIG_GPIO_WCD934X=m
CONFIG_GPIO_XGENE_SB=m
CONFIG_GPIO_XILINX=m
CONFIG_GPIO_XLP=m
CONFIG_GPIO_AMD_FCH=m
CONFIG_GPIO_IDT3243X=m
# end of Memory mapped GPIO drivers

#
# I2C GPIO expanders
#
CONFIG_GPIO_ADNP=m
CONFIG_GPIO_GW_PLD=m
CONFIG_GPIO_MAX7300=m
CONFIG_GPIO_MAX732X=m
CONFIG_GPIO_PCA953X=m
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCA9570=m
CONFIG_GPIO_PCF857X=m
CONFIG_GPIO_TPIC2810=m
CONFIG_GPIO_TS4900=m
# end of I2C GPIO expanders

#
# MFD GPIO expanders
#
CONFIG_GPIO_ARIZONA=m
CONFIG_GPIO_BD9571MWV=m
CONFIG_GPIO_DA9052=m
CONFIG_GPIO_DLN2=m
CONFIG_GPIO_KEMPLD=m
CONFIG_GPIO_LP3943=m
CONFIG_GPIO_LP873X=m
CONFIG_GPIO_LP87565=m
CONFIG_GPIO_MADERA=m
CONFIG_GPIO_MAX77650=m
CONFIG_GPIO_SL28CPLD=m
CONFIG_GPIO_STMPE=y
CONFIG_GPIO_TPS65086=m
CONFIG_GPIO_TPS65218=m
CONFIG_GPIO_TPS65912=m
CONFIG_GPIO_UCB1400=m
CONFIG_GPIO_WM831X=m
CONFIG_GPIO_WM8994=m
# end of MFD GPIO expanders

#
# SPI GPIO expanders
#
CONFIG_GPIO_74X164=m
CONFIG_GPIO_MAX3191X=m
CONFIG_GPIO_MAX7301=m
CONFIG_GPIO_MC33880=m
CONFIG_GPIO_PISOSR=m
CONFIG_GPIO_XRA1403=m
CONFIG_GPIO_MOXTET=m
# end of SPI GPIO expanders

#
# USB GPIO expanders
#
CONFIG_GPIO_VIPERBOARD=m
# end of USB GPIO expanders

#
# Virtual GPIO drivers
#
CONFIG_GPIO_AGGREGATOR=m
CONFIG_GPIO_MOCKUP=m
CONFIG_GPIO_VIRTIO=m
CONFIG_GPIO_SIM=m
# end of Virtual GPIO drivers

CONFIG_W1=m
CONFIG_W1_CON=y

#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
CONFIG_W1_MASTER_MXC=m
CONFIG_W1_MASTER_DS1WM=m
CONFIG_W1_MASTER_GPIO=m
CONFIG_W1_MASTER_SGI=m
# end of 1-wire Bus Masters

#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2405=m
CONFIG_W1_SLAVE_DS2408=m
CONFIG_W1_SLAVE_DS2408_READBACK=y
CONFIG_W1_SLAVE_DS2413=m
CONFIG_W1_SLAVE_DS2406=m
CONFIG_W1_SLAVE_DS2423=m
CONFIG_W1_SLAVE_DS2805=m
CONFIG_W1_SLAVE_DS2430=m
CONFIG_W1_SLAVE_DS2431=m
CONFIG_W1_SLAVE_DS2433=m
CONFIG_W1_SLAVE_DS2433_CRC=y
CONFIG_W1_SLAVE_DS2438=m
CONFIG_W1_SLAVE_DS250X=m
CONFIG_W1_SLAVE_DS2780=m
CONFIG_W1_SLAVE_DS2781=m
CONFIG_W1_SLAVE_DS28E04=m
CONFIG_W1_SLAVE_DS28E17=m
# end of 1-wire Slaves

CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_ATC260X=m
CONFIG_POWER_RESET_BRCMKONA=y
CONFIG_POWER_RESET_BRCMSTB=y
CONFIG_POWER_RESET_GEMINI_POWEROFF=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_LINKSTATION=m
CONFIG_POWER_RESET_OCELOT_RESET=y
CONFIG_POWER_RESET_LTC2952=y
CONFIG_POWER_RESET_MT6323=y
CONFIG_POWER_RESET_REGULATOR=y
CONFIG_POWER_RESET_RESTART=y
CONFIG_POWER_RESET_TPS65086=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_RESET_RMOBILE=m
CONFIG_REBOOT_MODE=m
CONFIG_SYSCON_REBOOT_MODE=m
CONFIG_POWER_RESET_SC27XX=m
CONFIG_NVMEM_REBOOT_MODE=m
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_SUPPLY_DEBUG=y
CONFIG_PDA_POWER=m
CONFIG_GENERIC_ADC_BATTERY=m
CONFIG_IP5XXX_POWER=m
CONFIG_WM831X_BACKUP=m
CONFIG_WM831X_POWER=m
CONFIG_TEST_POWER=m
CONFIG_CHARGER_ADP5061=m
CONFIG_BATTERY_ACT8945A=m
CONFIG_BATTERY_CPCAP=m
CONFIG_BATTERY_CW2015=m
CONFIG_BATTERY_DS2760=m
CONFIG_BATTERY_DS2780=m
CONFIG_BATTERY_DS2781=m
CONFIG_BATTERY_DS2782=m
CONFIG_BATTERY_LEGO_EV3=m
CONFIG_BATTERY_OLPC=m
CONFIG_BATTERY_SAMSUNG_SDI=y
CONFIG_BATTERY_INGENIC=m
CONFIG_BATTERY_SBS=m
CONFIG_CHARGER_SBS=m
CONFIG_MANAGER_SBS=m
CONFIG_BATTERY_BQ27XXX=m
CONFIG_BATTERY_BQ27XXX_I2C=m
CONFIG_BATTERY_BQ27XXX_HDQ=m
CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM=y
CONFIG_BATTERY_DA9052=m
CONFIG_CHARGER_DA9150=m
CONFIG_BATTERY_DA9150=m
CONFIG_CHARGER_AXP20X=m
CONFIG_BATTERY_AXP20X=m
CONFIG_AXP20X_POWER=m
CONFIG_BATTERY_MAX17040=m
CONFIG_BATTERY_MAX17042=m
CONFIG_BATTERY_MAX1721X=m
CONFIG_CHARGER_PCF50633=m
CONFIG_CHARGER_CPCAP=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_MAX8903=m
CONFIG_CHARGER_LP8727=m
CONFIG_CHARGER_GPIO=m
CONFIG_CHARGER_MANAGER=m
CONFIG_CHARGER_LT3651=m
CONFIG_CHARGER_LTC4162L=m
CONFIG_CHARGER_MAX14577=m
CONFIG_CHARGER_DETECTOR_MAX14656=m
CONFIG_CHARGER_MAX77650=m
CONFIG_CHARGER_MAX77693=m
CONFIG_CHARGER_MAX77976=m
CONFIG_CHARGER_MP2629=m
CONFIG_CHARGER_MT6360=m
CONFIG_CHARGER_MT6370=m
CONFIG_CHARGER_QCOM_SMBB=m
CONFIG_CHARGER_BQ2415X=m
CONFIG_CHARGER_BQ24190=m
CONFIG_CHARGER_BQ24257=m
CONFIG_CHARGER_BQ24735=m
CONFIG_CHARGER_BQ2515X=m
CONFIG_CHARGER_BQ25890=m
CONFIG_CHARGER_BQ25980=m
CONFIG_CHARGER_BQ256XX=m
CONFIG_CHARGER_RK817=m
CONFIG_CHARGER_SMB347=m
CONFIG_CHARGER_TPS65217=m
CONFIG_BATTERY_GAUGE_LTC2941=m
CONFIG_BATTERY_GOLDFISH=m
CONFIG_BATTERY_RT5033=m
CONFIG_CHARGER_RT9455=m
CONFIG_CHARGER_CROS_USBPD=m
CONFIG_CHARGER_CROS_PCHG=m
CONFIG_CHARGER_SC2731=m
CONFIG_FUEL_GAUGE_SC27XX=m
CONFIG_CHARGER_UCS1002=m
CONFIG_CHARGER_BD99954=m
CONFIG_RN5T618_POWER=m
CONFIG_BATTERY_ACER_A500=m
CONFIG_BATTERY_UG3105=m
CONFIG_HWMON=m
CONFIG_HWMON_VID=m
CONFIG_HWMON_DEBUG_CHIP=y

#
# Native drivers
#
CONFIG_SENSORS_AD7314=m
CONFIG_SENSORS_AD7414=m
CONFIG_SENSORS_AD7418=m
CONFIG_SENSORS_ADM1025=m
CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM1031=m
CONFIG_SENSORS_ADM1177=m
CONFIG_SENSORS_ADM9240=m
CONFIG_SENSORS_ADT7X10=m
CONFIG_SENSORS_ADT7310=m
CONFIG_SENSORS_ADT7410=m
CONFIG_SENSORS_ADT7411=m
CONFIG_SENSORS_ADT7462=m
CONFIG_SENSORS_ADT7470=m
CONFIG_SENSORS_ADT7475=m
CONFIG_SENSORS_AHT10=m
CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m
CONFIG_SENSORS_AS370=m
CONFIG_SENSORS_ASC7621=m
CONFIG_SENSORS_AXI_FAN_CONTROL=m
CONFIG_SENSORS_ARM_SCMI=m
CONFIG_SENSORS_ARM_SCPI=m
CONFIG_SENSORS_ASB100=m
CONFIG_SENSORS_ASPEED=m
CONFIG_SENSORS_ATXP1=m
CONFIG_SENSORS_BT1_PVT=m
CONFIG_SENSORS_BT1_PVT_ALARMS=y
CONFIG_SENSORS_CORSAIR_CPRO=m
CONFIG_SENSORS_CORSAIR_PSU=m
CONFIG_SENSORS_DRIVETEMP=m
CONFIG_SENSORS_DS620=m
CONFIG_SENSORS_DS1621=m
CONFIG_SENSORS_DA9052_ADC=m
CONFIG_SENSORS_SPARX5=m
CONFIG_SENSORS_F71805F=m
CONFIG_SENSORS_F71882FG=m
CONFIG_SENSORS_F75375S=m
CONFIG_SENSORS_GSC=m
CONFIG_SENSORS_MC13783_ADC=m
CONFIG_SENSORS_FSCHMD=m
CONFIG_SENSORS_FTSTEUTATES=m
CONFIG_SENSORS_GL518SM=m
CONFIG_SENSORS_GL520SM=m
CONFIG_SENSORS_G760A=m
CONFIG_SENSORS_G762=m
CONFIG_SENSORS_GPIO_FAN=m
CONFIG_SENSORS_HIH6130=m
CONFIG_SENSORS_IBMAEM=m
CONFIG_SENSORS_IBMPEX=m
CONFIG_SENSORS_IIO_HWMON=m
CONFIG_SENSORS_IT87=m
CONFIG_SENSORS_JC42=m
CONFIG_SENSORS_POWR1220=m
CONFIG_SENSORS_LAN966X=m
CONFIG_SENSORS_LINEAGE=m
CONFIG_SENSORS_LTC2945=m
CONFIG_SENSORS_LTC2947=m
CONFIG_SENSORS_LTC2947_I2C=m
CONFIG_SENSORS_LTC2947_SPI=m
CONFIG_SENSORS_LTC2990=m
CONFIG_SENSORS_LTC2992=m
CONFIG_SENSORS_LTC4151=m
CONFIG_SENSORS_LTC4215=m
CONFIG_SENSORS_LTC4222=m
CONFIG_SENSORS_LTC4245=m
CONFIG_SENSORS_LTC4260=m
CONFIG_SENSORS_LTC4261=m
CONFIG_SENSORS_MAX1111=m
CONFIG_SENSORS_MAX127=m
CONFIG_SENSORS_MAX16065=m
CONFIG_SENSORS_MAX1619=m
CONFIG_SENSORS_MAX1668=m
CONFIG_SENSORS_MAX197=m
CONFIG_SENSORS_MAX31722=m
CONFIG_SENSORS_MAX31730=m
CONFIG_SENSORS_MAX31760=m
CONFIG_SENSORS_MAX6620=m
CONFIG_SENSORS_MAX6621=m
CONFIG_SENSORS_MAX6639=m
CONFIG_SENSORS_MAX6650=m
CONFIG_SENSORS_MAX6697=m
CONFIG_SENSORS_MAX31790=m
CONFIG_SENSORS_MCP3021=m
CONFIG_SENSORS_MLXREG_FAN=m
CONFIG_SENSORS_TC654=m
CONFIG_SENSORS_TPS23861=m
CONFIG_SENSORS_MENF21BMC_HWMON=m
CONFIG_SENSORS_MR75203=m
CONFIG_SENSORS_ADCXX=m
CONFIG_SENSORS_LM63=m
CONFIG_SENSORS_LM70=m
CONFIG_SENSORS_LM73=m
CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_LM77=m
CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM80=m
CONFIG_SENSORS_LM83=m
CONFIG_SENSORS_LM85=m
CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_LM92=m
CONFIG_SENSORS_LM93=m
CONFIG_SENSORS_LM95234=m
CONFIG_SENSORS_LM95241=m
CONFIG_SENSORS_LM95245=m
CONFIG_SENSORS_PC87360=m
CONFIG_SENSORS_PC87427=m
CONFIG_SENSORS_NTC_THERMISTOR=m
CONFIG_SENSORS_NCT6683=m
CONFIG_SENSORS_NCT6775_CORE=m
CONFIG_SENSORS_NCT6775=m
CONFIG_SENSORS_NCT6775_I2C=m
CONFIG_SENSORS_NCT7802=m
CONFIG_SENSORS_NCT7904=m
CONFIG_SENSORS_NPCM7XX=m
CONFIG_SENSORS_NSA320=m
CONFIG_SENSORS_NZXT_KRAKEN2=m
CONFIG_SENSORS_NZXT_SMART2=m
CONFIG_SENSORS_OCC_P8_I2C=m
CONFIG_SENSORS_OCC_P9_SBE=m
CONFIG_SENSORS_OCC=m
CONFIG_SENSORS_PCF8591=m
CONFIG_SENSORS_PECI_CPUTEMP=m
CONFIG_SENSORS_PECI_DIMMTEMP=m
CONFIG_SENSORS_PECI=m
CONFIG_PMBUS=m
CONFIG_SENSORS_PMBUS=m
CONFIG_SENSORS_ADM1266=m
CONFIG_SENSORS_ADM1275=m
CONFIG_SENSORS_BEL_PFE=m
CONFIG_SENSORS_BPA_RS600=m
CONFIG_SENSORS_DELTA_AHE50DC_FAN=m
CONFIG_SENSORS_FSP_3Y=m
CONFIG_SENSORS_IBM_CFFPS=m
CONFIG_SENSORS_DPS920AB=m
CONFIG_SENSORS_INSPUR_IPSPS=m
CONFIG_SENSORS_IR35221=m
CONFIG_SENSORS_IR36021=m
CONFIG_SENSORS_IR38064=m
CONFIG_SENSORS_IR38064_REGULATOR=y
CONFIG_SENSORS_IRPS5401=m
CONFIG_SENSORS_ISL68137=m
CONFIG_SENSORS_LM25066=m
CONFIG_SENSORS_LM25066_REGULATOR=y
CONFIG_SENSORS_LT7182S=m
CONFIG_SENSORS_LTC2978=m
CONFIG_SENSORS_LTC2978_REGULATOR=y
CONFIG_SENSORS_LTC3815=m
CONFIG_SENSORS_MAX15301=m
CONFIG_SENSORS_MAX16064=m
CONFIG_SENSORS_MAX16601=m
CONFIG_SENSORS_MAX20730=m
CONFIG_SENSORS_MAX20751=m
CONFIG_SENSORS_MAX31785=m
CONFIG_SENSORS_MAX34440=m
CONFIG_SENSORS_MAX8688=m
CONFIG_SENSORS_MP2888=m
CONFIG_SENSORS_MP2975=m
CONFIG_SENSORS_MP5023=m
CONFIG_SENSORS_PIM4328=m
CONFIG_SENSORS_PLI1209BC=m
CONFIG_SENSORS_PLI1209BC_REGULATOR=y
CONFIG_SENSORS_PM6764TR=m
CONFIG_SENSORS_PXE1610=m
CONFIG_SENSORS_Q54SJ108A2=m
CONFIG_SENSORS_STPDDC60=m
CONFIG_SENSORS_TPS40422=m
CONFIG_SENSORS_TPS53679=m
CONFIG_SENSORS_TPS546D24=m
CONFIG_SENSORS_UCD9000=m
CONFIG_SENSORS_UCD9200=m
CONFIG_SENSORS_XDPE152=m
CONFIG_SENSORS_XDPE122=m
CONFIG_SENSORS_XDPE122_REGULATOR=y
CONFIG_SENSORS_ZL6100=m
CONFIG_SENSORS_PWM_FAN=m
CONFIG_SENSORS_RASPBERRYPI_HWMON=m
CONFIG_SENSORS_SL28CPLD=m
CONFIG_SENSORS_SBTSI=m
CONFIG_SENSORS_SBRMI=m
CONFIG_SENSORS_SHT15=m
CONFIG_SENSORS_SHT21=m
CONFIG_SENSORS_SHT3x=m
CONFIG_SENSORS_SHT4x=m
CONFIG_SENSORS_SHTC1=m
CONFIG_SENSORS_SY7636A=m
CONFIG_SENSORS_DME1737=m
CONFIG_SENSORS_EMC1403=m
CONFIG_SENSORS_EMC2103=m
CONFIG_SENSORS_EMC2305=m
CONFIG_SENSORS_EMC6W201=m
CONFIG_SENSORS_SMSC47M1=m
CONFIG_SENSORS_SMSC47M192=m
CONFIG_SENSORS_SMSC47B397=m
CONFIG_SENSORS_SCH56XX_COMMON=m
CONFIG_SENSORS_SCH5627=m
CONFIG_SENSORS_SCH5636=m
CONFIG_SENSORS_STTS751=m
CONFIG_SENSORS_SMM665=m
CONFIG_SENSORS_ADC128D818=m
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_ADS7871=m
CONFIG_SENSORS_AMC6821=m
CONFIG_SENSORS_INA209=m
CONFIG_SENSORS_INA2XX=m
CONFIG_SENSORS_INA238=m
CONFIG_SENSORS_INA3221=m
CONFIG_SENSORS_TC74=m
CONFIG_SENSORS_THMC50=m
CONFIG_SENSORS_TMP102=m
CONFIG_SENSORS_TMP103=m
CONFIG_SENSORS_TMP108=m
CONFIG_SENSORS_TMP401=m
CONFIG_SENSORS_TMP421=m
CONFIG_SENSORS_TMP464=m
CONFIG_SENSORS_TMP513=m
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_W83773G=m
CONFIG_SENSORS_W83781D=m
CONFIG_SENSORS_W83791D=m
CONFIG_SENSORS_W83792D=m
CONFIG_SENSORS_W83793=m
CONFIG_SENSORS_W83795=m
CONFIG_SENSORS_W83795_FANCTRL=y
CONFIG_SENSORS_W83L785TS=m
CONFIG_SENSORS_W83L786NG=m
CONFIG_SENSORS_W83627HF=m
CONFIG_SENSORS_W83627EHF=m
CONFIG_SENSORS_WM831X=m
CONFIG_SENSORS_INTEL_M10_BMC_HWMON=m
CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_OF=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_BANG_BANG=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_FREQ_THERMAL=y
CONFIG_CPU_IDLE_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_THERMAL_MMIO=m
CONFIG_HISI_THERMAL=m
CONFIG_IMX_THERMAL=m
CONFIG_IMX_SC_THERMAL=m
CONFIG_IMX8MM_THERMAL=m
CONFIG_K3_THERMAL=m
CONFIG_QORIQ_THERMAL=m
CONFIG_SPEAR_THERMAL=m
CONFIG_SUN8I_THERMAL=m
CONFIG_ROCKCHIP_THERMAL=m
CONFIG_RCAR_THERMAL=m
CONFIG_RCAR_GEN3_THERMAL=m
CONFIG_RZG2L_THERMAL=m
CONFIG_KIRKWOOD_THERMAL=m
CONFIG_DOVE_THERMAL=m
CONFIG_ARMADA_THERMAL=m
CONFIG_DA9062_THERMAL=m
CONFIG_MTK_THERMAL=m

#
# Intel thermal drivers
#

#
# ACPI INT340X thermal drivers
#
# end of ACPI INT340X thermal drivers
# end of Intel thermal drivers

#
# Broadcom thermal drivers
#
CONFIG_BCM2711_THERMAL=m
CONFIG_BCM2835_THERMAL=m
CONFIG_BRCMSTB_THERMAL=m
CONFIG_BCM_NS_THERMAL=m
CONFIG_BCM_SR_THERMAL=m
# end of Broadcom thermal drivers

#
# Texas Instruments thermal drivers
#
CONFIG_TI_SOC_THERMAL=m
CONFIG_TI_THERMAL=y
CONFIG_OMAP3_THERMAL=y
CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y
# end of Texas Instruments thermal drivers

#
# Samsung thermal drivers
#
CONFIG_EXYNOS_THERMAL=m
# end of Samsung thermal drivers

#
# NVIDIA Tegra thermal drivers
#
CONFIG_TEGRA_SOCTHERM=m
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_TEGRA30_TSENSOR=m
# end of NVIDIA Tegra thermal drivers

CONFIG_GENERIC_ADC_THERMAL=m

#
# Qualcomm thermal drivers
#
CONFIG_QCOM_TSENS=m
CONFIG_QCOM_SPMI_ADC_TM5=m
CONFIG_QCOM_SPMI_TEMP_ALARM=m
# end of Qualcomm thermal drivers

CONFIG_UNIPHIER_THERMAL=m
CONFIG_SPRD_THERMAL=m
CONFIG_KHADAS_MCU_FAN_THERMAL=m
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
CONFIG_WATCHDOG_OPEN_TIMEOUT=0
CONFIG_WATCHDOG_SYSFS=y
CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT=y

#
# Watchdog Pretimeout Governors
#
CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=m
CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m
# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set
CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y

#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y
CONFIG_DA9052_WATCHDOG=m
CONFIG_DA9055_WATCHDOG=m
CONFIG_DA9063_WATCHDOG=m
CONFIG_DA9062_WATCHDOG=m
CONFIG_GPIO_WATCHDOG=m
CONFIG_MENF21BMC_WATCHDOG=m
CONFIG_MENZ069_WATCHDOG=m
CONFIG_WM831X_WATCHDOG=m
CONFIG_XILINX_WATCHDOG=m
CONFIG_ZIIRAVE_WATCHDOG=m
CONFIG_RAVE_SP_WATCHDOG=m
CONFIG_MLX_WDT=m
CONFIG_SL28CPLD_WATCHDOG=m
CONFIG_ARMADA_37XX_WATCHDOG=m
CONFIG_ASM9260_WATCHDOG=m
CONFIG_AT91RM9200_WATCHDOG=m
CONFIG_AT91SAM9X_WATCHDOG=m
CONFIG_SAMA5D4_WATCHDOG=m
CONFIG_CADENCE_WATCHDOG=m
CONFIG_FTWDT010_WATCHDOG=m
CONFIG_S3C2410_WATCHDOG=m
CONFIG_DW_WATCHDOG=m
CONFIG_EP93XX_WATCHDOG=m
CONFIG_OMAP_WATCHDOG=m
CONFIG_PNX4008_WATCHDOG=m
CONFIG_DAVINCI_WATCHDOG=m
CONFIG_K3_RTI_WATCHDOG=m
CONFIG_RN5T618_WATCHDOG=m
CONFIG_SUNXI_WATCHDOG=m
CONFIG_NPCM7XX_WATCHDOG=m
CONFIG_STMP3XXX_RTC_WATCHDOG=m
CONFIG_TS4800_WATCHDOG=m
CONFIG_TS72XX_WATCHDOG=m
CONFIG_MAX63XX_WATCHDOG=m
CONFIG_MAX77620_WATCHDOG=m
CONFIG_IMX2_WDT=m
CONFIG_IMX7ULP_WDT=m
CONFIG_RETU_WATCHDOG=m
CONFIG_MOXART_WDT=m
CONFIG_ST_LPC_WATCHDOG=m
CONFIG_TEGRA_WATCHDOG=m
CONFIG_QCOM_WDT=m
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
CONFIG_MEDIATEK_WATCHDOG=m
CONFIG_DIGICOLOR_WATCHDOG=m
CONFIG_LPC18XX_WATCHDOG=m
CONFIG_RENESAS_WDT=m
CONFIG_RENESAS_RZAWDT=m
CONFIG_RENESAS_RZN1WDT=m
CONFIG_RENESAS_RZG2LWDT=m
CONFIG_ASPEED_WATCHDOG=m
CONFIG_UNIPHIER_WATCHDOG=m
CONFIG_RTD119X_WATCHDOG=y
CONFIG_REALTEK_OTTO_WDT=m
CONFIG_SPRD_WATCHDOG=m
CONFIG_PM8916_WATCHDOG=m
CONFIG_VISCONTI_WATCHDOG=m
CONFIG_MSC313E_WATCHDOG=m
CONFIG_APPLE_WATCHDOG=m
CONFIG_SUNPLUS_WATCHDOG=m
CONFIG_SC520_WDT=m
CONFIG_KEMPLD_WDT=m
CONFIG_BCM47XX_WDT=m
CONFIG_BCM2835_WDT=m
CONFIG_BCM_KONA_WDT=m
CONFIG_BCM_KONA_WDT_DEBUG=y
CONFIG_BCM7038_WDT=m
CONFIG_IMGPDC_WDT=m
CONFIG_MPC5200_WDT=y
CONFIG_MEN_A21_WDT=m
CONFIG_SH_WDT=m
CONFIG_UML_WATCHDOG=m

#
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=m

#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
CONFIG_MFD_ACT8945A=m
CONFIG_MFD_SUN4I_GPADC=m
CONFIG_MFD_AT91_USART=y
CONFIG_MFD_ATMEL_FLEXCOM=m
CONFIG_MFD_ATMEL_HLCDC=m
CONFIG_MFD_ATMEL_SMC=y
CONFIG_MFD_BCM590XX=m
CONFIG_MFD_BD9571MWV=m
CONFIG_MFD_AXP20X=m
CONFIG_MFD_AXP20X_I2C=m
CONFIG_MFD_CROS_EC_DEV=m
CONFIG_MFD_MADERA=m
CONFIG_MFD_MADERA_I2C=m
CONFIG_MFD_MADERA_SPI=m
CONFIG_MFD_CS47L15=y
CONFIG_MFD_CS47L35=y
CONFIG_MFD_CS47L85=y
CONFIG_MFD_CS47L90=y
CONFIG_MFD_CS47L92=y
CONFIG_MFD_ASIC3=y
CONFIG_PMIC_DA9052=y
CONFIG_MFD_DA9052_SPI=y
CONFIG_MFD_DA9062=m
CONFIG_MFD_DA9063=m
CONFIG_MFD_DA9150=m
CONFIG_MFD_DLN2=m
CONFIG_MFD_ENE_KB3930=m
CONFIG_MFD_EXYNOS_LPASS=m
CONFIG_MFD_GATEWORKS_GSC=m
CONFIG_MFD_MC13XXX=m
CONFIG_MFD_MC13XXX_SPI=m
CONFIG_MFD_MC13XXX_I2C=m
CONFIG_MFD_MP2629=m
CONFIG_MFD_MXS_LRADC=m
CONFIG_MFD_MX25_TSADC=m
CONFIG_MFD_HI6421_PMIC=m
CONFIG_MFD_HI6421_SPMI=m
CONFIG_MFD_HI655X_PMIC=m
CONFIG_HTC_PASIC3=m
CONFIG_MFD_IQS62X=m
CONFIG_MFD_KEMPLD=m
CONFIG_MFD_88PM800=m
CONFIG_MFD_88PM805=m
CONFIG_MFD_MAX14577=m
CONFIG_MFD_MAX77650=m
CONFIG_MFD_MAX77686=m
CONFIG_MFD_MAX77693=m
CONFIG_MFD_MAX77714=m
CONFIG_MFD_MAX8907=m
CONFIG_MFD_MT6360=m
CONFIG_MFD_MT6370=m
CONFIG_MFD_MT6397=m
CONFIG_MFD_MENF21BMC=m
CONFIG_MFD_OCELOT=m
CONFIG_EZX_PCAP=y
CONFIG_MFD_CPCAP=m
CONFIG_MFD_VIPERBOARD=m
CONFIG_MFD_NTXEC=m
CONFIG_MFD_RETU=m
CONFIG_MFD_PCF50633=m
CONFIG_PCF50633_ADC=m
CONFIG_PCF50633_GPIO=m
CONFIG_UCB1400_CORE=m
CONFIG_MFD_PM8XXX=m
CONFIG_MFD_SPMI_PMIC=m
CONFIG_MFD_SY7636A=m
CONFIG_MFD_RT4831=m
CONFIG_MFD_RT5033=m
CONFIG_MFD_RT5120=m
CONFIG_MFD_RK808=m
CONFIG_MFD_RN5T618=m
CONFIG_MFD_SI476X_CORE=m
CONFIG_MFD_SIMPLE_MFD_I2C=m
CONFIG_MFD_SL28CPLD=m
CONFIG_MFD_SKY81452=m
CONFIG_MFD_SC27XX_PMIC=m
CONFIG_ABX500_CORE=y
CONFIG_MFD_STMPE=y

#
# STMicroelectronics STMPE Interface Drivers
#
CONFIG_STMPE_SPI=y
# end of STMicroelectronics STMPE Interface Drivers

CONFIG_MFD_SUN6I_PRCM=y
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TI_AM335X_TSCADC=m
CONFIG_MFD_LP3943=m
CONFIG_MFD_TI_LMU=m
CONFIG_TPS6105X=m
CONFIG_TPS65010=m
CONFIG_TPS6507X=m
CONFIG_MFD_TPS65086=m
CONFIG_MFD_TPS65217=m
CONFIG_MFD_TI_LP873X=m
CONFIG_MFD_TI_LP87565=m
CONFIG_MFD_TPS65218=m
CONFIG_MFD_TPS65912=m
CONFIG_MFD_TPS65912_I2C=m
CONFIG_MFD_TPS65912_SPI=m
CONFIG_MFD_WL1273_CORE=m
CONFIG_MFD_LM3533=m
CONFIG_MFD_TQMX86=m
CONFIG_MFD_ARIZONA=m
CONFIG_MFD_ARIZONA_I2C=m
CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_CS47L24=y
CONFIG_MFD_WM5102=y
CONFIG_MFD_WM5110=y
CONFIG_MFD_WM8997=y
CONFIG_MFD_WM8998=y
CONFIG_MFD_WM831X=y
CONFIG_MFD_WM831X_SPI=y
CONFIG_MFD_WM8994=m
CONFIG_MFD_STW481X=m
CONFIG_MFD_STM32_LPTIMER=m
CONFIG_MFD_STM32_TIMERS=m
CONFIG_MFD_STMFX=m
CONFIG_MFD_WCD934X=m
CONFIG_MFD_ATC260X=m
CONFIG_MFD_ATC260X_I2C=m
CONFIG_MFD_KHADAS_MCU=m
CONFIG_MFD_ACER_A500_EC=m
CONFIG_MFD_QCOM_PM8008=m
CONFIG_RAVE_SP_CORE=m
CONFIG_MFD_INTEL_M10_BMC=m
CONFIG_MFD_RSMU_I2C=m
CONFIG_MFD_RSMU_SPI=m
# end of Multifunction device drivers

CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_REGULATOR_VIRTUAL_CONSUMER=m
CONFIG_REGULATOR_USERSPACE_CONSUMER=m
CONFIG_REGULATOR_88PG86X=m
CONFIG_REGULATOR_88PM800=m
CONFIG_REGULATOR_ACT8865=m
CONFIG_REGULATOR_ACT8945A=m
CONFIG_REGULATOR_AD5398=m
CONFIG_REGULATOR_ANATOP=m
CONFIG_REGULATOR_ARIZONA_LDO1=m
CONFIG_REGULATOR_ARIZONA_MICSUPP=m
CONFIG_REGULATOR_ARM_SCMI=m
CONFIG_REGULATOR_ATC260X=m
CONFIG_REGULATOR_AXP20X=m
CONFIG_REGULATOR_BCM590XX=m
CONFIG_REGULATOR_BD9571MWV=m
CONFIG_REGULATOR_CPCAP=m
CONFIG_REGULATOR_CROS_EC=m
CONFIG_REGULATOR_DA9052=m
CONFIG_REGULATOR_DA9062=m
CONFIG_REGULATOR_DA9063=m
CONFIG_REGULATOR_DA9121=m
CONFIG_REGULATOR_DA9210=m
CONFIG_REGULATOR_DA9211=m
CONFIG_REGULATOR_FAN53555=m
CONFIG_REGULATOR_FAN53880=m
CONFIG_REGULATOR_GPIO=m
CONFIG_REGULATOR_HI6421=m
CONFIG_REGULATOR_HI6421V530=m
CONFIG_REGULATOR_HI655X=m
CONFIG_REGULATOR_HI6421V600=m
CONFIG_REGULATOR_ISL9305=m
CONFIG_REGULATOR_ISL6271A=m
CONFIG_REGULATOR_LM363X=m
CONFIG_REGULATOR_LP3971=m
CONFIG_REGULATOR_LP3972=m
CONFIG_REGULATOR_LP872X=m
CONFIG_REGULATOR_LP873X=m
CONFIG_REGULATOR_LP8755=m
CONFIG_REGULATOR_LP87565=m
CONFIG_REGULATOR_LTC3589=m
CONFIG_REGULATOR_LTC3676=m
CONFIG_REGULATOR_MAX14577=m
CONFIG_REGULATOR_MAX1586=m
CONFIG_REGULATOR_MAX77620=m
CONFIG_REGULATOR_MAX77650=m
CONFIG_REGULATOR_MAX8649=m
CONFIG_REGULATOR_MAX8660=m
CONFIG_REGULATOR_MAX8893=m
CONFIG_REGULATOR_MAX8907=m
CONFIG_REGULATOR_MAX8952=m
CONFIG_REGULATOR_MAX8973=m
CONFIG_REGULATOR_MAX20086=m
CONFIG_REGULATOR_MAX77686=m
CONFIG_REGULATOR_MAX77693=m
CONFIG_REGULATOR_MAX77802=m
CONFIG_REGULATOR_MAX77826=m
CONFIG_REGULATOR_MC13XXX_CORE=m
CONFIG_REGULATOR_MC13783=m
CONFIG_REGULATOR_MC13892=m
CONFIG_REGULATOR_MCP16502=m
CONFIG_REGULATOR_MP5416=m
CONFIG_REGULATOR_MP8859=m
CONFIG_REGULATOR_MP886X=m
CONFIG_REGULATOR_MPQ7920=m
CONFIG_REGULATOR_MT6311=m
CONFIG_REGULATOR_MT6315=m
CONFIG_REGULATOR_MT6323=m
CONFIG_REGULATOR_MT6331=m
CONFIG_REGULATOR_MT6332=m
CONFIG_REGULATOR_MT6358=m
CONFIG_REGULATOR_MT6359=m
CONFIG_REGULATOR_MT6360=m
CONFIG_REGULATOR_MT6370=m
CONFIG_REGULATOR_MT6380=m
CONFIG_REGULATOR_MT6397=m
CONFIG_REGULATOR_PBIAS=m
CONFIG_REGULATOR_PCA9450=m
CONFIG_REGULATOR_PCAP=m
CONFIG_REGULATOR_PCF50633=m
CONFIG_REGULATOR_PF8X00=m
CONFIG_REGULATOR_PFUZE100=m
CONFIG_REGULATOR_PV88060=m
CONFIG_REGULATOR_PV88080=m
CONFIG_REGULATOR_PV88090=m
CONFIG_REGULATOR_PWM=m
CONFIG_REGULATOR_QCOM_RPMH=m
CONFIG_REGULATOR_QCOM_SMD_RPM=m
CONFIG_REGULATOR_QCOM_SPMI=m
CONFIG_REGULATOR_QCOM_USB_VBUS=m
CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m
CONFIG_REGULATOR_RK808=m
CONFIG_REGULATOR_RN5T618=m
CONFIG_REGULATOR_RT4801=m
CONFIG_REGULATOR_RT4831=m
CONFIG_REGULATOR_RT5033=m
CONFIG_REGULATOR_RT5120=m
CONFIG_REGULATOR_RT5190A=m
CONFIG_REGULATOR_RT5759=m
CONFIG_REGULATOR_RT6160=m
CONFIG_REGULATOR_RT6245=m
CONFIG_REGULATOR_RTQ2134=m
CONFIG_REGULATOR_RTMV20=m
CONFIG_REGULATOR_RTQ6752=m
CONFIG_REGULATOR_S2MPA01=m
CONFIG_REGULATOR_S2MPS11=m
CONFIG_REGULATOR_S5M8767=m
CONFIG_REGULATOR_SC2731=m
CONFIG_REGULATOR_SKY81452=m
CONFIG_REGULATOR_SLG51000=m
CONFIG_REGULATOR_STM32_BOOSTER=m
CONFIG_REGULATOR_STM32_VREFBUF=m
CONFIG_REGULATOR_STM32_PWR=y
CONFIG_REGULATOR_TI_ABB=m
CONFIG_REGULATOR_STW481X_VMMC=y
CONFIG_REGULATOR_SY7636A=m
CONFIG_REGULATOR_SY8106A=m
CONFIG_REGULATOR_SY8824X=m
CONFIG_REGULATOR_SY8827N=m
CONFIG_REGULATOR_TPS51632=m
CONFIG_REGULATOR_TPS6105X=m
CONFIG_REGULATOR_TPS62360=m
CONFIG_REGULATOR_TPS6286X=m
CONFIG_REGULATOR_TPS65023=m
CONFIG_REGULATOR_TPS6507X=m
CONFIG_REGULATOR_TPS65086=m
CONFIG_REGULATOR_TPS65132=m
CONFIG_REGULATOR_TPS65217=m
CONFIG_REGULATOR_TPS65218=m
CONFIG_REGULATOR_TPS6524X=m
CONFIG_REGULATOR_TPS65912=m
CONFIG_REGULATOR_TPS68470=m
CONFIG_REGULATOR_UNIPHIER=m
CONFIG_REGULATOR_VCTRL=m
CONFIG_REGULATOR_WM831X=m
CONFIG_REGULATOR_WM8994=m
CONFIG_REGULATOR_QCOM_LABIBB=m
CONFIG_RC_CORE=m
CONFIG_LIRC=y
CONFIG_RC_MAP=m
CONFIG_RC_DECODERS=y
CONFIG_IR_IMON_DECODER=m
CONFIG_IR_JVC_DECODER=m
CONFIG_IR_MCE_KBD_DECODER=m
CONFIG_IR_NEC_DECODER=m
CONFIG_IR_RC5_DECODER=m
CONFIG_IR_RC6_DECODER=m
CONFIG_IR_RCMM_DECODER=m
CONFIG_IR_SANYO_DECODER=m
CONFIG_IR_SHARP_DECODER=m
CONFIG_IR_SONY_DECODER=m
CONFIG_IR_XMP_DECODER=m
CONFIG_RC_DEVICES=y
CONFIG_IR_ENE=m
CONFIG_IR_FINTEK=m
CONFIG_IR_GPIO_CIR=m
CONFIG_IR_GPIO_TX=m
CONFIG_IR_HIX5HD2=m
CONFIG_IR_IGORPLUGUSB=m
CONFIG_IR_IGUANA=m
CONFIG_IR_IMON=m
CONFIG_IR_IMON_RAW=m
CONFIG_IR_ITE_CIR=m
CONFIG_IR_MCEUSB=m
CONFIG_IR_MESON=m
CONFIG_IR_MESON_TX=m
CONFIG_IR_MTK=m
CONFIG_IR_NUVOTON=m
CONFIG_IR_PWM_TX=m
CONFIG_IR_REDRAT3=m
CONFIG_IR_RX51=m
CONFIG_IR_SERIAL=m
CONFIG_IR_SERIAL_TRANSMITTER=y
CONFIG_IR_SPI=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_SUNXI=m
CONFIG_IR_TOY=m
CONFIG_IR_TTUSBIR=m
CONFIG_IR_WINBOND_CIR=m
CONFIG_RC_ATI_REMOTE=m
CONFIG_RC_LOOPBACK=m
CONFIG_RC_ST=m
CONFIG_RC_XBOX_DVD=m
CONFIG_IR_IMG=m
CONFIG_IR_IMG_RAW=y
CONFIG_IR_IMG_HW=y
CONFIG_IR_IMG_NEC=y
CONFIG_IR_IMG_JVC=y
CONFIG_IR_IMG_SONY=y
CONFIG_IR_IMG_SHARP=y
CONFIG_IR_IMG_SANYO=y
CONFIG_IR_IMG_RC5=y
CONFIG_IR_IMG_RC6=y
CONFIG_CEC_CORE=m
CONFIG_CEC_NOTIFIER=y
CONFIG_CEC_PIN=y

#
# CEC support
#
CONFIG_MEDIA_CEC_RC=y
CONFIG_CEC_PIN_ERROR_INJ=y
CONFIG_MEDIA_CEC_SUPPORT=y
CONFIG_CEC_CH7322=m
CONFIG_CEC_CROS_EC=m
CONFIG_CEC_MESON_AO=m
CONFIG_CEC_MESON_G12A_AO=m
CONFIG_CEC_GPIO=m
CONFIG_CEC_SAMSUNG_S5P=m
CONFIG_CEC_STI=m
CONFIG_CEC_STM32=m
CONFIG_CEC_TEGRA=m
CONFIG_USB_PULSE8_CEC=m
CONFIG_USB_RAINSHADOW_CEC=m
# end of CEC support

CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y

#
# Media device types
#
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_SDR_SUPPORT=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_MEDIA_TEST_SUPPORT=y
# end of Media device types

CONFIG_VIDEO_DEV=m
CONFIG_MEDIA_CONTROLLER=y
CONFIG_DVB_CORE=m

#
# Video4Linux options
#
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_VIDEO_TUNER=m
CONFIG_V4L2_JPEG_HELPER=m
CONFIG_V4L2_H264=m
CONFIG_V4L2_VP9=m
CONFIG_V4L2_MEM2MEM_DEV=m
CONFIG_V4L2_FLASH_LED_CLASS=m
CONFIG_V4L2_FWNODE=m
CONFIG_V4L2_ASYNC=m
CONFIG_VIDEOBUF_GEN=m
CONFIG_VIDEOBUF_VMALLOC=m
CONFIG_VIDEOBUF_DMA_CONTIG=m
# end of Video4Linux options

#
# Media controller options
#
CONFIG_MEDIA_CONTROLLER_DVB=y
CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
# end of Media controller options

#
# Digital TV options
#
CONFIG_DVB_MMAP=y
CONFIG_DVB_NET=y
CONFIG_DVB_MAX_ADAPTERS=16
CONFIG_DVB_DYNAMIC_MINORS=y
CONFIG_DVB_DEMUX_SECTION_LOSS_LOG=y
CONFIG_DVB_ULE_DEBUG=y
# end of Digital TV options

#
# Media drivers
#

#
# Drivers filtered as selected at 'Filter media drivers'
#

#
# Media drivers
#
CONFIG_MEDIA_USB_SUPPORT=y

#
# Webcam devices
#
CONFIG_USB_GSPCA=m
CONFIG_USB_GSPCA_BENQ=m
CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_CPIA1=m
CONFIG_USB_GSPCA_DTCS033=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_JEILINJ=m
CONFIG_USB_GSPCA_JL2005BCD=m
CONFIG_USB_GSPCA_KINECT=m
CONFIG_USB_GSPCA_KONICA=m
CONFIG_USB_GSPCA_MARS=m
CONFIG_USB_GSPCA_MR97310A=m
CONFIG_USB_GSPCA_NW80X=m
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_OV534_9=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7302=m
CONFIG_USB_GSPCA_PAC7311=m
CONFIG_USB_GSPCA_SE401=m
CONFIG_USB_GSPCA_SN9C2028=m
CONFIG_USB_GSPCA_SN9C20X=m
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA1528=m
CONFIG_USB_GSPCA_SPCA500=m
CONFIG_USB_GSPCA_SPCA501=m
CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
CONFIG_USB_GSPCA_SPCA508=m
CONFIG_USB_GSPCA_SPCA561=m
CONFIG_USB_GSPCA_SQ905=m
CONFIG_USB_GSPCA_SQ905C=m
CONFIG_USB_GSPCA_SQ930X=m
CONFIG_USB_GSPCA_STK014=m
CONFIG_USB_GSPCA_STK1135=m
CONFIG_USB_GSPCA_STV0680=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
CONFIG_USB_GSPCA_TOPRO=m
CONFIG_USB_GSPCA_TOUPTEK=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_VICAM=m
CONFIG_USB_GSPCA_XIRLINK_CIT=m
CONFIG_USB_GSPCA_ZC3XX=m
CONFIG_USB_GL860=m
CONFIG_USB_M5602=m
CONFIG_USB_STV06XX=m
CONFIG_USB_PWC=m
CONFIG_USB_PWC_DEBUG=y
CONFIG_USB_PWC_INPUT_EVDEV=y
CONFIG_USB_S2255=m
CONFIG_VIDEO_USBTV=m
CONFIG_USB_VIDEO_CLASS=m
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y

#
# Analog TV USB devices
#
CONFIG_VIDEO_GO7007=m
CONFIG_VIDEO_GO7007_USB=m
CONFIG_VIDEO_GO7007_LOADER=m
CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m
CONFIG_VIDEO_HDPVR=m
CONFIG_VIDEO_PVRUSB2=m
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
CONFIG_VIDEO_PVRUSB2_DEBUGIFC=y
CONFIG_VIDEO_STK1160_COMMON=m
CONFIG_VIDEO_STK1160=m

#
# Analog/digital TV USB devices
#
CONFIG_VIDEO_AU0828=m
CONFIG_VIDEO_AU0828_V4L2=y
CONFIG_VIDEO_AU0828_RC=y
CONFIG_VIDEO_CX231XX=m
CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_CX231XX_ALSA=m
CONFIG_VIDEO_CX231XX_DVB=m

#
# Digital TV USB devices
#
CONFIG_DVB_AS102=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG=y
CONFIG_DVB_USB_V2=m
CONFIG_DVB_USB_AF9015=m
CONFIG_DVB_USB_AF9035=m
CONFIG_DVB_USB_ANYSEE=m
CONFIG_DVB_USB_AU6610=m
CONFIG_DVB_USB_AZ6007=m
CONFIG_DVB_USB_CE6230=m
CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_USB_EC168=m
CONFIG_DVB_USB_GL861=m
CONFIG_DVB_USB_LME2510=m
CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
CONFIG_DVB_USB_ZD1301=m
CONFIG_DVB_USB=m
CONFIG_DVB_USB_DEBUG=y
CONFIG_DVB_USB_A800=m
CONFIG_DVB_USB_AF9005=m
CONFIG_DVB_USB_AF9005_REMOTE=m
CONFIG_DVB_USB_AZ6027=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_CXUSB=m
CONFIG_DVB_USB_CXUSB_ANALOG=y
CONFIG_DVB_USB_DIB0700=m
CONFIG_DVB_USB_DIB3000MC=m
CONFIG_DVB_USB_DIBUSB_MB=m
CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
CONFIG_DVB_USB_DIBUSB_MC=m
CONFIG_DVB_USB_DIGITV=m
CONFIG_DVB_USB_DTT200U=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_DW2102=m
CONFIG_DVB_USB_GP8PSK=m
CONFIG_DVB_USB_M920X=m
CONFIG_DVB_USB_NOVA_T_USB2=m
CONFIG_DVB_USB_OPERA1=m
CONFIG_DVB_USB_PCTV452E=m
CONFIG_DVB_USB_TECHNISAT_USB2=m
CONFIG_DVB_USB_TTUSB2=m
CONFIG_DVB_USB_UMT_010=m
CONFIG_DVB_USB_VP702X=m
CONFIG_DVB_USB_VP7045=m

#
# Webcam, TV (analog/digital) USB devices
#
CONFIG_VIDEO_EM28XX=m
CONFIG_VIDEO_EM28XX_V4L2=m
CONFIG_VIDEO_EM28XX_ALSA=m
CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_VIDEO_EM28XX_RC=m

#
# Software defined radio USB devices
#
CONFIG_USB_AIRSPY=m
CONFIG_USB_HACKRF=m
CONFIG_USB_MSI2500=m
CONFIG_RADIO_ADAPTERS=m
CONFIG_RADIO_SAA7706H=m
CONFIG_RADIO_SHARK=m
CONFIG_RADIO_SHARK2=m
CONFIG_RADIO_SI4713=m
CONFIG_RADIO_SI476X=m
CONFIG_RADIO_TEA575X=m
CONFIG_RADIO_TEA5764=m
CONFIG_RADIO_TEF6862=m
CONFIG_RADIO_WL1273=m
CONFIG_USB_DSBR=m
CONFIG_USB_KEENE=m
CONFIG_USB_MA901=m
CONFIG_USB_MR800=m
CONFIG_USB_RAREMONO=m
CONFIG_RADIO_SI470X=m
CONFIG_USB_SI470X=m
CONFIG_I2C_SI470X=m
CONFIG_USB_SI4713=m
CONFIG_PLATFORM_SI4713=m
CONFIG_I2C_SI4713=m
CONFIG_RADIO_WL128X=m
CONFIG_V4L_RADIO_ISA_DRIVERS=y
CONFIG_RADIO_AZTECH=m
CONFIG_RADIO_CADET=m
CONFIG_RADIO_GEMTEK=m
CONFIG_RADIO_ISA=m
CONFIG_RADIO_RTRACK=m
CONFIG_RADIO_RTRACK2=m
CONFIG_RADIO_SF16FMI=m
CONFIG_RADIO_SF16FMR2=m
CONFIG_RADIO_TERRATEC=m
CONFIG_RADIO_TRUST=m
CONFIG_RADIO_TYPHOON=m
CONFIG_RADIO_ZOLTRIX=m
CONFIG_MEDIA_PLATFORM_DRIVERS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_DVB_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_MUX=m

#
# Allegro DVT media platform drivers
#
CONFIG_VIDEO_ALLEGRO_DVT=m

#
# Amlogic media platform drivers
#
CONFIG_VIDEO_MESON_GE2D=m

#
# Amphion drivers
#
CONFIG_VIDEO_AMPHION_VPU=m

#
# Aspeed media platform drivers
#
CONFIG_VIDEO_ASPEED=m

#
# Atmel media platform drivers
#
CONFIG_VIDEO_ATMEL_ISC=m
CONFIG_VIDEO_ATMEL_XISC=m
CONFIG_VIDEO_ATMEL_ISC_BASE=m
CONFIG_VIDEO_ATMEL_ISI=m
CONFIG_VIDEO_MICROCHIP_CSI2DC=m

#
# Cadence media platform drivers
#
CONFIG_VIDEO_CADENCE_CSI2RX=m
CONFIG_VIDEO_CADENCE_CSI2TX=m

#
# Chips&Media media platform drivers
#
CONFIG_VIDEO_CODA=m
CONFIG_VIDEO_IMX_VDOA=m

#
# Intel media platform drivers
#
CONFIG_VIDEO_PXA27x=m

#
# Marvell media platform drivers
#
CONFIG_VIDEO_MMP_CAMERA=m

#
# Mediatek media platform drivers
#
CONFIG_VIDEO_MEDIATEK_JPEG=m
CONFIG_VIDEO_MEDIATEK_MDP=m
CONFIG_VIDEO_MEDIATEK_VCODEC_VPU=y
CONFIG_VIDEO_MEDIATEK_VCODEC=m
CONFIG_VIDEO_MEDIATEK_VPU=m

#
# NVidia media platform drivers
#
CONFIG_VIDEO_TEGRA_VDE=m

#
# NXP media platform drivers
#
CONFIG_VIDEO_IMX_MIPI_CSIS=m
CONFIG_VIDEO_IMX_PXP=m
CONFIG_VIDEO_MX2_EMMAPRP=m
CONFIG_VIDEO_DW100=m
CONFIG_VIDEO_IMX8_JPEG=m

#
# Qualcomm media platform drivers
#
CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_VIDEO_QCOM_VENUS=m

#
# Renesas media platform drivers
#
CONFIG_VIDEO_RENESAS_CEU=m
CONFIG_VIDEO_RCAR_ISP=m
CONFIG_VIDEO_SH_VOU=m
CONFIG_VIDEO_RCAR_CSI2=m
CONFIG_VIDEO_RCAR_VIN=m
CONFIG_VIDEO_RENESAS_FCP=m
CONFIG_VIDEO_RENESAS_FDP1=m
CONFIG_VIDEO_RENESAS_JPU=m
CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_VIDEO_RCAR_DRIF=m

#
# Rockchip media platform drivers
#
CONFIG_VIDEO_ROCKCHIP_RGA=m
CONFIG_VIDEO_ROCKCHIP_ISP1=m

#
# Samsung media platform drivers
#
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
CONFIG_VIDEO_S5P_MIPI_CSIS=m
CONFIG_VIDEO_S3C_CAMIF=m
CONFIG_VIDEO_SAMSUNG_S5P_G2D=m
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m

#
# STMicroelectronics media platform drivers
#
CONFIG_VIDEO_STI_BDISP=m
CONFIG_DVB_C8SECTPFE=m
CONFIG_VIDEO_STI_DELTA=m
CONFIG_VIDEO_STI_DELTA_MJPEG=y
CONFIG_VIDEO_STI_DELTA_DRIVER=m
CONFIG_VIDEO_STI_HVA=m
CONFIG_VIDEO_STI_HVA_DEBUGFS=y
CONFIG_VIDEO_STM32_DCMI=m
CONFIG_VIDEO_STM32_DMA2D=m

#
# Sunxi media platform drivers
#
CONFIG_VIDEO_SUN6I_MIPI_CSI2=m
CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2=m
CONFIG_VIDEO_SUN8I_DEINTERLACE=m
CONFIG_VIDEO_SUN8I_ROTATE=m

#
# Texas Instruments drivers
#
CONFIG_VIDEO_TI_VPDMA=m
CONFIG_VIDEO_TI_SC=m
CONFIG_VIDEO_TI_CSC=m
CONFIG_VIDEO_TI_CAL=m
CONFIG_VIDEO_TI_CAL_MC=y
CONFIG_VIDEO_TI_VPE=m
CONFIG_VIDEO_TI_VPE_DEBUG=y
CONFIG_VIDEO_AM437X_VPFE=m
CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY=m
CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE=m
CONFIG_VIDEO_DAVINCI_VPBE_DISPLAY=m
CONFIG_VIDEO_OMAP3=m
CONFIG_VIDEO_OMAP3_DEBUG=y

#
# Verisilicon media platform drivers
#
CONFIG_VIDEO_HANTRO=m
CONFIG_VIDEO_HANTRO_IMX8M=y
CONFIG_VIDEO_HANTRO_SAMA5D4=y
CONFIG_VIDEO_HANTRO_ROCKCHIP=y
CONFIG_VIDEO_HANTRO_SUNXI=y

#
# VIA media platform drivers
#

#
# Xilinx media platform drivers
#
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=m
CONFIG_VIDEO_VICODEC=m
CONFIG_VIDEO_VIMC=m
CONFIG_DVB_TEST_DRIVERS=y
CONFIG_DVB_VIDTV=m

#
# FireWire (IEEE 1394) Adapters
#
CONFIG_DVB_FIREDTV=m
CONFIG_DVB_FIREDTV_INPUT=y
CONFIG_CYPRESS_FIRMWARE=m
CONFIG_TTPCI_EEPROM=m
CONFIG_VIDEO_CX2341X=m
CONFIG_VIDEO_TVEEPROM=m
CONFIG_DVB_B2C2_FLEXCOP=m
CONFIG_DVB_B2C2_FLEXCOP_DEBUG=y
CONFIG_VIDEO_V4L2_TPG=m
CONFIG_VIDEOBUF2_CORE=m
CONFIG_VIDEOBUF2_V4L2=m
CONFIG_VIDEOBUF2_MEMOPS=m
CONFIG_VIDEOBUF2_DMA_CONTIG=m
CONFIG_VIDEOBUF2_VMALLOC=m
CONFIG_VIDEOBUF2_DMA_SG=m
# end of Media drivers

#
# Media ancillary drivers
#
CONFIG_MEDIA_ATTACH=y

#
# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
#
CONFIG_VIDEO_IR_I2C=m

#
# Camera sensor devices
#
CONFIG_VIDEO_APTINA_PLL=m
CONFIG_VIDEO_CCS_PLL=m
CONFIG_VIDEO_AR0521=m
CONFIG_VIDEO_HI556=m
CONFIG_VIDEO_HI846=m
CONFIG_VIDEO_HI847=m
CONFIG_VIDEO_IMX208=m
CONFIG_VIDEO_IMX214=m
CONFIG_VIDEO_IMX219=m
CONFIG_VIDEO_IMX258=m
CONFIG_VIDEO_IMX274=m
CONFIG_VIDEO_IMX290=m
CONFIG_VIDEO_IMX319=m
CONFIG_VIDEO_IMX334=m
CONFIG_VIDEO_IMX335=m
CONFIG_VIDEO_IMX355=m
CONFIG_VIDEO_IMX412=m
CONFIG_VIDEO_IMX492=m
CONFIG_VIDEO_MAX9271_LIB=m
CONFIG_VIDEO_MT9M001=m
CONFIG_VIDEO_MT9M032=m
CONFIG_VIDEO_MT9M111=m
CONFIG_VIDEO_MT9P031=m
CONFIG_VIDEO_MT9T001=m
CONFIG_VIDEO_MT9T112=m
CONFIG_VIDEO_MT9V011=m
CONFIG_VIDEO_MT9V032=m
CONFIG_VIDEO_MT9V111=m
CONFIG_VIDEO_NOON010PC30=m
CONFIG_VIDEO_OG01A1B=m
CONFIG_VIDEO_OV02A10=m
CONFIG_VIDEO_OV08D10=m
CONFIG_VIDEO_OV13858=m
CONFIG_VIDEO_OV13B10=m
CONFIG_VIDEO_OV2640=m
CONFIG_VIDEO_OV2659=m
CONFIG_VIDEO_OV2680=m
CONFIG_VIDEO_OV2685=m
CONFIG_VIDEO_OV2740=m
CONFIG_VIDEO_OV4689=m
CONFIG_VIDEO_OV5640=m
CONFIG_VIDEO_OV5645=m
CONFIG_VIDEO_OV5647=m
CONFIG_VIDEO_OV5648=m
CONFIG_VIDEO_OV5670=m
CONFIG_VIDEO_OV5675=m
CONFIG_VIDEO_OV5693=m
CONFIG_VIDEO_OV5695=m
CONFIG_VIDEO_OV6650=m
CONFIG_VIDEO_OV7251=m
CONFIG_VIDEO_OV7640=m
CONFIG_VIDEO_OV7670=m
CONFIG_VIDEO_OV772X=m
CONFIG_VIDEO_OV7740=m
CONFIG_VIDEO_OV8856=m
CONFIG_VIDEO_OV8865=m
CONFIG_VIDEO_OV9282=m
CONFIG_VIDEO_OV9640=m
CONFIG_VIDEO_OV9650=m
CONFIG_VIDEO_OV9734=m
CONFIG_VIDEO_RDACM20=m
CONFIG_VIDEO_RDACM21=m
CONFIG_VIDEO_RJ54N1=m
CONFIG_VIDEO_S5C73M3=m
CONFIG_VIDEO_S5K4ECGX=m
CONFIG_VIDEO_S5K5BAF=m
CONFIG_VIDEO_S5K6A3=m
CONFIG_VIDEO_S5K6AA=m
CONFIG_VIDEO_SR030PC30=m
CONFIG_VIDEO_ST_VGXY61=m
CONFIG_VIDEO_VS6624=m
CONFIG_VIDEO_CCS=m
CONFIG_VIDEO_ET8EK8=m
CONFIG_VIDEO_M5MOLS=m
# end of Camera sensor devices

#
# Lens drivers
#
CONFIG_VIDEO_AD5820=m
CONFIG_VIDEO_AK7375=m
CONFIG_VIDEO_DW9714=m
CONFIG_VIDEO_DW9768=m
CONFIG_VIDEO_DW9807_VCM=m
# end of Lens drivers

#
# Flash devices
#
CONFIG_VIDEO_ADP1653=m
CONFIG_VIDEO_LM3560=m
CONFIG_VIDEO_LM3646=m
# end of Flash devices

#
# Audio decoders, processors and mixers
#
CONFIG_VIDEO_CS3308=m
CONFIG_VIDEO_CS5345=m
CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_SONY_BTF_MPX=m
CONFIG_VIDEO_TDA1997X=m
CONFIG_VIDEO_TDA7432=m
CONFIG_VIDEO_TDA9840=m
CONFIG_VIDEO_TEA6415C=m
CONFIG_VIDEO_TEA6420=m
CONFIG_VIDEO_TLV320AIC23B=m
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_UDA1342=m
CONFIG_VIDEO_VP27SMPX=m
CONFIG_VIDEO_WM8739=m
CONFIG_VIDEO_WM8775=m
# end of Audio decoders, processors and mixers

#
# RDS decoders
#
CONFIG_VIDEO_SAA6588=m
# end of RDS decoders

#
# Video decoders
#
CONFIG_VIDEO_ADV7180=m
CONFIG_VIDEO_ADV7183=m
CONFIG_VIDEO_ADV748X=m
CONFIG_VIDEO_ADV7604=m
CONFIG_VIDEO_ADV7604_CEC=y
CONFIG_VIDEO_ADV7842=m
CONFIG_VIDEO_ADV7842_CEC=y
CONFIG_VIDEO_BT819=m
CONFIG_VIDEO_BT856=m
CONFIG_VIDEO_BT866=m
CONFIG_VIDEO_ISL7998X=m
CONFIG_VIDEO_KS0127=m
CONFIG_VIDEO_MAX9286=m
CONFIG_VIDEO_ML86V7667=m
CONFIG_VIDEO_SAA7110=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TC358743=m
CONFIG_VIDEO_TC358743_CEC=y
CONFIG_VIDEO_TC358746=m
CONFIG_VIDEO_TVP514X=m
CONFIG_VIDEO_TVP5150=m
CONFIG_VIDEO_TVP7002=m
CONFIG_VIDEO_TW2804=m
CONFIG_VIDEO_TW9903=m
CONFIG_VIDEO_TW9906=m
CONFIG_VIDEO_TW9910=m
CONFIG_VIDEO_VPX3220=m

#
# Video and audio decoders
#
CONFIG_VIDEO_SAA717X=m
CONFIG_VIDEO_CX25840=m
# end of Video decoders

#
# Video encoders
#
CONFIG_VIDEO_AD9389B=m
CONFIG_VIDEO_ADV7170=m
CONFIG_VIDEO_ADV7175=m
CONFIG_VIDEO_ADV7343=m
CONFIG_VIDEO_ADV7393=m
CONFIG_VIDEO_ADV7511=m
CONFIG_VIDEO_ADV7511_CEC=y
CONFIG_VIDEO_AK881X=m
CONFIG_VIDEO_SAA7127=m
CONFIG_VIDEO_SAA7185=m
CONFIG_VIDEO_THS8200=m
# end of Video encoders

#
# Video improvement chips
#
CONFIG_VIDEO_UPD64031A=m
CONFIG_VIDEO_UPD64083=m
# end of Video improvement chips

#
# Audio/Video compression chips
#
CONFIG_VIDEO_SAA6752HS=m
# end of Audio/Video compression chips

#
# SDR tuner chips
#
CONFIG_SDR_MAX2175=m
# end of SDR tuner chips

#
# Miscellaneous helper chips
#
CONFIG_VIDEO_I2C=m
CONFIG_VIDEO_M52790=m
CONFIG_VIDEO_ST_MIPID02=m
CONFIG_VIDEO_THS7303=m
# end of Miscellaneous helper chips

#
# Media SPI Adapters
#
CONFIG_CXD2880_SPI_DRV=m
CONFIG_VIDEO_GS1662=m
# end of Media SPI Adapters

CONFIG_MEDIA_TUNER=m

#
# Customize TV tuners
#
CONFIG_MEDIA_TUNER_E4000=m
CONFIG_MEDIA_TUNER_FC0011=m
CONFIG_MEDIA_TUNER_FC0012=m
CONFIG_MEDIA_TUNER_FC0013=m
CONFIG_MEDIA_TUNER_FC2580=m
CONFIG_MEDIA_TUNER_IT913X=m
CONFIG_MEDIA_TUNER_M88RS6000T=m
CONFIG_MEDIA_TUNER_MAX2165=m
CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_MEDIA_TUNER_MSI001=m
CONFIG_MEDIA_TUNER_MT2060=m
CONFIG_MEDIA_TUNER_MT2063=m
CONFIG_MEDIA_TUNER_MT20XX=m
CONFIG_MEDIA_TUNER_MT2131=m
CONFIG_MEDIA_TUNER_MT2266=m
CONFIG_MEDIA_TUNER_MXL301RF=m
CONFIG_MEDIA_TUNER_MXL5005S=m
CONFIG_MEDIA_TUNER_MXL5007T=m
CONFIG_MEDIA_TUNER_QM1D1B0004=m
CONFIG_MEDIA_TUNER_QM1D1C0042=m
CONFIG_MEDIA_TUNER_QT1010=m
CONFIG_MEDIA_TUNER_R820T=m
CONFIG_MEDIA_TUNER_SI2157=m
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA18212=m
CONFIG_MEDIA_TUNER_TDA18218=m
CONFIG_MEDIA_TUNER_TDA18250=m
CONFIG_MEDIA_TUNER_TDA18271=m
CONFIG_MEDIA_TUNER_TDA827X=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA9887=m
CONFIG_MEDIA_TUNER_TEA5761=m
CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_TUA9001=m
CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC4000=m
CONFIG_MEDIA_TUNER_XC5000=m
# end of Customize TV tuners

#
# Customise DVB Frontends
#

#
# Multistandard (satellite) frontends
#
CONFIG_DVB_M88DS3103=m
CONFIG_DVB_MXL5XX=m
CONFIG_DVB_STB0899=m
CONFIG_DVB_STB6100=m
CONFIG_DVB_STV090x=m
CONFIG_DVB_STV0910=m
CONFIG_DVB_STV6110x=m
CONFIG_DVB_STV6111=m

#
# Multistandard (cable + terrestrial) frontends
#
CONFIG_DVB_DRXK=m
CONFIG_DVB_MN88472=m
CONFIG_DVB_MN88473=m
CONFIG_DVB_SI2165=m
CONFIG_DVB_TDA18271C2DD=m

#
# DVB-S (satellite) frontends
#
CONFIG_DVB_CX24110=m
CONFIG_DVB_CX24116=m
CONFIG_DVB_CX24117=m
CONFIG_DVB_CX24120=m
CONFIG_DVB_CX24123=m
CONFIG_DVB_DS3000=m
CONFIG_DVB_MB86A16=m
CONFIG_DVB_MT312=m
CONFIG_DVB_S5H1420=m
CONFIG_DVB_SI21XX=m
CONFIG_DVB_STB6000=m
CONFIG_DVB_STV0288=m
CONFIG_DVB_STV0299=m
CONFIG_DVB_STV0900=m
CONFIG_DVB_STV6110=m
CONFIG_DVB_TDA10071=m
CONFIG_DVB_TDA10086=m
CONFIG_DVB_TDA8083=m
CONFIG_DVB_TDA8261=m
CONFIG_DVB_TDA826X=m
CONFIG_DVB_TS2020=m
CONFIG_DVB_TUA6100=m
CONFIG_DVB_TUNER_CX24113=m
CONFIG_DVB_TUNER_ITD1000=m
CONFIG_DVB_VES1X93=m
CONFIG_DVB_ZL10036=m
CONFIG_DVB_ZL10039=m

#
# DVB-T (terrestrial) frontends
#
CONFIG_DVB_AF9013=m
CONFIG_DVB_AS102_FE=m
CONFIG_DVB_CX22700=m
CONFIG_DVB_CX22702=m
CONFIG_DVB_CXD2820R=m
CONFIG_DVB_CXD2841ER=m
CONFIG_DVB_DIB3000MB=m
CONFIG_DVB_DIB3000MC=m
CONFIG_DVB_DIB7000M=m
CONFIG_DVB_DIB7000P=m
CONFIG_DVB_DIB9000=m
CONFIG_DVB_DRXD=m
CONFIG_DVB_EC100=m
CONFIG_DVB_GP8PSK_FE=m
CONFIG_DVB_L64781=m
CONFIG_DVB_MT352=m
CONFIG_DVB_NXT6000=m
CONFIG_DVB_RTL2830=m
CONFIG_DVB_RTL2832=m
CONFIG_DVB_RTL2832_SDR=m
CONFIG_DVB_S5H1432=m
CONFIG_DVB_SI2168=m
CONFIG_DVB_SP887X=m
CONFIG_DVB_STV0367=m
CONFIG_DVB_TDA10048=m
CONFIG_DVB_TDA1004X=m
CONFIG_DVB_ZD1301_DEMOD=m
CONFIG_DVB_ZL10353=m
CONFIG_DVB_CXD2880=m

#
# DVB-C (cable) frontends
#
CONFIG_DVB_STV0297=m
CONFIG_DVB_TDA10021=m
CONFIG_DVB_TDA10023=m
CONFIG_DVB_VES1820=m

#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
CONFIG_DVB_AU8522=m
CONFIG_DVB_AU8522_DTV=m
CONFIG_DVB_AU8522_V4L=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LG2160=m
CONFIG_DVB_LGDT3305=m
CONFIG_DVB_LGDT3306A=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_MXL692=m
CONFIG_DVB_NXT200X=m
CONFIG_DVB_OR51132=m
CONFIG_DVB_OR51211=m
CONFIG_DVB_S5H1409=m
CONFIG_DVB_S5H1411=m

#
# ISDB-T (terrestrial) frontends
#
CONFIG_DVB_DIB8000=m
CONFIG_DVB_MB86A20S=m
CONFIG_DVB_S921=m

#
# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
#
CONFIG_DVB_MN88443X=m
CONFIG_DVB_TC90522=m

#
# Digital terrestrial only tuners/PLL
#
CONFIG_DVB_PLL=m
CONFIG_DVB_TUNER_DIB0070=m
CONFIG_DVB_TUNER_DIB0090=m

#
# SEC control devices for DVB-S
#
CONFIG_DVB_A8293=m
CONFIG_DVB_AF9033=m
CONFIG_DVB_ASCOT2E=m
CONFIG_DVB_ATBM8830=m
CONFIG_DVB_HELENE=m
CONFIG_DVB_HORUS3A=m
CONFIG_DVB_ISL6405=m
CONFIG_DVB_ISL6421=m
CONFIG_DVB_ISL6423=m
CONFIG_DVB_IX2505V=m
CONFIG_DVB_LGS8GL5=m
CONFIG_DVB_LGS8GXX=m
CONFIG_DVB_LNBH25=m
CONFIG_DVB_LNBH29=m
CONFIG_DVB_LNBP21=m
CONFIG_DVB_LNBP22=m
CONFIG_DVB_M88RS2000=m
CONFIG_DVB_TDA665x=m
CONFIG_DVB_DRX39XYJ=m

#
# Common Interface (EN50221) controller drivers
#
CONFIG_DVB_CXD2099=m
CONFIG_DVB_SP2=m
# end of Customise DVB Frontends

#
# Tools to develop new frontends
#
CONFIG_DVB_DUMMY_FE=m
# end of Media ancillary drivers

#
# Graphics support
#
CONFIG_APERTURE_HELPERS=y
CONFIG_IMX_IPUV3_CORE=m
CONFIG_DRM_DEBUG_MODESET_LOCK=y

#
# ARM devices
#
# end of ARM devices

#
# Frame buffer Devices
#
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB=m
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_CFB_FILLRECT=m
CONFIG_FB_CFB_COPYAREA=m
CONFIG_FB_CFB_IMAGEBLIT=m
CONFIG_FB_CFB_REV_PIXELS_IN_BYTE=y
CONFIG_FB_SYS_FILLRECT=m
CONFIG_FB_SYS_COPYAREA=m
CONFIG_FB_SYS_IMAGEBLIT=m
CONFIG_FB_FOREIGN_ENDIAN=y
CONFIG_FB_BOTH_ENDIAN=y
# CONFIG_FB_BIG_ENDIAN is not set
# CONFIG_FB_LITTLE_ENDIAN is not set
CONFIG_FB_SYS_FOPS=m
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_BACKLIGHT=m
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y

#
# Frame buffer hardware drivers
#
CONFIG_FB_CLPS711X=m
CONFIG_FB_IMX=m
CONFIG_FB_ARC=m
CONFIG_FB_UVESA=m
CONFIG_FB_PVR2=m
CONFIG_FB_S1D13XXX=m
CONFIG_FB_ATMEL=m
CONFIG_FB_PXA168=m
CONFIG_FB_W100=m
CONFIG_FB_SH_MOBILE_LCDC=m
CONFIG_FB_TMIO=m
CONFIG_FB_TMIO_ACCELL=y
CONFIG_FB_S3C=m
CONFIG_FB_S3C_DEBUG_REGWRITE=y
CONFIG_FB_SMSCUFX=m
CONFIG_FB_UDL=m
CONFIG_FB_IBM_GXT4500=m
CONFIG_FB_GOLDFISH=m
CONFIG_FB_DA8XX=m
CONFIG_FB_VIRTUAL=m
CONFIG_FB_METRONOME=m
CONFIG_FB_BROADSHEET=m
CONFIG_FB_SIMPLE=m
CONFIG_FB_SSD1307=m
CONFIG_FB_OMAP2=m
CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
CONFIG_FB_OMAP2_NUM_FBS=3
CONFIG_FB_OMAP2_DSS_INIT=y
CONFIG_FB_OMAP2_DSS=m
CONFIG_FB_OMAP2_DSS_DEBUG=y
CONFIG_FB_OMAP2_DSS_DEBUGFS=y
CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS=y
CONFIG_FB_OMAP2_DSS_DPI=y
CONFIG_FB_OMAP2_DSS_VENC=y
CONFIG_FB_OMAP2_DSS_HDMI_COMMON=y
CONFIG_FB_OMAP4_DSS_HDMI=y
CONFIG_FB_OMAP5_DSS_HDMI=y
CONFIG_FB_OMAP2_DSS_SDI=y
CONFIG_FB_OMAP2_DSS_DSI=y
CONFIG_FB_OMAP2_DSS_MIN_FCK_PER_PCK=0
CONFIG_FB_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y

#
# OMAPFB Panel and Encoder Drivers
#
CONFIG_FB_OMAP2_ENCODER_OPA362=m
CONFIG_FB_OMAP2_ENCODER_TFP410=m
CONFIG_FB_OMAP2_ENCODER_TPD12S015=m
CONFIG_FB_OMAP2_CONNECTOR_DVI=m
CONFIG_FB_OMAP2_CONNECTOR_HDMI=m
CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV=m
CONFIG_FB_OMAP2_PANEL_DPI=m
CONFIG_FB_OMAP2_PANEL_DSI_CM=m
CONFIG_FB_OMAP2_PANEL_SONY_ACX565AKM=m
CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02=m
CONFIG_FB_OMAP2_PANEL_SHARP_LS037V7DW01=m
CONFIG_FB_OMAP2_PANEL_TPO_TD028TTEC1=m
CONFIG_FB_OMAP2_PANEL_TPO_TD043MTEA1=m
CONFIG_FB_OMAP2_PANEL_NEC_NL8048HL11=m
# end of OMAPFB Panel and Encoder Drivers

CONFIG_MMP_DISP=m
CONFIG_MMP_DISP_CONTROLLER=y
CONFIG_MMP_DISP_SPI=y
CONFIG_MMP_PANEL_TPOHVGA=y
CONFIG_MMP_FB=m
# end of Frame buffer Devices

#
# Backlight & LCD device support
#
CONFIG_LCD_CLASS_DEVICE=m
CONFIG_LCD_L4F00242T03=m
CONFIG_LCD_LMS283GF05=m
CONFIG_LCD_LTV350QV=m
CONFIG_LCD_ILI922X=m
CONFIG_LCD_ILI9320=m
CONFIG_LCD_TDO24M=m
CONFIG_LCD_VGG2432A4=m
CONFIG_LCD_PLATFORM=m
CONFIG_LCD_AMS369FG06=m
CONFIG_LCD_LMS501KF03=m
CONFIG_LCD_HX8357=m
CONFIG_LCD_OTM3225A=m
CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_ATMEL_LCDC=y
CONFIG_BACKLIGHT_KTD253=m
CONFIG_BACKLIGHT_LM3533=m
CONFIG_BACKLIGHT_OMAP1=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_DA9052=m
CONFIG_BACKLIGHT_MT6370=m
CONFIG_BACKLIGHT_QCOM_WLED=m
CONFIG_BACKLIGHT_RT4831=m
CONFIG_BACKLIGHT_WM831X=m
CONFIG_BACKLIGHT_ADP8860=m
CONFIG_BACKLIGHT_ADP8870=m
CONFIG_BACKLIGHT_PCF50633=m
CONFIG_BACKLIGHT_LM3630A=m
CONFIG_BACKLIGHT_LM3639=m
CONFIG_BACKLIGHT_LP855X=m
CONFIG_BACKLIGHT_SKY81452=m
CONFIG_BACKLIGHT_TPS65217=m
CONFIG_BACKLIGHT_GPIO=m
CONFIG_BACKLIGHT_LV5207LP=m
CONFIG_BACKLIGHT_BD6107=m
CONFIG_BACKLIGHT_ARCXCNN=m
CONFIG_BACKLIGHT_RAVE_SP=m
CONFIG_BACKLIGHT_LED=m
# end of Backlight & LCD device support

CONFIG_VIDEOMODE_HELPERS=y
CONFIG_HDMI=y

#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# end of Console display driver support

CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_LOGO_SUPERH_MONO=y
CONFIG_LOGO_SUPERH_VGA16=y
CONFIG_LOGO_SUPERH_CLUT224=y
# end of Graphics support

CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_PCM_ELD=y
CONFIG_SND_PCM_IEC958=y
CONFIG_SND_DMAENGINE_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_SEQ_DEVICE=m
CONFIG_SND_RAWMIDI=m
CONFIG_SND_COMPRESS_OFFLOAD=m
CONFIG_SND_JACK=y
CONFIG_SND_JACK_INPUT_DEV=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_PCM_TIMER=y
CONFIG_SND_HRTIMER=m
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_MAX_CARDS=32
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_PROC_FS=y
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_CTL_FAST_LOOKUP=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_PCM_XRUN_DEBUG=y
CONFIG_SND_CTL_INPUT_VALIDATION=y
CONFIG_SND_CTL_DEBUG=y
CONFIG_SND_JACK_INJECTION_DEBUG=y
CONFIG_SND_VMASTER=y
CONFIG_SND_CTL_LED=m
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
CONFIG_SND_SEQUENCER_OSS=m
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
CONFIG_SND_SEQ_MIDI_EVENT=m
CONFIG_SND_SEQ_MIDI=m
CONFIG_SND_SEQ_VIRMIDI=m
CONFIG_SND_MPU401_UART=m
CONFIG_SND_VX_LIB=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_DRIVERS=y
CONFIG_SND_DUMMY=m
CONFIG_SND_ALOOP=m
CONFIG_SND_VIRMIDI=m
CONFIG_SND_MTPAV=m
CONFIG_SND_MTS64=m
CONFIG_SND_SERIAL_U16550=m
CONFIG_SND_SERIAL_GENERIC=m
CONFIG_SND_MPU401=m
CONFIG_SND_PORTMAN2X4=m
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0

#
# HD-Audio
#
CONFIG_SND_HDA=m
CONFIG_SND_HDA_GENERIC_LEDS=y
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_RECONFIG=y
CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_INPUT_BEEP_MODE=1
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_CODEC_REALTEK=m
CONFIG_SND_HDA_CODEC_ANALOG=m
CONFIG_SND_HDA_CODEC_SIGMATEL=m
CONFIG_SND_HDA_CODEC_VIA=m
CONFIG_SND_HDA_CODEC_HDMI=m
CONFIG_SND_HDA_CODEC_CIRRUS=m
CONFIG_SND_HDA_CODEC_CS8409=m
CONFIG_SND_HDA_CODEC_CONEXANT=m
CONFIG_SND_HDA_CODEC_CA0110=m
CONFIG_SND_HDA_CODEC_CA0132=m
CONFIG_SND_HDA_CODEC_CA0132_DSP=y
CONFIG_SND_HDA_CODEC_CMEDIA=m
CONFIG_SND_HDA_CODEC_SI3054=m
CONFIG_SND_HDA_GENERIC=m
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
# end of HD-Audio

CONFIG_SND_HDA_CORE=m
CONFIG_SND_HDA_DSP_LOADER=y
CONFIG_SND_HDA_EXT_CORE=m
CONFIG_SND_HDA_PREALLOC_SIZE=64
CONFIG_SND_INTEL_DSP_CONFIG=m
CONFIG_SND_PXA2XX_LIB=m
CONFIG_SND_SPI=y
CONFIG_SND_AT73C213=m
CONFIG_SND_AT73C213_TARGET_BITRATE=48000
CONFIG_SND_SUPERH=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_CAIAQ=m
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_US122L=m
CONFIG_SND_USB_6FIRE=m
CONFIG_SND_USB_HIFACE=m
CONFIG_SND_BCD2000=m
CONFIG_SND_USB_LINE6=m
CONFIG_SND_USB_POD=m
CONFIG_SND_USB_PODHD=m
CONFIG_SND_USB_TONEPORT=m
CONFIG_SND_USB_VARIAX=m
CONFIG_SND_FIREWIRE=y
CONFIG_SND_FIREWIRE_LIB=m
CONFIG_SND_DICE=m
CONFIG_SND_OXFW=m
CONFIG_SND_ISIGHT=m
CONFIG_SND_FIREWORKS=m
CONFIG_SND_BEBOB=m
CONFIG_SND_FIREWIRE_DIGI00X=m
CONFIG_SND_FIREWIRE_TASCAM=m
CONFIG_SND_FIREWIRE_MOTU=m
CONFIG_SND_FIREFACE=m
CONFIG_SND_PCMCIA=y
CONFIG_SND_VXPOCKET=m
CONFIG_SND_PDAUDIOCF=m
CONFIG_SND_SOC=m
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_SOC_COMPRESS=y
CONFIG_SND_SOC_TOPOLOGY=y
CONFIG_SND_SOC_TOPOLOGY_KUNIT_TEST=m
CONFIG_SND_SOC_UTILS_KUNIT_TEST=m
CONFIG_SND_SOC_ADI=m
CONFIG_SND_SOC_ADI_AXI_I2S=m
CONFIG_SND_SOC_ADI_AXI_SPDIF=m
CONFIG_SND_SOC_AMD_ACP=m
CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m
CONFIG_SND_AMD_ACP_CONFIG=m
CONFIG_SND_SOC_APPLE_MCA=m
CONFIG_SND_ATMEL_SOC=m
CONFIG_SND_ATMEL_SOC_PDC=y
CONFIG_SND_ATMEL_SOC_DMA=y
CONFIG_SND_ATMEL_SOC_SSC=m
CONFIG_SND_ATMEL_SOC_SSC_PDC=m
CONFIG_SND_ATMEL_SOC_SSC_DMA=m
CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m
CONFIG_SND_ATMEL_SOC_WM8904=m
CONFIG_SND_AT91_SOC_SAM9X5_WM8731=m
CONFIG_SND_ATMEL_SOC_CLASSD=m
CONFIG_SND_ATMEL_SOC_PDMIC=m
CONFIG_SND_ATMEL_SOC_I2S=m
CONFIG_SND_SOC_MIKROE_PROTO=m
CONFIG_SND_MCHP_SOC_I2S_MCC=m
CONFIG_SND_MCHP_SOC_SPDIFTX=m
CONFIG_SND_MCHP_SOC_SPDIFRX=m
CONFIG_SND_MCHP_SOC_PDMC=m
CONFIG_SND_BCM2835_SOC_I2S=m
CONFIG_SND_SOC_CYGNUS=m
CONFIG_SND_BCM63XX_I2S_WHISTLER=m
CONFIG_SND_EP93XX_SOC=m
CONFIG_SND_DESIGNWARE_I2S=m
CONFIG_SND_DESIGNWARE_PCM=y

#
# SoC Audio for Freescale CPUs
#

#
# Common SoC Audio options for Freescale CPUs:
#
CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_SOC_FSL_MQS=m
CONFIG_SND_SOC_FSL_AUDMIX=m
CONFIG_SND_SOC_FSL_SSI=m
CONFIG_SND_SOC_FSL_SPDIF=m
CONFIG_SND_SOC_FSL_ESAI=m
CONFIG_SND_SOC_FSL_MICFIL=m
CONFIG_SND_SOC_FSL_XCVR=m
CONFIG_SND_SOC_FSL_AUD2HTX=m
CONFIG_SND_SOC_FSL_UTILS=m
CONFIG_SND_SOC_FSL_RPMSG=m
CONFIG_SND_SOC_IMX_PCM_DMA=m
CONFIG_SND_SOC_IMX_AUDIO_RPMSG=m
CONFIG_SND_SOC_IMX_PCM_RPMSG=m
CONFIG_SND_SOC_IMX_AUDMUX=m
CONFIG_SND_IMX_SOC=m

#
# SoC Audio support for Freescale i.MX boards:
#
CONFIG_SND_SOC_IMX_ES8328=m
CONFIG_SND_SOC_IMX_SGTL5000=m
CONFIG_SND_SOC_IMX_SPDIF=m
CONFIG_SND_SOC_FSL_ASOC_CARD=m
CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_SND_SOC_IMX_HDMI=m
CONFIG_SND_SOC_IMX_RPMSG=m
CONFIG_SND_SOC_IMX_CARD=m
# end of SoC Audio for Freescale CPUs

CONFIG_SND_I2S_HI6210_I2S=m
CONFIG_SND_JZ4740_SOC_I2S=m
CONFIG_SND_KIRKWOOD_SOC=m
CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB=m
CONFIG_SND_SOC_IMG=y
CONFIG_SND_SOC_IMG_I2S_IN=m
CONFIG_SND_SOC_IMG_I2S_OUT=m
CONFIG_SND_SOC_IMG_PARALLEL_OUT=m
CONFIG_SND_SOC_IMG_SPDIF_IN=m
CONFIG_SND_SOC_IMG_SPDIF_OUT=m
CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m
CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
CONFIG_SND_SOC_ACPI_INTEL_MATCH=m
CONFIG_SND_SOC_INTEL_KEEMBAY=m
CONFIG_SND_SOC_INTEL_MACH=y
CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES=y
CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=m
CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=m
CONFIG_SND_SOC_INTEL_BROADWELL_MACH=m
CONFIG_SND_SOC_MEDIATEK=m
CONFIG_SND_SOC_MT8186=m
CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357=m
CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S=m
CONFIG_SND_SOC_MTK_BTCVSD=m
CONFIG_SND_SOC_MT8195=m
CONFIG_SND_SOC_MT8195_MT6359=m

#
# ASoC support for Amlogic platforms
#
CONFIG_SND_MESON_AIU=m
CONFIG_SND_MESON_AXG_FIFO=m
CONFIG_SND_MESON_AXG_FRDDR=m
CONFIG_SND_MESON_AXG_TODDR=m
CONFIG_SND_MESON_AXG_TDM_FORMATTER=m
CONFIG_SND_MESON_AXG_TDM_INTERFACE=m
CONFIG_SND_MESON_AXG_TDMIN=m
CONFIG_SND_MESON_AXG_TDMOUT=m
CONFIG_SND_MESON_AXG_SOUND_CARD=m
CONFIG_SND_MESON_AXG_SPDIFOUT=m
CONFIG_SND_MESON_AXG_SPDIFIN=m
CONFIG_SND_MESON_AXG_PDM=m
CONFIG_SND_MESON_CARD_UTILS=m
CONFIG_SND_MESON_CODEC_GLUE=m
CONFIG_SND_MESON_GX_SOUND_CARD=m
CONFIG_SND_MESON_G12A_TOACODEC=m
CONFIG_SND_MESON_G12A_TOHDMITX=m
CONFIG_SND_SOC_MESON_T9015=m
# end of ASoC support for Amlogic platforms

CONFIG_SND_MXS_SOC=m
CONFIG_SND_SOC_MXS_SGTL5000=m
CONFIG_SND_PXA2XX_SOC=m
CONFIG_SND_SOC_QCOM=m
CONFIG_SND_SOC_LPASS_CPU=m
CONFIG_SND_SOC_LPASS_HDMI=m
CONFIG_SND_SOC_LPASS_PLATFORM=m
CONFIG_SND_SOC_LPASS_CDC_DMA=m
CONFIG_SND_SOC_LPASS_IPQ806X=m
CONFIG_SND_SOC_LPASS_APQ8016=m
CONFIG_SND_SOC_LPASS_SC7180=m
CONFIG_SND_SOC_LPASS_SC7280=m
CONFIG_SND_SOC_STORM=m
CONFIG_SND_SOC_APQ8016_SBC=m
CONFIG_SND_SOC_QCOM_COMMON=m
CONFIG_SND_SOC_QDSP6_COMMON=m
CONFIG_SND_SOC_QDSP6_CORE=m
CONFIG_SND_SOC_QDSP6_AFE=m
CONFIG_SND_SOC_QDSP6_AFE_DAI=m
CONFIG_SND_SOC_QDSP6_AFE_CLOCKS=m
CONFIG_SND_SOC_QDSP6_ADM=m
CONFIG_SND_SOC_QDSP6_ROUTING=m
CONFIG_SND_SOC_QDSP6_ASM=m
CONFIG_SND_SOC_QDSP6_ASM_DAI=m
CONFIG_SND_SOC_QDSP6_APM_DAI=m
CONFIG_SND_SOC_QDSP6_APM_LPASS_DAI=m
CONFIG_SND_SOC_QDSP6_APM=m
CONFIG_SND_SOC_QDSP6_PRM_LPASS_CLOCKS=m
CONFIG_SND_SOC_QDSP6_PRM=m
CONFIG_SND_SOC_QDSP6=m
CONFIG_SND_SOC_MSM8996=m
CONFIG_SND_SOC_SDM845=m
CONFIG_SND_SOC_SM8250=m
CONFIG_SND_SOC_SC8280XP=m
CONFIG_SND_SOC_SC7180=m
CONFIG_SND_SOC_SC7280=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_I2S=m
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m
CONFIG_SND_SOC_ROCKCHIP_PDM=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
CONFIG_SND_SOC_ROCKCHIP_RT5645=m
CONFIG_SND_SOC_RK3288_HDMI_ANALOG=m
CONFIG_SND_SOC_RK3399_GRU_SOUND=m
CONFIG_SND_SOC_SAMSUNG=m
CONFIG_SND_S3C24XX_I2S=m
CONFIG_SND_SAMSUNG_PCM=m
CONFIG_SND_SAMSUNG_SPDIF=m
CONFIG_SND_SAMSUNG_I2S=m
CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753=m
CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580=m
CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X=m
CONFIG_SND_SOC_SAMSUNG_SIMTEC=m
CONFIG_SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23=m
CONFIG_SND_SOC_SAMSUNG_SIMTEC_HERMES=m
CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380=m
CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380=m
CONFIG_SND_SOC_SMARTQ=m
CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=m
CONFIG_SND_SOC_SPEYSIDE=m
CONFIG_SND_SOC_TOBERMORY=m
CONFIG_SND_SOC_BELLS=m
CONFIG_SND_SOC_LOWLAND=m
CONFIG_SND_SOC_LITTLEMILL=m
CONFIG_SND_SOC_SNOW=m
CONFIG_SND_SOC_ODROID=m
CONFIG_SND_SOC_ARNDALE=m
CONFIG_SND_SOC_SAMSUNG_TM2_WM5110=m
CONFIG_SND_SOC_SAMSUNG_ARIES_WM8994=m
CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=m

#
# SoC Audio support for Renesas SoCs
#
CONFIG_SND_SOC_SH4_FSI=m
CONFIG_SND_SOC_RCAR=m
CONFIG_SND_SOC_RZ=m
# end of SoC Audio support for Renesas SoCs

CONFIG_SND_SOC_SOF_TOPLEVEL=y
CONFIG_SND_SOC_SOF_ACPI=m
CONFIG_SND_SOC_SOF_ACPI_DEV=m
CONFIG_SND_SOC_SOF_OF=m
CONFIG_SND_SOC_SOF_OF_DEV=m
CONFIG_SND_SOC_SOF_COMPRESS=y
CONFIG_SND_SOC_SOF_CLIENT=m
CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT=y
CONFIG_SND_SOC_SOF_FORCE_PROBE_WORKQUEUE=y
CONFIG_SND_SOC_SOF_NOCODEC=m
CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT=y
CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS=y
CONFIG_SND_SOC_SOF_DEBUG=y
CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE=y
CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP=y
CONFIG_SND_SOC_SOF_DEBUG_VERBOSE_IPC=y
CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE=y
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST=m
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM=2
CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR=m
CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT=y
CONFIG_SND_SOC_SOF=m
CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y
CONFIG_SND_SOC_SOF_IPC3=y
CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m
CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
CONFIG_SND_SOC_SOF_IMX_COMMON=m
CONFIG_SND_SOC_SOF_IMX8=m
CONFIG_SND_SOC_SOF_IMX8M=m
CONFIG_SND_SOC_SOF_IMX8ULP=m
CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y
CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m
CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m
CONFIG_SND_SOC_SOF_INTEL_COMMON=m
CONFIG_SND_SOC_SOF_BAYTRAIL=m
CONFIG_SND_SOC_SOF_BROADWELL=m
CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y
CONFIG_SND_SOC_SOF_MTK_COMMON=m
CONFIG_SND_SOC_SOF_MT8186=m
CONFIG_SND_SOC_SOF_MT8195=m
CONFIG_SND_SOC_SOF_XTENSA=m
CONFIG_SND_SOC_SPRD=m
CONFIG_SND_SOC_SPRD_MCDT=m
CONFIG_SND_SOC_STI=m

#
# STMicroelectronics STM32 SOC audio support
#
CONFIG_SND_SOC_STM32_SAI=m
CONFIG_SND_SOC_STM32_I2S=m
CONFIG_SND_SOC_STM32_SPDIFRX=m
CONFIG_SND_SOC_STM32_DFSDM=m
# end of STMicroelectronics STM32 SOC audio support

#
# Allwinner SoC Audio support
#
CONFIG_SND_SUN4I_CODEC=m
CONFIG_SND_SUN8I_CODEC=m
CONFIG_SND_SUN8I_CODEC_ANALOG=m
CONFIG_SND_SUN50I_CODEC_ANALOG=m
CONFIG_SND_SUN4I_I2S=m
CONFIG_SND_SUN4I_SPDIF=m
CONFIG_SND_SUN50I_DMIC=m
CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m
# end of Allwinner SoC Audio support

CONFIG_SND_SOC_TEGRA=m
CONFIG_SND_SOC_TEGRA20_AC97=m
CONFIG_SND_SOC_TEGRA20_DAS=m
CONFIG_SND_SOC_TEGRA20_I2S=m
CONFIG_SND_SOC_TEGRA20_SPDIF=m
CONFIG_SND_SOC_TEGRA30_AHUB=m
CONFIG_SND_SOC_TEGRA30_I2S=m
CONFIG_SND_SOC_TEGRA210_AHUB=m
CONFIG_SND_SOC_TEGRA210_DMIC=m
CONFIG_SND_SOC_TEGRA210_I2S=m
CONFIG_SND_SOC_TEGRA210_OPE=m
CONFIG_SND_SOC_TEGRA186_ASRC=m
CONFIG_SND_SOC_TEGRA186_DSPK=m
CONFIG_SND_SOC_TEGRA210_ADMAIF=m
CONFIG_SND_SOC_TEGRA210_MVC=m
CONFIG_SND_SOC_TEGRA210_SFC=m
CONFIG_SND_SOC_TEGRA210_AMX=m
CONFIG_SND_SOC_TEGRA210_ADX=m
CONFIG_SND_SOC_TEGRA210_MIXER=m
CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD=m
CONFIG_SND_SOC_TEGRA_MACHINE_DRV=m
CONFIG_SND_SOC_TEGRA_RT5640=m
CONFIG_SND_SOC_TEGRA_WM8753=m
CONFIG_SND_SOC_TEGRA_WM8903=m
CONFIG_SND_SOC_TEGRA_WM9712=m
CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
CONFIG_SND_SOC_TEGRA_ALC5632=m
CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_TEGRA_RT5677=m
CONFIG_SND_SOC_TEGRA_SGTL5000=m

#
# Audio support for Texas Instruments SoCs
#
CONFIG_SND_SOC_TI_EDMA_PCM=m
CONFIG_SND_SOC_TI_SDMA_PCM=m
CONFIG_SND_SOC_TI_UDMA_PCM=m

#
# Texas Instruments DAI support for:
#
CONFIG_SND_SOC_DAVINCI_ASP=m
CONFIG_SND_SOC_DAVINCI_MCASP=m
CONFIG_SND_SOC_DAVINCI_VCIF=m
CONFIG_SND_SOC_OMAP_DMIC=m
CONFIG_SND_SOC_OMAP_MCBSP=m
CONFIG_SND_SOC_OMAP_MCPDM=m

#
# Audio support for boards with Texas Instruments SoCs
#
CONFIG_SND_SOC_OMAP_HDMI=m
CONFIG_SND_SOC_J721E_EVM=m
# end of Audio support for Texas Instruments SoCs

CONFIG_SND_SOC_UNIPHIER=m
CONFIG_SND_SOC_UNIPHIER_AIO=m
CONFIG_SND_SOC_UNIPHIER_LD11=m
CONFIG_SND_SOC_UNIPHIER_PXS2=m
CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC=m
CONFIG_SND_SOC_XILINX_I2S=m
CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m
CONFIG_SND_SOC_XILINX_SPDIF=m
CONFIG_SND_SOC_XTFPGA_I2S=m
CONFIG_SND_SOC_I2C_AND_SPI=m

#
# CODEC drivers
#
CONFIG_SND_SOC_ALL_CODECS=m
# CONFIG_SND_SOC_88PM860X is not set
CONFIG_SND_SOC_ARIZONA=m
CONFIG_SND_SOC_WM_HUBS=m
CONFIG_SND_SOC_WM_ADSP=m
CONFIG_SND_SOC_AB8500_CODEC=m
CONFIG_SND_SOC_AC97_CODEC=m
CONFIG_SND_SOC_AD1836=m
CONFIG_SND_SOC_AD193X=m
CONFIG_SND_SOC_AD193X_SPI=m
CONFIG_SND_SOC_AD193X_I2C=m
CONFIG_SND_SOC_AD1980=m
CONFIG_SND_SOC_AD73311=m
CONFIG_SND_SOC_ADAU_UTILS=m
CONFIG_SND_SOC_ADAU1372=m
CONFIG_SND_SOC_ADAU1372_I2C=m
CONFIG_SND_SOC_ADAU1372_SPI=m
CONFIG_SND_SOC_ADAU1373=m
CONFIG_SND_SOC_ADAU1701=m
CONFIG_SND_SOC_ADAU17X1=m
CONFIG_SND_SOC_ADAU1761=m
CONFIG_SND_SOC_ADAU1761_I2C=m
CONFIG_SND_SOC_ADAU1761_SPI=m
CONFIG_SND_SOC_ADAU1781=m
CONFIG_SND_SOC_ADAU1781_I2C=m
CONFIG_SND_SOC_ADAU1781_SPI=m
CONFIG_SND_SOC_ADAU1977=m
CONFIG_SND_SOC_ADAU1977_SPI=m
CONFIG_SND_SOC_ADAU1977_I2C=m
CONFIG_SND_SOC_ADAU7002=m
CONFIG_SND_SOC_ADAU7118=m
CONFIG_SND_SOC_ADAU7118_HW=m
CONFIG_SND_SOC_ADAU7118_I2C=m
CONFIG_SND_SOC_ADAV80X=m
CONFIG_SND_SOC_ADAV801=m
CONFIG_SND_SOC_ADAV803=m
CONFIG_SND_SOC_ADS117X=m
CONFIG_SND_SOC_AK4104=m
CONFIG_SND_SOC_AK4118=m
CONFIG_SND_SOC_AK4375=m
CONFIG_SND_SOC_AK4458=m
CONFIG_SND_SOC_AK4535=m
CONFIG_SND_SOC_AK4554=m
CONFIG_SND_SOC_AK4613=m
CONFIG_SND_SOC_AK4641=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_AK4671=m
CONFIG_SND_SOC_AK5386=m
CONFIG_SND_SOC_AK5558=m
CONFIG_SND_SOC_ALC5623=m
CONFIG_SND_SOC_ALC5632=m
CONFIG_SND_SOC_AW8738=m
CONFIG_SND_SOC_BD28623=m
CONFIG_SND_SOC_BT_SCO=m
CONFIG_SND_SOC_CPCAP=m
CONFIG_SND_SOC_CQ0093VC=m
CONFIG_SND_SOC_CROS_EC_CODEC=m
CONFIG_SND_SOC_CS35L32=m
CONFIG_SND_SOC_CS35L33=m
CONFIG_SND_SOC_CS35L34=m
CONFIG_SND_SOC_CS35L35=m
CONFIG_SND_SOC_CS35L36=m
CONFIG_SND_SOC_CS35L41_LIB=m
CONFIG_SND_SOC_CS35L41=m
CONFIG_SND_SOC_CS35L41_SPI=m
CONFIG_SND_SOC_CS35L41_I2C=m
CONFIG_SND_SOC_CS35L45_TABLES=m
CONFIG_SND_SOC_CS35L45=m
CONFIG_SND_SOC_CS35L45_SPI=m
CONFIG_SND_SOC_CS35L45_I2C=m
CONFIG_SND_SOC_CS42L42_CORE=m
CONFIG_SND_SOC_CS42L42=m
CONFIG_SND_SOC_CS42L51=m
CONFIG_SND_SOC_CS42L51_I2C=m
CONFIG_SND_SOC_CS42L52=m
CONFIG_SND_SOC_CS42L56=m
CONFIG_SND_SOC_CS42L73=m
CONFIG_SND_SOC_CS42L83=m
CONFIG_SND_SOC_CS4234=m
CONFIG_SND_SOC_CS4265=m
CONFIG_SND_SOC_CS4270=m
CONFIG_SND_SOC_CS4271=m
CONFIG_SND_SOC_CS4271_I2C=m
CONFIG_SND_SOC_CS4271_SPI=m
CONFIG_SND_SOC_CS42XX8=m
CONFIG_SND_SOC_CS42XX8_I2C=m
CONFIG_SND_SOC_CS43130=m
CONFIG_SND_SOC_CS4341=m
CONFIG_SND_SOC_CS4349=m
CONFIG_SND_SOC_CS47L15=m
CONFIG_SND_SOC_CS47L24=m
CONFIG_SND_SOC_CS47L35=m
CONFIG_SND_SOC_CS47L85=m
CONFIG_SND_SOC_CS47L90=m
CONFIG_SND_SOC_CS47L92=m
CONFIG_SND_SOC_CS53L30=m
CONFIG_SND_SOC_CX20442=m
CONFIG_SND_SOC_CX2072X=m
CONFIG_SND_SOC_JZ4740_CODEC=m
CONFIG_SND_SOC_JZ4725B_CODEC=m
CONFIG_SND_SOC_JZ4760_CODEC=m
CONFIG_SND_SOC_JZ4770_CODEC=m
CONFIG_SND_SOC_L3=m
CONFIG_SND_SOC_DA7210=m
CONFIG_SND_SOC_DA7213=m
CONFIG_SND_SOC_DA7218=m
CONFIG_SND_SOC_DA7219=m
CONFIG_SND_SOC_DA732X=m
CONFIG_SND_SOC_DA9055=m
CONFIG_SND_SOC_DMIC=m
CONFIG_SND_SOC_HDMI_CODEC=m
CONFIG_SND_SOC_ES7134=m
CONFIG_SND_SOC_ES7241=m
CONFIG_SND_SOC_ES8316=m
CONFIG_SND_SOC_ES8326=m
CONFIG_SND_SOC_ES8328=m
CONFIG_SND_SOC_ES8328_I2C=m
CONFIG_SND_SOC_ES8328_SPI=m
CONFIG_SND_SOC_GTM601=m
CONFIG_SND_SOC_HDAC_HDMI=m
CONFIG_SND_SOC_HDAC_HDA=m
CONFIG_SND_SOC_HDA=m
CONFIG_SND_SOC_ICS43432=m
CONFIG_SND_SOC_INNO_RK3036=m
CONFIG_SND_SOC_ISABELLE=m
CONFIG_SND_SOC_LM49453=m
CONFIG_SND_SOC_LOCHNAGAR_SC=m
CONFIG_SND_SOC_MADERA=m
CONFIG_SND_SOC_MAX98088=m
CONFIG_SND_SOC_MAX98090=m
CONFIG_SND_SOC_MAX98095=m
CONFIG_SND_SOC_MAX98357A=m
CONFIG_SND_SOC_MAX98371=m
CONFIG_SND_SOC_MAX98504=m
CONFIG_SND_SOC_MAX9867=m
CONFIG_SND_SOC_MAX98925=m
CONFIG_SND_SOC_MAX98926=m
CONFIG_SND_SOC_MAX98927=m
CONFIG_SND_SOC_MAX98520=m
CONFIG_SND_SOC_MAX98373=m
CONFIG_SND_SOC_MAX98373_I2C=m
CONFIG_SND_SOC_MAX98373_SDW=m
CONFIG_SND_SOC_MAX98390=m
CONFIG_SND_SOC_MAX98396=m
CONFIG_SND_SOC_MAX9850=m
CONFIG_SND_SOC_MAX9860=m
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
CONFIG_SND_SOC_PCM1681=m
CONFIG_SND_SOC_PCM1789=m
CONFIG_SND_SOC_PCM1789_I2C=m
CONFIG_SND_SOC_PCM179X=m
CONFIG_SND_SOC_PCM179X_I2C=m
CONFIG_SND_SOC_PCM179X_SPI=m
CONFIG_SND_SOC_PCM186X=m
CONFIG_SND_SOC_PCM186X_I2C=m
CONFIG_SND_SOC_PCM186X_SPI=m
CONFIG_SND_SOC_PCM3008=m
CONFIG_SND_SOC_PCM3060=m
CONFIG_SND_SOC_PCM3060_I2C=m
CONFIG_SND_SOC_PCM3060_SPI=m
CONFIG_SND_SOC_PCM3168A=m
CONFIG_SND_SOC_PCM3168A_I2C=m
CONFIG_SND_SOC_PCM3168A_SPI=m
CONFIG_SND_SOC_PCM5102A=m
CONFIG_SND_SOC_PCM512x=m
CONFIG_SND_SOC_PCM512x_I2C=m
CONFIG_SND_SOC_PCM512x_SPI=m
CONFIG_SND_SOC_RK3328=m
CONFIG_SND_SOC_RK817=m
CONFIG_SND_SOC_RL6231=m
CONFIG_SND_SOC_RL6347A=m
CONFIG_SND_SOC_RT274=m
CONFIG_SND_SOC_RT286=m
CONFIG_SND_SOC_RT298=m
CONFIG_SND_SOC_RT1011=m
CONFIG_SND_SOC_RT1015=m
CONFIG_SND_SOC_RT1015P=m
CONFIG_SND_SOC_RT1016=m
CONFIG_SND_SOC_RT1019=m
CONFIG_SND_SOC_RT1305=m
CONFIG_SND_SOC_RT1308=m
CONFIG_SND_SOC_RT1308_SDW=m
CONFIG_SND_SOC_RT1316_SDW=m
CONFIG_SND_SOC_RT5514=m
CONFIG_SND_SOC_RT5514_SPI=m
CONFIG_SND_SOC_RT5616=m
CONFIG_SND_SOC_RT5631=m
CONFIG_SND_SOC_RT5640=m
CONFIG_SND_SOC_RT5645=m
CONFIG_SND_SOC_RT5651=m
CONFIG_SND_SOC_RT5659=m
CONFIG_SND_SOC_RT5660=m
CONFIG_SND_SOC_RT5663=m
CONFIG_SND_SOC_RT5665=m
CONFIG_SND_SOC_RT5668=m
CONFIG_SND_SOC_RT5670=m
CONFIG_SND_SOC_RT5677=m
CONFIG_SND_SOC_RT5677_SPI=m
CONFIG_SND_SOC_RT5682=m
CONFIG_SND_SOC_RT5682_I2C=m
CONFIG_SND_SOC_RT5682_SDW=m
CONFIG_SND_SOC_RT5682S=m
CONFIG_SND_SOC_RT700=m
CONFIG_SND_SOC_RT700_SDW=m
CONFIG_SND_SOC_RT711=m
CONFIG_SND_SOC_RT711_SDW=m
CONFIG_SND_SOC_RT711_SDCA_SDW=m
CONFIG_SND_SOC_RT715=m
CONFIG_SND_SOC_RT715_SDW=m
CONFIG_SND_SOC_RT715_SDCA_SDW=m
CONFIG_SND_SOC_RT9120=m
CONFIG_SND_SOC_SDW_MOCKUP=m
CONFIG_SND_SOC_SGTL5000=m
CONFIG_SND_SOC_SI476X=m
CONFIG_SND_SOC_SIGMADSP=m
CONFIG_SND_SOC_SIGMADSP_I2C=m
CONFIG_SND_SOC_SIGMADSP_REGMAP=m
CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m
CONFIG_SND_SOC_SIMPLE_MUX=m
CONFIG_SND_SOC_SPDIF=m
CONFIG_SND_SOC_SRC4XXX_I2C=m
CONFIG_SND_SOC_SRC4XXX=m
CONFIG_SND_SOC_SSM2305=m
CONFIG_SND_SOC_SSM2518=m
CONFIG_SND_SOC_SSM2602=m
CONFIG_SND_SOC_SSM2602_SPI=m
CONFIG_SND_SOC_SSM2602_I2C=m
CONFIG_SND_SOC_SSM4567=m
CONFIG_SND_SOC_STA32X=m
CONFIG_SND_SOC_STA350=m
CONFIG_SND_SOC_STA529=m
CONFIG_SND_SOC_STAC9766=m
CONFIG_SND_SOC_STI_SAS=m
CONFIG_SND_SOC_TAS2552=m
CONFIG_SND_SOC_TAS2562=m
CONFIG_SND_SOC_TAS2764=m
CONFIG_SND_SOC_TAS2770=m
CONFIG_SND_SOC_TAS2780=m
CONFIG_SND_SOC_TAS5086=m
CONFIG_SND_SOC_TAS571X=m
CONFIG_SND_SOC_TAS5720=m
CONFIG_SND_SOC_TAS5805M=m
CONFIG_SND_SOC_TAS6424=m
CONFIG_SND_SOC_TDA7419=m
CONFIG_SND_SOC_TFA9879=m
CONFIG_SND_SOC_TFA989X=m
CONFIG_SND_SOC_TLV320ADC3XXX=m
CONFIG_SND_SOC_TLV320AIC23=m
CONFIG_SND_SOC_TLV320AIC23_I2C=m
CONFIG_SND_SOC_TLV320AIC23_SPI=m
CONFIG_SND_SOC_TLV320AIC26=m
CONFIG_SND_SOC_TLV320AIC31XX=m
CONFIG_SND_SOC_TLV320AIC32X4=m
CONFIG_SND_SOC_TLV320AIC32X4_I2C=m
CONFIG_SND_SOC_TLV320AIC32X4_SPI=m
CONFIG_SND_SOC_TLV320AIC3X=m
CONFIG_SND_SOC_TLV320AIC3X_I2C=m
CONFIG_SND_SOC_TLV320AIC3X_SPI=m
CONFIG_SND_SOC_TLV320DAC33=m
CONFIG_SND_SOC_TLV320ADCX140=m
CONFIG_SND_SOC_TS3A227E=m
CONFIG_SND_SOC_TSCS42XX=m
CONFIG_SND_SOC_TSCS454=m
# CONFIG_SND_SOC_TWL4030 is not set
# CONFIG_SND_SOC_TWL6040 is not set
CONFIG_SND_SOC_UDA1334=m
CONFIG_SND_SOC_UDA134X=m
CONFIG_SND_SOC_UDA1380=m
CONFIG_SND_SOC_WCD9335=m
CONFIG_SND_SOC_WCD_MBHC=m
CONFIG_SND_SOC_WCD934X=m
CONFIG_SND_SOC_WCD938X=m
CONFIG_SND_SOC_WCD938X_SDW=m
CONFIG_SND_SOC_WL1273=m
CONFIG_SND_SOC_WM0010=m
CONFIG_SND_SOC_WM1250_EV1=m
CONFIG_SND_SOC_WM2000=m
CONFIG_SND_SOC_WM2200=m
CONFIG_SND_SOC_WM5100=m
CONFIG_SND_SOC_WM5102=m
CONFIG_SND_SOC_WM5110=m
# CONFIG_SND_SOC_WM8350 is not set
# CONFIG_SND_SOC_WM8400 is not set
CONFIG_SND_SOC_WM8510=m
CONFIG_SND_SOC_WM8523=m
CONFIG_SND_SOC_WM8524=m
CONFIG_SND_SOC_WM8580=m
CONFIG_SND_SOC_WM8711=m
CONFIG_SND_SOC_WM8727=m
CONFIG_SND_SOC_WM8728=m
CONFIG_SND_SOC_WM8731=m
CONFIG_SND_SOC_WM8731_I2C=m
CONFIG_SND_SOC_WM8731_SPI=m
CONFIG_SND_SOC_WM8737=m
CONFIG_SND_SOC_WM8741=m
CONFIG_SND_SOC_WM8750=m
CONFIG_SND_SOC_WM8753=m
CONFIG_SND_SOC_WM8770=m
CONFIG_SND_SOC_WM8776=m
CONFIG_SND_SOC_WM8782=m
CONFIG_SND_SOC_WM8804=m
CONFIG_SND_SOC_WM8804_I2C=m
CONFIG_SND_SOC_WM8804_SPI=m
CONFIG_SND_SOC_WM8900=m
CONFIG_SND_SOC_WM8903=m
CONFIG_SND_SOC_WM8904=m
CONFIG_SND_SOC_WM8940=m
CONFIG_SND_SOC_WM8955=m
CONFIG_SND_SOC_WM8960=m
CONFIG_SND_SOC_WM8961=m
CONFIG_SND_SOC_WM8962=m
CONFIG_SND_SOC_WM8971=m
CONFIG_SND_SOC_WM8974=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SOC_WM8983=m
CONFIG_SND_SOC_WM8985=m
CONFIG_SND_SOC_WM8988=m
CONFIG_SND_SOC_WM8990=m
CONFIG_SND_SOC_WM8991=m
CONFIG_SND_SOC_WM8993=m
CONFIG_SND_SOC_WM8994=m
CONFIG_SND_SOC_WM8995=m
CONFIG_SND_SOC_WM8996=m
CONFIG_SND_SOC_WM8997=m
CONFIG_SND_SOC_WM8998=m
CONFIG_SND_SOC_WM9081=m
CONFIG_SND_SOC_WM9090=m
CONFIG_SND_SOC_WM9705=m
CONFIG_SND_SOC_WM9712=m
CONFIG_SND_SOC_WM9713=m
CONFIG_SND_SOC_WSA881X=m
CONFIG_SND_SOC_WSA883X=m
CONFIG_SND_SOC_ZL38060=m
CONFIG_SND_SOC_LM4857=m
CONFIG_SND_SOC_MAX9759=m
CONFIG_SND_SOC_MAX9768=m
CONFIG_SND_SOC_MAX9877=m
CONFIG_SND_SOC_MC13783=m
CONFIG_SND_SOC_ML26124=m
CONFIG_SND_SOC_MT6351=m
CONFIG_SND_SOC_MT6358=m
CONFIG_SND_SOC_MT6359=m
CONFIG_SND_SOC_MT6359_ACCDET=m
CONFIG_SND_SOC_MT6660=m
CONFIG_SND_SOC_NAU8315=m
CONFIG_SND_SOC_NAU8540=m
CONFIG_SND_SOC_NAU8810=m
CONFIG_SND_SOC_NAU8821=m
CONFIG_SND_SOC_NAU8822=m
CONFIG_SND_SOC_NAU8824=m
CONFIG_SND_SOC_NAU8825=m
CONFIG_SND_SOC_TPA6130A2=m
CONFIG_SND_SOC_LPASS_MACRO_COMMON=m
CONFIG_SND_SOC_LPASS_WSA_MACRO=m
CONFIG_SND_SOC_LPASS_VA_MACRO=m
CONFIG_SND_SOC_LPASS_RX_MACRO=m
CONFIG_SND_SOC_LPASS_TX_MACRO=m
# end of CODEC drivers

CONFIG_SND_SIMPLE_CARD_UTILS=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SND_AUDIO_GRAPH_CARD=m
CONFIG_SND_AUDIO_GRAPH_CARD2=m
CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=m
CONFIG_SND_TEST_COMPONENT=m
CONFIG_SND_VIRTIO=m
CONFIG_AC97_BUS=m

#
# HID support
#
CONFIG_HID=m
CONFIG_HID_BATTERY_STRENGTH=y
CONFIG_HIDRAW=y
CONFIG_UHID=m
CONFIG_HID_GENERIC=m

#
# Special HID drivers
#
CONFIG_HID_A4TECH=m
CONFIG_HID_ACCUTOUCH=m
CONFIG_HID_ACRUX=m
CONFIG_HID_ACRUX_FF=y
CONFIG_HID_APPLE=m
CONFIG_HID_APPLEIR=m
CONFIG_HID_ASUS=m
CONFIG_HID_AUREAL=m
CONFIG_HID_BELKIN=m
CONFIG_HID_BETOP_FF=m
CONFIG_HID_BIGBEN_FF=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
CONFIG_HID_CORSAIR=m
CONFIG_HID_COUGAR=m
CONFIG_HID_MACALLY=m
CONFIG_HID_PRODIKEYS=m
CONFIG_HID_CMEDIA=m
CONFIG_HID_CP2112=m
CONFIG_HID_CREATIVE_SB0540=m
CONFIG_HID_CYPRESS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_DRAGONRISE_FF=y
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELAN=m
CONFIG_HID_ELECOM=m
CONFIG_HID_ELO=m
CONFIG_HID_EZKEY=m
CONFIG_HID_FT260=m
CONFIG_HID_GEMBIRD=m
CONFIG_HID_GFRM=m
CONFIG_HID_GLORIOUS=m
CONFIG_HID_HOLTEK=m
CONFIG_HOLTEK_FF=y
CONFIG_HID_VIVALDI_COMMON=m
CONFIG_HID_GOOGLE_HAMMER=m
CONFIG_HID_VIVALDI=m
CONFIG_HID_GT683R=m
CONFIG_HID_KEYTOUCH=m
CONFIG_HID_KYE=m
CONFIG_HID_UCLOGIC=m
CONFIG_HID_WALTOP=m
CONFIG_HID_VIEWSONIC=m
CONFIG_HID_VRC2=m
CONFIG_HID_XIAOMI=m
CONFIG_HID_GYRATION=m
CONFIG_HID_ICADE=m
CONFIG_HID_ITE=m
CONFIG_HID_JABRA=m
CONFIG_HID_TWINHAN=m
CONFIG_HID_KENSINGTON=m
CONFIG_HID_LCPOWER=m
CONFIG_HID_LED=m
CONFIG_HID_LENOVO=m
CONFIG_HID_LETSKETCH=m
CONFIG_HID_LOGITECH=m
CONFIG_HID_LOGITECH_DJ=m
CONFIG_HID_LOGITECH_HIDPP=m
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
CONFIG_LOGIG940_FF=y
CONFIG_LOGIWHEELS_FF=y
CONFIG_HID_MAGICMOUSE=m
CONFIG_HID_MALTRON=m
CONFIG_HID_MAYFLASH=m
CONFIG_HID_MEGAWORLD_FF=m
CONFIG_HID_REDRAGON=m
CONFIG_HID_MICROSOFT=m
CONFIG_HID_MONTEREY=m
CONFIG_HID_MULTITOUCH=m
CONFIG_HID_NINTENDO=m
CONFIG_NINTENDO_FF=y
CONFIG_HID_NTI=m
CONFIG_HID_NTRIG=m
CONFIG_HID_ORTEK=m
CONFIG_HID_PANTHERLORD=m
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PENMOUNT=m
CONFIG_HID_PETALYNX=m
CONFIG_HID_PICOLCD=m
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PICOLCD_CIR=y
CONFIG_HID_PLANTRONICS=m
CONFIG_HID_PLAYSTATION=m
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_PXRC=m
CONFIG_HID_RAZER=m
CONFIG_HID_PRIMAX=m
CONFIG_HID_RETRODE=m
CONFIG_HID_ROCCAT=m
CONFIG_HID_SAITEK=m
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SEMITEK=m
CONFIG_HID_SIGMAMICRO=m
CONFIG_HID_SONY=m
CONFIG_SONY_FF=y
CONFIG_HID_SPEEDLINK=m
CONFIG_HID_STEAM=m
CONFIG_HID_STEELSERIES=m
CONFIG_HID_SUNPLUS=m
CONFIG_HID_RMI=m
CONFIG_HID_GREENASIA=m
CONFIG_GREENASIA_FF=y
CONFIG_HID_SMARTJOYPLUS=m
CONFIG_SMARTJOYPLUS_FF=y
CONFIG_HID_TIVO=m
CONFIG_HID_TOPSEED=m
CONFIG_HID_TOPRE=m
CONFIG_HID_THINGM=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_THRUSTMASTER_FF=y
CONFIG_HID_UDRAW_PS3=m
CONFIG_HID_U2FZERO=m
CONFIG_HID_WACOM=m
CONFIG_HID_WIIMOTE=m
CONFIG_HID_XINMO=m
CONFIG_HID_ZEROPLUS=m
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=m
CONFIG_HID_SENSOR_HUB=m
CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
CONFIG_HID_ALPS=m
CONFIG_HID_MCP2221=m
# end of Special HID drivers

#
# USB HID support
#
CONFIG_USB_HID=m
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y

#
# USB HID Boot Protocol drivers
#
CONFIG_USB_KBD=m
CONFIG_USB_MOUSE=m
# end of USB HID Boot Protocol drivers
# end of USB HID support

#
# I2C HID support
#
CONFIG_I2C_HID_OF=m
CONFIG_I2C_HID_OF_ELAN=m
CONFIG_I2C_HID_OF_GOODIX=m
# end of I2C HID support

CONFIG_I2C_HID_CORE=m
# end of HID support

CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=m
CONFIG_USB_LED_TRIG=y
CONFIG_USB_ULPI_BUS=m
CONFIG_USB_CONN_GPIO=m
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=m
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_FEW_INIT_RETRIES=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
CONFIG_USB_OTG_PRODUCTLIST=y
CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB=y
CONFIG_USB_OTG_FSM=m
CONFIG_USB_LEDS_TRIGGER_USBPORT=m
CONFIG_USB_AUTOSUSPEND_DELAY=2
CONFIG_USB_MON=m

#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=m
CONFIG_USB_BRCMSTB=m
CONFIG_USB_OXU210HP_HCD=m
CONFIG_USB_ISP116X_HCD=m
CONFIG_USB_ISP1362_HCD=m
CONFIG_USB_MAX3421_HCD=m
CONFIG_USB_U132_HCD=m
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_HCD_ISO=y
CONFIG_USB_SL811_CS=m
CONFIG_USB_R8A66597_HCD=m
CONFIG_USB_RENESAS_USBHS_HCD=m
CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_RENESAS_USBHS=m

#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_WDM=m
CONFIG_USB_TMC=m

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_REALTEK_AUTOPM=y
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_USBAT=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_ALAUDA=m
CONFIG_USB_STORAGE_ONETOUCH=m
CONFIG_USB_STORAGE_KARMA=m
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
CONFIG_USB_STORAGE_ENE_UB6250=m
CONFIG_USB_UAS=m

#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=1
CONFIG_USBIP_HOST=m
CONFIG_USBIP_VUDC=m
CONFIG_USBIP_DEBUG=y
CONFIG_USB_MTU3=m
# CONFIG_USB_MTU3_HOST is not set
# CONFIG_USB_MTU3_GADGET is not set
CONFIG_USB_MTU3_DUAL_ROLE=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_HOST=y

#
# Platform Glue Layer
#
CONFIG_USB_MUSB_TUSB6010=m
CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_MUSB_UX500=m
CONFIG_USB_MUSB_MEDIATEK=m
CONFIG_USB_MUSB_POLARFIRE_SOC=m

#
# MUSB DMA mode
#
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_ISP1760=m
CONFIG_USB_ISP1760_HCD=y
CONFIG_USB_ISP1761_UDC=y
# CONFIG_USB_ISP1760_HOST_ROLE is not set
# CONFIG_USB_ISP1760_GADGET_ROLE is not set
CONFIG_USB_ISP1760_DUAL_ROLE=y

#
# USB port drivers
#
CONFIG_USB_USS720=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=m
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP210X=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_F81232=m
CONFIG_USB_SERIAL_F8153X=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_METRO=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MXUPORT=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
CONFIG_USB_SERIAL_QCAUX=m
CONFIG_USB_SERIAL_QUALCOMM=m
CONFIG_USB_SERIAL_SPCP8X5=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_WWAN=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_OPTICON=m
CONFIG_USB_SERIAL_XSENS_MT=m
CONFIG_USB_SERIAL_WISHBONE=m
CONFIG_USB_SERIAL_SSU100=m
CONFIG_USB_SERIAL_QT2=m
CONFIG_USB_SERIAL_UPD78F0730=m
CONFIG_USB_SERIAL_XR=m
CONFIG_USB_SERIAL_DEBUG=m

#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
CONFIG_USB_ADUTUX=m
CONFIG_USB_SEVSEG=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
CONFIG_USB_QCOM_EUD=m
CONFIG_APPLE_MFI_FASTCHARGE=m
CONFIG_USB_SISUSBVGA=m
CONFIG_USB_LD=m
CONFIG_USB_TRANCEVIBRATOR=m
CONFIG_USB_IOWARRIOR=m
CONFIG_USB_TEST=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
CONFIG_USB_EZUSB_FX2=m
CONFIG_USB_HUB_USB251XB=m
CONFIG_USB_HSIC_USB3503=m
CONFIG_USB_HSIC_USB4604=m
CONFIG_USB_LINK_LAYER_TEST=m
CONFIG_USB_CHAOSKEY=m
CONFIG_BRCM_USB_PINMAP=m
CONFIG_USB_ONBOARD_HUB=m
CONFIG_USB_ATM=m
CONFIG_USB_SPEEDTOUCH=m
CONFIG_USB_CXACRU=m
CONFIG_USB_UEAGLEATM=m
CONFIG_USB_XUSBATM=m

#
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
CONFIG_KEYSTONE_USB_PHY=m
CONFIG_NOP_USB_XCEIV=m
CONFIG_AM335X_CONTROL_USB=m
CONFIG_AM335X_PHY_USB=m
CONFIG_USB_GPIO_VBUS=m
CONFIG_TAHVO_USB=m
CONFIG_TAHVO_USB_HOST_BY_DEFAULT=y
CONFIG_USB_ISP1301=m
CONFIG_USB_TEGRA_PHY=m
CONFIG_USB_ULPI=y
CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_JZ4770_PHY=m
# end of USB Physical Layer drivers

CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_VERBOSE=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_U_SERIAL_CONSOLE=y

#
# USB Peripheral Controller
#
CONFIG_USB_LPC32XX=m
CONFIG_USB_RENESAS_USBHS_UDC=m
CONFIG_USB_RENESAS_USB3=m
CONFIG_USB_PXA27X=m
CONFIG_USB_M66592=m
CONFIG_USB_NET2272=m
CONFIG_USB_MAX3420_UDC=m
CONFIG_USB_ASPEED_UDC=m
CONFIG_USB_ASPEED_VHUB=m
CONFIG_USB_DUMMY_HCD=m
# end of USB Peripheral Controller

CONFIG_USB_LIBCOMPOSITE=m
CONFIG_USB_F_ACM=m
CONFIG_USB_F_SS_LB=m
CONFIG_USB_U_SERIAL=m
CONFIG_USB_U_ETHER=m
CONFIG_USB_U_AUDIO=m
CONFIG_USB_F_SERIAL=m
CONFIG_USB_F_OBEX=m
CONFIG_USB_F_NCM=m
CONFIG_USB_F_ECM=m
CONFIG_USB_F_PHONET=m
CONFIG_USB_F_EEM=m
CONFIG_USB_F_SUBSET=m
CONFIG_USB_F_RNDIS=m
CONFIG_USB_F_MASS_STORAGE=m
CONFIG_USB_F_FS=m
CONFIG_USB_F_UAC1=m
CONFIG_USB_F_UAC1_LEGACY=m
CONFIG_USB_F_UAC2=m
CONFIG_USB_F_UVC=m
CONFIG_USB_F_MIDI=m
CONFIG_USB_F_HID=m
CONFIG_USB_F_PRINTER=m
CONFIG_USB_F_TCM=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_PHONET=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_CONFIGFS_F_TCM=y

#
# USB Gadget precomposed configurations
#
CONFIG_USB_ZERO=m
CONFIG_USB_ZERO_HNPTEST=y
CONFIG_USB_AUDIO=m
CONFIG_GADGET_UAC1=y
CONFIG_GADGET_UAC1_LEGACY=y
CONFIG_USB_ETH=m
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_ETH_EEM=y
CONFIG_USB_G_NCM=m
CONFIG_USB_GADGETFS=m
CONFIG_USB_FUNCTIONFS=m
CONFIG_USB_FUNCTIONFS_ETH=y
CONFIG_USB_FUNCTIONFS_RNDIS=y
CONFIG_USB_FUNCTIONFS_GENERIC=y
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_GADGET_TARGET=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_MIDI_GADGET=m
CONFIG_USB_G_PRINTER=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_USB_G_NOKIA=m
CONFIG_USB_G_ACM_MS=m
CONFIG_USB_G_MULTI=m
CONFIG_USB_G_MULTI_RNDIS=y
CONFIG_USB_G_MULTI_CDC=y
CONFIG_USB_G_HID=m
CONFIG_USB_G_DBGP=m
# CONFIG_USB_G_DBGP_PRINTK is not set
CONFIG_USB_G_DBGP_SERIAL=y
CONFIG_USB_G_WEBCAM=m
CONFIG_USB_RAW_GADGET=m
# end of USB Gadget precomposed configurations

CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_RT1711H=m
CONFIG_TYPEC_MT6360=m
CONFIG_TYPEC_TCPCI_MT6370=m
CONFIG_TYPEC_TCPCI_MAXIM=m
CONFIG_TYPEC_FUSB302=m
CONFIG_TYPEC_UCSI=m
CONFIG_UCSI_CCG=m
CONFIG_UCSI_STM32G0=m
CONFIG_TYPEC_TPS6598X=m
CONFIG_TYPEC_ANX7411=m
CONFIG_TYPEC_RT1719=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_TYPEC_STUSB160X=m
CONFIG_TYPEC_QCOM_PMIC=m
CONFIG_TYPEC_WUSB3801=m

#
# USB Type-C Multiplexer/DeMultiplexer Switch support
#
CONFIG_TYPEC_MUX_FSA4480=m
CONFIG_TYPEC_MUX_PI3USB30532=m
# end of USB Type-C Multiplexer/DeMultiplexer Switch support

#
# USB Type-C Alternate Mode drivers
#
# end of USB Type-C Alternate Mode drivers

CONFIG_USB_ROLE_SWITCH=y
CONFIG_MMC=m
CONFIG_PWRSEQ_EMMC=m
CONFIG_PWRSEQ_SD8787=m
CONFIG_PWRSEQ_SIMPLE=m
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_SDIO_UART=m
CONFIG_MMC_TEST=m
CONFIG_MMC_CRYPTO=y

#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_DEBUG=y
CONFIG_MMC_MESON_GX=m
CONFIG_MMC_MESON_MX_SDHC=m
CONFIG_MMC_MESON_MX_SDIO=m
CONFIG_MMC_MOXART=m
CONFIG_MMC_OMAP_HS=m
CONFIG_MMC_DAVINCI=m
CONFIG_MMC_SPI=m
CONFIG_MMC_S3C=m
CONFIG_MMC_S3C_HW_SDIO_IRQ=y
CONFIG_MMC_S3C_PIO=y
# CONFIG_MMC_S3C_DMA is not set
CONFIG_MMC_TMIO_CORE=m
CONFIG_MMC_TMIO=m
CONFIG_MMC_SDHI=m
CONFIG_MMC_SDHI_SYS_DMAC=m
CONFIG_MMC_SDHI_INTERNAL_DMAC=m
CONFIG_MMC_UNIPHIER=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_PLTFM=m
CONFIG_MMC_DW_BLUEFIELD=m
CONFIG_MMC_DW_EXYNOS=m
CONFIG_MMC_DW_HI3798CV200=m
CONFIG_MMC_DW_K3=m
CONFIG_MMC_SH_MMCIF=m
CONFIG_MMC_VUB300=m
CONFIG_MMC_USHC=m
CONFIG_MMC_REALTEK_USB=m
CONFIG_MMC_SUNXI=m
CONFIG_MMC_HSQ=m
CONFIG_MMC_BCM2835=m
CONFIG_MMC_LITEX=m
CONFIG_MEMSTICK=m
CONFIG_MEMSTICK_DEBUG=y

#
# MemoryStick drivers
#
CONFIG_MEMSTICK_UNSAFE_RESUME=y
CONFIG_MSPRO_BLOCK=m
CONFIG_MS_BLOCK=m

#
# MemoryStick Host Controller Drivers
#
CONFIG_MEMSTICK_REALTEK_USB=m
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_CLASS_FLASH=m
CONFIG_LEDS_CLASS_MULTICOLOR=m
CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y

#
# LED drivers
#
CONFIG_LEDS_AN30259A=m
CONFIG_LEDS_ARIEL=m
CONFIG_LEDS_AW2013=m
CONFIG_LEDS_BCM6328=m
CONFIG_LEDS_BCM6358=m
CONFIG_LEDS_CPCAP=m
CONFIG_LEDS_CR0014114=m
CONFIG_LEDS_EL15203000=m
CONFIG_LEDS_TURRIS_OMNIA=m
CONFIG_LEDS_LM3530=m
CONFIG_LEDS_LM3532=m
CONFIG_LEDS_LM3533=m
CONFIG_LEDS_LM3642=m
CONFIG_LEDS_LM3692X=m
CONFIG_LEDS_MT6323=m
CONFIG_LEDS_S3C24XX=m
CONFIG_LEDS_COBALT_QUBE=m
CONFIG_LEDS_PCA9532=m
CONFIG_LEDS_PCA9532_GPIO=y
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_LP3944=m
CONFIG_LEDS_LP3952=m
CONFIG_LEDS_LP50XX=m
CONFIG_LEDS_LP55XX_COMMON=m
CONFIG_LEDS_LP5521=m
CONFIG_LEDS_LP5523=m
CONFIG_LEDS_LP5562=m
CONFIG_LEDS_LP8501=m
CONFIG_LEDS_LP8860=m
CONFIG_LEDS_PCA955X=m
CONFIG_LEDS_PCA955X_GPIO=y
CONFIG_LEDS_PCA963X=m
CONFIG_LEDS_WM831X_STATUS=m
CONFIG_LEDS_DA9052=m
CONFIG_LEDS_DAC124S085=m
CONFIG_LEDS_PWM=m
CONFIG_LEDS_REGULATOR=m
CONFIG_LEDS_BD2802=m
CONFIG_LEDS_LT3593=m
CONFIG_LEDS_MC13783=m
CONFIG_LEDS_NS2=m
CONFIG_LEDS_NETXBIG=m
CONFIG_LEDS_TCA6507=m
CONFIG_LEDS_TLC591XX=m
CONFIG_LEDS_MAX77650=m
CONFIG_LEDS_LM355x=m
CONFIG_LEDS_OT200=m
CONFIG_LEDS_MENF21BMC=m
CONFIG_LEDS_IS31FL319X=m
CONFIG_LEDS_IS31FL32XX=m
CONFIG_LEDS_SC27XX_BLTC=m

#
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
#
CONFIG_LEDS_BLINKM=m
CONFIG_LEDS_PM8058=m
CONFIG_LEDS_MLXREG=m
CONFIG_LEDS_USER=m
CONFIG_LEDS_SPI_BYTE=m
CONFIG_LEDS_TI_LMU_COMMON=m
CONFIG_LEDS_LM3697=m
CONFIG_LEDS_LM36274=m
CONFIG_LEDS_TPS6105X=m
CONFIG_LEDS_IP30=m
CONFIG_LEDS_ACER_A500=m
CONFIG_LEDS_BCM63138=m
CONFIG_LEDS_LGM=m

#
# Flash and Torch LED drivers
#
CONFIG_LEDS_AAT1290=m
CONFIG_LEDS_AS3645A=m
CONFIG_LEDS_KTD2692=m
CONFIG_LEDS_LM3601X=m
CONFIG_LEDS_MAX77693=m
CONFIG_LEDS_MT6360=m
CONFIG_LEDS_RT4505=m
CONFIG_LEDS_RT8515=m
CONFIG_LEDS_SGM3140=m

#
# RGB LED drivers
#
CONFIG_LEDS_PWM_MULTICOLOR=m
CONFIG_LEDS_QCOM_LPG=m

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_DISK=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=m
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m

#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_TRIGGER_CAMERA=m
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=m
CONFIG_LEDS_TRIGGER_PATTERN=m
CONFIG_LEDS_TRIGGER_AUDIO=m
CONFIG_LEDS_TRIGGER_TTY=m

#
# Simple LED drivers
#
CONFIG_ACCESSIBILITY=y
CONFIG_A11Y_BRAILLE_CONSOLE=y

#
# Speakup console speech
#
CONFIG_SPEAKUP=m
CONFIG_SPEAKUP_SERIALIO=y
CONFIG_SPEAKUP_SYNTH_ACNTSA=m
CONFIG_SPEAKUP_SYNTH_ACNTPC=m
CONFIG_SPEAKUP_SYNTH_APOLLO=m
CONFIG_SPEAKUP_SYNTH_AUDPTR=m
CONFIG_SPEAKUP_SYNTH_BNS=m
CONFIG_SPEAKUP_SYNTH_DECTLK=m
CONFIG_SPEAKUP_SYNTH_DECEXT=m
CONFIG_SPEAKUP_SYNTH_DECPC=m
CONFIG_SPEAKUP_SYNTH_DTLK=m
CONFIG_SPEAKUP_SYNTH_KEYPC=m
CONFIG_SPEAKUP_SYNTH_LTLK=m
CONFIG_SPEAKUP_SYNTH_SOFT=m
CONFIG_SPEAKUP_SYNTH_SPKOUT=m
CONFIG_SPEAKUP_SYNTH_TXPRT=m
CONFIG_SPEAKUP_SYNTH_DUMMY=m
# end of Speakup console speech

CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
CONFIG_RTC_DEBUG=y
CONFIG_RTC_LIB_KUNIT_TEST=m
CONFIG_RTC_NVMEM=y

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=m

#
# I2C RTC drivers
#
CONFIG_RTC_DRV_88PM80X=m
CONFIG_RTC_DRV_ABB5ZES3=m
CONFIG_RTC_DRV_ABEOZ9=m
CONFIG_RTC_DRV_ABX80X=m
CONFIG_RTC_DRV_BRCMSTB=m
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_DS1307_CENTURY=y
CONFIG_RTC_DRV_DS1374=m
CONFIG_RTC_DRV_DS1374_WDT=y
CONFIG_RTC_DRV_DS1672=m
CONFIG_RTC_DRV_HYM8563=m
CONFIG_RTC_DRV_MAX6900=m
CONFIG_RTC_DRV_MAX8907=m
CONFIG_RTC_DRV_MAX77686=m
CONFIG_RTC_DRV_NCT3018Y=m
CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_RS5C372=m
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_ISL12022=m
CONFIG_RTC_DRV_ISL12026=m
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_PCF8523=m
CONFIG_RTC_DRV_PCF85063=m
CONFIG_RTC_DRV_PCF85363=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_PCF8583=m
CONFIG_RTC_DRV_M41T80=m
CONFIG_RTC_DRV_M41T80_WDT=y
CONFIG_RTC_DRV_BQ32K=m
CONFIG_RTC_DRV_RC5T619=m
CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_FM3130=m
CONFIG_RTC_DRV_RX8010=m
CONFIG_RTC_DRV_RX8581=m
CONFIG_RTC_DRV_RX8025=m
CONFIG_RTC_DRV_EM3027=m
CONFIG_RTC_DRV_RV3028=m
CONFIG_RTC_DRV_RV3032=m
CONFIG_RTC_DRV_RV8803=m
CONFIG_RTC_DRV_S5M=m
CONFIG_RTC_DRV_SD3078=m

#
# SPI RTC drivers
#
CONFIG_RTC_DRV_M41T93=m
CONFIG_RTC_DRV_M41T94=m
CONFIG_RTC_DRV_DS1302=m
CONFIG_RTC_DRV_DS1305=m
CONFIG_RTC_DRV_DS1343=m
CONFIG_RTC_DRV_DS1347=m
CONFIG_RTC_DRV_DS1390=m
CONFIG_RTC_DRV_MAX6916=m
CONFIG_RTC_DRV_R9701=m
CONFIG_RTC_DRV_RX4581=m
CONFIG_RTC_DRV_RS5C348=m
CONFIG_RTC_DRV_MAX6902=m
CONFIG_RTC_DRV_PCF2123=m
CONFIG_RTC_DRV_MCP795=m
CONFIG_RTC_I2C_AND_SPI=m

#
# SPI and I2C RTC drivers
#
CONFIG_RTC_DRV_DS3232=m
CONFIG_RTC_DRV_DS3232_HWMON=y
CONFIG_RTC_DRV_PCF2127=m
CONFIG_RTC_DRV_RV3029C2=m
CONFIG_RTC_DRV_RV3029_HWMON=y
CONFIG_RTC_DRV_RX6110=m

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_DS1286=m
CONFIG_RTC_DRV_DS1511=m
CONFIG_RTC_DRV_DS1553=m
CONFIG_RTC_DRV_DS1685_FAMILY=m
CONFIG_RTC_DRV_DS1685=y
# CONFIG_RTC_DRV_DS1689 is not set
# CONFIG_RTC_DRV_DS17285 is not set
# CONFIG_RTC_DRV_DS17485 is not set
# CONFIG_RTC_DRV_DS17885 is not set
CONFIG_RTC_DRV_DS1742=m
CONFIG_RTC_DRV_DS2404=m
CONFIG_RTC_DRV_DA9052=m
CONFIG_RTC_DRV_DA9063=m
CONFIG_RTC_DRV_STK17TA8=m
CONFIG_RTC_DRV_M48T86=m
CONFIG_RTC_DRV_M48T35=m
CONFIG_RTC_DRV_M48T59=m
CONFIG_RTC_DRV_MSM6242=m
CONFIG_RTC_DRV_BQ4802=m
CONFIG_RTC_DRV_RP5C01=m
CONFIG_RTC_DRV_V3020=m
CONFIG_RTC_DRV_GAMECUBE=m
CONFIG_RTC_DRV_WM831X=m
CONFIG_RTC_DRV_SC27XX=m
CONFIG_RTC_DRV_SPEAR=m
CONFIG_RTC_DRV_PCF50633=m
CONFIG_RTC_DRV_ZYNQMP=m
CONFIG_RTC_DRV_CROS_EC=m
CONFIG_RTC_DRV_NTXEC=m

#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_ASM9260=m
CONFIG_RTC_DRV_DAVINCI=m
CONFIG_RTC_DRV_DIGICOLOR=m
CONFIG_RTC_DRV_FSL_FTM_ALARM=m
CONFIG_RTC_DRV_MESON=m
CONFIG_RTC_DRV_MESON_VRTC=m
CONFIG_RTC_DRV_OMAP=m
CONFIG_RTC_DRV_S3C=m
CONFIG_RTC_DRV_EP93XX=m
CONFIG_RTC_DRV_SH=m
CONFIG_RTC_DRV_AT91RM9200=m
CONFIG_RTC_DRV_AT91SAM9=m
CONFIG_RTC_DRV_RZN1=m
CONFIG_RTC_DRV_GENERIC=m
CONFIG_RTC_DRV_VT8500=m
CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_SUNXI=m
CONFIG_RTC_DRV_MV=m
CONFIG_RTC_DRV_ARMADA38X=m
CONFIG_RTC_DRV_CADENCE=m
CONFIG_RTC_DRV_FTRTC010=m
CONFIG_RTC_DRV_STMP=m
CONFIG_RTC_DRV_PCAP=m
CONFIG_RTC_DRV_MC13XXX=m
CONFIG_RTC_DRV_JZ4740=m
CONFIG_RTC_DRV_LPC24XX=m
CONFIG_RTC_DRV_LPC32XX=m
CONFIG_RTC_DRV_PM8XXX=m
CONFIG_RTC_DRV_TEGRA=m
CONFIG_RTC_DRV_MXC=m
CONFIG_RTC_DRV_MXC_V2=m
CONFIG_RTC_DRV_SNVS=m
CONFIG_RTC_DRV_MOXART=m
CONFIG_RTC_DRV_MT2712=m
CONFIG_RTC_DRV_MT6397=m
CONFIG_RTC_DRV_MT7622=m
CONFIG_RTC_DRV_XGENE=m
CONFIG_RTC_DRV_R7301=m
CONFIG_RTC_DRV_STM32=m
CONFIG_RTC_DRV_CPCAP=m
CONFIG_RTC_DRV_RTD119X=y
CONFIG_RTC_DRV_ASPEED=m
CONFIG_RTC_DRV_TI_K3=m

#
# HID Sensor RTC drivers
#
CONFIG_RTC_DRV_HID_SENSOR_TIME=m
CONFIG_RTC_DRV_GOLDFISH=m
CONFIG_RTC_DRV_MSC313=m

#
# DMABUF options
#
CONFIG_SYNC_FILE=y
CONFIG_SW_SYNC=y
CONFIG_UDMABUF=y
CONFIG_DMABUF_MOVE_NOTIFY=y
CONFIG_DMABUF_DEBUG=y
CONFIG_DMABUF_SELFTESTS=m
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_SYSFS_STATS=y
CONFIG_DMABUF_HEAPS_SYSTEM=y
# end of DMABUF options

CONFIG_AUXDISPLAY=y
CONFIG_CHARLCD=m
CONFIG_LINEDISP=m
CONFIG_HD44780_COMMON=m
CONFIG_HD44780=m
CONFIG_KS0108=m
CONFIG_KS0108_PORT=0x378
CONFIG_KS0108_DELAY=2
CONFIG_IMG_ASCII_LCD=m
CONFIG_HT16K33=m
CONFIG_LCD2S=m
CONFIG_PARPORT_PANEL=m
CONFIG_PANEL_PARPORT=0
CONFIG_PANEL_PROFILE=5
CONFIG_PANEL_CHANGE_MESSAGE=y
CONFIG_PANEL_BOOT_MESSAGE=""
# CONFIG_CHARLCD_BL_OFF is not set
# CONFIG_CHARLCD_BL_ON is not set
CONFIG_CHARLCD_BL_FLASH=y
CONFIG_PANEL=m
CONFIG_VFIO=m
CONFIG_VFIO_VIRQFD=m
CONFIG_VFIO_NOIOMMU=y
CONFIG_VFIO_PLATFORM=m
CONFIG_VFIO_AMBA=m
CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET=m
CONFIG_VFIO_PLATFORM_AMDXGBE_RESET=m
CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET=m
CONFIG_VFIO_MDEV=m
CONFIG_IRQ_BYPASS_MANAGER=m
CONFIG_VIRT_DRIVERS=y
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=m
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_VDPA=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=m
CONFIG_VDPA=m
CONFIG_VHOST_IOTLB=m
CONFIG_VHOST=m
CONFIG_VHOST_MENU=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_SCSI=m
CONFIG_VHOST_VSOCK=m
CONFIG_VHOST_VDPA=m
CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y

#
# Microsoft Hyper-V guest support
#
# end of Microsoft Hyper-V guest support

CONFIG_GREYBUS=m
CONFIG_GREYBUS_ES2=m
CONFIG_COMEDI=m
CONFIG_COMEDI_DEBUG=y
CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048
CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480
CONFIG_COMEDI_MISC_DRIVERS=y
CONFIG_COMEDI_BOND=m
CONFIG_COMEDI_TEST=m
CONFIG_COMEDI_PARPORT=m
CONFIG_COMEDI_SSV_DNP=m
CONFIG_COMEDI_ISA_DRIVERS=y
CONFIG_COMEDI_PCL711=m
CONFIG_COMEDI_PCL724=m
CONFIG_COMEDI_PCL726=m
CONFIG_COMEDI_PCL730=m
CONFIG_COMEDI_PCL812=m
CONFIG_COMEDI_PCL816=m
CONFIG_COMEDI_PCL818=m
CONFIG_COMEDI_PCM3724=m
CONFIG_COMEDI_AMPLC_DIO200_ISA=m
CONFIG_COMEDI_AMPLC_PC236_ISA=m
CONFIG_COMEDI_AMPLC_PC263_ISA=m
CONFIG_COMEDI_RTI800=m
CONFIG_COMEDI_RTI802=m
CONFIG_COMEDI_DAC02=m
CONFIG_COMEDI_DAS16M1=m
CONFIG_COMEDI_DAS08_ISA=m
CONFIG_COMEDI_DAS16=m
CONFIG_COMEDI_DAS800=m
CONFIG_COMEDI_DAS1800=m
CONFIG_COMEDI_DAS6402=m
CONFIG_COMEDI_DT2801=m
CONFIG_COMEDI_DT2811=m
CONFIG_COMEDI_DT2814=m
CONFIG_COMEDI_DT2815=m
CONFIG_COMEDI_DT2817=m
CONFIG_COMEDI_DT282X=m
CONFIG_COMEDI_DMM32AT=m
CONFIG_COMEDI_FL512=m
CONFIG_COMEDI_AIO_AIO12_8=m
CONFIG_COMEDI_AIO_IIRO_16=m
CONFIG_COMEDI_II_PCI20KC=m
CONFIG_COMEDI_C6XDIGIO=m
CONFIG_COMEDI_MPC624=m
CONFIG_COMEDI_ADQ12B=m
CONFIG_COMEDI_NI_AT_A2150=m
CONFIG_COMEDI_NI_AT_AO=m
CONFIG_COMEDI_NI_ATMIO=m
CONFIG_COMEDI_NI_ATMIO16D=m
CONFIG_COMEDI_NI_LABPC_ISA=m
CONFIG_COMEDI_PCMAD=m
CONFIG_COMEDI_PCMDA12=m
CONFIG_COMEDI_PCMMIO=m
CONFIG_COMEDI_PCMUIO=m
CONFIG_COMEDI_MULTIQ3=m
CONFIG_COMEDI_S526=m
CONFIG_COMEDI_PCMCIA_DRIVERS=m
CONFIG_COMEDI_CB_DAS16_CS=m
CONFIG_COMEDI_DAS08_CS=m
CONFIG_COMEDI_NI_DAQ_700_CS=m
CONFIG_COMEDI_NI_DAQ_DIO24_CS=m
CONFIG_COMEDI_NI_LABPC_CS=m
CONFIG_COMEDI_NI_MIO_CS=m
CONFIG_COMEDI_QUATECH_DAQP_CS=m
CONFIG_COMEDI_USB_DRIVERS=m
CONFIG_COMEDI_DT9812=m
CONFIG_COMEDI_NI_USB6501=m
CONFIG_COMEDI_USBDUX=m
CONFIG_COMEDI_USBDUXFAST=m
CONFIG_COMEDI_USBDUXSIGMA=m
CONFIG_COMEDI_VMK80XX=m
CONFIG_COMEDI_8254=m
CONFIG_COMEDI_8255=m
CONFIG_COMEDI_8255_SA=m
CONFIG_COMEDI_KCOMEDILIB=m
CONFIG_COMEDI_AMPLC_DIO200=m
CONFIG_COMEDI_AMPLC_PC236=m
CONFIG_COMEDI_DAS08=m
CONFIG_COMEDI_NI_LABPC=m
CONFIG_COMEDI_NI_TIO=m
CONFIG_COMEDI_NI_ROUTING=m
CONFIG_COMEDI_TESTS=m
CONFIG_COMEDI_TESTS_EXAMPLE=m
CONFIG_COMEDI_TESTS_NI_ROUTES=m
CONFIG_STAGING=y
CONFIG_PRISM2_USB=m
CONFIG_RTLLIB=m
CONFIG_RTLLIB_CRYPTO_CCMP=m
CONFIG_RTLLIB_CRYPTO_TKIP=m
CONFIG_RTLLIB_CRYPTO_WEP=m
CONFIG_RTL8723BS=m
CONFIG_R8712U=m
CONFIG_R8188EU=m
CONFIG_OCTEON_ETHERNET=m
CONFIG_VT6656=m

#
# IIO staging drivers
#

#
# Accelerometers
#
CONFIG_ADIS16203=m
CONFIG_ADIS16240=m
# end of Accelerometers

#
# Analog to digital converters
#
CONFIG_AD7816=m
# end of Analog to digital converters

#
# Analog digital bi-direction converters
#
CONFIG_ADT7316=m
CONFIG_ADT7316_SPI=m
CONFIG_ADT7316_I2C=m
# end of Analog digital bi-direction converters

#
# Direct Digital Synthesis
#
CONFIG_AD9832=m
CONFIG_AD9834=m
# end of Direct Digital Synthesis

#
# Network Analyzer, Impedance Converters
#
CONFIG_AD5933=m
# end of Network Analyzer, Impedance Converters

#
# Active energy metering IC
#
CONFIG_ADE7854=m
CONFIG_ADE7854_I2C=m
CONFIG_ADE7854_SPI=m
# end of Active energy metering IC

#
# Resolver to digital converters
#
CONFIG_AD2S1210=m
# end of Resolver to digital converters
# end of IIO staging drivers

CONFIG_USB_EMXX=m
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_MAX96712=m
CONFIG_VIDEO_OMAP4=m
CONFIG_VIDEO_ROCKCHIP_VDEC=m
CONFIG_VIDEO_SUNXI=y
CONFIG_STAGING_MEDIA_DEPRECATED=y
CONFIG_VIDEO_CPIA2=m
CONFIG_VIDEO_VIU=m
CONFIG_VIDEO_STKWEBCAM=m
CONFIG_VIDEO_TM6000=m
CONFIG_VIDEO_TM6000_ALSA=m
CONFIG_VIDEO_TM6000_DVB=m
CONFIG_VIDEO_DM6446_CCDC=m
CONFIG_VIDEO_DM355_CCDC=m
CONFIG_VIDEO_DM365_ISIF=m
CONFIG_USB_ZR364XX=m
CONFIG_STAGING_BOARD=y
CONFIG_LTE_GDM724X=m
CONFIG_FB_TFT=m
CONFIG_FB_TFT_AGM1264K_FL=m
CONFIG_FB_TFT_BD663474=m
CONFIG_FB_TFT_HX8340BN=m
CONFIG_FB_TFT_HX8347D=m
CONFIG_FB_TFT_HX8353D=m
CONFIG_FB_TFT_HX8357D=m
CONFIG_FB_TFT_ILI9163=m
CONFIG_FB_TFT_ILI9320=m
CONFIG_FB_TFT_ILI9325=m
CONFIG_FB_TFT_ILI9340=m
CONFIG_FB_TFT_ILI9341=m
CONFIG_FB_TFT_ILI9481=m
CONFIG_FB_TFT_ILI9486=m
CONFIG_FB_TFT_PCD8544=m
CONFIG_FB_TFT_RA8875=m
CONFIG_FB_TFT_S6D02A1=m
CONFIG_FB_TFT_S6D1121=m
CONFIG_FB_TFT_SEPS525=m
CONFIG_FB_TFT_SH1106=m
CONFIG_FB_TFT_SSD1289=m
CONFIG_FB_TFT_SSD1305=m
CONFIG_FB_TFT_SSD1306=m
CONFIG_FB_TFT_SSD1331=m
CONFIG_FB_TFT_SSD1351=m
CONFIG_FB_TFT_ST7735R=m
CONFIG_FB_TFT_ST7789V=m
CONFIG_FB_TFT_TINYLCD=m
CONFIG_FB_TFT_TLS8204=m
CONFIG_FB_TFT_UC1611=m
CONFIG_FB_TFT_UC1701=m
CONFIG_FB_TFT_UPD161704=m
CONFIG_KS7010=m
CONFIG_GREYBUS_AUDIO=m
CONFIG_GREYBUS_AUDIO_APB_CODEC=m
CONFIG_GREYBUS_BOOTROM=m
CONFIG_GREYBUS_FIRMWARE=m
CONFIG_GREYBUS_HID=m
CONFIG_GREYBUS_LIGHT=m
CONFIG_GREYBUS_LOG=m
CONFIG_GREYBUS_LOOPBACK=m
CONFIG_GREYBUS_POWER=m
CONFIG_GREYBUS_RAW=m
CONFIG_GREYBUS_VIBRATOR=m
CONFIG_GREYBUS_BRIDGED_PHY=m
CONFIG_GREYBUS_GPIO=m
CONFIG_GREYBUS_I2C=m
CONFIG_GREYBUS_PWM=m
CONFIG_GREYBUS_SDIO=m
CONFIG_GREYBUS_SPI=m
CONFIG_GREYBUS_UART=m
CONFIG_GREYBUS_USB=m
CONFIG_GREYBUS_ARCHE=m
CONFIG_BCM_VIDEOCORE=m
CONFIG_SND_BCM2835=m
CONFIG_VIDEO_BCM2835=m
CONFIG_PI433=m
CONFIG_XIL_AXIS_FIFO=m
CONFIG_FIELDBUS_DEV=m
CONFIG_HMS_ANYBUSS_BUS=m
CONFIG_ARCX_ANYBUS_CONTROLLER=m
CONFIG_HMS_PROFINET=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=m
CONFIG_CROS_EC_I2C=m
CONFIG_CROS_EC_RPMSG=m
CONFIG_CROS_EC_SPI=m
CONFIG_CROS_EC_PROTO=y
CONFIG_CROS_KBD_LED_BACKLIGHT=m
CONFIG_CROS_EC_CHARDEV=m
CONFIG_CROS_EC_LIGHTBAR=m
CONFIG_CROS_EC_VBC=m
CONFIG_CROS_EC_DEBUGFS=m
CONFIG_CROS_EC_SENSORHUB=m
CONFIG_CROS_EC_SYSFS=m
CONFIG_CROS_EC_TYPEC=m
CONFIG_CROS_USBPD_LOGGER=m
CONFIG_CROS_USBPD_NOTIFY=m
CONFIG_CROS_KUNIT=m
CONFIG_MELLANOX_PLATFORM=y
CONFIG_MLXREG_HOTPLUG=m
CONFIG_MLXREG_IO=m
CONFIG_MLXREG_LC=m
CONFIG_NVSW_SN2201=m
CONFIG_OLPC_EC=y
CONFIG_OLPC_XO175=y
CONFIG_OLPC_XO175_EC=m
CONFIG_SURFACE_PLATFORMS=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_LEGACY_CLK=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_WM831X=m

#
# Clock driver for ARM Reference designs
#
CONFIG_CLK_ICST=y
CONFIG_CLK_SP810=y
# end of Clock driver for ARM Reference designs

CONFIG_CLK_HSDK=y
CONFIG_LMK04832=m
CONFIG_COMMON_CLK_APPLE_NCO=m
CONFIG_COMMON_CLK_MAX77686=m
CONFIG_COMMON_CLK_MAX9485=m
CONFIG_COMMON_CLK_RK808=m
CONFIG_COMMON_CLK_HI655X=m
CONFIG_COMMON_CLK_SCMI=m
CONFIG_COMMON_CLK_SCPI=m
CONFIG_COMMON_CLK_SI5341=m
CONFIG_COMMON_CLK_SI5351=m
CONFIG_COMMON_CLK_SI514=m
CONFIG_COMMON_CLK_SI544=m
CONFIG_COMMON_CLK_SI570=m
CONFIG_COMMON_CLK_BM1880=y
CONFIG_COMMON_CLK_CDCE706=m
CONFIG_COMMON_CLK_TPS68470=m
CONFIG_COMMON_CLK_CDCE925=m
CONFIG_COMMON_CLK_CS2000_CP=m
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMMON_CLK_FSL_FLEXSPI=m
CONFIG_COMMON_CLK_FSL_SAI=y
CONFIG_COMMON_CLK_GEMINI=y
CONFIG_COMMON_CLK_LAN966X=m
CONFIG_COMMON_CLK_ASPEED=y
CONFIG_COMMON_CLK_S2MPS11=m
CONFIG_COMMON_CLK_AXI_CLKGEN=m
CONFIG_CLK_QORIQ=y
CONFIG_CLK_LS1028A_PLLDIG=m
CONFIG_COMMON_CLK_XGENE=y
CONFIG_COMMON_CLK_PWM=m
CONFIG_COMMON_CLK_OXNAS=y
CONFIG_COMMON_CLK_RS9_PCIE=m
CONFIG_COMMON_CLK_VC5=m
CONFIG_COMMON_CLK_VC7=m
CONFIG_COMMON_CLK_MMP2_AUDIO=m
CONFIG_COMMON_CLK_FIXED_MMIO=y
CONFIG_CLK_ACTIONS=y
CONFIG_CLK_OWL_S500=y
CONFIG_CLK_OWL_S700=y
CONFIG_CLK_OWL_S900=y
CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
CONFIG_CLK_BAIKAL_T1=y
CONFIG_CLK_BT1_CCU_PLL=y
CONFIG_CLK_BT1_CCU_DIV=y
CONFIG_CLK_BT1_CCU_RST=y
CONFIG_CLK_BCM2711_DVP=m
CONFIG_CLK_BCM2835=y
CONFIG_CLK_BCM_63XX=y
CONFIG_CLK_BCM_63XX_GATE=y
CONFIG_CLK_BCM_KONA=y
CONFIG_COMMON_CLK_IPROC=y
CONFIG_CLK_BCM_CYGNUS=y
CONFIG_CLK_BCM_HR2=y
CONFIG_CLK_BCM_NSP=y
CONFIG_CLK_BCM_NS2=y
CONFIG_CLK_BCM_SR=y
CONFIG_CLK_RASPBERRYPI=m
CONFIG_COMMON_CLK_HI3516CV300=m
CONFIG_COMMON_CLK_HI3519=m
CONFIG_COMMON_CLK_HI3559A=y
CONFIG_COMMON_CLK_HI3660=y
CONFIG_COMMON_CLK_HI3670=y
CONFIG_COMMON_CLK_HI3798CV200=m
CONFIG_COMMON_CLK_HI6220=y
CONFIG_RESET_HISI=y
CONFIG_STUB_CLK_HI6220=y
CONFIG_STUB_CLK_HI3660=y
CONFIG_COMMON_CLK_BOSTON=y
CONFIG_MXC_CLK=m
CONFIG_CLK_IMX8MM=m
CONFIG_CLK_IMX8MN=m
CONFIG_CLK_IMX8MP=m
CONFIG_CLK_IMX8MQ=m
CONFIG_CLK_IMX8ULP=m
CONFIG_CLK_IMX93=m

#
# Ingenic SoCs drivers
#
CONFIG_INGENIC_CGU_COMMON=y
CONFIG_INGENIC_CGU_JZ4740=y
CONFIG_INGENIC_CGU_JZ4725B=y
CONFIG_INGENIC_CGU_JZ4760=y
CONFIG_INGENIC_CGU_JZ4770=y
CONFIG_INGENIC_CGU_JZ4780=y
CONFIG_INGENIC_CGU_X1000=y
CONFIG_INGENIC_CGU_X1830=y
CONFIG_INGENIC_TCU_CLK=y
# end of Ingenic SoCs drivers

CONFIG_COMMON_CLK_KEYSTONE=m
CONFIG_TI_SYSCON_CLK=m

#
# Clock driver for MediaTek SoC
#
CONFIG_COMMON_CLK_MEDIATEK=y
CONFIG_COMMON_CLK_MT2701=y
CONFIG_COMMON_CLK_MT2701_MMSYS=y
CONFIG_COMMON_CLK_MT2701_IMGSYS=y
CONFIG_COMMON_CLK_MT2701_VDECSYS=y
CONFIG_COMMON_CLK_MT2701_HIFSYS=y
CONFIG_COMMON_CLK_MT2701_ETHSYS=y
CONFIG_COMMON_CLK_MT2701_BDPSYS=y
CONFIG_COMMON_CLK_MT2701_AUDSYS=y
CONFIG_COMMON_CLK_MT2701_G3DSYS=y
CONFIG_COMMON_CLK_MT2712=y
CONFIG_COMMON_CLK_MT2712_BDPSYS=y
CONFIG_COMMON_CLK_MT2712_IMGSYS=y
CONFIG_COMMON_CLK_MT2712_JPGDECSYS=y
CONFIG_COMMON_CLK_MT2712_MFGCFG=y
CONFIG_COMMON_CLK_MT2712_MMSYS=y
CONFIG_COMMON_CLK_MT2712_VDECSYS=y
CONFIG_COMMON_CLK_MT2712_VENCSYS=y
CONFIG_COMMON_CLK_MT6765=y
CONFIG_COMMON_CLK_MT6765_AUDIOSYS=y
CONFIG_COMMON_CLK_MT6765_CAMSYS=y
CONFIG_COMMON_CLK_MT6765_GCESYS=y
CONFIG_COMMON_CLK_MT6765_MMSYS=y
CONFIG_COMMON_CLK_MT6765_IMGSYS=y
CONFIG_COMMON_CLK_MT6765_VCODECSYS=y
CONFIG_COMMON_CLK_MT6765_MFGSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI0ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI0BSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI1ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI1BSYS=y
CONFIG_COMMON_CLK_MT6765_MIPI2ASYS=y
CONFIG_COMMON_CLK_MT6765_MIPI2BSYS=y
CONFIG_COMMON_CLK_MT6779=m
CONFIG_COMMON_CLK_MT6779_MMSYS=m
CONFIG_COMMON_CLK_MT6779_IMGSYS=m
CONFIG_COMMON_CLK_MT6779_IPESYS=m
CONFIG_COMMON_CLK_MT6779_CAMSYS=m
CONFIG_COMMON_CLK_MT6779_VDECSYS=m
CONFIG_COMMON_CLK_MT6779_VENCSYS=m
CONFIG_COMMON_CLK_MT6779_MFGCFG=m
CONFIG_COMMON_CLK_MT6779_AUDSYS=m
CONFIG_COMMON_CLK_MT6795=m
CONFIG_COMMON_CLK_MT6795_MFGCFG=m
CONFIG_COMMON_CLK_MT6795_MMSYS=m
CONFIG_COMMON_CLK_MT6795_VDECSYS=m
CONFIG_COMMON_CLK_MT6795_VENCSYS=m
CONFIG_COMMON_CLK_MT6797=y
CONFIG_COMMON_CLK_MT6797_MMSYS=y
CONFIG_COMMON_CLK_MT6797_IMGSYS=y
CONFIG_COMMON_CLK_MT6797_VDECSYS=y
CONFIG_COMMON_CLK_MT6797_VENCSYS=y
CONFIG_COMMON_CLK_MT7622=y
CONFIG_COMMON_CLK_MT7622_ETHSYS=y
CONFIG_COMMON_CLK_MT7622_HIFSYS=y
CONFIG_COMMON_CLK_MT7622_AUDSYS=y
CONFIG_COMMON_CLK_MT7629=y
CONFIG_COMMON_CLK_MT7629_ETHSYS=y
CONFIG_COMMON_CLK_MT7629_HIFSYS=y
CONFIG_COMMON_CLK_MT7986=y
CONFIG_COMMON_CLK_MT7986_ETHSYS=y
CONFIG_COMMON_CLK_MT8135=y
CONFIG_COMMON_CLK_MT8167=y
CONFIG_COMMON_CLK_MT8167_AUDSYS=y
CONFIG_COMMON_CLK_MT8167_IMGSYS=y
CONFIG_COMMON_CLK_MT8167_MFGCFG=y
CONFIG_COMMON_CLK_MT8167_MMSYS=y
CONFIG_COMMON_CLK_MT8167_VDECSYS=y
CONFIG_COMMON_CLK_MT8173=y
CONFIG_COMMON_CLK_MT8173_MMSYS=y
CONFIG_COMMON_CLK_MT8183=y
CONFIG_COMMON_CLK_MT8183_AUDIOSYS=y
CONFIG_COMMON_CLK_MT8183_CAMSYS=y
CONFIG_COMMON_CLK_MT8183_IMGSYS=y
CONFIG_COMMON_CLK_MT8183_IPU_CORE0=y
CONFIG_COMMON_CLK_MT8183_IPU_CORE1=y
CONFIG_COMMON_CLK_MT8183_IPU_ADL=y
CONFIG_COMMON_CLK_MT8183_IPU_CONN=y
CONFIG_COMMON_CLK_MT8183_MFGCFG=y
CONFIG_COMMON_CLK_MT8183_MMSYS=y
CONFIG_COMMON_CLK_MT8183_VDECSYS=y
CONFIG_COMMON_CLK_MT8183_VENCSYS=y
CONFIG_COMMON_CLK_MT8186=y
CONFIG_COMMON_CLK_MT8192=y
CONFIG_COMMON_CLK_MT8192_AUDSYS=y
CONFIG_COMMON_CLK_MT8192_CAMSYS=y
CONFIG_COMMON_CLK_MT8192_IMGSYS=y
CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP=y
CONFIG_COMMON_CLK_MT8192_IPESYS=y
CONFIG_COMMON_CLK_MT8192_MDPSYS=y
CONFIG_COMMON_CLK_MT8192_MFGCFG=y
CONFIG_COMMON_CLK_MT8192_MMSYS=y
CONFIG_COMMON_CLK_MT8192_MSDC=y
CONFIG_COMMON_CLK_MT8192_SCP_ADSP=y
CONFIG_COMMON_CLK_MT8192_VDECSYS=y
CONFIG_COMMON_CLK_MT8192_VENCSYS=y
CONFIG_COMMON_CLK_MT8195=y
CONFIG_COMMON_CLK_MT8365=m
CONFIG_COMMON_CLK_MT8365_APU=m
CONFIG_COMMON_CLK_MT8365_CAM=m
CONFIG_COMMON_CLK_MT8365_MFG=m
CONFIG_COMMON_CLK_MT8365_MMSYS=m
CONFIG_COMMON_CLK_MT8365_VDEC=m
CONFIG_COMMON_CLK_MT8365_VENC=m
CONFIG_COMMON_CLK_MT8516=y
CONFIG_COMMON_CLK_MT8516_AUDSYS=y
# end of Clock driver for MediaTek SoC

#
# Clock support for Amlogic platforms
#
# CONFIG_COMMON_CLK_AXG_AUDIO is not set
# end of Clock support for Amlogic platforms

CONFIG_MSTAR_MSC313_MPLL=y
CONFIG_MCHP_CLK_MPFS=y
CONFIG_COMMON_CLK_PISTACHIO=y
CONFIG_QCOM_GDSC=y
CONFIG_QCOM_RPMCC=y
CONFIG_COMMON_CLK_QCOM=m
CONFIG_QCOM_A53PLL=m
CONFIG_QCOM_A7PLL=m
CONFIG_QCOM_CLK_APCS_MSM8916=m
CONFIG_QCOM_CLK_APCS_SDX55=m
CONFIG_QCOM_CLK_SMD_RPM=m
CONFIG_QCOM_CLK_RPMH=m
CONFIG_APQ_GCC_8084=m
CONFIG_APQ_MMCC_8084=m
CONFIG_IPQ_APSS_PLL=m
CONFIG_IPQ_APSS_6018=m
CONFIG_IPQ_GCC_4019=m
CONFIG_IPQ_GCC_6018=m
CONFIG_IPQ_GCC_806X=m
CONFIG_IPQ_LCC_806X=m
CONFIG_IPQ_GCC_8074=m
CONFIG_MSM_GCC_8660=m
CONFIG_MSM_GCC_8909=m
CONFIG_MSM_GCC_8916=m
CONFIG_MSM_GCC_8939=m
CONFIG_MSM_GCC_8960=m
CONFIG_MSM_LCC_8960=m
CONFIG_MDM_GCC_9607=m
CONFIG_MDM_GCC_9615=m
CONFIG_MDM_LCC_9615=m
CONFIG_MSM_MMCC_8960=m
CONFIG_MSM_GCC_8953=m
CONFIG_MSM_GCC_8974=m
CONFIG_MSM_MMCC_8974=m
CONFIG_MSM_GCC_8976=m
CONFIG_MSM_MMCC_8994=m
CONFIG_MSM_GCC_8994=m
CONFIG_MSM_GCC_8996=m
CONFIG_MSM_MMCC_8996=m
CONFIG_MSM_GCC_8998=m
CONFIG_MSM_GPUCC_8998=m
CONFIG_MSM_MMCC_8998=m
CONFIG_QCM_GCC_2290=m
CONFIG_QCM_DISPCC_2290=m
CONFIG_QCS_GCC_404=m
CONFIG_SC_CAMCC_7180=m
CONFIG_SC_CAMCC_7280=m
CONFIG_SC_DISPCC_7180=m
CONFIG_SC_DISPCC_7280=m
CONFIG_SC_GCC_7180=m
CONFIG_SC_GCC_7280=m
CONFIG_SC_GCC_8180X=m
CONFIG_SC_GCC_8280XP=m
CONFIG_SC_GPUCC_7180=m
CONFIG_SC_GPUCC_7280=m
CONFIG_SC_GPUCC_8280XP=m
CONFIG_SC_LPASSCC_7280=m
CONFIG_SC_LPASS_CORECC_7180=m
CONFIG_SC_LPASS_CORECC_7280=m
CONFIG_SC_MSS_7180=m
CONFIG_SC_VIDEOCC_7180=m
CONFIG_SC_VIDEOCC_7280=m
CONFIG_SDM_CAMCC_845=m
CONFIG_SDM_GCC_660=m
CONFIG_SDM_MMCC_660=m
CONFIG_SDM_GPUCC_660=m
CONFIG_QCS_TURING_404=m
CONFIG_QCS_Q6SSTOP_404=m
CONFIG_SDM_GCC_845=m
CONFIG_SDM_GPUCC_845=m
CONFIG_SDM_VIDEOCC_845=m
CONFIG_SDM_DISPCC_845=m
CONFIG_SDM_LPASSCC_845=m
CONFIG_SDX_GCC_55=m
CONFIG_SDX_GCC_65=m
CONFIG_SM_CAMCC_8250=m
CONFIG_SM_CAMCC_8450=m
CONFIG_SM_DISPCC_6115=m
CONFIG_SM_DISPCC_6125=m
CONFIG_SM_DISPCC_8250=m
CONFIG_SM_DISPCC_6350=m
CONFIG_SM_DISPCC_8450=m
CONFIG_SM_GCC_6115=m
CONFIG_SM_GCC_6125=m
CONFIG_SM_GCC_6350=m
CONFIG_SM_GCC_6375=m
CONFIG_SM_GCC_8150=m
CONFIG_SM_GCC_8250=m
CONFIG_SM_GCC_8350=m
CONFIG_SM_GCC_8450=m
CONFIG_SM_GPUCC_6350=m
CONFIG_SM_GPUCC_8150=m
CONFIG_SM_GPUCC_8250=m
CONFIG_SM_GPUCC_8350=m
CONFIG_SM_VIDEOCC_8150=m
CONFIG_SM_VIDEOCC_8250=m
CONFIG_SPMI_PMIC_CLKDIV=m
CONFIG_QCOM_HFPLL=m
CONFIG_KPSS_XCC=m
CONFIG_CLK_GFM_LPASS_SM8250=m
CONFIG_CLK_MT7621=y
CONFIG_CLK_RENESAS=y
CONFIG_CLK_EMEV2=y
CONFIG_CLK_RZA1=y
CONFIG_CLK_R7S9210=y
CONFIG_CLK_R8A73A4=y
CONFIG_CLK_R8A7740=y
CONFIG_CLK_R8A7742=y
CONFIG_CLK_R8A7743=y
CONFIG_CLK_R8A7745=y
CONFIG_CLK_R8A77470=y
CONFIG_CLK_R8A774A1=y
CONFIG_CLK_R8A774B1=y
CONFIG_CLK_R8A774C0=y
CONFIG_CLK_R8A774E1=y
CONFIG_CLK_R8A7778=y
CONFIG_CLK_R8A7779=y
CONFIG_CLK_R8A7790=y
CONFIG_CLK_R8A7791=y
CONFIG_CLK_R8A7792=y
CONFIG_CLK_R8A7794=y
CONFIG_CLK_R8A7795=y
CONFIG_CLK_R8A77960=y
CONFIG_CLK_R8A77961=y
CONFIG_CLK_R8A77965=y
CONFIG_CLK_R8A77970=y
CONFIG_CLK_R8A77980=y
CONFIG_CLK_R8A77990=y
CONFIG_CLK_R8A77995=y
CONFIG_CLK_R8A779A0=y
CONFIG_CLK_R8A779F0=y
CONFIG_CLK_R8A779G0=y
CONFIG_CLK_R9A06G032=y
CONFIG_CLK_R9A07G043=y
CONFIG_CLK_R9A07G044=y
CONFIG_CLK_R9A07G054=y
CONFIG_CLK_R9A09G011=y
CONFIG_CLK_SH73A0=y
CONFIG_CLK_RCAR_CPG_LIB=y
CONFIG_CLK_RCAR_GEN2_CPG=y
CONFIG_CLK_RCAR_GEN3_CPG=y
CONFIG_CLK_RCAR_GEN4_CPG=y
CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
CONFIG_CLK_RZG2L=y
CONFIG_CLK_RENESAS_CPG_MSSR=y
CONFIG_CLK_RENESAS_CPG_MSTP=y
CONFIG_CLK_RENESAS_DIV6=y
CONFIG_COMMON_CLK_SAMSUNG=y
CONFIG_S3C64XX_COMMON_CLK=y
CONFIG_S5PV210_COMMON_CLK=y
CONFIG_EXYNOS_3250_COMMON_CLK=y
CONFIG_EXYNOS_4_COMMON_CLK=y
CONFIG_EXYNOS_5250_COMMON_CLK=y
CONFIG_EXYNOS_5260_COMMON_CLK=y
CONFIG_EXYNOS_5410_COMMON_CLK=y
CONFIG_EXYNOS_5420_COMMON_CLK=y
CONFIG_EXYNOS_ARM64_COMMON_CLK=y
CONFIG_EXYNOS_AUDSS_CLK_CON=m
CONFIG_EXYNOS_CLKOUT=m
CONFIG_S3C2410_COMMON_CLK=y
CONFIG_S3C2412_COMMON_CLK=y
CONFIG_S3C2443_COMMON_CLK=y
CONFIG_TESLA_FSD_COMMON_CLK=y
CONFIG_CLK_SIFIVE=y
CONFIG_CLK_SIFIVE_PRCI=y
CONFIG_CLK_INTEL_SOCFPGA=y
CONFIG_CLK_INTEL_SOCFPGA32=y
CONFIG_CLK_INTEL_SOCFPGA64=y
CONFIG_SPRD_COMMON_CLK=m
CONFIG_SPRD_SC9860_CLK=m
CONFIG_SPRD_SC9863A_CLK=m
CONFIG_SPRD_UMS512_CLK=m
CONFIG_CLK_STARFIVE_JH7100=y
CONFIG_CLK_STARFIVE_JH7100_AUDIO=m
CONFIG_CLK_SUNXI=y
CONFIG_CLK_SUNXI_CLOCKS=y
CONFIG_CLK_SUNXI_PRCM_SUN6I=y
CONFIG_CLK_SUNXI_PRCM_SUN8I=y
CONFIG_CLK_SUNXI_PRCM_SUN9I=y
CONFIG_SUNXI_CCU=m
CONFIG_SUNIV_F1C100S_CCU=m
CONFIG_SUN20I_D1_CCU=m
CONFIG_SUN20I_D1_R_CCU=m
CONFIG_SUN50I_A64_CCU=m
CONFIG_SUN50I_A100_CCU=m
CONFIG_SUN50I_A100_R_CCU=m
CONFIG_SUN50I_H6_CCU=m
CONFIG_SUN50I_H616_CCU=m
CONFIG_SUN50I_H6_R_CCU=m
CONFIG_SUN4I_A10_CCU=m
CONFIG_SUN6I_A31_CCU=m
CONFIG_SUN6I_RTC_CCU=m
CONFIG_SUN8I_A23_CCU=m
CONFIG_SUN8I_A33_CCU=m
CONFIG_SUN8I_A83T_CCU=m
CONFIG_SUN8I_H3_CCU=m
CONFIG_SUN8I_V3S_CCU=m
CONFIG_SUN8I_DE2_CCU=m
CONFIG_SUN8I_R40_CCU=m
CONFIG_SUN9I_A80_CCU=m
CONFIG_SUN8I_R_CCU=m
CONFIG_COMMON_CLK_TI_ADPLL=m
CONFIG_CLK_UNIPHIER=y
CONFIG_COMMON_CLK_VISCONTI=y
CONFIG_CLK_LGM_CGU=y
CONFIG_XILINX_VCU=m
CONFIG_COMMON_CLK_XLNX_CLKWZRD=m
CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_CLK_KUNIT_TEST=m
CONFIG_CLK_GATE_KUNIT_TEST=m
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_OMAP=m
CONFIG_HWSPINLOCK_QCOM=m
CONFIG_HWSPINLOCK_SPRD=m
CONFIG_HWSPINLOCK_STM32=m
CONFIG_HWSPINLOCK_SUN6I=m
CONFIG_HSEM_U8500=m

#
# Clock Source drivers
#
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_CLKSRC_MMIO=y
CONFIG_BCM2835_TIMER=y
CONFIG_BCM_KONA_TIMER=y
CONFIG_DAVINCI_TIMER=y
CONFIG_DIGICOLOR_TIMER=y
CONFIG_OMAP_DM_TIMER=y
CONFIG_DW_APB_TIMER=y
CONFIG_FTTMR010_TIMER=y
CONFIG_IXP4XX_TIMER=y
CONFIG_MESON6_TIMER=y
CONFIG_OWL_TIMER=y
CONFIG_RDA_TIMER=y
CONFIG_SUN4I_TIMER=y
CONFIG_SUN5I_HSTIMER=y
CONFIG_TEGRA_TIMER=y
CONFIG_TEGRA186_TIMER=y
CONFIG_VT8500_TIMER=y
CONFIG_NPCM7XX_TIMER=y
CONFIG_CADENCE_TTC_TIMER=y
CONFIG_ASM9260_TIMER=y
CONFIG_CLKSRC_DBX500_PRCMU=y
CONFIG_CLPS711X_TIMER=y
CONFIG_MXS_TIMER=y
CONFIG_NSPIRE_TIMER=y
CONFIG_INTEGRATOR_AP_TIMER=y
CONFIG_CLKSRC_PISTACHIO=y
CONFIG_CLKSRC_TI_32K=y
CONFIG_CLKSRC_STM32_LP=y
CONFIG_CLKSRC_MPS2=y
CONFIG_ARC_TIMERS=y
CONFIG_ARC_TIMERS_64BIT=y
CONFIG_ARM_TIMER_SP804=y
CONFIG_ARMV7M_SYSTICK=y
CONFIG_ATMEL_PIT=y
CONFIG_ATMEL_ST=y
CONFIG_CLKSRC_SAMSUNG_PWM=y
CONFIG_FSL_FTM_TIMER=y
CONFIG_OXNAS_RPS_TIMER=y
CONFIG_SYS_SUPPORTS_SH_CMT=y
CONFIG_MTK_TIMER=y
CONFIG_SPRD_TIMER=y
CONFIG_CLKSRC_JCORE_PIT=y
CONFIG_SH_TIMER_CMT=y
CONFIG_SH_TIMER_MTU2=y
CONFIG_RENESAS_OSTM=y
CONFIG_SH_TIMER_TMU=y
CONFIG_EM_TIMER_STI=y
CONFIG_CLKSRC_VERSATILE=y
CONFIG_CLKSRC_PXA=y
CONFIG_TIMER_IMX_SYS_CTR=y
CONFIG_CLKSRC_ST_LPC=y
CONFIG_GXP_TIMER=y
CONFIG_MSC313E_TIMER=y
CONFIG_INGENIC_TIMER=y
CONFIG_INGENIC_SYSOST=y
CONFIG_INGENIC_OST=y
CONFIG_MICROCHIP_PIT64B=y
CONFIG_GOLDFISH_TIMER=y
# end of Clock Source drivers

CONFIG_MAILBOX=y
CONFIG_IMX_MBOX=m
CONFIG_PLATFORM_MHU=m
CONFIG_ARMADA_37XX_RWTM_MBOX=m
CONFIG_ROCKCHIP_MBOX=y
CONFIG_ALTERA_MBOX=m
CONFIG_HI3660_MBOX=m
CONFIG_HI6220_MBOX=m
CONFIG_MAILBOX_TEST=m
CONFIG_POLARFIRE_SOC_MAILBOX=m
CONFIG_QCOM_APCS_IPC=m
CONFIG_BCM_PDC_MBOX=m
CONFIG_STM32_IPCC=m
CONFIG_MTK_ADSP_MBOX=m
CONFIG_MTK_CMDQ_MBOX=m
CONFIG_SUN6I_MSGBOX=m
CONFIG_SPRD_MBOX=m
CONFIG_QCOM_IPCC=m
CONFIG_IOMMU_IOVA=m
CONFIG_IOMMU_API=y

#
# Remoteproc drivers
#
# end of Remoteproc drivers

#
# Rpmsg drivers
#
CONFIG_RPMSG=m
CONFIG_RPMSG_CHAR=m
CONFIG_RPMSG_CTRL=m
CONFIG_RPMSG_NS=m
CONFIG_RPMSG_QCOM_GLINK=m
CONFIG_RPMSG_QCOM_GLINK_RPM=m
CONFIG_RPMSG_QCOM_GLINK_SMEM=m
CONFIG_RPMSG_QCOM_SMD=m
# end of Rpmsg drivers

CONFIG_SOUNDWIRE=m

#
# SoundWire Devices
#
CONFIG_SOUNDWIRE_QCOM=m

#
# SOC (System On Chip) specific Drivers
#
CONFIG_OWL_PM_DOMAINS_HELPER=y
CONFIG_OWL_PM_DOMAINS=y

#
# Amlogic SoC drivers
#
CONFIG_MESON_CANVAS=m
CONFIG_MESON_CLK_MEASURE=m
CONFIG_MESON_GX_SOCINFO=y
CONFIG_MESON_GX_PM_DOMAINS=m
CONFIG_MESON_EE_PM_DOMAINS=m
CONFIG_MESON_MX_SOCINFO=y
# end of Amlogic SoC drivers

#
# Apple SoC drivers
#
CONFIG_APPLE_PMGR_PWRSTATE=y
CONFIG_APPLE_RTKIT=m
CONFIG_APPLE_SART=m
# end of Apple SoC drivers

#
# ASPEED SoC drivers
#
CONFIG_ASPEED_LPC_CTRL=m
CONFIG_ASPEED_LPC_SNOOP=m
CONFIG_ASPEED_UART_ROUTING=m
CONFIG_ASPEED_P2A_CTRL=m
CONFIG_ASPEED_SOCINFO=y
# end of ASPEED SoC drivers

CONFIG_AT91_SOC_ID=y
CONFIG_AT91_SOC_SFR=m

#
# Broadcom SoC drivers
#
CONFIG_BCM2835_POWER=y
CONFIG_SOC_BCM63XX=y
CONFIG_SOC_BRCMSTB=y
CONFIG_BCM63XX_POWER=y
CONFIG_BCM_PMB=y
# end of Broadcom SoC drivers

#
# NXP/Freescale QorIQ SoC drivers
#
CONFIG_QUICC_ENGINE=y
CONFIG_UCC_SLOW=y
CONFIG_UCC_FAST=y
CONFIG_UCC=y
CONFIG_QE_TDM=y
CONFIG_DPAA2_CONSOLE=m
# end of NXP/Freescale QorIQ SoC drivers

#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers

#
# i.MX SoC drivers
#
CONFIG_IMX_GPCV2_PM_DOMAINS=y
CONFIG_SOC_IMX8M=y
CONFIG_SOC_IMX9=m
# end of i.MX SoC drivers

#
# IXP4xx SoC drivers
#
CONFIG_IXP4XX_QMGR=m
CONFIG_IXP4XX_NPE=m
# end of IXP4xx SoC drivers

#
# Enable LiteX SoC Builder specific drivers
#
CONFIG_LITEX=y
CONFIG_LITEX_SOC_CONTROLLER=m
# end of Enable LiteX SoC Builder specific drivers

#
# MediaTek SoC drivers
#
CONFIG_MTK_CMDQ=m
CONFIG_MTK_DEVAPC=m
CONFIG_MTK_INFRACFG=y
CONFIG_MTK_PMIC_WRAP=m
CONFIG_MTK_SCPSYS=y
CONFIG_MTK_SCPSYS_PM_DOMAINS=y
CONFIG_MTK_MMSYS=y
CONFIG_MTK_SVS=m
# end of MediaTek SoC drivers

CONFIG_POLARFIRE_SOC_SYS_CTRL=m

#
# Qualcomm SoC drivers
#
CONFIG_QCOM_AOSS_QMP=m
CONFIG_QCOM_COMMAND_DB=m
CONFIG_QCOM_GENI_SE=m
CONFIG_QCOM_GSBI=m
CONFIG_QCOM_LLCC=m
CONFIG_QCOM_PDR_HELPERS=m
CONFIG_QCOM_QMI_HELPERS=m
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_RPMHPD=m
CONFIG_QCOM_RPMPD=m
CONFIG_QCOM_SMEM=m
CONFIG_QCOM_SMD_RPM=m
CONFIG_QCOM_SMEM_STATE=y
CONFIG_QCOM_SMP2P=m
CONFIG_QCOM_SMSM=m
CONFIG_QCOM_SOCINFO=m
CONFIG_QCOM_SPM=m
CONFIG_QCOM_STATS=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_QCOM_APR=m
CONFIG_QCOM_ICC_BWMON=m
# end of Qualcomm SoC drivers

CONFIG_SOC_RENESAS=y
CONFIG_RST_RCAR=y
CONFIG_SYSC_RCAR=y
CONFIG_SYSC_RCAR_GEN4=y
CONFIG_SYSC_R8A77995=y
CONFIG_SYSC_R8A7794=y
CONFIG_SYSC_R8A77990=y
CONFIG_SYSC_R8A7779=y
CONFIG_SYSC_R8A7790=y
CONFIG_SYSC_R8A7795=y
CONFIG_SYSC_R8A7791=y
CONFIG_SYSC_R8A77965=y
CONFIG_SYSC_R8A77960=y
CONFIG_SYSC_R8A77961=y
CONFIG_SYSC_R8A779F0=y
CONFIG_SYSC_R8A7792=y
CONFIG_SYSC_R8A77980=y
CONFIG_SYSC_R8A77970=y
CONFIG_SYSC_R8A779A0=y
CONFIG_SYSC_R8A779G0=y
CONFIG_SYSC_RMOBILE=y
CONFIG_SYSC_R8A77470=y
CONFIG_SYSC_R8A7745=y
CONFIG_SYSC_R8A7742=y
CONFIG_SYSC_R8A7743=y
CONFIG_SYSC_R8A774C0=y
CONFIG_SYSC_R8A774E1=y
CONFIG_SYSC_R8A774A1=y
CONFIG_SYSC_R8A774B1=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=m
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ROCKCHIP_DTPM=m
CONFIG_SOC_SAMSUNG=y
CONFIG_EXYNOS_ASV_ARM=y
CONFIG_EXYNOS_CHIPID=m
CONFIG_EXYNOS_USI=m
CONFIG_EXYNOS_PM_DOMAINS=y
CONFIG_EXYNOS_REGULATOR_COUPLER=y
CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER=y
CONFIG_SOC_TI=y
CONFIG_UX500_SOC_ID=y

#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers

CONFIG_PM_DEVFREQ=y

#
# DEVFREQ Governors
#
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m
CONFIG_DEVFREQ_GOV_PERFORMANCE=m
CONFIG_DEVFREQ_GOV_POWERSAVE=m
CONFIG_DEVFREQ_GOV_USERSPACE=m
CONFIG_DEVFREQ_GOV_PASSIVE=m

#
# DEVFREQ Drivers
#
CONFIG_ARM_EXYNOS_BUS_DEVFREQ=m
CONFIG_ARM_IMX_BUS_DEVFREQ=m
CONFIG_ARM_TEGRA_DEVFREQ=m
CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=m
CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ=m
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU=m
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=m
CONFIG_EXTCON=y

#
# Extcon Device Drivers
#
CONFIG_EXTCON_ADC_JACK=m
CONFIG_EXTCON_FSA9480=m
CONFIG_EXTCON_GPIO=m
CONFIG_EXTCON_MAX14577=m
CONFIG_EXTCON_MAX3355=m
CONFIG_EXTCON_MAX77693=m
CONFIG_EXTCON_PTN5150=m
CONFIG_EXTCON_QCOM_SPMI_MISC=m
CONFIG_EXTCON_RT8973A=m
CONFIG_EXTCON_SM5502=m
CONFIG_EXTCON_USB_GPIO=m
CONFIG_EXTCON_USBC_CROS_EC=m
CONFIG_EXTCON_USBC_TUSB320=m
CONFIG_MEMORY=y
CONFIG_DDR=y
CONFIG_ATMEL_SDRAMC=y
CONFIG_ATMEL_EBI=y
CONFIG_BRCMSTB_DPFE=m
CONFIG_BRCMSTB_MEMC=m
CONFIG_BT1_L2_CTL=y
CONFIG_TI_AEMIF=m
CONFIG_TI_EMIF=m
CONFIG_OMAP_GPMC=m
CONFIG_OMAP_GPMC_DEBUG=y
CONFIG_FPGA_DFL_EMIF=m
CONFIG_MVEBU_DEVBUS=y
CONFIG_FSL_CORENET_CF=m
CONFIG_FSL_IFC=y
CONFIG_JZ4780_NEMC=y
CONFIG_MTK_SMI=m
CONFIG_DA8XX_DDRCTL=y
CONFIG_RENESAS_RPCIF=m
CONFIG_STM32_FMC2_EBI=m
CONFIG_SAMSUNG_MC=y
CONFIG_EXYNOS5422_DMC=m
CONFIG_EXYNOS_SROM=y
CONFIG_TEGRA_MC=y
CONFIG_TEGRA20_EMC=m
CONFIG_TEGRA30_EMC=m
CONFIG_TEGRA124_EMC=m
CONFIG_TEGRA210_EMC_TABLE=y
CONFIG_TEGRA210_EMC=m
CONFIG_IIO=m
CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=m
CONFIG_IIO_BUFFER_DMA=m
CONFIG_IIO_BUFFER_DMAENGINE=m
CONFIG_IIO_BUFFER_HW_CONSUMER=m
CONFIG_IIO_KFIFO_BUF=m
CONFIG_IIO_TRIGGERED_BUFFER=m
CONFIG_IIO_CONFIGFS=m
CONFIG_IIO_TRIGGER=y
CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
CONFIG_IIO_SW_DEVICE=m
CONFIG_IIO_SW_TRIGGER=m
CONFIG_IIO_TRIGGERED_EVENT=m

#
# Accelerometers
#
CONFIG_ADIS16201=m
CONFIG_ADIS16209=m
CONFIG_ADXL313=m
CONFIG_ADXL313_I2C=m
CONFIG_ADXL313_SPI=m
CONFIG_ADXL355=m
CONFIG_ADXL355_I2C=m
CONFIG_ADXL355_SPI=m
CONFIG_ADXL367=m
CONFIG_ADXL367_SPI=m
CONFIG_ADXL367_I2C=m
CONFIG_ADXL372=m
CONFIG_ADXL372_SPI=m
CONFIG_ADXL372_I2C=m
CONFIG_BMA220=m
CONFIG_BMA400=m
CONFIG_BMA400_I2C=m
CONFIG_BMA400_SPI=m
CONFIG_BMC150_ACCEL=m
CONFIG_BMC150_ACCEL_I2C=m
CONFIG_BMC150_ACCEL_SPI=m
CONFIG_BMI088_ACCEL=m
CONFIG_BMI088_ACCEL_SPI=m
CONFIG_DA280=m
CONFIG_DA311=m
CONFIG_DMARD06=m
CONFIG_DMARD09=m
CONFIG_DMARD10=m
CONFIG_FXLS8962AF=m
CONFIG_FXLS8962AF_I2C=m
CONFIG_FXLS8962AF_SPI=m
CONFIG_HID_SENSOR_ACCEL_3D=m
CONFIG_IIO_CROS_EC_ACCEL_LEGACY=m
CONFIG_IIO_ST_ACCEL_3AXIS=m
CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m
CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m
CONFIG_KXSD9=m
CONFIG_KXSD9_SPI=m
CONFIG_KXSD9_I2C=m
CONFIG_KXCJK1013=m
CONFIG_MC3230=m
CONFIG_MMA7455=m
CONFIG_MMA7455_I2C=m
CONFIG_MMA7455_SPI=m
CONFIG_MMA7660=m
CONFIG_MMA8452=m
CONFIG_MMA9551_CORE=m
CONFIG_MMA9551=m
CONFIG_MMA9553=m
CONFIG_MSA311=m
CONFIG_MXC4005=m
CONFIG_MXC6255=m
CONFIG_SCA3000=m
CONFIG_SCA3300=m
CONFIG_STK8312=m
CONFIG_STK8BA50=m
# end of Accelerometers

#
# Analog to digital converters
#
CONFIG_AD_SIGMA_DELTA=m
CONFIG_AD7091R5=m
CONFIG_AD7124=m
CONFIG_AD7192=m
CONFIG_AD7266=m
CONFIG_AD7280=m
CONFIG_AD7291=m
CONFIG_AD7292=m
CONFIG_AD7298=m
CONFIG_AD7476=m
CONFIG_AD7606=m
CONFIG_AD7606_IFACE_PARALLEL=m
CONFIG_AD7606_IFACE_SPI=m
CONFIG_AD7766=m
CONFIG_AD7768_1=m
CONFIG_AD7780=m
CONFIG_AD7791=m
CONFIG_AD7793=m
CONFIG_AD7887=m
CONFIG_AD7923=m
CONFIG_AD7949=m
CONFIG_AD799X=m
CONFIG_AD9467=m
CONFIG_ADI_AXI_ADC=m
CONFIG_ASPEED_ADC=m
CONFIG_AT91_ADC=m
CONFIG_AT91_SAMA5D2_ADC=m
CONFIG_AXP20X_ADC=m
CONFIG_AXP288_ADC=m
CONFIG_BCM_IPROC_ADC=m
CONFIG_BERLIN2_ADC=m
CONFIG_CC10001_ADC=m
CONFIG_CPCAP_ADC=m
CONFIG_DA9150_GPADC=m
CONFIG_DLN2_ADC=m
CONFIG_ENVELOPE_DETECTOR=m
CONFIG_EXYNOS_ADC=m
CONFIG_MXS_LRADC_ADC=m
CONFIG_FSL_MX25_ADC=m
CONFIG_HI8435=m
CONFIG_HX711=m
CONFIG_INA2XX_ADC=m
CONFIG_INGENIC_ADC=m
CONFIG_IMX7D_ADC=m
CONFIG_IMX8QXP_ADC=m
CONFIG_LPC18XX_ADC=m
CONFIG_LPC32XX_ADC=m
CONFIG_LTC2471=m
CONFIG_LTC2485=m
CONFIG_LTC2496=m
CONFIG_LTC2497=m
CONFIG_MAX1027=m
CONFIG_MAX11100=m
CONFIG_MAX1118=m
CONFIG_MAX11205=m
CONFIG_MAX1241=m
CONFIG_MAX1363=m
CONFIG_MAX9611=m
CONFIG_MCP320X=m
CONFIG_MCP3422=m
CONFIG_MCP3911=m
CONFIG_MEDIATEK_MT6360_ADC=m
CONFIG_MEDIATEK_MT6577_AUXADC=m
CONFIG_MEN_Z188_ADC=m
CONFIG_MESON_SARADC=m
CONFIG_MP2629_ADC=m
CONFIG_NAU7802=m
CONFIG_NPCM_ADC=m
CONFIG_QCOM_VADC_COMMON=m
CONFIG_QCOM_PM8XXX_XOADC=m
CONFIG_QCOM_SPMI_RRADC=m
CONFIG_QCOM_SPMI_IADC=m
CONFIG_QCOM_SPMI_VADC=m
CONFIG_QCOM_SPMI_ADC5=m
CONFIG_RCAR_GYRO_ADC=m
CONFIG_RN5T618_ADC=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_RICHTEK_RTQ6056=m
CONFIG_RZG2L_ADC=m
CONFIG_SC27XX_ADC=m
CONFIG_SPEAR_ADC=m
CONFIG_SD_ADC_MODULATOR=m
CONFIG_STM32_ADC_CORE=m
CONFIG_STM32_ADC=m
CONFIG_STM32_DFSDM_CORE=m
CONFIG_STM32_DFSDM_ADC=m
CONFIG_STMPE_ADC=m
CONFIG_SUN4I_GPADC=m
CONFIG_TI_ADC081C=m
CONFIG_TI_ADC0832=m
CONFIG_TI_ADC084S021=m
CONFIG_TI_ADC12138=m
CONFIG_TI_ADC108S102=m
CONFIG_TI_ADC128S052=m
CONFIG_TI_ADC161S626=m
CONFIG_TI_ADS1015=m
CONFIG_TI_ADS7950=m
CONFIG_TI_ADS8344=m
CONFIG_TI_ADS8688=m
CONFIG_TI_ADS124S08=m
CONFIG_TI_ADS131E08=m
CONFIG_TI_TLC4541=m
CONFIG_TI_TSC2046=m
CONFIG_VF610_ADC=m
CONFIG_VIPERBOARD_ADC=m
CONFIG_XILINX_XADC=m
CONFIG_XILINX_AMS=m
# end of Analog to digital converters

#
# Analog to digital and digital to analog converters
#
CONFIG_AD74413R=m
# end of Analog to digital and digital to analog converters

#
# Analog Front Ends
#
CONFIG_IIO_RESCALE=m
# end of Analog Front Ends

#
# Amplifiers
#
CONFIG_AD8366=m
CONFIG_ADA4250=m
CONFIG_HMC425=m
# end of Amplifiers

#
# Capacitance to digital converters
#
CONFIG_AD7150=m
CONFIG_AD7746=m
# end of Capacitance to digital converters

#
# Chemical Sensors
#
CONFIG_ATLAS_PH_SENSOR=m
CONFIG_ATLAS_EZO_SENSOR=m
CONFIG_BME680=m
CONFIG_BME680_I2C=m
CONFIG_BME680_SPI=m
CONFIG_CCS811=m
CONFIG_IAQCORE=m
CONFIG_PMS7003=m
CONFIG_SCD30_CORE=m
CONFIG_SCD30_I2C=m
CONFIG_SCD30_SERIAL=m
CONFIG_SCD4X=m
CONFIG_SENSIRION_SGP30=m
CONFIG_SENSIRION_SGP40=m
CONFIG_SPS30=m
CONFIG_SPS30_I2C=m
CONFIG_SPS30_SERIAL=m
CONFIG_SENSEAIR_SUNRISE_CO2=m
CONFIG_VZ89X=m
# end of Chemical Sensors

CONFIG_IIO_CROS_EC_SENSORS_CORE=m
CONFIG_IIO_CROS_EC_SENSORS=m
CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m

#
# Hid Sensor IIO Common
#
CONFIG_HID_SENSOR_IIO_COMMON=m
CONFIG_HID_SENSOR_IIO_TRIGGER=m
# end of Hid Sensor IIO Common

CONFIG_IIO_MS_SENSORS_I2C=m

#
# IIO SCMI Sensors
#
CONFIG_IIO_SCMI=m
# end of IIO SCMI Sensors

#
# SSP Sensor Common
#
CONFIG_IIO_SSP_SENSORS_COMMONS=m
CONFIG_IIO_SSP_SENSORHUB=m
# end of SSP Sensor Common

CONFIG_IIO_ST_SENSORS_I2C=m
CONFIG_IIO_ST_SENSORS_SPI=m
CONFIG_IIO_ST_SENSORS_CORE=m

#
# Digital to analog converters
#
CONFIG_AD3552R=m
CONFIG_AD5064=m
CONFIG_AD5360=m
CONFIG_AD5380=m
CONFIG_AD5421=m
CONFIG_AD5446=m
CONFIG_AD5449=m
CONFIG_AD5592R_BASE=m
CONFIG_AD5592R=m
CONFIG_AD5593R=m
CONFIG_AD5504=m
CONFIG_AD5624R_SPI=m
CONFIG_LTC2688=m
CONFIG_AD5686=m
CONFIG_AD5686_SPI=m
CONFIG_AD5696_I2C=m
CONFIG_AD5755=m
CONFIG_AD5758=m
CONFIG_AD5761=m
CONFIG_AD5764=m
CONFIG_AD5766=m
CONFIG_AD5770R=m
CONFIG_AD5791=m
CONFIG_AD7293=m
CONFIG_AD7303=m
CONFIG_AD8801=m
CONFIG_DPOT_DAC=m
CONFIG_DS4424=m
CONFIG_LPC18XX_DAC=m
CONFIG_LTC1660=m
CONFIG_LTC2632=m
CONFIG_M62332=m
CONFIG_MAX517=m
CONFIG_MAX5821=m
CONFIG_MCP4725=m
CONFIG_MCP4922=m
CONFIG_STM32_DAC=m
CONFIG_STM32_DAC_CORE=m
CONFIG_TI_DAC082S085=m
CONFIG_TI_DAC5571=m
CONFIG_TI_DAC7311=m
CONFIG_TI_DAC7612=m
CONFIG_VF610_DAC=m
# end of Digital to analog converters

#
# IIO dummy driver
#
CONFIG_IIO_DUMMY_EVGEN=m
CONFIG_IIO_SIMPLE_DUMMY=m
CONFIG_IIO_SIMPLE_DUMMY_EVENTS=y
CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y
# end of IIO dummy driver

#
# Filters
#
# end of Filters

#
# Frequency Synthesizers DDS/PLL
#

#
# Clock Generator/Distribution
#
CONFIG_AD9523=m
# end of Clock Generator/Distribution

#
# Phase-Locked Loop (PLL) frequency synthesizers
#
CONFIG_ADF4350=m
CONFIG_ADF4371=m
CONFIG_ADMV1013=m
CONFIG_ADMV4420=m
CONFIG_ADRF6780=m
# end of Phase-Locked Loop (PLL) frequency synthesizers
# end of Frequency Synthesizers DDS/PLL

#
# Digital gyroscope sensors
#
CONFIG_ADIS16080=m
CONFIG_ADIS16130=m
CONFIG_ADIS16136=m
CONFIG_ADIS16260=m
CONFIG_ADXRS290=m
CONFIG_ADXRS450=m
CONFIG_BMG160=m
CONFIG_BMG160_I2C=m
CONFIG_BMG160_SPI=m
CONFIG_FXAS21002C=m
CONFIG_FXAS21002C_I2C=m
CONFIG_FXAS21002C_SPI=m
CONFIG_HID_SENSOR_GYRO_3D=m
CONFIG_MPU3050=m
CONFIG_MPU3050_I2C=m
CONFIG_IIO_ST_GYRO_3AXIS=m
CONFIG_IIO_ST_GYRO_I2C_3AXIS=m
CONFIG_IIO_ST_GYRO_SPI_3AXIS=m
CONFIG_ITG3200=m
# end of Digital gyroscope sensors

#
# Health Sensors
#

#
# Heart Rate Monitors
#
CONFIG_AFE4403=m
CONFIG_AFE4404=m
CONFIG_MAX30100=m
CONFIG_MAX30102=m
# end of Heart Rate Monitors
# end of Health Sensors

#
# Humidity sensors
#
CONFIG_AM2315=m
CONFIG_DHT11=m
CONFIG_HDC100X=m
CONFIG_HDC2010=m
CONFIG_HID_SENSOR_HUMIDITY=m
CONFIG_HTS221=m
CONFIG_HTS221_I2C=m
CONFIG_HTS221_SPI=m
CONFIG_HTU21=m
CONFIG_SI7005=m
CONFIG_SI7020=m
# end of Humidity sensors

#
# Inertial measurement units
#
CONFIG_ADIS16400=m
CONFIG_ADIS16460=m
CONFIG_ADIS16475=m
CONFIG_ADIS16480=m
CONFIG_BMI160=m
CONFIG_BMI160_I2C=m
CONFIG_BMI160_SPI=m
CONFIG_BOSCH_BNO055=m
CONFIG_BOSCH_BNO055_SERIAL=m
CONFIG_BOSCH_BNO055_I2C=m
CONFIG_FXOS8700=m
CONFIG_FXOS8700_I2C=m
CONFIG_FXOS8700_SPI=m
CONFIG_KMX61=m
CONFIG_INV_ICM42600=m
CONFIG_INV_ICM42600_I2C=m
CONFIG_INV_ICM42600_SPI=m
CONFIG_INV_MPU6050_IIO=m
CONFIG_INV_MPU6050_I2C=m
CONFIG_INV_MPU6050_SPI=m
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_IIO_ST_LSM6DSX_I2C=m
CONFIG_IIO_ST_LSM6DSX_SPI=m
CONFIG_IIO_ST_LSM6DSX_I3C=m
CONFIG_IIO_ST_LSM9DS0=m
CONFIG_IIO_ST_LSM9DS0_I2C=m
CONFIG_IIO_ST_LSM9DS0_SPI=m
# end of Inertial measurement units

CONFIG_IIO_ADIS_LIB=m
CONFIG_IIO_ADIS_LIB_BUFFER=y

#
# Light sensors
#
CONFIG_ADJD_S311=m
CONFIG_ADUX1020=m
CONFIG_AL3010=m
CONFIG_AL3320A=m
CONFIG_APDS9300=m
CONFIG_APDS9960=m
CONFIG_AS73211=m
CONFIG_BH1750=m
CONFIG_BH1780=m
CONFIG_CM32181=m
CONFIG_CM3232=m
CONFIG_CM3323=m
CONFIG_CM3605=m
CONFIG_CM36651=m
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
CONFIG_GP2AP002=m
CONFIG_GP2AP020A00F=m
CONFIG_IQS621_ALS=m
CONFIG_SENSORS_ISL29018=m
CONFIG_SENSORS_ISL29028=m
CONFIG_ISL29125=m
CONFIG_HID_SENSOR_ALS=m
CONFIG_HID_SENSOR_PROX=m
CONFIG_JSA1212=m
CONFIG_RPR0521=m
CONFIG_SENSORS_LM3533=m
CONFIG_LTR501=m
CONFIG_LTRF216A=m
CONFIG_LV0104CS=m
CONFIG_MAX44000=m
CONFIG_MAX44009=m
CONFIG_NOA1305=m
CONFIG_OPT3001=m
CONFIG_PA12203001=m
CONFIG_SI1133=m
CONFIG_SI1145=m
CONFIG_STK3310=m
CONFIG_ST_UVIS25=m
CONFIG_ST_UVIS25_I2C=m
CONFIG_ST_UVIS25_SPI=m
CONFIG_TCS3414=m
CONFIG_TCS3472=m
CONFIG_SENSORS_TSL2563=m
CONFIG_TSL2583=m
CONFIG_TSL2591=m
CONFIG_TSL2772=m
CONFIG_TSL4531=m
CONFIG_US5182D=m
CONFIG_VCNL4000=m
CONFIG_VCNL4035=m
CONFIG_VEML6030=m
CONFIG_VEML6070=m
CONFIG_VL6180=m
CONFIG_ZOPT2201=m
# end of Light sensors

#
# Magnetometer sensors
#
CONFIG_AK8974=m
CONFIG_AK8975=m
CONFIG_AK09911=m
CONFIG_BMC150_MAGN=m
CONFIG_BMC150_MAGN_I2C=m
CONFIG_BMC150_MAGN_SPI=m
CONFIG_MAG3110=m
CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
CONFIG_MMC35240=m
CONFIG_IIO_ST_MAGN_3AXIS=m
CONFIG_IIO_ST_MAGN_I2C_3AXIS=m
CONFIG_IIO_ST_MAGN_SPI_3AXIS=m
CONFIG_SENSORS_HMC5843=m
CONFIG_SENSORS_HMC5843_I2C=m
CONFIG_SENSORS_HMC5843_SPI=m
CONFIG_SENSORS_RM3100=m
CONFIG_SENSORS_RM3100_I2C=m
CONFIG_SENSORS_RM3100_SPI=m
CONFIG_YAMAHA_YAS530=m
# end of Magnetometer sensors

#
# Multiplexers
#
CONFIG_IIO_MUX=m
# end of Multiplexers

#
# Inclinometer sensors
#
CONFIG_HID_SENSOR_INCLINOMETER_3D=m
CONFIG_HID_SENSOR_DEVICE_ROTATION=m
# end of Inclinometer sensors

CONFIG_IIO_RESCALE_KUNIT_TEST=m
CONFIG_IIO_FORMAT_KUNIT_TEST=m

#
# Triggers - standalone
#
CONFIG_IIO_HRTIMER_TRIGGER=m
CONFIG_IIO_INTERRUPT_TRIGGER=m
CONFIG_IIO_STM32_LPTIMER_TRIGGER=m
CONFIG_IIO_STM32_TIMER_TRIGGER=m
CONFIG_IIO_TIGHTLOOP_TRIGGER=m
CONFIG_IIO_SYSFS_TRIGGER=m
# end of Triggers - standalone

#
# Linear and angular position sensors
#
CONFIG_IQS624_POS=m
CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m
# end of Linear and angular position sensors

#
# Digital potentiometers
#
CONFIG_AD5110=m
CONFIG_AD5272=m
CONFIG_DS1803=m
CONFIG_MAX5432=m
CONFIG_MAX5481=m
CONFIG_MAX5487=m
CONFIG_MCP4018=m
CONFIG_MCP4131=m
CONFIG_MCP4531=m
CONFIG_MCP41010=m
CONFIG_TPL0102=m
# end of Digital potentiometers

#
# Digital potentiostats
#
CONFIG_LMP91000=m
# end of Digital potentiostats

#
# Pressure sensors
#
CONFIG_ABP060MG=m
CONFIG_BMP280=m
CONFIG_BMP280_I2C=m
CONFIG_BMP280_SPI=m
CONFIG_IIO_CROS_EC_BARO=m
CONFIG_DLHL60D=m
CONFIG_DPS310=m
CONFIG_HID_SENSOR_PRESS=m
CONFIG_HP03=m
CONFIG_ICP10100=m
CONFIG_MPL115=m
CONFIG_MPL115_I2C=m
CONFIG_MPL115_SPI=m
CONFIG_MPL3115=m
CONFIG_MS5611=m
CONFIG_MS5611_I2C=m
CONFIG_MS5611_SPI=m
CONFIG_MS5637=m
CONFIG_IIO_ST_PRESS=m
CONFIG_IIO_ST_PRESS_I2C=m
CONFIG_IIO_ST_PRESS_SPI=m
CONFIG_T5403=m
CONFIG_HP206C=m
CONFIG_ZPA2326=m
CONFIG_ZPA2326_I2C=m
CONFIG_ZPA2326_SPI=m
# end of Pressure sensors

#
# Lightning sensors
#
CONFIG_AS3935=m
# end of Lightning sensors

#
# Proximity and distance sensors
#
CONFIG_CROS_EC_MKBP_PROXIMITY=m
CONFIG_ISL29501=m
CONFIG_LIDAR_LITE_V2=m
CONFIG_MB1232=m
CONFIG_PING=m
CONFIG_RFD77402=m
CONFIG_SRF04=m
CONFIG_SX_COMMON=m
CONFIG_SX9310=m
CONFIG_SX9324=m
CONFIG_SX9360=m
CONFIG_SX9500=m
CONFIG_SRF08=m
CONFIG_VCNL3020=m
CONFIG_VL53L0X_I2C=m
# end of Proximity and distance sensors

#
# Resolver to digital converters
#
CONFIG_AD2S90=m
CONFIG_AD2S1200=m
# end of Resolver to digital converters

#
# Temperature sensors
#
CONFIG_IQS620AT_TEMP=m
CONFIG_LTC2983=m
CONFIG_MAXIM_THERMOCOUPLE=m
CONFIG_HID_SENSOR_TEMP=m
CONFIG_MLX90614=m
CONFIG_MLX90632=m
CONFIG_TMP006=m
CONFIG_TMP007=m
CONFIG_TMP117=m
CONFIG_TSYS01=m
CONFIG_TSYS02D=m
CONFIG_MAX31856=m
CONFIG_MAX31865=m
# end of Temperature sensors

CONFIG_PWM=y
CONFIG_PWM_SYSFS=y
CONFIG_PWM_DEBUG=y
CONFIG_PWM_ATMEL=m
CONFIG_PWM_ATMEL_HLCDC_PWM=m
CONFIG_PWM_ATMEL_TCB=m
CONFIG_PWM_BCM_IPROC=m
CONFIG_PWM_BCM_KONA=m
CONFIG_PWM_BCM2835=m
CONFIG_PWM_BERLIN=m
CONFIG_PWM_BRCMSTB=m
CONFIG_PWM_CLK=m
CONFIG_PWM_CLPS711X=m
CONFIG_PWM_CROS_EC=m
CONFIG_PWM_EP93XX=m
CONFIG_PWM_FSL_FTM=m
CONFIG_PWM_HIBVT=m
CONFIG_PWM_IMG=m
CONFIG_PWM_IMX1=m
CONFIG_PWM_IMX27=m
CONFIG_PWM_IMX_TPM=m
CONFIG_PWM_INTEL_LGM=m
CONFIG_PWM_IQS620A=m
CONFIG_PWM_JZ4740=m
CONFIG_PWM_KEEMBAY=m
CONFIG_PWM_LP3943=m
CONFIG_PWM_LPC18XX_SCT=m
CONFIG_PWM_LPC32XX=m
CONFIG_PWM_LPSS=m
CONFIG_PWM_LPSS_PLATFORM=m
CONFIG_PWM_MESON=m
CONFIG_PWM_MTK_DISP=m
CONFIG_PWM_MEDIATEK=m
CONFIG_PWM_MXS=m
CONFIG_PWM_NTXEC=m
CONFIG_PWM_OMAP_DMTIMER=m
CONFIG_PWM_PCA9685=m
CONFIG_PWM_PXA=m
CONFIG_PWM_RASPBERRYPI_POE=m
CONFIG_PWM_RCAR=m
CONFIG_PWM_RENESAS_TPU=m
CONFIG_PWM_ROCKCHIP=m
CONFIG_PWM_SAMSUNG=m
CONFIG_PWM_SIFIVE=m
CONFIG_PWM_SL28CPLD=m
CONFIG_PWM_SPEAR=m
CONFIG_PWM_SPRD=m
CONFIG_PWM_STI=m
CONFIG_PWM_STM32=m
CONFIG_PWM_STM32_LP=m
CONFIG_PWM_STMPE=y
CONFIG_PWM_SUN4I=m
CONFIG_PWM_SUNPLUS=m
CONFIG_PWM_TEGRA=m
CONFIG_PWM_TIECAP=m
CONFIG_PWM_TIEHRPWM=m
CONFIG_PWM_VISCONTI=m
CONFIG_PWM_VT8500=m
CONFIG_PWM_XILINX=m

#
# IRQ chip support
#
CONFIG_IRQCHIP=y
CONFIG_AL_FIC=y
CONFIG_MADERA_IRQ=m
CONFIG_JCORE_AIC=y
CONFIG_RENESAS_INTC_IRQPIN=y
CONFIG_RENESAS_IRQC=y
CONFIG_RENESAS_RZA1_IRQC=y
CONFIG_RENESAS_RZG2L_IRQC=y
CONFIG_SL28CPLD_INTC=y
CONFIG_TS4800_IRQ=m
CONFIG_XILINX_INTC=y
CONFIG_INGENIC_TCU_IRQ=y
CONFIG_IRQ_UNIPHIER_AIDET=y
CONFIG_MESON_IRQ_GPIO=m
CONFIG_IMX_IRQSTEER=y
CONFIG_IMX_INTMUX=y
CONFIG_IMX_MU_MSI=m
CONFIG_EXYNOS_IRQ_COMBINER=y
CONFIG_MST_IRQ=y
CONFIG_MCHP_EIC=y
CONFIG_SUNPLUS_SP7021_INTC=y
# end of IRQ chip support

CONFIG_IPACK_BUS=m
CONFIG_SERIAL_IPOCTAL=m
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_A10SR=m
CONFIG_RESET_ATH79=y
CONFIG_RESET_AXS10X=y
CONFIG_RESET_BCM6345=y
CONFIG_RESET_BERLIN=m
CONFIG_RESET_BRCMSTB=m
CONFIG_RESET_BRCMSTB_RESCAL=m
CONFIG_RESET_HSDK=y
CONFIG_RESET_IMX7=m
CONFIG_RESET_INTEL_GW=y
CONFIG_RESET_K210=y
CONFIG_RESET_LANTIQ=y
CONFIG_RESET_LPC18XX=y
CONFIG_RESET_MCHP_SPARX5=y
CONFIG_RESET_MESON=m
CONFIG_RESET_MESON_AUDIO_ARB=m
CONFIG_RESET_NPCM=y
CONFIG_RESET_PISTACHIO=y
CONFIG_RESET_POLARFIRE_SOC=y
CONFIG_RESET_QCOM_AOSS=m
CONFIG_RESET_QCOM_PDC=m
CONFIG_RESET_RASPBERRYPI=m
CONFIG_RESET_RZG2L_USBPHY_CTRL=m
CONFIG_RESET_SCMI=m
CONFIG_RESET_SIMPLE=y
CONFIG_RESET_SOCFPGA=y
CONFIG_RESET_STARFIVE_JH7100=y
CONFIG_RESET_SUNPLUS=y
CONFIG_RESET_SUNXI=y
CONFIG_RESET_TI_SCI=m
CONFIG_RESET_TI_SYSCON=m
CONFIG_RESET_TI_TPS380X=m
CONFIG_RESET_TN48M_CPLD=m
CONFIG_RESET_UNIPHIER=m
CONFIG_RESET_UNIPHIER_GLUE=m
CONFIG_RESET_ZYNQ=y
CONFIG_COMMON_RESET_HI3660=m
CONFIG_COMMON_RESET_HI6220=m

#
# PHY Subsystem
#
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PHY_MIPI_DPHY=y
CONFIG_PHY_LPC18XX_USB_OTG=m
CONFIG_PHY_PISTACHIO_USB=m
CONFIG_PHY_XGENE=m
CONFIG_USB_LGM_PHY=m
CONFIG_PHY_CAN_TRANSCEIVER=m
CONFIG_PHY_SUN4I_USB=m
CONFIG_PHY_SUN6I_MIPI_DPHY=m
CONFIG_PHY_SUN9I_USB=m
CONFIG_PHY_SUN50I_USB3=m
CONFIG_PHY_MESON8_HDMI_TX=m
CONFIG_PHY_MESON8B_USB2=m
CONFIG_PHY_MESON_GXL_USB2=m
CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG=m
CONFIG_PHY_MESON_G12A_USB2=m
CONFIG_PHY_MESON_G12A_USB3_PCIE=m
CONFIG_PHY_MESON_AXG_PCIE=m
CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=m
CONFIG_PHY_MESON_AXG_MIPI_DPHY=m

#
# PHY drivers for Broadcom platforms
#
CONFIG_PHY_BCM63XX_USBH=m
CONFIG_PHY_CYGNUS_PCIE=m
CONFIG_PHY_BCM_SR_USB=m
CONFIG_BCM_KONA_USB2_PHY=m
CONFIG_PHY_BCM_NS_USB2=m
CONFIG_PHY_BCM_NS_USB3=m
CONFIG_PHY_NS2_PCIE=m
CONFIG_PHY_NS2_USB_DRD=m
CONFIG_PHY_BRCM_SATA=m
CONFIG_PHY_BRCM_USB=m
CONFIG_PHY_BCM_SR_PCIE=m
# end of PHY drivers for Broadcom platforms

CONFIG_PHY_CADENCE_TORRENT=m
CONFIG_PHY_CADENCE_DPHY=m
CONFIG_PHY_CADENCE_DPHY_RX=m
CONFIG_PHY_CADENCE_SIERRA=m
CONFIG_PHY_CADENCE_SALVO=m
CONFIG_PHY_FSL_IMX8MQ_USB=m
CONFIG_PHY_MIXEL_LVDS_PHY=m
CONFIG_PHY_MIXEL_MIPI_DPHY=m
CONFIG_PHY_FSL_IMX8M_PCIE=m
CONFIG_PHY_FSL_LYNX_28G=m
CONFIG_PHY_HI6220_USB=m
CONFIG_PHY_HI3660_USB=m
CONFIG_PHY_HI3670_USB=m
CONFIG_PHY_HI3670_PCIE=m
CONFIG_PHY_HISTB_COMBPHY=m
CONFIG_PHY_HISI_INNO_USB2=m
CONFIG_PHY_INGENIC_USB=m
CONFIG_PHY_LANTIQ_VRX200_PCIE=m
CONFIG_PHY_LANTIQ_RCU_USB2=m
CONFIG_ARMADA375_USBCLUSTER_PHY=y
CONFIG_PHY_BERLIN_SATA=m
CONFIG_PHY_BERLIN_USB=m
CONFIG_PHY_MVEBU_A3700_UTMI=m
CONFIG_PHY_MVEBU_A38X_COMPHY=m
CONFIG_PHY_MVEBU_CP110_UTMI=m
CONFIG_PHY_PXA_28NM_HSIC=m
CONFIG_PHY_PXA_28NM_USB2=m
CONFIG_PHY_PXA_USB=m
CONFIG_PHY_MMP3_USB=m
CONFIG_PHY_MMP3_HSIC=m
CONFIG_PHY_MTK_PCIE=m
CONFIG_PHY_MTK_TPHY=m
CONFIG_PHY_MTK_UFS=m
CONFIG_PHY_MTK_XSPHY=m
CONFIG_PHY_MTK_HDMI=m
CONFIG_PHY_MTK_MIPI_DSI=m
CONFIG_PHY_MTK_DP=m
CONFIG_PHY_SPARX5_SERDES=m
CONFIG_PHY_LAN966X_SERDES=m
CONFIG_PHY_CPCAP_USB=m
CONFIG_PHY_MAPPHONE_MDM6600=m
CONFIG_PHY_OCELOT_SERDES=m
CONFIG_PHY_ATH79_USB=m
CONFIG_PHY_QCOM_EDP=m
CONFIG_PHY_QCOM_IPQ4019_USB=m
CONFIG_PHY_QCOM_PCIE2=m
CONFIG_PHY_QCOM_QMP=m
CONFIG_PHY_QCOM_QUSB2=m
CONFIG_PHY_QCOM_USB_HS=m
CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=m
CONFIG_PHY_QCOM_USB_HSIC=m
CONFIG_PHY_QCOM_USB_HS_28NM=m
CONFIG_PHY_QCOM_USB_SS=m
CONFIG_PHY_QCOM_IPQ806X_USB=m
CONFIG_PHY_MT7621_PCI=m
CONFIG_PHY_RALINK_USB=m
CONFIG_PHY_RCAR_GEN3_USB3=m
CONFIG_PHY_ROCKCHIP_DPHY_RX0=m
CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
CONFIG_PHY_ROCKCHIP_INNO_USB2=m
CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=m
CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
CONFIG_PHY_ROCKCHIP_PCIE=m
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=m
CONFIG_PHY_ROCKCHIP_TYPEC=m
CONFIG_PHY_EXYNOS_DP_VIDEO=m
CONFIG_PHY_EXYNOS_MIPI_VIDEO=m
CONFIG_PHY_EXYNOS_PCIE=y
CONFIG_PHY_SAMSUNG_UFS=m
CONFIG_PHY_SAMSUNG_USB2=m
CONFIG_PHY_S5PV210_USB2=y
CONFIG_PHY_UNIPHIER_USB2=m
CONFIG_PHY_UNIPHIER_USB3=m
CONFIG_PHY_UNIPHIER_PCIE=m
CONFIG_PHY_UNIPHIER_AHCI=m
CONFIG_PHY_ST_SPEAR1310_MIPHY=m
CONFIG_PHY_ST_SPEAR1340_MIPHY=m
CONFIG_PHY_STIH407_USB=m
CONFIG_PHY_STM32_USBPHYC=m
CONFIG_PHY_SUNPLUS_USB=m
CONFIG_PHY_TEGRA194_P2U=m
CONFIG_PHY_DA8XX_USB=m
CONFIG_PHY_DM816X_USB=m
CONFIG_PHY_AM654_SERDES=m
CONFIG_PHY_J721E_WIZ=m
CONFIG_OMAP_CONTROL_PHY=m
CONFIG_TI_PIPE3=m
CONFIG_PHY_TUSB1210=m
CONFIG_PHY_INTEL_KEEMBAY_EMMC=m
CONFIG_PHY_INTEL_KEEMBAY_USB=m
CONFIG_PHY_INTEL_LGM_COMBO=y
CONFIG_PHY_INTEL_LGM_EMMC=m
CONFIG_PHY_INTEL_THUNDERBAY_EMMC=m
CONFIG_PHY_XILINX_ZYNQMP=m
# end of PHY Subsystem

CONFIG_POWERCAP=y
CONFIG_IDLE_INJECT=y
CONFIG_DTPM=y
CONFIG_MCB=m
CONFIG_MCB_LPC=m

#
# Performance monitor support
#
CONFIG_ARM_CCN=m
CONFIG_ARM_CMN=m
CONFIG_FSL_IMX8_DDR_PMU=m
CONFIG_ARM_DMC620_PMU=m
CONFIG_ALIBABA_UNCORE_DRW_PMU=m
# end of Performance monitor support

CONFIG_RAS=y

#
# Android
#
# end of Android

CONFIG_DAX=m
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_APPLE_EFUSES=m
CONFIG_NVMEM_BCM_OCOTP=m
CONFIG_NVMEM_BRCM_NVRAM=m
CONFIG_NVMEM_IMX_IIM=m
CONFIG_NVMEM_IMX_OCOTP=m
CONFIG_NVMEM_JZ4780_EFUSE=m
CONFIG_NVMEM_LAN9662_OTPC=m
CONFIG_NVMEM_LAYERSCAPE_SFP=m
CONFIG_NVMEM_LPC18XX_EEPROM=m
CONFIG_NVMEM_LPC18XX_OTP=m
CONFIG_NVMEM_MESON_MX_EFUSE=m
CONFIG_NVMEM_MICROCHIP_OTPC=m
CONFIG_NVMEM_MTK_EFUSE=m
CONFIG_NVMEM_MXS_OCOTP=m
CONFIG_NVMEM_NINTENDO_OTP=m
CONFIG_NVMEM_QCOM_QFPROM=m
CONFIG_NVMEM_RAVE_SP_EEPROM=m
CONFIG_NVMEM_RMEM=m
CONFIG_NVMEM_ROCKCHIP_EFUSE=m
CONFIG_NVMEM_ROCKCHIP_OTP=m
CONFIG_NVMEM_SC27XX_EFUSE=m
CONFIG_NVMEM_SNVS_LPGPR=m
CONFIG_NVMEM_SPMI_SDAM=m
CONFIG_NVMEM_SPRD_EFUSE=m
CONFIG_NVMEM_STM32_ROMEM=m
CONFIG_NVMEM_SUNPLUS_OCOTP=m
CONFIG_NVMEM_U_BOOT_ENV=m
CONFIG_NVMEM_UNIPHIER_EFUSE=m
CONFIG_NVMEM_VF610_OCOTP=m

#
# HW tracing support
#
CONFIG_STM=m
CONFIG_STM_PROTO_BASIC=m
CONFIG_STM_PROTO_SYS_T=m
CONFIG_STM_DUMMY=m
CONFIG_STM_SOURCE_CONSOLE=m
CONFIG_STM_SOURCE_HEARTBEAT=m
CONFIG_STM_SOURCE_FTRACE=m
# end of HW tracing support

CONFIG_FPGA=m
CONFIG_FPGA_MGR_SOCFPGA=m
CONFIG_FPGA_MGR_SOCFPGA_A10=m
CONFIG_ALTERA_PR_IP_CORE=m
CONFIG_ALTERA_PR_IP_CORE_PLAT=m
CONFIG_FPGA_MGR_ALTERA_PS_SPI=m
CONFIG_FPGA_MGR_ZYNQ_FPGA=m
CONFIG_FPGA_MGR_XILINX_SPI=m
CONFIG_FPGA_MGR_ICE40_SPI=m
CONFIG_FPGA_MGR_MACHXO2_SPI=m
CONFIG_FPGA_BRIDGE=m
CONFIG_ALTERA_FREEZE_BRIDGE=m
CONFIG_XILINX_PR_DECOUPLER=m
CONFIG_FPGA_REGION=m
CONFIG_OF_FPGA_REGION=m
CONFIG_FPGA_DFL=m
CONFIG_FPGA_DFL_FME=m
CONFIG_FPGA_DFL_FME_MGR=m
CONFIG_FPGA_DFL_FME_BRIDGE=m
CONFIG_FPGA_DFL_FME_REGION=m
CONFIG_FPGA_DFL_AFU=m
CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000=m
CONFIG_FPGA_MGR_ZYNQMP_FPGA=m
CONFIG_FPGA_MGR_VERSAL_FPGA=m
CONFIG_FPGA_M10_BMC_SEC_UPDATE=m
CONFIG_FPGA_MGR_MICROCHIP_SPI=m
CONFIG_FSI=m
CONFIG_FSI_NEW_DEV_NODE=y
CONFIG_FSI_MASTER_GPIO=m
CONFIG_FSI_MASTER_HUB=m
CONFIG_FSI_MASTER_AST_CF=m
CONFIG_FSI_MASTER_ASPEED=m
CONFIG_FSI_SCOM=m
CONFIG_FSI_SBEFIFO=m
CONFIG_FSI_OCC=m
CONFIG_TEE=m
CONFIG_MULTIPLEXER=m

#
# Multiplexer drivers
#
CONFIG_MUX_ADG792A=m
CONFIG_MUX_ADGS1408=m
CONFIG_MUX_GPIO=m
CONFIG_MUX_MMIO=m
# end of Multiplexer drivers

CONFIG_PM_OPP=y
CONFIG_SIOX=m
CONFIG_SIOX_BUS_GPIO=m
CONFIG_SLIMBUS=m
CONFIG_SLIM_QCOM_CTRL=m
CONFIG_INTERCONNECT=y
CONFIG_INTERCONNECT_IMX=m
CONFIG_INTERCONNECT_IMX8MM=m
CONFIG_INTERCONNECT_IMX8MN=m
CONFIG_INTERCONNECT_IMX8MQ=m
CONFIG_INTERCONNECT_IMX8MP=m
CONFIG_INTERCONNECT_QCOM_OSM_L3=m
CONFIG_INTERCONNECT_SAMSUNG=y
CONFIG_INTERCONNECT_EXYNOS=m
CONFIG_COUNTER=m
CONFIG_104_QUAD_8=m
CONFIG_INTERRUPT_CNT=m
CONFIG_STM32_TIMER_CNT=m
CONFIG_STM32_LPTIMER_CNT=m
CONFIG_TI_EQEP=m
CONFIG_FTM_QUADDEC=m
CONFIG_MICROCHIP_TCB_CAPTURE=m
CONFIG_TI_ECAP_CAPTURE=m
CONFIG_PECI=m
CONFIG_PECI_CPU=m
CONFIG_PECI_ASPEED=m
CONFIG_HTE=y
# end of Device Drivers

#
# File systems
#
CONFIG_VALIDATE_FS_PARSER=y
CONFIG_FS_IOMAP=y
CONFIG_EXT2_FS=m
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=m
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=m
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_DEBUG=y
CONFIG_EXT4_KUNIT_TESTS=m
CONFIG_JBD2=m
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=m
CONFIG_REISERFS_FS=m
CONFIG_REISERFS_CHECK=y
CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_JFS_DEBUG=y
CONFIG_JFS_STATISTICS=y
CONFIG_XFS_FS=m
CONFIG_XFS_SUPPORT_V4=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_ONLINE_SCRUB=y
CONFIG_XFS_ONLINE_REPAIR=y
CONFIG_XFS_DEBUG=y
CONFIG_XFS_ASSERT_FATAL=y
CONFIG_GFS2_FS=m
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=m
CONFIG_OCFS2_FS_O2CB=m
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
CONFIG_OCFS2_FS_STATS=y
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BTRFS_FS_CHECK_INTEGRITY=y
CONFIG_BTRFS_FS_RUN_SANITY_TESTS=y
CONFIG_BTRFS_DEBUG=y
CONFIG_BTRFS_ASSERT=y
CONFIG_BTRFS_FS_REF_VERIFY=y
CONFIG_NILFS2_FS=m
CONFIG_F2FS_FS=m
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_F2FS_CHECK_FS=y
CONFIG_F2FS_FAULT_INJECTION=y
CONFIG_F2FS_FS_COMPRESSION=y
CONFIG_F2FS_FS_LZO=y
CONFIG_F2FS_FS_LZORLE=y
CONFIG_F2FS_FS_LZ4=y
CONFIG_F2FS_FS_LZ4HC=y
CONFIG_F2FS_FS_ZSTD=y
CONFIG_F2FS_IOSTAT=y
CONFIG_F2FS_UNFAIR_RWSEM=y
CONFIG_ZONEFS_FS=m
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=m
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_DEBUG=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=m
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_QUOTACTL=y
CONFIG_AUTOFS4_FS=m
CONFIG_AUTOFS_FS=m
CONFIG_FUSE_FS=m
CONFIG_CUSE=m
CONFIG_VIRTIO_FS=m
CONFIG_OVERLAY_FS=m
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
CONFIG_OVERLAY_FS_INDEX=y
CONFIG_OVERLAY_FS_METACOPY=y

#
# Caches
#
CONFIG_NETFS_SUPPORT=m
CONFIG_NETFS_STATS=y
CONFIG_FSCACHE=m
CONFIG_FSCACHE_STATS=y
CONFIG_FSCACHE_DEBUG=y
CONFIG_CACHEFILES=m
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_ERROR_INJECTION=y
CONFIG_CACHEFILES_ONDEMAND=y
# end of Caches

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
# end of CD-ROM/DVD Filesystems

#
# DOS/FAT/EXFAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_FAT_KUNIT_TEST=m
CONFIG_EXFAT_FS=m
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
CONFIG_NTFS_FS=m
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y
CONFIG_NTFS3_FS=m
CONFIG_NTFS3_LZX_XPRESS=y
CONFIG_NTFS3_FS_POSIX_ACL=y
# end of DOS/FAT/EXFAT/NT Filesystems

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_VMCORE=y
CONFIG_PROC_VMCORE_DEVICE_DUMP=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_CHILDREN=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
CONFIG_CONFIGFS_FS=m
# end of Pseudo filesystems

CONFIG_MISC_FILESYSTEMS=y
CONFIG_ORANGEFS_FS=m
CONFIG_ADFS_FS=m
CONFIG_ADFS_FS_RW=y
CONFIG_AFFS_FS=m
CONFIG_ECRYPT_FS=m
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BEFS_DEBUG=y
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_JFFS2_FS_WBUF_VERIFY=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_FS_POSIX_ACL=y
CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
CONFIG_UBIFS_ATIME_SUPPORT=y
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_SECURITY=y
CONFIG_UBIFS_FS_AUTHENTICATION=y
CONFIG_CRAMFS=m
CONFIG_CRAMFS_BLOCKDEV=y
CONFIG_CRAMFS_MTD=y
CONFIG_SQUASHFS=m
CONFIG_SQUASHFS_FILE_CACHE=y
# CONFIG_SQUASHFS_FILE_DIRECT is not set
CONFIG_SQUASHFS_DECOMP_SINGLE=y
# CONFIG_SQUASHFS_DECOMP_MULTI is not set
# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
CONFIG_VXFS_FS=m
CONFIG_MINIX_FS=m
CONFIG_MINIX_FS_NATIVE_ENDIAN=y
CONFIG_OMFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_QNX6FS_FS=m
CONFIG_QNX6FS_DEBUG=y
CONFIG_ROMFS_FS=m
CONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not set
CONFIG_ROMFS_ON_BLOCK=y
CONFIG_PSTORE=m
CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
CONFIG_PSTORE_DEFLATE_COMPRESS=m
CONFIG_PSTORE_LZO_COMPRESS=m
CONFIG_PSTORE_LZ4_COMPRESS=m
CONFIG_PSTORE_LZ4HC_COMPRESS=m
CONFIG_PSTORE_842_COMPRESS=y
CONFIG_PSTORE_ZSTD_COMPRESS=y
CONFIG_PSTORE_COMPRESS=y
CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y
# CONFIG_PSTORE_LZO_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_LZ4_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_842_COMPRESS_DEFAULT is not set
# CONFIG_PSTORE_ZSTD_COMPRESS_DEFAULT is not set
CONFIG_PSTORE_COMPRESS_DEFAULT="deflate"
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_FTRACE=y
CONFIG_PSTORE_RAM=m
CONFIG_PSTORE_ZONE=m
CONFIG_PSTORE_BLK=m
CONFIG_PSTORE_BLK_BLKDEV=""
CONFIG_PSTORE_BLK_KMSG_SIZE=64
CONFIG_PSTORE_BLK_MAX_REASON=2
CONFIG_PSTORE_BLK_PMSG_SIZE=64
CONFIG_PSTORE_BLK_CONSOLE_SIZE=64
CONFIG_PSTORE_BLK_FTRACE_SIZE=64
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_UFS_FS_WRITE=y
CONFIG_UFS_DEBUG=y
CONFIG_EROFS_FS=m
CONFIG_EROFS_FS_DEBUG=y
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZMA=y
CONFIG_EROFS_FS_ONDEMAND=y
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V2=m
CONFIG_NFS_V3=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=m
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_PNFS_FILE_LAYOUT=m
CONFIG_PNFS_BLOCK=m
CONFIG_PNFS_FLEXFILE_LAYOUT=m
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
CONFIG_NFS_V4_1_MIGRATION=y
CONFIG_NFS_V4_SECURITY_LABEL=y
CONFIG_NFS_FSCACHE=y
CONFIG_NFS_USE_LEGACY_DNS=y
CONFIG_NFS_DEBUG=y
CONFIG_NFS_DISABLE_UDP_SUPPORT=y
CONFIG_NFS_V4_2_READ_PLUS=y
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_PNFS=y
CONFIG_NFSD_BLOCKLAYOUT=y
CONFIG_NFSD_SCSILAYOUT=y
CONFIG_NFSD_FLEXFILELAYOUT=y
CONFIG_NFSD_V4_2_INTER_SSC=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
CONFIG_GRACE_PERIOD=m
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
CONFIG_NFS_V4_2_SSC_HELPER=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_SUNRPC_BACKCHANNEL=y
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
CONFIG_SUNRPC_DEBUG=y
CONFIG_CEPH_FS=m
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CEPH_FS_SECURITY_LABEL=y
CONFIG_CIFS=m
CONFIG_CIFS_STATS2=y
CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DEBUG=y
CONFIG_CIFS_DEBUG2=y
CONFIG_CIFS_DEBUG_DUMP_KEYS=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SWN_UPCALL=y
CONFIG_CIFS_FSCACHE=y
CONFIG_SMB_SERVER=m
CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y
CONFIG_SMB_SERVER_KERBEROS5=y
CONFIG_SMBFS_COMMON=m
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
CONFIG_AFS_DEBUG=y
CONFIG_AFS_FSCACHE=y
CONFIG_AFS_DEBUG_CURSOR=y
CONFIG_9P_FS=m
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS=m
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_MAC_ROMAN=m
CONFIG_NLS_MAC_CELTIC=m
CONFIG_NLS_MAC_CENTEURO=m
CONFIG_NLS_MAC_CROATIAN=m
CONFIG_NLS_MAC_CYRILLIC=m
CONFIG_NLS_MAC_GAELIC=m
CONFIG_NLS_MAC_GREEK=m
CONFIG_NLS_MAC_ICELAND=m
CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_NLS_UTF8=m
CONFIG_DLM=m
CONFIG_DLM_DEPRECATED_API=y
CONFIG_DLM_DEBUG=y
CONFIG_UNICODE=m
CONFIG_UNICODE_NORMALIZATION_SELFTEST=m
CONFIG_IO_WQ=y
# end of File systems

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_REQUEST_CACHE=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_TRUSTED_KEYS=m
CONFIG_TRUSTED_KEYS_TPM=y
CONFIG_TRUSTED_KEYS_TEE=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_USER_DECRYPTED_DATA=y
CONFIG_KEY_DH_OPERATIONS=y
CONFIG_KEY_NOTIFICATIONS=y
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_SECURITY_WRITABLE_HOOKS=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
CONFIG_LSM_MMAP_MIN_ADDR=65536
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_STATIC_USERMODEHELPER_PATH="/sbin/usermode-helper"
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SMACK_BRINGUP=y
CONFIG_SECURITY_SMACK_NETFILTER=y
CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048
CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024
CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER=y
CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_DEBUG=y
CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS=y
CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES=y
CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y
CONFIG_SECURITY_APPARMOR_HASH=y
CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y
CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y
CONFIG_SECURITY_LOADPIN=y
CONFIG_SECURITY_LOADPIN_ENFORCE=y
CONFIG_SECURITY_YAMA=y
CONFIG_SECURITY_SAFESETID=y
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
CONFIG_SECURITY_LANDLOCK=y
CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y
CONFIG_INTEGRITY_AUDIT=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_LSM_RULES=y
CONFIG_IMA_NG_TEMPLATE=y
# CONFIG_IMA_SIG_TEMPLATE is not set
CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
CONFIG_IMA_DEFAULT_HASH_SHA1=y
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
CONFIG_IMA_DEFAULT_HASH="sha1"
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_READ_POLICY=y
CONFIG_IMA_APPRAISE=y
CONFIG_IMA_ARCH_POLICY=y
CONFIG_IMA_APPRAISE_BUILD_POLICY=y
CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS=y
CONFIG_IMA_APPRAISE_BOOTPARAM=y
CONFIG_IMA_APPRAISE_MODSIG=y
CONFIG_IMA_TRUSTED_KEYRING=y
CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY=y
CONFIG_IMA_BLACKLIST_KEYRING=y
CONFIG_IMA_LOAD_X509=y
CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
CONFIG_IMA_APPRAISE_SIGNED_INIT=y
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
CONFIG_IMA_DISABLE_HTABLE=y
CONFIG_EVM=y
CONFIG_EVM_ATTR_FSUUID=y
CONFIG_EVM_EXTRA_SMACK_XATTRS=y
CONFIG_EVM_ADD_XATTRS=y
CONFIG_EVM_LOAD_X509=y
CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der"
CONFIG_DEFAULT_SECURITY_SELINUX=y
# CONFIG_DEFAULT_SECURITY_SMACK is not set
# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
# CONFIG_DEFAULT_SECURITY_APPARMOR is not set
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"

#
# Kernel hardening options
#

#
# Memory initialization
#
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
# CONFIG_INIT_STACK_NONE is not set
CONFIG_INIT_STACK_ALL_PATTERN=y
# CONFIG_INIT_STACK_ALL_ZERO is not set
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
CONFIG_ZERO_CALL_USED_REGS=y
# end of Memory initialization

CONFIG_RANDSTRUCT_NONE=y
# end of Kernel hardening options
# end of Security options

CONFIG_XOR_BLOCKS=m
CONFIG_ASYNC_CORE=m
CONFIG_ASYNC_MEMCPY=m
CONFIG_ASYNC_XOR=m
CONFIG_ASYNC_PQ=m
CONFIG_ASYNC_RAID6_RECOV=m
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_SKCIPHER=y
CONFIG_CRYPTO_SKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
CONFIG_CRYPTO_KPP=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=m
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_ENGINE=m
# end of Crypto core or helper

#
# Public-key cryptography
#
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_DH=y
CONFIG_CRYPTO_DH_RFC7919_GROUPS=y
CONFIG_CRYPTO_ECC=m
CONFIG_CRYPTO_ECDH=m
CONFIG_CRYPTO_ECDSA=m
CONFIG_CRYPTO_ECRDSA=m
CONFIG_CRYPTO_SM2=m
CONFIG_CRYPTO_CURVE25519=m
# end of Public-key cryptography

#
# Block ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_TI=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARIA=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_BLOWFISH_COMMON=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST_COMMON=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_SM4=m
CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# end of Block ciphers

#
# Length-preserving ciphers and modes
#
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XCTR=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_NHPOLY1305=m
# end of Length-preserving ciphers and modes

#
# AEAD (authenticated encryption with associated data) ciphers
#
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_CHACHA20POLY1305=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_SEQIV=m
CONFIG_CRYPTO_ECHAINIV=m
CONFIG_CRYPTO_ESSIV=m
# end of AEAD (authenticated encryption with associated data) ciphers

#
# Hashes, digests, and MACs
#
CONFIG_CRYPTO_BLAKE2B=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_GHASH=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_POLYVAL=m
CONFIG_CRYPTO_POLY1305=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA3=m
CONFIG_CRYPTO_SM3=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_STREEBOG=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_XXHASH=m
# end of Hashes, digests, and MACs

#
# CRCs (cyclic redundancy checks)
#
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CRC32=m
CONFIG_CRYPTO_CRCT10DIF=m
CONFIG_CRYPTO_CRC64_ROCKSOFT=m
# end of CRCs (cyclic redundancy checks)

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_LZO=m
CONFIG_CRYPTO_842=m
CONFIG_CRYPTO_LZ4=m
CONFIG_CRYPTO_LZ4HC=m
CONFIG_CRYPTO_ZSTD=m
# end of Compression

#
# Random number generation
#
CONFIG_CRYPTO_ANSI_CPRNG=m
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_DRBG_CTR=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_KDF800108_CTR=y
# end of Random number generation

#
# Userspace interface
#
CONFIG_CRYPTO_USER_API=m
CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_RNG_CAVP=y
CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
CONFIG_CRYPTO_STATS=y
# end of Userspace interface

CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_ALLWINNER=y
CONFIG_CRYPTO_DEV_SUN8I_CE=m
CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_HASH=y
CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS=m
CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_HASH=y
CONFIG_CRYPTO_DEV_SL3516=m
CONFIG_CRYPTO_DEV_SL3516_DEBUG=y
CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
CONFIG_CRYPTO_DEV_S5P=m
CONFIG_CRYPTO_DEV_ATMEL_AUTHENC=y
CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
CONFIG_CRYPTO_DEV_ATMEL_I2C=m
CONFIG_CRYPTO_DEV_ATMEL_ECC=m
CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
CONFIG_CRYPTO_DEV_QCE_SHA=y
CONFIG_CRYPTO_DEV_QCE_AEAD=y
CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_IMGTEC_HASH=m
CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=m
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_CRYPTO_DEV_SAFEXCEL=m
CONFIG_CRYPTO_DEV_HISI_SEC=m
CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m
CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y
CONFIG_CRYPTO_DEV_SA2UL=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU_HMAC_SHA224=y
CONFIG_CRYPTO_DEV_ASPEED=m
CONFIG_CRYPTO_DEV_ASPEED_DEBUG=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO=y
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_PKCS7_TEST_KEY=m
CONFIG_SIGNED_PE_FILE_VERIFICATION=y
CONFIG_FIPS_SIGNATURE_SELFTEST=y

#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_EXTRA_CERTIFICATE=y
CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096
CONFIG_SECONDARY_TRUSTED_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
CONFIG_SYSTEM_REVOCATION_LIST=y
CONFIG_SYSTEM_REVOCATION_KEYS=""
CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE=y
# end of Certificates for signature checking

CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_RAID6_PQ=m
CONFIG_RAID6_PQ_BENCHMARK=y
CONFIG_LINEAR_RANGES=y
CONFIG_PACKING=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_CORDIC=m
CONFIG_PRIME_NUMBERS=m
CONFIG_RATIONAL=m
CONFIG_STMP_DEVICE=y

#
# Crypto library routines
#
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_ARC4=m
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m
CONFIG_CRYPTO_LIB_CHACHA=m
CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m
CONFIG_CRYPTO_LIB_CURVE25519=m
CONFIG_CRYPTO_LIB_DES=m
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m
CONFIG_CRYPTO_LIB_POLY1305=m
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
# end of Crypto library routines

CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_T10DIF=m
CONFIG_CRC64_ROCKSOFT=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
CONFIG_CRC32_SELFTEST=m
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
CONFIG_CRC64=m
CONFIG_CRC4=m
CONFIG_CRC7=m
CONFIG_LIBCRC32C=m
CONFIG_CRC8=m
CONFIG_XXHASH=y
CONFIG_AUDIT_GENERIC=y
CONFIG_RANDOM32_SELFTEST=y
CONFIG_842_COMPRESS=m
CONFIG_842_DECOMPRESS=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=m
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4_COMPRESS=m
CONFIG_LZ4HC_COMPRESS=m
CONFIG_LZ4_DECOMPRESS=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=m
CONFIG_ZSTD_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_MICROLZMA=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_TEST=m
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_ZSTD=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=m
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_REED_SOLOMON_ENC16=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_BCH=m
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_BTREE=y
CONFIG_INTERVAL_TREE=y
CONFIG_XARRAY_MULTI=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_HAS_IOMEM=y
CONFIG_NO_DMA=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_DMA_DECLARE_COHERENT=y
CONFIG_DMA_NONCOHERENT_MMAP=y
CONFIG_DMA_API_DEBUG=y
CONFIG_DMA_API_DEBUG_SG=y
CONFIG_DMA_MAP_BENCHMARK=y
CONFIG_SGL_ALLOC=y
CONFIG_DQL=y
CONFIG_GLOB=y
CONFIG_GLOB_SELFTEST=m
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_LRU_CACHE=m
CONFIG_CLZ_TAB=y
CONFIG_IRQ_POLL=y
CONFIG_MPILIB=y
CONFIG_SIGNATURE=y
CONFIG_DIMLIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
CONFIG_FONT_SUPPORT=m
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_FONT_6x11=y
CONFIG_FONT_7x14=y
CONFIG_FONT_PEARL_8x8=y
CONFIG_FONT_ACORN_8x8=y
CONFIG_FONT_MINI_4x6=y
CONFIG_FONT_6x10=y
CONFIG_FONT_10x18=y
CONFIG_FONT_SUN8x16=y
CONFIG_FONT_SUN12x22=y
CONFIG_FONT_TER16x32=y
CONFIG_FONT_6x8=y
CONFIG_SG_SPLIT=y
CONFIG_SG_POOL=y
CONFIG_STACKDEPOT=y
CONFIG_STACKDEPOT_ALWAYS_INIT=y
CONFIG_REF_TRACKER=y
CONFIG_SBITMAP=y
CONFIG_PARMAN=m
CONFIG_OBJAGG=m
# end of Library routines

CONFIG_ASN1_ENCODER=m
CONFIG_POLYNOMIAL=m

#
# Kernel hacking
#

#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
CONFIG_STACKTRACE_BUILD_ID=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DYNAMIC_DEBUG_CORE=y
CONFIG_SYMBOLIC_ERRNAME=y
CONFIG_DEBUG_BUGVERBOSE=y
# end of printk and dmesg options

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y

#
# Compile-time checks and compiler options
#
CONFIG_AS_HAS_NON_CONST_LEB128=y
CONFIG_DEBUG_INFO_NONE=y
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
CONFIG_FRAME_WARN=1024
CONFIG_STRIP_ASM_SYMS=y
CONFIG_READABLE_ASM=y
CONFIG_HEADERS_INSTALL=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_FRAME_POINTER=y
CONFIG_VMLINUX_MAP=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# end of Compile-time checks and compiler options

#
# Generic Kernel Debugging Instruments
#
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_FS_ALLOW_ALL=y
# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_HONOUR_BLOCKLIST=y
CONFIG_KGDB_SERIAL_CONSOLE=m
CONFIG_KGDB_TESTS=y
CONFIG_KGDB_TESTS_ON_BOOT=y
CONFIG_KGDB_TESTS_BOOT_STRING="V1F100"
CONFIG_KGDB_KDB=y
CONFIG_KDB_DEFAULT_ENABLE=0x1
CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
CONFIG_UBSAN=y
CONFIG_CC_HAS_UBSAN_BOUNDS=y
CONFIG_UBSAN_BOUNDS=y
CONFIG_UBSAN_ONLY_BOUNDS=y
CONFIG_UBSAN_SHIFT=y
CONFIG_UBSAN_DIV_ZERO=y
CONFIG_UBSAN_UNREACHABLE=y
CONFIG_UBSAN_BOOL=y
CONFIG_UBSAN_ENUM=y
CONFIG_TEST_UBSAN=m
CONFIG_HAVE_KCSAN_COMPILER=y
# end of Generic Kernel Debugging Instruments

#
# Networking Debugging
#
CONFIG_NET_DEV_REFCNT_TRACKER=y
CONFIG_NET_NS_REFCNT_TRACKER=y
CONFIG_DEBUG_NET=y
# end of Networking Debugging

#
# Memory Debugging
#
CONFIG_PAGE_EXTENSION=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
CONFIG_SLUB_DEBUG=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_POISONING=y
CONFIG_DEBUG_PAGE_REF=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_WORK=y
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SHRINKER_DEBUG=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
CONFIG_DEBUG_KMEMLEAK_TEST=m
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_VM_IRQSOFF=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_MAPLE_TREE=y
CONFIG_DEBUG_VM_RB=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_DEBUG_NOMMU_REGIONS=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# end of Memory Debugging

CONFIG_DEBUG_SHIRQ=y

#
# Debug Oops, Lockups and Hangs
#
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_ON_OOPS_VALUE=1
CONFIG_PANIC_TIMEOUT=0
CONFIG_LOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_WQ_WATCHDOG=y
CONFIG_TEST_LOCKUP=m
# end of Debug Oops, Lockups and Hangs

#
# Scheduler Debugging
#
CONFIG_SCHED_DEBUG=y
CONFIG_SCHED_INFO=y
CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging

CONFIG_DEBUG_TIMEKEEPING=y

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_PROVE_LOCKING=y
CONFIG_PROVE_RAW_LOCK_NESTING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_LOCKDEP=y
CONFIG_LOCKDEP_BITS=15
CONFIG_LOCKDEP_CHAINS_BITS=16
CONFIG_LOCKDEP_STACK_TRACE_BITS=19
CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_LOCK_TORTURE_TEST=m
CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_SCF_TORTURE_TEST=m
# end of Lock Debugging (spinlocks, mutexes, etc...)

CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_IRQFLAGS=y
CONFIG_STACKTRACE=y
CONFIG_WARN_ALL_UNSEEDED_RANDOM=y
CONFIG_DEBUG_KOBJECT=y
CONFIG_DEBUG_KOBJECT_RELEASE=y
CONFIG_HAVE_DEBUG_BUGVERBOSE=y

#
# Debug kernel data structures
#
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_DEBUG_MAPLE_TREE=y
# end of Debug kernel data structures

CONFIG_DEBUG_CREDENTIALS=y

#
# RCU Debugging
#
CONFIG_PROVE_RCU=y
CONFIG_PROVE_RCU_LIST=y
CONFIG_TORTURE_TEST=m
CONFIG_RCU_SCALE_TEST=m
CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_REF_SCALE_TEST=m
CONFIG_RCU_TRACE=y
CONFIG_RCU_EQS_DEBUG=y
# end of RCU Debugging

CONFIG_DEBUG_WQ_FORCE_RR_CPU=y
CONFIG_LATENCYTOP=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_PREEMPTIRQ_TRACEPOINTS=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_BOOTTIME_TRACING=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_STACK_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_HWLAT_TRACER=y
CONFIG_OSNOISE_TRACER=y
CONFIG_TIMERLAT_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KPROBE_EVENTS=y
CONFIG_KPROBE_EVENTS_ON_NOTRACE=y
CONFIG_BPF_EVENTS=y
CONFIG_DYNAMIC_EVENTS=y
CONFIG_PROBE_EVENTS=y
CONFIG_FTRACE_MCOUNT_RECORD=y
CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT=y
CONFIG_SYNTH_EVENTS=y
CONFIG_USER_EVENTS=y
CONFIG_TRACE_EVENT_INJECT=y
CONFIG_TRACEPOINT_BENCHMARK=y
CONFIG_RING_BUFFER_BENCHMARK=m
CONFIG_TRACE_EVAL_MAP_FILE=y
CONFIG_FTRACE_RECORD_RECURSION=y
CONFIG_FTRACE_RECORD_RECURSION_SIZE=128
CONFIG_RING_BUFFER_RECORD_RECURSION=y
CONFIG_GCOV_PROFILE_FTRACE=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_TEST_SYSCALLS=y
CONFIG_RING_BUFFER_STARTUP_TEST=y
CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS=y
CONFIG_PREEMPTIRQ_DELAY_TEST=m
CONFIG_SYNTH_EVENT_GEN_TEST=m
CONFIG_KPROBE_EVENT_GEN_TEST=m
CONFIG_DA_MON_EVENTS=y
CONFIG_DA_MON_EVENTS_ID=y
CONFIG_RV=y
CONFIG_RV_MON_WWNR=y
CONFIG_RV_REACTORS=y
CONFIG_RV_REACT_PRINTK=y
CONFIG_RV_REACT_PANIC=y
# CONFIG_SAMPLES is not set
# CONFIG_STRICT_DEVMEM is not set

#
# sh Debugging
#
CONFIG_SH_STANDARD_BIOS=y
CONFIG_STACK_DEBUG=y
CONFIG_DUMP_CODE=y
CONFIG_DWARF_UNWINDER=y
CONFIG_SH_NO_BSS_INIT=y
CONFIG_MCOUNT=y
# end of sh Debugging

#
# Kernel Testing and Coverage
#
CONFIG_KUNIT=m
CONFIG_KUNIT_DEBUGFS=y
CONFIG_KUNIT_TEST=m
CONFIG_KUNIT_EXAMPLE_TEST=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_KUNIT_DEFAULT_ENABLED=y
CONFIG_NOTIFIER_ERROR_INJECTION=m
CONFIG_PM_NOTIFIER_ERROR_INJECT=m
CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT=m
CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_USERCOPY=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAIL_MMC_REQUEST=y
CONFIG_FAIL_SUNRPC=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
CONFIG_RUNTIME_TESTING_MENU=y
CONFIG_LKDTM=m
CONFIG_CPUMASK_KUNIT_TEST=m
CONFIG_TEST_LIST_SORT=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_SORT=m
CONFIG_TEST_DIV64=m
CONFIG_KPROBES_SANITY_TEST=m
CONFIG_BACKTRACE_SELF_TEST=m
CONFIG_TEST_REF_TRACKER=m
CONFIG_RBTREE_TEST=m
CONFIG_REED_SOLOMON_TEST=m
CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_STRING_SELFTEST=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_STRSCPY=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_PRINTF=m
CONFIG_TEST_SCANF=m
CONFIG_TEST_BITMAP=m
CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_PARMAN=m
CONFIG_TEST_LKM=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_USER_COPY=m
CONFIG_TEST_BPF=m
CONFIG_TEST_BLACKHOLE_DEV=m
CONFIG_FIND_BIT_BENCHMARK=m
CONFIG_TEST_FIRMWARE=m
CONFIG_TEST_SYSCTL=m
CONFIG_BITFIELD_KUNIT=m
CONFIG_HASH_KUNIT_TEST=m
CONFIG_RESOURCE_KUNIT_TEST=m
CONFIG_SYSCTL_KUNIT_TEST=m
CONFIG_LIST_KUNIT_TEST=m
CONFIG_LINEAR_RANGES_TEST=m
CONFIG_CMDLINE_KUNIT_TEST=m
CONFIG_BITS_TEST=m
CONFIG_SLUB_KUNIT_TEST=m
CONFIG_RATIONAL_KUNIT_TEST=m
CONFIG_MEMCPY_KUNIT_TEST=m
CONFIG_IS_SIGNED_TYPE_KUNIT_TEST=m
CONFIG_OVERFLOW_KUNIT_TEST=m
CONFIG_STACKINIT_KUNIT_TEST=m
CONFIG_TEST_UDELAY=m
CONFIG_TEST_STATIC_KEYS=m
CONFIG_TEST_DYNAMIC_DEBUG=m
CONFIG_TEST_KMOD=m
CONFIG_TEST_MEMCAT_P=m
CONFIG_TEST_OBJAGG=m
CONFIG_TEST_MEMINIT=m
CONFIG_TEST_FREE_PAGES=m
# end of Kernel Testing and Coverage

#
# Rust hacking
#
# end of Rust hacking

CONFIG_WARN_MISSING_DOCUMENTS=y
CONFIG_WARN_ABI_ERRORS=y
# end of Kernel hacking

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

* Re: [PATCH v1 1/5] DT bindings for imx492
  2022-11-25 15:31 ` [PATCH v1 1/5] DT bindings for imx492 Petko Manolov
@ 2022-11-28  4:37   ` Laurent Pinchart
  2022-11-28 13:07     ` Petko Manolov
  0 siblings, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28  4:37 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, sakari.ailus

Hi Petko,

Thank you for the patch.

The subject line should start with the proper prefix. Look at the git
log in the directory to see what is customary. Furthermore,
s/imx492/Sony IMX492/.

On Fri, Nov 25, 2022 at 05:31:16PM +0200, Petko Manolov wrote:
> Here goes the DT bindings file.

This is also a peculiar commit message :-)

> Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> ---
>  .../bindings/media/i2c/sony,imx492.yaml       | 101 ++++++++++++++++++
>  1 file changed, 101 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> new file mode 100644
> index 000000000000..f4feef17c677
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> @@ -0,0 +1,101 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/sony,imx492.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sony imx492 Sensor

s/imx492/IMX492/. Same below. When referring to the hardware, it's
customary to use uppercase.

> +
> +maintainers:
> +  - Petko Manolov <petko.manolov@konsulko.com>
> +
> +description:
> +
> +  imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> +  monochrome square pixel array and approximately 47.08 M effective pixels.
> +  12-bit digital output makes it possible to output the signals with high
> +  definition for moving pictures. It is programmable through I2C interface. The
> +  I2C client address can be either 0x10 or 0x1a depending on SLASEL pin. Image
> +  data is sent through MIPI CSI-2.
> +
> +properties:
> +  compatible:
> +    const: sony,imx492

Missing blank line.

> +  reg:
> +    description: I2C address

You can drop the description.

> +    maxItems: 1
> +
> +  assigned-clocks: true
> +  assigned-clock-parents: true
> +  assigned-clock-rates: true

This shouldn't be needed.

> +
> +  clocks:
> +    description: Clock frequency 6MHz, 12MHz, 18MHz and 24MHz

If you know the name of the clock pin, I would include it here.

> +    maxItems: 1
> +
> +  dovdd-supply:
> +    description: Interface power supply.

I would list the voltage. Same below.

> +
> +  avdd-supply:
> +    description: Analog power supply.
> +
> +  dvdd-supply:
> +    description: Digital power supply.
> +
> +  reset-gpios:
> +    description: Reference to the GPIO connected to the XCLR pin, if any.
> +    maxItems: 1
> +
> +  port:
> +    additionalProperties: false
> +    $ref: /schemas/graph.yaml#/$defs/port-base
> +
> +    properties:
> +      endpoint:
> +        $ref: /schemas/media/video-interfaces.yaml#
> +        unevaluatedProperties: false
> +
> +        properties:
> +          data-lanes: true
> +          link-frequencies: true
> +
> +        required:
> +          - data-lanes
> +          - link-frequencies
> +
> +    required:
> +      - endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - port
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    i2c0 {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        camera@10 {
> +            compatible = "sony,imx492";
> +            reg = <0x10>;
> +            clocks = <&imx492_clk>;
> +
> +            assigned-clocks = <&imx492_clk>;
> +            assigned-clock-parents = <&imx492_clk_parent>;
> +            assigned-clock-rates = <24000000>;

You can drop this from the example, it doesn't showcase the DT bindings
for the IMX492.

> +
> +            port {
> +                imx492: endpoint {

s/imx492/imx492_out/

> +                    remote-endpoint = <&cam>;

s/cam/cam_in/

> +                    data-lanes = <1 2 3 4>;
> +                    link-frequencies = /bits/ 64 <600000000>;
> +                };
> +            };
> +        };
> +    };
> +...

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-25 15:31 ` [PATCH v1 2/5] media: i2c: imx492: driver's header Petko Manolov
@ 2022-11-28  4:40   ` Laurent Pinchart
  2022-11-28 13:12     ` Petko Manolov
  2022-11-28 12:47   ` Kieran Bingham
  1 sibling, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28  4:40 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, sakari.ailus

Hi Petko,

Thank you for the patch.

On Fri, Nov 25, 2022 at 05:31:17PM +0200, Petko Manolov wrote:
> The header.  For the moment only two modes are supported.

No need to split this in a separate patch, you can squash patches 2/5 to
5/5 together for v2.

> Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> ---
>  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 555 insertions(+)
>  create mode 100644 drivers/media/i2c/imx492.h
> 
> diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> new file mode 100644
> index 000000000000..301fd66c77d5
> --- /dev/null
> +++ b/drivers/media/i2c/imx492.h
> @@ -0,0 +1,555 @@

Missing SPDX license header. Please run checkpath.pl on the whole
series.

> +#ifndef	__imx492_h__
> +#define	__imx492_h__

checkpatch.pl will also complain about this.

> +
> +struct imx492_reg {
> +	u16 address;
> +	u8 val;
> +};
> +
> +static const struct imx492_reg mode_17to9_regs[] = {
> +	{ 0x3033, 0x30 },
> +	{ 0x303c, 0x01 },
> +	{ 0x31e8, 0xa0 },
> +	{ 0x31f4, 0x01 },
> +	{ 0x31e9, 0x00 },
> +	{ 0x3122, 0x02 },
> +	{ 0x3129, 0x90 },
> +	{ 0x312a, 0x02 },
> +	{ 0x311f, 0x00 },
> +	{ 0x3123, 0x00 },
> +	{ 0x3124, 0x00 },
> +	{ 0x3125, 0x01 },
> +	{ 0x3127, 0x02 },
> +	{ 0x312d, 0x02 },
> +	{ 0x3000, 0x12 },
> +	{ 0x310b, 0x00 },
> +	{ 0x3004, 0x1c },
> +	{ 0x3005, 0x06 },
> +	{ 0x3006, 0x00 },
> +	{ 0x3007, 0xa7 },
> +	{ 0x3047, 0x02 },
> +	{ 0x304e, 0x0b },
> +	{ 0x304f, 0x2a },
> +	{ 0x3052, 0xee },
> +	{ 0x3062, 0x25 },
> +	{ 0x3064, 0x78 },
> +	{ 0x3065, 0x33 },
> +	{ 0x3066, 0x64 },
> +	{ 0x3067, 0x71 },
> +	{ 0x307e, 0x07 },
> +	{ 0x3081, 0x00 },
> +	{ 0x3088, 0x75 },
> +	{ 0x308a, 0x09 },
> +	{ 0x308c, 0x61 },
> +	{ 0x30ef, 0x01 },
> +	{ 0x3146, 0x00 },
> +	{ 0x31f5, 0x01 },
> +	{ 0x3234, 0x32 },
> +	{ 0x3248, 0xbc },
> +	{ 0x3250, 0xbc },
> +	{ 0x3258, 0xbc },
> +	{ 0x3260, 0xbc },
> +	{ 0x3274, 0x13 },
> +	{ 0x3276, 0x00 },
> +	{ 0x3277, 0x00 },
> +	{ 0x327c, 0x13 },
> +	{ 0x327e, 0x00 },
> +	{ 0x327f, 0x00 },
> +	{ 0x3284, 0x13 },
> +	{ 0x3286, 0x00 },
> +	{ 0x3287, 0x00 },
> +	{ 0x328c, 0x13 },
> +	{ 0x328e, 0x00 },
> +	{ 0x328f, 0x00 },
> +	{ 0x32ae, 0x00 },
> +	{ 0x32af, 0x00 },
> +	{ 0x32ca, 0x5a },
> +	{ 0x332c, 0x00 },
> +	{ 0x332f, 0x00 },
> +	{ 0x334a, 0x00 },
> +	{ 0x334c, 0x01 },
> +	{ 0x3352, 0x50 },
> +	{ 0x3356, 0x4f },
> +	{ 0x335a, 0x79 },
> +	{ 0x335e, 0x56 },
> +	{ 0x3360, 0x6a },
> +	{ 0x336a, 0x56 },
> +	{ 0x33d6, 0x79 },
> +	{ 0x340c, 0x6e },
> +	{ 0x3448, 0x7e },
> +	{ 0x348e, 0x6f },
> +	{ 0x3492, 0x11 },
> +	{ 0x34c4, 0x5a },
> +	{ 0x3506, 0x56 },
> +	{ 0x350c, 0x56 },
> +	{ 0x350e, 0x58 },
> +	{ 0x353d, 0x10 },
> +	{ 0x3549, 0x04 },
> +	{ 0x355d, 0x03 },
> +	{ 0x355e, 0x03 },
> +	{ 0x3574, 0x56 },
> +	{ 0x357f, 0x0c },
> +	{ 0x3580, 0x0a },
> +	{ 0x3581, 0x08 },
> +	{ 0x3583, 0x72 },
> +	{ 0x3587, 0x01 },
> +	{ 0x35b6, 0x00 },
> +	{ 0x35b8, 0x00 },
> +	{ 0x35d0, 0x5e },
> +	{ 0x35d4, 0x63 },
> +	{ 0x366a, 0x04 },
> +	{ 0x366b, 0x04 },
> +	{ 0x366c, 0x00 },
> +	{ 0x366d, 0x00 },
> +	{ 0x366e, 0x00 },
> +	{ 0x366f, 0x00 },
> +	{ 0x3670, 0x00 },
> +	{ 0x3671, 0x05 },
> +	{ 0x3676, 0x83 },
> +	{ 0x3677, 0x03 },
> +	{ 0x3678, 0x00 },
> +	{ 0x3679, 0x04 },
> +	{ 0x367a, 0x2c },
> +	{ 0x367b, 0x05 },
> +	{ 0x367d, 0x06 },
> +	{ 0x367e, 0xff },
> +	{ 0x367f, 0x06 },
> +	{ 0x3680, 0x4b },
> +	{ 0x3688, 0x05 },
> +	{ 0x3690, 0x27 },
> +	{ 0x3692, 0x65 },
> +	{ 0x3694, 0x4f },
> +	{ 0x3696, 0xa1 },
> +	{ 0x36bc, 0x00 },
> +	{ 0x371c, 0x02 },
> +	{ 0x372f, 0x3c },
> +	{ 0x3730, 0x01 },
> +	{ 0x3732, 0xb8 },
> +	{ 0x3734, 0x4a },
> +	{ 0x3736, 0x57 },
> +	{ 0x3738, 0x4d },
> +	{ 0x3744, 0x0f },
> +	{ 0x375b, 0x01 },
> +	{ 0x382b, 0x68 },
> +	{ 0x38b3, 0x00 },
> +	{ 0x3910, 0x90 },
> +	{ 0x3911, 0x70 },
> +	{ 0x3912, 0x92 },
> +	{ 0x3913, 0x24 },
> +	{ 0x3914, 0x93 },
> +	{ 0x3915, 0x0b },
> +	{ 0x3916, 0x01 },
> +	{ 0x3918, 0x04 },
> +	{ 0x391c, 0x90 },
> +	{ 0x391d, 0x05 },
> +	{ 0x3920, 0x96 },
> +	{ 0x3921, 0x06 },
> +	{ 0x3a2a, 0x01 },
> +	{ 0x3a7a, 0x01 },
> +	{ 0x3a7b, 0x01 },
> +	{ 0x3acb, 0x06 },
> +	{ 0x3c08, 0x3f },
> +	{ 0x3c0c, 0x1b },
> +	{ 0x3e80, 0x14 },
> +	{ 0x3e82, 0x30 },
> +	{ 0x3e84, 0x0c },
> +	{ 0x3e85, 0x06 },
> +	{ 0x3e86, 0xfc },
> +	{ 0x3e87, 0x10 },
> +	{ 0x3e88, 0x03 },
> +	{ 0x3e89, 0xfe },
> +	{ 0x3e8a, 0x01 },
> +	{ 0x3e8b, 0x06 },
> +	{ 0x3e8e, 0x03 },
> +	{ 0x3e8f, 0xfe },
> +	{ 0x3e90, 0x01 },
> +	{ 0x3e91, 0x06 },
> +	{ 0x3e94, 0x33 },
> +	{ 0x3e95, 0x01 },
> +	{ 0x3e96, 0x19 },
> +	{ 0x3e98, 0x30 },
> +	{ 0x3e9a, 0x11 },
> +	{ 0x3e9b, 0x06 },
> +	{ 0x3e9c, 0xfc },
> +	{ 0x3e9d, 0x10 },
> +	{ 0x3e9e, 0xfe },
> +	{ 0x3e9f, 0x03 },
> +	{ 0x3ea0, 0x06 },
> +	{ 0x3ea3, 0x01 },
> +	{ 0x3ea4, 0xfe },
> +	{ 0x3ea5, 0x03 },
> +	{ 0x3ea6, 0x06 },
> +	{ 0x3ea9, 0x33 },
> +	{ 0x3eaa, 0x00 },
> +	{ 0x3eab, 0x08 },
> +	{ 0x3eac, 0x08 },
> +	{ 0x3ead, 0x01 },
> +	{ 0x3eae, 0x08 },
> +	{ 0x3eaf, 0x08 },
> +	{ 0x3eb0, 0x00 },
> +	{ 0x3eb1, 0x10 },
> +	{ 0x3eb2, 0x10 },
> +	{ 0x3eb3, 0x01 },
> +	{ 0x3eb4, 0x10 },
> +	{ 0x3eb5, 0x10 },
> +	{ 0x3eb6, 0x00 },
> +	{ 0x3eb7, 0x00 },
> +	{ 0x3eb8, 0x00 },
> +	{ 0x3eb9, 0x00 },
> +	{ 0x3eba, 0x00 },
> +	{ 0x3ebb, 0x00 },
> +	{ 0x3ec0, 0x54 },
> +	{ 0x3ecc, 0x04 },
> +	{ 0x3ecd, 0x04 },
> +	{ 0x3ed0, 0xf0 },
> +	{ 0x3ed1, 0x20 },
> +	{ 0x3ed2, 0x0b },
> +	{ 0x3ed3, 0x04 },
> +	{ 0x3ed5, 0x13 },
> +	{ 0x3ed6, 0x00 },
> +	{ 0x3ed9, 0x0f },
> +	{ 0x3ee4, 0x02 },
> +	{ 0x3ee5, 0x02 },
> +	{ 0x3ee7, 0x00 },
> +	{ 0x3ef6, 0x00 },
> +	{ 0x3ef8, 0x10 },
> +	{ 0x3efa, 0x00 },
> +	{ 0x3efc, 0x10 },
> +	{ 0x3134, 0xa7 },
> +	{ 0x3135, 0x00 },
> +	{ 0x3136, 0x9f },
> +	{ 0x3137, 0x00 },
> +	{ 0x3138, 0x6f },
> +	{ 0x3139, 0x00 },
> +	{ 0x313a, 0x5f },
> +	{ 0x313b, 0x00 },
> +	{ 0x313c, 0x5f },
> +	{ 0x313d, 0x00 },
> +	{ 0x313e, 0x7f },
> +	{ 0x313f, 0x01 },
> +	{ 0x3140, 0x6f },
> +	{ 0x3141, 0x00 },
> +	{ 0x3142, 0x4f },
> +	{ 0x3143, 0x00 },
> +	{ 0x300e, 0x00 },
> +	{ 0x300f, 0x00 },
> +	{ 0x302c, 0x0c },
> +	{ 0x302d, 0x00 },
> +	{ 0x3034, 0x01 },
> +	{ 0x3035, 0x01 },
> +	{ 0x3036, 0x64 },
> +	{ 0x3037, 0x00 },
> +	{ 0x3038, 0xc8 },
> +	{ 0x3039, 0x00 },
> +	{ 0x3084, 0x4e },
> +	{ 0x3085, 0x04 },
> +	{ 0x3086, 0x4e },
> +	{ 0x3087, 0x04 },
> +	{ 0x30a9, 0xe0 },
> +	{ 0x30aa, 0x2e },
> +	{ 0x30ab, 0x00 },
> +	{ 0x30ac, 0x48 },
> +	{ 0x30ad, 0x0d },
> +	{ 0x30e2, 0x00 },
> +	{ 0x312f, 0x20 },
> +	{ 0x3130, 0x1c },
> +	{ 0x3131, 0x11 },
> +	{ 0x3132, 0xfc },
> +	{ 0x3133, 0x10 },
> +	{ 0x3a54, 0xf0 },
> +	{ 0x3a55, 0x20 },
> +	{ 0x3a43, 0x01 },
> +	{ 0x3a3b, 0x00 },
> +	{ 0x3042, 0x32 },
> +	{ 0x3092, 0x00 },
> +	{ 0x30dd, 0x00 },
> +	{ 0x30de, 0x00 },
> +	{ 0x30df, 0x00 },
> +	{ 0x30e0, 0x00 },
> +	{ 0x30e1, 0x00 },
> +	{ 0x332c, 0x00 },
> +	{ 0x332d, 0x00 },
> +	{ 0x334a, 0x00 },
> +	{ 0x334b, 0x00 },
> +	{ 0x35b6, 0x00 },
> +	{ 0x35b7, 0x00 },
> +	{ 0x35b8, 0x00 },
> +	{ 0x35b9, 0x00 },
> +	{ 0x36bc, 0x00 },
> +	{ 0x36bd, 0x00 },
> +};
> +
> +static const struct imx492_reg mode_all_regs[] = {
> +	{ 0x3033, 0x30 },
> +	{ 0x303c, 0x01 },
> +	{ 0x31e8, 0xa0 },
> +	{ 0x31f4, 0x01 },
> +	{ 0x31e9, 0x00 },
> +	{ 0x3122, 0x02 },
> +	{ 0x3129, 0x90 },
> +	{ 0x312a, 0x02 },
> +	{ 0x311f, 0x00 },
> +	{ 0x3123, 0x00 },
> +	{ 0x3124, 0x00 },
> +	{ 0x3125, 0x01 },
> +	{ 0x3127, 0x02 },
> +	{ 0x312d, 0x02 },
> +	{ 0x3000, 0x12 },
> +	{ 0x310b, 0x00 },
> +	{ 0x3004, 0x1c },
> +	{ 0x3005, 0x06 },
> +	{ 0x3006, 0x00 },
> +	{ 0x3007, 0xa7 },
> +	{ 0x3047, 0x02 },
> +	{ 0x304e, 0x0b },
> +	{ 0x304f, 0x2a },
> +	{ 0x3052, 0xee },
> +	{ 0x3062, 0x25 },
> +	{ 0x3064, 0x78 },
> +	{ 0x3065, 0x33 },
> +	{ 0x3066, 0x64 },
> +	{ 0x3067, 0x71 },
> +	{ 0x307e, 0x07 },
> +	{ 0x3081, 0x00 },
> +	{ 0x3088, 0x75 },
> +	{ 0x308a, 0x09 },
> +	{ 0x308c, 0x61 },
> +	{ 0x30ef, 0x01 },
> +	{ 0x3146, 0x00 },
> +	{ 0x31f5, 0x01 },
> +	{ 0x3234, 0x32 },
> +	{ 0x3248, 0xbc },
> +	{ 0x3250, 0xbc },
> +	{ 0x3258, 0xbc },
> +	{ 0x3260, 0xbc },
> +	{ 0x3274, 0x13 },
> +	{ 0x3276, 0x00 },
> +	{ 0x3277, 0x00 },
> +	{ 0x327c, 0x13 },
> +	{ 0x327e, 0x00 },
> +	{ 0x327f, 0x00 },
> +	{ 0x3284, 0x13 },
> +	{ 0x3286, 0x00 },
> +	{ 0x3287, 0x00 },
> +	{ 0x328c, 0x13 },
> +	{ 0x328e, 0x00 },
> +	{ 0x328f, 0x00 },
> +	{ 0x32ae, 0x00 },
> +	{ 0x32af, 0x00 },
> +	{ 0x32ca, 0x5a },
> +	{ 0x332c, 0x00 },
> +	{ 0x332f, 0x00 },
> +	{ 0x334a, 0x00 },
> +	{ 0x334c, 0x01 },
> +	{ 0x3352, 0x50 },
> +	{ 0x3356, 0x4f },
> +	{ 0x335a, 0x79 },
> +	{ 0x335e, 0x56 },
> +	{ 0x3360, 0x6a },
> +	{ 0x336a, 0x56 },
> +	{ 0x33d6, 0x79 },
> +	{ 0x340c, 0x6e },
> +	{ 0x3448, 0x7e },
> +	{ 0x348e, 0x6f },
> +	{ 0x3492, 0x11 },
> +	{ 0x34c4, 0x5a },
> +	{ 0x3506, 0x56 },
> +	{ 0x350c, 0x56 },
> +	{ 0x350e, 0x58 },
> +	{ 0x353d, 0x10 },
> +	{ 0x3549, 0x04 },
> +	{ 0x355d, 0x03 },
> +	{ 0x355e, 0x03 },
> +	{ 0x3574, 0x56 },
> +	{ 0x357f, 0x0c },
> +	{ 0x3580, 0x0a },
> +	{ 0x3581, 0x08 },
> +	{ 0x3583, 0x72 },
> +	{ 0x3587, 0x01 },
> +	{ 0x35b6, 0x00 },
> +	{ 0x35b8, 0x00 },
> +	{ 0x35d0, 0x5e },
> +	{ 0x35d4, 0x63 },
> +	{ 0x366a, 0x04 },
> +	{ 0x366b, 0x04 },
> +	{ 0x366c, 0x00 },
> +	{ 0x366d, 0x00 },
> +	{ 0x366e, 0x00 },
> +	{ 0x366f, 0x00 },
> +	{ 0x3670, 0x00 },
> +	{ 0x3671, 0x05 },
> +	{ 0x3676, 0x83 },
> +	{ 0x3677, 0x03 },
> +	{ 0x3678, 0x00 },
> +	{ 0x3679, 0x04 },
> +	{ 0x367a, 0x2c },
> +	{ 0x367b, 0x05 },
> +	{ 0x367d, 0x06 },
> +	{ 0x367e, 0xff },
> +	{ 0x367f, 0x06 },
> +	{ 0x3680, 0x4b },
> +	{ 0x3688, 0x05 },
> +	{ 0x3690, 0x27 },
> +	{ 0x3692, 0x65 },
> +	{ 0x3694, 0x4f },
> +	{ 0x3696, 0xa1 },
> +	{ 0x36bc, 0x00 },
> +	{ 0x371c, 0x02 },
> +	{ 0x372f, 0x3c },
> +	{ 0x3730, 0x01 },
> +	{ 0x3732, 0xb8 },
> +	{ 0x3734, 0x4a },
> +	{ 0x3736, 0x57 },
> +	{ 0x3738, 0x4d },
> +	{ 0x3744, 0x0f },
> +	{ 0x375b, 0x01 },
> +	{ 0x382b, 0x68 },
> +	{ 0x38b3, 0x00 },
> +	{ 0x3910, 0x90 },
> +	{ 0x3911, 0x70 },
> +	{ 0x3912, 0x92 },
> +	{ 0x3913, 0x24 },
> +	{ 0x3914, 0x93 },
> +	{ 0x3915, 0x0b },
> +	{ 0x3916, 0x01 },
> +	{ 0x3918, 0x04 },
> +	{ 0x391c, 0x90 },
> +	{ 0x391d, 0x05 },
> +	{ 0x3920, 0x96 },
> +	{ 0x3921, 0x06 },
> +	{ 0x3a2a, 0x01 },
> +	{ 0x3a7a, 0x01 },
> +	{ 0x3a7b, 0x01 },
> +	{ 0x3acb, 0x06 },
> +	{ 0x3c08, 0x3f },
> +	{ 0x3c0c, 0x1b },
> +	{ 0x3e80, 0x14 },
> +	{ 0x3e82, 0x30 },
> +	{ 0x3e84, 0x0c },
> +	{ 0x3e85, 0x06 },
> +	{ 0x3e86, 0xfc },
> +	{ 0x3e87, 0x10 },
> +	{ 0x3e88, 0x03 },
> +	{ 0x3e89, 0xfe },
> +	{ 0x3e8a, 0x01 },
> +	{ 0x3e8b, 0x06 },
> +	{ 0x3e8e, 0x03 },
> +	{ 0x3e8f, 0xfe },
> +	{ 0x3e90, 0x01 },
> +	{ 0x3e91, 0x06 },
> +	{ 0x3e94, 0x33 },
> +	{ 0x3e95, 0x01 },
> +	{ 0x3e96, 0x19 },
> +	{ 0x3e98, 0x30 },
> +	{ 0x3e9a, 0x11 },
> +	{ 0x3e9b, 0x06 },
> +	{ 0x3e9c, 0xfc },
> +	{ 0x3e9d, 0x10 },
> +	{ 0x3e9e, 0xfe },
> +	{ 0x3e9f, 0x03 },
> +	{ 0x3ea0, 0x06 },
> +	{ 0x3ea3, 0x01 },
> +	{ 0x3ea4, 0xfe },
> +	{ 0x3ea5, 0x03 },
> +	{ 0x3ea6, 0x06 },
> +	{ 0x3ea9, 0x33 },
> +	{ 0x3eaa, 0x00 },
> +	{ 0x3eab, 0x08 },
> +	{ 0x3eac, 0x08 },
> +	{ 0x3ead, 0x01 },
> +	{ 0x3eae, 0x08 },
> +	{ 0x3eaf, 0x08 },
> +	{ 0x3eb0, 0x00 },
> +	{ 0x3eb1, 0x10 },
> +	{ 0x3eb2, 0x10 },
> +	{ 0x3eb3, 0x01 },
> +	{ 0x3eb4, 0x10 },
> +	{ 0x3eb5, 0x10 },
> +	{ 0x3eb6, 0x00 },
> +	{ 0x3eb7, 0x00 },
> +	{ 0x3eb8, 0x00 },
> +	{ 0x3eb9, 0x00 },
> +	{ 0x3eba, 0x00 },
> +	{ 0x3ebb, 0x00 },
> +	{ 0x3ec0, 0x54 },
> +	{ 0x3ecc, 0x04 },
> +	{ 0x3ecd, 0x04 },
> +	{ 0x3ed0, 0xf0 },
> +	{ 0x3ed1, 0x20 },
> +	{ 0x3ed2, 0x0b },
> +	{ 0x3ed3, 0x04 },
> +	{ 0x3ed5, 0x13 },
> +	{ 0x3ed6, 0x00 },
> +	{ 0x3ed9, 0x0f },
> +	{ 0x3ee4, 0x02 },
> +	{ 0x3ee5, 0x02 },
> +	{ 0x3ee7, 0x00 },
> +	{ 0x3ef6, 0x00 },
> +	{ 0x3ef8, 0x10 },
> +	{ 0x3efa, 0x00 },
> +	{ 0x3efc, 0x10 },
> +	{ 0x3134, 0xa7 },
> +	{ 0x3135, 0x00 },
> +	{ 0x3136, 0x9f },
> +	{ 0x3137, 0x00 },
> +	{ 0x3138, 0x6f },
> +	{ 0x3139, 0x00 },
> +	{ 0x313a, 0x5f },
> +	{ 0x313b, 0x00 },
> +	{ 0x313c, 0x5f },
> +	{ 0x313d, 0x00 },
> +	{ 0x313e, 0x7f },
> +	{ 0x313f, 0x01 },
> +	{ 0x3140, 0x6f },
> +	{ 0x3141, 0x00 },
> +	{ 0x3142, 0x4f },
> +	{ 0x3143, 0x00 },
> +	{ 0x300e, 0x00 },
> +	{ 0x300f, 0x00 },
> +	{ 0x302c, 0x0c },
> +	{ 0x302d, 0x00 },
> +	{ 0x3034, 0x01 },
> +	{ 0x3035, 0x01 },
> +	{ 0x3036, 0x64 },
> +	{ 0x3037, 0x00 },
> +	{ 0x3038, 0xc8 },
> +	{ 0x3039, 0x00 },
> +	{ 0x3084, 0x4e },
> +	{ 0x3085, 0x04 },
> +	{ 0x3086, 0x4e },
> +	{ 0x3087, 0x04 },
> +	{ 0x30a9, 0xe0 },
> +	{ 0x30aa, 0x2e },
> +	{ 0x30ab, 0x00 },
> +	{ 0x30ac, 0x48 },
> +	{ 0x30ad, 0x0d },
> +	{ 0x30e2, 0x00 },
> +	{ 0x312f, 0x20 },
> +	{ 0x3130, 0x1c },
> +	{ 0x3131, 0x11 },
> +	{ 0x3132, 0xfc },
> +	{ 0x3133, 0x10 },
> +	{ 0x3a54, 0xf0 },
> +	{ 0x3a55, 0x20 },
> +	{ 0x3a43, 0x01 },
> +	{ 0x3a3b, 0x00 },
> +	{ 0x3042, 0x32 },
> +	{ 0x3092, 0x00 },
> +	{ 0x30dd, 0x00 },
> +	{ 0x30de, 0x00 },
> +	{ 0x30df, 0x00 },
> +	{ 0x30e0, 0x00 },
> +	{ 0x30e1, 0x00 },
> +	{ 0x332c, 0x00 },
> +	{ 0x332d, 0x00 },
> +	{ 0x334a, 0x00 },
> +	{ 0x334b, 0x00 },
> +	{ 0x35b6, 0x00 },
> +	{ 0x35b7, 0x00 },
> +	{ 0x35b8, 0x00 },
> +	{ 0x35b9, 0x00 },
> +	{ 0x36bc, 0x00 },
> +	{ 0x36bd, 0x00 },
> +};
> +
> +#endif /* __imx492_h__ */

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-25 15:31 ` [PATCH v1 3/5] media: i2c: imx492: driver's source Petko Manolov
@ 2022-11-28  5:16   ` Laurent Pinchart
  2022-11-28 13:42     ` Petko Manolov
  2022-11-28 12:58   ` Kieran Bingham
  1 sibling, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28  5:16 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, sakari.ailus

Hi Petko,

Thank you for the patch.

On Fri, Nov 25, 2022 at 05:31:18PM +0200, Petko Manolov wrote:
> imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> digital output makes it possible to output the signals with high definition for
> moving pictures. It is programmable through I2C interface. The I2C client
> address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> through MIPI CSI-2.
> 
> Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> ---
>  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 1092 insertions(+)
>  create mode 100644 drivers/media/i2c/imx492.c
> 
> diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> new file mode 100644
> index 000000000000..0713256b4b63
> --- /dev/null
> +++ b/drivers/media/i2c/imx492.c
> @@ -0,0 +1,1092 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> + *
> + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> + */
> +
> +#include <asm/unaligned.h>
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>

There are missing headers, at least for GPIO. Please check if anything
else is missing.

> +
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "imx492.h"
> +
> +/* Streaming Mode */
> +#define IMX492_REG_MODE_SELECT	0x3000
> +
> +/* Chip ID */
> +#define IMX492_ID		0x13
> +
> +/* Analog gain control */
> +#define IMX492_REG_AGAIN	0x300a
> +#define IMX492_AGAIN_MIN	0
> +#define IMX492_AGAIN_MAX	978
> +#define IMX492_AGAIN_STEP	1
> +#define IMX492_AGAIN_DEFAULT	0
> +
> +/* Group hold register */
> +#define IMX492_REG_HOLD		0x302b
> +#define	IMX492_REG_XMSTA	0x3033
> +#define	IMX492_REG_SYSCLKEN	0x35e5

You can replace the first tab (just after #define) with a space.

> +
> +/* CSI2 HW configuration */
> +#define IMX492_LINK_FREQ	745000000
> +#define IMX492_NUM_DATA_LANES	4
> +
> +#define IMX492_REG_MIN		0x3000
> +#define IMX492_REG_MAX		0xffff
> +
> +/* *** */
> +
> +#define IMX492_REG_STANDBY	IMX492_REG_MODE_SELECT

No aliases for register names please, that's confusing.

> +#define IMX492_BIT_STANDBY	0x01
> +#define IMX492_BIT_STBLOGIC	0x02
> +#define IMX492_BIT_STBDV	0x10
> +
> +#define IMX492_MODE_STANDBY	(IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> +#define IMX492_MODE_STREAMING	0x00
> +
> +#define IMX492_REG_TESTPTRN	0x303A
> +#define IMX492_BIT_CLKEN	0x01
> +#define IMX492_BIT_TESTPTRN	0x10
> +#define IMX492_BITS_TPTRN_ON	(IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> +#define IMX492_BITS_TPTRN_OFF	0x00
> +
> +#define IMX492_REG_TESTPATSEL	0x303B
> +#define IMX492_BIT_TPAT00	0x00
> +#define IMX492_BIT_TPAT01	0x01
> +#define IMX492_BIT_TPAT02	0x02
> +#define IMX492_BIT_TPAT03	0x03
> +#define IMX492_BIT_TPAT0A	0x0A
> +#define IMX492_BIT_TPAT0B	0x0B
> +
> +#define IMX492_EXPOSURE_MIN		8
> +#define IMX492_EXPOSURE_OFFSET		22
> +#define IMX492_EXPOSURE_STEP		1
> +#define IMX492_EXPOSURE_DEFAULT		0x0648
> +
> +#define	DEFAULT_FPS		6
> +
> +/**
> + * struct imx492_reg_list - imx492 sensor register list
> + * @num_of_regs: Number of registers in the list
> + * @regs: Pointer to register list
> + */
> +struct imx492_reg_list {
> +	u32 num_of_regs;
> +	const struct imx492_reg *regs;
> +};
> +
> +/**
> + * struct imx492_mode - imx492 sensor mode structure
> + * @width: Frame width
> + * @height: Frame height
> + * @code: Format code
> + * @hblank: Horizontal blanking in lines
> + * @vblank: Vertical blanking in lines
> + * @vblank_min: Minimum vertical blanking in lines
> + * @vblank_max: Maximum vertical blanking in lines
> + * @pclk: Sensor pixel clock
> + * @link_freq_idx: Link frequency index
> + * @reg_list: Register list for sensor mode
> + */
> +struct imx492_mode {
> +	u32 width;
> +	u32 height;
> +	u32 code;
> +	u32 hblank;
> +	u32 hblank_min;
> +	u32 hblank_max;
> +	u32 vblank;
> +	u32 vblank_min;
> +	u32 vblank_max;
> +	u64 pclk;
> +	u32 link_freq_idx;
> +	struct imx492_reg_list reg_list;
> +};
> +
> +/**
> + * struct imx492 - imx492 sensor device structure
> + * @dev: Pointer to generic device
> + * @client: Pointer to i2c client
> + * @sd: V4L2 sub-device
> + * @pad: Media pad. Only one pad supported
> + * @reset_gpio: Sensor reset gpio
> + * @reset_gpio: Sensor power gpio
> + * @inclk: Sensor input clock
> + * @supplies: Regulator supplies
> + * @ctrl_handler: V4L2 control handler
> + * @link_freq_ctrl: Pointer to link frequency control
> + * @pclk_ctrl: Pointer to pixel clock control
> + * @hblank_ctrl: Pointer to horizontal blanking control
> + * @vblank_ctrl: Pointer to vertical blanking control
> + * @exp_ctrl: Pointer to exposure control
> + * @again_ctrl: Pointer to analog gain control
> + * @vblank: Vertical blanking in lines
> + * @cur_mode: Pointer to current selected sensor mode
> + * @mutex: Mutex for serializing sensor controls

Please use the same order for fields in the documentation and the
structure defininition.

> + * @streaming: Flag indicating streaming state
> + */
> +struct imx492 {
> +	struct device *dev;
> +	struct i2c_client *client;
> +	struct v4l2_subdev sd;
> +	struct media_pad pad;
> +	struct v4l2_captureparm scap;

This is set but never used. You can drop it.

> +	struct gpio_desc *reset_gpio;
> +	struct gpio_desc *power_gpio;
> +	struct gpio_desc *oscen_gpio;
> +	struct clk *inclk;
> +	struct v4l2_ctrl_handler ctrl_handler;
> +	struct v4l2_ctrl *link_freq_ctrl;
> +	struct v4l2_ctrl *pclk_ctrl;
> +	struct v4l2_ctrl *hblank_ctrl;
> +	struct v4l2_ctrl *vblank_ctrl;
> +	struct v4l2_ctrl *exp_ctrl;
> +	struct v4l2_ctrl *again_ctrl;
> +	const struct imx492_mode *cur_mode;
> +	struct mutex mutex;
> +	u32 tpatt;

Not used, drop it.

> +	u32 vblank;
> +	bool streaming;
> +};
> +
> +static const s64 link_freq[] = {
> +	IMX492_LINK_FREQ,
> +};
> +
> +
> +/* Supported sensor mode configurations */
> +static const struct imx492_mode supported_modes[] = {
> +	{
> +		.width = 8192,
> +		.height = 4320,
> +		.hblank = 1108,
> +		.hblank_min = 1102,
> +		.hblank_max = 32768,
> +		.vblank = 5728,
> +		.vblank_min = 4428,
> +		.vblank_max = 32768,
> +		.pclk = 745000000,
> +		.link_freq_idx = 0,
> +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> +			.regs = mode_17to9_regs,
> +		},
> +	}, {
> +		.width = 8192,
> +		.height = 5556,
> +		.hblank = 1108,
> +		.hblank_min = 1102,
> +		.hblank_max = 32768,
> +		.vblank = 5728,
> +		.vblank_min = 4428,
> +		.vblank_max = 32768,
> +		.pclk = 745000000,
> +		.link_freq_idx = 0,
> +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_all_regs),
> +			.regs = mode_all_regs,
> +		},
> +	},
> +};
> +
> +static const char * const imx492_test_pattern_menu[] = {
> +	"Disabled",
> +	"Solid black",
> +	"Solid white",
> +	"Solid dark grey",
> +	"Solid light gray",
> +	"None",
> +	"None",
> +	"None",
> +	"None",
> +	"None",
> +	"None",

Menu controls shouldn't have entries with identical names. All these
should be dropped if they're not implemented by the sensor, or given a
proper name.

> +	"Vertical color bars",
> +	"Horizontal color bars",
> +};
> +
> +/**
> + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> + * @subdev: pointer to imx492 V4L2 sub-device
> + *
> + * Return: pointer to imx492 device
> + */
> +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct imx492, sd);
> +}
> +
> +/**
> + * imx492_read_reg() - Read registers.
> + * @imx492: pointer to imx492 device
> + * @reg: register address
> + * @len: length of bytes to read. Max supported bytes is 4
> + * @val: pointer to register value to be filled.
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> +	struct i2c_msg msgs[2] = {0};
> +	u8 addr_buf[2] = {0};
> +	u8 data_buf[4] = {0};
> +	int ret;
> +
> +	if (WARN_ON(len > 4))
> +		return -EINVAL;
> +
> +	put_unaligned_be16(reg, addr_buf);
> +
> +	/* Write register address */
> +	msgs[0].addr = client->addr;
> +	msgs[0].flags = 0;
> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> +	msgs[0].buf = addr_buf;
> +
> +	/* Read data from register */
> +	msgs[1].addr = client->addr;
> +	msgs[1].flags = I2C_M_RD;
> +	msgs[1].len = len;
> +	msgs[1].buf = &data_buf[4 - len];
> +
> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> +	if (ret != ARRAY_SIZE(msgs))
> +		return -EIO;
> +
> +	*val = get_unaligned_be32(data_buf);
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_write_reg() - Write register
> + * @imx492: pointer to imx492 device
> + * @reg: register address
> + * @len: length of bytes. Max supported bytes is 4
> + * @val: register value
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> +	u8 buf[6] = {0};
> +
> +	if (WARN_ON(len > 4))
> +		return -EINVAL;
> +
> +	put_unaligned_be16(reg, buf);
> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> +	if (i2c_master_send(client, buf, len + 2) != len + 2)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_write_regs() - Write a list of registers
> + * @imx492: pointer to imx492 device
> + * @regs: list of registers to be written
> + * @len: length of registers array
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_write_regs(struct imx492 *imx492,
> +			     const struct imx492_reg *regs, u32 len)
> +{
> +	unsigned int i;
> +	int ret;
> +
> +	for (i = 0; i < len; i++) {
> +		ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> +{
> +	/* for now this is the only format we support */
> +	return MEDIA_BUS_FMT_SGBRG12_1X12;
> +}
> +
> +/**
> + * imx492_update_controls() - Update control ranges based on streaming mode
> + * @imx492: pointer to imx492 device
> + * @mode: pointer to imx492_mode sensor mode
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_update_controls(struct imx492 *imx492,
> +				  const struct imx492_mode *mode)
> +{
> +	int ret;
> +
> +	ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> +	if (ret)
> +		return ret;
> +
> +	ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> +	if (ret)
> +		return ret;
> +
> +	return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> +					mode->vblank_max, 1, mode->vblank);
> +}
> +
> +/**
> + * imx492_update_exp_gain() - Set updated exposure and gain
> + * @imx492: pointer to imx492 device
> + * @exposure: updated exposure value
> + * @gain: updated analog gain value
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> +{
> +	u32 lpfr, shutter;
> +	int ret;
> +
> +	lpfr = imx492->vblank + imx492->cur_mode->height;
> +	shutter = lpfr - exposure;
> +
> +	ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> +	if (ret)
> +		return ret;
> +
> +	ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> +
> +	return ret;
> +}
> +
> +/**
> + * imx492_set_ctrl() - Set subdevice control
> + * @ctrl: pointer to v4l2_ctrl structure
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct imx492 *imx492 =
> +		container_of(ctrl->handler, struct imx492, ctrl_handler);
> +	u32 analog_gain;
> +	u32 exposure;
> +	int ret;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_VBLANK:
> +		imx492->vblank = imx492->vblank_ctrl->val;
> +
> +		ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> +					       IMX492_EXPOSURE_MIN,
> +					       imx492->vblank +
> +					       imx492->cur_mode->height -
> +					       IMX492_EXPOSURE_OFFSET,
> +					       1, IMX492_EXPOSURE_DEFAULT);

It looks like you forgot to write the corresponding registers.

> +		break;
> +	case V4L2_CID_EXPOSURE:
> +		/* Set controls only if sensor is in power on state */
> +		if (!pm_runtime_get_if_in_use(imx492->dev))
> +			return 0;
> +		exposure = ctrl->val;
> +		analog_gain = imx492->again_ctrl->val;
> +		ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> +		pm_runtime_put(imx492->dev);
> +		break;
> +	case V4L2_CID_TEST_PATTERN:
> +		if (ctrl->val) {
> +			imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> +		} else {
> +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> +		}

Don't you need the same pm_runtime_get_if_in_use() dance as for
V4L2_CID_EXPOSURE ?

> +		ret = 0;
> +		break;

Missing V4L2_CID_ANALOGUE_GAIN.

> +	default:
> +		dev_err(imx492->dev, "Invalid control %d", ctrl->id);

This shouldn't happen if you correctly handle all the controls you have
instanciated in imx492_init_controls().

> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +/* V4l2 subdevice control ops*/
> +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> +	.s_ctrl = imx492_set_ctrl,
> +};
> +
> +/**
> + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @code: V4L2 sub-device code enumeration need to be filled
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_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(supported_modes))
> +		return -EINVAL;
> +
> +	code->code = supported_modes[code->index].code;

All modes have the same media bus code, you shouldn't report duplicated
values.

> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fsize: V4L2 sub-device size enumeration need to be filled
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> +				  struct v4l2_subdev_state *sd_state,
> +				  struct v4l2_subdev_frame_size_enum *fsize)
> +{
> +	if (fsize->index > ARRAY_SIZE(supported_modes))
> +		return -EINVAL;
> +
> +	if (fsize->code != supported_modes[fsize->index].code)
> +		return -EINVAL;
> +
> +	fsize->max_width = supported_modes[fsize->index].width;
> +	fsize->min_width = fsize->max_width;
> +	fsize->max_height = supported_modes[fsize->index].height;
> +	fsize->min_height = fsize->max_height;
> +
> +	return 0;
> +}
> +
> +/**
> +n * imx492_fill_pad_format() - Fill subdevice pad format
> + *                            from selected sensor mode
> + * @imx492: pointer to imx492 device
> + * @mode: pointer to imx492_mode sensor mode
> + * @fmt: V4L2 sub-device format need to be filled
> + */
> +static void imx492_fill_pad_format(struct imx492 *imx492,
> +				   const struct imx492_mode *mode,
> +				   struct v4l2_subdev_format *fmt)
> +{
> +	fmt->format.width = mode->width;
> +	fmt->format.height = mode->height;
> +	fmt->format.code = mode->code;
> +	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;

You can use V4L2_QUANTIZATION_FULL_RANGE.

> +	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
> +}
> +
> +/**
> + * imx492_get_pad_format() - Get subdevice pad format
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fmt: V4L2 sub-device format need to be set
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_format *fmt)
> +{
> +	struct imx492 *imx492 = to_imx492(sd);
> +
> +	mutex_lock(&imx492->mutex);
> +
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		struct v4l2_mbus_framefmt *framefmt;
> +
> +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> +		fmt->format = *framefmt;
> +	} else {
> +		imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> +	}
> +
> +	mutex_unlock(&imx492->mutex);
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_set_pad_format() - Set subdevice pad format
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fmt: V4L2 sub-device format need to be set
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_format *fmt)
> +{
> +	struct imx492 *imx492 = to_imx492(sd);
> +	const struct imx492_mode *mode;
> +	int ret = 0;
> +
> +	mutex_lock(&imx492->mutex);
> +
> +	fmt->format.code = imx492_get_format_code(imx492, 0);
> +	mode = v4l2_find_nearest_size(supported_modes,
> +					ARRAY_SIZE(supported_modes),
> +					width, height,
> +					fmt->format.width, fmt->format.height);
> +	imx492_fill_pad_format(imx492, mode, fmt);
> +
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		struct v4l2_mbus_framefmt *framefmt;
> +
> +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> +		*framefmt = fmt->format;
> +	} else {
> +		ret = imx492_update_controls(imx492, mode);
> +		if (!ret)
> +			imx492->cur_mode = mode;
> +	}
> +
> +	mutex_unlock(&imx492->mutex);
> +
> +	return ret;
> +}
> +
> +/**
> + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> +			       struct v4l2_subdev_state *sd_state)
> +{
> +	struct imx492 *imx492 = to_imx492(sd);
> +	struct v4l2_subdev_format fmt = { 0 };
> +
> +	fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;

When using the active state API you will never get a null state here, so
you can set this to

	struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_TRY, };

unconditionally.

> +	imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> +
> +	return imx492_set_pad_format(sd, sd_state, &fmt);
> +}
> +
> +/**
> + * imx492_start_streaming() - Start sensor stream
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_start_streaming(struct imx492 *imx492)
> +{
> +	const struct imx492_reg_list *reg_list;
> +	int ret;
> +
> +	/* Write sensor mode registers */
> +	reg_list = &imx492->cur_mode->reg_list;
> +	ret = imx492_write_regs(imx492, reg_list->regs,
> +				reg_list->num_of_regs);
> +	if (ret) {
> +		dev_err(imx492->dev, "fail to write initial registers");
> +		return ret;
> +	}
> +
> +	/* Setup handler will write actual exposure and gain */
> +	ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> +	if (ret) {
> +		dev_err(imx492->dev, "fail to setup handler");
> +		return ret;
> +	}
> +
> +	/* 1st stabilization period */
> +	usleep_range(10000, 11000);
> +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> +
> +	/* 2nd stabilization period */
> +	usleep_range(7000, 8000);
> +
> +	/* Start streaming */
> +	ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> +
> +	if (ret) {
> +		dev_err(imx492->dev, "fail to start streaming");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_stop_streaming() - Stop sensor stream
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static void imx492_stop_streaming(struct imx492 *imx492)
> +{
> +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> +	imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> +}
> +
> +/**
> + * imx492_set_stream() - Enable sensor streaming
> + * @sd: pointer to imx492 subdevice
> + * @enable: set to enable sensor streaming
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> +{
> +	struct imx492 *imx492 = to_imx492(sd);
> +	int ret;
> +
> +	mutex_lock(&imx492->mutex);
> +
> +	if (imx492->streaming == enable) {

This should never happen. You can drop imx492->streaming.

> +		mutex_unlock(&imx492->mutex);
> +		return 0;
> +	}
> +
> +	if (enable) {
> +		ret = pm_runtime_resume_and_get(imx492->dev);
> +		if (ret)
> +			goto error_unlock;
> +		ret = imx492_start_streaming(imx492);
> +		if (ret)
> +			goto error_power_off;
> +	} else {
> +		imx492_stop_streaming(imx492);
> +		pm_runtime_put(imx492->dev);
> +	}
> +
> +	imx492->streaming = enable;
> +
> +	mutex_unlock(&imx492->mutex);
> +
> +	return 0;
> +
> +error_power_off:
> +	pm_runtime_put(imx492->dev);
> +error_unlock:
> +	mutex_unlock(&imx492->mutex);
> +
> +	return ret;
> +}
> +
> +/**
> + * imx492_detect() - Detect imx492 sensor
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, -EIO if sensor id does not match
> + */
> +static int imx492_detect(struct imx492 *imx492)
> +{
> +	int ret;
> +	u32 val;
> +
> +	ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);

Is the chip ID really stored in that register ?

> +	if (ret)
> +		return ret;
> +
> +	if (val != IMX492_ID) {
> +		dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> +		return -ENXIO;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_parse_hw_config(struct imx492 *imx492)
> +{
> +	struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> +	struct v4l2_fwnode_endpoint bus_cfg = {
> +		.bus_type = V4L2_MBUS_CSI2_DPHY
> +	};
> +	struct fwnode_handle *ep;
> +	unsigned int i;
> +	int ret;
> +
> +	if (!fwnode)
> +		return -ENXIO;
> +
> +	imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);

Not listed in the DT binding.

> +	if (IS_ERR(imx492->power_gpio)) {
> +		dev_err(imx492->dev, "failed to get power gpio %ld",
> +			PTR_ERR(imx492->power_gpio));
> +		return PTR_ERR(imx492->power_gpio);
> +	}
> +
> +	imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);

Not listed in the DT binding.

You should also handle regulators in the driver.

> +	if (IS_ERR(imx492->oscen_gpio)) {
> +		dev_err(imx492->dev, "failed to get oscen gpio %ld",
> +			PTR_ERR(imx492->oscen_gpio));
> +		return PTR_ERR(imx492->oscen_gpio);
> +	}
> +
> +	imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> +	if (IS_ERR(imx492->reset_gpio)) {
> +		dev_err(imx492->dev, "failed to get reset gpio %ld",
> +			PTR_ERR(imx492->reset_gpio));
> +		return PTR_ERR(imx492->reset_gpio);
> +	}
> +
> +	if (gpiod_direction_output(imx492->power_gpio, 1) ||
> +	    gpiod_direction_output(imx492->oscen_gpio, 1) ||
> +	    gpiod_direction_output(imx492->reset_gpio, 0)) {

This is done by devm_gpiod_get().

> +		dev_err(imx492->dev, "failed to change gpio direction");
> +		return -EINVAL;
> +	}
> +
> +	/* Get sensor input clock */
> +	imx492->inclk = devm_clk_get(imx492->dev, NULL);
> +	if (IS_ERR(imx492->inclk)) {
> +		dev_err(imx492->dev, "could not get inclk");
> +		return PTR_ERR(imx492->inclk);
> +	}
> +
> +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> +	if (!ep) {
> +		dev_err(imx492->dev, "next endpoint?");
> +		return -ENXIO;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> +	fwnode_handle_put(ep);
> +	if (ret) {
> +		dev_err(imx492->dev, "endpoint alloc parse");
> +		return ret;
> +	}
> +
> +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> +		dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> +		ret = -EINVAL;
> +		goto done_endpoint_free;
> +	}
> +
> +	if (!bus_cfg.nr_of_link_frequencies) {
> +		dev_err(imx492->dev, "no link frequencies defined");
> +		ret = -EINVAL;
> +		goto done_endpoint_free;
> +	}
> +
> +	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> +		if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> +			goto done_endpoint_free;
> +	}
> +
> +	ret = -EINVAL;
> +
> +done_endpoint_free:
> +	v4l2_fwnode_endpoint_free(&bus_cfg);
> +
> +	return ret;
> +}
> +
> +/* V4l2 subdevice ops */
> +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> +	.s_stream = imx492_set_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> +	.init_cfg = imx492_init_pad_cfg,
> +	.enum_mbus_code = imx492_enum_mbus_code,
> +	.enum_frame_size = imx492_enum_frame_size,
> +	.get_fmt = imx492_get_pad_format,

Please use the subdev active state API. You need to call
v4l2_subdev_init_finalize() at probe time, and you can set this to

	.get_fmt = v4l2_subdev_get_fmt,

Then, in imx492_set_pad_format() (and elsewhere as needed), you can use
v4l2_subdev_get_pad_format() to replace v4l2_subdev_get_try_format().
This helps making code paths identical for the TRY and ACTIVE cases, the
only exception being the update of controls in .set_fmt() in the ACTIVE
case.

> +	.set_fmt = imx492_set_pad_format,

Please also implement the .get_selection operation to report the
V4L2_SEL_TGT_CROP, V4L2_SEL_TGT_CROP_BOUNDS, V4L2_SEL_TGT_CROP_DEFAULT
and V4L2_SEL_TGT_NATIVE_SIZE values.

> +};
> +
> +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> +	.video = &imx492_video_ops,
> +	.pad = &imx492_pad_ops,
> +};
> +
> +/**
> + * imx492_power_on() - Sensor power on sequence
> + * @dev: pointer to i2c device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_power_on(struct device *dev)
> +{
> +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct imx492 *imx492 = to_imx492(sd);
> +
> +	gpiod_set_value_cansleep(imx492->power_gpio, 1);
> +	msleep(1);
> +	gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> +	msleep(1);
> +	gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> +	msleep(1);

How about regulators and clock ?

> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_power_off() - Sensor power off sequence
> + * @dev: pointer to i2c device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_power_off(struct device *dev)
> +{
> +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct imx492 *imx492 = to_imx492(sd);
> +
> +	gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> +	gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> +	gpiod_set_value_cansleep(imx492->power_gpio, 0);
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_init_controls() - Initialize sensor subdevice controls
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_init_controls(struct imx492 *imx492)
> +{
> +	struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> +	const struct imx492_mode *mode = imx492->cur_mode;
> +	u32 lpfr;
> +	int ret;
> +
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> +	if (ret)
> +		return ret;
> +
> +	/* Serialize controls with sensor device */
> +	ctrl_hdlr->lock = &imx492->mutex;
> +	/* Initialize exposure and gain */
> +	lpfr = mode->vblank + mode->height;
> +	imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +					     &imx492_ctrl_ops,
> +					     V4L2_CID_EXPOSURE,
> +					     IMX492_EXPOSURE_MIN,
> +					     lpfr - IMX492_EXPOSURE_OFFSET,
> +					     IMX492_EXPOSURE_STEP,
> +					     IMX492_EXPOSURE_DEFAULT);
> +
> +	imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +					       &imx492_ctrl_ops,
> +					       V4L2_CID_ANALOGUE_GAIN,
> +					       IMX492_AGAIN_MIN,
> +					       IMX492_AGAIN_MAX,
> +					       IMX492_AGAIN_STEP,
> +					       IMX492_AGAIN_DEFAULT);
> +
> +	v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> +
> +	imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +						&imx492_ctrl_ops,
> +						V4L2_CID_VBLANK,
> +						mode->vblank_min,
> +						mode->vblank_max,
> +						1, mode->vblank);
> +	/* Read only controls */
> +	imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +						&imx492_ctrl_ops,
> +						V4L2_CID_HBLANK,
> +						mode->hblank_min,
> +						mode->hblank_max,
> +						1, mode->hblank);
> +	if (imx492->hblank_ctrl)
> +		imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +	imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +					      &imx492_ctrl_ops,
> +					      V4L2_CID_PIXEL_RATE,
> +					      mode->pclk, mode->pclk,
> +					      1, mode->pclk);

Shouldn't this be read-only ?

> +
> +	imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> +							&imx492_ctrl_ops,
> +							V4L2_CID_LINK_FREQ,
> +							ARRAY_SIZE(link_freq) -
> +							1,
> +							mode->link_freq_idx,
> +							link_freq);
> +	if (imx492->link_freq_ctrl)
> +		imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> +				     V4L2_CID_TEST_PATTERN,
> +				     ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> +				     0, 0, imx492_test_pattern_menu);
> +
> +	if (ctrl_hdlr->error) {
> +		dev_err(imx492->dev, "control init failed: %d",	ctrl_hdlr->error);
> +		v4l2_ctrl_handler_free(ctrl_hdlr);
> +		return ctrl_hdlr->error;
> +	}
> +
> +	imx492->sd.ctrl_handler = ctrl_hdlr;
> +
> +	return 0;
> +}
> +
> +/**
> + * imx492_probe() - I2C client device binding
> + * @client: pointer to i2c client device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_probe(struct i2c_client *client)
> +{
> +	struct imx492 *imx492;
> +	int ret;
> +
> +	imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> +	if (!imx492)
> +		return -ENOMEM;
> +
> +	imx492->dev = &client->dev;
> +
> +	/* Initialize subdev */
> +	v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> +
> +	ret = imx492_parse_hw_config(imx492);
> +	if (ret) {
> +		dev_err(imx492->dev, "HW configuration is not supported");
> +		return ret;
> +	}
> +
> +	mutex_init(&imx492->mutex);
> +
> +	ret = imx492_power_on(imx492->dev);
> +	if (ret) {
> +		dev_err(imx492->dev, "failed to power-on the sensor");
> +		goto error_mutex_destroy;
> +	}
> +
> +	/* Check module identity */
> +	ret = imx492_detect(imx492);
> +	if (ret) {
> +		dev_err(imx492->dev, "failed to find sensor: %d", ret);
> +		goto error_power_off;
> +	}
> +
> +	/* Set default mode to max resolution */
> +	imx492->cur_mode = &supported_modes[0];
> +	imx492->vblank = imx492->cur_mode->vblank;
> +
> +	ret = imx492_init_controls(imx492);
> +	if (ret) {
> +		dev_err(imx492->dev, "failed to init controls: %d", ret);
> +		goto error_power_off;
> +	}
> +
> +	/* Initialize subdev */
> +	imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> +	imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> +	imx492->scap.capturemode = 0;
> +	imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> +	imx492->scap.timeperframe.numerator = 1;
> +
> +	/* Initialize source pad */
> +	imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> +	ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> +	if (ret) {
> +		dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> +		goto error_handler_free;
> +	}
> +
> +	ret = v4l2_async_register_subdev(&imx492->sd);
> +	if (ret < 0) {
> +		dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> +		goto error_media_entity;
> +	}

This should be done at the very end of probe(), as the sensor can be
used right after it gets registered, so it should be fully operational.

> +
> +	pm_runtime_set_active(imx492->dev);
> +	pm_runtime_enable(imx492->dev);
> +	pm_runtime_idle(imx492->dev);

While at it, I would also implement autosuspend. You should then add a
call to pm_runtime_get_noresume() before pm_runtime_enable(), drop the
pm_runtime_idle() call, and add

	pm_runtime_set_autosuspend_delay(imx492->dev, 1000);
	pm_runtime_use_autosuspend(imx492->dev);
	pm_runtime_put_autosuspend(imx492->dev);

You will also need to replace pm_runtime_put() with
pm_runtime_mark_last_busy() + pm_runtime_put_autosuspend() above.

> +
> +	return 0;
> +
> +error_media_entity:
> +	media_entity_cleanup(&imx492->sd.entity);
> +error_handler_free:
> +	v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> +error_power_off:
> +	imx492_power_off(imx492->dev);
> +error_mutex_destroy:
> +	mutex_destroy(&imx492->mutex);
> +
> +	return ret;
> +}
> +
> +/**
> + * imx492_remove() - I2C client device unbinding
> + * @client: pointer to I2C client device
> + */
> +static void imx492_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct imx492 *imx492 = to_imx492(sd);
> +
> +	v4l2_async_unregister_subdev(sd);
> +	media_entity_cleanup(&sd->entity);
> +	v4l2_ctrl_handler_free(sd->ctrl_handler);
> +	pm_runtime_disable(&client->dev);
> +	if (!pm_runtime_status_suspended(&client->dev))
> +		imx492_power_off(&client->dev);
> +	pm_runtime_set_suspended(&client->dev);
> +	mutex_destroy(&imx492->mutex);
> +}
> +
> +static const struct dev_pm_ops imx492_pm_ops = {
> +	SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> +};
> +
> +static const struct of_device_id imx492_of_match[] = {
> +	{ .compatible = "sony,imx492_mipi" },
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, imx492_of_match);
> +
> +static struct i2c_driver imx492_driver = {
> +	.probe_new = imx492_probe,
> +	.remove = imx492_remove,
> +	.driver = {
> +		.name = "imx492",
> +		.pm = &imx492_pm_ops,
> +		.of_match_table = imx492_of_match,
> +	},
> +};
> +
> +module_i2c_driver(imx492_driver);
> +
> +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
                   ` (4 preceding siblings ...)
  2022-11-25 15:31 ` [PATCH v1 5/5] media: i2c: add imx492 entry for make Petko Manolov
@ 2022-11-28 12:45 ` Kieran Bingham
  2022-11-28 13:11   ` Petko Manolov
  5 siblings, 1 reply; 28+ messages in thread
From: Kieran Bingham @ 2022-11-28 12:45 UTC (permalink / raw)
  To: Petko Manolov, linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Hi Petko,

What device/ISP are you testing this sensor on?

Quoting Petko Manolov (2022-11-25 15:31:15)
> This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> image sensor.
> 
> imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> digital output makes it possible to output the signals with high definition for
> moving pictures. It is programmable through I2C interface. The I2C client
> address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> through MIPI CSI-2.
> 
> Petko Manolov (5):
>   DT bindings for imx492
>   media: i2c: imx492: driver's header
>   media: i2c: imx492: driver's source
>   media: i2c: add imx492 config entry
>   media: i2c: add imx492 entry for make

Could you squash patches 2, 3, 4, and 5 into a single patch please?

Also - I think you'll need an entry in MAINTAINERS.

I can't see any reference to the selection controls:
 - V4L2_SEL_TGT_CROP_DEFAULT
 - V4L2_SEL_TGT_CROP
 - V4L2_SEL_TGT_CROP_BOUNDS

Do you have the datasheet or sufficient information to be able to
implement these controls?

--
Kieran

>  .../bindings/media/i2c/sony,imx492.yaml       |  101 ++
>  drivers/media/i2c/Kconfig                     |   14 +
>  drivers/media/i2c/Makefile                    |    1 +
>  drivers/media/i2c/imx492.c                    | 1092 +++++++++++++++++
>  drivers/media/i2c/imx492.h                    |  555 +++++++++
>  5 files changed, 1763 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
>  create mode 100644 drivers/media/i2c/imx492.c
>  create mode 100644 drivers/media/i2c/imx492.h
> 
> -- 
> 2.30.2
>

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-25 15:31 ` [PATCH v1 2/5] media: i2c: imx492: driver's header Petko Manolov
  2022-11-28  4:40   ` Laurent Pinchart
@ 2022-11-28 12:47   ` Kieran Bingham
  2022-11-28 13:14     ` Petko Manolov
  1 sibling, 1 reply; 28+ messages in thread
From: Kieran Bingham @ 2022-11-28 12:47 UTC (permalink / raw)
  To: Petko Manolov, linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Quoting Petko Manolov (2022-11-25 15:31:17)
> The header.  For the moment only two modes are supported.
> 
> Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> ---
>  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 555 insertions(+)
>  create mode 100644 drivers/media/i2c/imx492.h
> 
> diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> new file mode 100644
> index 000000000000..301fd66c77d5
> --- /dev/null
> +++ b/drivers/media/i2c/imx492.h
> @@ -0,0 +1,555 @@
> +#ifndef        __imx492_h__
> +#define        __imx492_h__
> +
> +struct imx492_reg {
> +       u16 address;
> +       u8 val;
> +};
> +
> +static const struct imx492_reg mode_17to9_regs[] = {

Why is this table in the header? Should it be available in multiple
locations?

I think it is likely better in the driver itself.

Even the struct imx492_reg could then be in the driver file, and there
wouldn't be a need for a header ?

--
Kieran


> +       { 0x3033, 0x30 },
> +       { 0x303c, 0x01 },
> +       { 0x31e8, 0xa0 },
> +       { 0x31f4, 0x01 },
> +       { 0x31e9, 0x00 },
> +       { 0x3122, 0x02 },
> +       { 0x3129, 0x90 },
> +       { 0x312a, 0x02 },
> +       { 0x311f, 0x00 },
> +       { 0x3123, 0x00 },
> +       { 0x3124, 0x00 },
> +       { 0x3125, 0x01 },
> +       { 0x3127, 0x02 },
> +       { 0x312d, 0x02 },
> +       { 0x3000, 0x12 },
> +       { 0x310b, 0x00 },
> +       { 0x3004, 0x1c },
> +       { 0x3005, 0x06 },
> +       { 0x3006, 0x00 },
> +       { 0x3007, 0xa7 },
> +       { 0x3047, 0x02 },
> +       { 0x304e, 0x0b },
> +       { 0x304f, 0x2a },
> +       { 0x3052, 0xee },
> +       { 0x3062, 0x25 },
> +       { 0x3064, 0x78 },
> +       { 0x3065, 0x33 },
> +       { 0x3066, 0x64 },
> +       { 0x3067, 0x71 },
> +       { 0x307e, 0x07 },
> +       { 0x3081, 0x00 },
> +       { 0x3088, 0x75 },
> +       { 0x308a, 0x09 },
> +       { 0x308c, 0x61 },
> +       { 0x30ef, 0x01 },
> +       { 0x3146, 0x00 },
> +       { 0x31f5, 0x01 },
> +       { 0x3234, 0x32 },
> +       { 0x3248, 0xbc },
> +       { 0x3250, 0xbc },
> +       { 0x3258, 0xbc },
> +       { 0x3260, 0xbc },
> +       { 0x3274, 0x13 },
> +       { 0x3276, 0x00 },
> +       { 0x3277, 0x00 },
> +       { 0x327c, 0x13 },
> +       { 0x327e, 0x00 },
> +       { 0x327f, 0x00 },
> +       { 0x3284, 0x13 },
> +       { 0x3286, 0x00 },
> +       { 0x3287, 0x00 },
> +       { 0x328c, 0x13 },
> +       { 0x328e, 0x00 },
> +       { 0x328f, 0x00 },
> +       { 0x32ae, 0x00 },
> +       { 0x32af, 0x00 },
> +       { 0x32ca, 0x5a },
> +       { 0x332c, 0x00 },
> +       { 0x332f, 0x00 },
> +       { 0x334a, 0x00 },
> +       { 0x334c, 0x01 },
> +       { 0x3352, 0x50 },
> +       { 0x3356, 0x4f },
> +       { 0x335a, 0x79 },
> +       { 0x335e, 0x56 },
> +       { 0x3360, 0x6a },
> +       { 0x336a, 0x56 },
> +       { 0x33d6, 0x79 },
> +       { 0x340c, 0x6e },
> +       { 0x3448, 0x7e },
> +       { 0x348e, 0x6f },
> +       { 0x3492, 0x11 },
> +       { 0x34c4, 0x5a },
> +       { 0x3506, 0x56 },
> +       { 0x350c, 0x56 },
> +       { 0x350e, 0x58 },
> +       { 0x353d, 0x10 },
> +       { 0x3549, 0x04 },
> +       { 0x355d, 0x03 },
> +       { 0x355e, 0x03 },
> +       { 0x3574, 0x56 },
> +       { 0x357f, 0x0c },
> +       { 0x3580, 0x0a },
> +       { 0x3581, 0x08 },
> +       { 0x3583, 0x72 },
> +       { 0x3587, 0x01 },
> +       { 0x35b6, 0x00 },
> +       { 0x35b8, 0x00 },
> +       { 0x35d0, 0x5e },
> +       { 0x35d4, 0x63 },
> +       { 0x366a, 0x04 },
> +       { 0x366b, 0x04 },
> +       { 0x366c, 0x00 },
> +       { 0x366d, 0x00 },
> +       { 0x366e, 0x00 },
> +       { 0x366f, 0x00 },
> +       { 0x3670, 0x00 },
> +       { 0x3671, 0x05 },
> +       { 0x3676, 0x83 },
> +       { 0x3677, 0x03 },
> +       { 0x3678, 0x00 },
> +       { 0x3679, 0x04 },
> +       { 0x367a, 0x2c },
> +       { 0x367b, 0x05 },
> +       { 0x367d, 0x06 },
> +       { 0x367e, 0xff },
> +       { 0x367f, 0x06 },
> +       { 0x3680, 0x4b },
> +       { 0x3688, 0x05 },
> +       { 0x3690, 0x27 },
> +       { 0x3692, 0x65 },
> +       { 0x3694, 0x4f },
> +       { 0x3696, 0xa1 },
> +       { 0x36bc, 0x00 },
> +       { 0x371c, 0x02 },
> +       { 0x372f, 0x3c },
> +       { 0x3730, 0x01 },
> +       { 0x3732, 0xb8 },
> +       { 0x3734, 0x4a },
> +       { 0x3736, 0x57 },
> +       { 0x3738, 0x4d },
> +       { 0x3744, 0x0f },
> +       { 0x375b, 0x01 },
> +       { 0x382b, 0x68 },
> +       { 0x38b3, 0x00 },
> +       { 0x3910, 0x90 },
> +       { 0x3911, 0x70 },
> +       { 0x3912, 0x92 },
> +       { 0x3913, 0x24 },
> +       { 0x3914, 0x93 },
> +       { 0x3915, 0x0b },
> +       { 0x3916, 0x01 },
> +       { 0x3918, 0x04 },
> +       { 0x391c, 0x90 },
> +       { 0x391d, 0x05 },
> +       { 0x3920, 0x96 },
> +       { 0x3921, 0x06 },
> +       { 0x3a2a, 0x01 },
> +       { 0x3a7a, 0x01 },
> +       { 0x3a7b, 0x01 },
> +       { 0x3acb, 0x06 },
> +       { 0x3c08, 0x3f },
> +       { 0x3c0c, 0x1b },
> +       { 0x3e80, 0x14 },
> +       { 0x3e82, 0x30 },
> +       { 0x3e84, 0x0c },
> +       { 0x3e85, 0x06 },
> +       { 0x3e86, 0xfc },
> +       { 0x3e87, 0x10 },
> +       { 0x3e88, 0x03 },
> +       { 0x3e89, 0xfe },
> +       { 0x3e8a, 0x01 },
> +       { 0x3e8b, 0x06 },
> +       { 0x3e8e, 0x03 },
> +       { 0x3e8f, 0xfe },
> +       { 0x3e90, 0x01 },
> +       { 0x3e91, 0x06 },
> +       { 0x3e94, 0x33 },
> +       { 0x3e95, 0x01 },
> +       { 0x3e96, 0x19 },
> +       { 0x3e98, 0x30 },
> +       { 0x3e9a, 0x11 },
> +       { 0x3e9b, 0x06 },
> +       { 0x3e9c, 0xfc },
> +       { 0x3e9d, 0x10 },
> +       { 0x3e9e, 0xfe },
> +       { 0x3e9f, 0x03 },
> +       { 0x3ea0, 0x06 },
> +       { 0x3ea3, 0x01 },
> +       { 0x3ea4, 0xfe },
> +       { 0x3ea5, 0x03 },
> +       { 0x3ea6, 0x06 },
> +       { 0x3ea9, 0x33 },
> +       { 0x3eaa, 0x00 },
> +       { 0x3eab, 0x08 },
> +       { 0x3eac, 0x08 },
> +       { 0x3ead, 0x01 },
> +       { 0x3eae, 0x08 },
> +       { 0x3eaf, 0x08 },
> +       { 0x3eb0, 0x00 },
> +       { 0x3eb1, 0x10 },
> +       { 0x3eb2, 0x10 },
> +       { 0x3eb3, 0x01 },
> +       { 0x3eb4, 0x10 },
> +       { 0x3eb5, 0x10 },
> +       { 0x3eb6, 0x00 },
> +       { 0x3eb7, 0x00 },
> +       { 0x3eb8, 0x00 },
> +       { 0x3eb9, 0x00 },
> +       { 0x3eba, 0x00 },
> +       { 0x3ebb, 0x00 },
> +       { 0x3ec0, 0x54 },
> +       { 0x3ecc, 0x04 },
> +       { 0x3ecd, 0x04 },
> +       { 0x3ed0, 0xf0 },
> +       { 0x3ed1, 0x20 },
> +       { 0x3ed2, 0x0b },
> +       { 0x3ed3, 0x04 },
> +       { 0x3ed5, 0x13 },
> +       { 0x3ed6, 0x00 },
> +       { 0x3ed9, 0x0f },
> +       { 0x3ee4, 0x02 },
> +       { 0x3ee5, 0x02 },
> +       { 0x3ee7, 0x00 },
> +       { 0x3ef6, 0x00 },
> +       { 0x3ef8, 0x10 },
> +       { 0x3efa, 0x00 },
> +       { 0x3efc, 0x10 },
> +       { 0x3134, 0xa7 },
> +       { 0x3135, 0x00 },
> +       { 0x3136, 0x9f },
> +       { 0x3137, 0x00 },
> +       { 0x3138, 0x6f },
> +       { 0x3139, 0x00 },
> +       { 0x313a, 0x5f },
> +       { 0x313b, 0x00 },
> +       { 0x313c, 0x5f },
> +       { 0x313d, 0x00 },
> +       { 0x313e, 0x7f },
> +       { 0x313f, 0x01 },
> +       { 0x3140, 0x6f },
> +       { 0x3141, 0x00 },
> +       { 0x3142, 0x4f },
> +       { 0x3143, 0x00 },
> +       { 0x300e, 0x00 },
> +       { 0x300f, 0x00 },
> +       { 0x302c, 0x0c },
> +       { 0x302d, 0x00 },
> +       { 0x3034, 0x01 },
> +       { 0x3035, 0x01 },
> +       { 0x3036, 0x64 },
> +       { 0x3037, 0x00 },
> +       { 0x3038, 0xc8 },
> +       { 0x3039, 0x00 },
> +       { 0x3084, 0x4e },
> +       { 0x3085, 0x04 },
> +       { 0x3086, 0x4e },
> +       { 0x3087, 0x04 },
> +       { 0x30a9, 0xe0 },
> +       { 0x30aa, 0x2e },
> +       { 0x30ab, 0x00 },
> +       { 0x30ac, 0x48 },
> +       { 0x30ad, 0x0d },
> +       { 0x30e2, 0x00 },
> +       { 0x312f, 0x20 },
> +       { 0x3130, 0x1c },
> +       { 0x3131, 0x11 },
> +       { 0x3132, 0xfc },
> +       { 0x3133, 0x10 },
> +       { 0x3a54, 0xf0 },
> +       { 0x3a55, 0x20 },
> +       { 0x3a43, 0x01 },
> +       { 0x3a3b, 0x00 },
> +       { 0x3042, 0x32 },
> +       { 0x3092, 0x00 },
> +       { 0x30dd, 0x00 },
> +       { 0x30de, 0x00 },
> +       { 0x30df, 0x00 },
> +       { 0x30e0, 0x00 },
> +       { 0x30e1, 0x00 },
> +       { 0x332c, 0x00 },
> +       { 0x332d, 0x00 },
> +       { 0x334a, 0x00 },
> +       { 0x334b, 0x00 },
> +       { 0x35b6, 0x00 },
> +       { 0x35b7, 0x00 },
> +       { 0x35b8, 0x00 },
> +       { 0x35b9, 0x00 },
> +       { 0x36bc, 0x00 },
> +       { 0x36bd, 0x00 },
> +};
> +
> +static const struct imx492_reg mode_all_regs[] = {
> +       { 0x3033, 0x30 },
> +       { 0x303c, 0x01 },
> +       { 0x31e8, 0xa0 },
> +       { 0x31f4, 0x01 },
> +       { 0x31e9, 0x00 },
> +       { 0x3122, 0x02 },
> +       { 0x3129, 0x90 },
> +       { 0x312a, 0x02 },
> +       { 0x311f, 0x00 },
> +       { 0x3123, 0x00 },
> +       { 0x3124, 0x00 },
> +       { 0x3125, 0x01 },
> +       { 0x3127, 0x02 },
> +       { 0x312d, 0x02 },
> +       { 0x3000, 0x12 },
> +       { 0x310b, 0x00 },
> +       { 0x3004, 0x1c },
> +       { 0x3005, 0x06 },
> +       { 0x3006, 0x00 },
> +       { 0x3007, 0xa7 },
> +       { 0x3047, 0x02 },
> +       { 0x304e, 0x0b },
> +       { 0x304f, 0x2a },
> +       { 0x3052, 0xee },
> +       { 0x3062, 0x25 },
> +       { 0x3064, 0x78 },
> +       { 0x3065, 0x33 },
> +       { 0x3066, 0x64 },
> +       { 0x3067, 0x71 },
> +       { 0x307e, 0x07 },
> +       { 0x3081, 0x00 },
> +       { 0x3088, 0x75 },
> +       { 0x308a, 0x09 },
> +       { 0x308c, 0x61 },
> +       { 0x30ef, 0x01 },
> +       { 0x3146, 0x00 },
> +       { 0x31f5, 0x01 },
> +       { 0x3234, 0x32 },
> +       { 0x3248, 0xbc },
> +       { 0x3250, 0xbc },
> +       { 0x3258, 0xbc },
> +       { 0x3260, 0xbc },
> +       { 0x3274, 0x13 },
> +       { 0x3276, 0x00 },
> +       { 0x3277, 0x00 },
> +       { 0x327c, 0x13 },
> +       { 0x327e, 0x00 },
> +       { 0x327f, 0x00 },
> +       { 0x3284, 0x13 },
> +       { 0x3286, 0x00 },
> +       { 0x3287, 0x00 },
> +       { 0x328c, 0x13 },
> +       { 0x328e, 0x00 },
> +       { 0x328f, 0x00 },
> +       { 0x32ae, 0x00 },
> +       { 0x32af, 0x00 },
> +       { 0x32ca, 0x5a },
> +       { 0x332c, 0x00 },
> +       { 0x332f, 0x00 },
> +       { 0x334a, 0x00 },
> +       { 0x334c, 0x01 },
> +       { 0x3352, 0x50 },
> +       { 0x3356, 0x4f },
> +       { 0x335a, 0x79 },
> +       { 0x335e, 0x56 },
> +       { 0x3360, 0x6a },
> +       { 0x336a, 0x56 },
> +       { 0x33d6, 0x79 },
> +       { 0x340c, 0x6e },
> +       { 0x3448, 0x7e },
> +       { 0x348e, 0x6f },
> +       { 0x3492, 0x11 },
> +       { 0x34c4, 0x5a },
> +       { 0x3506, 0x56 },
> +       { 0x350c, 0x56 },
> +       { 0x350e, 0x58 },
> +       { 0x353d, 0x10 },
> +       { 0x3549, 0x04 },
> +       { 0x355d, 0x03 },
> +       { 0x355e, 0x03 },
> +       { 0x3574, 0x56 },
> +       { 0x357f, 0x0c },
> +       { 0x3580, 0x0a },
> +       { 0x3581, 0x08 },
> +       { 0x3583, 0x72 },
> +       { 0x3587, 0x01 },
> +       { 0x35b6, 0x00 },
> +       { 0x35b8, 0x00 },
> +       { 0x35d0, 0x5e },
> +       { 0x35d4, 0x63 },
> +       { 0x366a, 0x04 },
> +       { 0x366b, 0x04 },
> +       { 0x366c, 0x00 },
> +       { 0x366d, 0x00 },
> +       { 0x366e, 0x00 },
> +       { 0x366f, 0x00 },
> +       { 0x3670, 0x00 },
> +       { 0x3671, 0x05 },
> +       { 0x3676, 0x83 },
> +       { 0x3677, 0x03 },
> +       { 0x3678, 0x00 },
> +       { 0x3679, 0x04 },
> +       { 0x367a, 0x2c },
> +       { 0x367b, 0x05 },
> +       { 0x367d, 0x06 },
> +       { 0x367e, 0xff },
> +       { 0x367f, 0x06 },
> +       { 0x3680, 0x4b },
> +       { 0x3688, 0x05 },
> +       { 0x3690, 0x27 },
> +       { 0x3692, 0x65 },
> +       { 0x3694, 0x4f },
> +       { 0x3696, 0xa1 },
> +       { 0x36bc, 0x00 },
> +       { 0x371c, 0x02 },
> +       { 0x372f, 0x3c },
> +       { 0x3730, 0x01 },
> +       { 0x3732, 0xb8 },
> +       { 0x3734, 0x4a },
> +       { 0x3736, 0x57 },
> +       { 0x3738, 0x4d },
> +       { 0x3744, 0x0f },
> +       { 0x375b, 0x01 },
> +       { 0x382b, 0x68 },
> +       { 0x38b3, 0x00 },
> +       { 0x3910, 0x90 },
> +       { 0x3911, 0x70 },
> +       { 0x3912, 0x92 },
> +       { 0x3913, 0x24 },
> +       { 0x3914, 0x93 },
> +       { 0x3915, 0x0b },
> +       { 0x3916, 0x01 },
> +       { 0x3918, 0x04 },
> +       { 0x391c, 0x90 },
> +       { 0x391d, 0x05 },
> +       { 0x3920, 0x96 },
> +       { 0x3921, 0x06 },
> +       { 0x3a2a, 0x01 },
> +       { 0x3a7a, 0x01 },
> +       { 0x3a7b, 0x01 },
> +       { 0x3acb, 0x06 },
> +       { 0x3c08, 0x3f },
> +       { 0x3c0c, 0x1b },
> +       { 0x3e80, 0x14 },
> +       { 0x3e82, 0x30 },
> +       { 0x3e84, 0x0c },
> +       { 0x3e85, 0x06 },
> +       { 0x3e86, 0xfc },
> +       { 0x3e87, 0x10 },
> +       { 0x3e88, 0x03 },
> +       { 0x3e89, 0xfe },
> +       { 0x3e8a, 0x01 },
> +       { 0x3e8b, 0x06 },
> +       { 0x3e8e, 0x03 },
> +       { 0x3e8f, 0xfe },
> +       { 0x3e90, 0x01 },
> +       { 0x3e91, 0x06 },
> +       { 0x3e94, 0x33 },
> +       { 0x3e95, 0x01 },
> +       { 0x3e96, 0x19 },
> +       { 0x3e98, 0x30 },
> +       { 0x3e9a, 0x11 },
> +       { 0x3e9b, 0x06 },
> +       { 0x3e9c, 0xfc },
> +       { 0x3e9d, 0x10 },
> +       { 0x3e9e, 0xfe },
> +       { 0x3e9f, 0x03 },
> +       { 0x3ea0, 0x06 },
> +       { 0x3ea3, 0x01 },
> +       { 0x3ea4, 0xfe },
> +       { 0x3ea5, 0x03 },
> +       { 0x3ea6, 0x06 },
> +       { 0x3ea9, 0x33 },
> +       { 0x3eaa, 0x00 },
> +       { 0x3eab, 0x08 },
> +       { 0x3eac, 0x08 },
> +       { 0x3ead, 0x01 },
> +       { 0x3eae, 0x08 },
> +       { 0x3eaf, 0x08 },
> +       { 0x3eb0, 0x00 },
> +       { 0x3eb1, 0x10 },
> +       { 0x3eb2, 0x10 },
> +       { 0x3eb3, 0x01 },
> +       { 0x3eb4, 0x10 },
> +       { 0x3eb5, 0x10 },
> +       { 0x3eb6, 0x00 },
> +       { 0x3eb7, 0x00 },
> +       { 0x3eb8, 0x00 },
> +       { 0x3eb9, 0x00 },
> +       { 0x3eba, 0x00 },
> +       { 0x3ebb, 0x00 },
> +       { 0x3ec0, 0x54 },
> +       { 0x3ecc, 0x04 },
> +       { 0x3ecd, 0x04 },
> +       { 0x3ed0, 0xf0 },
> +       { 0x3ed1, 0x20 },
> +       { 0x3ed2, 0x0b },
> +       { 0x3ed3, 0x04 },
> +       { 0x3ed5, 0x13 },
> +       { 0x3ed6, 0x00 },
> +       { 0x3ed9, 0x0f },
> +       { 0x3ee4, 0x02 },
> +       { 0x3ee5, 0x02 },
> +       { 0x3ee7, 0x00 },
> +       { 0x3ef6, 0x00 },
> +       { 0x3ef8, 0x10 },
> +       { 0x3efa, 0x00 },
> +       { 0x3efc, 0x10 },
> +       { 0x3134, 0xa7 },
> +       { 0x3135, 0x00 },
> +       { 0x3136, 0x9f },
> +       { 0x3137, 0x00 },
> +       { 0x3138, 0x6f },
> +       { 0x3139, 0x00 },
> +       { 0x313a, 0x5f },
> +       { 0x313b, 0x00 },
> +       { 0x313c, 0x5f },
> +       { 0x313d, 0x00 },
> +       { 0x313e, 0x7f },
> +       { 0x313f, 0x01 },
> +       { 0x3140, 0x6f },
> +       { 0x3141, 0x00 },
> +       { 0x3142, 0x4f },
> +       { 0x3143, 0x00 },
> +       { 0x300e, 0x00 },
> +       { 0x300f, 0x00 },
> +       { 0x302c, 0x0c },
> +       { 0x302d, 0x00 },
> +       { 0x3034, 0x01 },
> +       { 0x3035, 0x01 },
> +       { 0x3036, 0x64 },
> +       { 0x3037, 0x00 },
> +       { 0x3038, 0xc8 },
> +       { 0x3039, 0x00 },
> +       { 0x3084, 0x4e },
> +       { 0x3085, 0x04 },
> +       { 0x3086, 0x4e },
> +       { 0x3087, 0x04 },
> +       { 0x30a9, 0xe0 },
> +       { 0x30aa, 0x2e },
> +       { 0x30ab, 0x00 },
> +       { 0x30ac, 0x48 },
> +       { 0x30ad, 0x0d },
> +       { 0x30e2, 0x00 },
> +       { 0x312f, 0x20 },
> +       { 0x3130, 0x1c },
> +       { 0x3131, 0x11 },
> +       { 0x3132, 0xfc },
> +       { 0x3133, 0x10 },
> +       { 0x3a54, 0xf0 },
> +       { 0x3a55, 0x20 },
> +       { 0x3a43, 0x01 },
> +       { 0x3a3b, 0x00 },
> +       { 0x3042, 0x32 },
> +       { 0x3092, 0x00 },
> +       { 0x30dd, 0x00 },
> +       { 0x30de, 0x00 },
> +       { 0x30df, 0x00 },
> +       { 0x30e0, 0x00 },
> +       { 0x30e1, 0x00 },
> +       { 0x332c, 0x00 },
> +       { 0x332d, 0x00 },
> +       { 0x334a, 0x00 },
> +       { 0x334b, 0x00 },
> +       { 0x35b6, 0x00 },
> +       { 0x35b7, 0x00 },
> +       { 0x35b8, 0x00 },
> +       { 0x35b9, 0x00 },
> +       { 0x36bc, 0x00 },
> +       { 0x36bd, 0x00 },
> +};
> +
> +#endif /* __imx492_h__ */
> -- 
> 2.30.2
>

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-25 15:31 ` [PATCH v1 3/5] media: i2c: imx492: driver's source Petko Manolov
  2022-11-28  5:16   ` Laurent Pinchart
@ 2022-11-28 12:58   ` Kieran Bingham
  2022-11-28 13:48     ` Petko Manolov
  1 sibling, 1 reply; 28+ messages in thread
From: Kieran Bingham @ 2022-11-28 12:58 UTC (permalink / raw)
  To: Petko Manolov, linux-media; +Cc: laurent.pinchart, sakari.ailus, Petko Manolov

Quoting Petko Manolov (2022-11-25 15:31:18)
> imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> digital output makes it possible to output the signals with high definition for
> moving pictures. It is programmable through I2C interface. The I2C client
> address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> through MIPI CSI-2.
> 
> Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> ---
>  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 1092 insertions(+)
>  create mode 100644 drivers/media/i2c/imx492.c
> 
> diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> new file mode 100644
> index 000000000000..0713256b4b63
> --- /dev/null
> +++ b/drivers/media/i2c/imx492.c
> @@ -0,0 +1,1092 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> + *
> + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> + */
> +
> +#include <asm/unaligned.h>
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "imx492.h"
> +
> +/* Streaming Mode */
> +#define IMX492_REG_MODE_SELECT 0x3000
> +
> +/* Chip ID */
> +#define IMX492_ID              0x13

This seems ... surprising to me.


> +
> +/* Analog gain control */
> +#define IMX492_REG_AGAIN       0x300a
> +#define IMX492_AGAIN_MIN       0
> +#define IMX492_AGAIN_MAX       978
> +#define IMX492_AGAIN_STEP      1
> +#define IMX492_AGAIN_DEFAULT   0
> +
> +/* Group hold register */
> +#define IMX492_REG_HOLD                0x302b
> +#define        IMX492_REG_XMSTA        0x3033
> +#define        IMX492_REG_SYSCLKEN     0x35e5
> +
> +/* CSI2 HW configuration */
> +#define IMX492_LINK_FREQ       745000000
> +#define IMX492_NUM_DATA_LANES  4
> +
> +#define IMX492_REG_MIN         0x3000
> +#define IMX492_REG_MAX         0xffff
> +
> +/* *** */
> +
> +#define IMX492_REG_STANDBY     IMX492_REG_MODE_SELECT

Is it a standby register? or a mode select register ?


> +#define IMX492_BIT_STANDBY     0x01
> +#define IMX492_BIT_STBLOGIC    0x02
> +#define IMX492_BIT_STBDV       0x10
> +
> +#define IMX492_MODE_STANDBY    (IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> +#define IMX492_MODE_STREAMING  0x00
> +
> +#define IMX492_REG_TESTPTRN    0x303A
> +#define IMX492_BIT_CLKEN       0x01
> +#define IMX492_BIT_TESTPTRN    0x10
> +#define IMX492_BITS_TPTRN_ON   (IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> +#define IMX492_BITS_TPTRN_OFF  0x00
> +
> +#define IMX492_REG_TESTPATSEL  0x303B
> +#define IMX492_BIT_TPAT00      0x00
> +#define IMX492_BIT_TPAT01      0x01
> +#define IMX492_BIT_TPAT02      0x02
> +#define IMX492_BIT_TPAT03      0x03
> +#define IMX492_BIT_TPAT0A      0x0A
> +#define IMX492_BIT_TPAT0B      0x0B
> +
> +#define IMX492_EXPOSURE_MIN            8
> +#define IMX492_EXPOSURE_OFFSET         22
> +#define IMX492_EXPOSURE_STEP           1
> +#define IMX492_EXPOSURE_DEFAULT                0x0648
> +
> +#define        DEFAULT_FPS             6
> +
> +/**
> + * struct imx492_reg_list - imx492 sensor register list
> + * @num_of_regs: Number of registers in the list
> + * @regs: Pointer to register list
> + */
> +struct imx492_reg_list {
> +       u32 num_of_regs;
> +       const struct imx492_reg *regs;
> +};
> +
> +/**
> + * struct imx492_mode - imx492 sensor mode structure
> + * @width: Frame width
> + * @height: Frame height
> + * @code: Format code
> + * @hblank: Horizontal blanking in lines
> + * @vblank: Vertical blanking in lines
> + * @vblank_min: Minimum vertical blanking in lines
> + * @vblank_max: Maximum vertical blanking in lines
> + * @pclk: Sensor pixel clock
> + * @link_freq_idx: Link frequency index
> + * @reg_list: Register list for sensor mode
> + */
> +struct imx492_mode {
> +       u32 width;
> +       u32 height;
> +       u32 code;
> +       u32 hblank;
> +       u32 hblank_min;
> +       u32 hblank_max;
> +       u32 vblank;
> +       u32 vblank_min;
> +       u32 vblank_max;
> +       u64 pclk;
> +       u32 link_freq_idx;
> +       struct imx492_reg_list reg_list;
> +};
> +
> +/**
> + * struct imx492 - imx492 sensor device structure
> + * @dev: Pointer to generic device
> + * @client: Pointer to i2c client
> + * @sd: V4L2 sub-device
> + * @pad: Media pad. Only one pad supported
> + * @reset_gpio: Sensor reset gpio
> + * @reset_gpio: Sensor power gpio
> + * @inclk: Sensor input clock
> + * @supplies: Regulator supplies
> + * @ctrl_handler: V4L2 control handler
> + * @link_freq_ctrl: Pointer to link frequency control
> + * @pclk_ctrl: Pointer to pixel clock control
> + * @hblank_ctrl: Pointer to horizontal blanking control
> + * @vblank_ctrl: Pointer to vertical blanking control
> + * @exp_ctrl: Pointer to exposure control
> + * @again_ctrl: Pointer to analog gain control
> + * @vblank: Vertical blanking in lines
> + * @cur_mode: Pointer to current selected sensor mode
> + * @mutex: Mutex for serializing sensor controls
> + * @streaming: Flag indicating streaming state
> + */
> +struct imx492 {
> +       struct device *dev;
> +       struct i2c_client *client;
> +       struct v4l2_subdev sd;
> +       struct media_pad pad;
> +       struct v4l2_captureparm scap;
> +       struct gpio_desc *reset_gpio;
> +       struct gpio_desc *power_gpio;
> +       struct gpio_desc *oscen_gpio;
> +       struct clk *inclk;
> +       struct v4l2_ctrl_handler ctrl_handler;
> +       struct v4l2_ctrl *link_freq_ctrl;
> +       struct v4l2_ctrl *pclk_ctrl;
> +       struct v4l2_ctrl *hblank_ctrl;
> +       struct v4l2_ctrl *vblank_ctrl;
> +       struct v4l2_ctrl *exp_ctrl;
> +       struct v4l2_ctrl *again_ctrl;
> +       const struct imx492_mode *cur_mode;
> +       struct mutex mutex;
> +       u32 tpatt;
> +       u32 vblank;
> +       bool streaming;
> +};
> +
> +static const s64 link_freq[] = {
> +       IMX492_LINK_FREQ,
> +};
> +
> +
> +/* Supported sensor mode configurations */
> +static const struct imx492_mode supported_modes[] = {
> +       {
> +               .width = 8192,
> +               .height = 4320,
> +               .hblank = 1108,
> +               .hblank_min = 1102,
> +               .hblank_max = 32768,
> +               .vblank = 5728,
> +               .vblank_min = 4428,
> +               .vblank_max = 32768,
> +               .pclk = 745000000,
> +               .link_freq_idx = 0,
> +               .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +               .reg_list = {
> +                       .num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> +                       .regs = mode_17to9_regs,
> +               },
> +       }, {
> +               .width = 8192,
> +               .height = 5556,
> +               .hblank = 1108,
> +               .hblank_min = 1102,
> +               .hblank_max = 32768,
> +               .vblank = 5728,
> +               .vblank_min = 4428,
> +               .vblank_max = 32768,
> +               .pclk = 745000000,
> +               .link_freq_idx = 0,
> +               .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +               .reg_list = {
> +                       .num_of_regs = ARRAY_SIZE(mode_all_regs),
> +                       .regs = mode_all_regs,
> +               },
> +       },
> +};
> +
> +static const char * const imx492_test_pattern_menu[] = {
> +       "Disabled",
> +       "Solid black",
> +       "Solid white",
> +       "Solid dark grey",
> +       "Solid light gray",
> +       "None",
> +       "None",
> +       "None",
> +       "None",
> +       "None",
> +       "None",

Why so many 'none' entries. Can this be improved?

> +       "Vertical color bars",
> +       "Horizontal color bars",
> +};
> +
> +/**
> + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> + * @subdev: pointer to imx492 V4L2 sub-device
> + *
> + * Return: pointer to imx492 device
> + */
> +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> +{
> +       return container_of(subdev, struct imx492, sd);
> +}
> +
> +/**
> + * imx492_read_reg() - Read registers.
> + * @imx492: pointer to imx492 device
> + * @reg: register address
> + * @len: length of bytes to read. Max supported bytes is 4
> + * @val: pointer to register value to be filled.
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> +{
> +       struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> +       struct i2c_msg msgs[2] = {0};
> +       u8 addr_buf[2] = {0};
> +       u8 data_buf[4] = {0};
> +       int ret;
> +
> +       if (WARN_ON(len > 4))
> +               return -EINVAL;
> +
> +       put_unaligned_be16(reg, addr_buf);
> +
> +       /* Write register address */
> +       msgs[0].addr = client->addr;
> +       msgs[0].flags = 0;
> +       msgs[0].len = ARRAY_SIZE(addr_buf);
> +       msgs[0].buf = addr_buf;
> +
> +       /* Read data from register */
> +       msgs[1].addr = client->addr;
> +       msgs[1].flags = I2C_M_RD;
> +       msgs[1].len = len;
> +       msgs[1].buf = &data_buf[4 - len];
> +
> +       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> +       if (ret != ARRAY_SIZE(msgs))
> +               return -EIO;
> +
> +       *val = get_unaligned_be32(data_buf);
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_write_reg() - Write register
> + * @imx492: pointer to imx492 device
> + * @reg: register address
> + * @len: length of bytes. Max supported bytes is 4
> + * @val: register value
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> +{
> +       struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> +       u8 buf[6] = {0};
> +
> +       if (WARN_ON(len > 4))
> +               return -EINVAL;
> +
> +       put_unaligned_be16(reg, buf);
> +       put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> +       if (i2c_master_send(client, buf, len + 2) != len + 2)
> +               return -EIO;
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_write_regs() - Write a list of registers
> + * @imx492: pointer to imx492 device
> + * @regs: list of registers to be written
> + * @len: length of registers array
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_write_regs(struct imx492 *imx492,
> +                            const struct imx492_reg *regs, u32 len)
> +{
> +       unsigned int i;
> +       int ret;
> +
> +       for (i = 0; i < len; i++) {
> +               ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> +{
> +       /* for now this is the only format we support */
> +       return MEDIA_BUS_FMT_SGBRG12_1X12;
> +}
> +
> +/**
> + * imx492_update_controls() - Update control ranges based on streaming mode
> + * @imx492: pointer to imx492 device
> + * @mode: pointer to imx492_mode sensor mode
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_update_controls(struct imx492 *imx492,
> +                                 const struct imx492_mode *mode)
> +{
> +       int ret;
> +
> +       ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> +       if (ret)
> +               return ret;
> +
> +       ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> +       if (ret)
> +               return ret;
> +
> +       return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> +                                       mode->vblank_max, 1, mode->vblank);
> +}
> +
> +/**
> + * imx492_update_exp_gain() - Set updated exposure and gain
> + * @imx492: pointer to imx492 device
> + * @exposure: updated exposure value
> + * @gain: updated analog gain value
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> +{
> +       u32 lpfr, shutter;
> +       int ret;
> +
> +       lpfr = imx492->vblank + imx492->cur_mode->height;
> +       shutter = lpfr - exposure;
> +
> +       ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> +       if (ret)
> +               return ret;
> +
> +       ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> +
> +       return ret;
> +}
> +
> +/**
> + * imx492_set_ctrl() - Set subdevice control
> + * @ctrl: pointer to v4l2_ctrl structure
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +       struct imx492 *imx492 =
> +               container_of(ctrl->handler, struct imx492, ctrl_handler);
> +       u32 analog_gain;
> +       u32 exposure;
> +       int ret;
> +
> +       switch (ctrl->id) {
> +       case V4L2_CID_VBLANK:
> +               imx492->vblank = imx492->vblank_ctrl->val;
> +
> +               ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> +                                              IMX492_EXPOSURE_MIN,
> +                                              imx492->vblank +
> +                                              imx492->cur_mode->height -
> +                                              IMX492_EXPOSURE_OFFSET,
> +                                              1, IMX492_EXPOSURE_DEFAULT);
> +               break;
> +       case V4L2_CID_EXPOSURE:
> +               /* Set controls only if sensor is in power on state */
> +               if (!pm_runtime_get_if_in_use(imx492->dev))
> +                       return 0;
> +               exposure = ctrl->val;
> +               analog_gain = imx492->again_ctrl->val;
> +               ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> +               pm_runtime_put(imx492->dev);
> +               break;
> +       case V4L2_CID_TEST_PATTERN:
> +               if (ctrl->val) {
> +                       imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> +                       imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> +               } else {
> +                       imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> +               }
> +               ret = 0;
> +               break;
> +       default:
> +               dev_err(imx492->dev, "Invalid control %d", ctrl->id);
> +               ret = -EINVAL;
> +       }
> +
> +       return ret;
> +}
> +
> +/* V4l2 subdevice control ops*/
> +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> +       .s_ctrl = imx492_set_ctrl,
> +};
> +
> +/**
> + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @code: V4L2 sub-device code enumeration need to be filled
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_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(supported_modes))
> +               return -EINVAL;
> +
> +       code->code = supported_modes[code->index].code;
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fsize: V4L2 sub-device size enumeration need to be filled
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> +                                 struct v4l2_subdev_state *sd_state,
> +                                 struct v4l2_subdev_frame_size_enum *fsize)
> +{
> +       if (fsize->index > ARRAY_SIZE(supported_modes))
> +               return -EINVAL;
> +
> +       if (fsize->code != supported_modes[fsize->index].code)
> +               return -EINVAL;
> +
> +       fsize->max_width = supported_modes[fsize->index].width;
> +       fsize->min_width = fsize->max_width;
> +       fsize->max_height = supported_modes[fsize->index].height;
> +       fsize->min_height = fsize->max_height;
> +
> +       return 0;
> +}
> +
> +/**
> +n * imx492_fill_pad_format() - Fill subdevice pad format
> + *                            from selected sensor mode
> + * @imx492: pointer to imx492 device
> + * @mode: pointer to imx492_mode sensor mode
> + * @fmt: V4L2 sub-device format need to be filled
> + */
> +static void imx492_fill_pad_format(struct imx492 *imx492,
> +                                  const struct imx492_mode *mode,
> +                                  struct v4l2_subdev_format *fmt)
> +{
> +       fmt->format.width = mode->width;
> +       fmt->format.height = mode->height;
> +       fmt->format.code = mode->code;
> +       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;
> +}
> +
> +/**
> + * imx492_get_pad_format() - Get subdevice pad format
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fmt: V4L2 sub-device format need to be set
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> +                                struct v4l2_subdev_state *sd_state,
> +                                struct v4l2_subdev_format *fmt)
> +{
> +       struct imx492 *imx492 = to_imx492(sd);
> +
> +       mutex_lock(&imx492->mutex);
> +
> +       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +               struct v4l2_mbus_framefmt *framefmt;
> +
> +               framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> +               fmt->format = *framefmt;
> +       } else {
> +               imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> +       }
> +
> +       mutex_unlock(&imx492->mutex);
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_set_pad_format() - Set subdevice pad format
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + * @fmt: V4L2 sub-device format need to be set
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> +                                struct v4l2_subdev_state *sd_state,
> +                                struct v4l2_subdev_format *fmt)
> +{
> +       struct imx492 *imx492 = to_imx492(sd);
> +       const struct imx492_mode *mode;
> +       int ret = 0;
> +
> +       mutex_lock(&imx492->mutex);
> +
> +       fmt->format.code = imx492_get_format_code(imx492, 0);
> +       mode = v4l2_find_nearest_size(supported_modes,
> +                                       ARRAY_SIZE(supported_modes),
> +                                       width, height,
> +                                       fmt->format.width, fmt->format.height);
> +       imx492_fill_pad_format(imx492, mode, fmt);
> +
> +       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +               struct v4l2_mbus_framefmt *framefmt;
> +
> +               framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> +               *framefmt = fmt->format;
> +       } else {
> +               ret = imx492_update_controls(imx492, mode);
> +               if (!ret)
> +                       imx492->cur_mode = mode;
> +       }
> +
> +       mutex_unlock(&imx492->mutex);
> +
> +       return ret;
> +}
> +
> +/**
> + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> + * @sd: pointer to imx492 V4L2 sub-device structure
> + * @sd_state: V4L2 sub-device configuration
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> +                              struct v4l2_subdev_state *sd_state)
> +{
> +       struct imx492 *imx492 = to_imx492(sd);
> +       struct v4l2_subdev_format fmt = { 0 };
> +
> +       fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
> +       imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> +
> +       return imx492_set_pad_format(sd, sd_state, &fmt);
> +}
> +
> +/**
> + * imx492_start_streaming() - Start sensor stream
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_start_streaming(struct imx492 *imx492)
> +{
> +       const struct imx492_reg_list *reg_list;
> +       int ret;
> +
> +       /* Write sensor mode registers */
> +       reg_list = &imx492->cur_mode->reg_list;
> +       ret = imx492_write_regs(imx492, reg_list->regs,
> +                               reg_list->num_of_regs);
> +       if (ret) {
> +               dev_err(imx492->dev, "fail to write initial registers");
> +               return ret;
> +       }
> +
> +       /* Setup handler will write actual exposure and gain */
> +       ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> +       if (ret) {
> +               dev_err(imx492->dev, "fail to setup handler");
> +               return ret;
> +       }
> +
> +       /* 1st stabilization period */
> +       usleep_range(10000, 11000);
> +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> +       imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> +       imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> +
> +       /* 2nd stabilization period */
> +       usleep_range(7000, 8000);
> +
> +       /* Start streaming */
> +       ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> +
> +       if (ret) {
> +               dev_err(imx492->dev, "fail to start streaming");
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_stop_streaming() - Stop sensor stream
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static void imx492_stop_streaming(struct imx492 *imx492)
> +{
> +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> +       imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> +}
> +
> +/**
> + * imx492_set_stream() - Enable sensor streaming
> + * @sd: pointer to imx492 subdevice
> + * @enable: set to enable sensor streaming
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> +{
> +       struct imx492 *imx492 = to_imx492(sd);
> +       int ret;
> +
> +       mutex_lock(&imx492->mutex);
> +
> +       if (imx492->streaming == enable) {
> +               mutex_unlock(&imx492->mutex);
> +               return 0;
> +       }
> +
> +       if (enable) {
> +               ret = pm_runtime_resume_and_get(imx492->dev);
> +               if (ret)
> +                       goto error_unlock;
> +               ret = imx492_start_streaming(imx492);
> +               if (ret)
> +                       goto error_power_off;
> +       } else {
> +               imx492_stop_streaming(imx492);
> +               pm_runtime_put(imx492->dev);
> +       }
> +
> +       imx492->streaming = enable;
> +
> +       mutex_unlock(&imx492->mutex);
> +
> +       return 0;
> +
> +error_power_off:
> +       pm_runtime_put(imx492->dev);
> +error_unlock:
> +       mutex_unlock(&imx492->mutex);
> +
> +       return ret;
> +}
> +
> +/**
> + * imx492_detect() - Detect imx492 sensor
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, -EIO if sensor id does not match
> + */
> +static int imx492_detect(struct imx492 *imx492)
> +{
> +       int ret;
> +       u32 val;
> +
> +       ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);

This seems an odd register to read for the ID?

And why is it mapped to IMX492_REG_MODE_SELECT ?
How does this give us the ID?

> +       if (ret)
> +               return ret;
> +
> +       if (val != IMX492_ID) {

And seeing other IMX sensors, I would have expected the IMX492_ID to be
0x0492 ?

What is the contents of register 0x0016 ?



> +               dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> +               return -ENXIO;
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_parse_hw_config(struct imx492 *imx492)
> +{
> +       struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> +       struct v4l2_fwnode_endpoint bus_cfg = {
> +               .bus_type = V4L2_MBUS_CSI2_DPHY
> +       };
> +       struct fwnode_handle *ep;
> +       unsigned int i;
> +       int ret;
> +
> +       if (!fwnode)
> +               return -ENXIO;
> +
> +       imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
> +       if (IS_ERR(imx492->power_gpio)) {
> +               dev_err(imx492->dev, "failed to get power gpio %ld",
> +                       PTR_ERR(imx492->power_gpio));
> +               return PTR_ERR(imx492->power_gpio);
> +       }
> +
> +       imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
> +       if (IS_ERR(imx492->oscen_gpio)) {
> +               dev_err(imx492->dev, "failed to get oscen gpio %ld",
> +                       PTR_ERR(imx492->oscen_gpio));
> +               return PTR_ERR(imx492->oscen_gpio);
> +       }
> +
> +       imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> +       if (IS_ERR(imx492->reset_gpio)) {
> +               dev_err(imx492->dev, "failed to get reset gpio %ld",
> +                       PTR_ERR(imx492->reset_gpio));
> +               return PTR_ERR(imx492->reset_gpio);
> +       }
> +
> +       if (gpiod_direction_output(imx492->power_gpio, 1) ||
> +           gpiod_direction_output(imx492->oscen_gpio, 1) ||
> +           gpiod_direction_output(imx492->reset_gpio, 0)) {
> +               dev_err(imx492->dev, "failed to change gpio direction");
> +               return -EINVAL;
> +       }
> +
> +       /* Get sensor input clock */
> +       imx492->inclk = devm_clk_get(imx492->dev, NULL);
> +       if (IS_ERR(imx492->inclk)) {
> +               dev_err(imx492->dev, "could not get inclk");
> +               return PTR_ERR(imx492->inclk);
> +       }
> +
> +       ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> +       if (!ep) {
> +               dev_err(imx492->dev, "next endpoint?");
> +               return -ENXIO;
> +       }
> +
> +       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> +       fwnode_handle_put(ep);
> +       if (ret) {
> +               dev_err(imx492->dev, "endpoint alloc parse");
> +               return ret;
> +       }
> +
> +       if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> +               dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> +                       bus_cfg.bus.mipi_csi2.num_data_lanes);
> +               ret = -EINVAL;
> +               goto done_endpoint_free;
> +       }
> +
> +       if (!bus_cfg.nr_of_link_frequencies) {
> +               dev_err(imx492->dev, "no link frequencies defined");
> +               ret = -EINVAL;
> +               goto done_endpoint_free;
> +       }
> +
> +       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> +               if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> +                       goto done_endpoint_free;
> +       }
> +
> +       ret = -EINVAL;
> +
> +done_endpoint_free:
> +       v4l2_fwnode_endpoint_free(&bus_cfg);
> +
> +       return ret;
> +}
> +
> +/* V4l2 subdevice ops */
> +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> +       .s_stream = imx492_set_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> +       .init_cfg = imx492_init_pad_cfg,
> +       .enum_mbus_code = imx492_enum_mbus_code,
> +       .enum_frame_size = imx492_enum_frame_size,
> +       .get_fmt = imx492_get_pad_format,
> +       .set_fmt = imx492_set_pad_format,
> +};
> +
> +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> +       .video = &imx492_video_ops,
> +       .pad = &imx492_pad_ops,
> +};
> +
> +/**
> + * imx492_power_on() - Sensor power on sequence
> + * @dev: pointer to i2c device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_power_on(struct device *dev)
> +{
> +       struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +       struct imx492 *imx492 = to_imx492(sd);
> +
> +       gpiod_set_value_cansleep(imx492->power_gpio, 1);
> +       msleep(1);
> +       gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> +       msleep(1);
> +       gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> +       msleep(1);
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_power_off() - Sensor power off sequence
> + * @dev: pointer to i2c device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_power_off(struct device *dev)
> +{
> +       struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +       struct imx492 *imx492 = to_imx492(sd);
> +
> +       gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> +       gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> +       gpiod_set_value_cansleep(imx492->power_gpio, 0);
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_init_controls() - Initialize sensor subdevice controls
> + * @imx492: pointer to imx492 device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_init_controls(struct imx492 *imx492)
> +{
> +       struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> +       const struct imx492_mode *mode = imx492->cur_mode;
> +       u32 lpfr;
> +       int ret;
> +
> +       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> +       if (ret)
> +               return ret;
> +
> +       /* Serialize controls with sensor device */
> +       ctrl_hdlr->lock = &imx492->mutex;
> +       /* Initialize exposure and gain */
> +       lpfr = mode->vblank + mode->height;
> +       imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +                                            &imx492_ctrl_ops,
> +                                            V4L2_CID_EXPOSURE,
> +                                            IMX492_EXPOSURE_MIN,
> +                                            lpfr - IMX492_EXPOSURE_OFFSET,
> +                                            IMX492_EXPOSURE_STEP,
> +                                            IMX492_EXPOSURE_DEFAULT);
> +
> +       imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +                                              &imx492_ctrl_ops,
> +                                              V4L2_CID_ANALOGUE_GAIN,
> +                                              IMX492_AGAIN_MIN,
> +                                              IMX492_AGAIN_MAX,
> +                                              IMX492_AGAIN_STEP,
> +                                              IMX492_AGAIN_DEFAULT);
> +
> +       v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> +
> +       imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +                                               &imx492_ctrl_ops,
> +                                               V4L2_CID_VBLANK,
> +                                               mode->vblank_min,
> +                                               mode->vblank_max,
> +                                               1, mode->vblank);
> +       /* Read only controls */
> +       imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +                                               &imx492_ctrl_ops,
> +                                               V4L2_CID_HBLANK,
> +                                               mode->hblank_min,
> +                                               mode->hblank_max,
> +                                               1, mode->hblank);
> +       if (imx492->hblank_ctrl)
> +               imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +       imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> +                                             &imx492_ctrl_ops,
> +                                             V4L2_CID_PIXEL_RATE,
> +                                             mode->pclk, mode->pclk,
> +                                             1, mode->pclk);
> +
> +       imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> +                                                       &imx492_ctrl_ops,
> +                                                       V4L2_CID_LINK_FREQ,
> +                                                       ARRAY_SIZE(link_freq) -
> +                                                       1,
> +                                                       mode->link_freq_idx,
> +                                                       link_freq);
> +       if (imx492->link_freq_ctrl)
> +               imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> +                                    V4L2_CID_TEST_PATTERN,
> +                                    ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> +                                    0, 0, imx492_test_pattern_menu);
> +
> +       if (ctrl_hdlr->error) {
> +               dev_err(imx492->dev, "control init failed: %d", ctrl_hdlr->error);
> +               v4l2_ctrl_handler_free(ctrl_hdlr);
> +               return ctrl_hdlr->error;
> +       }
> +
> +       imx492->sd.ctrl_handler = ctrl_hdlr;
> +
> +       return 0;
> +}
> +
> +/**
> + * imx492_probe() - I2C client device binding
> + * @client: pointer to i2c client device
> + *
> + * Return: 0 if successful, error code otherwise.
> + */
> +static int imx492_probe(struct i2c_client *client)
> +{
> +       struct imx492 *imx492;
> +       int ret;
> +
> +       imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> +       if (!imx492)
> +               return -ENOMEM;
> +
> +       imx492->dev = &client->dev;
> +
> +       /* Initialize subdev */
> +       v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> +
> +       ret = imx492_parse_hw_config(imx492);
> +       if (ret) {
> +               dev_err(imx492->dev, "HW configuration is not supported");
> +               return ret;
> +       }
> +
> +       mutex_init(&imx492->mutex);
> +
> +       ret = imx492_power_on(imx492->dev);
> +       if (ret) {
> +               dev_err(imx492->dev, "failed to power-on the sensor");
> +               goto error_mutex_destroy;
> +       }
> +
> +       /* Check module identity */
> +       ret = imx492_detect(imx492);
> +       if (ret) {
> +               dev_err(imx492->dev, "failed to find sensor: %d", ret);
> +               goto error_power_off;
> +       }
> +
> +       /* Set default mode to max resolution */
> +       imx492->cur_mode = &supported_modes[0];
> +       imx492->vblank = imx492->cur_mode->vblank;
> +
> +       ret = imx492_init_controls(imx492);
> +       if (ret) {
> +               dev_err(imx492->dev, "failed to init controls: %d", ret);
> +               goto error_power_off;
> +       }
> +
> +       /* Initialize subdev */
> +       imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +       imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> +       imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> +       imx492->scap.capturemode = 0;
> +       imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> +       imx492->scap.timeperframe.numerator = 1;
> +
> +       /* Initialize source pad */
> +       imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> +       ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> +       if (ret) {
> +               dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> +               goto error_handler_free;
> +       }
> +
> +       ret = v4l2_async_register_subdev(&imx492->sd);
> +       if (ret < 0) {
> +               dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> +               goto error_media_entity;
> +       }
> +
> +       pm_runtime_set_active(imx492->dev);
> +       pm_runtime_enable(imx492->dev);
> +       pm_runtime_idle(imx492->dev);
> +
> +       return 0;
> +
> +error_media_entity:
> +       media_entity_cleanup(&imx492->sd.entity);
> +error_handler_free:
> +       v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> +error_power_off:
> +       imx492_power_off(imx492->dev);
> +error_mutex_destroy:
> +       mutex_destroy(&imx492->mutex);
> +
> +       return ret;
> +}
> +
> +/**
> + * imx492_remove() - I2C client device unbinding
> + * @client: pointer to I2C client device
> + */
> +static void imx492_remove(struct i2c_client *client)
> +{
> +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +       struct imx492 *imx492 = to_imx492(sd);
> +
> +       v4l2_async_unregister_subdev(sd);
> +       media_entity_cleanup(&sd->entity);
> +       v4l2_ctrl_handler_free(sd->ctrl_handler);
> +       pm_runtime_disable(&client->dev);
> +       if (!pm_runtime_status_suspended(&client->dev))
> +               imx492_power_off(&client->dev);
> +       pm_runtime_set_suspended(&client->dev);
> +       mutex_destroy(&imx492->mutex);
> +}
> +
> +static const struct dev_pm_ops imx492_pm_ops = {
> +       SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> +};
> +
> +static const struct of_device_id imx492_of_match[] = {
> +       { .compatible = "sony,imx492_mipi" },

This doesn't match the bindings. I think the _mipi should just be
removed.


> +       { }
> +};
> +
> +MODULE_DEVICE_TABLE(of, imx492_of_match);
> +
> +static struct i2c_driver imx492_driver = {
> +       .probe_new = imx492_probe,
> +       .remove = imx492_remove,
> +       .driver = {
> +               .name = "imx492",
> +               .pm = &imx492_pm_ops,
> +               .of_match_table = imx492_of_match,
> +       },
> +};
> +
> +module_i2c_driver(imx492_driver);
> +
> +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.30.2
>

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

* Re: [PATCH v1 1/5] DT bindings for imx492
  2022-11-28  4:37   ` Laurent Pinchart
@ 2022-11-28 13:07     ` Petko Manolov
  2022-11-28 13:28       ` Laurent Pinchart
  0 siblings, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:07 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-media, sakari.ailus

On 22-11-28 06:37:58, Laurent Pinchart wrote:
> Hi Petko,
> 
> Thank you for the patch.
> 
> The subject line should start with the proper prefix. Look at the git
> log in the directory to see what is customary. Furthermore,
> s/imx492/Sony IMX492/.
> 
> On Fri, Nov 25, 2022 at 05:31:16PM +0200, Petko Manolov wrote:
> > Here goes the DT bindings file.
> 
> This is also a peculiar commit message :-)

Short and to the point, isn't it? :)

Honestly, i'm not sure what else i should put as subject line, apart from "Sony
IMX492".

> > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > ---
> >  .../bindings/media/i2c/sony,imx492.yaml       | 101 ++++++++++++++++++
> >  1 file changed, 101 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > new file mode 100644
> > index 000000000000..f4feef17c677
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > @@ -0,0 +1,101 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/i2c/sony,imx492.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Sony imx492 Sensor
> 
> s/imx492/IMX492/. Same below. When referring to the hardware, it's
> customary to use uppercase.

OK.

> > +
> > +maintainers:
> > +  - Petko Manolov <petko.manolov@konsulko.com>
> > +
> > +description:
> > +
> > +  imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > +  monochrome square pixel array and approximately 47.08 M effective pixels.
> > +  12-bit digital output makes it possible to output the signals with high
> > +  definition for moving pictures. It is programmable through I2C interface. The
> > +  I2C client address can be either 0x10 or 0x1a depending on SLASEL pin. Image
> > +  data is sent through MIPI CSI-2.
> > +
> > +properties:
> > +  compatible:
> > +    const: sony,imx492
> 
> Missing blank line.

OK.

> > +  reg:
> > +    description: I2C address
> 
> You can drop the description.
> 
> > +    maxItems: 1
> > +
> > +  assigned-clocks: true
> > +  assigned-clock-parents: true
> > +  assigned-clock-rates: true
> 
> This shouldn't be needed.

OK.

> > +
> > +  clocks:
> > +    description: Clock frequency 6MHz, 12MHz, 18MHz and 24MHz
> 
> If you know the name of the clock pin, I would include it here.

OK.

> > +    maxItems: 1
> > +
> > +  dovdd-supply:
> > +    description: Interface power supply.
> 
> I would list the voltage. Same below.

OK.

> > +
> > +  avdd-supply:
> > +    description: Analog power supply.
> > +
> > +  dvdd-supply:
> > +    description: Digital power supply.
> > +
> > +  reset-gpios:
> > +    description: Reference to the GPIO connected to the XCLR pin, if any.
> > +    maxItems: 1
> > +
> > +  port:
> > +    additionalProperties: false
> > +    $ref: /schemas/graph.yaml#/$defs/port-base
> > +
> > +    properties:
> > +      endpoint:
> > +        $ref: /schemas/media/video-interfaces.yaml#
> > +        unevaluatedProperties: false
> > +
> > +        properties:
> > +          data-lanes: true
> > +          link-frequencies: true
> > +
> > +        required:
> > +          - data-lanes
> > +          - link-frequencies
> > +
> > +    required:
> > +      - endpoint
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - port
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    i2c0 {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        camera@10 {
> > +            compatible = "sony,imx492";
> > +            reg = <0x10>;
> > +            clocks = <&imx492_clk>;
> > +
> > +            assigned-clocks = <&imx492_clk>;
> > +            assigned-clock-parents = <&imx492_clk_parent>;
> > +            assigned-clock-rates = <24000000>;
> 
> You can drop this from the example, it doesn't showcase the DT bindings for
> the IMX492.

OK.

> > +
> > +            port {
> > +                imx492: endpoint {
> 
> s/imx492/imx492_out/
> 
> > +                    remote-endpoint = <&cam>;
> 
> s/cam/cam_in/

OK to both of the above.

> > +                    data-lanes = <1 2 3 4>;
> > +                    link-frequencies = /bits/ 64 <600000000>;
> > +                };
> > +            };
> > +        };
> > +    };
> > +...
> 
> -- 
> Regards,
> 
> Laurent Pinchart


cheers,
Petko

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-28 12:45 ` [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Kieran Bingham
@ 2022-11-28 13:11   ` Petko Manolov
  2022-11-28 13:38     ` Kieran Bingham
  0 siblings, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:11 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-media, laurent.pinchart, sakari.ailus

On 22-11-28 12:45:32, Kieran Bingham wrote:
> Hi Petko,
> 
> What device/ISP are you testing this sensor on?

I'll tell you, but only if you promise to not laugh too much.  Deal?

i.MX8M-Mini

I hope nobody will notice the above line...

> Quoting Petko Manolov (2022-11-25 15:31:15)
> > This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> > image sensor.
> > 
> > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > digital output makes it possible to output the signals with high definition for
> > moving pictures. It is programmable through I2C interface. The I2C client
> > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > through MIPI CSI-2.
> > 
> > Petko Manolov (5):
> >   DT bindings for imx492
> >   media: i2c: imx492: driver's header
> >   media: i2c: imx492: driver's source
> >   media: i2c: add imx492 config entry
> >   media: i2c: add imx492 entry for make
> 
> Could you squash patches 2, 3, 4, and 5 into a single patch please?

This is the exact opposite to what the networking folks would prefer, but it's
OK with me.

> Also - I think you'll need an entry in MAINTAINERS.

Right, that one too.

> I can't see any reference to the selection controls:
>  - V4L2_SEL_TGT_CROP_DEFAULT
>  - V4L2_SEL_TGT_CROP
>  - V4L2_SEL_TGT_CROP_BOUNDS

These are in a very early phase of implementing.

> Do you have the datasheet or sufficient information to be able to implement
> these controls?

Of course not.  We are brute forcing our way forward by mostly reverse
engineering another solution that has an FPGA on the other end of the CSI link.

> --
> Kieran
> 
> >  .../bindings/media/i2c/sony,imx492.yaml       |  101 ++
> >  drivers/media/i2c/Kconfig                     |   14 +
> >  drivers/media/i2c/Makefile                    |    1 +
> >  drivers/media/i2c/imx492.c                    | 1092 +++++++++++++++++
> >  drivers/media/i2c/imx492.h                    |  555 +++++++++
> >  5 files changed, 1763 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> >  create mode 100644 drivers/media/i2c/imx492.c
> >  create mode 100644 drivers/media/i2c/imx492.h
> > 
> > -- 
> > 2.30.2
> >


		Petko

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-28  4:40   ` Laurent Pinchart
@ 2022-11-28 13:12     ` Petko Manolov
  0 siblings, 0 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:12 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-media, sakari.ailus

On 22-11-28 06:40:23, Laurent Pinchart wrote:
> Hi Petko,
> 
> Thank you for the patch.
> 
> On Fri, Nov 25, 2022 at 05:31:17PM +0200, Petko Manolov wrote:
> > The header.  For the moment only two modes are supported.
> 
> No need to split this in a separate patch, you can squash patches 2/5 to 5/5
> together for v2.

Yup.

> > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > ---
> >  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
> >  1 file changed, 555 insertions(+)
> >  create mode 100644 drivers/media/i2c/imx492.h
> > 
> > diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> > new file mode 100644
> > index 000000000000..301fd66c77d5
> > --- /dev/null
> > +++ b/drivers/media/i2c/imx492.h
> > @@ -0,0 +1,555 @@
> 
> Missing SPDX license header. Please run checkpath.pl on the whole series.

OK.

> > +#ifndef	__imx492_h__
> > +#define	__imx492_h__
> 
> checkpatch.pl will also complain about this.
> 
> > +
> > +struct imx492_reg {
> > +	u16 address;
> > +	u8 val;
> > +};
> > +
> > +static const struct imx492_reg mode_17to9_regs[] = {
> > +	{ 0x3033, 0x30 },
> > +	{ 0x303c, 0x01 },
> > +	{ 0x31e8, 0xa0 },
> > +	{ 0x31f4, 0x01 },
> > +	{ 0x31e9, 0x00 },
> > +	{ 0x3122, 0x02 },
> > +	{ 0x3129, 0x90 },
> > +	{ 0x312a, 0x02 },
> > +	{ 0x311f, 0x00 },
> > +	{ 0x3123, 0x00 },
> > +	{ 0x3124, 0x00 },
> > +	{ 0x3125, 0x01 },
> > +	{ 0x3127, 0x02 },
> > +	{ 0x312d, 0x02 },
> > +	{ 0x3000, 0x12 },
> > +	{ 0x310b, 0x00 },
> > +	{ 0x3004, 0x1c },
> > +	{ 0x3005, 0x06 },
> > +	{ 0x3006, 0x00 },
> > +	{ 0x3007, 0xa7 },
> > +	{ 0x3047, 0x02 },
> > +	{ 0x304e, 0x0b },
> > +	{ 0x304f, 0x2a },
> > +	{ 0x3052, 0xee },
> > +	{ 0x3062, 0x25 },
> > +	{ 0x3064, 0x78 },
> > +	{ 0x3065, 0x33 },
> > +	{ 0x3066, 0x64 },
> > +	{ 0x3067, 0x71 },
> > +	{ 0x307e, 0x07 },
> > +	{ 0x3081, 0x00 },
> > +	{ 0x3088, 0x75 },
> > +	{ 0x308a, 0x09 },
> > +	{ 0x308c, 0x61 },
> > +	{ 0x30ef, 0x01 },
> > +	{ 0x3146, 0x00 },
> > +	{ 0x31f5, 0x01 },
> > +	{ 0x3234, 0x32 },
> > +	{ 0x3248, 0xbc },
> > +	{ 0x3250, 0xbc },
> > +	{ 0x3258, 0xbc },
> > +	{ 0x3260, 0xbc },
> > +	{ 0x3274, 0x13 },
> > +	{ 0x3276, 0x00 },
> > +	{ 0x3277, 0x00 },
> > +	{ 0x327c, 0x13 },
> > +	{ 0x327e, 0x00 },
> > +	{ 0x327f, 0x00 },
> > +	{ 0x3284, 0x13 },
> > +	{ 0x3286, 0x00 },
> > +	{ 0x3287, 0x00 },
> > +	{ 0x328c, 0x13 },
> > +	{ 0x328e, 0x00 },
> > +	{ 0x328f, 0x00 },
> > +	{ 0x32ae, 0x00 },
> > +	{ 0x32af, 0x00 },
> > +	{ 0x32ca, 0x5a },
> > +	{ 0x332c, 0x00 },
> > +	{ 0x332f, 0x00 },
> > +	{ 0x334a, 0x00 },
> > +	{ 0x334c, 0x01 },
> > +	{ 0x3352, 0x50 },
> > +	{ 0x3356, 0x4f },
> > +	{ 0x335a, 0x79 },
> > +	{ 0x335e, 0x56 },
> > +	{ 0x3360, 0x6a },
> > +	{ 0x336a, 0x56 },
> > +	{ 0x33d6, 0x79 },
> > +	{ 0x340c, 0x6e },
> > +	{ 0x3448, 0x7e },
> > +	{ 0x348e, 0x6f },
> > +	{ 0x3492, 0x11 },
> > +	{ 0x34c4, 0x5a },
> > +	{ 0x3506, 0x56 },
> > +	{ 0x350c, 0x56 },
> > +	{ 0x350e, 0x58 },
> > +	{ 0x353d, 0x10 },
> > +	{ 0x3549, 0x04 },
> > +	{ 0x355d, 0x03 },
> > +	{ 0x355e, 0x03 },
> > +	{ 0x3574, 0x56 },
> > +	{ 0x357f, 0x0c },
> > +	{ 0x3580, 0x0a },
> > +	{ 0x3581, 0x08 },
> > +	{ 0x3583, 0x72 },
> > +	{ 0x3587, 0x01 },
> > +	{ 0x35b6, 0x00 },
> > +	{ 0x35b8, 0x00 },
> > +	{ 0x35d0, 0x5e },
> > +	{ 0x35d4, 0x63 },
> > +	{ 0x366a, 0x04 },
> > +	{ 0x366b, 0x04 },
> > +	{ 0x366c, 0x00 },
> > +	{ 0x366d, 0x00 },
> > +	{ 0x366e, 0x00 },
> > +	{ 0x366f, 0x00 },
> > +	{ 0x3670, 0x00 },
> > +	{ 0x3671, 0x05 },
> > +	{ 0x3676, 0x83 },
> > +	{ 0x3677, 0x03 },
> > +	{ 0x3678, 0x00 },
> > +	{ 0x3679, 0x04 },
> > +	{ 0x367a, 0x2c },
> > +	{ 0x367b, 0x05 },
> > +	{ 0x367d, 0x06 },
> > +	{ 0x367e, 0xff },
> > +	{ 0x367f, 0x06 },
> > +	{ 0x3680, 0x4b },
> > +	{ 0x3688, 0x05 },
> > +	{ 0x3690, 0x27 },
> > +	{ 0x3692, 0x65 },
> > +	{ 0x3694, 0x4f },
> > +	{ 0x3696, 0xa1 },
> > +	{ 0x36bc, 0x00 },
> > +	{ 0x371c, 0x02 },
> > +	{ 0x372f, 0x3c },
> > +	{ 0x3730, 0x01 },
> > +	{ 0x3732, 0xb8 },
> > +	{ 0x3734, 0x4a },
> > +	{ 0x3736, 0x57 },
> > +	{ 0x3738, 0x4d },
> > +	{ 0x3744, 0x0f },
> > +	{ 0x375b, 0x01 },
> > +	{ 0x382b, 0x68 },
> > +	{ 0x38b3, 0x00 },
> > +	{ 0x3910, 0x90 },
> > +	{ 0x3911, 0x70 },
> > +	{ 0x3912, 0x92 },
> > +	{ 0x3913, 0x24 },
> > +	{ 0x3914, 0x93 },
> > +	{ 0x3915, 0x0b },
> > +	{ 0x3916, 0x01 },
> > +	{ 0x3918, 0x04 },
> > +	{ 0x391c, 0x90 },
> > +	{ 0x391d, 0x05 },
> > +	{ 0x3920, 0x96 },
> > +	{ 0x3921, 0x06 },
> > +	{ 0x3a2a, 0x01 },
> > +	{ 0x3a7a, 0x01 },
> > +	{ 0x3a7b, 0x01 },
> > +	{ 0x3acb, 0x06 },
> > +	{ 0x3c08, 0x3f },
> > +	{ 0x3c0c, 0x1b },
> > +	{ 0x3e80, 0x14 },
> > +	{ 0x3e82, 0x30 },
> > +	{ 0x3e84, 0x0c },
> > +	{ 0x3e85, 0x06 },
> > +	{ 0x3e86, 0xfc },
> > +	{ 0x3e87, 0x10 },
> > +	{ 0x3e88, 0x03 },
> > +	{ 0x3e89, 0xfe },
> > +	{ 0x3e8a, 0x01 },
> > +	{ 0x3e8b, 0x06 },
> > +	{ 0x3e8e, 0x03 },
> > +	{ 0x3e8f, 0xfe },
> > +	{ 0x3e90, 0x01 },
> > +	{ 0x3e91, 0x06 },
> > +	{ 0x3e94, 0x33 },
> > +	{ 0x3e95, 0x01 },
> > +	{ 0x3e96, 0x19 },
> > +	{ 0x3e98, 0x30 },
> > +	{ 0x3e9a, 0x11 },
> > +	{ 0x3e9b, 0x06 },
> > +	{ 0x3e9c, 0xfc },
> > +	{ 0x3e9d, 0x10 },
> > +	{ 0x3e9e, 0xfe },
> > +	{ 0x3e9f, 0x03 },
> > +	{ 0x3ea0, 0x06 },
> > +	{ 0x3ea3, 0x01 },
> > +	{ 0x3ea4, 0xfe },
> > +	{ 0x3ea5, 0x03 },
> > +	{ 0x3ea6, 0x06 },
> > +	{ 0x3ea9, 0x33 },
> > +	{ 0x3eaa, 0x00 },
> > +	{ 0x3eab, 0x08 },
> > +	{ 0x3eac, 0x08 },
> > +	{ 0x3ead, 0x01 },
> > +	{ 0x3eae, 0x08 },
> > +	{ 0x3eaf, 0x08 },
> > +	{ 0x3eb0, 0x00 },
> > +	{ 0x3eb1, 0x10 },
> > +	{ 0x3eb2, 0x10 },
> > +	{ 0x3eb3, 0x01 },
> > +	{ 0x3eb4, 0x10 },
> > +	{ 0x3eb5, 0x10 },
> > +	{ 0x3eb6, 0x00 },
> > +	{ 0x3eb7, 0x00 },
> > +	{ 0x3eb8, 0x00 },
> > +	{ 0x3eb9, 0x00 },
> > +	{ 0x3eba, 0x00 },
> > +	{ 0x3ebb, 0x00 },
> > +	{ 0x3ec0, 0x54 },
> > +	{ 0x3ecc, 0x04 },
> > +	{ 0x3ecd, 0x04 },
> > +	{ 0x3ed0, 0xf0 },
> > +	{ 0x3ed1, 0x20 },
> > +	{ 0x3ed2, 0x0b },
> > +	{ 0x3ed3, 0x04 },
> > +	{ 0x3ed5, 0x13 },
> > +	{ 0x3ed6, 0x00 },
> > +	{ 0x3ed9, 0x0f },
> > +	{ 0x3ee4, 0x02 },
> > +	{ 0x3ee5, 0x02 },
> > +	{ 0x3ee7, 0x00 },
> > +	{ 0x3ef6, 0x00 },
> > +	{ 0x3ef8, 0x10 },
> > +	{ 0x3efa, 0x00 },
> > +	{ 0x3efc, 0x10 },
> > +	{ 0x3134, 0xa7 },
> > +	{ 0x3135, 0x00 },
> > +	{ 0x3136, 0x9f },
> > +	{ 0x3137, 0x00 },
> > +	{ 0x3138, 0x6f },
> > +	{ 0x3139, 0x00 },
> > +	{ 0x313a, 0x5f },
> > +	{ 0x313b, 0x00 },
> > +	{ 0x313c, 0x5f },
> > +	{ 0x313d, 0x00 },
> > +	{ 0x313e, 0x7f },
> > +	{ 0x313f, 0x01 },
> > +	{ 0x3140, 0x6f },
> > +	{ 0x3141, 0x00 },
> > +	{ 0x3142, 0x4f },
> > +	{ 0x3143, 0x00 },
> > +	{ 0x300e, 0x00 },
> > +	{ 0x300f, 0x00 },
> > +	{ 0x302c, 0x0c },
> > +	{ 0x302d, 0x00 },
> > +	{ 0x3034, 0x01 },
> > +	{ 0x3035, 0x01 },
> > +	{ 0x3036, 0x64 },
> > +	{ 0x3037, 0x00 },
> > +	{ 0x3038, 0xc8 },
> > +	{ 0x3039, 0x00 },
> > +	{ 0x3084, 0x4e },
> > +	{ 0x3085, 0x04 },
> > +	{ 0x3086, 0x4e },
> > +	{ 0x3087, 0x04 },
> > +	{ 0x30a9, 0xe0 },
> > +	{ 0x30aa, 0x2e },
> > +	{ 0x30ab, 0x00 },
> > +	{ 0x30ac, 0x48 },
> > +	{ 0x30ad, 0x0d },
> > +	{ 0x30e2, 0x00 },
> > +	{ 0x312f, 0x20 },
> > +	{ 0x3130, 0x1c },
> > +	{ 0x3131, 0x11 },
> > +	{ 0x3132, 0xfc },
> > +	{ 0x3133, 0x10 },
> > +	{ 0x3a54, 0xf0 },
> > +	{ 0x3a55, 0x20 },
> > +	{ 0x3a43, 0x01 },
> > +	{ 0x3a3b, 0x00 },
> > +	{ 0x3042, 0x32 },
> > +	{ 0x3092, 0x00 },
> > +	{ 0x30dd, 0x00 },
> > +	{ 0x30de, 0x00 },
> > +	{ 0x30df, 0x00 },
> > +	{ 0x30e0, 0x00 },
> > +	{ 0x30e1, 0x00 },
> > +	{ 0x332c, 0x00 },
> > +	{ 0x332d, 0x00 },
> > +	{ 0x334a, 0x00 },
> > +	{ 0x334b, 0x00 },
> > +	{ 0x35b6, 0x00 },
> > +	{ 0x35b7, 0x00 },
> > +	{ 0x35b8, 0x00 },
> > +	{ 0x35b9, 0x00 },
> > +	{ 0x36bc, 0x00 },
> > +	{ 0x36bd, 0x00 },
> > +};
> > +
> > +static const struct imx492_reg mode_all_regs[] = {
> > +	{ 0x3033, 0x30 },
> > +	{ 0x303c, 0x01 },
> > +	{ 0x31e8, 0xa0 },
> > +	{ 0x31f4, 0x01 },
> > +	{ 0x31e9, 0x00 },
> > +	{ 0x3122, 0x02 },
> > +	{ 0x3129, 0x90 },
> > +	{ 0x312a, 0x02 },
> > +	{ 0x311f, 0x00 },
> > +	{ 0x3123, 0x00 },
> > +	{ 0x3124, 0x00 },
> > +	{ 0x3125, 0x01 },
> > +	{ 0x3127, 0x02 },
> > +	{ 0x312d, 0x02 },
> > +	{ 0x3000, 0x12 },
> > +	{ 0x310b, 0x00 },
> > +	{ 0x3004, 0x1c },
> > +	{ 0x3005, 0x06 },
> > +	{ 0x3006, 0x00 },
> > +	{ 0x3007, 0xa7 },
> > +	{ 0x3047, 0x02 },
> > +	{ 0x304e, 0x0b },
> > +	{ 0x304f, 0x2a },
> > +	{ 0x3052, 0xee },
> > +	{ 0x3062, 0x25 },
> > +	{ 0x3064, 0x78 },
> > +	{ 0x3065, 0x33 },
> > +	{ 0x3066, 0x64 },
> > +	{ 0x3067, 0x71 },
> > +	{ 0x307e, 0x07 },
> > +	{ 0x3081, 0x00 },
> > +	{ 0x3088, 0x75 },
> > +	{ 0x308a, 0x09 },
> > +	{ 0x308c, 0x61 },
> > +	{ 0x30ef, 0x01 },
> > +	{ 0x3146, 0x00 },
> > +	{ 0x31f5, 0x01 },
> > +	{ 0x3234, 0x32 },
> > +	{ 0x3248, 0xbc },
> > +	{ 0x3250, 0xbc },
> > +	{ 0x3258, 0xbc },
> > +	{ 0x3260, 0xbc },
> > +	{ 0x3274, 0x13 },
> > +	{ 0x3276, 0x00 },
> > +	{ 0x3277, 0x00 },
> > +	{ 0x327c, 0x13 },
> > +	{ 0x327e, 0x00 },
> > +	{ 0x327f, 0x00 },
> > +	{ 0x3284, 0x13 },
> > +	{ 0x3286, 0x00 },
> > +	{ 0x3287, 0x00 },
> > +	{ 0x328c, 0x13 },
> > +	{ 0x328e, 0x00 },
> > +	{ 0x328f, 0x00 },
> > +	{ 0x32ae, 0x00 },
> > +	{ 0x32af, 0x00 },
> > +	{ 0x32ca, 0x5a },
> > +	{ 0x332c, 0x00 },
> > +	{ 0x332f, 0x00 },
> > +	{ 0x334a, 0x00 },
> > +	{ 0x334c, 0x01 },
> > +	{ 0x3352, 0x50 },
> > +	{ 0x3356, 0x4f },
> > +	{ 0x335a, 0x79 },
> > +	{ 0x335e, 0x56 },
> > +	{ 0x3360, 0x6a },
> > +	{ 0x336a, 0x56 },
> > +	{ 0x33d6, 0x79 },
> > +	{ 0x340c, 0x6e },
> > +	{ 0x3448, 0x7e },
> > +	{ 0x348e, 0x6f },
> > +	{ 0x3492, 0x11 },
> > +	{ 0x34c4, 0x5a },
> > +	{ 0x3506, 0x56 },
> > +	{ 0x350c, 0x56 },
> > +	{ 0x350e, 0x58 },
> > +	{ 0x353d, 0x10 },
> > +	{ 0x3549, 0x04 },
> > +	{ 0x355d, 0x03 },
> > +	{ 0x355e, 0x03 },
> > +	{ 0x3574, 0x56 },
> > +	{ 0x357f, 0x0c },
> > +	{ 0x3580, 0x0a },
> > +	{ 0x3581, 0x08 },
> > +	{ 0x3583, 0x72 },
> > +	{ 0x3587, 0x01 },
> > +	{ 0x35b6, 0x00 },
> > +	{ 0x35b8, 0x00 },
> > +	{ 0x35d0, 0x5e },
> > +	{ 0x35d4, 0x63 },
> > +	{ 0x366a, 0x04 },
> > +	{ 0x366b, 0x04 },
> > +	{ 0x366c, 0x00 },
> > +	{ 0x366d, 0x00 },
> > +	{ 0x366e, 0x00 },
> > +	{ 0x366f, 0x00 },
> > +	{ 0x3670, 0x00 },
> > +	{ 0x3671, 0x05 },
> > +	{ 0x3676, 0x83 },
> > +	{ 0x3677, 0x03 },
> > +	{ 0x3678, 0x00 },
> > +	{ 0x3679, 0x04 },
> > +	{ 0x367a, 0x2c },
> > +	{ 0x367b, 0x05 },
> > +	{ 0x367d, 0x06 },
> > +	{ 0x367e, 0xff },
> > +	{ 0x367f, 0x06 },
> > +	{ 0x3680, 0x4b },
> > +	{ 0x3688, 0x05 },
> > +	{ 0x3690, 0x27 },
> > +	{ 0x3692, 0x65 },
> > +	{ 0x3694, 0x4f },
> > +	{ 0x3696, 0xa1 },
> > +	{ 0x36bc, 0x00 },
> > +	{ 0x371c, 0x02 },
> > +	{ 0x372f, 0x3c },
> > +	{ 0x3730, 0x01 },
> > +	{ 0x3732, 0xb8 },
> > +	{ 0x3734, 0x4a },
> > +	{ 0x3736, 0x57 },
> > +	{ 0x3738, 0x4d },
> > +	{ 0x3744, 0x0f },
> > +	{ 0x375b, 0x01 },
> > +	{ 0x382b, 0x68 },
> > +	{ 0x38b3, 0x00 },
> > +	{ 0x3910, 0x90 },
> > +	{ 0x3911, 0x70 },
> > +	{ 0x3912, 0x92 },
> > +	{ 0x3913, 0x24 },
> > +	{ 0x3914, 0x93 },
> > +	{ 0x3915, 0x0b },
> > +	{ 0x3916, 0x01 },
> > +	{ 0x3918, 0x04 },
> > +	{ 0x391c, 0x90 },
> > +	{ 0x391d, 0x05 },
> > +	{ 0x3920, 0x96 },
> > +	{ 0x3921, 0x06 },
> > +	{ 0x3a2a, 0x01 },
> > +	{ 0x3a7a, 0x01 },
> > +	{ 0x3a7b, 0x01 },
> > +	{ 0x3acb, 0x06 },
> > +	{ 0x3c08, 0x3f },
> > +	{ 0x3c0c, 0x1b },
> > +	{ 0x3e80, 0x14 },
> > +	{ 0x3e82, 0x30 },
> > +	{ 0x3e84, 0x0c },
> > +	{ 0x3e85, 0x06 },
> > +	{ 0x3e86, 0xfc },
> > +	{ 0x3e87, 0x10 },
> > +	{ 0x3e88, 0x03 },
> > +	{ 0x3e89, 0xfe },
> > +	{ 0x3e8a, 0x01 },
> > +	{ 0x3e8b, 0x06 },
> > +	{ 0x3e8e, 0x03 },
> > +	{ 0x3e8f, 0xfe },
> > +	{ 0x3e90, 0x01 },
> > +	{ 0x3e91, 0x06 },
> > +	{ 0x3e94, 0x33 },
> > +	{ 0x3e95, 0x01 },
> > +	{ 0x3e96, 0x19 },
> > +	{ 0x3e98, 0x30 },
> > +	{ 0x3e9a, 0x11 },
> > +	{ 0x3e9b, 0x06 },
> > +	{ 0x3e9c, 0xfc },
> > +	{ 0x3e9d, 0x10 },
> > +	{ 0x3e9e, 0xfe },
> > +	{ 0x3e9f, 0x03 },
> > +	{ 0x3ea0, 0x06 },
> > +	{ 0x3ea3, 0x01 },
> > +	{ 0x3ea4, 0xfe },
> > +	{ 0x3ea5, 0x03 },
> > +	{ 0x3ea6, 0x06 },
> > +	{ 0x3ea9, 0x33 },
> > +	{ 0x3eaa, 0x00 },
> > +	{ 0x3eab, 0x08 },
> > +	{ 0x3eac, 0x08 },
> > +	{ 0x3ead, 0x01 },
> > +	{ 0x3eae, 0x08 },
> > +	{ 0x3eaf, 0x08 },
> > +	{ 0x3eb0, 0x00 },
> > +	{ 0x3eb1, 0x10 },
> > +	{ 0x3eb2, 0x10 },
> > +	{ 0x3eb3, 0x01 },
> > +	{ 0x3eb4, 0x10 },
> > +	{ 0x3eb5, 0x10 },
> > +	{ 0x3eb6, 0x00 },
> > +	{ 0x3eb7, 0x00 },
> > +	{ 0x3eb8, 0x00 },
> > +	{ 0x3eb9, 0x00 },
> > +	{ 0x3eba, 0x00 },
> > +	{ 0x3ebb, 0x00 },
> > +	{ 0x3ec0, 0x54 },
> > +	{ 0x3ecc, 0x04 },
> > +	{ 0x3ecd, 0x04 },
> > +	{ 0x3ed0, 0xf0 },
> > +	{ 0x3ed1, 0x20 },
> > +	{ 0x3ed2, 0x0b },
> > +	{ 0x3ed3, 0x04 },
> > +	{ 0x3ed5, 0x13 },
> > +	{ 0x3ed6, 0x00 },
> > +	{ 0x3ed9, 0x0f },
> > +	{ 0x3ee4, 0x02 },
> > +	{ 0x3ee5, 0x02 },
> > +	{ 0x3ee7, 0x00 },
> > +	{ 0x3ef6, 0x00 },
> > +	{ 0x3ef8, 0x10 },
> > +	{ 0x3efa, 0x00 },
> > +	{ 0x3efc, 0x10 },
> > +	{ 0x3134, 0xa7 },
> > +	{ 0x3135, 0x00 },
> > +	{ 0x3136, 0x9f },
> > +	{ 0x3137, 0x00 },
> > +	{ 0x3138, 0x6f },
> > +	{ 0x3139, 0x00 },
> > +	{ 0x313a, 0x5f },
> > +	{ 0x313b, 0x00 },
> > +	{ 0x313c, 0x5f },
> > +	{ 0x313d, 0x00 },
> > +	{ 0x313e, 0x7f },
> > +	{ 0x313f, 0x01 },
> > +	{ 0x3140, 0x6f },
> > +	{ 0x3141, 0x00 },
> > +	{ 0x3142, 0x4f },
> > +	{ 0x3143, 0x00 },
> > +	{ 0x300e, 0x00 },
> > +	{ 0x300f, 0x00 },
> > +	{ 0x302c, 0x0c },
> > +	{ 0x302d, 0x00 },
> > +	{ 0x3034, 0x01 },
> > +	{ 0x3035, 0x01 },
> > +	{ 0x3036, 0x64 },
> > +	{ 0x3037, 0x00 },
> > +	{ 0x3038, 0xc8 },
> > +	{ 0x3039, 0x00 },
> > +	{ 0x3084, 0x4e },
> > +	{ 0x3085, 0x04 },
> > +	{ 0x3086, 0x4e },
> > +	{ 0x3087, 0x04 },
> > +	{ 0x30a9, 0xe0 },
> > +	{ 0x30aa, 0x2e },
> > +	{ 0x30ab, 0x00 },
> > +	{ 0x30ac, 0x48 },
> > +	{ 0x30ad, 0x0d },
> > +	{ 0x30e2, 0x00 },
> > +	{ 0x312f, 0x20 },
> > +	{ 0x3130, 0x1c },
> > +	{ 0x3131, 0x11 },
> > +	{ 0x3132, 0xfc },
> > +	{ 0x3133, 0x10 },
> > +	{ 0x3a54, 0xf0 },
> > +	{ 0x3a55, 0x20 },
> > +	{ 0x3a43, 0x01 },
> > +	{ 0x3a3b, 0x00 },
> > +	{ 0x3042, 0x32 },
> > +	{ 0x3092, 0x00 },
> > +	{ 0x30dd, 0x00 },
> > +	{ 0x30de, 0x00 },
> > +	{ 0x30df, 0x00 },
> > +	{ 0x30e0, 0x00 },
> > +	{ 0x30e1, 0x00 },
> > +	{ 0x332c, 0x00 },
> > +	{ 0x332d, 0x00 },
> > +	{ 0x334a, 0x00 },
> > +	{ 0x334b, 0x00 },
> > +	{ 0x35b6, 0x00 },
> > +	{ 0x35b7, 0x00 },
> > +	{ 0x35b8, 0x00 },
> > +	{ 0x35b9, 0x00 },
> > +	{ 0x36bc, 0x00 },
> > +	{ 0x36bd, 0x00 },
> > +};
> > +
> > +#endif /* __imx492_h__ */
> 
> -- 
> Regards,
> 
> Laurent Pinchart


		Petko

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-28 12:47   ` Kieran Bingham
@ 2022-11-28 13:14     ` Petko Manolov
  2022-11-28 13:30       ` Laurent Pinchart
  0 siblings, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:14 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-media, laurent.pinchart, sakari.ailus

On 22-11-28 12:47:25, Kieran Bingham wrote:
> Quoting Petko Manolov (2022-11-25 15:31:17)
> > The header.  For the moment only two modes are supported.
> > 
> > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > ---
> >  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
> >  1 file changed, 555 insertions(+)
> >  create mode 100644 drivers/media/i2c/imx492.h
> > 
> > diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> > new file mode 100644
> > index 000000000000..301fd66c77d5
> > --- /dev/null
> > +++ b/drivers/media/i2c/imx492.h
> > @@ -0,0 +1,555 @@
> > +#ifndef        __imx492_h__
> > +#define        __imx492_h__
> > +
> > +struct imx492_reg {
> > +       u16 address;
> > +       u8 val;
> > +};
> > +
> > +static const struct imx492_reg mode_17to9_regs[] = {
> 
> Why is this table in the header? Should it be available in multiple locations?

Nope, but there are multiple modes that will eventually be in use and scrolling
down a couple of seconds until one gets to the code started to get a bit boring.

> I think it is likely better in the driver itself.

Will put register definitions in the .c file for the time being.


		Petko

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

* Re: [PATCH v1 1/5] DT bindings for imx492
  2022-11-28 13:07     ` Petko Manolov
@ 2022-11-28 13:28       ` Laurent Pinchart
  0 siblings, 0 replies; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28 13:28 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, sakari.ailus

On Mon, Nov 28, 2022 at 03:07:22PM +0200, Petko Manolov wrote:
> On 22-11-28 06:37:58, Laurent Pinchart wrote:
> > Hi Petko,
> > 
> > Thank you for the patch.
> > 
> > The subject line should start with the proper prefix. Look at the git
> > log in the directory to see what is customary. Furthermore,
> > s/imx492/Sony IMX492/.
> > 
> > On Fri, Nov 25, 2022 at 05:31:16PM +0200, Petko Manolov wrote:
> > > Here goes the DT bindings file.
> > 
> > This is also a peculiar commit message :-)
> 
> Short and to the point, isn't it? :)
> 
> Honestly, i'm not sure what else i should put as subject line, apart from "Sony
> IMX492".

media: dt-bindings: Add binding for Sony IMX492 camera sensor

would be a good subject line.

> > > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > > ---
> > >  .../bindings/media/i2c/sony,imx492.yaml       | 101 ++++++++++++++++++
> > >  1 file changed, 101 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > > new file mode 100644
> > > index 000000000000..f4feef17c677
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > > @@ -0,0 +1,101 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/i2c/sony,imx492.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Sony imx492 Sensor
> > 
> > s/imx492/IMX492/. Same below. When referring to the hardware, it's
> > customary to use uppercase.
> 
> OK.
> 
> > > +
> > > +maintainers:
> > > +  - Petko Manolov <petko.manolov@konsulko.com>
> > > +
> > > +description:
> > > +
> > > +  imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > +  monochrome square pixel array and approximately 47.08 M effective pixels.
> > > +  12-bit digital output makes it possible to output the signals with high
> > > +  definition for moving pictures. It is programmable through I2C interface. The
> > > +  I2C client address can be either 0x10 or 0x1a depending on SLASEL pin. Image
> > > +  data is sent through MIPI CSI-2.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: sony,imx492
> > 
> > Missing blank line.
> 
> OK.
> 
> > > +  reg:
> > > +    description: I2C address
> > 
> > You can drop the description.
> > 
> > > +    maxItems: 1
> > > +
> > > +  assigned-clocks: true
> > > +  assigned-clock-parents: true
> > > +  assigned-clock-rates: true
> > 
> > This shouldn't be needed.
> 
> OK.
> 
> > > +
> > > +  clocks:
> > > +    description: Clock frequency 6MHz, 12MHz, 18MHz and 24MHz
> > 
> > If you know the name of the clock pin, I would include it here.
> 
> OK.
> 
> > > +    maxItems: 1
> > > +
> > > +  dovdd-supply:
> > > +    description: Interface power supply.
> > 
> > I would list the voltage. Same below.
> 
> OK.
> 
> > > +
> > > +  avdd-supply:
> > > +    description: Analog power supply.
> > > +
> > > +  dvdd-supply:
> > > +    description: Digital power supply.
> > > +
> > > +  reset-gpios:
> > > +    description: Reference to the GPIO connected to the XCLR pin, if any.
> > > +    maxItems: 1
> > > +
> > > +  port:
> > > +    additionalProperties: false
> > > +    $ref: /schemas/graph.yaml#/$defs/port-base
> > > +
> > > +    properties:
> > > +      endpoint:
> > > +        $ref: /schemas/media/video-interfaces.yaml#
> > > +        unevaluatedProperties: false
> > > +
> > > +        properties:
> > > +          data-lanes: true
> > > +          link-frequencies: true
> > > +
> > > +        required:
> > > +          - data-lanes
> > > +          - link-frequencies
> > > +
> > > +    required:
> > > +      - endpoint
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - clocks
> > > +  - port
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    i2c0 {
> > > +        #address-cells = <1>;
> > > +        #size-cells = <0>;
> > > +
> > > +        camera@10 {
> > > +            compatible = "sony,imx492";
> > > +            reg = <0x10>;
> > > +            clocks = <&imx492_clk>;
> > > +
> > > +            assigned-clocks = <&imx492_clk>;
> > > +            assigned-clock-parents = <&imx492_clk_parent>;
> > > +            assigned-clock-rates = <24000000>;
> > 
> > You can drop this from the example, it doesn't showcase the DT bindings for
> > the IMX492.
> 
> OK.
> 
> > > +
> > > +            port {
> > > +                imx492: endpoint {
> > 
> > s/imx492/imx492_out/
> > 
> > > +                    remote-endpoint = <&cam>;
> > 
> > s/cam/cam_in/
> 
> OK to both of the above.
> 
> > > +                    data-lanes = <1 2 3 4>;
> > > +                    link-frequencies = /bits/ 64 <600000000>;
> > > +                };
> > > +            };
> > > +        };
> > > +    };
> > > +...

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-28 13:14     ` Petko Manolov
@ 2022-11-28 13:30       ` Laurent Pinchart
  2022-11-28 13:53         ` Petko Manolov
  0 siblings, 1 reply; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28 13:30 UTC (permalink / raw)
  To: Petko Manolov; +Cc: Kieran Bingham, linux-media, sakari.ailus

On Mon, Nov 28, 2022 at 03:14:26PM +0200, Petko Manolov wrote:
> On 22-11-28 12:47:25, Kieran Bingham wrote:
> > Quoting Petko Manolov (2022-11-25 15:31:17)
> > > The header.  For the moment only two modes are supported.
> > > 
> > > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > > ---
> > >  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 555 insertions(+)
> > >  create mode 100644 drivers/media/i2c/imx492.h
> > > 
> > > diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> > > new file mode 100644
> > > index 000000000000..301fd66c77d5
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/imx492.h
> > > @@ -0,0 +1,555 @@
> > > +#ifndef        __imx492_h__
> > > +#define        __imx492_h__
> > > +
> > > +struct imx492_reg {
> > > +       u16 address;
> > > +       u8 val;
> > > +};
> > > +
> > > +static const struct imx492_reg mode_17to9_regs[] = {
> > 
> > Why is this table in the header? Should it be available in multiple locations?
> 
> Nope, but there are multiple modes that will eventually be in use and scrolling
> down a couple of seconds until one gets to the code started to get a bit boring.

Ideally we should get rid of those tables and use logic to compute
register values :-) That's a dream only at this point though.

I agree with Kieran that everything could be in the same file, and I
also agree with you that it's not nice to have a large list of registers
at the beginning of the driver. I'm thus fine with either option.

> > I think it is likely better in the driver itself.
> 
> Will put register definitions in the .c file for the time being.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-28 13:11   ` Petko Manolov
@ 2022-11-28 13:38     ` Kieran Bingham
  2022-11-28 13:46       ` Laurent Pinchart
  2022-11-28 14:07       ` Petko Manolov
  0 siblings, 2 replies; 28+ messages in thread
From: Kieran Bingham @ 2022-11-28 13:38 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, laurent.pinchart, sakari.ailus

Quoting Petko Manolov (2022-11-28 13:11:39)
> On 22-11-28 12:45:32, Kieran Bingham wrote:
> > Hi Petko,
> > 
> > What device/ISP are you testing this sensor on?
> 
> I'll tell you, but only if you promise to not laugh too much.  Deal?
> 
> i.MX8M-Mini
> 
> I hope nobody will notice the above line...

I won't laugh at all. We've just merged the ISI pipeline handler for
libcamera, which should let you use libcamera on this target (I think).

I would hope sometime in the future you'd be able to use the ISI
pipeline handler with a GPU based ISP with this sensor too.

How are you managing the image 3a? the imx492 is a raw sensor isn't it ?


> > Quoting Petko Manolov (2022-11-25 15:31:15)
> > > This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> > > image sensor.
> > > 
> > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > digital output makes it possible to output the signals with high definition for
> > > moving pictures. It is programmable through I2C interface. The I2C client
> > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > through MIPI CSI-2.
> > > 
> > > Petko Manolov (5):
> > >   DT bindings for imx492
> > >   media: i2c: imx492: driver's header
> > >   media: i2c: imx492: driver's source
> > >   media: i2c: add imx492 config entry
> > >   media: i2c: add imx492 entry for make
> > 
> > Could you squash patches 2, 3, 4, and 5 into a single patch please?
> 
> This is the exact opposite to what the networking folks would prefer, but it's
> OK with me.

Haha ... yes - isn't it great working in mulitple subsystems....

> > Also - I think you'll need an entry in MAINTAINERS.
> 
> Right, that one too.
> 
> > I can't see any reference to the selection controls:
> >  - V4L2_SEL_TGT_CROP_DEFAULT
> >  - V4L2_SEL_TGT_CROP
> >  - V4L2_SEL_TGT_CROP_BOUNDS
> 
> These are in a very early phase of implementing.

Ok

> > Do you have the datasheet or sufficient information to be able to implement
> > these controls?
> 
> Of course not.  We are brute forcing our way forward by mostly reverse
> engineering another solution that has an FPGA on the other end of the CSI link.

Understood ;-) (and ... I think what I was fearing/anticipating).

--
Kieran




> > --
> > Kieran
> > 
> > >  .../bindings/media/i2c/sony,imx492.yaml       |  101 ++
> > >  drivers/media/i2c/Kconfig                     |   14 +
> > >  drivers/media/i2c/Makefile                    |    1 +
> > >  drivers/media/i2c/imx492.c                    | 1092 +++++++++++++++++
> > >  drivers/media/i2c/imx492.h                    |  555 +++++++++
> > >  5 files changed, 1763 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > >  create mode 100644 drivers/media/i2c/imx492.c
> > >  create mode 100644 drivers/media/i2c/imx492.h
> > > 
> > > -- 
> > > 2.30.2
> > >
> 
> 
>                 Petko

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-28  5:16   ` Laurent Pinchart
@ 2022-11-28 13:42     ` Petko Manolov
  2022-11-28 14:08       ` Laurent Pinchart
  2022-11-28 14:18       ` Dave Stevenson
  0 siblings, 2 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:42 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-media, sakari.ailus

On 22-11-28 07:16:22, Laurent Pinchart wrote:
> Hi Petko,
> 
> Thank you for the patch.
> 
> On Fri, Nov 25, 2022 at 05:31:18PM +0200, Petko Manolov wrote:
> > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > digital output makes it possible to output the signals with high definition for
> > moving pictures. It is programmable through I2C interface. The I2C client
> > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > through MIPI CSI-2.
> > 
> > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > ---
> >  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 1092 insertions(+)
> >  create mode 100644 drivers/media/i2c/imx492.c
> > 
> > diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> > new file mode 100644
> > index 000000000000..0713256b4b63
> > --- /dev/null
> > +++ b/drivers/media/i2c/imx492.c
> > @@ -0,0 +1,1092 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> > + *
> > + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regulator/consumer.h>
> 
> There are missing headers, at least for GPIO. Please check if anything else is
> missing.

The driver compiles cleanly.  Not sure what i have to add here.

> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +
> > +#include "imx492.h"
> > +
> > +/* Streaming Mode */
> > +#define IMX492_REG_MODE_SELECT	0x3000
> > +
> > +/* Chip ID */
> > +#define IMX492_ID		0x13
> > +
> > +/* Analog gain control */
> > +#define IMX492_REG_AGAIN	0x300a
> > +#define IMX492_AGAIN_MIN	0
> > +#define IMX492_AGAIN_MAX	978
> > +#define IMX492_AGAIN_STEP	1
> > +#define IMX492_AGAIN_DEFAULT	0
> > +
> > +/* Group hold register */
> > +#define IMX492_REG_HOLD		0x302b
> > +#define	IMX492_REG_XMSTA	0x3033
> > +#define	IMX492_REG_SYSCLKEN	0x35e5
> 
> You can replace the first tab (just after #define) with a space.

OK.

> > +/* CSI2 HW configuration */
> > +#define IMX492_LINK_FREQ	745000000
> > +#define IMX492_NUM_DATA_LANES	4
> > +
> > +#define IMX492_REG_MIN		0x3000
> > +#define IMX492_REG_MAX		0xffff
> > +
> > +/* *** */
> > +
> > +#define IMX492_REG_STANDBY	IMX492_REG_MODE_SELECT
> 
> No aliases for register names please, that's confusing.

This register is known with both of the above names in the documentation.  I
strongly suspect that at least two different teams/persons at Sony had a go at
that document.

Will select one of these names to avoid confusion.

> > +#define IMX492_BIT_STANDBY	0x01
> > +#define IMX492_BIT_STBLOGIC	0x02
> > +#define IMX492_BIT_STBDV	0x10
> > +
> > +#define IMX492_MODE_STANDBY	(IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> > +#define IMX492_MODE_STREAMING	0x00
> > +
> > +#define IMX492_REG_TESTPTRN	0x303A
> > +#define IMX492_BIT_CLKEN	0x01
> > +#define IMX492_BIT_TESTPTRN	0x10
> > +#define IMX492_BITS_TPTRN_ON	(IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> > +#define IMX492_BITS_TPTRN_OFF	0x00
> > +
> > +#define IMX492_REG_TESTPATSEL	0x303B
> > +#define IMX492_BIT_TPAT00	0x00
> > +#define IMX492_BIT_TPAT01	0x01
> > +#define IMX492_BIT_TPAT02	0x02
> > +#define IMX492_BIT_TPAT03	0x03
> > +#define IMX492_BIT_TPAT0A	0x0A
> > +#define IMX492_BIT_TPAT0B	0x0B
> > +
> > +#define IMX492_EXPOSURE_MIN		8
> > +#define IMX492_EXPOSURE_OFFSET		22
> > +#define IMX492_EXPOSURE_STEP		1
> > +#define IMX492_EXPOSURE_DEFAULT		0x0648
> > +
> > +#define	DEFAULT_FPS		6
> > +
> > +/**
> > + * struct imx492_reg_list - imx492 sensor register list
> > + * @num_of_regs: Number of registers in the list
> > + * @regs: Pointer to register list
> > + */
> > +struct imx492_reg_list {
> > +	u32 num_of_regs;
> > +	const struct imx492_reg *regs;
> > +};
> > +
> > +/**
> > + * struct imx492_mode - imx492 sensor mode structure
> > + * @width: Frame width
> > + * @height: Frame height
> > + * @code: Format code
> > + * @hblank: Horizontal blanking in lines
> > + * @vblank: Vertical blanking in lines
> > + * @vblank_min: Minimum vertical blanking in lines
> > + * @vblank_max: Maximum vertical blanking in lines
> > + * @pclk: Sensor pixel clock
> > + * @link_freq_idx: Link frequency index
> > + * @reg_list: Register list for sensor mode
> > + */
> > +struct imx492_mode {
> > +	u32 width;
> > +	u32 height;
> > +	u32 code;
> > +	u32 hblank;
> > +	u32 hblank_min;
> > +	u32 hblank_max;
> > +	u32 vblank;
> > +	u32 vblank_min;
> > +	u32 vblank_max;
> > +	u64 pclk;
> > +	u32 link_freq_idx;
> > +	struct imx492_reg_list reg_list;
> > +};
> > +
> > +/**
> > + * struct imx492 - imx492 sensor device structure
> > + * @dev: Pointer to generic device
> > + * @client: Pointer to i2c client
> > + * @sd: V4L2 sub-device
> > + * @pad: Media pad. Only one pad supported
> > + * @reset_gpio: Sensor reset gpio
> > + * @reset_gpio: Sensor power gpio
> > + * @inclk: Sensor input clock
> > + * @supplies: Regulator supplies
> > + * @ctrl_handler: V4L2 control handler
> > + * @link_freq_ctrl: Pointer to link frequency control
> > + * @pclk_ctrl: Pointer to pixel clock control
> > + * @hblank_ctrl: Pointer to horizontal blanking control
> > + * @vblank_ctrl: Pointer to vertical blanking control
> > + * @exp_ctrl: Pointer to exposure control
> > + * @again_ctrl: Pointer to analog gain control
> > + * @vblank: Vertical blanking in lines
> > + * @cur_mode: Pointer to current selected sensor mode
> > + * @mutex: Mutex for serializing sensor controls
> 
> Please use the same order for fields in the documentation and the
> structure defininition.

Mkey.

> > + * @streaming: Flag indicating streaming state
> > + */
> > +struct imx492 {
> > +	struct device *dev;
> > +	struct i2c_client *client;
> > +	struct v4l2_subdev sd;
> > +	struct media_pad pad;
> > +	struct v4l2_captureparm scap;
> 
> This is set but never used. You can drop it.

OK.

> > +	struct gpio_desc *reset_gpio;
> > +	struct gpio_desc *power_gpio;
> > +	struct gpio_desc *oscen_gpio;
> > +	struct clk *inclk;
> > +	struct v4l2_ctrl_handler ctrl_handler;
> > +	struct v4l2_ctrl *link_freq_ctrl;
> > +	struct v4l2_ctrl *pclk_ctrl;
> > +	struct v4l2_ctrl *hblank_ctrl;
> > +	struct v4l2_ctrl *vblank_ctrl;
> > +	struct v4l2_ctrl *exp_ctrl;
> > +	struct v4l2_ctrl *again_ctrl;
> > +	const struct imx492_mode *cur_mode;
> > +	struct mutex mutex;
> > +	u32 tpatt;
> 
> Not used, drop it.

Ah, a left over.  Will remove it.

> > +	u32 vblank;
> > +	bool streaming;
> > +};
> > +
> > +static const s64 link_freq[] = {
> > +	IMX492_LINK_FREQ,
> > +};
> > +
> > +
> > +/* Supported sensor mode configurations */
> > +static const struct imx492_mode supported_modes[] = {
> > +	{
> > +		.width = 8192,
> > +		.height = 4320,
> > +		.hblank = 1108,
> > +		.hblank_min = 1102,
> > +		.hblank_max = 32768,
> > +		.vblank = 5728,
> > +		.vblank_min = 4428,
> > +		.vblank_max = 32768,
> > +		.pclk = 745000000,
> > +		.link_freq_idx = 0,
> > +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > +		.reg_list = {
> > +			.num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> > +			.regs = mode_17to9_regs,
> > +		},
> > +	}, {
> > +		.width = 8192,
> > +		.height = 5556,
> > +		.hblank = 1108,
> > +		.hblank_min = 1102,
> > +		.hblank_max = 32768,
> > +		.vblank = 5728,
> > +		.vblank_min = 4428,
> > +		.vblank_max = 32768,
> > +		.pclk = 745000000,
> > +		.link_freq_idx = 0,
> > +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > +		.reg_list = {
> > +			.num_of_regs = ARRAY_SIZE(mode_all_regs),
> > +			.regs = mode_all_regs,
> > +		},
> > +	},
> > +};
> > +
> > +static const char * const imx492_test_pattern_menu[] = {
> > +	"Disabled",
> > +	"Solid black",
> > +	"Solid white",
> > +	"Solid dark grey",
> > +	"Solid light gray",
> > +	"None",
> > +	"None",
> > +	"None",
> > +	"None",
> > +	"None",
> > +	"None",
> 
> Menu controls shouldn't have entries with identical names. All these should be
> dropped if they're not implemented by the sensor, or given a proper name.

Err, this was easier to do.  Will refactor...

> > +	"Vertical color bars",
> > +	"Horizontal color bars",
> > +};
> > +
> > +/**
> > + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> > + * @subdev: pointer to imx492 V4L2 sub-device
> > + *
> > + * Return: pointer to imx492 device
> > + */
> > +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> > +{
> > +	return container_of(subdev, struct imx492, sd);
> > +}
> > +
> > +/**
> > + * imx492_read_reg() - Read registers.
> > + * @imx492: pointer to imx492 device
> > + * @reg: register address
> > + * @len: length of bytes to read. Max supported bytes is 4
> > + * @val: pointer to register value to be filled.
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> > +{
> > +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > +	struct i2c_msg msgs[2] = {0};
> > +	u8 addr_buf[2] = {0};
> > +	u8 data_buf[4] = {0};
> > +	int ret;
> > +
> > +	if (WARN_ON(len > 4))
> > +		return -EINVAL;
> > +
> > +	put_unaligned_be16(reg, addr_buf);
> > +
> > +	/* Write register address */
> > +	msgs[0].addr = client->addr;
> > +	msgs[0].flags = 0;
> > +	msgs[0].len = ARRAY_SIZE(addr_buf);
> > +	msgs[0].buf = addr_buf;
> > +
> > +	/* Read data from register */
> > +	msgs[1].addr = client->addr;
> > +	msgs[1].flags = I2C_M_RD;
> > +	msgs[1].len = len;
> > +	msgs[1].buf = &data_buf[4 - len];
> > +
> > +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> > +	if (ret != ARRAY_SIZE(msgs))
> > +		return -EIO;
> > +
> > +	*val = get_unaligned_be32(data_buf);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_write_reg() - Write register
> > + * @imx492: pointer to imx492 device
> > + * @reg: register address
> > + * @len: length of bytes. Max supported bytes is 4
> > + * @val: register value
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> > +{
> > +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > +	u8 buf[6] = {0};
> > +
> > +	if (WARN_ON(len > 4))
> > +		return -EINVAL;
> > +
> > +	put_unaligned_be16(reg, buf);
> > +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> > +	if (i2c_master_send(client, buf, len + 2) != len + 2)
> > +		return -EIO;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_write_regs() - Write a list of registers
> > + * @imx492: pointer to imx492 device
> > + * @regs: list of registers to be written
> > + * @len: length of registers array
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_write_regs(struct imx492 *imx492,
> > +			     const struct imx492_reg *regs, u32 len)
> > +{
> > +	unsigned int i;
> > +	int ret;
> > +
> > +	for (i = 0; i < len; i++) {
> > +		ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> > +{
> > +	/* for now this is the only format we support */
> > +	return MEDIA_BUS_FMT_SGBRG12_1X12;
> > +}
> > +
> > +/**
> > + * imx492_update_controls() - Update control ranges based on streaming mode
> > + * @imx492: pointer to imx492 device
> > + * @mode: pointer to imx492_mode sensor mode
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_update_controls(struct imx492 *imx492,
> > +				  const struct imx492_mode *mode)
> > +{
> > +	int ret;
> > +
> > +	ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> > +					mode->vblank_max, 1, mode->vblank);
> > +}
> > +
> > +/**
> > + * imx492_update_exp_gain() - Set updated exposure and gain
> > + * @imx492: pointer to imx492 device
> > + * @exposure: updated exposure value
> > + * @gain: updated analog gain value
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> > +{
> > +	u32 lpfr, shutter;
> > +	int ret;
> > +
> > +	lpfr = imx492->vblank + imx492->cur_mode->height;
> > +	shutter = lpfr - exposure;
> > +
> > +	ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * imx492_set_ctrl() - Set subdevice control
> > + * @ctrl: pointer to v4l2_ctrl structure
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +	struct imx492 *imx492 =
> > +		container_of(ctrl->handler, struct imx492, ctrl_handler);
> > +	u32 analog_gain;
> > +	u32 exposure;
> > +	int ret;
> > +
> > +	switch (ctrl->id) {
> > +	case V4L2_CID_VBLANK:
> > +		imx492->vblank = imx492->vblank_ctrl->val;
> > +
> > +		ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> > +					       IMX492_EXPOSURE_MIN,
> > +					       imx492->vblank +
> > +					       imx492->cur_mode->height -
> > +					       IMX492_EXPOSURE_OFFSET,
> > +					       1, IMX492_EXPOSURE_DEFAULT);
> 
> It looks like you forgot to write the corresponding registers.

Yeah, will look into this one as well.

> > +		break;
> > +	case V4L2_CID_EXPOSURE:
> > +		/* Set controls only if sensor is in power on state */
> > +		if (!pm_runtime_get_if_in_use(imx492->dev))
> > +			return 0;
> > +		exposure = ctrl->val;
> > +		analog_gain = imx492->again_ctrl->val;
> > +		ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> > +		pm_runtime_put(imx492->dev);
> > +		break;
> > +	case V4L2_CID_TEST_PATTERN:
> > +		if (ctrl->val) {
> > +			imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> > +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> > +		} else {
> > +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> > +		}
> 
> Don't you need the same pm_runtime_get_if_in_use() dance as for
> V4L2_CID_EXPOSURE ?

Yup.

> > +		ret = 0;
> > +		break;
> 
> Missing V4L2_CID_ANALOGUE_GAIN.

Not implemented at the moment.

> > +	default:
> > +		dev_err(imx492->dev, "Invalid control %d", ctrl->id);
> 
> This shouldn't happen if you correctly handle all the controls you have
> instanciated in imx492_init_controls().

Well, need to verify if that's the case here.

> > +		ret = -EINVAL;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +/* V4l2 subdevice control ops*/
> > +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> > +	.s_ctrl = imx492_set_ctrl,
> > +};
> > +
> > +/**
> > + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @code: V4L2 sub-device code enumeration need to be filled
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_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(supported_modes))
> > +		return -EINVAL;
> > +
> > +	code->code = supported_modes[code->index].code;
> 
> All modes have the same media bus code, you shouldn't report duplicated
> values.

This sensor support 10bit format so this is prep work when these get properly
implemented.

> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fsize: V4L2 sub-device size enumeration need to be filled
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> > +				  struct v4l2_subdev_state *sd_state,
> > +				  struct v4l2_subdev_frame_size_enum *fsize)
> > +{
> > +	if (fsize->index > ARRAY_SIZE(supported_modes))
> > +		return -EINVAL;
> > +
> > +	if (fsize->code != supported_modes[fsize->index].code)
> > +		return -EINVAL;
> > +
> > +	fsize->max_width = supported_modes[fsize->index].width;
> > +	fsize->min_width = fsize->max_width;
> > +	fsize->max_height = supported_modes[fsize->index].height;
> > +	fsize->min_height = fsize->max_height;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > +n * imx492_fill_pad_format() - Fill subdevice pad format
> > + *                            from selected sensor mode
> > + * @imx492: pointer to imx492 device
> > + * @mode: pointer to imx492_mode sensor mode
> > + * @fmt: V4L2 sub-device format need to be filled
> > + */
> > +static void imx492_fill_pad_format(struct imx492 *imx492,
> > +				   const struct imx492_mode *mode,
> > +				   struct v4l2_subdev_format *fmt)
> > +{
> > +	fmt->format.width = mode->width;
> > +	fmt->format.height = mode->height;
> > +	fmt->format.code = mode->code;
> > +	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;
> 
> You can use V4L2_QUANTIZATION_FULL_RANGE.

OK.

> > +	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
> > +}
> > +
> > +/**
> > + * imx492_get_pad_format() - Get subdevice pad format
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fmt: V4L2 sub-device format need to be set
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> > +				 struct v4l2_subdev_state *sd_state,
> > +				 struct v4l2_subdev_format *fmt)
> > +{
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +
> > +	mutex_lock(&imx492->mutex);
> > +
> > +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > +		struct v4l2_mbus_framefmt *framefmt;
> > +
> > +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > +		fmt->format = *framefmt;
> > +	} else {
> > +		imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> > +	}
> > +
> > +	mutex_unlock(&imx492->mutex);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_set_pad_format() - Set subdevice pad format
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fmt: V4L2 sub-device format need to be set
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> > +				 struct v4l2_subdev_state *sd_state,
> > +				 struct v4l2_subdev_format *fmt)
> > +{
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +	const struct imx492_mode *mode;
> > +	int ret = 0;
> > +
> > +	mutex_lock(&imx492->mutex);
> > +
> > +	fmt->format.code = imx492_get_format_code(imx492, 0);
> > +	mode = v4l2_find_nearest_size(supported_modes,
> > +					ARRAY_SIZE(supported_modes),
> > +					width, height,
> > +					fmt->format.width, fmt->format.height);
> > +	imx492_fill_pad_format(imx492, mode, fmt);
> > +
> > +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > +		struct v4l2_mbus_framefmt *framefmt;
> > +
> > +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > +		*framefmt = fmt->format;
> > +	} else {
> > +		ret = imx492_update_controls(imx492, mode);
> > +		if (!ret)
> > +			imx492->cur_mode = mode;
> > +	}
> > +
> > +	mutex_unlock(&imx492->mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> > +			       struct v4l2_subdev_state *sd_state)
> > +{
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +	struct v4l2_subdev_format fmt = { 0 };
> > +
> > +	fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
> 
> When using the active state API you will never get a null state here, so you
> can set this to
> 
> 	struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_TRY, };
> 
> unconditionally.

OK.

> > +	imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> > +
> > +	return imx492_set_pad_format(sd, sd_state, &fmt);
> > +}
> > +
> > +/**
> > + * imx492_start_streaming() - Start sensor stream
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_start_streaming(struct imx492 *imx492)
> > +{
> > +	const struct imx492_reg_list *reg_list;
> > +	int ret;
> > +
> > +	/* Write sensor mode registers */
> > +	reg_list = &imx492->cur_mode->reg_list;
> > +	ret = imx492_write_regs(imx492, reg_list->regs,
> > +				reg_list->num_of_regs);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "fail to write initial registers");
> > +		return ret;
> > +	}
> > +
> > +	/* Setup handler will write actual exposure and gain */
> > +	ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "fail to setup handler");
> > +		return ret;
> > +	}
> > +
> > +	/* 1st stabilization period */
> > +	usleep_range(10000, 11000);
> > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> > +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> > +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> > +
> > +	/* 2nd stabilization period */
> > +	usleep_range(7000, 8000);
> > +
> > +	/* Start streaming */
> > +	ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> > +
> > +	if (ret) {
> > +		dev_err(imx492->dev, "fail to start streaming");
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_stop_streaming() - Stop sensor stream
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static void imx492_stop_streaming(struct imx492 *imx492)
> > +{
> > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> > +	imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> > +}
> > +
> > +/**
> > + * imx492_set_stream() - Enable sensor streaming
> > + * @sd: pointer to imx492 subdevice
> > + * @enable: set to enable sensor streaming
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> > +{
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +	int ret;
> > +
> > +	mutex_lock(&imx492->mutex);
> > +
> > +	if (imx492->streaming == enable) {
> 
> This should never happen. You can drop imx492->streaming.

Well, OK.

> > +		mutex_unlock(&imx492->mutex);
> > +		return 0;
> > +	}
> > +
> > +	if (enable) {
> > +		ret = pm_runtime_resume_and_get(imx492->dev);
> > +		if (ret)
> > +			goto error_unlock;
> > +		ret = imx492_start_streaming(imx492);
> > +		if (ret)
> > +			goto error_power_off;
> > +	} else {
> > +		imx492_stop_streaming(imx492);
> > +		pm_runtime_put(imx492->dev);
> > +	}
> > +
> > +	imx492->streaming = enable;
> > +
> > +	mutex_unlock(&imx492->mutex);
> > +
> > +	return 0;
> > +
> > +error_power_off:
> > +	pm_runtime_put(imx492->dev);
> > +error_unlock:
> > +	mutex_unlock(&imx492->mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * imx492_detect() - Detect imx492 sensor
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, -EIO if sensor id does not match
> > + */
> > +static int imx492_detect(struct imx492 *imx492)
> > +{
> > +	int ret;
> > +	u32 val;
> > +
> > +	ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);
> 
> Is the chip ID really stored in that register ?

No.  There simply isn't an ID register.  In order to see if the sensor is
properly powered up and reset i had to chose a register with a known, non-zero
value.

> > +	if (ret)
> > +		return ret;
> > +
> > +	if (val != IMX492_ID) {
> > +		dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> > +		return -ENXIO;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_parse_hw_config(struct imx492 *imx492)
> > +{
> > +	struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> > +	struct v4l2_fwnode_endpoint bus_cfg = {
> > +		.bus_type = V4L2_MBUS_CSI2_DPHY
> > +	};
> > +	struct fwnode_handle *ep;
> > +	unsigned int i;
> > +	int ret;
> > +
> > +	if (!fwnode)
> > +		return -ENXIO;
> > +
> > +	imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
> 
> Not listed in the DT binding.
>
> > +	if (IS_ERR(imx492->power_gpio)) {
> > +		dev_err(imx492->dev, "failed to get power gpio %ld",
> > +			PTR_ERR(imx492->power_gpio));
> > +		return PTR_ERR(imx492->power_gpio);
> > +	}
> > +
> > +	imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
> 
> Not listed in the DT binding.

Both of the above are specific to this particular sensor board.  Other
implementations may well not have any of these.

> You should also handle regulators in the driver.

Err...

> > +	if (IS_ERR(imx492->oscen_gpio)) {
> > +		dev_err(imx492->dev, "failed to get oscen gpio %ld",
> > +			PTR_ERR(imx492->oscen_gpio));
> > +		return PTR_ERR(imx492->oscen_gpio);
> > +	}
> > +
> > +	imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> > +	if (IS_ERR(imx492->reset_gpio)) {
> > +		dev_err(imx492->dev, "failed to get reset gpio %ld",
> > +			PTR_ERR(imx492->reset_gpio));
> > +		return PTR_ERR(imx492->reset_gpio);
> > +	}
> > +
> > +	if (gpiod_direction_output(imx492->power_gpio, 1) ||
> > +	    gpiod_direction_output(imx492->oscen_gpio, 1) ||
> > +	    gpiod_direction_output(imx492->reset_gpio, 0)) {
> 
> This is done by devm_gpiod_get().

OK.

> > +		dev_err(imx492->dev, "failed to change gpio direction");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Get sensor input clock */
> > +	imx492->inclk = devm_clk_get(imx492->dev, NULL);
> > +	if (IS_ERR(imx492->inclk)) {
> > +		dev_err(imx492->dev, "could not get inclk");
> > +		return PTR_ERR(imx492->inclk);
> > +	}
> > +
> > +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> > +	if (!ep) {
> > +		dev_err(imx492->dev, "next endpoint?");
> > +		return -ENXIO;
> > +	}
> > +
> > +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> > +	fwnode_handle_put(ep);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "endpoint alloc parse");
> > +		return ret;
> > +	}
> > +
> > +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> > +		dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> > +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> > +		ret = -EINVAL;
> > +		goto done_endpoint_free;
> > +	}
> > +
> > +	if (!bus_cfg.nr_of_link_frequencies) {
> > +		dev_err(imx492->dev, "no link frequencies defined");
> > +		ret = -EINVAL;
> > +		goto done_endpoint_free;
> > +	}
> > +
> > +	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> > +		if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> > +			goto done_endpoint_free;
> > +	}
> > +
> > +	ret = -EINVAL;
> > +
> > +done_endpoint_free:
> > +	v4l2_fwnode_endpoint_free(&bus_cfg);
> > +
> > +	return ret;
> > +}
> > +
> > +/* V4l2 subdevice ops */
> > +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> > +	.s_stream = imx492_set_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> > +	.init_cfg = imx492_init_pad_cfg,
> > +	.enum_mbus_code = imx492_enum_mbus_code,
> > +	.enum_frame_size = imx492_enum_frame_size,
> > +	.get_fmt = imx492_get_pad_format,
> 
> Please use the subdev active state API. You need to call
> v4l2_subdev_init_finalize() at probe time, and you can set this to
> 
> 	.get_fmt = v4l2_subdev_get_fmt,

OK.

> Then, in imx492_set_pad_format() (and elsewhere as needed), you can use
> v4l2_subdev_get_pad_format() to replace v4l2_subdev_get_try_format(). This
> helps making code paths identical for the TRY and ACTIVE cases, the only
> exception being the update of controls in .set_fmt() in the ACTIVE case.
> 
> > +	.set_fmt = imx492_set_pad_format,
> 
> Please also implement the .get_selection operation to report the
> V4L2_SEL_TGT_CROP, V4L2_SEL_TGT_CROP_BOUNDS, V4L2_SEL_TGT_CROP_DEFAULT and
> V4L2_SEL_TGT_NATIVE_SIZE values.

Cropping is a big pain in the ass with this sensor and is currently not stable.
Could you please point me to an existing driver that's a good example?

> > +};
> > +
> > +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> > +	.video = &imx492_video_ops,
> > +	.pad = &imx492_pad_ops,
> > +};
> > +
> > +/**
> > + * imx492_power_on() - Sensor power on sequence
> > + * @dev: pointer to i2c device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_power_on(struct device *dev)
> > +{
> > +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +
> > +	gpiod_set_value_cansleep(imx492->power_gpio, 1);
> > +	msleep(1);
> > +	gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> > +	msleep(1);
> > +	gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> > +	msleep(1);
> 
> How about regulators and clock ?

In this particular case i don't have to alter any of them.  Do i need to prepare
some code for the general case?

> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_power_off() - Sensor power off sequence
> > + * @dev: pointer to i2c device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_power_off(struct device *dev)
> > +{
> > +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +
> > +	gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> > +	gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> > +	gpiod_set_value_cansleep(imx492->power_gpio, 0);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_init_controls() - Initialize sensor subdevice controls
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_init_controls(struct imx492 *imx492)
> > +{
> > +	struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> > +	const struct imx492_mode *mode = imx492->cur_mode;
> > +	u32 lpfr;
> > +	int ret;
> > +
> > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Serialize controls with sensor device */
> > +	ctrl_hdlr->lock = &imx492->mutex;
> > +	/* Initialize exposure and gain */
> > +	lpfr = mode->vblank + mode->height;
> > +	imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +					     &imx492_ctrl_ops,
> > +					     V4L2_CID_EXPOSURE,
> > +					     IMX492_EXPOSURE_MIN,
> > +					     lpfr - IMX492_EXPOSURE_OFFSET,
> > +					     IMX492_EXPOSURE_STEP,
> > +					     IMX492_EXPOSURE_DEFAULT);
> > +
> > +	imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +					       &imx492_ctrl_ops,
> > +					       V4L2_CID_ANALOGUE_GAIN,
> > +					       IMX492_AGAIN_MIN,
> > +					       IMX492_AGAIN_MAX,
> > +					       IMX492_AGAIN_STEP,
> > +					       IMX492_AGAIN_DEFAULT);
> > +
> > +	v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> > +
> > +	imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +						&imx492_ctrl_ops,
> > +						V4L2_CID_VBLANK,
> > +						mode->vblank_min,
> > +						mode->vblank_max,
> > +						1, mode->vblank);
> > +	/* Read only controls */
> > +	imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +						&imx492_ctrl_ops,
> > +						V4L2_CID_HBLANK,
> > +						mode->hblank_min,
> > +						mode->hblank_max,
> > +						1, mode->hblank);
> > +	if (imx492->hblank_ctrl)
> > +		imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +	imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +					      &imx492_ctrl_ops,
> > +					      V4L2_CID_PIXEL_RATE,
> > +					      mode->pclk, mode->pclk,
> > +					      1, mode->pclk);
> 
> Shouldn't this be read-only ?

Yup.

> > +
> > +	imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > +							&imx492_ctrl_ops,
> > +							V4L2_CID_LINK_FREQ,
> > +							ARRAY_SIZE(link_freq) -
> > +							1,
> > +							mode->link_freq_idx,
> > +							link_freq);
> > +	if (imx492->link_freq_ctrl)
> > +		imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> > +				     V4L2_CID_TEST_PATTERN,
> > +				     ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> > +				     0, 0, imx492_test_pattern_menu);
> > +
> > +	if (ctrl_hdlr->error) {
> > +		dev_err(imx492->dev, "control init failed: %d",	ctrl_hdlr->error);
> > +		v4l2_ctrl_handler_free(ctrl_hdlr);
> > +		return ctrl_hdlr->error;
> > +	}
> > +
> > +	imx492->sd.ctrl_handler = ctrl_hdlr;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * imx492_probe() - I2C client device binding
> > + * @client: pointer to i2c client device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_probe(struct i2c_client *client)
> > +{
> > +	struct imx492 *imx492;
> > +	int ret;
> > +
> > +	imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> > +	if (!imx492)
> > +		return -ENOMEM;
> > +
> > +	imx492->dev = &client->dev;
> > +
> > +	/* Initialize subdev */
> > +	v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> > +
> > +	ret = imx492_parse_hw_config(imx492);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "HW configuration is not supported");
> > +		return ret;
> > +	}
> > +
> > +	mutex_init(&imx492->mutex);
> > +
> > +	ret = imx492_power_on(imx492->dev);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "failed to power-on the sensor");
> > +		goto error_mutex_destroy;
> > +	}
> > +
> > +	/* Check module identity */
> > +	ret = imx492_detect(imx492);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "failed to find sensor: %d", ret);
> > +		goto error_power_off;
> > +	}
> > +
> > +	/* Set default mode to max resolution */
> > +	imx492->cur_mode = &supported_modes[0];
> > +	imx492->vblank = imx492->cur_mode->vblank;
> > +
> > +	ret = imx492_init_controls(imx492);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "failed to init controls: %d", ret);
> > +		goto error_power_off;
> > +	}
> > +
> > +	/* Initialize subdev */
> > +	imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > +	imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +
> > +	imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> > +	imx492->scap.capturemode = 0;
> > +	imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> > +	imx492->scap.timeperframe.numerator = 1;
> > +
> > +	/* Initialize source pad */
> > +	imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +	ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> > +	if (ret) {
> > +		dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> > +		goto error_handler_free;
> > +	}
> > +
> > +	ret = v4l2_async_register_subdev(&imx492->sd);
> > +	if (ret < 0) {
> > +		dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> > +		goto error_media_entity;
> > +	}
> 
> This should be done at the very end of probe(), as the sensor can be used
> right after it gets registered, so it should be fully operational.
> 
> > +
> > +	pm_runtime_set_active(imx492->dev);
> > +	pm_runtime_enable(imx492->dev);
> > +	pm_runtime_idle(imx492->dev);
> 
> While at it, I would also implement autosuspend. You should then add a call to
> pm_runtime_get_noresume() before pm_runtime_enable(), drop the
> pm_runtime_idle() call, and add

From what i can see most, even 2022, drivers come with the above sequence.
Which one does it right?

> 	pm_runtime_set_autosuspend_delay(imx492->dev, 1000);
> 	pm_runtime_use_autosuspend(imx492->dev);
> 	pm_runtime_put_autosuspend(imx492->dev);
> 
> You will also need to replace pm_runtime_put() with
> pm_runtime_mark_last_busy() + pm_runtime_put_autosuspend() above.
> 
> > +
> > +	return 0;
> > +
> > +error_media_entity:
> > +	media_entity_cleanup(&imx492->sd.entity);
> > +error_handler_free:
> > +	v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> > +error_power_off:
> > +	imx492_power_off(imx492->dev);
> > +error_mutex_destroy:
> > +	mutex_destroy(&imx492->mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * imx492_remove() - I2C client device unbinding
> > + * @client: pointer to I2C client device
> > + */
> > +static void imx492_remove(struct i2c_client *client)
> > +{
> > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +	struct imx492 *imx492 = to_imx492(sd);
> > +
> > +	v4l2_async_unregister_subdev(sd);
> > +	media_entity_cleanup(&sd->entity);
> > +	v4l2_ctrl_handler_free(sd->ctrl_handler);
> > +	pm_runtime_disable(&client->dev);
> > +	if (!pm_runtime_status_suspended(&client->dev))
> > +		imx492_power_off(&client->dev);
> > +	pm_runtime_set_suspended(&client->dev);
> > +	mutex_destroy(&imx492->mutex);
> > +}
> > +
> > +static const struct dev_pm_ops imx492_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> > +};
> > +
> > +static const struct of_device_id imx492_of_match[] = {
> > +	{ .compatible = "sony,imx492_mipi" },
> > +	{ }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, imx492_of_match);
> > +
> > +static struct i2c_driver imx492_driver = {
> > +	.probe_new = imx492_probe,
> > +	.remove = imx492_remove,
> > +	.driver = {
> > +		.name = "imx492",
> > +		.pm = &imx492_pm_ops,
> > +		.of_match_table = imx492_of_match,
> > +	},
> > +};
> > +
> > +module_i2c_driver(imx492_driver);
> > +
> > +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> > +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> > +MODULE_LICENSE("GPL");
> 
> -- 
> Regards,
> 
> Laurent Pinchart


cheers,
Petko

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-28 13:38     ` Kieran Bingham
@ 2022-11-28 13:46       ` Laurent Pinchart
  2022-11-28 14:07       ` Petko Manolov
  1 sibling, 0 replies; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28 13:46 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: Petko Manolov, linux-media, sakari.ailus

On Mon, Nov 28, 2022 at 01:38:12PM +0000, Kieran Bingham wrote:
> Quoting Petko Manolov (2022-11-28 13:11:39)
> > On 22-11-28 12:45:32, Kieran Bingham wrote:
> > > Hi Petko,
> > > 
> > > What device/ISP are you testing this sensor on?
> > 
> > I'll tell you, but only if you promise to not laugh too much.  Deal?
> > 
> > i.MX8M-Mini
> > 
> > I hope nobody will notice the above line...
> 
> I won't laugh at all. We've just merged the ISI pipeline handler for
> libcamera, which should let you use libcamera on this target (I think).

The i.MX8MM doesn't have an ISI. The i.MX8MN does, but with a single
pipeline, so it won't work out of the box with libcamera, but it should
be easy to support it.

The i.MX8MM has a CSI bridge (CSI stands for CMOS Sensor Interface
there, it's a DMA engine, not to be confused with the CSI-2 receiver)
which should work with the simple pipeline handler.

> I would hope sometime in the future you'd be able to use the ISI
> pipeline handler with a GPU based ISP with this sensor too.
> 
> How are you managing the image 3a? the imx492 is a raw sensor isn't it ?
> 
> > > Quoting Petko Manolov (2022-11-25 15:31:15)
> > > > This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> > > > image sensor.
> > > > 
> > > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > > digital output makes it possible to output the signals with high definition for
> > > > moving pictures. It is programmable through I2C interface. The I2C client
> > > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > > through MIPI CSI-2.
> > > > 
> > > > Petko Manolov (5):
> > > >   DT bindings for imx492
> > > >   media: i2c: imx492: driver's header
> > > >   media: i2c: imx492: driver's source
> > > >   media: i2c: add imx492 config entry
> > > >   media: i2c: add imx492 entry for make
> > > 
> > > Could you squash patches 2, 3, 4, and 5 into a single patch please?
> > 
> > This is the exact opposite to what the networking folks would prefer, but it's
> > OK with me.
> 
> Haha ... yes - isn't it great working in mulitple subsystems....
> 
> > > Also - I think you'll need an entry in MAINTAINERS.
> > 
> > Right, that one too.
> > 
> > > I can't see any reference to the selection controls:
> > >  - V4L2_SEL_TGT_CROP_DEFAULT
> > >  - V4L2_SEL_TGT_CROP
> > >  - V4L2_SEL_TGT_CROP_BOUNDS
> > 
> > These are in a very early phase of implementing.
> 
> Ok
> 
> > > Do you have the datasheet or sufficient information to be able to implement
> > > these controls?
> > 
> > Of course not.  We are brute forcing our way forward by mostly reverse
> > engineering another solution that has an FPGA on the other end of the CSI link.
> 
> Understood ;-) (and ... I think what I was fearing/anticipating).
>
> > > >  .../bindings/media/i2c/sony,imx492.yaml       |  101 ++
> > > >  drivers/media/i2c/Kconfig                     |   14 +
> > > >  drivers/media/i2c/Makefile                    |    1 +
> > > >  drivers/media/i2c/imx492.c                    | 1092 +++++++++++++++++
> > > >  drivers/media/i2c/imx492.h                    |  555 +++++++++
> > > >  5 files changed, 1763 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx492.yaml
> > > >  create mode 100644 drivers/media/i2c/imx492.c
> > > >  create mode 100644 drivers/media/i2c/imx492.h

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-28 12:58   ` Kieran Bingham
@ 2022-11-28 13:48     ` Petko Manolov
  0 siblings, 0 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:48 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-media, laurent.pinchart, sakari.ailus

On 22-11-28 12:58:59, Kieran Bingham wrote:
> Quoting Petko Manolov (2022-11-25 15:31:18)
> > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > digital output makes it possible to output the signals with high definition for
> > moving pictures. It is programmable through I2C interface. The I2C client
> > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > through MIPI CSI-2.
> > 
> > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > ---
> >  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 1092 insertions(+)
> >  create mode 100644 drivers/media/i2c/imx492.c
> > 
> > diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> > new file mode 100644
> > index 000000000000..0713256b4b63
> > --- /dev/null
> > +++ b/drivers/media/i2c/imx492.c
> > @@ -0,0 +1,1092 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> > + *
> > + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regulator/consumer.h>
> > +
> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +
> > +#include "imx492.h"
> > +
> > +/* Streaming Mode */
> > +#define IMX492_REG_MODE_SELECT 0x3000
> > +
> > +/* Chip ID */
> > +#define IMX492_ID              0x13
> 
> This seems ... surprising to me.

It is.  There's no ID register mentioned anywhere in the documentation.  The one
that's used in other Sony sensors returns garbage and prefered not to base the
probe() on that.

> > +/* Analog gain control */
> > +#define IMX492_REG_AGAIN       0x300a
> > +#define IMX492_AGAIN_MIN       0
> > +#define IMX492_AGAIN_MAX       978
> > +#define IMX492_AGAIN_STEP      1
> > +#define IMX492_AGAIN_DEFAULT   0
> > +
> > +/* Group hold register */
> > +#define IMX492_REG_HOLD                0x302b
> > +#define        IMX492_REG_XMSTA        0x3033
> > +#define        IMX492_REG_SYSCLKEN     0x35e5
> > +
> > +/* CSI2 HW configuration */
> > +#define IMX492_LINK_FREQ       745000000
> > +#define IMX492_NUM_DATA_LANES  4
> > +
> > +#define IMX492_REG_MIN         0x3000
> > +#define IMX492_REG_MAX         0xffff
> > +
> > +/* *** */
> > +
> > +#define IMX492_REG_STANDBY     IMX492_REG_MODE_SELECT
> 
> Is it a standby register? or a mode select register ?

Both.  I've explained it in a previous email.

> > +#define IMX492_BIT_STANDBY     0x01
> > +#define IMX492_BIT_STBLOGIC    0x02
> > +#define IMX492_BIT_STBDV       0x10
> > +
> > +#define IMX492_MODE_STANDBY    (IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> > +#define IMX492_MODE_STREAMING  0x00
> > +
> > +#define IMX492_REG_TESTPTRN    0x303A
> > +#define IMX492_BIT_CLKEN       0x01
> > +#define IMX492_BIT_TESTPTRN    0x10
> > +#define IMX492_BITS_TPTRN_ON   (IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> > +#define IMX492_BITS_TPTRN_OFF  0x00
> > +
> > +#define IMX492_REG_TESTPATSEL  0x303B
> > +#define IMX492_BIT_TPAT00      0x00
> > +#define IMX492_BIT_TPAT01      0x01
> > +#define IMX492_BIT_TPAT02      0x02
> > +#define IMX492_BIT_TPAT03      0x03
> > +#define IMX492_BIT_TPAT0A      0x0A
> > +#define IMX492_BIT_TPAT0B      0x0B
> > +
> > +#define IMX492_EXPOSURE_MIN            8
> > +#define IMX492_EXPOSURE_OFFSET         22
> > +#define IMX492_EXPOSURE_STEP           1
> > +#define IMX492_EXPOSURE_DEFAULT                0x0648
> > +
> > +#define        DEFAULT_FPS             6
> > +
> > +/**
> > + * struct imx492_reg_list - imx492 sensor register list
> > + * @num_of_regs: Number of registers in the list
> > + * @regs: Pointer to register list
> > + */
> > +struct imx492_reg_list {
> > +       u32 num_of_regs;
> > +       const struct imx492_reg *regs;
> > +};
> > +
> > +/**
> > + * struct imx492_mode - imx492 sensor mode structure
> > + * @width: Frame width
> > + * @height: Frame height
> > + * @code: Format code
> > + * @hblank: Horizontal blanking in lines
> > + * @vblank: Vertical blanking in lines
> > + * @vblank_min: Minimum vertical blanking in lines
> > + * @vblank_max: Maximum vertical blanking in lines
> > + * @pclk: Sensor pixel clock
> > + * @link_freq_idx: Link frequency index
> > + * @reg_list: Register list for sensor mode
> > + */
> > +struct imx492_mode {
> > +       u32 width;
> > +       u32 height;
> > +       u32 code;
> > +       u32 hblank;
> > +       u32 hblank_min;
> > +       u32 hblank_max;
> > +       u32 vblank;
> > +       u32 vblank_min;
> > +       u32 vblank_max;
> > +       u64 pclk;
> > +       u32 link_freq_idx;
> > +       struct imx492_reg_list reg_list;
> > +};
> > +
> > +/**
> > + * struct imx492 - imx492 sensor device structure
> > + * @dev: Pointer to generic device
> > + * @client: Pointer to i2c client
> > + * @sd: V4L2 sub-device
> > + * @pad: Media pad. Only one pad supported
> > + * @reset_gpio: Sensor reset gpio
> > + * @reset_gpio: Sensor power gpio
> > + * @inclk: Sensor input clock
> > + * @supplies: Regulator supplies
> > + * @ctrl_handler: V4L2 control handler
> > + * @link_freq_ctrl: Pointer to link frequency control
> > + * @pclk_ctrl: Pointer to pixel clock control
> > + * @hblank_ctrl: Pointer to horizontal blanking control
> > + * @vblank_ctrl: Pointer to vertical blanking control
> > + * @exp_ctrl: Pointer to exposure control
> > + * @again_ctrl: Pointer to analog gain control
> > + * @vblank: Vertical blanking in lines
> > + * @cur_mode: Pointer to current selected sensor mode
> > + * @mutex: Mutex for serializing sensor controls
> > + * @streaming: Flag indicating streaming state
> > + */
> > +struct imx492 {
> > +       struct device *dev;
> > +       struct i2c_client *client;
> > +       struct v4l2_subdev sd;
> > +       struct media_pad pad;
> > +       struct v4l2_captureparm scap;
> > +       struct gpio_desc *reset_gpio;
> > +       struct gpio_desc *power_gpio;
> > +       struct gpio_desc *oscen_gpio;
> > +       struct clk *inclk;
> > +       struct v4l2_ctrl_handler ctrl_handler;
> > +       struct v4l2_ctrl *link_freq_ctrl;
> > +       struct v4l2_ctrl *pclk_ctrl;
> > +       struct v4l2_ctrl *hblank_ctrl;
> > +       struct v4l2_ctrl *vblank_ctrl;
> > +       struct v4l2_ctrl *exp_ctrl;
> > +       struct v4l2_ctrl *again_ctrl;
> > +       const struct imx492_mode *cur_mode;
> > +       struct mutex mutex;
> > +       u32 tpatt;
> > +       u32 vblank;
> > +       bool streaming;
> > +};
> > +
> > +static const s64 link_freq[] = {
> > +       IMX492_LINK_FREQ,
> > +};
> > +
> > +
> > +/* Supported sensor mode configurations */
> > +static const struct imx492_mode supported_modes[] = {
> > +       {
> > +               .width = 8192,
> > +               .height = 4320,
> > +               .hblank = 1108,
> > +               .hblank_min = 1102,
> > +               .hblank_max = 32768,
> > +               .vblank = 5728,
> > +               .vblank_min = 4428,
> > +               .vblank_max = 32768,
> > +               .pclk = 745000000,
> > +               .link_freq_idx = 0,
> > +               .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > +               .reg_list = {
> > +                       .num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> > +                       .regs = mode_17to9_regs,
> > +               },
> > +       }, {
> > +               .width = 8192,
> > +               .height = 5556,
> > +               .hblank = 1108,
> > +               .hblank_min = 1102,
> > +               .hblank_max = 32768,
> > +               .vblank = 5728,
> > +               .vblank_min = 4428,
> > +               .vblank_max = 32768,
> > +               .pclk = 745000000,
> > +               .link_freq_idx = 0,
> > +               .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > +               .reg_list = {
> > +                       .num_of_regs = ARRAY_SIZE(mode_all_regs),
> > +                       .regs = mode_all_regs,
> > +               },
> > +       },
> > +};
> > +
> > +static const char * const imx492_test_pattern_menu[] = {
> > +       "Disabled",
> > +       "Solid black",
> > +       "Solid white",
> > +       "Solid dark grey",
> > +       "Solid light gray",
> > +       "None",
> > +       "None",
> > +       "None",
> > +       "None",
> > +       "None",
> > +       "None",
> 
> Why so many 'none' entries. Can this be improved?

Sony don't have anything documented for these numbers.  I did it this way becase
it was easier vs enum and strings array.

> > +       "Vertical color bars",
> > +       "Horizontal color bars",
> > +};
> > +
> > +/**
> > + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> > + * @subdev: pointer to imx492 V4L2 sub-device
> > + *
> > + * Return: pointer to imx492 device
> > + */
> > +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> > +{
> > +       return container_of(subdev, struct imx492, sd);
> > +}
> > +
> > +/**
> > + * imx492_read_reg() - Read registers.
> > + * @imx492: pointer to imx492 device
> > + * @reg: register address
> > + * @len: length of bytes to read. Max supported bytes is 4
> > + * @val: pointer to register value to be filled.
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> > +{
> > +       struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > +       struct i2c_msg msgs[2] = {0};
> > +       u8 addr_buf[2] = {0};
> > +       u8 data_buf[4] = {0};
> > +       int ret;
> > +
> > +       if (WARN_ON(len > 4))
> > +               return -EINVAL;
> > +
> > +       put_unaligned_be16(reg, addr_buf);
> > +
> > +       /* Write register address */
> > +       msgs[0].addr = client->addr;
> > +       msgs[0].flags = 0;
> > +       msgs[0].len = ARRAY_SIZE(addr_buf);
> > +       msgs[0].buf = addr_buf;
> > +
> > +       /* Read data from register */
> > +       msgs[1].addr = client->addr;
> > +       msgs[1].flags = I2C_M_RD;
> > +       msgs[1].len = len;
> > +       msgs[1].buf = &data_buf[4 - len];
> > +
> > +       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> > +       if (ret != ARRAY_SIZE(msgs))
> > +               return -EIO;
> > +
> > +       *val = get_unaligned_be32(data_buf);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_write_reg() - Write register
> > + * @imx492: pointer to imx492 device
> > + * @reg: register address
> > + * @len: length of bytes. Max supported bytes is 4
> > + * @val: register value
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> > +{
> > +       struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > +       u8 buf[6] = {0};
> > +
> > +       if (WARN_ON(len > 4))
> > +               return -EINVAL;
> > +
> > +       put_unaligned_be16(reg, buf);
> > +       put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> > +       if (i2c_master_send(client, buf, len + 2) != len + 2)
> > +               return -EIO;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_write_regs() - Write a list of registers
> > + * @imx492: pointer to imx492 device
> > + * @regs: list of registers to be written
> > + * @len: length of registers array
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_write_regs(struct imx492 *imx492,
> > +                            const struct imx492_reg *regs, u32 len)
> > +{
> > +       unsigned int i;
> > +       int ret;
> > +
> > +       for (i = 0; i < len; i++) {
> > +               ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> > +{
> > +       /* for now this is the only format we support */
> > +       return MEDIA_BUS_FMT_SGBRG12_1X12;
> > +}
> > +
> > +/**
> > + * imx492_update_controls() - Update control ranges based on streaming mode
> > + * @imx492: pointer to imx492 device
> > + * @mode: pointer to imx492_mode sensor mode
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_update_controls(struct imx492 *imx492,
> > +                                 const struct imx492_mode *mode)
> > +{
> > +       int ret;
> > +
> > +       ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> > +       if (ret)
> > +               return ret;
> > +
> > +       ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> > +                                       mode->vblank_max, 1, mode->vblank);
> > +}
> > +
> > +/**
> > + * imx492_update_exp_gain() - Set updated exposure and gain
> > + * @imx492: pointer to imx492 device
> > + * @exposure: updated exposure value
> > + * @gain: updated analog gain value
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> > +{
> > +       u32 lpfr, shutter;
> > +       int ret;
> > +
> > +       lpfr = imx492->vblank + imx492->cur_mode->height;
> > +       shutter = lpfr - exposure;
> > +
> > +       ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> > +       if (ret)
> > +               return ret;
> > +
> > +       ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * imx492_set_ctrl() - Set subdevice control
> > + * @ctrl: pointer to v4l2_ctrl structure
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +       struct imx492 *imx492 =
> > +               container_of(ctrl->handler, struct imx492, ctrl_handler);
> > +       u32 analog_gain;
> > +       u32 exposure;
> > +       int ret;
> > +
> > +       switch (ctrl->id) {
> > +       case V4L2_CID_VBLANK:
> > +               imx492->vblank = imx492->vblank_ctrl->val;
> > +
> > +               ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> > +                                              IMX492_EXPOSURE_MIN,
> > +                                              imx492->vblank +
> > +                                              imx492->cur_mode->height -
> > +                                              IMX492_EXPOSURE_OFFSET,
> > +                                              1, IMX492_EXPOSURE_DEFAULT);
> > +               break;
> > +       case V4L2_CID_EXPOSURE:
> > +               /* Set controls only if sensor is in power on state */
> > +               if (!pm_runtime_get_if_in_use(imx492->dev))
> > +                       return 0;
> > +               exposure = ctrl->val;
> > +               analog_gain = imx492->again_ctrl->val;
> > +               ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> > +               pm_runtime_put(imx492->dev);
> > +               break;
> > +       case V4L2_CID_TEST_PATTERN:
> > +               if (ctrl->val) {
> > +                       imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> > +                       imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> > +               } else {
> > +                       imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> > +               }
> > +               ret = 0;
> > +               break;
> > +       default:
> > +               dev_err(imx492->dev, "Invalid control %d", ctrl->id);
> > +               ret = -EINVAL;
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +/* V4l2 subdevice control ops*/
> > +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> > +       .s_ctrl = imx492_set_ctrl,
> > +};
> > +
> > +/**
> > + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @code: V4L2 sub-device code enumeration need to be filled
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_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(supported_modes))
> > +               return -EINVAL;
> > +
> > +       code->code = supported_modes[code->index].code;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fsize: V4L2 sub-device size enumeration need to be filled
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> > +                                 struct v4l2_subdev_state *sd_state,
> > +                                 struct v4l2_subdev_frame_size_enum *fsize)
> > +{
> > +       if (fsize->index > ARRAY_SIZE(supported_modes))
> > +               return -EINVAL;
> > +
> > +       if (fsize->code != supported_modes[fsize->index].code)
> > +               return -EINVAL;
> > +
> > +       fsize->max_width = supported_modes[fsize->index].width;
> > +       fsize->min_width = fsize->max_width;
> > +       fsize->max_height = supported_modes[fsize->index].height;
> > +       fsize->min_height = fsize->max_height;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > +n * imx492_fill_pad_format() - Fill subdevice pad format
> > + *                            from selected sensor mode
> > + * @imx492: pointer to imx492 device
> > + * @mode: pointer to imx492_mode sensor mode
> > + * @fmt: V4L2 sub-device format need to be filled
> > + */
> > +static void imx492_fill_pad_format(struct imx492 *imx492,
> > +                                  const struct imx492_mode *mode,
> > +                                  struct v4l2_subdev_format *fmt)
> > +{
> > +       fmt->format.width = mode->width;
> > +       fmt->format.height = mode->height;
> > +       fmt->format.code = mode->code;
> > +       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;
> > +}
> > +
> > +/**
> > + * imx492_get_pad_format() - Get subdevice pad format
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fmt: V4L2 sub-device format need to be set
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> > +                                struct v4l2_subdev_state *sd_state,
> > +                                struct v4l2_subdev_format *fmt)
> > +{
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +
> > +       mutex_lock(&imx492->mutex);
> > +
> > +       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > +               struct v4l2_mbus_framefmt *framefmt;
> > +
> > +               framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > +               fmt->format = *framefmt;
> > +       } else {
> > +               imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> > +       }
> > +
> > +       mutex_unlock(&imx492->mutex);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_set_pad_format() - Set subdevice pad format
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + * @fmt: V4L2 sub-device format need to be set
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> > +                                struct v4l2_subdev_state *sd_state,
> > +                                struct v4l2_subdev_format *fmt)
> > +{
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +       const struct imx492_mode *mode;
> > +       int ret = 0;
> > +
> > +       mutex_lock(&imx492->mutex);
> > +
> > +       fmt->format.code = imx492_get_format_code(imx492, 0);
> > +       mode = v4l2_find_nearest_size(supported_modes,
> > +                                       ARRAY_SIZE(supported_modes),
> > +                                       width, height,
> > +                                       fmt->format.width, fmt->format.height);
> > +       imx492_fill_pad_format(imx492, mode, fmt);
> > +
> > +       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > +               struct v4l2_mbus_framefmt *framefmt;
> > +
> > +               framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > +               *framefmt = fmt->format;
> > +       } else {
> > +               ret = imx492_update_controls(imx492, mode);
> > +               if (!ret)
> > +                       imx492->cur_mode = mode;
> > +       }
> > +
> > +       mutex_unlock(&imx492->mutex);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> > + * @sd: pointer to imx492 V4L2 sub-device structure
> > + * @sd_state: V4L2 sub-device configuration
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> > +                              struct v4l2_subdev_state *sd_state)
> > +{
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +       struct v4l2_subdev_format fmt = { 0 };
> > +
> > +       fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
> > +       imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> > +
> > +       return imx492_set_pad_format(sd, sd_state, &fmt);
> > +}
> > +
> > +/**
> > + * imx492_start_streaming() - Start sensor stream
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_start_streaming(struct imx492 *imx492)
> > +{
> > +       const struct imx492_reg_list *reg_list;
> > +       int ret;
> > +
> > +       /* Write sensor mode registers */
> > +       reg_list = &imx492->cur_mode->reg_list;
> > +       ret = imx492_write_regs(imx492, reg_list->regs,
> > +                               reg_list->num_of_regs);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "fail to write initial registers");
> > +               return ret;
> > +       }
> > +
> > +       /* Setup handler will write actual exposure and gain */
> > +       ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "fail to setup handler");
> > +               return ret;
> > +       }
> > +
> > +       /* 1st stabilization period */
> > +       usleep_range(10000, 11000);
> > +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> > +       imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> > +       imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> > +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> > +
> > +       /* 2nd stabilization period */
> > +       usleep_range(7000, 8000);
> > +
> > +       /* Start streaming */
> > +       ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> > +
> > +       if (ret) {
> > +               dev_err(imx492->dev, "fail to start streaming");
> > +               return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_stop_streaming() - Stop sensor stream
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static void imx492_stop_streaming(struct imx492 *imx492)
> > +{
> > +       imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> > +       imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> > +}
> > +
> > +/**
> > + * imx492_set_stream() - Enable sensor streaming
> > + * @sd: pointer to imx492 subdevice
> > + * @enable: set to enable sensor streaming
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> > +{
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +       int ret;
> > +
> > +       mutex_lock(&imx492->mutex);
> > +
> > +       if (imx492->streaming == enable) {
> > +               mutex_unlock(&imx492->mutex);
> > +               return 0;
> > +       }
> > +
> > +       if (enable) {
> > +               ret = pm_runtime_resume_and_get(imx492->dev);
> > +               if (ret)
> > +                       goto error_unlock;
> > +               ret = imx492_start_streaming(imx492);
> > +               if (ret)
> > +                       goto error_power_off;
> > +       } else {
> > +               imx492_stop_streaming(imx492);
> > +               pm_runtime_put(imx492->dev);
> > +       }
> > +
> > +       imx492->streaming = enable;
> > +
> > +       mutex_unlock(&imx492->mutex);
> > +
> > +       return 0;
> > +
> > +error_power_off:
> > +       pm_runtime_put(imx492->dev);
> > +error_unlock:
> > +       mutex_unlock(&imx492->mutex);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * imx492_detect() - Detect imx492 sensor
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, -EIO if sensor id does not match
> > + */
> > +static int imx492_detect(struct imx492 *imx492)
> > +{
> > +       int ret;
> > +       u32 val;
> > +
> > +       ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);
> 
> This seems an odd register to read for the ID?
> 
> And why is it mapped to IMX492_REG_MODE_SELECT ?
> How does this give us the ID?
> 
> > +       if (ret)
> > +               return ret;
> > +
> > +       if (val != IMX492_ID) {
> 
> And seeing other IMX sensors, I would have expected the IMX492_ID to be
> 0x0492 ?
> 
> What is the contents of register 0x0016 ?

This sensor can operate in two modes, CSI and Sony's proprietary SLVS.  All
registers that have a meaning in the CSI case are at offset 0x3000.  Some are
present in one mode and missing in the other.  Like i said, it is a bit of a
mess garnished with really crappy documentation.

> > +               dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> > +               return -ENXIO;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_parse_hw_config(struct imx492 *imx492)
> > +{
> > +       struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> > +       struct v4l2_fwnode_endpoint bus_cfg = {
> > +               .bus_type = V4L2_MBUS_CSI2_DPHY
> > +       };
> > +       struct fwnode_handle *ep;
> > +       unsigned int i;
> > +       int ret;
> > +
> > +       if (!fwnode)
> > +               return -ENXIO;
> > +
> > +       imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
> > +       if (IS_ERR(imx492->power_gpio)) {
> > +               dev_err(imx492->dev, "failed to get power gpio %ld",
> > +                       PTR_ERR(imx492->power_gpio));
> > +               return PTR_ERR(imx492->power_gpio);
> > +       }
> > +
> > +       imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
> > +       if (IS_ERR(imx492->oscen_gpio)) {
> > +               dev_err(imx492->dev, "failed to get oscen gpio %ld",
> > +                       PTR_ERR(imx492->oscen_gpio));
> > +               return PTR_ERR(imx492->oscen_gpio);
> > +       }
> > +
> > +       imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> > +       if (IS_ERR(imx492->reset_gpio)) {
> > +               dev_err(imx492->dev, "failed to get reset gpio %ld",
> > +                       PTR_ERR(imx492->reset_gpio));
> > +               return PTR_ERR(imx492->reset_gpio);
> > +       }
> > +
> > +       if (gpiod_direction_output(imx492->power_gpio, 1) ||
> > +           gpiod_direction_output(imx492->oscen_gpio, 1) ||
> > +           gpiod_direction_output(imx492->reset_gpio, 0)) {
> > +               dev_err(imx492->dev, "failed to change gpio direction");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Get sensor input clock */
> > +       imx492->inclk = devm_clk_get(imx492->dev, NULL);
> > +       if (IS_ERR(imx492->inclk)) {
> > +               dev_err(imx492->dev, "could not get inclk");
> > +               return PTR_ERR(imx492->inclk);
> > +       }
> > +
> > +       ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> > +       if (!ep) {
> > +               dev_err(imx492->dev, "next endpoint?");
> > +               return -ENXIO;
> > +       }
> > +
> > +       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> > +       fwnode_handle_put(ep);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "endpoint alloc parse");
> > +               return ret;
> > +       }
> > +
> > +       if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> > +               dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> > +                       bus_cfg.bus.mipi_csi2.num_data_lanes);
> > +               ret = -EINVAL;
> > +               goto done_endpoint_free;
> > +       }
> > +
> > +       if (!bus_cfg.nr_of_link_frequencies) {
> > +               dev_err(imx492->dev, "no link frequencies defined");
> > +               ret = -EINVAL;
> > +               goto done_endpoint_free;
> > +       }
> > +
> > +       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> > +               if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> > +                       goto done_endpoint_free;
> > +       }
> > +
> > +       ret = -EINVAL;
> > +
> > +done_endpoint_free:
> > +       v4l2_fwnode_endpoint_free(&bus_cfg);
> > +
> > +       return ret;
> > +}
> > +
> > +/* V4l2 subdevice ops */
> > +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> > +       .s_stream = imx492_set_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> > +       .init_cfg = imx492_init_pad_cfg,
> > +       .enum_mbus_code = imx492_enum_mbus_code,
> > +       .enum_frame_size = imx492_enum_frame_size,
> > +       .get_fmt = imx492_get_pad_format,
> > +       .set_fmt = imx492_set_pad_format,
> > +};
> > +
> > +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> > +       .video = &imx492_video_ops,
> > +       .pad = &imx492_pad_ops,
> > +};
> > +
> > +/**
> > + * imx492_power_on() - Sensor power on sequence
> > + * @dev: pointer to i2c device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_power_on(struct device *dev)
> > +{
> > +       struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +
> > +       gpiod_set_value_cansleep(imx492->power_gpio, 1);
> > +       msleep(1);
> > +       gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> > +       msleep(1);
> > +       gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> > +       msleep(1);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_power_off() - Sensor power off sequence
> > + * @dev: pointer to i2c device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_power_off(struct device *dev)
> > +{
> > +       struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +
> > +       gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> > +       gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> > +       gpiod_set_value_cansleep(imx492->power_gpio, 0);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_init_controls() - Initialize sensor subdevice controls
> > + * @imx492: pointer to imx492 device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_init_controls(struct imx492 *imx492)
> > +{
> > +       struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> > +       const struct imx492_mode *mode = imx492->cur_mode;
> > +       u32 lpfr;
> > +       int ret;
> > +
> > +       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> > +       if (ret)
> > +               return ret;
> > +
> > +       /* Serialize controls with sensor device */
> > +       ctrl_hdlr->lock = &imx492->mutex;
> > +       /* Initialize exposure and gain */
> > +       lpfr = mode->vblank + mode->height;
> > +       imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +                                            &imx492_ctrl_ops,
> > +                                            V4L2_CID_EXPOSURE,
> > +                                            IMX492_EXPOSURE_MIN,
> > +                                            lpfr - IMX492_EXPOSURE_OFFSET,
> > +                                            IMX492_EXPOSURE_STEP,
> > +                                            IMX492_EXPOSURE_DEFAULT);
> > +
> > +       imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +                                              &imx492_ctrl_ops,
> > +                                              V4L2_CID_ANALOGUE_GAIN,
> > +                                              IMX492_AGAIN_MIN,
> > +                                              IMX492_AGAIN_MAX,
> > +                                              IMX492_AGAIN_STEP,
> > +                                              IMX492_AGAIN_DEFAULT);
> > +
> > +       v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> > +
> > +       imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +                                               &imx492_ctrl_ops,
> > +                                               V4L2_CID_VBLANK,
> > +                                               mode->vblank_min,
> > +                                               mode->vblank_max,
> > +                                               1, mode->vblank);
> > +       /* Read only controls */
> > +       imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +                                               &imx492_ctrl_ops,
> > +                                               V4L2_CID_HBLANK,
> > +                                               mode->hblank_min,
> > +                                               mode->hblank_max,
> > +                                               1, mode->hblank);
> > +       if (imx492->hblank_ctrl)
> > +               imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +       imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > +                                             &imx492_ctrl_ops,
> > +                                             V4L2_CID_PIXEL_RATE,
> > +                                             mode->pclk, mode->pclk,
> > +                                             1, mode->pclk);
> > +
> > +       imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > +                                                       &imx492_ctrl_ops,
> > +                                                       V4L2_CID_LINK_FREQ,
> > +                                                       ARRAY_SIZE(link_freq) -
> > +                                                       1,
> > +                                                       mode->link_freq_idx,
> > +                                                       link_freq);
> > +       if (imx492->link_freq_ctrl)
> > +               imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> > +                                    V4L2_CID_TEST_PATTERN,
> > +                                    ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> > +                                    0, 0, imx492_test_pattern_menu);
> > +
> > +       if (ctrl_hdlr->error) {
> > +               dev_err(imx492->dev, "control init failed: %d", ctrl_hdlr->error);
> > +               v4l2_ctrl_handler_free(ctrl_hdlr);
> > +               return ctrl_hdlr->error;
> > +       }
> > +
> > +       imx492->sd.ctrl_handler = ctrl_hdlr;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * imx492_probe() - I2C client device binding
> > + * @client: pointer to i2c client device
> > + *
> > + * Return: 0 if successful, error code otherwise.
> > + */
> > +static int imx492_probe(struct i2c_client *client)
> > +{
> > +       struct imx492 *imx492;
> > +       int ret;
> > +
> > +       imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> > +       if (!imx492)
> > +               return -ENOMEM;
> > +
> > +       imx492->dev = &client->dev;
> > +
> > +       /* Initialize subdev */
> > +       v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> > +
> > +       ret = imx492_parse_hw_config(imx492);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "HW configuration is not supported");
> > +               return ret;
> > +       }
> > +
> > +       mutex_init(&imx492->mutex);
> > +
> > +       ret = imx492_power_on(imx492->dev);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "failed to power-on the sensor");
> > +               goto error_mutex_destroy;
> > +       }
> > +
> > +       /* Check module identity */
> > +       ret = imx492_detect(imx492);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "failed to find sensor: %d", ret);
> > +               goto error_power_off;
> > +       }
> > +
> > +       /* Set default mode to max resolution */
> > +       imx492->cur_mode = &supported_modes[0];
> > +       imx492->vblank = imx492->cur_mode->vblank;
> > +
> > +       ret = imx492_init_controls(imx492);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "failed to init controls: %d", ret);
> > +               goto error_power_off;
> > +       }
> > +
> > +       /* Initialize subdev */
> > +       imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > +       imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +
> > +       imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> > +       imx492->scap.capturemode = 0;
> > +       imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> > +       imx492->scap.timeperframe.numerator = 1;
> > +
> > +       /* Initialize source pad */
> > +       imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +       ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> > +       if (ret) {
> > +               dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> > +               goto error_handler_free;
> > +       }
> > +
> > +       ret = v4l2_async_register_subdev(&imx492->sd);
> > +       if (ret < 0) {
> > +               dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> > +               goto error_media_entity;
> > +       }
> > +
> > +       pm_runtime_set_active(imx492->dev);
> > +       pm_runtime_enable(imx492->dev);
> > +       pm_runtime_idle(imx492->dev);
> > +
> > +       return 0;
> > +
> > +error_media_entity:
> > +       media_entity_cleanup(&imx492->sd.entity);
> > +error_handler_free:
> > +       v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> > +error_power_off:
> > +       imx492_power_off(imx492->dev);
> > +error_mutex_destroy:
> > +       mutex_destroy(&imx492->mutex);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * imx492_remove() - I2C client device unbinding
> > + * @client: pointer to I2C client device
> > + */
> > +static void imx492_remove(struct i2c_client *client)
> > +{
> > +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +       struct imx492 *imx492 = to_imx492(sd);
> > +
> > +       v4l2_async_unregister_subdev(sd);
> > +       media_entity_cleanup(&sd->entity);
> > +       v4l2_ctrl_handler_free(sd->ctrl_handler);
> > +       pm_runtime_disable(&client->dev);
> > +       if (!pm_runtime_status_suspended(&client->dev))
> > +               imx492_power_off(&client->dev);
> > +       pm_runtime_set_suspended(&client->dev);
> > +       mutex_destroy(&imx492->mutex);
> > +}
> > +
> > +static const struct dev_pm_ops imx492_pm_ops = {
> > +       SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> > +};
> > +
> > +static const struct of_device_id imx492_of_match[] = {
> > +       { .compatible = "sony,imx492_mipi" },
> 
> This doesn't match the bindings. I think the _mipi should just be removed.

Right you are.  Will be fixed.

> > +       { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, imx492_of_match);
> > +
> > +static struct i2c_driver imx492_driver = {
> > +       .probe_new = imx492_probe,
> > +       .remove = imx492_remove,
> > +       .driver = {
> > +               .name = "imx492",
> > +               .pm = &imx492_pm_ops,
> > +               .of_match_table = imx492_of_match,
> > +       },
> > +};
> > +
> > +module_i2c_driver(imx492_driver);
> > +
> > +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> > +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 2.30.2
> >


		Petko

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

* Re: [PATCH v1 2/5] media: i2c: imx492: driver's header
  2022-11-28 13:30       ` Laurent Pinchart
@ 2022-11-28 13:53         ` Petko Manolov
  0 siblings, 0 replies; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 13:53 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Kieran Bingham, linux-media, sakari.ailus

On 22-11-28 15:30:37, Laurent Pinchart wrote:
> On Mon, Nov 28, 2022 at 03:14:26PM +0200, Petko Manolov wrote:
> > On 22-11-28 12:47:25, Kieran Bingham wrote:
> > > Quoting Petko Manolov (2022-11-25 15:31:17)
> > > > The header.  For the moment only two modes are supported.
> > > > 
> > > > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > > > ---
> > > >  drivers/media/i2c/imx492.h | 555 +++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 555 insertions(+)
> > > >  create mode 100644 drivers/media/i2c/imx492.h
> > > > 
> > > > diff --git a/drivers/media/i2c/imx492.h b/drivers/media/i2c/imx492.h
> > > > new file mode 100644
> > > > index 000000000000..301fd66c77d5
> > > > --- /dev/null
> > > > +++ b/drivers/media/i2c/imx492.h
> > > > @@ -0,0 +1,555 @@
> > > > +#ifndef        __imx492_h__
> > > > +#define        __imx492_h__
> > > > +
> > > > +struct imx492_reg {
> > > > +       u16 address;
> > > > +       u8 val;
> > > > +};
> > > > +
> > > > +static const struct imx492_reg mode_17to9_regs[] = {
> > > 
> > > Why is this table in the header? Should it be available in multiple locations?
> > 
> > Nope, but there are multiple modes that will eventually be in use and scrolling
> > down a couple of seconds until one gets to the code started to get a bit boring.
> 
> Ideally we should get rid of those tables and use logic to compute register
> values :-) That's a dream only at this point though.

I don't see this happening anytime soon with this particular sensor. :)

> I agree with Kieran that everything could be in the same file, and I also
> agree with you that it's not nice to have a large list of registers at the
> beginning of the driver. I'm thus fine with either option.

I use one register/value pair in a row while the driver is in development,
because it is easy to modify some of them and put a comment at the back.  Once
done with it multiple entries per line will reduce the pain.

At that point most registers that are common for all modes could be put in a
separate array and modify only those that are relevant for a particular
mode/format.  Not quite there yet...

> > > I think it is likely better in the driver itself.
> > 
> > Will put register definitions in the .c file for the time being.
> 
> -- 
> Regards,
> 
> Laurent Pinchart


		Petko

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-28 13:38     ` Kieran Bingham
  2022-11-28 13:46       ` Laurent Pinchart
@ 2022-11-28 14:07       ` Petko Manolov
  2022-11-28 15:04         ` Kieran Bingham
  1 sibling, 1 reply; 28+ messages in thread
From: Petko Manolov @ 2022-11-28 14:07 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-media, laurent.pinchart, sakari.ailus

On 22-11-28 13:38:12, Kieran Bingham wrote:
> Quoting Petko Manolov (2022-11-28 13:11:39)
> > On 22-11-28 12:45:32, Kieran Bingham wrote:
> > > Hi Petko,
> > > 
> > > What device/ISP are you testing this sensor on?
> > 
> > I'll tell you, but only if you promise to not laugh too much.  Deal?
> > 
> > i.MX8M-Mini
> > 
> > I hope nobody will notice the above line...
> 
> I won't laugh at all. We've just merged the ISI pipeline handler for
> libcamera, which should let you use libcamera on this target (I think).

I think i saw your patch in the ML.

> I would hope sometime in the future you'd be able to use the ISI pipeline
> handler with a GPU based ISP with this sensor too.

Both of the above are present in i.MX8M-Plus, not the Mini.

> How are you managing the image 3a? the imx492 is a raw sensor isn't it ?

Not sure what you mean by "image 3a" and yes, it's a raw sensor.

> > > Quoting Petko Manolov (2022-11-25 15:31:15)
> > > > This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> > > > image sensor.
> > > > 
> > > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > > digital output makes it possible to output the signals with high definition for
> > > > moving pictures. It is programmable through I2C interface. The I2C client
> > > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > > through MIPI CSI-2.
> > > > 
> > > > Petko Manolov (5):
> > > >   DT bindings for imx492
> > > >   media: i2c: imx492: driver's header
> > > >   media: i2c: imx492: driver's source
> > > >   media: i2c: add imx492 config entry
> > > >   media: i2c: add imx492 entry for make
> > > 
> > > Could you squash patches 2, 3, 4, and 5 into a single patch please?
> > 
> > This is the exact opposite to what the networking folks would prefer, but it's
> > OK with me.
> 
> Haha ... yes - isn't it great working in mulitple subsystems....

Yeah, easy to get confused... :)

> > > Also - I think you'll need an entry in MAINTAINERS.
> > 
> > Right, that one too.
> > 
> > > I can't see any reference to the selection controls:
> > >  - V4L2_SEL_TGT_CROP_DEFAULT
> > >  - V4L2_SEL_TGT_CROP
> > >  - V4L2_SEL_TGT_CROP_BOUNDS
> > 
> > These are in a very early phase of implementing.
> 
> Ok
> 
> > > Do you have the datasheet or sufficient information to be able to implement
> > > these controls?
> > 
> > Of course not.  We are brute forcing our way forward by mostly reverse
> > engineering another solution that has an FPGA on the other end of the CSI link.
> 
> Understood ;-) (and ... I think what I was fearing/anticipating).

I would have been too easy otherwise.


		Petko

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-28 13:42     ` Petko Manolov
@ 2022-11-28 14:08       ` Laurent Pinchart
  2022-11-28 14:18       ` Dave Stevenson
  1 sibling, 0 replies; 28+ messages in thread
From: Laurent Pinchart @ 2022-11-28 14:08 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, sakari.ailus

Hi Petko,

On Mon, Nov 28, 2022 at 03:42:27PM +0200, Petko Manolov wrote:
> On 22-11-28 07:16:22, Laurent Pinchart wrote:
> > On Fri, Nov 25, 2022 at 05:31:18PM +0200, Petko Manolov wrote:
> > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > digital output makes it possible to output the signals with high definition for
> > > moving pictures. It is programmable through I2C interface. The I2C client
> > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > through MIPI CSI-2.
> > > 
> > > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > > ---
> > >  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 1092 insertions(+)
> > >  create mode 100644 drivers/media/i2c/imx492.c
> > > 
> > > diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> > > new file mode 100644
> > > index 000000000000..0713256b4b63
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/imx492.c
> > > @@ -0,0 +1,1092 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> > > + *
> > > + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> > > + */
> > > +
> > > +#include <asm/unaligned.h>
> > > +
> > > +#include <linux/clk.h>
> > > +#include <linux/delay.h>
> > > +#include <linux/i2c.h>
> > > +#include <linux/module.h>
> > > +#include <linux/pm_runtime.h>
> > > +#include <linux/regulator/consumer.h>
> > 
> > There are missing headers, at least for GPIO. Please check if anything else is
> > missing.
> 
> The driver compiles cleanly.  Not sure what i have to add here.

That's because of indirect inclusion. That could change at any time, so
it's good practice to explicitly include headers for all APIs used by
the driver.

> > > +#include <media/v4l2-ctrls.h>
> > > +#include <media/v4l2-fwnode.h>
> > > +#include <media/v4l2-subdev.h>
> > > +
> > > +#include "imx492.h"
> > > +
> > > +/* Streaming Mode */
> > > +#define IMX492_REG_MODE_SELECT	0x3000
> > > +
> > > +/* Chip ID */
> > > +#define IMX492_ID		0x13
> > > +
> > > +/* Analog gain control */
> > > +#define IMX492_REG_AGAIN	0x300a
> > > +#define IMX492_AGAIN_MIN	0
> > > +#define IMX492_AGAIN_MAX	978
> > > +#define IMX492_AGAIN_STEP	1
> > > +#define IMX492_AGAIN_DEFAULT	0
> > > +
> > > +/* Group hold register */
> > > +#define IMX492_REG_HOLD		0x302b
> > > +#define	IMX492_REG_XMSTA	0x3033
> > > +#define	IMX492_REG_SYSCLKEN	0x35e5
> > 
> > You can replace the first tab (just after #define) with a space.
> 
> OK.
> 
> > > +/* CSI2 HW configuration */
> > > +#define IMX492_LINK_FREQ	745000000
> > > +#define IMX492_NUM_DATA_LANES	4
> > > +
> > > +#define IMX492_REG_MIN		0x3000
> > > +#define IMX492_REG_MAX		0xffff
> > > +
> > > +/* *** */
> > > +
> > > +#define IMX492_REG_STANDBY	IMX492_REG_MODE_SELECT
> > 
> > No aliases for register names please, that's confusing.
> 
> This register is known with both of the above names in the documentation.  I
> strongly suspect that at least two different teams/persons at Sony had a go at
> that document.
> 
> Will select one of these names to avoid confusion.

My experience with Sony sensors is that they often name bits but not
registers. The registers then end up being named based on a particular
bit they contain when writing drivers.

> > > +#define IMX492_BIT_STANDBY	0x01
> > > +#define IMX492_BIT_STBLOGIC	0x02
> > > +#define IMX492_BIT_STBDV	0x10
> > > +
> > > +#define IMX492_MODE_STANDBY	(IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> > > +#define IMX492_MODE_STREAMING	0x00
> > > +
> > > +#define IMX492_REG_TESTPTRN	0x303A
> > > +#define IMX492_BIT_CLKEN	0x01
> > > +#define IMX492_BIT_TESTPTRN	0x10
> > > +#define IMX492_BITS_TPTRN_ON	(IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> > > +#define IMX492_BITS_TPTRN_OFF	0x00
> > > +
> > > +#define IMX492_REG_TESTPATSEL	0x303B
> > > +#define IMX492_BIT_TPAT00	0x00
> > > +#define IMX492_BIT_TPAT01	0x01
> > > +#define IMX492_BIT_TPAT02	0x02
> > > +#define IMX492_BIT_TPAT03	0x03
> > > +#define IMX492_BIT_TPAT0A	0x0A
> > > +#define IMX492_BIT_TPAT0B	0x0B
> > > +
> > > +#define IMX492_EXPOSURE_MIN		8
> > > +#define IMX492_EXPOSURE_OFFSET		22
> > > +#define IMX492_EXPOSURE_STEP		1
> > > +#define IMX492_EXPOSURE_DEFAULT		0x0648
> > > +
> > > +#define	DEFAULT_FPS		6
> > > +
> > > +/**
> > > + * struct imx492_reg_list - imx492 sensor register list
> > > + * @num_of_regs: Number of registers in the list
> > > + * @regs: Pointer to register list
> > > + */
> > > +struct imx492_reg_list {
> > > +	u32 num_of_regs;
> > > +	const struct imx492_reg *regs;
> > > +};
> > > +
> > > +/**
> > > + * struct imx492_mode - imx492 sensor mode structure
> > > + * @width: Frame width
> > > + * @height: Frame height
> > > + * @code: Format code
> > > + * @hblank: Horizontal blanking in lines
> > > + * @vblank: Vertical blanking in lines
> > > + * @vblank_min: Minimum vertical blanking in lines
> > > + * @vblank_max: Maximum vertical blanking in lines
> > > + * @pclk: Sensor pixel clock
> > > + * @link_freq_idx: Link frequency index
> > > + * @reg_list: Register list for sensor mode
> > > + */
> > > +struct imx492_mode {
> > > +	u32 width;
> > > +	u32 height;
> > > +	u32 code;
> > > +	u32 hblank;
> > > +	u32 hblank_min;
> > > +	u32 hblank_max;
> > > +	u32 vblank;
> > > +	u32 vblank_min;
> > > +	u32 vblank_max;
> > > +	u64 pclk;
> > > +	u32 link_freq_idx;
> > > +	struct imx492_reg_list reg_list;
> > > +};
> > > +
> > > +/**
> > > + * struct imx492 - imx492 sensor device structure
> > > + * @dev: Pointer to generic device
> > > + * @client: Pointer to i2c client
> > > + * @sd: V4L2 sub-device
> > > + * @pad: Media pad. Only one pad supported
> > > + * @reset_gpio: Sensor reset gpio
> > > + * @reset_gpio: Sensor power gpio
> > > + * @inclk: Sensor input clock
> > > + * @supplies: Regulator supplies
> > > + * @ctrl_handler: V4L2 control handler
> > > + * @link_freq_ctrl: Pointer to link frequency control
> > > + * @pclk_ctrl: Pointer to pixel clock control
> > > + * @hblank_ctrl: Pointer to horizontal blanking control
> > > + * @vblank_ctrl: Pointer to vertical blanking control
> > > + * @exp_ctrl: Pointer to exposure control
> > > + * @again_ctrl: Pointer to analog gain control
> > > + * @vblank: Vertical blanking in lines
> > > + * @cur_mode: Pointer to current selected sensor mode
> > > + * @mutex: Mutex for serializing sensor controls
> > 
> > Please use the same order for fields in the documentation and the
> > structure defininition.
> 
> Mkey.
> 
> > > + * @streaming: Flag indicating streaming state
> > > + */
> > > +struct imx492 {
> > > +	struct device *dev;
> > > +	struct i2c_client *client;
> > > +	struct v4l2_subdev sd;
> > > +	struct media_pad pad;
> > > +	struct v4l2_captureparm scap;
> > 
> > This is set but never used. You can drop it.
> 
> OK.
> 
> > > +	struct gpio_desc *reset_gpio;
> > > +	struct gpio_desc *power_gpio;
> > > +	struct gpio_desc *oscen_gpio;
> > > +	struct clk *inclk;
> > > +	struct v4l2_ctrl_handler ctrl_handler;
> > > +	struct v4l2_ctrl *link_freq_ctrl;
> > > +	struct v4l2_ctrl *pclk_ctrl;
> > > +	struct v4l2_ctrl *hblank_ctrl;
> > > +	struct v4l2_ctrl *vblank_ctrl;
> > > +	struct v4l2_ctrl *exp_ctrl;
> > > +	struct v4l2_ctrl *again_ctrl;
> > > +	const struct imx492_mode *cur_mode;
> > > +	struct mutex mutex;
> > > +	u32 tpatt;
> > 
> > Not used, drop it.
> 
> Ah, a left over.  Will remove it.
> 
> > > +	u32 vblank;
> > > +	bool streaming;
> > > +};
> > > +
> > > +static const s64 link_freq[] = {
> > > +	IMX492_LINK_FREQ,
> > > +};
> > > +
> > > +
> > > +/* Supported sensor mode configurations */
> > > +static const struct imx492_mode supported_modes[] = {
> > > +	{
> > > +		.width = 8192,
> > > +		.height = 4320,
> > > +		.hblank = 1108,
> > > +		.hblank_min = 1102,
> > > +		.hblank_max = 32768,
> > > +		.vblank = 5728,
> > > +		.vblank_min = 4428,
> > > +		.vblank_max = 32768,
> > > +		.pclk = 745000000,
> > > +		.link_freq_idx = 0,
> > > +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > > +		.reg_list = {
> > > +			.num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> > > +			.regs = mode_17to9_regs,
> > > +		},
> > > +	}, {
> > > +		.width = 8192,
> > > +		.height = 5556,
> > > +		.hblank = 1108,
> > > +		.hblank_min = 1102,
> > > +		.hblank_max = 32768,
> > > +		.vblank = 5728,
> > > +		.vblank_min = 4428,
> > > +		.vblank_max = 32768,
> > > +		.pclk = 745000000,
> > > +		.link_freq_idx = 0,
> > > +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > > +		.reg_list = {
> > > +			.num_of_regs = ARRAY_SIZE(mode_all_regs),
> > > +			.regs = mode_all_regs,
> > > +		},
> > > +	},
> > > +};
> > > +
> > > +static const char * const imx492_test_pattern_menu[] = {
> > > +	"Disabled",
> > > +	"Solid black",
> > > +	"Solid white",
> > > +	"Solid dark grey",
> > > +	"Solid light gray",
> > > +	"None",
> > > +	"None",
> > > +	"None",
> > > +	"None",
> > > +	"None",
> > > +	"None",
> > 
> > Menu controls shouldn't have entries with identical names. All these should be
> > dropped if they're not implemented by the sensor, or given a proper name.
> 
> Err, this was easier to do.  Will refactor...
> 
> > > +	"Vertical color bars",
> > > +	"Horizontal color bars",
> > > +};
> > > +
> > > +/**
> > > + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> > > + * @subdev: pointer to imx492 V4L2 sub-device
> > > + *
> > > + * Return: pointer to imx492 device
> > > + */
> > > +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> > > +{
> > > +	return container_of(subdev, struct imx492, sd);
> > > +}
> > > +
> > > +/**
> > > + * imx492_read_reg() - Read registers.
> > > + * @imx492: pointer to imx492 device
> > > + * @reg: register address
> > > + * @len: length of bytes to read. Max supported bytes is 4
> > > + * @val: pointer to register value to be filled.
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> > > +{
> > > +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > > +	struct i2c_msg msgs[2] = {0};
> > > +	u8 addr_buf[2] = {0};
> > > +	u8 data_buf[4] = {0};
> > > +	int ret;
> > > +
> > > +	if (WARN_ON(len > 4))
> > > +		return -EINVAL;
> > > +
> > > +	put_unaligned_be16(reg, addr_buf);
> > > +
> > > +	/* Write register address */
> > > +	msgs[0].addr = client->addr;
> > > +	msgs[0].flags = 0;
> > > +	msgs[0].len = ARRAY_SIZE(addr_buf);
> > > +	msgs[0].buf = addr_buf;
> > > +
> > > +	/* Read data from register */
> > > +	msgs[1].addr = client->addr;
> > > +	msgs[1].flags = I2C_M_RD;
> > > +	msgs[1].len = len;
> > > +	msgs[1].buf = &data_buf[4 - len];
> > > +
> > > +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> > > +	if (ret != ARRAY_SIZE(msgs))
> > > +		return -EIO;
> > > +
> > > +	*val = get_unaligned_be32(data_buf);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_write_reg() - Write register
> > > + * @imx492: pointer to imx492 device
> > > + * @reg: register address
> > > + * @len: length of bytes. Max supported bytes is 4
> > > + * @val: register value
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> > > +{
> > > +	struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > > +	u8 buf[6] = {0};
> > > +
> > > +	if (WARN_ON(len > 4))
> > > +		return -EINVAL;
> > > +
> > > +	put_unaligned_be16(reg, buf);
> > > +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> > > +	if (i2c_master_send(client, buf, len + 2) != len + 2)
> > > +		return -EIO;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_write_regs() - Write a list of registers
> > > + * @imx492: pointer to imx492 device
> > > + * @regs: list of registers to be written
> > > + * @len: length of registers array
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_write_regs(struct imx492 *imx492,
> > > +			     const struct imx492_reg *regs, u32 len)
> > > +{
> > > +	unsigned int i;
> > > +	int ret;
> > > +
> > > +	for (i = 0; i < len; i++) {
> > > +		ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> > > +		if (ret)
> > > +			return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> > > +{
> > > +	/* for now this is the only format we support */
> > > +	return MEDIA_BUS_FMT_SGBRG12_1X12;
> > > +}
> > > +
> > > +/**
> > > + * imx492_update_controls() - Update control ranges based on streaming mode
> > > + * @imx492: pointer to imx492 device
> > > + * @mode: pointer to imx492_mode sensor mode
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_update_controls(struct imx492 *imx492,
> > > +				  const struct imx492_mode *mode)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> > > +					mode->vblank_max, 1, mode->vblank);
> > > +}
> > > +
> > > +/**
> > > + * imx492_update_exp_gain() - Set updated exposure and gain
> > > + * @imx492: pointer to imx492 device
> > > + * @exposure: updated exposure value
> > > + * @gain: updated analog gain value
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> > > +{
> > > +	u32 lpfr, shutter;
> > > +	int ret;
> > > +
> > > +	lpfr = imx492->vblank + imx492->cur_mode->height;
> > > +	shutter = lpfr - exposure;
> > > +
> > > +	ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_ctrl() - Set subdevice control
> > > + * @ctrl: pointer to v4l2_ctrl structure
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> > > +{
> > > +	struct imx492 *imx492 =
> > > +		container_of(ctrl->handler, struct imx492, ctrl_handler);
> > > +	u32 analog_gain;
> > > +	u32 exposure;
> > > +	int ret;
> > > +
> > > +	switch (ctrl->id) {
> > > +	case V4L2_CID_VBLANK:
> > > +		imx492->vblank = imx492->vblank_ctrl->val;
> > > +
> > > +		ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> > > +					       IMX492_EXPOSURE_MIN,
> > > +					       imx492->vblank +
> > > +					       imx492->cur_mode->height -
> > > +					       IMX492_EXPOSURE_OFFSET,
> > > +					       1, IMX492_EXPOSURE_DEFAULT);
> > 
> > It looks like you forgot to write the corresponding registers.
> 
> Yeah, will look into this one as well.
> 
> > > +		break;
> > > +	case V4L2_CID_EXPOSURE:
> > > +		/* Set controls only if sensor is in power on state */
> > > +		if (!pm_runtime_get_if_in_use(imx492->dev))
> > > +			return 0;
> > > +		exposure = ctrl->val;
> > > +		analog_gain = imx492->again_ctrl->val;
> > > +		ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> > > +		pm_runtime_put(imx492->dev);
> > > +		break;
> > > +	case V4L2_CID_TEST_PATTERN:
> > > +		if (ctrl->val) {
> > > +			imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> > > +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> > > +		} else {
> > > +			imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> > > +		}
> > 
> > Don't you need the same pm_runtime_get_if_in_use() dance as for
> > V4L2_CID_EXPOSURE ?
> 
> Yup.
> 
> > > +		ret = 0;
> > > +		break;
> > 
> > Missing V4L2_CID_ANALOGUE_GAIN.
> 
> Not implemented at the moment.

Then you should remove the control from imx492_init_controls(), but it
would be great if you could instead implement it, given that
imx492_update_exp_gain() seems to handle the analogue gain. Actually,
what imx492_update_exp_gain() doesn't seem to handle is the exposure
time.

> > > +	default:
> > > +		dev_err(imx492->dev, "Invalid control %d", ctrl->id);
> > 
> > This shouldn't happen if you correctly handle all the controls you have
> > instanciated in imx492_init_controls().
> 
> Well, need to verify if that's the case here.
> 
> > > +		ret = -EINVAL;
> > > +	}
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/* V4l2 subdevice control ops*/
> > > +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> > > +	.s_ctrl = imx492_set_ctrl,
> > > +};
> > > +
> > > +/**
> > > + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @code: V4L2 sub-device code enumeration need to be filled
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_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(supported_modes))
> > > +		return -EINVAL;
> > > +
> > > +	code->code = supported_modes[code->index].code;
> > 
> > All modes have the same media bus code, you shouldn't report duplicated
> > values.
> 
> This sensor support 10bit format so this is prep work when these get properly
> implemented.

That's fine, but you should then add an array of supported media bus
codes, separate from the modes. .enum_mbus_code() is meant to enumerate
the formats, and for each supported format, .enum_frame_size() then
enumerates the sizes.

> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fsize: V4L2 sub-device size enumeration need to be filled
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> > > +				  struct v4l2_subdev_state *sd_state,
> > > +				  struct v4l2_subdev_frame_size_enum *fsize)
> > > +{
> > > +	if (fsize->index > ARRAY_SIZE(supported_modes))
> > > +		return -EINVAL;
> > > +
> > > +	if (fsize->code != supported_modes[fsize->index].code)
> > > +		return -EINVAL;
> > > +
> > > +	fsize->max_width = supported_modes[fsize->index].width;
> > > +	fsize->min_width = fsize->max_width;
> > > +	fsize->max_height = supported_modes[fsize->index].height;
> > > +	fsize->min_height = fsize->max_height;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > +n * imx492_fill_pad_format() - Fill subdevice pad format
> > > + *                            from selected sensor mode
> > > + * @imx492: pointer to imx492 device
> > > + * @mode: pointer to imx492_mode sensor mode
> > > + * @fmt: V4L2 sub-device format need to be filled
> > > + */
> > > +static void imx492_fill_pad_format(struct imx492 *imx492,
> > > +				   const struct imx492_mode *mode,
> > > +				   struct v4l2_subdev_format *fmt)
> > > +{
> > > +	fmt->format.width = mode->width;
> > > +	fmt->format.height = mode->height;
> > > +	fmt->format.code = mode->code;
> > > +	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;
> > 
> > You can use V4L2_QUANTIZATION_FULL_RANGE.
> 
> OK.
> 
> > > +	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
> > > +}
> > > +
> > > +/**
> > > + * imx492_get_pad_format() - Get subdevice pad format
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fmt: V4L2 sub-device format need to be set
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> > > +				 struct v4l2_subdev_state *sd_state,
> > > +				 struct v4l2_subdev_format *fmt)
> > > +{
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +	mutex_lock(&imx492->mutex);
> > > +
> > > +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > +		struct v4l2_mbus_framefmt *framefmt;
> > > +
> > > +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > > +		fmt->format = *framefmt;
> > > +	} else {
> > > +		imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> > > +	}
> > > +
> > > +	mutex_unlock(&imx492->mutex);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_pad_format() - Set subdevice pad format
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fmt: V4L2 sub-device format need to be set
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> > > +				 struct v4l2_subdev_state *sd_state,
> > > +				 struct v4l2_subdev_format *fmt)
> > > +{
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +	const struct imx492_mode *mode;
> > > +	int ret = 0;
> > > +
> > > +	mutex_lock(&imx492->mutex);
> > > +
> > > +	fmt->format.code = imx492_get_format_code(imx492, 0);
> > > +	mode = v4l2_find_nearest_size(supported_modes,
> > > +					ARRAY_SIZE(supported_modes),
> > > +					width, height,
> > > +					fmt->format.width, fmt->format.height);
> > > +	imx492_fill_pad_format(imx492, mode, fmt);
> > > +
> > > +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > +		struct v4l2_mbus_framefmt *framefmt;
> > > +
> > > +		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > > +		*framefmt = fmt->format;
> > > +	} else {
> > > +		ret = imx492_update_controls(imx492, mode);
> > > +		if (!ret)
> > > +			imx492->cur_mode = mode;
> > > +	}
> > > +
> > > +	mutex_unlock(&imx492->mutex);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> > > +			       struct v4l2_subdev_state *sd_state)
> > > +{
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +	struct v4l2_subdev_format fmt = { 0 };
> > > +
> > > +	fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
> > 
> > When using the active state API you will never get a null state here, so you
> > can set this to
> > 
> > 	struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_TRY, };
> > 
> > unconditionally.
> 
> OK.
> 
> > > +	imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> > > +
> > > +	return imx492_set_pad_format(sd, sd_state, &fmt);
> > > +}
> > > +
> > > +/**
> > > + * imx492_start_streaming() - Start sensor stream
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_start_streaming(struct imx492 *imx492)
> > > +{
> > > +	const struct imx492_reg_list *reg_list;
> > > +	int ret;
> > > +
> > > +	/* Write sensor mode registers */
> > > +	reg_list = &imx492->cur_mode->reg_list;
> > > +	ret = imx492_write_regs(imx492, reg_list->regs,
> > > +				reg_list->num_of_regs);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "fail to write initial registers");
> > > +		return ret;
> > > +	}
> > > +
> > > +	/* Setup handler will write actual exposure and gain */
> > > +	ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "fail to setup handler");
> > > +		return ret;
> > > +	}
> > > +
> > > +	/* 1st stabilization period */
> > > +	usleep_range(10000, 11000);
> > > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> > > +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> > > +	imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> > > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> > > +
> > > +	/* 2nd stabilization period */
> > > +	usleep_range(7000, 8000);
> > > +
> > > +	/* Start streaming */
> > > +	ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> > > +
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "fail to start streaming");
> > > +		return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_stop_streaming() - Stop sensor stream
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static void imx492_stop_streaming(struct imx492 *imx492)
> > > +{
> > > +	imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> > > +	imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_stream() - Enable sensor streaming
> > > + * @sd: pointer to imx492 subdevice
> > > + * @enable: set to enable sensor streaming
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> > > +{
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +	int ret;
> > > +
> > > +	mutex_lock(&imx492->mutex);
> > > +
> > > +	if (imx492->streaming == enable) {
> > 
> > This should never happen. You can drop imx492->streaming.
> 
> Well, OK.
> 
> > > +		mutex_unlock(&imx492->mutex);
> > > +		return 0;
> > > +	}
> > > +
> > > +	if (enable) {
> > > +		ret = pm_runtime_resume_and_get(imx492->dev);
> > > +		if (ret)
> > > +			goto error_unlock;
> > > +		ret = imx492_start_streaming(imx492);
> > > +		if (ret)
> > > +			goto error_power_off;
> > > +	} else {
> > > +		imx492_stop_streaming(imx492);
> > > +		pm_runtime_put(imx492->dev);
> > > +	}
> > > +
> > > +	imx492->streaming = enable;
> > > +
> > > +	mutex_unlock(&imx492->mutex);
> > > +
> > > +	return 0;
> > > +
> > > +error_power_off:
> > > +	pm_runtime_put(imx492->dev);
> > > +error_unlock:
> > > +	mutex_unlock(&imx492->mutex);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_detect() - Detect imx492 sensor
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, -EIO if sensor id does not match
> > > + */
> > > +static int imx492_detect(struct imx492 *imx492)
> > > +{
> > > +	int ret;
> > > +	u32 val;
> > > +
> > > +	ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);
> > 
> > Is the chip ID really stored in that register ?
> 
> No.  There simply isn't an ID register.  In order to see if the sensor is
> properly powered up and reset i had to chose a register with a known, non-zero
> value.

You may want to read the whole register space to check if there's an ID
register somewhere that may contain 0x0492 (or maybe in decimar). There
usually is one.

> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	if (val != IMX492_ID) {
> > > +		dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> > > +		return -ENXIO;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_parse_hw_config(struct imx492 *imx492)
> > > +{
> > > +	struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> > > +	struct v4l2_fwnode_endpoint bus_cfg = {
> > > +		.bus_type = V4L2_MBUS_CSI2_DPHY
> > > +	};
> > > +	struct fwnode_handle *ep;
> > > +	unsigned int i;
> > > +	int ret;
> > > +
> > > +	if (!fwnode)
> > > +		return -ENXIO;
> > > +
> > > +	imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
> > 
> > Not listed in the DT binding.
> >
> > > +	if (IS_ERR(imx492->power_gpio)) {
> > > +		dev_err(imx492->dev, "failed to get power gpio %ld",
> > > +			PTR_ERR(imx492->power_gpio));
> > > +		return PTR_ERR(imx492->power_gpio);
> > > +	}
> > > +
> > > +	imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
> > 
> > Not listed in the DT binding.
> 
> Both of the above are specific to this particular sensor board.  Other
> implementations may well not have any of these.

What are those two GPIOs connected to ?

> > You should also handle regulators in the driver.
> 
> Err...
> 
> > > +	if (IS_ERR(imx492->oscen_gpio)) {
> > > +		dev_err(imx492->dev, "failed to get oscen gpio %ld",
> > > +			PTR_ERR(imx492->oscen_gpio));
> > > +		return PTR_ERR(imx492->oscen_gpio);
> > > +	}
> > > +
> > > +	imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> > > +	if (IS_ERR(imx492->reset_gpio)) {
> > > +		dev_err(imx492->dev, "failed to get reset gpio %ld",
> > > +			PTR_ERR(imx492->reset_gpio));
> > > +		return PTR_ERR(imx492->reset_gpio);
> > > +	}
> > > +
> > > +	if (gpiod_direction_output(imx492->power_gpio, 1) ||
> > > +	    gpiod_direction_output(imx492->oscen_gpio, 1) ||
> > > +	    gpiod_direction_output(imx492->reset_gpio, 0)) {
> > 
> > This is done by devm_gpiod_get().
> 
> OK.
> 
> > > +		dev_err(imx492->dev, "failed to change gpio direction");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	/* Get sensor input clock */
> > > +	imx492->inclk = devm_clk_get(imx492->dev, NULL);
> > > +	if (IS_ERR(imx492->inclk)) {
> > > +		dev_err(imx492->dev, "could not get inclk");
> > > +		return PTR_ERR(imx492->inclk);
> > > +	}
> > > +
> > > +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> > > +	if (!ep) {
> > > +		dev_err(imx492->dev, "next endpoint?");
> > > +		return -ENXIO;
> > > +	}
> > > +
> > > +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> > > +	fwnode_handle_put(ep);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "endpoint alloc parse");
> > > +		return ret;
> > > +	}
> > > +
> > > +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> > > +		dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> > > +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> > > +		ret = -EINVAL;
> > > +		goto done_endpoint_free;
> > > +	}
> > > +
> > > +	if (!bus_cfg.nr_of_link_frequencies) {
> > > +		dev_err(imx492->dev, "no link frequencies defined");
> > > +		ret = -EINVAL;
> > > +		goto done_endpoint_free;
> > > +	}
> > > +
> > > +	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> > > +		if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> > > +			goto done_endpoint_free;
> > > +	}
> > > +
> > > +	ret = -EINVAL;
> > > +
> > > +done_endpoint_free:
> > > +	v4l2_fwnode_endpoint_free(&bus_cfg);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/* V4l2 subdevice ops */
> > > +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> > > +	.s_stream = imx492_set_stream,
> > > +};
> > > +
> > > +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> > > +	.init_cfg = imx492_init_pad_cfg,
> > > +	.enum_mbus_code = imx492_enum_mbus_code,
> > > +	.enum_frame_size = imx492_enum_frame_size,
> > > +	.get_fmt = imx492_get_pad_format,
> > 
> > Please use the subdev active state API. You need to call
> > v4l2_subdev_init_finalize() at probe time, and you can set this to
> > 
> > 	.get_fmt = v4l2_subdev_get_fmt,
> 
> OK.
> 
> > Then, in imx492_set_pad_format() (and elsewhere as needed), you can use
> > v4l2_subdev_get_pad_format() to replace v4l2_subdev_get_try_format(). This
> > helps making code paths identical for the TRY and ACTIVE cases, the only
> > exception being the update of controls in .set_fmt() in the ACTIVE case.
> > 
> > > +	.set_fmt = imx492_set_pad_format,
> > 
> > Please also implement the .get_selection operation to report the
> > V4L2_SEL_TGT_CROP, V4L2_SEL_TGT_CROP_BOUNDS, V4L2_SEL_TGT_CROP_DEFAULT and
> > V4L2_SEL_TGT_NATIVE_SIZE values.
> 
> Cropping is a big pain in the ass with this sensor and is currently not stable.
> Could you please point me to an existing driver that's a good example?

The imx219 driver is an example of a driver that exposes read-only
selection rectangles. It's not perfect, as it doesn't use the active
state API, but you should get the idea.

> > > +};
> > > +
> > > +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> > > +	.video = &imx492_video_ops,
> > > +	.pad = &imx492_pad_ops,
> > > +};
> > > +
> > > +/**
> > > + * imx492_power_on() - Sensor power on sequence
> > > + * @dev: pointer to i2c device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_power_on(struct device *dev)
> > > +{
> > > +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +	gpiod_set_value_cansleep(imx492->power_gpio, 1);
> > > +	msleep(1);
> > > +	gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> > > +	msleep(1);
> > > +	gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> > > +	msleep(1);
> > 
> > How about regulators and clock ?
> 
> In this particular case i don't have to alter any of them.  Do i need to prepare
> some code for the general case?

As they're defined in the DT bindings they should be supported, yes.
Given the oscen and power GPIOs used in this driver, I have a feeling
you should add a GPIO-controlled fixed regulator in DT to replace the
power GPIO, and a GPIO-controlled fixed-frequency clock to replace the
oscen GPIO.

> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_power_off() - Sensor power off sequence
> > > + * @dev: pointer to i2c device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_power_off(struct device *dev)
> > > +{
> > > +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +	gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> > > +	gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> > > +	gpiod_set_value_cansleep(imx492->power_gpio, 0);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_init_controls() - Initialize sensor subdevice controls
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_init_controls(struct imx492 *imx492)
> > > +{
> > > +	struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> > > +	const struct imx492_mode *mode = imx492->cur_mode;
> > > +	u32 lpfr;
> > > +	int ret;
> > > +
> > > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	/* Serialize controls with sensor device */
> > > +	ctrl_hdlr->lock = &imx492->mutex;
> > > +	/* Initialize exposure and gain */
> > > +	lpfr = mode->vblank + mode->height;
> > > +	imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +					     &imx492_ctrl_ops,
> > > +					     V4L2_CID_EXPOSURE,
> > > +					     IMX492_EXPOSURE_MIN,
> > > +					     lpfr - IMX492_EXPOSURE_OFFSET,
> > > +					     IMX492_EXPOSURE_STEP,
> > > +					     IMX492_EXPOSURE_DEFAULT);
> > > +
> > > +	imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +					       &imx492_ctrl_ops,
> > > +					       V4L2_CID_ANALOGUE_GAIN,
> > > +					       IMX492_AGAIN_MIN,
> > > +					       IMX492_AGAIN_MAX,
> > > +					       IMX492_AGAIN_STEP,
> > > +					       IMX492_AGAIN_DEFAULT);
> > > +
> > > +	v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> > > +
> > > +	imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +						&imx492_ctrl_ops,
> > > +						V4L2_CID_VBLANK,
> > > +						mode->vblank_min,
> > > +						mode->vblank_max,
> > > +						1, mode->vblank);
> > > +	/* Read only controls */
> > > +	imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +						&imx492_ctrl_ops,
> > > +						V4L2_CID_HBLANK,
> > > +						mode->hblank_min,
> > > +						mode->hblank_max,
> > > +						1, mode->hblank);
> > > +	if (imx492->hblank_ctrl)
> > > +		imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > > +
> > > +	imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +					      &imx492_ctrl_ops,
> > > +					      V4L2_CID_PIXEL_RATE,
> > > +					      mode->pclk, mode->pclk,
> > > +					      1, mode->pclk);
> > 
> > Shouldn't this be read-only ?
> 
> Yup.
> 
> > > +
> > > +	imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > > +							&imx492_ctrl_ops,
> > > +							V4L2_CID_LINK_FREQ,
> > > +							ARRAY_SIZE(link_freq) -
> > > +							1,
> > > +							mode->link_freq_idx,
> > > +							link_freq);
> > > +	if (imx492->link_freq_ctrl)
> > > +		imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > > +
> > > +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> > > +				     V4L2_CID_TEST_PATTERN,
> > > +				     ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> > > +				     0, 0, imx492_test_pattern_menu);
> > > +
> > > +	if (ctrl_hdlr->error) {
> > > +		dev_err(imx492->dev, "control init failed: %d",	ctrl_hdlr->error);
> > > +		v4l2_ctrl_handler_free(ctrl_hdlr);
> > > +		return ctrl_hdlr->error;
> > > +	}
> > > +
> > > +	imx492->sd.ctrl_handler = ctrl_hdlr;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_probe() - I2C client device binding
> > > + * @client: pointer to i2c client device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_probe(struct i2c_client *client)
> > > +{
> > > +	struct imx492 *imx492;
> > > +	int ret;
> > > +
> > > +	imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> > > +	if (!imx492)
> > > +		return -ENOMEM;
> > > +
> > > +	imx492->dev = &client->dev;
> > > +
> > > +	/* Initialize subdev */
> > > +	v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> > > +
> > > +	ret = imx492_parse_hw_config(imx492);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "HW configuration is not supported");
> > > +		return ret;
> > > +	}
> > > +
> > > +	mutex_init(&imx492->mutex);
> > > +
> > > +	ret = imx492_power_on(imx492->dev);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "failed to power-on the sensor");
> > > +		goto error_mutex_destroy;
> > > +	}
> > > +
> > > +	/* Check module identity */
> > > +	ret = imx492_detect(imx492);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "failed to find sensor: %d", ret);
> > > +		goto error_power_off;
> > > +	}
> > > +
> > > +	/* Set default mode to max resolution */
> > > +	imx492->cur_mode = &supported_modes[0];
> > > +	imx492->vblank = imx492->cur_mode->vblank;
> > > +
> > > +	ret = imx492_init_controls(imx492);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "failed to init controls: %d", ret);
> > > +		goto error_power_off;
> > > +	}
> > > +
> > > +	/* Initialize subdev */
> > > +	imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > > +	imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > > +
> > > +	imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> > > +	imx492->scap.capturemode = 0;
> > > +	imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> > > +	imx492->scap.timeperframe.numerator = 1;
> > > +
> > > +	/* Initialize source pad */
> > > +	imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> > > +	ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> > > +	if (ret) {
> > > +		dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> > > +		goto error_handler_free;
> > > +	}
> > > +
> > > +	ret = v4l2_async_register_subdev(&imx492->sd);
> > > +	if (ret < 0) {
> > > +		dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> > > +		goto error_media_entity;
> > > +	}
> > 
> > This should be done at the very end of probe(), as the sensor can be used
> > right after it gets registered, so it should be fully operational.
> > 
> > > +
> > > +	pm_runtime_set_active(imx492->dev);
> > > +	pm_runtime_enable(imx492->dev);
> > > +	pm_runtime_idle(imx492->dev);
> > 
> > While at it, I would also implement autosuspend. You should then add a call to
> > pm_runtime_get_noresume() before pm_runtime_enable(), drop the
> > pm_runtime_idle() call, and add
> 
> From what i can see most, even 2022, drivers come with the above sequence.
> Which one does it right?

I apologize for the runtime PM mess in camera sensor drivers :-( The
best option is

	pm_runtime_set_active(imx492->dev);
	pm_runtime_get_noresume(imx492->dev);
	pm_runtime_enable(imx492->dev);

 	pm_runtime_set_autosuspend_delay(imx492->dev, 1000);
 	pm_runtime_use_autosuspend(imx492->dev);
 	pm_runtime_put_autosuspend(imx492->dev);

> > 	pm_runtime_set_autosuspend_delay(imx492->dev, 1000);
> > 	pm_runtime_use_autosuspend(imx492->dev);
> > 	pm_runtime_put_autosuspend(imx492->dev);
> > 
> > You will also need to replace pm_runtime_put() with
> > pm_runtime_mark_last_busy() + pm_runtime_put_autosuspend() above.
> > 
> > > +
> > > +	return 0;
> > > +
> > > +error_media_entity:
> > > +	media_entity_cleanup(&imx492->sd.entity);
> > > +error_handler_free:
> > > +	v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> > > +error_power_off:
> > > +	imx492_power_off(imx492->dev);
> > > +error_mutex_destroy:
> > > +	mutex_destroy(&imx492->mutex);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_remove() - I2C client device unbinding
> > > + * @client: pointer to I2C client device
> > > + */
> > > +static void imx492_remove(struct i2c_client *client)
> > > +{
> > > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > +	struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +	v4l2_async_unregister_subdev(sd);
> > > +	media_entity_cleanup(&sd->entity);
> > > +	v4l2_ctrl_handler_free(sd->ctrl_handler);
> > > +	pm_runtime_disable(&client->dev);
> > > +	if (!pm_runtime_status_suspended(&client->dev))
> > > +		imx492_power_off(&client->dev);
> > > +	pm_runtime_set_suspended(&client->dev);
> > > +	mutex_destroy(&imx492->mutex);
> > > +}
> > > +
> > > +static const struct dev_pm_ops imx492_pm_ops = {
> > > +	SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> > > +};
> > > +
> > > +static const struct of_device_id imx492_of_match[] = {
> > > +	{ .compatible = "sony,imx492_mipi" },
> > > +	{ }
> > > +};
> > > +
> > > +MODULE_DEVICE_TABLE(of, imx492_of_match);
> > > +
> > > +static struct i2c_driver imx492_driver = {
> > > +	.probe_new = imx492_probe,
> > > +	.remove = imx492_remove,
> > > +	.driver = {
> > > +		.name = "imx492",
> > > +		.pm = &imx492_pm_ops,
> > > +		.of_match_table = imx492_of_match,
> > > +	},
> > > +};
> > > +
> > > +module_i2c_driver(imx492_driver);
> > > +
> > > +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> > > +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> > > +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v1 3/5] media: i2c: imx492: driver's source
  2022-11-28 13:42     ` Petko Manolov
  2022-11-28 14:08       ` Laurent Pinchart
@ 2022-11-28 14:18       ` Dave Stevenson
  1 sibling, 0 replies; 28+ messages in thread
From: Dave Stevenson @ 2022-11-28 14:18 UTC (permalink / raw)
  To: Petko Manolov; +Cc: Laurent Pinchart, linux-media, sakari.ailus

On Mon, 28 Nov 2022 at 13:43, Petko Manolov <petko.manolov@konsulko.com> wrote:
>
> On 22-11-28 07:16:22, Laurent Pinchart wrote:
> > Hi Petko,
> >
> > Thank you for the patch.
> >
> > On Fri, Nov 25, 2022 at 05:31:18PM +0200, Petko Manolov wrote:
> > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > digital output makes it possible to output the signals with high definition for
> > > moving pictures. It is programmable through I2C interface. The I2C client
> > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > through MIPI CSI-2.
> > >
> > > Signed-off-by: Petko Manolov <petko.manolov@konsulko.com>
> > > ---
> > >  drivers/media/i2c/imx492.c | 1092 ++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 1092 insertions(+)
> > >  create mode 100644 drivers/media/i2c/imx492.c
> > >
> > > diff --git a/drivers/media/i2c/imx492.c b/drivers/media/i2c/imx492.c
> > > new file mode 100644
> > > index 000000000000..0713256b4b63
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/imx492.c
> > > @@ -0,0 +1,1092 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Sony imx492 Camera Sensor Driver (based on imx412.c source);
> > > + *
> > > + * Copyright (C) 2022 Petko Manolov <petko.manolov@konsulko.com>
> > > + */
> > > +
> > > +#include <asm/unaligned.h>
> > > +
> > > +#include <linux/clk.h>
> > > +#include <linux/delay.h>
> > > +#include <linux/i2c.h>
> > > +#include <linux/module.h>
> > > +#include <linux/pm_runtime.h>
> > > +#include <linux/regulator/consumer.h>
> >
> > There are missing headers, at least for GPIO. Please check if anything else is
> > missing.
>
> The driver compiles cleanly.  Not sure what i have to add here.
>
> > > +#include <media/v4l2-ctrls.h>
> > > +#include <media/v4l2-fwnode.h>
> > > +#include <media/v4l2-subdev.h>
> > > +
> > > +#include "imx492.h"
> > > +
> > > +/* Streaming Mode */
> > > +#define IMX492_REG_MODE_SELECT     0x3000
> > > +
> > > +/* Chip ID */
> > > +#define IMX492_ID          0x13
> > > +
> > > +/* Analog gain control */
> > > +#define IMX492_REG_AGAIN   0x300a
> > > +#define IMX492_AGAIN_MIN   0
> > > +#define IMX492_AGAIN_MAX   978
> > > +#define IMX492_AGAIN_STEP  1
> > > +#define IMX492_AGAIN_DEFAULT       0
> > > +
> > > +/* Group hold register */
> > > +#define IMX492_REG_HOLD            0x302b
> > > +#define    IMX492_REG_XMSTA        0x3033
> > > +#define    IMX492_REG_SYSCLKEN     0x35e5
> >
> > You can replace the first tab (just after #define) with a space.
>
> OK.
>
> > > +/* CSI2 HW configuration */
> > > +#define IMX492_LINK_FREQ   745000000
> > > +#define IMX492_NUM_DATA_LANES      4
> > > +
> > > +#define IMX492_REG_MIN             0x3000
> > > +#define IMX492_REG_MAX             0xffff
> > > +
> > > +/* *** */
> > > +
> > > +#define IMX492_REG_STANDBY IMX492_REG_MODE_SELECT
> >
> > No aliases for register names please, that's confusing.
>
> This register is known with both of the above names in the documentation.  I
> strongly suspect that at least two different teams/persons at Sony had a go at
> that document.
>
> Will select one of these names to avoid confusion.
>
> > > +#define IMX492_BIT_STANDBY 0x01
> > > +#define IMX492_BIT_STBLOGIC        0x02
> > > +#define IMX492_BIT_STBDV   0x10
> > > +
> > > +#define IMX492_MODE_STANDBY        (IMX492_BIT_STBDV | IMX492_BIT_STBLOGIC | IMX492_BIT_STANDBY)
> > > +#define IMX492_MODE_STREAMING      0x00
> > > +
> > > +#define IMX492_REG_TESTPTRN        0x303A
> > > +#define IMX492_BIT_CLKEN   0x01
> > > +#define IMX492_BIT_TESTPTRN        0x10
> > > +#define IMX492_BITS_TPTRN_ON       (IMX492_BIT_TESTPTRN | IMX492_BIT_CLKEN)
> > > +#define IMX492_BITS_TPTRN_OFF      0x00
> > > +
> > > +#define IMX492_REG_TESTPATSEL      0x303B
> > > +#define IMX492_BIT_TPAT00  0x00
> > > +#define IMX492_BIT_TPAT01  0x01
> > > +#define IMX492_BIT_TPAT02  0x02
> > > +#define IMX492_BIT_TPAT03  0x03
> > > +#define IMX492_BIT_TPAT0A  0x0A
> > > +#define IMX492_BIT_TPAT0B  0x0B
> > > +
> > > +#define IMX492_EXPOSURE_MIN                8
> > > +#define IMX492_EXPOSURE_OFFSET             22
> > > +#define IMX492_EXPOSURE_STEP               1
> > > +#define IMX492_EXPOSURE_DEFAULT            0x0648
> > > +
> > > +#define    DEFAULT_FPS             6
> > > +
> > > +/**
> > > + * struct imx492_reg_list - imx492 sensor register list
> > > + * @num_of_regs: Number of registers in the list
> > > + * @regs: Pointer to register list
> > > + */
> > > +struct imx492_reg_list {
> > > +   u32 num_of_regs;
> > > +   const struct imx492_reg *regs;
> > > +};
> > > +
> > > +/**
> > > + * struct imx492_mode - imx492 sensor mode structure
> > > + * @width: Frame width
> > > + * @height: Frame height
> > > + * @code: Format code
> > > + * @hblank: Horizontal blanking in lines
> > > + * @vblank: Vertical blanking in lines
> > > + * @vblank_min: Minimum vertical blanking in lines
> > > + * @vblank_max: Maximum vertical blanking in lines
> > > + * @pclk: Sensor pixel clock
> > > + * @link_freq_idx: Link frequency index
> > > + * @reg_list: Register list for sensor mode
> > > + */
> > > +struct imx492_mode {
> > > +   u32 width;
> > > +   u32 height;
> > > +   u32 code;
> > > +   u32 hblank;
> > > +   u32 hblank_min;
> > > +   u32 hblank_max;
> > > +   u32 vblank;
> > > +   u32 vblank_min;
> > > +   u32 vblank_max;
> > > +   u64 pclk;
> > > +   u32 link_freq_idx;
> > > +   struct imx492_reg_list reg_list;
> > > +};
> > > +
> > > +/**
> > > + * struct imx492 - imx492 sensor device structure
> > > + * @dev: Pointer to generic device
> > > + * @client: Pointer to i2c client
> > > + * @sd: V4L2 sub-device
> > > + * @pad: Media pad. Only one pad supported
> > > + * @reset_gpio: Sensor reset gpio
> > > + * @reset_gpio: Sensor power gpio
> > > + * @inclk: Sensor input clock
> > > + * @supplies: Regulator supplies
> > > + * @ctrl_handler: V4L2 control handler
> > > + * @link_freq_ctrl: Pointer to link frequency control
> > > + * @pclk_ctrl: Pointer to pixel clock control
> > > + * @hblank_ctrl: Pointer to horizontal blanking control
> > > + * @vblank_ctrl: Pointer to vertical blanking control
> > > + * @exp_ctrl: Pointer to exposure control
> > > + * @again_ctrl: Pointer to analog gain control
> > > + * @vblank: Vertical blanking in lines
> > > + * @cur_mode: Pointer to current selected sensor mode
> > > + * @mutex: Mutex for serializing sensor controls
> >
> > Please use the same order for fields in the documentation and the
> > structure defininition.
>
> Mkey.
>
> > > + * @streaming: Flag indicating streaming state
> > > + */
> > > +struct imx492 {
> > > +   struct device *dev;
> > > +   struct i2c_client *client;
> > > +   struct v4l2_subdev sd;
> > > +   struct media_pad pad;
> > > +   struct v4l2_captureparm scap;
> >
> > This is set but never used. You can drop it.
>
> OK.
>
> > > +   struct gpio_desc *reset_gpio;
> > > +   struct gpio_desc *power_gpio;
> > > +   struct gpio_desc *oscen_gpio;
> > > +   struct clk *inclk;
> > > +   struct v4l2_ctrl_handler ctrl_handler;
> > > +   struct v4l2_ctrl *link_freq_ctrl;
> > > +   struct v4l2_ctrl *pclk_ctrl;
> > > +   struct v4l2_ctrl *hblank_ctrl;
> > > +   struct v4l2_ctrl *vblank_ctrl;
> > > +   struct v4l2_ctrl *exp_ctrl;
> > > +   struct v4l2_ctrl *again_ctrl;
> > > +   const struct imx492_mode *cur_mode;
> > > +   struct mutex mutex;
> > > +   u32 tpatt;
> >
> > Not used, drop it.
>
> Ah, a left over.  Will remove it.
>
> > > +   u32 vblank;
> > > +   bool streaming;
> > > +};
> > > +
> > > +static const s64 link_freq[] = {
> > > +   IMX492_LINK_FREQ,
> > > +};
> > > +
> > > +
> > > +/* Supported sensor mode configurations */
> > > +static const struct imx492_mode supported_modes[] = {
> > > +   {
> > > +           .width = 8192,
> > > +           .height = 4320,
> > > +           .hblank = 1108,
> > > +           .hblank_min = 1102,
> > > +           .hblank_max = 32768,
> > > +           .vblank = 5728,
> > > +           .vblank_min = 4428,
> > > +           .vblank_max = 32768,
> > > +           .pclk = 745000000,
> > > +           .link_freq_idx = 0,
> > > +           .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > > +           .reg_list = {
> > > +                   .num_of_regs = ARRAY_SIZE(mode_17to9_regs),
> > > +                   .regs = mode_17to9_regs,
> > > +           },
> > > +   }, {
> > > +           .width = 8192,
> > > +           .height = 5556,
> > > +           .hblank = 1108,
> > > +           .hblank_min = 1102,
> > > +           .hblank_max = 32768,
> > > +           .vblank = 5728,
> > > +           .vblank_min = 4428,
> > > +           .vblank_max = 32768,
> > > +           .pclk = 745000000,
> > > +           .link_freq_idx = 0,
> > > +           .code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > > +           .reg_list = {
> > > +                   .num_of_regs = ARRAY_SIZE(mode_all_regs),
> > > +                   .regs = mode_all_regs,
> > > +           },
> > > +   },
> > > +};
> > > +
> > > +static const char * const imx492_test_pattern_menu[] = {
> > > +   "Disabled",
> > > +   "Solid black",
> > > +   "Solid white",
> > > +   "Solid dark grey",
> > > +   "Solid light gray",
> > > +   "None",
> > > +   "None",
> > > +   "None",
> > > +   "None",
> > > +   "None",
> > > +   "None",
> >
> > Menu controls shouldn't have entries with identical names. All these should be
> > dropped if they're not implemented by the sensor, or given a proper name.
>
> Err, this was easier to do.  Will refactor...
>
> > > +   "Vertical color bars",
> > > +   "Horizontal color bars",
> > > +};
> > > +
> > > +/**
> > > + * to_imx492() - imx492 V4L2 sub-device to imx492 device.
> > > + * @subdev: pointer to imx492 V4L2 sub-device
> > > + *
> > > + * Return: pointer to imx492 device
> > > + */
> > > +static inline struct imx492 *to_imx492(struct v4l2_subdev *subdev)
> > > +{
> > > +   return container_of(subdev, struct imx492, sd);
> > > +}
> > > +
> > > +/**
> > > + * imx492_read_reg() - Read registers.
> > > + * @imx492: pointer to imx492 device
> > > + * @reg: register address
> > > + * @len: length of bytes to read. Max supported bytes is 4
> > > + * @val: pointer to register value to be filled.
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_read_reg(struct imx492 *imx492, u16 reg, u32 len, u32 *val)
> > > +{
> > > +   struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > > +   struct i2c_msg msgs[2] = {0};
> > > +   u8 addr_buf[2] = {0};
> > > +   u8 data_buf[4] = {0};
> > > +   int ret;
> > > +
> > > +   if (WARN_ON(len > 4))
> > > +           return -EINVAL;
> > > +
> > > +   put_unaligned_be16(reg, addr_buf);
> > > +
> > > +   /* Write register address */
> > > +   msgs[0].addr = client->addr;
> > > +   msgs[0].flags = 0;
> > > +   msgs[0].len = ARRAY_SIZE(addr_buf);
> > > +   msgs[0].buf = addr_buf;
> > > +
> > > +   /* Read data from register */
> > > +   msgs[1].addr = client->addr;
> > > +   msgs[1].flags = I2C_M_RD;
> > > +   msgs[1].len = len;
> > > +   msgs[1].buf = &data_buf[4 - len];
> > > +
> > > +   ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> > > +   if (ret != ARRAY_SIZE(msgs))
> > > +           return -EIO;
> > > +
> > > +   *val = get_unaligned_be32(data_buf);
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_write_reg() - Write register
> > > + * @imx492: pointer to imx492 device
> > > + * @reg: register address
> > > + * @len: length of bytes. Max supported bytes is 4
> > > + * @val: register value
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_write_reg(struct imx492 *imx492, u16 reg, u32 len, u32 val)
> > > +{
> > > +   struct i2c_client *client = v4l2_get_subdevdata(&imx492->sd);
> > > +   u8 buf[6] = {0};
> > > +
> > > +   if (WARN_ON(len > 4))
> > > +           return -EINVAL;
> > > +
> > > +   put_unaligned_be16(reg, buf);
> > > +   put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> > > +   if (i2c_master_send(client, buf, len + 2) != len + 2)
> > > +           return -EIO;
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_write_regs() - Write a list of registers
> > > + * @imx492: pointer to imx492 device
> > > + * @regs: list of registers to be written
> > > + * @len: length of registers array
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_write_regs(struct imx492 *imx492,
> > > +                        const struct imx492_reg *regs, u32 len)
> > > +{
> > > +   unsigned int i;
> > > +   int ret;
> > > +
> > > +   for (i = 0; i < len; i++) {
> > > +           ret = imx492_write_reg(imx492, regs[i].address, 1, regs[i].val);
> > > +           if (ret)
> > > +                   return ret;
> > > +   }
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +static u32 imx492_get_format_code(struct imx492 *imx492, u32 code)
> > > +{
> > > +   /* for now this is the only format we support */
> > > +   return MEDIA_BUS_FMT_SGBRG12_1X12;
> > > +}
> > > +
> > > +/**
> > > + * imx492_update_controls() - Update control ranges based on streaming mode
> > > + * @imx492: pointer to imx492 device
> > > + * @mode: pointer to imx492_mode sensor mode
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_update_controls(struct imx492 *imx492,
> > > +                             const struct imx492_mode *mode)
> > > +{
> > > +   int ret;
> > > +
> > > +   ret = __v4l2_ctrl_s_ctrl(imx492->link_freq_ctrl, mode->link_freq_idx);
> > > +   if (ret)
> > > +           return ret;
> > > +
> > > +   ret = __v4l2_ctrl_s_ctrl(imx492->hblank_ctrl, mode->hblank);
> > > +   if (ret)
> > > +           return ret;
> > > +
> > > +   return __v4l2_ctrl_modify_range(imx492->vblank_ctrl, mode->vblank_min,
> > > +                                   mode->vblank_max, 1, mode->vblank);
> > > +}
> > > +
> > > +/**
> > > + * imx492_update_exp_gain() - Set updated exposure and gain
> > > + * @imx492: pointer to imx492 device
> > > + * @exposure: updated exposure value
> > > + * @gain: updated analog gain value
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_update_exp_gain(struct imx492 *imx492, u32 exposure, u32 gain)
> > > +{
> > > +   u32 lpfr, shutter;
> > > +   int ret;
> > > +
> > > +   lpfr = imx492->vblank + imx492->cur_mode->height;
> > > +   shutter = lpfr - exposure;
> > > +
> > > +   ret = imx492_write_reg(imx492, IMX492_REG_HOLD, 1, 1);
> > > +   if (ret)
> > > +           return ret;
> > > +
> > > +   ret = imx492_write_reg(imx492, IMX492_REG_AGAIN, 2, gain);
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_ctrl() - Set subdevice control
> > > + * @ctrl: pointer to v4l2_ctrl structure
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_ctrl(struct v4l2_ctrl *ctrl)
> > > +{
> > > +   struct imx492 *imx492 =
> > > +           container_of(ctrl->handler, struct imx492, ctrl_handler);
> > > +   u32 analog_gain;
> > > +   u32 exposure;
> > > +   int ret;
> > > +
> > > +   switch (ctrl->id) {
> > > +   case V4L2_CID_VBLANK:
> > > +           imx492->vblank = imx492->vblank_ctrl->val;
> > > +
> > > +           ret = __v4l2_ctrl_modify_range(imx492->exp_ctrl,
> > > +                                          IMX492_EXPOSURE_MIN,
> > > +                                          imx492->vblank +
> > > +                                          imx492->cur_mode->height -
> > > +                                          IMX492_EXPOSURE_OFFSET,
> > > +                                          1, IMX492_EXPOSURE_DEFAULT);
> >
> > It looks like you forgot to write the corresponding registers.
>
> Yeah, will look into this one as well.
>
> > > +           break;
> > > +   case V4L2_CID_EXPOSURE:
> > > +           /* Set controls only if sensor is in power on state */
> > > +           if (!pm_runtime_get_if_in_use(imx492->dev))
> > > +                   return 0;
> > > +           exposure = ctrl->val;
> > > +           analog_gain = imx492->again_ctrl->val;
> > > +           ret = imx492_update_exp_gain(imx492, exposure, analog_gain);
> > > +           pm_runtime_put(imx492->dev);
> > > +           break;
> > > +   case V4L2_CID_TEST_PATTERN:
> > > +           if (ctrl->val) {
> > > +                   imx492_write_reg(imx492, IMX492_REG_TESTPATSEL, 1, ctrl->val - 1);
> > > +                   imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_ON);
> > > +           } else {
> > > +                   imx492_write_reg(imx492, IMX492_REG_TESTPTRN, 1, IMX492_BITS_TPTRN_OFF);
> > > +           }
> >
> > Don't you need the same pm_runtime_get_if_in_use() dance as for
> > V4L2_CID_EXPOSURE ?
>
> Yup.
>
> > > +           ret = 0;
> > > +           break;
> >
> > Missing V4L2_CID_ANALOGUE_GAIN.
>
> Not implemented at the moment.
>
> > > +   default:
> > > +           dev_err(imx492->dev, "Invalid control %d", ctrl->id);
> >
> > This shouldn't happen if you correctly handle all the controls you have
> > instanciated in imx492_init_controls().
>
> Well, need to verify if that's the case here.
>
> > > +           ret = -EINVAL;
> > > +   }
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/* V4l2 subdevice control ops*/
> > > +static const struct v4l2_ctrl_ops imx492_ctrl_ops = {
> > > +   .s_ctrl = imx492_set_ctrl,
> > > +};
> > > +
> > > +/**
> > > + * imx492_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @code: V4L2 sub-device code enumeration need to be filled
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_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(supported_modes))
> > > +           return -EINVAL;
> > > +
> > > +   code->code = supported_modes[code->index].code;
> >
> > All modes have the same media bus code, you shouldn't report duplicated
> > values.
>
> This sensor support 10bit format so this is prep work when these get properly
> implemented.
>
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fsize: V4L2 sub-device size enumeration need to be filled
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_enum_frame_size(struct v4l2_subdev *sd,
> > > +                             struct v4l2_subdev_state *sd_state,
> > > +                             struct v4l2_subdev_frame_size_enum *fsize)
> > > +{
> > > +   if (fsize->index > ARRAY_SIZE(supported_modes))
> > > +           return -EINVAL;
> > > +
> > > +   if (fsize->code != supported_modes[fsize->index].code)
> > > +           return -EINVAL;
> > > +
> > > +   fsize->max_width = supported_modes[fsize->index].width;
> > > +   fsize->min_width = fsize->max_width;
> > > +   fsize->max_height = supported_modes[fsize->index].height;
> > > +   fsize->min_height = fsize->max_height;
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > +n * imx492_fill_pad_format() - Fill subdevice pad format
> > > + *                            from selected sensor mode
> > > + * @imx492: pointer to imx492 device
> > > + * @mode: pointer to imx492_mode sensor mode
> > > + * @fmt: V4L2 sub-device format need to be filled
> > > + */
> > > +static void imx492_fill_pad_format(struct imx492 *imx492,
> > > +                              const struct imx492_mode *mode,
> > > +                              struct v4l2_subdev_format *fmt)
> > > +{
> > > +   fmt->format.width = mode->width;
> > > +   fmt->format.height = mode->height;
> > > +   fmt->format.code = mode->code;
> > > +   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;
> >
> > You can use V4L2_QUANTIZATION_FULL_RANGE.
>
> OK.
>
> > > +   fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
> > > +}
> > > +
> > > +/**
> > > + * imx492_get_pad_format() - Get subdevice pad format
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fmt: V4L2 sub-device format need to be set
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_get_pad_format(struct v4l2_subdev *sd,
> > > +                            struct v4l2_subdev_state *sd_state,
> > > +                            struct v4l2_subdev_format *fmt)
> > > +{
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +   mutex_lock(&imx492->mutex);
> > > +
> > > +   if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > +           struct v4l2_mbus_framefmt *framefmt;
> > > +
> > > +           framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > > +           fmt->format = *framefmt;
> > > +   } else {
> > > +           imx492_fill_pad_format(imx492, imx492->cur_mode, fmt);
> > > +   }
> > > +
> > > +   mutex_unlock(&imx492->mutex);
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_pad_format() - Set subdevice pad format
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + * @fmt: V4L2 sub-device format need to be set
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_pad_format(struct v4l2_subdev *sd,
> > > +                            struct v4l2_subdev_state *sd_state,
> > > +                            struct v4l2_subdev_format *fmt)
> > > +{
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +   const struct imx492_mode *mode;
> > > +   int ret = 0;
> > > +
> > > +   mutex_lock(&imx492->mutex);
> > > +
> > > +   fmt->format.code = imx492_get_format_code(imx492, 0);
> > > +   mode = v4l2_find_nearest_size(supported_modes,
> > > +                                   ARRAY_SIZE(supported_modes),
> > > +                                   width, height,
> > > +                                   fmt->format.width, fmt->format.height);
> > > +   imx492_fill_pad_format(imx492, mode, fmt);
> > > +
> > > +   if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> > > +           struct v4l2_mbus_framefmt *framefmt;
> > > +
> > > +           framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> > > +           *framefmt = fmt->format;
> > > +   } else {
> > > +           ret = imx492_update_controls(imx492, mode);
> > > +           if (!ret)
> > > +                   imx492->cur_mode = mode;
> > > +   }
> > > +
> > > +   mutex_unlock(&imx492->mutex);
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_init_pad_cfg() - Initialize sub-device pad configuration
> > > + * @sd: pointer to imx492 V4L2 sub-device structure
> > > + * @sd_state: V4L2 sub-device configuration
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_init_pad_cfg(struct v4l2_subdev *sd,
> > > +                          struct v4l2_subdev_state *sd_state)
> > > +{
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +   struct v4l2_subdev_format fmt = { 0 };
> > > +
> > > +   fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
> >
> > When using the active state API you will never get a null state here, so you
> > can set this to
> >
> >       struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_TRY, };
> >
> > unconditionally.
>
> OK.
>
> > > +   imx492_fill_pad_format(imx492, &supported_modes[0], &fmt);
> > > +
> > > +   return imx492_set_pad_format(sd, sd_state, &fmt);
> > > +}
> > > +
> > > +/**
> > > + * imx492_start_streaming() - Start sensor stream
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_start_streaming(struct imx492 *imx492)
> > > +{
> > > +   const struct imx492_reg_list *reg_list;
> > > +   int ret;
> > > +
> > > +   /* Write sensor mode registers */
> > > +   reg_list = &imx492->cur_mode->reg_list;
> > > +   ret = imx492_write_regs(imx492, reg_list->regs,
> > > +                           reg_list->num_of_regs);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "fail to write initial registers");
> > > +           return ret;
> > > +   }
> > > +
> > > +   /* Setup handler will write actual exposure and gain */
> > > +   ret = __v4l2_ctrl_handler_setup(imx492->sd.ctrl_handler);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "fail to setup handler");
> > > +           return ret;
> > > +   }
> > > +
> > > +   /* 1st stabilization period */
> > > +   usleep_range(10000, 11000);
> > > +   imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, 0x02);
> > > +   imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x92);
> > > +   imx492_write_reg(imx492, IMX492_REG_SYSCLKEN, 1, 0x9a);
> > > +   imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STREAMING);
> > > +
> > > +   /* 2nd stabilization period */
> > > +   usleep_range(7000, 8000);
> > > +
> > > +   /* Start streaming */
> > > +   ret = imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x20);
> > > +
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "fail to start streaming");
> > > +           return ret;
> > > +   }
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_stop_streaming() - Stop sensor stream
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static void imx492_stop_streaming(struct imx492 *imx492)
> > > +{
> > > +   imx492_write_reg(imx492, IMX492_REG_MODE_SELECT, 1, IMX492_MODE_STANDBY);
> > > +   imx492_write_reg(imx492, IMX492_REG_XMSTA, 1, 0x10);
> > > +}
> > > +
> > > +/**
> > > + * imx492_set_stream() - Enable sensor streaming
> > > + * @sd: pointer to imx492 subdevice
> > > + * @enable: set to enable sensor streaming
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_set_stream(struct v4l2_subdev *sd, int enable)
> > > +{
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +   int ret;
> > > +
> > > +   mutex_lock(&imx492->mutex);
> > > +
> > > +   if (imx492->streaming == enable) {
> >
> > This should never happen. You can drop imx492->streaming.
>
> Well, OK.
>
> > > +           mutex_unlock(&imx492->mutex);
> > > +           return 0;
> > > +   }
> > > +
> > > +   if (enable) {
> > > +           ret = pm_runtime_resume_and_get(imx492->dev);
> > > +           if (ret)
> > > +                   goto error_unlock;
> > > +           ret = imx492_start_streaming(imx492);
> > > +           if (ret)
> > > +                   goto error_power_off;
> > > +   } else {
> > > +           imx492_stop_streaming(imx492);
> > > +           pm_runtime_put(imx492->dev);
> > > +   }
> > > +
> > > +   imx492->streaming = enable;
> > > +
> > > +   mutex_unlock(&imx492->mutex);
> > > +
> > > +   return 0;
> > > +
> > > +error_power_off:
> > > +   pm_runtime_put(imx492->dev);
> > > +error_unlock:
> > > +   mutex_unlock(&imx492->mutex);
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_detect() - Detect imx492 sensor
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, -EIO if sensor id does not match
> > > + */
> > > +static int imx492_detect(struct imx492 *imx492)
> > > +{
> > > +   int ret;
> > > +   u32 val;
> > > +
> > > +   ret = imx492_read_reg(imx492, IMX492_REG_STANDBY, 1, &val);
> >
> > Is the chip ID really stored in that register ?
>
> No.  There simply isn't an ID register.  In order to see if the sensor is
> properly powered up and reset i had to chose a register with a known, non-zero
> value.
>
> > > +   if (ret)
> > > +           return ret;
> > > +
> > > +   if (val != IMX492_ID) {
> > > +           dev_err(imx492->dev, "chip id mismatch: %x!=%x", IMX492_ID, val);
> > > +           return -ENXIO;
> > > +   }
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_parse_hw_config() - Parse HW configuration and check if supported
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_parse_hw_config(struct imx492 *imx492)
> > > +{
> > > +   struct fwnode_handle *fwnode = dev_fwnode(imx492->dev);
> > > +   struct v4l2_fwnode_endpoint bus_cfg = {
> > > +           .bus_type = V4L2_MBUS_CSI2_DPHY
> > > +   };
> > > +   struct fwnode_handle *ep;
> > > +   unsigned int i;
> > > +   int ret;
> > > +
> > > +   if (!fwnode)
> > > +           return -ENXIO;
> > > +
> > > +   imx492->power_gpio = devm_gpiod_get(imx492->dev, "power", GPIOD_OUT_HIGH);
> >
> > Not listed in the DT binding.
> >
> > > +   if (IS_ERR(imx492->power_gpio)) {
> > > +           dev_err(imx492->dev, "failed to get power gpio %ld",
> > > +                   PTR_ERR(imx492->power_gpio));
> > > +           return PTR_ERR(imx492->power_gpio);
> > > +   }
> > > +
> > > +   imx492->oscen_gpio = devm_gpiod_get(imx492->dev, "oscen", GPIOD_OUT_HIGH);
> >
> > Not listed in the DT binding.
>
> Both of the above are specific to this particular sensor board.  Other
> implementations may well not have any of these.
>
> > You should also handle regulators in the driver.
>
> Err...
>
> > > +   if (IS_ERR(imx492->oscen_gpio)) {
> > > +           dev_err(imx492->dev, "failed to get oscen gpio %ld",
> > > +                   PTR_ERR(imx492->oscen_gpio));
> > > +           return PTR_ERR(imx492->oscen_gpio);
> > > +   }
> > > +
> > > +   imx492->reset_gpio = devm_gpiod_get(imx492->dev, "reset", GPIOD_OUT_HIGH);
> > > +   if (IS_ERR(imx492->reset_gpio)) {
> > > +           dev_err(imx492->dev, "failed to get reset gpio %ld",
> > > +                   PTR_ERR(imx492->reset_gpio));
> > > +           return PTR_ERR(imx492->reset_gpio);
> > > +   }
> > > +
> > > +   if (gpiod_direction_output(imx492->power_gpio, 1) ||
> > > +       gpiod_direction_output(imx492->oscen_gpio, 1) ||
> > > +       gpiod_direction_output(imx492->reset_gpio, 0)) {
> >
> > This is done by devm_gpiod_get().
>
> OK.
>
> > > +           dev_err(imx492->dev, "failed to change gpio direction");
> > > +           return -EINVAL;
> > > +   }
> > > +
> > > +   /* Get sensor input clock */
> > > +   imx492->inclk = devm_clk_get(imx492->dev, NULL);
> > > +   if (IS_ERR(imx492->inclk)) {
> > > +           dev_err(imx492->dev, "could not get inclk");
> > > +           return PTR_ERR(imx492->inclk);
> > > +   }
> > > +
> > > +   ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> > > +   if (!ep) {
> > > +           dev_err(imx492->dev, "next endpoint?");
> > > +           return -ENXIO;
> > > +   }
> > > +
> > > +   ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> > > +   fwnode_handle_put(ep);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "endpoint alloc parse");
> > > +           return ret;
> > > +   }
> > > +
> > > +   if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX492_NUM_DATA_LANES) {
> > > +           dev_err(imx492->dev, "number of CSI2 data lanes %d is not supported",
> > > +                   bus_cfg.bus.mipi_csi2.num_data_lanes);
> > > +           ret = -EINVAL;
> > > +           goto done_endpoint_free;
> > > +   }
> > > +
> > > +   if (!bus_cfg.nr_of_link_frequencies) {
> > > +           dev_err(imx492->dev, "no link frequencies defined");
> > > +           ret = -EINVAL;
> > > +           goto done_endpoint_free;
> > > +   }
> > > +
> > > +   for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> > > +           if (bus_cfg.link_frequencies[i] == IMX492_LINK_FREQ)
> > > +                   goto done_endpoint_free;
> > > +   }
> > > +
> > > +   ret = -EINVAL;
> > > +
> > > +done_endpoint_free:
> > > +   v4l2_fwnode_endpoint_free(&bus_cfg);
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/* V4l2 subdevice ops */
> > > +static const struct v4l2_subdev_video_ops imx492_video_ops = {
> > > +   .s_stream = imx492_set_stream,
> > > +};
> > > +
> > > +static const struct v4l2_subdev_pad_ops imx492_pad_ops = {
> > > +   .init_cfg = imx492_init_pad_cfg,
> > > +   .enum_mbus_code = imx492_enum_mbus_code,
> > > +   .enum_frame_size = imx492_enum_frame_size,
> > > +   .get_fmt = imx492_get_pad_format,
> >
> > Please use the subdev active state API. You need to call
> > v4l2_subdev_init_finalize() at probe time, and you can set this to
> >
> >       .get_fmt = v4l2_subdev_get_fmt,
>
> OK.
>
> > Then, in imx492_set_pad_format() (and elsewhere as needed), you can use
> > v4l2_subdev_get_pad_format() to replace v4l2_subdev_get_try_format(). This
> > helps making code paths identical for the TRY and ACTIVE cases, the only
> > exception being the update of controls in .set_fmt() in the ACTIVE case.
> >
> > > +   .set_fmt = imx492_set_pad_format,
> >
> > Please also implement the .get_selection operation to report the
> > V4L2_SEL_TGT_CROP, V4L2_SEL_TGT_CROP_BOUNDS, V4L2_SEL_TGT_CROP_DEFAULT and
> > V4L2_SEL_TGT_NATIVE_SIZE values.
>
> Cropping is a big pain in the ass with this sensor and is currently not stable.
> Could you please point me to an existing driver that's a good example?
>
> > > +};
> > > +
> > > +static const struct v4l2_subdev_ops imx492_subdev_ops = {
> > > +   .video = &imx492_video_ops,
> > > +   .pad = &imx492_pad_ops,
> > > +};
> > > +
> > > +/**
> > > + * imx492_power_on() - Sensor power on sequence
> > > + * @dev: pointer to i2c device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_power_on(struct device *dev)
> > > +{
> > > +   struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +   gpiod_set_value_cansleep(imx492->power_gpio, 1);
> > > +   msleep(1);
> > > +   gpiod_set_value_cansleep(imx492->reset_gpio, 1);
> > > +   msleep(1);
> > > +   gpiod_set_value_cansleep(imx492->oscen_gpio, 1);
> > > +   msleep(1);
> >
> > How about regulators and clock ?
>
> In this particular case i don't have to alter any of them.  Do i need to prepare
> some code for the general case?
>
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_power_off() - Sensor power off sequence
> > > + * @dev: pointer to i2c device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_power_off(struct device *dev)
> > > +{
> > > +   struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +   gpiod_set_value_cansleep(imx492->oscen_gpio, 0);
> > > +   gpiod_set_value_cansleep(imx492->reset_gpio, 0);
> > > +   gpiod_set_value_cansleep(imx492->power_gpio, 0);
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_init_controls() - Initialize sensor subdevice controls
> > > + * @imx492: pointer to imx492 device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_init_controls(struct imx492 *imx492)
> > > +{
> > > +   struct v4l2_ctrl_handler *ctrl_hdlr = &imx492->ctrl_handler;
> > > +   const struct imx492_mode *mode = imx492->cur_mode;
> > > +   u32 lpfr;
> > > +   int ret;
> > > +
> > > +   ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> > > +   if (ret)
> > > +           return ret;
> > > +
> > > +   /* Serialize controls with sensor device */
> > > +   ctrl_hdlr->lock = &imx492->mutex;
> > > +   /* Initialize exposure and gain */
> > > +   lpfr = mode->vblank + mode->height;
> > > +   imx492->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +                                        &imx492_ctrl_ops,
> > > +                                        V4L2_CID_EXPOSURE,
> > > +                                        IMX492_EXPOSURE_MIN,
> > > +                                        lpfr - IMX492_EXPOSURE_OFFSET,
> > > +                                        IMX492_EXPOSURE_STEP,
> > > +                                        IMX492_EXPOSURE_DEFAULT);
> > > +
> > > +   imx492->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +                                          &imx492_ctrl_ops,
> > > +                                          V4L2_CID_ANALOGUE_GAIN,
> > > +                                          IMX492_AGAIN_MIN,
> > > +                                          IMX492_AGAIN_MAX,
> > > +                                          IMX492_AGAIN_STEP,
> > > +                                          IMX492_AGAIN_DEFAULT);
> > > +
> > > +   v4l2_ctrl_cluster(2, &imx492->exp_ctrl);
> > > +
> > > +   imx492->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +                                           &imx492_ctrl_ops,
> > > +                                           V4L2_CID_VBLANK,
> > > +                                           mode->vblank_min,
> > > +                                           mode->vblank_max,
> > > +                                           1, mode->vblank);
> > > +   /* Read only controls */
> > > +   imx492->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +                                           &imx492_ctrl_ops,
> > > +                                           V4L2_CID_HBLANK,
> > > +                                           mode->hblank_min,
> > > +                                           mode->hblank_max,
> > > +                                           1, mode->hblank);
> > > +   if (imx492->hblank_ctrl)
> > > +           imx492->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > > +
> > > +   imx492->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
> > > +                                         &imx492_ctrl_ops,
> > > +                                         V4L2_CID_PIXEL_RATE,
> > > +                                         mode->pclk, mode->pclk,
> > > +                                         1, mode->pclk);
> >
> > Shouldn't this be read-only ?
>
> Yup.

It is already made read only by the framework. The driver code here is correct.
https://elixir.bootlin.com/linux/latest/source/drivers/media/v4l2-core/v4l2-ctrls-defs.c#L1460

  Dave

> > > +
> > > +   imx492->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > > +                                                   &imx492_ctrl_ops,
> > > +                                                   V4L2_CID_LINK_FREQ,
> > > +                                                   ARRAY_SIZE(link_freq) -
> > > +                                                   1,
> > > +                                                   mode->link_freq_idx,
> > > +                                                   link_freq);
> > > +   if (imx492->link_freq_ctrl)
> > > +           imx492->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > > +
> > > +   v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx492_ctrl_ops,
> > > +                                V4L2_CID_TEST_PATTERN,
> > > +                                ARRAY_SIZE(imx492_test_pattern_menu) - 1,
> > > +                                0, 0, imx492_test_pattern_menu);
> > > +
> > > +   if (ctrl_hdlr->error) {
> > > +           dev_err(imx492->dev, "control init failed: %d", ctrl_hdlr->error);
> > > +           v4l2_ctrl_handler_free(ctrl_hdlr);
> > > +           return ctrl_hdlr->error;
> > > +   }
> > > +
> > > +   imx492->sd.ctrl_handler = ctrl_hdlr;
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +/**
> > > + * imx492_probe() - I2C client device binding
> > > + * @client: pointer to i2c client device
> > > + *
> > > + * Return: 0 if successful, error code otherwise.
> > > + */
> > > +static int imx492_probe(struct i2c_client *client)
> > > +{
> > > +   struct imx492 *imx492;
> > > +   int ret;
> > > +
> > > +   imx492 = devm_kzalloc(&client->dev, sizeof(*imx492), GFP_KERNEL);
> > > +   if (!imx492)
> > > +           return -ENOMEM;
> > > +
> > > +   imx492->dev = &client->dev;
> > > +
> > > +   /* Initialize subdev */
> > > +   v4l2_i2c_subdev_init(&imx492->sd, client, &imx492_subdev_ops);
> > > +
> > > +   ret = imx492_parse_hw_config(imx492);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "HW configuration is not supported");
> > > +           return ret;
> > > +   }
> > > +
> > > +   mutex_init(&imx492->mutex);
> > > +
> > > +   ret = imx492_power_on(imx492->dev);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "failed to power-on the sensor");
> > > +           goto error_mutex_destroy;
> > > +   }
> > > +
> > > +   /* Check module identity */
> > > +   ret = imx492_detect(imx492);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "failed to find sensor: %d", ret);
> > > +           goto error_power_off;
> > > +   }
> > > +
> > > +   /* Set default mode to max resolution */
> > > +   imx492->cur_mode = &supported_modes[0];
> > > +   imx492->vblank = imx492->cur_mode->vblank;
> > > +
> > > +   ret = imx492_init_controls(imx492);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "failed to init controls: %d", ret);
> > > +           goto error_power_off;
> > > +   }
> > > +
> > > +   /* Initialize subdev */
> > > +   imx492->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > > +   imx492->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > > +
> > > +   imx492->scap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
> > > +   imx492->scap.capturemode = 0;
> > > +   imx492->scap.timeperframe.denominator = DEFAULT_FPS;
> > > +   imx492->scap.timeperframe.numerator = 1;
> > > +
> > > +   /* Initialize source pad */
> > > +   imx492->pad.flags = MEDIA_PAD_FL_SOURCE;
> > > +   ret = media_entity_pads_init(&imx492->sd.entity, 1, &imx492->pad);
> > > +   if (ret) {
> > > +           dev_err(imx492->dev, "failed to init entity pads: %d", ret);
> > > +           goto error_handler_free;
> > > +   }
> > > +
> > > +   ret = v4l2_async_register_subdev(&imx492->sd);
> > > +   if (ret < 0) {
> > > +           dev_err(imx492->dev, "failed to register async subdev: %d", ret);
> > > +           goto error_media_entity;
> > > +   }
> >
> > This should be done at the very end of probe(), as the sensor can be used
> > right after it gets registered, so it should be fully operational.
> >
> > > +
> > > +   pm_runtime_set_active(imx492->dev);
> > > +   pm_runtime_enable(imx492->dev);
> > > +   pm_runtime_idle(imx492->dev);
> >
> > While at it, I would also implement autosuspend. You should then add a call to
> > pm_runtime_get_noresume() before pm_runtime_enable(), drop the
> > pm_runtime_idle() call, and add
>
> From what i can see most, even 2022, drivers come with the above sequence.
> Which one does it right?
>
> >       pm_runtime_set_autosuspend_delay(imx492->dev, 1000);
> >       pm_runtime_use_autosuspend(imx492->dev);
> >       pm_runtime_put_autosuspend(imx492->dev);
> >
> > You will also need to replace pm_runtime_put() with
> > pm_runtime_mark_last_busy() + pm_runtime_put_autosuspend() above.
> >
> > > +
> > > +   return 0;
> > > +
> > > +error_media_entity:
> > > +   media_entity_cleanup(&imx492->sd.entity);
> > > +error_handler_free:
> > > +   v4l2_ctrl_handler_free(imx492->sd.ctrl_handler);
> > > +error_power_off:
> > > +   imx492_power_off(imx492->dev);
> > > +error_mutex_destroy:
> > > +   mutex_destroy(&imx492->mutex);
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +/**
> > > + * imx492_remove() - I2C client device unbinding
> > > + * @client: pointer to I2C client device
> > > + */
> > > +static void imx492_remove(struct i2c_client *client)
> > > +{
> > > +   struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > +   struct imx492 *imx492 = to_imx492(sd);
> > > +
> > > +   v4l2_async_unregister_subdev(sd);
> > > +   media_entity_cleanup(&sd->entity);
> > > +   v4l2_ctrl_handler_free(sd->ctrl_handler);
> > > +   pm_runtime_disable(&client->dev);
> > > +   if (!pm_runtime_status_suspended(&client->dev))
> > > +           imx492_power_off(&client->dev);
> > > +   pm_runtime_set_suspended(&client->dev);
> > > +   mutex_destroy(&imx492->mutex);
> > > +}
> > > +
> > > +static const struct dev_pm_ops imx492_pm_ops = {
> > > +   SET_RUNTIME_PM_OPS(imx492_power_off, imx492_power_on, NULL)
> > > +};
> > > +
> > > +static const struct of_device_id imx492_of_match[] = {
> > > +   { .compatible = "sony,imx492_mipi" },
> > > +   { }
> > > +};
> > > +
> > > +MODULE_DEVICE_TABLE(of, imx492_of_match);
> > > +
> > > +static struct i2c_driver imx492_driver = {
> > > +   .probe_new = imx492_probe,
> > > +   .remove = imx492_remove,
> > > +   .driver = {
> > > +           .name = "imx492",
> > > +           .pm = &imx492_pm_ops,
> > > +           .of_match_table = imx492_of_match,
> > > +   },
> > > +};
> > > +
> > > +module_i2c_driver(imx492_driver);
> > > +
> > > +MODULE_DESCRIPTION("Sony imx492 sensor driver");
> > > +MODULE_AUTHOR("Petko Manolov <petko.manolov@konsulko.com>");
> > > +MODULE_LICENSE("GPL");
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
>
>
> cheers,
> Petko

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

* Re: [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor
  2022-11-28 14:07       ` Petko Manolov
@ 2022-11-28 15:04         ` Kieran Bingham
  0 siblings, 0 replies; 28+ messages in thread
From: Kieran Bingham @ 2022-11-28 15:04 UTC (permalink / raw)
  To: Petko Manolov; +Cc: linux-media, laurent.pinchart, sakari.ailus

Quoting Petko Manolov (2022-11-28 14:07:22)
> On 22-11-28 13:38:12, Kieran Bingham wrote:
> > Quoting Petko Manolov (2022-11-28 13:11:39)
> > > On 22-11-28 12:45:32, Kieran Bingham wrote:
> > > > Hi Petko,
> > > > 
> > > > What device/ISP are you testing this sensor on?
> > > 
> > > I'll tell you, but only if you promise to not laugh too much.  Deal?
> > > 
> > > i.MX8M-Mini
> > > 
> > > I hope nobody will notice the above line...
> > 
> > I won't laugh at all. We've just merged the ISI pipeline handler for
> > libcamera, which should let you use libcamera on this target (I think).
> 
> I think i saw your patch in the ML.
> 
> > I would hope sometime in the future you'd be able to use the ISI pipeline
> > handler with a GPU based ISP with this sensor too.
> 
> Both of the above are present in i.MX8M-Plus, not the Mini.
> 
> > How are you managing the image 3a? the imx492 is a raw sensor isn't it ?
> 
> Not sure what you mean by "image 3a" and yes, it's a raw sensor.

I meant how are you handling "Auto-exposure" "Auto-gain"
"Auto-whitebalance" (known as 3a).

There's more than that of course, but those are the basics that are
expected to be able to get a 'usable' image. Unless of course you're
doing everything with manual controls ... which is the alternative for a
fixed/known lighting environment.

But without an ISP on the device anyway, perhaps there's already more
going on elsewhere?

--
Kieran.



> > > > Quoting Petko Manolov (2022-11-25 15:31:15)
> > > > > This patch adds dt-bindings documentation, driver source, etc for Sony imx492
> > > > > image sensor.
> > > > > 
> > > > > imx492 is a diagonal 23.1 mm (Type 1.4) CMOS image sensor with color or
> > > > > monochrome square pixel array and approximately 47.08 M effective pixels. 12-bit
> > > > > digital output makes it possible to output the signals with high definition for
> > > > > moving pictures. It is programmable through I2C interface. The I2C client
> > > > > address can be either 0x10 or 0x1a depending on SLASEL pin. Image data is sent
> > > > > through MIPI CSI-2.
> > > > > 
> > > > > Petko Manolov (5):
> > > > >   DT bindings for imx492
> > > > >   media: i2c: imx492: driver's header
> > > > >   media: i2c: imx492: driver's source
> > > > >   media: i2c: add imx492 config entry
> > > > >   media: i2c: add imx492 entry for make
> > > > 
> > > > Could you squash patches 2, 3, 4, and 5 into a single patch please?
> > > 
> > > This is the exact opposite to what the networking folks would prefer, but it's
> > > OK with me.
> > 
> > Haha ... yes - isn't it great working in mulitple subsystems....
> 
> Yeah, easy to get confused... :)
> 
> > > > Also - I think you'll need an entry in MAINTAINERS.
> > > 
> > > Right, that one too.
> > > 
> > > > I can't see any reference to the selection controls:
> > > >  - V4L2_SEL_TGT_CROP_DEFAULT
> > > >  - V4L2_SEL_TGT_CROP
> > > >  - V4L2_SEL_TGT_CROP_BOUNDS
> > > 
> > > These are in a very early phase of implementing.
> > 
> > Ok
> > 
> > > > Do you have the datasheet or sufficient information to be able to implement
> > > > these controls?
> > > 
> > > Of course not.  We are brute forcing our way forward by mostly reverse
> > > engineering another solution that has an FPGA on the other end of the CSI link.
> > 
> > Understood ;-) (and ... I think what I was fearing/anticipating).
> 
> I would have been too easy otherwise.
> 
> 
>                 Petko

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

end of thread, other threads:[~2022-11-28 15:05 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-25 15:31 [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Petko Manolov
2022-11-25 15:31 ` [PATCH v1 1/5] DT bindings for imx492 Petko Manolov
2022-11-28  4:37   ` Laurent Pinchart
2022-11-28 13:07     ` Petko Manolov
2022-11-28 13:28       ` Laurent Pinchart
2022-11-25 15:31 ` [PATCH v1 2/5] media: i2c: imx492: driver's header Petko Manolov
2022-11-28  4:40   ` Laurent Pinchart
2022-11-28 13:12     ` Petko Manolov
2022-11-28 12:47   ` Kieran Bingham
2022-11-28 13:14     ` Petko Manolov
2022-11-28 13:30       ` Laurent Pinchart
2022-11-28 13:53         ` Petko Manolov
2022-11-25 15:31 ` [PATCH v1 3/5] media: i2c: imx492: driver's source Petko Manolov
2022-11-28  5:16   ` Laurent Pinchart
2022-11-28 13:42     ` Petko Manolov
2022-11-28 14:08       ` Laurent Pinchart
2022-11-28 14:18       ` Dave Stevenson
2022-11-28 12:58   ` Kieran Bingham
2022-11-28 13:48     ` Petko Manolov
2022-11-25 15:31 ` [PATCH v1 4/5] media: i2c: add imx492 config entry Petko Manolov
2022-11-25 15:31 ` [PATCH v1 5/5] media: i2c: add imx492 entry for make Petko Manolov
2022-11-25 19:48   ` kernel test robot
2022-11-28 12:45 ` [PATCH v1 0/5] Adds media driver for Sony IMX492 sensor Kieran Bingham
2022-11-28 13:11   ` Petko Manolov
2022-11-28 13:38     ` Kieran Bingham
2022-11-28 13:46       ` Laurent Pinchart
2022-11-28 14:07       ` Petko Manolov
2022-11-28 15:04         ` Kieran Bingham

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.