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