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