aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov519.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-10-12 10:32:44 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:34 -0500
commitebbb5c3e0eb73db4da5bee57cd0344a74cf73319 (patch)
treea02fc47f82731627aab320a4735c1f2d7b0c4910 /drivers/media/video/gspca/ov519.c
parentb46aaa02648cd8c1ebc20191304e2f6a2382d04c (diff)
V4L/DVB (13146): gspca_ov519: cleanup sensor handling
There were various "if (sensor == foo)" pieces of code inside ov519.c, move these bits to the sensor specific init functions, where they belong. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r--drivers/media/video/gspca/ov519.c159
1 files changed, 59 insertions, 100 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 30e91c365ea4..4d6a762a6f3d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -3501,7 +3501,8 @@ static int ov519_mode_init_regs(struct sd *sd)
3501static int mode_init_ov_sensor_regs(struct sd *sd) 3501static int mode_init_ov_sensor_regs(struct sd *sd)
3502{ 3502{
3503 struct gspca_dev *gspca_dev; 3503 struct gspca_dev *gspca_dev;
3504 int qvga; 3504 int qvga, xstart, xend, ystart, yend;
3505 __u8 v;
3505 3506
3506 gspca_dev = &sd->gspca_dev; 3507 gspca_dev = &sd->gspca_dev;
3507 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; 3508 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
@@ -3517,9 +3518,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3517 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); 3518 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3518 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3519 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3519 return 0; 3520 return 0;
3520 case SEN_OV3610: { 3521 case SEN_OV3610:
3521 int xstart, xend, ystart, yend;
3522
3523 if (qvga) { 3522 if (qvga) {
3524 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); 3523 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
3525 ystart = (776 - gspca_dev->height) / 2; 3524 ystart = (776 - gspca_dev->height) / 2;
@@ -3543,13 +3542,19 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3543 i2c_w(sd, 0x19, ystart >> 3); 3542 i2c_w(sd, 0x19, ystart >> 3);
3544 i2c_w(sd, 0x1a, yend >> 3); 3543 i2c_w(sd, 0x1a, yend >> 3);
3545 return 0; 3544 return 0;
3546 }
3547 case SEN_OV8610: 3545 case SEN_OV8610:
3548 /* For OV8610 qvga means qsvga */ 3546 /* For OV8610 qvga means qsvga */
3549 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); 3547 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
3548 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3549 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3550 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3551 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
3550 break; 3552 break;
3551 case SEN_OV7610: 3553 case SEN_OV7610:
3552 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3554 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3555 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3556 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3557 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3553 break; 3558 break;
3554 case SEN_OV7620: 3559 case SEN_OV7620:
3555 case SEN_OV76BE: 3560 case SEN_OV76BE:
@@ -3560,6 +3565,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3560 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); 3565 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3561 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); 3566 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
3562 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3567 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3568 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3569 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3570 if (sd->sensor == SEN_OV76BE)
3571 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3563 break; 3572 break;
3564 case SEN_OV7640: 3573 case SEN_OV7640:
3565 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3574 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -3569,6 +3578,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3569/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ 3578/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
3570/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ 3579/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
3571/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ 3580/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
3581 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
3572 break; 3582 break;
3573 case SEN_OV7670: 3583 case SEN_OV7670:
3574 /* set COM7_FMT_VGA or COM7_FMT_QVGA 3584 /* set COM7_FMT_VGA or COM7_FMT_QVGA
@@ -3577,55 +3587,56 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3577 i2c_w_mask(sd, OV7670_REG_COM7, 3587 i2c_w_mask(sd, OV7670_REG_COM7,
3578 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, 3588 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3579 OV7670_COM7_FMT_MASK); 3589 OV7670_COM7_FMT_MASK);
3590 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3591 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3592 OV7670_COM8_AWB);
3593 if (qvga) { /* QVGA from ov7670.c by
3594 * Jonathan Corbet */
3595 xstart = 164;
3596 xend = 28;
3597 ystart = 14;
3598 yend = 494;
3599 } else { /* VGA */
3600 xstart = 158;
3601 xend = 14;
3602 ystart = 10;
3603 yend = 490;
3604 }
3605 /* OV7670 hardware window registers are split across
3606 * multiple locations */
3607 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3608 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3609 v = i2c_r(sd, OV7670_REG_HREF);
3610 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3611 msleep(10); /* need to sleep between read and write to
3612 * same reg! */
3613 i2c_w(sd, OV7670_REG_HREF, v);
3614
3615 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3616 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3617 v = i2c_r(sd, OV7670_REG_VREF);
3618 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3619 msleep(10); /* need to sleep between read and write to
3620 * same reg! */
3621 i2c_w(sd, OV7670_REG_VREF, v);
3580 break; 3622 break;
3581 case SEN_OV6620: 3623 case SEN_OV6620:
3624 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3625 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3626 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3627 break;
3582 case SEN_OV6630: 3628 case SEN_OV6630:
3583 case SEN_OV66308AF: 3629 case SEN_OV66308AF:
3584 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3630 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3631 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3585 break; 3632 break;
3586 default: 3633 default:
3587 return -EINVAL; 3634 return -EINVAL;
3588 } 3635 }
3589 3636
3590 /******** Palette-specific regs ********/
3591
3592 /* The OV518 needs special treatment. Although both the OV518
3593 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
3594 * bus is actually used. The UV bus is tied to ground.
3595 * Therefore, the OV6630 needs to be in 8-bit multiplexed
3596 * output mode */
3597
3598 /* OV7640 is 8-bit only */
3599
3600 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
3601 sd->sensor != SEN_OV7640)
3602 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3603
3604 /******** Clock programming ********/ 3637 /******** Clock programming ********/
3605 i2c_w(sd, 0x11, sd->clockdiv); 3638 i2c_w(sd, 0x11, sd->clockdiv);
3606 3639
3607 /******** Special Features ********/
3608/* no evidence this is possible with OV7670, either */
3609 /* Test Pattern */
3610 if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
3611 i2c_w_mask(sd, 0x12, 0x00, 0x02);
3612
3613 /* Enable auto white balance */
3614 if (sd->sensor == SEN_OV7670)
3615 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3616 OV7670_COM8_AWB);
3617 else
3618 i2c_w_mask(sd, 0x12, 0x04, 0x04);
3619
3620 /* This will go away as soon as ov51x_mode_init_sensor_regs() */
3621 /* is fully tested. */
3622 /* 7620/6620/6630? don't have register 0x35, so play it safe */
3623 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
3624 if (!qvga)
3625 i2c_w(sd, 0x35, 0x9e);
3626 else
3627 i2c_w(sd, 0x35, 0x1e);
3628 }
3629 return 0; 3640 return 0;
3630} 3641}
3631 3642
@@ -3648,11 +3659,11 @@ static int set_ov_sensor_window(struct sd *sd)
3648 struct gspca_dev *gspca_dev; 3659 struct gspca_dev *gspca_dev;
3649 int qvga, crop; 3660 int qvga, crop;
3650 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 3661 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
3651 int ret, hstart, hstop, vstop, vstart; 3662 int ret;
3652 __u8 v;
3653 3663
3654 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ 3664 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3655 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) 3665 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3666 sd->sensor == SEN_OV7670)
3656 return mode_init_ov_sensor_regs(sd); 3667 return mode_init_ov_sensor_regs(sd);
3657 3668
3658 gspca_dev = &sd->gspca_dev; 3669 gspca_dev = &sd->gspca_dev;
@@ -3701,11 +3712,6 @@ static int set_ov_sensor_window(struct sd *sd)
3701 hwebase = 0x1a; 3712 hwebase = 0x1a;
3702 vwsbase = vwebase = 0x03; 3713 vwsbase = vwebase = 0x03;
3703 break; 3714 break;
3704 case SEN_OV7670:
3705 /*handling of OV7670 hardware sensor start and stop values
3706 * is very odd, compared to the other OV sensors */
3707 vwsbase = vwebase = hwebase = hwsbase = 0x00;
3708 break;
3709 default: 3715 default:
3710 return -EINVAL; 3716 return -EINVAL;
3711 } 3717 }
@@ -3746,58 +3752,11 @@ static int set_ov_sensor_window(struct sd *sd)
3746 if (ret < 0) 3752 if (ret < 0)
3747 return ret; 3753 return ret;
3748 3754
3749 if (sd->sensor == SEN_OV8610) { 3755 i2c_w(sd, 0x17, hwsbase);
3750 i2c_w_mask(sd, 0x2d, 0x05, 0x40); 3756 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
3751 /* old 0x95, new 0x05 from windrv 090403 */ 3757 i2c_w(sd, 0x19, vwsbase);
3752 /* bits 5-7: reserved */ 3758 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
3753 i2c_w_mask(sd, 0x28, 0x20, 0x20);
3754 /* bit 5: progressive mode on */
3755 }
3756
3757 /* The below is wrong for OV7670s because their window registers
3758 * only store the high bits in 0x17 to 0x1a */
3759
3760 /* SRH Use sd->max values instead of requested win values */
3761 /* SCS Since we're sticking with only the max hardware widths
3762 * for a given mode */
3763 /* I can hard code this for OV7670s */
3764 /* Yes, these numbers do look odd, but they're tested and work! */
3765 if (sd->sensor == SEN_OV7670) {
3766 if (qvga) { /* QVGA from ov7670.c by
3767 * Jonathan Corbet */
3768 hstart = 164;
3769 hstop = 28;
3770 vstart = 14;
3771 vstop = 494;
3772 } else { /* VGA */
3773 hstart = 158;
3774 hstop = 14;
3775 vstart = 10;
3776 vstop = 490;
3777 }
3778 /* OV7670 hardware window registers are split across
3779 * multiple locations */
3780 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
3781 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
3782 v = i2c_r(sd, OV7670_REG_HREF);
3783 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
3784 msleep(10); /* need to sleep between read and write to
3785 * same reg! */
3786 i2c_w(sd, OV7670_REG_HREF, v);
3787 3759
3788 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
3789 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
3790 v = i2c_r(sd, OV7670_REG_VREF);
3791 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
3792 msleep(10); /* need to sleep between read and write to
3793 * same reg! */
3794 i2c_w(sd, OV7670_REG_VREF, v);
3795 } else {
3796 i2c_w(sd, 0x17, hwsbase);
3797 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
3798 i2c_w(sd, 0x19, vwsbase);
3799 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
3800 }
3801 return 0; 3760 return 0;
3802} 3761}
3803 3762