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