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

media: i2c: imx219: Convert to CCI register access helpers

Use the new common CCI register access helpers to replace the private
register access helpers in the imx219 driver. This simplifies the driver
by reducing the amount of code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

authored by

Laurent Pinchart and committed by
Hans Verkuil
852798cc 24d756e9

+221 -295
+1
drivers/media/i2c/Kconfig
··· 99 99 100 100 config VIDEO_IMX219 101 101 tristate "Sony IMX219 sensor support" 102 + select V4L2_CCI_I2C 102 103 help 103 104 This is a Video4Linux2 sensor driver for the Sony 104 105 IMX219 camera.
+220 -295
drivers/media/i2c/imx219.c
··· 21 21 #include <linux/module.h> 22 22 #include <linux/pm_runtime.h> 23 23 #include <linux/regulator/consumer.h> 24 + 25 + #include <media/v4l2-cci.h> 24 26 #include <media/v4l2-ctrls.h> 25 27 #include <media/v4l2-device.h> 26 28 #include <media/v4l2-event.h> 27 29 #include <media/v4l2-fwnode.h> 28 30 #include <media/v4l2-mediabus.h> 29 - #include <asm/unaligned.h> 30 31 31 - #define IMX219_REG_VALUE_08BIT 1 32 - #define IMX219_REG_VALUE_16BIT 2 32 + /* Chip ID */ 33 + #define IMX219_REG_CHIP_ID CCI_REG16(0x0000) 34 + #define IMX219_CHIP_ID 0x0219 33 35 34 - #define IMX219_REG_MODE_SELECT 0x0100 36 + #define IMX219_REG_MODE_SELECT CCI_REG8(0x0100) 35 37 #define IMX219_MODE_STANDBY 0x00 36 38 #define IMX219_MODE_STREAMING 0x01 37 39 38 - /* Chip ID */ 39 - #define IMX219_REG_CHIP_ID 0x0000 40 - #define IMX219_CHIP_ID 0x0219 41 - 42 - /* External clock frequency is 24.0M */ 43 - #define IMX219_XCLK_FREQ 24000000 44 - 45 - /* Pixel rate is fixed for all the modes */ 46 - #define IMX219_PIXEL_RATE 182400000 47 - #define IMX219_PIXEL_RATE_4LANE 280800000 48 - 49 - #define IMX219_DEFAULT_LINK_FREQ 456000000 50 - #define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 51 - 52 - #define IMX219_REG_CSI_LANE_MODE 0x0114 40 + #define IMX219_REG_CSI_LANE_MODE CCI_REG8(0x0114) 53 41 #define IMX219_CSI_2_LANE_MODE 0x01 54 42 #define IMX219_CSI_4_LANE_MODE 0x03 55 43 44 + /* Analog gain control */ 45 + #define IMX219_REG_ANALOG_GAIN CCI_REG8(0x0157) 46 + #define IMX219_ANA_GAIN_MIN 0 47 + #define IMX219_ANA_GAIN_MAX 232 48 + #define IMX219_ANA_GAIN_STEP 1 49 + #define IMX219_ANA_GAIN_DEFAULT 0x0 50 + 51 + /* Digital gain control */ 52 + #define IMX219_REG_DIGITAL_GAIN CCI_REG16(0x0158) 53 + #define IMX219_DGTL_GAIN_MIN 0x0100 54 + #define IMX219_DGTL_GAIN_MAX 0x0fff 55 + #define IMX219_DGTL_GAIN_DEFAULT 0x0100 56 + #define IMX219_DGTL_GAIN_STEP 1 57 + 58 + /* Exposure control */ 59 + #define IMX219_REG_EXPOSURE CCI_REG16(0x015a) 60 + #define IMX219_EXPOSURE_MIN 4 61 + #define IMX219_EXPOSURE_STEP 1 62 + #define IMX219_EXPOSURE_DEFAULT 0x640 63 + #define IMX219_EXPOSURE_MAX 65535 64 + 56 65 /* V_TIMING internal */ 57 - #define IMX219_REG_VTS 0x0160 66 + #define IMX219_REG_VTS CCI_REG16(0x0160) 58 67 #define IMX219_VTS_15FPS 0x0dc6 59 68 #define IMX219_VTS_30FPS_1080P 0x06e3 60 69 #define IMX219_VTS_30FPS_BINNED 0x06e3 ··· 81 72 /* HBLANK control - read only */ 82 73 #define IMX219_PPL_DEFAULT 3448 83 74 84 - /* Exposure control */ 85 - #define IMX219_REG_EXPOSURE 0x015a 86 - #define IMX219_EXPOSURE_MIN 4 87 - #define IMX219_EXPOSURE_STEP 1 88 - #define IMX219_EXPOSURE_DEFAULT 0x640 89 - #define IMX219_EXPOSURE_MAX 65535 90 - 91 - /* Analog gain control */ 92 - #define IMX219_REG_ANALOG_GAIN 0x0157 93 - #define IMX219_ANA_GAIN_MIN 0 94 - #define IMX219_ANA_GAIN_MAX 232 95 - #define IMX219_ANA_GAIN_STEP 1 96 - #define IMX219_ANA_GAIN_DEFAULT 0x0 97 - 98 - /* Digital gain control */ 99 - #define IMX219_REG_DIGITAL_GAIN 0x0158 100 - #define IMX219_DGTL_GAIN_MIN 0x0100 101 - #define IMX219_DGTL_GAIN_MAX 0x0fff 102 - #define IMX219_DGTL_GAIN_DEFAULT 0x0100 103 - #define IMX219_DGTL_GAIN_STEP 1 104 - 105 - #define IMX219_REG_ORIENTATION 0x0172 75 + #define IMX219_REG_ORIENTATION CCI_REG8(0x0172) 106 76 107 77 /* Binning Mode */ 108 - #define IMX219_REG_BINNING_MODE 0x0174 78 + #define IMX219_REG_BINNING_MODE CCI_REG16(0x0174) 109 79 #define IMX219_BINNING_NONE 0x0000 110 80 #define IMX219_BINNING_2X2 0x0101 111 81 #define IMX219_BINNING_2X2_ANALOG 0x0303 112 82 113 83 /* Test Pattern Control */ 114 - #define IMX219_REG_TEST_PATTERN 0x0600 84 + #define IMX219_REG_TEST_PATTERN CCI_REG16(0x0600) 115 85 #define IMX219_TEST_PATTERN_DISABLE 0 116 86 #define IMX219_TEST_PATTERN_SOLID_COLOR 1 117 87 #define IMX219_TEST_PATTERN_COLOR_BARS 2 ··· 98 110 #define IMX219_TEST_PATTERN_PN9 4 99 111 100 112 /* Test pattern colour components */ 101 - #define IMX219_REG_TESTP_RED 0x0602 102 - #define IMX219_REG_TESTP_GREENR 0x0604 103 - #define IMX219_REG_TESTP_BLUE 0x0606 104 - #define IMX219_REG_TESTP_GREENB 0x0608 113 + #define IMX219_REG_TESTP_RED CCI_REG16(0x0602) 114 + #define IMX219_REG_TESTP_GREENR CCI_REG16(0x0604) 115 + #define IMX219_REG_TESTP_BLUE CCI_REG16(0x0606) 116 + #define IMX219_REG_TESTP_GREENB CCI_REG16(0x0608) 105 117 #define IMX219_TESTP_COLOUR_MIN 0 106 118 #define IMX219_TESTP_COLOUR_MAX 0x03ff 107 119 #define IMX219_TESTP_COLOUR_STEP 1 ··· 109 121 #define IMX219_TESTP_GREENR_DEFAULT 0 110 122 #define IMX219_TESTP_BLUE_DEFAULT 0 111 123 #define IMX219_TESTP_GREENB_DEFAULT 0 124 + 125 + /* External clock frequency is 24.0M */ 126 + #define IMX219_XCLK_FREQ 24000000 127 + 128 + /* Pixel rate is fixed for all the modes */ 129 + #define IMX219_PIXEL_RATE 182400000 130 + #define IMX219_PIXEL_RATE_4LANE 280800000 131 + 132 + #define IMX219_DEFAULT_LINK_FREQ 456000000 133 + #define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 112 134 113 135 /* IMX219 native and active pixel array size. */ 114 136 #define IMX219_NATIVE_WIDTH 3296U ··· 128 130 #define IMX219_PIXEL_ARRAY_WIDTH 3280U 129 131 #define IMX219_PIXEL_ARRAY_HEIGHT 2464U 130 132 131 - struct imx219_reg { 132 - u16 address; 133 - u8 val; 134 - }; 135 - 136 133 struct imx219_reg_list { 137 134 unsigned int num_of_regs; 138 - const struct imx219_reg *regs; 135 + const struct cci_reg_sequence *regs; 139 136 }; 140 137 141 138 /* Mode : resolution and related config&values */ ··· 153 160 bool binning; 154 161 }; 155 162 156 - static const struct imx219_reg imx219_common_regs[] = { 157 - {0x0100, 0x00}, /* Mode Select */ 163 + static const struct cci_reg_sequence imx219_common_regs[] = { 164 + { CCI_REG8(0x0100), 0x00 }, /* Mode Select */ 158 165 159 166 /* To Access Addresses 3000-5fff, send the following commands */ 160 - {0x30eb, 0x0c}, 161 - {0x30eb, 0x05}, 162 - {0x300a, 0xff}, 163 - {0x300b, 0xff}, 164 - {0x30eb, 0x05}, 165 - {0x30eb, 0x09}, 167 + { CCI_REG8(0x30eb), 0x0c }, 168 + { CCI_REG8(0x30eb), 0x05 }, 169 + { CCI_REG8(0x300a), 0xff }, 170 + { CCI_REG8(0x300b), 0xff }, 171 + { CCI_REG8(0x30eb), 0x05 }, 172 + { CCI_REG8(0x30eb), 0x09 }, 166 173 167 174 /* PLL Clock Table */ 168 - {0x0301, 0x05}, /* VTPXCK_DIV */ 169 - {0x0303, 0x01}, /* VTSYSCK_DIV */ 170 - {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ 171 - {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ 172 - {0x0306, 0x00}, /* PLL_VT_MPY */ 173 - {0x0307, 0x39}, 174 - {0x030b, 0x01}, /* OP_SYS_CLK_DIV */ 175 - {0x030c, 0x00}, /* PLL_OP_MPY */ 176 - {0x030d, 0x72}, 175 + { CCI_REG8(0x0301), 0x05 }, /* VTPXCK_DIV */ 176 + { CCI_REG8(0x0303), 0x01 }, /* VTSYSCK_DIV */ 177 + { CCI_REG8(0x0304), 0x03 }, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ 178 + { CCI_REG8(0x0305), 0x03 }, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ 179 + { CCI_REG8(0x0306), 0x00 }, /* PLL_VT_MPY */ 180 + { CCI_REG8(0x0307), 0x39 }, 181 + { CCI_REG8(0x030b), 0x01 }, /* OP_SYS_CLK_DIV */ 182 + { CCI_REG8(0x030c), 0x00 }, /* PLL_OP_MPY */ 183 + { CCI_REG8(0x030d), 0x72 }, 177 184 178 185 /* Undocumented registers */ 179 - {0x455e, 0x00}, 180 - {0x471e, 0x4b}, 181 - {0x4767, 0x0f}, 182 - {0x4750, 0x14}, 183 - {0x4540, 0x00}, 184 - {0x47b4, 0x14}, 185 - {0x4713, 0x30}, 186 - {0x478b, 0x10}, 187 - {0x478f, 0x10}, 188 - {0x4793, 0x10}, 189 - {0x4797, 0x0e}, 190 - {0x479b, 0x0e}, 186 + { CCI_REG8(0x455e), 0x00 }, 187 + { CCI_REG8(0x471e), 0x4b }, 188 + { CCI_REG8(0x4767), 0x0f }, 189 + { CCI_REG8(0x4750), 0x14 }, 190 + { CCI_REG8(0x4540), 0x00 }, 191 + { CCI_REG8(0x47b4), 0x14 }, 192 + { CCI_REG8(0x4713), 0x30 }, 193 + { CCI_REG8(0x478b), 0x10 }, 194 + { CCI_REG8(0x478f), 0x10 }, 195 + { CCI_REG8(0x4793), 0x10 }, 196 + { CCI_REG8(0x4797), 0x0e }, 197 + { CCI_REG8(0x479b), 0x0e }, 191 198 192 199 /* Frame Bank Register Group "A" */ 193 - {0x0162, 0x0d}, /* Line_Length_A */ 194 - {0x0163, 0x78}, 195 - {0x0170, 0x01}, /* X_ODD_INC_A */ 196 - {0x0171, 0x01}, /* Y_ODD_INC_A */ 200 + { CCI_REG8(0x0162), 0x0d }, /* Line_Length_A */ 201 + { CCI_REG8(0x0163), 0x78 }, 202 + { CCI_REG8(0x0170), 0x01 }, /* X_ODD_INC_A */ 203 + { CCI_REG8(0x0171), 0x01 }, /* Y_ODD_INC_A */ 197 204 198 205 /* Output setup registers */ 199 - {0x0114, 0x01}, /* CSI 2-Lane Mode */ 200 - {0x0128, 0x00}, /* DPHY Auto Mode */ 201 - {0x012a, 0x18}, /* EXCK_Freq */ 202 - {0x012b, 0x00}, 206 + { CCI_REG8(0x0114), 0x01 }, /* CSI 2-Lane Mode */ 207 + { CCI_REG8(0x0128), 0x00 }, /* DPHY Auto Mode */ 208 + { CCI_REG8(0x012a), 0x18 }, /* EXCK_Freq */ 209 + { CCI_REG8(0x012b), 0x00 }, 203 210 }; 204 211 205 212 /* ··· 207 214 * driver. 208 215 * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. 209 216 */ 210 - static const struct imx219_reg mode_3280x2464_regs[] = { 211 - {0x0164, 0x00}, 212 - {0x0165, 0x00}, 213 - {0x0166, 0x0c}, 214 - {0x0167, 0xcf}, 215 - {0x0168, 0x00}, 216 - {0x0169, 0x00}, 217 - {0x016a, 0x09}, 218 - {0x016b, 0x9f}, 219 - {0x016c, 0x0c}, 220 - {0x016d, 0xd0}, 221 - {0x016e, 0x09}, 222 - {0x016f, 0xa0}, 223 - {0x0624, 0x0c}, 224 - {0x0625, 0xd0}, 225 - {0x0626, 0x09}, 226 - {0x0627, 0xa0}, 217 + static const struct cci_reg_sequence mode_3280x2464_regs[] = { 218 + { CCI_REG8(0x0164), 0x00 }, 219 + { CCI_REG8(0x0165), 0x00 }, 220 + { CCI_REG8(0x0166), 0x0c }, 221 + { CCI_REG8(0x0167), 0xcf }, 222 + { CCI_REG8(0x0168), 0x00 }, 223 + { CCI_REG8(0x0169), 0x00 }, 224 + { CCI_REG8(0x016a), 0x09 }, 225 + { CCI_REG8(0x016b), 0x9f }, 226 + { CCI_REG8(0x016c), 0x0c }, 227 + { CCI_REG8(0x016d), 0xd0 }, 228 + { CCI_REG8(0x016e), 0x09 }, 229 + { CCI_REG8(0x016f), 0xa0 }, 230 + { CCI_REG8(0x0624), 0x0c }, 231 + { CCI_REG8(0x0625), 0xd0 }, 232 + { CCI_REG8(0x0626), 0x09 }, 233 + { CCI_REG8(0x0627), 0xa0 }, 227 234 }; 228 235 229 - static const struct imx219_reg mode_1920_1080_regs[] = { 230 - {0x0164, 0x02}, 231 - {0x0165, 0xa8}, 232 - {0x0166, 0x0a}, 233 - {0x0167, 0x27}, 234 - {0x0168, 0x02}, 235 - {0x0169, 0xb4}, 236 - {0x016a, 0x06}, 237 - {0x016b, 0xeb}, 238 - {0x016c, 0x07}, 239 - {0x016d, 0x80}, 240 - {0x016e, 0x04}, 241 - {0x016f, 0x38}, 242 - {0x0624, 0x07}, 243 - {0x0625, 0x80}, 244 - {0x0626, 0x04}, 245 - {0x0627, 0x38}, 236 + static const struct cci_reg_sequence mode_1920_1080_regs[] = { 237 + { CCI_REG8(0x0164), 0x02 }, 238 + { CCI_REG8(0x0165), 0xa8 }, 239 + { CCI_REG8(0x0166), 0x0a }, 240 + { CCI_REG8(0x0167), 0x27 }, 241 + { CCI_REG8(0x0168), 0x02 }, 242 + { CCI_REG8(0x0169), 0xb4 }, 243 + { CCI_REG8(0x016a), 0x06 }, 244 + { CCI_REG8(0x016b), 0xeb }, 245 + { CCI_REG8(0x016c), 0x07 }, 246 + { CCI_REG8(0x016d), 0x80 }, 247 + { CCI_REG8(0x016e), 0x04 }, 248 + { CCI_REG8(0x016f), 0x38 }, 249 + { CCI_REG8(0x0624), 0x07 }, 250 + { CCI_REG8(0x0625), 0x80 }, 251 + { CCI_REG8(0x0626), 0x04 }, 252 + { CCI_REG8(0x0627), 0x38 }, 246 253 }; 247 254 248 - static const struct imx219_reg mode_1640_1232_regs[] = { 249 - {0x0164, 0x00}, 250 - {0x0165, 0x00}, 251 - {0x0166, 0x0c}, 252 - {0x0167, 0xcf}, 253 - {0x0168, 0x00}, 254 - {0x0169, 0x00}, 255 - {0x016a, 0x09}, 256 - {0x016b, 0x9f}, 257 - {0x016c, 0x06}, 258 - {0x016d, 0x68}, 259 - {0x016e, 0x04}, 260 - {0x016f, 0xd0}, 261 - {0x0624, 0x06}, 262 - {0x0625, 0x68}, 263 - {0x0626, 0x04}, 264 - {0x0627, 0xd0}, 255 + static const struct cci_reg_sequence mode_1640_1232_regs[] = { 256 + { CCI_REG8(0x0164), 0x00 }, 257 + { CCI_REG8(0x0165), 0x00 }, 258 + { CCI_REG8(0x0166), 0x0c }, 259 + { CCI_REG8(0x0167), 0xcf }, 260 + { CCI_REG8(0x0168), 0x00 }, 261 + { CCI_REG8(0x0169), 0x00 }, 262 + { CCI_REG8(0x016a), 0x09 }, 263 + { CCI_REG8(0x016b), 0x9f }, 264 + { CCI_REG8(0x016c), 0x06 }, 265 + { CCI_REG8(0x016d), 0x68 }, 266 + { CCI_REG8(0x016e), 0x04 }, 267 + { CCI_REG8(0x016f), 0xd0 }, 268 + { CCI_REG8(0x0624), 0x06 }, 269 + { CCI_REG8(0x0625), 0x68 }, 270 + { CCI_REG8(0x0626), 0x04 }, 271 + { CCI_REG8(0x0627), 0xd0 }, 265 272 }; 266 273 267 - static const struct imx219_reg mode_640_480_regs[] = { 268 - {0x0164, 0x03}, 269 - {0x0165, 0xe8}, 270 - {0x0166, 0x08}, 271 - {0x0167, 0xe7}, 272 - {0x0168, 0x02}, 273 - {0x0169, 0xf0}, 274 - {0x016a, 0x06}, 275 - {0x016b, 0xaf}, 276 - {0x016c, 0x02}, 277 - {0x016d, 0x80}, 278 - {0x016e, 0x01}, 279 - {0x016f, 0xe0}, 280 - {0x0624, 0x06}, 281 - {0x0625, 0x68}, 282 - {0x0626, 0x04}, 283 - {0x0627, 0xd0}, 274 + static const struct cci_reg_sequence mode_640_480_regs[] = { 275 + { CCI_REG8(0x0164), 0x03 }, 276 + { CCI_REG8(0x0165), 0xe8 }, 277 + { CCI_REG8(0x0166), 0x08 }, 278 + { CCI_REG8(0x0167), 0xe7 }, 279 + { CCI_REG8(0x0168), 0x02 }, 280 + { CCI_REG8(0x0169), 0xf0 }, 281 + { CCI_REG8(0x016a), 0x06 }, 282 + { CCI_REG8(0x016b), 0xaf }, 283 + { CCI_REG8(0x016c), 0x02 }, 284 + { CCI_REG8(0x016d), 0x80 }, 285 + { CCI_REG8(0x016e), 0x01 }, 286 + { CCI_REG8(0x016f), 0xe0 }, 287 + { CCI_REG8(0x0624), 0x06 }, 288 + { CCI_REG8(0x0625), 0x68 }, 289 + { CCI_REG8(0x0626), 0x04 }, 290 + { CCI_REG8(0x0627), 0xd0 }, 284 291 }; 285 292 286 - static const struct imx219_reg raw8_framefmt_regs[] = { 287 - {0x018c, 0x08}, 288 - {0x018d, 0x08}, 289 - {0x0309, 0x08}, 293 + static const struct cci_reg_sequence raw8_framefmt_regs[] = { 294 + { CCI_REG8(0x018c), 0x08 }, 295 + { CCI_REG8(0x018d), 0x08 }, 296 + { CCI_REG8(0x0309), 0x08 }, 290 297 }; 291 298 292 - static const struct imx219_reg raw10_framefmt_regs[] = { 293 - {0x018c, 0x0a}, 294 - {0x018d, 0x0a}, 295 - {0x0309, 0x0a}, 299 + static const struct cci_reg_sequence raw10_framefmt_regs[] = { 300 + { CCI_REG8(0x018c), 0x0a }, 301 + { CCI_REG8(0x018d), 0x0a }, 302 + { CCI_REG8(0x0309), 0x0a }, 296 303 }; 297 304 298 305 static const s64 imx219_link_freq_menu[] = { ··· 453 460 struct v4l2_subdev sd; 454 461 struct media_pad pad; 455 462 463 + struct regmap *regmap; 456 464 struct clk *xclk; /* system clock to IMX219 */ 457 465 u32 xclk_freq; 458 466 ··· 482 488 return container_of(_sd, struct imx219, sd); 483 489 } 484 490 485 - /* Read registers up to 2 at a time */ 486 - static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val) 487 - { 488 - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); 489 - struct i2c_msg msgs[2]; 490 - u8 addr_buf[2] = { reg >> 8, reg & 0xff }; 491 - u8 data_buf[4] = { 0, }; 492 - int ret; 493 - 494 - if (len > 4) 495 - return -EINVAL; 496 - 497 - /* Write register address */ 498 - msgs[0].addr = client->addr; 499 - msgs[0].flags = 0; 500 - msgs[0].len = ARRAY_SIZE(addr_buf); 501 - msgs[0].buf = addr_buf; 502 - 503 - /* Read data from register */ 504 - msgs[1].addr = client->addr; 505 - msgs[1].flags = I2C_M_RD; 506 - msgs[1].len = len; 507 - msgs[1].buf = &data_buf[4 - len]; 508 - 509 - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 510 - if (ret != ARRAY_SIZE(msgs)) 511 - return -EIO; 512 - 513 - *val = get_unaligned_be32(data_buf); 514 - 515 - return 0; 516 - } 517 - 518 - /* Write registers up to 2 at a time */ 519 - static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val) 520 - { 521 - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); 522 - u8 buf[6]; 523 - 524 - if (len > 4) 525 - return -EINVAL; 526 - 527 - put_unaligned_be16(reg, buf); 528 - put_unaligned_be32(val << (8 * (4 - len)), buf + 2); 529 - if (i2c_master_send(client, buf, len + 2) != len + 2) 530 - return -EIO; 531 - 532 - return 0; 533 - } 534 - 535 - /* Write a list of registers */ 536 - static int imx219_write_regs(struct imx219 *imx219, 537 - const struct imx219_reg *regs, u32 len) 538 - { 539 - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); 540 - unsigned int i; 541 - int ret; 542 - 543 - for (i = 0; i < len; i++) { 544 - ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val); 545 - if (ret) { 546 - dev_err_ratelimited(&client->dev, 547 - "Failed to write reg 0x%4.4x. error = %d\n", 548 - regs[i].address, ret); 549 - 550 - return ret; 551 - } 552 - } 553 - 554 - return 0; 555 - } 556 - 557 491 /* Get bayer order based on flip setting. */ 558 492 static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) 559 493 { ··· 505 583 struct imx219 *imx219 = 506 584 container_of(ctrl->handler, struct imx219, ctrl_handler); 507 585 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); 508 - int ret; 586 + int ret = 0; 509 587 510 588 if (ctrl->id == V4L2_CID_VBLANK) { 511 589 int exposure_max, exposure_def; ··· 529 607 530 608 switch (ctrl->id) { 531 609 case V4L2_CID_ANALOGUE_GAIN: 532 - ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN, 533 - IMX219_REG_VALUE_08BIT, ctrl->val); 610 + cci_write(imx219->regmap, IMX219_REG_ANALOG_GAIN, 611 + ctrl->val, &ret); 534 612 break; 535 613 case V4L2_CID_EXPOSURE: 536 - ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, 537 - IMX219_REG_VALUE_16BIT, ctrl->val); 614 + cci_write(imx219->regmap, IMX219_REG_EXPOSURE, 615 + ctrl->val, &ret); 538 616 break; 539 617 case V4L2_CID_DIGITAL_GAIN: 540 - ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, 541 - IMX219_REG_VALUE_16BIT, ctrl->val); 618 + cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, 619 + ctrl->val, &ret); 542 620 break; 543 621 case V4L2_CID_TEST_PATTERN: 544 - ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN, 545 - IMX219_REG_VALUE_16BIT, 546 - imx219_test_pattern_val[ctrl->val]); 622 + cci_write(imx219->regmap, IMX219_REG_TEST_PATTERN, 623 + imx219_test_pattern_val[ctrl->val], &ret); 547 624 break; 548 625 case V4L2_CID_HFLIP: 549 626 case V4L2_CID_VFLIP: 550 - ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1, 551 - imx219->hflip->val | 552 - imx219->vflip->val << 1); 627 + cci_write(imx219->regmap, IMX219_REG_ORIENTATION, 628 + imx219->hflip->val | imx219->vflip->val << 1, &ret); 553 629 break; 554 630 case V4L2_CID_VBLANK: 555 - ret = imx219_write_reg(imx219, IMX219_REG_VTS, 556 - IMX219_REG_VALUE_16BIT, 557 - imx219->mode->height + ctrl->val); 631 + cci_write(imx219->regmap, IMX219_REG_VTS, 632 + imx219->mode->height + ctrl->val, &ret); 558 633 break; 559 634 case V4L2_CID_TEST_PATTERN_RED: 560 - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, 561 - IMX219_REG_VALUE_16BIT, ctrl->val); 635 + cci_write(imx219->regmap, IMX219_REG_TESTP_RED, 636 + ctrl->val, &ret); 562 637 break; 563 638 case V4L2_CID_TEST_PATTERN_GREENR: 564 - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR, 565 - IMX219_REG_VALUE_16BIT, ctrl->val); 639 + cci_write(imx219->regmap, IMX219_REG_TESTP_GREENR, 640 + ctrl->val, &ret); 566 641 break; 567 642 case V4L2_CID_TEST_PATTERN_BLUE: 568 - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE, 569 - IMX219_REG_VALUE_16BIT, ctrl->val); 643 + cci_write(imx219->regmap, IMX219_REG_TESTP_BLUE, 644 + ctrl->val, &ret); 570 645 break; 571 646 case V4L2_CID_TEST_PATTERN_GREENB: 572 - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB, 573 - IMX219_REG_VALUE_16BIT, ctrl->val); 647 + cci_write(imx219->regmap, IMX219_REG_TESTP_GREENB, 648 + ctrl->val, &ret); 574 649 break; 575 650 default: 576 651 dev_info(&client->dev, ··· 718 799 case MEDIA_BUS_FMT_SGRBG8_1X8: 719 800 case MEDIA_BUS_FMT_SGBRG8_1X8: 720 801 case MEDIA_BUS_FMT_SBGGR8_1X8: 721 - return imx219_write_regs(imx219, raw8_framefmt_regs, 722 - ARRAY_SIZE(raw8_framefmt_regs)); 802 + return cci_multi_reg_write(imx219->regmap, raw8_framefmt_regs, 803 + ARRAY_SIZE(raw8_framefmt_regs), NULL); 723 804 724 805 case MEDIA_BUS_FMT_SRGGB10_1X10: 725 806 case MEDIA_BUS_FMT_SGRBG10_1X10: 726 807 case MEDIA_BUS_FMT_SGBRG10_1X10: 727 808 case MEDIA_BUS_FMT_SBGGR10_1X10: 728 - return imx219_write_regs(imx219, raw10_framefmt_regs, 729 - ARRAY_SIZE(raw10_framefmt_regs)); 809 + return cci_multi_reg_write(imx219->regmap, raw10_framefmt_regs, 810 + ARRAY_SIZE(raw10_framefmt_regs), NULL); 730 811 } 731 812 732 813 return -EINVAL; ··· 735 816 static int imx219_set_binning(struct imx219 *imx219, 736 817 const struct v4l2_mbus_framefmt *format) 737 818 { 738 - if (!imx219->mode->binning) { 739 - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, 740 - IMX219_REG_VALUE_16BIT, 741 - IMX219_BINNING_NONE); 742 - } 819 + if (!imx219->mode->binning) 820 + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, 821 + IMX219_BINNING_NONE, NULL); 743 822 744 823 switch (format->code) { 745 824 case MEDIA_BUS_FMT_SRGGB8_1X8: 746 825 case MEDIA_BUS_FMT_SGRBG8_1X8: 747 826 case MEDIA_BUS_FMT_SGBRG8_1X8: 748 827 case MEDIA_BUS_FMT_SBGGR8_1X8: 749 - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, 750 - IMX219_REG_VALUE_16BIT, 751 - IMX219_BINNING_2X2_ANALOG); 828 + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, 829 + IMX219_BINNING_2X2_ANALOG, NULL); 752 830 753 831 case MEDIA_BUS_FMT_SRGGB10_1X10: 754 832 case MEDIA_BUS_FMT_SGRBG10_1X10: 755 833 case MEDIA_BUS_FMT_SGBRG10_1X10: 756 834 case MEDIA_BUS_FMT_SBGGR10_1X10: 757 - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, 758 - IMX219_REG_VALUE_16BIT, 759 - IMX219_BINNING_2X2); 835 + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, 836 + IMX219_BINNING_2X2, NULL); 760 837 } 761 838 762 839 return -EINVAL; ··· 791 876 792 877 static int imx219_configure_lanes(struct imx219 *imx219) 793 878 { 794 - return imx219_write_reg(imx219, IMX219_REG_CSI_LANE_MODE, 795 - IMX219_REG_VALUE_08BIT, (imx219->lanes == 2) ? 796 - IMX219_CSI_2_LANE_MODE : IMX219_CSI_4_LANE_MODE); 879 + return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, 880 + imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : 881 + IMX219_CSI_4_LANE_MODE, NULL); 797 882 }; 798 883 799 884 static int imx219_start_streaming(struct imx219 *imx219, ··· 809 894 return ret; 810 895 811 896 /* Send all registers that are common to all modes */ 812 - ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs)); 897 + ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, 898 + ARRAY_SIZE(imx219_common_regs), NULL); 813 899 if (ret) { 814 900 dev_err(&client->dev, "%s failed to send mfg header\n", __func__); 815 901 goto err_rpm_put; ··· 825 909 826 910 /* Apply default values of current mode */ 827 911 reg_list = &imx219->mode->reg_list; 828 - ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); 912 + ret = cci_multi_reg_write(imx219->regmap, reg_list->regs, 913 + reg_list->num_of_regs, NULL); 829 914 if (ret) { 830 915 dev_err(&client->dev, "%s failed to set mode\n", __func__); 831 916 goto err_rpm_put; ··· 853 936 goto err_rpm_put; 854 937 855 938 /* set stream on register */ 856 - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, 857 - IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); 939 + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, 940 + IMX219_MODE_STREAMING, NULL); 858 941 if (ret) 859 942 goto err_rpm_put; 860 943 ··· 875 958 int ret; 876 959 877 960 /* set stream off register */ 878 - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, 879 - IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); 961 + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, 962 + IMX219_MODE_STANDBY, NULL); 880 963 if (ret) 881 964 dev_err(&client->dev, "%s failed to set stream\n", __func__); 882 965 ··· 975 1058 { 976 1059 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); 977 1060 int ret; 978 - u32 val; 1061 + u64 val; 979 1062 980 - ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID, 981 - IMX219_REG_VALUE_16BIT, &val); 1063 + ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); 982 1064 if (ret) { 983 1065 dev_err(&client->dev, "failed to read chip id %x\n", 984 1066 IMX219_CHIP_ID); ··· 985 1069 } 986 1070 987 1071 if (val != IMX219_CHIP_ID) { 988 - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", 1072 + dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", 989 1073 IMX219_CHIP_ID, val); 990 1074 return -EIO; 991 1075 } ··· 1209 1293 if (imx219_check_hwcfg(dev, imx219)) 1210 1294 return -EINVAL; 1211 1295 1296 + imx219->regmap = devm_cci_regmap_init_i2c(client, 16); 1297 + if (IS_ERR(imx219->regmap)) { 1298 + ret = PTR_ERR(imx219->regmap); 1299 + dev_err(dev, "failed to initialize CCI: %d\n", ret); 1300 + return ret; 1301 + } 1302 + 1212 1303 /* Get system clock (xclk) */ 1213 1304 imx219->xclk = devm_clk_get(dev, NULL); 1214 1305 if (IS_ERR(imx219->xclk)) { ··· 1259 1336 * streaming is started, so upon power up switch the modes to: 1260 1337 * streaming -> standby 1261 1338 */ 1262 - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, 1263 - IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); 1339 + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, 1340 + IMX219_MODE_STREAMING, NULL); 1264 1341 if (ret < 0) 1265 1342 goto error_power_off; 1343 + 1266 1344 usleep_range(100, 110); 1267 1345 1268 1346 /* put sensor back to standby mode */ 1269 - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, 1270 - IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); 1347 + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, 1348 + IMX219_MODE_STANDBY, NULL); 1271 1349 if (ret < 0) 1272 1350 goto error_power_off; 1351 + 1273 1352 usleep_range(100, 110); 1274 1353 1275 1354 ret = imx219_init_controls(imx219);