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