1 /* 2 * Driver for MT9V022, MT9V024, MT9V032, and MT9V034 CMOS Image Sensors 3 * 4 * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com> 5 * 6 * Based on the MT9M001 driver, 7 * 8 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/clk.h> 16 #include <linux/delay.h> 17 #include <linux/i2c.h> 18 #include <linux/log2.h> 19 #include <linux/mutex.h> 20 #include <linux/of.h> 21 #include <linux/of_gpio.h> 22 #include <linux/regmap.h> 23 #include <linux/slab.h> 24 #include <linux/videodev2.h> 25 #include <linux/v4l2-mediabus.h> 26 #include <linux/module.h> 27 28 #include <media/mt9v032.h> 29 #include <media/v4l2-ctrls.h> 30 #include <media/v4l2-device.h> 31 #include <media/v4l2-of.h> 32 #include <media/v4l2-subdev.h> 33 34 /* The first four rows are black rows. The active area spans 753x481 pixels. */ 35 #define MT9V032_PIXEL_ARRAY_HEIGHT 485 36 #define MT9V032_PIXEL_ARRAY_WIDTH 753 37 38 #define MT9V032_SYSCLK_FREQ_DEF 26600000 39 40 #define MT9V032_CHIP_VERSION 0x00 41 #define MT9V032_CHIP_ID_REV1 0x1311 42 #define MT9V032_CHIP_ID_REV3 0x1313 43 #define MT9V034_CHIP_ID_REV1 0X1324 44 #define MT9V032_COLUMN_START 0x01 45 #define MT9V032_COLUMN_START_MIN 1 46 #define MT9V032_COLUMN_START_DEF 1 47 #define MT9V032_COLUMN_START_MAX 752 48 #define MT9V032_ROW_START 0x02 49 #define MT9V032_ROW_START_MIN 4 50 #define MT9V032_ROW_START_DEF 5 51 #define MT9V032_ROW_START_MAX 482 52 #define MT9V032_WINDOW_HEIGHT 0x03 53 #define MT9V032_WINDOW_HEIGHT_MIN 1 54 #define MT9V032_WINDOW_HEIGHT_DEF 480 55 #define MT9V032_WINDOW_HEIGHT_MAX 480 56 #define MT9V032_WINDOW_WIDTH 0x04 57 #define MT9V032_WINDOW_WIDTH_MIN 1 58 #define MT9V032_WINDOW_WIDTH_DEF 752 59 #define MT9V032_WINDOW_WIDTH_MAX 752 60 #define MT9V032_HORIZONTAL_BLANKING 0x05 61 #define MT9V032_HORIZONTAL_BLANKING_MIN 43 62 #define MT9V034_HORIZONTAL_BLANKING_MIN 61 63 #define MT9V032_HORIZONTAL_BLANKING_DEF 94 64 #define MT9V032_HORIZONTAL_BLANKING_MAX 1023 65 #define MT9V032_VERTICAL_BLANKING 0x06 66 #define MT9V032_VERTICAL_BLANKING_MIN 4 67 #define MT9V034_VERTICAL_BLANKING_MIN 2 68 #define MT9V032_VERTICAL_BLANKING_DEF 45 69 #define MT9V032_VERTICAL_BLANKING_MAX 3000 70 #define MT9V034_VERTICAL_BLANKING_MAX 32288 71 #define MT9V032_CHIP_CONTROL 0x07 72 #define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3) 73 #define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7) 74 #define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8) 75 #define MT9V032_SHUTTER_WIDTH1 0x08 76 #define MT9V032_SHUTTER_WIDTH2 0x09 77 #define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a 78 #define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b 79 #define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1 80 #define MT9V034_TOTAL_SHUTTER_WIDTH_MIN 0 81 #define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480 82 #define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767 83 #define MT9V034_TOTAL_SHUTTER_WIDTH_MAX 32765 84 #define MT9V032_RESET 0x0c 85 #define MT9V032_READ_MODE 0x0d 86 #define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0) 87 #define MT9V032_READ_MODE_ROW_BIN_SHIFT 0 88 #define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2) 89 #define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2 90 #define MT9V032_READ_MODE_ROW_FLIP (1 << 4) 91 #define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5) 92 #define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6) 93 #define MT9V032_READ_MODE_DARK_ROWS (1 << 7) 94 #define MT9V032_READ_MODE_RESERVED 0x0300 95 #define MT9V032_PIXEL_OPERATION_MODE 0x0f 96 #define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0) 97 #define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1) 98 #define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2) 99 #define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6) 100 #define MT9V032_ANALOG_GAIN 0x35 101 #define MT9V032_ANALOG_GAIN_MIN 16 102 #define MT9V032_ANALOG_GAIN_DEF 16 103 #define MT9V032_ANALOG_GAIN_MAX 64 104 #define MT9V032_MAX_ANALOG_GAIN 0x36 105 #define MT9V032_MAX_ANALOG_GAIN_MAX 127 106 #define MT9V032_FRAME_DARK_AVERAGE 0x42 107 #define MT9V032_DARK_AVG_THRESH 0x46 108 #define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0) 109 #define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0 110 #define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8) 111 #define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8 112 #define MT9V032_ROW_NOISE_CORR_CONTROL 0x70 113 #define MT9V034_ROW_NOISE_CORR_ENABLE (1 << 0) 114 #define MT9V034_ROW_NOISE_CORR_USE_BLK_AVG (1 << 1) 115 #define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5) 116 #define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7) 117 #define MT9V032_PIXEL_CLOCK 0x74 118 #define MT9V034_PIXEL_CLOCK 0x72 119 #define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0) 120 #define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1) 121 #define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2) 122 #define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3) 123 #define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4) 124 #define MT9V032_TEST_PATTERN 0x7f 125 #define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0) 126 #define MT9V032_TEST_PATTERN_DATA_SHIFT 0 127 #define MT9V032_TEST_PATTERN_USE_DATA (1 << 10) 128 #define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11) 129 #define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11) 130 #define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11) 131 #define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11) 132 #define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11) 133 #define MT9V032_TEST_PATTERN_ENABLE (1 << 13) 134 #define MT9V032_TEST_PATTERN_FLIP (1 << 14) 135 #define MT9V032_AEC_AGC_ENABLE 0xaf 136 #define MT9V032_AEC_ENABLE (1 << 0) 137 #define MT9V032_AGC_ENABLE (1 << 1) 138 #define MT9V032_THERMAL_INFO 0xc1 139 140 enum mt9v032_model { 141 MT9V032_MODEL_V022_COLOR, /* MT9V022IX7ATC */ 142 MT9V032_MODEL_V022_MONO, /* MT9V022IX7ATM */ 143 MT9V032_MODEL_V024_COLOR, /* MT9V024IA7XTC */ 144 MT9V032_MODEL_V024_MONO, /* MT9V024IA7XTM */ 145 MT9V032_MODEL_V032_COLOR, /* MT9V032C12STM */ 146 MT9V032_MODEL_V032_MONO, /* MT9V032C12STC */ 147 MT9V032_MODEL_V034_COLOR, 148 MT9V032_MODEL_V034_MONO, 149 }; 150 151 struct mt9v032_model_version { 152 unsigned int version; 153 const char *name; 154 }; 155 156 struct mt9v032_model_data { 157 unsigned int min_row_time; 158 unsigned int min_hblank; 159 unsigned int min_vblank; 160 unsigned int max_vblank; 161 unsigned int min_shutter; 162 unsigned int max_shutter; 163 unsigned int pclk_reg; 164 }; 165 166 struct mt9v032_model_info { 167 const struct mt9v032_model_data *data; 168 bool color; 169 }; 170 171 static const struct mt9v032_model_version mt9v032_versions[] = { 172 { MT9V032_CHIP_ID_REV1, "MT9V022/MT9V032 rev1/2" }, 173 { MT9V032_CHIP_ID_REV3, "MT9V022/MT9V032 rev3" }, 174 { MT9V034_CHIP_ID_REV1, "MT9V024/MT9V034 rev1" }, 175 }; 176 177 static const struct mt9v032_model_data mt9v032_model_data[] = { 178 { 179 /* MT9V022, MT9V032 revisions 1/2/3 */ 180 .min_row_time = 660, 181 .min_hblank = MT9V032_HORIZONTAL_BLANKING_MIN, 182 .min_vblank = MT9V032_VERTICAL_BLANKING_MIN, 183 .max_vblank = MT9V032_VERTICAL_BLANKING_MAX, 184 .min_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MIN, 185 .max_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 186 .pclk_reg = MT9V032_PIXEL_CLOCK, 187 }, { 188 /* MT9V024, MT9V034 */ 189 .min_row_time = 690, 190 .min_hblank = MT9V034_HORIZONTAL_BLANKING_MIN, 191 .min_vblank = MT9V034_VERTICAL_BLANKING_MIN, 192 .max_vblank = MT9V034_VERTICAL_BLANKING_MAX, 193 .min_shutter = MT9V034_TOTAL_SHUTTER_WIDTH_MIN, 194 .max_shutter = MT9V034_TOTAL_SHUTTER_WIDTH_MAX, 195 .pclk_reg = MT9V034_PIXEL_CLOCK, 196 }, 197 }; 198 199 static const struct mt9v032_model_info mt9v032_models[] = { 200 [MT9V032_MODEL_V022_COLOR] = { 201 .data = &mt9v032_model_data[0], 202 .color = true, 203 }, 204 [MT9V032_MODEL_V022_MONO] = { 205 .data = &mt9v032_model_data[0], 206 .color = false, 207 }, 208 [MT9V032_MODEL_V024_COLOR] = { 209 .data = &mt9v032_model_data[1], 210 .color = true, 211 }, 212 [MT9V032_MODEL_V024_MONO] = { 213 .data = &mt9v032_model_data[1], 214 .color = false, 215 }, 216 [MT9V032_MODEL_V032_COLOR] = { 217 .data = &mt9v032_model_data[0], 218 .color = true, 219 }, 220 [MT9V032_MODEL_V032_MONO] = { 221 .data = &mt9v032_model_data[0], 222 .color = false, 223 }, 224 [MT9V032_MODEL_V034_COLOR] = { 225 .data = &mt9v032_model_data[1], 226 .color = true, 227 }, 228 [MT9V032_MODEL_V034_MONO] = { 229 .data = &mt9v032_model_data[1], 230 .color = false, 231 }, 232 }; 233 234 struct mt9v032 { 235 struct v4l2_subdev subdev; 236 struct media_pad pad; 237 238 struct v4l2_mbus_framefmt format; 239 struct v4l2_rect crop; 240 unsigned int hratio; 241 unsigned int vratio; 242 243 struct v4l2_ctrl_handler ctrls; 244 struct { 245 struct v4l2_ctrl *link_freq; 246 struct v4l2_ctrl *pixel_rate; 247 }; 248 249 struct mutex power_lock; 250 int power_count; 251 252 struct regmap *regmap; 253 struct clk *clk; 254 255 struct mt9v032_platform_data *pdata; 256 const struct mt9v032_model_info *model; 257 const struct mt9v032_model_version *version; 258 259 u32 sysclk; 260 u16 aec_agc; 261 u16 hblank; 262 struct { 263 struct v4l2_ctrl *test_pattern; 264 struct v4l2_ctrl *test_pattern_color; 265 }; 266 }; 267 268 static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) 269 { 270 return container_of(sd, struct mt9v032, subdev); 271 } 272 273 static int 274 mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable) 275 { 276 struct regmap *map = mt9v032->regmap; 277 u16 value = mt9v032->aec_agc; 278 int ret; 279 280 if (enable) 281 value |= which; 282 else 283 value &= ~which; 284 285 ret = regmap_write(map, MT9V032_AEC_AGC_ENABLE, value); 286 if (ret < 0) 287 return ret; 288 289 mt9v032->aec_agc = value; 290 return 0; 291 } 292 293 static int 294 mt9v032_update_hblank(struct mt9v032 *mt9v032) 295 { 296 struct v4l2_rect *crop = &mt9v032->crop; 297 unsigned int min_hblank = mt9v032->model->data->min_hblank; 298 unsigned int hblank; 299 300 if (mt9v032->version->version == MT9V034_CHIP_ID_REV1) 301 min_hblank += (mt9v032->hratio - 1) * 10; 302 min_hblank = max_t(int, mt9v032->model->data->min_row_time - crop->width, 303 min_hblank); 304 hblank = max_t(unsigned int, mt9v032->hblank, min_hblank); 305 306 return regmap_write(mt9v032->regmap, MT9V032_HORIZONTAL_BLANKING, 307 hblank); 308 } 309 310 static int mt9v032_power_on(struct mt9v032 *mt9v032) 311 { 312 struct regmap *map = mt9v032->regmap; 313 int ret; 314 315 ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk); 316 if (ret < 0) 317 return ret; 318 319 ret = clk_prepare_enable(mt9v032->clk); 320 if (ret) 321 return ret; 322 323 udelay(1); 324 325 /* Reset the chip and stop data read out */ 326 ret = regmap_write(map, MT9V032_RESET, 1); 327 if (ret < 0) 328 return ret; 329 330 ret = regmap_write(map, MT9V032_RESET, 0); 331 if (ret < 0) 332 return ret; 333 334 return regmap_write(map, MT9V032_CHIP_CONTROL, 0); 335 } 336 337 static void mt9v032_power_off(struct mt9v032 *mt9v032) 338 { 339 clk_disable_unprepare(mt9v032->clk); 340 } 341 342 static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on) 343 { 344 struct regmap *map = mt9v032->regmap; 345 int ret; 346 347 if (!on) { 348 mt9v032_power_off(mt9v032); 349 return 0; 350 } 351 352 ret = mt9v032_power_on(mt9v032); 353 if (ret < 0) 354 return ret; 355 356 /* Configure the pixel clock polarity */ 357 if (mt9v032->pdata && mt9v032->pdata->clk_pol) { 358 ret = regmap_write(map, mt9v032->model->data->pclk_reg, 359 MT9V032_PIXEL_CLOCK_INV_PXL_CLK); 360 if (ret < 0) 361 return ret; 362 } 363 364 /* Disable the noise correction algorithm and restore the controls. */ 365 ret = regmap_write(map, MT9V032_ROW_NOISE_CORR_CONTROL, 0); 366 if (ret < 0) 367 return ret; 368 369 return v4l2_ctrl_handler_setup(&mt9v032->ctrls); 370 } 371 372 /* ----------------------------------------------------------------------------- 373 * V4L2 subdev video operations 374 */ 375 376 static struct v4l2_mbus_framefmt * 377 __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, 378 unsigned int pad, enum v4l2_subdev_format_whence which) 379 { 380 switch (which) { 381 case V4L2_SUBDEV_FORMAT_TRY: 382 return v4l2_subdev_get_try_format(&mt9v032->subdev, cfg, pad); 383 case V4L2_SUBDEV_FORMAT_ACTIVE: 384 return &mt9v032->format; 385 default: 386 return NULL; 387 } 388 } 389 390 static struct v4l2_rect * 391 __mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, 392 unsigned int pad, enum v4l2_subdev_format_whence which) 393 { 394 switch (which) { 395 case V4L2_SUBDEV_FORMAT_TRY: 396 return v4l2_subdev_get_try_crop(&mt9v032->subdev, cfg, pad); 397 case V4L2_SUBDEV_FORMAT_ACTIVE: 398 return &mt9v032->crop; 399 default: 400 return NULL; 401 } 402 } 403 404 static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable) 405 { 406 const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE 407 | MT9V032_CHIP_CONTROL_DOUT_ENABLE 408 | MT9V032_CHIP_CONTROL_SEQUENTIAL; 409 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 410 struct v4l2_rect *crop = &mt9v032->crop; 411 struct regmap *map = mt9v032->regmap; 412 unsigned int hbin; 413 unsigned int vbin; 414 int ret; 415 416 if (!enable) 417 return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, 0); 418 419 /* Configure the window size and row/column bin */ 420 hbin = fls(mt9v032->hratio) - 1; 421 vbin = fls(mt9v032->vratio) - 1; 422 ret = regmap_update_bits(map, MT9V032_READ_MODE, 423 ~MT9V032_READ_MODE_RESERVED, 424 hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT | 425 vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT); 426 if (ret < 0) 427 return ret; 428 429 ret = regmap_write(map, MT9V032_COLUMN_START, crop->left); 430 if (ret < 0) 431 return ret; 432 433 ret = regmap_write(map, MT9V032_ROW_START, crop->top); 434 if (ret < 0) 435 return ret; 436 437 ret = regmap_write(map, MT9V032_WINDOW_WIDTH, crop->width); 438 if (ret < 0) 439 return ret; 440 441 ret = regmap_write(map, MT9V032_WINDOW_HEIGHT, crop->height); 442 if (ret < 0) 443 return ret; 444 445 ret = mt9v032_update_hblank(mt9v032); 446 if (ret < 0) 447 return ret; 448 449 /* Switch to master "normal" mode */ 450 return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, mode); 451 } 452 453 static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, 454 struct v4l2_subdev_pad_config *cfg, 455 struct v4l2_subdev_mbus_code_enum *code) 456 { 457 if (code->index > 0) 458 return -EINVAL; 459 460 code->code = MEDIA_BUS_FMT_SGRBG10_1X10; 461 return 0; 462 } 463 464 static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, 465 struct v4l2_subdev_pad_config *cfg, 466 struct v4l2_subdev_frame_size_enum *fse) 467 { 468 if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) 469 return -EINVAL; 470 471 fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index); 472 fse->max_width = fse->min_width; 473 fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / (1 << fse->index); 474 fse->max_height = fse->min_height; 475 476 return 0; 477 } 478 479 static int mt9v032_get_format(struct v4l2_subdev *subdev, 480 struct v4l2_subdev_pad_config *cfg, 481 struct v4l2_subdev_format *format) 482 { 483 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 484 485 format->format = *__mt9v032_get_pad_format(mt9v032, cfg, format->pad, 486 format->which); 487 return 0; 488 } 489 490 static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032) 491 { 492 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); 493 int ret; 494 495 ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate, 496 mt9v032->sysclk / mt9v032->hratio); 497 if (ret < 0) 498 dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret); 499 } 500 501 static unsigned int mt9v032_calc_ratio(unsigned int input, unsigned int output) 502 { 503 /* Compute the power-of-two binning factor closest to the input size to 504 * output size ratio. Given that the output size is bounded by input/4 505 * and input, a generic implementation would be an ineffective luxury. 506 */ 507 if (output * 3 > input * 2) 508 return 1; 509 if (output * 3 > input) 510 return 2; 511 return 4; 512 } 513 514 static int mt9v032_set_format(struct v4l2_subdev *subdev, 515 struct v4l2_subdev_pad_config *cfg, 516 struct v4l2_subdev_format *format) 517 { 518 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 519 struct v4l2_mbus_framefmt *__format; 520 struct v4l2_rect *__crop; 521 unsigned int width; 522 unsigned int height; 523 unsigned int hratio; 524 unsigned int vratio; 525 526 __crop = __mt9v032_get_pad_crop(mt9v032, cfg, format->pad, 527 format->which); 528 529 /* Clamp the width and height to avoid dividing by zero. */ 530 width = clamp(ALIGN(format->format.width, 2), 531 max_t(unsigned int, __crop->width / 4, 532 MT9V032_WINDOW_WIDTH_MIN), 533 __crop->width); 534 height = clamp(ALIGN(format->format.height, 2), 535 max_t(unsigned int, __crop->height / 4, 536 MT9V032_WINDOW_HEIGHT_MIN), 537 __crop->height); 538 539 hratio = mt9v032_calc_ratio(__crop->width, width); 540 vratio = mt9v032_calc_ratio(__crop->height, height); 541 542 __format = __mt9v032_get_pad_format(mt9v032, cfg, format->pad, 543 format->which); 544 __format->width = __crop->width / hratio; 545 __format->height = __crop->height / vratio; 546 547 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 548 mt9v032->hratio = hratio; 549 mt9v032->vratio = vratio; 550 mt9v032_configure_pixel_rate(mt9v032); 551 } 552 553 format->format = *__format; 554 555 return 0; 556 } 557 558 static int mt9v032_get_selection(struct v4l2_subdev *subdev, 559 struct v4l2_subdev_pad_config *cfg, 560 struct v4l2_subdev_selection *sel) 561 { 562 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 563 564 if (sel->target != V4L2_SEL_TGT_CROP) 565 return -EINVAL; 566 567 sel->r = *__mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); 568 return 0; 569 } 570 571 static int mt9v032_set_selection(struct v4l2_subdev *subdev, 572 struct v4l2_subdev_pad_config *cfg, 573 struct v4l2_subdev_selection *sel) 574 { 575 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 576 struct v4l2_mbus_framefmt *__format; 577 struct v4l2_rect *__crop; 578 struct v4l2_rect rect; 579 580 if (sel->target != V4L2_SEL_TGT_CROP) 581 return -EINVAL; 582 583 /* Clamp the crop rectangle boundaries and align them to a non multiple 584 * of 2 pixels to ensure a GRBG Bayer pattern. 585 */ 586 rect.left = clamp(ALIGN(sel->r.left + 1, 2) - 1, 587 MT9V032_COLUMN_START_MIN, 588 MT9V032_COLUMN_START_MAX); 589 rect.top = clamp(ALIGN(sel->r.top + 1, 2) - 1, 590 MT9V032_ROW_START_MIN, 591 MT9V032_ROW_START_MAX); 592 rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), 593 MT9V032_WINDOW_WIDTH_MIN, 594 MT9V032_WINDOW_WIDTH_MAX); 595 rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), 596 MT9V032_WINDOW_HEIGHT_MIN, 597 MT9V032_WINDOW_HEIGHT_MAX); 598 599 rect.width = min_t(unsigned int, 600 rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left); 601 rect.height = min_t(unsigned int, 602 rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); 603 604 __crop = __mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); 605 606 if (rect.width != __crop->width || rect.height != __crop->height) { 607 /* Reset the output image size if the crop rectangle size has 608 * been modified. 609 */ 610 __format = __mt9v032_get_pad_format(mt9v032, cfg, sel->pad, 611 sel->which); 612 __format->width = rect.width; 613 __format->height = rect.height; 614 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 615 mt9v032->hratio = 1; 616 mt9v032->vratio = 1; 617 mt9v032_configure_pixel_rate(mt9v032); 618 } 619 } 620 621 *__crop = rect; 622 sel->r = rect; 623 624 return 0; 625 } 626 627 /* ----------------------------------------------------------------------------- 628 * V4L2 subdev control operations 629 */ 630 631 #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001) 632 633 static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) 634 { 635 struct mt9v032 *mt9v032 = 636 container_of(ctrl->handler, struct mt9v032, ctrls); 637 struct regmap *map = mt9v032->regmap; 638 u32 freq; 639 u16 data; 640 641 switch (ctrl->id) { 642 case V4L2_CID_AUTOGAIN: 643 return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE, 644 ctrl->val); 645 646 case V4L2_CID_GAIN: 647 return regmap_write(map, MT9V032_ANALOG_GAIN, ctrl->val); 648 649 case V4L2_CID_EXPOSURE_AUTO: 650 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE, 651 !ctrl->val); 652 653 case V4L2_CID_EXPOSURE: 654 return regmap_write(map, MT9V032_TOTAL_SHUTTER_WIDTH, 655 ctrl->val); 656 657 case V4L2_CID_HBLANK: 658 mt9v032->hblank = ctrl->val; 659 return mt9v032_update_hblank(mt9v032); 660 661 case V4L2_CID_VBLANK: 662 return regmap_write(map, MT9V032_VERTICAL_BLANKING, 663 ctrl->val); 664 665 case V4L2_CID_PIXEL_RATE: 666 case V4L2_CID_LINK_FREQ: 667 if (mt9v032->link_freq == NULL) 668 break; 669 670 freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val]; 671 *mt9v032->pixel_rate->p_new.p_s64 = freq; 672 mt9v032->sysclk = freq; 673 break; 674 675 case V4L2_CID_TEST_PATTERN: 676 switch (mt9v032->test_pattern->val) { 677 case 0: 678 data = 0; 679 break; 680 case 1: 681 data = MT9V032_TEST_PATTERN_GRAY_VERTICAL 682 | MT9V032_TEST_PATTERN_ENABLE; 683 break; 684 case 2: 685 data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL 686 | MT9V032_TEST_PATTERN_ENABLE; 687 break; 688 case 3: 689 data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL 690 | MT9V032_TEST_PATTERN_ENABLE; 691 break; 692 default: 693 data = (mt9v032->test_pattern_color->val << 694 MT9V032_TEST_PATTERN_DATA_SHIFT) 695 | MT9V032_TEST_PATTERN_USE_DATA 696 | MT9V032_TEST_PATTERN_ENABLE 697 | MT9V032_TEST_PATTERN_FLIP; 698 break; 699 } 700 return regmap_write(map, MT9V032_TEST_PATTERN, data); 701 } 702 703 return 0; 704 } 705 706 static struct v4l2_ctrl_ops mt9v032_ctrl_ops = { 707 .s_ctrl = mt9v032_s_ctrl, 708 }; 709 710 static const char * const mt9v032_test_pattern_menu[] = { 711 "Disabled", 712 "Gray Vertical Shade", 713 "Gray Horizontal Shade", 714 "Gray Diagonal Shade", 715 "Plain", 716 }; 717 718 static const struct v4l2_ctrl_config mt9v032_test_pattern_color = { 719 .ops = &mt9v032_ctrl_ops, 720 .id = V4L2_CID_TEST_PATTERN_COLOR, 721 .type = V4L2_CTRL_TYPE_INTEGER, 722 .name = "Test Pattern Color", 723 .min = 0, 724 .max = 1023, 725 .step = 1, 726 .def = 0, 727 .flags = 0, 728 }; 729 730 /* ----------------------------------------------------------------------------- 731 * V4L2 subdev core operations 732 */ 733 734 static int mt9v032_set_power(struct v4l2_subdev *subdev, int on) 735 { 736 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 737 int ret = 0; 738 739 mutex_lock(&mt9v032->power_lock); 740 741 /* If the power count is modified from 0 to != 0 or from != 0 to 0, 742 * update the power state. 743 */ 744 if (mt9v032->power_count == !on) { 745 ret = __mt9v032_set_power(mt9v032, !!on); 746 if (ret < 0) 747 goto done; 748 } 749 750 /* Update the power count. */ 751 mt9v032->power_count += on ? 1 : -1; 752 WARN_ON(mt9v032->power_count < 0); 753 754 done: 755 mutex_unlock(&mt9v032->power_lock); 756 return ret; 757 } 758 759 /* ----------------------------------------------------------------------------- 760 * V4L2 subdev internal operations 761 */ 762 763 static int mt9v032_registered(struct v4l2_subdev *subdev) 764 { 765 struct i2c_client *client = v4l2_get_subdevdata(subdev); 766 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 767 unsigned int i; 768 u32 version; 769 int ret; 770 771 dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n", 772 client->addr); 773 774 ret = mt9v032_power_on(mt9v032); 775 if (ret < 0) { 776 dev_err(&client->dev, "MT9V032 power up failed\n"); 777 return ret; 778 } 779 780 /* Read and check the sensor version */ 781 ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version); 782 if (ret < 0) { 783 dev_err(&client->dev, "Failed reading chip version\n"); 784 return ret; 785 } 786 787 for (i = 0; i < ARRAY_SIZE(mt9v032_versions); ++i) { 788 if (mt9v032_versions[i].version == version) { 789 mt9v032->version = &mt9v032_versions[i]; 790 break; 791 } 792 } 793 794 if (mt9v032->version == NULL) { 795 dev_err(&client->dev, "Unsupported chip version 0x%04x\n", 796 version); 797 return -ENODEV; 798 } 799 800 mt9v032_power_off(mt9v032); 801 802 dev_info(&client->dev, "%s detected at address 0x%02x\n", 803 mt9v032->version->name, client->addr); 804 805 mt9v032_configure_pixel_rate(mt9v032); 806 807 return ret; 808 } 809 810 static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 811 { 812 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 813 struct v4l2_mbus_framefmt *format; 814 struct v4l2_rect *crop; 815 816 crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); 817 crop->left = MT9V032_COLUMN_START_DEF; 818 crop->top = MT9V032_ROW_START_DEF; 819 crop->width = MT9V032_WINDOW_WIDTH_DEF; 820 crop->height = MT9V032_WINDOW_HEIGHT_DEF; 821 822 format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); 823 824 if (mt9v032->model->color) 825 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; 826 else 827 format->code = MEDIA_BUS_FMT_Y10_1X10; 828 829 format->width = MT9V032_WINDOW_WIDTH_DEF; 830 format->height = MT9V032_WINDOW_HEIGHT_DEF; 831 format->field = V4L2_FIELD_NONE; 832 format->colorspace = V4L2_COLORSPACE_SRGB; 833 834 return mt9v032_set_power(subdev, 1); 835 } 836 837 static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 838 { 839 return mt9v032_set_power(subdev, 0); 840 } 841 842 static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = { 843 .s_power = mt9v032_set_power, 844 }; 845 846 static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = { 847 .s_stream = mt9v032_s_stream, 848 }; 849 850 static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = { 851 .enum_mbus_code = mt9v032_enum_mbus_code, 852 .enum_frame_size = mt9v032_enum_frame_size, 853 .get_fmt = mt9v032_get_format, 854 .set_fmt = mt9v032_set_format, 855 .get_selection = mt9v032_get_selection, 856 .set_selection = mt9v032_set_selection, 857 }; 858 859 static struct v4l2_subdev_ops mt9v032_subdev_ops = { 860 .core = &mt9v032_subdev_core_ops, 861 .video = &mt9v032_subdev_video_ops, 862 .pad = &mt9v032_subdev_pad_ops, 863 }; 864 865 static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = { 866 .registered = mt9v032_registered, 867 .open = mt9v032_open, 868 .close = mt9v032_close, 869 }; 870 871 static const struct regmap_config mt9v032_regmap_config = { 872 .reg_bits = 8, 873 .val_bits = 16, 874 .max_register = 0xff, 875 .cache_type = REGCACHE_RBTREE, 876 }; 877 878 /* ----------------------------------------------------------------------------- 879 * Driver initialization and probing 880 */ 881 882 static struct mt9v032_platform_data * 883 mt9v032_get_pdata(struct i2c_client *client) 884 { 885 struct mt9v032_platform_data *pdata = NULL; 886 struct v4l2_of_endpoint endpoint; 887 struct device_node *np; 888 struct property *prop; 889 890 if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) 891 return client->dev.platform_data; 892 893 np = of_graph_get_next_endpoint(client->dev.of_node, NULL); 894 if (!np) 895 return NULL; 896 897 if (v4l2_of_parse_endpoint(np, &endpoint) < 0) 898 goto done; 899 900 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 901 if (!pdata) 902 goto done; 903 904 prop = of_find_property(np, "link-frequencies", NULL); 905 if (prop) { 906 u64 *link_freqs; 907 size_t size = prop->length / sizeof(*link_freqs); 908 909 link_freqs = devm_kcalloc(&client->dev, size, 910 sizeof(*link_freqs), GFP_KERNEL); 911 if (!link_freqs) 912 goto done; 913 914 if (of_property_read_u64_array(np, "link-frequencies", 915 link_freqs, size) < 0) 916 goto done; 917 918 pdata->link_freqs = link_freqs; 919 pdata->link_def_freq = link_freqs[0]; 920 } 921 922 pdata->clk_pol = !!(endpoint.bus.parallel.flags & 923 V4L2_MBUS_PCLK_SAMPLE_RISING); 924 925 done: 926 of_node_put(np); 927 return pdata; 928 } 929 930 static int mt9v032_probe(struct i2c_client *client, 931 const struct i2c_device_id *did) 932 { 933 struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client); 934 struct mt9v032 *mt9v032; 935 unsigned int i; 936 int ret; 937 938 if (!i2c_check_functionality(client->adapter, 939 I2C_FUNC_SMBUS_WORD_DATA)) { 940 dev_warn(&client->adapter->dev, 941 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); 942 return -EIO; 943 } 944 945 mt9v032 = devm_kzalloc(&client->dev, sizeof(*mt9v032), GFP_KERNEL); 946 if (!mt9v032) 947 return -ENOMEM; 948 949 mt9v032->regmap = devm_regmap_init_i2c(client, &mt9v032_regmap_config); 950 if (IS_ERR(mt9v032->regmap)) 951 return PTR_ERR(mt9v032->regmap); 952 953 mt9v032->clk = devm_clk_get(&client->dev, NULL); 954 if (IS_ERR(mt9v032->clk)) 955 return PTR_ERR(mt9v032->clk); 956 957 mutex_init(&mt9v032->power_lock); 958 mt9v032->pdata = pdata; 959 mt9v032->model = (const void *)did->driver_data; 960 961 v4l2_ctrl_handler_init(&mt9v032->ctrls, 10); 962 963 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 964 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 965 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 966 V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN, 967 MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF); 968 v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops, 969 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0, 970 V4L2_EXPOSURE_AUTO); 971 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 972 V4L2_CID_EXPOSURE, mt9v032->model->data->min_shutter, 973 mt9v032->model->data->max_shutter, 1, 974 MT9V032_TOTAL_SHUTTER_WIDTH_DEF); 975 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 976 V4L2_CID_HBLANK, mt9v032->model->data->min_hblank, 977 MT9V032_HORIZONTAL_BLANKING_MAX, 1, 978 MT9V032_HORIZONTAL_BLANKING_DEF); 979 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 980 V4L2_CID_VBLANK, mt9v032->model->data->min_vblank, 981 mt9v032->model->data->max_vblank, 1, 982 MT9V032_VERTICAL_BLANKING_DEF); 983 mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls, 984 &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN, 985 ARRAY_SIZE(mt9v032_test_pattern_menu) - 1, 0, 0, 986 mt9v032_test_pattern_menu); 987 mt9v032->test_pattern_color = v4l2_ctrl_new_custom(&mt9v032->ctrls, 988 &mt9v032_test_pattern_color, NULL); 989 990 v4l2_ctrl_cluster(2, &mt9v032->test_pattern); 991 992 mt9v032->pixel_rate = 993 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 994 V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); 995 996 if (pdata && pdata->link_freqs) { 997 unsigned int def = 0; 998 999 for (i = 0; pdata->link_freqs[i]; ++i) { 1000 if (pdata->link_freqs[i] == pdata->link_def_freq) 1001 def = i; 1002 } 1003 1004 mt9v032->link_freq = 1005 v4l2_ctrl_new_int_menu(&mt9v032->ctrls, 1006 &mt9v032_ctrl_ops, 1007 V4L2_CID_LINK_FREQ, i - 1, def, 1008 pdata->link_freqs); 1009 v4l2_ctrl_cluster(2, &mt9v032->link_freq); 1010 } 1011 1012 1013 mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; 1014 1015 if (mt9v032->ctrls.error) { 1016 dev_err(&client->dev, "control initialization error %d\n", 1017 mt9v032->ctrls.error); 1018 ret = mt9v032->ctrls.error; 1019 goto err; 1020 } 1021 1022 mt9v032->crop.left = MT9V032_COLUMN_START_DEF; 1023 mt9v032->crop.top = MT9V032_ROW_START_DEF; 1024 mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF; 1025 mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF; 1026 1027 if (mt9v032->model->color) 1028 mt9v032->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 1029 else 1030 mt9v032->format.code = MEDIA_BUS_FMT_Y10_1X10; 1031 1032 mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF; 1033 mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF; 1034 mt9v032->format.field = V4L2_FIELD_NONE; 1035 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB; 1036 1037 mt9v032->hratio = 1; 1038 mt9v032->vratio = 1; 1039 1040 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE; 1041 mt9v032->hblank = MT9V032_HORIZONTAL_BLANKING_DEF; 1042 mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF; 1043 1044 v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops); 1045 mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops; 1046 mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1047 1048 mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE; 1049 ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0); 1050 if (ret < 0) 1051 goto err; 1052 1053 mt9v032->subdev.dev = &client->dev; 1054 ret = v4l2_async_register_subdev(&mt9v032->subdev); 1055 if (ret < 0) 1056 goto err; 1057 1058 return 0; 1059 1060 err: 1061 media_entity_cleanup(&mt9v032->subdev.entity); 1062 v4l2_ctrl_handler_free(&mt9v032->ctrls); 1063 return ret; 1064 } 1065 1066 static int mt9v032_remove(struct i2c_client *client) 1067 { 1068 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 1069 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 1070 1071 v4l2_async_unregister_subdev(subdev); 1072 v4l2_ctrl_handler_free(&mt9v032->ctrls); 1073 media_entity_cleanup(&subdev->entity); 1074 1075 return 0; 1076 } 1077 1078 static const struct i2c_device_id mt9v032_id[] = { 1079 { "mt9v022", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_COLOR] }, 1080 { "mt9v022m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_MONO] }, 1081 { "mt9v024", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_COLOR] }, 1082 { "mt9v024m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_MONO] }, 1083 { "mt9v032", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_COLOR] }, 1084 { "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] }, 1085 { "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] }, 1086 { "mt9v034m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_MONO] }, 1087 { } 1088 }; 1089 MODULE_DEVICE_TABLE(i2c, mt9v032_id); 1090 1091 #if IS_ENABLED(CONFIG_OF) 1092 static const struct of_device_id mt9v032_of_match[] = { 1093 { .compatible = "aptina,mt9v022" }, 1094 { .compatible = "aptina,mt9v022m" }, 1095 { .compatible = "aptina,mt9v024" }, 1096 { .compatible = "aptina,mt9v024m" }, 1097 { .compatible = "aptina,mt9v032" }, 1098 { .compatible = "aptina,mt9v032m" }, 1099 { .compatible = "aptina,mt9v034" }, 1100 { .compatible = "aptina,mt9v034m" }, 1101 { /* Sentinel */ } 1102 }; 1103 MODULE_DEVICE_TABLE(of, mt9v032_of_match); 1104 #endif 1105 1106 static struct i2c_driver mt9v032_driver = { 1107 .driver = { 1108 .name = "mt9v032", 1109 .of_match_table = of_match_ptr(mt9v032_of_match), 1110 }, 1111 .probe = mt9v032_probe, 1112 .remove = mt9v032_remove, 1113 .id_table = mt9v032_id, 1114 }; 1115 1116 module_i2c_driver(mt9v032_driver); 1117 1118 MODULE_DESCRIPTION("Aptina MT9V032 Camera driver"); 1119 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 1120 MODULE_LICENSE("GPL"); 1121