0001
0002
0003
0004
0005
0006
0007
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
0024 struct sd {
0025 struct gspca_dev gspca_dev;
0026
0027 struct {
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;
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
0092
0093
0094
0095
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},
0118 {0x0001, 0x8114},
0119 {0x0000, 0x8112},
0120 {}
0121 };
0122 static const __u16 rev72a_init_data1[][2] = {
0123 {0x0003, 0x8701},
0124 {0x0001, 0x8703},
0125 {0x0011, 0x8118},
0126 {0x0001, 0x8118},
0127 {0x0092, 0x8804},
0128 {0x0010, 0x8802},
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},
0148 {0x0000, 0x8602},
0149 {0x0060, 0x8604},
0150 {0x0002, 0x8605},
0151 {0x0000, 0x8603},
0152 {0x0002, 0x865b},
0153 {0x0000, 0x865f},
0154 {0x00b0, 0x865d},
0155 {0x0090, 0x865e},
0156 {0x00e0, 0x8406},
0157 {0x0000, 0x8660},
0158 {0x0002, 0x8201},
0159 {0x0008, 0x8200},
0160 {0x0001, 0x8200},
0161
0162 {0x0000, 0x8611},
0163 {0x00fd, 0x8612},
0164 {0x0003, 0x8613},
0165 {0x0000, 0x8614},
0166
0167 {0x0035, 0x8651},
0168 {0x0040, 0x8652},
0169 {0x005f, 0x8653},
0170 {0x0040, 0x8654},
0171 {0x0002, 0x8502},
0172 {0x0011, 0x8802},
0173
0174 {0x0087, 0x8700},
0175 {0x0081, 0x8702},
0176
0177 {0x0000, 0x8500},
0178
0179
0180 {0x0002, 0x865b},
0181 {0x0003, 0x865c},
0182 {}
0183 };
0184 static const u16 rev72a_init_sensor2[][2] = {
0185 {0x0003, 0x0121},
0186 {0x0004, 0x0165},
0187 {0x0005, 0x002f},
0188 {0x0006, 0x0000},
0189 {0x000a, 0x0002},
0190 {0x0009, 0x1061},
0191
0192 {0x0035, 0x0014},
0193 {}
0194 };
0195
0196
0197 static const __u16 Pb100_1map8300[][2] = {
0198
0199 {0x8320, 0x3304},
0200
0201 {0x8303, 0x0125},
0202 {0x8304, 0x0169},
0203 {0x8328, 0x000b},
0204 {0x833c, 0x0001},
0205
0206 {0x832f, 0x1904},
0207 {0x8307, 0x00aa},
0208 {0x8301, 0x0003},
0209 {0x8302, 0x000e},
0210 {}
0211 };
0212 static const __u16 Pb100_2map8300[][2] = {
0213
0214 {0x8339, 0x0000},
0215 {0x8307, 0x00aa},
0216 {}
0217 };
0218
0219 static const __u16 spca561_161rev12A_data1[][2] = {
0220 {0x29, 0x8118},
0221 {0x08, 0x8114},
0222 {0x0e, 0x8112},
0223 {0x00, 0x8102},
0224 {0x92, 0x8804},
0225 {0x04, 0x8802},
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},
0236 {0x08, 0x8200},
0237 {0x01, 0x8200},
0238
0239 {0x90, 0x8604},
0240 {0x00, 0x8605},
0241 {0xb0, 0x8603},
0242
0243
0244 {0x07, 0x8601},
0245 {0x07, 0x8602},
0246 {0x00, 0x8610},
0247 {0x00, 0x8611},
0248 {0x00, 0x8612},
0249 {0x00, 0x8613},
0250 {0x43, 0x8614},
0251 {0x40, 0x8615},
0252 {0x71, 0x8616},
0253 {0x40, 0x8617},
0254
0255 {0x0c, 0x8620},
0256 {0xc8, 0x8631},
0257 {0xc8, 0x8634},
0258 {0x23, 0x8635},
0259 {0x1f, 0x8636},
0260 {0xdd, 0x8637},
0261 {0xe1, 0x8638},
0262 {0x1d, 0x8639},
0263 {0x21, 0x863a},
0264 {0xe3, 0x863b},
0265 {0xdf, 0x863c},
0266 {0xf0, 0x8505},
0267 {0x32, 0x850a},
0268
0269
0270
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,
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
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,
0309 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0310 0,
0311 index, gspca_dev->usb_buf, length, 500);
0312 }
0313
0314
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,
0321 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0322 0,
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
0387 write_vector(gspca_dev, spca561_161rev12A_data2);
0388 sensor_mapwrite(gspca_dev, Pb100_2map8300);
0389 }
0390
0391
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
0401
0402
0403
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
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);
0465 reg_w_val(gspca_dev, reg + 1, val);
0466 reg_w_val(gspca_dev, reg + 2, val);
0467 reg_w_val(gspca_dev, reg + 3, val);
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
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);
0486 reg_w_val(gspca_dev, 0x8654, contrast + 0x20);
0487 }
0488 reg_w_val(gspca_dev, reg, red);
0489 reg_w_val(gspca_dev, reg + 2, blue);
0490 }
0491
0492
0493 static void setexposure(struct gspca_dev *gspca_dev, s32 val)
0494 {
0495 int i, expo = 0;
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
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
0531 static void setgain(struct gspca_dev *gspca_dev, s32 val)
0532 {
0533
0534
0535
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
0566 reg_w_val(gspca_dev, 0x8500, 0x10 | mode);
0567 } else {
0568
0569
0570
0571 reg_w_val(gspca_dev, 0x8500, mode);
0572 }
0573
0574 gspca_dev->usb_buf[0] = 0xaa;
0575 gspca_dev->usb_buf[1] = 0x00;
0576 reg_w_buf(gspca_dev, 0x8307, 2);
0577
0578 reg_w_val(gspca_dev, 0x8700, 0x8a);
0579
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
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;
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);
0618 reg_w_val(gspca_dev, 0x8702, 0x81);
0619 reg_w_val(gspca_dev, 0x8500, 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
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
0636 reg_w_val(gspca_dev, 0x8114, 0x08);
0637 } else {
0638 reg_w_val(gspca_dev, 0x8112, 0x20);
0639
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
0673
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,
0703 int len)
0704 {
0705 struct sd *sd = (struct sd *) gspca_dev;
0706
0707 len--;
0708 switch (*data++) {
0709 case 0:
0710 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
0711
0712
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
0730 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
0731 } else {
0732
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:
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
0766 setwhite(gspca_dev, sd->hue->val, ctrl->val);
0767 break;
0768 case V4L2_CID_HUE:
0769
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
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
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
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);