0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #define MODULE_NAME "sn9c2028"
0011
0012 #include "gspca.h"
0013
0014 MODULE_AUTHOR("Theodore Kilgore");
0015 MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver");
0016 MODULE_LICENSE("GPL");
0017
0018
0019 struct sd {
0020 struct gspca_dev gspca_dev;
0021 u8 sof_read;
0022 u16 model;
0023
0024 #define MIN_AVG_LUM 8500
0025 #define MAX_AVG_LUM 10000
0026 int avg_lum;
0027 u8 avg_lum_l;
0028
0029 struct {
0030 struct v4l2_ctrl *autogain;
0031 struct v4l2_ctrl *gain;
0032 };
0033 };
0034
0035 struct init_command {
0036 unsigned char instruction[6];
0037 unsigned char to_read;
0038 };
0039
0040
0041 static const struct v4l2_pix_format vga_mode[] = {
0042 {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
0043 .bytesperline = 640,
0044 .sizeimage = 640 * 480 * 3 / 4,
0045 .colorspace = V4L2_COLORSPACE_SRGB,
0046 .priv = 0},
0047 };
0048
0049
0050 static const struct v4l2_pix_format cif_mode[] = {
0051 {352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
0052 .bytesperline = 352,
0053 .sizeimage = 352 * 288 * 3 / 4,
0054 .colorspace = V4L2_COLORSPACE_SRGB,
0055 .priv = 0},
0056 };
0057
0058
0059 static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
0060 {
0061 int rc;
0062
0063 gspca_dbg(gspca_dev, D_USBO, "sending command %02x%02x%02x%02x%02x%02x\n",
0064 command[0], command[1], command[2],
0065 command[3], command[4], command[5]);
0066
0067 memcpy(gspca_dev->usb_buf, command, 6);
0068 rc = usb_control_msg(gspca_dev->dev,
0069 usb_sndctrlpipe(gspca_dev->dev, 0),
0070 USB_REQ_GET_CONFIGURATION,
0071 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0072 2, 0, gspca_dev->usb_buf, 6, 500);
0073 if (rc < 0) {
0074 pr_err("command write [%02x] error %d\n",
0075 gspca_dev->usb_buf[0], rc);
0076 return rc;
0077 }
0078
0079 return 0;
0080 }
0081
0082 static int sn9c2028_read1(struct gspca_dev *gspca_dev)
0083 {
0084 int rc;
0085
0086 rc = usb_control_msg(gspca_dev->dev,
0087 usb_rcvctrlpipe(gspca_dev->dev, 0),
0088 USB_REQ_GET_STATUS,
0089 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0090 1, 0, gspca_dev->usb_buf, 1, 500);
0091 if (rc != 1) {
0092 pr_err("read1 error %d\n", rc);
0093 return (rc < 0) ? rc : -EIO;
0094 }
0095 gspca_dbg(gspca_dev, D_USBI, "read1 response %02x\n",
0096 gspca_dev->usb_buf[0]);
0097 return gspca_dev->usb_buf[0];
0098 }
0099
0100 static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
0101 {
0102 int rc;
0103 rc = usb_control_msg(gspca_dev->dev,
0104 usb_rcvctrlpipe(gspca_dev->dev, 0),
0105 USB_REQ_GET_STATUS,
0106 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0107 4, 0, gspca_dev->usb_buf, 4, 500);
0108 if (rc != 4) {
0109 pr_err("read4 error %d\n", rc);
0110 return (rc < 0) ? rc : -EIO;
0111 }
0112 memcpy(reading, gspca_dev->usb_buf, 4);
0113 gspca_dbg(gspca_dev, D_USBI, "read4 response %02x%02x%02x%02x\n",
0114 reading[0], reading[1], reading[2], reading[3]);
0115 return rc;
0116 }
0117
0118 static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
0119 {
0120 int i, status;
0121 __u8 reading[4];
0122
0123 status = sn9c2028_command(gspca_dev, command);
0124 if (status < 0)
0125 return status;
0126
0127 status = -1;
0128 for (i = 0; i < 256 && status < 2; i++)
0129 status = sn9c2028_read1(gspca_dev);
0130 if (status < 0) {
0131 pr_err("long command status read error %d\n", status);
0132 return status;
0133 }
0134
0135 memset(reading, 0, 4);
0136 status = sn9c2028_read4(gspca_dev, reading);
0137 if (status < 0)
0138 return status;
0139
0140
0141
0142 status = sn9c2028_read1(gspca_dev);
0143 if (status < 0)
0144 return status;
0145
0146 return 0;
0147 }
0148
0149 static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command)
0150 {
0151 int err_code;
0152
0153 err_code = sn9c2028_command(gspca_dev, command);
0154 if (err_code < 0)
0155 return err_code;
0156
0157 err_code = sn9c2028_read1(gspca_dev);
0158 if (err_code < 0)
0159 return err_code;
0160
0161 return 0;
0162 }
0163
0164
0165 static int sd_config(struct gspca_dev *gspca_dev,
0166 const struct usb_device_id *id)
0167 {
0168 struct sd *sd = (struct sd *) gspca_dev;
0169 struct cam *cam = &gspca_dev->cam;
0170
0171 gspca_dbg(gspca_dev, D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)\n",
0172 id->idVendor, id->idProduct);
0173
0174 sd->model = id->idProduct;
0175
0176 switch (sd->model) {
0177 case 0x7005:
0178 gspca_dbg(gspca_dev, D_PROBE, "Genius Smart 300 camera\n");
0179 break;
0180 case 0x7003:
0181 gspca_dbg(gspca_dev, D_PROBE, "Genius Videocam Live v2\n");
0182 break;
0183 case 0x8000:
0184 gspca_dbg(gspca_dev, D_PROBE, "DC31VC\n");
0185 break;
0186 case 0x8001:
0187 gspca_dbg(gspca_dev, D_PROBE, "Spy camera\n");
0188 break;
0189 case 0x8003:
0190 gspca_dbg(gspca_dev, D_PROBE, "CIF camera\n");
0191 break;
0192 case 0x8008:
0193 gspca_dbg(gspca_dev, D_PROBE, "Mini-Shotz ms-350 camera\n");
0194 break;
0195 case 0x800a:
0196 gspca_dbg(gspca_dev, D_PROBE, "Vivitar 3350b type camera\n");
0197 cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
0198 break;
0199 }
0200
0201 switch (sd->model) {
0202 case 0x8000:
0203 case 0x8001:
0204 case 0x8003:
0205 cam->cam_mode = cif_mode;
0206 cam->nmodes = ARRAY_SIZE(cif_mode);
0207 break;
0208 default:
0209 cam->cam_mode = vga_mode;
0210 cam->nmodes = ARRAY_SIZE(vga_mode);
0211 }
0212 return 0;
0213 }
0214
0215
0216 static int sd_init(struct gspca_dev *gspca_dev)
0217 {
0218 int status;
0219
0220 sn9c2028_read1(gspca_dev);
0221 sn9c2028_read1(gspca_dev);
0222 status = sn9c2028_read1(gspca_dev);
0223
0224 return (status < 0) ? status : 0;
0225 }
0226
0227 static int run_start_commands(struct gspca_dev *gspca_dev,
0228 struct init_command *cam_commands, int n)
0229 {
0230 int i, err_code = -1;
0231
0232 for (i = 0; i < n; i++) {
0233 switch (cam_commands[i].to_read) {
0234 case 4:
0235 err_code = sn9c2028_long_command(gspca_dev,
0236 cam_commands[i].instruction);
0237 break;
0238 case 1:
0239 err_code = sn9c2028_short_command(gspca_dev,
0240 cam_commands[i].instruction);
0241 break;
0242 case 0:
0243 err_code = sn9c2028_command(gspca_dev,
0244 cam_commands[i].instruction);
0245 break;
0246 }
0247 if (err_code < 0)
0248 return err_code;
0249 }
0250 return 0;
0251 }
0252
0253 static void set_gain(struct gspca_dev *gspca_dev, s32 g)
0254 {
0255 struct sd *sd = (struct sd *) gspca_dev;
0256
0257 struct init_command genius_vcam_live_gain_cmds[] = {
0258 {{0x1d, 0x25, 0x10 ,
0259 0x20, 0xab, 0x00}, 0},
0260 };
0261 if (!gspca_dev->streaming)
0262 return;
0263
0264 switch (sd->model) {
0265 case 0x7003:
0266 genius_vcam_live_gain_cmds[0].instruction[2] = g;
0267 run_start_commands(gspca_dev, genius_vcam_live_gain_cmds,
0268 ARRAY_SIZE(genius_vcam_live_gain_cmds));
0269 break;
0270 default:
0271 break;
0272 }
0273 }
0274
0275 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0276 {
0277 struct gspca_dev *gspca_dev =
0278 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0279 struct sd *sd = (struct sd *)gspca_dev;
0280
0281 gspca_dev->usb_err = 0;
0282
0283 if (!gspca_dev->streaming)
0284 return 0;
0285
0286 switch (ctrl->id) {
0287
0288 case V4L2_CID_GAIN:
0289 set_gain(gspca_dev, ctrl->val);
0290 break;
0291
0292 case V4L2_CID_AUTOGAIN:
0293 set_gain(gspca_dev, sd->gain->val);
0294 break;
0295 }
0296 return gspca_dev->usb_err;
0297 }
0298
0299 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0300 .s_ctrl = sd_s_ctrl,
0301 };
0302
0303
0304 static int sd_init_controls(struct gspca_dev *gspca_dev)
0305 {
0306 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0307 struct sd *sd = (struct sd *)gspca_dev;
0308
0309 gspca_dev->vdev.ctrl_handler = hdl;
0310 v4l2_ctrl_handler_init(hdl, 2);
0311
0312 switch (sd->model) {
0313 case 0x7003:
0314 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0315 V4L2_CID_GAIN, 0, 20, 1, 0);
0316 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0317 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
0318 break;
0319 default:
0320 break;
0321 }
0322
0323 return 0;
0324 }
0325 static int start_spy_cam(struct gspca_dev *gspca_dev)
0326 {
0327 struct init_command spy_start_commands[] = {
0328 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0329 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
0330 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
0331 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
0332 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
0333 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
0334 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
0335 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
0336
0337 {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4},
0338 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
0339
0340 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
0341
0342 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
0343 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
0344
0345 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0346 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
0347
0348 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
0349 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
0350 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
0351 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
0352 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
0353 {{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4},
0354 {{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4},
0355
0356 {{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4},
0357
0358 {{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4},
0359 {{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4},
0360 {{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4},
0361
0362 {{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4},
0363 {{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4},
0364 {{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4},
0365 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
0366 {{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4},
0367 {{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4},
0368 {{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4},
0369
0370
0371
0372 {{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4},
0373 {{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4},
0374 {{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4},
0375 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0376 {{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4},
0377 {{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4},
0378
0379 {{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1},
0380
0381 {{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1},
0382 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},
0383
0384 };
0385
0386 return run_start_commands(gspca_dev, spy_start_commands,
0387 ARRAY_SIZE(spy_start_commands));
0388 }
0389
0390 static int start_cif_cam(struct gspca_dev *gspca_dev)
0391 {
0392 struct init_command cif_start_commands[] = {
0393 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 {{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1},
0415 {{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1},
0416 {{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1},
0417 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
0418 {{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1},
0419 {{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1},
0420 {{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1},
0421 {{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1},
0422 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
0423 {{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1},
0424 {{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1},
0425 {{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1},
0426 {{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1},
0427 {{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1},
0428 {{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1},
0429 {{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1},
0430 {{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1},
0431 {{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1},
0432 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
0433 {{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1},
0434 {{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1},
0435 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
0436 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1},
0437 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1},
0438
0439
0440
0441
0442
0443
0444 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0445 {{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4},
0446 {{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4},
0447 {{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4},
0448 {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
0449 {{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1},
0450 {{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1},
0451 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
0452 {{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1},
0453 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
0454 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
0455 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
0456 {{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1},
0457 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
0458 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
0459 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},
0460
0461 };
0462
0463 return run_start_commands(gspca_dev, cif_start_commands,
0464 ARRAY_SIZE(cif_start_commands));
0465 }
0466
0467 static int start_ms350_cam(struct gspca_dev *gspca_dev)
0468 {
0469 struct init_command ms350_start_commands[] = {
0470 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0471 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0472 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
0473 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
0474 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
0475 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
0476 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
0477 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
0478 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
0479 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
0480 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
0481 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
0482 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
0483 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
0484 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0485 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
0486 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
0487 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
0488 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
0489 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
0490 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
0491 {{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4},
0492 {{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4},
0493 {{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4},
0494 {{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4},
0495 {{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4},
0496 {{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4},
0497 {{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4},
0498 {{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4},
0499 {{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4},
0500 {{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4},
0501 {{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4},
0502 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
0503 {{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4},
0504 {{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4},
0505 {{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4},
0506 {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4},
0507 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0508 {{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4},
0509 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0510 {{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4},
0511 {{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4},
0512 {{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4},
0513 {{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4},
0514 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
0515 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
0516 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
0517 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
0518 {{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4},
0519 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0520 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
0521 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
0522 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
0523 {{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1},
0524 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
0525 {{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1},
0526 {{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1},
0527 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0},
0528
0529 };
0530
0531 return run_start_commands(gspca_dev, ms350_start_commands,
0532 ARRAY_SIZE(ms350_start_commands));
0533 }
0534
0535 static int start_genius_cam(struct gspca_dev *gspca_dev)
0536 {
0537 struct init_command genius_start_commands[] = {
0538 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0539 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0540 {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
0541 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
0542 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
0543
0544 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
0545 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0546 {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
0547 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0548 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
0549 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
0550 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
0551 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0552 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
0553 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0554 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
0555 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0556 {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
0557 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0558 {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
0559 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
0560 {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
0561 {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
0562 {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
0563 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0564 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
0565 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0566 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
0567 {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
0568 {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
0569 {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
0570 {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
0571 {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
0572 {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
0573 {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
0574 {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
0575 {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
0576 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
0577 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
0578 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
0579 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0580 {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
0581 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0582 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
0583 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
0584 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
0585 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0586 {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
0587 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0588 {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
0589 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0590 {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
0591 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0592 {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
0593 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
0594 {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
0595 {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
0596 {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
0597 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
0598 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
0599 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}
0600
0601 };
0602
0603 return run_start_commands(gspca_dev, genius_start_commands,
0604 ARRAY_SIZE(genius_start_commands));
0605 }
0606
0607 static int start_genius_videocam_live(struct gspca_dev *gspca_dev)
0608 {
0609 int r;
0610 struct sd *sd = (struct sd *) gspca_dev;
0611 struct init_command genius_vcam_live_start_commands[] = {
0612 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 0},
0613 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0614 {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
0615 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
0616 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
0617
0618 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
0619 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0620 {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
0621 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0622 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
0623 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
0624 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
0625 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0626 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
0627 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0628 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
0629 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0630 {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
0631 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0632 {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
0633 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
0634 {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
0635 {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
0636 {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
0637 {{0x1c, 0x20, 0x00, 0x2d, 0x00, 0x00}, 4},
0638 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
0639 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
0640 {{0x13, 0x22, 0x01, 0x00, 0x00, 0x00}, 4},
0641 {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
0642 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
0643 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
0644 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
0645 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0646 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
0647 {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
0648 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
0649 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
0650 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0651 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
0652 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
0653 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
0654 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
0655 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
0656 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
0657 {{0x11, 0x01, 0x04, 0x00, 0x00, 0x00}, 4},
0658 {{0x11, 0x02, 0x92, 0x00, 0x00, 0x00}, 4},
0659 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0660 {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
0661 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0662 {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
0663 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
0664 {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
0665 {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
0666 {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
0667 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0668 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
0669 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0670 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
0671 {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
0672 {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
0673 {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
0674 {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
0675 {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
0676 {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
0677 {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
0678 {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
0679 {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
0680 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
0681 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
0682 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
0683 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0684 {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
0685 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0686 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
0687 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
0688 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
0689 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
0690 {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
0691 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
0692 {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
0693 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
0694 {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
0695 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
0696 {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
0697 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
0698 {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
0699 {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
0700 {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
0701 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
0702 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0},
0703
0704 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 0},
0705 {{0x1b, 0x32, 0x26, 0x00, 0x00, 0x00}, 0},
0706 {{0x1d, 0x25, 0x10, 0x20, 0xab, 0x00}, 0},
0707 };
0708
0709 r = run_start_commands(gspca_dev, genius_vcam_live_start_commands,
0710 ARRAY_SIZE(genius_vcam_live_start_commands));
0711 if (r < 0)
0712 return r;
0713
0714 if (sd->gain)
0715 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
0716
0717 return r;
0718 }
0719
0720 static int start_vivitar_cam(struct gspca_dev *gspca_dev)
0721 {
0722 struct init_command vivitar_start_commands[] = {
0723 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
0724 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
0725 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
0726 {{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4},
0727 {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
0728 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
0729 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
0730 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
0731 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
0732 {{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4},
0733
0734
0735
0736
0737 {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
0738
0739 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
0740 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
0741 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
0742 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
0743 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
0744 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
0745
0746 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
0747 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
0748 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
0749 {{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1},
0750 {{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1},
0751 {{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1},
0752 {{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1},
0753 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
0754 {{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1},
0755 {{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1},
0756 {{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1},
0757 {{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1},
0758 {{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1},
0759 {{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1},
0760 {{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1},
0761 {{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1},
0762 {{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
0763 {{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1},
0764 {{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1},
0765 {{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1},
0766 {{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1},
0767 {{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1},
0768 {{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1},
0769 {{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1},
0770 {{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1},
0771 {{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1},
0772 {{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1},
0773 {{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1},
0774 {{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1},
0775 {{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1},
0776 {{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1},
0777 {{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1},
0778 {{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1},
0779 {{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1},
0780 {{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1},
0781 {{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1},
0782 {{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1},
0783
0784
0785
0786 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
0787 {{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1},
0788 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
0789 {{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1},
0790 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
0791 {{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1},
0792
0793 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
0794 {{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
0795 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}
0796 };
0797
0798 return run_start_commands(gspca_dev, vivitar_start_commands,
0799 ARRAY_SIZE(vivitar_start_commands));
0800 }
0801
0802 static int sd_start(struct gspca_dev *gspca_dev)
0803 {
0804 struct sd *sd = (struct sd *) gspca_dev;
0805 int err_code;
0806
0807 sd->sof_read = 0;
0808
0809 switch (sd->model) {
0810 case 0x7005:
0811 err_code = start_genius_cam(gspca_dev);
0812 break;
0813 case 0x7003:
0814 err_code = start_genius_videocam_live(gspca_dev);
0815 break;
0816 case 0x8001:
0817 err_code = start_spy_cam(gspca_dev);
0818 break;
0819 case 0x8003:
0820 err_code = start_cif_cam(gspca_dev);
0821 break;
0822 case 0x8008:
0823 err_code = start_ms350_cam(gspca_dev);
0824 break;
0825 case 0x800a:
0826 err_code = start_vivitar_cam(gspca_dev);
0827 break;
0828 default:
0829 pr_err("Starting unknown camera, please report this\n");
0830 return -ENXIO;
0831 }
0832
0833 sd->avg_lum = -1;
0834
0835 return err_code;
0836 }
0837
0838 static void sd_stopN(struct gspca_dev *gspca_dev)
0839 {
0840 int result;
0841 __u8 data[6];
0842
0843 result = sn9c2028_read1(gspca_dev);
0844 if (result < 0)
0845 gspca_err(gspca_dev, "Camera Stop read failed\n");
0846
0847 memset(data, 0, 6);
0848 data[0] = 0x14;
0849 result = sn9c2028_command(gspca_dev, data);
0850 if (result < 0)
0851 gspca_err(gspca_dev, "Camera Stop command failed\n");
0852 }
0853
0854 static void do_autogain(struct gspca_dev *gspca_dev, int avg_lum)
0855 {
0856 struct sd *sd = (struct sd *) gspca_dev;
0857 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
0858
0859 if (avg_lum == -1)
0860 return;
0861
0862 if (avg_lum < MIN_AVG_LUM) {
0863 if (cur_gain == sd->gain->maximum)
0864 return;
0865 cur_gain++;
0866 v4l2_ctrl_s_ctrl(sd->gain, cur_gain);
0867 }
0868 if (avg_lum > MAX_AVG_LUM) {
0869 if (cur_gain == sd->gain->minimum)
0870 return;
0871 cur_gain--;
0872 v4l2_ctrl_s_ctrl(sd->gain, cur_gain);
0873 }
0874
0875 }
0876
0877 static void sd_dqcallback(struct gspca_dev *gspca_dev)
0878 {
0879 struct sd *sd = (struct sd *) gspca_dev;
0880
0881 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
0882 return;
0883
0884 do_autogain(gspca_dev, sd->avg_lum);
0885 }
0886
0887
0888 #include "sn9c2028.h"
0889
0890 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0891 __u8 *data,
0892 int len)
0893 {
0894 unsigned char *sof;
0895
0896 sof = sn9c2028_find_sof(gspca_dev, data, len);
0897 if (sof) {
0898 int n;
0899
0900
0901 n = sof - data;
0902 if (n > sizeof sn9c2028_sof_marker)
0903 n -= sizeof sn9c2028_sof_marker;
0904 else
0905 n = 0;
0906 gspca_frame_add(gspca_dev, LAST_PACKET, data, n);
0907
0908 gspca_frame_add(gspca_dev, FIRST_PACKET,
0909 sn9c2028_sof_marker, sizeof sn9c2028_sof_marker);
0910 len -= sof - data;
0911 data = sof;
0912 }
0913 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0914 }
0915
0916
0917 static const struct sd_desc sd_desc = {
0918 .name = MODULE_NAME,
0919 .config = sd_config,
0920 .init = sd_init,
0921 .init_controls = sd_init_controls,
0922 .start = sd_start,
0923 .stopN = sd_stopN,
0924 .dq_callback = sd_dqcallback,
0925 .pkt_scan = sd_pkt_scan,
0926 };
0927
0928
0929 static const struct usb_device_id device_table[] = {
0930 {USB_DEVICE(0x0458, 0x7005)},
0931 {USB_DEVICE(0x0458, 0x7003)},
0932
0933
0934 {USB_DEVICE(0x0c45, 0x8001)},
0935 {USB_DEVICE(0x0c45, 0x8003)},
0936
0937 {USB_DEVICE(0x0c45, 0x8008)},
0938 {USB_DEVICE(0x0c45, 0x800a)},
0939 {}
0940 };
0941 MODULE_DEVICE_TABLE(usb, device_table);
0942
0943
0944 static int sd_probe(struct usb_interface *intf,
0945 const struct usb_device_id *id)
0946 {
0947 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
0948 THIS_MODULE);
0949 }
0950
0951 static struct usb_driver sd_driver = {
0952 .name = MODULE_NAME,
0953 .id_table = device_table,
0954 .probe = sd_probe,
0955 .disconnect = gspca_disconnect,
0956 #ifdef CONFIG_PM
0957 .suspend = gspca_suspend,
0958 .resume = gspca_resume,
0959 .reset_resume = gspca_resume,
0960 #endif
0961 };
0962
0963 module_usb_driver(sd_driver);