Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Sunplus spca561 subdriver
0004  *
0005  * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
0006  *
0007  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #define MODULE_NAME "spca561"
0013 
0014 #include <linux/input.h>
0015 #include "gspca.h"
0016 
0017 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
0018 MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
0019 MODULE_LICENSE("GPL");
0020 
0021 #define EXPOSURE_MAX (2047 + 325)
0022 
0023 /* specific webcam descriptor */
0024 struct sd {
0025     struct gspca_dev gspca_dev; /* !! must be the first item */
0026 
0027     struct { /* hue/contrast control cluster */
0028         struct v4l2_ctrl *contrast;
0029         struct v4l2_ctrl *hue;
0030     };
0031     struct v4l2_ctrl *autogain;
0032 
0033 #define EXPO12A_DEF 3
0034     __u8 expo12a;       /* expo/gain? for rev 12a */
0035 
0036     __u8 chip_revision;
0037 #define Rev012A 0
0038 #define Rev072A 1
0039 
0040     signed char ag_cnt;
0041 #define AG_CNT_START 13
0042 };
0043 
0044 static const struct v4l2_pix_format sif_012a_mode[] = {
0045     {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0046         .bytesperline = 160,
0047         .sizeimage = 160 * 120,
0048         .colorspace = V4L2_COLORSPACE_SRGB,
0049         .priv = 3},
0050     {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0051         .bytesperline = 176,
0052         .sizeimage = 176 * 144,
0053         .colorspace = V4L2_COLORSPACE_SRGB,
0054         .priv = 2},
0055     {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
0056         .bytesperline = 320,
0057         .sizeimage = 320 * 240 * 4 / 8,
0058         .colorspace = V4L2_COLORSPACE_SRGB,
0059         .priv = 1},
0060     {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
0061         .bytesperline = 352,
0062         .sizeimage = 352 * 288 * 4 / 8,
0063         .colorspace = V4L2_COLORSPACE_SRGB,
0064         .priv = 0},
0065 };
0066 
0067 static const struct v4l2_pix_format sif_072a_mode[] = {
0068     {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0069         .bytesperline = 160,
0070         .sizeimage = 160 * 120,
0071         .colorspace = V4L2_COLORSPACE_SRGB,
0072         .priv = 3},
0073     {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0074         .bytesperline = 176,
0075         .sizeimage = 176 * 144,
0076         .colorspace = V4L2_COLORSPACE_SRGB,
0077         .priv = 2},
0078     {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0079         .bytesperline = 320,
0080         .sizeimage = 320 * 240,
0081         .colorspace = V4L2_COLORSPACE_SRGB,
0082         .priv = 1},
0083     {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
0084         .bytesperline = 352,
0085         .sizeimage = 352 * 288,
0086         .colorspace = V4L2_COLORSPACE_SRGB,
0087         .priv = 0},
0088 };
0089 
0090 /*
0091  * Initialization data
0092  * I'm not very sure how to split initialization from open data
0093  * chunks. For now, we'll consider everything as initialization
0094  */
0095 /* Frame packet header offsets for the spca561 */
0096 #define SPCA561_OFFSET_SNAP 1
0097 #define SPCA561_OFFSET_TYPE 2
0098 #define SPCA561_OFFSET_COMPRESS 3
0099 #define SPCA561_OFFSET_FRAMSEQ   4
0100 #define SPCA561_OFFSET_GPIO 5
0101 #define SPCA561_OFFSET_USBBUFF 6
0102 #define SPCA561_OFFSET_WIN2GRAVE 7
0103 #define SPCA561_OFFSET_WIN2RAVE 8
0104 #define SPCA561_OFFSET_WIN2BAVE 9
0105 #define SPCA561_OFFSET_WIN2GBAVE 10
0106 #define SPCA561_OFFSET_WIN1GRAVE 11
0107 #define SPCA561_OFFSET_WIN1RAVE 12
0108 #define SPCA561_OFFSET_WIN1BAVE 13
0109 #define SPCA561_OFFSET_WIN1GBAVE 14
0110 #define SPCA561_OFFSET_FREQ 15
0111 #define SPCA561_OFFSET_VSYNC 16
0112 #define SPCA561_INDEX_I2C_BASE 0x8800
0113 #define SPCA561_SNAPBIT 0x20
0114 #define SPCA561_SNAPCTRL 0x40
0115 
0116 static const u16 rev72a_reset[][2] = {
0117     {0x0000, 0x8114},   /* Software GPIO output data */
0118     {0x0001, 0x8114},   /* Software GPIO output data */
0119     {0x0000, 0x8112},   /* Some kind of reset */
0120     {}
0121 };
0122 static const __u16 rev72a_init_data1[][2] = {
0123     {0x0003, 0x8701},   /* PCLK clock delay adjustment */
0124     {0x0001, 0x8703},   /* HSYNC from cmos inverted */
0125     {0x0011, 0x8118},   /* Enable and conf sensor */
0126     {0x0001, 0x8118},   /* Conf sensor */
0127     {0x0092, 0x8804},   /* I know nothing about these */
0128     {0x0010, 0x8802},   /* 0x88xx registers, so I won't */
0129     {}
0130 };
0131 static const u16 rev72a_init_sensor1[][2] = {
0132     {0x0001, 0x000d},
0133     {0x0002, 0x0018},
0134     {0x0004, 0x0165},
0135     {0x0005, 0x0021},
0136     {0x0007, 0x00aa},
0137     {0x0020, 0x1504},
0138     {0x0039, 0x0002},
0139     {0x0035, 0x0010},
0140     {0x0009, 0x1049},
0141     {0x0028, 0x000b},
0142     {0x003b, 0x000f},
0143     {0x003c, 0x0000},
0144     {}
0145 };
0146 static const __u16 rev72a_init_data2[][2] = {
0147     {0x0018, 0x8601},   /* Pixel/line selection for color separation */
0148     {0x0000, 0x8602},   /* Optical black level for user setting */
0149     {0x0060, 0x8604},   /* Optical black horizontal offset */
0150     {0x0002, 0x8605},   /* Optical black vertical offset */
0151     {0x0000, 0x8603},   /* Non-automatic optical black level */
0152     {0x0002, 0x865b},   /* Horizontal offset for valid pixels */
0153     {0x0000, 0x865f},   /* Vertical valid pixels window (x2) */
0154     {0x00b0, 0x865d},   /* Horizontal valid pixels window (x2) */
0155     {0x0090, 0x865e},   /* Vertical valid lines window (x2) */
0156     {0x00e0, 0x8406},   /* Memory buffer threshold */
0157     {0x0000, 0x8660},   /* Compensation memory stuff */
0158     {0x0002, 0x8201},   /* Output address for r/w serial EEPROM */
0159     {0x0008, 0x8200},   /* Clear valid bit for serial EEPROM */
0160     {0x0001, 0x8200},   /* OprMode to be executed by hardware */
0161 /* from ms-win */
0162     {0x0000, 0x8611},   /* R offset for white balance */
0163     {0x00fd, 0x8612},   /* Gr offset for white balance */
0164     {0x0003, 0x8613},   /* B offset for white balance */
0165     {0x0000, 0x8614},   /* Gb offset for white balance */
0166 /* from ms-win */
0167     {0x0035, 0x8651},   /* R gain for white balance */
0168     {0x0040, 0x8652},   /* Gr gain for white balance */
0169     {0x005f, 0x8653},   /* B gain for white balance */
0170     {0x0040, 0x8654},   /* Gb gain for white balance */
0171     {0x0002, 0x8502},   /* Maximum average bit rate stuff */
0172     {0x0011, 0x8802},
0173 
0174     {0x0087, 0x8700},   /* Set master clock (96Mhz????) */
0175     {0x0081, 0x8702},   /* Master clock output enable */
0176 
0177     {0x0000, 0x8500},   /* Set image type (352x288 no compression) */
0178     /* Originally was 0x0010 (352x288 compression) */
0179 
0180     {0x0002, 0x865b},   /* Horizontal offset for valid pixels */
0181     {0x0003, 0x865c},   /* Vertical offset for valid lines */
0182     {}
0183 };
0184 static const u16 rev72a_init_sensor2[][2] = {
0185     {0x0003, 0x0121},
0186     {0x0004, 0x0165},
0187     {0x0005, 0x002f},   /* blanking control column */
0188     {0x0006, 0x0000},   /* blanking mode row*/
0189     {0x000a, 0x0002},
0190     {0x0009, 0x1061},   /* setexposure times && pixel clock
0191                  * 0001 0 | 000 0110 0001 */
0192     {0x0035, 0x0014},
0193     {}
0194 };
0195 
0196 /******************** QC Express etch2 stuff ********************/
0197 static const __u16 Pb100_1map8300[][2] = {
0198     /* reg, value */
0199     {0x8320, 0x3304},
0200 
0201     {0x8303, 0x0125},   /* image area */
0202     {0x8304, 0x0169},
0203     {0x8328, 0x000b},
0204     {0x833c, 0x0001},       /*fixme: win:07*/
0205 
0206     {0x832f, 0x1904},       /*fixme: was 0419*/
0207     {0x8307, 0x00aa},
0208     {0x8301, 0x0003},
0209     {0x8302, 0x000e},
0210     {}
0211 };
0212 static const __u16 Pb100_2map8300[][2] = {
0213     /* reg, value */
0214     {0x8339, 0x0000},
0215     {0x8307, 0x00aa},
0216     {}
0217 };
0218 
0219 static const __u16 spca561_161rev12A_data1[][2] = {
0220     {0x29, 0x8118},     /* Control register (various enable bits) */
0221     {0x08, 0x8114},     /* GPIO: Led off */
0222     {0x0e, 0x8112},     /* 0x0e stream off 0x3e stream on */
0223     {0x00, 0x8102},     /* white balance - new */
0224     {0x92, 0x8804},
0225     {0x04, 0x8802},     /* windows uses 08 */
0226     {}
0227 };
0228 static const __u16 spca561_161rev12A_data2[][2] = {
0229     {0x21, 0x8118},
0230     {0x10, 0x8500},
0231     {0x07, 0x8601},
0232     {0x07, 0x8602},
0233     {0x04, 0x8501},
0234 
0235     {0x07, 0x8201},     /* windows uses 02 */
0236     {0x08, 0x8200},
0237     {0x01, 0x8200},
0238 
0239     {0x90, 0x8604},
0240     {0x00, 0x8605},
0241     {0xb0, 0x8603},
0242 
0243     /* sensor gains */
0244     {0x07, 0x8601},     /* white balance - new */
0245     {0x07, 0x8602},     /* white balance - new */
0246     {0x00, 0x8610},     /* *red */
0247     {0x00, 0x8611},     /* 3f   *green */
0248     {0x00, 0x8612},     /* green *blue */
0249     {0x00, 0x8613},     /* blue *green */
0250     {0x43, 0x8614},     /* green *red - white balance - was 0x35 */
0251     {0x40, 0x8615},     /* 40   *green - white balance - was 0x35 */
0252     {0x71, 0x8616},     /* 7a   *blue - white balance - was 0x35 */
0253     {0x40, 0x8617},     /* 40   *green - white balance - was 0x35 */
0254 
0255     {0x0c, 0x8620},     /* 0c */
0256     {0xc8, 0x8631},     /* c8 */
0257     {0xc8, 0x8634},     /* c8 */
0258     {0x23, 0x8635},     /* 23 */
0259     {0x1f, 0x8636},     /* 1f */
0260     {0xdd, 0x8637},     /* dd */
0261     {0xe1, 0x8638},     /* e1 */
0262     {0x1d, 0x8639},     /* 1d */
0263     {0x21, 0x863a},     /* 21 */
0264     {0xe3, 0x863b},     /* e3 */
0265     {0xdf, 0x863c},     /* df */
0266     {0xf0, 0x8505},
0267     {0x32, 0x850a},
0268 /*  {0x99, 0x8700},      * - white balance - new (removed) */
0269     /* HDG we used to do this in stop0, making the init state and the state
0270        after a start / stop different, so do this here instead. */
0271     {0x29, 0x8118},
0272     {}
0273 };
0274 
0275 static void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value)
0276 {
0277     int ret;
0278     struct usb_device *dev = gspca_dev->dev;
0279 
0280     ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0281                   0,        /* request */
0282                   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0283                   value, index, NULL, 0, 500);
0284     gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x:0x%02x\n",
0285           index, value);
0286     if (ret < 0)
0287         pr_err("reg write: error %d\n", ret);
0288 }
0289 
0290 static void write_vector(struct gspca_dev *gspca_dev,
0291             const __u16 data[][2])
0292 {
0293     int i;
0294 
0295     i = 0;
0296     while (data[i][1] != 0) {
0297         reg_w_val(gspca_dev, data[i][1], data[i][0]);
0298         i++;
0299     }
0300 }
0301 
0302 /* read 'len' bytes to gspca_dev->usb_buf */
0303 static void reg_r(struct gspca_dev *gspca_dev,
0304           __u16 index, __u16 length)
0305 {
0306     usb_control_msg(gspca_dev->dev,
0307             usb_rcvctrlpipe(gspca_dev->dev, 0),
0308             0,          /* request */
0309             USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0310             0,          /* value */
0311             index, gspca_dev->usb_buf, length, 500);
0312 }
0313 
0314 /* write 'len' bytes from gspca_dev->usb_buf */
0315 static void reg_w_buf(struct gspca_dev *gspca_dev,
0316               __u16 index, __u16 len)
0317 {
0318     usb_control_msg(gspca_dev->dev,
0319             usb_sndctrlpipe(gspca_dev->dev, 0),
0320             0,          /* request */
0321             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0322             0,          /* value */
0323             index, gspca_dev->usb_buf, len, 500);
0324 }
0325 
0326 static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
0327 {
0328     int retry = 60;
0329 
0330     reg_w_val(gspca_dev, 0x8801, reg);
0331     reg_w_val(gspca_dev, 0x8805, value);
0332     reg_w_val(gspca_dev, 0x8800, value >> 8);
0333     do {
0334         reg_r(gspca_dev, 0x8803, 1);
0335         if (!gspca_dev->usb_buf[0])
0336             return;
0337         msleep(10);
0338     } while (--retry);
0339 }
0340 
0341 static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
0342 {
0343     int retry = 60;
0344     __u8 value;
0345 
0346     reg_w_val(gspca_dev, 0x8804, 0x92);
0347     reg_w_val(gspca_dev, 0x8801, reg);
0348     reg_w_val(gspca_dev, 0x8802, mode | 0x01);
0349     do {
0350         reg_r(gspca_dev, 0x8803, 1);
0351         if (!gspca_dev->usb_buf[0]) {
0352             reg_r(gspca_dev, 0x8800, 1);
0353             value = gspca_dev->usb_buf[0];
0354             reg_r(gspca_dev, 0x8805, 1);
0355             return ((int) value << 8) | gspca_dev->usb_buf[0];
0356         }
0357         msleep(10);
0358     } while (--retry);
0359     return -1;
0360 }
0361 
0362 static void sensor_mapwrite(struct gspca_dev *gspca_dev,
0363                 const __u16 (*sensormap)[2])
0364 {
0365     while ((*sensormap)[0]) {
0366         gspca_dev->usb_buf[0] = (*sensormap)[1];
0367         gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
0368         reg_w_buf(gspca_dev, (*sensormap)[0], 2);
0369         sensormap++;
0370     }
0371 }
0372 
0373 static void write_sensor_72a(struct gspca_dev *gspca_dev,
0374                 const __u16 (*sensor)[2])
0375 {
0376     while ((*sensor)[0]) {
0377         i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
0378         sensor++;
0379     }
0380 }
0381 
0382 static void init_161rev12A(struct gspca_dev *gspca_dev)
0383 {
0384     write_vector(gspca_dev, spca561_161rev12A_data1);
0385     sensor_mapwrite(gspca_dev, Pb100_1map8300);
0386 /*fixme: should be in sd_start*/
0387     write_vector(gspca_dev, spca561_161rev12A_data2);
0388     sensor_mapwrite(gspca_dev, Pb100_2map8300);
0389 }
0390 
0391 /* this function is called at probe time */
0392 static int sd_config(struct gspca_dev *gspca_dev,
0393              const struct usb_device_id *id)
0394 {
0395     struct sd *sd = (struct sd *) gspca_dev;
0396     struct cam *cam;
0397     __u16 vendor, product;
0398     __u8 data1, data2;
0399 
0400     /* Read frm global register the USB product and vendor IDs, just to
0401      * prove that we can communicate with the device.  This works, which
0402      * confirms at we are communicating properly and that the device
0403      * is a 561. */
0404     reg_r(gspca_dev, 0x8104, 1);
0405     data1 = gspca_dev->usb_buf[0];
0406     reg_r(gspca_dev, 0x8105, 1);
0407     data2 = gspca_dev->usb_buf[0];
0408     vendor = (data2 << 8) | data1;
0409     reg_r(gspca_dev, 0x8106, 1);
0410     data1 = gspca_dev->usb_buf[0];
0411     reg_r(gspca_dev, 0x8107, 1);
0412     data2 = gspca_dev->usb_buf[0];
0413     product = (data2 << 8) | data1;
0414     if (vendor != id->idVendor || product != id->idProduct) {
0415         gspca_dbg(gspca_dev, D_PROBE, "Bad vendor / product from device\n");
0416         return -EINVAL;
0417     }
0418 
0419     cam = &gspca_dev->cam;
0420     cam->needs_full_bandwidth = 1;
0421 
0422     sd->chip_revision = id->driver_info;
0423     if (sd->chip_revision == Rev012A) {
0424         cam->cam_mode = sif_012a_mode;
0425         cam->nmodes = ARRAY_SIZE(sif_012a_mode);
0426     } else {
0427         cam->cam_mode = sif_072a_mode;
0428         cam->nmodes = ARRAY_SIZE(sif_072a_mode);
0429     }
0430     sd->expo12a = EXPO12A_DEF;
0431     return 0;
0432 }
0433 
0434 /* this function is called at probe and resume time */
0435 static int sd_init_12a(struct gspca_dev *gspca_dev)
0436 {
0437     gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 012a\n");
0438     init_161rev12A(gspca_dev);
0439     return 0;
0440 }
0441 static int sd_init_72a(struct gspca_dev *gspca_dev)
0442 {
0443     gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 072a\n");
0444     write_vector(gspca_dev, rev72a_reset);
0445     msleep(200);
0446     write_vector(gspca_dev, rev72a_init_data1);
0447     write_sensor_72a(gspca_dev, rev72a_init_sensor1);
0448     write_vector(gspca_dev, rev72a_init_data2);
0449     write_sensor_72a(gspca_dev, rev72a_init_sensor2);
0450     reg_w_val(gspca_dev, 0x8112, 0x30);
0451     return 0;
0452 }
0453 
0454 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
0455 {
0456     struct sd *sd = (struct sd *) gspca_dev;
0457     __u16 reg;
0458 
0459     if (sd->chip_revision == Rev012A)
0460         reg = 0x8610;
0461     else
0462         reg = 0x8611;
0463 
0464     reg_w_val(gspca_dev, reg + 0, val);     /* R */
0465     reg_w_val(gspca_dev, reg + 1, val);     /* Gr */
0466     reg_w_val(gspca_dev, reg + 2, val);     /* B */
0467     reg_w_val(gspca_dev, reg + 3, val);     /* Gb */
0468 }
0469 
0470 static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast)
0471 {
0472     struct sd *sd = (struct sd *) gspca_dev;
0473     __u8 blue, red;
0474     __u16 reg;
0475 
0476     /* try to emulate MS-win as possible */
0477     red = 0x20 + white * 3 / 8;
0478     blue = 0x90 - white * 5 / 8;
0479     if (sd->chip_revision == Rev012A) {
0480         reg = 0x8614;
0481     } else {
0482         reg = 0x8651;
0483         red += contrast - 0x20;
0484         blue += contrast - 0x20;
0485         reg_w_val(gspca_dev, 0x8652, contrast + 0x20); /* Gr */
0486         reg_w_val(gspca_dev, 0x8654, contrast + 0x20); /* Gb */
0487     }
0488     reg_w_val(gspca_dev, reg, red);
0489     reg_w_val(gspca_dev, reg + 2, blue);
0490 }
0491 
0492 /* rev 12a only */
0493 static void setexposure(struct gspca_dev *gspca_dev, s32 val)
0494 {
0495     int i, expo = 0;
0496 
0497     /* Register 0x8309 controls exposure for the spca561,
0498        the basic exposure setting goes from 1-2047, where 1 is completely
0499        dark and 2047 is very bright. It not only influences exposure but
0500        also the framerate (to allow for longer exposure) from 1 - 300 it
0501        only raises the exposure time then from 300 - 600 it halves the
0502        framerate to be able to further raise the exposure time and for every
0503        300 more it halves the framerate again. This allows for a maximum
0504        exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
0505        Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
0506        configure a divider for the base framerate which us used at the
0507        exposure setting of 1-300. These bits configure the base framerate
0508        according to the following formula: fps = 60 / (value + 2) */
0509 
0510     /* We choose to use the high bits setting the fixed framerate divisor
0511        asap, as setting high basic exposure setting without the fixed
0512        divider in combination with high gains makes the cam stop */
0513     static const int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
0514 
0515     for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
0516         if (val <= table[i + 1]) {
0517             expo  = val - table[i];
0518             if (i)
0519                 expo += 300;
0520             expo |= i << 11;
0521             break;
0522         }
0523     }
0524 
0525     gspca_dev->usb_buf[0] = expo;
0526     gspca_dev->usb_buf[1] = expo >> 8;
0527     reg_w_buf(gspca_dev, 0x8309, 2);
0528 }
0529 
0530 /* rev 12a only */
0531 static void setgain(struct gspca_dev *gspca_dev, s32 val)
0532 {
0533     /* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
0534        sensitivity when set, so 31 + one of them set == 63, and 15
0535        with both of them set == 63 */
0536     if (val < 64)
0537         gspca_dev->usb_buf[0] = val;
0538     else if (val < 128)
0539         gspca_dev->usb_buf[0] = (val / 2) | 0x40;
0540     else
0541         gspca_dev->usb_buf[0] = (val / 4) | 0xc0;
0542 
0543     gspca_dev->usb_buf[1] = 0;
0544     reg_w_buf(gspca_dev, 0x8335, 2);
0545 }
0546 
0547 static void setautogain(struct gspca_dev *gspca_dev, s32 val)
0548 {
0549     struct sd *sd = (struct sd *) gspca_dev;
0550 
0551     if (val)
0552         sd->ag_cnt = AG_CNT_START;
0553     else
0554         sd->ag_cnt = -1;
0555 }
0556 
0557 static int sd_start_12a(struct gspca_dev *gspca_dev)
0558 {
0559     int mode;
0560     static const __u8 Reg8391[8] =
0561         {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
0562 
0563     mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
0564     if (mode <= 1) {
0565         /* Use compression on 320x240 and above */
0566         reg_w_val(gspca_dev, 0x8500, 0x10 | mode);
0567     } else {
0568         /* I couldn't get the compression to work below 320x240
0569          * Fortunately at these resolutions the bandwidth
0570          * is sufficient to push raw frames at ~20fps */
0571         reg_w_val(gspca_dev, 0x8500, mode);
0572     }       /* -- qq@kuku.eu.org */
0573 
0574     gspca_dev->usb_buf[0] = 0xaa;
0575     gspca_dev->usb_buf[1] = 0x00;
0576     reg_w_buf(gspca_dev, 0x8307, 2);
0577     /* clock - lower 0x8X values lead to fps > 30 */
0578     reg_w_val(gspca_dev, 0x8700, 0x8a);
0579                     /* 0x8f 0x85 0x27 clock */
0580     reg_w_val(gspca_dev, 0x8112, 0x1e | 0x20);
0581     reg_w_val(gspca_dev, 0x850b, 0x03);
0582     memcpy(gspca_dev->usb_buf, Reg8391, 8);
0583     reg_w_buf(gspca_dev, 0x8391, 8);
0584     reg_w_buf(gspca_dev, 0x8390, 8);
0585 
0586     /* Led ON (bit 3 -> 0 */
0587     reg_w_val(gspca_dev, 0x8114, 0x00);
0588     return 0;
0589 }
0590 static int sd_start_72a(struct gspca_dev *gspca_dev)
0591 {
0592     struct sd *sd = (struct sd *) gspca_dev;
0593     int Clck;
0594     int mode;
0595 
0596     write_vector(gspca_dev, rev72a_reset);
0597     msleep(200);
0598     write_vector(gspca_dev, rev72a_init_data1);
0599     write_sensor_72a(gspca_dev, rev72a_init_sensor1);
0600 
0601     mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
0602     switch (mode) {
0603     default:
0604     case 0:
0605         Clck = 0x27;        /* ms-win 0x87 */
0606         break;
0607     case 1:
0608         Clck = 0x25;
0609         break;
0610     case 2:
0611         Clck = 0x22;
0612         break;
0613     case 3:
0614         Clck = 0x21;
0615         break;
0616     }
0617     reg_w_val(gspca_dev, 0x8700, Clck); /* 0x27 clock */
0618     reg_w_val(gspca_dev, 0x8702, 0x81);
0619     reg_w_val(gspca_dev, 0x8500, mode); /* mode */
0620     write_sensor_72a(gspca_dev, rev72a_init_sensor2);
0621     setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue),
0622             v4l2_ctrl_g_ctrl(sd->contrast));
0623 /*  setbrightness(gspca_dev);    * fixme: bad values */
0624     setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
0625     reg_w_val(gspca_dev, 0x8112, 0x10 | 0x20);
0626     return 0;
0627 }
0628 
0629 static void sd_stopN(struct gspca_dev *gspca_dev)
0630 {
0631     struct sd *sd = (struct sd *) gspca_dev;
0632 
0633     if (sd->chip_revision == Rev012A) {
0634         reg_w_val(gspca_dev, 0x8112, 0x0e);
0635         /* Led Off (bit 3 -> 1 */
0636         reg_w_val(gspca_dev, 0x8114, 0x08);
0637     } else {
0638         reg_w_val(gspca_dev, 0x8112, 0x20);
0639 /*      reg_w_val(gspca_dev, 0x8102, 0x00); ?? */
0640     }
0641 }
0642 
0643 static void do_autogain(struct gspca_dev *gspca_dev)
0644 {
0645     struct sd *sd = (struct sd *) gspca_dev;
0646     int expotimes;
0647     int pixelclk;
0648     int gainG;
0649     __u8 R, Gr, Gb, B;
0650     int y;
0651     __u8 luma_mean = 110;
0652     __u8 luma_delta = 20;
0653     __u8 spring = 4;
0654 
0655     if (sd->ag_cnt < 0)
0656         return;
0657     if (--sd->ag_cnt >= 0)
0658         return;
0659     sd->ag_cnt = AG_CNT_START;
0660 
0661     switch (sd->chip_revision) {
0662     case Rev072A:
0663         reg_r(gspca_dev, 0x8621, 1);
0664         Gr = gspca_dev->usb_buf[0];
0665         reg_r(gspca_dev, 0x8622, 1);
0666         R = gspca_dev->usb_buf[0];
0667         reg_r(gspca_dev, 0x8623, 1);
0668         B = gspca_dev->usb_buf[0];
0669         reg_r(gspca_dev, 0x8624, 1);
0670         Gb = gspca_dev->usb_buf[0];
0671         y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
0672         /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
0673         /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
0674 
0675         if (y < luma_mean - luma_delta ||
0676             y > luma_mean + luma_delta) {
0677             expotimes = i2c_read(gspca_dev, 0x09, 0x10);
0678             pixelclk = 0x0800;
0679             expotimes = expotimes & 0x07ff;
0680             gainG = i2c_read(gspca_dev, 0x35, 0x10);
0681 
0682             expotimes += (luma_mean - y) >> spring;
0683             gainG += (luma_mean - y) / 50;
0684 
0685             if (gainG > 0x3f)
0686                 gainG = 0x3f;
0687             else if (gainG < 3)
0688                 gainG = 3;
0689             i2c_write(gspca_dev, gainG, 0x35);
0690 
0691             if (expotimes > 0x0256)
0692                 expotimes = 0x0256;
0693             else if (expotimes < 3)
0694                 expotimes = 3;
0695             i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
0696         }
0697         break;
0698     }
0699 }
0700 
0701 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0702             u8 *data,       /* isoc packet */
0703             int len)        /* iso packet length */
0704 {
0705     struct sd *sd = (struct sd *) gspca_dev;
0706 
0707     len--;
0708     switch (*data++) {          /* sequence number */
0709     case 0:                 /* start of frame */
0710         gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
0711 
0712         /* This should never happen */
0713         if (len < 2) {
0714             gspca_err(gspca_dev, "Short SOF packet, ignoring\n\n\n\n\n");
0715             gspca_dev->last_packet_type = DISCARD_PACKET;
0716             return;
0717         }
0718 
0719 #if IS_ENABLED(CONFIG_INPUT)
0720         if (data[0] & 0x20) {
0721             input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
0722             input_sync(gspca_dev->input_dev);
0723             input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
0724             input_sync(gspca_dev->input_dev);
0725         }
0726 #endif
0727 
0728         if (data[1] & 0x10) {
0729             /* compressed bayer */
0730             gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
0731         } else {
0732             /* raw bayer (with a header, which we skip) */
0733             if (sd->chip_revision == Rev012A) {
0734                 data += 20;
0735                 len -= 20;
0736             } else {
0737                 data += 16;
0738                 len -= 16;
0739             }
0740             gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
0741         }
0742         return;
0743     case 0xff:          /* drop (empty mpackets) */
0744         return;
0745     }
0746     gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0747 }
0748 
0749 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0750 {
0751     struct gspca_dev *gspca_dev =
0752         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0753     struct sd *sd = (struct sd *)gspca_dev;
0754 
0755     gspca_dev->usb_err = 0;
0756 
0757     if (!gspca_dev->streaming)
0758         return 0;
0759 
0760     switch (ctrl->id) {
0761     case V4L2_CID_BRIGHTNESS:
0762         setbrightness(gspca_dev, ctrl->val);
0763         break;
0764     case V4L2_CID_CONTRAST:
0765         /* hue/contrast control cluster for 72a */
0766         setwhite(gspca_dev, sd->hue->val, ctrl->val);
0767         break;
0768     case V4L2_CID_HUE:
0769         /* just plain hue control for 12a */
0770         setwhite(gspca_dev, ctrl->val, 0);
0771         break;
0772     case V4L2_CID_EXPOSURE:
0773         setexposure(gspca_dev, ctrl->val);
0774         break;
0775     case V4L2_CID_GAIN:
0776         setgain(gspca_dev, ctrl->val);
0777         break;
0778     case V4L2_CID_AUTOGAIN:
0779         setautogain(gspca_dev, ctrl->val);
0780         break;
0781     }
0782     return gspca_dev->usb_err;
0783 }
0784 
0785 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0786     .s_ctrl = sd_s_ctrl,
0787 };
0788 
0789 static int sd_init_controls_12a(struct gspca_dev *gspca_dev)
0790 {
0791     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0792 
0793     gspca_dev->vdev.ctrl_handler = hdl;
0794     v4l2_ctrl_handler_init(hdl, 3);
0795     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0796             V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
0797     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0798             V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
0799     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0800             V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700);
0801     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0802             V4L2_CID_GAIN, 0, 255, 1, 63);
0803 
0804     if (hdl->error) {
0805         pr_err("Could not initialize controls\n");
0806         return hdl->error;
0807     }
0808     return 0;
0809 }
0810 
0811 static int sd_init_controls_72a(struct gspca_dev *gspca_dev)
0812 {
0813     struct sd *sd = (struct sd *)gspca_dev;
0814     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0815 
0816     gspca_dev->vdev.ctrl_handler = hdl;
0817     v4l2_ctrl_handler_init(hdl, 4);
0818     sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0819             V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20);
0820     sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0821             V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
0822     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0823             V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20);
0824     sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0825             V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
0826 
0827     if (hdl->error) {
0828         pr_err("Could not initialize controls\n");
0829         return hdl->error;
0830     }
0831     v4l2_ctrl_cluster(2, &sd->contrast);
0832     return 0;
0833 }
0834 
0835 /* sub-driver description */
0836 static const struct sd_desc sd_desc_12a = {
0837     .name = MODULE_NAME,
0838     .init_controls = sd_init_controls_12a,
0839     .config = sd_config,
0840     .init = sd_init_12a,
0841     .start = sd_start_12a,
0842     .stopN = sd_stopN,
0843     .pkt_scan = sd_pkt_scan,
0844 #if IS_ENABLED(CONFIG_INPUT)
0845     .other_input = 1,
0846 #endif
0847 };
0848 static const struct sd_desc sd_desc_72a = {
0849     .name = MODULE_NAME,
0850     .init_controls = sd_init_controls_72a,
0851     .config = sd_config,
0852     .init = sd_init_72a,
0853     .start = sd_start_72a,
0854     .stopN = sd_stopN,
0855     .pkt_scan = sd_pkt_scan,
0856     .dq_callback = do_autogain,
0857 #if IS_ENABLED(CONFIG_INPUT)
0858     .other_input = 1,
0859 #endif
0860 };
0861 static const struct sd_desc *sd_desc[2] = {
0862     &sd_desc_12a,
0863     &sd_desc_72a
0864 };
0865 
0866 /* -- module initialisation -- */
0867 static const struct usb_device_id device_table[] = {
0868     {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
0869     {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
0870     {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
0871     {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
0872     {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
0873     {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
0874     {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
0875     {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
0876     {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
0877     {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
0878     {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
0879     {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
0880     {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
0881     {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
0882     {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
0883     {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
0884     {}
0885 };
0886 
0887 MODULE_DEVICE_TABLE(usb, device_table);
0888 
0889 /* -- device connect -- */
0890 static int sd_probe(struct usb_interface *intf,
0891             const struct usb_device_id *id)
0892 {
0893     return gspca_dev_probe(intf, id,
0894                 sd_desc[id->driver_info],
0895                 sizeof(struct sd),
0896                    THIS_MODULE);
0897 }
0898 
0899 static struct usb_driver sd_driver = {
0900     .name = MODULE_NAME,
0901     .id_table = device_table,
0902     .probe = sd_probe,
0903     .disconnect = gspca_disconnect,
0904 #ifdef CONFIG_PM
0905     .suspend = gspca_suspend,
0906     .resume = gspca_resume,
0907     .reset_resume = gspca_resume,
0908 #endif
0909 };
0910 
0911 module_usb_driver(sd_driver);