linux/drivers/media/usb/gspca/spca506.c
<<
>>
Prefs
   1/*
   2 * SPCA506 chip based cameras function
   3 * M Xhaard 15/04/2004 based on different work Mark Taylor and others
   4 * and my own snoopy file on a pv-321c donate by a german compagny
   5 *                "Firma Frank Gmbh" from  Saarbruecken
   6 *
   7 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 * GNU General Public License for more details.
  18 */
  19
  20#define MODULE_NAME "spca506"
  21
  22#include "gspca.h"
  23
  24MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  25MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
  26MODULE_LICENSE("GPL");
  27
  28/* specific webcam descriptor */
  29struct sd {
  30        struct gspca_dev gspca_dev;     /* !! must be the first item */
  31
  32        char norme;
  33        char channel;
  34};
  35
  36static const struct v4l2_pix_format vga_mode[] = {
  37        {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  38                .bytesperline = 160,
  39                .sizeimage = 160 * 120 * 3 / 2,
  40                .colorspace = V4L2_COLORSPACE_SRGB,
  41                .priv = 5},
  42        {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  43                .bytesperline = 176,
  44                .sizeimage = 176 * 144 * 3 / 2,
  45                .colorspace = V4L2_COLORSPACE_SRGB,
  46                .priv = 4},
  47        {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  48                .bytesperline = 320,
  49                .sizeimage = 320 * 240 * 3 / 2,
  50                .colorspace = V4L2_COLORSPACE_SRGB,
  51                .priv = 2},
  52        {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  53                .bytesperline = 352,
  54                .sizeimage = 352 * 288 * 3 / 2,
  55                .colorspace = V4L2_COLORSPACE_SRGB,
  56                .priv = 1},
  57        {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  58                .bytesperline = 640,
  59                .sizeimage = 640 * 480 * 3 / 2,
  60                .colorspace = V4L2_COLORSPACE_SRGB,
  61                .priv = 0},
  62};
  63
  64#define SPCA50X_OFFSET_DATA 10
  65
  66#define SAA7113_bright 0x0a     /* defaults 0x80 */
  67#define SAA7113_contrast 0x0b   /* defaults 0x47 */
  68#define SAA7113_saturation 0x0c /* defaults 0x40 */
  69#define SAA7113_hue 0x0d        /* defaults 0x00 */
  70#define SAA7113_I2C_BASE_WRITE 0x4a
  71
  72/* read 'len' bytes to gspca_dev->usb_buf */
  73static void reg_r(struct gspca_dev *gspca_dev,
  74                  __u16 req,
  75                  __u16 index,
  76                  __u16 length)
  77{
  78        usb_control_msg(gspca_dev->dev,
  79                        usb_rcvctrlpipe(gspca_dev->dev, 0),
  80                        req,
  81                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  82                        0,              /* value */
  83                        index, gspca_dev->usb_buf, length,
  84                        500);
  85}
  86
  87static void reg_w(struct usb_device *dev,
  88                  __u16 req,
  89                  __u16 value,
  90                  __u16 index)
  91{
  92        usb_control_msg(dev,
  93                        usb_sndctrlpipe(dev, 0),
  94                        req,
  95                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  96                        value, index,
  97                        NULL, 0, 500);
  98}
  99
 100static void spca506_Initi2c(struct gspca_dev *gspca_dev)
 101{
 102        reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
 103}
 104
 105static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
 106                             __u16 reg)
 107{
 108        int retry = 60;
 109
 110        reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
 111        reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
 112        while (retry--) {
 113                reg_r(gspca_dev, 0x07, 0x0003, 2);
 114                if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
 115                        break;
 116        }
 117}
 118
 119static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
 120                                 __u16 norme,
 121                                 __u16 channel)
 122{
 123        struct sd *sd = (struct sd *) gspca_dev;
 124/* fixme: check if channel == 0..3 and 6..9 (8 values) */
 125        __u8 setbit0 = 0x00;
 126        __u8 setbit1 = 0x00;
 127        __u8 videomask = 0x00;
 128
 129        gspca_dbg(gspca_dev, D_STREAM, "** Open Set Norme **\n");
 130        spca506_Initi2c(gspca_dev);
 131        /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
 132        /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
 133        /* and exclude SAA7113 reserved channel set default 0 otherwise */
 134        if (norme & V4L2_STD_NTSC)
 135                setbit0 = 0x01;
 136        if (channel == 4 || channel == 5 || channel > 9)
 137                channel = 0;
 138        if (channel < 4)
 139                setbit1 = 0x02;
 140        videomask = (0x48 | setbit0 | setbit1);
 141        reg_w(gspca_dev->dev, 0x08, videomask, 0x0000);
 142        spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02);
 143
 144        if (norme & V4L2_STD_NTSC)
 145                spca506_WriteI2c(gspca_dev, 0x33, 0x0e);
 146                                        /* Chrominance Control NTSC N */
 147        else if (norme & V4L2_STD_SECAM)
 148                spca506_WriteI2c(gspca_dev, 0x53, 0x0e);
 149                                        /* Chrominance Control SECAM */
 150        else
 151                spca506_WriteI2c(gspca_dev, 0x03, 0x0e);
 152                                        /* Chrominance Control PAL BGHIV */
 153
 154        sd->norme = norme;
 155        sd->channel = channel;
 156        gspca_dbg(gspca_dev, D_STREAM, "Set Video Byte to 0x%2x\n", videomask);
 157        gspca_dbg(gspca_dev, D_STREAM, "Set Norme: %08x Channel %d",
 158                  norme, channel);
 159}
 160
 161static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
 162                                  __u16 *norme, __u16 *channel)
 163{
 164        struct sd *sd = (struct sd *) gspca_dev;
 165
 166        /* Read the register is not so good value change so
 167           we use your own copy in spca50x struct */
 168        *norme = sd->norme;
 169        *channel = sd->channel;
 170        gspca_dbg(gspca_dev, D_STREAM, "Get Norme: %d Channel %d\n",
 171                  *norme, *channel);
 172}
 173
 174static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
 175                            __u16 xmult, __u16 ymult)
 176{
 177        struct usb_device *dev = gspca_dev->dev;
 178
 179        gspca_dbg(gspca_dev, D_STREAM, "** SetSize **\n");
 180        reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
 181        /* Soft snap 0x40 Hard 0x41 */
 182        reg_w(dev, 0x04, 0x41, 0x0001);
 183        reg_w(dev, 0x04, 0x00, 0x0002);
 184        /* reserved */
 185        reg_w(dev, 0x04, 0x00, 0x0003);
 186
 187        /* reserved */
 188        reg_w(dev, 0x04, 0x00, 0x0004);
 189        /* reserved */
 190        reg_w(dev, 0x04, 0x01, 0x0005);
 191        /* reserced */
 192        reg_w(dev, 0x04, xmult, 0x0006);
 193        /* reserved */
 194        reg_w(dev, 0x04, ymult, 0x0007);
 195        /* compression 1 */
 196        reg_w(dev, 0x04, 0x00, 0x0008);
 197        /* T=64 -> 2 */
 198        reg_w(dev, 0x04, 0x00, 0x0009);
 199        /* threshold2D */
 200        reg_w(dev, 0x04, 0x21, 0x000a);
 201        /* quantization */
 202        reg_w(dev, 0x04, 0x00, 0x000b);
 203}
 204
 205/* this function is called at probe time */
 206static int sd_config(struct gspca_dev *gspca_dev,
 207                        const struct usb_device_id *id)
 208{
 209        struct cam *cam;
 210
 211        cam = &gspca_dev->cam;
 212        cam->cam_mode = vga_mode;
 213        cam->nmodes = ARRAY_SIZE(vga_mode);
 214        return 0;
 215}
 216
 217/* this function is called at probe and resume time */
 218static int sd_init(struct gspca_dev *gspca_dev)
 219{
 220        struct usb_device *dev = gspca_dev->dev;
 221
 222        reg_w(dev, 0x03, 0x00, 0x0004);
 223        reg_w(dev, 0x03, 0xFF, 0x0003);
 224        reg_w(dev, 0x03, 0x00, 0x0000);
 225        reg_w(dev, 0x03, 0x1c, 0x0001);
 226        reg_w(dev, 0x03, 0x18, 0x0001);
 227        /* Init on PAL and composite input0 */
 228        spca506_SetNormeInput(gspca_dev, 0, 0);
 229        reg_w(dev, 0x03, 0x1c, 0x0001);
 230        reg_w(dev, 0x03, 0x18, 0x0001);
 231        reg_w(dev, 0x05, 0x00, 0x0000);
 232        reg_w(dev, 0x05, 0xef, 0x0001);
 233        reg_w(dev, 0x05, 0x00, 0x00c1);
 234        reg_w(dev, 0x05, 0x00, 0x00c2);
 235        reg_w(dev, 0x06, 0x18, 0x0002);
 236        reg_w(dev, 0x06, 0xf5, 0x0011);
 237        reg_w(dev, 0x06, 0x02, 0x0012);
 238        reg_w(dev, 0x06, 0xfb, 0x0013);
 239        reg_w(dev, 0x06, 0x00, 0x0014);
 240        reg_w(dev, 0x06, 0xa4, 0x0051);
 241        reg_w(dev, 0x06, 0x40, 0x0052);
 242        reg_w(dev, 0x06, 0x71, 0x0053);
 243        reg_w(dev, 0x06, 0x40, 0x0054);
 244        /************************************************/
 245        reg_w(dev, 0x03, 0x00, 0x0004);
 246        reg_w(dev, 0x03, 0x00, 0x0003);
 247        reg_w(dev, 0x03, 0x00, 0x0004);
 248        reg_w(dev, 0x03, 0xFF, 0x0003);
 249        reg_w(dev, 0x02, 0x00, 0x0000);
 250        reg_w(dev, 0x03, 0x60, 0x0000);
 251        reg_w(dev, 0x03, 0x18, 0x0001);
 252        /* for a better reading mx :)     */
 253        /*sdca506_WriteI2c(value,register) */
 254        spca506_Initi2c(gspca_dev);
 255        spca506_WriteI2c(gspca_dev, 0x08, 0x01);
 256        spca506_WriteI2c(gspca_dev, 0xc0, 0x02);
 257                                                /* input composite video */
 258        spca506_WriteI2c(gspca_dev, 0x33, 0x03);
 259        spca506_WriteI2c(gspca_dev, 0x00, 0x04);
 260        spca506_WriteI2c(gspca_dev, 0x00, 0x05);
 261        spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
 262        spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
 263        spca506_WriteI2c(gspca_dev, 0x98, 0x08);
 264        spca506_WriteI2c(gspca_dev, 0x03, 0x09);
 265        spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
 266        spca506_WriteI2c(gspca_dev, 0x47, 0x0b);
 267        spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
 268        spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
 269        spca506_WriteI2c(gspca_dev, 0x03, 0x0e);        /* Chroma Pal adjust */
 270        spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
 271        spca506_WriteI2c(gspca_dev, 0x00, 0x10);
 272        spca506_WriteI2c(gspca_dev, 0x0c, 0x11);
 273        spca506_WriteI2c(gspca_dev, 0xb8, 0x12);
 274        spca506_WriteI2c(gspca_dev, 0x01, 0x13);
 275        spca506_WriteI2c(gspca_dev, 0x00, 0x14);
 276        spca506_WriteI2c(gspca_dev, 0x00, 0x15);
 277        spca506_WriteI2c(gspca_dev, 0x00, 0x16);
 278        spca506_WriteI2c(gspca_dev, 0x00, 0x17);
 279        spca506_WriteI2c(gspca_dev, 0x00, 0x18);
 280        spca506_WriteI2c(gspca_dev, 0x00, 0x19);
 281        spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
 282        spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
 283        spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
 284        spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
 285        spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
 286        spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
 287        spca506_WriteI2c(gspca_dev, 0x02, 0x40);
 288        spca506_WriteI2c(gspca_dev, 0xff, 0x41);
 289        spca506_WriteI2c(gspca_dev, 0xff, 0x42);
 290        spca506_WriteI2c(gspca_dev, 0xff, 0x43);
 291        spca506_WriteI2c(gspca_dev, 0xff, 0x44);
 292        spca506_WriteI2c(gspca_dev, 0xff, 0x45);
 293        spca506_WriteI2c(gspca_dev, 0xff, 0x46);
 294        spca506_WriteI2c(gspca_dev, 0xff, 0x47);
 295        spca506_WriteI2c(gspca_dev, 0xff, 0x48);
 296        spca506_WriteI2c(gspca_dev, 0xff, 0x49);
 297        spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
 298        spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
 299        spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
 300        spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
 301        spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
 302        spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
 303        spca506_WriteI2c(gspca_dev, 0xff, 0x50);
 304        spca506_WriteI2c(gspca_dev, 0xff, 0x51);
 305        spca506_WriteI2c(gspca_dev, 0xff, 0x52);
 306        spca506_WriteI2c(gspca_dev, 0xff, 0x53);
 307        spca506_WriteI2c(gspca_dev, 0xff, 0x54);
 308        spca506_WriteI2c(gspca_dev, 0xff, 0x55);
 309        spca506_WriteI2c(gspca_dev, 0xff, 0x56);
 310        spca506_WriteI2c(gspca_dev, 0xff, 0x57);
 311        spca506_WriteI2c(gspca_dev, 0x00, 0x58);
 312        spca506_WriteI2c(gspca_dev, 0x54, 0x59);
 313        spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
 314        spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
 315        spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
 316        spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
 317        spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
 318        spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
 319        spca506_WriteI2c(gspca_dev, 0x00, 0x60);
 320        spca506_WriteI2c(gspca_dev, 0x05, 0x61);
 321        spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
 322        gspca_dbg(gspca_dev, D_STREAM, "** Close Init *\n");
 323        return 0;
 324}
 325
 326static int sd_start(struct gspca_dev *gspca_dev)
 327{
 328        struct usb_device *dev = gspca_dev->dev;
 329        __u16 norme;
 330        __u16 channel;
 331
 332        /**************************************/
 333        reg_w(dev, 0x03, 0x00, 0x0004);
 334        reg_w(dev, 0x03, 0x00, 0x0003);
 335        reg_w(dev, 0x03, 0x00, 0x0004);
 336        reg_w(dev, 0x03, 0xFF, 0x0003);
 337        reg_w(dev, 0x02, 0x00, 0x0000);
 338        reg_w(dev, 0x03, 0x60, 0x0000);
 339        reg_w(dev, 0x03, 0x18, 0x0001);
 340
 341        /*sdca506_WriteI2c(value,register) */
 342        spca506_Initi2c(gspca_dev);
 343        spca506_WriteI2c(gspca_dev, 0x08, 0x01);        /* Increment Delay */
 344/*      spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */
 345        spca506_WriteI2c(gspca_dev, 0x33, 0x03);
 346                                                /* Analog Input Control 2 */
 347        spca506_WriteI2c(gspca_dev, 0x00, 0x04);
 348                                                /* Analog Input Control 3 */
 349        spca506_WriteI2c(gspca_dev, 0x00, 0x05);
 350                                                /* Analog Input Control 4 */
 351        spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
 352                                        /* Horizontal Sync Start 0xe9-0x0d */
 353        spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
 354                                        /* Horizontal Sync Stop  0x0d-0xf0 */
 355
 356        spca506_WriteI2c(gspca_dev, 0x98, 0x08);        /* Sync Control */
 357/*              Defaults value                  */
 358        spca506_WriteI2c(gspca_dev, 0x03, 0x09);        /* Luminance Control */
 359        spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
 360                                                /* Luminance Brightness */
 361        spca506_WriteI2c(gspca_dev, 0x47, 0x0b);        /* Luminance Contrast */
 362        spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
 363                                                /* Chrominance Saturation */
 364        spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
 365                                                /* Chrominance Hue Control */
 366        spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
 367                                                /* Chrominance Gain Control */
 368        /**************************************/
 369        spca506_WriteI2c(gspca_dev, 0x00, 0x10);
 370                                                /* Format/Delay Control */
 371        spca506_WriteI2c(gspca_dev, 0x0c, 0x11);        /* Output Control 1 */
 372        spca506_WriteI2c(gspca_dev, 0xb8, 0x12);        /* Output Control 2 */
 373        spca506_WriteI2c(gspca_dev, 0x01, 0x13);        /* Output Control 3 */
 374        spca506_WriteI2c(gspca_dev, 0x00, 0x14);        /* reserved */
 375        spca506_WriteI2c(gspca_dev, 0x00, 0x15);        /* VGATE START */
 376        spca506_WriteI2c(gspca_dev, 0x00, 0x16);        /* VGATE STOP */
 377        spca506_WriteI2c(gspca_dev, 0x00, 0x17);    /* VGATE Control (MSB) */
 378        spca506_WriteI2c(gspca_dev, 0x00, 0x18);
 379        spca506_WriteI2c(gspca_dev, 0x00, 0x19);
 380        spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
 381        spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
 382        spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
 383        spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
 384        spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
 385        spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
 386        spca506_WriteI2c(gspca_dev, 0x02, 0x40);
 387        spca506_WriteI2c(gspca_dev, 0xff, 0x41);
 388        spca506_WriteI2c(gspca_dev, 0xff, 0x42);
 389        spca506_WriteI2c(gspca_dev, 0xff, 0x43);
 390        spca506_WriteI2c(gspca_dev, 0xff, 0x44);
 391        spca506_WriteI2c(gspca_dev, 0xff, 0x45);
 392        spca506_WriteI2c(gspca_dev, 0xff, 0x46);
 393        spca506_WriteI2c(gspca_dev, 0xff, 0x47);
 394        spca506_WriteI2c(gspca_dev, 0xff, 0x48);
 395        spca506_WriteI2c(gspca_dev, 0xff, 0x49);
 396        spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
 397        spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
 398        spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
 399        spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
 400        spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
 401        spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
 402        spca506_WriteI2c(gspca_dev, 0xff, 0x50);
 403        spca506_WriteI2c(gspca_dev, 0xff, 0x51);
 404        spca506_WriteI2c(gspca_dev, 0xff, 0x52);
 405        spca506_WriteI2c(gspca_dev, 0xff, 0x53);
 406        spca506_WriteI2c(gspca_dev, 0xff, 0x54);
 407        spca506_WriteI2c(gspca_dev, 0xff, 0x55);
 408        spca506_WriteI2c(gspca_dev, 0xff, 0x56);
 409        spca506_WriteI2c(gspca_dev, 0xff, 0x57);
 410        spca506_WriteI2c(gspca_dev, 0x00, 0x58);
 411        spca506_WriteI2c(gspca_dev, 0x54, 0x59);
 412        spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
 413        spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
 414        spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
 415        spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
 416        spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
 417        spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
 418        spca506_WriteI2c(gspca_dev, 0x00, 0x60);
 419        spca506_WriteI2c(gspca_dev, 0x05, 0x61);
 420        spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
 421        /**************************************/
 422        reg_w(dev, 0x05, 0x00, 0x0003);
 423        reg_w(dev, 0x05, 0x00, 0x0004);
 424        reg_w(dev, 0x03, 0x10, 0x0001);
 425        reg_w(dev, 0x03, 0x78, 0x0000);
 426        switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 427        case 0:
 428                spca506_Setsize(gspca_dev, 0, 0x10, 0x10);
 429                break;
 430        case 1:
 431                spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a);
 432                break;
 433        case 2:
 434                spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c);
 435                break;
 436        case 4:
 437                spca506_Setsize(gspca_dev, 4, 0x34, 0x34);
 438                break;
 439        default:
 440/*      case 5: */
 441                spca506_Setsize(gspca_dev, 5, 0x40, 0x40);
 442                break;
 443        }
 444
 445        /* compress setting and size */
 446        /* set i2c luma */
 447        reg_w(dev, 0x02, 0x01, 0x0000);
 448        reg_w(dev, 0x03, 0x12, 0x0000);
 449        reg_r(gspca_dev, 0x04, 0x0001, 2);
 450        gspca_dbg(gspca_dev, D_STREAM, "webcam started\n");
 451        spca506_GetNormeInput(gspca_dev, &norme, &channel);
 452        spca506_SetNormeInput(gspca_dev, norme, channel);
 453        return 0;
 454}
 455
 456static void sd_stopN(struct gspca_dev *gspca_dev)
 457{
 458        struct usb_device *dev = gspca_dev->dev;
 459
 460        reg_w(dev, 0x02, 0x00, 0x0000);
 461        reg_w(dev, 0x03, 0x00, 0x0004);
 462        reg_w(dev, 0x03, 0x00, 0x0003);
 463}
 464
 465static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 466                        u8 *data,                       /* isoc packet */
 467                        int len)                        /* iso packet length */
 468{
 469        switch (data[0]) {
 470        case 0:                         /* start of frame */
 471                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 472                data += SPCA50X_OFFSET_DATA;
 473                len -= SPCA50X_OFFSET_DATA;
 474                gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 475                break;
 476        case 0xff:                      /* drop */
 477/*              gspca_dev->last_packet_type = DISCARD_PACKET; */
 478                break;
 479        default:
 480                data += 1;
 481                len -= 1;
 482                gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 483                break;
 484        }
 485}
 486
 487static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
 488{
 489        spca506_Initi2c(gspca_dev);
 490        spca506_WriteI2c(gspca_dev, val, SAA7113_bright);
 491        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 492}
 493
 494static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 495{
 496        spca506_Initi2c(gspca_dev);
 497        spca506_WriteI2c(gspca_dev, val, SAA7113_contrast);
 498        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 499}
 500
 501static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 502{
 503        spca506_Initi2c(gspca_dev);
 504        spca506_WriteI2c(gspca_dev, val, SAA7113_saturation);
 505        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 506}
 507
 508static void sethue(struct gspca_dev *gspca_dev, s32 val)
 509{
 510        spca506_Initi2c(gspca_dev);
 511        spca506_WriteI2c(gspca_dev, val, SAA7113_hue);
 512        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 513}
 514
 515static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 516{
 517        struct gspca_dev *gspca_dev =
 518                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 519
 520        gspca_dev->usb_err = 0;
 521
 522        if (!gspca_dev->streaming)
 523                return 0;
 524
 525        switch (ctrl->id) {
 526        case V4L2_CID_BRIGHTNESS:
 527                setbrightness(gspca_dev, ctrl->val);
 528                break;
 529        case V4L2_CID_CONTRAST:
 530                setcontrast(gspca_dev, ctrl->val);
 531                break;
 532        case V4L2_CID_SATURATION:
 533                setcolors(gspca_dev, ctrl->val);
 534                break;
 535        case V4L2_CID_HUE:
 536                sethue(gspca_dev, ctrl->val);
 537                break;
 538        }
 539        return gspca_dev->usb_err;
 540}
 541
 542static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 543        .s_ctrl = sd_s_ctrl,
 544};
 545
 546static int sd_init_controls(struct gspca_dev *gspca_dev)
 547{
 548        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 549
 550        gspca_dev->vdev.ctrl_handler = hdl;
 551        v4l2_ctrl_handler_init(hdl, 4);
 552        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 553                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
 554        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 555                        V4L2_CID_CONTRAST, 0, 255, 1, 0x47);
 556        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 557                        V4L2_CID_SATURATION, 0, 255, 1, 0x40);
 558        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 559                        V4L2_CID_HUE, 0, 255, 1, 0);
 560
 561        if (hdl->error) {
 562                pr_err("Could not initialize controls\n");
 563                return hdl->error;
 564        }
 565        return 0;
 566}
 567
 568/* sub-driver description */
 569static const struct sd_desc sd_desc = {
 570        .name = MODULE_NAME,
 571        .config = sd_config,
 572        .init = sd_init,
 573        .init_controls = sd_init_controls,
 574        .start = sd_start,
 575        .stopN = sd_stopN,
 576        .pkt_scan = sd_pkt_scan,
 577};
 578
 579/* -- module initialisation -- */
 580static const struct usb_device_id device_table[] = {
 581        {USB_DEVICE(0x06e1, 0xa190)},
 582/*      {USB_DEVICE(0x0733, 0x0430)}, FIXME: may be IntelPCCameraPro BRIDGE_SPCA505 */
 583        {USB_DEVICE(0x0734, 0x043b)},
 584        {USB_DEVICE(0x99fa, 0x8988)},
 585        {}
 586};
 587MODULE_DEVICE_TABLE(usb, device_table);
 588
 589/* -- device connect -- */
 590static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
 591{
 592        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 593                                THIS_MODULE);
 594}
 595
 596static struct usb_driver sd_driver = {
 597        .name = MODULE_NAME,
 598        .id_table = device_table,
 599        .probe = sd_probe,
 600        .disconnect = gspca_disconnect,
 601#ifdef CONFIG_PM
 602        .suspend = gspca_suspend,
 603        .resume = gspca_resume,
 604        .reset_resume = gspca_resume,
 605#endif
 606};
 607
 608module_usb_driver(sd_driver);
 609