diff options
Diffstat (limited to 'drivers/media/video/gspca/mr97310a.c')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 602 |
1 files changed, 368 insertions, 234 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f8328b9efae5..126d968dd9e0 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -1,23 +1,30 @@ | |||
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> and | ||
22 | * Edmond Rodriguez <erodrig_97@yahoo.com> and | ||
23 | * Aurelien Jacobs <aurel@gnuage.org> | ||
12 | * | 24 | * |
13 | * The MR97311A support in gspca/mars.c has been helpful in understanding some | 25 | * The MR97311A support in gspca/mars.c has been helpful in understanding some |
14 | * of the registers in these cameras. | 26 | * of the registers in these cameras. |
15 | * | 27 | * |
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 | 28 | * 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 | 29 | * 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 | 30 | * the Free Software Foundation; either version 2 of the License, or |
@@ -40,11 +47,9 @@ | |||
40 | #define CAM_TYPE_CIF 0 | 47 | #define CAM_TYPE_CIF 0 |
41 | #define CAM_TYPE_VGA 1 | 48 | #define CAM_TYPE_VGA 1 |
42 | 49 | ||
43 | #define MR97310A_BRIGHTNESS_MIN -254 | ||
44 | #define MR97310A_BRIGHTNESS_MAX 255 | ||
45 | #define MR97310A_BRIGHTNESS_DEFAULT 0 | 50 | #define MR97310A_BRIGHTNESS_DEFAULT 0 |
46 | 51 | ||
47 | #define MR97310A_EXPOSURE_MIN 300 | 52 | #define MR97310A_EXPOSURE_MIN 0 |
48 | #define MR97310A_EXPOSURE_MAX 4095 | 53 | #define MR97310A_EXPOSURE_MAX 4095 |
49 | #define MR97310A_EXPOSURE_DEFAULT 1000 | 54 | #define MR97310A_EXPOSURE_DEFAULT 1000 |
50 | 55 | ||
@@ -52,6 +57,10 @@ | |||
52 | #define MR97310A_GAIN_MAX 31 | 57 | #define MR97310A_GAIN_MAX 31 |
53 | #define MR97310A_GAIN_DEFAULT 25 | 58 | #define MR97310A_GAIN_DEFAULT 25 |
54 | 59 | ||
60 | #define MR97310A_MIN_CLOCKDIV_MIN 3 | ||
61 | #define MR97310A_MIN_CLOCKDIV_MAX 8 | ||
62 | #define MR97310A_MIN_CLOCKDIV_DEFAULT 3 | ||
63 | |||
55 | MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," | 64 | MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," |
56 | "Theodore Kilgore <kilgota@auburn.edu>"); | 65 | "Theodore Kilgore <kilgota@auburn.edu>"); |
57 | MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); | 66 | MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); |
@@ -69,10 +78,12 @@ struct sd { | |||
69 | u8 cam_type; /* 0 is CIF and 1 is VGA */ | 78 | u8 cam_type; /* 0 is CIF and 1 is VGA */ |
70 | u8 sensor_type; /* We use 0 and 1 here, too. */ | 79 | u8 sensor_type; /* We use 0 and 1 here, too. */ |
71 | u8 do_lcd_stop; | 80 | u8 do_lcd_stop; |
81 | u8 adj_colors; | ||
72 | 82 | ||
73 | int brightness; | 83 | int brightness; |
74 | u16 exposure; | 84 | u16 exposure; |
75 | u8 gain; | 85 | u8 gain; |
86 | u8 min_clockdiv; | ||
76 | }; | 87 | }; |
77 | 88 | ||
78 | struct sensor_w_data { | 89 | struct sensor_w_data { |
@@ -82,26 +93,31 @@ struct sensor_w_data { | |||
82 | int len; | 93 | int len; |
83 | }; | 94 | }; |
84 | 95 | ||
96 | static void sd_stopN(struct gspca_dev *gspca_dev); | ||
85 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 97 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); |
86 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 98 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); |
87 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | 99 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); |
88 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | 100 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); |
89 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | 101 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); |
90 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | 102 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); |
103 | static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); | ||
104 | static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val); | ||
91 | static void setbrightness(struct gspca_dev *gspca_dev); | 105 | static void setbrightness(struct gspca_dev *gspca_dev); |
92 | static void setexposure(struct gspca_dev *gspca_dev); | 106 | static void setexposure(struct gspca_dev *gspca_dev); |
93 | static void setgain(struct gspca_dev *gspca_dev); | 107 | static void setgain(struct gspca_dev *gspca_dev); |
94 | 108 | ||
95 | /* V4L2 controls supported by the driver */ | 109 | /* V4L2 controls supported by the driver */ |
96 | static struct ctrl sd_ctrls[] = { | 110 | static struct ctrl sd_ctrls[] = { |
111 | /* Separate brightness control description for Argus QuickClix as it has | ||
112 | different limits from the other mr97310a cameras */ | ||
97 | { | 113 | { |
98 | #define BRIGHTNESS_IDX 0 | 114 | #define NORM_BRIGHTNESS_IDX 0 |
99 | { | 115 | { |
100 | .id = V4L2_CID_BRIGHTNESS, | 116 | .id = V4L2_CID_BRIGHTNESS, |
101 | .type = V4L2_CTRL_TYPE_INTEGER, | 117 | .type = V4L2_CTRL_TYPE_INTEGER, |
102 | .name = "Brightness", | 118 | .name = "Brightness", |
103 | .minimum = MR97310A_BRIGHTNESS_MIN, | 119 | .minimum = -254, |
104 | .maximum = MR97310A_BRIGHTNESS_MAX, | 120 | .maximum = 255, |
105 | .step = 1, | 121 | .step = 1, |
106 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | 122 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, |
107 | .flags = 0, | 123 | .flags = 0, |
@@ -110,7 +126,22 @@ static struct ctrl sd_ctrls[] = { | |||
110 | .get = sd_getbrightness, | 126 | .get = sd_getbrightness, |
111 | }, | 127 | }, |
112 | { | 128 | { |
113 | #define EXPOSURE_IDX 1 | 129 | #define ARGUS_QC_BRIGHTNESS_IDX 1 |
130 | { | ||
131 | .id = V4L2_CID_BRIGHTNESS, | ||
132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
133 | .name = "Brightness", | ||
134 | .minimum = 0, | ||
135 | .maximum = 15, | ||
136 | .step = 1, | ||
137 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | ||
138 | .flags = 0, | ||
139 | }, | ||
140 | .set = sd_setbrightness, | ||
141 | .get = sd_getbrightness, | ||
142 | }, | ||
143 | { | ||
144 | #define EXPOSURE_IDX 2 | ||
114 | { | 145 | { |
115 | .id = V4L2_CID_EXPOSURE, | 146 | .id = V4L2_CID_EXPOSURE, |
116 | .type = V4L2_CTRL_TYPE_INTEGER, | 147 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -125,7 +156,7 @@ static struct ctrl sd_ctrls[] = { | |||
125 | .get = sd_getexposure, | 156 | .get = sd_getexposure, |
126 | }, | 157 | }, |
127 | { | 158 | { |
128 | #define GAIN_IDX 2 | 159 | #define GAIN_IDX 3 |
129 | { | 160 | { |
130 | .id = V4L2_CID_GAIN, | 161 | .id = V4L2_CID_GAIN, |
131 | .type = V4L2_CTRL_TYPE_INTEGER, | 162 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -139,6 +170,21 @@ static struct ctrl sd_ctrls[] = { | |||
139 | .set = sd_setgain, | 170 | .set = sd_setgain, |
140 | .get = sd_getgain, | 171 | .get = sd_getgain, |
141 | }, | 172 | }, |
173 | { | ||
174 | #define MIN_CLOCKDIV_IDX 4 | ||
175 | { | ||
176 | .id = V4L2_CID_PRIVATE_BASE, | ||
177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
178 | .name = "Minimum Clock Divider", | ||
179 | .minimum = MR97310A_MIN_CLOCKDIV_MIN, | ||
180 | .maximum = MR97310A_MIN_CLOCKDIV_MAX, | ||
181 | .step = 1, | ||
182 | .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT, | ||
183 | .flags = 0, | ||
184 | }, | ||
185 | .set = sd_setmin_clockdiv, | ||
186 | .get = sd_getmin_clockdiv, | ||
187 | }, | ||
142 | }; | 188 | }; |
143 | 189 | ||
144 | static const struct v4l2_pix_format vga_mode[] = { | 190 | static const struct v4l2_pix_format vga_mode[] = { |
@@ -230,12 +276,17 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | |||
230 | int rc; | 276 | int rc; |
231 | 277 | ||
232 | buf = data; | 278 | buf = data; |
233 | rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); | 279 | if (sd->cam_type == CAM_TYPE_CIF) { |
280 | rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); | ||
281 | confirm_reg = sd->sensor_type ? 0x13 : 0x11; | ||
282 | } else { | ||
283 | rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1); | ||
284 | confirm_reg = 0x11; | ||
285 | } | ||
234 | if (rc < 0) | 286 | if (rc < 0) |
235 | return rc; | 287 | return rc; |
236 | 288 | ||
237 | buf = 0x01; | 289 | buf = 0x01; |
238 | confirm_reg = sd->sensor_type ? 0x13 : 0x11; | ||
239 | rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); | 290 | rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); |
240 | if (rc < 0) | 291 | if (rc < 0) |
241 | return rc; | 292 | return rc; |
@@ -243,18 +294,26 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | |||
243 | return 0; | 294 | return 0; |
244 | } | 295 | } |
245 | 296 | ||
246 | static int cam_get_response16(struct gspca_dev *gspca_dev) | 297 | static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose) |
247 | { | 298 | { |
248 | __u8 *data = gspca_dev->usb_buf; | ||
249 | int err_code; | 299 | int err_code; |
250 | 300 | ||
251 | data[0] = 0x21; | 301 | gspca_dev->usb_buf[0] = reg; |
252 | err_code = mr_write(gspca_dev, 1); | 302 | err_code = mr_write(gspca_dev, 1); |
253 | if (err_code < 0) | 303 | if (err_code < 0) |
254 | return err_code; | 304 | return err_code; |
255 | 305 | ||
256 | err_code = mr_read(gspca_dev, 16); | 306 | err_code = mr_read(gspca_dev, 16); |
257 | return err_code; | 307 | if (err_code < 0) |
308 | return err_code; | ||
309 | |||
310 | if (verbose) | ||
311 | PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg, | ||
312 | gspca_dev->usb_buf[0], | ||
313 | gspca_dev->usb_buf[1], | ||
314 | gspca_dev->usb_buf[2]); | ||
315 | |||
316 | return 0; | ||
258 | } | 317 | } |
259 | 318 | ||
260 | static int zero_the_pointer(struct gspca_dev *gspca_dev) | 319 | static int zero_the_pointer(struct gspca_dev *gspca_dev) |
@@ -264,7 +323,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
264 | u8 status = 0; | 323 | u8 status = 0; |
265 | int tries = 0; | 324 | int tries = 0; |
266 | 325 | ||
267 | err_code = cam_get_response16(gspca_dev); | 326 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
268 | if (err_code < 0) | 327 | if (err_code < 0) |
269 | return err_code; | 328 | return err_code; |
270 | 329 | ||
@@ -275,7 +334,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
275 | if (err_code < 0) | 334 | if (err_code < 0) |
276 | return err_code; | 335 | return err_code; |
277 | 336 | ||
278 | err_code = cam_get_response16(gspca_dev); | 337 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
279 | if (err_code < 0) | 338 | if (err_code < 0) |
280 | return err_code; | 339 | return err_code; |
281 | 340 | ||
@@ -285,7 +344,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
285 | if (err_code < 0) | 344 | if (err_code < 0) |
286 | return err_code; | 345 | return err_code; |
287 | 346 | ||
288 | err_code = cam_get_response16(gspca_dev); | 347 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
289 | if (err_code < 0) | 348 | if (err_code < 0) |
290 | return err_code; | 349 | return err_code; |
291 | 350 | ||
@@ -295,7 +354,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
295 | if (err_code < 0) | 354 | if (err_code < 0) |
296 | return err_code; | 355 | return err_code; |
297 | 356 | ||
298 | err_code = cam_get_response16(gspca_dev); | 357 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
299 | if (err_code < 0) | 358 | if (err_code < 0) |
300 | return err_code; | 359 | return err_code; |
301 | 360 | ||
@@ -306,7 +365,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
306 | return err_code; | 365 | return err_code; |
307 | 366 | ||
308 | while (status != 0x0a && tries < 256) { | 367 | while (status != 0x0a && tries < 256) { |
309 | err_code = cam_get_response16(gspca_dev); | 368 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
310 | status = data[0]; | 369 | status = data[0]; |
311 | tries++; | 370 | tries++; |
312 | if (err_code < 0) | 371 | if (err_code < 0) |
@@ -323,7 +382,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
323 | if (err_code < 0) | 382 | if (err_code < 0) |
324 | return err_code; | 383 | return err_code; |
325 | 384 | ||
326 | err_code = cam_get_response16(gspca_dev); | 385 | err_code = cam_get_response16(gspca_dev, 0x21, 0); |
327 | status = data[0]; | 386 | status = data[0]; |
328 | tries++; | 387 | tries++; |
329 | if (err_code < 0) | 388 | if (err_code < 0) |
@@ -342,89 +401,202 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) | |||
342 | return 0; | 401 | return 0; |
343 | } | 402 | } |
344 | 403 | ||
345 | static u8 get_sensor_id(struct gspca_dev *gspca_dev) | 404 | static int stream_start(struct gspca_dev *gspca_dev) |
346 | { | 405 | { |
347 | int err_code; | 406 | gspca_dev->usb_buf[0] = 0x01; |
348 | 407 | gspca_dev->usb_buf[1] = 0x01; | |
349 | gspca_dev->usb_buf[0] = 0x1e; | 408 | return mr_write(gspca_dev, 2); |
350 | err_code = mr_write(gspca_dev, 1); | 409 | } |
351 | if (err_code < 0) | ||
352 | return err_code; | ||
353 | 410 | ||
354 | err_code = mr_read(gspca_dev, 16); | 411 | static void stream_stop(struct gspca_dev *gspca_dev) |
355 | if (err_code < 0) | 412 | { |
356 | return err_code; | 413 | gspca_dev->usb_buf[0] = 0x01; |
414 | gspca_dev->usb_buf[1] = 0x00; | ||
415 | if (mr_write(gspca_dev, 2) < 0) | ||
416 | PDEBUG(D_ERR, "Stream Stop failed"); | ||
417 | } | ||
357 | 418 | ||
358 | PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]); | 419 | static void lcd_stop(struct gspca_dev *gspca_dev) |
420 | { | ||
421 | gspca_dev->usb_buf[0] = 0x19; | ||
422 | gspca_dev->usb_buf[1] = 0x54; | ||
423 | if (mr_write(gspca_dev, 2) < 0) | ||
424 | PDEBUG(D_ERR, "LCD Stop failed"); | ||
425 | } | ||
359 | 426 | ||
360 | return gspca_dev->usb_buf[0]; | 427 | static int isoc_enable(struct gspca_dev *gspca_dev) |
428 | { | ||
429 | gspca_dev->usb_buf[0] = 0x00; | ||
430 | gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */ | ||
431 | return mr_write(gspca_dev, 2); | ||
361 | } | 432 | } |
362 | 433 | ||
363 | /* this function is called at probe time */ | 434 | /* This function is called at probe time */ |
364 | static int sd_config(struct gspca_dev *gspca_dev, | 435 | static int sd_config(struct gspca_dev *gspca_dev, |
365 | const struct usb_device_id *id) | 436 | const struct usb_device_id *id) |
366 | { | 437 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 438 | struct sd *sd = (struct sd *) gspca_dev; |
368 | struct cam *cam; | 439 | struct cam *cam; |
369 | __u8 *data = gspca_dev->usb_buf; | ||
370 | int err_code; | 440 | int err_code; |
371 | 441 | ||
372 | cam = &gspca_dev->cam; | 442 | cam = &gspca_dev->cam; |
373 | cam->cam_mode = vga_mode; | 443 | cam->cam_mode = vga_mode; |
374 | cam->nmodes = ARRAY_SIZE(vga_mode); | 444 | cam->nmodes = ARRAY_SIZE(vga_mode); |
445 | sd->do_lcd_stop = 0; | ||
446 | |||
447 | /* Several of the supported CIF cameras share the same USB ID but | ||
448 | * require different initializations and different control settings. | ||
449 | * The same is true of the VGA cameras. Therefore, we are forced | ||
450 | * to start the initialization process in order to determine which | ||
451 | * camera is present. Some of the supported cameras require the | ||
452 | * memory pointer to be set to 0 as the very first item of business | ||
453 | * or else they will not stream. So we do that immediately. | ||
454 | */ | ||
455 | err_code = zero_the_pointer(gspca_dev); | ||
456 | if (err_code < 0) | ||
457 | return err_code; | ||
458 | |||
459 | err_code = stream_start(gspca_dev); | ||
460 | if (err_code < 0) | ||
461 | return err_code; | ||
375 | 462 | ||
376 | if (id->idProduct == 0x010e) { | 463 | if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { |
377 | sd->cam_type = CAM_TYPE_CIF; | 464 | sd->cam_type = CAM_TYPE_CIF; |
378 | cam->nmodes--; | 465 | cam->nmodes--; |
379 | 466 | err_code = cam_get_response16(gspca_dev, 0x06, 1); | |
380 | data[0] = 0x01; | ||
381 | data[1] = 0x01; | ||
382 | err_code = mr_write(gspca_dev, 2); | ||
383 | if (err_code < 0) | 467 | if (err_code < 0) |
384 | return err_code; | 468 | return err_code; |
385 | |||
386 | msleep(200); | ||
387 | data[0] = get_sensor_id(gspca_dev); | ||
388 | /* | 469 | /* |
389 | * Known CIF cameras. If you have another to report, please do | 470 | * All but one of the known CIF cameras share the same USB ID, |
471 | * but two different init routines are in use, and the control | ||
472 | * settings are different, too. We need to detect which camera | ||
473 | * of the two known varieties is connected! | ||
390 | * | 474 | * |
391 | * Name byte just read sd->sensor_type | 475 | * A list of known CIF cameras follows. They all report either |
392 | * reported by | 476 | * 0002 for type 0 or 0003 for type 1. |
393 | * Sakar Spy-shot 0x28 T. Kilgore 0 | 477 | * If you have another to report, please do |
394 | * Innovage 0xf5 (unstable) T. Kilgore 0 | 478 | * |
395 | * Vivitar Mini 0x53 H. De Goede 0 | 479 | * Name sd->sensor_type reported by |
396 | * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0 | 480 | * |
397 | * Vivitar Mini 0x08 T. Kilgore 1 | 481 | * Sakar Spy-shot 0 T. Kilgore |
398 | * Elta-Media 8212dc 0x23 T. Kaiser 1 | 482 | * Innovage 0 T. Kilgore |
399 | * Philips dig. keych. 0x37 T. Kilgore 1 | 483 | * Vivitar Mini 0 H. De Goede |
484 | * Vivitar Mini 0 E. Rodriguez | ||
485 | * Vivitar Mini 1 T. Kilgore | ||
486 | * Elta-Media 8212dc 1 T. Kaiser | ||
487 | * Philips dig. keych. 1 T. Kilgore | ||
488 | * Trust Spyc@m 100 1 A. Jacobs | ||
400 | */ | 489 | */ |
401 | if ((data[0] & 0x78) == 8 || | 490 | switch (gspca_dev->usb_buf[1]) { |
402 | ((data[0] & 0x2) == 0x2 && data[0] != 0x53)) | 491 | case 2: |
403 | sd->sensor_type = 1; | ||
404 | else | ||
405 | sd->sensor_type = 0; | 492 | sd->sensor_type = 0; |
406 | 493 | break; | |
494 | case 3: | ||
495 | sd->sensor_type = 1; | ||
496 | break; | ||
497 | default: | ||
498 | PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x", | ||
499 | gspca_dev->usb_buf[1]); | ||
500 | return -ENODEV; | ||
501 | } | ||
407 | PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", | 502 | PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", |
408 | sd->sensor_type); | 503 | sd->sensor_type); |
504 | } else { | ||
505 | sd->cam_type = CAM_TYPE_VGA; | ||
409 | 506 | ||
410 | if (force_sensor_type != -1) { | 507 | err_code = cam_get_response16(gspca_dev, 0x07, 1); |
411 | sd->sensor_type = !! force_sensor_type; | 508 | if (err_code < 0) |
412 | PDEBUG(D_PROBE, "Forcing sensor type to: %d", | 509 | return err_code; |
413 | sd->sensor_type); | 510 | |
511 | /* | ||
512 | * Here is a table of the responses to the previous command | ||
513 | * from the known MR97310A VGA cameras. | ||
514 | * | ||
515 | * Name gspca_dev->usb_buf[] sd->sensor_type | ||
516 | * sd->do_lcd_stop | ||
517 | * Aiptek Pencam VGA+ 0300 0 1 | ||
518 | * ION digital 0350 0 1 | ||
519 | * Argus DC-1620 0450 1 0 | ||
520 | * Argus QuickClix 0420 1 1 | ||
521 | * | ||
522 | * Based upon these results, we assume default settings | ||
523 | * and then correct as necessary, as follows. | ||
524 | * | ||
525 | */ | ||
526 | |||
527 | sd->sensor_type = 1; | ||
528 | sd->do_lcd_stop = 0; | ||
529 | sd->adj_colors = 0; | ||
530 | if ((gspca_dev->usb_buf[0] != 0x03) && | ||
531 | (gspca_dev->usb_buf[0] != 0x04)) { | ||
532 | PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", | ||
533 | gspca_dev->usb_buf[1]); | ||
534 | PDEBUG(D_ERR, "Defaults assumed, may not work"); | ||
535 | PDEBUG(D_ERR, "Please report this"); | ||
536 | } | ||
537 | /* Sakar Digital color needs to be adjusted. */ | ||
538 | if ((gspca_dev->usb_buf[0] == 0x03) && | ||
539 | (gspca_dev->usb_buf[1] == 0x50)) | ||
540 | sd->adj_colors = 1; | ||
541 | if (gspca_dev->usb_buf[0] == 0x04) { | ||
542 | sd->do_lcd_stop = 1; | ||
543 | switch (gspca_dev->usb_buf[1]) { | ||
544 | case 0x50: | ||
545 | sd->sensor_type = 0; | ||
546 | PDEBUG(D_PROBE, "sensor_type corrected to 0"); | ||
547 | break; | ||
548 | case 0x20: | ||
549 | /* Nothing to do here. */ | ||
550 | break; | ||
551 | default: | ||
552 | PDEBUG(D_ERR, | ||
553 | "Unknown VGA Sensor id Byte 1: %02x", | ||
554 | gspca_dev->usb_buf[1]); | ||
555 | PDEBUG(D_ERR, | ||
556 | "Defaults assumed, may not work"); | ||
557 | PDEBUG(D_ERR, "Please report this"); | ||
558 | } | ||
414 | } | 559 | } |
560 | PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", | ||
561 | sd->sensor_type); | ||
562 | } | ||
563 | /* Stop streaming as we've started it to probe the sensor type. */ | ||
564 | sd_stopN(gspca_dev); | ||
565 | |||
566 | if (force_sensor_type != -1) { | ||
567 | sd->sensor_type = !!force_sensor_type; | ||
568 | PDEBUG(D_PROBE, "Forcing sensor type to: %d", | ||
569 | sd->sensor_type); | ||
570 | } | ||
415 | 571 | ||
572 | /* Setup controls depending on camera type */ | ||
573 | if (sd->cam_type == CAM_TYPE_CIF) { | ||
574 | /* No brightness for sensor_type 0 */ | ||
416 | if (sd->sensor_type == 0) | 575 | if (sd->sensor_type == 0) |
417 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); | 576 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | |
577 | (1 << ARGUS_QC_BRIGHTNESS_IDX); | ||
578 | else | ||
579 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
580 | (1 << MIN_CLOCKDIV_IDX); | ||
418 | } else { | 581 | } else { |
419 | sd->cam_type = CAM_TYPE_VGA; | 582 | /* All controls need to be disabled if VGA sensor_type is 0 */ |
420 | PDEBUG(D_PROBE, "MR97310A VGA camera detected"); | 583 | if (sd->sensor_type == 0) |
421 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | | 584 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | |
422 | (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); | 585 | (1 << ARGUS_QC_BRIGHTNESS_IDX) | |
586 | (1 << EXPOSURE_IDX) | | ||
587 | (1 << GAIN_IDX) | | ||
588 | (1 << MIN_CLOCKDIV_IDX); | ||
589 | else if (sd->do_lcd_stop) | ||
590 | /* Argus QuickClix has different brightness limits */ | ||
591 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); | ||
592 | else | ||
593 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); | ||
423 | } | 594 | } |
424 | 595 | ||
425 | sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; | 596 | sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; |
426 | sd->exposure = MR97310A_EXPOSURE_DEFAULT; | 597 | sd->exposure = MR97310A_EXPOSURE_DEFAULT; |
427 | sd->gain = MR97310A_GAIN_DEFAULT; | 598 | sd->gain = MR97310A_GAIN_DEFAULT; |
599 | sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; | ||
428 | 600 | ||
429 | return 0; | 601 | return 0; |
430 | } | 602 | } |
@@ -455,11 +627,6 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
455 | }; | 627 | }; |
456 | 628 | ||
457 | /* Note: Some of the above descriptions guessed from MR97113A driver */ | 629 | /* 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 | 630 | ||
464 | memcpy(data, startup_string, 11); | 631 | memcpy(data, startup_string, 11); |
465 | if (sd->sensor_type) | 632 | if (sd->sensor_type) |
@@ -533,22 +700,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
533 | err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, | 700 | err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, |
534 | ARRAY_SIZE(cif_sensor1_init_data)); | 701 | ARRAY_SIZE(cif_sensor1_init_data)); |
535 | } | 702 | } |
536 | if (err_code < 0) | 703 | 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 | } | 704 | } |
553 | 705 | ||
554 | static int start_vga_cam(struct gspca_dev *gspca_dev) | 706 | static int start_vga_cam(struct gspca_dev *gspca_dev) |
@@ -558,84 +710,8 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
558 | int err_code; | 710 | int err_code; |
559 | const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, | 711 | const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, |
560 | 0x00, 0x00, 0x00, 0x50, 0xc0}; | 712 | 0x00, 0x00, 0x00, 0x50, 0xc0}; |
561 | |||
562 | /* What some of these mean is explained in start_cif_cam(), above */ | 713 | /* 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 | 714 | ||
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 | |||
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); | 715 | memcpy(data, startup_string, 11); |
640 | if (!sd->sensor_type) { | 716 | if (!sd->sensor_type) { |
641 | data[5] = 0x00; | 717 | data[5] = 0x00; |
@@ -689,29 +765,44 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
689 | err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, | 765 | err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, |
690 | ARRAY_SIZE(vga_sensor0_init_data)); | 766 | ARRAY_SIZE(vga_sensor0_init_data)); |
691 | } else { /* sd->sensor_type = 1 */ | 767 | } else { /* sd->sensor_type = 1 */ |
692 | const struct sensor_w_data vga_sensor1_init_data[] = { | 768 | const struct sensor_w_data color_adj[] = { |
693 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, | 769 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, |
694 | 0x07, 0x00, 0x01}, 8}, | 770 | /* adjusted blue, green, red gain correct |
771 | too much blue from the Sakar Digital */ | ||
772 | 0x05, 0x01, 0x04}, 8} | ||
773 | }; | ||
774 | |||
775 | const struct sensor_w_data color_no_adj[] = { | ||
776 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, | ||
777 | /* default blue, green, red gain settings */ | ||
778 | 0x07, 0x00, 0x01}, 8} | ||
779 | }; | ||
780 | |||
781 | const struct sensor_w_data vga_sensor1_init_data[] = { | ||
695 | {0x11, 0x04, {0x01}, 1}, | 782 | {0x11, 0x04, {0x01}, 1}, |
696 | /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */ | 783 | {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, |
697 | {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, | 784 | /* These settings may be better for some cameras */ |
785 | /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */ | ||
698 | 0x00, 0x0a}, 7}, | 786 | 0x00, 0x0a}, 7}, |
699 | {0x11, 0x04, {0x01}, 1}, | 787 | {0x11, 0x04, {0x01}, 1}, |
700 | {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, | 788 | {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, |
701 | {0x11, 0x04, {0x01}, 1}, | 789 | {0x11, 0x04, {0x01}, 1}, |
702 | {0, 0, {0}, 0} | 790 | {0, 0, {0}, 0} |
703 | }; | 791 | }; |
792 | |||
793 | if (sd->adj_colors) | ||
794 | err_code = sensor_write_regs(gspca_dev, color_adj, | ||
795 | ARRAY_SIZE(color_adj)); | ||
796 | else | ||
797 | err_code = sensor_write_regs(gspca_dev, color_no_adj, | ||
798 | ARRAY_SIZE(color_no_adj)); | ||
799 | |||
800 | if (err_code < 0) | ||
801 | return err_code; | ||
802 | |||
704 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, | 803 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, |
705 | ARRAY_SIZE(vga_sensor1_init_data)); | 804 | ARRAY_SIZE(vga_sensor1_init_data)); |
706 | } | 805 | } |
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; | 806 | return err_code; |
716 | } | 807 | } |
717 | 808 | ||
@@ -719,97 +810,120 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
719 | { | 810 | { |
720 | struct sd *sd = (struct sd *) gspca_dev; | 811 | struct sd *sd = (struct sd *) gspca_dev; |
721 | int err_code; | 812 | int err_code; |
722 | struct cam *cam; | ||
723 | 813 | ||
724 | cam = &gspca_dev->cam; | ||
725 | sd->sof_read = 0; | 814 | sd->sof_read = 0; |
726 | /* | 815 | |
727 | * Some of the supported cameras require the memory pointer to be | 816 | /* Some of the VGA cameras require the memory pointer |
728 | * set to 0, or else they will not stream. | 817 | * to be set to 0 again. We have been forced to start the |
729 | */ | 818 | * stream in sd_config() to detect the hardware, and closed it. |
730 | zero_the_pointer(gspca_dev); | 819 | * Thus, we need here to do a completely fresh and clean start. */ |
731 | msleep(200); | 820 | err_code = zero_the_pointer(gspca_dev); |
821 | if (err_code < 0) | ||
822 | return err_code; | ||
823 | |||
824 | err_code = stream_start(gspca_dev); | ||
825 | if (err_code < 0) | ||
826 | return err_code; | ||
827 | |||
732 | if (sd->cam_type == CAM_TYPE_CIF) { | 828 | if (sd->cam_type == CAM_TYPE_CIF) { |
733 | err_code = start_cif_cam(gspca_dev); | 829 | err_code = start_cif_cam(gspca_dev); |
734 | } else { | 830 | } else { |
735 | err_code = start_vga_cam(gspca_dev); | 831 | err_code = start_vga_cam(gspca_dev); |
736 | } | 832 | } |
737 | return err_code; | 833 | if (err_code < 0) |
834 | return err_code; | ||
835 | |||
836 | setbrightness(gspca_dev); | ||
837 | setexposure(gspca_dev); | ||
838 | setgain(gspca_dev); | ||
839 | |||
840 | return isoc_enable(gspca_dev); | ||
738 | } | 841 | } |
739 | 842 | ||
740 | static void sd_stopN(struct gspca_dev *gspca_dev) | 843 | static void sd_stopN(struct gspca_dev *gspca_dev) |
741 | { | 844 | { |
742 | struct sd *sd = (struct sd *) gspca_dev; | 845 | 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 | 846 | ||
847 | stream_stop(gspca_dev); | ||
751 | /* Not all the cams need this, but even if not, probably a good idea */ | 848 | /* Not all the cams need this, but even if not, probably a good idea */ |
752 | zero_the_pointer(gspca_dev); | 849 | zero_the_pointer(gspca_dev); |
753 | if (sd->do_lcd_stop) { | 850 | if (sd->do_lcd_stop) |
754 | gspca_dev->usb_buf[0] = 0x19; | 851 | 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 | } | 852 | } |
761 | 853 | ||
762 | static void setbrightness(struct gspca_dev *gspca_dev) | 854 | static void setbrightness(struct gspca_dev *gspca_dev) |
763 | { | 855 | { |
764 | struct sd *sd = (struct sd *) gspca_dev; | 856 | struct sd *sd = (struct sd *) gspca_dev; |
765 | u8 val; | 857 | u8 val; |
766 | 858 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ | |
767 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) | 859 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ |
860 | const u8 quick_clix_table[] = | ||
861 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ | ||
862 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; | ||
863 | /* | ||
864 | * This control is disabled for CIF type 1 and VGA type 0 cameras. | ||
865 | * It does not quite act linearly for the Argus QuickClix camera, | ||
866 | * but it does control brightness. The values are 0 - 15 only, and | ||
867 | * the table above makes them act consecutively. | ||
868 | */ | ||
869 | if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) && | ||
870 | (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX))) | ||
768 | return; | 871 | return; |
769 | 872 | ||
770 | /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ | 873 | if (sd->cam_type == CAM_TYPE_VGA) { |
874 | sign_reg += 4; | ||
875 | value_reg += 4; | ||
876 | } | ||
877 | |||
878 | /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ | ||
771 | if (sd->brightness > 0) { | 879 | if (sd->brightness > 0) { |
772 | sensor_write1(gspca_dev, 7, 0x00); | 880 | sensor_write1(gspca_dev, sign_reg, 0x00); |
773 | val = sd->brightness; | 881 | val = sd->brightness; |
774 | } else { | 882 | } else { |
775 | sensor_write1(gspca_dev, 7, 0x01); | 883 | sensor_write1(gspca_dev, sign_reg, 0x01); |
776 | val = 257 - sd->brightness; | 884 | val = (257 - sd->brightness); |
777 | } | 885 | } |
778 | sensor_write1(gspca_dev, 8, val); | 886 | /* Use lookup table for funky Argus QuickClix brightness */ |
887 | if (sd->do_lcd_stop) | ||
888 | val = quick_clix_table[val]; | ||
889 | |||
890 | sensor_write1(gspca_dev, value_reg, val); | ||
779 | } | 891 | } |
780 | 892 | ||
781 | static void setexposure(struct gspca_dev *gspca_dev) | 893 | static void setexposure(struct gspca_dev *gspca_dev) |
782 | { | 894 | { |
783 | struct sd *sd = (struct sd *) gspca_dev; | 895 | struct sd *sd = (struct sd *) gspca_dev; |
784 | u8 val; | 896 | int exposure; |
897 | u8 buf[2]; | ||
785 | 898 | ||
786 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | 899 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) |
787 | return; | 900 | return; |
788 | 901 | ||
789 | if (sd->sensor_type) { | 902 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { |
790 | val = sd->exposure >> 4; | 903 | /* This cam does not like exposure settings < 300, |
791 | sensor_write1(gspca_dev, 3, val); | 904 | so scale 0 - 4095 to 300 - 4095 */ |
792 | val = sd->exposure & 0xf; | 905 | exposure = (sd->exposure * 9267) / 10000 + 300; |
793 | sensor_write1(gspca_dev, 4, val); | 906 | sensor_write1(gspca_dev, 3, exposure >> 4); |
907 | sensor_write1(gspca_dev, 4, exposure & 0x0f); | ||
794 | } else { | 908 | } else { |
795 | u8 clockdiv; | ||
796 | int exposure; | ||
797 | |||
798 | /* We have both a clock divider and an exposure register. | 909 | /* We have both a clock divider and an exposure register. |
799 | We first calculate the clock divider, as that determines | 910 | We first calculate the clock divider, as that determines |
800 | the maximum exposure and then we calculayte the exposure | 911 | the maximum exposure and then we calculate the exposure |
801 | register setting (which goes from 0 - 511). | 912 | register setting (which goes from 0 - 511). |
802 | 913 | ||
803 | Note our 0 - 4095 exposure is mapped to 0 - 511 | 914 | Note our 0 - 4095 exposure is mapped to 0 - 511 |
804 | milliseconds exposure time */ | 915 | milliseconds exposure time */ |
805 | clockdiv = (60 * sd->exposure + 7999) / 8000; | 916 | u8 clockdiv = (60 * sd->exposure + 7999) / 8000; |
806 | 917 | ||
807 | /* Limit framerate to not exceed usb bandwidth */ | 918 | /* Limit framerate to not exceed usb bandwidth */ |
808 | if (clockdiv < 3 && gspca_dev->width >= 320) | 919 | if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320) |
809 | clockdiv = 3; | 920 | clockdiv = sd->min_clockdiv; |
810 | else if (clockdiv < 2) | 921 | else if (clockdiv < 2) |
811 | clockdiv = 2; | 922 | clockdiv = 2; |
812 | 923 | ||
924 | if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4) | ||
925 | clockdiv = 4; | ||
926 | |||
813 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> | 927 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> |
814 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ | 928 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ |
815 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); | 929 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); |
@@ -819,9 +933,10 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
819 | /* exposure register value is reversed! */ | 933 | /* exposure register value is reversed! */ |
820 | exposure = 511 - exposure; | 934 | exposure = 511 - exposure; |
821 | 935 | ||
936 | buf[0] = exposure & 0xff; | ||
937 | buf[1] = exposure >> 8; | ||
938 | sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2); | ||
822 | sensor_write1(gspca_dev, 0x02, clockdiv); | 939 | sensor_write1(gspca_dev, 0x02, clockdiv); |
823 | sensor_write1(gspca_dev, 0x0e, exposure & 0xff); | ||
824 | sensor_write1(gspca_dev, 0x0f, exposure >> 8); | ||
825 | } | 940 | } |
826 | } | 941 | } |
827 | 942 | ||
@@ -832,7 +947,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
832 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) | 947 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) |
833 | return; | 948 | return; |
834 | 949 | ||
835 | if (sd->sensor_type) { | 950 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { |
836 | sensor_write1(gspca_dev, 0x0e, sd->gain); | 951 | sensor_write1(gspca_dev, 0x0e, sd->gain); |
837 | } else { | 952 | } else { |
838 | sensor_write1(gspca_dev, 0x10, sd->gain); | 953 | sensor_write1(gspca_dev, 0x10, sd->gain); |
@@ -893,17 +1008,35 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | |||
893 | return 0; | 1008 | return 0; |
894 | } | 1009 | } |
895 | 1010 | ||
1011 | static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) | ||
1012 | { | ||
1013 | struct sd *sd = (struct sd *) gspca_dev; | ||
1014 | |||
1015 | sd->min_clockdiv = val; | ||
1016 | if (gspca_dev->streaming) | ||
1017 | setexposure(gspca_dev); | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val) | ||
1022 | { | ||
1023 | struct sd *sd = (struct sd *) gspca_dev; | ||
1024 | |||
1025 | *val = sd->min_clockdiv; | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
896 | /* Include pac common sof detection functions */ | 1029 | /* Include pac common sof detection functions */ |
897 | #include "pac_common.h" | 1030 | #include "pac_common.h" |
898 | 1031 | ||
899 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1032 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
900 | struct gspca_frame *frame, /* target */ | 1033 | u8 *data, /* isoc packet */ |
901 | __u8 *data, /* isoc packet */ | 1034 | int len) /* iso packet length */ |
902 | int len) /* iso packet length */ | ||
903 | { | 1035 | { |
1036 | struct sd *sd = (struct sd *) gspca_dev; | ||
904 | unsigned char *sof; | 1037 | unsigned char *sof; |
905 | 1038 | ||
906 | sof = pac_find_sof(gspca_dev, data, len); | 1039 | sof = pac_find_sof(&sd->sof_read, data, len); |
907 | if (sof) { | 1040 | if (sof) { |
908 | int n; | 1041 | int n; |
909 | 1042 | ||
@@ -913,15 +1046,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
913 | n -= sizeof pac_sof_marker; | 1046 | n -= sizeof pac_sof_marker; |
914 | else | 1047 | else |
915 | n = 0; | 1048 | n = 0; |
916 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 1049 | gspca_frame_add(gspca_dev, LAST_PACKET, |
917 | data, n); | 1050 | data, n); |
918 | /* Start next frame. */ | 1051 | /* Start next frame. */ |
919 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 1052 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
920 | pac_sof_marker, sizeof pac_sof_marker); | 1053 | pac_sof_marker, sizeof pac_sof_marker); |
921 | len -= sof - data; | 1054 | len -= sof - data; |
922 | data = sof; | 1055 | data = sof; |
923 | } | 1056 | } |
924 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 1057 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
925 | } | 1058 | } |
926 | 1059 | ||
927 | /* sub-driver description */ | 1060 | /* sub-driver description */ |
@@ -938,6 +1071,7 @@ static const struct sd_desc sd_desc = { | |||
938 | 1071 | ||
939 | /* -- module initialisation -- */ | 1072 | /* -- module initialisation -- */ |
940 | static const __devinitdata struct usb_device_id device_table[] = { | 1073 | static const __devinitdata struct usb_device_id device_table[] = { |
1074 | {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */ | ||
941 | {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ | 1075 | {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ |
942 | {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ | 1076 | {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ |
943 | {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ | 1077 | {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ |