linux/drivers/media/video/gspca/spca500.c
<<
>>
Prefs
   1/*
   2 * SPCA500 chip based cameras initialization data
   3 *
   4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 *
  20 */
  21
  22#define MODULE_NAME "spca500"
  23
  24#include "gspca.h"
  25#include "jpeg.h"
  26
  27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  28MODULE_DESCRIPTION("GSPCA/SPCA500 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        unsigned char brightness;
  36        unsigned char contrast;
  37        unsigned char colors;
  38        u8 quality;
  39#define QUALITY_MIN 70
  40#define QUALITY_MAX 95
  41#define QUALITY_DEF 85
  42
  43        char subtype;
  44#define AgfaCl20 0
  45#define AiptekPocketDV 1
  46#define BenqDC1016 2
  47#define CreativePCCam300 3
  48#define DLinkDSC350 4
  49#define Gsmartmini 5
  50#define IntelPocketPCCamera 6
  51#define KodakEZ200 7
  52#define LogitechClickSmart310 8
  53#define LogitechClickSmart510 9
  54#define LogitechTraveler 10
  55#define MustekGsmart300 11
  56#define Optimedia 12
  57#define PalmPixDC85 13
  58#define ToptroIndus 14
  59
  60        u8 jpeg_hdr[JPEG_HDR_SZ];
  61};
  62
  63/* V4L2 controls supported by the driver */
  64static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  65static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  66static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
  67static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
  68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
  69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
  70
  71static const struct ctrl sd_ctrls[] = {
  72        {
  73            {
  74                .id      = V4L2_CID_BRIGHTNESS,
  75                .type    = V4L2_CTRL_TYPE_INTEGER,
  76                .name    = "Brightness",
  77                .minimum = 0,
  78                .maximum = 255,
  79                .step    = 1,
  80#define BRIGHTNESS_DEF 127
  81                .default_value = BRIGHTNESS_DEF,
  82            },
  83            .set = sd_setbrightness,
  84            .get = sd_getbrightness,
  85        },
  86        {
  87            {
  88                .id      = V4L2_CID_CONTRAST,
  89                .type    = V4L2_CTRL_TYPE_INTEGER,
  90                .name    = "Contrast",
  91                .minimum = 0,
  92                .maximum = 63,
  93                .step    = 1,
  94#define CONTRAST_DEF 31
  95                .default_value = CONTRAST_DEF,
  96            },
  97            .set = sd_setcontrast,
  98            .get = sd_getcontrast,
  99        },
 100        {
 101            {
 102                .id      = V4L2_CID_SATURATION,
 103                .type    = V4L2_CTRL_TYPE_INTEGER,
 104                .name    = "Color",
 105                .minimum = 0,
 106                .maximum = 63,
 107                .step    = 1,
 108#define COLOR_DEF 31
 109                .default_value = COLOR_DEF,
 110            },
 111            .set = sd_setcolors,
 112            .get = sd_getcolors,
 113        },
 114};
 115
 116static const struct v4l2_pix_format vga_mode[] = {
 117        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 118                .bytesperline = 320,
 119                .sizeimage = 320 * 240 * 3 / 8 + 590,
 120                .colorspace = V4L2_COLORSPACE_JPEG,
 121                .priv = 1},
 122        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 123                .bytesperline = 640,
 124                .sizeimage = 640 * 480 * 3 / 8 + 590,
 125                .colorspace = V4L2_COLORSPACE_JPEG,
 126                .priv = 0},
 127};
 128
 129static const struct v4l2_pix_format sif_mode[] = {
 130        {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 131                .bytesperline = 176,
 132                .sizeimage = 176 * 144 * 3 / 8 + 590,
 133                .colorspace = V4L2_COLORSPACE_JPEG,
 134                .priv = 1},
 135        {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 136                .bytesperline = 352,
 137                .sizeimage = 352 * 288 * 3 / 8 + 590,
 138                .colorspace = V4L2_COLORSPACE_JPEG,
 139                .priv = 0},
 140};
 141
 142/* Frame packet header offsets for the spca500 */
 143#define SPCA500_OFFSET_PADDINGLB 2
 144#define SPCA500_OFFSET_PADDINGHB 3
 145#define SPCA500_OFFSET_MODE      4
 146#define SPCA500_OFFSET_IMGWIDTH  5
 147#define SPCA500_OFFSET_IMGHEIGHT 6
 148#define SPCA500_OFFSET_IMGMODE   7
 149#define SPCA500_OFFSET_QTBLINDEX 8
 150#define SPCA500_OFFSET_FRAMSEQ   9
 151#define SPCA500_OFFSET_CDSPINFO  10
 152#define SPCA500_OFFSET_GPIO      11
 153#define SPCA500_OFFSET_AUGPIO    12
 154#define SPCA500_OFFSET_DATA      16
 155
 156
 157static const __u16 spca500_visual_defaults[][3] = {
 158        {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
 159                                 * hue (H byte) = 0,
 160                                 * saturation/hue enable,
 161                                 * brightness/contrast enable.
 162                                 */
 163        {0x00, 0x0000, 0x8167}, /* brightness = 0 */
 164        {0x00, 0x0020, 0x8168}, /* contrast = 0 */
 165        {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
 166                                 * hue (H byte) = 0, saturation/hue enable,
 167                                 * brightness/contrast enable.
 168                                 * was 0x0003, now 0x0000.
 169                                 */
 170        {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
 171        {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
 172        {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
 173        {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
 174        {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
 175        {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
 176        {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
 177        {0x0c, 0x0004, 0x0000},
 178        /* set interface */
 179        {}
 180};
 181static const __u16 Clicksmart510_defaults[][3] = {
 182        {0x00, 0x00, 0x8211},
 183        {0x00, 0x01, 0x82c0},
 184        {0x00, 0x10, 0x82cb},
 185        {0x00, 0x0f, 0x800d},
 186        {0x00, 0x82, 0x8225},
 187        {0x00, 0x21, 0x8228},
 188        {0x00, 0x00, 0x8203},
 189        {0x00, 0x00, 0x8204},
 190        {0x00, 0x08, 0x8205},
 191        {0x00, 0xf8, 0x8206},
 192        {0x00, 0x28, 0x8207},
 193        {0x00, 0xa0, 0x8208},
 194        {0x00, 0x08, 0x824a},
 195        {0x00, 0x08, 0x8214},
 196        {0x00, 0x80, 0x82c1},
 197        {0x00, 0x00, 0x82c2},
 198        {0x00, 0x00, 0x82ca},
 199        {0x00, 0x80, 0x82c1},
 200        {0x00, 0x04, 0x82c2},
 201        {0x00, 0x00, 0x82ca},
 202        {0x00, 0xfc, 0x8100},
 203        {0x00, 0xfc, 0x8105},
 204        {0x00, 0x30, 0x8101},
 205        {0x00, 0x00, 0x8102},
 206        {0x00, 0x00, 0x8103},
 207        {0x00, 0x66, 0x8107},
 208        {0x00, 0x00, 0x816b},
 209        {0x00, 0x00, 0x8155},
 210        {0x00, 0x01, 0x8156},
 211        {0x00, 0x60, 0x8157},
 212        {0x00, 0x40, 0x8158},
 213        {0x00, 0x0a, 0x8159},
 214        {0x00, 0x06, 0x815a},
 215        {0x00, 0x00, 0x813f},
 216        {0x00, 0x00, 0x8200},
 217        {0x00, 0x19, 0x8201},
 218        {0x00, 0x00, 0x82c1},
 219        {0x00, 0xa0, 0x82c2},
 220        {0x00, 0x00, 0x82ca},
 221        {0x00, 0x00, 0x8117},
 222        {0x00, 0x00, 0x8118},
 223        {0x00, 0x65, 0x8119},
 224        {0x00, 0x00, 0x811a},
 225        {0x00, 0x00, 0x811b},
 226        {0x00, 0x55, 0x811c},
 227        {0x00, 0x65, 0x811d},
 228        {0x00, 0x55, 0x811e},
 229        {0x00, 0x16, 0x811f},
 230        {0x00, 0x19, 0x8120},
 231        {0x00, 0x80, 0x8103},
 232        {0x00, 0x83, 0x816b},
 233        {0x00, 0x25, 0x8168},
 234        {0x00, 0x01, 0x820f},
 235        {0x00, 0xff, 0x8115},
 236        {0x00, 0x48, 0x8116},
 237        {0x00, 0x50, 0x8151},
 238        {0x00, 0x40, 0x8152},
 239        {0x00, 0x78, 0x8153},
 240        {0x00, 0x40, 0x8154},
 241        {0x00, 0x00, 0x8167},
 242        {0x00, 0x20, 0x8168},
 243        {0x00, 0x00, 0x816a},
 244        {0x00, 0x03, 0x816b},
 245        {0x00, 0x20, 0x8169},
 246        {0x00, 0x60, 0x8157},
 247        {0x00, 0x00, 0x8190},
 248        {0x00, 0x00, 0x81a1},
 249        {0x00, 0x00, 0x81b2},
 250        {0x00, 0x27, 0x8191},
 251        {0x00, 0x27, 0x81a2},
 252        {0x00, 0x27, 0x81b3},
 253        {0x00, 0x4b, 0x8192},
 254        {0x00, 0x4b, 0x81a3},
 255        {0x00, 0x4b, 0x81b4},
 256        {0x00, 0x66, 0x8193},
 257        {0x00, 0x66, 0x81a4},
 258        {0x00, 0x66, 0x81b5},
 259        {0x00, 0x79, 0x8194},
 260        {0x00, 0x79, 0x81a5},
 261        {0x00, 0x79, 0x81b6},
 262        {0x00, 0x8a, 0x8195},
 263        {0x00, 0x8a, 0x81a6},
 264        {0x00, 0x8a, 0x81b7},
 265        {0x00, 0x9b, 0x8196},
 266        {0x00, 0x9b, 0x81a7},
 267        {0x00, 0x9b, 0x81b8},
 268        {0x00, 0xa6, 0x8197},
 269        {0x00, 0xa6, 0x81a8},
 270        {0x00, 0xa6, 0x81b9},
 271        {0x00, 0xb2, 0x8198},
 272        {0x00, 0xb2, 0x81a9},
 273        {0x00, 0xb2, 0x81ba},
 274        {0x00, 0xbe, 0x8199},
 275        {0x00, 0xbe, 0x81aa},
 276        {0x00, 0xbe, 0x81bb},
 277        {0x00, 0xc8, 0x819a},
 278        {0x00, 0xc8, 0x81ab},
 279        {0x00, 0xc8, 0x81bc},
 280        {0x00, 0xd2, 0x819b},
 281        {0x00, 0xd2, 0x81ac},
 282        {0x00, 0xd2, 0x81bd},
 283        {0x00, 0xdb, 0x819c},
 284        {0x00, 0xdb, 0x81ad},
 285        {0x00, 0xdb, 0x81be},
 286        {0x00, 0xe4, 0x819d},
 287        {0x00, 0xe4, 0x81ae},
 288        {0x00, 0xe4, 0x81bf},
 289        {0x00, 0xed, 0x819e},
 290        {0x00, 0xed, 0x81af},
 291        {0x00, 0xed, 0x81c0},
 292        {0x00, 0xf7, 0x819f},
 293        {0x00, 0xf7, 0x81b0},
 294        {0x00, 0xf7, 0x81c1},
 295        {0x00, 0xff, 0x81a0},
 296        {0x00, 0xff, 0x81b1},
 297        {0x00, 0xff, 0x81c2},
 298        {0x00, 0x03, 0x8156},
 299        {0x00, 0x00, 0x8211},
 300        {0x00, 0x20, 0x8168},
 301        {0x00, 0x01, 0x8202},
 302        {0x00, 0x30, 0x8101},
 303        {0x00, 0x00, 0x8111},
 304        {0x00, 0x00, 0x8112},
 305        {0x00, 0x00, 0x8113},
 306        {0x00, 0x00, 0x8114},
 307        {}
 308};
 309
 310static const __u8 qtable_creative_pccam[2][64] = {
 311        {                               /* Q-table Y-components */
 312         0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 313         0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
 314         0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
 315         0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
 316         0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
 317         0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
 318         0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
 319         0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
 320        {                               /* Q-table C-components */
 321         0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
 322         0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
 323         0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 324         0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 325         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 326         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 327         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 328         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
 329};
 330
 331static const __u8 qtable_kodak_ez200[2][64] = {
 332        {                               /* Q-table Y-components */
 333         0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
 334         0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
 335         0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
 336         0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
 337         0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
 338         0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
 339         0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
 340         0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
 341        {                               /* Q-table C-components */
 342         0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
 343         0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
 344         0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 345         0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 346         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 347         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 348         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 349         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
 350};
 351
 352static const __u8 qtable_pocketdv[2][64] = {
 353        {               /* Q-table Y-components start registers 0x8800 */
 354         0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
 355         0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
 356         0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
 357         0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
 358         0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
 359         0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
 360         0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
 361         0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
 362         },
 363        {               /* Q-table C-components start registers 0x8840 */
 364         0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
 365         0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
 366         0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
 367         0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 368         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 369         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 370         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 371         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
 372};
 373
 374/* read 'len' bytes to gspca_dev->usb_buf */
 375static void reg_r(struct gspca_dev *gspca_dev,
 376                  __u16 index,
 377                  __u16 length)
 378{
 379        usb_control_msg(gspca_dev->dev,
 380                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 381                        0,
 382                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 383                        0,              /* value */
 384                        index, gspca_dev->usb_buf, length, 500);
 385}
 386
 387static int reg_w(struct gspca_dev *gspca_dev,
 388                     __u16 req, __u16 index, __u16 value)
 389{
 390        int ret;
 391
 392        PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
 393        ret = usb_control_msg(gspca_dev->dev,
 394                        usb_sndctrlpipe(gspca_dev->dev, 0),
 395                        req,
 396                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 397                        value, index, NULL, 0, 500);
 398        if (ret < 0)
 399                err("reg write: error %d", ret);
 400        return ret;
 401}
 402
 403/* returns: negative is error, pos or zero is data */
 404static int reg_r_12(struct gspca_dev *gspca_dev,
 405                        __u16 req,      /* bRequest */
 406                        __u16 index,    /* wIndex */
 407                        __u16 length)   /* wLength (1 or 2 only) */
 408{
 409        int ret;
 410
 411        gspca_dev->usb_buf[1] = 0;
 412        ret = usb_control_msg(gspca_dev->dev,
 413                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 414                        req,
 415                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 416                        0,              /* value */
 417                        index,
 418                        gspca_dev->usb_buf, length,
 419                        500);           /* timeout */
 420        if (ret < 0) {
 421                err("reg_r_12 err %d", ret);
 422                return ret;
 423        }
 424        return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
 425}
 426
 427/*
 428 * Simple function to wait for a given 8-bit value to be returned from
 429 * a reg_read call.
 430 * Returns: negative is error or timeout, zero is success.
 431 */
 432static int reg_r_wait(struct gspca_dev *gspca_dev,
 433                        __u16 reg, __u16 index, __u16 value)
 434{
 435        int ret, cnt = 20;
 436
 437        while (--cnt > 0) {
 438                ret = reg_r_12(gspca_dev, reg, index, 1);
 439                if (ret == value)
 440                        return 0;
 441                msleep(50);
 442        }
 443        return -EIO;
 444}
 445
 446static int write_vector(struct gspca_dev *gspca_dev,
 447                        const __u16 data[][3])
 448{
 449        int ret, i = 0;
 450
 451        while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
 452                ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
 453                if (ret < 0)
 454                        return ret;
 455                i++;
 456        }
 457        return 0;
 458}
 459
 460static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
 461                                unsigned int request,
 462                                unsigned int ybase,
 463                                unsigned int cbase,
 464                                const __u8 qtable[2][64])
 465{
 466        int i, err;
 467
 468        /* loop over y components */
 469        for (i = 0; i < 64; i++) {
 470                err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
 471                if (err < 0)
 472                        return err;
 473        }
 474
 475        /* loop over c components */
 476        for (i = 0; i < 64; i++) {
 477                err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
 478                if (err < 0)
 479                        return err;
 480        }
 481        return 0;
 482}
 483
 484static void spca500_ping310(struct gspca_dev *gspca_dev)
 485{
 486        reg_r(gspca_dev, 0x0d04, 2);
 487        PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
 488                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 489}
 490
 491static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
 492{
 493        reg_r(gspca_dev, 0x0d05, 2);
 494        PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
 495                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 496        reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
 497        spca500_ping310(gspca_dev);
 498
 499        reg_w(gspca_dev, 0x00, 0x8168, 0x22);
 500        reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
 501        reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
 502        reg_w(gspca_dev, 0x00, 0x8169, 0x25);
 503        reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
 504        reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
 505        reg_w(gspca_dev, 0x00, 0x813f, 0x03);
 506        reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
 507        reg_w(gspca_dev, 0x00, 0x8153, 0x78);
 508        reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
 509                                                /* 00 for adjust shutter */
 510        reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
 511        reg_w(gspca_dev, 0x00, 0x8169, 0x25);
 512        reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
 513}
 514
 515static void spca500_setmode(struct gspca_dev *gspca_dev,
 516                        __u8 xmult, __u8 ymult)
 517{
 518        int mode;
 519
 520        /* set x multiplier */
 521        reg_w(gspca_dev, 0, 0x8001, xmult);
 522
 523        /* set y multiplier */
 524        reg_w(gspca_dev, 0, 0x8002, ymult);
 525
 526        /* use compressed mode, VGA, with mode specific subsample */
 527        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 528        reg_w(gspca_dev, 0, 0x8003, mode << 4);
 529}
 530
 531static int spca500_full_reset(struct gspca_dev *gspca_dev)
 532{
 533        int err;
 534
 535        /* send the reset command */
 536        err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
 537        if (err < 0)
 538                return err;
 539
 540        /* wait for the reset to complete */
 541        err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
 542        if (err < 0)
 543                return err;
 544        err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
 545        if (err < 0)
 546                return err;
 547        err = reg_r_wait(gspca_dev, 0x06, 0, 0);
 548        if (err < 0) {
 549                PDEBUG(D_ERR, "reg_r_wait() failed");
 550                return err;
 551        }
 552        /* all ok */
 553        return 0;
 554}
 555
 556/* Synchro the Bridge with sensor */
 557/* Maybe that will work on all spca500 chip */
 558/* because i only own a clicksmart310 try for that chip */
 559/* using spca50x_set_packet_size() cause an Ooops here */
 560/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
 561/* up-port the same feature as in 2.4.x kernel */
 562static int spca500_synch310(struct gspca_dev *gspca_dev)
 563{
 564        if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
 565                PDEBUG(D_ERR, "Set packet size: set interface error");
 566                goto error;
 567        }
 568        spca500_ping310(gspca_dev);
 569
 570        reg_r(gspca_dev, 0x0d00, 1);
 571
 572        /* need alt setting here */
 573        PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
 574
 575        /* Windoze use pipe with altsetting 6 why 7 here */
 576        if (usb_set_interface(gspca_dev->dev,
 577                                gspca_dev->iface,
 578                                gspca_dev->alt) < 0) {
 579                PDEBUG(D_ERR, "Set packet size: set interface error");
 580                goto error;
 581        }
 582        return 0;
 583error:
 584        return -EBUSY;
 585}
 586
 587static void spca500_reinit(struct gspca_dev *gspca_dev)
 588{
 589        int err;
 590        __u8 Data;
 591
 592        /* some unknown command from Aiptek pocket dv and family300 */
 593
 594        reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 595        reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
 596        reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
 597
 598        /* enable drop packet */
 599        reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 600
 601        err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
 602                                 qtable_pocketdv);
 603        if (err < 0)
 604                PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
 605
 606        /* set qtable index */
 607        reg_w(gspca_dev, 0x00, 0x8880, 2);
 608        /* family cam Quicksmart stuff */
 609        reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 610        /* Set agc transfer: synced between frames */
 611        reg_w(gspca_dev, 0x00, 0x820f, 0x01);
 612        /* Init SDRAM - needed for SDRAM access */
 613        reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 614        /*Start init sequence or stream */
 615        reg_w(gspca_dev, 0, 0x8003, 0x00);
 616        /* switch to video camera mode */
 617        reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 618        msleep(2000);
 619        if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
 620                reg_r(gspca_dev, 0x816b, 1);
 621                Data = gspca_dev->usb_buf[0];
 622                reg_w(gspca_dev, 0x00, 0x816b, Data);
 623        }
 624}
 625
 626/* this function is called at probe time */
 627static int sd_config(struct gspca_dev *gspca_dev,
 628                        const struct usb_device_id *id)
 629{
 630        struct sd *sd = (struct sd *) gspca_dev;
 631        struct cam *cam;
 632
 633        cam = &gspca_dev->cam;
 634        sd->subtype = id->driver_info;
 635        if (sd->subtype != LogitechClickSmart310) {
 636                cam->cam_mode = vga_mode;
 637                cam->nmodes = ARRAY_SIZE(vga_mode);
 638        } else {
 639                cam->cam_mode = sif_mode;
 640                cam->nmodes = ARRAY_SIZE(sif_mode);
 641        }
 642        sd->brightness = BRIGHTNESS_DEF;
 643        sd->contrast = CONTRAST_DEF;
 644        sd->colors = COLOR_DEF;
 645        sd->quality = QUALITY_DEF;
 646        return 0;
 647}
 648
 649/* this function is called at probe and resume time */
 650static int sd_init(struct gspca_dev *gspca_dev)
 651{
 652        struct sd *sd = (struct sd *) gspca_dev;
 653
 654        /* initialisation of spca500 based cameras is deferred */
 655        PDEBUG(D_STREAM, "SPCA500 init");
 656        if (sd->subtype == LogitechClickSmart310)
 657                spca500_clksmart310_init(gspca_dev);
 658/*      else
 659                spca500_initialise(gspca_dev); */
 660        PDEBUG(D_STREAM, "SPCA500 init done");
 661        return 0;
 662}
 663
 664static int sd_start(struct gspca_dev *gspca_dev)
 665{
 666        struct sd *sd = (struct sd *) gspca_dev;
 667        int err;
 668        __u8 Data;
 669        __u8 xmult, ymult;
 670
 671        /* create the JPEG header */
 672        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 673                        0x22);          /* JPEG 411 */
 674        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 675
 676        if (sd->subtype == LogitechClickSmart310) {
 677                xmult = 0x16;
 678                ymult = 0x12;
 679        } else {
 680                xmult = 0x28;
 681                ymult = 0x1e;
 682        }
 683
 684        /* is there a sensor here ? */
 685        reg_r(gspca_dev, 0x8a04, 1);
 686        PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
 687                gspca_dev->usb_buf[0]);
 688        PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
 689                gspca_dev->curr_mode, xmult, ymult);
 690
 691        /* setup qtable */
 692        switch (sd->subtype) {
 693        case LogitechClickSmart310:
 694                 spca500_setmode(gspca_dev, xmult, ymult);
 695
 696                /* enable drop packet */
 697                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 698                reg_w(gspca_dev, 0x00, 0x8880, 3);
 699                err = spca50x_setup_qtable(gspca_dev,
 700                                           0x00, 0x8800, 0x8840,
 701                                           qtable_creative_pccam);
 702                if (err < 0)
 703                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 704                /* Init SDRAM - needed for SDRAM access */
 705                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 706
 707                /* switch to video camera mode */
 708                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 709                msleep(500);
 710                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 711                        PDEBUG(D_ERR, "reg_r_wait() failed");
 712
 713                reg_r(gspca_dev, 0x816b, 1);
 714                Data = gspca_dev->usb_buf[0];
 715                reg_w(gspca_dev, 0x00, 0x816b, Data);
 716
 717                spca500_synch310(gspca_dev);
 718
 719                write_vector(gspca_dev, spca500_visual_defaults);
 720                spca500_setmode(gspca_dev, xmult, ymult);
 721                /* enable drop packet */
 722                err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 723                if (err < 0)
 724                        PDEBUG(D_ERR, "failed to enable drop packet");
 725                reg_w(gspca_dev, 0x00, 0x8880, 3);
 726                err = spca50x_setup_qtable(gspca_dev,
 727                                           0x00, 0x8800, 0x8840,
 728                                           qtable_creative_pccam);
 729                if (err < 0)
 730                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 731
 732                /* Init SDRAM - needed for SDRAM access */
 733                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 734
 735                /* switch to video camera mode */
 736                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 737
 738                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 739                        PDEBUG(D_ERR, "reg_r_wait() failed");
 740
 741                reg_r(gspca_dev, 0x816b, 1);
 742                Data = gspca_dev->usb_buf[0];
 743                reg_w(gspca_dev, 0x00, 0x816b, Data);
 744                break;
 745        case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
 746        case IntelPocketPCCamera:       /* FIXME: Temporary fix for
 747                                         *      Intel Pocket PC Camera
 748                                         *      - NWG (Sat 29th March 2003) */
 749
 750                /* do a full reset */
 751                err = spca500_full_reset(gspca_dev);
 752                if (err < 0)
 753                        PDEBUG(D_ERR, "spca500_full_reset failed");
 754
 755                /* enable drop packet */
 756                err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 757                if (err < 0)
 758                        PDEBUG(D_ERR, "failed to enable drop packet");
 759                reg_w(gspca_dev, 0x00, 0x8880, 3);
 760                err = spca50x_setup_qtable(gspca_dev,
 761                                           0x00, 0x8800, 0x8840,
 762                                           qtable_creative_pccam);
 763                if (err < 0)
 764                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 765
 766                spca500_setmode(gspca_dev, xmult, ymult);
 767                reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
 768
 769                /* switch to video camera mode */
 770                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 771
 772                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 773                        PDEBUG(D_ERR, "reg_r_wait() failed");
 774
 775                reg_r(gspca_dev, 0x816b, 1);
 776                Data = gspca_dev->usb_buf[0];
 777                reg_w(gspca_dev, 0x00, 0x816b, Data);
 778
 779/*              write_vector(gspca_dev, spca500_visual_defaults); */
 780                break;
 781        case KodakEZ200:                /* Kodak EZ200 */
 782
 783                /* do a full reset */
 784                err = spca500_full_reset(gspca_dev);
 785                if (err < 0)
 786                        PDEBUG(D_ERR, "spca500_full_reset failed");
 787                /* enable drop packet */
 788                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 789                reg_w(gspca_dev, 0x00, 0x8880, 0);
 790                err = spca50x_setup_qtable(gspca_dev,
 791                                           0x00, 0x8800, 0x8840,
 792                                           qtable_kodak_ez200);
 793                if (err < 0)
 794                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 795                spca500_setmode(gspca_dev, xmult, ymult);
 796
 797                reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
 798
 799                /* switch to video camera mode */
 800                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 801
 802                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 803                        PDEBUG(D_ERR, "reg_r_wait() failed");
 804
 805                reg_r(gspca_dev, 0x816b, 1);
 806                Data = gspca_dev->usb_buf[0];
 807                reg_w(gspca_dev, 0x00, 0x816b, Data);
 808
 809/*              write_vector(gspca_dev, spca500_visual_defaults); */
 810                break;
 811
 812        case BenqDC1016:
 813        case DLinkDSC350:               /* FamilyCam 300 */
 814        case AiptekPocketDV:            /* Aiptek PocketDV */
 815        case Gsmartmini:                /*Mustek Gsmart Mini */
 816        case MustekGsmart300:           /* Mustek Gsmart 300 */
 817        case PalmPixDC85:
 818        case Optimedia:
 819        case ToptroIndus:
 820        case AgfaCl20:
 821                spca500_reinit(gspca_dev);
 822                reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 823                /* enable drop packet */
 824                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 825
 826                err = spca50x_setup_qtable(gspca_dev,
 827                                   0x00, 0x8800, 0x8840, qtable_pocketdv);
 828                if (err < 0)
 829                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 830                reg_w(gspca_dev, 0x00, 0x8880, 2);
 831
 832                /* familycam Quicksmart pocketDV stuff */
 833                reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 834                /* Set agc transfer: synced between frames */
 835                reg_w(gspca_dev, 0x00, 0x820f, 0x01);
 836                /* Init SDRAM - needed for SDRAM access */
 837                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 838
 839                spca500_setmode(gspca_dev, xmult, ymult);
 840                /* switch to video camera mode */
 841                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 842
 843                reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
 844
 845                reg_r(gspca_dev, 0x816b, 1);
 846                Data = gspca_dev->usb_buf[0];
 847                reg_w(gspca_dev, 0x00, 0x816b, Data);
 848                break;
 849        case LogitechTraveler:
 850        case LogitechClickSmart510:
 851                reg_w(gspca_dev, 0x02, 0x00, 0x00);
 852                /* enable drop packet */
 853                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 854
 855                err = spca50x_setup_qtable(gspca_dev,
 856                                        0x00, 0x8800,
 857                                        0x8840, qtable_creative_pccam);
 858                if (err < 0)
 859                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 860                reg_w(gspca_dev, 0x00, 0x8880, 3);
 861                reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 862                /* Init SDRAM - needed for SDRAM access */
 863                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 864
 865                spca500_setmode(gspca_dev, xmult, ymult);
 866
 867                /* switch to video camera mode */
 868                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 869                reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
 870
 871                reg_r(gspca_dev, 0x816b, 1);
 872                Data = gspca_dev->usb_buf[0];
 873                reg_w(gspca_dev, 0x00, 0x816b, Data);
 874                write_vector(gspca_dev, Clicksmart510_defaults);
 875                break;
 876        }
 877        return 0;
 878}
 879
 880static void sd_stopN(struct gspca_dev *gspca_dev)
 881{
 882        reg_w(gspca_dev, 0, 0x8003, 0x00);
 883
 884        /* switch to video camera mode */
 885        reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 886        reg_r(gspca_dev, 0x8000, 1);
 887        PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
 888                gspca_dev->usb_buf[0]);
 889}
 890
 891static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 892                        u8 *data,                       /* isoc packet */
 893                        int len)                        /* iso packet length */
 894{
 895        struct sd *sd = (struct sd *) gspca_dev;
 896        int i;
 897        static __u8 ffd9[] = {0xff, 0xd9};
 898
 899/* frames are jpeg 4.1.1 without 0xff escape */
 900        if (data[0] == 0xff) {
 901                if (data[1] != 0x01) {  /* drop packet */
 902/*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
 903                        return;
 904                }
 905                gspca_frame_add(gspca_dev, LAST_PACKET,
 906                                        ffd9, 2);
 907
 908                /* put the JPEG header in the new frame */
 909                gspca_frame_add(gspca_dev, FIRST_PACKET,
 910                        sd->jpeg_hdr, JPEG_HDR_SZ);
 911
 912                data += SPCA500_OFFSET_DATA;
 913                len -= SPCA500_OFFSET_DATA;
 914        } else {
 915                data += 1;
 916                len -= 1;
 917        }
 918
 919        /* add 0x00 after 0xff */
 920        i = 0;
 921        do {
 922                if (data[i] == 0xff) {
 923                        gspca_frame_add(gspca_dev, INTER_PACKET,
 924                                        data, i + 1);
 925                        len -= i;
 926                        data += i;
 927                        *data = 0x00;
 928                        i = 0;
 929                }
 930                i++;
 931        } while (i < len);
 932        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 933}
 934
 935static void setbrightness(struct gspca_dev *gspca_dev)
 936{
 937        struct sd *sd = (struct sd *) gspca_dev;
 938
 939        reg_w(gspca_dev, 0x00, 0x8167,
 940                        (__u8) (sd->brightness - 128));
 941}
 942
 943static void setcontrast(struct gspca_dev *gspca_dev)
 944{
 945        struct sd *sd = (struct sd *) gspca_dev;
 946
 947        reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
 948}
 949
 950static void setcolors(struct gspca_dev *gspca_dev)
 951{
 952        struct sd *sd = (struct sd *) gspca_dev;
 953
 954        reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
 955}
 956
 957static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 958{
 959        struct sd *sd = (struct sd *) gspca_dev;
 960
 961        sd->brightness = val;
 962        if (gspca_dev->streaming)
 963                setbrightness(gspca_dev);
 964        return 0;
 965}
 966
 967static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
 968{
 969        struct sd *sd = (struct sd *) gspca_dev;
 970
 971        *val = sd->brightness;
 972        return 0;
 973}
 974
 975static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 976{
 977        struct sd *sd = (struct sd *) gspca_dev;
 978
 979        sd->contrast = val;
 980        if (gspca_dev->streaming)
 981                setcontrast(gspca_dev);
 982        return 0;
 983}
 984
 985static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
 986{
 987        struct sd *sd = (struct sd *) gspca_dev;
 988
 989        *val = sd->contrast;
 990        return 0;
 991}
 992
 993static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
 994{
 995        struct sd *sd = (struct sd *) gspca_dev;
 996
 997        sd->colors = val;
 998        if (gspca_dev->streaming)
 999                setcolors(gspca_dev);
1000        return 0;
1001}
1002
1003static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1004{
1005        struct sd *sd = (struct sd *) gspca_dev;
1006
1007        *val = sd->colors;
1008        return 0;
1009}
1010
1011static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1012                        struct v4l2_jpegcompression *jcomp)
1013{
1014        struct sd *sd = (struct sd *) gspca_dev;
1015
1016        if (jcomp->quality < QUALITY_MIN)
1017                sd->quality = QUALITY_MIN;
1018        else if (jcomp->quality > QUALITY_MAX)
1019                sd->quality = QUALITY_MAX;
1020        else
1021                sd->quality = jcomp->quality;
1022        if (gspca_dev->streaming)
1023                jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1024        return 0;
1025}
1026
1027static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1028                        struct v4l2_jpegcompression *jcomp)
1029{
1030        struct sd *sd = (struct sd *) gspca_dev;
1031
1032        memset(jcomp, 0, sizeof *jcomp);
1033        jcomp->quality = sd->quality;
1034        jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1035                        | V4L2_JPEG_MARKER_DQT;
1036        return 0;
1037}
1038
1039/* sub-driver description */
1040static const struct sd_desc sd_desc = {
1041        .name = MODULE_NAME,
1042        .ctrls = sd_ctrls,
1043        .nctrls = ARRAY_SIZE(sd_ctrls),
1044        .config = sd_config,
1045        .init = sd_init,
1046        .start = sd_start,
1047        .stopN = sd_stopN,
1048        .pkt_scan = sd_pkt_scan,
1049        .get_jcomp = sd_get_jcomp,
1050        .set_jcomp = sd_set_jcomp,
1051};
1052
1053/* -- module initialisation -- */
1054static const struct usb_device_id device_table[] = {
1055        {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1056        {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1057        {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1058        {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1059        {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1060        {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1061        {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1062        {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1063        {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1064        {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1065        {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1066        {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1067        {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1068        {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1069        {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1070        {}
1071};
1072MODULE_DEVICE_TABLE(usb, device_table);
1073
1074/* -- device connect -- */
1075static int sd_probe(struct usb_interface *intf,
1076                        const struct usb_device_id *id)
1077{
1078        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1079                                THIS_MODULE);
1080}
1081
1082static struct usb_driver sd_driver = {
1083        .name = MODULE_NAME,
1084        .id_table = device_table,
1085        .probe = sd_probe,
1086        .disconnect = gspca_disconnect,
1087#ifdef CONFIG_PM
1088        .suspend = gspca_suspend,
1089        .resume = gspca_resume,
1090#endif
1091};
1092
1093/* -- module insert / remove -- */
1094static int __init sd_mod_init(void)
1095{
1096        return usb_register(&sd_driver);
1097}
1098static void __exit sd_mod_exit(void)
1099{
1100        usb_deregister(&sd_driver);
1101}
1102
1103module_init(sd_mod_init);
1104module_exit(sd_mod_exit);
1105