m5602_po1030.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. * Driver for the po1030 sensor
  3. *
  4. * Copyright (c) 2008 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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19. #include "m5602_po1030.h"
  20. static int po1030_s_ctrl(struct v4l2_ctrl *ctrl);
  21. static void po1030_dump_registers(struct sd *sd);
  22. static struct v4l2_pix_format po1030_modes[] = {
  23. {
  24. 640,
  25. 480,
  26. V4L2_PIX_FMT_SBGGR8,
  27. V4L2_FIELD_NONE,
  28. .sizeimage = 640 * 480,
  29. .bytesperline = 640,
  30. .colorspace = V4L2_COLORSPACE_SRGB,
  31. .priv = 2
  32. }
  33. };
  34. static const struct v4l2_ctrl_ops po1030_ctrl_ops = {
  35. .s_ctrl = po1030_s_ctrl,
  36. };
  37. static const struct v4l2_ctrl_config po1030_greenbal_cfg = {
  38. .ops = &po1030_ctrl_ops,
  39. .id = M5602_V4L2_CID_GREEN_BALANCE,
  40. .name = "Green Balance",
  41. .type = V4L2_CTRL_TYPE_INTEGER,
  42. .min = 0,
  43. .max = 255,
  44. .step = 1,
  45. .def = PO1030_GREEN_GAIN_DEFAULT,
  46. .flags = V4L2_CTRL_FLAG_SLIDER,
  47. };
  48. int po1030_probe(struct sd *sd)
  49. {
  50. u8 dev_id_h = 0, i;
  51. struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
  52. if (force_sensor) {
  53. if (force_sensor == PO1030_SENSOR) {
  54. pr_info("Forcing a %s sensor\n", po1030.name);
  55. goto sensor_found;
  56. }
  57. /* If we want to force another sensor, don't try to probe this
  58. * one */
  59. return -ENODEV;
  60. }
  61. PDEBUG(D_PROBE, "Probing for a po1030 sensor");
  62. /* Run the pre-init to actually probe the unit */
  63. for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
  64. u8 data = preinit_po1030[i][2];
  65. if (preinit_po1030[i][0] == SENSOR)
  66. m5602_write_sensor(sd,
  67. preinit_po1030[i][1], &data, 1);
  68. else
  69. m5602_write_bridge(sd, preinit_po1030[i][1], data);
  70. }
  71. if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
  72. return -ENODEV;
  73. if (dev_id_h == 0x30) {
  74. pr_info("Detected a po1030 sensor\n");
  75. goto sensor_found;
  76. }
  77. return -ENODEV;
  78. sensor_found:
  79. sd->gspca_dev.cam.cam_mode = po1030_modes;
  80. sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
  81. return 0;
  82. }
  83. int po1030_init(struct sd *sd)
  84. {
  85. int i, err = 0;
  86. /* Init the sensor */
  87. for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
  88. u8 data[2] = {0x00, 0x00};
  89. switch (init_po1030[i][0]) {
  90. case BRIDGE:
  91. err = m5602_write_bridge(sd,
  92. init_po1030[i][1],
  93. init_po1030[i][2]);
  94. break;
  95. case SENSOR:
  96. data[0] = init_po1030[i][2];
  97. err = m5602_write_sensor(sd,
  98. init_po1030[i][1], data, 1);
  99. break;
  100. default:
  101. pr_info("Invalid stream command, exiting init\n");
  102. return -EINVAL;
  103. }
  104. }
  105. if (err < 0)
  106. return err;
  107. if (dump_sensor)
  108. po1030_dump_registers(sd);
  109. return 0;
  110. }
  111. int po1030_init_controls(struct sd *sd)
  112. {
  113. struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
  114. sd->gspca_dev.vdev.ctrl_handler = hdl;
  115. v4l2_ctrl_handler_init(hdl, 9);
  116. sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
  117. V4L2_CID_AUTO_WHITE_BALANCE,
  118. 0, 1, 1, 0);
  119. sd->green_bal = v4l2_ctrl_new_custom(hdl, &po1030_greenbal_cfg, NULL);
  120. sd->red_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
  121. V4L2_CID_RED_BALANCE, 0, 255, 1,
  122. PO1030_RED_GAIN_DEFAULT);
  123. sd->blue_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
  124. V4L2_CID_BLUE_BALANCE, 0, 255, 1,
  125. PO1030_BLUE_GAIN_DEFAULT);
  126. sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &po1030_ctrl_ops,
  127. V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_MANUAL);
  128. sd->expo = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_EXPOSURE,
  129. 0, 0x2ff, 1, PO1030_EXPOSURE_DEFAULT);
  130. sd->gain = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_GAIN, 0,
  131. 0x4f, 1, PO1030_GLOBAL_GAIN_DEFAULT);
  132. sd->hflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_HFLIP,
  133. 0, 1, 1, 0);
  134. sd->vflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_VFLIP,
  135. 0, 1, 1, 0);
  136. if (hdl->error) {
  137. pr_err("Could not initialize controls\n");
  138. return hdl->error;
  139. }
  140. v4l2_ctrl_auto_cluster(4, &sd->auto_white_bal, 0, false);
  141. v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false);
  142. v4l2_ctrl_cluster(2, &sd->hflip);
  143. return 0;
  144. }
  145. int po1030_start(struct sd *sd)
  146. {
  147. struct cam *cam = &sd->gspca_dev.cam;
  148. int i, err = 0;
  149. int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
  150. int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
  151. int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
  152. u8 data;
  153. switch (width) {
  154. case 320:
  155. data = PO1030_SUBSAMPLING;
  156. err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
  157. if (err < 0)
  158. return err;
  159. data = ((width + 3) >> 8) & 0xff;
  160. err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
  161. if (err < 0)
  162. return err;
  163. data = (width + 3) & 0xff;
  164. err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
  165. if (err < 0)
  166. return err;
  167. data = ((height + 1) >> 8) & 0xff;
  168. err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
  169. if (err < 0)
  170. return err;
  171. data = (height + 1) & 0xff;
  172. err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
  173. height += 6;
  174. width -= 1;
  175. break;
  176. case 640:
  177. data = 0;
  178. err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
  179. if (err < 0)
  180. return err;
  181. data = ((width + 7) >> 8) & 0xff;
  182. err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
  183. if (err < 0)
  184. return err;
  185. data = (width + 7) & 0xff;
  186. err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
  187. if (err < 0)
  188. return err;
  189. data = ((height + 3) >> 8) & 0xff;
  190. err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
  191. if (err < 0)
  192. return err;
  193. data = (height + 3) & 0xff;
  194. err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
  195. height += 12;
  196. width -= 2;
  197. break;
  198. }
  199. err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
  200. if (err < 0)
  201. return err;
  202. err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
  203. if (err < 0)
  204. return err;
  205. err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
  206. if (err < 0)
  207. return err;
  208. err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
  209. if (err < 0)
  210. return err;
  211. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
  212. ((ver_offs >> 8) & 0xff));
  213. if (err < 0)
  214. return err;
  215. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
  216. if (err < 0)
  217. return err;
  218. for (i = 0; i < 2 && !err; i++)
  219. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
  220. if (err < 0)
  221. return err;
  222. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
  223. if (err < 0)
  224. return err;
  225. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
  226. if (err < 0)
  227. return err;
  228. for (i = 0; i < 2 && !err; i++)
  229. err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
  230. for (i = 0; i < 2 && !err; i++)
  231. err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
  232. for (i = 0; i < 2 && !err; i++)
  233. err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
  234. if (err < 0)
  235. return err;
  236. err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
  237. if (err < 0)
  238. return err;
  239. err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
  240. if (err < 0)
  241. return err;
  242. err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
  243. return err;
  244. }
  245. static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
  246. {
  247. struct sd *sd = (struct sd *) gspca_dev;
  248. u8 i2c_data;
  249. int err;
  250. PDEBUG(D_CONF, "Set exposure to %d", val & 0xffff);
  251. i2c_data = ((val & 0xff00) >> 8);
  252. PDEBUG(D_CONF, "Set exposure to high byte to 0x%x",
  253. i2c_data);
  254. err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
  255. &i2c_data, 1);
  256. if (err < 0)
  257. return err;
  258. i2c_data = (val & 0xff);
  259. PDEBUG(D_CONF, "Set exposure to low byte to 0x%x",
  260. i2c_data);
  261. err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
  262. &i2c_data, 1);
  263. return err;
  264. }
  265. static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  266. {
  267. struct sd *sd = (struct sd *) gspca_dev;
  268. u8 i2c_data;
  269. int err;
  270. i2c_data = val & 0xff;
  271. PDEBUG(D_CONF, "Set global gain to %d", i2c_data);
  272. err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
  273. &i2c_data, 1);
  274. return err;
  275. }
  276. static int po1030_set_hvflip(struct gspca_dev *gspca_dev)
  277. {
  278. struct sd *sd = (struct sd *) gspca_dev;
  279. u8 i2c_data;
  280. int err;
  281. PDEBUG(D_CONF, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val);
  282. err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
  283. if (err < 0)
  284. return err;
  285. i2c_data = (0x3f & i2c_data) | (sd->hflip->val << 7) |
  286. (sd->vflip->val << 6);
  287. err = m5602_write_sensor(sd, PO1030_CONTROL2,
  288. &i2c_data, 1);
  289. return err;
  290. }
  291. static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
  292. {
  293. struct sd *sd = (struct sd *) gspca_dev;
  294. u8 i2c_data;
  295. int err;
  296. i2c_data = val & 0xff;
  297. PDEBUG(D_CONF, "Set red gain to %d", i2c_data);
  298. err = m5602_write_sensor(sd, PO1030_RED_GAIN,
  299. &i2c_data, 1);
  300. return err;
  301. }
  302. static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
  303. {
  304. struct sd *sd = (struct sd *) gspca_dev;
  305. u8 i2c_data;
  306. int err;
  307. i2c_data = val & 0xff;
  308. PDEBUG(D_CONF, "Set blue gain to %d", i2c_data);
  309. err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
  310. &i2c_data, 1);
  311. return err;
  312. }
  313. static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
  314. {
  315. struct sd *sd = (struct sd *) gspca_dev;
  316. u8 i2c_data;
  317. int err;
  318. i2c_data = val & 0xff;
  319. PDEBUG(D_CONF, "Set green gain to %d", i2c_data);
  320. err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
  321. &i2c_data, 1);
  322. if (err < 0)
  323. return err;
  324. return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
  325. &i2c_data, 1);
  326. }
  327. static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
  328. __s32 val)
  329. {
  330. struct sd *sd = (struct sd *) gspca_dev;
  331. u8 i2c_data;
  332. int err;
  333. err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
  334. if (err < 0)
  335. return err;
  336. PDEBUG(D_CONF, "Set auto white balance to %d", val);
  337. i2c_data = (i2c_data & 0xfe) | (val & 0x01);
  338. err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
  339. return err;
  340. }
  341. static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
  342. __s32 val)
  343. {
  344. struct sd *sd = (struct sd *) gspca_dev;
  345. u8 i2c_data;
  346. int err;
  347. err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
  348. if (err < 0)
  349. return err;
  350. PDEBUG(D_CONF, "Set auto exposure to %d", val);
  351. val = (val == V4L2_EXPOSURE_AUTO);
  352. i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
  353. return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
  354. }
  355. void po1030_disconnect(struct sd *sd)
  356. {
  357. sd->sensor = NULL;
  358. }
  359. static int po1030_s_ctrl(struct v4l2_ctrl *ctrl)
  360. {
  361. struct gspca_dev *gspca_dev =
  362. container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
  363. struct sd *sd = (struct sd *) gspca_dev;
  364. int err;
  365. if (!gspca_dev->streaming)
  366. return 0;
  367. switch (ctrl->id) {
  368. case V4L2_CID_AUTO_WHITE_BALANCE:
  369. err = po1030_set_auto_white_balance(gspca_dev, ctrl->val);
  370. if (err || ctrl->val)
  371. return err;
  372. err = po1030_set_green_balance(gspca_dev, sd->green_bal->val);
  373. if (err)
  374. return err;
  375. err = po1030_set_red_balance(gspca_dev, sd->red_bal->val);
  376. if (err)
  377. return err;
  378. err = po1030_set_blue_balance(gspca_dev, sd->blue_bal->val);
  379. break;
  380. case V4L2_CID_EXPOSURE_AUTO:
  381. err = po1030_set_auto_exposure(gspca_dev, ctrl->val);
  382. if (err || ctrl->val == V4L2_EXPOSURE_AUTO)
  383. return err;
  384. err = po1030_set_exposure(gspca_dev, sd->expo->val);
  385. break;
  386. case V4L2_CID_GAIN:
  387. err = po1030_set_gain(gspca_dev, ctrl->val);
  388. break;
  389. case V4L2_CID_HFLIP:
  390. err = po1030_set_hvflip(gspca_dev);
  391. break;
  392. default:
  393. return -EINVAL;
  394. }
  395. return err;
  396. }
  397. static void po1030_dump_registers(struct sd *sd)
  398. {
  399. int address;
  400. u8 value = 0;
  401. pr_info("Dumping the po1030 sensor core registers\n");
  402. for (address = 0; address < 0x7f; address++) {
  403. m5602_read_sensor(sd, address, &value, 1);
  404. pr_info("register 0x%x contains 0x%x\n", address, value);
  405. }
  406. pr_info("po1030 register state dump complete\n");
  407. pr_info("Probing for which registers that are read/write\n");
  408. for (address = 0; address < 0xff; address++) {
  409. u8 old_value, ctrl_value;
  410. u8 test_value[2] = {0xff, 0xff};
  411. m5602_read_sensor(sd, address, &old_value, 1);
  412. m5602_write_sensor(sd, address, test_value, 1);
  413. m5602_read_sensor(sd, address, &ctrl_value, 1);
  414. if (ctrl_value == test_value[0])
  415. pr_info("register 0x%x is writeable\n", address);
  416. else
  417. pr_info("register 0x%x is read only\n", address);
  418. /* Restore original value */
  419. m5602_write_sensor(sd, address, &old_value, 1);
  420. }
  421. }