diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-03 11:58:12 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-04-06 20:44:46 -0400 |
commit | be63b722a56f0fe8fbe8e76cbdadaee0429cd291 (patch) | |
tree | 7736db163a170e56feea3036f2ebbb54c97c3da8 /drivers | |
parent | d9c700d415f05760f0129f798223cb4ac6a46d4b (diff) |
V4L/DVB (11424): gspca - m5602-ov9650: Use the local ctrl cache. Adjust image on vflip.
Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 189 |
1 files changed, 93 insertions, 96 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 39902652d24a..0cff90579772 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -69,6 +69,7 @@ static | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | const static struct ctrl ov9650_ctrls[] = { | 71 | const static struct ctrl ov9650_ctrls[] = { |
72 | #define EXPOSURE_IDX 0 | ||
72 | { | 73 | { |
73 | { | 74 | { |
74 | .id = V4L2_CID_EXPOSURE, | 75 | .id = V4L2_CID_EXPOSURE, |
@@ -82,7 +83,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
82 | }, | 83 | }, |
83 | .set = ov9650_set_exposure, | 84 | .set = ov9650_set_exposure, |
84 | .get = ov9650_get_exposure | 85 | .get = ov9650_get_exposure |
85 | }, { | 86 | }, |
87 | #define GAIN_IDX 1 | ||
88 | { | ||
86 | { | 89 | { |
87 | .id = V4L2_CID_GAIN, | 90 | .id = V4L2_CID_GAIN, |
88 | .type = V4L2_CTRL_TYPE_INTEGER, | 91 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -95,7 +98,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
95 | }, | 98 | }, |
96 | .set = ov9650_set_gain, | 99 | .set = ov9650_set_gain, |
97 | .get = ov9650_get_gain | 100 | .get = ov9650_get_gain |
98 | }, { | 101 | }, |
102 | #define RED_BALANCE_IDX 2 | ||
103 | { | ||
99 | { | 104 | { |
100 | .type = V4L2_CTRL_TYPE_INTEGER, | 105 | .type = V4L2_CTRL_TYPE_INTEGER, |
101 | .name = "red balance", | 106 | .name = "red balance", |
@@ -107,7 +112,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
107 | }, | 112 | }, |
108 | .set = ov9650_set_red_balance, | 113 | .set = ov9650_set_red_balance, |
109 | .get = ov9650_get_red_balance | 114 | .get = ov9650_get_red_balance |
110 | }, { | 115 | }, |
116 | #define BLUE_BALANCE_IDX 3 | ||
117 | { | ||
111 | { | 118 | { |
112 | .type = V4L2_CTRL_TYPE_INTEGER, | 119 | .type = V4L2_CTRL_TYPE_INTEGER, |
113 | .name = "blue balance", | 120 | .name = "blue balance", |
@@ -119,7 +126,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
119 | }, | 126 | }, |
120 | .set = ov9650_set_blue_balance, | 127 | .set = ov9650_set_blue_balance, |
121 | .get = ov9650_get_blue_balance | 128 | .get = ov9650_get_blue_balance |
122 | }, { | 129 | }, |
130 | #define HFLIP_IDX 4 | ||
131 | { | ||
123 | { | 132 | { |
124 | .id = V4L2_CID_HFLIP, | 133 | .id = V4L2_CID_HFLIP, |
125 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 134 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -131,7 +140,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
131 | }, | 140 | }, |
132 | .set = ov9650_set_hflip, | 141 | .set = ov9650_set_hflip, |
133 | .get = ov9650_get_hflip | 142 | .get = ov9650_get_hflip |
134 | }, { | 143 | }, |
144 | #define VFLIP_IDX 5 | ||
145 | { | ||
135 | { | 146 | { |
136 | .id = V4L2_CID_VFLIP, | 147 | .id = V4L2_CID_VFLIP, |
137 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 148 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -143,7 +154,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
143 | }, | 154 | }, |
144 | .set = ov9650_set_vflip, | 155 | .set = ov9650_set_vflip, |
145 | .get = ov9650_get_vflip | 156 | .get = ov9650_get_vflip |
146 | }, { | 157 | }, |
158 | #define AUTO_WHITE_BALANCE_IDX 6 | ||
159 | { | ||
147 | { | 160 | { |
148 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | 161 | .id = V4L2_CID_AUTO_WHITE_BALANCE, |
149 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 162 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -155,7 +168,9 @@ const static struct ctrl ov9650_ctrls[] = { | |||
155 | }, | 168 | }, |
156 | .set = ov9650_set_auto_white_balance, | 169 | .set = ov9650_set_auto_white_balance, |
157 | .get = ov9650_get_auto_white_balance | 170 | .get = ov9650_get_auto_white_balance |
158 | }, { | 171 | }, |
172 | #define AUTO_GAIN_CTRL_IDX 7 | ||
173 | { | ||
159 | { | 174 | { |
160 | .id = V4L2_CID_AUTOGAIN, | 175 | .id = V4L2_CID_AUTOGAIN, |
161 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 176 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -311,18 +326,19 @@ int ov9650_start(struct sd *sd) | |||
311 | u8 data; | 326 | u8 data; |
312 | int i, err = 0; | 327 | int i, err = 0; |
313 | struct cam *cam = &sd->gspca_dev.cam; | 328 | struct cam *cam = &sd->gspca_dev.cam; |
329 | s32 *sensor_settings = sd->sensor_priv; | ||
330 | |||
314 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; | 331 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; |
315 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | 332 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; |
316 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | 333 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; |
317 | int hor_offs = OV9650_LEFT_OFFSET; | 334 | int hor_offs = OV9650_LEFT_OFFSET; |
318 | 335 | ||
336 | if (sensor_settings[VFLIP_IDX]) | ||
337 | ver_offs--; | ||
338 | |||
319 | if (width <= 320) | 339 | if (width <= 320) |
320 | hor_offs /= 2; | 340 | hor_offs /= 2; |
321 | 341 | ||
322 | err = ov9650_init(sd); | ||
323 | if (err < 0) | ||
324 | return err; | ||
325 | |||
326 | /* Synthesize the vsync/hsync setup */ | 342 | /* Synthesize the vsync/hsync setup */ |
327 | for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { | 343 | for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { |
328 | if (res_init_ov9650[i][0] == BRIDGE) | 344 | if (res_init_ov9650[i][0] == BRIDGE) |
@@ -460,32 +476,23 @@ void ov9650_disconnect(struct sd *sd) | |||
460 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 476 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
461 | { | 477 | { |
462 | struct sd *sd = (struct sd *) gspca_dev; | 478 | struct sd *sd = (struct sd *) gspca_dev; |
463 | u8 i2c_data; | 479 | s32 *sensor_settings = sd->sensor_priv; |
464 | int err; | ||
465 | |||
466 | err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1); | ||
467 | if (err < 0) | ||
468 | return err; | ||
469 | *val |= (i2c_data << 2); | ||
470 | |||
471 | err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1); | ||
472 | if (err < 0) | ||
473 | return err; | ||
474 | *val |= (i2c_data & 0x3f) << 10; | ||
475 | 480 | ||
481 | *val = sensor_settings[EXPOSURE_IDX]; | ||
476 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 482 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
477 | 483 | return 0; | |
478 | return err; | ||
479 | } | 484 | } |
480 | 485 | ||
481 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 486 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
482 | { | 487 | { |
483 | struct sd *sd = (struct sd *) gspca_dev; | 488 | struct sd *sd = (struct sd *) gspca_dev; |
489 | s32 *sensor_settings = sd->sensor_priv; | ||
484 | u8 i2c_data; | 490 | u8 i2c_data; |
485 | int err; | 491 | int err; |
486 | 492 | ||
487 | PDEBUG(D_V4L2, "Set exposure to %d", | 493 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
488 | val & 0xffff); | 494 | |
495 | sensor_settings[EXPOSURE_IDX] = val; | ||
489 | 496 | ||
490 | /* The 6 MSBs */ | 497 | /* The 6 MSBs */ |
491 | i2c_data = (val >> 10) & 0x3f; | 498 | i2c_data = (val >> 10) & 0x3f; |
@@ -510,20 +517,12 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
510 | 517 | ||
511 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 518 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
512 | { | 519 | { |
513 | int err; | ||
514 | u8 i2c_data; | ||
515 | struct sd *sd = (struct sd *) gspca_dev; | 520 | struct sd *sd = (struct sd *) gspca_dev; |
521 | s32 *sensor_settings = sd->sensor_priv; | ||
516 | 522 | ||
517 | err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); | 523 | *val = sensor_settings[GAIN_IDX]; |
518 | if (err < 0) | ||
519 | return err; | ||
520 | |||
521 | *val = (i2c_data & 0x03) << 8; | ||
522 | |||
523 | err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); | ||
524 | *val |= i2c_data; | ||
525 | PDEBUG(D_V4L2, "Read gain %d", *val); | 524 | PDEBUG(D_V4L2, "Read gain %d", *val); |
526 | return err; | 525 | return 0; |
527 | } | 526 | } |
528 | 527 | ||
529 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 528 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
@@ -531,6 +530,11 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
531 | int err; | 530 | int err; |
532 | u8 i2c_data; | 531 | u8 i2c_data; |
533 | struct sd *sd = (struct sd *) gspca_dev; | 532 | struct sd *sd = (struct sd *) gspca_dev; |
533 | s32 *sensor_settings = sd->sensor_priv; | ||
534 | |||
535 | PDEBUG(D_V4L2, "Setting gain to %d", val); | ||
536 | |||
537 | sensor_settings[GAIN_IDX] = val; | ||
534 | 538 | ||
535 | /* The 2 MSB */ | 539 | /* The 2 MSB */ |
536 | /* Read the OV9650_VREF register first to avoid | 540 | /* Read the OV9650_VREF register first to avoid |
@@ -554,16 +558,12 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
554 | 558 | ||
555 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 559 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
556 | { | 560 | { |
557 | int err; | ||
558 | u8 i2c_data; | ||
559 | struct sd *sd = (struct sd *) gspca_dev; | 561 | struct sd *sd = (struct sd *) gspca_dev; |
562 | s32 *sensor_settings = sd->sensor_priv; | ||
560 | 563 | ||
561 | err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1); | 564 | *val = sensor_settings[RED_BALANCE_IDX]; |
562 | *val = i2c_data; | ||
563 | |||
564 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 565 | PDEBUG(D_V4L2, "Read red gain %d", *val); |
565 | 566 | return 0; | |
566 | return err; | ||
567 | } | 567 | } |
568 | 568 | ||
569 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 569 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -571,9 +571,11 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
571 | int err; | 571 | int err; |
572 | u8 i2c_data; | 572 | u8 i2c_data; |
573 | struct sd *sd = (struct sd *) gspca_dev; | 573 | struct sd *sd = (struct sd *) gspca_dev; |
574 | s32 *sensor_settings = sd->sensor_priv; | ||
574 | 575 | ||
575 | PDEBUG(D_V4L2, "Set red gain to %d", | 576 | PDEBUG(D_V4L2, "Set red gain to %d", val); |
576 | val & 0xff); | 577 | |
578 | sensor_settings[RED_BALANCE_IDX] = val; | ||
577 | 579 | ||
578 | i2c_data = val & 0xff; | 580 | i2c_data = val & 0xff; |
579 | err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); | 581 | err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); |
@@ -583,16 +585,13 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
583 | 585 | ||
584 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 586 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
585 | { | 587 | { |
586 | int err; | ||
587 | u8 i2c_data; | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | 588 | struct sd *sd = (struct sd *) gspca_dev; |
589 | s32 *sensor_settings = sd->sensor_priv; | ||
589 | 590 | ||
590 | err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); | 591 | *val = sensor_settings[BLUE_BALANCE_IDX]; |
591 | *val = i2c_data; | ||
592 | |||
593 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | 592 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
594 | 593 | ||
595 | return err; | 594 | return 0; |
596 | } | 595 | } |
597 | 596 | ||
598 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 597 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -600,9 +599,11 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
600 | int err; | 599 | int err; |
601 | u8 i2c_data; | 600 | u8 i2c_data; |
602 | struct sd *sd = (struct sd *) gspca_dev; | 601 | struct sd *sd = (struct sd *) gspca_dev; |
602 | s32 *sensor_settings = sd->sensor_priv; | ||
603 | |||
604 | PDEBUG(D_V4L2, "Set blue gain to %d", val); | ||
603 | 605 | ||
604 | PDEBUG(D_V4L2, "Set blue gain to %d", | 606 | sensor_settings[BLUE_BALANCE_IDX] = val; |
605 | val & 0xff); | ||
606 | 607 | ||
607 | i2c_data = val & 0xff; | 608 | i2c_data = val & 0xff; |
608 | err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); | 609 | err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); |
@@ -612,18 +613,12 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
612 | 613 | ||
613 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 614 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
614 | { | 615 | { |
615 | int err; | ||
616 | u8 i2c_data; | ||
617 | struct sd *sd = (struct sd *) gspca_dev; | 616 | struct sd *sd = (struct sd *) gspca_dev; |
618 | 617 | s32 *sensor_settings = sd->sensor_priv; | |
619 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 618 | *val = sensor_settings[HFLIP_IDX]; |
620 | if (dmi_check_system(ov9650_flip_dmi_table)) | ||
621 | *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; | ||
622 | else | ||
623 | *val = (i2c_data & OV9650_HFLIP) >> 5; | ||
624 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 619 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
625 | 620 | ||
626 | return err; | 621 | return 0; |
627 | } | 622 | } |
628 | 623 | ||
629 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 624 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -631,8 +626,11 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
631 | int err; | 626 | int err; |
632 | u8 i2c_data; | 627 | u8 i2c_data; |
633 | struct sd *sd = (struct sd *) gspca_dev; | 628 | struct sd *sd = (struct sd *) gspca_dev; |
629 | s32 *sensor_settings = sd->sensor_priv; | ||
634 | 630 | ||
635 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 631 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
632 | |||
633 | sensor_settings[HFLIP_IDX] = val; | ||
636 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 634 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
637 | if (err < 0) | 635 | if (err < 0) |
638 | return err; | 636 | return err; |
@@ -651,18 +649,13 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
651 | 649 | ||
652 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 650 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
653 | { | 651 | { |
654 | int err; | ||
655 | u8 i2c_data; | ||
656 | struct sd *sd = (struct sd *) gspca_dev; | 652 | struct sd *sd = (struct sd *) gspca_dev; |
653 | s32 *sensor_settings = sd->sensor_priv; | ||
657 | 654 | ||
658 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 655 | *val = sensor_settings[VFLIP_IDX]; |
659 | if (dmi_check_system(ov9650_flip_dmi_table)) | ||
660 | *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; | ||
661 | else | ||
662 | *val = (i2c_data & 0x10) >> 4; | ||
663 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 656 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
664 | 657 | ||
665 | return err; | 658 | return 0; |
666 | } | 659 | } |
667 | 660 | ||
668 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 661 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -670,8 +663,11 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
670 | int err; | 663 | int err; |
671 | u8 i2c_data; | 664 | u8 i2c_data; |
672 | struct sd *sd = (struct sd *) gspca_dev; | 665 | struct sd *sd = (struct sd *) gspca_dev; |
666 | s32 *sensor_settings = sd->sensor_priv; | ||
673 | 667 | ||
674 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 668 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
669 | |||
670 | sensor_settings[VFLIP_IDX] = val; | ||
675 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 671 | err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
676 | if (err < 0) | 672 | if (err < 0) |
677 | return err; | 673 | return err; |
@@ -685,25 +681,24 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
685 | 681 | ||
686 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 682 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
687 | 683 | ||
684 | if (err < 0) | ||
685 | return err; | ||
686 | |||
687 | if (gspca_dev->streaming) | ||
688 | err = ov9650_start(sd); | ||
689 | |||
688 | return err; | 690 | return err; |
689 | } | 691 | } |
690 | 692 | ||
691 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 693 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
692 | { | 694 | { |
693 | int err; | ||
694 | u8 i2c_data; | ||
695 | struct sd *sd = (struct sd *) gspca_dev; | 695 | struct sd *sd = (struct sd *) gspca_dev; |
696 | s32 *sensor_settings = sd->sensor_priv; | ||
696 | 697 | ||
697 | err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); | 698 | *val = sensor_settings[GAIN_IDX]; |
698 | if (err < 0) | ||
699 | return err; | ||
700 | *val = (i2c_data & 0x03) << 8; | ||
701 | |||
702 | err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); | ||
703 | *val |= i2c_data; | ||
704 | PDEBUG(D_V4L2, "Read gain %d", *val); | 699 | PDEBUG(D_V4L2, "Read gain %d", *val); |
705 | 700 | ||
706 | return err; | 701 | return 0; |
707 | } | 702 | } |
708 | 703 | ||
709 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 704 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) |
@@ -711,8 +706,11 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
711 | int err; | 706 | int err; |
712 | u8 i2c_data; | 707 | u8 i2c_data; |
713 | struct sd *sd = (struct sd *) gspca_dev; | 708 | struct sd *sd = (struct sd *) gspca_dev; |
709 | s32 *sensor_settings = sd->sensor_priv; | ||
710 | |||
711 | PDEBUG(D_V4L2, "Set gain to %d", val); | ||
714 | 712 | ||
715 | PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff); | 713 | sensor_settings[GAIN_IDX] = val; |
716 | 714 | ||
717 | /* Read the OV9650_VREF register first to avoid | 715 | /* Read the OV9650_VREF register first to avoid |
718 | corrupting the VREF high and low bits */ | 716 | corrupting the VREF high and low bits */ |
@@ -735,15 +733,11 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
735 | 733 | ||
736 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 734 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) |
737 | { | 735 | { |
738 | int err; | ||
739 | u8 i2c_data; | ||
740 | struct sd *sd = (struct sd *) gspca_dev; | 736 | struct sd *sd = (struct sd *) gspca_dev; |
737 | s32 *sensor_settings = sd->sensor_priv; | ||
741 | 738 | ||
742 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 739 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; |
743 | *val = (i2c_data & OV9650_AWB_EN) >> 1; | 740 | return 0; |
744 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); | ||
745 | |||
746 | return err; | ||
747 | } | 741 | } |
748 | 742 | ||
749 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 743 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -751,8 +745,11 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
751 | int err; | 745 | int err; |
752 | u8 i2c_data; | 746 | u8 i2c_data; |
753 | struct sd *sd = (struct sd *) gspca_dev; | 747 | struct sd *sd = (struct sd *) gspca_dev; |
748 | s32 *sensor_settings = sd->sensor_priv; | ||
754 | 749 | ||
755 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); | 750 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); |
751 | |||
752 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; | ||
756 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 753 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
757 | if (err < 0) | 754 | if (err < 0) |
758 | return err; | 755 | return err; |
@@ -765,15 +762,12 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
765 | 762 | ||
766 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 763 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) |
767 | { | 764 | { |
768 | int err; | ||
769 | u8 i2c_data; | ||
770 | struct sd *sd = (struct sd *) gspca_dev; | 765 | struct sd *sd = (struct sd *) gspca_dev; |
766 | s32 *sensor_settings = sd->sensor_priv; | ||
771 | 767 | ||
772 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 768 | *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; |
773 | *val = (i2c_data & OV9650_AGC_EN) >> 2; | ||
774 | PDEBUG(D_V4L2, "Read auto gain control %d", *val); | 769 | PDEBUG(D_V4L2, "Read auto gain control %d", *val); |
775 | 770 | return 0; | |
776 | return err; | ||
777 | } | 771 | } |
778 | 772 | ||
779 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 773 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) |
@@ -781,8 +775,11 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
781 | int err; | 775 | int err; |
782 | u8 i2c_data; | 776 | u8 i2c_data; |
783 | struct sd *sd = (struct sd *) gspca_dev; | 777 | struct sd *sd = (struct sd *) gspca_dev; |
778 | s32 *sensor_settings = sd->sensor_priv; | ||
784 | 779 | ||
785 | PDEBUG(D_V4L2, "Set auto gain control to %d", val); | 780 | PDEBUG(D_V4L2, "Set auto gain control to %d", val); |
781 | |||
782 | sensor_settings[AUTO_GAIN_CTRL_IDX] = val; | ||
786 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 783 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
787 | if (err < 0) | 784 | if (err < 0) |
788 | return err; | 785 | return err; |