m5602_mt9m111.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * Driver for the mt9m111 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. #include "m5602_mt9m111.h"
  19. int mt9m111_probe(struct sd *sd)
  20. {
  21. u8 data[2] = {0x00, 0x00};
  22. int i;
  23. if (force_sensor) {
  24. if (force_sensor == MT9M111_SENSOR) {
  25. info("Forcing a %s sensor", mt9m111.name);
  26. goto sensor_found;
  27. }
  28. /* If we want to force another sensor, don't try to probe this
  29. * one */
  30. return -ENODEV;
  31. }
  32. info("Probing for a mt9m111 sensor");
  33. /* Do the preinit */
  34. for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
  35. if (preinit_mt9m111[i][0] == BRIDGE) {
  36. m5602_write_bridge(sd,
  37. preinit_mt9m111[i][1],
  38. preinit_mt9m111[i][2]);
  39. } else {
  40. data[0] = preinit_mt9m111[i][2];
  41. data[1] = preinit_mt9m111[i][3];
  42. mt9m111_write_sensor(sd,
  43. preinit_mt9m111[i][1], data, 2);
  44. }
  45. }
  46. if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
  47. return -ENODEV;
  48. if ((data[0] == 0x14) && (data[1] == 0x3a)) {
  49. info("Detected a mt9m111 sensor");
  50. goto sensor_found;
  51. }
  52. return -ENODEV;
  53. sensor_found:
  54. sd->gspca_dev.cam.cam_mode = mt9m111.modes;
  55. sd->gspca_dev.cam.nmodes = mt9m111.nmodes;
  56. sd->desc->ctrls = mt9m111.ctrls;
  57. sd->desc->nctrls = mt9m111.nctrls;
  58. return 0;
  59. }
  60. int mt9m111_init(struct sd *sd)
  61. {
  62. int i, err = 0;
  63. /* Init the sensor */
  64. for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) {
  65. u8 data[2];
  66. if (init_mt9m111[i][0] == BRIDGE) {
  67. err = m5602_write_bridge(sd,
  68. init_mt9m111[i][1],
  69. init_mt9m111[i][2]);
  70. } else {
  71. data[0] = init_mt9m111[i][2];
  72. data[1] = init_mt9m111[i][3];
  73. err = mt9m111_write_sensor(sd,
  74. init_mt9m111[i][1], data, 2);
  75. }
  76. }
  77. if (dump_sensor)
  78. mt9m111_dump_registers(sd);
  79. return (err < 0) ? err : 0;
  80. }
  81. int mt9m111_power_down(struct sd *sd)
  82. {
  83. return 0;
  84. }
  85. int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
  86. {
  87. int err;
  88. u8 data[2] = {0x00, 0x00};
  89. struct sd *sd = (struct sd *) gspca_dev;
  90. err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
  91. data, 2);
  92. *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
  93. PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
  94. return (err < 0) ? err : 0;
  95. }
  96. int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
  97. {
  98. int err;
  99. u8 data[2] = {0x00, 0x00};
  100. struct sd *sd = (struct sd *) gspca_dev;
  101. PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
  102. /* Set the correct page map */
  103. err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
  104. if (err < 0)
  105. goto out;
  106. err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
  107. if (err < 0)
  108. goto out;
  109. data[0] = (data[0] & 0xfe) | val;
  110. err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
  111. data, 2);
  112. out:
  113. return (err < 0) ? err : 0;
  114. }
  115. int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
  116. {
  117. int err;
  118. u8 data[2] = {0x00, 0x00};
  119. struct sd *sd = (struct sd *) gspca_dev;
  120. err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
  121. data, 2);
  122. *val = data[0] & MT9M111_RMB_MIRROR_COLS;
  123. PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
  124. return (err < 0) ? err : 0;
  125. }
  126. int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
  127. {
  128. int err;
  129. u8 data[2] = {0x00, 0x00};
  130. struct sd *sd = (struct sd *) gspca_dev;
  131. PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
  132. /* Set the correct page map */
  133. err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
  134. if (err < 0)
  135. goto out;
  136. err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
  137. if (err < 0)
  138. goto out;
  139. data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
  140. err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
  141. data, 2);
  142. out:
  143. return (err < 0) ? err : 0;
  144. }
  145. int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
  146. {
  147. int err, tmp;
  148. u8 data[2] = {0x00, 0x00};
  149. struct sd *sd = (struct sd *) gspca_dev;
  150. err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
  151. tmp = ((data[1] << 8) | data[0]);
  152. *val = ((tmp & (1 << 10)) * 2) |
  153. ((tmp & (1 << 9)) * 2) |
  154. ((tmp & (1 << 8)) * 2) |
  155. (tmp & 0x7f);
  156. PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
  157. return (err < 0) ? err : 0;
  158. }
  159. int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  160. {
  161. int err, tmp;
  162. u8 data[2] = {0x00, 0x00};
  163. struct sd *sd = (struct sd *) gspca_dev;
  164. /* Set the correct page map */
  165. err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
  166. if (err < 0)
  167. goto out;
  168. if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
  169. return -EINVAL;
  170. if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
  171. (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
  172. tmp = (1 << 10) | (val << 9) |
  173. (val << 8) | (val / 8);
  174. else if ((val >= INITIAL_MAX_GAIN * 2) &&
  175. (val < INITIAL_MAX_GAIN * 2 * 2))
  176. tmp = (1 << 9) | (1 << 8) | (val / 4);
  177. else if ((val >= INITIAL_MAX_GAIN) &&
  178. (val < INITIAL_MAX_GAIN * 2))
  179. tmp = (1 << 8) | (val / 2);
  180. else
  181. tmp = val;
  182. data[1] = (tmp & 0xff00) >> 8;
  183. data[0] = (tmp & 0xff);
  184. PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
  185. data[1], data[0]);
  186. err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
  187. data, 2);
  188. out:
  189. return (err < 0) ? err : 0;
  190. }
  191. int mt9m111_read_sensor(struct sd *sd, const u8 address,
  192. u8 *i2c_data, const u8 len) {
  193. int err, i;
  194. do {
  195. err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
  196. } while ((*i2c_data & I2C_BUSY) && !err);
  197. if (err < 0)
  198. goto out;
  199. err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
  200. sd->sensor->i2c_slave_id);
  201. if (err < 0)
  202. goto out;
  203. err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
  204. if (err < 0)
  205. goto out;
  206. err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
  207. if (err < 0)
  208. goto out;
  209. for (i = 0; i < len && !err; i++) {
  210. err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
  211. PDEBUG(DBG_TRACE, "Reading sensor register "
  212. "0x%x contains 0x%x ", address, *i2c_data);
  213. }
  214. out:
  215. return (err < 0) ? err : 0;
  216. }
  217. int mt9m111_write_sensor(struct sd *sd, const u8 address,
  218. u8 *i2c_data, const u8 len)
  219. {
  220. int err, i;
  221. u8 *p;
  222. struct usb_device *udev = sd->gspca_dev.dev;
  223. __u8 *buf = sd->gspca_dev.usb_buf;
  224. /* No sensor with a data width larger
  225. than 16 bits has yet been seen, nor with 0 :p*/
  226. if (len > 2 || !len)
  227. return -EINVAL;
  228. memcpy(buf, sensor_urb_skeleton,
  229. sizeof(sensor_urb_skeleton));
  230. buf[11] = sd->sensor->i2c_slave_id;
  231. buf[15] = address;
  232. p = buf + 16;
  233. /* Copy a four byte write sequence for each byte to be written to */
  234. for (i = 0; i < len; i++) {
  235. memcpy(p, sensor_urb_skeleton + 16, 4);
  236. p[3] = i2c_data[i];
  237. p += 4;
  238. PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
  239. address, i2c_data[i]);
  240. }
  241. /* Copy the tailer */
  242. memcpy(p, sensor_urb_skeleton + 20, 4);
  243. /* Set the total length */
  244. p[3] = 0x10 + len;
  245. err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  246. 0x04, 0x40, 0x19,
  247. 0x0000, buf,
  248. 20 + len * 4, M5602_URB_MSG_TIMEOUT);
  249. return (err < 0) ? err : 0;
  250. }
  251. void mt9m111_dump_registers(struct sd *sd)
  252. {
  253. u8 address, value[2] = {0x00, 0x00};
  254. info("Dumping the mt9m111 register state");
  255. info("Dumping the mt9m111 sensor core registers");
  256. value[1] = MT9M111_SENSOR_CORE;
  257. mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
  258. for (address = 0; address < 0xff; address++) {
  259. mt9m111_read_sensor(sd, address, value, 2);
  260. info("register 0x%x contains 0x%x%x",
  261. address, value[0], value[1]);
  262. }
  263. info("Dumping the mt9m111 color pipeline registers");
  264. value[1] = MT9M111_COLORPIPE;
  265. mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
  266. for (address = 0; address < 0xff; address++) {
  267. mt9m111_read_sensor(sd, address, value, 2);
  268. info("register 0x%x contains 0x%x%x",
  269. address, value[0], value[1]);
  270. }
  271. info("Dumping the mt9m111 camera control registers");
  272. value[1] = MT9M111_CAMERA_CONTROL;
  273. mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
  274. for (address = 0; address < 0xff; address++) {
  275. mt9m111_read_sensor(sd, address, value, 2);
  276. info("register 0x%x contains 0x%x%x",
  277. address, value[0], value[1]);
  278. }
  279. info("mt9m111 register state dump complete");
  280. }