1 /* 2 * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor 3 * 4 * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) 5 * This code is placed under the terms of the GNU General Public License v2 6 */ 7 8 #include <linux/i2c.h> 9 #include <linux/slab.h> 10 #include <linux/videodev2.h> 11 #include <linux/delay.h> 12 #include <linux/module.h> 13 #include <asm/div64.h> 14 #include <media/v4l2-device.h> 15 #include <media/v4l2-chip-ident.h> 16 #include <media/v4l2-ctrls.h> 17 #include <media/mt9v011.h> 18 19 MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); 20 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); 21 MODULE_LICENSE("GPL"); 22 23 static int debug; 24 module_param(debug, int, 0); 25 MODULE_PARM_DESC(debug, "Debug level (0-2)"); 26 27 #define R00_MT9V011_CHIP_VERSION 0x00 28 #define R01_MT9V011_ROWSTART 0x01 29 #define R02_MT9V011_COLSTART 0x02 30 #define R03_MT9V011_HEIGHT 0x03 31 #define R04_MT9V011_WIDTH 0x04 32 #define R05_MT9V011_HBLANK 0x05 33 #define R06_MT9V011_VBLANK 0x06 34 #define R07_MT9V011_OUT_CTRL 0x07 35 #define R09_MT9V011_SHUTTER_WIDTH 0x09 36 #define R0A_MT9V011_CLK_SPEED 0x0a 37 #define R0B_MT9V011_RESTART 0x0b 38 #define R0C_MT9V011_SHUTTER_DELAY 0x0c 39 #define R0D_MT9V011_RESET 0x0d 40 #define R1E_MT9V011_DIGITAL_ZOOM 0x1e 41 #define R20_MT9V011_READ_MODE 0x20 42 #define R2B_MT9V011_GREEN_1_GAIN 0x2b 43 #define R2C_MT9V011_BLUE_GAIN 0x2c 44 #define R2D_MT9V011_RED_GAIN 0x2d 45 #define R2E_MT9V011_GREEN_2_GAIN 0x2e 46 #define R35_MT9V011_GLOBAL_GAIN 0x35 47 #define RF1_MT9V011_CHIP_ENABLE 0xf1 48 49 #define MT9V011_VERSION 0x8232 50 #define MT9V011_REV_B_VERSION 0x8243 51 52 struct mt9v011 { 53 struct v4l2_subdev sd; 54 struct v4l2_ctrl_handler ctrls; 55 unsigned width, height; 56 unsigned xtal; 57 unsigned hflip:1; 58 unsigned vflip:1; 59 60 u16 global_gain, exposure; 61 s16 red_bal, blue_bal; 62 }; 63 64 static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd) 65 { 66 return container_of(sd, struct mt9v011, sd); 67 } 68 69 static int mt9v011_read(struct v4l2_subdev *sd, unsigned char addr) 70 { 71 struct i2c_client *c = v4l2_get_subdevdata(sd); 72 __be16 buffer; 73 int rc, val; 74 75 rc = i2c_master_send(c, &addr, 1); 76 if (rc != 1) 77 v4l2_dbg(0, debug, sd, 78 "i2c i/o error: rc == %d (should be 1)\n", rc); 79 80 msleep(10); 81 82 rc = i2c_master_recv(c, (char *)&buffer, 2); 83 if (rc != 2) 84 v4l2_dbg(0, debug, sd, 85 "i2c i/o error: rc == %d (should be 2)\n", rc); 86 87 val = be16_to_cpu(buffer); 88 89 v4l2_dbg(2, debug, sd, "mt9v011: read 0x%02x = 0x%04x\n", addr, val); 90 91 return val; 92 } 93 94 static void mt9v011_write(struct v4l2_subdev *sd, unsigned char addr, 95 u16 value) 96 { 97 struct i2c_client *c = v4l2_get_subdevdata(sd); 98 unsigned char buffer[3]; 99 int rc; 100 101 buffer[0] = addr; 102 buffer[1] = value >> 8; 103 buffer[2] = value & 0xff; 104 105 v4l2_dbg(2, debug, sd, 106 "mt9v011: writing 0x%02x 0x%04x\n", buffer[0], value); 107 rc = i2c_master_send(c, buffer, 3); 108 if (rc != 3) 109 v4l2_dbg(0, debug, sd, 110 "i2c i/o error: rc == %d (should be 3)\n", rc); 111 } 112 113 114 struct i2c_reg_value { 115 unsigned char reg; 116 u16 value; 117 }; 118 119 /* 120 * Values used at the original driver 121 * Some values are marked as Reserved at the datasheet 122 */ 123 static const struct i2c_reg_value mt9v011_init_default[] = { 124 { R0D_MT9V011_RESET, 0x0001 }, 125 { R0D_MT9V011_RESET, 0x0000 }, 126 127 { R0C_MT9V011_SHUTTER_DELAY, 0x0000 }, 128 { R09_MT9V011_SHUTTER_WIDTH, 0x1fc }, 129 130 { R0A_MT9V011_CLK_SPEED, 0x0000 }, 131 { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, 132 133 { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */ 134 }; 135 136 137 static u16 calc_mt9v011_gain(s16 lineargain) 138 { 139 140 u16 digitalgain = 0; 141 u16 analogmult = 0; 142 u16 analoginit = 0; 143 144 if (lineargain < 0) 145 lineargain = 0; 146 147 /* recommended minimum */ 148 lineargain += 0x0020; 149 150 if (lineargain > 2047) 151 lineargain = 2047; 152 153 if (lineargain > 1023) { 154 digitalgain = 3; 155 analogmult = 3; 156 analoginit = lineargain / 16; 157 } else if (lineargain > 511) { 158 digitalgain = 1; 159 analogmult = 3; 160 analoginit = lineargain / 8; 161 } else if (lineargain > 255) { 162 analogmult = 3; 163 analoginit = lineargain / 4; 164 } else if (lineargain > 127) { 165 analogmult = 1; 166 analoginit = lineargain / 2; 167 } else 168 analoginit = lineargain; 169 170 return analoginit + (analogmult << 7) + (digitalgain << 9); 171 172 } 173 174 static void set_balance(struct v4l2_subdev *sd) 175 { 176 struct mt9v011 *core = to_mt9v011(sd); 177 u16 green_gain, blue_gain, red_gain; 178 u16 exposure; 179 s16 bal; 180 181 exposure = core->exposure; 182 183 green_gain = calc_mt9v011_gain(core->global_gain); 184 185 bal = core->global_gain; 186 bal += (core->blue_bal * core->global_gain / (1 << 7)); 187 blue_gain = calc_mt9v011_gain(bal); 188 189 bal = core->global_gain; 190 bal += (core->red_bal * core->global_gain / (1 << 7)); 191 red_gain = calc_mt9v011_gain(bal); 192 193 mt9v011_write(sd, R2B_MT9V011_GREEN_1_GAIN, green_gain); 194 mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green_gain); 195 mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain); 196 mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); 197 mt9v011_write(sd, R09_MT9V011_SHUTTER_WIDTH, exposure); 198 } 199 200 static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator) 201 { 202 struct mt9v011 *core = to_mt9v011(sd); 203 unsigned height, width, hblank, vblank, speed; 204 unsigned row_time, t_time; 205 u64 frames_per_ms; 206 unsigned tmp; 207 208 height = mt9v011_read(sd, R03_MT9V011_HEIGHT); 209 width = mt9v011_read(sd, R04_MT9V011_WIDTH); 210 hblank = mt9v011_read(sd, R05_MT9V011_HBLANK); 211 vblank = mt9v011_read(sd, R06_MT9V011_VBLANK); 212 speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED); 213 214 row_time = (width + 113 + hblank) * (speed + 2); 215 t_time = row_time * (height + vblank + 1); 216 217 frames_per_ms = core->xtal * 1000l; 218 do_div(frames_per_ms, t_time); 219 tmp = frames_per_ms; 220 221 v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n", 222 tmp / 1000, tmp % 1000, t_time); 223 224 if (numerator && denominator) { 225 *numerator = 1000; 226 *denominator = (u32)frames_per_ms; 227 } 228 } 229 230 static u16 calc_speed(struct v4l2_subdev *sd, u32 numerator, u32 denominator) 231 { 232 struct mt9v011 *core = to_mt9v011(sd); 233 unsigned height, width, hblank, vblank; 234 unsigned row_time, line_time; 235 u64 t_time, speed; 236 237 /* Avoid bogus calculus */ 238 if (!numerator || !denominator) 239 return 0; 240 241 height = mt9v011_read(sd, R03_MT9V011_HEIGHT); 242 width = mt9v011_read(sd, R04_MT9V011_WIDTH); 243 hblank = mt9v011_read(sd, R05_MT9V011_HBLANK); 244 vblank = mt9v011_read(sd, R06_MT9V011_VBLANK); 245 246 row_time = width + 113 + hblank; 247 line_time = height + vblank + 1; 248 249 t_time = core->xtal * ((u64)numerator); 250 /* round to the closest value */ 251 t_time += denominator / 2; 252 do_div(t_time, denominator); 253 254 speed = t_time; 255 do_div(speed, row_time * line_time); 256 257 /* Avoid having a negative value for speed */ 258 if (speed < 2) 259 speed = 0; 260 else 261 speed -= 2; 262 263 /* Avoid speed overflow */ 264 if (speed > 15) 265 return 15; 266 267 return (u16)speed; 268 } 269 270 static void set_res(struct v4l2_subdev *sd) 271 { 272 struct mt9v011 *core = to_mt9v011(sd); 273 unsigned vstart, hstart; 274 275 /* 276 * The mt9v011 doesn't have scaling. So, in order to select the desired 277 * resolution, we're cropping at the middle of the sensor. 278 * hblank and vblank should be adjusted, in order to warrant that 279 * we'll preserve the line timings for 30 fps, no matter what resolution 280 * is selected. 281 * NOTE: datasheet says that width (and height) should be filled with 282 * width-1. However, this doesn't work, since one pixel per line will 283 * be missing. 284 */ 285 286 hstart = 20 + (640 - core->width) / 2; 287 mt9v011_write(sd, R02_MT9V011_COLSTART, hstart); 288 mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); 289 mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); 290 291 vstart = 8 + (480 - core->height) / 2; 292 mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); 293 mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); 294 mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); 295 296 calc_fps(sd, NULL, NULL); 297 }; 298 299 static void set_read_mode(struct v4l2_subdev *sd) 300 { 301 struct mt9v011 *core = to_mt9v011(sd); 302 unsigned mode = 0x1000; 303 304 if (core->hflip) 305 mode |= 0x4000; 306 307 if (core->vflip) 308 mode |= 0x8000; 309 310 mt9v011_write(sd, R20_MT9V011_READ_MODE, mode); 311 } 312 313 static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) 314 { 315 int i; 316 317 for (i = 0; i < ARRAY_SIZE(mt9v011_init_default); i++) 318 mt9v011_write(sd, mt9v011_init_default[i].reg, 319 mt9v011_init_default[i].value); 320 321 set_balance(sd); 322 set_res(sd); 323 set_read_mode(sd); 324 325 return 0; 326 } 327 328 static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, 329 enum v4l2_mbus_pixelcode *code) 330 { 331 if (index > 0) 332 return -EINVAL; 333 334 *code = V4L2_MBUS_FMT_SGRBG8_1X8; 335 return 0; 336 } 337 338 static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) 339 { 340 if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8) 341 return -EINVAL; 342 343 v4l_bound_align_image(&fmt->width, 48, 639, 1, 344 &fmt->height, 32, 480, 1, 0); 345 fmt->field = V4L2_FIELD_NONE; 346 fmt->colorspace = V4L2_COLORSPACE_SRGB; 347 348 return 0; 349 } 350 351 static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 352 { 353 struct v4l2_captureparm *cp = &parms->parm.capture; 354 355 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 356 return -EINVAL; 357 358 memset(cp, 0, sizeof(struct v4l2_captureparm)); 359 cp->capability = V4L2_CAP_TIMEPERFRAME; 360 calc_fps(sd, 361 &cp->timeperframe.numerator, 362 &cp->timeperframe.denominator); 363 364 return 0; 365 } 366 367 static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 368 { 369 struct v4l2_captureparm *cp = &parms->parm.capture; 370 struct v4l2_fract *tpf = &cp->timeperframe; 371 u16 speed; 372 373 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 374 return -EINVAL; 375 if (cp->extendedmode != 0) 376 return -EINVAL; 377 378 speed = calc_speed(sd, tpf->numerator, tpf->denominator); 379 380 mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed); 381 v4l2_dbg(1, debug, sd, "Setting speed to %d\n", speed); 382 383 /* Recalculate and update fps info */ 384 calc_fps(sd, &tpf->numerator, &tpf->denominator); 385 386 return 0; 387 } 388 389 static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) 390 { 391 struct mt9v011 *core = to_mt9v011(sd); 392 int rc; 393 394 rc = mt9v011_try_mbus_fmt(sd, fmt); 395 if (rc < 0) 396 return -EINVAL; 397 398 core->width = fmt->width; 399 core->height = fmt->height; 400 401 set_res(sd); 402 403 return 0; 404 } 405 406 #ifdef CONFIG_VIDEO_ADV_DEBUG 407 static int mt9v011_g_register(struct v4l2_subdev *sd, 408 struct v4l2_dbg_register *reg) 409 { 410 struct i2c_client *client = v4l2_get_subdevdata(sd); 411 412 if (!v4l2_chip_match_i2c_client(client, ®->match)) 413 return -EINVAL; 414 if (!capable(CAP_SYS_ADMIN)) 415 return -EPERM; 416 417 reg->val = mt9v011_read(sd, reg->reg & 0xff); 418 reg->size = 2; 419 420 return 0; 421 } 422 423 static int mt9v011_s_register(struct v4l2_subdev *sd, 424 const struct v4l2_dbg_register *reg) 425 { 426 struct i2c_client *client = v4l2_get_subdevdata(sd); 427 428 if (!v4l2_chip_match_i2c_client(client, ®->match)) 429 return -EINVAL; 430 if (!capable(CAP_SYS_ADMIN)) 431 return -EPERM; 432 433 mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff); 434 435 return 0; 436 } 437 #endif 438 439 static int mt9v011_g_chip_ident(struct v4l2_subdev *sd, 440 struct v4l2_dbg_chip_ident *chip) 441 { 442 u16 version; 443 struct i2c_client *client = v4l2_get_subdevdata(sd); 444 445 version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION); 446 447 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011, 448 version); 449 } 450 451 static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl) 452 { 453 struct mt9v011 *core = 454 container_of(ctrl->handler, struct mt9v011, ctrls); 455 struct v4l2_subdev *sd = &core->sd; 456 457 switch (ctrl->id) { 458 case V4L2_CID_GAIN: 459 core->global_gain = ctrl->val; 460 break; 461 case V4L2_CID_EXPOSURE: 462 core->exposure = ctrl->val; 463 break; 464 case V4L2_CID_RED_BALANCE: 465 core->red_bal = ctrl->val; 466 break; 467 case V4L2_CID_BLUE_BALANCE: 468 core->blue_bal = ctrl->val; 469 break; 470 case V4L2_CID_HFLIP: 471 core->hflip = ctrl->val; 472 set_read_mode(sd); 473 return 0; 474 case V4L2_CID_VFLIP: 475 core->vflip = ctrl->val; 476 set_read_mode(sd); 477 return 0; 478 default: 479 return -EINVAL; 480 } 481 482 set_balance(sd); 483 return 0; 484 } 485 486 static struct v4l2_ctrl_ops mt9v011_ctrl_ops = { 487 .s_ctrl = mt9v011_s_ctrl, 488 }; 489 490 static const struct v4l2_subdev_core_ops mt9v011_core_ops = { 491 .reset = mt9v011_reset, 492 .g_chip_ident = mt9v011_g_chip_ident, 493 #ifdef CONFIG_VIDEO_ADV_DEBUG 494 .g_register = mt9v011_g_register, 495 .s_register = mt9v011_s_register, 496 #endif 497 }; 498 499 static const struct v4l2_subdev_video_ops mt9v011_video_ops = { 500 .enum_mbus_fmt = mt9v011_enum_mbus_fmt, 501 .try_mbus_fmt = mt9v011_try_mbus_fmt, 502 .s_mbus_fmt = mt9v011_s_mbus_fmt, 503 .g_parm = mt9v011_g_parm, 504 .s_parm = mt9v011_s_parm, 505 }; 506 507 static const struct v4l2_subdev_ops mt9v011_ops = { 508 .core = &mt9v011_core_ops, 509 .video = &mt9v011_video_ops, 510 }; 511 512 513 /**************************************************************************** 514 I2C Client & Driver 515 ****************************************************************************/ 516 517 static int mt9v011_probe(struct i2c_client *c, 518 const struct i2c_device_id *id) 519 { 520 u16 version; 521 struct mt9v011 *core; 522 struct v4l2_subdev *sd; 523 524 /* Check if the adapter supports the needed features */ 525 if (!i2c_check_functionality(c->adapter, 526 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 527 return -EIO; 528 529 core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL); 530 if (!core) 531 return -ENOMEM; 532 533 sd = &core->sd; 534 v4l2_i2c_subdev_init(sd, c, &mt9v011_ops); 535 536 /* Check if the sensor is really a MT9V011 */ 537 version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION); 538 if ((version != MT9V011_VERSION) && 539 (version != MT9V011_REV_B_VERSION)) { 540 v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n", 541 version); 542 kfree(core); 543 return -EINVAL; 544 } 545 546 v4l2_ctrl_handler_init(&core->ctrls, 5); 547 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 548 V4L2_CID_GAIN, 0, (1 << 12) - 1 - 0x20, 1, 0x20); 549 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 550 V4L2_CID_EXPOSURE, 0, 2047, 1, 0x01fc); 551 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 552 V4L2_CID_RED_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0); 553 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 554 V4L2_CID_BLUE_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0); 555 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 556 V4L2_CID_HFLIP, 0, 1, 1, 0); 557 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops, 558 V4L2_CID_VFLIP, 0, 1, 1, 0); 559 560 if (core->ctrls.error) { 561 int ret = core->ctrls.error; 562 563 v4l2_err(sd, "control initialization error %d\n", ret); 564 v4l2_ctrl_handler_free(&core->ctrls); 565 kfree(core); 566 return ret; 567 } 568 core->sd.ctrl_handler = &core->ctrls; 569 570 core->global_gain = 0x0024; 571 core->exposure = 0x01fc; 572 core->width = 640; 573 core->height = 480; 574 core->xtal = 27000000; /* Hz */ 575 576 if (c->dev.platform_data) { 577 struct mt9v011_platform_data *pdata = c->dev.platform_data; 578 579 core->xtal = pdata->xtal; 580 v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", 581 core->xtal / 1000000, (core->xtal / 1000) % 1000); 582 } 583 584 v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n", 585 c->addr << 1, c->adapter->name, version); 586 587 return 0; 588 } 589 590 static int mt9v011_remove(struct i2c_client *c) 591 { 592 struct v4l2_subdev *sd = i2c_get_clientdata(c); 593 struct mt9v011 *core = to_mt9v011(sd); 594 595 v4l2_dbg(1, debug, sd, 596 "mt9v011.c: removing mt9v011 adapter on address 0x%x\n", 597 c->addr << 1); 598 599 v4l2_device_unregister_subdev(sd); 600 v4l2_ctrl_handler_free(&core->ctrls); 601 kfree(to_mt9v011(sd)); 602 return 0; 603 } 604 605 /* ----------------------------------------------------------------------- */ 606 607 static const struct i2c_device_id mt9v011_id[] = { 608 { "mt9v011", 0 }, 609 { } 610 }; 611 MODULE_DEVICE_TABLE(i2c, mt9v011_id); 612 613 static struct i2c_driver mt9v011_driver = { 614 .driver = { 615 .owner = THIS_MODULE, 616 .name = "mt9v011", 617 }, 618 .probe = mt9v011_probe, 619 .remove = mt9v011_remove, 620 .id_table = mt9v011_id, 621 }; 622 623 module_i2c_driver(mt9v011_driver); 624