ov2778_driver.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. #include <linux/module.h>
  2. #include <linux/uaccess.h>
  3. #include "vvsensor.h"
  4. #include "sensor_common.h"
  5. #include "ov2778_reg_cfg.h"
  6. #define SENSOR_CLK 51000000
  7. static struct vvcam_mode_info pov2778_mode_info[] = {
  8. {
  9. .index = 0,
  10. .width = 1920,
  11. .height = 1080,
  12. .fps = 30,
  13. .hdr_mode = SENSOR_MODE_LINEAR,
  14. .bit_width = 10,
  15. .bayer_pattern = BAYER_GBRG,
  16. },
  17. {
  18. .index = 1,
  19. .width = 1920,
  20. .height = 1080,
  21. .fps = 30,
  22. .hdr_mode = SENSOR_MODE_HDR_STITCH,
  23. .stitching_mode = SENSOR_STITCHING_3DOL,
  24. .bit_width = 10,
  25. .bayer_pattern = BAYER_GBRG,
  26. },
  27. {
  28. .index = 2,
  29. .width = 1280,
  30. .height = 720,
  31. .fps = 60,
  32. .hdr_mode = SENSOR_MODE_LINEAR,
  33. .bit_width = 10,
  34. .bayer_pattern = BAYER_GBRG,
  35. }
  36. };
  37. static int32_t sensor_query(void *ctx, struct vvcam_mode_info_array *pmode_info_arry)
  38. {
  39. if (!pmode_info_arry)
  40. {
  41. return -1;
  42. }
  43. pmode_info_arry->count = ARRAY_SIZE(pov2778_mode_info);
  44. memcpy(pmode_info_arry->modes,pov2778_mode_info,sizeof(pov2778_mode_info));
  45. return 0;
  46. }
  47. static int32_t sensor_write_reg(void *ctx, uint32_t reg, uint32_t val)
  48. {
  49. int32_t ret = 0;
  50. struct vvcam_sensor_dev *dev = ctx;
  51. ret = vvcam_sensor_i2c_write(dev, reg, val);
  52. return ret;
  53. }
  54. static int32_t sensor_read_reg(void *ctx, uint32_t reg, uint32_t *pval)
  55. {
  56. int32_t ret = 0;
  57. struct vvcam_sensor_dev *dev = ctx;
  58. ret = vvcam_sensor_i2c_read(dev, reg, pval);
  59. return ret;
  60. }
  61. static int32_t sensor_write_reg_arry(void *ctx, struct vvcam_sccb_array *parray)
  62. {
  63. int32_t ret = 0;
  64. int32_t index = 0;
  65. struct vvcam_sensor_dev *dev = ctx;
  66. for (index = 0; index < parray->count; index++)
  67. {
  68. ret = vvcam_sensor_i2c_write(dev, parray->sccb_data[index].addr, parray->sccb_data[index].data);
  69. if (ret != 0)
  70. {
  71. return ret;
  72. }
  73. }
  74. return ret;
  75. }
  76. static int32_t sensor_get_chip_id(void *ctx, uint32_t *chip_id)
  77. {
  78. int32_t ret = 0;
  79. int32_t chip_id_high = 0;
  80. int32_t chip_id_low = 0;
  81. ret = sensor_read_reg(ctx, 0x300a, &chip_id_high);
  82. ret |= sensor_read_reg(ctx, 0x300b, &chip_id_low);
  83. *chip_id = ((chip_id_high & 0xff)<<8) | (chip_id_low & 0xff);
  84. return ret;
  85. }
  86. static int32_t sensor_init(void *ctx, struct vvcam_mode_info *pmode)
  87. {
  88. int32_t ret = 0;
  89. int32_t i = 0;
  90. struct vvcam_sensor_dev *dev = ctx;
  91. struct vvcam_mode_info *psensor_mode = NULL;
  92. for (i=0; i < sizeof(pov2778_mode_info)/ sizeof(struct vvcam_mode_info); i++)
  93. {
  94. if (pov2778_mode_info[i].index == pmode->index)
  95. {
  96. psensor_mode = &(pov2778_mode_info[i]);
  97. break;
  98. }
  99. }
  100. if (psensor_mode == NULL)
  101. {
  102. return -1;
  103. }
  104. memcpy(&(dev->sensor_mode),psensor_mode,sizeof(struct vvcam_mode_info));
  105. switch(dev->sensor_mode.index)
  106. {
  107. case 0:
  108. ret = sensor_write_reg_arry(ctx,&ov2778_mipi4lane_1080p_30fps_linear_arry);
  109. dev->ae_info.DefaultFrameLengthLines = 0x466;
  110. dev->ae_info.CurFrameLengthLines = dev->ae_info.DefaultFrameLengthLines;
  111. dev->ae_info.one_line_exp_time_ns = 69607;//ns
  112. dev->ae_info.max_integration_time = dev->ae_info.CurFrameLengthLines -4;
  113. dev->ae_info.min_integration_time = 1;
  114. dev->ae_info.integration_accuracy = 1;
  115. dev->ae_info.gain_accuracy = 1024;
  116. dev->ae_info.max_gain = 22 * dev->ae_info.gain_accuracy;
  117. dev->ae_info.min_gain = 3 * dev->ae_info.gain_accuracy;
  118. dev->ae_info.cur_fps = dev->sensor_mode.fps;
  119. break;
  120. case 1:
  121. ret = sensor_write_reg_arry(ctx,&ov2778_mipi4lane_1080p_30fps_linear_arry);
  122. dev->ae_info.DefaultFrameLengthLines = 0x466;
  123. dev->ae_info.CurFrameLengthLines = dev->ae_info.DefaultFrameLengthLines;
  124. dev->ae_info.one_line_exp_time_ns = 69607;//ns
  125. dev->ae_info.max_integration_time = dev->ae_info.CurFrameLengthLines -4;
  126. dev->ae_info.min_integration_time = 1;
  127. dev->ae_info.integration_accuracy = 1;
  128. dev->ae_info.gain_accuracy = 1024;
  129. dev->ae_info.max_gain = 22 * dev->ae_info.gain_accuracy;
  130. dev->ae_info.min_gain = 3 * dev->ae_info.gain_accuracy;
  131. dev->ae_info.cur_fps = dev->sensor_mode.fps;
  132. break;
  133. default:
  134. break;
  135. }
  136. return ret;
  137. }
  138. static int32_t sensor_set_stream(void *ctx, uint32_t status)
  139. {
  140. int32_t ret = 0;
  141. if (status)
  142. {
  143. ret = sensor_write_reg(ctx, 0x3012, 0x01);
  144. }else
  145. {
  146. ret = sensor_write_reg(ctx, 0x3012, 0x00);
  147. }
  148. return ret;
  149. }
  150. static int32_t sensor_set_exp(void *ctx, uint32_t exp_line)
  151. {
  152. int32_t ret = 0;
  153. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  154. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  155. ret |= sensor_write_reg(ctx, 0x30b6, (exp_line>>8) & 0xff);
  156. ret |= sensor_write_reg(ctx, 0x30b7, exp_line & 0xff);
  157. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  158. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  159. return ret;
  160. }
  161. static int32_t sensor_set_vs_exp(void *ctx, uint32_t exp_line)
  162. {
  163. int32_t ret = 0;
  164. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  165. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  166. ret |= sensor_write_reg(ctx, 0x30b8, (exp_line>>8) & 0xff);
  167. ret |= sensor_write_reg(ctx, 0x30b9, exp_line & 0xff);
  168. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  169. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  170. return ret;
  171. }
  172. static int32_t sensor_calc_gain(uint32_t total_gain, uint32_t *pagain, uint32_t *pdgain, uint32_t *phcg)
  173. {
  174. uint32_t sensor_gain;
  175. sensor_gain = total_gain;
  176. if(sensor_gain <= 3072)// 3 * gain_accuracy
  177. {
  178. sensor_gain = 3072;
  179. }
  180. else if((sensor_gain >= 22528) && (sensor_gain < 23552)) //gain >22*gain_accuracy && gain < 23*gain_accuracy
  181. {
  182. sensor_gain = 22528;
  183. }
  184. if (sensor_gain < 4480) //gain < 4.375 * gain_accuracy
  185. {
  186. *pagain = 1;
  187. *phcg = 1;
  188. }
  189. else if(sensor_gain < 8960)//gain < 8.75 * gain_accuracy
  190. {
  191. *pagain = 2;
  192. *phcg = 1;
  193. }
  194. else if(sensor_gain < 22528)//gain < 22 * gain_accuracy
  195. {
  196. *pagain = 3;
  197. *phcg = 1;
  198. }
  199. else if(sensor_gain < 44990)//gain < 44 * gain_accuracy
  200. {
  201. *pagain = 0;
  202. *phcg = 11;
  203. }
  204. else if (sensor_gain < 89320)//gain < 88 * gain_accuracy
  205. {
  206. *pagain = 1;
  207. *phcg = 11;
  208. }
  209. else if (sensor_gain < 179498)//gain < 176 * gain_accuracy
  210. {
  211. *pagain = 2;
  212. *phcg = 11;
  213. }else
  214. {
  215. *pagain = 3;
  216. *phcg = 11;
  217. }
  218. *pdgain = ((sensor_gain << 8) >> (*pagain)) / (1024 * (*phcg));
  219. return 0;
  220. }
  221. static int32_t sensor_set_gain(void *ctx, uint32_t gain)
  222. {
  223. int32_t ret = 0;
  224. uint32_t again = 0;
  225. uint32_t dgain = 0;
  226. uint32_t hcg = 1;
  227. uint32_t hcg_gain;
  228. uint32_t lcg_gain;
  229. uint32_t hcg_again = 0;
  230. uint32_t hcg_dgain = 0;
  231. uint32_t lcg_again = 0;
  232. uint32_t lcg_dgain = 0;
  233. uint32_t reg_val = 0;
  234. uint32_t hdr_radio;
  235. struct vvcam_sensor_dev *dev = ctx;
  236. hdr_radio= dev->ae_info.hdr_radio;
  237. switch(dev->sensor_mode.index)
  238. {
  239. case 0:
  240. sensor_calc_gain(gain, &again, &dgain, &hcg);
  241. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  242. if (hcg == 1)
  243. {
  244. reg_val &= ~(1<<6); //LCG
  245. }else
  246. {
  247. reg_val |= (1<<6); //HCG
  248. }
  249. reg_val &= ~0x03;
  250. reg_val |= again;
  251. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  252. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  253. ret |= sensor_write_reg(ctx, 0x315a, (dgain>>8) & 0xff);
  254. ret |= sensor_write_reg(ctx, 0x315b, dgain & 0xff);
  255. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  256. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  257. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  258. break;
  259. case 1:
  260. hcg_gain = gain * hdr_radio / 11;
  261. sensor_calc_gain(gain, &hcg_again, &hcg_dgain, &hcg);
  262. lcg_gain = gain;
  263. sensor_calc_gain(gain, &lcg_again, &lcg_dgain, &hcg);
  264. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  265. reg_val &= ~0x0f;
  266. reg_val |= (lcg_again<<2)&0x03;
  267. reg_val |= hcg_again & 0x03;
  268. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  269. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  270. ret |= sensor_write_reg(ctx, 0x315a, (hcg_dgain>>8) & 0xff);
  271. ret |= sensor_write_reg(ctx, 0x315b, hcg_dgain & 0xff);
  272. ret |= sensor_write_reg(ctx, 0x315c, (lcg_dgain>>8) & 0xff);
  273. ret |= sensor_write_reg(ctx, 0x315d, lcg_dgain & 0xff);
  274. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  275. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  276. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  277. break;
  278. default:
  279. break;
  280. }
  281. return ret;
  282. }
  283. static int32_t sensor_set_vs_gain(void *ctx, uint32_t gain)
  284. {
  285. int32_t ret = 0;
  286. uint32_t again = 0;
  287. uint32_t dgain = 0;
  288. uint32_t sensor_gain;
  289. uint32_t hcg = 1;
  290. uint32_t reg_val = 0;
  291. sensor_gain = gain;
  292. sensor_calc_gain(gain, &again, &dgain, &hcg);
  293. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  294. reg_val &= ~0x30;
  295. reg_val |= (again & 0x03) << 4;
  296. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  297. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  298. ret |= sensor_write_reg(ctx, 0x315e, (dgain>>8) & 0xff);
  299. ret |= sensor_write_reg(ctx, 0x315f, dgain & 0xff);
  300. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  301. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  302. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  303. return ret;
  304. }
  305. static int32_t sensor_set_fps(void *ctx, uint32_t fps)
  306. {
  307. int32_t ret = 0;
  308. uint32_t FrameLengthLines = 0;
  309. struct vvcam_sensor_dev *dev = ctx;
  310. if (fps > dev->sensor_mode.fps)
  311. {
  312. return -1;
  313. }
  314. FrameLengthLines = dev->sensor_mode.fps * dev->ae_info.DefaultFrameLengthLines / fps;
  315. if (FrameLengthLines != dev->ae_info.CurFrameLengthLines)
  316. {
  317. ret = sensor_write_reg(ctx, 0x30b2, (FrameLengthLines >> 8) & 0xff);
  318. ret |= sensor_write_reg(ctx, 0x30b3, FrameLengthLines & 0xff);
  319. if (ret != 0)
  320. {
  321. return -1;
  322. }
  323. dev->ae_info.CurFrameLengthLines = FrameLengthLines;
  324. dev->ae_info.max_integration_time = FrameLengthLines-3;
  325. dev->ae_info.cur_fps = fps;
  326. }
  327. return ret;
  328. }
  329. static int32_t sensor_set_resolution(void *ctx, uint32_t width, uint32_t height)
  330. {
  331. return 0;
  332. }
  333. static int32_t sensor_set_hdr_mode(void *ctx, uint32_t hdr_mode)
  334. {
  335. int32_t ret = 0;
  336. struct vvcam_sensor_dev *dev = ctx;
  337. if (hdr_mode == dev->sensor_mode.hdr_mode)
  338. {
  339. return 0;
  340. }
  341. if (hdr_mode == SENSOR_MODE_LINEAR)
  342. {
  343. ret = sensor_write_reg(ctx, 0x3190, 0x08);
  344. dev->sensor_mode.hdr_mode = SENSOR_MODE_LINEAR;
  345. }
  346. else if(hdr_mode == SENSOR_MODE_HDR_STITCH)
  347. {
  348. ret = sensor_write_reg(ctx, 0x3190, 0x05);
  349. dev->sensor_mode.hdr_mode = SENSOR_MODE_HDR_STITCH;
  350. }
  351. return ret;
  352. }
  353. struct vvcam_sensor_function_s ov2778_function =
  354. {
  355. .sensor_name = "ov2778",
  356. .reserve_id = 0x2770,
  357. .sensor_clk = SENSOR_CLK,
  358. .mipi_info.mipi_lane = 4,
  359. .sensor_get_chip_id = sensor_get_chip_id,
  360. .sensor_init = sensor_init,
  361. .sensor_set_stream = sensor_set_stream,
  362. .sensor_set_exp = sensor_set_exp,
  363. .sensor_set_vs_exp = sensor_set_vs_exp,
  364. .sensor_set_gain = sensor_set_gain,
  365. .sensor_set_vs_gain = sensor_set_vs_gain,
  366. .sensor_set_fps = sensor_set_fps,
  367. .sensor_set_resolution = sensor_set_resolution,
  368. .sensor_set_hdr_mode = sensor_set_hdr_mode,
  369. .sensor_query = sensor_query,
  370. };