root/drivers/media/usb/gspca/gl860/gl860.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sd_s_ctrl
  2. sd_init_controls
  3. sd_config
  4. sd_init
  5. sd_isoc_init
  6. sd_start
  7. sd_stop0
  8. sd_pkt_scan
  9. sd_callback
  10. sd_probe
  11. sd_disconnect
  12. gl860_RTx
  13. fetch_validx
  14. keep_on_fetching_validx
  15. fetch_idxdata
  16. gl860_guess_sensor

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

/* [<][>][^][v][top][bottom][index][help] */