ov2775_driver.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. *
  25. *****************************************************************************
  26. *
  27. * The GPL License (GPL)
  28. *
  29. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  30. *
  31. * This program is free software; you can redistribute it and/or
  32. * modify it under the terms of the GNU General Public License
  33. * as published by the Free Software Foundation; either version 2
  34. * of the License, or (at your option) any later version.
  35. *
  36. * This program is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with this program;
  43. *
  44. *****************************************************************************
  45. *
  46. * Note: This software is released under dual MIT and GPL licenses. A
  47. * recipient may use this file under the terms of either the MIT license or
  48. * GPL License. If you wish to use only one license not the other, you can
  49. * indicate your decision by deleting one of the above license notices in your
  50. * version of this file.
  51. *
  52. *****************************************************************************/
  53. #include <linux/module.h>
  54. #include <linux/uaccess.h>
  55. #include "vvsensor.h"
  56. #include "sensor_common.h"
  57. #include "ov2775_reg_cfg.h"
  58. #define SENSOR_CLK 24000000
  59. static struct vvcam_mode_info pov2775_mode_info[] = {
  60. {
  61. .index = 0,
  62. .width = 640,
  63. .height = 480,
  64. .fps = 2,//30,
  65. .hdr_mode = SENSOR_MODE_LINEAR,
  66. .bit_width = 12,
  67. .bayer_pattern = BAYER_BGGR,
  68. .mipi_phy_freq = 408, //mbps
  69. .mipi_line_num = 4,
  70. },
  71. {
  72. .index = 1,
  73. .width = 1920,
  74. .height = 1080,
  75. .fps = 30,
  76. .hdr_mode = SENSOR_MODE_HDR_STITCH,
  77. .stitching_mode = SENSOR_STITCHING_3DOL,
  78. .bit_width = 12,
  79. .bayer_pattern = BAYER_BGGR,
  80. .mipi_phy_freq = 408, //mbps
  81. .mipi_line_num = 4,
  82. },
  83. {
  84. .index = 2,
  85. .width = 1280,
  86. .height = 720,
  87. .fps = 60,
  88. .hdr_mode = SENSOR_MODE_LINEAR,
  89. .bit_width = 12,
  90. .bayer_pattern = BAYER_BGGR,
  91. .mipi_phy_freq = 408, //mbps
  92. .mipi_line_num = 4,
  93. }
  94. };
  95. static int32_t sensor_query(void *ctx, struct vvcam_mode_info_array *pmode_info_arry)
  96. {
  97. if (!pmode_info_arry)
  98. {
  99. return -1;
  100. }
  101. pmode_info_arry->count = ARRAY_SIZE(pov2775_mode_info);
  102. memcpy(pmode_info_arry->modes,pov2775_mode_info,sizeof(pov2775_mode_info));
  103. return 0;
  104. }
  105. static int32_t sensor_write_reg(void *ctx, uint32_t reg, uint32_t val)
  106. {
  107. int32_t ret = 0;
  108. struct vvcam_sensor_dev *dev = ctx;
  109. ret = vvcam_sensor_i2c_write(dev, reg, val);
  110. return ret;
  111. }
  112. static int32_t sensor_read_reg(void *ctx, uint32_t reg, uint32_t *pval)
  113. {
  114. int32_t ret = 0;
  115. struct vvcam_sensor_dev *dev = ctx;
  116. ret = vvcam_sensor_i2c_read(dev, reg, pval);
  117. return ret;
  118. }
  119. static int32_t sensor_write_reg_arry(void *ctx, struct vvcam_sccb_array *parray)
  120. {
  121. int32_t ret = 0;
  122. int32_t index = 0;
  123. struct vvcam_sensor_dev *dev = ctx;
  124. for (index = 0; index < parray->count; index++)
  125. {
  126. ret = vvcam_sensor_i2c_write(dev, parray->sccb_data[index].addr, parray->sccb_data[index].data);
  127. if (ret != 0)
  128. {
  129. return ret;
  130. }
  131. }
  132. return ret;
  133. }
  134. static int32_t sensor_get_chip_id(void *ctx, uint32_t *chip_id)
  135. {
  136. int32_t ret = 0;
  137. int32_t chip_id_high = 0;
  138. int32_t chip_id_low = 0;
  139. ret = sensor_read_reg(ctx, 0x300a, &chip_id_high);
  140. ret |= sensor_read_reg(ctx, 0x300b, &chip_id_low);
  141. *chip_id = ((chip_id_high & 0xff)<<8) | (chip_id_low & 0xff);
  142. return ret;
  143. }
  144. static int32_t sensor_init(void *ctx, struct vvcam_mode_info *pmode)
  145. {
  146. int32_t ret = 0;
  147. int32_t i = 0;
  148. struct vvcam_sensor_dev *dev = ctx;
  149. struct vvcam_mode_info *psensor_mode = NULL;
  150. for (i=0; i < sizeof(pov2775_mode_info)/ sizeof(struct vvcam_mode_info); i++)
  151. {
  152. if (pov2775_mode_info[i].index == pmode->index)
  153. {
  154. psensor_mode = &(pov2775_mode_info[i]);
  155. break;
  156. }
  157. }
  158. if (psensor_mode == NULL)
  159. {
  160. return -1;
  161. }
  162. memcpy(&(dev->sensor_mode),psensor_mode,sizeof(struct vvcam_mode_info));
  163. switch(dev->sensor_mode.index)
  164. {
  165. case 0:
  166. ret = sensor_write_reg_arry(ctx,&ov2775_mipi4lane_1080p_30fps_linear_arry);
  167. dev->ae_info.DefaultFrameLengthLines = 0x466;
  168. dev->ae_info.CurFrameLengthLines = dev->ae_info.DefaultFrameLengthLines;
  169. dev->ae_info.one_line_exp_time_ns = 69607;//ns
  170. dev->ae_info.max_integration_time = dev->ae_info.CurFrameLengthLines -4;
  171. dev->ae_info.min_integration_time = 1;
  172. dev->ae_info.integration_accuracy = 1;
  173. dev->ae_info.gain_accuracy = 1024;
  174. dev->ae_info.max_gain = 22 * dev->ae_info.gain_accuracy;
  175. dev->ae_info.min_gain = 3 * dev->ae_info.gain_accuracy;
  176. dev->ae_info.cur_fps = dev->sensor_mode.fps;
  177. break;
  178. case 1:
  179. ret = sensor_write_reg_arry(ctx,&ov2775_mipi4lane_1080p_30fps_linear_arry);
  180. dev->ae_info.DefaultFrameLengthLines = 0x466;
  181. dev->ae_info.CurFrameLengthLines = dev->ae_info.DefaultFrameLengthLines;
  182. dev->ae_info.one_line_exp_time_ns = 69607;//ns
  183. dev->ae_info.max_integration_time = dev->ae_info.CurFrameLengthLines -4;
  184. dev->ae_info.min_integration_time = 1;
  185. dev->ae_info.integration_accuracy = 1;
  186. dev->ae_info.gain_accuracy = 1024;
  187. dev->ae_info.max_gain = 22 * dev->ae_info.gain_accuracy;
  188. dev->ae_info.min_gain = 3 * dev->ae_info.gain_accuracy;
  189. dev->ae_info.cur_fps = dev->sensor_mode.fps;
  190. break;
  191. default:
  192. break;
  193. }
  194. return ret;
  195. }
  196. static int32_t sensor_set_stream(void *ctx, uint32_t status)
  197. {
  198. int32_t ret = 0;
  199. if (status)
  200. {
  201. ret = sensor_write_reg(ctx, 0x3012, 0x01);
  202. }else
  203. {
  204. ret = sensor_write_reg(ctx, 0x3012, 0x00);
  205. }
  206. return ret;
  207. }
  208. static int32_t sensor_set_exp(void *ctx, uint32_t exp_line)
  209. {
  210. int32_t ret = 0;
  211. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  212. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  213. ret |= sensor_write_reg(ctx, 0x30b6, (exp_line>>8) & 0xff);
  214. ret |= sensor_write_reg(ctx, 0x30b7, exp_line & 0xff);
  215. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  216. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  217. return ret;
  218. }
  219. static int32_t sensor_set_vs_exp(void *ctx, uint32_t exp_line)
  220. {
  221. int32_t ret = 0;
  222. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  223. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  224. ret |= sensor_write_reg(ctx, 0x30b8, (exp_line>>8) & 0xff);
  225. ret |= sensor_write_reg(ctx, 0x30b9, exp_line & 0xff);
  226. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  227. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  228. return ret;
  229. }
  230. static int32_t sensor_calc_gain(uint32_t total_gain, uint32_t *pagain, uint32_t *pdgain, uint32_t *phcg)
  231. {
  232. uint32_t sensor_gain;
  233. sensor_gain = total_gain;
  234. if(sensor_gain <= 3072)// 3 * gain_accuracy
  235. {
  236. sensor_gain = 3072;
  237. }
  238. else if((sensor_gain >= 22528) && (sensor_gain < 23552)) //gain >22*gain_accuracy && gain < 23*gain_accuracy
  239. {
  240. sensor_gain = 22528;
  241. }
  242. if (sensor_gain < 4480) //gain < 4.375 * gain_accuracy
  243. {
  244. *pagain = 1;
  245. *phcg = 1;
  246. }
  247. else if(sensor_gain < 8960)//gain < 8.75 * gain_accuracy
  248. {
  249. *pagain = 2;
  250. *phcg = 1;
  251. }
  252. else if(sensor_gain < 22528)//gain < 22 * gain_accuracy
  253. {
  254. *pagain = 3;
  255. *phcg = 1;
  256. }
  257. else if(sensor_gain < 44990)//gain < 44 * gain_accuracy
  258. {
  259. *pagain = 0;
  260. *phcg = 11;
  261. }
  262. else if (sensor_gain < 89320)//gain < 88 * gain_accuracy
  263. {
  264. *pagain = 1;
  265. *phcg = 11;
  266. }
  267. else if (sensor_gain < 179498)//gain < 176 * gain_accuracy
  268. {
  269. *pagain = 2;
  270. *phcg = 11;
  271. }else
  272. {
  273. *pagain = 3;
  274. *phcg = 11;
  275. }
  276. *pdgain = ((sensor_gain << 8) >> (*pagain)) / (1024 * (*phcg));
  277. return 0;
  278. }
  279. static int32_t sensor_set_gain(void *ctx, uint32_t gain)
  280. {
  281. int32_t ret = 0;
  282. uint32_t again = 0;
  283. uint32_t dgain = 0;
  284. uint32_t hcg = 1;
  285. uint32_t hcg_gain;
  286. uint32_t lcg_gain;
  287. uint32_t hcg_again = 0;
  288. uint32_t hcg_dgain = 0;
  289. uint32_t lcg_again = 0;
  290. uint32_t lcg_dgain = 0;
  291. uint32_t reg_val = 0;
  292. uint32_t hdr_radio;
  293. struct vvcam_sensor_dev *dev = ctx;
  294. hdr_radio= dev->ae_info.hdr_radio;
  295. switch(dev->sensor_mode.index)
  296. {
  297. case 0:
  298. sensor_calc_gain(gain, &again, &dgain, &hcg);
  299. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  300. if (hcg == 1)
  301. {
  302. reg_val &= ~(1<<6); //LCG
  303. }else
  304. {
  305. reg_val |= (1<<6); //HCG
  306. }
  307. reg_val &= ~0x03;
  308. reg_val |= again;
  309. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  310. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  311. ret |= sensor_write_reg(ctx, 0x315a, (dgain>>8) & 0xff);
  312. ret |= sensor_write_reg(ctx, 0x315b, dgain & 0xff);
  313. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  314. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  315. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  316. break;
  317. case 1:
  318. hcg_gain = gain * hdr_radio / 11;
  319. sensor_calc_gain(gain, &hcg_again, &hcg_dgain, &hcg);
  320. lcg_gain = gain;
  321. sensor_calc_gain(gain, &lcg_again, &lcg_dgain, &hcg);
  322. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  323. reg_val &= ~0x0f;
  324. reg_val |= (lcg_again<<2)&0x03;
  325. reg_val |= hcg_again & 0x03;
  326. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  327. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  328. ret |= sensor_write_reg(ctx, 0x315a, (hcg_dgain>>8) & 0xff);
  329. ret |= sensor_write_reg(ctx, 0x315b, hcg_dgain & 0xff);
  330. ret |= sensor_write_reg(ctx, 0x315c, (lcg_dgain>>8) & 0xff);
  331. ret |= sensor_write_reg(ctx, 0x315d, lcg_dgain & 0xff);
  332. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  333. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  334. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  335. break;
  336. default:
  337. break;
  338. }
  339. return ret;
  340. }
  341. static int32_t sensor_set_vs_gain(void *ctx, uint32_t gain)
  342. {
  343. int32_t ret = 0;
  344. uint32_t again = 0;
  345. uint32_t dgain = 0;
  346. uint32_t sensor_gain;
  347. uint32_t hcg = 1;
  348. uint32_t reg_val = 0;
  349. sensor_gain = gain;
  350. sensor_calc_gain(gain, &again, &dgain, &hcg);
  351. ret = sensor_read_reg(ctx, 0x30bb, &reg_val);
  352. reg_val &= ~0x30;
  353. reg_val |= (again & 0x03) << 4;
  354. ret = sensor_write_reg(ctx, 0x3467, 0x00);
  355. ret |= sensor_write_reg(ctx, 0x3464, 0x04);
  356. ret |= sensor_write_reg(ctx, 0x315e, (dgain>>8) & 0xff);
  357. ret |= sensor_write_reg(ctx, 0x315f, dgain & 0xff);
  358. ret |= sensor_write_reg(ctx, 0x30bb, reg_val);
  359. ret |= sensor_write_reg(ctx, 0x3464, 0x14);
  360. ret |= sensor_write_reg(ctx, 0x3467, 0x01);
  361. return ret;
  362. }
  363. static int32_t sensor_set_fps(void *ctx, uint32_t fps)
  364. {
  365. int32_t ret = 0;
  366. uint32_t FrameLengthLines = 0;
  367. struct vvcam_sensor_dev *dev = ctx;
  368. if (fps > dev->sensor_mode.fps)
  369. {
  370. return -1;
  371. }
  372. FrameLengthLines = dev->sensor_mode.fps * dev->ae_info.DefaultFrameLengthLines / fps;
  373. if (FrameLengthLines != dev->ae_info.CurFrameLengthLines)
  374. {
  375. ret = sensor_write_reg(ctx, 0x30b2, (FrameLengthLines >> 8) & 0xff);
  376. ret |= sensor_write_reg(ctx, 0x30b3, FrameLengthLines & 0xff);
  377. if (ret != 0)
  378. {
  379. return -1;
  380. }
  381. dev->ae_info.CurFrameLengthLines = FrameLengthLines;
  382. dev->ae_info.max_integration_time = FrameLengthLines-3;
  383. dev->ae_info.cur_fps = fps;
  384. }
  385. return ret;
  386. }
  387. static int32_t sensor_set_resolution(void *ctx, uint32_t width, uint32_t height)
  388. {
  389. return 0;
  390. }
  391. static int32_t sensor_set_hdr_mode(void *ctx, uint32_t hdr_mode)
  392. {
  393. int32_t ret = 0;
  394. struct vvcam_sensor_dev *dev = ctx;
  395. if (hdr_mode == dev->sensor_mode.hdr_mode)
  396. {
  397. return 0;
  398. }
  399. if (hdr_mode == SENSOR_MODE_LINEAR)
  400. {
  401. ret = sensor_write_reg(ctx, 0x3190, 0x08);
  402. dev->sensor_mode.hdr_mode = SENSOR_MODE_LINEAR;
  403. }
  404. else if(hdr_mode == SENSOR_MODE_HDR_STITCH)
  405. {
  406. ret = sensor_write_reg(ctx, 0x3190, 0x05);
  407. dev->sensor_mode.hdr_mode = SENSOR_MODE_HDR_STITCH;
  408. }
  409. return ret;
  410. }
  411. struct vvcam_sensor_function_s ov2775_function =
  412. {
  413. .sensor_name = "ov2775",
  414. .reserve_id = 0x2770,
  415. .sensor_clk = SENSOR_CLK,
  416. .mipi_info.mipi_lane = 4,
  417. .sensor_get_chip_id = sensor_get_chip_id,
  418. .sensor_init = sensor_init,
  419. .sensor_set_stream = sensor_set_stream,
  420. .sensor_set_exp = sensor_set_exp,
  421. .sensor_set_vs_exp = sensor_set_vs_exp,
  422. .sensor_set_gain = sensor_set_gain,
  423. .sensor_set_vs_gain = sensor_set_vs_gain,
  424. .sensor_set_fps = sensor_set_fps,
  425. .sensor_set_resolution = sensor_set_resolution,
  426. .sensor_set_hdr_mode = sensor_set_hdr_mode,
  427. .sensor_query = sensor_query,
  428. };