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