diff options
author | Theodore Kilgore <kilgota@banach.math.auburn.edu> | 2009-10-05 04:11:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-05 15:40:30 -0500 |
commit | 930bf78c20187f3cbbf0775cd317616c6b681a8a (patch) | |
tree | 0b51dc082c3aafadbb1484332764b956374175b5 /drivers | |
parent | 9d2ba7ad802300d6a1830df9268d8ba478c66a18 (diff) |
V4L/DVB (13137): gspca_mr97310a: Add controls for vga cams with sensor type 0
This patch adds controls for vga cams with sensor type 0, in order to
correctly report the present controls, the probing of the sensor type
has been moved from sd_start to sd_config, since this made the sensor
type probing unreliable the detection method was changed.
Note this requires the camera to enter streaming mode, so sd_config now
briefly makes the camera stream.
Signed-off-by: Theodore Kilgore <kilgota@banach.math.auburn.edu>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 506 |
1 files changed, 291 insertions, 215 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f8328b9efae5..f4c83b367900 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -1,23 +1,28 @@ | |||
1 | /* | 1 | /* |
2 | * Mars MR97310A library | 2 | * Mars MR97310A library |
3 | * | 3 | * |
4 | * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is | ||
4 | * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> | 5 | * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> |
5 | * | 6 | * |
6 | * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ | 7 | * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ |
7 | * and for the routines for detecting and classifying these various cameras, | 8 | * and for the routines for detecting and classifying these various cameras, |
9 | * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> | ||
8 | * | 10 | * |
11 | * Support for the control settings for the CIF cameras is | ||
12 | * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and | ||
13 | * Thomas Kaiser <thomas@kaiser-linux.li> | ||
14 | * | ||
15 | * Support for the control settings for the VGA cameras is | ||
9 | * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> | 16 | * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> |
10 | * | 17 | * |
11 | * Acknowledgements: | 18 | * Several previously unsupported cameras are owned and have been tested by |
19 | * Hans de Goede <hdgoede@redhat.com> and | ||
20 | * Thomas Kaiser <thomas@kaiser-linux.li> and | ||
21 | * Theodore Kilgore <kilgota@auburn.edu> | ||
12 | * | 22 | * |
13 | * The MR97311A support in gspca/mars.c has been helpful in understanding some | 23 | * The MR97311A support in gspca/mars.c has been helpful in understanding some |
14 | * of the registers in these cameras. | 24 | * of the registers in these cameras. |
15 | * | 25 | * |
16 | * Hans de Goede <hdgoede@redhat.com> and | ||
17 | * Thomas Kaiser <thomas@kaiser-linux.li> | ||
18 | * have assisted with their experience. Each of them has also helped by | ||
19 | * testing a previously unsupported camera. | ||
20 | * | ||
21 | * This program is free software; you can redistribute it and/or modify | 26 | * This program is free software; you can redistribute it and/or modify |
22 | * it under the terms of the GNU General Public License as published by | 27 | * it under the terms of the GNU General Public License as published by |
23 | * the Free Software Foundation; either version 2 of the License, or | 28 | * the Free Software Foundation; either version 2 of the License, or |
@@ -40,11 +45,9 @@ | |||
40 | #define CAM_TYPE_CIF 0 | 45 | #define CAM_TYPE_CIF 0 |
41 | #define CAM_TYPE_VGA 1 | 46 | #define CAM_TYPE_VGA 1 |
42 | 47 | ||
43 | #define MR97310A_BRIGHTNESS_MIN -254 | ||
44 | #define MR97310A_BRIGHTNESS_MAX 255 | ||
45 | #define MR97310A_BRIGHTNESS_DEFAULT 0 | 48 | #define MR97310A_BRIGHTNESS_DEFAULT 0 |
46 | 49 | ||
47 | #define MR97310A_EXPOSURE_MIN 300 | 50 | #define MR97310A_EXPOSURE_MIN 0 |
48 | #define MR97310A_EXPOSURE_MAX 4095 | 51 | #define MR97310A_EXPOSURE_MAX 4095 |
49 | #define MR97310A_EXPOSURE_DEFAULT 1000 | 52 | #define MR97310A_EXPOSURE_DEFAULT 1000 |
50 | 53 | ||
@@ -82,6 +85,7 @@ struct sensor_w_data { | |||
82 | int len; | 85 | int len; |
83 | }; | 86 | }; |
84 | 87 | ||
88 | static void sd_stopN(struct gspca_dev *gspca_dev); | ||
85 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 89 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); |
86 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 90 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); |
87 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | 91 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); |
@@ -94,14 +98,16 @@ static void setgain(struct gspca_dev *gspca_dev); | |||
94 | 98 | ||
95 | /* V4L2 controls supported by the driver */ | 99 | /* V4L2 controls supported by the driver */ |
96 | static struct ctrl sd_ctrls[] = { | 100 | static struct ctrl sd_ctrls[] = { |
101 | /* Seprate brightness control description for Argus QuickClix as it has | ||
102 | different limits from to other mr97310a camera's */ | ||
97 | { | 103 | { |
98 | #define BRIGHTNESS_IDX 0 | 104 | #define NORM_BRIGHTNESS_IDX 0 |
99 | { | 105 | { |
100 | .id = V4L2_CID_BRIGHTNESS, | 106 | .id = V4L2_CID_BRIGHTNESS, |
101 | .type = V4L2_CTRL_TYPE_INTEGER, | 107 | .type = V4L2_CTRL_TYPE_INTEGER, |
102 | .name = "Brightness", | 108 | .name = "Brightness", |
103 | .minimum = MR97310A_BRIGHTNESS_MIN, | 109 | .minimum = -254, |
104 | .maximum = MR97310A_BRIGHTNESS_MAX, | 110 | .maximum = 255, |
105 | .step = 1, | 111 | .step = 1, |
106 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | 112 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, |
107 | .flags = 0, | 113 | .flags = 0, |
@@ -110,7 +116,22 @@ static struct ctrl sd_ctrls[] = { | |||
110 | .get = sd_getbrightness, | 116 | .get = sd_getbrightness, |
111 | }, | 117 | }, |
112 | { | 118 | { |
113 | #define EXPOSURE_IDX 1 | 119 | #define ARGUS_QC_BRIGHTNESS_IDX 1 |
120 | { | ||
121 | .id = V4L2_CID_BRIGHTNESS, | ||
122 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
123 | .name = "Brightness", | ||
124 | .minimum = 0, | ||
125 | .maximum = 15, | ||
126 | .step = 1, | ||
127 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | ||
128 | .flags = 0, | ||
129 | }, | ||
130 | .set = sd_setbrightness, | ||
131 | .get = sd_getbrightness, | ||
132 | }, | ||
133 | { | ||
134 | #define EXPOSURE_IDX 2 | ||
114 | { | 135 | { |
115 | .id = V4L2_CID_EXPOSURE, | 136 | .id = V4L2_CID_EXPOSURE, |
116 | .type = V4L2_CTRL_TYPE_INTEGER, | 137 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -125,7 +146,7 @@ static struct ctrl sd_ctrls[] = { | |||
125 | .get = sd_getexposure, | 146 | .get = sd_getexposure, |
126 | }, | 147 | }, |
127 | { | 148 | { |
128 | #define GAIN_IDX 2 | 149 | #define GAIN_IDX 3 |
129 | { | 150 | { |
130 | .id = V4L2_CID_GAIN, | 151 | .id = V4L2_CID_GAIN, |
131 | .type = V4L2_CTRL_TYPE_INTEGER, | 152 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -230,12 +251,17 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | |||
230 | int rc; | 251 | int rc; |
231 | 252 | ||
232 | buf = data; | 253 | buf = data; |
233 | rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); | 254 | if (sd->cam_type == CAM_TYPE_CIF) { |
255 | rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); | ||
256 | confirm_reg = sd->sensor_type ? 0x13 : 0x11; | ||
257 | } else { | ||
258 | rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1); | ||
259 | confirm_reg = 0x11; | ||
260 | } | ||
234 | if (rc < 0) | 261 | if (rc < 0) |
235 | return rc; | 262 | return rc; |
236 | 263 | ||
237 | buf = 0x01; | 264 | buf = 0x01; |
238 | confirm_reg = sd->sensor_type ? 0x13 : 0x11; | ||
239 | rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); | 265 | rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); |
240 | if (rc < 0) | 266 | if (rc < 0) |
241 | return rc; | 267 | return rc; |
@@ -243,18 +269,26 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | |||
243 | return 0; | 269 | return 0; |
244 | } | 270 | } |
245 | 271 | ||
246 | static int cam_get_response16(struct gspca_dev *gspca_dev) | 272 | static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose) |
247 | { | 273 | { |
248 | __u8 *data = gspca_dev->usb_buf; | ||
249 | int err_code; | 274 | int err_code; |
250 | 275 | ||
251 | data[0] = 0x21; | 276 | gspca_dev->usb_buf[0] = reg; |
252 | err_code = mr_write(gspca_dev, 1); | 277 | err_code = mr_write(gspca_dev, 1); |
253 | if (err_code < 0) | 278 | if (err_code < 0) |
254 | return err_code; | 279 | return err_code; |
255 | 280 | ||
256 | err_code = mr_read(gspca_dev, 16); | 281 | err_code = mr_read(gspca_dev, 16); |
257 | return err_code; | 282 | if (err_code < 0) |
283 | return err_code; | ||
284 | |||
285 | if (verbose) | ||
286 | PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg, | ||
287 | gspca_dev->usb_buf[0], | ||
288 | gspca_dev->usb_buf[1], | ||
289 | gspca_dev->usb_buf[2]); | ||
290 | |||
291 | return 0; | ||
258 | } | 292 | } |
259 | 293 | ||
260 | static int zero_the_pointer(struct gspca_dev *gspca_dev) | 294 | static int zero_the_pointer(struct gspca_dev *gspca_dev) |
@@ -264,7 +298,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
264 | u8 status = 0; | 298 | u8 status = 0; |
265 | int tries = 0; | 299 | int tries = 0; |
266 | 300 | ||
267 | err_code = cam_get_response16(gspca_dev); | 301 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
268 | if (err_code < 0) | 302 | if (err_code < 0) |
269 | return err_code; | 303 | return err_code; |
270 | 304 | ||
@@ -275,7 +309,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
275 | if (err_code < 0) | 309 | if (err_code < 0) |
276 | return err_code; | 310 | return err_code; |
277 | 311 | ||
278 | err_code = cam_get_response16(gspca_dev); | 312 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
279 | if (err_code < 0) | 313 | if (err_code < 0) |
280 | return err_code; | 314 | return err_code; |
281 | 315 | ||
@@ -285,7 +319,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
285 | if (err_code < 0) | 319 | if (err_code < 0) |
286 | return err_code; | 320 | return err_code; |
287 | 321 | ||
288 | err_code = cam_get_response16(gspca_dev); | 322 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
289 | if (err_code < 0) | 323 | if (err_code < 0) |
290 | return err_code; | 324 | return err_code; |
291 | 325 | ||
@@ -295,7 +329,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
295 | if (err_code < 0) | 329 | if (err_code < 0) |
296 | return err_code; | 330 | return err_code; |
297 | 331 | ||
298 | err_code = cam_get_response16(gspca_dev); | 332 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
299 | if (err_code < 0) | 333 | if (err_code < 0) |
300 | return err_code; | 334 | return err_code; |
301 | 335 | ||
@@ -306,7 +340,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
306 | return err_code; | 340 | return err_code; |
307 | 341 | ||
308 | while (status != 0x0a && tries < 256) { | 342 | while (status != 0x0a && tries < 256) { |
309 | err_code = cam_get_response16(gspca_dev); | 343 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
310 | status = data[0]; | 344 | status = data[0]; |
311 | tries++; | 345 | tries++; |
312 | if (err_code < 0) | 346 | if (err_code < 0) |
@@ -323,7 +357,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
323 | if (err_code < 0) | 357 | if (err_code < 0) |
324 | return err_code; | 358 | return err_code; |
325 | 359 | ||
326 | err_code = cam_get_response16(gspca_dev); | 360 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
327 | status = data[0]; | 361 | status = data[0]; |
328 | tries++; | 362 | tries++; |
329 | if (err_code < 0) | 363 | if (err_code < 0) |
@@ -342,22 +376,34 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
342 | return 0; | 376 | return 0; |
343 | } | 377 | } |
344 | 378 | ||
345 | static u8 get_sensor_id(struct gspca_dev *gspca_dev) | 379 | static int stream_start(struct gspca_dev *gspca_dev) |
346 | { | 380 | { |
347 | int err_code; | 381 | gspca_dev->usb_buf[0] = 0x01; |
348 | 382 | gspca_dev->usb_buf[1] = 0x01; | |
349 | gspca_dev->usb_buf[0] = 0x1e; | 383 | return mr_write(gspca_dev, 2); |
350 | err_code = mr_write(gspca_dev, 1); | 384 | } |
351 | if (err_code < 0) | ||
352 | return err_code; | ||
353 | 385 | ||
354 | err_code = mr_read(gspca_dev, 16); | 386 | static void stream_stop(struct gspca_dev *gspca_dev) |
355 | if (err_code < 0) | 387 | { |
356 | return err_code; | 388 | gspca_dev->usb_buf[0] = 0x01; |
389 | gspca_dev->usb_buf[1] = 0x00; | ||
390 | if (mr_write(gspca_dev, 2) < 0) | ||
391 | PDEBUG(D_ERR, "Stream Stop failed"); | ||
392 | } | ||
357 | 393 | ||
358 | PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]); | 394 | static void lcd_stop(struct gspca_dev *gspca_dev) |
395 | { | ||
396 | gspca_dev->usb_buf[0] = 0x19; | ||
397 | gspca_dev->usb_buf[1] = 0x54; | ||
398 | if (mr_write(gspca_dev, 2) < 0) | ||
399 | PDEBUG(D_ERR, "LCD Stop failed"); | ||
400 | } | ||
359 | 401 | ||
360 | return gspca_dev->usb_buf[0]; | 402 | static int isoc_enable(struct gspca_dev *gspca_dev) |
403 | { | ||
404 | gspca_dev->usb_buf[0] = 0x00; | ||
405 | gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */ | ||
406 | return mr_write(gspca_dev, 2); | ||
361 | } | 407 | } |
362 | 408 | ||
363 | /* this function is called at probe time */ | 409 | /* this function is called at probe time */ |
@@ -366,60 +412,172 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
366 | { | 412 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 413 | struct sd *sd = (struct sd *) gspca_dev; |
368 | struct cam *cam; | 414 | struct cam *cam; |
369 | __u8 *data = gspca_dev->usb_buf; | ||
370 | int err_code; | 415 | int err_code; |
371 | 416 | ||
372 | cam = &gspca_dev->cam; | 417 | cam = &gspca_dev->cam; |
373 | cam->cam_mode = vga_mode; | 418 | cam->cam_mode = vga_mode; |
374 | cam->nmodes = ARRAY_SIZE(vga_mode); | 419 | cam->nmodes = ARRAY_SIZE(vga_mode); |
420 | sd->do_lcd_stop = 0; | ||
421 | |||
422 | /* Now, logical layout of the driver must fall sacrifice to the | ||
423 | * realities of the hardware supported. We have to sort out several | ||
424 | * cameras which share the USB ID but are in fact different inside. | ||
425 | * We need to start the initialization process for the cameras in | ||
426 | * order to classify them. Some of the supported cameras require the | ||
427 | * memory pointer to be set to 0 as the very first item of business | ||
428 | * or else they will not stream. So we do that immediately. | ||
429 | */ | ||
430 | err_code = zero_the_pointer(gspca_dev); | ||
431 | if (err_code < 0) | ||
432 | return err_code; | ||
375 | 433 | ||
376 | if (id->idProduct == 0x010e) { | 434 | if (id->idProduct == 0x010e) { |
377 | sd->cam_type = CAM_TYPE_CIF; | 435 | sd->cam_type = CAM_TYPE_CIF; |
378 | cam->nmodes--; | 436 | cam->nmodes--; |
379 | 437 | err_code = stream_start(gspca_dev); | |
380 | data[0] = 0x01; | 438 | if (err_code < 0) |
381 | data[1] = 0x01; | 439 | return err_code; |
382 | err_code = mr_write(gspca_dev, 2); | 440 | err_code = cam_get_response16(gspca_dev, 0x06, 1); |
383 | if (err_code < 0) | 441 | if (err_code < 0) |
384 | return err_code; | 442 | return err_code; |
385 | |||
386 | msleep(200); | ||
387 | data[0] = get_sensor_id(gspca_dev); | ||
388 | /* | 443 | /* |
389 | * Known CIF cameras. If you have another to report, please do | 444 | * The various CIF cameras share the same USB ID but use |
445 | * different init routines and different controls. We need to | ||
446 | * detect which one is connected! | ||
390 | * | 447 | * |
391 | * Name byte just read sd->sensor_type | 448 | * A list of known CIF cameras follows. They all report either |
392 | * reported by | 449 | * 0002 for type 0 or 0003 for type 1. |
393 | * Sakar Spy-shot 0x28 T. Kilgore 0 | 450 | * If you have another to report, please do |
394 | * Innovage 0xf5 (unstable) T. Kilgore 0 | 451 | * |
395 | * Vivitar Mini 0x53 H. De Goede 0 | 452 | * Name sd->sensor_type reported by |
396 | * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0 | 453 | * |
397 | * Vivitar Mini 0x08 T. Kilgore 1 | 454 | * Sakar Spy-shot 0 T. Kilgore |
398 | * Elta-Media 8212dc 0x23 T. Kaiser 1 | 455 | * Innovage 0 T. Kilgore |
399 | * Philips dig. keych. 0x37 T. Kilgore 1 | 456 | * Vivitar Mini 0 H. De Goede |
457 | * Vivitar Mini 0 E. Rodriguez | ||
458 | * Vivitar Mini 1 T. Kilgore | ||
459 | * Elta-Media 8212dc 1 T. Kaiser | ||
460 | * Philips dig. keych. 1 T. Kilgore | ||
400 | */ | 461 | */ |
401 | if ((data[0] & 0x78) == 8 || | 462 | switch (gspca_dev->usb_buf[1]) { |
402 | ((data[0] & 0x2) == 0x2 && data[0] != 0x53)) | 463 | case 2: |
403 | sd->sensor_type = 1; | ||
404 | else | ||
405 | sd->sensor_type = 0; | 464 | sd->sensor_type = 0; |
406 | 465 | break; | |
466 | case 3: | ||
467 | sd->sensor_type = 1; | ||
468 | break; | ||
469 | default: | ||
470 | PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x", | ||
471 | gspca_dev->usb_buf[1]); | ||
472 | return -ENODEV; | ||
473 | } | ||
407 | PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", | 474 | PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", |
408 | sd->sensor_type); | 475 | sd->sensor_type); |
476 | } else { | ||
477 | sd->cam_type = CAM_TYPE_VGA; | ||
409 | 478 | ||
410 | if (force_sensor_type != -1) { | 479 | /* |
411 | sd->sensor_type = !! force_sensor_type; | 480 | * VGA cams also have two different sensor types. Detection |
412 | PDEBUG(D_PROBE, "Forcing sensor type to: %d", | 481 | * requires a two-step process. |
413 | sd->sensor_type); | 482 | * |
483 | * Here is a report on the result of the first test for the | ||
484 | * known MR97310a VGA cameras. If you have another to report, | ||
485 | * please do. | ||
486 | * | ||
487 | * Name byte just read sd->sensor_type | ||
488 | * sd->do_lcd_stop | ||
489 | * Aiptek Pencam VGA+ 0x31 0 1 | ||
490 | * ION digital 0x31 0 1 | ||
491 | * Sakar Digital 77379 0x31 0 1 | ||
492 | * Argus DC-1620 0x30 1 0 | ||
493 | * Argus QuickClix 0x30 1 1 (see note) | ||
494 | * Note that this test fails to distinguish sd->sensor_type | ||
495 | * for the two cameras which have reported 0x30. | ||
496 | * Another test will be run on them. | ||
497 | * But the sd->do_lcd_stop setting is needed, too. | ||
498 | */ | ||
499 | |||
500 | err_code = cam_get_response16(gspca_dev, 0x20, 1); | ||
501 | if (err_code < 0) | ||
502 | return err_code; | ||
503 | sd->sensor_type = gspca_dev->usb_buf[0] & 1; | ||
504 | sd->do_lcd_stop = (~gspca_dev->usb_buf[0]) & 1; | ||
505 | err_code = stream_start(gspca_dev); | ||
506 | if (err_code < 0) | ||
507 | return err_code; | ||
508 | |||
509 | /* | ||
510 | * A second test can now resolve any remaining ambiguity in the | ||
511 | * identification of the camera's sensor type. Specifically, | ||
512 | * it now gives the correct sensor_type for the Argus DC-1620 | ||
513 | * and the Argus QuickClix. | ||
514 | * | ||
515 | * This second test is only run if needed, | ||
516 | * but additional results from testing some other cameras | ||
517 | * are recorded here, too: | ||
518 | * | ||
519 | * Name gspca_dev->usb_buf[] sd->sensor_type | ||
520 | * | ||
521 | * Aiptek Pencam VGA+ 0300 (test not needed) 1 | ||
522 | * ION digital 0350 (test not needed) 1 | ||
523 | * Argus DC-1620 0450 (remains as type 0) 0 | ||
524 | * Argus QuickClix 0420 (corrected to type 1) 1 | ||
525 | * | ||
526 | * This test even seems able to distinguish one VGA cam from | ||
527 | * another which may be useful. However, the CIF type 1 cameras | ||
528 | * do not like it. | ||
529 | */ | ||
530 | |||
531 | if (!sd->sensor_type) { | ||
532 | err_code = cam_get_response16(gspca_dev, 0x07, 1); | ||
533 | if (err_code < 0) | ||
534 | return err_code; | ||
535 | |||
536 | switch (gspca_dev->usb_buf[1]) { | ||
537 | case 0x50: | ||
538 | break; | ||
539 | case 0x20: | ||
540 | sd->sensor_type = 1; | ||
541 | PDEBUG(D_PROBE, "sensor_type corrected to 1"); | ||
542 | break; | ||
543 | default: | ||
544 | PDEBUG(D_ERR, "Unknown VGA Sensor id : %02x", | ||
545 | gspca_dev->usb_buf[1]); | ||
546 | return -ENODEV; | ||
547 | } | ||
414 | } | 548 | } |
549 | PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", | ||
550 | sd->sensor_type); | ||
551 | } | ||
552 | /* Stop streaming as we've started it to probe the sensor type. */ | ||
553 | sd_stopN(gspca_dev); | ||
415 | 554 | ||
555 | if (force_sensor_type != -1) { | ||
556 | sd->sensor_type = !!force_sensor_type; | ||
557 | PDEBUG(D_PROBE, "Forcing sensor type to: %d", | ||
558 | sd->sensor_type); | ||
559 | } | ||
560 | |||
561 | /* Setup controls depending on camera type */ | ||
562 | if (sd->cam_type == CAM_TYPE_CIF) { | ||
563 | /* No brightness for sensor_type 0 */ | ||
416 | if (sd->sensor_type == 0) | 564 | if (sd->sensor_type == 0) |
417 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); | 565 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | |
566 | (1 << ARGUS_QC_BRIGHTNESS_IDX); | ||
567 | else | ||
568 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); | ||
418 | } else { | 569 | } else { |
419 | sd->cam_type = CAM_TYPE_VGA; | 570 | /* All controls need to be disabled if VGA sensor_type is 0 */ |
420 | PDEBUG(D_PROBE, "MR97310A VGA camera detected"); | 571 | if (sd->sensor_type == 0) |
421 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | | 572 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | |
422 | (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); | 573 | (1 << ARGUS_QC_BRIGHTNESS_IDX) | |
574 | (1 << EXPOSURE_IDX) | | ||
575 | (1 << GAIN_IDX); | ||
576 | else if (sd->do_lcd_stop) | ||
577 | /* Argus QuickClix has different brightness limits */ | ||
578 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); | ||
579 | else | ||
580 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); | ||
423 | } | 581 | } |
424 | 582 | ||
425 | sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; | 583 | sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; |
@@ -455,11 +613,6 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
455 | }; | 613 | }; |
456 | 614 | ||
457 | /* Note: Some of the above descriptions guessed from MR97113A driver */ | 615 | /* Note: Some of the above descriptions guessed from MR97113A driver */ |
458 | data[0] = 0x01; | ||
459 | data[1] = 0x01; | ||
460 | err_code = mr_write(gspca_dev, 2); | ||
461 | if (err_code < 0) | ||
462 | return err_code; | ||
463 | 616 | ||
464 | memcpy(data, startup_string, 11); | 617 | memcpy(data, startup_string, 11); |
465 | if (sd->sensor_type) | 618 | if (sd->sensor_type) |
@@ -533,22 +686,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
533 | err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, | 686 | err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, |
534 | ARRAY_SIZE(cif_sensor1_init_data)); | 687 | ARRAY_SIZE(cif_sensor1_init_data)); |
535 | } | 688 | } |
536 | if (err_code < 0) | 689 | return err_code; |
537 | return err_code; | ||
538 | |||
539 | setbrightness(gspca_dev); | ||
540 | setexposure(gspca_dev); | ||
541 | setgain(gspca_dev); | ||
542 | |||
543 | msleep(200); | ||
544 | |||
545 | data[0] = 0x00; | ||
546 | data[1] = 0x4d; /* ISOC transfering enable... */ | ||
547 | err_code = mr_write(gspca_dev, 2); | ||
548 | if (err_code < 0) | ||
549 | return err_code; | ||
550 | |||
551 | return 0; | ||
552 | } | 690 | } |
553 | 691 | ||
554 | static int start_vga_cam(struct gspca_dev *gspca_dev) | 692 | static int start_vga_cam(struct gspca_dev *gspca_dev) |
@@ -558,84 +696,8 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
558 | int err_code; | 696 | int err_code; |
559 | const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, | 697 | const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, |
560 | 0x00, 0x00, 0x00, 0x50, 0xc0}; | 698 | 0x00, 0x00, 0x00, 0x50, 0xc0}; |
561 | |||
562 | /* What some of these mean is explained in start_cif_cam(), above */ | 699 | /* What some of these mean is explained in start_cif_cam(), above */ |
563 | sd->sof_read = 0; | ||
564 | |||
565 | /* | ||
566 | * We have to know which camera we have, because the register writes | ||
567 | * depend upon the camera. This test, run before we actually enter | ||
568 | * the initialization routine, distinguishes most of the cameras, If | ||
569 | * needed, another routine is done later, too. | ||
570 | */ | ||
571 | memset(data, 0, 16); | ||
572 | data[0] = 0x20; | ||
573 | err_code = mr_write(gspca_dev, 1); | ||
574 | if (err_code < 0) | ||
575 | return err_code; | ||
576 | |||
577 | err_code = mr_read(gspca_dev, 16); | ||
578 | if (err_code < 0) | ||
579 | return err_code; | ||
580 | |||
581 | PDEBUG(D_PROBE, "Byte reported is %02x", data[0]); | ||
582 | |||
583 | msleep(200); | ||
584 | /* | ||
585 | * Known VGA cameras. If you have another to report, please do | ||
586 | * | ||
587 | * Name byte just read sd->sensor_type | ||
588 | * sd->do_lcd_stop | ||
589 | * Aiptek Pencam VGA+ 0x31 0 1 | ||
590 | * ION digital 0x31 0 1 | ||
591 | * Argus DC-1620 0x30 1 0 | ||
592 | * Argus QuickClix 0x30 1 1 (not caught here) | ||
593 | */ | ||
594 | sd->sensor_type = data[0] & 1; | ||
595 | sd->do_lcd_stop = (~data[0]) & 1; | ||
596 | |||
597 | |||
598 | |||
599 | /* Streaming setup begins here. */ | ||
600 | |||
601 | |||
602 | data[0] = 0x01; | ||
603 | data[1] = 0x01; | ||
604 | err_code = mr_write(gspca_dev, 2); | ||
605 | if (err_code < 0) | ||
606 | return err_code; | ||
607 | |||
608 | /* | ||
609 | * A second test can now resolve any remaining ambiguity in the | ||
610 | * identification of the camera type, | ||
611 | */ | ||
612 | if (!sd->sensor_type) { | ||
613 | data[0] = get_sensor_id(gspca_dev); | ||
614 | if (data[0] == 0x7f) { | ||
615 | sd->sensor_type = 1; | ||
616 | PDEBUG(D_PROBE, "sensor_type corrected to 1"); | ||
617 | } | ||
618 | msleep(200); | ||
619 | } | ||
620 | |||
621 | if (force_sensor_type != -1) { | ||
622 | sd->sensor_type = !! force_sensor_type; | ||
623 | PDEBUG(D_PROBE, "Forcing sensor type to: %d", | ||
624 | sd->sensor_type); | ||
625 | } | ||
626 | 700 | ||
627 | /* | ||
628 | * Known VGA cameras. | ||
629 | * This test is only run if the previous test returned 0x30, but | ||
630 | * here is the information for all others, too, just for reference. | ||
631 | * | ||
632 | * Name byte just read sd->sensor_type | ||
633 | * | ||
634 | * Aiptek Pencam VGA+ 0xfb (this test not run) 1 | ||
635 | * ION digital 0xbd (this test not run) 1 | ||
636 | * Argus DC-1620 0xe5 (no change) 0 | ||
637 | * Argus QuickClix 0x7f (reclassified) 1 | ||
638 | */ | ||
639 | memcpy(data, startup_string, 11); | 701 | memcpy(data, startup_string, 11); |
640 | if (!sd->sensor_type) { | 702 | if (!sd->sensor_type) { |
641 | data[5] = 0x00; | 703 | data[5] = 0x00; |
@@ -704,14 +766,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
704 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, | 766 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, |
705 | ARRAY_SIZE(vga_sensor1_init_data)); | 767 | ARRAY_SIZE(vga_sensor1_init_data)); |
706 | } | 768 | } |
707 | if (err_code < 0) | ||
708 | return err_code; | ||
709 | |||
710 | msleep(200); | ||
711 | data[0] = 0x00; | ||
712 | data[1] = 0x4d; /* ISOC transfering enable... */ | ||
713 | err_code = mr_write(gspca_dev, 2); | ||
714 | |||
715 | return err_code; | 769 | return err_code; |
716 | } | 770 | } |
717 | 771 | ||
@@ -719,82 +773,101 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
719 | { | 773 | { |
720 | struct sd *sd = (struct sd *) gspca_dev; | 774 | struct sd *sd = (struct sd *) gspca_dev; |
721 | int err_code; | 775 | int err_code; |
722 | struct cam *cam; | ||
723 | 776 | ||
724 | cam = &gspca_dev->cam; | ||
725 | sd->sof_read = 0; | 777 | sd->sof_read = 0; |
726 | /* | 778 | |
727 | * Some of the supported cameras require the memory pointer to be | 779 | /* Some of the VGA cameras require the memory pointer |
728 | * set to 0, or else they will not stream. | 780 | * to be set to 0 again. We have been forced to start the |
729 | */ | 781 | * stream somewhere else to detect the hardware, and closed it, |
730 | zero_the_pointer(gspca_dev); | 782 | * and now since we are restarting the stream we need to do a |
731 | msleep(200); | 783 | * completely fresh and clean start. */ |
784 | err_code = zero_the_pointer(gspca_dev); | ||
785 | if (err_code < 0) | ||
786 | return err_code; | ||
787 | |||
788 | err_code = stream_start(gspca_dev); | ||
789 | if (err_code < 0) | ||
790 | return err_code; | ||
791 | |||
732 | if (sd->cam_type == CAM_TYPE_CIF) { | 792 | if (sd->cam_type == CAM_TYPE_CIF) { |
733 | err_code = start_cif_cam(gspca_dev); | 793 | err_code = start_cif_cam(gspca_dev); |
734 | } else { | 794 | } else { |
735 | err_code = start_vga_cam(gspca_dev); | 795 | err_code = start_vga_cam(gspca_dev); |
736 | } | 796 | } |
737 | return err_code; | 797 | if (err_code < 0) |
798 | return err_code; | ||
799 | |||
800 | setbrightness(gspca_dev); | ||
801 | setexposure(gspca_dev); | ||
802 | setgain(gspca_dev); | ||
803 | |||
804 | return isoc_enable(gspca_dev); | ||
738 | } | 805 | } |
739 | 806 | ||
740 | static void sd_stopN(struct gspca_dev *gspca_dev) | 807 | static void sd_stopN(struct gspca_dev *gspca_dev) |
741 | { | 808 | { |
742 | struct sd *sd = (struct sd *) gspca_dev; | 809 | struct sd *sd = (struct sd *) gspca_dev; |
743 | int result; | ||
744 | |||
745 | gspca_dev->usb_buf[0] = 1; | ||
746 | gspca_dev->usb_buf[1] = 0; | ||
747 | result = mr_write(gspca_dev, 2); | ||
748 | if (result < 0) | ||
749 | PDEBUG(D_ERR, "Camera Stop failed"); | ||
750 | 810 | ||
811 | stream_stop(gspca_dev); | ||
751 | /* Not all the cams need this, but even if not, probably a good idea */ | 812 | /* Not all the cams need this, but even if not, probably a good idea */ |
752 | zero_the_pointer(gspca_dev); | 813 | zero_the_pointer(gspca_dev); |
753 | if (sd->do_lcd_stop) { | 814 | if (sd->do_lcd_stop) |
754 | gspca_dev->usb_buf[0] = 0x19; | 815 | lcd_stop(gspca_dev); |
755 | gspca_dev->usb_buf[1] = 0x54; | ||
756 | result = mr_write(gspca_dev, 2); | ||
757 | if (result < 0) | ||
758 | PDEBUG(D_ERR, "Camera Stop failed"); | ||
759 | } | ||
760 | } | 816 | } |
761 | 817 | ||
762 | static void setbrightness(struct gspca_dev *gspca_dev) | 818 | static void setbrightness(struct gspca_dev *gspca_dev) |
763 | { | 819 | { |
764 | struct sd *sd = (struct sd *) gspca_dev; | 820 | struct sd *sd = (struct sd *) gspca_dev; |
765 | u8 val; | 821 | u8 val; |
766 | 822 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ | |
767 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) | 823 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ |
824 | const u8 quick_clix_table[] = | ||
825 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ | ||
826 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; | ||
827 | /* | ||
828 | * This control is disabled for CIF type 1 and VGA type 0 cameras. | ||
829 | * It does not quite act linearly for the Argus QuickClix camera, | ||
830 | * but it does control brightness. The values are 0 - 15 only, and | ||
831 | * the table above makes them act consecutively. | ||
832 | */ | ||
833 | if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) && | ||
834 | (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX))) | ||
768 | return; | 835 | return; |
769 | 836 | ||
837 | if (sd->cam_type == CAM_TYPE_VGA) { | ||
838 | sign_reg += 4; | ||
839 | value_reg += 4; | ||
840 | } | ||
841 | |||
770 | /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ | 842 | /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ |
771 | if (sd->brightness > 0) { | 843 | if (sd->brightness > 0) { |
772 | sensor_write1(gspca_dev, 7, 0x00); | 844 | sensor_write1(gspca_dev, sign_reg, 0x00); |
773 | val = sd->brightness; | 845 | val = sd->brightness; |
774 | } else { | 846 | } else { |
775 | sensor_write1(gspca_dev, 7, 0x01); | 847 | sensor_write1(gspca_dev, sign_reg, 0x01); |
776 | val = 257 - sd->brightness; | 848 | val = (257 - sd->brightness); |
777 | } | 849 | } |
778 | sensor_write1(gspca_dev, 8, val); | 850 | /* Use lookup table for funky Argus QuickClix brightness */ |
851 | if (sd->do_lcd_stop) | ||
852 | val = quick_clix_table[val]; | ||
853 | |||
854 | sensor_write1(gspca_dev, value_reg, val); | ||
779 | } | 855 | } |
780 | 856 | ||
781 | static void setexposure(struct gspca_dev *gspca_dev) | 857 | static void setexposure(struct gspca_dev *gspca_dev) |
782 | { | 858 | { |
783 | struct sd *sd = (struct sd *) gspca_dev; | 859 | struct sd *sd = (struct sd *) gspca_dev; |
784 | u8 val; | 860 | int exposure; |
785 | 861 | ||
786 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | 862 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) |
787 | return; | 863 | return; |
788 | 864 | ||
789 | if (sd->sensor_type) { | 865 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { |
790 | val = sd->exposure >> 4; | 866 | /* This cam does not like very low exposure settings */ |
791 | sensor_write1(gspca_dev, 3, val); | 867 | exposure = (sd->exposure < 300) ? 300 : sd->exposure; |
792 | val = sd->exposure & 0xf; | 868 | sensor_write1(gspca_dev, 3, exposure >> 4); |
793 | sensor_write1(gspca_dev, 4, val); | 869 | sensor_write1(gspca_dev, 4, exposure & 0x0f); |
794 | } else { | 870 | } else { |
795 | u8 clockdiv; | ||
796 | int exposure; | ||
797 | |||
798 | /* We have both a clock divider and an exposure register. | 871 | /* We have both a clock divider and an exposure register. |
799 | We first calculate the clock divider, as that determines | 872 | We first calculate the clock divider, as that determines |
800 | the maximum exposure and then we calculayte the exposure | 873 | the maximum exposure and then we calculayte the exposure |
@@ -802,7 +875,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
802 | 875 | ||
803 | Note our 0 - 4095 exposure is mapped to 0 - 511 | 876 | Note our 0 - 4095 exposure is mapped to 0 - 511 |
804 | milliseconds exposure time */ | 877 | milliseconds exposure time */ |
805 | clockdiv = (60 * sd->exposure + 7999) / 8000; | 878 | u8 clockdiv = (60 * sd->exposure + 7999) / 8000; |
806 | 879 | ||
807 | /* Limit framerate to not exceed usb bandwidth */ | 880 | /* Limit framerate to not exceed usb bandwidth */ |
808 | if (clockdiv < 3 && gspca_dev->width >= 320) | 881 | if (clockdiv < 3 && gspca_dev->width >= 320) |
@@ -810,6 +883,9 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
810 | else if (clockdiv < 2) | 883 | else if (clockdiv < 2) |
811 | clockdiv = 2; | 884 | clockdiv = 2; |
812 | 885 | ||
886 | if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4) | ||
887 | clockdiv = 4; | ||
888 | |||
813 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> | 889 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> |
814 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ | 890 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ |
815 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); | 891 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); |
@@ -832,7 +908,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
832 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) | 908 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) |
833 | return; | 909 | return; |
834 | 910 | ||
835 | if (sd->sensor_type) { | 911 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { |
836 | sensor_write1(gspca_dev, 0x0e, sd->gain); | 912 | sensor_write1(gspca_dev, 0x0e, sd->gain); |
837 | } else { | 913 | } else { |
838 | sensor_write1(gspca_dev, 0x10, sd->gain); | 914 | sensor_write1(gspca_dev, 0x10, sd->gain); |