/drivers/media/video/msm/sensors/ov8820_v4l2.c
C | 1015 lines | 874 code | 89 blank | 52 comment | 32 complexity | b17326a2c963252344b364f45449db71 MD5 | raw file
1/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 */ 13 14#include "msm_sensor.h" 15#include <linux/regulator/consumer.h> 16 17#define SENSOR_NAME "ov8820" 18#define PLATFORM_DRIVER_NAME "msm_camera_ov8820" 19#define ov8820_obj ov8820_##obj 20 21#define OV8820_DEFAULT_MCLK_RATE 24000000 22 23#define OV8820_OTP_DATA 0x3D00 24#define OV8820_OTP_LOAD 0x3D81 25#define OV8820_OTP_BANK 0x3D84 26#define OV8820_OTP_BANK_SIZE 0x20 27 28DEFINE_MUTEX(ov8820_mut); 29static struct msm_sensor_ctrl_t ov8820_s_ctrl; 30 31static struct regulator *reg_1p8; 32 33static struct otp_info_t otp_info; 34 35static struct msm_camera_i2c_reg_conf ov8820_start_settings[] = { 36 {0x0100, 0x01}, 37}; 38 39static struct msm_camera_i2c_reg_conf ov8820_stop_settings[] = { 40 {0x0100, 0x00}, 41}; 42 43static struct msm_camera_i2c_reg_conf ov8820_groupon_settings[] = { 44 {0x3208, 0x00}, 45}; 46 47static struct msm_camera_i2c_reg_conf ov8820_groupoff_settings[] = { 48 {0x3208, 0x10}, 49 {0x3208, 0xA0}, 50}; 51 52static struct msm_camera_i2c_reg_conf ov8820_1080_settings[] = { 53 {0x3004, 0xce}, 54 {0x3005, 0x10}, 55 {0x3006, 0x00}, 56 //{0x3501, 0x74}, 57 //{0x3502, 0x60}, 58 {0x370e, 0x00}, 59 {0x3801, 0x00}, 60 {0x3802, 0x01}, 61 {0x3803, 0x30}, 62 {0x3805, 0xdf}, 63 {0x3806, 0x08}, 64 {0x3807, 0x67}, 65 {0x3808, 0x07}, 66 {0x3809, 0x80}, 67 {0x380a, 0x04}, 68 {0x380b, 0x38}, 69 {0x380c, 0x0d}, 70 {0x380d, 0xf0}, 71 {0x380e, 0x07}, 72 {0x380f, 0x4c}, 73 {0x3811, 0x10}, 74 {0x3813, 0x06}, 75 {0x3814, 0x11}, 76 {0x3815, 0x11}, 77 {0x3820, 0x00}, 78 {0x3821, 0x16}, 79 {0x3f00, 0x02}, 80 {0x3f05, 0x10}, 81 {0x4005, 0x1a}, 82 {0x4600, 0x04}, 83 {0x4601, 0x01}, 84 {0x4602, 0x00}, 85 {0x4837, 0x27}, 86 {0x5068, 0x53}, 87 {0x506a, 0x53}, 88}; 89 90static struct msm_camera_i2c_reg_conf ov8820_prev_settings[] = { 91 {0x3004, 0xd5}, 92 {0x3005, 0x11}, 93 {0x3006, 0x11}, 94 //{0x3501, 0x4e}, 95 //{0x3502, 0xa0}, 96 {0x370e, 0x08}, 97 {0x3801, 0x00}, 98 {0x3802, 0x00}, 99 {0x3803, 0x00}, 100 {0x3805, 0xdf}, 101 {0x3806, 0x09}, 102 {0x3807, 0x9b}, 103 {0x3808, 0x06}, 104 {0x3809, 0x60}, 105 {0x380a, 0x04}, 106 {0x380b, 0xc8}, 107 {0x380c, 0x06}, 108 {0x380d, 0xde}, 109 {0x380e, 0x05}, 110 {0x380f, 0x06}, 111 {0x3811, 0x08}, 112 {0x3813, 0x04}, 113 {0x3814, 0x31}, 114 {0x3815, 0x31}, 115 {0x3820, 0x00}, 116 {0x3821, 0x17}, 117 {0x3f00, 0x00}, 118 {0x3f05, 0x10}, 119 {0x4005, 0x1a}, 120 {0x4600, 0x04}, 121 {0x4601, 0x00}, 122 {0x4602, 0x78}, 123 {0x4837, 0x5a}, 124 {0x5068, 0x00}, 125 {0x506a, 0x00}, 126}; 127 128static struct msm_camera_i2c_reg_conf ov8820_snap_settings[] = { 129 {0x3004, 0xbf}, 130 {0x3005, 0x10}, 131 {0x3006, 0x00}, 132 //{0x3501, 0x9a}, 133 //{0x3502, 0xa0}, 134 {0x370e, 0x00}, 135 {0x3801, 0x00}, 136 {0x3712, 0xcc}, 137 {0x3802, 0x00}, 138 {0x3803, 0x00}, 139 {0x3805, 0xdf}, 140 {0x3806, 0x09}, 141 {0x3807, 0x9b}, 142 {0x3808, 0x0c}, 143 {0x3809, 0xc0}, 144 {0x380a, 0x09}, 145 {0x380b, 0x90}, 146 {0x380c, 0x0d}, 147 {0x380d, 0x20}, 148 {0x380e, 0x09}, 149 {0x380f, 0xb0}, 150 {0x3811, 0x10}, 151 {0x3813, 0x06}, 152 {0x3814, 0x11}, 153 {0x3815, 0x11}, 154 {0x3820, 0x00}, 155 {0x3821, 0x16}, 156 {0x3f00, 0x02}, 157 {0x3f05, 0x10}, 158 {0x4005, 0x1a}, 159 {0x4600, 0x04}, 160 {0x4601, 0x00}, 161 {0x4602, 0x20}, 162 {0x4837, 0x1e}, 163 {0x5068, 0x00}, 164 {0x506a, 0x00}, 165}; 166 167static struct msm_camera_i2c_reg_conf ov8820_60fps_settings[] = { 168 {0x3004, 0xbf}, 169 {0x3005, 0x10}, 170 {0x3006, 0x00}, 171 {0x3501, 0x39}, 172 {0x3502, 0xa0}, 173 {0x370e, 0x08}, 174 {0x3801, 0x28}, 175 {0x3802, 0x01}, 176 {0x3803, 0x40}, 177 {0x3805, 0xb7}, 178 {0x3806, 0x08}, 179 {0x3807, 0x57}, 180 {0x3808, 0x05}, 181 {0x3809, 0x00}, 182 {0x380a, 0x02}, 183 {0x380b, 0xd0}, 184 {0x380c, 0x0d}, 185 {0x380d, 0xe0}, 186 {0x380e, 0x03}, 187 {0x380f, 0xa0}, 188 {0x3811, 0x04}, 189 {0x3813, 0x04}, 190 {0x3814, 0x31}, 191 {0x3815, 0x31}, 192 {0x3820, 0x80}, 193 {0x3821, 0x17}, 194 {0x3f00, 0x00}, 195 {0x3f05, 0x50}, 196 {0x4005, 0x18}, 197 {0x4600, 0x14}, 198 {0x4601, 0x14}, 199 {0x4602, 0x00}, 200 {0x4837, 0x1e}, 201 {0x5068, 0x5a}, 202 {0x506a, 0x5a}, 203 /* 204 * TBD if we need these registers * 205 {0x5c00, 0x81}, 206 {0x5c01, 0x01}, 207 {0x5c02, 0x1f}, 208 {0x5c03, 0x01}, 209 {0x5c04, 0x1f}, 210 {0x5c08, 0x87}, 211 {0x6703, 0xd7}, 212 {0x6900, 0x63}, 213 */ 214}; 215 216static struct msm_camera_i2c_reg_conf ov8820_reset_settings[] = { 217 {0x0103, 0x01}, 218}; 219 220static struct msm_camera_i2c_reg_conf ov8820_recommend_settings[] = { 221 {0x3000, 0x02}, 222 {0x3001, 0x00}, 223 {0x3002, 0x6c}, 224 {0x3003, 0xce}, 225 {0x3004, 0xd5}, 226 {0x3005, 0x11}, 227 {0x3006, 0x11}, 228 {0x3007, 0x3b}, 229 {0x300d, 0x00}, 230 {0x301f, 0x09}, 231 {0x3010, 0x00}, 232 {0x3011, 0x02}, 233 {0x3012, 0x80}, 234 {0x3013, 0x39}, 235 {0x3018, 0x00}, 236 {0x3104, 0x20}, 237 {0x3300, 0x00}, 238 {0x3500, 0x00}, 239 {0x3501, 0x4e}, 240 {0x3502, 0xa0}, 241 {0x3503, 0x07}, 242 {0x3509, 0x00}, 243 {0x350b, 0x1f}, 244 {0x3600, 0x05}, 245 {0x3601, 0x32}, 246 {0x3602, 0x44}, 247 {0x3603, 0x5c}, 248 {0x3604, 0x98}, 249 {0x3605, 0xe9}, 250 {0x3609, 0xb8}, 251 {0x360a, 0xbc}, 252 {0x360b, 0xb4}, 253 {0x360c, 0x0d}, 254 {0x3613, 0x02}, 255 {0x3614, 0x0f}, 256 {0x3615, 0x00}, 257 {0x3616, 0x03}, 258 {0x3617, 0x01}, 259 {0x3618, 0x00}, 260 {0x3619, 0x00}, 261 {0x361a, 0x00}, 262 {0x361b, 0x00}, 263 {0x3700, 0x20}, 264 {0x3701, 0x44}, 265 {0x3702, 0x70}, 266 {0x3703, 0x4f}, 267 {0x3704, 0x69}, 268 {0x3706, 0x7b}, 269 {0x3707, 0x63}, 270 {0x3708, 0x85}, 271 {0x3709, 0x40}, 272 {0x370a, 0x12}, 273 {0x370b, 0x01}, 274 {0x370c, 0x50}, 275 {0x370d, 0x0c}, 276 {0x370e, 0x08}, 277 {0x3711, 0x01}, 278 {0x3712, 0xcc}, 279 {0x3800, 0x00}, 280 {0x3801, 0x00}, 281 {0x3802, 0x00}, 282 {0x3803, 0x00}, 283 {0x3804, 0x0c}, 284 {0x3805, 0xdf}, 285 {0x3806, 0x09}, 286 {0x3807, 0x9b}, 287 {0x3808, 0x06}, 288 {0x3809, 0x60}, 289 {0x380a, 0x04}, 290 {0x380b, 0xc8}, 291 {0x380c, 0x06}, 292 {0x380d, 0xde}, 293 {0x380e, 0x05}, 294 {0x380f, 0x06}, 295 {0x3810, 0x00}, 296 {0x3811, 0x08}, 297 {0x3812, 0x00}, 298 {0x3813, 0x04}, 299 {0x3814, 0x31}, 300 {0x3815, 0x31}, 301 {0x3816, 0x02}, 302 {0x3817, 0x40}, 303 {0x3818, 0x00}, 304 {0x3819, 0x40}, 305 {0x3820, 0x00}, 306 {0x3821, 0x17}, 307 {0x3d00, 0x00}, 308 {0x3d01, 0x00}, 309 {0x3d02, 0x00}, 310 {0x3d03, 0x00}, 311 {0x3d04, 0x00}, 312 {0x3d05, 0x00}, 313 {0x3d06, 0x00}, 314 {0x3d07, 0x00}, 315 {0x3d08, 0x00}, 316 {0x3d09, 0x00}, 317 {0x3d0a, 0x00}, 318 {0x3d0b, 0x00}, 319 {0x3d0c, 0x00}, 320 {0x3d0d, 0x00}, 321 {0x3d0e, 0x00}, 322 {0x3d0f, 0x00}, 323 {0x3d10, 0x00}, 324 {0x3d11, 0x00}, 325 {0x3d12, 0x00}, 326 {0x3d13, 0x00}, 327 {0x3d14, 0x00}, 328 {0x3d15, 0x00}, 329 {0x3d16, 0x00}, 330 {0x3d17, 0x00}, 331 {0x3d18, 0x00}, 332 {0x3d19, 0x00}, 333 {0x3d1a, 0x00}, 334 {0x3d1b, 0x00}, 335 {0x3d1c, 0x00}, 336 {0x3d1d, 0x00}, 337 {0x3d1e, 0x00}, 338 {0x3d1f, 0x00}, 339 {0x3d80, 0x00}, 340 {0x3d81, 0x00}, 341 {0x3d84, 0x00}, 342 {0x3f00, 0x00}, 343 {0x3f01, 0xfc}, 344 {0x3f05, 0x10}, 345 {0x3f06, 0x00}, 346 {0x3f07, 0x00}, 347 {0x4000, 0x29}, 348 {0x4001, 0x02}, 349 {0x4002, 0x45}, 350 {0x4003, 0x08}, 351 {0x4004, 0x04}, 352 {0x4005, 0x1a}, 353 {0x4300, 0xff}, 354 {0x4303, 0x00}, 355 {0x4304, 0x08}, 356 {0x4307, 0x00}, 357 {0x4600, 0x04}, 358 {0x4601, 0x00}, 359 {0x4602, 0x78}, 360 {0x4800, 0x04}, 361 {0x4801, 0x0f}, 362 {0x4837, 0x5a}, 363 {0x4843, 0x02}, 364 {0x5000, 0x06}, 365 {0x5001, 0x00}, 366 {0x5002, 0x00}, 367 {0x5068, 0x00}, 368 {0x506a, 0x00}, 369 {0x501f, 0x00}, 370 {0x5780, 0xfc}, 371 {0x5c00, 0x80}, 372 {0x5c01, 0x00}, 373 {0x5c02, 0x00}, 374 {0x5c03, 0x00}, 375 {0x5c04, 0x00}, 376 {0x5c05, 0x00}, 377 {0x5c06, 0x00}, 378 {0x5c07, 0x80}, 379 {0x5c08, 0x10}, 380 {0x6700, 0x05}, 381 {0x6701, 0x19}, 382 {0x6702, 0xfd}, 383 {0x6703, 0xd1}, 384 {0x6704, 0xff}, 385 {0x6705, 0xff}, 386 {0x6800, 0x10}, 387 {0x6801, 0x02}, 388 {0x6802, 0x90}, 389 {0x6803, 0x10}, 390 {0x6804, 0x59}, 391 {0x6900, 0x61}, 392 {0x6901, 0x04}, 393 {0x3612, 0x00}, 394 {0x3617, 0xa1}, 395 {0x3b1f, 0x00}, 396 {0x3000, 0x12}, 397 {0x3000, 0x16}, 398 {0x3b1f, 0x00}, 399 {0x0100, 0x01}, 400 {0x5800, 0x16}, 401 {0x5801, 0x0b}, 402 {0x5802, 0x09}, 403 {0x5803, 0x09}, 404 {0x5804, 0x0b}, 405 {0x5805, 0x15}, 406 {0x5806, 0x07}, 407 {0x5807, 0x05}, 408 {0x5808, 0x03}, 409 {0x5809, 0x03}, 410 {0x580a, 0x05}, 411 {0x580b, 0x06}, 412 {0x580c, 0x05}, 413 {0x580d, 0x02}, 414 {0x580e, 0x00}, 415 {0x580f, 0x00}, 416 {0x5810, 0x02}, 417 {0x5811, 0x05}, 418 {0x5812, 0x06}, 419 {0x5813, 0x02}, 420 {0x5814, 0x00}, 421 {0x5815, 0x00}, 422 {0x5816, 0x02}, 423 {0x5817, 0x05}, 424 {0x5818, 0x07}, 425 {0x5819, 0x05}, 426 {0x581a, 0x04}, 427 {0x581b, 0x03}, 428 {0x581c, 0x05}, 429 {0x581d, 0x06}, 430 {0x581e, 0x13}, 431 {0x581f, 0x0b}, 432 {0x5820, 0x09}, 433 {0x5821, 0x09}, 434 {0x5822, 0x0b}, 435 {0x5823, 0x16}, 436 {0x5824, 0x63}, 437 {0x5825, 0x23}, 438 {0x5826, 0x25}, 439 {0x5827, 0x23}, 440 {0x5828, 0x45}, 441 {0x5829, 0x23}, 442 {0x582a, 0x21}, 443 {0x582b, 0x41}, 444 {0x582c, 0x41}, 445 {0x582d, 0x05}, 446 {0x582e, 0x23}, 447 {0x582f, 0x41}, 448 {0x5830, 0x41}, 449 {0x5831, 0x41}, 450 {0x5832, 0x03}, 451 {0x5833, 0x25}, 452 {0x5834, 0x23}, 453 {0x5835, 0x21}, 454 {0x5836, 0x23}, 455 {0x5837, 0x05}, 456 {0x5838, 0x25}, 457 {0x5839, 0x43}, 458 {0x583a, 0x25}, 459 {0x583b, 0x23}, 460 {0x583c, 0x65}, 461 {0x583d, 0xcf}, 462 {0x5842, 0x00}, 463 {0x5843, 0xef}, 464 {0x5844, 0x01}, 465 {0x5845, 0x3f}, 466 {0x5846, 0x01}, 467 {0x5847, 0x3f}, 468 {0x5848, 0x00}, 469 {0x5849, 0xd5}, 470}; 471 472static struct v4l2_subdev_info ov8820_subdev_info[] = { 473 { 474 .code = V4L2_MBUS_FMT_SBGGR10_1X10, 475 .colorspace = V4L2_COLORSPACE_JPEG, 476 .fmt = 1, 477 .order = 0, 478 }, 479 /* more can be supported, to be added later */ 480}; 481 482static struct msm_camera_i2c_conf_array ov8820_init_conf[] = { 483 {&ov8820_reset_settings[0], 484 ARRAY_SIZE(ov8820_reset_settings), 50, MSM_CAMERA_I2C_BYTE_DATA}, 485 {&ov8820_recommend_settings[0], 486 ARRAY_SIZE(ov8820_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA} 487}; 488 489static struct msm_camera_i2c_conf_array ov8820_confs[] = { 490 {&ov8820_snap_settings[0], 491 ARRAY_SIZE(ov8820_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}, 492 {&ov8820_prev_settings[0], 493 ARRAY_SIZE(ov8820_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}, 494 {&ov8820_1080_settings[0], 495 ARRAY_SIZE(ov8820_1080_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}, 496 {&ov8820_60fps_settings[0], 497 ARRAY_SIZE(ov8820_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}, 498}; 499 500/* vt_pixel_clk==pll sys clk, op_pixel_clk==mipi clk */ 501static struct msm_sensor_output_info_t ov8820_dimensions[] = { 502 { 503 .x_output = 0xCC0, 504 .y_output = 0x990, 505 .line_length_pclk = 0xD68, 506 .frame_length_lines = 0x9B0, 507 .vt_pixel_clk = 200000000, 508 .op_pixel_clk = 264000000, 509 .binning_factor = 1, 510 }, 511 { 512 .x_output = 0x660, 513 .y_output = 0x4C8, 514 .line_length_pclk = 0x6DE, 515 .frame_length_lines = 0x506, 516 .vt_pixel_clk = 66700000, 517 .op_pixel_clk = 88000000, 518 .binning_factor = 2, 519 }, 520 { 521 .x_output = 0x780, /*1920*/ 522 .y_output = 0x438, /*1080*/ 523 .line_length_pclk = 0xDF0, /*3568*/ 524 .frame_length_lines = 0x74C, /*1868*/ 525 .vt_pixel_clk = 200000000, 526 .op_pixel_clk = 204000000, 527 .binning_factor = 1, 528 }, 529 { 530 .x_output = 0x500, /*1280*/ 531 .y_output = 0x2D0, /*720*/ 532 .line_length_pclk = 0xDE0, /*3552*/ 533 .frame_length_lines = 0x3A0, /*928*/ 534 .vt_pixel_clk = 200000000, 535 .op_pixel_clk = 264000000, 536 .binning_factor = 1, 537 }, 538}; 539 540static struct msm_camera_csid_vc_cfg ov8820_cid_cfg[] = { 541 {0, CSI_RAW10, CSI_DECODE_10BIT}, 542 {1, CSI_EMBED_DATA, CSI_DECODE_8BIT}, 543}; 544 545static struct msm_camera_csi2_params ov8820_csi_params = { 546 .csid_params = { 547 .lane_assign = 0xe4, 548 .lane_cnt = 4, 549 .lut_params = { 550 .num_cid = 2, 551 .vc_cfg = ov8820_cid_cfg, 552 }, 553 }, 554 .csiphy_params = { 555 .lane_cnt = 4, 556 .settle_cnt = 0x14, 557 }, 558}; 559 560static struct msm_camera_csi2_params *ov8820_csi_params_array[] = { 561 &ov8820_csi_params, 562 &ov8820_csi_params, 563 &ov8820_csi_params, 564 &ov8820_csi_params, 565}; 566 567static struct msm_sensor_output_reg_addr_t ov8820_reg_addr = { 568 .x_output = 0x3808, 569 .y_output = 0x380a, 570 .line_length_pclk = 0x380c, 571 .frame_length_lines = 0x380e, 572}; 573 574static struct msm_sensor_id_info_t ov8820_id_info = { 575 .sensor_id_reg_addr = 0x300A, 576 .sensor_id = 0x8820, 577}; 578 579static struct msm_sensor_exp_gain_info_t ov8820_exp_gain_info = { 580 .coarse_int_time_addr = 0x3501, 581 .global_gain_addr = 0x350A, 582 .vert_offset = 6, 583}; 584 585static int32_t ov8820_read_otp(struct msm_sensor_ctrl_t *s_ctrl) 586{ 587 int32_t rc = 0; 588 int16_t i, j; 589 uint8_t otp[256]; 590 uint16_t readData; 591 592 /* Start Stream to read OTP Data */ 593 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 594 0x0100, 0x01, MSM_CAMERA_I2C_BYTE_DATA); 595 596 if (rc < 0) { 597 pr_err("%s: Unable to read otp\n", __func__); 598 return rc; 599 } 600 601 /* Read all 8 banks */ 602 for (i = 0; i < 8; i++) { 603 /* Reset OTP Buffer Registers */ 604 for (j = 0; j < 32; j++) { 605 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 606 (uint16_t)(OV8820_OTP_DATA+j), 0xFF, 607 MSM_CAMERA_I2C_BYTE_DATA); 608 if (rc < 0) 609 return rc; 610 } 611 612 /* Set OTP Bank & Enable */ 613 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 614 OV8820_OTP_BANK, 0x08|i, 615 MSM_CAMERA_I2C_BYTE_DATA); 616 if (rc < 0) 617 return rc; 618 619 /* Set Read OTP Bank */ 620 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 621 OV8820_OTP_LOAD, 0x01, 622 MSM_CAMERA_I2C_BYTE_DATA); 623 624 if (rc < 0) 625 return rc; 626 627 /* Delay */ 628 msleep(25); 629 630 /* Read OTP Buffer Registers */ 631 for (j = 0; j < 32; j++) { 632 rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client, 633 OV8820_OTP_DATA+j, 634 &readData, 635 MSM_CAMERA_I2C_BYTE_DATA); 636 637 otp[(i*32)+j] = (uint8_t)readData; 638 639 if (rc < 0) 640 return rc; 641 } 642 643 /* Reset Read OTP Bank */ 644 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 645 OV8820_OTP_LOAD, 0x00, 646 MSM_CAMERA_I2C_BYTE_DATA); 647 648 if (rc < 0) 649 return rc; 650 } 651 652 /* Stop Streaming */ 653 rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 654 0x0100, 0x00, MSM_CAMERA_I2C_BYTE_DATA); 655 if (rc < 0) { 656 pr_err("%s: Unable to stop streaming of imager\n", __func__); 657 return rc; 658 } 659 660 memcpy((void *)&otp_info, otp, sizeof(struct otp_info_t)); 661 return rc; 662} 663 664static int32_t ov8820_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl, 665 uint16_t gain, uint32_t line) 666{ 667 uint32_t fl_lines, offset; 668 uint8_t int_time[3]; 669 670 fl_lines = 671 (s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10; 672 offset = s_ctrl->sensor_exp_gain_info->vert_offset; 673 if (line > (fl_lines - offset)) 674 fl_lines = line + offset; 675 676 fl_lines += (fl_lines & 0x1); 677 s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl); 678 msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 679 s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines, 680 MSM_CAMERA_I2C_WORD_DATA); 681 int_time[0] = line >> 12; 682 int_time[1] = line >> 4; 683 int_time[2] = line << 4; 684 msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client, 685 s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1, 686 &int_time[0], 3); 687 msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 688 s_ctrl->sensor_exp_gain_info->global_gain_addr, gain, 689 MSM_CAMERA_I2C_WORD_DATA); 690 s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl); 691 return 0; 692} 693 694static int32_t ov8820_regulator_on(struct regulator **reg, 695 char *regname, int uV) 696{ 697 int32_t rc = 0; 698 pr_info("ov8820_regulator_on: %s %d\n", regname, uV); 699 700 *reg = regulator_get(NULL, regname); 701 if (IS_ERR(*reg)) { 702 pr_err("ov8820: failed to get %s (%ld)\n", 703 regname, PTR_ERR(*reg)); 704 goto reg_on_done; 705 } 706 rc = regulator_set_voltage(*reg, uV, uV); 707 if (rc) { 708 pr_err("ov8820: failed to set voltage for %s (%d)\n", 709 regname, rc); 710 goto reg_on_done; 711 } 712 rc = regulator_enable(*reg); 713 if (rc) { 714 pr_err("ov8820: failed to enable %s (%d)\n", 715 regname, rc); 716 goto reg_on_done; 717 } 718reg_on_done: 719 return rc; 720} 721 722static int32_t ov8820_regulator_off(struct regulator *reg, char *regname) 723{ 724 int32_t rc = 0; 725 726 if (reg) { 727 pr_err("ov8820_regulator_off: %s\n", regname); 728 729 rc = regulator_disable(reg); 730 if (rc) { 731 pr_err("ov8820: failed to disable %s (%d)\n", 732 regname, rc); 733 goto reg_off_done; 734 } 735 regulator_put(reg); 736 } 737reg_off_done: 738 return rc; 739} 740 741 742static int32_t ov8820_power_up(struct msm_sensor_ctrl_t *s_ctrl) 743{ 744 int32_t rc = 0; 745 struct msm_camera_sensor_platform_info *pinfo = 746 s_ctrl->sensordata->sensor_platform_info; 747 748 pr_info("ov8820_power_up R:%d P:%d D:%d A:%d 1.8:%s\n", 749 pinfo->sensor_reset, 750 pinfo->sensor_pwd, 751 pinfo->digital_en, 752 pinfo->analog_en, 753 (pinfo->reg_1p8 ? pinfo->reg_1p8 : "-")); 754 755 /*obtain gpios*/ 756 rc = gpio_request(pinfo->analog_en, "ov8820"); 757 if (rc < 0) { 758 pr_err("ov8820: gpio request ANALOG_EN failed (%d)\n", 759 rc); 760 goto power_up_done; 761 } 762 rc = gpio_request(pinfo->sensor_pwd, "ov8820"); 763 if (rc < 0) { 764 pr_err("ov8820: gpio request PWRDWN failed (%d)\n", rc); 765 goto power_up_done; 766 } 767 rc = gpio_request(pinfo->sensor_reset, "ov8820"); 768 if (rc < 0) { 769 pr_err("ov8820: gpio request RESET failed (%d)\n", rc); 770 goto power_up_done; 771 } 772 if (pinfo->digital_en) { 773 rc = gpio_request(pinfo->digital_en, "ov8820"); 774 if (rc < 0) { 775 pr_err("ov8820: gpio request DIG_EN failed (%d)\n", 776 rc); 777 goto power_up_done; 778 } 779 } 780 781 /*Turn on VDDIO*/ 782 if (pinfo->digital_en) { 783 gpio_direction_output(pinfo->digital_en, 1); 784 } else { 785 rc = ov8820_regulator_on(®_1p8, pinfo->reg_1p8, 1800000); 786 if (rc < 0) 787 goto power_up_done; 788 } 789 790 /* Enable AVDD and AF supplies*/ 791 gpio_direction_output(pinfo->analog_en, 1); 792 usleep(200); 793 794 /*Enable MCLK*/ 795 msm_sensor_probe_on(&s_ctrl->sensor_i2c_client->client->dev); 796 msm_camio_clk_rate_set(OV8820_DEFAULT_MCLK_RATE); 797 usleep(20000); 798 799 /*set PWRDWN high*/ 800 gpio_direction_output(pinfo->sensor_pwd, 1); 801 usleep(26000); 802 803 /*Set Reset high*/ 804 gpio_direction_output(pinfo->sensor_reset, 1); 805 usleep(35000); 806 807power_up_done: 808 return rc; 809} 810 811static int32_t ov8820_power_down( 812 struct msm_sensor_ctrl_t *s_ctrl) 813{ 814 struct msm_camera_sensor_platform_info *pinfo = 815 s_ctrl->sensordata->sensor_platform_info; 816 817 pr_info("ov8820_power_down\n"); 818 819 /*Set Reset Low*/ 820 gpio_direction_output(pinfo->sensor_reset, 0); 821 usleep(10000); 822 823 /*Disable MCLK*/ 824 msm_sensor_probe_off(&s_ctrl->sensor_i2c_client->client->dev); 825 usleep(10000); 826 827 /*Disable AVDD and AF supplies*/ 828 gpio_direction_output(pinfo->analog_en, 0); 829 usleep(15000); 830 831 /*Disable VDDIO*/ 832 if (pinfo->digital_en) 833 gpio_direction_output(pinfo->digital_en, 0); 834 else 835 ov8820_regulator_off(reg_1p8, "1.8"); 836 837 /*Set PWRDWN Low*/ 838 gpio_direction_output(pinfo->sensor_pwd, 0); 839 840 /*Clean up*/ 841 if (pinfo->digital_en) 842 gpio_free(pinfo->digital_en); 843 gpio_free(pinfo->sensor_pwd); 844 gpio_free(pinfo->sensor_reset); 845 gpio_free(pinfo->analog_en); 846 847 return 0; 848} 849 850static const struct i2c_device_id ov8820_i2c_id[] = { 851 {SENSOR_NAME, (kernel_ulong_t)&ov8820_s_ctrl}, 852 { } 853}; 854 855static struct i2c_driver ov8820_i2c_driver = { 856 .id_table = ov8820_i2c_id, 857 .probe = msm_sensor_i2c_probe, 858 .driver = { 859 .name = SENSOR_NAME, 860 }, 861}; 862 863static struct msm_camera_i2c_client ov8820_sensor_i2c_client = { 864 .addr_type = MSM_CAMERA_I2C_WORD_ADDR, 865}; 866 867static int32_t ov8820_match_id(struct msm_sensor_ctrl_t *s_ctrl) 868{ 869 int32_t rc = 0; 870 uint16_t chipid = 0; 871 rc = msm_camera_i2c_read( 872 s_ctrl->sensor_i2c_client, 873 s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid, 874 MSM_CAMERA_I2C_WORD_DATA); 875 if (rc < 0) { 876 pr_err("%s: read id failed\n", __func__); 877 return rc; 878 } 879 880 pr_info("ov8820 chipid: %04x\n", chipid); 881 if (chipid != s_ctrl->sensor_id_info->sensor_id) { 882 pr_err("%s: chip id does not match\n", __func__); 883 return -ENODEV; 884 } 885 886 rc = ov8820_read_otp(s_ctrl); 887 if (rc < 0) { 888 pr_err("%s: unable to read otp data\n", __func__); 889 return -ENODEV; 890 } 891 892 pr_info("ov8820: match_id success\n"); 893 return 0; 894} 895 896static int32_t ov8820_get_module_info(struct msm_sensor_ctrl_t *s_ctrl, 897 struct otp_info_t *module_info) 898{ 899 *(module_info) = otp_info; 900 return 0; 901} 902 903int32_t ov8820_adjust_frame_lines(struct msm_sensor_ctrl_t *s_ctrl, 904 uint16_t res) 905{ 906 uint16_t cur_line = 0; 907 uint16_t exp_fl_lines = 0; 908 uint8_t int_time[3]; 909 if (s_ctrl->sensor_exp_gain_info) { 910 msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client, 911 s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1, 912 &int_time[0], 3); 913 cur_line |= int_time[0] << 12; 914 cur_line |= int_time[1] << 4; 915 cur_line |= int_time[2] >> 4; 916 exp_fl_lines = cur_line + 917 s_ctrl->sensor_exp_gain_info->vert_offset; 918 if (exp_fl_lines > s_ctrl->msm_sensor_reg-> 919 output_settings[res].frame_length_lines) { 920 exp_fl_lines += (exp_fl_lines & 0x1); 921 msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 922 s_ctrl->sensor_output_reg_addr-> 923 frame_length_lines, 924 exp_fl_lines, 925 MSM_CAMERA_I2C_WORD_DATA); 926 } 927 CDBG("%s cur_line %x cur_fl_lines %x, exp_fl_lines %x\n", 928 __func__, 929 cur_line, 930 s_ctrl->msm_sensor_reg-> 931 output_settings[res].frame_length_lines, 932 exp_fl_lines); 933 } 934 return 0; 935} 936 937 938static int __init msm_sensor_init_module(void) 939{ 940 return i2c_add_driver(&ov8820_i2c_driver); 941} 942 943static struct v4l2_subdev_core_ops ov8820_subdev_core_ops = { 944 .ioctl = msm_sensor_subdev_ioctl, 945 .s_power = msm_sensor_power, 946}; 947 948static struct v4l2_subdev_video_ops ov8820_subdev_video_ops = { 949 .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt, 950}; 951 952static struct v4l2_subdev_ops ov8820_subdev_ops = { 953 .core = &ov8820_subdev_core_ops, 954 .video = &ov8820_subdev_video_ops, 955}; 956 957static struct msm_sensor_fn_t ov8820_func_tbl = { 958 .sensor_start_stream = msm_sensor_start_stream, 959 .sensor_stop_stream = msm_sensor_stop_stream, 960 .sensor_group_hold_on = msm_sensor_group_hold_on, 961 .sensor_group_hold_off = msm_sensor_group_hold_off, 962 .sensor_set_fps = msm_sensor_set_fps, 963 .sensor_write_exp_gain = ov8820_write_exp_gain, 964 .sensor_write_snapshot_exp_gain = ov8820_write_exp_gain, 965 .sensor_setting = msm_sensor_setting, 966 .sensor_set_sensor_mode = msm_sensor_set_sensor_mode, 967 .sensor_mode_init = msm_sensor_mode_init, 968 .sensor_get_output_info = msm_sensor_get_output_info, 969 .sensor_config = msm_sensor_config, 970 .sensor_power_up = ov8820_power_up, 971 .sensor_power_down = ov8820_power_down, 972 .sensor_match_id = ov8820_match_id, 973 .sensor_adjust_frame_lines = ov8820_adjust_frame_lines, 974 .sensor_get_module_info = ov8820_get_module_info, 975}; 976 977static struct msm_sensor_reg_t ov8820_regs = { 978 .default_data_type = MSM_CAMERA_I2C_BYTE_DATA, 979 .start_stream_conf = ov8820_start_settings, 980 .start_stream_conf_size = ARRAY_SIZE(ov8820_start_settings), 981 .stop_stream_conf = ov8820_stop_settings, 982 .stop_stream_conf_size = ARRAY_SIZE(ov8820_stop_settings), 983 .group_hold_on_conf = ov8820_groupon_settings, 984 .group_hold_on_conf_size = ARRAY_SIZE(ov8820_groupon_settings), 985 .group_hold_off_conf = ov8820_groupoff_settings, 986 .group_hold_off_conf_size = ARRAY_SIZE(ov8820_groupoff_settings), 987 .init_settings = &ov8820_init_conf[0], 988 .init_size = ARRAY_SIZE(ov8820_init_conf), 989 .mode_settings = &ov8820_confs[0], 990 .output_settings = &ov8820_dimensions[0], 991 .num_conf = ARRAY_SIZE(ov8820_confs), 992}; 993 994static struct msm_sensor_ctrl_t ov8820_s_ctrl = { 995 .msm_sensor_reg = &ov8820_regs, 996 .sensor_i2c_client = &ov8820_sensor_i2c_client, 997 .sensor_i2c_addr = 0x6C, 998 .sensor_output_reg_addr = &ov8820_reg_addr, 999 .sensor_id_info = &ov8820_id_info, 1000 .sensor_exp_gain_info = &ov8820_exp_gain_info, 1001 .cam_mode = MSM_SENSOR_MODE_INVALID, 1002 .csi_params = &ov8820_csi_params_array[0], 1003 .msm_sensor_mutex = &ov8820_mut, 1004 .sensor_i2c_driver = &ov8820_i2c_driver, 1005 .sensor_v4l2_subdev_info = ov8820_subdev_info, 1006 .sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov8820_subdev_info), 1007 .sensor_v4l2_subdev_ops = &ov8820_subdev_ops, 1008 .func_tbl = &ov8820_func_tbl, 1009}; 1010 1011module_init(msm_sensor_init_module); 1012MODULE_DESCRIPTION("Omnivision 8820 Bayer sensor driver"); 1013MODULE_LICENSE("GPL v2"); 1014 1015