m5602_po1030.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Driver for the po1030 sensor
  3. *
  4. * Copyright (c) 2008 Erik Andren
  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_po1030.h"
  19. int po1030_probe(struct sd *sd)
  20. {
  21. u8 prod_id = 0, ver_id = 0, i;
  22. if (force_sensor) {
  23. if (force_sensor == PO1030_SENSOR) {
  24. info("Forcing a %s sensor", po1030.name);
  25. goto sensor_found;
  26. }
  27. /* If we want to force another sensor, don't try to probe this
  28. * one */
  29. return -ENODEV;
  30. }
  31. info("Probing for a po1030 sensor");
  32. /* Run the pre-init to actually probe the unit */
  33. for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
  34. u8 data = preinit_po1030[i][2];
  35. if (preinit_po1030[i][0] == SENSOR)
  36. po1030_write_sensor(sd,
  37. preinit_po1030[i][1], &data, 1);
  38. else
  39. m5602_write_bridge(sd, preinit_po1030[i][1], data);
  40. }
  41. if (po1030_read_sensor(sd, 0x3, &prod_id, 1))
  42. return -ENODEV;
  43. if (po1030_read_sensor(sd, 0x4, &ver_id, 1))
  44. return -ENODEV;
  45. if ((prod_id == 0x02) && (ver_id == 0xef)) {
  46. info("Detected a po1030 sensor");
  47. goto sensor_found;
  48. }
  49. return -ENODEV;
  50. sensor_found:
  51. sd->gspca_dev.cam.cam_mode = po1030.modes;
  52. sd->gspca_dev.cam.nmodes = po1030.nmodes;
  53. return 0;
  54. }
  55. int po1030_read_sensor(struct sd *sd, const u8 address,
  56. u8 *i2c_data, const u8 len)
  57. {
  58. int err, i;
  59. do {
  60. err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
  61. } while ((*i2c_data & I2C_BUSY) && !err);
  62. m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
  63. sd->sensor->i2c_slave_id);
  64. m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
  65. m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
  66. m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
  67. for (i = 0; i < len; i++) {
  68. err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
  69. PDEBUG(DBG_TRACE, "Reading sensor register "
  70. "0x%x containing 0x%x ", address, *i2c_data);
  71. }
  72. return (err < 0) ? err : 0;
  73. }
  74. int po1030_write_sensor(struct sd *sd, const u8 address,
  75. u8 *i2c_data, const u8 len)
  76. {
  77. int err, i;
  78. u8 *p;
  79. struct usb_device *udev = sd->gspca_dev.dev;
  80. __u8 *buf = sd->gspca_dev.usb_buf;
  81. /* The po1030 only supports one byte writes */
  82. if (len > 1 || !len)
  83. return -EINVAL;
  84. memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
  85. buf[11] = sd->sensor->i2c_slave_id;
  86. buf[15] = address;
  87. p = buf + 16;
  88. /* Copy a four byte write sequence for each byte to be written to */
  89. for (i = 0; i < len; i++) {
  90. memcpy(p, sensor_urb_skeleton + 16, 4);
  91. p[3] = i2c_data[i];
  92. p += 4;
  93. PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
  94. address, i2c_data[i]);
  95. }
  96. /* Copy the footer */
  97. memcpy(p, sensor_urb_skeleton + 20, 4);
  98. /* Set the total length */
  99. p[3] = 0x10 + len;
  100. err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  101. 0x04, 0x40, 0x19,
  102. 0x0000, buf,
  103. 20 + len * 4, M5602_URB_MSG_TIMEOUT);
  104. return (err < 0) ? err : 0;
  105. }
  106. int po1030_init(struct sd *sd)
  107. {
  108. int i, err = 0;
  109. /* Init the sensor */
  110. for (i = 0; i < ARRAY_SIZE(init_po1030); i++) {
  111. u8 data[2] = {0x00, 0x00};
  112. switch (init_po1030[i][0]) {
  113. case BRIDGE:
  114. err = m5602_write_bridge(sd,
  115. init_po1030[i][1],
  116. init_po1030[i][2]);
  117. break;
  118. case SENSOR:
  119. data[0] = init_po1030[i][2];
  120. err = po1030_write_sensor(sd,
  121. init_po1030[i][1], data, 1);
  122. break;
  123. case SENSOR_LONG:
  124. data[0] = init_po1030[i][2];
  125. data[1] = init_po1030[i][3];
  126. err = po1030_write_sensor(sd,
  127. init_po1030[i][1], data, 2);
  128. break;
  129. default:
  130. info("Invalid stream command, exiting init");
  131. return -EINVAL;
  132. }
  133. }
  134. if (dump_sensor)
  135. po1030_dump_registers(sd);
  136. return (err < 0) ? err : 0;
  137. }
  138. int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
  139. {
  140. struct sd *sd = (struct sd *) gspca_dev;
  141. u8 i2c_data;
  142. int err;
  143. err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H,
  144. &i2c_data, 1);
  145. if (err < 0)
  146. goto out;
  147. *val = (i2c_data << 8);
  148. err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M,
  149. &i2c_data, 1);
  150. *val |= i2c_data;
  151. PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val);
  152. out:
  153. return (err < 0) ? err : 0;
  154. }
  155. int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
  156. {
  157. struct sd *sd = (struct sd *) gspca_dev;
  158. u8 i2c_data;
  159. int err;
  160. PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff);
  161. i2c_data = ((val & 0xff00) >> 8);
  162. PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x",
  163. i2c_data);
  164. err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H,
  165. &i2c_data, 1);
  166. if (err < 0)
  167. goto out;
  168. i2c_data = (val & 0xff);
  169. PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x",
  170. i2c_data);
  171. err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
  172. &i2c_data, 1);
  173. out:
  174. return (err < 0) ? err : 0;
  175. }
  176. int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
  177. {
  178. struct sd *sd = (struct sd *) gspca_dev;
  179. u8 i2c_data;
  180. int err;
  181. err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
  182. &i2c_data, 1);
  183. *val = i2c_data;
  184. PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val);
  185. return (err < 0) ? err : 0;
  186. }
  187. int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  188. {
  189. struct sd *sd = (struct sd *) gspca_dev;
  190. u8 i2c_data;
  191. int err;
  192. i2c_data = val & 0xff;
  193. PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data);
  194. err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
  195. &i2c_data, 1);
  196. return (err < 0) ? err : 0;
  197. }
  198. int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
  199. {
  200. struct sd *sd = (struct sd *) gspca_dev;
  201. u8 i2c_data;
  202. int err;
  203. err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
  204. &i2c_data, 1);
  205. *val = i2c_data;
  206. PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
  207. return (err < 0) ? err : 0;
  208. }
  209. int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
  210. {
  211. struct sd *sd = (struct sd *) gspca_dev;
  212. u8 i2c_data;
  213. int err;
  214. i2c_data = val & 0xff;
  215. PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data);
  216. err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
  217. &i2c_data, 1);
  218. return (err < 0) ? err : 0;
  219. }
  220. int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
  221. {
  222. struct sd *sd = (struct sd *) gspca_dev;
  223. u8 i2c_data;
  224. int err;
  225. err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
  226. &i2c_data, 1);
  227. *val = i2c_data;
  228. PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
  229. return (err < 0) ? err : 0;
  230. }
  231. int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
  232. {
  233. struct sd *sd = (struct sd *) gspca_dev;
  234. u8 i2c_data;
  235. int err;
  236. i2c_data = val & 0xff;
  237. PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data);
  238. err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
  239. &i2c_data, 1);
  240. return (err < 0) ? err : 0;
  241. }
  242. int po1030_power_down(struct sd *sd)
  243. {
  244. return 0;
  245. }
  246. void po1030_dump_registers(struct sd *sd)
  247. {
  248. int address;
  249. u8 value = 0;
  250. info("Dumping the po1030 sensor core registers");
  251. for (address = 0; address < 0x7f; address++) {
  252. po1030_read_sensor(sd, address, &value, 1);
  253. info("register 0x%x contains 0x%x",
  254. address, value);
  255. }
  256. info("po1030 register state dump complete");
  257. info("Probing for which registers that are read/write");
  258. for (address = 0; address < 0xff; address++) {
  259. u8 old_value, ctrl_value;
  260. u8 test_value[2] = {0xff, 0xff};
  261. po1030_read_sensor(sd, address, &old_value, 1);
  262. po1030_write_sensor(sd, address, test_value, 1);
  263. po1030_read_sensor(sd, address, &ctrl_value, 1);
  264. if (ctrl_value == test_value[0])
  265. info("register 0x%x is writeable", address);
  266. else
  267. info("register 0x%x is read only", address);
  268. /* Restore original value */
  269. po1030_write_sensor(sd, address, &old_value, 1);
  270. }
  271. }