m5602_ov7660.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. * Driver for the ov7660 sensor
  3. *
  4. * Copyright (C) 2009 Erik Andrén
  5. * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  6. * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  7. *
  8. * Portions of code to USB interface and ALi driver software,
  9. * Copyright (c) 2006 Willem Duinker
  10. * v4l2 interface modeled after the V4L2 driver
  11. * for SN9C10x PC Camera Controllers
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation, version 2.
  16. *
  17. */
  18. #include "m5602_ov7660.h"
  19. static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
  20. static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
  21. static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
  22. __s32 *val);
  23. static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
  24. __s32 val);
  25. static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
  26. static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
  27. static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
  28. static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
  29. static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
  30. static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
  31. static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
  32. static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
  33. static const struct ctrl ov7660_ctrls[] = {
  34. #define GAIN_IDX 1
  35. {
  36. {
  37. .id = V4L2_CID_GAIN,
  38. .type = V4L2_CTRL_TYPE_INTEGER,
  39. .name = "gain",
  40. .minimum = 0x00,
  41. .maximum = 0xff,
  42. .step = 0x1,
  43. .default_value = OV7660_DEFAULT_GAIN,
  44. .flags = V4L2_CTRL_FLAG_SLIDER
  45. },
  46. .set = ov7660_set_gain,
  47. .get = ov7660_get_gain
  48. },
  49. #define BLUE_BALANCE_IDX 2
  50. #define RED_BALANCE_IDX 3
  51. #define AUTO_WHITE_BALANCE_IDX 4
  52. {
  53. {
  54. .id = V4L2_CID_AUTO_WHITE_BALANCE,
  55. .type = V4L2_CTRL_TYPE_BOOLEAN,
  56. .name = "auto white balance",
  57. .minimum = 0,
  58. .maximum = 1,
  59. .step = 1,
  60. .default_value = 1
  61. },
  62. .set = ov7660_set_auto_white_balance,
  63. .get = ov7660_get_auto_white_balance
  64. },
  65. #define AUTO_GAIN_CTRL_IDX 5
  66. {
  67. {
  68. .id = V4L2_CID_AUTOGAIN,
  69. .type = V4L2_CTRL_TYPE_BOOLEAN,
  70. .name = "auto gain control",
  71. .minimum = 0,
  72. .maximum = 1,
  73. .step = 1,
  74. .default_value = 1
  75. },
  76. .set = ov7660_set_auto_gain,
  77. .get = ov7660_get_auto_gain
  78. },
  79. #define AUTO_EXPOSURE_IDX 6
  80. {
  81. {
  82. .id = V4L2_CID_EXPOSURE_AUTO,
  83. .type = V4L2_CTRL_TYPE_BOOLEAN,
  84. .name = "auto exposure",
  85. .minimum = 0,
  86. .maximum = 1,
  87. .step = 1,
  88. .default_value = 1
  89. },
  90. .set = ov7660_set_auto_exposure,
  91. .get = ov7660_get_auto_exposure
  92. },
  93. #define HFLIP_IDX 7
  94. {
  95. {
  96. .id = V4L2_CID_HFLIP,
  97. .type = V4L2_CTRL_TYPE_BOOLEAN,
  98. .name = "horizontal flip",
  99. .minimum = 0,
  100. .maximum = 1,
  101. .step = 1,
  102. .default_value = 0
  103. },
  104. .set = ov7660_set_hflip,
  105. .get = ov7660_get_hflip
  106. },
  107. #define VFLIP_IDX 8
  108. {
  109. {
  110. .id = V4L2_CID_VFLIP,
  111. .type = V4L2_CTRL_TYPE_BOOLEAN,
  112. .name = "vertical flip",
  113. .minimum = 0,
  114. .maximum = 1,
  115. .step = 1,
  116. .default_value = 0
  117. },
  118. .set = ov7660_set_vflip,
  119. .get = ov7660_get_vflip
  120. },
  121. };
  122. static struct v4l2_pix_format ov7660_modes[] = {
  123. {
  124. 640,
  125. 480,
  126. V4L2_PIX_FMT_SBGGR8,
  127. V4L2_FIELD_NONE,
  128. .sizeimage =
  129. 640 * 480,
  130. .bytesperline = 640,
  131. .colorspace = V4L2_COLORSPACE_SRGB,
  132. .priv = 0
  133. }
  134. };
  135. static void ov7660_dump_registers(struct sd *sd);
  136. int ov7660_probe(struct sd *sd)
  137. {
  138. int err = 0, i;
  139. u8 prod_id = 0, ver_id = 0;
  140. s32 *sensor_settings;
  141. if (force_sensor) {
  142. if (force_sensor == OV7660_SENSOR) {
  143. info("Forcing an %s sensor", ov7660.name);
  144. goto sensor_found;
  145. }
  146. /* If we want to force another sensor,
  147. don't try to probe this one */
  148. return -ENODEV;
  149. }
  150. /* Do the preinit */
  151. for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
  152. u8 data[2];
  153. if (preinit_ov7660[i][0] == BRIDGE) {
  154. err = m5602_write_bridge(sd,
  155. preinit_ov7660[i][1],
  156. preinit_ov7660[i][2]);
  157. } else {
  158. data[0] = preinit_ov7660[i][2];
  159. err = m5602_write_sensor(sd,
  160. preinit_ov7660[i][1], data, 1);
  161. }
  162. }
  163. if (err < 0)
  164. return err;
  165. if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
  166. return -ENODEV;
  167. if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
  168. return -ENODEV;
  169. info("Sensor reported 0x%x%x", prod_id, ver_id);
  170. if ((prod_id == 0x76) && (ver_id == 0x60)) {
  171. info("Detected a ov7660 sensor");
  172. goto sensor_found;
  173. }
  174. return -ENODEV;
  175. sensor_found:
  176. sensor_settings = kmalloc(
  177. ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
  178. if (!sensor_settings)
  179. return -ENOMEM;
  180. sd->gspca_dev.cam.cam_mode = ov7660_modes;
  181. sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
  182. sd->desc->ctrls = ov7660_ctrls;
  183. sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
  184. for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
  185. sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
  186. sd->sensor_priv = sensor_settings;
  187. return 0;
  188. }
  189. int ov7660_init(struct sd *sd)
  190. {
  191. int i, err = 0;
  192. s32 *sensor_settings = sd->sensor_priv;
  193. /* Init the sensor */
  194. for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
  195. u8 data[2];
  196. if (init_ov7660[i][0] == BRIDGE) {
  197. err = m5602_write_bridge(sd,
  198. init_ov7660[i][1],
  199. init_ov7660[i][2]);
  200. } else {
  201. data[0] = init_ov7660[i][2];
  202. err = m5602_write_sensor(sd,
  203. init_ov7660[i][1], data, 1);
  204. }
  205. }
  206. if (dump_sensor)
  207. ov7660_dump_registers(sd);
  208. err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
  209. if (err < 0)
  210. return err;
  211. err = ov7660_set_auto_white_balance(&sd->gspca_dev,
  212. sensor_settings[AUTO_WHITE_BALANCE_IDX]);
  213. if (err < 0)
  214. return err;
  215. err = ov7660_set_auto_gain(&sd->gspca_dev,
  216. sensor_settings[AUTO_GAIN_CTRL_IDX]);
  217. if (err < 0)
  218. return err;
  219. err = ov7660_set_auto_exposure(&sd->gspca_dev,
  220. sensor_settings[AUTO_EXPOSURE_IDX]);
  221. if (err < 0)
  222. return err;
  223. err = ov7660_set_hflip(&sd->gspca_dev,
  224. sensor_settings[HFLIP_IDX]);
  225. if (err < 0)
  226. return err;
  227. err = ov7660_set_vflip(&sd->gspca_dev,
  228. sensor_settings[VFLIP_IDX]);
  229. return err;
  230. }
  231. int ov7660_start(struct sd *sd)
  232. {
  233. return 0;
  234. }
  235. int ov7660_stop(struct sd *sd)
  236. {
  237. return 0;
  238. }
  239. void ov7660_disconnect(struct sd *sd)
  240. {
  241. ov7660_stop(sd);
  242. sd->sensor = NULL;
  243. kfree(sd->sensor_priv);
  244. }
  245. static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
  246. {
  247. struct sd *sd = (struct sd *) gspca_dev;
  248. s32 *sensor_settings = sd->sensor_priv;
  249. *val = sensor_settings[GAIN_IDX];
  250. PDEBUG(D_V4L2, "Read gain %d", *val);
  251. return 0;
  252. }
  253. static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  254. {
  255. int err;
  256. u8 i2c_data;
  257. struct sd *sd = (struct sd *) gspca_dev;
  258. s32 *sensor_settings = sd->sensor_priv;
  259. PDEBUG(D_V4L2, "Setting gain to %d", val);
  260. sensor_settings[GAIN_IDX] = val;
  261. err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
  262. return err;
  263. }
  264. static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
  265. __s32 *val)
  266. {
  267. struct sd *sd = (struct sd *) gspca_dev;
  268. s32 *sensor_settings = sd->sensor_priv;
  269. *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
  270. return 0;
  271. }
  272. static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
  273. __s32 val)
  274. {
  275. int err;
  276. u8 i2c_data;
  277. struct sd *sd = (struct sd *) gspca_dev;
  278. s32 *sensor_settings = sd->sensor_priv;
  279. PDEBUG(D_V4L2, "Set auto white balance to %d", val);
  280. sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
  281. err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
  282. if (err < 0)
  283. return err;
  284. i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
  285. err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
  286. return err;
  287. }
  288. static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
  289. {
  290. struct sd *sd = (struct sd *) gspca_dev;
  291. s32 *sensor_settings = sd->sensor_priv;
  292. *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
  293. PDEBUG(D_V4L2, "Read auto gain control %d", *val);
  294. return 0;
  295. }
  296. static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
  297. {
  298. int err;
  299. u8 i2c_data;
  300. struct sd *sd = (struct sd *) gspca_dev;
  301. s32 *sensor_settings = sd->sensor_priv;
  302. PDEBUG(D_V4L2, "Set auto gain control to %d", val);
  303. sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
  304. err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
  305. if (err < 0)
  306. return err;
  307. i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
  308. return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
  309. }
  310. static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
  311. {
  312. struct sd *sd = (struct sd *) gspca_dev;
  313. s32 *sensor_settings = sd->sensor_priv;
  314. *val = sensor_settings[AUTO_EXPOSURE_IDX];
  315. PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
  316. return 0;
  317. }
  318. static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
  319. __s32 val)
  320. {
  321. int err;
  322. u8 i2c_data;
  323. struct sd *sd = (struct sd *) gspca_dev;
  324. s32 *sensor_settings = sd->sensor_priv;
  325. PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
  326. sensor_settings[AUTO_EXPOSURE_IDX] = val;
  327. err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
  328. if (err < 0)
  329. return err;
  330. i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
  331. return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
  332. }
  333. static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
  334. {
  335. struct sd *sd = (struct sd *) gspca_dev;
  336. s32 *sensor_settings = sd->sensor_priv;
  337. *val = sensor_settings[HFLIP_IDX];
  338. PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
  339. return 0;
  340. }
  341. static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
  342. {
  343. int err;
  344. u8 i2c_data;
  345. struct sd *sd = (struct sd *) gspca_dev;
  346. s32 *sensor_settings = sd->sensor_priv;
  347. PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
  348. sensor_settings[HFLIP_IDX] = val;
  349. i2c_data = ((val & 0x01) << 5) |
  350. (sensor_settings[VFLIP_IDX] << 4);
  351. err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
  352. return err;
  353. }
  354. static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
  355. {
  356. struct sd *sd = (struct sd *) gspca_dev;
  357. s32 *sensor_settings = sd->sensor_priv;
  358. *val = sensor_settings[VFLIP_IDX];
  359. PDEBUG(D_V4L2, "Read vertical flip %d", *val);
  360. return 0;
  361. }
  362. static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
  363. {
  364. int err;
  365. u8 i2c_data;
  366. struct sd *sd = (struct sd *) gspca_dev;
  367. s32 *sensor_settings = sd->sensor_priv;
  368. PDEBUG(D_V4L2, "Set vertical flip to %d", val);
  369. sensor_settings[VFLIP_IDX] = val;
  370. i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
  371. err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
  372. if (err < 0)
  373. return err;
  374. /* When vflip is toggled we need to readjust the bridge hsync/vsync */
  375. if (gspca_dev->streaming)
  376. err = ov7660_start(sd);
  377. return err;
  378. }
  379. static void ov7660_dump_registers(struct sd *sd)
  380. {
  381. int address;
  382. info("Dumping the ov7660 register state");
  383. for (address = 0; address < 0xa9; address++) {
  384. u8 value;
  385. m5602_read_sensor(sd, address, &value, 1);
  386. info("register 0x%x contains 0x%x",
  387. address, value);
  388. }
  389. info("ov7660 register state dump complete");
  390. info("Probing for which registers that are read/write");
  391. for (address = 0; address < 0xff; address++) {
  392. u8 old_value, ctrl_value;
  393. u8 test_value[2] = {0xff, 0xff};
  394. m5602_read_sensor(sd, address, &old_value, 1);
  395. m5602_write_sensor(sd, address, test_value, 1);
  396. m5602_read_sensor(sd, address, &ctrl_value, 1);
  397. if (ctrl_value == test_value[0])
  398. info("register 0x%x is writeable", address);
  399. else
  400. info("register 0x%x is read only", address);
  401. /* Restore original value */
  402. m5602_write_sensor(sd, address, &old_value, 1);
  403. }
  404. }