aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/mr97310a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/mr97310a.c')
-rw-r--r--drivers/media/video/gspca/mr97310a.c98
1 files changed, 45 insertions, 53 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index db2f84e635c..3bdf064699e 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -64,11 +64,9 @@ struct sd {
64 u8 cam_type; /* 0 is CIF and 1 is VGA */ 64 u8 cam_type; /* 0 is CIF and 1 is VGA */
65 u8 sensor_type; /* We use 0 and 1 here, too. */ 65 u8 sensor_type; /* We use 0 and 1 here, too. */
66 u8 do_lcd_stop; 66 u8 do_lcd_stop;
67 u8 regs[15];
68 67
69 int brightness; 68 int brightness;
70 u16 exposure; 69 u16 exposure;
71 u8 autogain;
72 u8 gain; 70 u8 gain;
73}; 71};
74 72
@@ -85,10 +83,14 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 83static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 84static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 85static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
86static void setbrightness(struct gspca_dev *gspca_dev);
87static void setexposure(struct gspca_dev *gspca_dev);
88static void setgain(struct gspca_dev *gspca_dev);
88 89
89/* V4L2 controls supported by the driver */ 90/* V4L2 controls supported by the driver */
90static struct ctrl sd_ctrls[] = { 91static struct ctrl sd_ctrls[] = {
91 { 92 {
93#define BRIGHTNESS_IDX 0
92 { 94 {
93 .id = V4L2_CID_BRIGHTNESS, 95 .id = V4L2_CID_BRIGHTNESS,
94 .type = V4L2_CTRL_TYPE_INTEGER, 96 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -103,6 +105,7 @@ static struct ctrl sd_ctrls[] = {
103 .get = sd_getbrightness, 105 .get = sd_getbrightness,
104 }, 106 },
105 { 107 {
108#define EXPOSURE_IDX 1
106 { 109 {
107 .id = V4L2_CID_EXPOSURE, 110 .id = V4L2_CID_EXPOSURE,
108 .type = V4L2_CTRL_TYPE_INTEGER, 111 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -117,6 +120,7 @@ static struct ctrl sd_ctrls[] = {
117 .get = sd_getexposure, 120 .get = sd_getexposure,
118 }, 121 },
119 { 122 {
123#define GAIN_IDX 2
120 { 124 {
121 .id = V4L2_CID_GAIN, 125 .id = V4L2_CID_GAIN,
122 .type = V4L2_CTRL_TYPE_INTEGER, 126 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -360,14 +364,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
360 cam = &gspca_dev->cam; 364 cam = &gspca_dev->cam;
361 cam->cam_mode = vga_mode; 365 cam->cam_mode = vga_mode;
362 cam->nmodes = ARRAY_SIZE(vga_mode); 366 cam->nmodes = ARRAY_SIZE(vga_mode);
363 sd->cam_type = CAM_TYPE_VGA; 367
364 PDEBUG(D_PROBE, 368 PDEBUG(D_PROBE,
365 "MR97310A camera detected" 369 "MR97310A camera detected"
366 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 370 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
371
367 if (id->idProduct == 0x010e) { 372 if (id->idProduct == 0x010e) {
368 cam->nmodes--;
369 sd->cam_type = CAM_TYPE_CIF; 373 sd->cam_type = CAM_TYPE_CIF;
374 cam->nmodes--;
375 } else {
376 sd->cam_type = CAM_TYPE_VGA;
377 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
378 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
370 } 379 }
380
381 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
382 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
383 sd->gain = MR97310A_GAIN_DEFAULT;
384
371 return 0; 385 return 0;
372} 386}
373 387
@@ -377,35 +391,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
377 return 0; 391 return 0;
378} 392}
379 393
380static int adjust_cif_sensor(struct gspca_dev *gspca_dev)
381{
382 /*
383 * FIXME: The following sequence resets brightness, contrast, and
384 * related settings. Some of the values are adjustable, presumably
385 * based upon what is detected in the frames. Here, only some
386 * vaules are used which are compromises. When more is known about
387 * what is done here, this needs to be moved out to presently
388 * nonexistent functions which do controls. The same control messages
389 * do work for all of the CIF cameras.
390 */
391
392 const struct sensor_w_data cif_sensor1_adjust_data[] = {
393 {0x02, 0x01, {0x10, 0x12, 0x0a}, 3},
394 /* Last or possibly two last bytes adjustable, above. */
395 {0x13, 0x04, {0x01}, 1}, /* seems to mean "write" */
396 {0x05, 0x01, {0x22, 0x00, 0x81, 0x06}, 4},
397 /* Last or possibly two last bytes adjustable, above. */
398 {0x13, 0x04, {0x01}, 1},
399 {0x09, 0x02, {0x05, 0x00, 0x00, 0x05, 0x07, 0x16}, 6},
400 /* Last or possibly two last bytes adjustable, above. */
401 {0x13, 0x04, {0x01}, 1},
402 {0, 0, {0}, 0}
403 };
404
405 return sensor_write_regs(gspca_dev, cif_sensor1_adjust_data,
406 ARRAY_SIZE(cif_sensor1_adjust_data));
407}
408
409static int start_cif_cam(struct gspca_dev *gspca_dev) 394static int start_cif_cam(struct gspca_dev *gspca_dev)
410{ 395{
411 struct sd *sd = (struct sd *) gspca_dev; 396 struct sd *sd = (struct sd *) gspca_dev;
@@ -452,6 +437,11 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
452 sd->sensor_type = 1; 437 sd->sensor_type = 1;
453 438
454 PDEBUG(D_ERR, "Sensor type is %01x", sd->sensor_type); 439 PDEBUG(D_ERR, "Sensor type is %01x", sd->sensor_type);
440
441 if (sd->sensor_type == 0)
442 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
443 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
444
455 memcpy(data, startup_string, 11); 445 memcpy(data, startup_string, 11);
456 if (sd->sensor_type) 446 if (sd->sensor_type)
457 data[5] = 0xbb; 447 data[5] = 0xbb;
@@ -504,18 +494,15 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
504 ARRAY_SIZE(cif_sensor0_init_data)); 494 ARRAY_SIZE(cif_sensor0_init_data));
505 } else { /* sd->sensor_type = 1 */ 495 } else { /* sd->sensor_type = 1 */
506 const struct sensor_w_data cif_sensor1_init_data[] = { 496 const struct sensor_w_data cif_sensor1_init_data[] = {
497 /* Reg 3,4, 7,8 get set by the controls */
507 {0x02, 0x00, {0x10}, 1}, 498 {0x02, 0x00, {0x10}, 1},
508 {0x03, 0x01, {0x12}, 1}, 499 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
509 {0x04, 0x01, {0x05}, 1}, 500 {0x06, 0x01, {0x00}, 1},
510 {0x05, 0x01, {0x65}, 1},
511 {0x06, 0x01, {0x32}, 1},
512 {0x07, 0x01, {0x00}, 1},
513 {0x08, 0x02, {0x06}, 1},
514 {0x09, 0x02, {0x0e}, 1}, 501 {0x09, 0x02, {0x0e}, 1},
515 {0x0a, 0x02, {0x05}, 1}, 502 {0x0a, 0x02, {0x05}, 1},
516 {0x0b, 0x02, {0x05}, 1}, 503 {0x0b, 0x02, {0x05}, 1},
517 {0x0c, 0x02, {0x0f}, 1}, 504 {0x0c, 0x02, {0x0f}, 1},
518 {0x0d, 0x02, {0x00}, 1}, 505 {0x0d, 0x02, {0x07}, 1},
519 {0x0e, 0x02, {0x0c}, 1}, 506 {0x0e, 0x02, {0x0c}, 1},
520 {0x0f, 0x00, {0x00}, 1}, 507 {0x0f, 0x00, {0x00}, 1},
521 {0x10, 0x00, {0x06}, 1}, 508 {0x10, 0x00, {0x06}, 1},
@@ -530,19 +517,18 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
530 if (err_code < 0) 517 if (err_code < 0)
531 return err_code; 518 return err_code;
532 519
520 setbrightness(gspca_dev);
521 setexposure(gspca_dev);
522 setgain(gspca_dev);
523
533 msleep(200); 524 msleep(200);
525
534 data[0] = 0x00; 526 data[0] = 0x00;
535 data[1] = 0x4d; /* ISOC transfering enable... */ 527 data[1] = 0x4d; /* ISOC transfering enable... */
536 err_code = mr_write(gspca_dev, 2); 528 err_code = mr_write(gspca_dev, 2);
537 if (err_code < 0) 529 if (err_code < 0)
538 return err_code; 530 return err_code;
539 531
540 msleep(200);
541 err_code = adjust_cif_sensor(gspca_dev);
542 if (err_code < 0)
543 return err_code;
544
545 msleep(200);
546 return 0; 532 return 0;
547} 533}
548 534
@@ -711,11 +697,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
711 int err_code; 697 int err_code;
712 struct cam *cam; 698 struct cam *cam;
713 699
714 /* TEST TEST */
715 int i;
716 for (i = 2; i <= 14; i++)
717 sd->regs[i] = sd_ctrls[i - 2].qctrl.default_value;
718
719 cam = &gspca_dev->cam; 700 cam = &gspca_dev->cam;
720 sd->sof_read = 0; 701 sd->sof_read = 0;
721 /* 702 /*
@@ -760,11 +741,16 @@ static void setbrightness(struct gspca_dev *gspca_dev)
760{ 741{
761 struct sd *sd = (struct sd *) gspca_dev; 742 struct sd *sd = (struct sd *) gspca_dev;
762 u8 val; 743 u8 val;
744
745 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
746 return;
747
748 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
763 if (sd->brightness > 0) { 749 if (sd->brightness > 0) {
764 sensor_write1(gspca_dev, 7, 0); 750 sensor_write1(gspca_dev, 7, 0x00);
765 val = sd->brightness; 751 val = sd->brightness;
766 } else { 752 } else {
767 sensor_write1(gspca_dev, 7, 1); 753 sensor_write1(gspca_dev, 7, 0x01);
768 val = 257 - sd->brightness; 754 val = 257 - sd->brightness;
769 } 755 }
770 sensor_write1(gspca_dev, 8, val); 756 sensor_write1(gspca_dev, 8, val);
@@ -775,6 +761,9 @@ static void setexposure(struct gspca_dev *gspca_dev)
775 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
776 u8 val; 762 u8 val;
777 763
764 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
765 return;
766
778 val = sd->exposure >> 4; 767 val = sd->exposure >> 4;
779 sensor_write1(gspca_dev, 3, val); 768 sensor_write1(gspca_dev, 3, val);
780 val = sd->exposure & 0xf; 769 val = sd->exposure & 0xf;
@@ -785,6 +774,9 @@ static void setgain(struct gspca_dev *gspca_dev)
785{ 774{
786 struct sd *sd = (struct sd *) gspca_dev; 775 struct sd *sd = (struct sd *) gspca_dev;
787 776
777 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
778 return;
779
788 sensor_write1(gspca_dev, 3, sd->gain); 780 sensor_write1(gspca_dev, 3, sd->gain);
789} 781}
790 782