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