linux/drivers/media/video/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 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24#define MODULE_NAME "spca506"
  25
  26#include "gspca.h"
  27
  28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  29MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
  30MODULE_LICENSE("GPL");
  31
  32/* specific webcam descriptor */
  33struct sd {
  34        struct gspca_dev gspca_dev;     /* !! must be the first item */
  35
  36        unsigned char brightness;
  37        unsigned char contrast;
  38        unsigned char colors;
  39        unsigned char hue;
  40        char norme;
  41        char channel;
  42};
  43
  44/* V4L2 controls supported by the driver */
  45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
  48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
  49static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
  50static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
  51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
  52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
  53
  54static struct ctrl sd_ctrls[] = {
  55#define SD_BRIGHTNESS 0
  56        {
  57            {
  58                .id      = V4L2_CID_BRIGHTNESS,
  59                .type    = V4L2_CTRL_TYPE_INTEGER,
  60                .name    = "Brightness",
  61                .minimum = 0,
  62                .maximum = 0xff,
  63                .step    = 1,
  64                .default_value = 0x80,
  65            },
  66            .set = sd_setbrightness,
  67            .get = sd_getbrightness,
  68        },
  69#define SD_CONTRAST 1
  70        {
  71            {
  72                .id      = V4L2_CID_CONTRAST,
  73                .type    = V4L2_CTRL_TYPE_INTEGER,
  74                .name    = "Contrast",
  75                .minimum = 0,
  76                .maximum = 0xff,
  77                .step    = 1,
  78                .default_value = 0x47,
  79            },
  80            .set = sd_setcontrast,
  81            .get = sd_getcontrast,
  82        },
  83#define SD_COLOR 2
  84        {
  85            {
  86                .id      = V4L2_CID_SATURATION,
  87                .type    = V4L2_CTRL_TYPE_INTEGER,
  88                .name    = "Saturation",
  89                .minimum = 0,
  90                .maximum = 0xff,
  91                .step    = 1,
  92                .default_value = 0x40,
  93            },
  94            .set = sd_setcolors,
  95            .get = sd_getcolors,
  96        },
  97#define SD_HUE 3
  98        {
  99            {
 100                .id      = V4L2_CID_HUE,
 101                .type    = V4L2_CTRL_TYPE_INTEGER,
 102                .name    = "Hue",
 103                .minimum = 0,
 104                .maximum = 0xff,
 105                .step    = 1,
 106                .default_value = 0,
 107            },
 108            .set = sd_sethue,
 109            .get = sd_gethue,
 110        },
 111};
 112
 113static const struct v4l2_pix_format vga_mode[] = {
 114        {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 115                .bytesperline = 160,
 116                .sizeimage = 160 * 120 * 3 / 2,
 117                .colorspace = V4L2_COLORSPACE_SRGB,
 118                .priv = 5},
 119        {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 120                .bytesperline = 176,
 121                .sizeimage = 176 * 144 * 3 / 2,
 122                .colorspace = V4L2_COLORSPACE_SRGB,
 123                .priv = 4},
 124        {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 125                .bytesperline = 320,
 126                .sizeimage = 320 * 240 * 3 / 2,
 127                .colorspace = V4L2_COLORSPACE_SRGB,
 128                .priv = 2},
 129        {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 130                .bytesperline = 352,
 131                .sizeimage = 352 * 288 * 3 / 2,
 132                .colorspace = V4L2_COLORSPACE_SRGB,
 133                .priv = 1},
 134        {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 135                .bytesperline = 640,
 136                .sizeimage = 640 * 480 * 3 / 2,
 137                .colorspace = V4L2_COLORSPACE_SRGB,
 138                .priv = 0},
 139};
 140
 141#define SPCA50X_OFFSET_DATA 10
 142
 143#define SAA7113_bright 0x0a     /* defaults 0x80 */
 144#define SAA7113_contrast 0x0b   /* defaults 0x47 */
 145#define SAA7113_saturation 0x0c /* defaults 0x40 */
 146#define SAA7113_hue 0x0d        /* defaults 0x00 */
 147#define SAA7113_I2C_BASE_WRITE 0x4a
 148
 149/* read 'len' bytes to gspca_dev->usb_buf */
 150static void reg_r(struct gspca_dev *gspca_dev,
 151                  __u16 req,
 152                  __u16 index,
 153                  __u16 length)
 154{
 155        usb_control_msg(gspca_dev->dev,
 156                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 157                        req,
 158                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 159                        0,              /* value */
 160                        index, gspca_dev->usb_buf, length,
 161                        500);
 162}
 163
 164static void reg_w(struct usb_device *dev,
 165                  __u16 req,
 166                  __u16 value,
 167                  __u16 index)
 168{
 169        usb_control_msg(dev,
 170                        usb_sndctrlpipe(dev, 0),
 171                        req,
 172                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 173                        value, index,
 174                        NULL, 0, 500);
 175}
 176
 177static void spca506_Initi2c(struct gspca_dev *gspca_dev)
 178{
 179        reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
 180}
 181
 182static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
 183                             __u16 reg)
 184{
 185        int retry = 60;
 186
 187        reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
 188        reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
 189        while (retry--) {
 190                reg_r(gspca_dev, 0x07, 0x0003, 2);
 191                if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
 192                        break;
 193        }
 194}
 195
 196static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
 197                                 __u16 norme,
 198                                 __u16 channel)
 199{
 200        struct sd *sd = (struct sd *) gspca_dev;
 201/* fixme: check if channel == 0..3 and 6..9 (8 values) */
 202        __u8 setbit0 = 0x00;
 203        __u8 setbit1 = 0x00;
 204        __u8 videomask = 0x00;
 205
 206        PDEBUG(D_STREAM, "** Open Set Norme **");
 207        spca506_Initi2c(gspca_dev);
 208        /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
 209        /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
 210        /* and exclude SAA7113 reserved channel set default 0 otherwise */
 211        if (norme & V4L2_STD_NTSC)
 212                setbit0 = 0x01;
 213        if (channel == 4 || channel == 5 || channel > 9)
 214                channel = 0;
 215        if (channel < 4)
 216                setbit1 = 0x02;
 217        videomask = (0x48 | setbit0 | setbit1);
 218        reg_w(gspca_dev->dev, 0x08, videomask, 0x0000);
 219        spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02);
 220
 221        if (norme & V4L2_STD_NTSC)
 222                spca506_WriteI2c(gspca_dev, 0x33, 0x0e);
 223                                        /* Chrominance Control NTSC N */
 224        else if (norme & V4L2_STD_SECAM)
 225                spca506_WriteI2c(gspca_dev, 0x53, 0x0e);
 226                                        /* Chrominance Control SECAM */
 227        else
 228                spca506_WriteI2c(gspca_dev, 0x03, 0x0e);
 229                                        /* Chrominance Control PAL BGHIV */
 230
 231        sd->norme = norme;
 232        sd->channel = channel;
 233        PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
 234        PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
 235}
 236
 237static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
 238                                  __u16 *norme, __u16 *channel)
 239{
 240        struct sd *sd = (struct sd *) gspca_dev;
 241
 242        /* Read the register is not so good value change so
 243           we use your own copy in spca50x struct */
 244        *norme = sd->norme;
 245        *channel = sd->channel;
 246        PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
 247}
 248
 249static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
 250                            __u16 xmult, __u16 ymult)
 251{
 252        struct usb_device *dev = gspca_dev->dev;
 253
 254        PDEBUG(D_STREAM, "** SetSize **");
 255        reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
 256        /* Soft snap 0x40 Hard 0x41 */
 257        reg_w(dev, 0x04, 0x41, 0x0001);
 258        reg_w(dev, 0x04, 0x00, 0x0002);
 259        /* reserved */
 260        reg_w(dev, 0x04, 0x00, 0x0003);
 261
 262        /* reserved */
 263        reg_w(dev, 0x04, 0x00, 0x0004);
 264        /* reserved */
 265        reg_w(dev, 0x04, 0x01, 0x0005);
 266        /* reserced */
 267        reg_w(dev, 0x04, xmult, 0x0006);
 268        /* reserved */
 269        reg_w(dev, 0x04, ymult, 0x0007);
 270        /* compression 1 */
 271        reg_w(dev, 0x04, 0x00, 0x0008);
 272        /* T=64 -> 2 */
 273        reg_w(dev, 0x04, 0x00, 0x0009);
 274        /* threshold2D */
 275        reg_w(dev, 0x04, 0x21, 0x000a);
 276        /* quantization */
 277        reg_w(dev, 0x04, 0x00, 0x000b);
 278}
 279
 280/* this function is called at probe time */
 281static int sd_config(struct gspca_dev *gspca_dev,
 282                        const struct usb_device_id *id)
 283{
 284        struct sd *sd = (struct sd *) gspca_dev;
 285        struct cam *cam;
 286
 287        cam = &gspca_dev->cam;
 288        cam->cam_mode = vga_mode;
 289        cam->nmodes = ARRAY_SIZE(vga_mode);
 290        sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 291        sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 292        sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
 293        sd->hue = sd_ctrls[SD_HUE].qctrl.default_value;
 294        return 0;
 295}
 296
 297/* this function is called at probe and resume time */
 298static int sd_init(struct gspca_dev *gspca_dev)
 299{
 300        struct usb_device *dev = gspca_dev->dev;
 301
 302        reg_w(dev, 0x03, 0x00, 0x0004);
 303        reg_w(dev, 0x03, 0xFF, 0x0003);
 304        reg_w(dev, 0x03, 0x00, 0x0000);
 305        reg_w(dev, 0x03, 0x1c, 0x0001);
 306        reg_w(dev, 0x03, 0x18, 0x0001);
 307        /* Init on PAL and composite input0 */
 308        spca506_SetNormeInput(gspca_dev, 0, 0);
 309        reg_w(dev, 0x03, 0x1c, 0x0001);
 310        reg_w(dev, 0x03, 0x18, 0x0001);
 311        reg_w(dev, 0x05, 0x00, 0x0000);
 312        reg_w(dev, 0x05, 0xef, 0x0001);
 313        reg_w(dev, 0x05, 0x00, 0x00c1);
 314        reg_w(dev, 0x05, 0x00, 0x00c2);
 315        reg_w(dev, 0x06, 0x18, 0x0002);
 316        reg_w(dev, 0x06, 0xf5, 0x0011);
 317        reg_w(dev, 0x06, 0x02, 0x0012);
 318        reg_w(dev, 0x06, 0xfb, 0x0013);
 319        reg_w(dev, 0x06, 0x00, 0x0014);
 320        reg_w(dev, 0x06, 0xa4, 0x0051);
 321        reg_w(dev, 0x06, 0x40, 0x0052);
 322        reg_w(dev, 0x06, 0x71, 0x0053);
 323        reg_w(dev, 0x06, 0x40, 0x0054);
 324        /************************************************/
 325        reg_w(dev, 0x03, 0x00, 0x0004);
 326        reg_w(dev, 0x03, 0x00, 0x0003);
 327        reg_w(dev, 0x03, 0x00, 0x0004);
 328        reg_w(dev, 0x03, 0xFF, 0x0003);
 329        reg_w(dev, 0x02, 0x00, 0x0000);
 330        reg_w(dev, 0x03, 0x60, 0x0000);
 331        reg_w(dev, 0x03, 0x18, 0x0001);
 332        /* for a better reading mx :)     */
 333        /*sdca506_WriteI2c(value,register) */
 334        spca506_Initi2c(gspca_dev);
 335        spca506_WriteI2c(gspca_dev, 0x08, 0x01);
 336        spca506_WriteI2c(gspca_dev, 0xc0, 0x02);
 337                                                /* input composite video */
 338        spca506_WriteI2c(gspca_dev, 0x33, 0x03);
 339        spca506_WriteI2c(gspca_dev, 0x00, 0x04);
 340        spca506_WriteI2c(gspca_dev, 0x00, 0x05);
 341        spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
 342        spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
 343        spca506_WriteI2c(gspca_dev, 0x98, 0x08);
 344        spca506_WriteI2c(gspca_dev, 0x03, 0x09);
 345        spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
 346        spca506_WriteI2c(gspca_dev, 0x47, 0x0b);
 347        spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
 348        spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
 349        spca506_WriteI2c(gspca_dev, 0x03, 0x0e);        /* Chroma Pal adjust */
 350        spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
 351        spca506_WriteI2c(gspca_dev, 0x00, 0x10);
 352        spca506_WriteI2c(gspca_dev, 0x0c, 0x11);
 353        spca506_WriteI2c(gspca_dev, 0xb8, 0x12);
 354        spca506_WriteI2c(gspca_dev, 0x01, 0x13);
 355        spca506_WriteI2c(gspca_dev, 0x00, 0x14);
 356        spca506_WriteI2c(gspca_dev, 0x00, 0x15);
 357        spca506_WriteI2c(gspca_dev, 0x00, 0x16);
 358        spca506_WriteI2c(gspca_dev, 0x00, 0x17);
 359        spca506_WriteI2c(gspca_dev, 0x00, 0x18);
 360        spca506_WriteI2c(gspca_dev, 0x00, 0x19);
 361        spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
 362        spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
 363        spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
 364        spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
 365        spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
 366        spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
 367        spca506_WriteI2c(gspca_dev, 0x02, 0x40);
 368        spca506_WriteI2c(gspca_dev, 0xff, 0x41);
 369        spca506_WriteI2c(gspca_dev, 0xff, 0x42);
 370        spca506_WriteI2c(gspca_dev, 0xff, 0x43);
 371        spca506_WriteI2c(gspca_dev, 0xff, 0x44);
 372        spca506_WriteI2c(gspca_dev, 0xff, 0x45);
 373        spca506_WriteI2c(gspca_dev, 0xff, 0x46);
 374        spca506_WriteI2c(gspca_dev, 0xff, 0x47);
 375        spca506_WriteI2c(gspca_dev, 0xff, 0x48);
 376        spca506_WriteI2c(gspca_dev, 0xff, 0x49);
 377        spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
 378        spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
 379        spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
 380        spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
 381        spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
 382        spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
 383        spca506_WriteI2c(gspca_dev, 0xff, 0x50);
 384        spca506_WriteI2c(gspca_dev, 0xff, 0x51);
 385        spca506_WriteI2c(gspca_dev, 0xff, 0x52);
 386        spca506_WriteI2c(gspca_dev, 0xff, 0x53);
 387        spca506_WriteI2c(gspca_dev, 0xff, 0x54);
 388        spca506_WriteI2c(gspca_dev, 0xff, 0x55);
 389        spca506_WriteI2c(gspca_dev, 0xff, 0x56);
 390        spca506_WriteI2c(gspca_dev, 0xff, 0x57);
 391        spca506_WriteI2c(gspca_dev, 0x00, 0x58);
 392        spca506_WriteI2c(gspca_dev, 0x54, 0x59);
 393        spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
 394        spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
 395        spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
 396        spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
 397        spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
 398        spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
 399        spca506_WriteI2c(gspca_dev, 0x00, 0x60);
 400        spca506_WriteI2c(gspca_dev, 0x05, 0x61);
 401        spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
 402        PDEBUG(D_STREAM, "** Close Init *");
 403        return 0;
 404}
 405
 406static int sd_start(struct gspca_dev *gspca_dev)
 407{
 408        struct usb_device *dev = gspca_dev->dev;
 409        __u16 norme;
 410        __u16 channel;
 411
 412        /**************************************/
 413        reg_w(dev, 0x03, 0x00, 0x0004);
 414        reg_w(dev, 0x03, 0x00, 0x0003);
 415        reg_w(dev, 0x03, 0x00, 0x0004);
 416        reg_w(dev, 0x03, 0xFF, 0x0003);
 417        reg_w(dev, 0x02, 0x00, 0x0000);
 418        reg_w(dev, 0x03, 0x60, 0x0000);
 419        reg_w(dev, 0x03, 0x18, 0x0001);
 420
 421        /*sdca506_WriteI2c(value,register) */
 422        spca506_Initi2c(gspca_dev);
 423        spca506_WriteI2c(gspca_dev, 0x08, 0x01);        /* Increment Delay */
 424/*      spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */
 425        spca506_WriteI2c(gspca_dev, 0x33, 0x03);
 426                                                /* Analog Input Control 2 */
 427        spca506_WriteI2c(gspca_dev, 0x00, 0x04);
 428                                                /* Analog Input Control 3 */
 429        spca506_WriteI2c(gspca_dev, 0x00, 0x05);
 430                                                /* Analog Input Control 4 */
 431        spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
 432                                        /* Horizontal Sync Start 0xe9-0x0d */
 433        spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
 434                                        /* Horizontal Sync Stop  0x0d-0xf0 */
 435
 436        spca506_WriteI2c(gspca_dev, 0x98, 0x08);        /* Sync Control */
 437/*              Defaults value                  */
 438        spca506_WriteI2c(gspca_dev, 0x03, 0x09);        /* Luminance Control */
 439        spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
 440                                                /* Luminance Brightness */
 441        spca506_WriteI2c(gspca_dev, 0x47, 0x0b);        /* Luminance Contrast */
 442        spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
 443                                                /* Chrominance Saturation */
 444        spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
 445                                                /* Chrominance Hue Control */
 446        spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
 447                                                /* Chrominance Gain Control */
 448        /**************************************/
 449        spca506_WriteI2c(gspca_dev, 0x00, 0x10);
 450                                                /* Format/Delay Control */
 451        spca506_WriteI2c(gspca_dev, 0x0c, 0x11);        /* Output Control 1 */
 452        spca506_WriteI2c(gspca_dev, 0xb8, 0x12);        /* Output Control 2 */
 453        spca506_WriteI2c(gspca_dev, 0x01, 0x13);        /* Output Control 3 */
 454        spca506_WriteI2c(gspca_dev, 0x00, 0x14);        /* reserved */
 455        spca506_WriteI2c(gspca_dev, 0x00, 0x15);        /* VGATE START */
 456        spca506_WriteI2c(gspca_dev, 0x00, 0x16);        /* VGATE STOP */
 457        spca506_WriteI2c(gspca_dev, 0x00, 0x17);    /* VGATE Control (MSB) */
 458        spca506_WriteI2c(gspca_dev, 0x00, 0x18);
 459        spca506_WriteI2c(gspca_dev, 0x00, 0x19);
 460        spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
 461        spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
 462        spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
 463        spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
 464        spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
 465        spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
 466        spca506_WriteI2c(gspca_dev, 0x02, 0x40);
 467        spca506_WriteI2c(gspca_dev, 0xff, 0x41);
 468        spca506_WriteI2c(gspca_dev, 0xff, 0x42);
 469        spca506_WriteI2c(gspca_dev, 0xff, 0x43);
 470        spca506_WriteI2c(gspca_dev, 0xff, 0x44);
 471        spca506_WriteI2c(gspca_dev, 0xff, 0x45);
 472        spca506_WriteI2c(gspca_dev, 0xff, 0x46);
 473        spca506_WriteI2c(gspca_dev, 0xff, 0x47);
 474        spca506_WriteI2c(gspca_dev, 0xff, 0x48);
 475        spca506_WriteI2c(gspca_dev, 0xff, 0x49);
 476        spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
 477        spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
 478        spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
 479        spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
 480        spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
 481        spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
 482        spca506_WriteI2c(gspca_dev, 0xff, 0x50);
 483        spca506_WriteI2c(gspca_dev, 0xff, 0x51);
 484        spca506_WriteI2c(gspca_dev, 0xff, 0x52);
 485        spca506_WriteI2c(gspca_dev, 0xff, 0x53);
 486        spca506_WriteI2c(gspca_dev, 0xff, 0x54);
 487        spca506_WriteI2c(gspca_dev, 0xff, 0x55);
 488        spca506_WriteI2c(gspca_dev, 0xff, 0x56);
 489        spca506_WriteI2c(gspca_dev, 0xff, 0x57);
 490        spca506_WriteI2c(gspca_dev, 0x00, 0x58);
 491        spca506_WriteI2c(gspca_dev, 0x54, 0x59);
 492        spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
 493        spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
 494        spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
 495        spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
 496        spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
 497        spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
 498        spca506_WriteI2c(gspca_dev, 0x00, 0x60);
 499        spca506_WriteI2c(gspca_dev, 0x05, 0x61);
 500        spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
 501        /**************************************/
 502        reg_w(dev, 0x05, 0x00, 0x0003);
 503        reg_w(dev, 0x05, 0x00, 0x0004);
 504        reg_w(dev, 0x03, 0x10, 0x0001);
 505        reg_w(dev, 0x03, 0x78, 0x0000);
 506        switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 507        case 0:
 508                spca506_Setsize(gspca_dev, 0, 0x10, 0x10);
 509                break;
 510        case 1:
 511                spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a);
 512                break;
 513        case 2:
 514                spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c);
 515                break;
 516        case 4:
 517                spca506_Setsize(gspca_dev, 4, 0x34, 0x34);
 518                break;
 519        default:
 520/*      case 5: */
 521                spca506_Setsize(gspca_dev, 5, 0x40, 0x40);
 522                break;
 523        }
 524
 525        /* compress setting and size */
 526        /* set i2c luma */
 527        reg_w(dev, 0x02, 0x01, 0x0000);
 528        reg_w(dev, 0x03, 0x12, 0x0000);
 529        reg_r(gspca_dev, 0x04, 0x0001, 2);
 530        PDEBUG(D_STREAM, "webcam started");
 531        spca506_GetNormeInput(gspca_dev, &norme, &channel);
 532        spca506_SetNormeInput(gspca_dev, norme, channel);
 533        return 0;
 534}
 535
 536static void sd_stopN(struct gspca_dev *gspca_dev)
 537{
 538        struct usb_device *dev = gspca_dev->dev;
 539
 540        reg_w(dev, 0x02, 0x00, 0x0000);
 541        reg_w(dev, 0x03, 0x00, 0x0004);
 542        reg_w(dev, 0x03, 0x00, 0x0003);
 543}
 544
 545static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 546                        struct gspca_frame *frame,      /* target */
 547                        __u8 *data,                     /* isoc packet */
 548                        int len)                        /* iso packet length */
 549{
 550        switch (data[0]) {
 551        case 0:                         /* start of frame */
 552                frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
 553                                        data, 0);
 554                data += SPCA50X_OFFSET_DATA;
 555                len -= SPCA50X_OFFSET_DATA;
 556                gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
 557                                data, len);
 558                break;
 559        case 0xff:                      /* drop */
 560/*              gspca_dev->last_packet_type = DISCARD_PACKET; */
 561                break;
 562        default:
 563                data += 1;
 564                len -= 1;
 565                gspca_frame_add(gspca_dev, INTER_PACKET, frame,
 566                                data, len);
 567                break;
 568        }
 569}
 570
 571static void setbrightness(struct gspca_dev *gspca_dev)
 572{
 573        struct sd *sd = (struct sd *) gspca_dev;
 574
 575        spca506_Initi2c(gspca_dev);
 576        spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright);
 577        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 578}
 579
 580static void setcontrast(struct gspca_dev *gspca_dev)
 581{
 582        struct sd *sd = (struct sd *) gspca_dev;
 583
 584        spca506_Initi2c(gspca_dev);
 585        spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast);
 586        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 587}
 588
 589static void setcolors(struct gspca_dev *gspca_dev)
 590{
 591        struct sd *sd = (struct sd *) gspca_dev;
 592
 593        spca506_Initi2c(gspca_dev);
 594        spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation);
 595        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 596}
 597
 598static void sethue(struct gspca_dev *gspca_dev)
 599{
 600        struct sd *sd = (struct sd *) gspca_dev;
 601
 602        spca506_Initi2c(gspca_dev);
 603        spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue);
 604        spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 605}
 606
 607static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 608{
 609        struct sd *sd = (struct sd *) gspca_dev;
 610
 611        sd->brightness = val;
 612        if (gspca_dev->streaming)
 613                setbrightness(gspca_dev);
 614        return 0;
 615}
 616
 617static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
 618{
 619        struct sd *sd = (struct sd *) gspca_dev;
 620
 621        *val = sd->brightness;
 622        return 0;
 623}
 624
 625static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 626{
 627        struct sd *sd = (struct sd *) gspca_dev;
 628
 629        sd->contrast = val;
 630        if (gspca_dev->streaming)
 631                setcontrast(gspca_dev);
 632        return 0;
 633}
 634
 635static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
 636{
 637        struct sd *sd = (struct sd *) gspca_dev;
 638
 639        *val = sd->contrast;
 640        return 0;
 641}
 642
 643static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
 644{
 645        struct sd *sd = (struct sd *) gspca_dev;
 646
 647        sd->colors = val;
 648        if (gspca_dev->streaming)
 649                setcolors(gspca_dev);
 650        return 0;
 651}
 652
 653static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
 654{
 655        struct sd *sd = (struct sd *) gspca_dev;
 656
 657        *val = sd->colors;
 658        return 0;
 659}
 660
 661static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
 662{
 663        struct sd *sd = (struct sd *) gspca_dev;
 664
 665        sd->hue = val;
 666        if (gspca_dev->streaming)
 667                sethue(gspca_dev);
 668        return 0;
 669}
 670
 671static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
 672{
 673        struct sd *sd = (struct sd *) gspca_dev;
 674
 675        *val = sd->hue;
 676        return 0;
 677}
 678
 679/* sub-driver description */
 680static struct sd_desc sd_desc = {
 681        .name = MODULE_NAME,
 682        .ctrls = sd_ctrls,
 683        .nctrls = ARRAY_SIZE(sd_ctrls),
 684        .config = sd_config,
 685        .init = sd_init,
 686        .start = sd_start,
 687        .stopN = sd_stopN,
 688        .pkt_scan = sd_pkt_scan,
 689};
 690
 691/* -- module initialisation -- */
 692static __devinitdata struct usb_device_id device_table[] = {
 693        {USB_DEVICE(0x06e1, 0xa190)},
 694/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
 695        {USB_DEVICE(0x0733, 0x0430)}, */
 696        {USB_DEVICE(0x0734, 0x043b)},
 697        {USB_DEVICE(0x99fa, 0x8988)},
 698        {}
 699};
 700MODULE_DEVICE_TABLE(usb, device_table);
 701
 702/* -- device connect -- */
 703static int sd_probe(struct usb_interface *intf,
 704                        const struct usb_device_id *id)
 705{
 706        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 707                                THIS_MODULE);
 708}
 709
 710static struct usb_driver sd_driver = {
 711        .name = MODULE_NAME,
 712        .id_table = device_table,
 713        .probe = sd_probe,
 714        .disconnect = gspca_disconnect,
 715#ifdef CONFIG_PM
 716        .suspend = gspca_suspend,
 717        .resume = gspca_resume,
 718#endif
 719};
 720
 721/* -- module insert / remove -- */
 722static int __init sd_mod_init(void)
 723{
 724        int ret;
 725        ret = usb_register(&sd_driver);
 726        if (ret < 0)
 727                return ret;
 728        PDEBUG(D_PROBE, "registered");
 729        return 0;
 730}
 731static void __exit sd_mod_exit(void)
 732{
 733        usb_deregister(&sd_driver);
 734        PDEBUG(D_PROBE, "deregistered");
 735}
 736
 737module_init(sd_mod_init);
 738module_exit(sd_mod_exit);
 739