diff options
author | Hans de Goede <hdegoede@redhat.com> | 2009-08-14 09:15:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:19:55 -0400 |
commit | 9ac6978a10a22499f6333d55364809f4ddb32b0c (patch) | |
tree | 41b593fa1fe9c7509c6e0efb859a3e8490511daa /drivers/media | |
parent | 58d0b2f66e2495429bc7c4e7c8b0f02fe4a7c260 (diff) |
V4L/DVB (12620): gspca_mr97310a: cleanup/fixup control handling
gspca_mr97310a: cleanup/fixup control handling
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 98 |
1 files changed, 45 insertions, 53 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index db2f84e635c5..3bdf064699e9 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); | |||
85 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | 83 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); |
86 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | 84 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); |
87 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | 85 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); |
86 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
87 | static void setexposure(struct gspca_dev *gspca_dev); | ||
88 | static void setgain(struct gspca_dev *gspca_dev); | ||
88 | 89 | ||
89 | /* V4L2 controls supported by the driver */ | 90 | /* V4L2 controls supported by the driver */ |
90 | static struct ctrl sd_ctrls[] = { | 91 | static 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 | ||
380 | static 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 | |||
409 | static int start_cif_cam(struct gspca_dev *gspca_dev) | 394 | static 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 | ||