ov534.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * ov534/ov772x gspca driver
  3. * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
  4. *
  5. * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
  6. * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
  7. * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #define MODULE_NAME "ov534"
  24. #include "gspca.h"
  25. #define OV534_REG_ADDRESS 0xf1 /* ? */
  26. #define OV534_REG_SUBADDR 0xf2
  27. #define OV534_REG_WRITE 0xf3
  28. #define OV534_REG_READ 0xf4
  29. #define OV534_REG_OPERATION 0xf5
  30. #define OV534_REG_STATUS 0xf6
  31. #define OV534_OP_WRITE_3 0x37
  32. #define OV534_OP_WRITE_2 0x33
  33. #define OV534_OP_READ_2 0xf9
  34. #define CTRL_TIMEOUT 500
  35. MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
  36. MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
  37. MODULE_LICENSE("GPL");
  38. /* global parameters */
  39. static int frame_rate;
  40. /* specific webcam descriptor */
  41. struct sd {
  42. struct gspca_dev gspca_dev; /* !! must be the first item */
  43. };
  44. /* V4L2 controls supported by the driver */
  45. static struct ctrl sd_ctrls[] = {
  46. };
  47. static struct v4l2_pix_format vga_mode[] = {
  48. {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
  49. .bytesperline = 640 * 2,
  50. .sizeimage = 640 * 480 * 2,
  51. .colorspace = V4L2_COLORSPACE_JPEG,
  52. .priv = 0},
  53. };
  54. static void ov534_reg_write(struct usb_device *udev, u16 reg, u8 val)
  55. {
  56. u8 data = val;
  57. int ret;
  58. PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
  59. ret = usb_control_msg(udev,
  60. usb_sndctrlpipe(udev, 0),
  61. 0x1,
  62. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  63. 0x0, reg, &data, 1, CTRL_TIMEOUT);
  64. if (ret < 0)
  65. PDEBUG(D_ERR, "write failed");
  66. }
  67. static u8 ov534_reg_read(struct usb_device *udev, u16 reg)
  68. {
  69. u8 data;
  70. int ret;
  71. ret = usb_control_msg(udev,
  72. usb_rcvctrlpipe(udev, 0),
  73. 0x1,
  74. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  75. 0x0, reg, &data, 1, CTRL_TIMEOUT);
  76. PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, data);
  77. if (ret < 0)
  78. PDEBUG(D_ERR, "read failed");
  79. return data;
  80. }
  81. static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u8 val)
  82. {
  83. u8 data;
  84. ov534_reg_write(udev, reg, val);
  85. data = ov534_reg_read(udev, reg);
  86. if (data != val) {
  87. PDEBUG(D_ERR | D_USBO,
  88. "unexpected result from read: 0x%02x != 0x%02x", val,
  89. data);
  90. }
  91. }
  92. /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
  93. * (direction and output)? */
  94. static void ov534_set_led(struct usb_device *udev, int status)
  95. {
  96. u8 data;
  97. PDEBUG(D_CONF, "led status: %d", status);
  98. data = ov534_reg_read(udev, 0x21);
  99. data |= 0x80;
  100. ov534_reg_write(udev, 0x21, data);
  101. data = ov534_reg_read(udev, 0x23);
  102. if (status)
  103. data |= 0x80;
  104. else
  105. data &= ~(0x80);
  106. ov534_reg_write(udev, 0x23, data);
  107. }
  108. static int sccb_check_status(struct usb_device *udev)
  109. {
  110. u8 data;
  111. int i;
  112. for (i = 0; i < 5; i++) {
  113. data = ov534_reg_read(udev, OV534_REG_STATUS);
  114. switch (data) {
  115. case 0x00:
  116. return 1;
  117. case 0x04:
  118. return 0;
  119. case 0x03:
  120. break;
  121. default:
  122. PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5\n",
  123. data, i + 1);
  124. }
  125. }
  126. return 0;
  127. }
  128. static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val)
  129. {
  130. PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
  131. ov534_reg_write(udev, OV534_REG_SUBADDR, reg);
  132. ov534_reg_write(udev, OV534_REG_WRITE, val);
  133. ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
  134. if (!sccb_check_status(udev))
  135. PDEBUG(D_ERR, "sccb_reg_write failed");
  136. }
  137. /* setup method */
  138. static void ov534_setup(struct usb_device *udev)
  139. {
  140. ov534_reg_verify_write(udev, 0xe7, 0x3a);
  141. ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
  142. ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
  143. ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
  144. ov534_reg_write(udev, OV534_REG_ADDRESS, 0x42);
  145. ov534_reg_verify_write(udev, 0xc2, 0x0c);
  146. ov534_reg_verify_write(udev, 0x88, 0xf8);
  147. ov534_reg_verify_write(udev, 0xc3, 0x69);
  148. ov534_reg_verify_write(udev, 0x89, 0xff);
  149. ov534_reg_verify_write(udev, 0x76, 0x03);
  150. ov534_reg_verify_write(udev, 0x92, 0x01);
  151. ov534_reg_verify_write(udev, 0x93, 0x18);
  152. ov534_reg_verify_write(udev, 0x94, 0x10);
  153. ov534_reg_verify_write(udev, 0x95, 0x10);
  154. ov534_reg_verify_write(udev, 0xe2, 0x00);
  155. ov534_reg_verify_write(udev, 0xe7, 0x3e);
  156. ov534_reg_write(udev, 0x1c, 0x0a);
  157. ov534_reg_write(udev, 0x1d, 0x22);
  158. ov534_reg_write(udev, 0x1d, 0x06);
  159. ov534_reg_verify_write(udev, 0x96, 0x00);
  160. ov534_reg_write(udev, 0x97, 0x20);
  161. ov534_reg_write(udev, 0x97, 0x20);
  162. ov534_reg_write(udev, 0x97, 0x20);
  163. ov534_reg_write(udev, 0x97, 0x0a);
  164. ov534_reg_write(udev, 0x97, 0x3f);
  165. ov534_reg_write(udev, 0x97, 0x4a);
  166. ov534_reg_write(udev, 0x97, 0x20);
  167. ov534_reg_write(udev, 0x97, 0x15);
  168. ov534_reg_write(udev, 0x97, 0x0b);
  169. ov534_reg_verify_write(udev, 0x8e, 0x40);
  170. ov534_reg_verify_write(udev, 0x1f, 0x81);
  171. ov534_reg_verify_write(udev, 0x34, 0x05);
  172. ov534_reg_verify_write(udev, 0xe3, 0x04);
  173. ov534_reg_verify_write(udev, 0x88, 0x00);
  174. ov534_reg_verify_write(udev, 0x89, 0x00);
  175. ov534_reg_verify_write(udev, 0x76, 0x00);
  176. ov534_reg_verify_write(udev, 0xe7, 0x2e);
  177. ov534_reg_verify_write(udev, 0x31, 0xf9);
  178. ov534_reg_verify_write(udev, 0x25, 0x42);
  179. ov534_reg_verify_write(udev, 0x21, 0xf0);
  180. ov534_reg_write(udev, 0x1c, 0x00);
  181. ov534_reg_write(udev, 0x1d, 0x40);
  182. ov534_reg_write(udev, 0x1d, 0x02);
  183. ov534_reg_write(udev, 0x1d, 0x00);
  184. ov534_reg_write(udev, 0x1d, 0x02);
  185. ov534_reg_write(udev, 0x1d, 0x57);
  186. ov534_reg_write(udev, 0x1d, 0xff);
  187. ov534_reg_verify_write(udev, 0x8d, 0x1c);
  188. ov534_reg_verify_write(udev, 0x8e, 0x80);
  189. ov534_reg_verify_write(udev, 0xe5, 0x04);
  190. ov534_set_led(udev, 1);
  191. sccb_reg_write(udev, 0x12, 0x80);
  192. sccb_reg_write(udev, 0x11, 0x01);
  193. sccb_reg_write(udev, 0x11, 0x01);
  194. sccb_reg_write(udev, 0x11, 0x01);
  195. sccb_reg_write(udev, 0x11, 0x01);
  196. sccb_reg_write(udev, 0x11, 0x01);
  197. sccb_reg_write(udev, 0x11, 0x01);
  198. sccb_reg_write(udev, 0x11, 0x01);
  199. sccb_reg_write(udev, 0x11, 0x01);
  200. sccb_reg_write(udev, 0x11, 0x01);
  201. sccb_reg_write(udev, 0x11, 0x01);
  202. sccb_reg_write(udev, 0x11, 0x01);
  203. ov534_set_led(udev, 0);
  204. sccb_reg_write(udev, 0x3d, 0x03);
  205. sccb_reg_write(udev, 0x17, 0x26);
  206. sccb_reg_write(udev, 0x18, 0xa0);
  207. sccb_reg_write(udev, 0x19, 0x07);
  208. sccb_reg_write(udev, 0x1a, 0xf0);
  209. sccb_reg_write(udev, 0x32, 0x00);
  210. sccb_reg_write(udev, 0x29, 0xa0);
  211. sccb_reg_write(udev, 0x2c, 0xf0);
  212. sccb_reg_write(udev, 0x65, 0x20);
  213. sccb_reg_write(udev, 0x11, 0x01);
  214. sccb_reg_write(udev, 0x42, 0x7f);
  215. sccb_reg_write(udev, 0x63, 0xe0);
  216. sccb_reg_write(udev, 0x64, 0xff);
  217. sccb_reg_write(udev, 0x66, 0x00);
  218. sccb_reg_write(udev, 0x13, 0xf0);
  219. sccb_reg_write(udev, 0x0d, 0x41);
  220. sccb_reg_write(udev, 0x0f, 0xc5);
  221. sccb_reg_write(udev, 0x14, 0x11);
  222. ov534_set_led(udev, 1);
  223. sccb_reg_write(udev, 0x22, 0x7f);
  224. sccb_reg_write(udev, 0x23, 0x03);
  225. sccb_reg_write(udev, 0x24, 0x40);
  226. sccb_reg_write(udev, 0x25, 0x30);
  227. sccb_reg_write(udev, 0x26, 0xa1);
  228. sccb_reg_write(udev, 0x2a, 0x00);
  229. sccb_reg_write(udev, 0x2b, 0x00);
  230. sccb_reg_write(udev, 0x6b, 0xaa);
  231. sccb_reg_write(udev, 0x13, 0xff);
  232. ov534_set_led(udev, 0);
  233. sccb_reg_write(udev, 0x90, 0x05);
  234. sccb_reg_write(udev, 0x91, 0x01);
  235. sccb_reg_write(udev, 0x92, 0x03);
  236. sccb_reg_write(udev, 0x93, 0x00);
  237. sccb_reg_write(udev, 0x94, 0x60);
  238. sccb_reg_write(udev, 0x95, 0x3c);
  239. sccb_reg_write(udev, 0x96, 0x24);
  240. sccb_reg_write(udev, 0x97, 0x1e);
  241. sccb_reg_write(udev, 0x98, 0x62);
  242. sccb_reg_write(udev, 0x99, 0x80);
  243. sccb_reg_write(udev, 0x9a, 0x1e);
  244. sccb_reg_write(udev, 0x9b, 0x08);
  245. sccb_reg_write(udev, 0x9c, 0x20);
  246. sccb_reg_write(udev, 0x9e, 0x81);
  247. ov534_set_led(udev, 1);
  248. sccb_reg_write(udev, 0xa6, 0x04);
  249. sccb_reg_write(udev, 0x7e, 0x0c);
  250. sccb_reg_write(udev, 0x7f, 0x16);
  251. sccb_reg_write(udev, 0x80, 0x2a);
  252. sccb_reg_write(udev, 0x81, 0x4e);
  253. sccb_reg_write(udev, 0x82, 0x61);
  254. sccb_reg_write(udev, 0x83, 0x6f);
  255. sccb_reg_write(udev, 0x84, 0x7b);
  256. sccb_reg_write(udev, 0x85, 0x86);
  257. sccb_reg_write(udev, 0x86, 0x8e);
  258. sccb_reg_write(udev, 0x87, 0x97);
  259. sccb_reg_write(udev, 0x88, 0xa4);
  260. sccb_reg_write(udev, 0x89, 0xaf);
  261. sccb_reg_write(udev, 0x8a, 0xc5);
  262. sccb_reg_write(udev, 0x8b, 0xd7);
  263. sccb_reg_write(udev, 0x8c, 0xe8);
  264. sccb_reg_write(udev, 0x8d, 0x20);
  265. sccb_reg_write(udev, 0x0c, 0x90);
  266. ov534_reg_verify_write(udev, 0xc0, 0x50);
  267. ov534_reg_verify_write(udev, 0xc1, 0x3c);
  268. ov534_reg_verify_write(udev, 0xc2, 0x0c);
  269. ov534_set_led(udev, 1);
  270. sccb_reg_write(udev, 0x2b, 0x00);
  271. sccb_reg_write(udev, 0x22, 0x7f);
  272. sccb_reg_write(udev, 0x23, 0x03);
  273. sccb_reg_write(udev, 0x11, 0x01);
  274. sccb_reg_write(udev, 0x0c, 0xd0);
  275. sccb_reg_write(udev, 0x64, 0xff);
  276. sccb_reg_write(udev, 0x0d, 0x41);
  277. sccb_reg_write(udev, 0x14, 0x41);
  278. sccb_reg_write(udev, 0x0e, 0xcd);
  279. sccb_reg_write(udev, 0xac, 0xbf);
  280. sccb_reg_write(udev, 0x8e, 0x00);
  281. sccb_reg_write(udev, 0x0c, 0xd0);
  282. ov534_reg_write(udev, 0xe0, 0x09);
  283. ov534_set_led(udev, 0);
  284. }
  285. /* this function is called at probe time */
  286. static int sd_config(struct gspca_dev *gspca_dev,
  287. const struct usb_device_id *id)
  288. {
  289. struct cam *cam;
  290. cam = &gspca_dev->cam;
  291. cam->epaddr = 0x01;
  292. cam->cam_mode = vga_mode;
  293. cam->nmodes = ARRAY_SIZE(vga_mode);
  294. /*
  295. * On some architectures we need contiguous memory for urb buffers, and
  296. * in low memory situation 'sizeimage' can be too much.
  297. * 16kiB chunks should be available even when we are low in memory.
  298. * TODO: CHECK this description: is the problem arch-dependent or more
  299. * general?
  300. */
  301. cam->bulk_size = 16 * 1024;
  302. cam->bulk_nurbs = 2;
  303. PDEBUG(D_PROBE, "bulk_size = %d", cam->bulk_size);
  304. return 0;
  305. }
  306. /* this function is called at probe and resume time */
  307. static int sd_init(struct gspca_dev *gspca_dev)
  308. {
  309. int fr;
  310. ov534_setup(gspca_dev->dev);
  311. fr = frame_rate;
  312. switch (fr) {
  313. case 50:
  314. sccb_reg_write(gspca_dev->dev, 0x11, 0x01);
  315. sccb_reg_write(gspca_dev->dev, 0x0d, 0x41);
  316. ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02);
  317. break;
  318. case 40:
  319. sccb_reg_write(gspca_dev->dev, 0x11, 0x02);
  320. sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1);
  321. ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04);
  322. break;
  323. /* case 30: */
  324. default:
  325. fr = 30;
  326. sccb_reg_write(gspca_dev->dev, 0x11, 0x04);
  327. sccb_reg_write(gspca_dev->dev, 0x0d, 0x81);
  328. ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02);
  329. break;
  330. case 15:
  331. sccb_reg_write(gspca_dev->dev, 0x11, 0x03);
  332. sccb_reg_write(gspca_dev->dev, 0x0d, 0x41);
  333. ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04);
  334. break;
  335. }
  336. PDEBUG(D_PROBE, "frame_rate: %d", fr);
  337. return 0;
  338. }
  339. static int sd_start(struct gspca_dev *gspca_dev)
  340. {
  341. struct gspca_frame *frame;
  342. /* start streaming data */
  343. ov534_set_led(gspca_dev->dev, 1);
  344. ov534_reg_write(gspca_dev->dev, 0xe0, 0x00);
  345. frame = gspca_get_i_frame(gspca_dev);
  346. if (frame == NULL) {
  347. PDEBUG(D_ERR, "NULL frame!");
  348. return -1;
  349. }
  350. gspca_frame_add(gspca_dev, FIRST_PACKET, frame, gspca_dev->usb_buf, 0);
  351. return 0;
  352. }
  353. static void sd_stopN(struct gspca_dev *gspca_dev)
  354. {
  355. /* stop streaming data */
  356. ov534_reg_write(gspca_dev->dev, 0xe0, 0x09);
  357. ov534_set_led(gspca_dev->dev, 0);
  358. }
  359. static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
  360. __u8 *data, int len)
  361. {
  362. /*
  363. * The current camera setup doesn't stream the last pixel, so we set it
  364. * to a dummy value
  365. */
  366. __u8 last[4] = { 0, 0, 0, 0 };
  367. int framesize = frame->v4l2_buf.length;
  368. PDEBUG(D_PACK, "");
  369. PDEBUG(D_PACK, "** packet len = %d, framesize = %d", len, framesize);
  370. PDEBUG(D_PACK, "** frame->data_end - frame->data + len = %d",
  371. frame->data_end - frame->data + len);
  372. if (frame->data_end - frame->data + len == framesize - 4) {
  373. PDEBUG(D_PACK, " end of frame!");
  374. gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
  375. frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, last, 4);
  376. gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
  377. } else
  378. gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
  379. }
  380. /* sub-driver description */
  381. static const struct sd_desc sd_desc = {
  382. .name = MODULE_NAME,
  383. .ctrls = sd_ctrls,
  384. .nctrls = ARRAY_SIZE(sd_ctrls),
  385. .config = sd_config,
  386. .init = sd_init,
  387. .start = sd_start,
  388. .stopN = sd_stopN,
  389. .pkt_scan = sd_pkt_scan,
  390. };
  391. /* -- module initialisation -- */
  392. static const __devinitdata struct usb_device_id device_table[] = {
  393. {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
  394. {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
  395. {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
  396. {}
  397. };
  398. MODULE_DEVICE_TABLE(usb, device_table);
  399. /* -- device connect -- */
  400. static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
  401. {
  402. return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
  403. THIS_MODULE);
  404. }
  405. static struct usb_driver sd_driver = {
  406. .name = MODULE_NAME,
  407. .id_table = device_table,
  408. .probe = sd_probe,
  409. .disconnect = gspca_disconnect,
  410. #ifdef CONFIG_PM
  411. .suspend = gspca_suspend,
  412. .resume = gspca_resume,
  413. #endif
  414. };
  415. /* -- module insert / remove -- */
  416. static int __init sd_mod_init(void)
  417. {
  418. if (usb_register(&sd_driver) < 0)
  419. return -1;
  420. PDEBUG(D_PROBE, "registered");
  421. return 0;
  422. }
  423. static void __exit sd_mod_exit(void)
  424. {
  425. usb_deregister(&sd_driver);
  426. PDEBUG(D_PROBE, "deregistered");
  427. }
  428. module_init(sd_mod_init);
  429. module_exit(sd_mod_exit);
  430. module_param(frame_rate, int, 0644);
  431. MODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)");