Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: i2c: imx290: Support variable-sized registers

The IMX290 has registers of different sizes. To simplify the code,
handle this in the read/write functions instead of in the callers by
encoding the register size in the symbolic name macros. All registers
are defined as 8-bit for now, a subsequent change will move to larger
registers where applicable.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>

authored by

Laurent Pinchart and committed by
Sakari Ailus
e70abe88 72825bc6

+180 -172
+180 -172
drivers/media/i2c/imx290.c
··· 22 22 #include <media/v4l2-fwnode.h> 23 23 #include <media/v4l2-subdev.h> 24 24 25 - #define IMX290_STANDBY 0x3000 26 - #define IMX290_REGHOLD 0x3001 27 - #define IMX290_XMSTA 0x3002 28 - #define IMX290_FR_FDG_SEL 0x3009 29 - #define IMX290_BLKLEVEL_LOW 0x300a 30 - #define IMX290_BLKLEVEL_HIGH 0x300b 31 - #define IMX290_GAIN 0x3014 32 - #define IMX290_HMAX_LOW 0x301c 33 - #define IMX290_HMAX_HIGH 0x301d 34 - #define IMX290_PGCTRL 0x308c 35 - #define IMX290_PHY_LANE_NUM 0x3407 36 - #define IMX290_CSI_LANE_MODE 0x3443 25 + #define IMX290_REG_SIZE_SHIFT 16 26 + #define IMX290_REG_ADDR_MASK 0xffff 27 + #define IMX290_REG_8BIT(n) ((1U << IMX290_REG_SIZE_SHIFT) | (n)) 28 + #define IMX290_REG_16BIT(n) ((2U << IMX290_REG_SIZE_SHIFT) | (n)) 29 + #define IMX290_REG_24BIT(n) ((3U << IMX290_REG_SIZE_SHIFT) | (n)) 37 30 38 - #define IMX290_PGCTRL_REGEN BIT(0) 39 - #define IMX290_PGCTRL_THRU BIT(1) 40 - #define IMX290_PGCTRL_MODE(n) ((n) << 4) 31 + #define IMX290_STANDBY IMX290_REG_8BIT(0x3000) 32 + #define IMX290_REGHOLD IMX290_REG_8BIT(0x3001) 33 + #define IMX290_XMSTA IMX290_REG_8BIT(0x3002) 34 + #define IMX290_FR_FDG_SEL IMX290_REG_8BIT(0x3009) 35 + #define IMX290_BLKLEVEL_LOW IMX290_REG_8BIT(0x300a) 36 + #define IMX290_BLKLEVEL_HIGH IMX290_REG_8BIT(0x300b) 37 + #define IMX290_GAIN IMX290_REG_8BIT(0x3014) 38 + #define IMX290_HMAX_LOW IMX290_REG_8BIT(0x301c) 39 + #define IMX290_HMAX_HIGH IMX290_REG_8BIT(0x301d) 40 + #define IMX290_PGCTRL IMX290_REG_8BIT(0x308c) 41 + #define IMX290_PHY_LANE_NUM IMX290_REG_8BIT(0x3407) 42 + #define IMX290_CSI_LANE_MODE IMX290_REG_8BIT(0x3443) 43 + 44 + #define IMX290_PGCTRL_REGEN BIT(0) 45 + #define IMX290_PGCTRL_THRU BIT(1) 46 + #define IMX290_PGCTRL_MODE(n) ((n) << 4) 41 47 42 48 static const char * const imx290_supply_name[] = { 43 49 "vdda", ··· 54 48 #define IMX290_NUM_SUPPLIES ARRAY_SIZE(imx290_supply_name) 55 49 56 50 struct imx290_regval { 57 - u16 reg; 51 + u32 reg; 58 52 u8 val; 59 53 }; 60 54 ··· 117 111 }; 118 112 119 113 static const struct imx290_regval imx290_global_init_settings[] = { 120 - { 0x3007, 0x00 }, 121 - { 0x3018, 0x65 }, 122 - { 0x3019, 0x04 }, 123 - { 0x301a, 0x00 }, 124 - { 0x3444, 0x20 }, 125 - { 0x3445, 0x25 }, 126 - { 0x303a, 0x0c }, 127 - { 0x3040, 0x00 }, 128 - { 0x3041, 0x00 }, 129 - { 0x303c, 0x00 }, 130 - { 0x303d, 0x00 }, 131 - { 0x3042, 0x9c }, 132 - { 0x3043, 0x07 }, 133 - { 0x303e, 0x49 }, 134 - { 0x303f, 0x04 }, 135 - { 0x304b, 0x0a }, 136 - { 0x300f, 0x00 }, 137 - { 0x3010, 0x21 }, 138 - { 0x3012, 0x64 }, 139 - { 0x3016, 0x09 }, 140 - { 0x3070, 0x02 }, 141 - { 0x3071, 0x11 }, 142 - { 0x309b, 0x10 }, 143 - { 0x309c, 0x22 }, 144 - { 0x30a2, 0x02 }, 145 - { 0x30a6, 0x20 }, 146 - { 0x30a8, 0x20 }, 147 - { 0x30aa, 0x20 }, 148 - { 0x30ac, 0x20 }, 149 - { 0x30b0, 0x43 }, 150 - { 0x3119, 0x9e }, 151 - { 0x311c, 0x1e }, 152 - { 0x311e, 0x08 }, 153 - { 0x3128, 0x05 }, 154 - { 0x313d, 0x83 }, 155 - { 0x3150, 0x03 }, 156 - { 0x317e, 0x00 }, 157 - { 0x32b8, 0x50 }, 158 - { 0x32b9, 0x10 }, 159 - { 0x32ba, 0x00 }, 160 - { 0x32bb, 0x04 }, 161 - { 0x32c8, 0x50 }, 162 - { 0x32c9, 0x10 }, 163 - { 0x32ca, 0x00 }, 164 - { 0x32cb, 0x04 }, 165 - { 0x332c, 0xd3 }, 166 - { 0x332d, 0x10 }, 167 - { 0x332e, 0x0d }, 168 - { 0x3358, 0x06 }, 169 - { 0x3359, 0xe1 }, 170 - { 0x335a, 0x11 }, 171 - { 0x3360, 0x1e }, 172 - { 0x3361, 0x61 }, 173 - { 0x3362, 0x10 }, 174 - { 0x33b0, 0x50 }, 175 - { 0x33b2, 0x1a }, 176 - { 0x33b3, 0x04 }, 114 + { IMX290_REG_8BIT(0x3007), 0x00 }, 115 + { IMX290_REG_8BIT(0x3018), 0x65 }, 116 + { IMX290_REG_8BIT(0x3019), 0x04 }, 117 + { IMX290_REG_8BIT(0x301a), 0x00 }, 118 + { IMX290_REG_8BIT(0x3444), 0x20 }, 119 + { IMX290_REG_8BIT(0x3445), 0x25 }, 120 + { IMX290_REG_8BIT(0x303a), 0x0c }, 121 + { IMX290_REG_8BIT(0x3040), 0x00 }, 122 + { IMX290_REG_8BIT(0x3041), 0x00 }, 123 + { IMX290_REG_8BIT(0x303c), 0x00 }, 124 + { IMX290_REG_8BIT(0x303d), 0x00 }, 125 + { IMX290_REG_8BIT(0x3042), 0x9c }, 126 + { IMX290_REG_8BIT(0x3043), 0x07 }, 127 + { IMX290_REG_8BIT(0x303e), 0x49 }, 128 + { IMX290_REG_8BIT(0x303f), 0x04 }, 129 + { IMX290_REG_8BIT(0x304b), 0x0a }, 130 + { IMX290_REG_8BIT(0x300f), 0x00 }, 131 + { IMX290_REG_8BIT(0x3010), 0x21 }, 132 + { IMX290_REG_8BIT(0x3012), 0x64 }, 133 + { IMX290_REG_8BIT(0x3016), 0x09 }, 134 + { IMX290_REG_8BIT(0x3070), 0x02 }, 135 + { IMX290_REG_8BIT(0x3071), 0x11 }, 136 + { IMX290_REG_8BIT(0x309b), 0x10 }, 137 + { IMX290_REG_8BIT(0x309c), 0x22 }, 138 + { IMX290_REG_8BIT(0x30a2), 0x02 }, 139 + { IMX290_REG_8BIT(0x30a6), 0x20 }, 140 + { IMX290_REG_8BIT(0x30a8), 0x20 }, 141 + { IMX290_REG_8BIT(0x30aa), 0x20 }, 142 + { IMX290_REG_8BIT(0x30ac), 0x20 }, 143 + { IMX290_REG_8BIT(0x30b0), 0x43 }, 144 + { IMX290_REG_8BIT(0x3119), 0x9e }, 145 + { IMX290_REG_8BIT(0x311c), 0x1e }, 146 + { IMX290_REG_8BIT(0x311e), 0x08 }, 147 + { IMX290_REG_8BIT(0x3128), 0x05 }, 148 + { IMX290_REG_8BIT(0x313d), 0x83 }, 149 + { IMX290_REG_8BIT(0x3150), 0x03 }, 150 + { IMX290_REG_8BIT(0x317e), 0x00 }, 151 + { IMX290_REG_8BIT(0x32b8), 0x50 }, 152 + { IMX290_REG_8BIT(0x32b9), 0x10 }, 153 + { IMX290_REG_8BIT(0x32ba), 0x00 }, 154 + { IMX290_REG_8BIT(0x32bb), 0x04 }, 155 + { IMX290_REG_8BIT(0x32c8), 0x50 }, 156 + { IMX290_REG_8BIT(0x32c9), 0x10 }, 157 + { IMX290_REG_8BIT(0x32ca), 0x00 }, 158 + { IMX290_REG_8BIT(0x32cb), 0x04 }, 159 + { IMX290_REG_8BIT(0x332c), 0xd3 }, 160 + { IMX290_REG_8BIT(0x332d), 0x10 }, 161 + { IMX290_REG_8BIT(0x332e), 0x0d }, 162 + { IMX290_REG_8BIT(0x3358), 0x06 }, 163 + { IMX290_REG_8BIT(0x3359), 0xe1 }, 164 + { IMX290_REG_8BIT(0x335a), 0x11 }, 165 + { IMX290_REG_8BIT(0x3360), 0x1e }, 166 + { IMX290_REG_8BIT(0x3361), 0x61 }, 167 + { IMX290_REG_8BIT(0x3362), 0x10 }, 168 + { IMX290_REG_8BIT(0x33b0), 0x50 }, 169 + { IMX290_REG_8BIT(0x33b2), 0x1a }, 170 + { IMX290_REG_8BIT(0x33b3), 0x04 }, 177 171 }; 178 172 179 173 static const struct imx290_regval imx290_1080p_settings[] = { 180 174 /* mode settings */ 181 - { 0x3007, 0x00 }, 182 - { 0x303a, 0x0c }, 183 - { 0x3414, 0x0a }, 184 - { 0x3472, 0x80 }, 185 - { 0x3473, 0x07 }, 186 - { 0x3418, 0x38 }, 187 - { 0x3419, 0x04 }, 188 - { 0x3012, 0x64 }, 189 - { 0x3013, 0x00 }, 190 - { 0x305c, 0x18 }, 191 - { 0x305d, 0x03 }, 192 - { 0x305e, 0x20 }, 193 - { 0x305f, 0x01 }, 194 - { 0x315e, 0x1a }, 195 - { 0x3164, 0x1a }, 196 - { 0x3480, 0x49 }, 175 + { IMX290_REG_8BIT(0x3007), 0x00 }, 176 + { IMX290_REG_8BIT(0x303a), 0x0c }, 177 + { IMX290_REG_8BIT(0x3414), 0x0a }, 178 + { IMX290_REG_8BIT(0x3472), 0x80 }, 179 + { IMX290_REG_8BIT(0x3473), 0x07 }, 180 + { IMX290_REG_8BIT(0x3418), 0x38 }, 181 + { IMX290_REG_8BIT(0x3419), 0x04 }, 182 + { IMX290_REG_8BIT(0x3012), 0x64 }, 183 + { IMX290_REG_8BIT(0x3013), 0x00 }, 184 + { IMX290_REG_8BIT(0x305c), 0x18 }, 185 + { IMX290_REG_8BIT(0x305d), 0x03 }, 186 + { IMX290_REG_8BIT(0x305e), 0x20 }, 187 + { IMX290_REG_8BIT(0x305f), 0x01 }, 188 + { IMX290_REG_8BIT(0x315e), 0x1a }, 189 + { IMX290_REG_8BIT(0x3164), 0x1a }, 190 + { IMX290_REG_8BIT(0x3480), 0x49 }, 197 191 /* data rate settings */ 198 - { 0x3405, 0x10 }, 199 - { 0x3446, 0x57 }, 200 - { 0x3447, 0x00 }, 201 - { 0x3448, 0x37 }, 202 - { 0x3449, 0x00 }, 203 - { 0x344a, 0x1f }, 204 - { 0x344b, 0x00 }, 205 - { 0x344c, 0x1f }, 206 - { 0x344d, 0x00 }, 207 - { 0x344e, 0x1f }, 208 - { 0x344f, 0x00 }, 209 - { 0x3450, 0x77 }, 210 - { 0x3451, 0x00 }, 211 - { 0x3452, 0x1f }, 212 - { 0x3453, 0x00 }, 213 - { 0x3454, 0x17 }, 214 - { 0x3455, 0x00 }, 192 + { IMX290_REG_8BIT(0x3405), 0x10 }, 193 + { IMX290_REG_8BIT(0x3446), 0x57 }, 194 + { IMX290_REG_8BIT(0x3447), 0x00 }, 195 + { IMX290_REG_8BIT(0x3448), 0x37 }, 196 + { IMX290_REG_8BIT(0x3449), 0x00 }, 197 + { IMX290_REG_8BIT(0x344a), 0x1f }, 198 + { IMX290_REG_8BIT(0x344b), 0x00 }, 199 + { IMX290_REG_8BIT(0x344c), 0x1f }, 200 + { IMX290_REG_8BIT(0x344d), 0x00 }, 201 + { IMX290_REG_8BIT(0x344e), 0x1f }, 202 + { IMX290_REG_8BIT(0x344f), 0x00 }, 203 + { IMX290_REG_8BIT(0x3450), 0x77 }, 204 + { IMX290_REG_8BIT(0x3451), 0x00 }, 205 + { IMX290_REG_8BIT(0x3452), 0x1f }, 206 + { IMX290_REG_8BIT(0x3453), 0x00 }, 207 + { IMX290_REG_8BIT(0x3454), 0x17 }, 208 + { IMX290_REG_8BIT(0x3455), 0x00 }, 215 209 }; 216 210 217 211 static const struct imx290_regval imx290_720p_settings[] = { 218 212 /* mode settings */ 219 - { 0x3007, 0x10 }, 220 - { 0x303a, 0x06 }, 221 - { 0x3414, 0x04 }, 222 - { 0x3472, 0x00 }, 223 - { 0x3473, 0x05 }, 224 - { 0x3418, 0xd0 }, 225 - { 0x3419, 0x02 }, 226 - { 0x3012, 0x64 }, 227 - { 0x3013, 0x00 }, 228 - { 0x305c, 0x20 }, 229 - { 0x305d, 0x00 }, 230 - { 0x305e, 0x20 }, 231 - { 0x305f, 0x01 }, 232 - { 0x315e, 0x1a }, 233 - { 0x3164, 0x1a }, 234 - { 0x3480, 0x49 }, 213 + { IMX290_REG_8BIT(0x3007), 0x10 }, 214 + { IMX290_REG_8BIT(0x303a), 0x06 }, 215 + { IMX290_REG_8BIT(0x3414), 0x04 }, 216 + { IMX290_REG_8BIT(0x3472), 0x00 }, 217 + { IMX290_REG_8BIT(0x3473), 0x05 }, 218 + { IMX290_REG_8BIT(0x3418), 0xd0 }, 219 + { IMX290_REG_8BIT(0x3419), 0x02 }, 220 + { IMX290_REG_8BIT(0x3012), 0x64 }, 221 + { IMX290_REG_8BIT(0x3013), 0x00 }, 222 + { IMX290_REG_8BIT(0x305c), 0x20 }, 223 + { IMX290_REG_8BIT(0x305d), 0x00 }, 224 + { IMX290_REG_8BIT(0x305e), 0x20 }, 225 + { IMX290_REG_8BIT(0x305f), 0x01 }, 226 + { IMX290_REG_8BIT(0x315e), 0x1a }, 227 + { IMX290_REG_8BIT(0x3164), 0x1a }, 228 + { IMX290_REG_8BIT(0x3480), 0x49 }, 235 229 /* data rate settings */ 236 - { 0x3405, 0x10 }, 237 - { 0x3446, 0x4f }, 238 - { 0x3447, 0x00 }, 239 - { 0x3448, 0x2f }, 240 - { 0x3449, 0x00 }, 241 - { 0x344a, 0x17 }, 242 - { 0x344b, 0x00 }, 243 - { 0x344c, 0x17 }, 244 - { 0x344d, 0x00 }, 245 - { 0x344e, 0x17 }, 246 - { 0x344f, 0x00 }, 247 - { 0x3450, 0x57 }, 248 - { 0x3451, 0x00 }, 249 - { 0x3452, 0x17 }, 250 - { 0x3453, 0x00 }, 251 - { 0x3454, 0x17 }, 252 - { 0x3455, 0x00 }, 230 + { IMX290_REG_8BIT(0x3405), 0x10 }, 231 + { IMX290_REG_8BIT(0x3446), 0x4f }, 232 + { IMX290_REG_8BIT(0x3447), 0x00 }, 233 + { IMX290_REG_8BIT(0x3448), 0x2f }, 234 + { IMX290_REG_8BIT(0x3449), 0x00 }, 235 + { IMX290_REG_8BIT(0x344a), 0x17 }, 236 + { IMX290_REG_8BIT(0x344b), 0x00 }, 237 + { IMX290_REG_8BIT(0x344c), 0x17 }, 238 + { IMX290_REG_8BIT(0x344d), 0x00 }, 239 + { IMX290_REG_8BIT(0x344e), 0x17 }, 240 + { IMX290_REG_8BIT(0x344f), 0x00 }, 241 + { IMX290_REG_8BIT(0x3450), 0x57 }, 242 + { IMX290_REG_8BIT(0x3451), 0x00 }, 243 + { IMX290_REG_8BIT(0x3452), 0x17 }, 244 + { IMX290_REG_8BIT(0x3453), 0x00 }, 245 + { IMX290_REG_8BIT(0x3454), 0x17 }, 246 + { IMX290_REG_8BIT(0x3455), 0x00 }, 253 247 }; 254 248 255 249 static const struct imx290_regval imx290_10bit_settings[] = { 256 - { 0x3005, 0x00}, 257 - { 0x3046, 0x00}, 258 - { 0x3129, 0x1d}, 259 - { 0x317c, 0x12}, 260 - { 0x31ec, 0x37}, 261 - { 0x3441, 0x0a}, 262 - { 0x3442, 0x0a}, 263 - { 0x300a, 0x3c}, 264 - { 0x300b, 0x00}, 250 + { IMX290_REG_8BIT(0x3005), 0x00}, 251 + { IMX290_REG_8BIT(0x3046), 0x00}, 252 + { IMX290_REG_8BIT(0x3129), 0x1d}, 253 + { IMX290_REG_8BIT(0x317c), 0x12}, 254 + { IMX290_REG_8BIT(0x31ec), 0x37}, 255 + { IMX290_REG_8BIT(0x3441), 0x0a}, 256 + { IMX290_REG_8BIT(0x3442), 0x0a}, 257 + { IMX290_REG_8BIT(0x300a), 0x3c}, 258 + { IMX290_REG_8BIT(0x300b), 0x00}, 265 259 }; 266 260 267 261 static const struct imx290_regval imx290_12bit_settings[] = { 268 - { 0x3005, 0x01 }, 269 - { 0x3046, 0x01 }, 270 - { 0x3129, 0x00 }, 271 - { 0x317c, 0x00 }, 272 - { 0x31ec, 0x0e }, 273 - { 0x3441, 0x0c }, 274 - { 0x3442, 0x0c }, 275 - { 0x300a, 0xf0 }, 276 - { 0x300b, 0x00 }, 262 + { IMX290_REG_8BIT(0x3005), 0x01 }, 263 + { IMX290_REG_8BIT(0x3046), 0x01 }, 264 + { IMX290_REG_8BIT(0x3129), 0x00 }, 265 + { IMX290_REG_8BIT(0x317c), 0x00 }, 266 + { IMX290_REG_8BIT(0x31ec), 0x0e }, 267 + { IMX290_REG_8BIT(0x3441), 0x0c }, 268 + { IMX290_REG_8BIT(0x3442), 0x0c }, 269 + { IMX290_REG_8BIT(0x300a), 0xf0 }, 270 + { IMX290_REG_8BIT(0x300b), 0x00 }, 277 271 }; 278 272 279 273 /* supported link frequencies */ ··· 368 362 return container_of(_sd, struct imx290, sd); 369 363 } 370 364 371 - static inline int __always_unused imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value) 365 + static int __always_unused imx290_read_reg(struct imx290 *imx290, u32 addr, u32 *value) 372 366 { 373 - unsigned int regval; 367 + u8 data[3] = { 0, 0, 0 }; 374 368 int ret; 375 369 376 - ret = regmap_read(imx290->regmap, addr, &regval); 377 - if (ret) { 378 - dev_err(imx290->dev, "Failed to read register 0x%04x: %d\n", 379 - addr, ret); 370 + ret = regmap_raw_read(imx290->regmap, addr & IMX290_REG_ADDR_MASK, 371 + data, (addr >> IMX290_REG_SIZE_SHIFT) & 3); 372 + if (ret < 0) { 373 + dev_err(imx290->dev, "%u-bit read from 0x%04x failed: %d\n", 374 + ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8, 375 + addr & IMX290_REG_ADDR_MASK, ret); 380 376 return ret; 381 377 } 382 378 383 - *value = regval & 0xff; 384 - 379 + *value = (data[2] << 16) | (data[1] << 8) | data[0]; 385 380 return 0; 386 381 } 387 382 388 - static int imx290_write_reg(struct imx290 *imx290, u16 addr, u8 value) 383 + static int imx290_write_reg(struct imx290 *imx290, u32 addr, u32 value) 389 384 { 385 + u8 data[3] = { value & 0xff, (value >> 8) & 0xff, value >> 16 }; 390 386 int ret; 391 387 392 - ret = regmap_write(imx290->regmap, addr, value); 393 - if (ret) { 394 - dev_err(imx290->dev, "Failed to write register 0x%04x: %d\n", 395 - addr, ret); 396 - return ret; 397 - } 388 + ret = regmap_raw_write(imx290->regmap, addr & IMX290_REG_ADDR_MASK, 389 + data, (addr >> IMX290_REG_SIZE_SHIFT) & 3); 390 + if (ret < 0) 391 + dev_err(imx290->dev, "%u-bit write to 0x%04x failed: %d\n", 392 + ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8, 393 + addr & IMX290_REG_ADDR_MASK, ret); 398 394 399 395 return ret; 400 396 }