linux/drivers/media/video/gspca/spca561.c
<<
>>
Prefs
   1/*
   2 * Sunplus spca561 subdriver
   3 *
   4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
   5 *
   6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22
  23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  24
  25#define MODULE_NAME "spca561"
  26
  27#include <linux/input.h>
  28#include "gspca.h"
  29
  30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
  32MODULE_LICENSE("GPL");
  33
  34/* specific webcam descriptor */
  35struct sd {
  36        struct gspca_dev gspca_dev;     /* !! must be the first item */
  37
  38        __u16 exposure;                 /* rev12a only */
  39#define EXPOSURE_MIN 1
  40#define EXPOSURE_DEF 700                /* == 10 fps */
  41#define EXPOSURE_MAX (2047 + 325)       /* see setexposure */
  42
  43        __u8 contrast;                  /* rev72a only */
  44#define CONTRAST_MIN 0x00
  45#define CONTRAST_DEF 0x20
  46#define CONTRAST_MAX 0x3f
  47
  48        __u8 brightness;                /* rev72a only */
  49#define BRIGHTNESS_MIN 0
  50#define BRIGHTNESS_DEF 0x20
  51#define BRIGHTNESS_MAX 0x3f
  52
  53        __u8 white;
  54#define HUE_MIN 1
  55#define HUE_DEF 0x40
  56#define HUE_MAX 0x7f
  57
  58        __u8 autogain;
  59#define AUTOGAIN_MIN 0
  60#define AUTOGAIN_DEF 1
  61#define AUTOGAIN_MAX 1
  62
  63        __u8 gain;                      /* rev12a only */
  64#define GAIN_MIN 0
  65#define GAIN_DEF 63
  66#define GAIN_MAX 255
  67
  68#define EXPO12A_DEF 3
  69        __u8 expo12a;           /* expo/gain? for rev 12a */
  70
  71        __u8 chip_revision;
  72#define Rev012A 0
  73#define Rev072A 1
  74
  75        signed char ag_cnt;
  76#define AG_CNT_START 13
  77};
  78
  79static const struct v4l2_pix_format sif_012a_mode[] = {
  80        {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  81                .bytesperline = 160,
  82                .sizeimage = 160 * 120,
  83                .colorspace = V4L2_COLORSPACE_SRGB,
  84                .priv = 3},
  85        {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  86                .bytesperline = 176,
  87                .sizeimage = 176 * 144,
  88                .colorspace = V4L2_COLORSPACE_SRGB,
  89                .priv = 2},
  90        {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
  91                .bytesperline = 320,
  92                .sizeimage = 320 * 240 * 4 / 8,
  93                .colorspace = V4L2_COLORSPACE_SRGB,
  94                .priv = 1},
  95        {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
  96                .bytesperline = 352,
  97                .sizeimage = 352 * 288 * 4 / 8,
  98                .colorspace = V4L2_COLORSPACE_SRGB,
  99                .priv = 0},
 100};
 101
 102static const struct v4l2_pix_format sif_072a_mode[] = {
 103        {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 104                .bytesperline = 160,
 105                .sizeimage = 160 * 120,
 106                .colorspace = V4L2_COLORSPACE_SRGB,
 107                .priv = 3},
 108        {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 109                .bytesperline = 176,
 110                .sizeimage = 176 * 144,
 111                .colorspace = V4L2_COLORSPACE_SRGB,
 112                .priv = 2},
 113        {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 114                .bytesperline = 320,
 115                .sizeimage = 320 * 240,
 116                .colorspace = V4L2_COLORSPACE_SRGB,
 117                .priv = 1},
 118        {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 119                .bytesperline = 352,
 120                .sizeimage = 352 * 288,
 121                .colorspace = V4L2_COLORSPACE_SRGB,
 122                .priv = 0},
 123};
 124
 125/*
 126 * Initialization data
 127 * I'm not very sure how to split initialization from open data
 128 * chunks. For now, we'll consider everything as initialization
 129 */
 130/* Frame packet header offsets for the spca561 */
 131#define SPCA561_OFFSET_SNAP 1
 132#define SPCA561_OFFSET_TYPE 2
 133#define SPCA561_OFFSET_COMPRESS 3
 134#define SPCA561_OFFSET_FRAMSEQ   4
 135#define SPCA561_OFFSET_GPIO 5
 136#define SPCA561_OFFSET_USBBUFF 6
 137#define SPCA561_OFFSET_WIN2GRAVE 7
 138#define SPCA561_OFFSET_WIN2RAVE 8
 139#define SPCA561_OFFSET_WIN2BAVE 9
 140#define SPCA561_OFFSET_WIN2GBAVE 10
 141#define SPCA561_OFFSET_WIN1GRAVE 11
 142#define SPCA561_OFFSET_WIN1RAVE 12
 143#define SPCA561_OFFSET_WIN1BAVE 13
 144#define SPCA561_OFFSET_WIN1GBAVE 14
 145#define SPCA561_OFFSET_FREQ 15
 146#define SPCA561_OFFSET_VSYNC 16
 147#define SPCA561_INDEX_I2C_BASE 0x8800
 148#define SPCA561_SNAPBIT 0x20
 149#define SPCA561_SNAPCTRL 0x40
 150
 151static const u16 rev72a_reset[][2] = {
 152        {0x0000, 0x8114},       /* Software GPIO output data */
 153        {0x0001, 0x8114},       /* Software GPIO output data */
 154        {0x0000, 0x8112},       /* Some kind of reset */
 155        {}
 156};
 157static const __u16 rev72a_init_data1[][2] = {
 158        {0x0003, 0x8701},       /* PCLK clock delay adjustment */
 159        {0x0001, 0x8703},       /* HSYNC from cmos inverted */
 160        {0x0011, 0x8118},       /* Enable and conf sensor */
 161        {0x0001, 0x8118},       /* Conf sensor */
 162        {0x0092, 0x8804},       /* I know nothing about these */
 163        {0x0010, 0x8802},       /* 0x88xx registers, so I won't */
 164        {}
 165};
 166static const u16 rev72a_init_sensor1[][2] = {
 167        {0x0001, 0x000d},
 168        {0x0002, 0x0018},
 169        {0x0004, 0x0165},
 170        {0x0005, 0x0021},
 171        {0x0007, 0x00aa},
 172        {0x0020, 0x1504},
 173        {0x0039, 0x0002},
 174        {0x0035, 0x0010},
 175        {0x0009, 0x1049},
 176        {0x0028, 0x000b},
 177        {0x003b, 0x000f},
 178        {0x003c, 0x0000},
 179        {}
 180};
 181static const __u16 rev72a_init_data2[][2] = {
 182        {0x0018, 0x8601},       /* Pixel/line selection for color separation */
 183        {0x0000, 0x8602},       /* Optical black level for user setting */
 184        {0x0060, 0x8604},       /* Optical black horizontal offset */
 185        {0x0002, 0x8605},       /* Optical black vertical offset */
 186        {0x0000, 0x8603},       /* Non-automatic optical black level */
 187        {0x0002, 0x865b},       /* Horizontal offset for valid pixels */
 188        {0x0000, 0x865f},       /* Vertical valid pixels window (x2) */
 189        {0x00b0, 0x865d},       /* Horizontal valid pixels window (x2) */
 190        {0x0090, 0x865e},       /* Vertical valid lines window (x2) */
 191        {0x00e0, 0x8406},       /* Memory buffer threshold */
 192        {0x0000, 0x8660},       /* Compensation memory stuff */
 193        {0x0002, 0x8201},       /* Output address for r/w serial EEPROM */
 194        {0x0008, 0x8200},       /* Clear valid bit for serial EEPROM */
 195        {0x0001, 0x8200},       /* OprMode to be executed by hardware */
 196/* from ms-win */
 197        {0x0000, 0x8611},       /* R offset for white balance */
 198        {0x00fd, 0x8612},       /* Gr offset for white balance */
 199        {0x0003, 0x8613},       /* B offset for white balance */
 200        {0x0000, 0x8614},       /* Gb offset for white balance */
 201/* from ms-win */
 202        {0x0035, 0x8651},       /* R gain for white balance */
 203        {0x0040, 0x8652},       /* Gr gain for white balance */
 204        {0x005f, 0x8653},       /* B gain for white balance */
 205        {0x0040, 0x8654},       /* Gb gain for white balance */
 206        {0x0002, 0x8502},       /* Maximum average bit rate stuff */
 207        {0x0011, 0x8802},
 208
 209        {0x0087, 0x8700},       /* Set master clock (96Mhz????) */
 210        {0x0081, 0x8702},       /* Master clock output enable */
 211
 212        {0x0000, 0x8500},       /* Set image type (352x288 no compression) */
 213        /* Originally was 0x0010 (352x288 compression) */
 214
 215        {0x0002, 0x865b},       /* Horizontal offset for valid pixels */
 216        {0x0003, 0x865c},       /* Vertical offset for valid lines */
 217        {}
 218};
 219static const u16 rev72a_init_sensor2[][2] = {
 220        {0x0003, 0x0121},
 221        {0x0004, 0x0165},
 222        {0x0005, 0x002f},       /* blanking control column */
 223        {0x0006, 0x0000},       /* blanking mode row*/
 224        {0x000a, 0x0002},
 225        {0x0009, 0x1061},       /* setexposure times && pixel clock
 226                                 * 0001 0 | 000 0110 0001 */
 227        {0x0035, 0x0014},
 228        {}
 229};
 230
 231/******************** QC Express etch2 stuff ********************/
 232static const __u16 Pb100_1map8300[][2] = {
 233        /* reg, value */
 234        {0x8320, 0x3304},
 235
 236        {0x8303, 0x0125},       /* image area */
 237        {0x8304, 0x0169},
 238        {0x8328, 0x000b},
 239        {0x833c, 0x0001},               /*fixme: win:07*/
 240
 241        {0x832f, 0x1904},               /*fixme: was 0419*/
 242        {0x8307, 0x00aa},
 243        {0x8301, 0x0003},
 244        {0x8302, 0x000e},
 245        {}
 246};
 247static const __u16 Pb100_2map8300[][2] = {
 248        /* reg, value */
 249        {0x8339, 0x0000},
 250        {0x8307, 0x00aa},
 251        {}
 252};
 253
 254static const __u16 spca561_161rev12A_data1[][2] = {
 255        {0x29, 0x8118},         /* Control register (various enable bits) */
 256        {0x08, 0x8114},         /* GPIO: Led off */
 257        {0x0e, 0x8112},         /* 0x0e stream off 0x3e stream on */
 258        {0x00, 0x8102},         /* white balance - new */
 259        {0x92, 0x8804},
 260        {0x04, 0x8802},         /* windows uses 08 */
 261        {}
 262};
 263static const __u16 spca561_161rev12A_data2[][2] = {
 264        {0x21, 0x8118},
 265        {0x10, 0x8500},
 266        {0x07, 0x8601},
 267        {0x07, 0x8602},
 268        {0x04, 0x8501},
 269
 270        {0x07, 0x8201},         /* windows uses 02 */
 271        {0x08, 0x8200},
 272        {0x01, 0x8200},
 273
 274        {0x90, 0x8604},
 275        {0x00, 0x8605},
 276        {0xb0, 0x8603},
 277
 278        /* sensor gains */
 279        {0x07, 0x8601},         /* white balance - new */
 280        {0x07, 0x8602},         /* white balance - new */
 281        {0x00, 0x8610},         /* *red */
 282        {0x00, 0x8611},         /* 3f   *green */
 283        {0x00, 0x8612},         /* green *blue */
 284        {0x00, 0x8613},         /* blue *green */
 285        {0x43, 0x8614},         /* green *red - white balance - was 0x35 */
 286        {0x40, 0x8615},         /* 40   *green - white balance - was 0x35 */
 287        {0x71, 0x8616},         /* 7a   *blue - white balance - was 0x35 */
 288        {0x40, 0x8617},         /* 40   *green - white balance - was 0x35 */
 289
 290        {0x0c, 0x8620},         /* 0c */
 291        {0xc8, 0x8631},         /* c8 */
 292        {0xc8, 0x8634},         /* c8 */
 293        {0x23, 0x8635},         /* 23 */
 294        {0x1f, 0x8636},         /* 1f */
 295        {0xdd, 0x8637},         /* dd */
 296        {0xe1, 0x8638},         /* e1 */
 297        {0x1d, 0x8639},         /* 1d */
 298        {0x21, 0x863a},         /* 21 */
 299        {0xe3, 0x863b},         /* e3 */
 300        {0xdf, 0x863c},         /* df */
 301        {0xf0, 0x8505},
 302        {0x32, 0x850a},
 303/*      {0x99, 0x8700},          * - white balance - new (removed) */
 304        /* HDG we used to do this in stop0, making the init state and the state
 305           after a start / stop different, so do this here instead. */
 306        {0x29, 0x8118},
 307        {}
 308};
 309
 310static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
 311{
 312        int ret;
 313
 314        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 315                              0,                /* request */
 316                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 317                              value, index, NULL, 0, 500);
 318        PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
 319        if (ret < 0)
 320                pr_err("reg write: error %d\n", ret);
 321}
 322
 323static void write_vector(struct gspca_dev *gspca_dev,
 324                        const __u16 data[][2])
 325{
 326        struct usb_device *dev = gspca_dev->dev;
 327        int i;
 328
 329        i = 0;
 330        while (data[i][1] != 0) {
 331                reg_w_val(dev, data[i][1], data[i][0]);
 332                i++;
 333        }
 334}
 335
 336/* read 'len' bytes to gspca_dev->usb_buf */
 337static void reg_r(struct gspca_dev *gspca_dev,
 338                  __u16 index, __u16 length)
 339{
 340        usb_control_msg(gspca_dev->dev,
 341                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 342                        0,                      /* request */
 343                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 344                        0,                      /* value */
 345                        index, gspca_dev->usb_buf, length, 500);
 346}
 347
 348/* write 'len' bytes from gspca_dev->usb_buf */
 349static void reg_w_buf(struct gspca_dev *gspca_dev,
 350                      __u16 index, __u16 len)
 351{
 352        usb_control_msg(gspca_dev->dev,
 353                        usb_sndctrlpipe(gspca_dev->dev, 0),
 354                        0,                      /* request */
 355                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 356                        0,                      /* value */
 357                        index, gspca_dev->usb_buf, len, 500);
 358}
 359
 360static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
 361{
 362        int retry = 60;
 363
 364        reg_w_val(gspca_dev->dev, 0x8801, reg);
 365        reg_w_val(gspca_dev->dev, 0x8805, value);
 366        reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
 367        do {
 368                reg_r(gspca_dev, 0x8803, 1);
 369                if (!gspca_dev->usb_buf[0])
 370                        return;
 371                msleep(10);
 372        } while (--retry);
 373}
 374
 375static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
 376{
 377        int retry = 60;
 378        __u8 value;
 379
 380        reg_w_val(gspca_dev->dev, 0x8804, 0x92);
 381        reg_w_val(gspca_dev->dev, 0x8801, reg);
 382        reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
 383        do {
 384                reg_r(gspca_dev, 0x8803, 1);
 385                if (!gspca_dev->usb_buf[0]) {
 386                        reg_r(gspca_dev, 0x8800, 1);
 387                        value = gspca_dev->usb_buf[0];
 388                        reg_r(gspca_dev, 0x8805, 1);
 389                        return ((int) value << 8) | gspca_dev->usb_buf[0];
 390                }
 391                msleep(10);
 392        } while (--retry);
 393        return -1;
 394}
 395
 396static void sensor_mapwrite(struct gspca_dev *gspca_dev,
 397                            const __u16 (*sensormap)[2])
 398{
 399        while ((*sensormap)[0]) {
 400                gspca_dev->usb_buf[0] = (*sensormap)[1];
 401                gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
 402                reg_w_buf(gspca_dev, (*sensormap)[0], 2);
 403                sensormap++;
 404        }
 405}
 406
 407static void write_sensor_72a(struct gspca_dev *gspca_dev,
 408                            const __u16 (*sensor)[2])
 409{
 410        while ((*sensor)[0]) {
 411                i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
 412                sensor++;
 413        }
 414}
 415
 416static void init_161rev12A(struct gspca_dev *gspca_dev)
 417{
 418        write_vector(gspca_dev, spca561_161rev12A_data1);
 419        sensor_mapwrite(gspca_dev, Pb100_1map8300);
 420/*fixme: should be in sd_start*/
 421        write_vector(gspca_dev, spca561_161rev12A_data2);
 422        sensor_mapwrite(gspca_dev, Pb100_2map8300);
 423}
 424
 425/* this function is called at probe time */
 426static int sd_config(struct gspca_dev *gspca_dev,
 427                     const struct usb_device_id *id)
 428{
 429        struct sd *sd = (struct sd *) gspca_dev;
 430        struct cam *cam;
 431        __u16 vendor, product;
 432        __u8 data1, data2;
 433
 434        /* Read frm global register the USB product and vendor IDs, just to
 435         * prove that we can communicate with the device.  This works, which
 436         * confirms at we are communicating properly and that the device
 437         * is a 561. */
 438        reg_r(gspca_dev, 0x8104, 1);
 439        data1 = gspca_dev->usb_buf[0];
 440        reg_r(gspca_dev, 0x8105, 1);
 441        data2 = gspca_dev->usb_buf[0];
 442        vendor = (data2 << 8) | data1;
 443        reg_r(gspca_dev, 0x8106, 1);
 444        data1 = gspca_dev->usb_buf[0];
 445        reg_r(gspca_dev, 0x8107, 1);
 446        data2 = gspca_dev->usb_buf[0];
 447        product = (data2 << 8) | data1;
 448        if (vendor != id->idVendor || product != id->idProduct) {
 449                PDEBUG(D_PROBE, "Bad vendor / product from device");
 450                return -EINVAL;
 451        }
 452
 453        cam = &gspca_dev->cam;
 454        gspca_dev->nbalt = 7 + 1;       /* choose alternate 7 first */
 455
 456        sd->chip_revision = id->driver_info;
 457        if (sd->chip_revision == Rev012A) {
 458                cam->cam_mode = sif_012a_mode;
 459                cam->nmodes = ARRAY_SIZE(sif_012a_mode);
 460        } else {
 461                cam->cam_mode = sif_072a_mode;
 462                cam->nmodes = ARRAY_SIZE(sif_072a_mode);
 463        }
 464        sd->brightness = BRIGHTNESS_DEF;
 465        sd->contrast = CONTRAST_DEF;
 466        sd->white = HUE_DEF;
 467        sd->exposure = EXPOSURE_DEF;
 468        sd->autogain = AUTOGAIN_DEF;
 469        sd->gain = GAIN_DEF;
 470        sd->expo12a = EXPO12A_DEF;
 471        return 0;
 472}
 473
 474/* this function is called at probe and resume time */
 475static int sd_init_12a(struct gspca_dev *gspca_dev)
 476{
 477        PDEBUG(D_STREAM, "Chip revision: 012a");
 478        init_161rev12A(gspca_dev);
 479        return 0;
 480}
 481static int sd_init_72a(struct gspca_dev *gspca_dev)
 482{
 483        PDEBUG(D_STREAM, "Chip revision: 072a");
 484        write_vector(gspca_dev, rev72a_reset);
 485        msleep(200);
 486        write_vector(gspca_dev, rev72a_init_data1);
 487        write_sensor_72a(gspca_dev, rev72a_init_sensor1);
 488        write_vector(gspca_dev, rev72a_init_data2);
 489        write_sensor_72a(gspca_dev, rev72a_init_sensor2);
 490        reg_w_val(gspca_dev->dev, 0x8112, 0x30);
 491        return 0;
 492}
 493
 494/* rev 72a only */
 495static void setbrightness(struct gspca_dev *gspca_dev)
 496{
 497        struct sd *sd = (struct sd *) gspca_dev;
 498        struct usb_device *dev = gspca_dev->dev;
 499        __u8 value;
 500
 501        value = sd->brightness;
 502
 503        /* offsets for white balance */
 504        reg_w_val(dev, 0x8611, value);          /* R */
 505        reg_w_val(dev, 0x8612, value);          /* Gr */
 506        reg_w_val(dev, 0x8613, value);          /* B */
 507        reg_w_val(dev, 0x8614, value);          /* Gb */
 508}
 509
 510static void setwhite(struct gspca_dev *gspca_dev)
 511{
 512        struct sd *sd = (struct sd *) gspca_dev;
 513        __u16 white;
 514        __u8 blue, red;
 515        __u16 reg;
 516
 517        /* try to emulate MS-win as possible */
 518        white = sd->white;
 519        red = 0x20 + white * 3 / 8;
 520        blue = 0x90 - white * 5 / 8;
 521        if (sd->chip_revision == Rev012A) {
 522                reg = 0x8614;
 523        } else {
 524                reg = 0x8651;
 525                red += sd->contrast - 0x20;
 526                blue += sd->contrast - 0x20;
 527        }
 528        reg_w_val(gspca_dev->dev, reg, red);
 529        reg_w_val(gspca_dev->dev, reg + 2, blue);
 530}
 531
 532static void setcontrast(struct gspca_dev *gspca_dev)
 533{
 534        struct sd *sd = (struct sd *) gspca_dev;
 535        struct usb_device *dev = gspca_dev->dev;
 536        __u8 value;
 537
 538        if (sd->chip_revision != Rev072A)
 539                return;
 540        value = sd->contrast + 0x20;
 541
 542        /* gains for white balance */
 543        setwhite(gspca_dev);
 544/*      reg_w_val(dev, 0x8651, value);           * R - done by setwhite */
 545        reg_w_val(dev, 0x8652, value);          /* Gr */
 546/*      reg_w_val(dev, 0x8653, value);           * B - done by setwhite */
 547        reg_w_val(dev, 0x8654, value);          /* Gb */
 548}
 549
 550/* rev 12a only */
 551static void setexposure(struct gspca_dev *gspca_dev)
 552{
 553        struct sd *sd = (struct sd *) gspca_dev;
 554        int i, expo = 0;
 555
 556        /* Register 0x8309 controls exposure for the spca561,
 557           the basic exposure setting goes from 1-2047, where 1 is completely
 558           dark and 2047 is very bright. It not only influences exposure but
 559           also the framerate (to allow for longer exposure) from 1 - 300 it
 560           only raises the exposure time then from 300 - 600 it halves the
 561           framerate to be able to further raise the exposure time and for every
 562           300 more it halves the framerate again. This allows for a maximum
 563           exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
 564           Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
 565           configure a divider for the base framerate which us used at the
 566           exposure setting of 1-300. These bits configure the base framerate
 567           according to the following formula: fps = 60 / (value + 2) */
 568
 569        /* We choose to use the high bits setting the fixed framerate divisor
 570           asap, as setting high basic exposure setting without the fixed
 571           divider in combination with high gains makes the cam stop */
 572        int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
 573
 574        for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
 575                if (sd->exposure <= table[i + 1]) {
 576                        expo  = sd->exposure - table[i];
 577                        if (i)
 578                                expo += 300;
 579                        expo |= i << 11;
 580                        break;
 581                }
 582        }
 583
 584        gspca_dev->usb_buf[0] = expo;
 585        gspca_dev->usb_buf[1] = expo >> 8;
 586        reg_w_buf(gspca_dev, 0x8309, 2);
 587}
 588
 589/* rev 12a only */
 590static void setgain(struct gspca_dev *gspca_dev)
 591{
 592        struct sd *sd = (struct sd *) gspca_dev;
 593
 594        /* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
 595           sensitivity when set, so 31 + one of them set == 63, and 15
 596           with both of them set == 63 */
 597        if (sd->gain < 64)
 598                gspca_dev->usb_buf[0] = sd->gain;
 599        else if (sd->gain < 128)
 600                gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
 601        else
 602                gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
 603
 604        gspca_dev->usb_buf[1] = 0;
 605        reg_w_buf(gspca_dev, 0x8335, 2);
 606}
 607
 608static void setautogain(struct gspca_dev *gspca_dev)
 609{
 610        struct sd *sd = (struct sd *) gspca_dev;
 611
 612        if (sd->autogain)
 613                sd->ag_cnt = AG_CNT_START;
 614        else
 615                sd->ag_cnt = -1;
 616}
 617
 618static int sd_start_12a(struct gspca_dev *gspca_dev)
 619{
 620        struct usb_device *dev = gspca_dev->dev;
 621        int mode;
 622        static const __u8 Reg8391[8] =
 623                {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
 624
 625        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 626        if (mode <= 1) {
 627                /* Use compression on 320x240 and above */
 628                reg_w_val(dev, 0x8500, 0x10 | mode);
 629        } else {
 630                /* I couldn't get the compression to work below 320x240
 631                 * Fortunately at these resolutions the bandwidth
 632                 * is sufficient to push raw frames at ~20fps */
 633                reg_w_val(dev, 0x8500, mode);
 634        }               /* -- qq@kuku.eu.org */
 635
 636        gspca_dev->usb_buf[0] = 0xaa;
 637        gspca_dev->usb_buf[1] = 0x00;
 638        reg_w_buf(gspca_dev, 0x8307, 2);
 639        /* clock - lower 0x8X values lead to fps > 30 */
 640        reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
 641                                        /* 0x8f 0x85 0x27 clock */
 642        reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
 643        reg_w_val(gspca_dev->dev, 0x850b, 0x03);
 644        memcpy(gspca_dev->usb_buf, Reg8391, 8);
 645        reg_w_buf(gspca_dev, 0x8391, 8);
 646        reg_w_buf(gspca_dev, 0x8390, 8);
 647        setwhite(gspca_dev);
 648        setgain(gspca_dev);
 649        setexposure(gspca_dev);
 650
 651        /* Led ON (bit 3 -> 0 */
 652        reg_w_val(gspca_dev->dev, 0x8114, 0x00);
 653        return 0;
 654}
 655static int sd_start_72a(struct gspca_dev *gspca_dev)
 656{
 657        struct usb_device *dev = gspca_dev->dev;
 658        int Clck;
 659        int mode;
 660
 661        write_vector(gspca_dev, rev72a_reset);
 662        msleep(200);
 663        write_vector(gspca_dev, rev72a_init_data1);
 664        write_sensor_72a(gspca_dev, rev72a_init_sensor1);
 665
 666        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 667        switch (mode) {
 668        default:
 669        case 0:
 670                Clck = 0x27;            /* ms-win 0x87 */
 671                break;
 672        case 1:
 673                Clck = 0x25;
 674                break;
 675        case 2:
 676                Clck = 0x22;
 677                break;
 678        case 3:
 679                Clck = 0x21;
 680                break;
 681        }
 682        reg_w_val(dev, 0x8700, Clck);   /* 0x27 clock */
 683        reg_w_val(dev, 0x8702, 0x81);
 684        reg_w_val(dev, 0x8500, mode);   /* mode */
 685        write_sensor_72a(gspca_dev, rev72a_init_sensor2);
 686        setcontrast(gspca_dev);
 687/*      setbrightness(gspca_dev);        * fixme: bad values */
 688        setautogain(gspca_dev);
 689        reg_w_val(dev, 0x8112, 0x10 | 0x20);
 690        return 0;
 691}
 692
 693static void sd_stopN(struct gspca_dev *gspca_dev)
 694{
 695        struct sd *sd = (struct sd *) gspca_dev;
 696
 697        if (sd->chip_revision == Rev012A) {
 698                reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
 699                /* Led Off (bit 3 -> 1 */
 700                reg_w_val(gspca_dev->dev, 0x8114, 0x08);
 701        } else {
 702                reg_w_val(gspca_dev->dev, 0x8112, 0x20);
 703/*              reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
 704        }
 705}
 706
 707static void do_autogain(struct gspca_dev *gspca_dev)
 708{
 709        struct sd *sd = (struct sd *) gspca_dev;
 710        int expotimes;
 711        int pixelclk;
 712        int gainG;
 713        __u8 R, Gr, Gb, B;
 714        int y;
 715        __u8 luma_mean = 110;
 716        __u8 luma_delta = 20;
 717        __u8 spring = 4;
 718
 719        if (sd->ag_cnt < 0)
 720                return;
 721        if (--sd->ag_cnt >= 0)
 722                return;
 723        sd->ag_cnt = AG_CNT_START;
 724
 725        switch (sd->chip_revision) {
 726        case Rev072A:
 727                reg_r(gspca_dev, 0x8621, 1);
 728                Gr = gspca_dev->usb_buf[0];
 729                reg_r(gspca_dev, 0x8622, 1);
 730                R = gspca_dev->usb_buf[0];
 731                reg_r(gspca_dev, 0x8623, 1);
 732                B = gspca_dev->usb_buf[0];
 733                reg_r(gspca_dev, 0x8624, 1);
 734                Gb = gspca_dev->usb_buf[0];
 735                y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
 736                /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
 737                /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
 738                /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
 739
 740                if (y < luma_mean - luma_delta ||
 741                    y > luma_mean + luma_delta) {
 742                        expotimes = i2c_read(gspca_dev, 0x09, 0x10);
 743                        pixelclk = 0x0800;
 744                        expotimes = expotimes & 0x07ff;
 745                        /* PDEBUG(D_PACK,
 746                                "Exposition Times 0x%03X Clock 0x%04X ",
 747                                expotimes,pixelclk); */
 748                        gainG = i2c_read(gspca_dev, 0x35, 0x10);
 749                        /* PDEBUG(D_PACK,
 750                                "reading Gain register %d", gainG); */
 751
 752                        expotimes += (luma_mean - y) >> spring;
 753                        gainG += (luma_mean - y) / 50;
 754                        /* PDEBUG(D_PACK,
 755                                "compute expotimes %d gain %d",
 756                                expotimes,gainG); */
 757
 758                        if (gainG > 0x3f)
 759                                gainG = 0x3f;
 760                        else if (gainG < 3)
 761                                gainG = 3;
 762                        i2c_write(gspca_dev, gainG, 0x35);
 763
 764                        if (expotimes > 0x0256)
 765                                expotimes = 0x0256;
 766                        else if (expotimes < 3)
 767                                expotimes = 3;
 768                        i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
 769                }
 770                break;
 771        }
 772}
 773
 774static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 775                        u8 *data,               /* isoc packet */
 776                        int len)                /* iso packet length */
 777{
 778        struct sd *sd = (struct sd *) gspca_dev;
 779
 780        len--;
 781        switch (*data++) {                      /* sequence number */
 782        case 0:                                 /* start of frame */
 783                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 784
 785                /* This should never happen */
 786                if (len < 2) {
 787                        PDEBUG(D_ERR, "Short SOF packet, ignoring");
 788                        gspca_dev->last_packet_type = DISCARD_PACKET;
 789                        return;
 790                }
 791
 792#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
 793                if (data[0] & 0x20) {
 794                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
 795                        input_sync(gspca_dev->input_dev);
 796                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
 797                        input_sync(gspca_dev->input_dev);
 798                }
 799#endif
 800
 801                if (data[1] & 0x10) {
 802                        /* compressed bayer */
 803                        gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 804                } else {
 805                        /* raw bayer (with a header, which we skip) */
 806                        if (sd->chip_revision == Rev012A) {
 807                                data += 20;
 808                                len -= 20;
 809                        } else {
 810                                data += 16;
 811                                len -= 16;
 812                        }
 813                        gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 814                }
 815                return;
 816        case 0xff:                      /* drop (empty mpackets) */
 817                return;
 818        }
 819        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 820}
 821
 822/* rev 72a only */
 823static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 824{
 825        struct sd *sd = (struct sd *) gspca_dev;
 826
 827        sd->brightness = val;
 828        if (gspca_dev->streaming)
 829                setbrightness(gspca_dev);
 830        return 0;
 831}
 832
 833static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
 834{
 835        struct sd *sd = (struct sd *) gspca_dev;
 836
 837        *val = sd->brightness;
 838        return 0;
 839}
 840
 841/* rev 72a only */
 842static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 843{
 844        struct sd *sd = (struct sd *) gspca_dev;
 845
 846        sd->contrast = val;
 847        if (gspca_dev->streaming)
 848                setcontrast(gspca_dev);
 849        return 0;
 850}
 851
 852static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
 853{
 854        struct sd *sd = (struct sd *) gspca_dev;
 855
 856        *val = sd->contrast;
 857        return 0;
 858}
 859
 860static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
 861{
 862        struct sd *sd = (struct sd *) gspca_dev;
 863
 864        sd->autogain = val;
 865        if (gspca_dev->streaming)
 866                setautogain(gspca_dev);
 867        return 0;
 868}
 869
 870static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
 871{
 872        struct sd *sd = (struct sd *) gspca_dev;
 873
 874        *val = sd->autogain;
 875        return 0;
 876}
 877
 878static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
 879{
 880        struct sd *sd = (struct sd *) gspca_dev;
 881
 882        sd->white = val;
 883        if (gspca_dev->streaming)
 884                setwhite(gspca_dev);
 885        return 0;
 886}
 887
 888static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
 889{
 890        struct sd *sd = (struct sd *) gspca_dev;
 891
 892        *val = sd->white;
 893        return 0;
 894}
 895
 896/* rev12a only */
 897static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
 898{
 899        struct sd *sd = (struct sd *) gspca_dev;
 900
 901        sd->exposure = val;
 902        if (gspca_dev->streaming)
 903                setexposure(gspca_dev);
 904        return 0;
 905}
 906
 907static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
 908{
 909        struct sd *sd = (struct sd *) gspca_dev;
 910
 911        *val = sd->exposure;
 912        return 0;
 913}
 914
 915/* rev12a only */
 916static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
 917{
 918        struct sd *sd = (struct sd *) gspca_dev;
 919
 920        sd->gain = val;
 921        if (gspca_dev->streaming)
 922                setgain(gspca_dev);
 923        return 0;
 924}
 925
 926static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
 927{
 928        struct sd *sd = (struct sd *) gspca_dev;
 929
 930        *val = sd->gain;
 931        return 0;
 932}
 933
 934/* control tables */
 935static const struct ctrl sd_ctrls_12a[] = {
 936        {
 937            {
 938                .id = V4L2_CID_HUE,
 939                .type = V4L2_CTRL_TYPE_INTEGER,
 940                .name = "Hue",
 941                .minimum = HUE_MIN,
 942                .maximum = HUE_MAX,
 943                .step = 1,
 944                .default_value = HUE_DEF,
 945            },
 946            .set = sd_setwhite,
 947            .get = sd_getwhite,
 948        },
 949        {
 950            {
 951                .id = V4L2_CID_EXPOSURE,
 952                .type = V4L2_CTRL_TYPE_INTEGER,
 953                .name = "Exposure",
 954                .minimum = EXPOSURE_MIN,
 955                .maximum = EXPOSURE_MAX,
 956                .step = 1,
 957                .default_value = EXPOSURE_DEF,
 958            },
 959            .set = sd_setexposure,
 960            .get = sd_getexposure,
 961        },
 962        {
 963            {
 964                .id = V4L2_CID_GAIN,
 965                .type = V4L2_CTRL_TYPE_INTEGER,
 966                .name = "Gain",
 967                .minimum = GAIN_MIN,
 968                .maximum = GAIN_MAX,
 969                .step = 1,
 970                .default_value = GAIN_DEF,
 971            },
 972            .set = sd_setgain,
 973            .get = sd_getgain,
 974        },
 975};
 976
 977static const struct ctrl sd_ctrls_72a[] = {
 978        {
 979            {
 980                .id = V4L2_CID_HUE,
 981                .type = V4L2_CTRL_TYPE_INTEGER,
 982                .name = "Hue",
 983                .minimum = HUE_MIN,
 984                .maximum = HUE_MAX,
 985                .step = 1,
 986                .default_value = HUE_DEF,
 987            },
 988            .set = sd_setwhite,
 989            .get = sd_getwhite,
 990        },
 991        {
 992           {
 993                .id = V4L2_CID_BRIGHTNESS,
 994                .type = V4L2_CTRL_TYPE_INTEGER,
 995                .name = "Brightness",
 996                .minimum = BRIGHTNESS_MIN,
 997                .maximum = BRIGHTNESS_MAX,
 998                .step = 1,
 999                .default_value = BRIGHTNESS_DEF,
1000            },
1001            .set = sd_setbrightness,
1002            .get = sd_getbrightness,
1003        },
1004        {
1005            {
1006                .id = V4L2_CID_CONTRAST,
1007                .type = V4L2_CTRL_TYPE_INTEGER,
1008                .name = "Contrast",
1009                .minimum = CONTRAST_MIN,
1010                .maximum = CONTRAST_MAX,
1011                .step = 1,
1012                .default_value = CONTRAST_DEF,
1013            },
1014            .set = sd_setcontrast,
1015            .get = sd_getcontrast,
1016        },
1017        {
1018            {
1019                .id = V4L2_CID_AUTOGAIN,
1020                .type = V4L2_CTRL_TYPE_BOOLEAN,
1021                .name = "Auto Gain",
1022                .minimum = AUTOGAIN_MIN,
1023                .maximum = AUTOGAIN_MAX,
1024                .step = 1,
1025                .default_value = AUTOGAIN_DEF,
1026            },
1027            .set = sd_setautogain,
1028            .get = sd_getautogain,
1029        },
1030};
1031
1032/* sub-driver description */
1033static const struct sd_desc sd_desc_12a = {
1034        .name = MODULE_NAME,
1035        .ctrls = sd_ctrls_12a,
1036        .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1037        .config = sd_config,
1038        .init = sd_init_12a,
1039        .start = sd_start_12a,
1040        .stopN = sd_stopN,
1041        .pkt_scan = sd_pkt_scan,
1042#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1043        .other_input = 1,
1044#endif
1045};
1046static const struct sd_desc sd_desc_72a = {
1047        .name = MODULE_NAME,
1048        .ctrls = sd_ctrls_72a,
1049        .nctrls = ARRAY_SIZE(sd_ctrls_72a),
1050        .config = sd_config,
1051        .init = sd_init_72a,
1052        .start = sd_start_72a,
1053        .stopN = sd_stopN,
1054        .pkt_scan = sd_pkt_scan,
1055        .dq_callback = do_autogain,
1056#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1057        .other_input = 1,
1058#endif
1059};
1060static const struct sd_desc *sd_desc[2] = {
1061        &sd_desc_12a,
1062        &sd_desc_72a
1063};
1064
1065/* -- module initialisation -- */
1066static const struct usb_device_id device_table[] = {
1067        {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1068        {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1069        {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1070        {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1071        {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1072        {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1073        {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1074        {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1075        {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1076        {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1077        {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1078        {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1079        {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1080        {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1081        {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1082        {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1083        {}
1084};
1085
1086MODULE_DEVICE_TABLE(usb, device_table);
1087
1088/* -- device connect -- */
1089static int sd_probe(struct usb_interface *intf,
1090                    const struct usb_device_id *id)
1091{
1092        return gspca_dev_probe(intf, id,
1093                                sd_desc[id->driver_info],
1094                                sizeof(struct sd),
1095                               THIS_MODULE);
1096}
1097
1098static struct usb_driver sd_driver = {
1099        .name = MODULE_NAME,
1100        .id_table = device_table,
1101        .probe = sd_probe,
1102        .disconnect = gspca_disconnect,
1103#ifdef CONFIG_PM
1104        .suspend = gspca_suspend,
1105        .resume = gspca_resume,
1106#endif
1107};
1108
1109/* -- module insert / remove -- */
1110static int __init sd_mod_init(void)
1111{
1112        return usb_register(&sd_driver);
1113}
1114static void __exit sd_mod_exit(void)
1115{
1116        usb_deregister(&sd_driver);
1117}
1118
1119module_init(sd_mod_init);
1120module_exit(sd_mod_exit);
1121
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.