1/* 2 * Driver for MT9T001 CMOS Image Sensor from Aptina (Micron) 3 * 4 * Copyright (C) 2010-2011, 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/i2c.h> 17#include <linux/log2.h> 18#include <linux/module.h> 19#include <linux/regulator/consumer.h> 20#include <linux/slab.h> 21#include <linux/videodev2.h> 22#include <linux/v4l2-mediabus.h> 23 24#include <media/mt9t001.h> 25#include <media/v4l2-ctrls.h> 26#include <media/v4l2-device.h> 27#include <media/v4l2-subdev.h> 28 29#define MT9T001_PIXEL_ARRAY_HEIGHT 1568 30#define MT9T001_PIXEL_ARRAY_WIDTH 2112 31 32#define MT9T001_CHIP_VERSION 0x00 33#define MT9T001_CHIP_ID 0x1621 34#define MT9T001_ROW_START 0x01 35#define MT9T001_ROW_START_MIN 0 36#define MT9T001_ROW_START_DEF 20 37#define MT9T001_ROW_START_MAX 1534 38#define MT9T001_COLUMN_START 0x02 39#define MT9T001_COLUMN_START_MIN 0 40#define MT9T001_COLUMN_START_DEF 32 41#define MT9T001_COLUMN_START_MAX 2046 42#define MT9T001_WINDOW_HEIGHT 0x03 43#define MT9T001_WINDOW_HEIGHT_MIN 1 44#define MT9T001_WINDOW_HEIGHT_DEF 1535 45#define MT9T001_WINDOW_HEIGHT_MAX 1567 46#define MT9T001_WINDOW_WIDTH 0x04 47#define MT9T001_WINDOW_WIDTH_MIN 1 48#define MT9T001_WINDOW_WIDTH_DEF 2047 49#define MT9T001_WINDOW_WIDTH_MAX 2111 50#define MT9T001_HORIZONTAL_BLANKING 0x05 51#define MT9T001_HORIZONTAL_BLANKING_MIN 21 52#define MT9T001_HORIZONTAL_BLANKING_MAX 1023 53#define MT9T001_VERTICAL_BLANKING 0x06 54#define MT9T001_VERTICAL_BLANKING_MIN 3 55#define MT9T001_VERTICAL_BLANKING_MAX 1023 56#define MT9T001_OUTPUT_CONTROL 0x07 57#define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0) 58#define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1) 59#define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6) 60#define MT9T001_OUTPUT_CONTROL_DEF 0x0002 61#define MT9T001_SHUTTER_WIDTH_HIGH 0x08 62#define MT9T001_SHUTTER_WIDTH_LOW 0x09 63#define MT9T001_SHUTTER_WIDTH_MIN 1 64#define MT9T001_SHUTTER_WIDTH_DEF 1561 65#define MT9T001_SHUTTER_WIDTH_MAX (1024 * 1024) 66#define MT9T001_PIXEL_CLOCK 0x0a 67#define MT9T001_PIXEL_CLOCK_INVERT (1 << 15) 68#define MT9T001_PIXEL_CLOCK_SHIFT_MASK (7 << 8) 69#define MT9T001_PIXEL_CLOCK_SHIFT_SHIFT 8 70#define MT9T001_PIXEL_CLOCK_DIVIDE_MASK (0x7f << 0) 71#define MT9T001_FRAME_RESTART 0x0b 72#define MT9T001_SHUTTER_DELAY 0x0c 73#define MT9T001_SHUTTER_DELAY_MAX 2047 74#define MT9T001_RESET 0x0d 75#define MT9T001_READ_MODE1 0x1e 76#define MT9T001_READ_MODE_SNAPSHOT (1 << 8) 77#define MT9T001_READ_MODE_STROBE_ENABLE (1 << 9) 78#define MT9T001_READ_MODE_STROBE_WIDTH (1 << 10) 79#define MT9T001_READ_MODE_STROBE_OVERRIDE (1 << 11) 80#define MT9T001_READ_MODE2 0x20 81#define MT9T001_READ_MODE_BAD_FRAMES (1 << 0) 82#define MT9T001_READ_MODE_LINE_VALID_CONTINUOUS (1 << 9) 83#define MT9T001_READ_MODE_LINE_VALID_FRAME (1 << 10) 84#define MT9T001_READ_MODE3 0x21 85#define MT9T001_READ_MODE_GLOBAL_RESET (1 << 0) 86#define MT9T001_READ_MODE_GHST_CTL (1 << 1) 87#define MT9T001_ROW_ADDRESS_MODE 0x22 88#define MT9T001_ROW_SKIP_MASK (7 << 0) 89#define MT9T001_ROW_BIN_MASK (3 << 3) 90#define MT9T001_ROW_BIN_SHIFT 3 91#define MT9T001_COLUMN_ADDRESS_MODE 0x23 92#define MT9T001_COLUMN_SKIP_MASK (7 << 0) 93#define MT9T001_COLUMN_BIN_MASK (3 << 3) 94#define MT9T001_COLUMN_BIN_SHIFT 3 95#define MT9T001_GREEN1_GAIN 0x2b 96#define MT9T001_BLUE_GAIN 0x2c 97#define MT9T001_RED_GAIN 0x2d 98#define MT9T001_GREEN2_GAIN 0x2e 99#define MT9T001_TEST_DATA 0x32 100#define MT9T001_GLOBAL_GAIN 0x35 101#define MT9T001_GLOBAL_GAIN_MIN 8 102#define MT9T001_GLOBAL_GAIN_MAX 1024 103#define MT9T001_BLACK_LEVEL 0x49 104#define MT9T001_ROW_BLACK_DEFAULT_OFFSET 0x4b 105#define MT9T001_BLC_DELTA_THRESHOLDS 0x5d 106#define MT9T001_CAL_THRESHOLDS 0x5f 107#define MT9T001_GREEN1_OFFSET 0x60 108#define MT9T001_GREEN2_OFFSET 0x61 109#define MT9T001_BLACK_LEVEL_CALIBRATION 0x62 110#define MT9T001_BLACK_LEVEL_OVERRIDE (1 << 0) 111#define MT9T001_BLACK_LEVEL_DISABLE_OFFSET (1 << 1) 112#define MT9T001_BLACK_LEVEL_RECALCULATE (1 << 12) 113#define MT9T001_BLACK_LEVEL_LOCK_RED_BLUE (1 << 13) 114#define MT9T001_BLACK_LEVEL_LOCK_GREEN (1 << 14) 115#define MT9T001_RED_OFFSET 0x63 116#define MT9T001_BLUE_OFFSET 0x64 117 118struct mt9t001 { 119 struct v4l2_subdev subdev; 120 struct media_pad pad; 121 122 struct clk *clk; 123 struct regulator_bulk_data regulators[2]; 124 125 struct mutex power_lock; /* lock to protect power_count */ 126 int power_count; 127 128 struct v4l2_mbus_framefmt format; 129 struct v4l2_rect crop; 130 131 struct v4l2_ctrl_handler ctrls; 132 struct v4l2_ctrl *gains[4]; 133 134 u16 output_control; 135 u16 black_level; 136}; 137 138static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd) 139{ 140 return container_of(sd, struct mt9t001, subdev); 141} 142 143static int mt9t001_read(struct i2c_client *client, u8 reg) 144{ 145 return i2c_smbus_read_word_swapped(client, reg); 146} 147 148static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data) 149{ 150 return i2c_smbus_write_word_swapped(client, reg, data); 151} 152 153static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear, 154 u16 set) 155{ 156 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 157 u16 value = (mt9t001->output_control & ~clear) | set; 158 int ret; 159 160 if (value == mt9t001->output_control) 161 return 0; 162 163 ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, value); 164 if (ret < 0) 165 return ret; 166 167 mt9t001->output_control = value; 168 return 0; 169} 170 171static int mt9t001_reset(struct mt9t001 *mt9t001) 172{ 173 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 174 int ret; 175 176 /* Reset the chip and stop data read out */ 177 ret = mt9t001_write(client, MT9T001_RESET, 1); 178 if (ret < 0) 179 return ret; 180 181 ret = mt9t001_write(client, MT9T001_RESET, 0); 182 if (ret < 0) 183 return ret; 184 185 mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF; 186 187 return mt9t001_set_output_control(mt9t001, 188 MT9T001_OUTPUT_CONTROL_CHIP_ENABLE, 189 0); 190} 191 192static int mt9t001_power_on(struct mt9t001 *mt9t001) 193{ 194 int ret; 195 196 /* Bring up the supplies */ 197 ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators), 198 mt9t001->regulators); 199 if (ret < 0) 200 return ret; 201 202 /* Enable clock */ 203 ret = clk_prepare_enable(mt9t001->clk); 204 if (ret < 0) 205 regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators), 206 mt9t001->regulators); 207 208 return ret; 209} 210 211static void mt9t001_power_off(struct mt9t001 *mt9t001) 212{ 213 regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators), 214 mt9t001->regulators); 215 216 clk_disable_unprepare(mt9t001->clk); 217} 218 219static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on) 220{ 221 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 222 int ret; 223 224 if (!on) { 225 mt9t001_power_off(mt9t001); 226 return 0; 227 } 228 229 ret = mt9t001_power_on(mt9t001); 230 if (ret < 0) 231 return ret; 232 233 ret = mt9t001_reset(mt9t001); 234 if (ret < 0) { 235 dev_err(&client->dev, "Failed to reset the camera\n"); 236 return ret; 237 } 238 239 return v4l2_ctrl_handler_setup(&mt9t001->ctrls); 240} 241 242/* ----------------------------------------------------------------------------- 243 * V4L2 subdev video operations 244 */ 245 246static struct v4l2_mbus_framefmt * 247__mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh, 248 unsigned int pad, enum v4l2_subdev_format_whence which) 249{ 250 switch (which) { 251 case V4L2_SUBDEV_FORMAT_TRY: 252 return v4l2_subdev_get_try_format(fh, pad); 253 case V4L2_SUBDEV_FORMAT_ACTIVE: 254 return &mt9t001->format; 255 default: 256 return NULL; 257 } 258} 259 260static struct v4l2_rect * 261__mt9t001_get_pad_crop(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh, 262 unsigned int pad, enum v4l2_subdev_format_whence which) 263{ 264 switch (which) { 265 case V4L2_SUBDEV_FORMAT_TRY: 266 return v4l2_subdev_get_try_crop(fh, pad); 267 case V4L2_SUBDEV_FORMAT_ACTIVE: 268 return &mt9t001->crop; 269 default: 270 return NULL; 271 } 272} 273 274static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable) 275{ 276 const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE; 277 struct i2c_client *client = v4l2_get_subdevdata(subdev); 278 struct mt9t001_platform_data *pdata = client->dev.platform_data; 279 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 280 struct v4l2_mbus_framefmt *format = &mt9t001->format; 281 struct v4l2_rect *crop = &mt9t001->crop; 282 unsigned int hratio; 283 unsigned int vratio; 284 int ret; 285 286 if (!enable) 287 return mt9t001_set_output_control(mt9t001, mode, 0); 288 289 /* Configure the pixel clock polarity */ 290 if (pdata->clk_pol) { 291 ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK, 292 MT9T001_PIXEL_CLOCK_INVERT); 293 if (ret < 0) 294 return ret; 295 } 296 297 /* Configure the window size and row/column bin */ 298 hratio = DIV_ROUND_CLOSEST(crop->width, format->width); 299 vratio = DIV_ROUND_CLOSEST(crop->height, format->height); 300 301 ret = mt9t001_write(client, MT9T001_ROW_ADDRESS_MODE, hratio - 1); 302 if (ret < 0) 303 return ret; 304 305 ret = mt9t001_write(client, MT9T001_COLUMN_ADDRESS_MODE, vratio - 1); 306 if (ret < 0) 307 return ret; 308 309 ret = mt9t001_write(client, MT9T001_COLUMN_START, crop->left); 310 if (ret < 0) 311 return ret; 312 313 ret = mt9t001_write(client, MT9T001_ROW_START, crop->top); 314 if (ret < 0) 315 return ret; 316 317 ret = mt9t001_write(client, MT9T001_WINDOW_WIDTH, crop->width - 1); 318 if (ret < 0) 319 return ret; 320 321 ret = mt9t001_write(client, MT9T001_WINDOW_HEIGHT, crop->height - 1); 322 if (ret < 0) 323 return ret; 324 325 /* Switch to master "normal" mode */ 326 return mt9t001_set_output_control(mt9t001, 0, mode); 327} 328 329static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, 330 struct v4l2_subdev_fh *fh, 331 struct v4l2_subdev_mbus_code_enum *code) 332{ 333 if (code->index > 0) 334 return -EINVAL; 335 336 code->code = V4L2_MBUS_FMT_SGRBG10_1X10; 337 return 0; 338} 339 340static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, 341 struct v4l2_subdev_fh *fh, 342 struct v4l2_subdev_frame_size_enum *fse) 343{ 344 if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) 345 return -EINVAL; 346 347 fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index; 348 fse->max_width = fse->min_width; 349 fse->min_height = (MT9T001_WINDOW_HEIGHT_DEF + 1) / fse->index; 350 fse->max_height = fse->min_height; 351 352 return 0; 353} 354 355static int mt9t001_get_format(struct v4l2_subdev *subdev, 356 struct v4l2_subdev_fh *fh, 357 struct v4l2_subdev_format *format) 358{ 359 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 360 361 format->format = *__mt9t001_get_pad_format(mt9t001, fh, format->pad, 362 format->which); 363 return 0; 364} 365 366static int mt9t001_set_format(struct v4l2_subdev *subdev, 367 struct v4l2_subdev_fh *fh, 368 struct v4l2_subdev_format *format) 369{ 370 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 371 struct v4l2_mbus_framefmt *__format; 372 struct v4l2_rect *__crop; 373 unsigned int width; 374 unsigned int height; 375 unsigned int hratio; 376 unsigned int vratio; 377 378 __crop = __mt9t001_get_pad_crop(mt9t001, fh, format->pad, 379 format->which); 380 381 /* Clamp the width and height to avoid dividing by zero. */ 382 width = clamp_t(unsigned int, ALIGN(format->format.width, 2), 383 max_t(unsigned int, __crop->width / 8, 384 MT9T001_WINDOW_HEIGHT_MIN + 1), 385 __crop->width); 386 height = clamp_t(unsigned int, ALIGN(format->format.height, 2), 387 max_t(unsigned int, __crop->height / 8, 388 MT9T001_WINDOW_HEIGHT_MIN + 1), 389 __crop->height); 390 391 hratio = DIV_ROUND_CLOSEST(__crop->width, width); 392 vratio = DIV_ROUND_CLOSEST(__crop->height, height); 393 394 __format = __mt9t001_get_pad_format(mt9t001, fh, format->pad, 395 format->which); 396 __format->width = __crop->width / hratio; 397 __format->height = __crop->height / vratio; 398 399 format->format = *__format; 400 401 return 0; 402} 403 404static int mt9t001_get_crop(struct v4l2_subdev *subdev, 405 struct v4l2_subdev_fh *fh, 406 struct v4l2_subdev_crop *crop) 407{ 408 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 409 410 crop->rect = *__mt9t001_get_pad_crop(mt9t001, fh, crop->pad, 411 crop->which); 412 return 0; 413} 414 415static int mt9t001_set_crop(struct v4l2_subdev *subdev, 416 struct v4l2_subdev_fh *fh, 417 struct v4l2_subdev_crop *crop) 418{ 419 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 420 struct v4l2_mbus_framefmt *__format; 421 struct v4l2_rect *__crop; 422 struct v4l2_rect rect; 423 424 /* Clamp the crop rectangle boundaries and align them to a multiple of 2 425 * pixels. 426 */ 427 rect.left = clamp(ALIGN(crop->rect.left, 2), 428 MT9T001_COLUMN_START_MIN, 429 MT9T001_COLUMN_START_MAX); 430 rect.top = clamp(ALIGN(crop->rect.top, 2), 431 MT9T001_ROW_START_MIN, 432 MT9T001_ROW_START_MAX); 433 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2), 434 MT9T001_WINDOW_WIDTH_MIN + 1, 435 MT9T001_WINDOW_WIDTH_MAX + 1); 436 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2), 437 MT9T001_WINDOW_HEIGHT_MIN + 1, 438 MT9T001_WINDOW_HEIGHT_MAX + 1); 439 440 rect.width = min_t(unsigned int, rect.width, 441 MT9T001_PIXEL_ARRAY_WIDTH - rect.left); 442 rect.height = min_t(unsigned int, rect.height, 443 MT9T001_PIXEL_ARRAY_HEIGHT - rect.top); 444 445 __crop = __mt9t001_get_pad_crop(mt9t001, fh, crop->pad, crop->which); 446 447 if (rect.width != __crop->width || rect.height != __crop->height) { 448 /* Reset the output image size if the crop rectangle size has 449 * been modified. 450 */ 451 __format = __mt9t001_get_pad_format(mt9t001, fh, crop->pad, 452 crop->which); 453 __format->width = rect.width; 454 __format->height = rect.height; 455 } 456 457 *__crop = rect; 458 crop->rect = rect; 459 460 return 0; 461} 462 463/* ----------------------------------------------------------------------------- 464 * V4L2 subdev control operations 465 */ 466 467#define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001) 468#define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002) 469#define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003) 470#define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004) 471 472#define V4L2_CID_GAIN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1001) 473#define V4L2_CID_GAIN_GREEN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1002) 474#define V4L2_CID_GAIN_GREEN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1003) 475#define V4L2_CID_GAIN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1004) 476 477static u16 mt9t001_gain_value(s32 *gain) 478{ 479 /* Gain is controlled by 2 analog stages and a digital stage. Valid 480 * values for the 3 stages are 481 * 482 * Stage Min Max Step 483 * ------------------------------------------ 484 * First analog stage x1 x2 1 485 * Second analog stage x1 x4 0.125 486 * Digital stage x1 x16 0.125 487 * 488 * To minimize noise, the gain stages should be used in the second 489 * analog stage, first analog stage, digital stage order. Gain from a 490 * previous stage should be pushed to its maximum value before the next 491 * stage is used. 492 */ 493 if (*gain <= 32) 494 return *gain; 495 496 if (*gain <= 64) { 497 *gain &= ~1; 498 return (1 << 6) | (*gain >> 1); 499 } 500 501 *gain &= ~7; 502 return ((*gain - 64) << 5) | (1 << 6) | 32; 503} 504 505static int mt9t001_ctrl_freeze(struct mt9t001 *mt9t001, bool freeze) 506{ 507 return mt9t001_set_output_control(mt9t001, 508 freeze ? 0 : MT9T001_OUTPUT_CONTROL_SYNC, 509 freeze ? MT9T001_OUTPUT_CONTROL_SYNC : 0); 510} 511 512static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl) 513{ 514 static const u8 gains[4] = { 515 MT9T001_RED_GAIN, MT9T001_GREEN1_GAIN, 516 MT9T001_GREEN2_GAIN, MT9T001_BLUE_GAIN 517 }; 518 519 struct mt9t001 *mt9t001 = 520 container_of(ctrl->handler, struct mt9t001, ctrls); 521 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 522 unsigned int count; 523 unsigned int i; 524 u16 value; 525 int ret; 526 527 switch (ctrl->id) { 528 case V4L2_CID_GAIN_RED: 529 case V4L2_CID_GAIN_GREEN_RED: 530 case V4L2_CID_GAIN_GREEN_BLUE: 531 case V4L2_CID_GAIN_BLUE: 532 533 /* Disable control updates if more than one control has changed 534 * in the cluster. 535 */ 536 for (i = 0, count = 0; i < 4; ++i) { 537 struct v4l2_ctrl *gain = mt9t001->gains[i]; 538 539 if (gain->val != gain->cur.val) 540 count++; 541 } 542 543 if (count > 1) { 544 ret = mt9t001_ctrl_freeze(mt9t001, true); 545 if (ret < 0) 546 return ret; 547 } 548 549 /* Update the gain controls. */ 550 for (i = 0; i < 4; ++i) { 551 struct v4l2_ctrl *gain = mt9t001->gains[i]; 552 553 if (gain->val == gain->cur.val) 554 continue; 555 556 value = mt9t001_gain_value(&gain->val); 557 ret = mt9t001_write(client, gains[i], value); 558 if (ret < 0) { 559 mt9t001_ctrl_freeze(mt9t001, false); 560 return ret; 561 } 562 } 563 564 /* Enable control updates. */ 565 if (count > 1) { 566 ret = mt9t001_ctrl_freeze(mt9t001, false); 567 if (ret < 0) 568 return ret; 569 } 570 571 break; 572 573 case V4L2_CID_EXPOSURE: 574 ret = mt9t001_write(client, MT9T001_SHUTTER_WIDTH_LOW, 575 ctrl->val & 0xffff); 576 if (ret < 0) 577 return ret; 578 579 return mt9t001_write(client, MT9T001_SHUTTER_WIDTH_HIGH, 580 ctrl->val >> 16); 581 582 case V4L2_CID_TEST_PATTERN: 583 return mt9t001_set_output_control(mt9t001, 584 ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA, 585 ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0); 586 587 case V4L2_CID_TEST_PATTERN_COLOR: 588 return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2); 589 590 case V4L2_CID_BLACK_LEVEL_AUTO: 591 value = ctrl->val ? 0 : MT9T001_BLACK_LEVEL_OVERRIDE; 592 ret = mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION, 593 value); 594 if (ret < 0) 595 return ret; 596 597 mt9t001->black_level = value; 598 break; 599 600 case V4L2_CID_BLACK_LEVEL_OFFSET: 601 ret = mt9t001_write(client, MT9T001_GREEN1_OFFSET, ctrl->val); 602 if (ret < 0) 603 return ret; 604 605 ret = mt9t001_write(client, MT9T001_GREEN2_OFFSET, ctrl->val); 606 if (ret < 0) 607 return ret; 608 609 ret = mt9t001_write(client, MT9T001_RED_OFFSET, ctrl->val); 610 if (ret < 0) 611 return ret; 612 613 return mt9t001_write(client, MT9T001_BLUE_OFFSET, ctrl->val); 614 615 case V4L2_CID_BLACK_LEVEL_CALIBRATE: 616 return mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION, 617 MT9T001_BLACK_LEVEL_RECALCULATE | 618 mt9t001->black_level); 619 } 620 621 return 0; 622} 623 624static struct v4l2_ctrl_ops mt9t001_ctrl_ops = { 625 .s_ctrl = mt9t001_s_ctrl, 626}; 627 628static const char * const mt9t001_test_pattern_menu[] = { 629 "Disabled", 630 "Enabled", 631}; 632 633static const struct v4l2_ctrl_config mt9t001_ctrls[] = { 634 { 635 .ops = &mt9t001_ctrl_ops, 636 .id = V4L2_CID_TEST_PATTERN_COLOR, 637 .type = V4L2_CTRL_TYPE_INTEGER, 638 .name = "Test Pattern Color", 639 .min = 0, 640 .max = 1023, 641 .step = 1, 642 .def = 0, 643 .flags = 0, 644 }, { 645 .ops = &mt9t001_ctrl_ops, 646 .id = V4L2_CID_BLACK_LEVEL_AUTO, 647 .type = V4L2_CTRL_TYPE_BOOLEAN, 648 .name = "Black Level, Auto", 649 .min = 0, 650 .max = 1, 651 .step = 1, 652 .def = 1, 653 .flags = 0, 654 }, { 655 .ops = &mt9t001_ctrl_ops, 656 .id = V4L2_CID_BLACK_LEVEL_OFFSET, 657 .type = V4L2_CTRL_TYPE_INTEGER, 658 .name = "Black Level, Offset", 659 .min = -256, 660 .max = 255, 661 .step = 1, 662 .def = 32, 663 .flags = 0, 664 }, { 665 .ops = &mt9t001_ctrl_ops, 666 .id = V4L2_CID_BLACK_LEVEL_CALIBRATE, 667 .type = V4L2_CTRL_TYPE_BUTTON, 668 .name = "Black Level, Calibrate", 669 .min = 0, 670 .max = 0, 671 .step = 0, 672 .def = 0, 673 .flags = V4L2_CTRL_FLAG_WRITE_ONLY, 674 }, 675}; 676 677static const struct v4l2_ctrl_config mt9t001_gains[] = { 678 { 679 .ops = &mt9t001_ctrl_ops, 680 .id = V4L2_CID_GAIN_RED, 681 .type = V4L2_CTRL_TYPE_INTEGER, 682 .name = "Gain, Red", 683 .min = MT9T001_GLOBAL_GAIN_MIN, 684 .max = MT9T001_GLOBAL_GAIN_MAX, 685 .step = 1, 686 .def = MT9T001_GLOBAL_GAIN_MIN, 687 .flags = 0, 688 }, { 689 .ops = &mt9t001_ctrl_ops, 690 .id = V4L2_CID_GAIN_GREEN_RED, 691 .type = V4L2_CTRL_TYPE_INTEGER, 692 .name = "Gain, Green (R)", 693 .min = MT9T001_GLOBAL_GAIN_MIN, 694 .max = MT9T001_GLOBAL_GAIN_MAX, 695 .step = 1, 696 .def = MT9T001_GLOBAL_GAIN_MIN, 697 .flags = 0, 698 }, { 699 .ops = &mt9t001_ctrl_ops, 700 .id = V4L2_CID_GAIN_GREEN_BLUE, 701 .type = V4L2_CTRL_TYPE_INTEGER, 702 .name = "Gain, Green (B)", 703 .min = MT9T001_GLOBAL_GAIN_MIN, 704 .max = MT9T001_GLOBAL_GAIN_MAX, 705 .step = 1, 706 .def = MT9T001_GLOBAL_GAIN_MIN, 707 .flags = 0, 708 }, { 709 .ops = &mt9t001_ctrl_ops, 710 .id = V4L2_CID_GAIN_BLUE, 711 .type = V4L2_CTRL_TYPE_INTEGER, 712 .name = "Gain, Blue", 713 .min = MT9T001_GLOBAL_GAIN_MIN, 714 .max = MT9T001_GLOBAL_GAIN_MAX, 715 .step = 1, 716 .def = MT9T001_GLOBAL_GAIN_MIN, 717 .flags = 0, 718 }, 719}; 720 721/* ----------------------------------------------------------------------------- 722 * V4L2 subdev core operations 723 */ 724 725static int mt9t001_set_power(struct v4l2_subdev *subdev, int on) 726{ 727 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 728 int ret = 0; 729 730 mutex_lock(&mt9t001->power_lock); 731 732 /* If the power count is modified from 0 to != 0 or from != 0 to 0, 733 * update the power state. 734 */ 735 if (mt9t001->power_count == !on) { 736 ret = __mt9t001_set_power(mt9t001, !!on); 737 if (ret < 0) 738 goto out; 739 } 740 741 /* Update the power count. */ 742 mt9t001->power_count += on ? 1 : -1; 743 WARN_ON(mt9t001->power_count < 0); 744 745out: 746 mutex_unlock(&mt9t001->power_lock); 747 return ret; 748} 749 750/* ----------------------------------------------------------------------------- 751 * V4L2 subdev internal operations 752 */ 753 754static int mt9t001_registered(struct v4l2_subdev *subdev) 755{ 756 struct i2c_client *client = v4l2_get_subdevdata(subdev); 757 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 758 s32 data; 759 int ret; 760 761 ret = mt9t001_power_on(mt9t001); 762 if (ret < 0) { 763 dev_err(&client->dev, "MT9T001 power up failed\n"); 764 return ret; 765 } 766 767 /* Read out the chip version register */ 768 data = mt9t001_read(client, MT9T001_CHIP_VERSION); 769 mt9t001_power_off(mt9t001); 770 771 if (data != MT9T001_CHIP_ID) { 772 dev_err(&client->dev, 773 "MT9T001 not detected, wrong version 0x%04x\n", data); 774 return -ENODEV; 775 } 776 777 dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n", 778 client->addr); 779 780 return 0; 781} 782 783static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 784{ 785 struct v4l2_mbus_framefmt *format; 786 struct v4l2_rect *crop; 787 788 crop = v4l2_subdev_get_try_crop(fh, 0); 789 crop->left = MT9T001_COLUMN_START_DEF; 790 crop->top = MT9T001_ROW_START_DEF; 791 crop->width = MT9T001_WINDOW_WIDTH_DEF + 1; 792 crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; 793 794 format = v4l2_subdev_get_try_format(fh, 0); 795 format->code = V4L2_MBUS_FMT_SGRBG10_1X10; 796 format->width = MT9T001_WINDOW_WIDTH_DEF + 1; 797 format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; 798 format->field = V4L2_FIELD_NONE; 799 format->colorspace = V4L2_COLORSPACE_SRGB; 800 801 return mt9t001_set_power(subdev, 1); 802} 803 804static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 805{ 806 return mt9t001_set_power(subdev, 0); 807} 808 809static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = { 810 .s_power = mt9t001_set_power, 811}; 812 813static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = { 814 .s_stream = mt9t001_s_stream, 815}; 816 817static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = { 818 .enum_mbus_code = mt9t001_enum_mbus_code, 819 .enum_frame_size = mt9t001_enum_frame_size, 820 .get_fmt = mt9t001_get_format, 821 .set_fmt = mt9t001_set_format, 822 .get_crop = mt9t001_get_crop, 823 .set_crop = mt9t001_set_crop, 824}; 825 826static struct v4l2_subdev_ops mt9t001_subdev_ops = { 827 .core = &mt9t001_subdev_core_ops, 828 .video = &mt9t001_subdev_video_ops, 829 .pad = &mt9t001_subdev_pad_ops, 830}; 831 832static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = { 833 .registered = mt9t001_registered, 834 .open = mt9t001_open, 835 .close = mt9t001_close, 836}; 837 838static int mt9t001_probe(struct i2c_client *client, 839 const struct i2c_device_id *did) 840{ 841 struct mt9t001_platform_data *pdata = client->dev.platform_data; 842 struct mt9t001 *mt9t001; 843 unsigned int i; 844 int ret; 845 846 if (pdata == NULL) { 847 dev_err(&client->dev, "No platform data\n"); 848 return -EINVAL; 849 } 850 851 if (!i2c_check_functionality(client->adapter, 852 I2C_FUNC_SMBUS_WORD_DATA)) { 853 dev_warn(&client->adapter->dev, 854 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); 855 return -EIO; 856 } 857 858 mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL); 859 if (!mt9t001) 860 return -ENOMEM; 861 862 mutex_init(&mt9t001->power_lock); 863 mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF; 864 865 mt9t001->regulators[0].supply = "vdd"; 866 mt9t001->regulators[1].supply = "vaa"; 867 868 ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators); 869 if (ret < 0) { 870 dev_err(&client->dev, "Unable to get regulators\n"); 871 return ret; 872 } 873 874 mt9t001->clk = devm_clk_get(&client->dev, NULL); 875 if (IS_ERR(mt9t001->clk)) { 876 dev_err(&client->dev, "Unable to get clock\n"); 877 return PTR_ERR(mt9t001->clk); 878 } 879 880 v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) + 881 ARRAY_SIZE(mt9t001_gains) + 4); 882 883 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, 884 V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN, 885 MT9T001_SHUTTER_WIDTH_MAX, 1, 886 MT9T001_SHUTTER_WIDTH_DEF); 887 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, 888 V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1); 889 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, 890 V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk, 891 1, pdata->ext_clk); 892 v4l2_ctrl_new_std_menu_items(&mt9t001->ctrls, &mt9t001_ctrl_ops, 893 V4L2_CID_TEST_PATTERN, 894 ARRAY_SIZE(mt9t001_test_pattern_menu) - 1, 0, 895 0, mt9t001_test_pattern_menu); 896 897 for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i) 898 v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL); 899 900 for (i = 0; i < ARRAY_SIZE(mt9t001_gains); ++i) 901 mt9t001->gains[i] = v4l2_ctrl_new_custom(&mt9t001->ctrls, 902 &mt9t001_gains[i], NULL); 903 904 v4l2_ctrl_cluster(ARRAY_SIZE(mt9t001_gains), mt9t001->gains); 905 906 mt9t001->subdev.ctrl_handler = &mt9t001->ctrls; 907 908 if (mt9t001->ctrls.error) { 909 printk(KERN_INFO "%s: control initialization error %d\n", 910 __func__, mt9t001->ctrls.error); 911 ret = -EINVAL; 912 goto done; 913 } 914 915 mt9t001->crop.left = MT9T001_COLUMN_START_DEF; 916 mt9t001->crop.top = MT9T001_ROW_START_DEF; 917 mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1; 918 mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1; 919 920 mt9t001->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; 921 mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1; 922 mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1; 923 mt9t001->format.field = V4L2_FIELD_NONE; 924 mt9t001->format.colorspace = V4L2_COLORSPACE_SRGB; 925 926 v4l2_i2c_subdev_init(&mt9t001->subdev, client, &mt9t001_subdev_ops); 927 mt9t001->subdev.internal_ops = &mt9t001_subdev_internal_ops; 928 mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 929 930 mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE; 931 ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0); 932 933done: 934 if (ret < 0) { 935 v4l2_ctrl_handler_free(&mt9t001->ctrls); 936 media_entity_cleanup(&mt9t001->subdev.entity); 937 } 938 939 return ret; 940} 941 942static int mt9t001_remove(struct i2c_client *client) 943{ 944 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 945 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 946 947 v4l2_ctrl_handler_free(&mt9t001->ctrls); 948 v4l2_device_unregister_subdev(subdev); 949 media_entity_cleanup(&subdev->entity); 950 return 0; 951} 952 953static const struct i2c_device_id mt9t001_id[] = { 954 { "mt9t001", 0 }, 955 { } 956}; 957MODULE_DEVICE_TABLE(i2c, mt9t001_id); 958 959static struct i2c_driver mt9t001_driver = { 960 .driver = { 961 .name = "mt9t001", 962 }, 963 .probe = mt9t001_probe, 964 .remove = mt9t001_remove, 965 .id_table = mt9t001_id, 966}; 967 968module_i2c_driver(mt9t001_driver); 969 970MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver"); 971MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 972MODULE_LICENSE("GPL"); 973