aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorErik Andr?n <erik.andren@gmail.com>2009-01-03 11:58:12 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-06 20:44:46 -0400
commitbe63b722a56f0fe8fbe8e76cbdadaee0429cd291 (patch)
tree7736db163a170e56feea3036f2ebbb54c97c3da8 /drivers/media/video
parentd9c700d415f05760f0129f798223cb4ac6a46d4b (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/media/video')
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c189
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
71const static struct ctrl ov9650_ctrls[] = { 71const 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)
460int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 476int 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
481int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 486int 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
511int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 518int 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
529int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 528int 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
555int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 559int 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
569int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 569int 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
584int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 586int 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
598int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 597int 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
613int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 614int 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
629int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 624int 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
652int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 650int 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
668int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 661int 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
691int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 693int 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
709int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 704int 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
736int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 734int 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
749int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 743int 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
766int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 763int 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
779int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 773int 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;