gl860.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
  2. * Subdriver core
  3. *
  4. * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
  5. * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
  6. * Thanks BUGabundo and Malmostoso for your amazing help!
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  22. #include "gspca.h"
  23. #include "gl860.h"
  24. MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
  25. MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
  26. MODULE_LICENSE("GPL");
  27. /*======================== static function declarations ====================*/
  28. static void (*dev_init_settings)(struct gspca_dev *gspca_dev);
  29. static int sd_config(struct gspca_dev *gspca_dev,
  30. const struct usb_device_id *id);
  31. static int sd_init(struct gspca_dev *gspca_dev);
  32. static int sd_isoc_init(struct gspca_dev *gspca_dev);
  33. static int sd_start(struct gspca_dev *gspca_dev);
  34. static void sd_stop0(struct gspca_dev *gspca_dev);
  35. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  36. u8 *data, int len);
  37. static void sd_callback(struct gspca_dev *gspca_dev);
  38. static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
  39. u16 vendor_id, u16 product_id);
  40. /*============================ driver options ==============================*/
  41. static s32 AC50Hz = 0xff;
  42. module_param(AC50Hz, int, 0644);
  43. MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
  44. static char sensor[7];
  45. module_param_string(sensor, sensor, sizeof(sensor), 0644);
  46. MODULE_PARM_DESC(sensor,
  47. " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
  48. /*============================ webcam controls =============================*/
  49. static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
  50. {
  51. struct gspca_dev *gspca_dev =
  52. container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
  53. struct sd *sd = (struct sd *) gspca_dev;
  54. switch (ctrl->id) {
  55. case V4L2_CID_BRIGHTNESS:
  56. sd->vcur.brightness = ctrl->val;
  57. break;
  58. case V4L2_CID_CONTRAST:
  59. sd->vcur.contrast = ctrl->val;
  60. break;
  61. case V4L2_CID_SATURATION:
  62. sd->vcur.saturation = ctrl->val;
  63. break;
  64. case V4L2_CID_HUE:
  65. sd->vcur.hue = ctrl->val;
  66. break;
  67. case V4L2_CID_GAMMA:
  68. sd->vcur.gamma = ctrl->val;
  69. break;
  70. case V4L2_CID_HFLIP:
  71. sd->vcur.mirror = ctrl->val;
  72. break;
  73. case V4L2_CID_VFLIP:
  74. sd->vcur.flip = ctrl->val;
  75. break;
  76. case V4L2_CID_POWER_LINE_FREQUENCY:
  77. sd->vcur.AC50Hz = ctrl->val;
  78. break;
  79. case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
  80. sd->vcur.whitebal = ctrl->val;
  81. break;
  82. case V4L2_CID_SHARPNESS:
  83. sd->vcur.sharpness = ctrl->val;
  84. break;
  85. case V4L2_CID_BACKLIGHT_COMPENSATION:
  86. sd->vcur.backlight = ctrl->val;
  87. break;
  88. default:
  89. return -EINVAL;
  90. }
  91. if (gspca_dev->streaming)
  92. sd->waitSet = 1;
  93. return 0;
  94. }
  95. static const struct v4l2_ctrl_ops sd_ctrl_ops = {
  96. .s_ctrl = sd_s_ctrl,
  97. };
  98. static int sd_init_controls(struct gspca_dev *gspca_dev)
  99. {
  100. struct sd *sd = (struct sd *) gspca_dev;
  101. struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
  102. gspca_dev->vdev.ctrl_handler = hdl;
  103. v4l2_ctrl_handler_init(hdl, 11);
  104. if (sd->vmax.brightness)
  105. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS,
  106. 0, sd->vmax.brightness, 1,
  107. sd->vcur.brightness);
  108. if (sd->vmax.contrast)
  109. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST,
  110. 0, sd->vmax.contrast, 1,
  111. sd->vcur.contrast);
  112. if (sd->vmax.saturation)
  113. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION,
  114. 0, sd->vmax.saturation, 1,
  115. sd->vcur.saturation);
  116. if (sd->vmax.hue)
  117. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE,
  118. 0, sd->vmax.hue, 1, sd->vcur.hue);
  119. if (sd->vmax.gamma)
  120. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA,
  121. 0, sd->vmax.gamma, 1, sd->vcur.gamma);
  122. if (sd->vmax.mirror)
  123. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HFLIP,
  124. 0, sd->vmax.mirror, 1, sd->vcur.mirror);
  125. if (sd->vmax.flip)
  126. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP,
  127. 0, sd->vmax.flip, 1, sd->vcur.flip);
  128. if (sd->vmax.AC50Hz)
  129. v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
  130. V4L2_CID_POWER_LINE_FREQUENCY,
  131. sd->vmax.AC50Hz, 0, sd->vcur.AC50Hz);
  132. if (sd->vmax.whitebal)
  133. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
  134. V4L2_CID_WHITE_BALANCE_TEMPERATURE,
  135. 0, sd->vmax.whitebal, 1, sd->vcur.whitebal);
  136. if (sd->vmax.sharpness)
  137. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS,
  138. 0, sd->vmax.sharpness, 1,
  139. sd->vcur.sharpness);
  140. if (sd->vmax.backlight)
  141. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
  142. V4L2_CID_BACKLIGHT_COMPENSATION,
  143. 0, sd->vmax.backlight, 1,
  144. sd->vcur.backlight);
  145. if (hdl->error) {
  146. pr_err("Could not initialize controls\n");
  147. return hdl->error;
  148. }
  149. return 0;
  150. }
  151. /*==================== sud-driver structure initialisation =================*/
  152. static const struct sd_desc sd_desc_mi1320 = {
  153. .name = MODULE_NAME,
  154. .config = sd_config,
  155. .init = sd_init,
  156. .init_controls = sd_init_controls,
  157. .isoc_init = sd_isoc_init,
  158. .start = sd_start,
  159. .stop0 = sd_stop0,
  160. .pkt_scan = sd_pkt_scan,
  161. .dq_callback = sd_callback,
  162. };
  163. static const struct sd_desc sd_desc_mi2020 = {
  164. .name = MODULE_NAME,
  165. .config = sd_config,
  166. .init = sd_init,
  167. .init_controls = sd_init_controls,
  168. .isoc_init = sd_isoc_init,
  169. .start = sd_start,
  170. .stop0 = sd_stop0,
  171. .pkt_scan = sd_pkt_scan,
  172. .dq_callback = sd_callback,
  173. };
  174. static const struct sd_desc sd_desc_ov2640 = {
  175. .name = MODULE_NAME,
  176. .config = sd_config,
  177. .init = sd_init,
  178. .init_controls = sd_init_controls,
  179. .isoc_init = sd_isoc_init,
  180. .start = sd_start,
  181. .stop0 = sd_stop0,
  182. .pkt_scan = sd_pkt_scan,
  183. .dq_callback = sd_callback,
  184. };
  185. static const struct sd_desc sd_desc_ov9655 = {
  186. .name = MODULE_NAME,
  187. .config = sd_config,
  188. .init = sd_init,
  189. .init_controls = sd_init_controls,
  190. .isoc_init = sd_isoc_init,
  191. .start = sd_start,
  192. .stop0 = sd_stop0,
  193. .pkt_scan = sd_pkt_scan,
  194. .dq_callback = sd_callback,
  195. };
  196. /*=========================== sub-driver image sizes =======================*/
  197. static struct v4l2_pix_format mi2020_mode[] = {
  198. { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  199. .bytesperline = 640,
  200. .sizeimage = 640 * 480,
  201. .colorspace = V4L2_COLORSPACE_SRGB,
  202. .priv = 0
  203. },
  204. { 800, 598, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  205. .bytesperline = 800,
  206. .sizeimage = 800 * 598,
  207. .colorspace = V4L2_COLORSPACE_SRGB,
  208. .priv = 1
  209. },
  210. {1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  211. .bytesperline = 1280,
  212. .sizeimage = 1280 * 1024,
  213. .colorspace = V4L2_COLORSPACE_SRGB,
  214. .priv = 2
  215. },
  216. {1600, 1198, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  217. .bytesperline = 1600,
  218. .sizeimage = 1600 * 1198,
  219. .colorspace = V4L2_COLORSPACE_SRGB,
  220. .priv = 3
  221. },
  222. };
  223. static struct v4l2_pix_format ov2640_mode[] = {
  224. { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  225. .bytesperline = 640,
  226. .sizeimage = 640 * 480,
  227. .colorspace = V4L2_COLORSPACE_SRGB,
  228. .priv = 0
  229. },
  230. { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  231. .bytesperline = 800,
  232. .sizeimage = 800 * 600,
  233. .colorspace = V4L2_COLORSPACE_SRGB,
  234. .priv = 1
  235. },
  236. {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  237. .bytesperline = 1280,
  238. .sizeimage = 1280 * 960,
  239. .colorspace = V4L2_COLORSPACE_SRGB,
  240. .priv = 2
  241. },
  242. {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  243. .bytesperline = 1600,
  244. .sizeimage = 1600 * 1200,
  245. .colorspace = V4L2_COLORSPACE_SRGB,
  246. .priv = 3
  247. },
  248. };
  249. static struct v4l2_pix_format mi1320_mode[] = {
  250. { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  251. .bytesperline = 640,
  252. .sizeimage = 640 * 480,
  253. .colorspace = V4L2_COLORSPACE_SRGB,
  254. .priv = 0
  255. },
  256. { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  257. .bytesperline = 800,
  258. .sizeimage = 800 * 600,
  259. .colorspace = V4L2_COLORSPACE_SRGB,
  260. .priv = 1
  261. },
  262. {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  263. .bytesperline = 1280,
  264. .sizeimage = 1280 * 960,
  265. .colorspace = V4L2_COLORSPACE_SRGB,
  266. .priv = 2
  267. },
  268. };
  269. static struct v4l2_pix_format ov9655_mode[] = {
  270. { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  271. .bytesperline = 640,
  272. .sizeimage = 640 * 480,
  273. .colorspace = V4L2_COLORSPACE_SRGB,
  274. .priv = 0
  275. },
  276. {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  277. .bytesperline = 1280,
  278. .sizeimage = 1280 * 960,
  279. .colorspace = V4L2_COLORSPACE_SRGB,
  280. .priv = 1
  281. },
  282. };
  283. /*========================= sud-driver functions ===========================*/
  284. /* This function is called at probe time */
  285. static int sd_config(struct gspca_dev *gspca_dev,
  286. const struct usb_device_id *id)
  287. {
  288. struct sd *sd = (struct sd *) gspca_dev;
  289. struct cam *cam;
  290. u16 vendor_id, product_id;
  291. /* Get USB VendorID and ProductID */
  292. vendor_id = id->idVendor;
  293. product_id = id->idProduct;
  294. sd->nbRightUp = 1;
  295. sd->nbIm = -1;
  296. sd->sensor = 0xff;
  297. if (strcmp(sensor, "MI1320") == 0)
  298. sd->sensor = ID_MI1320;
  299. else if (strcmp(sensor, "OV2640") == 0)
  300. sd->sensor = ID_OV2640;
  301. else if (strcmp(sensor, "OV9655") == 0)
  302. sd->sensor = ID_OV9655;
  303. else if (strcmp(sensor, "MI2020") == 0)
  304. sd->sensor = ID_MI2020;
  305. /* Get sensor and set the suitable init/start/../stop functions */
  306. if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
  307. return -1;
  308. cam = &gspca_dev->cam;
  309. switch (sd->sensor) {
  310. case ID_MI1320:
  311. gspca_dev->sd_desc = &sd_desc_mi1320;
  312. cam->cam_mode = mi1320_mode;
  313. cam->nmodes = ARRAY_SIZE(mi1320_mode);
  314. dev_init_settings = mi1320_init_settings;
  315. break;
  316. case ID_MI2020:
  317. gspca_dev->sd_desc = &sd_desc_mi2020;
  318. cam->cam_mode = mi2020_mode;
  319. cam->nmodes = ARRAY_SIZE(mi2020_mode);
  320. dev_init_settings = mi2020_init_settings;
  321. break;
  322. case ID_OV2640:
  323. gspca_dev->sd_desc = &sd_desc_ov2640;
  324. cam->cam_mode = ov2640_mode;
  325. cam->nmodes = ARRAY_SIZE(ov2640_mode);
  326. dev_init_settings = ov2640_init_settings;
  327. break;
  328. case ID_OV9655:
  329. gspca_dev->sd_desc = &sd_desc_ov9655;
  330. cam->cam_mode = ov9655_mode;
  331. cam->nmodes = ARRAY_SIZE(ov9655_mode);
  332. dev_init_settings = ov9655_init_settings;
  333. break;
  334. }
  335. dev_init_settings(gspca_dev);
  336. if (AC50Hz != 0xff)
  337. ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz;
  338. return 0;
  339. }
  340. /* This function is called at probe time after sd_config */
  341. static int sd_init(struct gspca_dev *gspca_dev)
  342. {
  343. struct sd *sd = (struct sd *) gspca_dev;
  344. return sd->dev_init_at_startup(gspca_dev);
  345. }
  346. /* This function is called before to choose the alt setting */
  347. static int sd_isoc_init(struct gspca_dev *gspca_dev)
  348. {
  349. struct sd *sd = (struct sd *) gspca_dev;
  350. return sd->dev_configure_alt(gspca_dev);
  351. }
  352. /* This function is called to start the webcam */
  353. static int sd_start(struct gspca_dev *gspca_dev)
  354. {
  355. struct sd *sd = (struct sd *) gspca_dev;
  356. return sd->dev_init_pre_alt(gspca_dev);
  357. }
  358. /* This function is called to stop the webcam */
  359. static void sd_stop0(struct gspca_dev *gspca_dev)
  360. {
  361. struct sd *sd = (struct sd *) gspca_dev;
  362. if (!sd->gspca_dev.present)
  363. return;
  364. return sd->dev_post_unset_alt(gspca_dev);
  365. }
  366. /* This function is called when an image is being received */
  367. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  368. u8 *data, int len)
  369. {
  370. struct sd *sd = (struct sd *) gspca_dev;
  371. static s32 nSkipped;
  372. s32 mode = (s32) gspca_dev->curr_mode;
  373. s32 nToSkip =
  374. sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
  375. /* Test only against 0202h, so endianness does not matter */
  376. switch (*(s16 *) data) {
  377. case 0x0202: /* End of frame, start a new one */
  378. gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
  379. nSkipped = 0;
  380. if (sd->nbIm >= 0 && sd->nbIm < 10)
  381. sd->nbIm++;
  382. gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
  383. break;
  384. default:
  385. data += 2;
  386. len -= 2;
  387. if (nSkipped + len <= nToSkip)
  388. nSkipped += len;
  389. else {
  390. if (nSkipped < nToSkip && nSkipped + len > nToSkip) {
  391. data += nToSkip - nSkipped;
  392. len -= nToSkip - nSkipped;
  393. nSkipped = nToSkip + 1;
  394. }
  395. gspca_frame_add(gspca_dev,
  396. INTER_PACKET, data, len);
  397. }
  398. break;
  399. }
  400. }
  401. /* This function is called when an image has been read */
  402. /* This function is used to monitor webcam orientation */
  403. static void sd_callback(struct gspca_dev *gspca_dev)
  404. {
  405. struct sd *sd = (struct sd *) gspca_dev;
  406. if (!_OV9655_) {
  407. u8 state;
  408. u8 upsideDown;
  409. /* Probe sensor orientation */
  410. ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state);
  411. /* C8/40 means upside-down (looking backwards) */
  412. /* D8/50 means right-up (looking onwards) */
  413. upsideDown = (state == 0xc8 || state == 0x40);
  414. if (upsideDown && sd->nbRightUp > -4) {
  415. if (sd->nbRightUp > 0)
  416. sd->nbRightUp = 0;
  417. if (sd->nbRightUp == -3) {
  418. sd->mirrorMask = 1;
  419. sd->waitSet = 1;
  420. }
  421. sd->nbRightUp--;
  422. }
  423. if (!upsideDown && sd->nbRightUp < 4) {
  424. if (sd->nbRightUp < 0)
  425. sd->nbRightUp = 0;
  426. if (sd->nbRightUp == 3) {
  427. sd->mirrorMask = 0;
  428. sd->waitSet = 1;
  429. }
  430. sd->nbRightUp++;
  431. }
  432. }
  433. if (sd->waitSet)
  434. sd->dev_camera_settings(gspca_dev);
  435. }
  436. /*=================== USB driver structure initialisation ==================*/
  437. static const struct usb_device_id device_table[] = {
  438. {USB_DEVICE(0x05e3, 0x0503)},
  439. {USB_DEVICE(0x05e3, 0xf191)},
  440. {}
  441. };
  442. MODULE_DEVICE_TABLE(usb, device_table);
  443. static int sd_probe(struct usb_interface *intf,
  444. const struct usb_device_id *id)
  445. {
  446. return gspca_dev_probe(intf, id,
  447. &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
  448. }
  449. static void sd_disconnect(struct usb_interface *intf)
  450. {
  451. gspca_disconnect(intf);
  452. }
  453. static struct usb_driver sd_driver = {
  454. .name = MODULE_NAME,
  455. .id_table = device_table,
  456. .probe = sd_probe,
  457. .disconnect = sd_disconnect,
  458. #ifdef CONFIG_PM
  459. .suspend = gspca_suspend,
  460. .resume = gspca_resume,
  461. .reset_resume = gspca_resume,
  462. #endif
  463. };
  464. /*====================== Init and Exit module functions ====================*/
  465. module_usb_driver(sd_driver);
  466. /*==========================================================================*/
  467. int gl860_RTx(struct gspca_dev *gspca_dev,
  468. unsigned char pref, u32 req, u16 val, u16 index,
  469. s32 len, void *pdata)
  470. {
  471. struct usb_device *udev = gspca_dev->dev;
  472. s32 r = 0;
  473. if (pref == 0x40) { /* Send */
  474. if (len > 0) {
  475. memcpy(gspca_dev->usb_buf, pdata, len);
  476. r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  477. req, pref, val, index,
  478. gspca_dev->usb_buf,
  479. len, 400 + 200 * (len > 1));
  480. } else {
  481. r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  482. req, pref, val, index, NULL, len, 400);
  483. }
  484. } else { /* Receive */
  485. if (len > 0) {
  486. r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  487. req, pref, val, index,
  488. gspca_dev->usb_buf,
  489. len, 400 + 200 * (len > 1));
  490. memcpy(pdata, gspca_dev->usb_buf, len);
  491. } else {
  492. r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  493. req, pref, val, index, NULL, len, 400);
  494. }
  495. }
  496. if (r < 0)
  497. pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n",
  498. r, pref, req, val, index, len);
  499. else if (len > 1 && r < len)
  500. PERR("short ctrl transfer %d/%d", r, len);
  501. msleep(1);
  502. return r;
  503. }
  504. int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len)
  505. {
  506. int n;
  507. for (n = 0; n < len; n++) {
  508. if (tbl[n].idx != 0xffff)
  509. ctrl_out(gspca_dev, 0x40, 1, tbl[n].val,
  510. tbl[n].idx, 0, NULL);
  511. else if (tbl[n].val == 0xffff)
  512. break;
  513. else
  514. msleep(tbl[n].val);
  515. }
  516. return n;
  517. }
  518. int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
  519. int len, int n)
  520. {
  521. while (++n < len) {
  522. if (tbl[n].idx != 0xffff)
  523. ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx,
  524. 0, NULL);
  525. else if (tbl[n].val == 0xffff)
  526. break;
  527. else
  528. msleep(tbl[n].val);
  529. }
  530. return n;
  531. }
  532. void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
  533. {
  534. int n;
  535. for (n = 0; n < len; n++) {
  536. if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0)
  537. ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx,
  538. 3, tbl[n].data);
  539. else
  540. msleep(tbl[n].idx);
  541. }
  542. }
  543. static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
  544. u16 vendor_id, u16 product_id)
  545. {
  546. struct sd *sd = (struct sd *) gspca_dev;
  547. u8 probe, nb26, nb96, nOV, ntry;
  548. if (product_id == 0xf191)
  549. sd->sensor = ID_MI1320;
  550. if (sd->sensor == 0xff) {
  551. ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
  552. ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
  553. ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
  554. msleep(3);
  555. ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
  556. msleep(3);
  557. ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
  558. msleep(3);
  559. ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
  560. msleep(3);
  561. ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
  562. msleep(3);
  563. ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
  564. msleep(3);
  565. ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
  566. msleep(56);
  567. PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
  568. nOV = 0;
  569. for (ntry = 0; ntry < 4; ntry++) {
  570. ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
  571. msleep(3);
  572. ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
  573. msleep(3);
  574. ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
  575. msleep(10);
  576. ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
  577. PDEBUG(D_PROBE, "probe=0x%02x", probe);
  578. if (probe == 0xff)
  579. nOV++;
  580. }
  581. if (nOV) {
  582. PDEBUG(D_PROBE, "0xff -> OVXXXX");
  583. PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
  584. nb26 = nb96 = 0;
  585. for (ntry = 0; ntry < 4; ntry++) {
  586. ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
  587. 0, NULL);
  588. msleep(3);
  589. ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
  590. 0, NULL);
  591. msleep(10);
  592. /* Wait for 26(OV2640) or 96(OV9655) */
  593. ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
  594. 1, &probe);
  595. if (probe == 0x26 || probe == 0x40) {
  596. PDEBUG(D_PROBE,
  597. "probe=0x%02x -> OV2640",
  598. probe);
  599. sd->sensor = ID_OV2640;
  600. nb26 += 4;
  601. break;
  602. }
  603. if (probe == 0x96 || probe == 0x55) {
  604. PDEBUG(D_PROBE,
  605. "probe=0x%02x -> OV9655",
  606. probe);
  607. sd->sensor = ID_OV9655;
  608. nb96 += 4;
  609. break;
  610. }
  611. PDEBUG(D_PROBE, "probe=0x%02x", probe);
  612. if (probe == 0x00)
  613. nb26++;
  614. if (probe == 0xff)
  615. nb96++;
  616. msleep(3);
  617. }
  618. if (nb26 < 4 && nb96 < 4)
  619. return -1;
  620. } else {
  621. PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
  622. sd->sensor = ID_MI2020;
  623. }
  624. }
  625. if (_MI1320_) {
  626. PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
  627. } else if (_MI2020_) {
  628. PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
  629. } else if (_OV9655_) {
  630. PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
  631. } else if (_OV2640_) {
  632. PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
  633. } else {
  634. PDEBUG(D_PROBE, "***** Unknown sensor *****");
  635. return -1;
  636. }
  637. return 0;
  638. }