PageRenderTime 65ms CodeModel.GetById 13ms app.highlight 44ms RepoModel.GetById 2ms app.codeStats 0ms

/drivers/media/video/msm/sensors/ov8820_v4l2.c

https://bitbucket.org/simonsimons34/android_kernel_motorola_electrifym
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(&reg_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