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