1/* 2 * Copyright (C) 2008-2009 QUALCOMM Incorporated. 3 */ 4 5#include <linux/delay.h> 6#include <linux/slab.h> 7#include <linux/types.h> 8#include <linux/i2c.h> 9#include <linux/uaccess.h> 10#include <linux/miscdevice.h> 11#include <media/msm_camera.h> 12#include <mach/gpio.h> 13#include "mt9d112.h" 14 15/* Micron MT9D112 Registers and their values */ 16/* Sensor Core Registers */ 17#define REG_MT9D112_MODEL_ID 0x3000 18#define MT9D112_MODEL_ID 0x1580 19 20/* SOC Registers Page 1 */ 21#define REG_MT9D112_SENSOR_RESET 0x301A 22#define REG_MT9D112_STANDBY_CONTROL 0x3202 23#define REG_MT9D112_MCU_BOOT 0x3386 24 25struct mt9d112_work { 26 struct work_struct work; 27}; 28 29static struct mt9d112_work *mt9d112_sensorw; 30static struct i2c_client *mt9d112_client; 31 32struct mt9d112_ctrl { 33 const struct msm_camera_sensor_info *sensordata; 34}; 35 36 37static struct mt9d112_ctrl *mt9d112_ctrl; 38 39static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue); 40DECLARE_MUTEX(mt9d112_sem); 41 42 43/*============================================================= 44 EXTERNAL DECLARATIONS 45==============================================================*/ 46extern struct mt9d112_reg mt9d112_regs; 47 48 49/*=============================================================*/ 50 51static int mt9d112_reset(const struct msm_camera_sensor_info *dev) 52{ 53 int rc = 0; 54 55 rc = gpio_request(dev->sensor_reset, "mt9d112"); 56 57 if (!rc) { 58 rc = gpio_direction_output(dev->sensor_reset, 0); 59 mdelay(20); 60 rc = gpio_direction_output(dev->sensor_reset, 1); 61 } 62 63 gpio_free(dev->sensor_reset); 64 return rc; 65} 66 67static int32_t mt9d112_i2c_txdata(unsigned short saddr, 68 unsigned char *txdata, int length) 69{ 70 struct i2c_msg msg[] = { 71 { 72 .addr = saddr, 73 .flags = 0, 74 .len = length, 75 .buf = txdata, 76 }, 77 }; 78 79 if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) { 80 CDBG("mt9d112_i2c_txdata failed\n"); 81 return -EIO; 82 } 83 84 return 0; 85} 86 87static int32_t mt9d112_i2c_write(unsigned short saddr, 88 unsigned short waddr, unsigned short wdata, enum mt9d112_width width) 89{ 90 int32_t rc = -EIO; 91 unsigned char buf[4]; 92 93 memset(buf, 0, sizeof(buf)); 94 switch (width) { 95 case WORD_LEN: { 96 buf[0] = (waddr & 0xFF00)>>8; 97 buf[1] = (waddr & 0x00FF); 98 buf[2] = (wdata & 0xFF00)>>8; 99 buf[3] = (wdata & 0x00FF); 100 101 rc = mt9d112_i2c_txdata(saddr, buf, 4); 102 } 103 break; 104 105 case BYTE_LEN: { 106 buf[0] = waddr; 107 buf[1] = wdata; 108 rc = mt9d112_i2c_txdata(saddr, buf, 2); 109 } 110 break; 111 112 default: 113 break; 114 } 115 116 if (rc < 0) 117 CDBG( 118 "i2c_write failed, addr = 0x%x, val = 0x%x!\n", 119 waddr, wdata); 120 121 return rc; 122} 123 124static int32_t mt9d112_i2c_write_table( 125 struct mt9d112_i2c_reg_conf const *reg_conf_tbl, 126 int num_of_items_in_table) 127{ 128 int i; 129 int32_t rc = -EIO; 130 131 for (i = 0; i < num_of_items_in_table; i++) { 132 rc = mt9d112_i2c_write(mt9d112_client->addr, 133 reg_conf_tbl->waddr, reg_conf_tbl->wdata, 134 reg_conf_tbl->width); 135 if (rc < 0) 136 break; 137 if (reg_conf_tbl->mdelay_time != 0) 138 mdelay(reg_conf_tbl->mdelay_time); 139 reg_conf_tbl++; 140 } 141 142 return rc; 143} 144 145static int mt9d112_i2c_rxdata(unsigned short saddr, 146 unsigned char *rxdata, int length) 147{ 148 struct i2c_msg msgs[] = { 149 { 150 .addr = saddr, 151 .flags = 0, 152 .len = 2, 153 .buf = rxdata, 154 }, 155 { 156 .addr = saddr, 157 .flags = I2C_M_RD, 158 .len = length, 159 .buf = rxdata, 160 }, 161 }; 162 163 if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) { 164 CDBG("mt9d112_i2c_rxdata failed!\n"); 165 return -EIO; 166 } 167 168 return 0; 169} 170 171static int32_t mt9d112_i2c_read(unsigned short saddr, 172 unsigned short raddr, unsigned short *rdata, enum mt9d112_width width) 173{ 174 int32_t rc = 0; 175 unsigned char buf[4]; 176 177 if (!rdata) 178 return -EIO; 179 180 memset(buf, 0, sizeof(buf)); 181 182 switch (width) { 183 case WORD_LEN: { 184 buf[0] = (raddr & 0xFF00)>>8; 185 buf[1] = (raddr & 0x00FF); 186 187 rc = mt9d112_i2c_rxdata(saddr, buf, 2); 188 if (rc < 0) 189 return rc; 190 191 *rdata = buf[0] << 8 | buf[1]; 192 } 193 break; 194 195 default: 196 break; 197 } 198 199 if (rc < 0) 200 CDBG("mt9d112_i2c_read failed!\n"); 201 202 return rc; 203} 204 205static int32_t mt9d112_set_lens_roll_off(void) 206{ 207 int32_t rc = 0; 208 rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0], 209 mt9d112_regs.rftbl_size); 210 return rc; 211} 212 213static long mt9d112_reg_init(void) 214{ 215 int32_t array_length; 216 int32_t i; 217 long rc; 218 219 /* PLL Setup Start */ 220 rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0], 221 mt9d112_regs.plltbl_size); 222 223 if (rc < 0) 224 return rc; 225 /* PLL Setup End */ 226 227 array_length = mt9d112_regs.prev_snap_reg_settings_size; 228 229 /* Configure sensor for Preview mode and Snapshot mode */ 230 for (i = 0; i < array_length; i++) { 231 rc = mt9d112_i2c_write(mt9d112_client->addr, 232 mt9d112_regs.prev_snap_reg_settings[i].register_address, 233 mt9d112_regs.prev_snap_reg_settings[i].register_value, 234 WORD_LEN); 235 236 if (rc < 0) 237 return rc; 238 } 239 240 /* Configure for Noise Reduction, Saturation and Aperture Correction */ 241 array_length = mt9d112_regs.noise_reduction_reg_settings_size; 242 243 for (i = 0; i < array_length; i++) { 244 rc = mt9d112_i2c_write(mt9d112_client->addr, 245 mt9d112_regs.noise_reduction_reg_settings[i].register_address, 246 mt9d112_regs.noise_reduction_reg_settings[i].register_value, 247 WORD_LEN); 248 249 if (rc < 0) 250 return rc; 251 } 252 253 /* Set Color Kill Saturation point to optimum value */ 254 rc = 255 mt9d112_i2c_write(mt9d112_client->addr, 256 0x35A4, 257 0x0593, 258 WORD_LEN); 259 if (rc < 0) 260 return rc; 261 262 rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0], 263 mt9d112_regs.stbl_size); 264 if (rc < 0) 265 return rc; 266 267 rc = mt9d112_set_lens_roll_off(); 268 if (rc < 0) 269 return rc; 270 271 return 0; 272} 273 274static long mt9d112_set_sensor_mode(int mode) 275{ 276 uint16_t clock; 277 long rc = 0; 278 279 switch (mode) { 280 case SENSOR_PREVIEW_MODE: 281 rc = 282 mt9d112_i2c_write(mt9d112_client->addr, 283 0x338C, 0xA20C, WORD_LEN); 284 if (rc < 0) 285 return rc; 286 287 rc = 288 mt9d112_i2c_write(mt9d112_client->addr, 289 0x3390, 0x0004, WORD_LEN); 290 if (rc < 0) 291 return rc; 292 293 rc = 294 mt9d112_i2c_write(mt9d112_client->addr, 295 0x338C, 0xA215, WORD_LEN); 296 if (rc < 0) 297 return rc; 298 299 rc = 300 mt9d112_i2c_write(mt9d112_client->addr, 301 0x3390, 0x0004, WORD_LEN); 302 if (rc < 0) 303 return rc; 304 305 rc = 306 mt9d112_i2c_write(mt9d112_client->addr, 307 0x338C, 0xA20B, WORD_LEN); 308 if (rc < 0) 309 return rc; 310 311 rc = 312 mt9d112_i2c_write(mt9d112_client->addr, 313 0x3390, 0x0000, WORD_LEN); 314 if (rc < 0) 315 return rc; 316 317 clock = 0x0250; 318 319 rc = 320 mt9d112_i2c_write(mt9d112_client->addr, 321 0x341C, clock, WORD_LEN); 322 if (rc < 0) 323 return rc; 324 325 rc = 326 mt9d112_i2c_write(mt9d112_client->addr, 327 0x338C, 0xA103, WORD_LEN); 328 if (rc < 0) 329 return rc; 330 331 rc = 332 mt9d112_i2c_write(mt9d112_client->addr, 333 0x3390, 0x0001, WORD_LEN); 334 if (rc < 0) 335 return rc; 336 337 mdelay(5); 338 break; 339 340 case SENSOR_SNAPSHOT_MODE: 341 /* Switch to lower fps for Snapshot */ 342 rc = 343 mt9d112_i2c_write(mt9d112_client->addr, 344 0x341C, 0x0120, WORD_LEN); 345 if (rc < 0) 346 return rc; 347 348 rc = 349 mt9d112_i2c_write(mt9d112_client->addr, 350 0x338C, 0xA120, WORD_LEN); 351 if (rc < 0) 352 return rc; 353 354 rc = 355 mt9d112_i2c_write(mt9d112_client->addr, 356 0x3390, 0x0002, WORD_LEN); 357 if (rc < 0) 358 return rc; 359 360 mdelay(5); 361 362 rc = 363 mt9d112_i2c_write(mt9d112_client->addr, 364 0x338C, 0xA103, WORD_LEN); 365 if (rc < 0) 366 return rc; 367 368 rc = 369 mt9d112_i2c_write(mt9d112_client->addr, 370 0x3390, 0x0002, WORD_LEN); 371 if (rc < 0) 372 return rc; 373 break; 374 375 default: 376 return -EINVAL; 377 } 378 379 return 0; 380} 381 382static long mt9d112_set_effect(int mode, int effect) 383{ 384 uint16_t reg_addr; 385 uint16_t reg_val; 386 long rc = 0; 387 388 switch (mode) { 389 case SENSOR_PREVIEW_MODE: 390 /* Context A Special Effects */ 391 reg_addr = 0x2799; 392 break; 393 394 case SENSOR_SNAPSHOT_MODE: 395 /* Context B Special Effects */ 396 reg_addr = 0x279B; 397 break; 398 399 default: 400 reg_addr = 0x2799; 401 break; 402 } 403 404 switch (effect) { 405 case CAMERA_EFFECT_OFF: { 406 reg_val = 0x6440; 407 408 rc = mt9d112_i2c_write(mt9d112_client->addr, 409 0x338C, reg_addr, WORD_LEN); 410 if (rc < 0) 411 return rc; 412 413 rc = mt9d112_i2c_write(mt9d112_client->addr, 414 0x3390, reg_val, WORD_LEN); 415 if (rc < 0) 416 return rc; 417 } 418 break; 419 420 case CAMERA_EFFECT_MONO: { 421 reg_val = 0x6441; 422 rc = mt9d112_i2c_write(mt9d112_client->addr, 423 0x338C, reg_addr, WORD_LEN); 424 if (rc < 0) 425 return rc; 426 427 rc = mt9d112_i2c_write(mt9d112_client->addr, 428 0x3390, reg_val, WORD_LEN); 429 if (rc < 0) 430 return rc; 431 } 432 break; 433 434 case CAMERA_EFFECT_NEGATIVE: { 435 reg_val = 0x6443; 436 rc = mt9d112_i2c_write(mt9d112_client->addr, 437 0x338C, reg_addr, WORD_LEN); 438 if (rc < 0) 439 return rc; 440 441 rc = mt9d112_i2c_write(mt9d112_client->addr, 442 0x3390, reg_val, WORD_LEN); 443 if (rc < 0) 444 return rc; 445 } 446 break; 447 448 case CAMERA_EFFECT_SOLARIZE: { 449 reg_val = 0x6445; 450 rc = mt9d112_i2c_write(mt9d112_client->addr, 451 0x338C, reg_addr, WORD_LEN); 452 if (rc < 0) 453 return rc; 454 455 rc = mt9d112_i2c_write(mt9d112_client->addr, 456 0x3390, reg_val, WORD_LEN); 457 if (rc < 0) 458 return rc; 459 } 460 break; 461 462 case CAMERA_EFFECT_SEPIA: { 463 reg_val = 0x6442; 464 rc = mt9d112_i2c_write(mt9d112_client->addr, 465 0x338C, reg_addr, WORD_LEN); 466 if (rc < 0) 467 return rc; 468 469 rc = mt9d112_i2c_write(mt9d112_client->addr, 470 0x3390, reg_val, WORD_LEN); 471 if (rc < 0) 472 return rc; 473 } 474 break; 475 476 case CAMERA_EFFECT_PASTEL: 477 case CAMERA_EFFECT_MOSAIC: 478 case CAMERA_EFFECT_RESIZE: 479 return -EINVAL; 480 481 default: { 482 reg_val = 0x6440; 483 rc = mt9d112_i2c_write(mt9d112_client->addr, 484 0x338C, reg_addr, WORD_LEN); 485 if (rc < 0) 486 return rc; 487 488 rc = mt9d112_i2c_write(mt9d112_client->addr, 489 0x3390, reg_val, WORD_LEN); 490 if (rc < 0) 491 return rc; 492 493 return -EINVAL; 494 } 495 } 496 497 /* Refresh Sequencer */ 498 rc = mt9d112_i2c_write(mt9d112_client->addr, 499 0x338C, 0xA103, WORD_LEN); 500 if (rc < 0) 501 return rc; 502 503 rc = mt9d112_i2c_write(mt9d112_client->addr, 504 0x3390, 0x0005, WORD_LEN); 505 506 return rc; 507} 508 509static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data) 510{ 511 uint16_t model_id = 0; 512 int rc = 0; 513 514 CDBG("init entry \n"); 515 rc = mt9d112_reset(data); 516 if (rc < 0) { 517 CDBG("reset failed!\n"); 518 goto init_probe_fail; 519 } 520 521 mdelay(5); 522 523 /* Micron suggested Power up block Start: 524 * Put MCU into Reset - Stop MCU */ 525 rc = mt9d112_i2c_write(mt9d112_client->addr, 526 REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN); 527 if (rc < 0) 528 goto init_probe_fail; 529 530 /* Pull MCU from Reset - Start MCU */ 531 rc = mt9d112_i2c_write(mt9d112_client->addr, 532 REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN); 533 if (rc < 0) 534 goto init_probe_fail; 535 536 mdelay(5); 537 538 /* Micron Suggested - Power up block */ 539 rc = mt9d112_i2c_write(mt9d112_client->addr, 540 REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN); 541 if (rc < 0) 542 goto init_probe_fail; 543 544 rc = mt9d112_i2c_write(mt9d112_client->addr, 545 REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN); 546 if (rc < 0) 547 goto init_probe_fail; 548 549 /* FUSED_DEFECT_CORRECTION */ 550 rc = mt9d112_i2c_write(mt9d112_client->addr, 551 0x33F4, 0x031D, WORD_LEN); 552 if (rc < 0) 553 goto init_probe_fail; 554 555 mdelay(5); 556 557 /* Micron suggested Power up block End */ 558 /* Read the Model ID of the sensor */ 559 rc = mt9d112_i2c_read(mt9d112_client->addr, 560 REG_MT9D112_MODEL_ID, &model_id, WORD_LEN); 561 if (rc < 0) 562 goto init_probe_fail; 563 564 CDBG("mt9d112 model_id = 0x%x\n", model_id); 565 566 /* Check if it matches it with the value in Datasheet */ 567 if (model_id != MT9D112_MODEL_ID) { 568 rc = -EINVAL; 569 goto init_probe_fail; 570 } 571 572 rc = mt9d112_reg_init(); 573 if (rc < 0) 574 goto init_probe_fail; 575 576 return rc; 577 578init_probe_fail: 579 return rc; 580} 581 582int mt9d112_sensor_init(const struct msm_camera_sensor_info *data) 583{ 584 int rc = 0; 585 586 mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL); 587 if (!mt9d112_ctrl) { 588 CDBG("mt9d112_init failed!\n"); 589 rc = -ENOMEM; 590 goto init_done; 591 } 592 593 if (data) 594 mt9d112_ctrl->sensordata = data; 595 596 /* Input MCLK = 24MHz */ 597 msm_camio_clk_rate_set(24000000); 598 mdelay(5); 599 600 msm_camio_camif_pad_reg_reset(); 601 602 rc = mt9d112_sensor_init_probe(data); 603 if (rc < 0) { 604 CDBG("mt9d112_sensor_init failed!\n"); 605 goto init_fail; 606 } 607 608init_done: 609 return rc; 610 611init_fail: 612 kfree(mt9d112_ctrl); 613 return rc; 614} 615 616static int mt9d112_init_client(struct i2c_client *client) 617{ 618 /* Initialize the MSM_CAMI2C Chip */ 619 init_waitqueue_head(&mt9d112_wait_queue); 620 return 0; 621} 622 623int mt9d112_sensor_config(void __user *argp) 624{ 625 struct sensor_cfg_data cfg_data; 626 long rc = 0; 627 628 if (copy_from_user(&cfg_data, 629 (void *)argp, 630 sizeof(struct sensor_cfg_data))) 631 return -EFAULT; 632 633 /* down(&mt9d112_sem); */ 634 635 CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n", 636 cfg_data.cfgtype, cfg_data.mode); 637 638 switch (cfg_data.cfgtype) { 639 case CFG_SET_MODE: 640 rc = mt9d112_set_sensor_mode( 641 cfg_data.mode); 642 break; 643 644 case CFG_SET_EFFECT: 645 rc = mt9d112_set_effect(cfg_data.mode, 646 cfg_data.cfg.effect); 647 break; 648 649 case CFG_GET_AF_MAX_STEPS: 650 default: 651 rc = -EINVAL; 652 break; 653 } 654 655 /* up(&mt9d112_sem); */ 656 657 return rc; 658} 659 660int mt9d112_sensor_release(void) 661{ 662 int rc = 0; 663 664 /* down(&mt9d112_sem); */ 665 666 kfree(mt9d112_ctrl); 667 /* up(&mt9d112_sem); */ 668 669 return rc; 670} 671 672static int mt9d112_i2c_probe(struct i2c_client *client, 673 const struct i2c_device_id *id) 674{ 675 int rc = 0; 676 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 677 rc = -ENOTSUPP; 678 goto probe_failure; 679 } 680 681 mt9d112_sensorw = 682 kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL); 683 684 if (!mt9d112_sensorw) { 685 rc = -ENOMEM; 686 goto probe_failure; 687 } 688 689 i2c_set_clientdata(client, mt9d112_sensorw); 690 mt9d112_init_client(client); 691 mt9d112_client = client; 692 693 CDBG("mt9d112_probe succeeded!\n"); 694 695 return 0; 696 697probe_failure: 698 kfree(mt9d112_sensorw); 699 mt9d112_sensorw = NULL; 700 CDBG("mt9d112_probe failed!\n"); 701 return rc; 702} 703 704static const struct i2c_device_id mt9d112_i2c_id[] = { 705 { "mt9d112", 0}, 706 { }, 707}; 708 709static struct i2c_driver mt9d112_i2c_driver = { 710 .id_table = mt9d112_i2c_id, 711 .probe = mt9d112_i2c_probe, 712 .remove = __exit_p(mt9d112_i2c_remove), 713 .driver = { 714 .name = "mt9d112", 715 }, 716}; 717 718static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info, 719 struct msm_sensor_ctrl *s) 720{ 721 int rc = i2c_add_driver(&mt9d112_i2c_driver); 722 if (rc < 0 || mt9d112_client == NULL) { 723 rc = -ENOTSUPP; 724 goto probe_done; 725 } 726 727 /* Input MCLK = 24MHz */ 728 msm_camio_clk_rate_set(24000000); 729 mdelay(5); 730 731 rc = mt9d112_sensor_init_probe(info); 732 if (rc < 0) 733 goto probe_done; 734 735 s->s_init = mt9d112_sensor_init; 736 s->s_release = mt9d112_sensor_release; 737 s->s_config = mt9d112_sensor_config; 738 739probe_done: 740 CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__); 741 return rc; 742} 743 744static int __mt9d112_probe(struct platform_device *pdev) 745{ 746 return msm_camera_drv_start(pdev, mt9d112_sensor_probe); 747} 748 749static struct platform_driver msm_camera_driver = { 750 .probe = __mt9d112_probe, 751 .driver = { 752 .name = "msm_camera_mt9d112", 753 .owner = THIS_MODULE, 754 }, 755}; 756 757static int __init mt9d112_init(void) 758{ 759 return platform_driver_register(&msm_camera_driver); 760} 761 762module_init(mt9d112_init); 763