...
...
12
12
13
Regards,
13
Regards,
14
Benjamin
14
Benjamin
15
15
16
---
16
---
17
Changes in v4:
18
- Fix data-lanes syntax in binding
19
- Link to v3: https://lore.kernel.org/r/20250402-b4-vd55g1-v3-0-393985404759@foss.st.com
20
21
Changes in v3:
22
- Add maxItems to data-lanes in binding
23
- Drop redondant 'binding' in binding commit message
24
- Link to v2: https://lore.kernel.org/r/20250401-b4-vd55g1-v2-0-0c8ab8a48c55@foss.st.com
25
17
Changes in v2:
26
Changes in v2:
18
- Fix device tree binding mistakes
27
- Fix device tree binding mistakes
19
- Drop linux media git from MAINTAINERS file
28
- Drop linux media git from MAINTAINERS file
20
- Fix coding style mistakes
29
- Fix coding style mistakes
21
- Drop vd55g1_err_probe wrapper
30
- Drop vd55g1_err_probe wrapper
22
- Fix 32bits build
31
- Fix 32bits build
23
- Fix config symbol help paragraph being too short for checkpatch
32
- Fix config symbol help paragraph being too short for checkpatch
24
- Link to v1: https://lore.kernel.org/r/20250328-b4-vd55g1-v1-0-8d16b4a79f29@foss.st.com
33
- Link to v1: https://lore.kernel.org/r/20250328-b4-vd55g1-v1-0-8d16b4a79f29@foss.st.com
25
34
26
---
35
---
27
Benjamin Mugnier (2):
36
Benjamin Mugnier (2):
28
media: dt-bindings: Add ST VD55G1 camera sensor binding
37
media: dt-bindings: Add ST VD55G1 camera sensor
29
media: i2c: Add driver for ST VD55G1 camera sensor
38
media: i2c: Add driver for ST VD55G1 camera sensor
30
39
31
.../devicetree/bindings/media/i2c/st,vd55g1.yaml | 132 ++
40
.../devicetree/bindings/media/i2c/st,vd55g1.yaml | 132 ++
32
MAINTAINERS | 9 +
41
MAINTAINERS | 9 +
33
drivers/media/i2c/Kconfig | 11 +
42
drivers/media/i2c/Kconfig | 11 +
...
...
diff view generated by jsdifflib
...
...
81
+ unevaluatedProperties: false
81
+ unevaluatedProperties: false
82
+
82
+
83
+ properties:
83
+ properties:
84
+ data-lanes:
84
+ data-lanes:
85
+ items:
85
+ items:
86
+ const: 1
86
+ - const: 1
87
+
87
+
88
+ link-frequencies:
88
+ link-frequencies:
89
+ maxItems: 1
89
+ maxItems: 1
90
+ items:
90
+ items:
91
+ minimum: 125000000
91
+ minimum: 125000000
...
...
diff view generated by jsdifflib
1
The VD55G1 is a monochrome global shutter camera with a 804x704 maximum
1
The VD55G1 is a monochrome global shutter camera with a 804x704 maximum
2
resolution with RAW8 and RAW10 bytes per pixel.
2
resolution with RAW8 and RAW10 bytes per pixel.
3
The driver supports :
3
The driver supports :
4
- Auto exposure from the sensor, or manual exposure mode
4
- Auto exposure from the sensor, or manual exposure mode
5
- HDR subtraction mode, allowing edge detection and background removal
5
- HDR subtraction mode, allowing edge detection and background removal
6
- Auto exposure cold start, using configuration values from last stream
6
- Auto exposure cold start, using configuration values from last stream
7
to start the next one
7
to start the next one
8
- LED GPIOs for illumination
8
- LED GPIOs for illumination
9
- Most standard camera sensor features (hblank, vblank, test patterns,
9
- Most standard camera sensor features (hblank, vblank, test patterns,
10
again, dgain, hflip, vflip, auto exposure bias, etc.)
10
again, dgain, hflip, vflip, auto exposure bias, etc.)
11
Add driver source code to MAINTAINERS file.
11
Add driver source code to MAINTAINERS file.
12
12
13
Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
13
Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
14
---
14
---
15
MAINTAINERS | 2 +
15
MAINTAINERS | 2 +
16
drivers/media/i2c/Kconfig | 11 +
16
drivers/media/i2c/Kconfig | 11 +
17
drivers/media/i2c/Makefile | 1 +
17
drivers/media/i2c/Makefile | 1 +
18
drivers/media/i2c/vd55g1.c | 1993 ++++++++++++++++++++++++++++++++++++++++++++
18
drivers/media/i2c/vd55g1.c | 1993 ++++++++++++++++++++++++++++++++++++++++++++
19
4 files changed, 2007 insertions(+)
19
4 files changed, 2007 insertions(+)
20
20
21
diff --git a/MAINTAINERS b/MAINTAINERS
21
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
23
--- a/MAINTAINERS
23
--- a/MAINTAINERS
24
+++ b/MAINTAINERS
24
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@ M:    Sylvain Petinot <sylvain.petinot@foss.st.com>
25
@@ -XXX,XX +XXX,XX @@ M:    Sylvain Petinot <sylvain.petinot@foss.st.com>
26
L:    linux-media@vger.kernel.org
26
L:    linux-media@vger.kernel.org
27
S:    Maintained
27
S:    Maintained
28
F:    Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
28
F:    Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
29
+F:    drivers/media/i2c/vd55g1.c
29
+F:    drivers/media/i2c/vd55g1.c
30
30
31
ST VGXY61 DRIVER
31
ST VGXY61 DRIVER
32
M:    Benjamin Mugnier <benjamin.mugnier@foss.st.com>
32
M:    Benjamin Mugnier <benjamin.mugnier@foss.st.com>
33
@@ -XXX,XX +XXX,XX @@ F:    drivers/media/i2c/mt*
33
@@ -XXX,XX +XXX,XX @@ F:    drivers/media/i2c/mt*
34
F:    drivers/media/i2c/og*
34
F:    drivers/media/i2c/og*
35
F:    drivers/media/i2c/ov*
35
F:    drivers/media/i2c/ov*
36
F:    drivers/media/i2c/s5*
36
F:    drivers/media/i2c/s5*
37
+F:    drivers/media/i2c/vd55g1.c
37
+F:    drivers/media/i2c/vd55g1.c
38
F:    drivers/media/i2c/vgxy61.c
38
F:    drivers/media/i2c/vgxy61.c
39
39
40
VF610 NAND DRIVER
40
VF610 NAND DRIVER
41
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
41
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
42
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
43
--- a/drivers/media/i2c/Kconfig
43
--- a/drivers/media/i2c/Kconfig
44
+++ b/drivers/media/i2c/Kconfig
44
+++ b/drivers/media/i2c/Kconfig
45
@@ -XXX,XX +XXX,XX @@ config VIDEO_S5K6A3
45
@@ -XXX,XX +XXX,XX @@ config VIDEO_S5K6A3
46
     This is a V4L2 sensor driver for Samsung S5K6A3 raw
46
     This is a V4L2 sensor driver for Samsung S5K6A3 raw
47
     camera sensor.
47
     camera sensor.
48
48
49
+config VIDEO_VD55G1
49
+config VIDEO_VD55G1
50
+    tristate "ST VD55G1 sensor support"
50
+    tristate "ST VD55G1 sensor support"
51
+    select V4L2_CCI_I2C
51
+    select V4L2_CCI_I2C
52
+    depends on OF && GPIOLIB
52
+    depends on OF && GPIOLIB
53
+    help
53
+    help
54
+     This is a Video4Linux2 sensor driver for the ST VD55G1
54
+     This is a Video4Linux2 sensor driver for the ST VD55G1
55
+     camera sensor.
55
+     camera sensor.
56
+
56
+
57
+     To compile this driver as a module, choose M here: the
57
+     To compile this driver as a module, choose M here: the
58
+     module will be called vd55g1.
58
+     module will be called vd55g1.
59
+
59
+
60
config VIDEO_VGXY61
60
config VIDEO_VGXY61
61
    tristate "ST VGXY61 sensor support"
61
    tristate "ST VGXY61 sensor support"
62
    select V4L2_CCI_I2C
62
    select V4L2_CCI_I2C
63
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
63
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
64
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
65
--- a/drivers/media/i2c/Makefile
65
--- a/drivers/media/i2c/Makefile
66
+++ b/drivers/media/i2c/Makefile
66
+++ b/drivers/media/i2c/Makefile
67
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_VIDEO_TW9910) += tw9910.o
67
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_VIDEO_TW9910) += tw9910.o
68
obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o
68
obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o
69
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
69
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
70
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
70
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
71
+obj-$(CONFIG_VIDEO_VD55G1) += vd55g1.o
71
+obj-$(CONFIG_VIDEO_VD55G1) += vd55g1.o
72
obj-$(CONFIG_VIDEO_VGXY61) += vgxy61.o
72
obj-$(CONFIG_VIDEO_VGXY61) += vgxy61.o
73
obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
73
obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
74
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
74
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
75
diff --git a/drivers/media/i2c/vd55g1.c b/drivers/media/i2c/vd55g1.c
75
diff --git a/drivers/media/i2c/vd55g1.c b/drivers/media/i2c/vd55g1.c
76
new file mode 100644
76
new file mode 100644
77
index XXXXXXX..XXXXXXX
77
index XXXXXXX..XXXXXXX
78
--- /dev/null
78
--- /dev/null
79
+++ b/drivers/media/i2c/vd55g1.c
79
+++ b/drivers/media/i2c/vd55g1.c
80
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
81
+// SPDX-License-Identifier: GPL-2.0
81
+// SPDX-License-Identifier: GPL-2.0
82
+/*
82
+/*
83
+ * Driver for VD55G1 global shutter sensor family driver
83
+ * Driver for VD55G1 global shutter sensor family driver
84
+ *
84
+ *
85
+ * Copyright (C) 2025 STMicroelectronics SA
85
+ * Copyright (C) 2025 STMicroelectronics SA
86
+ */
86
+ */
87
+
87
+
88
+#include <linux/clk.h>
88
+#include <linux/clk.h>
89
+#include <linux/delay.h>
89
+#include <linux/delay.h>
90
+#include <linux/gpio/consumer.h>
90
+#include <linux/gpio/consumer.h>
91
+#include <linux/i2c.h>
91
+#include <linux/i2c.h>
92
+#include <linux/iopoll.h>
92
+#include <linux/iopoll.h>
93
+#include <linux/module.h>
93
+#include <linux/module.h>
94
+#include <linux/pm_runtime.h>
94
+#include <linux/pm_runtime.h>
95
+#include <linux/regmap.h>
95
+#include <linux/regmap.h>
96
+#include <linux/regulator/consumer.h>
96
+#include <linux/regulator/consumer.h>
97
+#include <linux/unaligned.h>
97
+#include <linux/unaligned.h>
98
+#include <linux/units.h>
98
+#include <linux/units.h>
99
+
99
+
100
+#include <media/mipi-csi2.h>
100
+#include <media/mipi-csi2.h>
101
+#include <media/v4l2-async.h>
101
+#include <media/v4l2-async.h>
102
+#include <media/v4l2-cci.h>
102
+#include <media/v4l2-cci.h>
103
+#include <media/v4l2-ctrls.h>
103
+#include <media/v4l2-ctrls.h>
104
+#include <media/v4l2-device.h>
104
+#include <media/v4l2-device.h>
105
+#include <media/v4l2-event.h>
105
+#include <media/v4l2-event.h>
106
+#include <media/v4l2-fwnode.h>
106
+#include <media/v4l2-fwnode.h>
107
+#include <media/v4l2-subdev.h>
107
+#include <media/v4l2-subdev.h>
108
+
108
+
109
+/* Register Map */
109
+/* Register Map */
110
+#define VD55G1_REG_MODEL_ID                CCI_REG32_LE(0x0000)
110
+#define VD55G1_REG_MODEL_ID                CCI_REG32_LE(0x0000)
111
+#define VD55G1_MODEL_ID                    0x53354731
111
+#define VD55G1_MODEL_ID                    0x53354731
112
+#define VD55G1_REG_REVISION                CCI_REG16_LE(0x0004)
112
+#define VD55G1_REG_REVISION                CCI_REG16_LE(0x0004)
113
+#define VD55G1_REVISION_CCB                0x2020
113
+#define VD55G1_REVISION_CCB                0x2020
114
+#define VD55G1_REG_FWPATCH_REVISION            CCI_REG16_LE(0x0012)
114
+#define VD55G1_REG_FWPATCH_REVISION            CCI_REG16_LE(0x0012)
115
+#define VD55G1_REG_FWPATCH_START_ADDR            CCI_REG8(0x2000)
115
+#define VD55G1_REG_FWPATCH_START_ADDR            CCI_REG8(0x2000)
116
+#define VD55G1_REG_SYSTEM_FSM                CCI_REG8(0x001c)
116
+#define VD55G1_REG_SYSTEM_FSM                CCI_REG8(0x001c)
117
+#define VD55G1_SYSTEM_FSM_READY_TO_BOOT            0x01
117
+#define VD55G1_SYSTEM_FSM_READY_TO_BOOT            0x01
118
+#define VD55G1_SYSTEM_FSM_SW_STBY            0x02
118
+#define VD55G1_SYSTEM_FSM_SW_STBY            0x02
119
+#define VD55G1_SYSTEM_FSM_STREAMING            0x03
119
+#define VD55G1_SYSTEM_FSM_STREAMING            0x03
120
+#define VD55G1_REG_BOOT                    CCI_REG8(0x0200)
120
+#define VD55G1_REG_BOOT                    CCI_REG8(0x0200)
121
+#define VD55G1_BOOT_PATCH_SETUP                2
121
+#define VD55G1_BOOT_PATCH_SETUP                2
122
+#define VD55G1_REG_STBY                    CCI_REG8(0x0201)
122
+#define VD55G1_REG_STBY                    CCI_REG8(0x0201)
123
+#define VD55G1_STBY_START_STREAM            1
123
+#define VD55G1_STBY_START_STREAM            1
124
+#define VD55G1_REG_STREAMING                CCI_REG8(0x0202)
124
+#define VD55G1_REG_STREAMING                CCI_REG8(0x0202)
125
+#define VD55G1_STREAMING_STOP_STREAM            1
125
+#define VD55G1_STREAMING_STOP_STREAM            1
126
+#define VD55G1_REG_EXT_CLOCK                CCI_REG32_LE(0x0220)
126
+#define VD55G1_REG_EXT_CLOCK                CCI_REG32_LE(0x0220)
127
+#define VD55G1_REG_LINE_LENGTH                CCI_REG16_LE(0x0300)
127
+#define VD55G1_REG_LINE_LENGTH                CCI_REG16_LE(0x0300)
128
+#define VD55G1_REG_ORIENTATION                CCI_REG8(0x0302)
128
+#define VD55G1_REG_ORIENTATION                CCI_REG8(0x0302)
129
+#define VD55G1_REG_FORMAT_CTRL                CCI_REG8(0x030a)
129
+#define VD55G1_REG_FORMAT_CTRL                CCI_REG8(0x030a)
130
+#define VD55G1_REG_OIF_CTRL                CCI_REG16_LE(0x030c)
130
+#define VD55G1_REG_OIF_CTRL                CCI_REG16_LE(0x030c)
131
+#define VD55G1_REG_ISL_ENABLE                CCI_REG16_LE(0x326)
131
+#define VD55G1_REG_ISL_ENABLE                CCI_REG16_LE(0x326)
132
+#define VD55G1_REG_OIF_IMG_CTRL                CCI_REG8(0x030f)
132
+#define VD55G1_REG_OIF_IMG_CTRL                CCI_REG8(0x030f)
133
+#define VD55G1_REG_MIPI_DATA_RATE            CCI_REG32_LE(0x0224)
133
+#define VD55G1_REG_MIPI_DATA_RATE            CCI_REG32_LE(0x0224)
134
+#define VD55G1_REG_PATGEN_CTRL                CCI_REG16_LE(0x0304)
134
+#define VD55G1_REG_PATGEN_CTRL                CCI_REG16_LE(0x0304)
135
+#define VD55G1_PATGEN_TYPE_SHIFT            4
135
+#define VD55G1_PATGEN_TYPE_SHIFT            4
136
+#define VD55G1_PATGEN_ENABLE                BIT(0)
136
+#define VD55G1_PATGEN_ENABLE                BIT(0)
137
+#define VD55G1_REG_MANUAL_ANALOG_GAIN            CCI_REG8(0x0501)
137
+#define VD55G1_REG_MANUAL_ANALOG_GAIN            CCI_REG8(0x0501)
138
+#define VD55G1_REG_MANUAL_COARSE_EXPOSURE        CCI_REG16_LE(0x0502)
138
+#define VD55G1_REG_MANUAL_COARSE_EXPOSURE        CCI_REG16_LE(0x0502)
139
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN            CCI_REG16_LE(0x0504)
139
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN            CCI_REG16_LE(0x0504)
140
+#define VD55G1_REG_APPLIED_COARSE_EXPOSURE        CCI_REG16_LE(0x00e8)
140
+#define VD55G1_REG_APPLIED_COARSE_EXPOSURE        CCI_REG16_LE(0x00e8)
141
+#define VD55G1_REG_APPLIED_ANALOG_GAIN            CCI_REG16_LE(0x00ea)
141
+#define VD55G1_REG_APPLIED_ANALOG_GAIN            CCI_REG16_LE(0x00ea)
142
+#define VD55G1_REG_APPLIED_DIGITAL_GAIN            CCI_REG16_LE(0x00ec)
142
+#define VD55G1_REG_APPLIED_DIGITAL_GAIN            CCI_REG16_LE(0x00ec)
143
+#define VD55G1_REG_AE_FORCE_COLDSTART            CCI_REG16_LE(0x0308)
143
+#define VD55G1_REG_AE_FORCE_COLDSTART            CCI_REG16_LE(0x0308)
144
+#define VD55G1_REG_AE_COLDSTART_EXP_TIME        CCI_REG32_LE(0x0374)
144
+#define VD55G1_REG_AE_COLDSTART_EXP_TIME        CCI_REG32_LE(0x0374)
145
+#define VD55G1_REG_READOUT_CTRL                CCI_REG8(0x052e)
145
+#define VD55G1_REG_READOUT_CTRL                CCI_REG8(0x052e)
146
+#define VD55G1_REG_DARKCAL_CTRL                CCI_REG8(0x032a)
146
+#define VD55G1_REG_DARKCAL_CTRL                CCI_REG8(0x032a)
147
+#define VD55G1_DARKCAL_BYPASS                0
147
+#define VD55G1_DARKCAL_BYPASS                0
148
+#define VD55G1_DARKCAL_AUTO                1
148
+#define VD55G1_DARKCAL_AUTO                1
149
+#define VD55G1_REG_DUSTER_CTRL                CCI_REG8(0x03ea)
149
+#define VD55G1_REG_DUSTER_CTRL                CCI_REG8(0x03ea)
150
+#define VD55G1_DUSTER_ENABLE                BIT(0)
150
+#define VD55G1_DUSTER_ENABLE                BIT(0)
151
+#define VD55G1_DUSTER_DISABLE                0
151
+#define VD55G1_DUSTER_DISABLE                0
152
+#define VD55G1_DUSTER_DYN_ENABLE            BIT(1)
152
+#define VD55G1_DUSTER_DYN_ENABLE            BIT(1)
153
+#define VD55G1_DUSTER_RING_ENABLE            BIT(4)
153
+#define VD55G1_DUSTER_RING_ENABLE            BIT(4)
154
+#define VD55G1_REG_AE_TARGET_PERCENTAGE            CCI_REG8(0x0486)
154
+#define VD55G1_REG_AE_TARGET_PERCENTAGE            CCI_REG8(0x0486)
155
+#define VD55G1_REG_NEXT_CTX                CCI_REG16_LE(0x03e4)
155
+#define VD55G1_REG_NEXT_CTX                CCI_REG16_LE(0x03e4)
156
+#define VD55G1_REG_EXPOSURE_USE_CASES            CCI_REG8(0x0312)
156
+#define VD55G1_REG_EXPOSURE_USE_CASES            CCI_REG8(0x0312)
157
+#define VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT        BIT(2)
157
+#define VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT        BIT(2)
158
+#define VD55G1_REG_EXPOSURE_MAX_COARSE            CCI_REG16_LE(0x0372)
158
+#define VD55G1_REG_EXPOSURE_MAX_COARSE            CCI_REG16_LE(0x0372)
159
+#define VD55G1_EXPOSURE_MAX_COARSE_DEF            0x7fff
159
+#define VD55G1_EXPOSURE_MAX_COARSE_DEF            0x7fff
160
+#define VD55G1_EXPOSURE_MAX_COARSE_SUB            446
160
+#define VD55G1_EXPOSURE_MAX_COARSE_SUB            446
161
+#define VD55G1_REG_CTX_REPEAT_COUNT_CTX0        CCI_REG16_LE(0x03dc)
161
+#define VD55G1_REG_CTX_REPEAT_COUNT_CTX0        CCI_REG16_LE(0x03dc)
162
+#define VD55G1_REG_CTX_REPEAT_COUNT_CTX1        CCI_REG16_LE(0x03de)
162
+#define VD55G1_REG_CTX_REPEAT_COUNT_CTX1        CCI_REG16_LE(0x03de)
163
+
163
+
164
+#define VD55G1_REG_EXP_MODE(ctx) \
164
+#define VD55G1_REG_EXP_MODE(ctx) \
165
+    CCI_REG8(0x0500 + VD55G1_CTX_OFFSET * (ctx))
165
+    CCI_REG8(0x0500 + VD55G1_CTX_OFFSET * (ctx))
166
+#define VD55G1_REG_FRAME_LENGTH(ctx) \
166
+#define VD55G1_REG_FRAME_LENGTH(ctx) \
167
+    CCI_REG32_LE(0x050c + VD55G1_CTX_OFFSET * (ctx))
167
+    CCI_REG32_LE(0x050c + VD55G1_CTX_OFFSET * (ctx))
168
+#define VD55G1_REG_X_START(ctx) \
168
+#define VD55G1_REG_X_START(ctx) \
169
+    CCI_REG16_LE(0x0514 + VD55G1_CTX_OFFSET * (ctx))
169
+    CCI_REG16_LE(0x0514 + VD55G1_CTX_OFFSET * (ctx))
170
+#define VD55G1_REG_X_WIDTH(ctx) \
170
+#define VD55G1_REG_X_WIDTH(ctx) \
171
+    CCI_REG16_LE(0x0516 + VD55G1_CTX_OFFSET * (ctx))
171
+    CCI_REG16_LE(0x0516 + VD55G1_CTX_OFFSET * (ctx))
172
+#define VD55G1_REG_Y_START(ctx) \
172
+#define VD55G1_REG_Y_START(ctx) \
173
+    CCI_REG16_LE(0x0510 + VD55G1_CTX_OFFSET * (ctx))
173
+    CCI_REG16_LE(0x0510 + VD55G1_CTX_OFFSET * (ctx))
174
+#define VD55G1_REG_Y_HEIGHT(ctx) \
174
+#define VD55G1_REG_Y_HEIGHT(ctx) \
175
+    CCI_REG16_LE(0x0512 + VD55G1_CTX_OFFSET * (ctx))
175
+    CCI_REG16_LE(0x0512 + VD55G1_CTX_OFFSET * (ctx))
176
+#define VD55G1_REG_GPIO_0_CTRL(ctx) \
176
+#define VD55G1_REG_GPIO_0_CTRL(ctx) \
177
+    CCI_REG8(0x051d + VD55G1_CTX_OFFSET * (ctx))
177
+    CCI_REG8(0x051d + VD55G1_CTX_OFFSET * (ctx))
178
+#define VD55G1_REG_VT_MODE(ctx) \
178
+#define VD55G1_REG_VT_MODE(ctx) \
179
+    CCI_REG8(0x0536 + VD55G1_CTX_OFFSET * (ctx))
179
+    CCI_REG8(0x0536 + VD55G1_CTX_OFFSET * (ctx))
180
+#define VD55G1_VT_MODE_NORMAL 0
180
+#define VD55G1_VT_MODE_NORMAL 0
181
+#define VD55G1_VT_MODE_SUBTRACTION 1
181
+#define VD55G1_VT_MODE_SUBTRACTION 1
182
+#define VD55G1_REG_MASK_FRAME_CTRL(ctx) \
182
+#define VD55G1_REG_MASK_FRAME_CTRL(ctx) \
183
+    CCI_REG8(0x0537 + VD55G1_CTX_OFFSET * (ctx))
183
+    CCI_REG8(0x0537 + VD55G1_CTX_OFFSET * (ctx))
184
+#define VD55G1_MASK_FRAME_CTRL_OUTPUT 0
184
+#define VD55G1_MASK_FRAME_CTRL_OUTPUT 0
185
+#define VD55G1_MASK_FRAME_CTRL_MASK 1
185
+#define VD55G1_MASK_FRAME_CTRL_MASK 1
186
+#define VD55G1_REG_EXPOSURE_INSTANCE(ctx) \
186
+#define VD55G1_REG_EXPOSURE_INSTANCE(ctx) \
187
+    CCI_REG32_LE(0x52D + VD55G1_CTX_OFFSET * (ctx))
187
+    CCI_REG32_LE(0x52D + VD55G1_CTX_OFFSET * (ctx))
188
+
188
+
189
+#define VD55G1_WIDTH                    804
189
+#define VD55G1_WIDTH                    804
190
+#define VD55G1_HEIGHT                    704
190
+#define VD55G1_HEIGHT                    704
191
+#define VD55G1_DEFAULT_MODE                0
191
+#define VD55G1_DEFAULT_MODE                0
192
+#define VD55G1_NB_GPIOS                    4
192
+#define VD55G1_NB_GPIOS                    4
193
+#define VD55G1_MEDIA_BUS_FMT_DEF            MEDIA_BUS_FMT_Y8_1X8
193
+#define VD55G1_MEDIA_BUS_FMT_DEF            MEDIA_BUS_FMT_Y8_1X8
194
+#define VD55G1_DGAIN_DEF                256
194
+#define VD55G1_DGAIN_DEF                256
195
+#define VD55G1_AGAIN_DEF                19
195
+#define VD55G1_AGAIN_DEF                19
196
+#define VD55G1_EXPO_MAX_TERM                64
196
+#define VD55G1_EXPO_MAX_TERM                64
197
+#define VD55G1_EXPO_DEF                    500
197
+#define VD55G1_EXPO_DEF                    500
198
+#define VD55G1_LINE_LENGTH_MIN                1128
198
+#define VD55G1_LINE_LENGTH_MIN                1128
199
+#define VD55G1_LINE_LENGTH_SUB_MIN            1344
199
+#define VD55G1_LINE_LENGTH_SUB_MIN            1344
200
+#define VD55G1_VBLANK_MIN                86
200
+#define VD55G1_VBLANK_MIN                86
201
+#define VD55G1_VBLANK_MAX                0xffff
201
+#define VD55G1_VBLANK_MAX                0xffff
202
+#define VD55G1_FRAME_LENGTH_DEF                1860 /* 60 fps */
202
+#define VD55G1_FRAME_LENGTH_DEF                1860 /* 60 fps */
203
+#define VD55G1_MIPI_MARGIN                900
203
+#define VD55G1_MIPI_MARGIN                900
204
+#define VD55G1_CTX_OFFSET                0x50
204
+#define VD55G1_CTX_OFFSET                0x50
205
+#define VD55G1_FWPATCH_REVISION_MAJOR            2
205
+#define VD55G1_FWPATCH_REVISION_MAJOR            2
206
+#define VD55G1_FWPATCH_REVISION_MINOR            9
206
+#define VD55G1_FWPATCH_REVISION_MINOR            9
207
+
207
+
208
+static const u8 patch_array[] = {
208
+static const u8 patch_array[] = {
209
+0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00, 0xf0,
209
+0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00, 0xf0,
210
+0x01, 0x42, 0x00, 0xe6, 0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210
+0x01, 0x42, 0x00, 0xe6, 0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00,
215
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00,
216
+0xfa, 0x68, 0x40, 0x00, 0xe8, 0x09, 0xbe, 0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd,
216
+0xfa, 0x68, 0x40, 0x00, 0xe8, 0x09, 0xbe, 0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd,
217
+0x1c, 0x00, 0xc0, 0xe2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa, 0x6b,
217
+0x1c, 0x00, 0xc0, 0xe2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa, 0x6b,
218
+0x80, 0x98, 0x7f, 0xfc, 0xef, 0x11, 0xc1, 0x0f, 0x82, 0x69, 0xbe, 0x0f, 0xac,
218
+0x80, 0x98, 0x7f, 0xfc, 0xef, 0x11, 0xc1, 0x0f, 0x82, 0x69, 0xbe, 0x0f, 0xac,
219
+0x58, 0x40, 0x00, 0xe8, 0x0c, 0x0c, 0x00, 0xf2, 0x93, 0xdd, 0x1c, 0x00, 0x40,
219
+0x58, 0x40, 0x00, 0xe8, 0x0c, 0x0c, 0x00, 0xf2, 0x93, 0xdd, 0x1c, 0x00, 0x40,
220
+0xe3, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x84, 0xfa, 0x46, 0x0e, 0xe8, 0xe0,
220
+0xe3, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x84, 0xfa, 0x46, 0x0e, 0xe8, 0xe0,
221
+0x08, 0xde, 0x4a, 0x40, 0x84, 0xe0, 0xa5, 0x86, 0xa8, 0x7d, 0xfc, 0xef, 0x6b,
221
+0x08, 0xde, 0x4a, 0x40, 0x84, 0xe0, 0xa5, 0x86, 0xa8, 0x7d, 0xfc, 0xef, 0x6b,
222
+0x80, 0x01, 0xbf, 0x28, 0x77, 0x0c, 0xef, 0x0b, 0x0e, 0x21, 0x78, 0x06, 0xc0,
222
+0x80, 0x01, 0xbf, 0x28, 0x77, 0x0c, 0xef, 0x0b, 0x0e, 0x21, 0x78, 0x06, 0xc0,
223
+0x0b, 0xa5, 0xb5, 0x84, 0x06, 0x42, 0x98, 0xe1, 0x01, 0x81, 0x01, 0x42, 0x38,
223
+0x0b, 0xa5, 0xb5, 0x84, 0x06, 0x42, 0x98, 0xe1, 0x01, 0x81, 0x01, 0x42, 0x38,
224
+0xe0, 0x0c, 0xc4, 0x0e, 0x84, 0x46, 0x02, 0x84, 0xe0, 0x0c, 0x84, 0x11, 0x81,
224
+0xe0, 0x0c, 0xc4, 0x0e, 0x84, 0x46, 0x02, 0x84, 0xe0, 0x0c, 0x84, 0x11, 0x81,
225
+0x21, 0x81, 0x31, 0x81, 0x41, 0x81, 0x51, 0x81, 0xc1, 0x81, 0x05, 0x83, 0x0c,
225
+0x21, 0x81, 0x31, 0x81, 0x41, 0x81, 0x51, 0x81, 0xc1, 0x81, 0x05, 0x83, 0x0c,
226
+0x0c, 0x84, 0xf2, 0x93, 0xdd, 0x06, 0x40, 0x98, 0xe1, 0xc8, 0x80, 0x58, 0x82,
226
+0x0c, 0x84, 0xf2, 0x93, 0xdd, 0x06, 0x40, 0x98, 0xe1, 0xc8, 0x80, 0x58, 0x82,
227
+0x48, 0xc0, 0x38, 0xc2, 0x29, 0x00, 0x10, 0xe0, 0x19, 0x00, 0x14, 0xe0, 0x09,
227
+0x48, 0xc0, 0x38, 0xc2, 0x29, 0x00, 0x10, 0xe0, 0x19, 0x00, 0x14, 0xe0, 0x09,
228
+0x00, 0x38, 0xe0, 0x5f, 0xb8, 0x5f, 0xa8, 0x5f, 0xa6, 0x5f, 0xa4, 0x5f, 0xa2,
228
+0x00, 0x38, 0xe0, 0x5f, 0xb8, 0x5f, 0xa8, 0x5f, 0xa6, 0x5f, 0xa4, 0x5f, 0xa2,
229
+0x5f, 0xa0, 0x56, 0x41, 0x98, 0xe1, 0x18, 0x82, 0x28, 0x80, 0x38, 0xc0, 0x5f,
229
+0x5f, 0xa0, 0x56, 0x41, 0x98, 0xe1, 0x18, 0x82, 0x28, 0x80, 0x38, 0xc0, 0x5f,
230
+0xa2, 0x19, 0x00, 0x20, 0xf8, 0x5f, 0xa4, 0x28, 0xc2, 0x5f, 0xa6, 0x39, 0x00,
230
+0xa2, 0x19, 0x00, 0x20, 0xf8, 0x5f, 0xa4, 0x28, 0xc2, 0x5f, 0xa6, 0x39, 0x00,
231
+0x10, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x14, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x18,
231
+0x10, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x14, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x18,
232
+0xe0, 0x5f, 0xa6, 0x39, 0x00, 0x40, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x44, 0xe0,
232
+0xe0, 0x5f, 0xa6, 0x39, 0x00, 0x40, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x44, 0xe0,
233
+0x5f, 0xa4, 0x29, 0x00, 0x1c, 0xe0, 0x5f, 0xa6, 0x39, 0x00, 0x38, 0xe0, 0x5f,
233
+0x5f, 0xa4, 0x29, 0x00, 0x1c, 0xe0, 0x5f, 0xa6, 0x39, 0x00, 0x38, 0xe0, 0x5f,
234
+0xa2, 0x19, 0x00, 0x20, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x24, 0xe0, 0x5f, 0xa6,
234
+0xa2, 0x19, 0x00, 0x20, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x24, 0xe0, 0x5f, 0xa6,
235
+0x39, 0x00, 0x28, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x2c, 0xe0, 0x5f, 0xa4, 0x29,
235
+0x39, 0x00, 0x28, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x2c, 0xe0, 0x5f, 0xa4, 0x29,
236
+0x00, 0x30, 0xe0, 0x5f, 0xa6, 0x09, 0x00, 0x34, 0xe0, 0x5f, 0xa2, 0x5f, 0xa4,
236
+0x00, 0x30, 0xe0, 0x5f, 0xa6, 0x09, 0x00, 0x34, 0xe0, 0x5f, 0xa2, 0x5f, 0xa4,
237
+0x5f, 0xa0, 0x4a, 0x0a, 0xfc, 0xfb, 0xe5, 0x82, 0x08, 0xde, 0x4a, 0x40, 0x88,
237
+0x5f, 0xa0, 0x4a, 0x0a, 0xfc, 0xfb, 0xe5, 0x82, 0x08, 0xde, 0x4a, 0x40, 0x88,
238
+0xe0, 0xf6, 0x40, 0x00, 0xe0, 0x01, 0x4e, 0x99, 0x78, 0x0a, 0xc0, 0x85, 0x80,
238
+0xe0, 0xf6, 0x40, 0x00, 0xe0, 0x01, 0x4e, 0x99, 0x78, 0x0a, 0xc0, 0x85, 0x80,
239
+0x98, 0x40, 0x00, 0xe8, 0x35, 0x81, 0xa8, 0x40, 0x00, 0xe8, 0x0b, 0x8c, 0x0c,
239
+0x98, 0x40, 0x00, 0xe8, 0x35, 0x81, 0xa8, 0x40, 0x00, 0xe8, 0x0b, 0x8c, 0x0c,
240
+0x0c, 0x84, 0xf2, 0xd5, 0xed, 0x83, 0xc1, 0x13, 0xc5, 0x93, 0xdd, 0xc3, 0xc1,
240
+0x0c, 0x84, 0xf2, 0xd5, 0xed, 0x83, 0xc1, 0x13, 0xc5, 0x93, 0xdd, 0xc3, 0xc1,
241
+0x83, 0xc1, 0x13, 0xc3, 0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0xc6,
241
+0x83, 0xc1, 0x13, 0xc3, 0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0xc6,
242
+0x0f, 0x94, 0xe0, 0x19, 0x0e, 0xc9, 0x65, 0x01, 0xc0, 0x28, 0xde, 0x0a, 0x42,
242
+0x0f, 0x94, 0xe0, 0x19, 0x0e, 0xc9, 0x65, 0x01, 0xc0, 0x28, 0xde, 0x0a, 0x42,
243
+0x80, 0xe0, 0x24, 0x02, 0x00, 0xfc, 0x16, 0xde, 0xa5, 0x8a, 0x19, 0x00, 0xb8,
243
+0x80, 0xe0, 0x24, 0x02, 0x00, 0xfc, 0x16, 0xde, 0xa5, 0x8a, 0x19, 0x00, 0xb8,
244
+0xe0, 0x10, 0x02, 0x0c, 0xec, 0x1d, 0xe6, 0x14, 0x02, 0x88, 0x80, 0x4e, 0x04,
244
+0xe0, 0x10, 0x02, 0x0c, 0xec, 0x1d, 0xe6, 0x14, 0x02, 0x88, 0x80, 0x4e, 0x04,
245
+0x01, 0x00, 0x10, 0x80, 0x25, 0x02, 0x08, 0x9c, 0x86, 0x02, 0x00, 0x80, 0x08,
245
+0x01, 0x00, 0x10, 0x80, 0x25, 0x02, 0x08, 0x9c, 0x86, 0x02, 0x00, 0x80, 0x08,
246
+0x44, 0x00, 0x98, 0x55, 0x81, 0x11, 0x85, 0x45, 0x81, 0x11, 0x89, 0x25, 0x81,
246
+0x44, 0x00, 0x98, 0x55, 0x81, 0x11, 0x85, 0x45, 0x81, 0x11, 0x89, 0x25, 0x81,
247
+0x11, 0x83, 0x2b, 0x00, 0x24, 0xe0, 0x64, 0xc2, 0x0b, 0x84, 0x08, 0x51, 0x00,
247
+0x11, 0x83, 0x2b, 0x00, 0x24, 0xe0, 0x64, 0xc2, 0x0b, 0x84, 0x08, 0x51, 0x00,
248
+0xef, 0x2b, 0x80, 0x01, 0x83, 0x1b, 0x8c, 0x38, 0x7d, 0x5c, 0xef, 0x18, 0xde,
248
+0xef, 0x2b, 0x80, 0x01, 0x83, 0x1b, 0x8c, 0x38, 0x7d, 0x5c, 0xef, 0x18, 0xde,
249
+0x0b, 0xa1, 0x25, 0x82, 0x0b, 0x0e, 0x88, 0xf9, 0x0a, 0x00, 0x00, 0xe8, 0x10,
249
+0x0b, 0xa1, 0x25, 0x82, 0x0b, 0x0e, 0x88, 0xf9, 0x0a, 0x00, 0x00, 0xe8, 0x10,
250
+0x42, 0x04, 0x9c, 0x11, 0x4e, 0x0c, 0x80, 0x10, 0x40, 0x04, 0xf0, 0x4e, 0x05,
250
+0x42, 0x04, 0x9c, 0x11, 0x4e, 0x0c, 0x80, 0x10, 0x40, 0x04, 0xf0, 0x4e, 0x05,
251
+0x01, 0x60, 0x10, 0xc0, 0x06, 0x88, 0x10, 0x40, 0xf8, 0xf3, 0x06, 0xde, 0x4c,
251
+0x01, 0x60, 0x10, 0xc0, 0x06, 0x88, 0x10, 0x40, 0xf8, 0xf3, 0x06, 0xde, 0x4c,
252
+0x0c, 0x04, 0xf2, 0x93, 0xdd, 0x0c, 0x04, 0x1c, 0xfe, 0xf6, 0x0f, 0x94, 0xe0,
252
+0x0c, 0x04, 0xf2, 0x93, 0xdd, 0x0c, 0x04, 0x1c, 0xfe, 0xf6, 0x0f, 0x94, 0xe0,
253
+0x38, 0x9c, 0x46, 0x51, 0xfc, 0xe0, 0x46, 0x49, 0x38, 0xe2, 0x30, 0x46, 0xf8,
253
+0x38, 0x9c, 0x46, 0x51, 0xfc, 0xe0, 0x46, 0x49, 0x38, 0xe2, 0x30, 0x46, 0xf8,
254
+0xf3, 0x36, 0x9c, 0xc6, 0x46, 0x0c, 0xe1, 0x34, 0x8c, 0x94, 0xa0, 0x4e, 0xa0,
254
+0xf3, 0x36, 0x9c, 0xc6, 0x46, 0x0c, 0xe1, 0x34, 0x8c, 0x94, 0xa0, 0x4e, 0xa0,
255
+0x39, 0x06, 0x80, 0xe0, 0x4a, 0x46, 0x94, 0xe0, 0x05, 0x8c, 0x6a, 0x40, 0x80,
255
+0x39, 0x06, 0x80, 0xe0, 0x4a, 0x46, 0x94, 0xe0, 0x05, 0x8c, 0x6a, 0x40, 0x80,
256
+0xe0, 0x2c, 0x0c, 0x00, 0xe2, 0x0b, 0x8c, 0xb8, 0x7c, 0x5c, 0xef, 0x0b, 0x8c,
256
+0xe0, 0x2c, 0x0c, 0x00, 0xe2, 0x0b, 0x8c, 0xb8, 0x7c, 0x5c, 0xef, 0x0b, 0x8c,
257
+0x9e, 0xa0, 0xf8, 0x40, 0x60, 0xef, 0x0b, 0xa1, 0x5a, 0x40, 0x80, 0xe0, 0x65,
257
+0x9e, 0xa0, 0xf8, 0x40, 0x60, 0xef, 0x0b, 0xa1, 0x5a, 0x40, 0x80, 0xe0, 0x65,
258
+0x88, 0x28, 0x02, 0x01, 0x40, 0x00, 0x80, 0x2a, 0x42, 0x9c, 0xe1, 0x28, 0x49,
258
+0x88, 0x28, 0x02, 0x01, 0x40, 0x00, 0x80, 0x2a, 0x42, 0x9c, 0xe1, 0x28, 0x49,
259
+0x60, 0xef, 0x96, 0x4d, 0x9c, 0xe1, 0x01, 0x81, 0x06, 0x98, 0xd5, 0x81, 0x09,
259
+0x60, 0xef, 0x96, 0x4d, 0x9c, 0xe1, 0x01, 0x81, 0x06, 0x98, 0xd5, 0x81, 0x09,
260
+0x0e, 0xa1, 0x64, 0x01, 0xc0, 0x4a, 0x40, 0x88, 0xe0, 0x85, 0x80, 0xb8, 0x77,
260
+0x0e, 0xa1, 0x64, 0x01, 0xc0, 0x4a, 0x40, 0x88, 0xe0, 0x85, 0x80, 0xb8, 0x77,
261
+0xfc, 0xef, 0x35, 0x81, 0xc8, 0x77, 0xfc, 0xef, 0x08, 0x98, 0x4a, 0x00, 0xfc,
261
+0xfc, 0xef, 0x35, 0x81, 0xc8, 0x77, 0xfc, 0xef, 0x08, 0x98, 0x4a, 0x00, 0xfc,
262
+0xfb, 0x55, 0xfc, 0xe8, 0x4a, 0x60, 0xef, 0x1a, 0x44, 0x9c, 0xe1, 0x35, 0x81,
262
+0xfb, 0x55, 0xfc, 0xe8, 0x4a, 0x60, 0xef, 0x1a, 0x44, 0x9c, 0xe1, 0x35, 0x81,
263
+0x1a, 0x4e, 0x9c, 0xe9, 0x1c, 0x00, 0x00, 0xe2, 0x0c, 0x0c, 0x1c, 0xf6, 0x93,
263
+0x1a, 0x4e, 0x9c, 0xe9, 0x1c, 0x00, 0x00, 0xe2, 0x0c, 0x0c, 0x1c, 0xf6, 0x93,
264
+0xdd, 0x0d, 0xc3, 0x1a, 0x41, 0x08, 0xe4, 0x0a, 0x40, 0x84, 0xe1, 0x0c, 0x00,
264
+0xdd, 0x0d, 0xc3, 0x1a, 0x41, 0x08, 0xe4, 0x0a, 0x40, 0x84, 0xe1, 0x0c, 0x00,
265
+0x00, 0xe2, 0x93, 0xdd, 0x4c, 0x04, 0x1c, 0xfa, 0x86, 0x52, 0xec, 0xe1, 0x08,
265
+0x00, 0xe2, 0x93, 0xdd, 0x4c, 0x04, 0x1c, 0xfa, 0x86, 0x52, 0xec, 0xe1, 0x08,
266
+0xa6, 0x65, 0x12, 0x24, 0xf8, 0x0e, 0x02, 0x99, 0x7a, 0x00, 0xc0, 0x00, 0x40,
266
+0xa6, 0x65, 0x12, 0x24, 0xf8, 0x0e, 0x02, 0x99, 0x7a, 0x00, 0xc0, 0x00, 0x40,
267
+0xa0, 0xf3, 0x06, 0xa6, 0x0b, 0x8c, 0x08, 0x49, 0x00, 0xef, 0x85, 0x12, 0x28,
267
+0xa0, 0xf3, 0x06, 0xa6, 0x0b, 0x8c, 0x08, 0x49, 0x00, 0xef, 0x85, 0x12, 0x28,
268
+0xf8, 0x02, 0x02, 0xfc, 0xed, 0xf6, 0x47, 0xfd, 0x6f, 0xe0, 0xff, 0x04, 0xe2,
268
+0xf8, 0x02, 0x02, 0xfc, 0xed, 0xf6, 0x47, 0xfd, 0x6f, 0xe0, 0xff, 0x04, 0xe2,
269
+0x14, 0x04, 0xc0, 0xe0, 0x0f, 0x86, 0x2f, 0xa0, 0x0b, 0x8c, 0x2e, 0xe2, 0x08,
269
+0x14, 0x04, 0xc0, 0xe0, 0x0f, 0x86, 0x2f, 0xa0, 0x0b, 0x8c, 0x2e, 0xe2, 0x08,
270
+0x48, 0x00, 0xef, 0x86, 0x02, 0x84, 0xfe, 0x0e, 0x05, 0x09, 0x7d, 0x00, 0xc0,
270
+0x48, 0x00, 0xef, 0x86, 0x02, 0x84, 0xfe, 0x0e, 0x05, 0x09, 0x7d, 0x00, 0xc0,
271
+0x05, 0x52, 0x08, 0xf8, 0x18, 0x7d, 0xfc, 0xef, 0x4a, 0x40, 0x80, 0xe0, 0x09,
271
+0x05, 0x52, 0x08, 0xf8, 0x18, 0x7d, 0xfc, 0xef, 0x4a, 0x40, 0x80, 0xe0, 0x09,
272
+0x12, 0x04, 0xc0, 0x65, 0x12, 0x20, 0xf8, 0x00, 0x40, 0x40, 0xdc, 0x01, 0x52,
272
+0x12, 0x04, 0xc0, 0x65, 0x12, 0x20, 0xf8, 0x00, 0x40, 0x40, 0xdc, 0x01, 0x52,
273
+0x04, 0xc0, 0x0e, 0x00, 0x41, 0x78, 0xf5, 0xc5, 0x6d, 0xc0, 0xb5, 0x82, 0x05,
273
+0x04, 0xc0, 0x0e, 0x00, 0x41, 0x78, 0xf5, 0xc5, 0x6d, 0xc0, 0xb5, 0x82, 0x05,
274
+0x10, 0x10, 0xe0, 0x11, 0xf1, 0x0f, 0x82, 0x05, 0x50, 0x10, 0xe0, 0x05, 0x10,
274
+0x10, 0x10, 0xe0, 0x11, 0xf1, 0x0f, 0x82, 0x05, 0x50, 0x10, 0xe0, 0x05, 0x10,
275
+0x10, 0xe0, 0xfe, 0x02, 0xf0, 0xff, 0x0f, 0x82, 0x85, 0x83, 0x15, 0x10, 0x10,
275
+0x10, 0xe0, 0xfe, 0x02, 0xf0, 0xff, 0x0f, 0x82, 0x85, 0x83, 0x15, 0x10, 0x10,
276
+0xe0, 0x16, 0x00, 0x91, 0x6e, 0x69, 0xcd, 0x21, 0xf1, 0x6d, 0xc1, 0x01, 0x83,
276
+0xe0, 0x16, 0x00, 0x91, 0x6e, 0x69, 0xcd, 0x21, 0xf1, 0x6d, 0xc1, 0x01, 0x83,
277
+0x2f, 0x82, 0x26, 0x00, 0x00, 0x80, 0x2f, 0xa0, 0x25, 0x50, 0x10, 0xe0, 0x05,
277
+0x2f, 0x82, 0x26, 0x00, 0x00, 0x80, 0x2f, 0xa0, 0x25, 0x50, 0x10, 0xe0, 0x05,
278
+0x10, 0x10, 0xe0, 0x11, 0xa1, 0xfe, 0x04, 0xf0, 0xff, 0x06, 0x42, 0x00, 0x80,
278
+0x10, 0x10, 0xe0, 0x11, 0xa1, 0xfe, 0x04, 0xf0, 0xff, 0x06, 0x42, 0x00, 0x80,
279
+0x0f, 0x84, 0x0f, 0xa2, 0x05, 0x50, 0x10, 0xe0, 0x16, 0x00, 0x91, 0x6e, 0x69,
279
+0x0f, 0x84, 0x0f, 0xa2, 0x05, 0x50, 0x10, 0xe0, 0x16, 0x00, 0x91, 0x6e, 0x69,
280
+0xcd, 0x6d, 0xc1, 0x71, 0x8d, 0x16, 0x00, 0x79, 0x61, 0x2d, 0xcb, 0x86, 0x0e,
280
+0xcd, 0x6d, 0xc1, 0x71, 0x8d, 0x16, 0x00, 0x79, 0x61, 0x2d, 0xcb, 0x86, 0x0e,
281
+0x00, 0x80, 0x6d, 0xc1, 0x56, 0x0e, 0x00, 0xc0, 0x0b, 0x8c, 0x1b, 0x8e, 0x71,
281
+0x00, 0x80, 0x6d, 0xc1, 0x56, 0x0e, 0x00, 0xc0, 0x0b, 0x8c, 0x1b, 0x8e, 0x71,
282
+0x52, 0x0c, 0xf8, 0x08, 0x43, 0x00, 0xef, 0x05, 0x52, 0x14, 0xf8, 0x15, 0x10,
282
+0x52, 0x0c, 0xf8, 0x08, 0x43, 0x00, 0xef, 0x05, 0x52, 0x14, 0xf8, 0x15, 0x10,
283
+0x28, 0xe0, 0x70, 0x04, 0x04, 0xec, 0x31, 0xe1, 0x29, 0x9e, 0x1f, 0x86, 0x1f,
283
+0x28, 0xe0, 0x70, 0x04, 0x04, 0xec, 0x31, 0xe1, 0x29, 0x9e, 0x1f, 0x86, 0x1f,
284
+0xa4, 0x15, 0x50, 0x28, 0xe0, 0x86, 0x42, 0x3c, 0xe0, 0x0e, 0x04, 0x9d, 0x64,
284
+0xa4, 0x15, 0x50, 0x28, 0xe0, 0x86, 0x42, 0x3c, 0xe0, 0x0e, 0x04, 0x9d, 0x64,
285
+0x9b, 0xc2, 0x05, 0x52, 0x1c, 0xf8, 0x78, 0xa6, 0x48, 0x77, 0xfc, 0xef, 0x4a,
285
+0x9b, 0xc2, 0x05, 0x52, 0x1c, 0xf8, 0x78, 0xa6, 0x48, 0x77, 0xfc, 0xef, 0x4a,
286
+0x40, 0x80, 0xe0, 0x70, 0x4e, 0x10, 0xdc, 0x1e, 0x00, 0x81, 0x70, 0xeb, 0xcb,
286
+0x40, 0x80, 0xe0, 0x70, 0x4e, 0x10, 0xdc, 0x1e, 0x00, 0x81, 0x70, 0xeb, 0xcb,
287
+0x70, 0x4e, 0xec, 0x93, 0x6d, 0xc1, 0x11, 0x85, 0x36, 0x02, 0x00, 0x80, 0x76,
287
+0x70, 0x4e, 0xec, 0x93, 0x6d, 0xc1, 0x11, 0x85, 0x36, 0x02, 0x00, 0x80, 0x76,
288
+0xa6, 0x11, 0x52, 0x10, 0xf8, 0x05, 0x10, 0x40, 0xe0, 0xfe, 0x47, 0x0c, 0xff,
288
+0xa6, 0x11, 0x52, 0x10, 0xf8, 0x05, 0x10, 0x40, 0xe0, 0xfe, 0x47, 0x0c, 0xff,
289
+0x14, 0x04, 0xa0, 0xe0, 0x0f, 0x86, 0x0f, 0xa4, 0x05, 0x50, 0x40, 0xe0, 0x05,
289
+0x14, 0x04, 0xa0, 0xe0, 0x0f, 0x86, 0x0f, 0xa4, 0x05, 0x50, 0x40, 0xe0, 0x05,
290
+0x10, 0x28, 0xe0, 0xfe, 0x47, 0xfd, 0x7f, 0xe3, 0xff, 0x14, 0x04, 0xd0, 0xe0,
290
+0x10, 0x28, 0xe0, 0xfe, 0x47, 0xfd, 0x7f, 0xe3, 0xff, 0x14, 0x04, 0xd0, 0xe0,
291
+0x0f, 0x86, 0x2f, 0xa0, 0x20, 0x00, 0x01, 0x6c, 0x00, 0xd0, 0x05, 0x50, 0x28,
291
+0x0f, 0x86, 0x2f, 0xa0, 0x20, 0x00, 0x01, 0x6c, 0x00, 0xd0, 0x05, 0x50, 0x28,
292
+0xe0, 0x0b, 0x8c, 0xf8, 0x7e, 0xfc, 0xee, 0x0e, 0x03, 0x59, 0x78, 0xf5, 0xc5,
292
+0xe0, 0x0b, 0x8c, 0xf8, 0x7e, 0xfc, 0xee, 0x0e, 0x03, 0x59, 0x78, 0xf5, 0xc5,
293
+0x0d, 0xc2, 0x05, 0x52, 0x0c, 0xf8, 0x08, 0xa6, 0x46, 0x42, 0xb4, 0xe0, 0x18,
293
+0x0d, 0xc2, 0x05, 0x52, 0x0c, 0xf8, 0x08, 0xa6, 0x46, 0x42, 0xb4, 0xe0, 0x18,
294
+0x84, 0x00, 0x40, 0xf4, 0x93, 0x00, 0x40, 0x08, 0xdc, 0x1b, 0xa1, 0x06, 0xa6,
294
+0x84, 0x00, 0x40, 0xf4, 0x93, 0x00, 0x40, 0x08, 0xdc, 0x1b, 0xa1, 0x06, 0xa6,
295
+0x05, 0x10, 0x40, 0x80, 0x04, 0x00, 0x50, 0x9c, 0x65, 0x8a, 0x05, 0x10, 0x44,
295
+0x05, 0x10, 0x40, 0x80, 0x04, 0x00, 0x50, 0x9c, 0x65, 0x8a, 0x05, 0x10, 0x44,
296
+0xe0, 0xf6, 0x43, 0xfd, 0x6f, 0x00, 0xf8, 0x0f, 0x82, 0x06, 0x02, 0x01, 0x60,
296
+0xe0, 0xf6, 0x43, 0xfd, 0x6f, 0x00, 0xf8, 0x0f, 0x82, 0x06, 0x02, 0x01, 0x60,
297
+0x1e, 0xc0, 0x0f, 0xa2, 0x05, 0x50, 0x44, 0xe0, 0x05, 0x10, 0x44, 0xe0, 0x0e,
297
+0x1e, 0xc0, 0x0f, 0xa2, 0x05, 0x50, 0x44, 0xe0, 0x05, 0x10, 0x44, 0xe0, 0x0e,
298
+0x02, 0x00, 0xf8, 0x0f, 0x82, 0x09, 0xf6, 0x05, 0x50, 0x44, 0xe0, 0x05, 0x10,
298
+0x02, 0x00, 0xf8, 0x0f, 0x82, 0x09, 0xf6, 0x05, 0x50, 0x44, 0xe0, 0x05, 0x10,
299
+0x40, 0xe0, 0x04, 0x00, 0x54, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40,
299
+0x40, 0xe0, 0x04, 0x00, 0x54, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40,
300
+0xe0, 0x04, 0x00, 0xcc, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0,
300
+0xe0, 0x04, 0x00, 0xcc, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0,
301
+0x04, 0x00, 0x4c, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04,
301
+0x04, 0x00, 0x4c, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04,
302
+0x00, 0xd0, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x4c, 0x0c, 0x1c, 0xf2, 0x93, 0xdd,
302
+0x00, 0xd0, 0xfc, 0x05, 0x50, 0x40, 0xe0, 0x4c, 0x0c, 0x1c, 0xf2, 0x93, 0xdd,
303
+0xc3, 0xc1, 0xc6, 0x40, 0xfc, 0xe0, 0x04, 0x80, 0xc6, 0x44, 0x0c, 0xe1, 0x15,
303
+0xc3, 0xc1, 0xc6, 0x40, 0xfc, 0xe0, 0x04, 0x80, 0xc6, 0x44, 0x0c, 0xe1, 0x15,
304
+0x04, 0x0c, 0xf8, 0x0a, 0x80, 0x06, 0x07, 0x04, 0xe0, 0x03, 0x42, 0x48, 0xe1,
304
+0x04, 0x0c, 0xf8, 0x0a, 0x80, 0x06, 0x07, 0x04, 0xe0, 0x03, 0x42, 0x48, 0xe1,
305
+0x46, 0x02, 0x40, 0xe2, 0x08, 0xc6, 0x44, 0x88, 0x06, 0x46, 0x0e, 0xe0, 0x86,
305
+0x46, 0x02, 0x40, 0xe2, 0x08, 0xc6, 0x44, 0x88, 0x06, 0x46, 0x0e, 0xe0, 0x86,
306
+0x01, 0x84, 0xe0, 0x33, 0x80, 0x39, 0x06, 0xd8, 0xef, 0x0a, 0x46, 0x80, 0xe0,
306
+0x01, 0x84, 0xe0, 0x33, 0x80, 0x39, 0x06, 0xd8, 0xef, 0x0a, 0x46, 0x80, 0xe0,
307
+0x31, 0xbf, 0x06, 0x06, 0x00, 0xc0, 0x31, 0x48, 0x60, 0xe0, 0x34, 0x88, 0x49,
307
+0x31, 0xbf, 0x06, 0x06, 0x00, 0xc0, 0x31, 0x48, 0x60, 0xe0, 0x34, 0x88, 0x49,
308
+0x06, 0x40, 0xe1, 0x40, 0x48, 0x7c, 0xf3, 0x41, 0x46, 0x40, 0xe1, 0x24, 0x8a,
308
+0x06, 0x40, 0xe1, 0x40, 0x48, 0x7c, 0xf3, 0x41, 0x46, 0x40, 0xe1, 0x24, 0x8a,
309
+0x39, 0x04, 0x10, 0xe0, 0x39, 0xc2, 0x31, 0x44, 0x10, 0xe0, 0x14, 0xc4, 0x1b,
309
+0x39, 0x04, 0x10, 0xe0, 0x39, 0xc2, 0x31, 0x44, 0x10, 0xe0, 0x14, 0xc4, 0x1b,
310
+0xa5, 0x11, 0x83, 0x11, 0x40, 0x25, 0x6a, 0x01, 0xc0, 0x08, 0x5c, 0x00, 0xda,
310
+0xa5, 0x11, 0x83, 0x11, 0x40, 0x25, 0x6a, 0x01, 0xc0, 0x08, 0x5c, 0x00, 0xda,
311
+0x15, 0x00, 0xcc, 0xe0, 0x25, 0x00, 0xf8, 0xe0, 0x1b, 0x85, 0x08, 0x5c, 0x00,
311
+0x15, 0x00, 0xcc, 0xe0, 0x25, 0x00, 0xf8, 0xe0, 0x1b, 0x85, 0x08, 0x5c, 0x00,
312
+0x9a, 0x4e, 0x03, 0x01, 0x60, 0x10, 0xc0, 0x29, 0x00, 0x1c, 0xe4, 0x18, 0x84,
312
+0x9a, 0x4e, 0x03, 0x01, 0x60, 0x10, 0xc0, 0x29, 0x00, 0x1c, 0xe4, 0x18, 0x84,
313
+0x20, 0x44, 0xf8, 0xf3, 0x2f, 0xa2, 0x21, 0x40, 0x1c, 0xe4, 0x93, 0xdd, 0x0c,
313
+0x20, 0x44, 0xf8, 0xf3, 0x2f, 0xa2, 0x21, 0x40, 0x1c, 0xe4, 0x93, 0xdd, 0x0c,
314
+0x00, 0x80, 0xfa, 0x15, 0x00, 0x3c, 0xe0, 0x21, 0x81, 0x31, 0x85, 0x21, 0x42,
314
+0x00, 0x80, 0xfa, 0x15, 0x00, 0x3c, 0xe0, 0x21, 0x81, 0x31, 0x85, 0x21, 0x42,
315
+0x60, 0xe0, 0x15, 0x00, 0x44, 0xe0, 0x31, 0x42, 0x40, 0xe1, 0x15, 0x00, 0x34,
315
+0x60, 0xe0, 0x15, 0x00, 0x44, 0xe0, 0x31, 0x42, 0x40, 0xe1, 0x15, 0x00, 0x34,
316
+0xe0, 0x21, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0xd6, 0x04, 0x10, 0xe0,
316
+0xe0, 0x21, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0xd6, 0x04, 0x10, 0xe0,
317
+0x23, 0x42, 0x30, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0x86, 0x44, 0x04, 0xe0, 0x23,
317
+0x23, 0x42, 0x30, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0x86, 0x44, 0x04, 0xe0, 0x23,
318
+0x42, 0x38, 0xe0, 0x05, 0x00, 0x30, 0xe0, 0xc6, 0x02, 0x08, 0xe0, 0x13, 0x40,
318
+0x42, 0x38, 0xe0, 0x05, 0x00, 0x30, 0xe0, 0xc6, 0x02, 0x08, 0xe0, 0x13, 0x40,
319
+0x10, 0xe3, 0xe8, 0x56, 0x40, 0xef, 0x06, 0x40, 0x0c, 0xe1, 0x04, 0x80, 0x06,
319
+0x10, 0xe3, 0xe8, 0x56, 0x40, 0xef, 0x06, 0x40, 0x0c, 0xe1, 0x04, 0x80, 0x06,
320
+0x02, 0x94, 0xe0, 0x2b, 0x02, 0xc4, 0xea, 0x3b, 0x00, 0x78, 0xe2, 0x20, 0x44,
320
+0x02, 0x94, 0xe0, 0x2b, 0x02, 0xc4, 0xea, 0x3b, 0x00, 0x78, 0xe2, 0x20, 0x44,
321
+0xfd, 0x73, 0x07, 0xc0, 0x30, 0x46, 0x01, 0x70, 0xf8, 0xc0, 0x3f, 0xa4, 0x33,
321
+0xfd, 0x73, 0x07, 0xc0, 0x30, 0x46, 0x01, 0x70, 0xf8, 0xc0, 0x3f, 0xa4, 0x33,
322
+0x40, 0x78, 0xe2, 0x0a, 0x84, 0x0c, 0x08, 0x80, 0xf2, 0xf8, 0x3b, 0x3c, 0xff,
322
+0x40, 0x78, 0xe2, 0x0a, 0x84, 0x0c, 0x08, 0x80, 0xf2, 0xf8, 0x3b, 0x3c, 0xff,
323
+0xc3, 0xc1, 0x06, 0x40, 0x0c, 0xe1, 0x04, 0x80, 0x1b, 0x00, 0x40, 0xe4, 0x19,
323
+0xc3, 0xc1, 0x06, 0x40, 0x0c, 0xe1, 0x04, 0x80, 0x1b, 0x00, 0x40, 0xe4, 0x19,
324
+0xc2, 0x13, 0x40, 0x40, 0xe4, 0x1b, 0x00, 0x40, 0xe4, 0x19, 0xc4, 0x13, 0x40,
324
+0xc2, 0x13, 0x40, 0x40, 0xe4, 0x1b, 0x00, 0x40, 0xe4, 0x19, 0xc4, 0x13, 0x40,
325
+0x40, 0xe4, 0x93, 0xdd, 0xc6, 0x43, 0xec, 0xe0, 0x46, 0x41, 0xfc, 0xe0, 0x24,
325
+0x40, 0xe4, 0x93, 0xdd, 0xc6, 0x43, 0xec, 0xe0, 0x46, 0x41, 0xfc, 0xe0, 0x24,
326
+0x84, 0x04, 0x80, 0x31, 0x81, 0x4a, 0x44, 0x80, 0xe0, 0x86, 0x44, 0x0c, 0xe1,
326
+0x84, 0x04, 0x80, 0x31, 0x81, 0x4a, 0x44, 0x80, 0xe0, 0x86, 0x44, 0x0c, 0xe1,
327
+0x09, 0x00, 0x6c, 0xe0, 0xc4, 0x8a, 0x8e, 0x47, 0xfc, 0x9f, 0x01, 0x42, 0x51,
327
+0x09, 0x00, 0x6c, 0xe0, 0xc4, 0x8a, 0x8e, 0x47, 0xfc, 0x9f, 0x01, 0x42, 0x51,
328
+0x78, 0x0c, 0xc0, 0x31, 0x58, 0x90, 0xe0, 0x34, 0x8a, 0x41, 0xbf, 0x06, 0x08,
328
+0x78, 0x0c, 0xc0, 0x31, 0x58, 0x90, 0xe0, 0x34, 0x8a, 0x41, 0xbf, 0x06, 0x08,
329
+0x00, 0xc0, 0x41, 0x46, 0xa0, 0xe0, 0x34, 0x8a, 0x51, 0x81, 0xf6, 0x0b, 0x00,
329
+0x00, 0xc0, 0x41, 0x46, 0xa0, 0xe0, 0x34, 0x8a, 0x51, 0x81, 0xf6, 0x0b, 0x00,
330
+0xc0, 0x51, 0x46, 0xd0, 0xe0, 0x34, 0x8a, 0x01, 0xbf, 0x51, 0x46, 0xe0, 0xe0,
330
+0xc0, 0x51, 0x46, 0xd0, 0xe0, 0x34, 0x8a, 0x01, 0xbf, 0x51, 0x46, 0xe0, 0xe0,
331
+0x44, 0x84, 0x0a, 0x48, 0x84, 0xe0, 0x75, 0x86, 0x54, 0xca, 0x49, 0x88, 0x44,
331
+0x44, 0x84, 0x0a, 0x48, 0x84, 0xe0, 0x75, 0x86, 0x54, 0xca, 0x49, 0x88, 0x44,
332
+0x06, 0x88, 0xe1, 0x36, 0x94, 0x4a, 0x46, 0x80, 0xe0, 0x34, 0xca, 0x47, 0xc6,
332
+0x06, 0x88, 0xe1, 0x36, 0x94, 0x4a, 0x46, 0x80, 0xe0, 0x34, 0xca, 0x47, 0xc6,
333
+0x11, 0x8d, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88, 0x76, 0x02, 0x00, 0xc0, 0x06,
333
+0x11, 0x8d, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88, 0x76, 0x02, 0x00, 0xc0, 0x06,
334
+0x00, 0x00, 0xc0, 0x16, 0x8c, 0x14, 0x88, 0x01, 0x42, 0xc0, 0xe1, 0x01, 0x42,
334
+0x00, 0x00, 0xc0, 0x16, 0x8c, 0x14, 0x88, 0x01, 0x42, 0xc0, 0xe1, 0x01, 0x42,
335
+0xe0, 0xe1, 0x01, 0x42, 0xf0, 0xe1, 0x93, 0xdd, 0x34, 0xca, 0x41, 0x85, 0x46,
335
+0xe0, 0xe1, 0x01, 0x42, 0xf0, 0xe1, 0x93, 0xdd, 0x34, 0xca, 0x41, 0x85, 0x46,
336
+0x8c, 0x34, 0xca, 0x06, 0x48, 0x00, 0xe0, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88,
336
+0x8c, 0x34, 0xca, 0x06, 0x48, 0x00, 0xe0, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88,
337
+0x41, 0x83, 0x46, 0x8c, 0x34, 0x88, 0x01, 0x46, 0xc0, 0xe1, 0x01, 0x46, 0xe0,
337
+0x41, 0x83, 0x46, 0x8c, 0x34, 0x88, 0x01, 0x46, 0xc0, 0xe1, 0x01, 0x46, 0xe0,
338
+0xe1, 0x01, 0x46, 0xf0, 0xe1, 0x09, 0x02, 0x20, 0xe0, 0x14, 0xca, 0x03, 0x42,
338
+0xe1, 0x01, 0x46, 0xf0, 0xe1, 0x09, 0x02, 0x20, 0xe0, 0x14, 0xca, 0x03, 0x42,
339
+0x58, 0xe0, 0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0x46, 0x4e, 0x08,
339
+0x58, 0xe0, 0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0x46, 0x4e, 0x08,
340
+0xe1, 0x06, 0x4c, 0x0c, 0xe1, 0x0a, 0x9e, 0x14, 0x98, 0x05, 0x42, 0x44, 0xe0,
340
+0xe1, 0x06, 0x4c, 0x0c, 0xe1, 0x0a, 0x9e, 0x14, 0x98, 0x05, 0x42, 0x44, 0xe0,
341
+0x10, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0x78, 0x41, 0x00, 0xe8, 0x08, 0x9c, 0x0b,
341
+0x10, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0x78, 0x41, 0x00, 0xe8, 0x08, 0x9c, 0x0b,
342
+0xa1, 0x04, 0x98, 0x06, 0x02, 0x10, 0x80, 0x13, 0x40, 0xf8, 0x86, 0x65, 0x82,
342
+0xa1, 0x04, 0x98, 0x06, 0x02, 0x10, 0x80, 0x13, 0x40, 0xf8, 0x86, 0x65, 0x82,
343
+0x00, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0xa8, 0x40, 0x00, 0xe8, 0x14, 0x98, 0x04,
343
+0x00, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0xa8, 0x40, 0x00, 0xe8, 0x14, 0x98, 0x04,
344
+0x00, 0xa0, 0xfc, 0x03, 0x42, 0x00, 0xe7, 0x4c, 0x0c, 0x04, 0xf2, 0x93, 0xdd,
344
+0x00, 0xa0, 0xfc, 0x03, 0x42, 0x00, 0xe7, 0x4c, 0x0c, 0x04, 0xf2, 0x93, 0xdd,
345
+0x0a, 0x80, 0x93, 0xdd, 0x0c, 0x04, 0x00, 0xfa, 0x06, 0x02, 0xec, 0xe1, 0x64,
345
+0x0a, 0x80, 0x93, 0xdd, 0x0c, 0x04, 0x00, 0xfa, 0x06, 0x02, 0xec, 0xe1, 0x64,
346
+0x84, 0x15, 0x0c, 0x2c, 0xe0, 0x14, 0x02, 0xa0, 0xfc, 0x15, 0x4c, 0x2c, 0xe0,
346
+0x84, 0x15, 0x0c, 0x2c, 0xe0, 0x14, 0x02, 0xa0, 0xfc, 0x15, 0x4c, 0x2c, 0xe0,
347
+0xd8, 0x40, 0x00, 0xe8, 0x14, 0xd8, 0x09, 0x82, 0x14, 0x02, 0x00, 0xfc, 0x1f,
347
+0xd8, 0x40, 0x00, 0xe8, 0x14, 0xd8, 0x09, 0x82, 0x14, 0x02, 0x00, 0xfc, 0x1f,
348
+0xa0, 0x1e, 0xd8, 0x01, 0x85, 0x0c, 0x0c, 0x00, 0xf2, 0xe8, 0x32, 0x2c, 0xff,
348
+0xa0, 0x1e, 0xd8, 0x01, 0x85, 0x0c, 0x0c, 0x00, 0xf2, 0xe8, 0x32, 0x2c, 0xff,
349
+0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa, 0x6b, 0x80, 0xf6, 0x01, 0x94,
349
+0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa, 0x6b, 0x80, 0xf6, 0x01, 0x94,
350
+0xe0, 0x08, 0x80, 0x4a, 0x40, 0x80, 0xe0, 0x45, 0x86, 0x06, 0x40, 0x0c, 0xe1,
350
+0xe0, 0x08, 0x80, 0x4a, 0x40, 0x80, 0xe0, 0x45, 0x86, 0x06, 0x40, 0x0c, 0xe1,
351
+0x04, 0x80, 0xc6, 0x02, 0x40, 0xe2, 0x09, 0x00, 0xd0, 0xe0, 0x14, 0x84, 0x1b,
351
+0x04, 0x80, 0xc6, 0x02, 0x40, 0xe2, 0x09, 0x00, 0xd0, 0xe0, 0x14, 0x84, 0x1b,
352
+0xa5, 0x15, 0x84, 0x07, 0xc5, 0x09, 0x82, 0x18, 0x41, 0x00, 0xe8, 0x46, 0x43,
352
+0xa5, 0x15, 0x84, 0x07, 0xc5, 0x09, 0x82, 0x18, 0x41, 0x00, 0xe8, 0x46, 0x43,
353
+0xfc, 0xe0, 0x14, 0x84, 0x19, 0x02, 0xd8, 0xe0, 0x19, 0x82, 0x0b, 0x83, 0x16,
353
+0xfc, 0xe0, 0x14, 0x84, 0x19, 0x02, 0xd8, 0xe0, 0x19, 0x82, 0x0b, 0x83, 0x16,
354
+0x00, 0x00, 0xc0, 0x01, 0x4c, 0x00, 0xc0, 0x0c, 0x0c, 0x00, 0xf2, 0x93, 0xdd,
354
+0x00, 0x00, 0xc0, 0x01, 0x4c, 0x00, 0xc0, 0x0c, 0x0c, 0x00, 0xf2, 0x93, 0xdd,
355
+0xc3, 0xc1, 0x4a, 0x00, 0x00, 0xe0, 0x0c, 0x00, 0x00, 0xe2, 0x93, 0xdd, 0xc3,
355
+0xc3, 0xc1, 0x4a, 0x00, 0x00, 0xe0, 0x0c, 0x00, 0x00, 0xe2, 0x93, 0xdd, 0xc3,
356
+0xc1, 0x46, 0x40, 0x84, 0xe0, 0x11, 0xaf, 0x13, 0x40, 0x6c, 0xec, 0x11, 0xb3,
356
+0xc1, 0x46, 0x40, 0x84, 0xe0, 0x11, 0xaf, 0x13, 0x40, 0x6c, 0xec, 0x11, 0xb3,
357
+0x13, 0x40, 0x70, 0xec, 0xc6, 0x43, 0xf0, 0xe0, 0x13, 0x40, 0xdc, 0xec, 0xc6,
357
+0x13, 0x40, 0x70, 0xec, 0xc6, 0x43, 0xf0, 0xe0, 0x13, 0x40, 0xdc, 0xec, 0xc6,
358
+0x02, 0x24, 0xe0, 0x1c, 0x80, 0x93, 0xdd, 0x4c, 0x00, 0x00, 0xfa, 0xc8, 0x60,
358
+0x02, 0x24, 0xe0, 0x1c, 0x80, 0x93, 0xdd, 0x4c, 0x00, 0x00, 0xfa, 0xc8, 0x60,
359
+0x7c, 0xef, 0xe8, 0x61, 0x7c, 0xef, 0x28, 0x7e, 0x80, 0xef, 0xc6, 0x40, 0x98,
359
+0x7c, 0xef, 0xe8, 0x61, 0x7c, 0xef, 0x28, 0x7e, 0x80, 0xef, 0xc6, 0x40, 0x98,
360
+0xe1, 0x11, 0x83, 0x16, 0x80, 0x46, 0x01, 0x10, 0xe1, 0x11, 0x81, 0x16, 0x80,
360
+0xe1, 0x11, 0x83, 0x16, 0x80, 0x46, 0x01, 0x10, 0xe1, 0x11, 0x81, 0x16, 0x80,
361
+0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x0c, 0xfa, 0x6b,
361
+0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x0c, 0xfa, 0x6b,
362
+0x80, 0x04, 0x98, 0x7b, 0x82, 0x56, 0x42, 0xb4, 0xe0, 0x88, 0x84, 0x05, 0x00,
362
+0x80, 0x04, 0x98, 0x7b, 0x82, 0x56, 0x42, 0xb4, 0xe0, 0x88, 0x84, 0x05, 0x00,
363
+0x10, 0xe0, 0x09, 0x86, 0x0b, 0xa5, 0x46, 0x02, 0x00, 0x80, 0x06, 0x05, 0x00,
363
+0x10, 0xe0, 0x09, 0x86, 0x0b, 0xa5, 0x46, 0x02, 0x00, 0x80, 0x06, 0x05, 0x00,
364
+0x80, 0x25, 0x82, 0x0b, 0xa3, 0xa5, 0x80, 0x0b, 0xa1, 0x06, 0x00, 0xf4, 0xef,
364
+0x80, 0x25, 0x82, 0x0b, 0xa3, 0xa5, 0x80, 0x0b, 0xa1, 0x06, 0x00, 0xf4, 0xef,
365
+0xd5, 0x84, 0x11, 0x85, 0x21, 0x91, 0x0b, 0x8e, 0x88, 0x74, 0x10, 0xef, 0x0b,
365
+0xd5, 0x84, 0x11, 0x85, 0x21, 0x91, 0x0b, 0x8e, 0x88, 0x74, 0x10, 0xef, 0x0b,
366
+0xa1, 0xf5, 0x82, 0x0a, 0x9e, 0x1a, 0x9c, 0x24, 0x98, 0x07, 0xe0, 0x0f, 0xa2,
366
+0xa1, 0xf5, 0x82, 0x0a, 0x9e, 0x1a, 0x9c, 0x24, 0x98, 0x07, 0xe0, 0x0f, 0xa2,
367
+0x0e, 0xca, 0x0a, 0xde, 0x1a, 0xdc, 0x24, 0x98, 0x03, 0xb0, 0x07, 0xe0, 0x0f,
367
+0x0e, 0xca, 0x0a, 0xde, 0x1a, 0xdc, 0x24, 0x98, 0x03, 0xb0, 0x07, 0xe0, 0x0f,
368
+0xa2, 0x0e, 0xc8, 0x01, 0x81, 0x0c, 0x0c, 0x0c, 0xf2, 0x93, 0xdd, 0xc3, 0xc1,
368
+0xa2, 0x0e, 0xc8, 0x01, 0x81, 0x0c, 0x0c, 0x0c, 0xf2, 0x93, 0xdd, 0xc3, 0xc1,
369
+0x0c, 0x04, 0x7c, 0xfa, 0x46, 0x42, 0x9c, 0xe0, 0x0b, 0x02, 0x04, 0xe3, 0xf0,
369
+0x0c, 0x04, 0x7c, 0xfa, 0x46, 0x42, 0x9c, 0xe0, 0x0b, 0x02, 0x04, 0xe3, 0xf0,
370
+0x1e, 0x30, 0xec, 0x0b, 0xa3, 0x35, 0x96, 0x8e, 0x01, 0x01, 0x60, 0x10, 0xc0,
370
+0x1e, 0x30, 0xec, 0x0b, 0xa3, 0x35, 0x96, 0x8e, 0x01, 0x01, 0x60, 0x10, 0xc0,
371
+0x0e, 0xfc, 0xc6, 0x05, 0xd0, 0xe1, 0x0b, 0x82, 0x31, 0x81, 0x10, 0x16, 0x00,
371
+0x0e, 0xfc, 0xc6, 0x05, 0xd0, 0xe1, 0x0b, 0x82, 0x31, 0x81, 0x10, 0x16, 0x00,
372
+0xe5, 0x20, 0x10, 0x20, 0xe7, 0x0e, 0xbe, 0xb5, 0x85, 0x94, 0xfc, 0xa4, 0xbe,
372
+0xe5, 0x20, 0x10, 0x20, 0xe7, 0x0e, 0xbe, 0xb5, 0x85, 0x94, 0xfc, 0xa4, 0xbe,
373
+0x82, 0x4c, 0x9c, 0xf0, 0x05, 0x0c, 0x40, 0xe0, 0x11, 0x89, 0x93, 0x8e, 0xa3,
373
+0x82, 0x4c, 0x9c, 0xf0, 0x05, 0x0c, 0x40, 0xe0, 0x11, 0x89, 0x93, 0x8e, 0xa3,
374
+0x8e, 0x58, 0x44, 0x00, 0xe8, 0x15, 0x0c, 0xc0, 0xf8, 0x04, 0x0c, 0x80, 0xfb,
374
+0x8e, 0x58, 0x44, 0x00, 0xe8, 0x15, 0x0c, 0xc0, 0xf8, 0x04, 0x0c, 0x80, 0xfb,
375
+0x0c, 0xed, 0x0b, 0x82, 0x1b, 0x8c, 0x48, 0x44, 0x00, 0xe8, 0x15, 0x10, 0x1c,
375
+0x0c, 0xed, 0x0b, 0x82, 0x1b, 0x8c, 0x48, 0x44, 0x00, 0xe8, 0x15, 0x10, 0x1c,
376
+0xfc, 0x0e, 0xa8, 0x0b, 0x82, 0x1b, 0x8c, 0xd8, 0x43, 0x00, 0xe8, 0x71, 0x88,
376
+0xfc, 0x0e, 0xa8, 0x0b, 0x82, 0x1b, 0x8c, 0xd8, 0x43, 0x00, 0xe8, 0x71, 0x88,
377
+0x0e, 0xa4, 0x0a, 0x0e, 0x40, 0xe0, 0x35, 0xf8, 0x04, 0xbe, 0x14, 0xbc, 0x81,
377
+0x0e, 0xa4, 0x0a, 0x0e, 0x40, 0xe0, 0x35, 0xf8, 0x04, 0xbe, 0x14, 0xbc, 0x81,
378
+0xa0, 0x03, 0x8e, 0x0e, 0xbe, 0x04, 0xfc, 0x11, 0x82, 0x3b, 0x82, 0x03, 0x8e,
378
+0xa0, 0x03, 0x8e, 0x0e, 0xbe, 0x04, 0xfc, 0x11, 0x82, 0x3b, 0x82, 0x03, 0x8e,
379
+0x0e, 0xfc, 0x3b, 0xa9, 0x06, 0x0e, 0x00, 0xc0, 0x35, 0x5e, 0x00, 0xc0, 0xd5,
379
+0x0e, 0xfc, 0x3b, 0xa9, 0x06, 0x0e, 0x00, 0xc0, 0x35, 0x5e, 0x00, 0xc0, 0xd5,
380
+0xfa, 0xc6, 0x01, 0xd0, 0xe1, 0x7b, 0x80, 0x04, 0x9e, 0x11, 0x91, 0x98, 0x41,
380
+0xfa, 0xc6, 0x01, 0xd0, 0xe1, 0x7b, 0x80, 0x04, 0x9e, 0x11, 0x91, 0x98, 0x41,
381
+0x00, 0xe8, 0x24, 0x9c, 0x46, 0x42, 0x9c, 0xe0, 0x6b, 0x82, 0x03, 0x4c, 0xc4,
381
+0x00, 0xe8, 0x24, 0x9c, 0x46, 0x42, 0x9c, 0xe0, 0x6b, 0x82, 0x03, 0x4c, 0xc4,
382
+0xe0, 0x11, 0x91, 0x0b, 0x84, 0xf8, 0x40, 0x00, 0xe8, 0x19, 0x0e, 0x20, 0xe5,
382
+0xe0, 0x11, 0x91, 0x0b, 0x84, 0xf8, 0x40, 0x00, 0xe8, 0x19, 0x0e, 0x20, 0xe5,
383
+0x03, 0x4c, 0xc0, 0xe0, 0x0b, 0x82, 0x08, 0x72, 0xfc, 0xef, 0x01, 0x4c, 0x24,
383
+0x03, 0x4c, 0xc0, 0xe0, 0x0b, 0x82, 0x08, 0x72, 0xfc, 0xef, 0x01, 0x4c, 0x24,
384
+0xf9, 0xf1, 0x98, 0x0c, 0x0c, 0x7c, 0xf2, 0x93, 0xdd, 0x4c, 0x00, 0x00, 0xfa,
384
+0xf9, 0xf1, 0x98, 0x0c, 0x0c, 0x7c, 0xf2, 0x93, 0xdd, 0x4c, 0x00, 0x00, 0xfa,
385
+0x48, 0x65, 0x2c, 0xef, 0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c,
385
+0x48, 0x65, 0x2c, 0xef, 0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c,
386
+0x04, 0x00, 0xfa, 0x6b, 0x82, 0x78, 0x6e, 0xfc, 0xee, 0x46, 0x42, 0xec, 0xe0,
386
+0x04, 0x00, 0xfa, 0x6b, 0x82, 0x78, 0x6e, 0xfc, 0xee, 0x46, 0x42, 0xec, 0xe0,
387
+0x24, 0x84, 0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x83, 0xf5, 0x82, 0x24,
387
+0x24, 0x84, 0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x83, 0xf5, 0x82, 0x24,
388
+0x02, 0xa0, 0xe1, 0x14, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x85, 0x15, 0x82,
388
+0x02, 0xa0, 0xe1, 0x14, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x85, 0x15, 0x82,
389
+0x27, 0xe1, 0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x89, 0x86, 0x02, 0x00,
389
+0x27, 0xe1, 0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x89, 0x86, 0x02, 0x00,
390
+0x80, 0x0c, 0x0c, 0x00, 0xf2, 0x18, 0x17, 0xfc, 0xfe, 0xc3, 0xc1, 0x0c, 0x04,
390
+0x80, 0x0c, 0x0c, 0x00, 0xf2, 0x18, 0x17, 0xfc, 0xfe, 0xc3, 0xc1, 0x0c, 0x04,
391
+0x00, 0xfa, 0x06, 0x41, 0x8c, 0xe0, 0x1b, 0x00, 0xec, 0xe4, 0x1b, 0xa3, 0x75,
391
+0x00, 0xfa, 0x06, 0x41, 0x8c, 0xe0, 0x1b, 0x00, 0xec, 0xe4, 0x1b, 0xa3, 0x75,
392
+0x84, 0x11, 0x81, 0x8e, 0x05, 0x01, 0x60, 0x10, 0xc0, 0x00, 0x06, 0xc0, 0xe5,
392
+0x84, 0x11, 0x81, 0x8e, 0x05, 0x01, 0x60, 0x10, 0xc0, 0x00, 0x06, 0xc0, 0xe5,
393
+0x95, 0x81, 0x44, 0x88, 0x1d, 0xee, 0x75, 0x80, 0x4e, 0xc1, 0x25, 0x81, 0x4e,
393
+0x95, 0x81, 0x44, 0x88, 0x1d, 0xee, 0x75, 0x80, 0x4e, 0xc1, 0x25, 0x81, 0x4e,
394
+0xcd, 0x21, 0x88, 0x11, 0x82, 0x0a, 0x02, 0x40, 0xe0, 0xd5, 0xfc, 0x56, 0x00,
394
+0xcd, 0x21, 0x88, 0x11, 0x82, 0x0a, 0x02, 0x40, 0xe0, 0xd5, 0xfc, 0x56, 0x00,
395
+0x00, 0xe1, 0x18, 0x80, 0x1b, 0xa1, 0xc5, 0x84, 0x08, 0x82, 0x4a, 0x00, 0xfc,
395
+0x00, 0xe1, 0x18, 0x80, 0x1b, 0xa1, 0xc5, 0x84, 0x08, 0x82, 0x4a, 0x00, 0xfc,
396
+0xfb, 0x45, 0x84, 0x86, 0x4d, 0x84, 0xe1, 0x04, 0x98, 0x05, 0x00, 0x10, 0xe0,
396
+0xfb, 0x45, 0x84, 0x86, 0x4d, 0x84, 0xe1, 0x04, 0x98, 0x05, 0x00, 0x10, 0xe0,
397
+0x4a, 0x40, 0x80, 0xe0, 0x45, 0x82, 0x11, 0x81, 0x0b, 0x8c, 0x58, 0x76, 0x28,
397
+0x4a, 0x40, 0x80, 0xe0, 0x45, 0x82, 0x11, 0x81, 0x0b, 0x8c, 0x58, 0x76, 0x28,
398
+0xef, 0x0b, 0x8c, 0x0c, 0x0c, 0x00, 0xf2, 0x88, 0x35, 0x28, 0xff, 0x0c, 0x0c,
398
+0xef, 0x0b, 0x8c, 0x0c, 0x0c, 0x00, 0xf2, 0x88, 0x35, 0x28, 0xff, 0x0c, 0x0c,
399
+0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x46, 0x41, 0xfc, 0xe0, 0x04, 0x80, 0x09,
399
+0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x46, 0x41, 0xfc, 0xe0, 0x04, 0x80, 0x09,
400
+0x00, 0x80, 0xe0, 0x09, 0x9e, 0x0b, 0xa3, 0x75, 0x82, 0x46, 0x41, 0x80, 0xe1,
400
+0x00, 0x80, 0xe0, 0x09, 0x9e, 0x0b, 0xa3, 0x75, 0x82, 0x46, 0x41, 0x80, 0xe1,
401
+0x04, 0x80, 0xc6, 0x42, 0x8c, 0xe0, 0x04, 0xc2, 0x00, 0x40, 0x00, 0xf2, 0x07,
401
+0x04, 0x80, 0xc6, 0x42, 0x8c, 0xe0, 0x04, 0xc2, 0x00, 0x40, 0x00, 0xf2, 0x07,
402
+0xcf, 0x06, 0x84, 0x06, 0x40, 0x84, 0xe0, 0x15, 0x00, 0x28, 0xe5, 0x1c, 0xc2,
402
+0xcf, 0x06, 0x84, 0x06, 0x40, 0x84, 0xe0, 0x15, 0x00, 0x28, 0xe5, 0x1c, 0xc2,
403
+0x93, 0xdd, 0x0b, 0xa1, 0xc6, 0x00, 0xa0, 0xe1, 0x15, 0x00, 0x04, 0xf8, 0x05,
403
+0x93, 0xdd, 0x0b, 0xa1, 0xc6, 0x00, 0xa0, 0xe1, 0x15, 0x00, 0x04, 0xf8, 0x05,
404
+0x84, 0x21, 0x8b, 0x2c, 0x84, 0x14, 0x80, 0x2c, 0x84, 0x14, 0x82, 0x2c, 0x84,
404
+0x84, 0x21, 0x8b, 0x2c, 0x84, 0x14, 0x80, 0x2c, 0x84, 0x14, 0x82, 0x2c, 0x84,
405
+0x15, 0x00, 0x10, 0xe0, 0x21, 0xa1, 0x21, 0x42, 0x10, 0xe0, 0x05, 0x00, 0x14,
405
+0x15, 0x00, 0x10, 0xe0, 0x21, 0xa1, 0x21, 0x42, 0x10, 0xe0, 0x05, 0x00, 0x14,
406
+0xe0, 0x01, 0x88, 0x75, 0x83, 0x21, 0x85, 0x2c, 0x84, 0x14, 0x80, 0x06, 0x46,
406
+0xe0, 0x01, 0x88, 0x75, 0x83, 0x21, 0x85, 0x2c, 0x84, 0x14, 0x80, 0x06, 0x46,
407
+0x00, 0xe0, 0x2c, 0x84, 0x14, 0x82, 0x2c, 0x84, 0x14, 0xc0, 0x21, 0xa1, 0x21,
407
+0x00, 0xe0, 0x2c, 0x84, 0x14, 0x82, 0x2c, 0x84, 0x14, 0xc0, 0x21, 0xa1, 0x21,
408
+0x42, 0x20, 0xe0, 0x14, 0xc2, 0x31, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x10, 0xe0,
408
+0x42, 0x20, 0xe0, 0x14, 0xc2, 0x31, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x10, 0xe0,
409
+0x21, 0x42, 0x20, 0xe0, 0x05, 0x00, 0x14, 0xe0, 0x01, 0x90, 0x06, 0x42, 0x00,
409
+0x21, 0x42, 0x20, 0xe0, 0x05, 0x00, 0x14, 0xe0, 0x01, 0x90, 0x06, 0x42, 0x00,
410
+0xe0, 0x16, 0x80, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x7c, 0xfa, 0x4a, 0x40,
410
+0xe0, 0x16, 0x80, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x7c, 0xfa, 0x4a, 0x40,
411
+0x80, 0xe0, 0xf0, 0x1e, 0x30, 0xec, 0xe5, 0x82, 0xa6, 0x40, 0x00, 0xe1, 0x1a,
411
+0x80, 0xe0, 0xf0, 0x1e, 0x30, 0xec, 0xe5, 0x82, 0xa6, 0x40, 0x00, 0xe1, 0x1a,
412
+0x80, 0x2a, 0xc0, 0x3a, 0xc2, 0x13, 0x40, 0x10, 0xe0, 0x1a, 0x82, 0x23, 0x40,
412
+0x80, 0x2a, 0xc0, 0x3a, 0xc2, 0x13, 0x40, 0x10, 0xe0, 0x1a, 0x82, 0x23, 0x40,
413
+0x18, 0xe0, 0x33, 0x40, 0x1c, 0xe0, 0x13, 0x40, 0x14, 0xe0, 0xf8, 0x61, 0x68,
413
+0x18, 0xe0, 0x33, 0x40, 0x1c, 0xe0, 0x13, 0x40, 0x14, 0xe0, 0xf8, 0x61, 0x68,
414
+0xef, 0xc6, 0x13, 0x00, 0xe1, 0x15, 0x12, 0x28, 0xf8, 0x0b, 0x02, 0x2c, 0xe0,
414
+0xef, 0xc6, 0x13, 0x00, 0xe1, 0x15, 0x12, 0x28, 0xf8, 0x0b, 0x02, 0x2c, 0xe0,
415
+0x1b, 0x02, 0x24, 0xe0, 0x8a, 0x00, 0xa5, 0x64, 0x03, 0xc0, 0x35, 0x82, 0x0a,
415
+0x1b, 0x02, 0x24, 0xe0, 0x8a, 0x00, 0xa5, 0x64, 0x03, 0xc0, 0x35, 0x82, 0x0a,
416
+0x4e, 0x9c, 0xe1, 0x1a, 0x03, 0x11, 0x6f, 0x02, 0xc0, 0xe8, 0x13, 0x01, 0x20,
416
+0x4e, 0x9c, 0xe1, 0x1a, 0x03, 0x11, 0x6f, 0x02, 0xc0, 0xe8, 0x13, 0x01, 0x20,
417
+0x00, 0xc0, 0x1f, 0xa0, 0x5a, 0x42, 0x80, 0xe0, 0x0a, 0x4e, 0x9c, 0xe1, 0x68,
417
+0x00, 0xc0, 0x1f, 0xa0, 0x5a, 0x42, 0x80, 0xe0, 0x0a, 0x4e, 0x9c, 0xe1, 0x68,
418
+0x13, 0x00, 0xa0, 0x09, 0x12, 0x78, 0xf8, 0xa1, 0x81, 0xf0, 0x02, 0x10, 0xe4,
418
+0x13, 0x00, 0xa0, 0x09, 0x12, 0x78, 0xf8, 0xa1, 0x81, 0xf0, 0x02, 0x10, 0xe4,
419
+0x07, 0xc4, 0x0c, 0xfc, 0xf0, 0x00, 0x20, 0xe4, 0xa6, 0x91, 0xa8, 0x53, 0x74,
419
+0x07, 0xc4, 0x0c, 0xfc, 0xf0, 0x00, 0x20, 0xe4, 0xa6, 0x91, 0xa8, 0x53, 0x74,
420
+0xef, 0x05, 0x12, 0x30, 0xf8, 0x25, 0x12, 0x28, 0xf8, 0x61, 0x87, 0x09, 0x00,
420
+0xef, 0x05, 0x12, 0x30, 0xf8, 0x25, 0x12, 0x28, 0xf8, 0x61, 0x87, 0x09, 0x00,
421
+0x48, 0xe0, 0x81, 0x85, 0x09, 0x86, 0x0b, 0xa7, 0x26, 0x0c, 0x00, 0xc0, 0x0b,
421
+0x48, 0xe0, 0x81, 0x85, 0x09, 0x86, 0x0b, 0xa7, 0x26, 0x0c, 0x00, 0xc0, 0x0b,
422
+0xa1, 0x0b, 0x04, 0x28, 0xe0, 0x16, 0x0c, 0x00, 0x80, 0x03, 0x52, 0x04, 0xf8,
422
+0xa1, 0x0b, 0x04, 0x28, 0xe0, 0x16, 0x0c, 0x00, 0x80, 0x03, 0x52, 0x04, 0xf8,
423
+0x0b, 0x04, 0x20, 0xe0, 0x0c, 0xa6, 0x1b, 0x04, 0x2c, 0xe0, 0x3b, 0x04, 0x28,
423
+0x0b, 0x04, 0x20, 0xe0, 0x0c, 0xa6, 0x1b, 0x04, 0x2c, 0xe0, 0x3b, 0x04, 0x28,
424
+0xe0, 0x4b, 0x04, 0x20, 0xe0, 0x13, 0x86, 0x3b, 0x04, 0x24, 0xe0, 0x10, 0x0a,
424
+0xe0, 0x4b, 0x04, 0x20, 0xe0, 0x13, 0x86, 0x3b, 0x04, 0x24, 0xe0, 0x10, 0x0a,
425
+0x04, 0xec, 0x1a, 0xfc, 0x33, 0x88, 0x30, 0x06, 0x04, 0xec, 0x12, 0x4e, 0x94,
425
+0x04, 0xec, 0x1a, 0xfc, 0x33, 0x88, 0x30, 0x06, 0x04, 0xec, 0x12, 0x4e, 0x94,
426
+0xf0, 0x32, 0x48, 0x84, 0xf0, 0x4c, 0xe4, 0x7c, 0xa4, 0xcb, 0x04, 0x28, 0xe0,
426
+0xf0, 0x32, 0x48, 0x84, 0xf0, 0x4c, 0xe4, 0x7c, 0xa4, 0xcb, 0x04, 0x28, 0xe0,
427
+0x14, 0x08, 0x84, 0xe1, 0xcd, 0xc9, 0xc2, 0x58, 0x90, 0x91, 0x42, 0x4e, 0x94,
427
+0x14, 0x08, 0x84, 0xe1, 0xcd, 0xc9, 0xc2, 0x58, 0x90, 0x91, 0x42, 0x4e, 0x94,
428
+0x90, 0xc3, 0x52, 0x04, 0x98, 0x73, 0x52, 0x00, 0x80, 0x5b, 0x04, 0x20, 0xe0,
428
+0x90, 0xc3, 0x52, 0x04, 0x98, 0x73, 0x52, 0x00, 0x80, 0x5b, 0x04, 0x20, 0xe0,
429
+0x5d, 0xc9, 0x52, 0x40, 0x90, 0x91, 0x42, 0x48, 0x8c, 0x90, 0x03, 0x52, 0x04,
429
+0x5d, 0xc9, 0x52, 0x40, 0x90, 0x91, 0x42, 0x48, 0x8c, 0x90, 0x03, 0x52, 0x04,
430
+0x80, 0x43, 0x52, 0x08, 0x80, 0x3b, 0x04, 0x2c, 0xe0, 0x49, 0x04, 0xb8, 0xe0,
430
+0x80, 0x43, 0x52, 0x08, 0x80, 0x3b, 0x04, 0x2c, 0xe0, 0x49, 0x04, 0xb8, 0xe0,
431
+0x33, 0x52, 0x1c, 0xf8, 0x2b, 0x04, 0x24, 0xe0, 0x4b, 0xab, 0x23, 0x52, 0x18,
431
+0x33, 0x52, 0x1c, 0xf8, 0x2b, 0x04, 0x24, 0xe0, 0x4b, 0xab, 0x23, 0x52, 0x18,
432
+0xf8, 0x65, 0x8a, 0x4b, 0xa9, 0xe5, 0x90, 0x4b, 0xa7, 0x22, 0x44, 0x84, 0xd0,
432
+0xf8, 0x65, 0x8a, 0x4b, 0xa9, 0xe5, 0x90, 0x4b, 0xa7, 0x22, 0x44, 0x84, 0xd0,
433
+0x32, 0x46, 0x84, 0xd0, 0x33, 0x52, 0x1c, 0xd8, 0x23, 0x52, 0x18, 0xd8, 0x95,
433
+0x32, 0x46, 0x84, 0xd0, 0x33, 0x52, 0x1c, 0xd8, 0x23, 0x52, 0x18, 0xd8, 0x95,
434
+0x96, 0x20, 0x44, 0xf9, 0x73, 0xff, 0xc0, 0x27, 0xc3, 0x23, 0x82, 0x23, 0x52,
434
+0x96, 0x20, 0x44, 0xf9, 0x73, 0xff, 0xc0, 0x27, 0xc3, 0x23, 0x82, 0x23, 0x52,
435
+0x18, 0xf8, 0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x58,
435
+0x18, 0xf8, 0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x58,
436
+0x52, 0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc3,
436
+0x52, 0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc3,
437
+0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02, 0x80,
437
+0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02, 0x80,
438
+0xfb, 0x2b, 0x8c, 0x68, 0x51, 0x74, 0xef, 0xc5, 0x87, 0x20, 0x44, 0xe1, 0x73,
438
+0xfb, 0x2b, 0x8c, 0x68, 0x51, 0x74, 0xef, 0xc5, 0x87, 0x20, 0x44, 0xe1, 0x73,
439
+0xff, 0xc0, 0x27, 0xc7, 0x23, 0x82, 0x23, 0x52, 0x18, 0xf8, 0x24, 0x02, 0x80,
439
+0xff, 0xc0, 0x27, 0xc7, 0x23, 0x82, 0x23, 0x52, 0x18, 0xf8, 0x24, 0x02, 0x80,
440
+0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x78, 0x57, 0x74, 0xef, 0x1b, 0x12,
440
+0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x78, 0x57, 0x74, 0xef, 0x1b, 0x12,
441
+0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc7, 0x13, 0x84, 0x13, 0x52, 0x1c,
441
+0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc7, 0x13, 0x84, 0x13, 0x52, 0x1c,
442
+0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02, 0x80, 0xfb, 0x2b, 0x8c, 0x88, 0x56,
442
+0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02, 0x80, 0xfb, 0x2b, 0x8c, 0x88, 0x56,
443
+0x74, 0xef, 0xe5, 0x83, 0x20, 0x44, 0xf1, 0x73, 0xff, 0xc0, 0x27, 0xc5, 0x23,
443
+0x74, 0xef, 0xe5, 0x83, 0x20, 0x44, 0xf1, 0x73, 0xff, 0xc0, 0x27, 0xc5, 0x23,
444
+0x82, 0x23, 0x52, 0x18, 0xf8, 0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb,
444
+0x82, 0x23, 0x52, 0x18, 0xf8, 0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb,
445
+0x2b, 0x8c, 0x18, 0x52, 0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c,
445
+0x2b, 0x8c, 0x18, 0x52, 0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c,
446
+0xe4, 0x17, 0xc5, 0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8,
446
+0xe4, 0x17, 0xc5, 0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8,
447
+0x14, 0x02, 0x80, 0xfb, 0x2b, 0x8c, 0x28, 0x51, 0x74, 0xef, 0x7b, 0x80, 0x7c,
447
+0x14, 0x02, 0x80, 0xfb, 0x2b, 0x8c, 0x28, 0x51, 0x74, 0xef, 0x7b, 0x80, 0x7c,
448
+0xa4, 0x08, 0x91, 0xa3, 0x52, 0x1c, 0xe0, 0xa3, 0x52, 0x24, 0xe0, 0x0b, 0xa1,
448
+0xa4, 0x08, 0x91, 0xa3, 0x52, 0x1c, 0xe0, 0xa3, 0x52, 0x24, 0xe0, 0x0b, 0xa1,
449
+0x83, 0x52, 0x1c, 0x80, 0x83, 0x52, 0x24, 0x80, 0x89, 0x12, 0x78, 0xf8, 0xf6,
449
+0x83, 0x52, 0x1c, 0x80, 0x83, 0x52, 0x24, 0x80, 0x89, 0x12, 0x78, 0xf8, 0xf6,
450
+0x57, 0xfc, 0xef, 0x6b, 0x12, 0x1c, 0xf8, 0xab, 0x12, 0x18, 0xf8, 0xd6, 0x57,
450
+0x57, 0xfc, 0xef, 0x6b, 0x12, 0x1c, 0xf8, 0xab, 0x12, 0x18, 0xf8, 0xd6, 0x57,
451
+0xfc, 0x8f, 0x8b, 0xa3, 0xa0, 0x40, 0x00, 0x9c, 0xa5, 0x86, 0x64, 0x00, 0x80,
451
+0xfc, 0x8f, 0x8b, 0xa3, 0xa0, 0x40, 0x00, 0x9c, 0xa5, 0x86, 0x64, 0x00, 0x80,
452
+0xfb, 0x1b, 0x90, 0xf8, 0x7d, 0xf8, 0xee, 0x6b, 0x80, 0xa4, 0x00, 0x80, 0xfb,
452
+0xfb, 0x1b, 0x90, 0xf8, 0x7d, 0xf8, 0xee, 0x6b, 0x80, 0xa4, 0x00, 0x80, 0xfb,
453
+0x1b, 0x90, 0x98, 0x7d, 0xf8, 0xee, 0x15, 0x12, 0x28, 0xf8, 0x19, 0x02, 0xb8,
453
+0x1b, 0x90, 0x98, 0x7d, 0xf8, 0xee, 0x15, 0x12, 0x28, 0xf8, 0x19, 0x02, 0xb8,
454
+0xe0, 0x1b, 0xad, 0x95, 0x82, 0x1a, 0xa6, 0xa0, 0x44, 0xf9, 0x73, 0xff, 0xc0,
454
+0xe0, 0x1b, 0xad, 0x95, 0x82, 0x1a, 0xa6, 0xa0, 0x44, 0xf9, 0x73, 0xff, 0xc0,
455
+0x27, 0xc3, 0x13, 0x94, 0x10, 0x02, 0x08, 0xec, 0x1c, 0xe4, 0x23, 0x52, 0x18,
455
+0x27, 0xc3, 0x13, 0x94, 0x10, 0x02, 0x08, 0xec, 0x1c, 0xe4, 0x23, 0x52, 0x18,
456
+0xf8, 0x1b, 0x12, 0x04, 0xf8, 0x03, 0x96, 0x03, 0x52, 0x28, 0xe0, 0x1c, 0xe6,
456
+0xf8, 0x1b, 0x12, 0x04, 0xf8, 0x03, 0x96, 0x03, 0x52, 0x28, 0xe0, 0x1c, 0xe6,
457
+0x0a, 0xa6, 0x1a, 0xe4, 0x63, 0x96, 0x63, 0x52, 0x20, 0xe0, 0x73, 0x52, 0x10,
457
+0x0a, 0xa6, 0x1a, 0xe4, 0x63, 0x96, 0x63, 0x52, 0x20, 0xe0, 0x73, 0x52, 0x10,
458
+0xe0, 0x03, 0x52, 0x14, 0xe0, 0x13, 0x52, 0x18, 0xe0, 0x98, 0x52, 0x74, 0xef,
458
+0xe0, 0x03, 0x52, 0x14, 0xe0, 0x13, 0x52, 0x18, 0xe0, 0x98, 0x52, 0x74, 0xef,
459
+0x09, 0x12, 0x8c, 0xe0, 0x0b, 0xa1, 0x01, 0x81, 0x01, 0x52, 0x90, 0xe0, 0x65,
459
+0x09, 0x12, 0x8c, 0xe0, 0x0b, 0xa1, 0x01, 0x81, 0x01, 0x52, 0x90, 0xe0, 0x65,
460
+0x82, 0x05, 0x12, 0x30, 0xf8, 0x09, 0x00, 0xa8, 0xe0, 0x0a, 0x00, 0x0c, 0xf8,
460
+0x82, 0x05, 0x12, 0x30, 0xf8, 0x09, 0x00, 0xa8, 0xe0, 0x0a, 0x00, 0x0c, 0xf8,
461
+0x16, 0x00, 0x00, 0xc0, 0x01, 0x52, 0x90, 0xc0, 0x46, 0x41, 0x84, 0xe0, 0x0a,
461
+0x16, 0x00, 0x00, 0xc0, 0x01, 0x52, 0x90, 0xc0, 0x46, 0x41, 0x84, 0xe0, 0x0a,
462
+0x80, 0x0a, 0x4e, 0x9c, 0xe9, 0x1a, 0x00, 0x08, 0xe0, 0x38, 0x01, 0x01, 0x20,
462
+0x80, 0x0a, 0x4e, 0x9c, 0xe9, 0x1a, 0x00, 0x08, 0xe0, 0x38, 0x01, 0x01, 0x20,
463
+0x00, 0xc0, 0x0b, 0x12, 0x1c, 0xe0, 0x1b, 0x12, 0x24, 0xe0, 0x2b, 0x12, 0x28,
463
+0x00, 0xc0, 0x0b, 0x12, 0x1c, 0xe0, 0x1b, 0x12, 0x24, 0xe0, 0x2b, 0x12, 0x28,
464
+0xe0, 0x03, 0x52, 0x2c, 0xe0, 0x0b, 0x12, 0x20, 0xe0, 0x13, 0x52, 0x34, 0xe0,
464
+0xe0, 0x03, 0x52, 0x2c, 0xe0, 0x0b, 0x12, 0x20, 0xe0, 0x13, 0x52, 0x34, 0xe0,
465
+0x23, 0x52, 0x38, 0xe0, 0x03, 0x52, 0x30, 0xe0, 0x0c, 0x00, 0x00, 0xe2, 0xf1,
465
+0x23, 0x52, 0x38, 0xe0, 0x03, 0x52, 0x30, 0xe0, 0x0c, 0x00, 0x00, 0xe2, 0xf1,
466
+0x98, 0x0c, 0x0c, 0x7c, 0xf2, 0x93, 0xdd, 0x13, 0xa9, 0x00, 0x00, 0xa8, 0xc1,
466
+0x98, 0x0c, 0x0c, 0x7c, 0xf2, 0x93, 0xdd, 0x13, 0xa9, 0x00, 0x00, 0xa8, 0xc1,
467
+0x40, 0x00, 0x68, 0x04, 0xa0, 0xe0, 0x40, 0x6c, 0x40, 0x00, 0xe8, 0x34, 0xc8,
467
+0x40, 0x00, 0x68, 0x04, 0xa0, 0xe0, 0x40, 0x6c, 0x40, 0x00, 0xe8, 0x34, 0xc8,
468
+0xe0, 0xfc, 0x91, 0x40, 0x00, 0x68, 0x1f, 0xb8, 0xe0, 0x30, 0x16, 0x41, 0x00,
468
+0xe0, 0xfc, 0x91, 0x40, 0x00, 0x68, 0x1f, 0xb8, 0xe0, 0x30, 0x16, 0x41, 0x00,
469
+0x28, 0x39, 0x74, 0xe0, 0xb0, 0x7e, 0x40, 0x00, 0xe8, 0x38, 0xc0, 0xe0, 0x30,
469
+0x28, 0x39, 0x74, 0xe0, 0xb0, 0x7e, 0x40, 0x00, 0xe8, 0x38, 0xc0, 0xe0, 0x30,
470
+0x04, 0x41, 0x00, 0x48, 0x1b, 0x80, 0xe0, 0x30, 0x2e, 0x40, 0x00, 0x88, 0x0c,
470
+0x04, 0x41, 0x00, 0x48, 0x1b, 0x80, 0xe0, 0x30, 0x2e, 0x40, 0x00, 0x88, 0x0c,
471
+0xec, 0xe0, 0x10, 0x9f, 0x40, 0x00, 0x88, 0x08, 0xb4, 0xe0, 0x10, 0x01, 0x41,
471
+0xec, 0xe0, 0x10, 0x9f, 0x40, 0x00, 0x88, 0x08, 0xb4, 0xe0, 0x10, 0x01, 0x41,
472
+0x00, 0x68, 0x01, 0x84, 0xe0, 0x54, 0xd6, 0x40, 0x00, 0xc8, 0x1a, 0x98, 0xe0,
472
+0x00, 0x68, 0x01, 0x84, 0xe0, 0x54, 0xd6, 0x40, 0x00, 0xc8, 0x1a, 0x98, 0xe0,
473
+0xd0, 0xc8, 0x40, 0x00, 0x68, 0x08, 0xa0, 0xe0, 0x80, 0xdb, 0x40, 0x00, 0xe8,
473
+0xd0, 0xc8, 0x40, 0x00, 0x68, 0x08, 0xa0, 0xe0, 0x80, 0xdb, 0x40, 0x00, 0xe8,
474
+0x35, 0x94, 0xe0, 0x74, 0xff, 0x40, 0x00, 0xa8, 0x11, 0x80, 0xe0, 0xf8, 0x89,
474
+0x35, 0x94, 0xe0, 0x74, 0xff, 0x40, 0x00, 0xa8, 0x11, 0x80, 0xe0, 0xf8, 0x89,
475
+0x40, 0x00, 0x88, 0x16, 0xbc, 0xe0, 0x00, 0x90, 0x40, 0x00, 0x08, 0x35, 0xb8,
475
+0x40, 0x00, 0x88, 0x16, 0xbc, 0xe0, 0x00, 0x90, 0x40, 0x00, 0x08, 0x35, 0xb8,
476
+0xe0, 0x7c, 0x73, 0x40, 0x00, 0x88, 0x1b, 0xc8, 0xe0, 0xf4, 0xff, 0x40, 0x00,
476
+0xe0, 0x7c, 0x73, 0x40, 0x00, 0x88, 0x1b, 0xc8, 0xe0, 0xf4, 0xff, 0x40, 0x00,
477
+0x68, 0x39, 0x80, 0xe0, 0xa4, 0xa4, 0x40, 0x00, 0xa8, 0x16, 0xb0, 0xe0, 0x50,
477
+0x68, 0x39, 0x80, 0xe0, 0xa4, 0xa4, 0x40, 0x00, 0xa8, 0x16, 0xb0, 0xe0, 0x50,
478
+0xc9, 0x40, 0x00, 0x28, 0x3a, 0x98, 0xe0, 0x00, 0xb9, 0x00, 0x00, 0xb6, 0x85,
478
+0xc9, 0x40, 0x00, 0x28, 0x3a, 0x98, 0xe0, 0x00, 0xb9, 0x00, 0x00, 0xb6, 0x85,
479
+0x00, 0x00,
479
+0x00, 0x00,
480
+};
480
+};
481
+
481
+
482
+static const char * const vd55g1_tp_menu[] = {
482
+static const char * const vd55g1_tp_menu[] = {
483
+    "Disabled",
483
+    "Disabled",
484
+    "Dgrey",
484
+    "Dgrey",
485
+    "PN28",
485
+    "PN28",
486
+};
486
+};
487
+
487
+
488
+static const s64 vd55g1_ev_bias_menu[] = {
488
+static const s64 vd55g1_ev_bias_menu[] = {
489
+    -3000, -2500, -2000, -1500, -1000, -500,
489
+    -3000, -2500, -2000, -1500, -1000, -500,
490
+     0,
490
+     0,
491
+     500, 1000, 1500, 2000, 2500, 3000,
491
+     500, 1000, 1500, 2000, 2500, 3000,
492
+};
492
+};
493
+
493
+
494
+static const char * const vd55g1_hdr_menu[] = {
494
+static const char * const vd55g1_hdr_menu[] = {
495
+    "No HDR",
495
+    "No HDR",
496
+    /*
496
+    /*
497
+     * This mode acquires 2 frames on the sensor, the first one is ditched
497
+     * This mode acquires 2 frames on the sensor, the first one is ditched
498
+     * out and only used for auto exposure data, the second one is output to
498
+     * out and only used for auto exposure data, the second one is output to
499
+     * the host
499
+     * the host
500
+     */
500
+     */
501
+    "Internal subtraction",
501
+    "Internal subtraction",
502
+};
502
+};
503
+
503
+
504
+static const char * const vd55g1_supply_name[] = {
504
+static const char * const vd55g1_supply_name[] = {
505
+    "vcore",
505
+    "vcore",
506
+    "vddio",
506
+    "vddio",
507
+    "vana",
507
+    "vana",
508
+};
508
+};
509
+
509
+
510
+/* Will be filled on device tree parse */
510
+/* Will be filled on device tree parse */
511
+static u64 link_freq[1];
511
+static u64 link_freq[1];
512
+
512
+
513
+enum vd55g1_hdr_mode {
513
+enum vd55g1_hdr_mode {
514
+    VD55G1_NO_HDR,
514
+    VD55G1_NO_HDR,
515
+    VD55G1_HDR_SUB,
515
+    VD55G1_HDR_SUB,
516
+};
516
+};
517
+
517
+
518
+enum vd55g1_bin_mode {
518
+enum vd55g1_bin_mode {
519
+    VD55G1_BIN_MODE_NORMAL,
519
+    VD55G1_BIN_MODE_NORMAL,
520
+    VD55G1_BIN_MODE_DIGITAL_X2,
520
+    VD55G1_BIN_MODE_DIGITAL_X2,
521
+    VD55G1_BIN_MODE_DIGITAL_X4,
521
+    VD55G1_BIN_MODE_DIGITAL_X4,
522
+};
522
+};
523
+
523
+
524
+enum vd55g1_gpio_mode {
524
+enum vd55g1_gpio_mode {
525
+    VD55G1_GPIO_MODE_IN = 0x01,
525
+    VD55G1_GPIO_MODE_IN = 0x01,
526
+    VD55G1_GPIO_MODE_STROBE = 0x02,
526
+    VD55G1_GPIO_MODE_STROBE = 0x02,
527
+};
527
+};
528
+
528
+
529
+struct vd55g1_mode {
529
+struct vd55g1_mode {
530
+    u32 width;
530
+    u32 width;
531
+    u32 height;
531
+    u32 height;
532
+};
532
+};
533
+
533
+
534
+struct vd55g1_fmt_desc {
534
+struct vd55g1_fmt_desc {
535
+    u32 code;
535
+    u32 code;
536
+    u8 bpp;
536
+    u8 bpp;
537
+    u8 data_type;
537
+    u8 data_type;
538
+};
538
+};
539
+
539
+
540
+static const struct vd55g1_fmt_desc vd55g1_mbus_codes[] = {
540
+static const struct vd55g1_fmt_desc vd55g1_mbus_codes[] = {
541
+    {
541
+    {
542
+        .code = MEDIA_BUS_FMT_Y8_1X8,
542
+        .code = MEDIA_BUS_FMT_Y8_1X8,
543
+        .bpp = 8,
543
+        .bpp = 8,
544
+        .data_type = MIPI_CSI2_DT_RAW8,
544
+        .data_type = MIPI_CSI2_DT_RAW8,
545
+    },
545
+    },
546
+    {
546
+    {
547
+        .code = MEDIA_BUS_FMT_Y10_1X10,
547
+        .code = MEDIA_BUS_FMT_Y10_1X10,
548
+        .bpp = 10,
548
+        .bpp = 10,
549
+        .data_type = MIPI_CSI2_DT_RAW10,
549
+        .data_type = MIPI_CSI2_DT_RAW10,
550
+    },
550
+    },
551
+};
551
+};
552
+
552
+
553
+static const struct vd55g1_mode vd55g1_supported_modes[] = {
553
+static const struct vd55g1_mode vd55g1_supported_modes[] = {
554
+    {
554
+    {
555
+        .width = VD55G1_WIDTH,
555
+        .width = VD55G1_WIDTH,
556
+        .height = VD55G1_HEIGHT,
556
+        .height = VD55G1_HEIGHT,
557
+    },
557
+    },
558
+    {
558
+    {
559
+        .width = 800,
559
+        .width = 800,
560
+        .height = VD55G1_HEIGHT,
560
+        .height = VD55G1_HEIGHT,
561
+    },
561
+    },
562
+    {
562
+    {
563
+        .width = 800,
563
+        .width = 800,
564
+        .height = 600,
564
+        .height = 600,
565
+    },
565
+    },
566
+    {
566
+    {
567
+        .width = 640,
567
+        .width = 640,
568
+        .height = 480,
568
+        .height = 480,
569
+    },
569
+    },
570
+    {
570
+    {
571
+        .width = 320,
571
+        .width = 320,
572
+        .height = 240,
572
+        .height = 240,
573
+    },
573
+    },
574
+};
574
+};
575
+
575
+
576
+enum vd55g1_expo_state {
576
+enum vd55g1_expo_state {
577
+    VD55G1_EXP_AUTO,
577
+    VD55G1_EXP_AUTO,
578
+    VD55G1_EXP_FREEZE,
578
+    VD55G1_EXP_FREEZE,
579
+    VD55G1_EXP_MANUAL,
579
+    VD55G1_EXP_MANUAL,
580
+    VD55G1_EXP_SINGLE_STEP,
580
+    VD55G1_EXP_SINGLE_STEP,
581
+    VD55G1_EXP_BYPASS,
581
+    VD55G1_EXP_BYPASS,
582
+};
582
+};
583
+
583
+
584
+struct vblank_limits {
584
+struct vblank_limits {
585
+    u16 min;
585
+    u16 min;
586
+    u16 def;
586
+    u16 def;
587
+    u16 max;
587
+    u16 max;
588
+};
588
+};
589
+
589
+
590
+struct vd55g1 {
590
+struct vd55g1 {
591
+    struct i2c_client *i2c_client;
591
+    struct i2c_client *i2c_client;
592
+    struct v4l2_subdev sd;
592
+    struct v4l2_subdev sd;
593
+    struct media_pad pad;
593
+    struct media_pad pad;
594
+    struct regulator_bulk_data supplies[ARRAY_SIZE(vd55g1_supply_name)];
594
+    struct regulator_bulk_data supplies[ARRAY_SIZE(vd55g1_supply_name)];
595
+    struct gpio_desc *reset_gpio;
595
+    struct gpio_desc *reset_gpio;
596
+    struct clk *xclk;
596
+    struct clk *xclk;
597
+    struct regmap *regmap;
597
+    struct regmap *regmap;
598
+    u32 xclk_freq;
598
+    u32 xclk_freq;
599
+    u16 oif_ctrl;
599
+    u16 oif_ctrl;
600
+    enum vd55g1_gpio_mode gpios[VD55G1_NB_GPIOS];
600
+    enum vd55g1_gpio_mode gpios[VD55G1_NB_GPIOS];
601
+    unsigned long ext_leds_mask;
601
+    unsigned long ext_leds_mask;
602
+    int data_rate_in_mbps;
602
+    int data_rate_in_mbps;
603
+    u32 pixel_clock;
603
+    u32 pixel_clock;
604
+    struct v4l2_ctrl_handler ctrl_handler;
604
+    struct v4l2_ctrl_handler ctrl_handler;
605
+    struct v4l2_ctrl *pixel_rate_ctrl;
605
+    struct v4l2_ctrl *pixel_rate_ctrl;
606
+    struct v4l2_ctrl *vblank_ctrl;
606
+    struct v4l2_ctrl *vblank_ctrl;
607
+    struct v4l2_ctrl *hblank_ctrl;
607
+    struct v4l2_ctrl *hblank_ctrl;
608
+    struct {
608
+    struct {
609
+        struct v4l2_ctrl *hflip_ctrl;
609
+        struct v4l2_ctrl *hflip_ctrl;
610
+        struct v4l2_ctrl *vflip_ctrl;
610
+        struct v4l2_ctrl *vflip_ctrl;
611
+    };
611
+    };
612
+    struct v4l2_ctrl *patgen_ctrl;
612
+    struct v4l2_ctrl *patgen_ctrl;
613
+    struct {
613
+    struct {
614
+        struct v4l2_ctrl *ae_ctrl;
614
+        struct v4l2_ctrl *ae_ctrl;
615
+        struct v4l2_ctrl *expo_ctrl;
615
+        struct v4l2_ctrl *expo_ctrl;
616
+        struct v4l2_ctrl *again_ctrl;
616
+        struct v4l2_ctrl *again_ctrl;
617
+        struct v4l2_ctrl *dgain_ctrl;
617
+        struct v4l2_ctrl *dgain_ctrl;
618
+    };
618
+    };
619
+    struct v4l2_ctrl *ae_lock_ctrl;
619
+    struct v4l2_ctrl *ae_lock_ctrl;
620
+    struct v4l2_ctrl *ae_bias_ctrl;
620
+    struct v4l2_ctrl *ae_bias_ctrl;
621
+    struct v4l2_ctrl *led_ctrl;
621
+    struct v4l2_ctrl *led_ctrl;
622
+    struct v4l2_ctrl *hdr_ctrl;
622
+    struct v4l2_ctrl *hdr_ctrl;
623
+};
623
+};
624
+
624
+
625
+static inline struct vd55g1 *to_vd55g1(struct v4l2_subdev *sd)
625
+static inline struct vd55g1 *to_vd55g1(struct v4l2_subdev *sd)
626
+{
626
+{
627
+    return container_of_const(sd, struct vd55g1, sd);
627
+    return container_of_const(sd, struct vd55g1, sd);
628
+}
628
+}
629
+
629
+
630
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
630
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
631
+{
631
+{
632
+    return &container_of_const(ctrl->handler, struct vd55g1,
632
+    return &container_of_const(ctrl->handler, struct vd55g1,
633
+        ctrl_handler)->sd;
633
+        ctrl_handler)->sd;
634
+}
634
+}
635
+
635
+
636
+static u8 get_bpp_by_code(struct vd55g1 *sensor, u32 code)
636
+static u8 get_bpp_by_code(struct vd55g1 *sensor, u32 code)
637
+{
637
+{
638
+    struct i2c_client *client = sensor->i2c_client;
638
+    struct i2c_client *client = sensor->i2c_client;
639
+    unsigned int i;
639
+    unsigned int i;
640
+
640
+
641
+    for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_codes); i++) {
641
+    for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_codes); i++) {
642
+        if (vd55g1_mbus_codes[i].code == code)
642
+        if (vd55g1_mbus_codes[i].code == code)
643
+            return vd55g1_mbus_codes[i].bpp;
643
+            return vd55g1_mbus_codes[i].bpp;
644
+    }
644
+    }
645
+    /* Should never happen */
645
+    /* Should never happen */
646
+    dev_warn(&client->dev, "Unsupported code %d. default to 8 bpp", code);
646
+    dev_warn(&client->dev, "Unsupported code %d. default to 8 bpp", code);
647
+    return 8;
647
+    return 8;
648
+}
648
+}
649
+
649
+
650
+static u8 get_data_type_by_code(struct vd55g1 *sensor, u32 code)
650
+static u8 get_data_type_by_code(struct vd55g1 *sensor, u32 code)
651
+{
651
+{
652
+    struct i2c_client *client = sensor->i2c_client;
652
+    struct i2c_client *client = sensor->i2c_client;
653
+    unsigned int i;
653
+    unsigned int i;
654
+
654
+
655
+    for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_codes); i++) {
655
+    for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_codes); i++) {
656
+        if (vd55g1_mbus_codes[i].code == code)
656
+        if (vd55g1_mbus_codes[i].code == code)
657
+            return vd55g1_mbus_codes[i].data_type;
657
+            return vd55g1_mbus_codes[i].data_type;
658
+    }
658
+    }
659
+    /* Should never happen */
659
+    /* Should never happen */
660
+    dev_warn(&client->dev, "Unsupported code %d. default to MIPI_CSI2_DT_RAW8 data type",
660
+    dev_warn(&client->dev, "Unsupported code %d. default to MIPI_CSI2_DT_RAW8 data type",
661
+         code);
661
+         code);
662
+    return MIPI_CSI2_DT_RAW8;
662
+    return MIPI_CSI2_DT_RAW8;
663
+}
663
+}
664
+
664
+
665
+static s32 get_pixel_rate(struct vd55g1 *sensor)
665
+static s32 get_pixel_rate(struct vd55g1 *sensor)
666
+{
666
+{
667
+    struct v4l2_subdev_state *state =
667
+    struct v4l2_subdev_state *state =
668
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
668
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
669
+    const struct v4l2_mbus_framefmt *format =
669
+    const struct v4l2_mbus_framefmt *format =
670
+        v4l2_subdev_state_get_format(state, 0);
670
+        v4l2_subdev_state_get_format(state, 0);
671
+
671
+
672
+    return div64_u64((u64)sensor->data_rate_in_mbps,
672
+    return div64_u64((u64)sensor->data_rate_in_mbps,
673
+             get_bpp_by_code(sensor, format->code));
673
+             get_bpp_by_code(sensor, format->code));
674
+}
674
+}
675
+
675
+
676
+static s32 get_min_line_length(struct vd55g1 *sensor)
676
+static s32 get_min_line_length(struct vd55g1 *sensor)
677
+{
677
+{
678
+    u32 mipi_req_line_time;
678
+    u32 mipi_req_line_time;
679
+    u32 mipi_req_line_length;
679
+    u32 mipi_req_line_length;
680
+    u32 min_line_length;
680
+    u32 min_line_length;
681
+    struct v4l2_subdev_state *state =
681
+    struct v4l2_subdev_state *state =
682
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
682
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
683
+    const struct v4l2_rect *crop =
683
+    const struct v4l2_rect *crop =
684
+        v4l2_subdev_state_get_crop(state, 0);
684
+        v4l2_subdev_state_get_crop(state, 0);
685
+    const struct v4l2_mbus_framefmt *format =
685
+    const struct v4l2_mbus_framefmt *format =
686
+        v4l2_subdev_state_get_format(state, 0);
686
+        v4l2_subdev_state_get_format(state, 0);
687
+
687
+
688
+    /* MIPI required time */
688
+    /* MIPI required time */
689
+    mipi_req_line_time = (crop->width *
689
+    mipi_req_line_time = (crop->width *
690
+             get_bpp_by_code(sensor, format->code) +
690
+             get_bpp_by_code(sensor, format->code) +
691
+             VD55G1_MIPI_MARGIN) /
691
+             VD55G1_MIPI_MARGIN) /
692
+             (sensor->data_rate_in_mbps / MEGA);
692
+             (sensor->data_rate_in_mbps / MEGA);
693
+    mipi_req_line_length = mipi_req_line_time * sensor->pixel_clock /
693
+    mipi_req_line_length = mipi_req_line_time * sensor->pixel_clock /
694
+             HZ_PER_MHZ;
694
+             HZ_PER_MHZ;
695
+
695
+
696
+    /* Absolute time required for ADCs to convert pixels */
696
+    /* Absolute time required for ADCs to convert pixels */
697
+    min_line_length = VD55G1_LINE_LENGTH_MIN;
697
+    min_line_length = VD55G1_LINE_LENGTH_MIN;
698
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB)
698
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB)
699
+        min_line_length = VD55G1_LINE_LENGTH_SUB_MIN;
699
+        min_line_length = VD55G1_LINE_LENGTH_SUB_MIN;
700
+
700
+
701
+    /* Respect both constraint */
701
+    /* Respect both constraint */
702
+    return max(min_line_length, mipi_req_line_length);
702
+    return max(min_line_length, mipi_req_line_length);
703
+}
703
+}
704
+
704
+
705
+static unsigned int get_hblank_min(struct vd55g1 *sensor)
705
+static unsigned int get_hblank_min(struct vd55g1 *sensor)
706
+{
706
+{
707
+    struct v4l2_subdev_state *state =
707
+    struct v4l2_subdev_state *state =
708
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
708
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
709
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
709
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
710
+
710
+
711
+    return get_min_line_length(sensor) - crop->width;
711
+    return get_min_line_length(sensor) - crop->width;
712
+}
712
+}
713
+
713
+
714
+static struct vblank_limits get_vblank_limits(struct vd55g1 *sensor)
714
+static struct vblank_limits get_vblank_limits(struct vd55g1 *sensor)
715
+{
715
+{
716
+    struct vblank_limits limits;
716
+    struct vblank_limits limits;
717
+    struct v4l2_subdev_state *state =
717
+    struct v4l2_subdev_state *state =
718
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
718
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
719
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
719
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
720
+
720
+
721
+    limits.min = VD55G1_VBLANK_MIN;
721
+    limits.min = VD55G1_VBLANK_MIN;
722
+    limits.def = VD55G1_FRAME_LENGTH_DEF - crop->height;
722
+    limits.def = VD55G1_FRAME_LENGTH_DEF - crop->height;
723
+    limits.max = VD55G1_VBLANK_MAX - crop->height;
723
+    limits.max = VD55G1_VBLANK_MAX - crop->height;
724
+
724
+
725
+    return limits;
725
+    return limits;
726
+}
726
+}
727
+
727
+
728
+#define vd55g1_read(sensor, reg, val, err) \
728
+#define vd55g1_read(sensor, reg, val, err) \
729
+    cci_read((sensor)->regmap, reg, val, err)
729
+    cci_read((sensor)->regmap, reg, val, err)
730
+
730
+
731
+#define vd55g1_write(sensor, reg, val, err) \
731
+#define vd55g1_write(sensor, reg, val, err) \
732
+    cci_write((sensor)->regmap, reg, (u64)val, err)
732
+    cci_write((sensor)->regmap, reg, (u64)val, err)
733
+
733
+
734
+static int vd55g1_write_array(struct vd55g1 *sensor, u32 reg, unsigned int len,
734
+static int vd55g1_write_array(struct vd55g1 *sensor, u32 reg, unsigned int len,
735
+             const u8 *array, int *err)
735
+             const u8 *array, int *err)
736
+{
736
+{
737
+    unsigned int chunk_sz = 1024;
737
+    unsigned int chunk_sz = 1024;
738
+    unsigned int sz;
738
+    unsigned int sz;
739
+    int ret = 0;
739
+    int ret = 0;
740
+
740
+
741
+    if (err && *err)
741
+    if (err && *err)
742
+        return *err;
742
+        return *err;
743
+
743
+
744
+    /*
744
+    /*
745
+     * This loop isn't necessary but in certains conditions (platforms, cpu
745
+     * This loop isn't necessary but in certains conditions (platforms, cpu
746
+     * load, etc.) it has been observed that the bulk write could timeout.
746
+     * load, etc.) it has been observed that the bulk write could timeout.
747
+     */
747
+     */
748
+    while (len) {
748
+    while (len) {
749
+        sz = min(len, chunk_sz);
749
+        sz = min(len, chunk_sz);
750
+        ret = regmap_bulk_write(sensor->regmap, reg, array, sz);
750
+        ret = regmap_bulk_write(sensor->regmap, reg, array, sz);
751
+        if (ret < 0)
751
+        if (ret < 0)
752
+            goto out;
752
+            goto out;
753
+        len -= sz;
753
+        len -= sz;
754
+        reg += sz;
754
+        reg += sz;
755
+        array += sz;
755
+        array += sz;
756
+    }
756
+    }
757
+
757
+
758
+out:
758
+out:
759
+    if (ret && err)
759
+    if (ret && err)
760
+        *err = ret;
760
+        *err = ret;
761
+
761
+
762
+    return ret;
762
+    return ret;
763
+}
763
+}
764
+
764
+
765
+static int vd55g1_poll_reg(struct vd55g1 *sensor, u32 reg, u8 poll_val,
765
+static int vd55g1_poll_reg(struct vd55g1 *sensor, u32 reg, u8 poll_val,
766
+             int *err)
766
+             int *err)
767
+{
767
+{
768
+    unsigned int val = 0;
768
+    unsigned int val = 0;
769
+    int ret;
769
+    int ret;
770
+
770
+
771
+    if (err && *err)
771
+    if (err && *err)
772
+        return *err;
772
+        return *err;
773
+
773
+
774
+    ret = regmap_read_poll_timeout(sensor->regmap, CCI_REG_ADDR(reg), val,
774
+    ret = regmap_read_poll_timeout(sensor->regmap, CCI_REG_ADDR(reg), val,
775
+                 (val == poll_val), 2000,
775
+                 (val == poll_val), 2000,
776
+                 500 * USEC_PER_MSEC);
776
+                 500 * USEC_PER_MSEC);
777
+
777
+
778
+    if (ret && err)
778
+    if (ret && err)
779
+        *err = ret;
779
+        *err = ret;
780
+
780
+
781
+    return ret;
781
+    return ret;
782
+}
782
+}
783
+
783
+
784
+static int vd55g1_wait_state(struct vd55g1 *sensor, int state, int *err)
784
+static int vd55g1_wait_state(struct vd55g1 *sensor, int state, int *err)
785
+{
785
+{
786
+    return vd55g1_poll_reg(sensor, VD55G1_REG_SYSTEM_FSM, state, err);
786
+    return vd55g1_poll_reg(sensor, VD55G1_REG_SYSTEM_FSM, state, err);
787
+}
787
+}
788
+
788
+
789
+static int vd55g1_get_regulators(struct vd55g1 *sensor)
789
+static int vd55g1_get_regulators(struct vd55g1 *sensor)
790
+{
790
+{
791
+    int i;
791
+    int i;
792
+
792
+
793
+    for (i = 0; i < ARRAY_SIZE(vd55g1_supply_name); i++)
793
+    for (i = 0; i < ARRAY_SIZE(vd55g1_supply_name); i++)
794
+        sensor->supplies[i].supply = vd55g1_supply_name[i];
794
+        sensor->supplies[i].supply = vd55g1_supply_name[i];
795
+
795
+
796
+    return devm_regulator_bulk_get(&sensor->i2c_client->dev,
796
+    return devm_regulator_bulk_get(&sensor->i2c_client->dev,
797
+                 ARRAY_SIZE(vd55g1_supply_name),
797
+                 ARRAY_SIZE(vd55g1_supply_name),
798
+                 sensor->supplies);
798
+                 sensor->supplies);
799
+}
799
+}
800
+
800
+
801
+static int vd55g1_prepare_clock_tree(struct vd55g1 *sensor)
801
+static int vd55g1_prepare_clock_tree(struct vd55g1 *sensor)
802
+{
802
+{
803
+    struct i2c_client *client = sensor->i2c_client;
803
+    struct i2c_client *client = sensor->i2c_client;
804
+    /* Double data rate */
804
+    /* Double data rate */
805
+    u32 mipi_freq = link_freq[0] * 2;
805
+    u32 mipi_freq = link_freq[0] * 2;
806
+    u32 sys_clk, mipi_div, pixel_div;
806
+    u32 sys_clk, mipi_div, pixel_div;
807
+    int ret = 0;
807
+    int ret = 0;
808
+
808
+
809
+    if (sensor->xclk_freq < 6 * HZ_PER_MHZ ||
809
+    if (sensor->xclk_freq < 6 * HZ_PER_MHZ ||
810
+     sensor->xclk_freq > 27 * HZ_PER_MHZ) {
810
+     sensor->xclk_freq > 27 * HZ_PER_MHZ) {
811
+        dev_err(&client->dev,
811
+        dev_err(&client->dev,
812
+            "Only 6Mhz-27Mhz clock range supported. Provided %lu MHz\n",
812
+            "Only 6Mhz-27Mhz clock range supported. Provided %lu MHz\n",
813
+            sensor->xclk_freq / HZ_PER_MHZ);
813
+            sensor->xclk_freq / HZ_PER_MHZ);
814
+        return -EINVAL;
814
+        return -EINVAL;
815
+    }
815
+    }
816
+
816
+
817
+    if (mipi_freq < 250 * HZ_PER_MHZ ||
817
+    if (mipi_freq < 250 * HZ_PER_MHZ ||
818
+     mipi_freq > 1200 * HZ_PER_MHZ) {
818
+     mipi_freq > 1200 * HZ_PER_MHZ) {
819
+        dev_err(&client->dev,
819
+        dev_err(&client->dev,
820
+            "Only 250Mhz-1200Mhz link frequency range supported. Provided %lu MHz\n",
820
+            "Only 250Mhz-1200Mhz link frequency range supported. Provided %lu MHz\n",
821
+            mipi_freq / HZ_PER_MHZ);
821
+            mipi_freq / HZ_PER_MHZ);
822
+        return -EINVAL;
822
+        return -EINVAL;
823
+    }
823
+    }
824
+
824
+
825
+    if (mipi_freq <= 300 * HZ_PER_MHZ)
825
+    if (mipi_freq <= 300 * HZ_PER_MHZ)
826
+        mipi_div = 4;
826
+        mipi_div = 4;
827
+    else if (mipi_freq <= 600 * HZ_PER_MHZ)
827
+    else if (mipi_freq <= 600 * HZ_PER_MHZ)
828
+        mipi_div = 2;
828
+        mipi_div = 2;
829
+    else
829
+    else
830
+        mipi_div = 1;
830
+        mipi_div = 1;
831
+
831
+
832
+    sys_clk = mipi_freq * mipi_div;
832
+    sys_clk = mipi_freq * mipi_div;
833
+
833
+
834
+    if (sys_clk <= 780 * HZ_PER_MHZ)
834
+    if (sys_clk <= 780 * HZ_PER_MHZ)
835
+        pixel_div = 5;
835
+        pixel_div = 5;
836
+    else if (sys_clk <= 900 * HZ_PER_MHZ)
836
+    else if (sys_clk <= 900 * HZ_PER_MHZ)
837
+        pixel_div = 6;
837
+        pixel_div = 6;
838
+    else
838
+    else
839
+        pixel_div = 8;
839
+        pixel_div = 8;
840
+
840
+
841
+    sensor->pixel_clock = sys_clk / pixel_div;
841
+    sensor->pixel_clock = sys_clk / pixel_div;
842
+    /* Frequency to data rate is 1:1 ratio for MIPI */
842
+    /* Frequency to data rate is 1:1 ratio for MIPI */
843
+    sensor->data_rate_in_mbps = mipi_freq;
843
+    sensor->data_rate_in_mbps = mipi_freq;
844
+
844
+
845
+    return ret;
845
+    return ret;
846
+}
846
+}
847
+
847
+
848
+static int vd55g1_update_patgen(struct vd55g1 *sensor, u32 patgen_index)
848
+static int vd55g1_update_patgen(struct vd55g1 *sensor, u32 patgen_index)
849
+{
849
+{
850
+    static const u8 index2val[] = {
850
+    static const u8 index2val[] = {
851
+        0x0, 0x22, 0x28
851
+        0x0, 0x22, 0x28
852
+    };
852
+    };
853
+    u32 pattern = index2val[patgen_index];
853
+    u32 pattern = index2val[patgen_index];
854
+    u32 reg = pattern << VD55G1_PATGEN_TYPE_SHIFT;
854
+    u32 reg = pattern << VD55G1_PATGEN_TYPE_SHIFT;
855
+    u8 darkcal = VD55G1_DARKCAL_AUTO;
855
+    u8 darkcal = VD55G1_DARKCAL_AUTO;
856
+    u8 duster = VD55G1_DUSTER_RING_ENABLE | VD55G1_DUSTER_DYN_ENABLE |
856
+    u8 duster = VD55G1_DUSTER_RING_ENABLE | VD55G1_DUSTER_DYN_ENABLE |
857
+         VD55G1_DUSTER_ENABLE;
857
+         VD55G1_DUSTER_ENABLE;
858
+    int ret = 0;
858
+    int ret = 0;
859
+
859
+
860
+    if (pattern != 0) {
860
+    if (pattern != 0) {
861
+        reg |= VD55G1_PATGEN_ENABLE;
861
+        reg |= VD55G1_PATGEN_ENABLE;
862
+        /*
862
+        /*
863
+         * Take care of dark calibaration and duster to not mess up the
863
+         * Take care of dark calibaration and duster to not mess up the
864
+         * test pattern output.
864
+         * test pattern output.
865
+         */
865
+         */
866
+        darkcal = VD55G1_DARKCAL_BYPASS;
866
+        darkcal = VD55G1_DARKCAL_BYPASS;
867
+        duster = VD55G1_DUSTER_DISABLE;
867
+        duster = VD55G1_DUSTER_DISABLE;
868
+    }
868
+    }
869
+
869
+
870
+    vd55g1_write(sensor, VD55G1_REG_DARKCAL_CTRL, darkcal, &ret);
870
+    vd55g1_write(sensor, VD55G1_REG_DARKCAL_CTRL, darkcal, &ret);
871
+    vd55g1_write(sensor, VD55G1_REG_DUSTER_CTRL, duster, &ret);
871
+    vd55g1_write(sensor, VD55G1_REG_DUSTER_CTRL, duster, &ret);
872
+    vd55g1_write(sensor, VD55G1_REG_PATGEN_CTRL, reg, &ret);
872
+    vd55g1_write(sensor, VD55G1_REG_PATGEN_CTRL, reg, &ret);
873
+
873
+
874
+    return ret;
874
+    return ret;
875
+}
875
+}
876
+
876
+
877
+static int vd55g1_update_expo_cluster(struct vd55g1 *sensor, bool is_auto)
877
+static int vd55g1_update_expo_cluster(struct vd55g1 *sensor, bool is_auto)
878
+{
878
+{
879
+    enum vd55g1_expo_state expo_state = is_auto ? VD55G1_EXP_AUTO :
879
+    enum vd55g1_expo_state expo_state = is_auto ? VD55G1_EXP_AUTO :
880
+                         VD55G1_EXP_MANUAL;
880
+                         VD55G1_EXP_MANUAL;
881
+    int ret = 0;
881
+    int ret = 0;
882
+
882
+
883
+    if (sensor->ae_ctrl->is_new)
883
+    if (sensor->ae_ctrl->is_new)
884
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
884
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
885
+
885
+
886
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB &&
886
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB &&
887
+     sensor->hdr_ctrl->is_new) {
887
+     sensor->hdr_ctrl->is_new) {
888
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(1), VD55G1_EXP_BYPASS,
888
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(1), VD55G1_EXP_BYPASS,
889
+             &ret);
889
+             &ret);
890
+        if (ret)
890
+        if (ret)
891
+            return ret;
891
+            return ret;
892
+    }
892
+    }
893
+
893
+
894
+    if (!is_auto && sensor->expo_ctrl->is_new)
894
+    if (!is_auto && sensor->expo_ctrl->is_new)
895
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_COARSE_EXPOSURE,
895
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_COARSE_EXPOSURE,
896
+             sensor->expo_ctrl->val, &ret);
896
+             sensor->expo_ctrl->val, &ret);
897
+
897
+
898
+    if (!is_auto && sensor->again_ctrl->is_new)
898
+    if (!is_auto && sensor->again_ctrl->is_new)
899
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_ANALOG_GAIN,
899
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_ANALOG_GAIN,
900
+             sensor->again_ctrl->val, &ret);
900
+             sensor->again_ctrl->val, &ret);
901
+
901
+
902
+    if (!is_auto && sensor->dgain_ctrl->is_new) {
902
+    if (!is_auto && sensor->dgain_ctrl->is_new) {
903
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN,
903
+        vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN,
904
+             sensor->dgain_ctrl->val, &ret);
904
+             sensor->dgain_ctrl->val, &ret);
905
+    }
905
+    }
906
+
906
+
907
+    return ret;
907
+    return ret;
908
+}
908
+}
909
+
909
+
910
+static int vd55g1_lock_exposure(struct vd55g1 *sensor, u32 lock_val)
910
+static int vd55g1_lock_exposure(struct vd55g1 *sensor, u32 lock_val)
911
+{
911
+{
912
+    bool ae_lock = lock_val & V4L2_LOCK_EXPOSURE;
912
+    bool ae_lock = lock_val & V4L2_LOCK_EXPOSURE;
913
+    enum vd55g1_expo_state expo_state = ae_lock ? VD55G1_EXP_FREEZE :
913
+    enum vd55g1_expo_state expo_state = ae_lock ? VD55G1_EXP_FREEZE :
914
+                         VD55G1_EXP_AUTO;
914
+                         VD55G1_EXP_AUTO;
915
+    int ret = 0;
915
+    int ret = 0;
916
+
916
+
917
+    if (sensor->ae_ctrl->val == V4L2_EXPOSURE_AUTO)
917
+    if (sensor->ae_ctrl->val == V4L2_EXPOSURE_AUTO)
918
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
918
+        vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
919
+
919
+
920
+    return ret;
920
+    return ret;
921
+}
921
+}
922
+
922
+
923
+static int vd55g1_read_expo_cluster(struct vd55g1 *sensor)
923
+static int vd55g1_read_expo_cluster(struct vd55g1 *sensor)
924
+{
924
+{
925
+    u64 exposure = 0;
925
+    u64 exposure = 0;
926
+    u64 again = 0;
926
+    u64 again = 0;
927
+    u64 dgain = 0;
927
+    u64 dgain = 0;
928
+    int ret = 0;
928
+    int ret = 0;
929
+
929
+
930
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_COARSE_EXPOSURE, &exposure,
930
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_COARSE_EXPOSURE, &exposure,
931
+         &ret);
931
+         &ret);
932
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_ANALOG_GAIN, &again, &ret);
932
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_ANALOG_GAIN, &again, &ret);
933
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_DIGITAL_GAIN, &dgain, &ret);
933
+    vd55g1_read(sensor, VD55G1_REG_APPLIED_DIGITAL_GAIN, &dgain, &ret);
934
+    if (ret)
934
+    if (ret)
935
+        return ret;
935
+        return ret;
936
+
936
+
937
+    sensor->expo_ctrl->cur.val = exposure;
937
+    sensor->expo_ctrl->cur.val = exposure;
938
+    sensor->again_ctrl->cur.val = again;
938
+    sensor->again_ctrl->cur.val = again;
939
+    sensor->dgain_ctrl->cur.val = dgain;
939
+    sensor->dgain_ctrl->cur.val = dgain;
940
+
940
+
941
+    return 0;
941
+    return 0;
942
+}
942
+}
943
+
943
+
944
+static int vd55g1_update_frame_length(struct vd55g1 *sensor,
944
+static int vd55g1_update_frame_length(struct vd55g1 *sensor,
945
+                 unsigned int frame_length)
945
+                 unsigned int frame_length)
946
+{
946
+{
947
+    int ret = 0;
947
+    int ret = 0;
948
+
948
+
949
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB) {
949
+    if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB) {
950
+        vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(1), frame_length,
950
+        vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(1), frame_length,
951
+             &ret);
951
+             &ret);
952
+    }
952
+    }
953
+    vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(0), frame_length, &ret);
953
+    vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(0), frame_length, &ret);
954
+
954
+
955
+    return ret;
955
+    return ret;
956
+}
956
+}
957
+
957
+
958
+static int vd55g1_update_exposure_target(struct vd55g1 *sensor, int index)
958
+static int vd55g1_update_exposure_target(struct vd55g1 *sensor, int index)
959
+{
959
+{
960
+    /*
960
+    /*
961
+     * Find auto exposure target with: default target exposure * 2^EV
961
+     * Find auto exposure target with: default target exposure * 2^EV
962
+     * Defaut target exposure being 27 for the sensor.
962
+     * Defaut target exposure being 27 for the sensor.
963
+     */
963
+     */
964
+    static const unsigned int index2exposure_target[] = {
964
+    static const unsigned int index2exposure_target[] = {
965
+        3, 5, 7, 10, 14, 19, 27, 38, 54, 76, 108, 153, 216,
965
+        3, 5, 7, 10, 14, 19, 27, 38, 54, 76, 108, 153, 216,
966
+    };
966
+    };
967
+    int exposure_target = index2exposure_target[index];
967
+    int exposure_target = index2exposure_target[index];
968
+
968
+
969
+    return vd55g1_write(sensor, VD55G1_REG_AE_TARGET_PERCENTAGE,
969
+    return vd55g1_write(sensor, VD55G1_REG_AE_TARGET_PERCENTAGE,
970
+             exposure_target, NULL);
970
+             exposure_target, NULL);
971
+}
971
+}
972
+
972
+
973
+static int vd55g1_apply_cold_start(struct vd55g1 *sensor)
973
+static int vd55g1_apply_cold_start(struct vd55g1 *sensor)
974
+{
974
+{
975
+    struct v4l2_subdev_state *state =
975
+    struct v4l2_subdev_state *state =
976
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
976
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
977
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
977
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
978
+
978
+
979
+    /*
979
+    /*
980
+     * Cold start register is a single register expressed as exposure time
980
+     * Cold start register is a single register expressed as exposure time
981
+     * in us. This differ from status registers being a combination of
981
+     * in us. This differ from status registers being a combination of
982
+     * exposure, digital gain, and analog gain, requiring the following
982
+     * exposure, digital gain, and analog gain, requiring the following
983
+     * format conversion.
983
+     * format conversion.
984
+     */
984
+     */
985
+    unsigned int line_length = crop->width + sensor->hblank_ctrl->val;
985
+    unsigned int line_length = crop->width + sensor->hblank_ctrl->val;
986
+    unsigned int line_time_us = DIV_ROUND_UP(line_length * MEGA,
986
+    unsigned int line_time_us = DIV_ROUND_UP(line_length * MEGA,
987
+                         sensor->pixel_clock);
987
+                         sensor->pixel_clock);
988
+    u8 d_gain = DIV_ROUND_CLOSEST(sensor->dgain_ctrl->val, 1 << 8);
988
+    u8 d_gain = DIV_ROUND_CLOSEST(sensor->dgain_ctrl->val, 1 << 8);
989
+    u8 a_gain = DIV_ROUND_CLOSEST(32, (32 - sensor->again_ctrl->val));
989
+    u8 a_gain = DIV_ROUND_CLOSEST(32, (32 - sensor->again_ctrl->val));
990
+    unsigned int expo_us = sensor->expo_ctrl->val * d_gain * a_gain *
990
+    unsigned int expo_us = sensor->expo_ctrl->val * d_gain * a_gain *
991
+             line_time_us;
991
+             line_time_us;
992
+    int ret = 0;
992
+    int ret = 0;
993
+
993
+
994
+    vd55g1_write(sensor, VD55G1_REG_AE_FORCE_COLDSTART, 1, &ret);
994
+    vd55g1_write(sensor, VD55G1_REG_AE_FORCE_COLDSTART, 1, &ret);
995
+    vd55g1_write(sensor, VD55G1_REG_AE_COLDSTART_EXP_TIME, expo_us, &ret);
995
+    vd55g1_write(sensor, VD55G1_REG_AE_COLDSTART_EXP_TIME, expo_us, &ret);
996
+
996
+
997
+    return ret;
997
+    return ret;
998
+}
998
+}
999
+
999
+
1000
+static void vd55g1_update_img_pad_format(struct vd55g1 *sensor,
1000
+static void vd55g1_update_img_pad_format(struct vd55g1 *sensor,
1001
+                     const struct vd55g1_mode *mode,
1001
+                     const struct vd55g1_mode *mode,
1002
+                     u32 code,
1002
+                     u32 code,
1003
+                     struct v4l2_mbus_framefmt *fmt)
1003
+                     struct v4l2_mbus_framefmt *fmt)
1004
+{
1004
+{
1005
+    fmt->code = code;
1005
+    fmt->code = code;
1006
+    fmt->width = mode->width;
1006
+    fmt->width = mode->width;
1007
+    fmt->height = mode->height;
1007
+    fmt->height = mode->height;
1008
+    fmt->colorspace = V4L2_COLORSPACE_RAW;
1008
+    fmt->colorspace = V4L2_COLORSPACE_RAW;
1009
+    fmt->field = V4L2_FIELD_NONE;
1009
+    fmt->field = V4L2_FIELD_NONE;
1010
+    fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1010
+    fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1011
+    fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
1011
+    fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
1012
+    fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1012
+    fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1013
+}
1013
+}
1014
+
1014
+
1015
+static int vd55g1_update_hdr_mode(struct vd55g1 *sensor)
1015
+static int vd55g1_update_hdr_mode(struct vd55g1 *sensor)
1016
+{
1016
+{
1017
+    int ret = 0;
1017
+    int ret = 0;
1018
+
1018
+
1019
+    switch (sensor->hdr_ctrl->val) {
1019
+    switch (sensor->hdr_ctrl->val) {
1020
+    case VD55G1_NO_HDR:
1020
+    case VD55G1_NO_HDR:
1021
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
1021
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
1022
+             VD55G1_EXPOSURE_MAX_COARSE_DEF, &ret);
1022
+             VD55G1_EXPOSURE_MAX_COARSE_DEF, &ret);
1023
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES, 0, &ret);
1023
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES, 0, &ret);
1024
+        vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0, &ret);
1024
+        vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0, &ret);
1025
+
1025
+
1026
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 0, &ret);
1026
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 0, &ret);
1027
+
1027
+
1028
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
1028
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
1029
+             VD55G1_VT_MODE_NORMAL, &ret);
1029
+             VD55G1_VT_MODE_NORMAL, &ret);
1030
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
1030
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
1031
+             VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
1031
+             VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
1032
+        break;
1032
+        break;
1033
+    case VD55G1_HDR_SUB:
1033
+    case VD55G1_HDR_SUB:
1034
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
1034
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
1035
+             VD55G1_EXPOSURE_MAX_COARSE_SUB, &ret);
1035
+             VD55G1_EXPOSURE_MAX_COARSE_SUB, &ret);
1036
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES,
1036
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES,
1037
+             VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT, &ret);
1037
+             VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT, &ret);
1038
+        vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0001, &ret);
1038
+        vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0001, &ret);
1039
+
1039
+
1040
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 1, &ret);
1040
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 1, &ret);
1041
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX1, 1, &ret);
1041
+        vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX1, 1, &ret);
1042
+
1042
+
1043
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
1043
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
1044
+             VD55G1_VT_MODE_NORMAL, &ret);
1044
+             VD55G1_VT_MODE_NORMAL, &ret);
1045
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
1045
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
1046
+             VD55G1_MASK_FRAME_CTRL_MASK, &ret);
1046
+             VD55G1_MASK_FRAME_CTRL_MASK, &ret);
1047
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(0), 0, &ret);
1047
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(0), 0, &ret);
1048
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(1),
1048
+        vd55g1_write(sensor, VD55G1_REG_VT_MODE(1),
1049
+             VD55G1_VT_MODE_SUBTRACTION, &ret);
1049
+             VD55G1_VT_MODE_SUBTRACTION, &ret);
1050
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(1),
1050
+        vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(1),
1051
+             VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
1051
+             VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
1052
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(1), 1, &ret);
1052
+        vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(1), 1, &ret);
1053
+        break;
1053
+        break;
1054
+    default:
1054
+    default:
1055
+        ret = -EINVAL;
1055
+        ret = -EINVAL;
1056
+    }
1056
+    }
1057
+
1057
+
1058
+    return ret;
1058
+    return ret;
1059
+}
1059
+}
1060
+
1060
+
1061
+static int vd55g1_set_framefmt(struct vd55g1 *sensor)
1061
+static int vd55g1_set_framefmt(struct vd55g1 *sensor)
1062
+{
1062
+{
1063
+    struct v4l2_subdev_state *state =
1063
+    struct v4l2_subdev_state *state =
1064
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1064
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1065
+    const struct v4l2_rect *crop =
1065
+    const struct v4l2_rect *crop =
1066
+        v4l2_subdev_state_get_crop(state, 0);
1066
+        v4l2_subdev_state_get_crop(state, 0);
1067
+    const struct v4l2_mbus_framefmt *format =
1067
+    const struct v4l2_mbus_framefmt *format =
1068
+        v4l2_subdev_state_get_format(state, 0);
1068
+        v4l2_subdev_state_get_format(state, 0);
1069
+    enum vd55g1_bin_mode binning;
1069
+    enum vd55g1_bin_mode binning;
1070
+    int ret = 0;
1070
+    int ret = 0;
1071
+
1071
+
1072
+    vd55g1_write(sensor, VD55G1_REG_FORMAT_CTRL,
1072
+    vd55g1_write(sensor, VD55G1_REG_FORMAT_CTRL,
1073
+         get_bpp_by_code(sensor, format->code), &ret);
1073
+         get_bpp_by_code(sensor, format->code), &ret);
1074
+    vd55g1_write(sensor, VD55G1_REG_OIF_IMG_CTRL,
1074
+    vd55g1_write(sensor, VD55G1_REG_OIF_IMG_CTRL,
1075
+         get_data_type_by_code(sensor, format->code), &ret);
1075
+         get_data_type_by_code(sensor, format->code), &ret);
1076
+
1076
+
1077
+    switch (crop->width / format->width) {
1077
+    switch (crop->width / format->width) {
1078
+    case 1:
1078
+    case 1:
1079
+    default:
1079
+    default:
1080
+        binning = VD55G1_BIN_MODE_NORMAL;
1080
+        binning = VD55G1_BIN_MODE_NORMAL;
1081
+        break;
1081
+        break;
1082
+    case 2:
1082
+    case 2:
1083
+        binning = VD55G1_BIN_MODE_DIGITAL_X2;
1083
+        binning = VD55G1_BIN_MODE_DIGITAL_X2;
1084
+        break;
1084
+        break;
1085
+    }
1085
+    }
1086
+    vd55g1_write(sensor, VD55G1_REG_READOUT_CTRL, binning, &ret);
1086
+    vd55g1_write(sensor, VD55G1_REG_READOUT_CTRL, binning, &ret);
1087
+
1087
+
1088
+    vd55g1_write(sensor, VD55G1_REG_X_START(0), crop->left, &ret);
1088
+    vd55g1_write(sensor, VD55G1_REG_X_START(0), crop->left, &ret);
1089
+    vd55g1_write(sensor, VD55G1_REG_X_WIDTH(0), crop->width, &ret);
1089
+    vd55g1_write(sensor, VD55G1_REG_X_WIDTH(0), crop->width, &ret);
1090
+    vd55g1_write(sensor, VD55G1_REG_Y_START(0), crop->top, &ret);
1090
+    vd55g1_write(sensor, VD55G1_REG_Y_START(0), crop->top, &ret);
1091
+    vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(0), crop->height, &ret);
1091
+    vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(0), crop->height, &ret);
1092
+
1092
+
1093
+    vd55g1_write(sensor, VD55G1_REG_X_START(1), crop->left, &ret);
1093
+    vd55g1_write(sensor, VD55G1_REG_X_START(1), crop->left, &ret);
1094
+    vd55g1_write(sensor, VD55G1_REG_X_WIDTH(1), crop->width, &ret);
1094
+    vd55g1_write(sensor, VD55G1_REG_X_WIDTH(1), crop->width, &ret);
1095
+    vd55g1_write(sensor, VD55G1_REG_Y_START(1), crop->top, &ret);
1095
+    vd55g1_write(sensor, VD55G1_REG_Y_START(1), crop->top, &ret);
1096
+    vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(1), crop->height, &ret);
1096
+    vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(1), crop->height, &ret);
1097
+
1097
+
1098
+    return ret;
1098
+    return ret;
1099
+}
1099
+}
1100
+
1100
+
1101
+static int vd55g1_update_gpios(struct vd55g1 *sensor, unsigned long gpio_mask)
1101
+static int vd55g1_update_gpios(struct vd55g1 *sensor, unsigned long gpio_mask)
1102
+{
1102
+{
1103
+    unsigned long io;
1103
+    unsigned long io;
1104
+    u32 gpio_val;
1104
+    u32 gpio_val;
1105
+    int ret = 0;
1105
+    int ret = 0;
1106
+
1106
+
1107
+    for_each_set_bit(io, &gpio_mask, VD55G1_NB_GPIOS) {
1107
+    for_each_set_bit(io, &gpio_mask, VD55G1_NB_GPIOS) {
1108
+        gpio_val = sensor->gpios[io];
1108
+        gpio_val = sensor->gpios[io];
1109
+
1109
+
1110
+        if (gpio_val == VD55G1_GPIO_MODE_STROBE &&
1110
+        if (gpio_val == VD55G1_GPIO_MODE_STROBE &&
1111
+         sensor->led_ctrl->val == V4L2_FLASH_LED_MODE_NONE) {
1111
+         sensor->led_ctrl->val == V4L2_FLASH_LED_MODE_NONE) {
1112
+            gpio_val = VD55G1_GPIO_MODE_IN;
1112
+            gpio_val = VD55G1_GPIO_MODE_IN;
1113
+            if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB) {
1113
+            if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB) {
1114
+                /* Make its context 1 counterpart strobe too */
1114
+                /* Make its context 1 counterpart strobe too */
1115
+                vd55g1_write(sensor,
1115
+                vd55g1_write(sensor,
1116
+                     VD55G1_REG_GPIO_0_CTRL(1) + io,
1116
+                     VD55G1_REG_GPIO_0_CTRL(1) + io,
1117
+                     gpio_val, &ret);
1117
+                     gpio_val, &ret);
1118
+            }
1118
+            }
1119
+        }
1119
+        }
1120
+
1120
+
1121
+        ret = vd55g1_write(sensor, VD55G1_REG_GPIO_0_CTRL(0) + io,
1121
+        ret = vd55g1_write(sensor, VD55G1_REG_GPIO_0_CTRL(0) + io,
1122
+                 gpio_val, &ret);
1122
+                 gpio_val, &ret);
1123
+    }
1123
+    }
1124
+
1124
+
1125
+    return ret;
1125
+    return ret;
1126
+}
1126
+}
1127
+
1127
+
1128
+static int vd55g1_ro_ctrls_setup(struct vd55g1 *sensor)
1128
+static int vd55g1_ro_ctrls_setup(struct vd55g1 *sensor)
1129
+{
1129
+{
1130
+    struct v4l2_subdev_state *state =
1130
+    struct v4l2_subdev_state *state =
1131
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1131
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1132
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1132
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1133
+
1133
+
1134
+    return vd55g1_write(sensor, VD55G1_REG_LINE_LENGTH,
1134
+    return vd55g1_write(sensor, VD55G1_REG_LINE_LENGTH,
1135
+             crop->width + sensor->hblank_ctrl->val, NULL);
1135
+             crop->width + sensor->hblank_ctrl->val, NULL);
1136
+}
1136
+}
1137
+
1137
+
1138
+static void vd55g1_lock_ctrls(struct vd55g1 *sensor, bool enable)
1138
+static void vd55g1_lock_ctrls(struct vd55g1 *sensor, bool enable)
1139
+{
1139
+{
1140
+    /* These settings cannot change during stream */
1140
+    /* These settings cannot change during stream */
1141
+    v4l2_ctrl_grab(sensor->hflip_ctrl, enable);
1141
+    v4l2_ctrl_grab(sensor->hflip_ctrl, enable);
1142
+    v4l2_ctrl_grab(sensor->vflip_ctrl, enable);
1142
+    v4l2_ctrl_grab(sensor->vflip_ctrl, enable);
1143
+    v4l2_ctrl_grab(sensor->patgen_ctrl, enable);
1143
+    v4l2_ctrl_grab(sensor->patgen_ctrl, enable);
1144
+    v4l2_ctrl_grab(sensor->hdr_ctrl, enable);
1144
+    v4l2_ctrl_grab(sensor->hdr_ctrl, enable);
1145
+    v4l2_ctrl_grab(sensor->hblank_ctrl, enable);
1145
+    v4l2_ctrl_grab(sensor->hblank_ctrl, enable);
1146
+}
1146
+}
1147
+
1147
+
1148
+static int vd55g1_enable_streams(struct v4l2_subdev *sd,
1148
+static int vd55g1_enable_streams(struct v4l2_subdev *sd,
1149
+                 struct v4l2_subdev_state *state, u32 pad,
1149
+                 struct v4l2_subdev_state *state, u32 pad,
1150
+                 u64 streams_mask)
1150
+                 u64 streams_mask)
1151
+{
1151
+{
1152
+    struct vd55g1 *sensor = to_vd55g1(sd);
1152
+    struct vd55g1 *sensor = to_vd55g1(sd);
1153
+    struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
1153
+    struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
1154
+    int ret = 0;
1154
+    int ret = 0;
1155
+
1155
+
1156
+    ret = pm_runtime_resume_and_get(&client->dev);
1156
+    ret = pm_runtime_resume_and_get(&client->dev);
1157
+    if (ret < 0)
1157
+    if (ret < 0)
1158
+        return ret;
1158
+        return ret;
1159
+
1159
+
1160
+    vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1160
+    vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1161
+
1161
+
1162
+    /* configure output */
1162
+    /* configure output */
1163
+    vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,
1163
+    vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,
1164
+         sensor->data_rate_in_mbps, &ret);
1164
+         sensor->data_rate_in_mbps, &ret);
1165
+    vd55g1_write(sensor, VD55G1_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
1165
+    vd55g1_write(sensor, VD55G1_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
1166
+    vd55g1_write(sensor, VD55G1_REG_ISL_ENABLE, 0, &ret);
1166
+    vd55g1_write(sensor, VD55G1_REG_ISL_ENABLE, 0, &ret);
1167
+    if (ret)
1167
+    if (ret)
1168
+        goto err_rpm_put;
1168
+        goto err_rpm_put;
1169
+
1169
+
1170
+    ret = vd55g1_set_framefmt(sensor);
1170
+    ret = vd55g1_set_framefmt(sensor);
1171
+    if (ret)
1171
+    if (ret)
1172
+        goto err_rpm_put;
1172
+        goto err_rpm_put;
1173
+
1173
+
1174
+    /* Setup default GPIO values; could be overridden by V4L2 ctrl setup */
1174
+    /* Setup default GPIO values; could be overridden by V4L2 ctrl setup */
1175
+    ret = vd55g1_update_gpios(sensor, GENMASK(VD55G1_NB_GPIOS - 1, 0));
1175
+    ret = vd55g1_update_gpios(sensor, GENMASK(VD55G1_NB_GPIOS - 1, 0));
1176
+    if (ret)
1176
+    if (ret)
1177
+        goto err_rpm_put;
1177
+        goto err_rpm_put;
1178
+
1178
+
1179
+    ret = vd55g1_apply_cold_start(sensor);
1179
+    ret = vd55g1_apply_cold_start(sensor);
1180
+    if (ret)
1180
+    if (ret)
1181
+        goto err_rpm_put;
1181
+        goto err_rpm_put;
1182
+
1182
+
1183
+    /* Apply settings from V4L2 ctrls */
1183
+    /* Apply settings from V4L2 ctrls */
1184
+    ret = __v4l2_ctrl_handler_setup(&sensor->ctrl_handler);
1184
+    ret = __v4l2_ctrl_handler_setup(&sensor->ctrl_handler);
1185
+    if (ret)
1185
+    if (ret)
1186
+        goto err_rpm_put;
1186
+        goto err_rpm_put;
1187
+
1187
+
1188
+    /* Also apply settings from read-only V4L2 ctrls */
1188
+    /* Also apply settings from read-only V4L2 ctrls */
1189
+    ret = vd55g1_ro_ctrls_setup(sensor);
1189
+    ret = vd55g1_ro_ctrls_setup(sensor);
1190
+    if (ret)
1190
+    if (ret)
1191
+        goto err_rpm_put;
1191
+        goto err_rpm_put;
1192
+
1192
+
1193
+    /* Start streaming */
1193
+    /* Start streaming */
1194
+    vd55g1_write(sensor, VD55G1_REG_STBY, VD55G1_STBY_START_STREAM, &ret);
1194
+    vd55g1_write(sensor, VD55G1_REG_STBY, VD55G1_STBY_START_STREAM, &ret);
1195
+    vd55g1_poll_reg(sensor, VD55G1_REG_STBY, 0, &ret);
1195
+    vd55g1_poll_reg(sensor, VD55G1_REG_STBY, 0, &ret);
1196
+    vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_STREAMING, &ret);
1196
+    vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_STREAMING, &ret);
1197
+    if (ret)
1197
+    if (ret)
1198
+        goto err_rpm_put;
1198
+        goto err_rpm_put;
1199
+
1199
+
1200
+    vd55g1_lock_ctrls(sensor, true);
1200
+    vd55g1_lock_ctrls(sensor, true);
1201
+
1201
+
1202
+    return ret;
1202
+    return ret;
1203
+
1203
+
1204
+err_rpm_put:
1204
+err_rpm_put:
1205
+    pm_runtime_put(&client->dev);
1205
+    pm_runtime_put(&client->dev);
1206
+    return ret;
1206
+    return ret;
1207
+}
1207
+}
1208
+
1208
+
1209
+static int vd55g1_disable_streams(struct v4l2_subdev *sd,
1209
+static int vd55g1_disable_streams(struct v4l2_subdev *sd,
1210
+                 struct v4l2_subdev_state *state, u32 pad,
1210
+                 struct v4l2_subdev_state *state, u32 pad,
1211
+                 u64 streams_mask)
1211
+                 u64 streams_mask)
1212
+{
1212
+{
1213
+    struct vd55g1 *sensor = to_vd55g1(sd);
1213
+    struct vd55g1 *sensor = to_vd55g1(sd);
1214
+    struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
1214
+    struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
1215
+    int ret = 0;
1215
+    int ret = 0;
1216
+
1216
+
1217
+    /* Retrieve Expo cluster to enable coldstart of AE */
1217
+    /* Retrieve Expo cluster to enable coldstart of AE */
1218
+    ret = vd55g1_read_expo_cluster(sensor);
1218
+    ret = vd55g1_read_expo_cluster(sensor);
1219
+
1219
+
1220
+    vd55g1_write(sensor, VD55G1_REG_STREAMING, VD55G1_STREAMING_STOP_STREAM,
1220
+    vd55g1_write(sensor, VD55G1_REG_STREAMING, VD55G1_STREAMING_STOP_STREAM,
1221
+         &ret);
1221
+         &ret);
1222
+    vd55g1_poll_reg(sensor, VD55G1_REG_STREAMING, 0, &ret);
1222
+    vd55g1_poll_reg(sensor, VD55G1_REG_STREAMING, 0, &ret);
1223
+    vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, &ret);
1223
+    vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, &ret);
1224
+
1224
+
1225
+    if (ret)
1225
+    if (ret)
1226
+        dev_warn(&client->dev, "Can't disable stream");
1226
+        dev_warn(&client->dev, "Can't disable stream");
1227
+
1227
+
1228
+    vd55g1_lock_ctrls(sensor, false);
1228
+    vd55g1_lock_ctrls(sensor, false);
1229
+
1229
+
1230
+    pm_runtime_mark_last_busy(&client->dev);
1230
+    pm_runtime_mark_last_busy(&client->dev);
1231
+    __pm_runtime_put_autosuspend(&client->dev);
1231
+    __pm_runtime_put_autosuspend(&client->dev);
1232
+
1232
+
1233
+    return ret;
1233
+    return ret;
1234
+}
1234
+}
1235
+
1235
+
1236
+static int vd55g1_patch(struct vd55g1 *sensor)
1236
+static int vd55g1_patch(struct vd55g1 *sensor)
1237
+{
1237
+{
1238
+    struct i2c_client *client = sensor->i2c_client;
1238
+    struct i2c_client *client = sensor->i2c_client;
1239
+    u64 patch;
1239
+    u64 patch;
1240
+    int ret = 0;
1240
+    int ret = 0;
1241
+
1241
+
1242
+    vd55g1_write_array(sensor, VD55G1_REG_FWPATCH_START_ADDR,
1242
+    vd55g1_write_array(sensor, VD55G1_REG_FWPATCH_START_ADDR,
1243
+             sizeof(patch_array), patch_array, &ret);
1243
+             sizeof(patch_array), patch_array, &ret);
1244
+    vd55g1_write(sensor, VD55G1_REG_BOOT, VD55G1_BOOT_PATCH_SETUP, &ret);
1244
+    vd55g1_write(sensor, VD55G1_REG_BOOT, VD55G1_BOOT_PATCH_SETUP, &ret);
1245
+    vd55g1_poll_reg(sensor, VD55G1_REG_BOOT, 0, &ret);
1245
+    vd55g1_poll_reg(sensor, VD55G1_REG_BOOT, 0, &ret);
1246
+    if (ret) {
1246
+    if (ret) {
1247
+        dev_err(&client->dev, "Failed to apply patch");
1247
+        dev_err(&client->dev, "Failed to apply patch");
1248
+        return ret;
1248
+        return ret;
1249
+    }
1249
+    }
1250
+
1250
+
1251
+    vd55g1_read(sensor, VD55G1_REG_FWPATCH_REVISION, &patch, &ret);
1251
+    vd55g1_read(sensor, VD55G1_REG_FWPATCH_REVISION, &patch, &ret);
1252
+    if (patch != (VD55G1_FWPATCH_REVISION_MAJOR << 8) +
1252
+    if (patch != (VD55G1_FWPATCH_REVISION_MAJOR << 8) +
1253
+     VD55G1_FWPATCH_REVISION_MINOR) {
1253
+     VD55G1_FWPATCH_REVISION_MINOR) {
1254
+        dev_err(&client->dev, "Bad patch version expected %d.%d got %d.%d",
1254
+        dev_err(&client->dev, "Bad patch version expected %d.%d got %d.%d",
1255
+            VD55G1_FWPATCH_REVISION_MAJOR,
1255
+            VD55G1_FWPATCH_REVISION_MAJOR,
1256
+            VD55G1_FWPATCH_REVISION_MINOR,
1256
+            VD55G1_FWPATCH_REVISION_MINOR,
1257
+            (u8)(patch >> 8), (u8)(patch & 0xff));
1257
+            (u8)(patch >> 8), (u8)(patch & 0xff));
1258
+        return -ENODEV;
1258
+        return -ENODEV;
1259
+    }
1259
+    }
1260
+    dev_dbg(&client->dev, "patch %d.%d applied",
1260
+    dev_dbg(&client->dev, "patch %d.%d applied",
1261
+        (u8)(patch >> 8), (u8)(patch & 0xff));
1261
+        (u8)(patch >> 8), (u8)(patch & 0xff));
1262
+
1262
+
1263
+    return 0;
1263
+    return 0;
1264
+}
1264
+}
1265
+
1265
+
1266
+static int vd55g1_get_selection(struct v4l2_subdev *sd,
1266
+static int vd55g1_get_selection(struct v4l2_subdev *sd,
1267
+                struct v4l2_subdev_state *sd_state,
1267
+                struct v4l2_subdev_state *sd_state,
1268
+                struct v4l2_subdev_selection *sel)
1268
+                struct v4l2_subdev_selection *sel)
1269
+{
1269
+{
1270
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(sd_state, 0);
1270
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(sd_state, 0);
1271
+
1271
+
1272
+    switch (sel->target) {
1272
+    switch (sel->target) {
1273
+    case V4L2_SEL_TGT_CROP:
1273
+    case V4L2_SEL_TGT_CROP:
1274
+        sel->r = *crop;
1274
+        sel->r = *crop;
1275
+        return 0;
1275
+        return 0;
1276
+    case V4L2_SEL_TGT_NATIVE_SIZE:
1276
+    case V4L2_SEL_TGT_NATIVE_SIZE:
1277
+    case V4L2_SEL_TGT_CROP_DEFAULT:
1277
+    case V4L2_SEL_TGT_CROP_DEFAULT:
1278
+    case V4L2_SEL_TGT_CROP_BOUNDS:
1278
+    case V4L2_SEL_TGT_CROP_BOUNDS:
1279
+        sel->r.top = 0;
1279
+        sel->r.top = 0;
1280
+        sel->r.left = 0;
1280
+        sel->r.left = 0;
1281
+        sel->r.width = VD55G1_WIDTH;
1281
+        sel->r.width = VD55G1_WIDTH;
1282
+        sel->r.height = VD55G1_HEIGHT;
1282
+        sel->r.height = VD55G1_HEIGHT;
1283
+        return 0;
1283
+        return 0;
1284
+    }
1284
+    }
1285
+
1285
+
1286
+    return -EINVAL;
1286
+    return -EINVAL;
1287
+}
1287
+}
1288
+
1288
+
1289
+static int vd55g1_enum_mbus_code(struct v4l2_subdev *sd,
1289
+static int vd55g1_enum_mbus_code(struct v4l2_subdev *sd,
1290
+                 struct v4l2_subdev_state *sd_state,
1290
+                 struct v4l2_subdev_state *sd_state,
1291
+                 struct v4l2_subdev_mbus_code_enum *code)
1291
+                 struct v4l2_subdev_mbus_code_enum *code)
1292
+{
1292
+{
1293
+    if (code->index >= ARRAY_SIZE(vd55g1_mbus_codes))
1293
+    if (code->index >= ARRAY_SIZE(vd55g1_mbus_codes))
1294
+        return -EINVAL;
1294
+        return -EINVAL;
1295
+
1295
+
1296
+    code->code = vd55g1_mbus_codes[code->index].code;
1296
+    code->code = vd55g1_mbus_codes[code->index].code;
1297
+
1297
+
1298
+    return 0;
1298
+    return 0;
1299
+}
1299
+}
1300
+
1300
+
1301
+static int vd55g1_new_format_change_controls(struct vd55g1 *sensor)
1301
+static int vd55g1_new_format_change_controls(struct vd55g1 *sensor)
1302
+{
1302
+{
1303
+    struct v4l2_subdev_state *state =
1303
+    struct v4l2_subdev_state *state =
1304
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1304
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1305
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1305
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1306
+    struct vblank_limits vblank;
1306
+    struct vblank_limits vblank;
1307
+    unsigned int hblank;
1307
+    unsigned int hblank;
1308
+    unsigned int frame_length = 0;
1308
+    unsigned int frame_length = 0;
1309
+    unsigned int expo_max;
1309
+    unsigned int expo_max;
1310
+    int ret;
1310
+    int ret;
1311
+
1311
+
1312
+    /* Reset vblank and frame length to default */
1312
+    /* Reset vblank and frame length to default */
1313
+    vblank = get_vblank_limits(sensor);
1313
+    vblank = get_vblank_limits(sensor);
1314
+    ret = __v4l2_ctrl_modify_range(sensor->vblank_ctrl, vblank.min,
1314
+    ret = __v4l2_ctrl_modify_range(sensor->vblank_ctrl, vblank.min,
1315
+                 vblank.max, 1, vblank.def);
1315
+                 vblank.max, 1, vblank.def);
1316
+    if (ret)
1316
+    if (ret)
1317
+        return ret;
1317
+        return ret;
1318
+
1318
+
1319
+    /* Max exposure changes with vblank */
1319
+    /* Max exposure changes with vblank */
1320
+    frame_length = crop->height + sensor->vblank_ctrl->val;
1320
+    frame_length = crop->height + sensor->vblank_ctrl->val;
1321
+    expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1321
+    expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1322
+    ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max, 1,
1322
+    ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max, 1,
1323
+                 VD55G1_EXPO_DEF);
1323
+                 VD55G1_EXPO_DEF);
1324
+    if (ret)
1324
+    if (ret)
1325
+        return ret;
1325
+        return ret;
1326
+
1326
+
1327
+    /* Update pixel rate to reflect new bpp */
1327
+    /* Update pixel rate to reflect new bpp */
1328
+    ret = __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl,
1328
+    ret = __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl,
1329
+                 get_pixel_rate(sensor));
1329
+                 get_pixel_rate(sensor));
1330
+    if (ret)
1330
+    if (ret)
1331
+        return ret;
1331
+        return ret;
1332
+
1332
+
1333
+    /* Update hblank according to new width */
1333
+    /* Update hblank according to new width */
1334
+    hblank = get_hblank_min(sensor);
1334
+    hblank = get_hblank_min(sensor);
1335
+    ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl, hblank, hblank, 1,
1335
+    ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl, hblank, hblank, 1,
1336
+                 hblank);
1336
+                 hblank);
1337
+
1337
+
1338
+    return ret;
1338
+    return ret;
1339
+}
1339
+}
1340
+
1340
+
1341
+static int vd55g1_set_pad_fmt(struct v4l2_subdev *sd,
1341
+static int vd55g1_set_pad_fmt(struct v4l2_subdev *sd,
1342
+             struct v4l2_subdev_state *sd_state,
1342
+             struct v4l2_subdev_state *sd_state,
1343
+             struct v4l2_subdev_format *sd_fmt)
1343
+             struct v4l2_subdev_format *sd_fmt)
1344
+{
1344
+{
1345
+    struct vd55g1 *sensor = to_vd55g1(sd);
1345
+    struct vd55g1 *sensor = to_vd55g1(sd);
1346
+    const struct vd55g1_mode *new_mode;
1346
+    const struct vd55g1_mode *new_mode;
1347
+    struct v4l2_mbus_framefmt *format;
1347
+    struct v4l2_mbus_framefmt *format;
1348
+    struct v4l2_rect pad_crop;
1348
+    struct v4l2_rect pad_crop;
1349
+    unsigned int binning;
1349
+    unsigned int binning;
1350
+
1350
+
1351
+    new_mode = v4l2_find_nearest_size(vd55g1_supported_modes,
1351
+    new_mode = v4l2_find_nearest_size(vd55g1_supported_modes,
1352
+                     ARRAY_SIZE(vd55g1_supported_modes),
1352
+                     ARRAY_SIZE(vd55g1_supported_modes),
1353
+                     width, height, sd_fmt->format.width,
1353
+                     width, height, sd_fmt->format.width,
1354
+                     sd_fmt->format.height);
1354
+                     sd_fmt->format.height);
1355
+
1355
+
1356
+    vd55g1_update_img_pad_format(sensor, new_mode, sd_fmt->format.code,
1356
+    vd55g1_update_img_pad_format(sensor, new_mode, sd_fmt->format.code,
1357
+                 &sd_fmt->format);
1357
+                 &sd_fmt->format);
1358
+
1358
+
1359
+    /*
1359
+    /*
1360
+     * Use binning to maximize the crop rectangle size, and centre it in the
1360
+     * Use binning to maximize the crop rectangle size, and centre it in the
1361
+     * sensor.
1361
+     * sensor.
1362
+     */
1362
+     */
1363
+    binning = min(VD55G1_WIDTH / sd_fmt->format.width,
1363
+    binning = min(VD55G1_WIDTH / sd_fmt->format.width,
1364
+         VD55G1_HEIGHT / sd_fmt->format.height);
1364
+         VD55G1_HEIGHT / sd_fmt->format.height);
1365
+    binning = min(binning, 2U);
1365
+    binning = min(binning, 2U);
1366
+    pad_crop.width = sd_fmt->format.width * binning;
1366
+    pad_crop.width = sd_fmt->format.width * binning;
1367
+    pad_crop.height = sd_fmt->format.height * binning;
1367
+    pad_crop.height = sd_fmt->format.height * binning;
1368
+    pad_crop.left = (VD55G1_WIDTH - pad_crop.width) / 2;
1368
+    pad_crop.left = (VD55G1_WIDTH - pad_crop.width) / 2;
1369
+    pad_crop.top = (VD55G1_HEIGHT - pad_crop.height) / 2;
1369
+    pad_crop.top = (VD55G1_HEIGHT - pad_crop.height) / 2;
1370
+
1370
+
1371
+    format = v4l2_subdev_state_get_format(sd_state, sd_fmt->pad);
1371
+    format = v4l2_subdev_state_get_format(sd_state, sd_fmt->pad);
1372
+
1372
+
1373
+    *format = sd_fmt->format;
1373
+    *format = sd_fmt->format;
1374
+
1374
+
1375
+    *v4l2_subdev_state_get_crop(sd_state, sd_fmt->pad) = pad_crop;
1375
+    *v4l2_subdev_state_get_crop(sd_state, sd_fmt->pad) = pad_crop;
1376
+    if (sd_fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1376
+    if (sd_fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1377
+        return vd55g1_new_format_change_controls(sensor);
1377
+        return vd55g1_new_format_change_controls(sensor);
1378
+
1378
+
1379
+    return 0;
1379
+    return 0;
1380
+}
1380
+}
1381
+
1381
+
1382
+static int vd55g1_init_state(struct v4l2_subdev *sd,
1382
+static int vd55g1_init_state(struct v4l2_subdev *sd,
1383
+             struct v4l2_subdev_state *sd_state)
1383
+             struct v4l2_subdev_state *sd_state)
1384
+{
1384
+{
1385
+    unsigned int def_mode = VD55G1_DEFAULT_MODE;
1385
+    unsigned int def_mode = VD55G1_DEFAULT_MODE;
1386
+    struct vd55g1 *sensor = to_vd55g1(sd);
1386
+    struct vd55g1 *sensor = to_vd55g1(sd);
1387
+    struct v4l2_subdev_format fmt = { 0 };
1387
+    struct v4l2_subdev_format fmt = { 0 };
1388
+    struct v4l2_subdev_route routes[] = { 0 };
1388
+    struct v4l2_subdev_route routes[] = { 0 };
1389
+    struct v4l2_subdev_krouting routing = {
1389
+    struct v4l2_subdev_krouting routing = {
1390
+     .num_routes = ARRAY_SIZE(routes),
1390
+     .num_routes = ARRAY_SIZE(routes),
1391
+     .routes = routes,
1391
+     .routes = routes,
1392
+    };
1392
+    };
1393
+    int ret;
1393
+    int ret;
1394
+
1394
+
1395
+    /* Needed by v4l2_subdev_s_stream_helper(), even with 1 stream only */
1395
+    /* Needed by v4l2_subdev_s_stream_helper(), even with 1 stream only */
1396
+    routes[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
1396
+    routes[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
1397
+    ret = v4l2_subdev_set_routing(sd, sd_state, &routing);
1397
+    ret = v4l2_subdev_set_routing(sd, sd_state, &routing);
1398
+    if (ret)
1398
+    if (ret)
1399
+        return ret;
1399
+        return ret;
1400
+
1400
+
1401
+    vd55g1_update_img_pad_format(sensor, &vd55g1_supported_modes[def_mode],
1401
+    vd55g1_update_img_pad_format(sensor, &vd55g1_supported_modes[def_mode],
1402
+                 VD55G1_MEDIA_BUS_FMT_DEF, &fmt.format);
1402
+                 VD55G1_MEDIA_BUS_FMT_DEF, &fmt.format);
1403
+
1403
+
1404
+    return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
1404
+    return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
1405
+}
1405
+}
1406
+
1406
+
1407
+static int vd55g1_enum_frame_size(struct v4l2_subdev *sd,
1407
+static int vd55g1_enum_frame_size(struct v4l2_subdev *sd,
1408
+                 struct v4l2_subdev_state *sd_state,
1408
+                 struct v4l2_subdev_state *sd_state,
1409
+                 struct v4l2_subdev_frame_size_enum *fse)
1409
+                 struct v4l2_subdev_frame_size_enum *fse)
1410
+{
1410
+{
1411
+    if (fse->index >= ARRAY_SIZE(vd55g1_supported_modes))
1411
+    if (fse->index >= ARRAY_SIZE(vd55g1_supported_modes))
1412
+        return -EINVAL;
1412
+        return -EINVAL;
1413
+
1413
+
1414
+    fse->min_width = vd55g1_supported_modes[fse->index].width;
1414
+    fse->min_width = vd55g1_supported_modes[fse->index].width;
1415
+    fse->max_width = fse->min_width;
1415
+    fse->max_width = fse->min_width;
1416
+    fse->min_height = vd55g1_supported_modes[fse->index].height;
1416
+    fse->min_height = vd55g1_supported_modes[fse->index].height;
1417
+    fse->max_height = fse->min_height;
1417
+    fse->max_height = fse->min_height;
1418
+
1418
+
1419
+    return 0;
1419
+    return 0;
1420
+}
1420
+}
1421
+
1421
+
1422
+static const struct v4l2_subdev_internal_ops vd55g1_internal_ops = {
1422
+static const struct v4l2_subdev_internal_ops vd55g1_internal_ops = {
1423
+    .init_state = vd55g1_init_state,
1423
+    .init_state = vd55g1_init_state,
1424
+};
1424
+};
1425
+
1425
+
1426
+static const struct v4l2_subdev_pad_ops vd55g1_pad_ops = {
1426
+static const struct v4l2_subdev_pad_ops vd55g1_pad_ops = {
1427
+    .enum_mbus_code = vd55g1_enum_mbus_code,
1427
+    .enum_mbus_code = vd55g1_enum_mbus_code,
1428
+    .get_fmt = v4l2_subdev_get_fmt,
1428
+    .get_fmt = v4l2_subdev_get_fmt,
1429
+    .set_fmt = vd55g1_set_pad_fmt,
1429
+    .set_fmt = vd55g1_set_pad_fmt,
1430
+    .get_selection = vd55g1_get_selection,
1430
+    .get_selection = vd55g1_get_selection,
1431
+    .enum_frame_size = vd55g1_enum_frame_size,
1431
+    .enum_frame_size = vd55g1_enum_frame_size,
1432
+    .enable_streams = vd55g1_enable_streams,
1432
+    .enable_streams = vd55g1_enable_streams,
1433
+    .disable_streams = vd55g1_disable_streams,
1433
+    .disable_streams = vd55g1_disable_streams,
1434
+};
1434
+};
1435
+
1435
+
1436
+static const struct v4l2_subdev_video_ops vd55g1_video_ops = {
1436
+static const struct v4l2_subdev_video_ops vd55g1_video_ops = {
1437
+    .s_stream = v4l2_subdev_s_stream_helper,
1437
+    .s_stream = v4l2_subdev_s_stream_helper,
1438
+};
1438
+};
1439
+
1439
+
1440
+static const struct v4l2_subdev_ops vd55g1_subdev_ops = {
1440
+static const struct v4l2_subdev_ops vd55g1_subdev_ops = {
1441
+    .video = &vd55g1_video_ops,
1441
+    .video = &vd55g1_video_ops,
1442
+    .pad = &vd55g1_pad_ops,
1442
+    .pad = &vd55g1_pad_ops,
1443
+};
1443
+};
1444
+
1444
+
1445
+static int vd55g1_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1445
+static int vd55g1_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1446
+{
1446
+{
1447
+    struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1447
+    struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1448
+    struct vd55g1 *sensor = to_vd55g1(sd);
1448
+    struct vd55g1 *sensor = to_vd55g1(sd);
1449
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
1449
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
1450
+    int ret = 0;
1450
+    int ret = 0;
1451
+
1451
+
1452
+    /* Interact with HW only when it is powered ON */
1452
+    /* Interact with HW only when it is powered ON */
1453
+    if (!pm_runtime_get_if_in_use(&client->dev))
1453
+    if (!pm_runtime_get_if_in_use(&client->dev))
1454
+        return 0;
1454
+        return 0;
1455
+
1455
+
1456
+    switch (ctrl->id) {
1456
+    switch (ctrl->id) {
1457
+    case V4L2_CID_EXPOSURE_AUTO:
1457
+    case V4L2_CID_EXPOSURE_AUTO:
1458
+        ret = vd55g1_read_expo_cluster(sensor);
1458
+        ret = vd55g1_read_expo_cluster(sensor);
1459
+        break;
1459
+        break;
1460
+    default:
1460
+    default:
1461
+        ret = -EINVAL;
1461
+        ret = -EINVAL;
1462
+        break;
1462
+        break;
1463
+    }
1463
+    }
1464
+
1464
+
1465
+    pm_runtime_mark_last_busy(&client->dev);
1465
+    pm_runtime_mark_last_busy(&client->dev);
1466
+    pm_runtime_put_autosuspend(&client->dev);
1466
+    pm_runtime_put_autosuspend(&client->dev);
1467
+
1467
+
1468
+    return ret;
1468
+    return ret;
1469
+}
1469
+}
1470
+
1470
+
1471
+static int vd55g1_s_ctrl(struct v4l2_ctrl *ctrl)
1471
+static int vd55g1_s_ctrl(struct v4l2_ctrl *ctrl)
1472
+{
1472
+{
1473
+    struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1473
+    struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1474
+    struct vd55g1 *sensor = to_vd55g1(sd);
1474
+    struct vd55g1 *sensor = to_vd55g1(sd);
1475
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
1475
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
1476
+    unsigned int frame_length = 0;
1476
+    unsigned int frame_length = 0;
1477
+    unsigned int expo_max;
1477
+    unsigned int expo_max;
1478
+    unsigned int hblank = get_hblank_min(sensor);
1478
+    unsigned int hblank = get_hblank_min(sensor);
1479
+    bool is_auto = false;
1479
+    bool is_auto = false;
1480
+    struct v4l2_subdev_state *state =
1480
+    struct v4l2_subdev_state *state =
1481
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1481
+        v4l2_subdev_get_locked_active_state(&sensor->sd);
1482
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1482
+    const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
1483
+    int ret = 0;
1483
+    int ret = 0;
1484
+
1484
+
1485
+    if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
1485
+    if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
1486
+        return 0;
1486
+        return 0;
1487
+
1487
+
1488
+    /* Update controls state, range, etc. whatever the state of the HW */
1488
+    /* Update controls state, range, etc. whatever the state of the HW */
1489
+    switch (ctrl->id) {
1489
+    switch (ctrl->id) {
1490
+    case V4L2_CID_VBLANK:
1490
+    case V4L2_CID_VBLANK:
1491
+        frame_length = crop->height + ctrl->val;
1491
+        frame_length = crop->height + ctrl->val;
1492
+        expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1492
+        expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1493
+        ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max,
1493
+        ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max,
1494
+                     1, VD55G1_EXPO_DEF);
1494
+                     1, VD55G1_EXPO_DEF);
1495
+        break;
1495
+        break;
1496
+    case V4L2_CID_EXPOSURE_AUTO:
1496
+    case V4L2_CID_EXPOSURE_AUTO:
1497
+        is_auto = (ctrl->val == V4L2_EXPOSURE_AUTO);
1497
+        is_auto = (ctrl->val == V4L2_EXPOSURE_AUTO);
1498
+        __v4l2_ctrl_grab(sensor->ae_lock_ctrl, !is_auto);
1498
+        __v4l2_ctrl_grab(sensor->ae_lock_ctrl, !is_auto);
1499
+        __v4l2_ctrl_grab(sensor->ae_bias_ctrl, !is_auto);
1499
+        __v4l2_ctrl_grab(sensor->ae_bias_ctrl, !is_auto);
1500
+        break;
1500
+        break;
1501
+    case V4L2_CID_HDR_SENSOR_MODE:
1501
+    case V4L2_CID_HDR_SENSOR_MODE:
1502
+        /* Discriminate if the userspace changed the control value */
1502
+        /* Discriminate if the userspace changed the control value */
1503
+        if (ctrl->val != ctrl->cur.val) {
1503
+        if (ctrl->val != ctrl->cur.val) {
1504
+            /* Max horizontal blanking changes with hdr mode */
1504
+            /* Max horizontal blanking changes with hdr mode */
1505
+            ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl,
1505
+            ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl,
1506
+                         hblank, hblank, 1,
1506
+                         hblank, hblank, 1,
1507
+                         hblank);
1507
+                         hblank);
1508
+        }
1508
+        }
1509
+        break;
1509
+        break;
1510
+    default:
1510
+    default:
1511
+        break;
1511
+        break;
1512
+    }
1512
+    }
1513
+
1513
+
1514
+    /* Don't modify hardware if controls modification failed */
1514
+    /* Don't modify hardware if controls modification failed */
1515
+    if (ret)
1515
+    if (ret)
1516
+        return ret;
1516
+        return ret;
1517
+
1517
+
1518
+    /* Interact with HW only when it is powered ON */
1518
+    /* Interact with HW only when it is powered ON */
1519
+    if (!pm_runtime_get_if_in_use(&client->dev))
1519
+    if (!pm_runtime_get_if_in_use(&client->dev))
1520
+        return 0;
1520
+        return 0;
1521
+
1521
+
1522
+    switch (ctrl->id) {
1522
+    switch (ctrl->id) {
1523
+    case V4L2_CID_HFLIP:
1523
+    case V4L2_CID_HFLIP:
1524
+        ret = vd55g1_write(sensor, VD55G1_REG_ORIENTATION,
1524
+        ret = vd55g1_write(sensor, VD55G1_REG_ORIENTATION,
1525
+                 sensor->hflip_ctrl->val |
1525
+                 sensor->hflip_ctrl->val |
1526
+                     (sensor->vflip_ctrl->val << 1),
1526
+                     (sensor->vflip_ctrl->val << 1),
1527
+                 NULL);
1527
+                 NULL);
1528
+        break;
1528
+        break;
1529
+    case V4L2_CID_TEST_PATTERN:
1529
+    case V4L2_CID_TEST_PATTERN:
1530
+        ret = vd55g1_update_patgen(sensor, ctrl->val);
1530
+        ret = vd55g1_update_patgen(sensor, ctrl->val);
1531
+        break;
1531
+        break;
1532
+    case V4L2_CID_EXPOSURE_AUTO:
1532
+    case V4L2_CID_EXPOSURE_AUTO:
1533
+        ret = vd55g1_update_expo_cluster(sensor, is_auto);
1533
+        ret = vd55g1_update_expo_cluster(sensor, is_auto);
1534
+        break;
1534
+        break;
1535
+    case V4L2_CID_3A_LOCK:
1535
+    case V4L2_CID_3A_LOCK:
1536
+        ret = vd55g1_lock_exposure(sensor, ctrl->val);
1536
+        ret = vd55g1_lock_exposure(sensor, ctrl->val);
1537
+        break;
1537
+        break;
1538
+    case V4L2_CID_AUTO_EXPOSURE_BIAS:
1538
+    case V4L2_CID_AUTO_EXPOSURE_BIAS:
1539
+        /*
1539
+        /*
1540
+         * We use auto exposure target percentage register to control
1540
+         * We use auto exposure target percentage register to control
1541
+         * exposure bias for more precision.
1541
+         * exposure bias for more precision.
1542
+         */
1542
+         */
1543
+        ret = vd55g1_update_exposure_target(sensor, ctrl->val);
1543
+        ret = vd55g1_update_exposure_target(sensor, ctrl->val);
1544
+        break;
1544
+        break;
1545
+    case V4L2_CID_VBLANK:
1545
+    case V4L2_CID_VBLANK:
1546
+        ret = vd55g1_update_frame_length(sensor, frame_length);
1546
+        ret = vd55g1_update_frame_length(sensor, frame_length);
1547
+        break;
1547
+        break;
1548
+    case V4L2_CID_FLASH_LED_MODE:
1548
+    case V4L2_CID_FLASH_LED_MODE:
1549
+        ret = vd55g1_update_gpios(sensor, sensor->ext_leds_mask);
1549
+        ret = vd55g1_update_gpios(sensor, sensor->ext_leds_mask);
1550
+        break;
1550
+        break;
1551
+    case V4L2_CID_HDR_SENSOR_MODE:
1551
+    case V4L2_CID_HDR_SENSOR_MODE:
1552
+        ret = vd55g1_update_hdr_mode(sensor);
1552
+        ret = vd55g1_update_hdr_mode(sensor);
1553
+        break;
1553
+        break;
1554
+    default:
1554
+    default:
1555
+        ret = -EINVAL;
1555
+        ret = -EINVAL;
1556
+        break;
1556
+        break;
1557
+    }
1557
+    }
1558
+
1558
+
1559
+    pm_runtime_mark_last_busy(&client->dev);
1559
+    pm_runtime_mark_last_busy(&client->dev);
1560
+    pm_runtime_put_autosuspend(&client->dev);
1560
+    pm_runtime_put_autosuspend(&client->dev);
1561
+
1561
+
1562
+    return ret;
1562
+    return ret;
1563
+}
1563
+}
1564
+
1564
+
1565
+static const struct v4l2_ctrl_ops vd55g1_ctrl_ops = {
1565
+static const struct v4l2_ctrl_ops vd55g1_ctrl_ops = {
1566
+    .g_volatile_ctrl = vd55g1_g_volatile_ctrl,
1566
+    .g_volatile_ctrl = vd55g1_g_volatile_ctrl,
1567
+    .s_ctrl = vd55g1_s_ctrl,
1567
+    .s_ctrl = vd55g1_s_ctrl,
1568
+};
1568
+};
1569
+
1569
+
1570
+static int vd55g1_init_ctrls(struct vd55g1 *sensor)
1570
+static int vd55g1_init_ctrls(struct vd55g1 *sensor)
1571
+{
1571
+{
1572
+    const struct v4l2_ctrl_ops *ops = &vd55g1_ctrl_ops;
1572
+    const struct v4l2_ctrl_ops *ops = &vd55g1_ctrl_ops;
1573
+    struct v4l2_ctrl_handler *hdl = &sensor->ctrl_handler;
1573
+    struct v4l2_ctrl_handler *hdl = &sensor->ctrl_handler;
1574
+    struct v4l2_ctrl *ctrl;
1574
+    struct v4l2_ctrl *ctrl;
1575
+    struct v4l2_fwnode_device_properties fwnode_props;
1575
+    struct v4l2_fwnode_device_properties fwnode_props;
1576
+    struct vblank_limits vblank;
1576
+    struct vblank_limits vblank;
1577
+    unsigned int hblank;
1577
+    unsigned int hblank;
1578
+    int ret;
1578
+    int ret;
1579
+
1579
+
1580
+    v4l2_ctrl_handler_init(hdl, 16);
1580
+    v4l2_ctrl_handler_init(hdl, 16);
1581
+
1581
+
1582
+    /* Flip cluster */
1582
+    /* Flip cluster */
1583
+    sensor->hflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
1583
+    sensor->hflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
1584
+                     0, 1, 1, 0);
1584
+                     0, 1, 1, 0);
1585
+    sensor->vflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
1585
+    sensor->vflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
1586
+                     0, 1, 1, 0);
1586
+                     0, 1, 1, 0);
1587
+    v4l2_ctrl_cluster(2, &sensor->hflip_ctrl);
1587
+    v4l2_ctrl_cluster(2, &sensor->hflip_ctrl);
1588
+
1588
+
1589
+    /* Exposition cluster */
1589
+    /* Exposition cluster */
1590
+    sensor->ae_ctrl = v4l2_ctrl_new_std_menu(hdl, ops,
1590
+    sensor->ae_ctrl = v4l2_ctrl_new_std_menu(hdl, ops,
1591
+                         V4L2_CID_EXPOSURE_AUTO, 1,
1591
+                         V4L2_CID_EXPOSURE_AUTO, 1,
1592
+                         ~0x3, V4L2_EXPOSURE_AUTO);
1592
+                         ~0x3, V4L2_EXPOSURE_AUTO);
1593
+    sensor->again_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
1593
+    sensor->again_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
1594
+                     0, 0x1c, 1, VD55G1_AGAIN_DEF);
1594
+                     0, 0x1c, 1, VD55G1_AGAIN_DEF);
1595
+    sensor->dgain_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DIGITAL_GAIN,
1595
+    sensor->dgain_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DIGITAL_GAIN,
1596
+                     256, 0xffff, 1,
1596
+                     256, 0xffff, 1,
1597
+                     VD55G1_DGAIN_DEF);
1597
+                     VD55G1_DGAIN_DEF);
1598
+    sensor->expo_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0,
1598
+    sensor->expo_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0,
1599
+                     VD55G1_FRAME_LENGTH_DEF -
1599
+                     VD55G1_FRAME_LENGTH_DEF -
1600
+                     VD55G1_EXPO_MAX_TERM,
1600
+                     VD55G1_EXPO_MAX_TERM,
1601
+                     1, VD55G1_EXPO_DEF);
1601
+                     1, VD55G1_EXPO_DEF);
1602
+    v4l2_ctrl_auto_cluster(4, &sensor->ae_ctrl, V4L2_EXPOSURE_MANUAL, true);
1602
+    v4l2_ctrl_auto_cluster(4, &sensor->ae_ctrl, V4L2_EXPOSURE_MANUAL, true);
1603
+
1603
+
1604
+    sensor->patgen_ctrl =
1604
+    sensor->patgen_ctrl =
1605
+        v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
1605
+        v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
1606
+                     ARRAY_SIZE(vd55g1_tp_menu) - 1, 0,
1606
+                     ARRAY_SIZE(vd55g1_tp_menu) - 1, 0,
1607
+                     0, vd55g1_tp_menu);
1607
+                     0, vd55g1_tp_menu);
1608
+    ctrl = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
1608
+    ctrl = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
1609
+                 ARRAY_SIZE(link_freq) - 1, 0, link_freq);
1609
+                 ARRAY_SIZE(link_freq) - 1, 0, link_freq);
1610
+    if (ctrl)
1610
+    if (ctrl)
1611
+        ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1611
+        ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1612
+    sensor->pixel_rate_ctrl = v4l2_ctrl_new_std(hdl, ops,
1612
+    sensor->pixel_rate_ctrl = v4l2_ctrl_new_std(hdl, ops,
1613
+                         V4L2_CID_PIXEL_RATE, 1,
1613
+                         V4L2_CID_PIXEL_RATE, 1,
1614
+                         INT_MAX, 1,
1614
+                         INT_MAX, 1,
1615
+                         get_pixel_rate(sensor));
1615
+                         get_pixel_rate(sensor));
1616
+    if (sensor->pixel_rate_ctrl)
1616
+    if (sensor->pixel_rate_ctrl)
1617
+        sensor->pixel_rate_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1617
+        sensor->pixel_rate_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1618
+    sensor->ae_lock_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_3A_LOCK,
1618
+    sensor->ae_lock_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_3A_LOCK,
1619
+                         0, 1, 0, 0);
1619
+                         0, 1, 0, 0);
1620
+    sensor->ae_bias_ctrl =
1620
+    sensor->ae_bias_ctrl =
1621
+        v4l2_ctrl_new_int_menu(hdl, ops,
1621
+        v4l2_ctrl_new_int_menu(hdl, ops,
1622
+                 V4L2_CID_AUTO_EXPOSURE_BIAS,
1622
+                 V4L2_CID_AUTO_EXPOSURE_BIAS,
1623
+                 ARRAY_SIZE(vd55g1_ev_bias_menu) - 1,
1623
+                 ARRAY_SIZE(vd55g1_ev_bias_menu) - 1,
1624
+                 ARRAY_SIZE(vd55g1_ev_bias_menu) / 2,
1624
+                 ARRAY_SIZE(vd55g1_ev_bias_menu) / 2,
1625
+                 vd55g1_ev_bias_menu);
1625
+                 vd55g1_ev_bias_menu);
1626
+    sensor->hdr_ctrl =
1626
+    sensor->hdr_ctrl =
1627
+        v4l2_ctrl_new_std_menu_items(hdl, ops,
1627
+        v4l2_ctrl_new_std_menu_items(hdl, ops,
1628
+                     V4L2_CID_HDR_SENSOR_MODE,
1628
+                     V4L2_CID_HDR_SENSOR_MODE,
1629
+                     ARRAY_SIZE(vd55g1_hdr_menu) - 1, 0,
1629
+                     ARRAY_SIZE(vd55g1_hdr_menu) - 1, 0,
1630
+                     VD55G1_NO_HDR, vd55g1_hdr_menu);
1630
+                     VD55G1_NO_HDR, vd55g1_hdr_menu);
1631
+    hblank = get_hblank_min(sensor);
1631
+    hblank = get_hblank_min(sensor);
1632
+    sensor->hblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK,
1632
+    sensor->hblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK,
1633
+                        hblank, hblank, 1, hblank);
1633
+                        hblank, hblank, 1, hblank);
1634
+    if (sensor->hblank_ctrl)
1634
+    if (sensor->hblank_ctrl)
1635
+        sensor->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1635
+        sensor->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1636
+    vblank = get_vblank_limits(sensor);
1636
+    vblank = get_vblank_limits(sensor);
1637
+    sensor->vblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK,
1637
+    sensor->vblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK,
1638
+                        vblank.min, vblank.max,
1638
+                        vblank.min, vblank.max,
1639
+                        1, vblank.def);
1639
+                        1, vblank.def);
1640
+
1640
+
1641
+    /* Additional controls based on device tree properties */
1641
+    /* Additional controls based on device tree properties */
1642
+    if (sensor->ext_leds_mask) {
1642
+    if (sensor->ext_leds_mask) {
1643
+        sensor->led_ctrl =
1643
+        sensor->led_ctrl =
1644
+            v4l2_ctrl_new_std_menu(hdl, ops,
1644
+            v4l2_ctrl_new_std_menu(hdl, ops,
1645
+                     V4L2_CID_FLASH_LED_MODE,
1645
+                     V4L2_CID_FLASH_LED_MODE,
1646
+                     V4L2_FLASH_LED_MODE_FLASH, 0,
1646
+                     V4L2_FLASH_LED_MODE_FLASH, 0,
1647
+                     V4L2_FLASH_LED_MODE_NONE);
1647
+                     V4L2_FLASH_LED_MODE_NONE);
1648
+    }
1648
+    }
1649
+
1649
+
1650
+    if (hdl->error) {
1650
+    if (hdl->error) {
1651
+        ret = hdl->error;
1651
+        ret = hdl->error;
1652
+        goto free_ctrls;
1652
+        goto free_ctrls;
1653
+    }
1653
+    }
1654
+
1654
+
1655
+    ret = v4l2_fwnode_device_parse(&sensor->i2c_client->dev, &fwnode_props);
1655
+    ret = v4l2_fwnode_device_parse(&sensor->i2c_client->dev, &fwnode_props);
1656
+    if (ret)
1656
+    if (ret)
1657
+        goto free_ctrls;
1657
+        goto free_ctrls;
1658
+
1658
+
1659
+    ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &fwnode_props);
1659
+    ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &fwnode_props);
1660
+    if (ret)
1660
+    if (ret)
1661
+        goto free_ctrls;
1661
+        goto free_ctrls;
1662
+
1662
+
1663
+    sensor->sd.ctrl_handler = hdl;
1663
+    sensor->sd.ctrl_handler = hdl;
1664
+    return 0;
1664
+    return 0;
1665
+
1665
+
1666
+free_ctrls:
1666
+free_ctrls:
1667
+    v4l2_ctrl_handler_free(hdl);
1667
+    v4l2_ctrl_handler_free(hdl);
1668
+    return ret;
1668
+    return ret;
1669
+}
1669
+}
1670
+
1670
+
1671
+static int vd55g1_check_sensor_revision(struct vd55g1 *sensor)
1671
+static int vd55g1_check_sensor_revision(struct vd55g1 *sensor)
1672
+{
1672
+{
1673
+    struct i2c_client *client = sensor->i2c_client;
1673
+    struct i2c_client *client = sensor->i2c_client;
1674
+    u64 device_rev;
1674
+    u64 device_rev;
1675
+    int ret;
1675
+    int ret;
1676
+
1676
+
1677
+    ret = vd55g1_read(sensor, VD55G1_REG_REVISION, &device_rev, NULL);
1677
+    ret = vd55g1_read(sensor, VD55G1_REG_REVISION, &device_rev, NULL);
1678
+    if (ret)
1678
+    if (ret)
1679
+        return ret;
1679
+        return ret;
1680
+
1680
+
1681
+    if (device_rev != VD55G1_REVISION_CCB) {
1681
+    if (device_rev != VD55G1_REVISION_CCB) {
1682
+        dev_err(&client->dev, "Unsupported sensor revision (0x%x)\n",
1682
+        dev_err(&client->dev, "Unsupported sensor revision (0x%x)\n",
1683
+            (u16)device_rev);
1683
+            (u16)device_rev);
1684
+        return -ENODEV;
1684
+        return -ENODEV;
1685
+    }
1685
+    }
1686
+
1686
+
1687
+    return 0;
1687
+    return 0;
1688
+}
1688
+}
1689
+
1689
+
1690
+static int vd55g1_detect(struct vd55g1 *sensor)
1690
+static int vd55g1_detect(struct vd55g1 *sensor)
1691
+{
1691
+{
1692
+    struct i2c_client *client = sensor->i2c_client;
1692
+    struct i2c_client *client = sensor->i2c_client;
1693
+    u64 id;
1693
+    u64 id;
1694
+    int ret;
1694
+    int ret;
1695
+
1695
+
1696
+    ret = vd55g1_read(sensor, VD55G1_REG_MODEL_ID, &id, NULL);
1696
+    ret = vd55g1_read(sensor, VD55G1_REG_MODEL_ID, &id, NULL);
1697
+    if (ret)
1697
+    if (ret)
1698
+        return ret;
1698
+        return ret;
1699
+
1699
+
1700
+    if (id != VD55G1_MODEL_ID) {
1700
+    if (id != VD55G1_MODEL_ID) {
1701
+        dev_warn(&client->dev, "Unsupported sensor id %x", (u32)id);
1701
+        dev_warn(&client->dev, "Unsupported sensor id %x", (u32)id);
1702
+        return -ENODEV;
1702
+        return -ENODEV;
1703
+    }
1703
+    }
1704
+
1704
+
1705
+    return vd55g1_check_sensor_revision(sensor);
1705
+    return vd55g1_check_sensor_revision(sensor);
1706
+}
1706
+}
1707
+
1707
+
1708
+static int vd55g1_power_on(struct device *dev)
1708
+static int vd55g1_power_on(struct device *dev)
1709
+{
1709
+{
1710
+    struct v4l2_subdev *sd = dev_get_drvdata(dev);
1710
+    struct v4l2_subdev *sd = dev_get_drvdata(dev);
1711
+    struct vd55g1 *sensor = to_vd55g1(sd);
1711
+    struct vd55g1 *sensor = to_vd55g1(sd);
1712
+    int ret;
1712
+    int ret;
1713
+
1713
+
1714
+    ret = regulator_bulk_enable(ARRAY_SIZE(vd55g1_supply_name),
1714
+    ret = regulator_bulk_enable(ARRAY_SIZE(vd55g1_supply_name),
1715
+                 sensor->supplies);
1715
+                 sensor->supplies);
1716
+    if (ret) {
1716
+    if (ret) {
1717
+        dev_err(dev, "Failed to enable regulators %d", ret);
1717
+        dev_err(dev, "Failed to enable regulators %d", ret);
1718
+        return ret;
1718
+        return ret;
1719
+    }
1719
+    }
1720
+
1720
+
1721
+    ret = clk_prepare_enable(sensor->xclk);
1721
+    ret = clk_prepare_enable(sensor->xclk);
1722
+    if (ret) {
1722
+    if (ret) {
1723
+        dev_err(dev, "Failed to enable clock %d", ret);
1723
+        dev_err(dev, "Failed to enable clock %d", ret);
1724
+        goto disable_bulk;
1724
+        goto disable_bulk;
1725
+    }
1725
+    }
1726
+
1726
+
1727
+    gpiod_set_value_cansleep(sensor->reset_gpio, 0);
1727
+    gpiod_set_value_cansleep(sensor->reset_gpio, 0);
1728
+    usleep_range(5000, 10000);
1728
+    usleep_range(5000, 10000);
1729
+    ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_READY_TO_BOOT, NULL);
1729
+    ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_READY_TO_BOOT, NULL);
1730
+    if (ret) {
1730
+    if (ret) {
1731
+        dev_err(dev, "Sensor reset failed %d\n", ret);
1731
+        dev_err(dev, "Sensor reset failed %d\n", ret);
1732
+        goto disable_clock;
1732
+        goto disable_clock;
1733
+    }
1733
+    }
1734
+
1734
+
1735
+    ret = vd55g1_detect(sensor);
1735
+    ret = vd55g1_detect(sensor);
1736
+    if (ret) {
1736
+    if (ret) {
1737
+        dev_err(dev, "Sensor detect failed %d", ret);
1737
+        dev_err(dev, "Sensor detect failed %d", ret);
1738
+        goto disable_clock;
1738
+        goto disable_clock;
1739
+    }
1739
+    }
1740
+
1740
+
1741
+    ret = vd55g1_patch(sensor);
1741
+    ret = vd55g1_patch(sensor);
1742
+    if (ret) {
1742
+    if (ret) {
1743
+        dev_err(dev, "Sensor patch failed %d", ret);
1743
+        dev_err(dev, "Sensor patch failed %d", ret);
1744
+        goto disable_clock;
1744
+        goto disable_clock;
1745
+    }
1745
+    }
1746
+
1746
+
1747
+    ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, NULL);
1747
+    ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, NULL);
1748
+    if (ret) {
1748
+    if (ret) {
1749
+        dev_err(dev, "Sensor waiting after patch failed %d",
1749
+        dev_err(dev, "Sensor waiting after patch failed %d",
1750
+            ret);
1750
+            ret);
1751
+        goto disable_clock;
1751
+        goto disable_clock;
1752
+    }
1752
+    }
1753
+
1753
+
1754
+    return 0;
1754
+    return 0;
1755
+
1755
+
1756
+disable_clock:
1756
+disable_clock:
1757
+    gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1757
+    gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1758
+    clk_disable_unprepare(sensor->xclk);
1758
+    clk_disable_unprepare(sensor->xclk);
1759
+disable_bulk:
1759
+disable_bulk:
1760
+    regulator_bulk_disable(ARRAY_SIZE(vd55g1_supply_name),
1760
+    regulator_bulk_disable(ARRAY_SIZE(vd55g1_supply_name),
1761
+             sensor->supplies);
1761
+             sensor->supplies);
1762
+
1762
+
1763
+    return ret;
1763
+    return ret;
1764
+}
1764
+}
1765
+
1765
+
1766
+static int vd55g1_power_off(struct device *dev)
1766
+static int vd55g1_power_off(struct device *dev)
1767
+{
1767
+{
1768
+    struct v4l2_subdev *sd = dev_get_drvdata(dev);
1768
+    struct v4l2_subdev *sd = dev_get_drvdata(dev);
1769
+    struct vd55g1 *sensor = to_vd55g1(sd);
1769
+    struct vd55g1 *sensor = to_vd55g1(sd);
1770
+
1770
+
1771
+    clk_disable_unprepare(sensor->xclk);
1771
+    clk_disable_unprepare(sensor->xclk);
1772
+    gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1772
+    gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1773
+    regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies);
1773
+    regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies);
1774
+    return 0;
1774
+    return 0;
1775
+}
1775
+}
1776
+
1776
+
1777
+static int vd55g1_check_csi_conf(struct vd55g1 *sensor,
1777
+static int vd55g1_check_csi_conf(struct vd55g1 *sensor,
1778
+                 struct fwnode_handle *endpoint)
1778
+                 struct fwnode_handle *endpoint)
1779
+{
1779
+{
1780
+    struct i2c_client *client = sensor->i2c_client;
1780
+    struct i2c_client *client = sensor->i2c_client;
1781
+    struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
1781
+    struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
1782
+    u8 n_lanes;
1782
+    u8 n_lanes;
1783
+    int ret = 0;
1783
+    int ret = 0;
1784
+
1784
+
1785
+    ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
1785
+    ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
1786
+    if (ret)
1786
+    if (ret)
1787
+        return -EINVAL;
1787
+        return -EINVAL;
1788
+
1788
+
1789
+    /* Check lanes number */
1789
+    /* Check lanes number */
1790
+    n_lanes = ep.bus.mipi_csi2.num_data_lanes;
1790
+    n_lanes = ep.bus.mipi_csi2.num_data_lanes;
1791
+    if (n_lanes != 1) {
1791
+    if (n_lanes != 1) {
1792
+        dev_err(&client->dev, "Sensor only supports 1 lane, found %d\n",
1792
+        dev_err(&client->dev, "Sensor only supports 1 lane, found %d\n",
1793
+            n_lanes);
1793
+            n_lanes);
1794
+        ret = -EINVAL;
1794
+        ret = -EINVAL;
1795
+        goto done;
1795
+        goto done;
1796
+    }
1796
+    }
1797
+
1797
+
1798
+    /* Clock lane must be first */
1798
+    /* Clock lane must be first */
1799
+    if (ep.bus.mipi_csi2.clock_lane != 0) {
1799
+    if (ep.bus.mipi_csi2.clock_lane != 0) {
1800
+        dev_err(&client->dev, "Clock lane must be mapped to lane 0\n");
1800
+        dev_err(&client->dev, "Clock lane must be mapped to lane 0\n");
1801
+        ret = -EINVAL;
1801
+        ret = -EINVAL;
1802
+        goto done;
1802
+        goto done;
1803
+    }
1803
+    }
1804
+
1804
+
1805
+    /* Handle polarities in sensor configuration */
1805
+    /* Handle polarities in sensor configuration */
1806
+    sensor->oif_ctrl = (ep.bus.mipi_csi2.lane_polarities[0] << 3) |
1806
+    sensor->oif_ctrl = (ep.bus.mipi_csi2.lane_polarities[0] << 3) |
1807
+             (ep.bus.mipi_csi2.lane_polarities[1] << 6);
1807
+             (ep.bus.mipi_csi2.lane_polarities[1] << 6);
1808
+
1808
+
1809
+    /* Check the link frequency set in device tree */
1809
+    /* Check the link frequency set in device tree */
1810
+    if (!ep.nr_of_link_frequencies) {
1810
+    if (!ep.nr_of_link_frequencies) {
1811
+        dev_err(&client->dev, "link-frequency property not found in DT\n");
1811
+        dev_err(&client->dev, "link-frequency property not found in DT\n");
1812
+        ret = -EINVAL;
1812
+        ret = -EINVAL;
1813
+        goto done;
1813
+        goto done;
1814
+    }
1814
+    }
1815
+    if (ep.nr_of_link_frequencies != 1) {
1815
+    if (ep.nr_of_link_frequencies != 1) {
1816
+        dev_err(&client->dev, "Multiple link frequencies not supported\n");
1816
+        dev_err(&client->dev, "Multiple link frequencies not supported\n");
1817
+        ret = -EINVAL;
1817
+        ret = -EINVAL;
1818
+        goto done;
1818
+        goto done;
1819
+    }
1819
+    }
1820
+    link_freq[0] = ep.link_frequencies[0];
1820
+    link_freq[0] = ep.link_frequencies[0];
1821
+
1821
+
1822
+done:
1822
+done:
1823
+    v4l2_fwnode_endpoint_free(&ep);
1823
+    v4l2_fwnode_endpoint_free(&ep);
1824
+
1824
+
1825
+    return ret;
1825
+    return ret;
1826
+}
1826
+}
1827
+
1827
+
1828
+static int vd55g1_parse_dt_gpios_array(struct vd55g1 *sensor,
1828
+static int vd55g1_parse_dt_gpios_array(struct vd55g1 *sensor,
1829
+                 char *prop_name, u32 *array, int *nb)
1829
+                 char *prop_name, u32 *array, int *nb)
1830
+{
1830
+{
1831
+    struct i2c_client *client = sensor->i2c_client;
1831
+    struct i2c_client *client = sensor->i2c_client;
1832
+    struct device_node *np = client->dev.of_node;
1832
+    struct device_node *np = client->dev.of_node;
1833
+    unsigned int i;
1833
+    unsigned int i;
1834
+
1834
+
1835
+    *nb = of_property_read_variable_u32_array(np, prop_name, array, 0,
1835
+    *nb = of_property_read_variable_u32_array(np, prop_name, array, 0,
1836
+                         VD55G1_NB_GPIOS);
1836
+                         VD55G1_NB_GPIOS);
1837
+    if (*nb == -EINVAL) {
1837
+    if (*nb == -EINVAL) {
1838
+        /* Property not found */
1838
+        /* Property not found */
1839
+        *nb = 0;
1839
+        *nb = 0;
1840
+        return 0;
1840
+        return 0;
1841
+    } else if (*nb < 0) {
1841
+    } else if (*nb < 0) {
1842
+        dev_err(&client->dev, "Failed to read %s prop\n", prop_name);
1842
+        dev_err(&client->dev, "Failed to read %s prop\n", prop_name);
1843
+        return *nb;
1843
+        return *nb;
1844
+    }
1844
+    }
1845
+
1845
+
1846
+    for (i = 0; i < *nb; i++) {
1846
+    for (i = 0; i < *nb; i++) {
1847
+        if (array[i] >= VD55G1_NB_GPIOS) {
1847
+        if (array[i] >= VD55G1_NB_GPIOS) {
1848
+            dev_err(&client->dev, "Invalid GPIO number %d\n",
1848
+            dev_err(&client->dev, "Invalid GPIO number %d\n",
1849
+                array[i]);
1849
+                array[i]);
1850
+            return -EINVAL;
1850
+            return -EINVAL;
1851
+        }
1851
+        }
1852
+    }
1852
+    }
1853
+
1853
+
1854
+    return 0;
1854
+    return 0;
1855
+}
1855
+}
1856
+
1856
+
1857
+static int vd55g1_parse_dt_gpios(struct vd55g1 *sensor)
1857
+static int vd55g1_parse_dt_gpios(struct vd55g1 *sensor)
1858
+{
1858
+{
1859
+    u32 led_gpios[VD55G1_NB_GPIOS];
1859
+    u32 led_gpios[VD55G1_NB_GPIOS];
1860
+    int nb_gpios_leds;
1860
+    int nb_gpios_leds;
1861
+    unsigned int i;
1861
+    unsigned int i;
1862
+    int ret;
1862
+    int ret;
1863
+
1863
+
1864
+    /* Initialize GPIOs to default */
1864
+    /* Initialize GPIOs to default */
1865
+    for (i = 0; i < VD55G1_NB_GPIOS; i++)
1865
+    for (i = 0; i < VD55G1_NB_GPIOS; i++)
1866
+        sensor->gpios[i] = VD55G1_GPIO_MODE_IN;
1866
+        sensor->gpios[i] = VD55G1_GPIO_MODE_IN;
1867
+    sensor->ext_leds_mask = 0;
1867
+    sensor->ext_leds_mask = 0;
1868
+
1868
+
1869
+    /* Take into account optional 'st,leds' output for GPIOs */
1869
+    /* Take into account optional 'st,leds' output for GPIOs */
1870
+    ret = vd55g1_parse_dt_gpios_array(sensor, "st,leds", led_gpios,
1870
+    ret = vd55g1_parse_dt_gpios_array(sensor, "st,leds", led_gpios,
1871
+                     &nb_gpios_leds);
1871
+                     &nb_gpios_leds);
1872
+    if (ret)
1872
+    if (ret)
1873
+        return ret;
1873
+        return ret;
1874
+
1874
+
1875
+    for (i = 0; i < nb_gpios_leds; i++) {
1875
+    for (i = 0; i < nb_gpios_leds; i++) {
1876
+        sensor->gpios[led_gpios[i]] = VD55G1_GPIO_MODE_STROBE;
1876
+        sensor->gpios[led_gpios[i]] = VD55G1_GPIO_MODE_STROBE;
1877
+        set_bit(led_gpios[i], &sensor->ext_leds_mask);
1877
+        set_bit(led_gpios[i], &sensor->ext_leds_mask);
1878
+    }
1878
+    }
1879
+
1879
+
1880
+    return 0;
1880
+    return 0;
1881
+}
1881
+}
1882
+
1882
+
1883
+static int vd55g1_parse_dt(struct vd55g1 *sensor)
1883
+static int vd55g1_parse_dt(struct vd55g1 *sensor)
1884
+{
1884
+{
1885
+    struct i2c_client *client = sensor->i2c_client;
1885
+    struct i2c_client *client = sensor->i2c_client;
1886
+    struct device *dev = &client->dev;
1886
+    struct device *dev = &client->dev;
1887
+    struct fwnode_handle *endpoint;
1887
+    struct fwnode_handle *endpoint;
1888
+    int ret;
1888
+    int ret;
1889
+
1889
+
1890
+    endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
1890
+    endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
1891
+    if (!endpoint) {
1891
+    if (!endpoint) {
1892
+        dev_err(dev, "Endpoint node not found\n");
1892
+        dev_err(dev, "Endpoint node not found\n");
1893
+        return -EINVAL;
1893
+        return -EINVAL;
1894
+    }
1894
+    }
1895
+
1895
+
1896
+    ret = vd55g1_check_csi_conf(sensor, endpoint);
1896
+    ret = vd55g1_check_csi_conf(sensor, endpoint);
1897
+    fwnode_handle_put(endpoint);
1897
+    fwnode_handle_put(endpoint);
1898
+    if (ret)
1898
+    if (ret)
1899
+        return ret;
1899
+        return ret;
1900
+
1900
+
1901
+    return vd55g1_parse_dt_gpios(sensor);
1901
+    return vd55g1_parse_dt_gpios(sensor);
1902
+}
1902
+}
1903
+
1903
+
1904
+static int vd55g1_subdev_init(struct vd55g1 *sensor)
1904
+static int vd55g1_subdev_init(struct vd55g1 *sensor)
1905
+{
1905
+{
1906
+    struct i2c_client *client = sensor->i2c_client;
1906
+    struct i2c_client *client = sensor->i2c_client;
1907
+    int ret;
1907
+    int ret;
1908
+
1908
+
1909
+    /* Init sub device */
1909
+    /* Init sub device */
1910
+    sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1910
+    sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1911
+    sensor->sd.internal_ops = &vd55g1_internal_ops;
1911
+    sensor->sd.internal_ops = &vd55g1_internal_ops;
1912
+
1912
+
1913
+    /* Init source pad */
1913
+    /* Init source pad */
1914
+    sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
1914
+    sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
1915
+    sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1915
+    sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1916
+    ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
1916
+    ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
1917
+    if (ret) {
1917
+    if (ret) {
1918
+        dev_err(&client->dev, "Failed to init media entity : %d", ret);
1918
+        dev_err(&client->dev, "Failed to init media entity : %d", ret);
1919
+        return ret;
1919
+        return ret;
1920
+    }
1920
+    }
1921
+
1921
+
1922
+    sensor->sd.state_lock = sensor->ctrl_handler.lock;
1922
+    sensor->sd.state_lock = sensor->ctrl_handler.lock;
1923
+    ret = v4l2_subdev_init_finalize(&sensor->sd);
1923
+    ret = v4l2_subdev_init_finalize(&sensor->sd);
1924
+    if (ret) {
1924
+    if (ret) {
1925
+        dev_err(&client->dev, "Subdev init error: %d", ret);
1925
+        dev_err(&client->dev, "Subdev init error: %d", ret);
1926
+        goto err_ctrls;
1926
+        goto err_ctrls;
1927
+    }
1927
+    }
1928
+
1928
+
1929
+    /*
1929
+    /*
1930
+     * Initiliaze controls after v4l2_subdev_init_finalize() to make sure
1930
+     * Initiliaze controls after v4l2_subdev_init_finalize() to make sure
1931
+     * default values are set.
1931
+     * default values are set.
1932
+     */
1932
+     */
1933
+    ret = vd55g1_init_ctrls(sensor);
1933
+    ret = vd55g1_init_ctrls(sensor);
1934
+    if (ret) {
1934
+    if (ret) {
1935
+        dev_err(&client->dev, "Controls initialization failed %d", ret);
1935
+        dev_err(&client->dev, "Controls initialization failed %d", ret);
1936
+        goto err_media;
1936
+        goto err_media;
1937
+    }
1937
+    }
1938
+
1938
+
1939
+    return ret;
1939
+    return ret;
1940
+
1940
+
1941
+err_ctrls:
1941
+err_ctrls:
1942
+    v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1942
+    v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1943
+
1943
+
1944
+err_media:
1944
+err_media:
1945
+    media_entity_cleanup(&sensor->sd.entity);
1945
+    media_entity_cleanup(&sensor->sd.entity);
1946
+    return ret;
1946
+    return ret;
1947
+}
1947
+}
1948
+
1948
+
1949
+static void vd55g1_subdev_cleanup(struct vd55g1 *sensor)
1949
+static void vd55g1_subdev_cleanup(struct vd55g1 *sensor)
1950
+{
1950
+{
1951
+    v4l2_async_unregister_subdev(&sensor->sd);
1951
+    v4l2_async_unregister_subdev(&sensor->sd);
1952
+    v4l2_subdev_cleanup(&sensor->sd);
1952
+    v4l2_subdev_cleanup(&sensor->sd);
1953
+    media_entity_cleanup(&sensor->sd.entity);
1953
+    media_entity_cleanup(&sensor->sd.entity);
1954
+    v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1954
+    v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1955
+}
1955
+}
1956
+
1956
+
1957
+static int vd55g1_probe(struct i2c_client *client)
1957
+static int vd55g1_probe(struct i2c_client *client)
1958
+{
1958
+{
1959
+    struct device *dev = &client->dev;
1959
+    struct device *dev = &client->dev;
1960
+    struct vd55g1 *sensor;
1960
+    struct vd55g1 *sensor;
1961
+    int ret;
1961
+    int ret;
1962
+
1962
+
1963
+    sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
1963
+    sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
1964
+    if (!sensor)
1964
+    if (!sensor)
1965
+        return -ENOMEM;
1965
+        return -ENOMEM;
1966
+
1966
+
1967
+    v4l2_i2c_subdev_init(&sensor->sd, client, &vd55g1_subdev_ops);
1967
+    v4l2_i2c_subdev_init(&sensor->sd, client, &vd55g1_subdev_ops);
1968
+    sensor->i2c_client = client;
1968
+    sensor->i2c_client = client;
1969
+
1969
+
1970
+    ret = vd55g1_parse_dt(sensor);
1970
+    ret = vd55g1_parse_dt(sensor);
1971
+    if (ret)
1971
+    if (ret)
1972
+        return dev_err_probe(dev, ret, "Failed to parse Device Tree.");
1972
+        return dev_err_probe(dev, ret, "Failed to parse Device Tree.");
1973
+
1973
+
1974
+    /* Get (and check) resources : power regs, ext clock, reset gpio */
1974
+    /* Get (and check) resources : power regs, ext clock, reset gpio */
1975
+    ret = vd55g1_get_regulators(sensor);
1975
+    ret = vd55g1_get_regulators(sensor);
1976
+    if (ret)
1976
+    if (ret)
1977
+        return dev_err_probe(dev, ret, "Failed to get regulators.");
1977
+        return dev_err_probe(dev, ret, "Failed to get regulators.");
1978
+
1978
+
1979
+    sensor->xclk = devm_clk_get(dev, NULL);
1979
+    sensor->xclk = devm_clk_get(dev, NULL);
1980
+    if (IS_ERR(sensor->xclk))
1980
+    if (IS_ERR(sensor->xclk))
1981
+        return dev_err_probe(dev, PTR_ERR(sensor->xclk),
1981
+        return dev_err_probe(dev, PTR_ERR(sensor->xclk),
1982
+                 "Failed to get xclk.");
1982
+                 "Failed to get xclk.");
1983
+
1983
+
1984
+    sensor->xclk_freq = clk_get_rate(sensor->xclk);
1984
+    sensor->xclk_freq = clk_get_rate(sensor->xclk);
1985
+    ret = vd55g1_prepare_clock_tree(sensor);
1985
+    ret = vd55g1_prepare_clock_tree(sensor);
1986
+    if (ret)
1986
+    if (ret)
1987
+        return ret;
1987
+        return ret;
1988
+
1988
+
1989
+    sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1989
+    sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1990
+                         GPIOD_OUT_HIGH);
1990
+                         GPIOD_OUT_HIGH);
1991
+    if (IS_ERR(sensor->reset_gpio))
1991
+    if (IS_ERR(sensor->reset_gpio))
1992
+        return dev_err_probe(dev, PTR_ERR(sensor->reset_gpio),
1992
+        return dev_err_probe(dev, PTR_ERR(sensor->reset_gpio),
1993
+                 "Failed to get reset gpio.");
1993
+                 "Failed to get reset gpio.");
1994
+
1994
+
1995
+    sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
1995
+    sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
1996
+    if (IS_ERR(sensor->regmap))
1996
+    if (IS_ERR(sensor->regmap))
1997
+        return dev_err_probe(dev, PTR_ERR(sensor->regmap),
1997
+        return dev_err_probe(dev, PTR_ERR(sensor->regmap),
1998
+                 "Failed to init regmap.");
1998
+                 "Failed to init regmap.");
1999
+
1999
+
2000
+    /* Detect if sensor is present and if its revision is supported */
2000
+    /* Detect if sensor is present and if its revision is supported */
2001
+    ret = vd55g1_power_on(dev);
2001
+    ret = vd55g1_power_on(dev);
2002
+    if (ret)
2002
+    if (ret)
2003
+        return ret;
2003
+        return ret;
2004
+
2004
+
2005
+    ret = vd55g1_subdev_init(sensor);
2005
+    ret = vd55g1_subdev_init(sensor);
2006
+    if (ret) {
2006
+    if (ret) {
2007
+        dev_err(dev, "V4l2 init failed : %d", ret);
2007
+        dev_err(dev, "V4l2 init failed : %d", ret);
2008
+        goto err_power_off;
2008
+        goto err_power_off;
2009
+    }
2009
+    }
2010
+
2010
+
2011
+    ret = v4l2_async_register_subdev(&sensor->sd);
2011
+    ret = v4l2_async_register_subdev(&sensor->sd);
2012
+    if (ret) {
2012
+    if (ret) {
2013
+        dev_err(dev, "async subdev register failed %d", ret);
2013
+        dev_err(dev, "async subdev register failed %d", ret);
2014
+        goto err_subdev;
2014
+        goto err_subdev;
2015
+    }
2015
+    }
2016
+
2016
+
2017
+    /* Enable pm_runtime and power off the sensor */
2017
+    /* Enable pm_runtime and power off the sensor */
2018
+    pm_runtime_set_active(dev);
2018
+    pm_runtime_set_active(dev);
2019
+    pm_runtime_get_noresume(dev);
2019
+    pm_runtime_get_noresume(dev);
2020
+    pm_runtime_enable(dev);
2020
+    pm_runtime_enable(dev);
2021
+    pm_runtime_set_autosuspend_delay(dev, 4000);
2021
+    pm_runtime_set_autosuspend_delay(dev, 4000);
2022
+    pm_runtime_use_autosuspend(dev);
2022
+    pm_runtime_use_autosuspend(dev);
2023
+    pm_runtime_mark_last_busy(dev);
2023
+    pm_runtime_mark_last_busy(dev);
2024
+
2024
+
2025
+    return 0;
2025
+    return 0;
2026
+
2026
+
2027
+err_subdev:
2027
+err_subdev:
2028
+    vd55g1_subdev_cleanup(sensor);
2028
+    vd55g1_subdev_cleanup(sensor);
2029
+err_power_off:
2029
+err_power_off:
2030
+    vd55g1_power_off(dev);
2030
+    vd55g1_power_off(dev);
2031
+
2031
+
2032
+    return ret;
2032
+    return ret;
2033
+}
2033
+}
2034
+
2034
+
2035
+static void vd55g1_remove(struct i2c_client *client)
2035
+static void vd55g1_remove(struct i2c_client *client)
2036
+{
2036
+{
2037
+    struct v4l2_subdev *sd = i2c_get_clientdata(client);
2037
+    struct v4l2_subdev *sd = i2c_get_clientdata(client);
2038
+    struct vd55g1 *sensor = to_vd55g1(sd);
2038
+    struct vd55g1 *sensor = to_vd55g1(sd);
2039
+
2039
+
2040
+    vd55g1_subdev_cleanup(sensor);
2040
+    vd55g1_subdev_cleanup(sensor);
2041
+
2041
+
2042
+    pm_runtime_disable(&client->dev);
2042
+    pm_runtime_disable(&client->dev);
2043
+    if (!pm_runtime_status_suspended(&client->dev))
2043
+    if (!pm_runtime_status_suspended(&client->dev))
2044
+        vd55g1_power_off(&client->dev);
2044
+        vd55g1_power_off(&client->dev);
2045
+    pm_runtime_set_suspended(&client->dev);
2045
+    pm_runtime_set_suspended(&client->dev);
2046
+}
2046
+}
2047
+
2047
+
2048
+static const struct of_device_id vd55g1_dt_ids[] = {
2048
+static const struct of_device_id vd55g1_dt_ids[] = {
2049
+    { .compatible = "st,vd55g1" },
2049
+    { .compatible = "st,vd55g1" },
2050
+    { /* sentinel */ }
2050
+    { /* sentinel */ }
2051
+};
2051
+};
2052
+MODULE_DEVICE_TABLE(of, vd55g1_dt_ids);
2052
+MODULE_DEVICE_TABLE(of, vd55g1_dt_ids);
2053
+
2053
+
2054
+static const struct dev_pm_ops vd55g1_pm_ops = {
2054
+static const struct dev_pm_ops vd55g1_pm_ops = {
2055
+    SET_RUNTIME_PM_OPS(vd55g1_power_off, vd55g1_power_on, NULL)
2055
+    SET_RUNTIME_PM_OPS(vd55g1_power_off, vd55g1_power_on, NULL)
2056
+};
2056
+};
2057
+
2057
+
2058
+static struct i2c_driver vd55g1_i2c_driver = {
2058
+static struct i2c_driver vd55g1_i2c_driver = {
2059
+    .driver = {
2059
+    .driver = {
2060
+        .name = "vd55g1",
2060
+        .name = "vd55g1",
2061
+        .of_match_table = vd55g1_dt_ids,
2061
+        .of_match_table = vd55g1_dt_ids,
2062
+        .pm = &vd55g1_pm_ops,
2062
+        .pm = &vd55g1_pm_ops,
2063
+    },
2063
+    },
2064
+    .probe = vd55g1_probe,
2064
+    .probe = vd55g1_probe,
2065
+    .remove = vd55g1_remove,
2065
+    .remove = vd55g1_remove,
2066
+};
2066
+};
2067
+
2067
+
2068
+module_i2c_driver(vd55g1_i2c_driver);
2068
+module_i2c_driver(vd55g1_i2c_driver);
2069
+
2069
+
2070
+MODULE_AUTHOR("Benjamin Mugnier <benjamin.mugnier@foss.st.com>");
2070
+MODULE_AUTHOR("Benjamin Mugnier <benjamin.mugnier@foss.st.com>");
2071
+MODULE_AUTHOR("Sylvain Petinot <sylvain.petinot@foss.st.com>");
2071
+MODULE_AUTHOR("Sylvain Petinot <sylvain.petinot@foss.st.com>");
2072
+MODULE_DESCRIPTION("VD55G1 camera subdev driver");
2072
+MODULE_DESCRIPTION("VD55G1 camera subdev driver");
2073
+MODULE_LICENSE("GPL");
2073
+MODULE_LICENSE("GPL");
2074
2074
2075
--
2075
--
2076
2.25.1
2076
2.25.1
diff view generated by jsdifflib