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