1078 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Mars MR97310A library4 *5 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is6 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>7 *8 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+9 * and for the routines for detecting and classifying these various cameras,10 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>11 *12 * Support for the control settings for the CIF cameras is13 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and14 * Thomas Kaiser <thomas@kaiser-linux.li>15 *16 * Support for the control settings for the VGA cameras is17 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>18 *19 * Several previously unsupported cameras are owned and have been tested by20 * Hans de Goede <hdegoede@redhat.com> and21 * Thomas Kaiser <thomas@kaiser-linux.li> and22 * Theodore Kilgore <kilgota@auburn.edu> and23 * Edmond Rodriguez <erodrig_97@yahoo.com> and24 * Aurelien Jacobs <aurel@gnuage.org>25 *26 * The MR97311A support in gspca/mars.c has been helpful in understanding some27 * of the registers in these cameras.28 */29 30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt31 32#define MODULE_NAME "mr97310a"33 34#include "gspca.h"35 36#define CAM_TYPE_CIF 037#define CAM_TYPE_VGA 138 39#define MR97310A_BRIGHTNESS_DEFAULT 040 41#define MR97310A_EXPOSURE_MIN 042#define MR97310A_EXPOSURE_MAX 409543#define MR97310A_EXPOSURE_DEFAULT 100044 45#define MR97310A_GAIN_MIN 046#define MR97310A_GAIN_MAX 3147#define MR97310A_GAIN_DEFAULT 2548 49#define MR97310A_CONTRAST_MIN 050#define MR97310A_CONTRAST_MAX 3151#define MR97310A_CONTRAST_DEFAULT 2352 53#define MR97310A_CS_GAIN_MIN 054#define MR97310A_CS_GAIN_MAX 0x7ff55#define MR97310A_CS_GAIN_DEFAULT 0x11056 57#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000)58#define MR97310A_MIN_CLOCKDIV_MIN 359#define MR97310A_MIN_CLOCKDIV_MAX 860#define MR97310A_MIN_CLOCKDIV_DEFAULT 361 62MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,Theodore Kilgore <kilgota@auburn.edu>");63MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");64MODULE_LICENSE("GPL");65 66/* global parameters */67static int force_sensor_type = -1;68module_param(force_sensor_type, int, 0644);69MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");70 71/* specific webcam descriptor */72struct sd {73 struct gspca_dev gspca_dev; /* !! must be the first item */74 struct { /* exposure/min_clockdiv control cluster */75 struct v4l2_ctrl *exposure;76 struct v4l2_ctrl *min_clockdiv;77 };78 u8 sof_read;79 u8 cam_type; /* 0 is CIF and 1 is VGA */80 u8 sensor_type; /* We use 0 and 1 here, too. */81 u8 do_lcd_stop;82 u8 adj_colors;83};84 85struct sensor_w_data {86 u8 reg;87 u8 flags;88 u8 data[16];89 int len;90};91 92static void sd_stopN(struct gspca_dev *gspca_dev);93 94static const struct v4l2_pix_format vga_mode[] = {95 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,96 .bytesperline = 160,97 .sizeimage = 160 * 120,98 .colorspace = V4L2_COLORSPACE_SRGB,99 .priv = 4},100 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,101 .bytesperline = 176,102 .sizeimage = 176 * 144,103 .colorspace = V4L2_COLORSPACE_SRGB,104 .priv = 3},105 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,106 .bytesperline = 320,107 .sizeimage = 320 * 240,108 .colorspace = V4L2_COLORSPACE_SRGB,109 .priv = 2},110 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,111 .bytesperline = 352,112 .sizeimage = 352 * 288,113 .colorspace = V4L2_COLORSPACE_SRGB,114 .priv = 1},115 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,116 .bytesperline = 640,117 .sizeimage = 640 * 480,118 .colorspace = V4L2_COLORSPACE_SRGB,119 .priv = 0},120};121 122/* the bytes to write are in gspca_dev->usb_buf */123static int mr_write(struct gspca_dev *gspca_dev, int len)124{125 int rc;126 127 rc = usb_bulk_msg(gspca_dev->dev,128 usb_sndbulkpipe(gspca_dev->dev, 4),129 gspca_dev->usb_buf, len, NULL, 500);130 if (rc < 0)131 pr_err("reg write [%02x] error %d\n",132 gspca_dev->usb_buf[0], rc);133 return rc;134}135 136/* the bytes are read into gspca_dev->usb_buf */137static int mr_read(struct gspca_dev *gspca_dev, int len)138{139 int rc;140 141 rc = usb_bulk_msg(gspca_dev->dev,142 usb_rcvbulkpipe(gspca_dev->dev, 3),143 gspca_dev->usb_buf, len, NULL, 500);144 if (rc < 0)145 pr_err("reg read [%02x] error %d\n",146 gspca_dev->usb_buf[0], rc);147 return rc;148}149 150static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,151 const u8 *data, int len)152{153 gspca_dev->usb_buf[0] = 0x1f;154 gspca_dev->usb_buf[1] = flags;155 gspca_dev->usb_buf[2] = reg;156 memcpy(gspca_dev->usb_buf + 3, data, len);157 158 return mr_write(gspca_dev, len + 3);159}160 161static int sensor_write_regs(struct gspca_dev *gspca_dev,162 const struct sensor_w_data *data, int len)163{164 int i, rc;165 166 for (i = 0; i < len; i++) {167 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,168 data[i].data, data[i].len);169 if (rc < 0)170 return rc;171 }172 173 return 0;174}175 176static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)177{178 struct sd *sd = (struct sd *) gspca_dev;179 u8 buf, confirm_reg;180 int rc;181 182 buf = data;183 if (sd->cam_type == CAM_TYPE_CIF) {184 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);185 confirm_reg = sd->sensor_type ? 0x13 : 0x11;186 } else {187 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);188 confirm_reg = 0x11;189 }190 if (rc < 0)191 return rc;192 193 buf = 0x01;194 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);195 if (rc < 0)196 return rc;197 198 return 0;199}200 201static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)202{203 int err_code;204 205 gspca_dev->usb_buf[0] = reg;206 err_code = mr_write(gspca_dev, 1);207 if (err_code < 0)208 return err_code;209 210 err_code = mr_read(gspca_dev, 16);211 if (err_code < 0)212 return err_code;213 214 if (verbose)215 gspca_dbg(gspca_dev, D_PROBE, "Register: %02x reads %02x%02x%02x\n",216 reg,217 gspca_dev->usb_buf[0],218 gspca_dev->usb_buf[1],219 gspca_dev->usb_buf[2]);220 221 return 0;222}223 224static int zero_the_pointer(struct gspca_dev *gspca_dev)225{226 __u8 *data = gspca_dev->usb_buf;227 int err_code;228 u8 status = 0;229 int tries = 0;230 231 err_code = cam_get_response16(gspca_dev, 0x21, 0);232 if (err_code < 0)233 return err_code;234 235 data[0] = 0x19;236 data[1] = 0x51;237 err_code = mr_write(gspca_dev, 2);238 if (err_code < 0)239 return err_code;240 241 err_code = cam_get_response16(gspca_dev, 0x21, 0);242 if (err_code < 0)243 return err_code;244 245 data[0] = 0x19;246 data[1] = 0xba;247 err_code = mr_write(gspca_dev, 2);248 if (err_code < 0)249 return err_code;250 251 err_code = cam_get_response16(gspca_dev, 0x21, 0);252 if (err_code < 0)253 return err_code;254 255 data[0] = 0x19;256 data[1] = 0x00;257 err_code = mr_write(gspca_dev, 2);258 if (err_code < 0)259 return err_code;260 261 err_code = cam_get_response16(gspca_dev, 0x21, 0);262 if (err_code < 0)263 return err_code;264 265 data[0] = 0x19;266 data[1] = 0x00;267 err_code = mr_write(gspca_dev, 2);268 if (err_code < 0)269 return err_code;270 271 while (status != 0x0a && tries < 256) {272 err_code = cam_get_response16(gspca_dev, 0x21, 0);273 status = data[0];274 tries++;275 if (err_code < 0)276 return err_code;277 }278 if (status != 0x0a)279 gspca_err(gspca_dev, "status is %02x\n", status);280 281 tries = 0;282 while (tries < 4) {283 data[0] = 0x19;284 data[1] = 0x00;285 err_code = mr_write(gspca_dev, 2);286 if (err_code < 0)287 return err_code;288 289 err_code = cam_get_response16(gspca_dev, 0x21, 0);290 tries++;291 if (err_code < 0)292 return err_code;293 }294 295 data[0] = 0x19;296 err_code = mr_write(gspca_dev, 1);297 if (err_code < 0)298 return err_code;299 300 err_code = mr_read(gspca_dev, 16);301 if (err_code < 0)302 return err_code;303 304 return 0;305}306 307static int stream_start(struct gspca_dev *gspca_dev)308{309 gspca_dev->usb_buf[0] = 0x01;310 gspca_dev->usb_buf[1] = 0x01;311 return mr_write(gspca_dev, 2);312}313 314static void stream_stop(struct gspca_dev *gspca_dev)315{316 gspca_dev->usb_buf[0] = 0x01;317 gspca_dev->usb_buf[1] = 0x00;318 if (mr_write(gspca_dev, 2) < 0)319 gspca_err(gspca_dev, "Stream Stop failed\n");320}321 322static void lcd_stop(struct gspca_dev *gspca_dev)323{324 gspca_dev->usb_buf[0] = 0x19;325 gspca_dev->usb_buf[1] = 0x54;326 if (mr_write(gspca_dev, 2) < 0)327 gspca_err(gspca_dev, "LCD Stop failed\n");328}329 330static int isoc_enable(struct gspca_dev *gspca_dev)331{332 gspca_dev->usb_buf[0] = 0x00;333 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */334 return mr_write(gspca_dev, 2);335}336 337/* This function is called at probe time */338static int sd_config(struct gspca_dev *gspca_dev,339 const struct usb_device_id *id)340{341 struct sd *sd = (struct sd *) gspca_dev;342 struct cam *cam;343 int err_code;344 345 cam = &gspca_dev->cam;346 cam->cam_mode = vga_mode;347 cam->nmodes = ARRAY_SIZE(vga_mode);348 sd->do_lcd_stop = 0;349 350 /* Several of the supported CIF cameras share the same USB ID but351 * require different initializations and different control settings.352 * The same is true of the VGA cameras. Therefore, we are forced353 * to start the initialization process in order to determine which354 * camera is present. Some of the supported cameras require the355 * memory pointer to be set to 0 as the very first item of business356 * or else they will not stream. So we do that immediately.357 */358 err_code = zero_the_pointer(gspca_dev);359 if (err_code < 0)360 return err_code;361 362 err_code = stream_start(gspca_dev);363 if (err_code < 0)364 return err_code;365 366 /* Now, the query for sensor type. */367 err_code = cam_get_response16(gspca_dev, 0x07, 1);368 if (err_code < 0)369 return err_code;370 371 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {372 sd->cam_type = CAM_TYPE_CIF;373 cam->nmodes--;374 /*375 * All but one of the known CIF cameras share the same USB ID,376 * but two different init routines are in use, and the control377 * settings are different, too. We need to detect which camera378 * of the two known varieties is connected!379 *380 * A list of known CIF cameras follows. They all report either381 * 0200 for type 0 or 0300 for type 1.382 * If you have another to report, please do383 *384 * Name sd->sensor_type reported by385 *386 * Sakar 56379 Spy-shot 0 T. Kilgore387 * Innovage 0 T. Kilgore388 * Vivitar Mini 0 H. De Goede389 * Vivitar Mini 0 E. Rodriguez390 * Vivitar Mini 1 T. Kilgore391 * Elta-Media 8212dc 1 T. Kaiser392 * Philips dig. keych. 1 T. Kilgore393 * Trust Spyc@m 100 1 A. Jacobs394 */395 switch (gspca_dev->usb_buf[0]) {396 case 2:397 sd->sensor_type = 0;398 break;399 case 3:400 sd->sensor_type = 1;401 break;402 default:403 pr_err("Unknown CIF Sensor id : %02x\n",404 gspca_dev->usb_buf[1]);405 return -ENODEV;406 }407 gspca_dbg(gspca_dev, D_PROBE, "MR97310A CIF camera detected, sensor: %d\n",408 sd->sensor_type);409 } else {410 sd->cam_type = CAM_TYPE_VGA;411 412 /*413 * Here is a table of the responses to the query for sensor414 * type, from the known MR97310A VGA cameras. Six different415 * cameras of which five share the same USB ID.416 *417 * Name gspca_dev->usb_buf[] sd->sensor_type418 * sd->do_lcd_stop419 * Aiptek Pencam VGA+ 0300 0 1420 * ION digital 0300 0 1421 * Argus DC-1620 0450 1 0422 * Argus QuickClix 0420 1 1423 * Sakar 77379 Digital 0350 0 1424 * Sakar 1638x CyberPix 0120 0 2425 *426 * Based upon these results, we assume default settings427 * and then correct as necessary, as follows.428 *429 */430 431 sd->sensor_type = 1;432 sd->do_lcd_stop = 0;433 sd->adj_colors = 0;434 if (gspca_dev->usb_buf[0] == 0x01) {435 sd->sensor_type = 2;436 } else if ((gspca_dev->usb_buf[0] != 0x03) &&437 (gspca_dev->usb_buf[0] != 0x04)) {438 pr_err("Unknown VGA Sensor id Byte 0: %02x\n",439 gspca_dev->usb_buf[0]);440 pr_err("Defaults assumed, may not work\n");441 pr_err("Please report this\n");442 }443 /* Sakar Digital color needs to be adjusted. */444 if ((gspca_dev->usb_buf[0] == 0x03) &&445 (gspca_dev->usb_buf[1] == 0x50))446 sd->adj_colors = 1;447 if (gspca_dev->usb_buf[0] == 0x04) {448 sd->do_lcd_stop = 1;449 switch (gspca_dev->usb_buf[1]) {450 case 0x50:451 sd->sensor_type = 0;452 gspca_dbg(gspca_dev, D_PROBE, "sensor_type corrected to 0\n");453 break;454 case 0x20:455 /* Nothing to do here. */456 break;457 default:458 pr_err("Unknown VGA Sensor id Byte 1: %02x\n",459 gspca_dev->usb_buf[1]);460 pr_err("Defaults assumed, may not work\n");461 pr_err("Please report this\n");462 }463 }464 gspca_dbg(gspca_dev, D_PROBE, "MR97310A VGA camera detected, sensor: %d\n",465 sd->sensor_type);466 }467 /* Stop streaming as we've started it only to probe the sensor type. */468 sd_stopN(gspca_dev);469 470 if (force_sensor_type != -1) {471 sd->sensor_type = !!force_sensor_type;472 gspca_dbg(gspca_dev, D_PROBE, "Forcing sensor type to: %d\n",473 sd->sensor_type);474 }475 476 return 0;477}478 479/* this function is called at probe and resume time */480static int sd_init(struct gspca_dev *gspca_dev)481{482 return 0;483}484 485static int start_cif_cam(struct gspca_dev *gspca_dev)486{487 struct sd *sd = (struct sd *) gspca_dev;488 __u8 *data = gspca_dev->usb_buf;489 int err_code;490 static const __u8 startup_string[] = {491 0x00,492 0x0d,493 0x01,494 0x00, /* Hsize/8 for 352 or 320 */495 0x00, /* Vsize/4 for 288 or 240 */496 0x13, /* or 0xbb, depends on sensor */497 0x00, /* Hstart, depends on res. */498 0x00, /* reserved ? */499 0x00, /* Vstart, depends on res. and sensor */500 0x50, /* 0x54 to get 176 or 160 */501 0xc0502 };503 504 /* Note: Some of the above descriptions guessed from MR97113A driver */505 506 memcpy(data, startup_string, 11);507 if (sd->sensor_type)508 data[5] = 0xbb;509 510 switch (gspca_dev->pixfmt.width) {511 case 160:512 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */513 fallthrough;514 case 320:515 default:516 data[3] = 0x28; /* reg 2, H size/8 */517 data[4] = 0x3c; /* reg 3, V size/4 */518 data[6] = 0x14; /* reg 5, H start */519 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */520 break;521 case 176:522 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */523 fallthrough;524 case 352:525 data[3] = 0x2c; /* reg 2, H size/8 */526 data[4] = 0x48; /* reg 3, V size/4 */527 data[6] = 0x06; /* reg 5, H start */528 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */529 break;530 }531 err_code = mr_write(gspca_dev, 11);532 if (err_code < 0)533 return err_code;534 535 if (!sd->sensor_type) {536 static const struct sensor_w_data cif_sensor0_init_data[] = {537 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,538 0x0f, 0x14, 0x0f, 0x10}, 8},539 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},540 {0x12, 0x00, {0x07}, 1},541 {0x1f, 0x00, {0x06}, 1},542 {0x27, 0x00, {0x04}, 1},543 {0x29, 0x00, {0x0c}, 1},544 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},545 {0x50, 0x00, {0x60}, 1},546 {0x60, 0x00, {0x06}, 1},547 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},548 {0x72, 0x00, {0x1e, 0x56}, 2},549 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,550 0x31, 0x80, 0x00}, 9},551 {0x11, 0x00, {0x01}, 1},552 {0, 0, {0}, 0}553 };554 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,555 ARRAY_SIZE(cif_sensor0_init_data));556 } else { /* sd->sensor_type = 1 */557 static const struct sensor_w_data cif_sensor1_init_data[] = {558 /* Reg 3,4, 7,8 get set by the controls */559 {0x02, 0x00, {0x10}, 1},560 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */561 {0x06, 0x01, {0x00}, 1},562 {0x09, 0x02, {0x0e}, 1},563 {0x0a, 0x02, {0x05}, 1},564 {0x0b, 0x02, {0x05}, 1},565 {0x0c, 0x02, {0x0f}, 1},566 {0x0d, 0x02, {0x07}, 1},567 {0x0e, 0x02, {0x0c}, 1},568 {0x0f, 0x00, {0x00}, 1},569 {0x10, 0x00, {0x06}, 1},570 {0x11, 0x00, {0x07}, 1},571 {0x12, 0x00, {0x00}, 1},572 {0x13, 0x00, {0x01}, 1},573 {0, 0, {0}, 0}574 };575 /* Without this command the cam won't work with USB-UHCI */576 gspca_dev->usb_buf[0] = 0x0a;577 gspca_dev->usb_buf[1] = 0x00;578 err_code = mr_write(gspca_dev, 2);579 if (err_code < 0)580 return err_code;581 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,582 ARRAY_SIZE(cif_sensor1_init_data));583 }584 return err_code;585}586 587static int start_vga_cam(struct gspca_dev *gspca_dev)588{589 struct sd *sd = (struct sd *) gspca_dev;590 __u8 *data = gspca_dev->usb_buf;591 int err_code;592 static const __u8 startup_string[] =593 {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,594 0x00, 0x50, 0xc0};595 /* What some of these mean is explained in start_cif_cam(), above */596 597 memcpy(data, startup_string, 11);598 if (!sd->sensor_type) {599 data[5] = 0x00;600 data[10] = 0x91;601 }602 if (sd->sensor_type == 2) {603 data[5] = 0x00;604 data[10] = 0x18;605 }606 607 switch (gspca_dev->pixfmt.width) {608 case 160:609 data[9] |= 0x0c; /* reg 8, 4:1 scale down */610 fallthrough;611 case 320:612 data[9] |= 0x04; /* reg 8, 2:1 scale down */613 fallthrough;614 case 640:615 default:616 data[3] = 0x50; /* reg 2, H size/8 */617 data[4] = 0x78; /* reg 3, V size/4 */618 data[6] = 0x04; /* reg 5, H start */619 data[8] = 0x03; /* reg 7, V start */620 if (sd->sensor_type == 2) {621 data[6] = 2;622 data[8] = 1;623 }624 if (sd->do_lcd_stop)625 data[8] = 0x04; /* Bayer tile shifted */626 break;627 628 case 176:629 data[9] |= 0x04; /* reg 8, 2:1 scale down */630 fallthrough;631 case 352:632 data[3] = 0x2c; /* reg 2, H size */633 data[4] = 0x48; /* reg 3, V size */634 data[6] = 0x94; /* reg 5, H start */635 data[8] = 0x63; /* reg 7, V start */636 if (sd->do_lcd_stop)637 data[8] = 0x64; /* Bayer tile shifted */638 break;639 }640 641 err_code = mr_write(gspca_dev, 11);642 if (err_code < 0)643 return err_code;644 645 if (!sd->sensor_type) {646 static const struct sensor_w_data vga_sensor0_init_data[] = {647 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},648 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},649 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},650 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},651 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},652 {0, 0, {0}, 0}653 };654 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,655 ARRAY_SIZE(vga_sensor0_init_data));656 } else if (sd->sensor_type == 1) {657 static const struct sensor_w_data color_adj[] = {658 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,659 /* adjusted blue, green, red gain correct660 too much blue from the Sakar Digital */661 0x05, 0x01, 0x04}, 8}662 };663 664 static const struct sensor_w_data color_no_adj[] = {665 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,666 /* default blue, green, red gain settings */667 0x07, 0x00, 0x01}, 8}668 };669 670 static const struct sensor_w_data vga_sensor1_init_data[] = {671 {0x11, 0x04, {0x01}, 1},672 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,673 /* These settings may be better for some cameras */674 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */675 0x00, 0x0a}, 7},676 {0x11, 0x04, {0x01}, 1},677 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},678 {0x11, 0x04, {0x01}, 1},679 {0, 0, {0}, 0}680 };681 682 if (sd->adj_colors)683 err_code = sensor_write_regs(gspca_dev, color_adj,684 ARRAY_SIZE(color_adj));685 else686 err_code = sensor_write_regs(gspca_dev, color_no_adj,687 ARRAY_SIZE(color_no_adj));688 689 if (err_code < 0)690 return err_code;691 692 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,693 ARRAY_SIZE(vga_sensor1_init_data));694 } else { /* sensor type == 2 */695 static const struct sensor_w_data vga_sensor2_init_data[] = {696 697 {0x01, 0x00, {0x48}, 1},698 {0x02, 0x00, {0x22}, 1},699 /* Reg 3 msb and 4 is lsb of the exposure setting*/700 {0x05, 0x00, {0x10}, 1},701 {0x06, 0x00, {0x00}, 1},702 {0x07, 0x00, {0x00}, 1},703 {0x08, 0x00, {0x00}, 1},704 {0x09, 0x00, {0x00}, 1},705 /* The following are used in the gain control706 * which is BTW completely borked in the OEM driver707 * The values for each color go from 0 to 0x7ff708 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb709 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb710 *{0x0c, 0x00, {0x01}, 1}, red gain msb711 *{0x0d, 0x00, {0x10}, 1}, red gain lsb712 *{0x0e, 0x00, {0x01}, 1}, blue gain msb713 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb714 *{0x10, 0x00, {0x01}, 1}, green2 gain msb715 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb716 */717 {0x12, 0x00, {0x00}, 1},718 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */719 {0x14, 0x00, {0x00}, 1},720 {0x15, 0x00, {0x06}, 1},721 {0x16, 0x00, {0x01}, 1},722 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */723 {0x18, 0x00, {0x02}, 1},724 {0x19, 0x00, {0x82}, 1}, /* don't mess with */725 {0x1a, 0x00, {0x00}, 1},726 {0x1b, 0x00, {0x20}, 1},727 /* {0x1c, 0x00, {0x17}, 1}, contrast control */728 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */729 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */730 {0x1f, 0x00, {0x0c}, 1},731 {0x20, 0x00, {0x00}, 1},732 {0, 0, {0}, 0}733 };734 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,735 ARRAY_SIZE(vga_sensor2_init_data));736 }737 return err_code;738}739 740static int sd_start(struct gspca_dev *gspca_dev)741{742 struct sd *sd = (struct sd *) gspca_dev;743 int err_code;744 745 sd->sof_read = 0;746 747 /* Some of the VGA cameras require the memory pointer748 * to be set to 0 again. We have been forced to start the749 * stream in sd_config() to detect the hardware, and closed it.750 * Thus, we need here to do a completely fresh and clean start. */751 err_code = zero_the_pointer(gspca_dev);752 if (err_code < 0)753 return err_code;754 755 err_code = stream_start(gspca_dev);756 if (err_code < 0)757 return err_code;758 759 if (sd->cam_type == CAM_TYPE_CIF) {760 err_code = start_cif_cam(gspca_dev);761 } else {762 err_code = start_vga_cam(gspca_dev);763 }764 if (err_code < 0)765 return err_code;766 767 return isoc_enable(gspca_dev);768}769 770static void sd_stopN(struct gspca_dev *gspca_dev)771{772 struct sd *sd = (struct sd *) gspca_dev;773 774 stream_stop(gspca_dev);775 /* Not all the cams need this, but even if not, probably a good idea */776 zero_the_pointer(gspca_dev);777 if (sd->do_lcd_stop)778 lcd_stop(gspca_dev);779}780 781static void setbrightness(struct gspca_dev *gspca_dev, s32 val)782{783 struct sd *sd = (struct sd *) gspca_dev;784 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */785 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */786 static const u8 quick_clix_table[] =787 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */788 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};789 if (sd->cam_type == CAM_TYPE_VGA) {790 sign_reg += 4;791 value_reg += 4;792 }793 794 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */795 if (val > 0) {796 sensor_write1(gspca_dev, sign_reg, 0x00);797 } else {798 sensor_write1(gspca_dev, sign_reg, 0x01);799 val = 257 - val;800 }801 /* Use lookup table for funky Argus QuickClix brightness */802 if (sd->do_lcd_stop)803 val = quick_clix_table[val];804 805 sensor_write1(gspca_dev, value_reg, val);806}807 808static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv)809{810 struct sd *sd = (struct sd *) gspca_dev;811 int exposure = MR97310A_EXPOSURE_DEFAULT;812 u8 buf[2];813 814 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {815 /* This cam does not like exposure settings < 300,816 so scale 0 - 4095 to 300 - 4095 */817 exposure = (expo * 9267) / 10000 + 300;818 sensor_write1(gspca_dev, 3, exposure >> 4);819 sensor_write1(gspca_dev, 4, exposure & 0x0f);820 } else if (sd->sensor_type == 2) {821 exposure = expo;822 exposure >>= 3;823 sensor_write1(gspca_dev, 3, exposure >> 8);824 sensor_write1(gspca_dev, 4, exposure & 0xff);825 } else {826 /* We have both a clock divider and an exposure register.827 We first calculate the clock divider, as that determines828 the maximum exposure and then we calculate the exposure829 register setting (which goes from 0 - 511).830 831 Note our 0 - 4095 exposure is mapped to 0 - 511832 milliseconds exposure time */833 u8 clockdiv = (60 * expo + 7999) / 8000;834 835 /* Limit framerate to not exceed usb bandwidth */836 if (clockdiv < min_clockdiv && gspca_dev->pixfmt.width >= 320)837 clockdiv = min_clockdiv;838 else if (clockdiv < 2)839 clockdiv = 2;840 841 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)842 clockdiv = 4;843 844 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->845 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */846 exposure = (60 * 511 * expo) / (8000 * clockdiv);847 if (exposure > 511)848 exposure = 511;849 850 /* exposure register value is reversed! */851 exposure = 511 - exposure;852 853 buf[0] = exposure & 0xff;854 buf[1] = exposure >> 8;855 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);856 sensor_write1(gspca_dev, 0x02, clockdiv);857 }858}859 860static void setgain(struct gspca_dev *gspca_dev, s32 val)861{862 struct sd *sd = (struct sd *) gspca_dev;863 u8 gainreg;864 865 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)866 sensor_write1(gspca_dev, 0x0e, val);867 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)868 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {869 sensor_write1(gspca_dev, gainreg, val >> 8);870 sensor_write1(gspca_dev, gainreg + 1, val & 0xff);871 }872 else873 sensor_write1(gspca_dev, 0x10, val);874}875 876static void setcontrast(struct gspca_dev *gspca_dev, s32 val)877{878 sensor_write1(gspca_dev, 0x1c, val);879}880 881static int sd_s_ctrl(struct v4l2_ctrl *ctrl)882{883 struct gspca_dev *gspca_dev =884 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);885 struct sd *sd = (struct sd *)gspca_dev;886 887 gspca_dev->usb_err = 0;888 889 if (!gspca_dev->streaming)890 return 0;891 892 switch (ctrl->id) {893 case V4L2_CID_BRIGHTNESS:894 setbrightness(gspca_dev, ctrl->val);895 break;896 case V4L2_CID_CONTRAST:897 setcontrast(gspca_dev, ctrl->val);898 break;899 case V4L2_CID_EXPOSURE:900 setexposure(gspca_dev, sd->exposure->val,901 sd->min_clockdiv ? sd->min_clockdiv->val : 0);902 break;903 case V4L2_CID_GAIN:904 setgain(gspca_dev, ctrl->val);905 break;906 }907 return gspca_dev->usb_err;908}909 910static const struct v4l2_ctrl_ops sd_ctrl_ops = {911 .s_ctrl = sd_s_ctrl,912};913 914static int sd_init_controls(struct gspca_dev *gspca_dev)915{916 struct sd *sd = (struct sd *)gspca_dev;917 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;918 static const struct v4l2_ctrl_config clockdiv = {919 .ops = &sd_ctrl_ops,920 .id = MR97310A_CID_CLOCKDIV,921 .type = V4L2_CTRL_TYPE_INTEGER,922 .name = "Minimum Clock Divider",923 .min = MR97310A_MIN_CLOCKDIV_MIN,924 .max = MR97310A_MIN_CLOCKDIV_MAX,925 .step = 1,926 .def = MR97310A_MIN_CLOCKDIV_DEFAULT,927 };928 bool has_brightness = false;929 bool has_argus_brightness = false;930 bool has_contrast = false;931 bool has_gain = false;932 bool has_cs_gain = false;933 bool has_exposure = false;934 bool has_clockdiv = false;935 936 gspca_dev->vdev.ctrl_handler = hdl;937 v4l2_ctrl_handler_init(hdl, 4);938 939 /* Setup controls depending on camera type */940 if (sd->cam_type == CAM_TYPE_CIF) {941 /* No brightness for sensor_type 0 */942 if (sd->sensor_type == 0)943 has_exposure = has_gain = has_clockdiv = true;944 else945 has_exposure = has_gain = has_brightness = true;946 } else {947 /* All controls need to be disabled if VGA sensor_type is 0 */948 if (sd->sensor_type == 0)949 ; /* no controls! */950 else if (sd->sensor_type == 2)951 has_exposure = has_cs_gain = has_contrast = true;952 else if (sd->do_lcd_stop)953 has_exposure = has_gain = has_argus_brightness =954 has_clockdiv = true;955 else956 has_exposure = has_gain = has_brightness =957 has_clockdiv = true;958 }959 960 /* Separate brightness control description for Argus QuickClix as it has961 * different limits from the other mr97310a cameras, and separate gain962 * control for Sakar CyberPix camera. */963 /*964 * This control is disabled for CIF type 1 and VGA type 0 cameras.965 * It does not quite act linearly for the Argus QuickClix camera,966 * but it does control brightness. The values are 0 - 15 only, and967 * the table above makes them act consecutively.968 */969 if (has_brightness)970 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,971 V4L2_CID_BRIGHTNESS, -254, 255, 1,972 MR97310A_BRIGHTNESS_DEFAULT);973 else if (has_argus_brightness)974 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,975 V4L2_CID_BRIGHTNESS, 0, 15, 1,976 MR97310A_BRIGHTNESS_DEFAULT);977 if (has_contrast)978 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,979 V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN,980 MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT);981 if (has_gain)982 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,983 V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX,984 1, MR97310A_GAIN_DEFAULT);985 else if (has_cs_gain)986 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN,987 MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX,988 1, MR97310A_CS_GAIN_DEFAULT);989 if (has_exposure)990 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,991 V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN,992 MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT);993 if (has_clockdiv)994 sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL);995 996 if (hdl->error) {997 pr_err("Could not initialize controls\n");998 return hdl->error;999 }1000 if (has_exposure && has_clockdiv)1001 v4l2_ctrl_cluster(2, &sd->exposure);1002 return 0;1003}1004 1005/* Include pac common sof detection functions */1006#include "pac_common.h"1007 1008static void sd_pkt_scan(struct gspca_dev *gspca_dev,1009 u8 *data, /* isoc packet */1010 int len) /* iso packet length */1011{1012 struct sd *sd = (struct sd *) gspca_dev;1013 unsigned char *sof;1014 1015 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);1016 if (sof) {1017 int n;1018 1019 /* finish decoding current frame */1020 n = sof - data;1021 if (n > sizeof pac_sof_marker)1022 n -= sizeof pac_sof_marker;1023 else1024 n = 0;1025 gspca_frame_add(gspca_dev, LAST_PACKET,1026 data, n);1027 /* Start next frame. */1028 gspca_frame_add(gspca_dev, FIRST_PACKET,1029 pac_sof_marker, sizeof pac_sof_marker);1030 len -= sof - data;1031 data = sof;1032 }1033 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);1034}1035 1036/* sub-driver description */1037static const struct sd_desc sd_desc = {1038 .name = MODULE_NAME,1039 .config = sd_config,1040 .init = sd_init,1041 .init_controls = sd_init_controls,1042 .start = sd_start,1043 .stopN = sd_stopN,1044 .pkt_scan = sd_pkt_scan,1045};1046 1047/* -- module initialisation -- */1048static const struct usb_device_id device_table[] = {1049 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */1050 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */1051 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */1052 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */1053 {}1054};1055MODULE_DEVICE_TABLE(usb, device_table);1056 1057/* -- device connect -- */1058static int sd_probe(struct usb_interface *intf,1059 const struct usb_device_id *id)1060{1061 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),1062 THIS_MODULE);1063}1064 1065static struct usb_driver sd_driver = {1066 .name = MODULE_NAME,1067 .id_table = device_table,1068 .probe = sd_probe,1069 .disconnect = gspca_disconnect,1070#ifdef CONFIG_PM1071 .suspend = gspca_suspend,1072 .resume = gspca_resume,1073 .reset_resume = gspca_resume,1074#endif1075};1076 1077module_usb_driver(sd_driver);1078