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

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

DEFINITIONS

This source file includes following definitions.
  1. reg_r
  2. reg_w_1
  3. reg_w_riv
  4. write_vector
  5. setup_qtable
  6. spca504_acknowledged_command
  7. spca504_read_info
  8. spca504A_acknowledged_command
  9. spca504B_PollingDataReady
  10. spca504B_WaitCmdStatus
  11. spca50x_GetFirmware
  12. spca504B_SetSizeType
  13. spca504_wait_status
  14. spca504B_setQtable
  15. setbrightness
  16. setcontrast
  17. setcolors
  18. init_ctl_reg
  19. sd_config
  20. sd_init
  21. sd_start
  22. sd_stopN
  23. sd_pkt_scan
  24. sd_s_ctrl
  25. sd_init_controls
  26. sd_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *              Sunplus spca504(abc) spca533 spca536 library
   4  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
   5  *
   6  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   7  */
   8 
   9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10 
  11 #define MODULE_NAME "sunplus"
  12 
  13 #include "gspca.h"
  14 #include "jpeg.h"
  15 
  16 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  17 MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
  18 MODULE_LICENSE("GPL");
  19 
  20 #define QUALITY 85
  21 
  22 /* specific webcam descriptor */
  23 struct sd {
  24         struct gspca_dev gspca_dev;     /* !! must be the first item */
  25 
  26         bool autogain;
  27 
  28         u8 bridge;
  29 #define BRIDGE_SPCA504 0
  30 #define BRIDGE_SPCA504B 1
  31 #define BRIDGE_SPCA504C 2
  32 #define BRIDGE_SPCA533 3
  33 #define BRIDGE_SPCA536 4
  34         u8 subtype;
  35 #define AiptekMiniPenCam13 1
  36 #define LogitechClickSmart420 2
  37 #define LogitechClickSmart820 3
  38 #define MegapixV4 4
  39 #define MegaImageVI 5
  40 
  41         u8 jpeg_hdr[JPEG_HDR_SZ];
  42 };
  43 
  44 static const struct v4l2_pix_format vga_mode[] = {
  45         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  46                 .bytesperline = 320,
  47                 .sizeimage = 320 * 240 * 3 / 8 + 590,
  48                 .colorspace = V4L2_COLORSPACE_JPEG,
  49                 .priv = 2},
  50         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  51                 .bytesperline = 640,
  52                 .sizeimage = 640 * 480 * 3 / 8 + 590,
  53                 .colorspace = V4L2_COLORSPACE_JPEG,
  54                 .priv = 1},
  55 };
  56 
  57 static const struct v4l2_pix_format custom_mode[] = {
  58         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  59                 .bytesperline = 320,
  60                 .sizeimage = 320 * 240 * 3 / 8 + 590,
  61                 .colorspace = V4L2_COLORSPACE_JPEG,
  62                 .priv = 2},
  63         {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  64                 .bytesperline = 464,
  65                 .sizeimage = 464 * 480 * 3 / 8 + 590,
  66                 .colorspace = V4L2_COLORSPACE_JPEG,
  67                 .priv = 1},
  68 };
  69 
  70 static const struct v4l2_pix_format vga_mode2[] = {
  71         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  72                 .bytesperline = 176,
  73                 .sizeimage = 176 * 144 * 3 / 8 + 590,
  74                 .colorspace = V4L2_COLORSPACE_JPEG,
  75                 .priv = 4},
  76         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  77                 .bytesperline = 320,
  78                 .sizeimage = 320 * 240 * 3 / 8 + 590,
  79                 .colorspace = V4L2_COLORSPACE_JPEG,
  80                 .priv = 3},
  81         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  82                 .bytesperline = 352,
  83                 .sizeimage = 352 * 288 * 3 / 8 + 590,
  84                 .colorspace = V4L2_COLORSPACE_JPEG,
  85                 .priv = 2},
  86         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  87                 .bytesperline = 640,
  88                 .sizeimage = 640 * 480 * 3 / 8 + 590,
  89                 .colorspace = V4L2_COLORSPACE_JPEG,
  90                 .priv = 1},
  91 };
  92 
  93 #define SPCA50X_OFFSET_DATA 10
  94 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
  95 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
  96 #define SPCA504_PCCAM600_OFFSET_MODE     5
  97 #define SPCA504_PCCAM600_OFFSET_DATA     14
  98  /* Frame packet header offsets for the spca533 */
  99 #define SPCA533_OFFSET_DATA     16
 100 #define SPCA533_OFFSET_FRAMSEQ  15
 101 /* Frame packet header offsets for the spca536 */
 102 #define SPCA536_OFFSET_DATA     4
 103 #define SPCA536_OFFSET_FRAMSEQ  1
 104 
 105 struct cmd {
 106         u8 req;
 107         u16 val;
 108         u16 idx;
 109 };
 110 
 111 /* Initialisation data for the Creative PC-CAM 600 */
 112 static const struct cmd spca504_pccam600_init_data[] = {
 113 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
 114         {0x00, 0x0000, 0x2000},
 115         {0x00, 0x0013, 0x2301},
 116         {0x00, 0x0003, 0x2000},
 117         {0x00, 0x0001, 0x21ac},
 118         {0x00, 0x0001, 0x21a6},
 119         {0x00, 0x0000, 0x21a7}, /* brightness */
 120         {0x00, 0x0020, 0x21a8}, /* contrast */
 121         {0x00, 0x0001, 0x21ac}, /* sat/hue */
 122         {0x00, 0x0000, 0x21ad}, /* hue */
 123         {0x00, 0x001a, 0x21ae}, /* saturation */
 124         {0x00, 0x0002, 0x21a3}, /* gamma */
 125         {0x30, 0x0154, 0x0008},
 126         {0x30, 0x0004, 0x0006},
 127         {0x30, 0x0258, 0x0009},
 128         {0x30, 0x0004, 0x0000},
 129         {0x30, 0x0093, 0x0004},
 130         {0x30, 0x0066, 0x0005},
 131         {0x00, 0x0000, 0x2000},
 132         {0x00, 0x0013, 0x2301},
 133         {0x00, 0x0003, 0x2000},
 134         {0x00, 0x0013, 0x2301},
 135         {0x00, 0x0003, 0x2000},
 136 };
 137 
 138 /* Creative PC-CAM 600 specific open data, sent before using the
 139  * generic initialisation data from spca504_open_data.
 140  */
 141 static const struct cmd spca504_pccam600_open_data[] = {
 142         {0x00, 0x0001, 0x2501},
 143         {0x20, 0x0500, 0x0001}, /* snapshot mode */
 144         {0x00, 0x0003, 0x2880},
 145         {0x00, 0x0001, 0x2881},
 146 };
 147 
 148 /* Initialisation data for the logitech clicksmart 420 */
 149 static const struct cmd spca504A_clicksmart420_init_data[] = {
 150 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
 151         {0x00, 0x0000, 0x2000},
 152         {0x00, 0x0013, 0x2301},
 153         {0x00, 0x0003, 0x2000},
 154         {0x00, 0x0001, 0x21ac},
 155         {0x00, 0x0001, 0x21a6},
 156         {0x00, 0x0000, 0x21a7}, /* brightness */
 157         {0x00, 0x0020, 0x21a8}, /* contrast */
 158         {0x00, 0x0001, 0x21ac}, /* sat/hue */
 159         {0x00, 0x0000, 0x21ad}, /* hue */
 160         {0x00, 0x001a, 0x21ae}, /* saturation */
 161         {0x00, 0x0002, 0x21a3}, /* gamma */
 162         {0x30, 0x0004, 0x000a},
 163         {0xb0, 0x0001, 0x0000},
 164 
 165         {0xa1, 0x0080, 0x0001},
 166         {0x30, 0x0049, 0x0000},
 167         {0x30, 0x0060, 0x0005},
 168         {0x0c, 0x0004, 0x0000},
 169         {0x00, 0x0000, 0x0000},
 170         {0x00, 0x0000, 0x2000},
 171         {0x00, 0x0013, 0x2301},
 172         {0x00, 0x0003, 0x2000},
 173 };
 174 
 175 /* clicksmart 420 open data ? */
 176 static const struct cmd spca504A_clicksmart420_open_data[] = {
 177         {0x00, 0x0001, 0x2501},
 178         {0x20, 0x0502, 0x0000},
 179         {0x06, 0x0000, 0x0000},
 180         {0x00, 0x0004, 0x2880},
 181         {0x00, 0x0001, 0x2881},
 182 
 183         {0xa0, 0x0000, 0x0503},
 184 };
 185 
 186 static const u8 qtable_creative_pccam[2][64] = {
 187         {                               /* Q-table Y-components */
 188          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 189          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
 190          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
 191          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
 192          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
 193          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
 194          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
 195          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
 196         {                               /* Q-table C-components */
 197          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
 198          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
 199          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 200          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 201          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 202          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 203          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 204          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
 205 };
 206 
 207 /* FIXME: This Q-table is identical to the Creative PC-CAM one,
 208  *              except for one byte. Possibly a typo?
 209  *              NWG: 18/05/2003.
 210  */
 211 static const u8 qtable_spca504_default[2][64] = {
 212         {                               /* Q-table Y-components */
 213          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 214          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
 215          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
 216          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
 217          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
 218          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
 219          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
 220          0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
 221          },
 222         {                               /* Q-table C-components */
 223          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
 224          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
 225          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 226          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 227          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 228          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 229          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 230          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
 231 };
 232 
 233 /* read <len> bytes to gspca_dev->usb_buf */
 234 static void reg_r(struct gspca_dev *gspca_dev,
 235                   u8 req,
 236                   u16 index,
 237                   u16 len)
 238 {
 239         int ret;
 240 
 241         if (len > USB_BUF_SZ) {
 242                 gspca_err(gspca_dev, "reg_r: buffer overflow\n");
 243                 return;
 244         }
 245         if (gspca_dev->usb_err < 0)
 246                 return;
 247         ret = usb_control_msg(gspca_dev->dev,
 248                         usb_rcvctrlpipe(gspca_dev->dev, 0),
 249                         req,
 250                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 251                         0,              /* value */
 252                         index,
 253                         len ? gspca_dev->usb_buf : NULL, len,
 254                         500);
 255         if (ret < 0) {
 256                 pr_err("reg_r err %d\n", ret);
 257                 gspca_dev->usb_err = ret;
 258                 /*
 259                  * Make sure the buffer is zeroed to avoid uninitialized
 260                  * values.
 261                  */
 262                 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 263         }
 264 }
 265 
 266 /* write one byte */
 267 static void reg_w_1(struct gspca_dev *gspca_dev,
 268                    u8 req,
 269                    u16 value,
 270                    u16 index,
 271                    u16 byte)
 272 {
 273         int ret;
 274 
 275         if (gspca_dev->usb_err < 0)
 276                 return;
 277         gspca_dev->usb_buf[0] = byte;
 278         ret = usb_control_msg(gspca_dev->dev,
 279                         usb_sndctrlpipe(gspca_dev->dev, 0),
 280                         req,
 281                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 282                         value, index,
 283                         gspca_dev->usb_buf, 1,
 284                         500);
 285         if (ret < 0) {
 286                 pr_err("reg_w_1 err %d\n", ret);
 287                 gspca_dev->usb_err = ret;
 288         }
 289 }
 290 
 291 /* write req / index / value */
 292 static void reg_w_riv(struct gspca_dev *gspca_dev,
 293                      u8 req, u16 index, u16 value)
 294 {
 295         struct usb_device *dev = gspca_dev->dev;
 296         int ret;
 297 
 298         if (gspca_dev->usb_err < 0)
 299                 return;
 300         ret = usb_control_msg(dev,
 301                         usb_sndctrlpipe(dev, 0),
 302                         req,
 303                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 304                         value, index, NULL, 0, 500);
 305         if (ret < 0) {
 306                 pr_err("reg_w_riv err %d\n", ret);
 307                 gspca_dev->usb_err = ret;
 308                 return;
 309         }
 310         gspca_dbg(gspca_dev, D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x\n",
 311                   req, index, value);
 312 }
 313 
 314 static void write_vector(struct gspca_dev *gspca_dev,
 315                         const struct cmd *data, int ncmds)
 316 {
 317         while (--ncmds >= 0) {
 318                 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
 319                 data++;
 320         }
 321 }
 322 
 323 static void setup_qtable(struct gspca_dev *gspca_dev,
 324                         const u8 qtable[2][64])
 325 {
 326         int i;
 327 
 328         /* loop over y components */
 329         for (i = 0; i < 64; i++)
 330                 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
 331 
 332         /* loop over c components */
 333         for (i = 0; i < 64; i++)
 334                 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
 335 }
 336 
 337 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
 338                              u8 req, u16 idx, u16 val)
 339 {
 340         reg_w_riv(gspca_dev, req, idx, val);
 341         reg_r(gspca_dev, 0x01, 0x0001, 1);
 342         gspca_dbg(gspca_dev, D_FRAM, "before wait 0x%04x\n",
 343                   gspca_dev->usb_buf[0]);
 344         reg_w_riv(gspca_dev, req, idx, val);
 345 
 346         msleep(200);
 347         reg_r(gspca_dev, 0x01, 0x0001, 1);
 348         gspca_dbg(gspca_dev, D_FRAM, "after wait 0x%04x\n",
 349                   gspca_dev->usb_buf[0]);
 350 }
 351 
 352 static void spca504_read_info(struct gspca_dev *gspca_dev)
 353 {
 354         int i;
 355         u8 info[6];
 356 
 357         if (gspca_debug < D_STREAM)
 358                 return;
 359 
 360         for (i = 0; i < 6; i++) {
 361                 reg_r(gspca_dev, 0, i, 1);
 362                 info[i] = gspca_dev->usb_buf[0];
 363         }
 364         gspca_dbg(gspca_dev, D_STREAM,
 365                   "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0\n",
 366                   info[0], info[1], info[2],
 367                   info[3], info[4], info[5]);
 368 }
 369 
 370 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 371                         u8 req,
 372                         u16 idx, u16 val, u8 endcode, u8 count)
 373 {
 374         u16 status;
 375 
 376         reg_w_riv(gspca_dev, req, idx, val);
 377         reg_r(gspca_dev, 0x01, 0x0001, 1);
 378         if (gspca_dev->usb_err < 0)
 379                 return;
 380         gspca_dbg(gspca_dev, D_FRAM, "Status 0x%02x Need 0x%02x\n",
 381                   gspca_dev->usb_buf[0], endcode);
 382         if (!count)
 383                 return;
 384         count = 200;
 385         while (--count > 0) {
 386                 msleep(10);
 387                 /* gsmart mini2 write a each wait setting 1 ms is enough */
 388 /*              reg_w_riv(gspca_dev, req, idx, val); */
 389                 reg_r(gspca_dev, 0x01, 0x0001, 1);
 390                 status = gspca_dev->usb_buf[0];
 391                 if (status == endcode) {
 392                         gspca_dbg(gspca_dev, D_FRAM, "status 0x%04x after wait %d\n",
 393                                   status, 200 - count);
 394                                 break;
 395                 }
 396         }
 397 }
 398 
 399 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
 400 {
 401         int count = 10;
 402 
 403         while (--count > 0) {
 404                 reg_r(gspca_dev, 0x21, 0, 1);
 405                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
 406                         break;
 407                 msleep(10);
 408         }
 409 }
 410 
 411 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
 412 {
 413         int count = 50;
 414 
 415         while (--count > 0) {
 416                 reg_r(gspca_dev, 0x21, 1, 1);
 417                 if (gspca_dev->usb_buf[0] != 0) {
 418                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
 419                         reg_r(gspca_dev, 0x21, 1, 1);
 420                         spca504B_PollingDataReady(gspca_dev);
 421                         break;
 422                 }
 423                 msleep(10);
 424         }
 425 }
 426 
 427 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
 428 {
 429         u8 *data;
 430 
 431         if (gspca_debug < D_STREAM)
 432                 return;
 433 
 434         data = gspca_dev->usb_buf;
 435         reg_r(gspca_dev, 0x20, 0, 5);
 436         gspca_dbg(gspca_dev, D_STREAM, "FirmWare: %d %d %d %d %d\n",
 437                   data[0], data[1], data[2], data[3], data[4]);
 438         reg_r(gspca_dev, 0x23, 0, 64);
 439         reg_r(gspca_dev, 0x23, 1, 64);
 440 }
 441 
 442 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
 443 {
 444         struct sd *sd = (struct sd *) gspca_dev;
 445         u8 Size;
 446 
 447         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 448         switch (sd->bridge) {
 449         case BRIDGE_SPCA533:
 450                 reg_w_riv(gspca_dev, 0x31, 0, 0);
 451                 spca504B_WaitCmdStatus(gspca_dev);
 452                 spca504B_PollingDataReady(gspca_dev);
 453                 spca50x_GetFirmware(gspca_dev);
 454 
 455                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
 456                 reg_r(gspca_dev, 0x24, 8, 1);
 457 
 458                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
 459                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
 460                 spca504B_PollingDataReady(gspca_dev);
 461 
 462                 /* Init the cam width height with some values get on init ? */
 463                 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
 464                 spca504B_WaitCmdStatus(gspca_dev);
 465                 spca504B_PollingDataReady(gspca_dev);
 466                 break;
 467         default:
 468 /* case BRIDGE_SPCA504B: */
 469 /* case BRIDGE_SPCA536: */
 470                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
 471                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
 472                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
 473                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
 474                 spca504B_PollingDataReady(gspca_dev);
 475                 break;
 476         case BRIDGE_SPCA504:
 477                 Size += 3;
 478                 if (sd->subtype == AiptekMiniPenCam13) {
 479                         /* spca504a aiptek */
 480                         spca504A_acknowledged_command(gspca_dev,
 481                                                 0x08, Size, 0,
 482                                                 0x80 | (Size & 0x0f), 1);
 483                         spca504A_acknowledged_command(gspca_dev,
 484                                                         1, 3, 0, 0x9f, 0);
 485                 } else {
 486                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
 487                 }
 488                 break;
 489         case BRIDGE_SPCA504C:
 490                 /* capture mode */
 491                 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
 492                 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
 493                 break;
 494         }
 495 }
 496 
 497 static void spca504_wait_status(struct gspca_dev *gspca_dev)
 498 {
 499         int cnt;
 500 
 501         cnt = 256;
 502         while (--cnt > 0) {
 503                 /* With this we get the status, when return 0 it's all ok */
 504                 reg_r(gspca_dev, 0x06, 0x00, 1);
 505                 if (gspca_dev->usb_buf[0] == 0)
 506                         return;
 507                 msleep(10);
 508         }
 509 }
 510 
 511 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
 512 {
 513         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
 514         reg_r(gspca_dev, 0x26, 0, 1);
 515         spca504B_PollingDataReady(gspca_dev);
 516 }
 517 
 518 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
 519 {
 520         struct sd *sd = (struct sd *) gspca_dev;
 521         u16 reg;
 522 
 523         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
 524         reg_w_riv(gspca_dev, 0x00, reg, val);
 525 }
 526 
 527 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 528 {
 529         struct sd *sd = (struct sd *) gspca_dev;
 530         u16 reg;
 531 
 532         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
 533         reg_w_riv(gspca_dev, 0x00, reg, val);
 534 }
 535 
 536 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 537 {
 538         struct sd *sd = (struct sd *) gspca_dev;
 539         u16 reg;
 540 
 541         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
 542         reg_w_riv(gspca_dev, 0x00, reg, val);
 543 }
 544 
 545 static void init_ctl_reg(struct gspca_dev *gspca_dev)
 546 {
 547         struct sd *sd = (struct sd *) gspca_dev;
 548         int pollreg = 1;
 549 
 550         switch (sd->bridge) {
 551         case BRIDGE_SPCA504:
 552         case BRIDGE_SPCA504C:
 553                 pollreg = 0;
 554                 /* fall through */
 555         default:
 556 /*      case BRIDGE_SPCA533: */
 557 /*      case BRIDGE_SPCA504B: */
 558                 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
 559                 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
 560                 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
 561                 break;
 562         case BRIDGE_SPCA536:
 563                 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
 564                 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
 565                 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
 566                 break;
 567         }
 568         if (pollreg)
 569                 spca504B_PollingDataReady(gspca_dev);
 570 }
 571 
 572 /* this function is called at probe time */
 573 static int sd_config(struct gspca_dev *gspca_dev,
 574                         const struct usb_device_id *id)
 575 {
 576         struct sd *sd = (struct sd *) gspca_dev;
 577         struct cam *cam;
 578 
 579         cam = &gspca_dev->cam;
 580 
 581         sd->bridge = id->driver_info >> 8;
 582         sd->subtype = id->driver_info;
 583 
 584         if (sd->subtype == AiptekMiniPenCam13) {
 585 
 586                 /* try to get the firmware as some cam answer 2.0.1.2.2
 587                  * and should be a spca504b then overwrite that setting */
 588                 reg_r(gspca_dev, 0x20, 0, 1);
 589                 switch (gspca_dev->usb_buf[0]) {
 590                 case 1:
 591                         break;          /* (right bridge/subtype) */
 592                 case 2:
 593                         sd->bridge = BRIDGE_SPCA504B;
 594                         sd->subtype = 0;
 595                         break;
 596                 default:
 597                         return -ENODEV;
 598                 }
 599         }
 600 
 601         switch (sd->bridge) {
 602         default:
 603 /*      case BRIDGE_SPCA504B: */
 604 /*      case BRIDGE_SPCA504: */
 605 /*      case BRIDGE_SPCA536: */
 606                 cam->cam_mode = vga_mode;
 607                 cam->nmodes = ARRAY_SIZE(vga_mode);
 608                 break;
 609         case BRIDGE_SPCA533:
 610                 cam->cam_mode = custom_mode;
 611                 if (sd->subtype == MegaImageVI)         /* 320x240 only */
 612                         cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
 613                 else
 614                         cam->nmodes = ARRAY_SIZE(custom_mode);
 615                 break;
 616         case BRIDGE_SPCA504C:
 617                 cam->cam_mode = vga_mode2;
 618                 cam->nmodes = ARRAY_SIZE(vga_mode2);
 619                 break;
 620         }
 621         return 0;
 622 }
 623 
 624 /* this function is called at probe and resume time */
 625 static int sd_init(struct gspca_dev *gspca_dev)
 626 {
 627         struct sd *sd = (struct sd *) gspca_dev;
 628 
 629         switch (sd->bridge) {
 630         case BRIDGE_SPCA504B:
 631                 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
 632                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
 633                 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
 634                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
 635                 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
 636                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
 637                 /* fall through */
 638         case BRIDGE_SPCA533:
 639                 spca504B_PollingDataReady(gspca_dev);
 640                 spca50x_GetFirmware(gspca_dev);
 641                 break;
 642         case BRIDGE_SPCA536:
 643                 spca50x_GetFirmware(gspca_dev);
 644                 reg_r(gspca_dev, 0x00, 0x5002, 1);
 645                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
 646                 reg_r(gspca_dev, 0x24, 0, 1);
 647                 spca504B_PollingDataReady(gspca_dev);
 648                 reg_w_riv(gspca_dev, 0x34, 0, 0);
 649                 spca504B_WaitCmdStatus(gspca_dev);
 650                 break;
 651         case BRIDGE_SPCA504C:   /* pccam600 */
 652                 gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504 (PC-CAM 600)\n");
 653                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
 654                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);     /* reset */
 655                 spca504_wait_status(gspca_dev);
 656                 if (sd->subtype == LogitechClickSmart420)
 657                         write_vector(gspca_dev,
 658                                 spca504A_clicksmart420_open_data,
 659                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
 660                 else
 661                         write_vector(gspca_dev, spca504_pccam600_open_data,
 662                                 ARRAY_SIZE(spca504_pccam600_open_data));
 663                 setup_qtable(gspca_dev, qtable_creative_pccam);
 664                 break;
 665         default:
 666 /*      case BRIDGE_SPCA504: */
 667                 gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504\n");
 668                 if (sd->subtype == AiptekMiniPenCam13) {
 669                         spca504_read_info(gspca_dev);
 670 
 671                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 672                         spca504A_acknowledged_command(gspca_dev, 0x24,
 673                                                         8, 3, 0x9e, 1);
 674                         /* Twice sequential need status 0xff->0x9e->0x9d */
 675                         spca504A_acknowledged_command(gspca_dev, 0x24,
 676                                                         8, 3, 0x9e, 0);
 677 
 678                         spca504A_acknowledged_command(gspca_dev, 0x24,
 679                                                         0, 0, 0x9d, 1);
 680                         /******************************/
 681                         /* spca504a aiptek */
 682                         spca504A_acknowledged_command(gspca_dev, 0x08,
 683                                                         6, 0, 0x86, 1);
 684 /*                      reg_write (dev, 0, 0x2000, 0); */
 685 /*                      reg_write (dev, 0, 0x2883, 1); */
 686 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
 687                                                         6, 0, 0x86, 1); */
 688 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
 689                                                         0, 0, 0x9D, 1); */
 690                         reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
 691                                                         /* L92 sno1t.txt */
 692                         reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
 693                         spca504A_acknowledged_command(gspca_dev, 0x01,
 694                                                         0x0f, 0, 0xff, 0);
 695                 }
 696                 /* setup qtable */
 697                 reg_w_riv(gspca_dev, 0, 0x2000, 0);
 698                 reg_w_riv(gspca_dev, 0, 0x2883, 1);
 699                 setup_qtable(gspca_dev, qtable_spca504_default);
 700                 break;
 701         }
 702         return gspca_dev->usb_err;
 703 }
 704 
 705 static int sd_start(struct gspca_dev *gspca_dev)
 706 {
 707         struct sd *sd = (struct sd *) gspca_dev;
 708         int enable;
 709 
 710         /* create the JPEG header */
 711         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
 712                         gspca_dev->pixfmt.width,
 713                         0x22);          /* JPEG 411 */
 714         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
 715 
 716         if (sd->bridge == BRIDGE_SPCA504B)
 717                 spca504B_setQtable(gspca_dev);
 718         spca504B_SetSizeType(gspca_dev);
 719         switch (sd->bridge) {
 720         default:
 721 /*      case BRIDGE_SPCA504B: */
 722 /*      case BRIDGE_SPCA533: */
 723 /*      case BRIDGE_SPCA536: */
 724                 switch (sd->subtype) {
 725                 case MegapixV4:
 726                 case LogitechClickSmart820:
 727                 case MegaImageVI:
 728                         reg_w_riv(gspca_dev, 0xf0, 0, 0);
 729                         spca504B_WaitCmdStatus(gspca_dev);
 730                         reg_r(gspca_dev, 0xf0, 4, 0);
 731                         spca504B_WaitCmdStatus(gspca_dev);
 732                         break;
 733                 default:
 734                         reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
 735                         spca504B_WaitCmdStatus(gspca_dev);
 736                         spca504B_PollingDataReady(gspca_dev);
 737                         break;
 738                 }
 739                 break;
 740         case BRIDGE_SPCA504:
 741                 if (sd->subtype == AiptekMiniPenCam13) {
 742                         spca504_read_info(gspca_dev);
 743 
 744                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 745                         spca504A_acknowledged_command(gspca_dev, 0x24,
 746                                                         8, 3, 0x9e, 1);
 747                         /* Twice sequential need status 0xff->0x9e->0x9d */
 748                         spca504A_acknowledged_command(gspca_dev, 0x24,
 749                                                         8, 3, 0x9e, 0);
 750                         spca504A_acknowledged_command(gspca_dev, 0x24,
 751                                                         0, 0, 0x9d, 1);
 752                 } else {
 753                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
 754                         spca504_read_info(gspca_dev);
 755                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
 756                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 757                 }
 758                 spca504B_SetSizeType(gspca_dev);
 759                 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
 760                                                         /* L92 sno1t.txt */
 761                 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
 762                 break;
 763         case BRIDGE_SPCA504C:
 764                 if (sd->subtype == LogitechClickSmart420) {
 765                         write_vector(gspca_dev,
 766                                 spca504A_clicksmart420_init_data,
 767                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
 768                 } else {
 769                         write_vector(gspca_dev, spca504_pccam600_init_data,
 770                                 ARRAY_SIZE(spca504_pccam600_init_data));
 771                 }
 772                 enable = (sd->autogain ? 0x04 : 0x01);
 773                 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
 774                                                         /* auto exposure */
 775                 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
 776                                                         /* auto whiteness */
 777 
 778                 /* set default exposure compensation and whiteness balance */
 779                 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);        /* ~ 20 fps */
 780                 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
 781                 spca504B_SetSizeType(gspca_dev);
 782                 break;
 783         }
 784         init_ctl_reg(gspca_dev);
 785         return gspca_dev->usb_err;
 786 }
 787 
 788 static void sd_stopN(struct gspca_dev *gspca_dev)
 789 {
 790         struct sd *sd = (struct sd *) gspca_dev;
 791 
 792         switch (sd->bridge) {
 793         default:
 794 /*      case BRIDGE_SPCA533: */
 795 /*      case BRIDGE_SPCA536: */
 796 /*      case BRIDGE_SPCA504B: */
 797                 reg_w_riv(gspca_dev, 0x31, 0, 0);
 798                 spca504B_WaitCmdStatus(gspca_dev);
 799                 spca504B_PollingDataReady(gspca_dev);
 800                 break;
 801         case BRIDGE_SPCA504:
 802         case BRIDGE_SPCA504C:
 803                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
 804 
 805                 if (sd->subtype == AiptekMiniPenCam13) {
 806                         /* spca504a aiptek */
 807 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
 808                                                          6, 0, 0x86, 1); */
 809                         spca504A_acknowledged_command(gspca_dev, 0x24,
 810                                                         0x00, 0x00, 0x9d, 1);
 811                         spca504A_acknowledged_command(gspca_dev, 0x01,
 812                                                         0x0f, 0x00, 0xff, 1);
 813                 } else {
 814                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 815                         reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
 816                 }
 817                 break;
 818         }
 819 }
 820 
 821 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 822                         u8 *data,                       /* isoc packet */
 823                         int len)                        /* iso packet length */
 824 {
 825         struct sd *sd = (struct sd *) gspca_dev;
 826         int i, sof = 0;
 827         static u8 ffd9[] = {0xff, 0xd9};
 828 
 829 /* frames are jpeg 4.1.1 without 0xff escape */
 830         switch (sd->bridge) {
 831         case BRIDGE_SPCA533:
 832                 if (data[0] == 0xff) {
 833                         if (data[1] != 0x01) {  /* drop packet */
 834 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
 835                                 return;
 836                         }
 837                         sof = 1;
 838                         data += SPCA533_OFFSET_DATA;
 839                         len -= SPCA533_OFFSET_DATA;
 840                 } else {
 841                         data += 1;
 842                         len -= 1;
 843                 }
 844                 break;
 845         case BRIDGE_SPCA536:
 846                 if (data[0] == 0xff) {
 847                         sof = 1;
 848                         data += SPCA536_OFFSET_DATA;
 849                         len -= SPCA536_OFFSET_DATA;
 850                 } else {
 851                         data += 2;
 852                         len -= 2;
 853                 }
 854                 break;
 855         default:
 856 /*      case BRIDGE_SPCA504: */
 857 /*      case BRIDGE_SPCA504B: */
 858                 switch (data[0]) {
 859                 case 0xfe:                      /* start of frame */
 860                         sof = 1;
 861                         data += SPCA50X_OFFSET_DATA;
 862                         len -= SPCA50X_OFFSET_DATA;
 863                         break;
 864                 case 0xff:                      /* drop packet */
 865 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
 866                         return;
 867                 default:
 868                         data += 1;
 869                         len -= 1;
 870                         break;
 871                 }
 872                 break;
 873         case BRIDGE_SPCA504C:
 874                 switch (data[0]) {
 875                 case 0xfe:                      /* start of frame */
 876                         sof = 1;
 877                         data += SPCA504_PCCAM600_OFFSET_DATA;
 878                         len -= SPCA504_PCCAM600_OFFSET_DATA;
 879                         break;
 880                 case 0xff:                      /* drop packet */
 881 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
 882                         return;
 883                 default:
 884                         data += 1;
 885                         len -= 1;
 886                         break;
 887                 }
 888                 break;
 889         }
 890         if (sof) {              /* start of frame */
 891                 gspca_frame_add(gspca_dev, LAST_PACKET,
 892                                 ffd9, 2);
 893 
 894                 /* put the JPEG header in the new frame */
 895                 gspca_frame_add(gspca_dev, FIRST_PACKET,
 896                         sd->jpeg_hdr, JPEG_HDR_SZ);
 897         }
 898 
 899         /* add 0x00 after 0xff */
 900         i = 0;
 901         do {
 902                 if (data[i] == 0xff) {
 903                         gspca_frame_add(gspca_dev, INTER_PACKET,
 904                                         data, i + 1);
 905                         len -= i;
 906                         data += i;
 907                         *data = 0x00;
 908                         i = 0;
 909                 }
 910                 i++;
 911         } while (i < len);
 912         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 913 }
 914 
 915 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 916 {
 917         struct gspca_dev *gspca_dev =
 918                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 919         struct sd *sd = (struct sd *)gspca_dev;
 920 
 921         gspca_dev->usb_err = 0;
 922 
 923         if (!gspca_dev->streaming)
 924                 return 0;
 925 
 926         switch (ctrl->id) {
 927         case V4L2_CID_BRIGHTNESS:
 928                 setbrightness(gspca_dev, ctrl->val);
 929                 break;
 930         case V4L2_CID_CONTRAST:
 931                 setcontrast(gspca_dev, ctrl->val);
 932                 break;
 933         case V4L2_CID_SATURATION:
 934                 setcolors(gspca_dev, ctrl->val);
 935                 break;
 936         case V4L2_CID_AUTOGAIN:
 937                 sd->autogain = ctrl->val;
 938                 break;
 939         }
 940         return gspca_dev->usb_err;
 941 }
 942 
 943 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 944         .s_ctrl = sd_s_ctrl,
 945 };
 946 
 947 static int sd_init_controls(struct gspca_dev *gspca_dev)
 948 {
 949         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 950 
 951         gspca_dev->vdev.ctrl_handler = hdl;
 952         v4l2_ctrl_handler_init(hdl, 4);
 953         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 954                         V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
 955         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 956                         V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
 957         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 958                         V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
 959         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 960                         V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 961 
 962         if (hdl->error) {
 963                 pr_err("Could not initialize controls\n");
 964                 return hdl->error;
 965         }
 966         return 0;
 967 }
 968 
 969 /* sub-driver description */
 970 static const struct sd_desc sd_desc = {
 971         .name = MODULE_NAME,
 972         .config = sd_config,
 973         .init = sd_init,
 974         .init_controls = sd_init_controls,
 975         .start = sd_start,
 976         .stopN = sd_stopN,
 977         .pkt_scan = sd_pkt_scan,
 978 };
 979 
 980 /* -- module initialisation -- */
 981 #define BS(bridge, subtype) \
 982         .driver_info = (BRIDGE_ ## bridge << 8) \
 983                         | (subtype)
 984 static const struct usb_device_id device_table[] = {
 985         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
 986         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
 987         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
 988         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
 989         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
 990         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
 991         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
 992         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
 993         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
 994         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
 995         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
 996         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
 997         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
 998         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
 999         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1000         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1001         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1002         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1003         {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1004         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1005         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1006         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1007         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1008         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1009         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1010         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1011         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1012         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1013         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1014         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1015         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1016         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1017         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1018         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1019         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1020         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1021         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1022         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1023         {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 0)},
1024         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1025         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1026         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1027         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1028         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1029         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1030         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1031         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1032         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1033         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1034         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1035         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1036         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1037         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1038         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1039         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1040         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1041         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1042         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1043         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1044         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1045         {}
1046 };
1047 MODULE_DEVICE_TABLE(usb, device_table);
1048 
1049 /* -- device connect -- */
1050 static int sd_probe(struct usb_interface *intf,
1051                         const struct usb_device_id *id)
1052 {
1053         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1054                                 THIS_MODULE);
1055 }
1056 
1057 static struct usb_driver sd_driver = {
1058         .name = MODULE_NAME,
1059         .id_table = device_table,
1060         .probe = sd_probe,
1061         .disconnect = gspca_disconnect,
1062 #ifdef CONFIG_PM
1063         .suspend = gspca_suspend,
1064         .resume = gspca_resume,
1065         .reset_resume = gspca_resume,
1066 #endif
1067 };
1068 
1069 module_usb_driver(sd_driver);

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