diff options
author | Jean-François Moine <moinejf@free.fr> | 2011-02-10 11:32:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:08 -0400 |
commit | 07c6c9c6d0e797590a7cc76fc8f0b740f34d21a2 (patch) | |
tree | b8b280e5ee806bd34279c07240a6cacde45bb46f | |
parent | 20c957b360f85c293fbb6bcec9d1ec11b241ef1a (diff) |
[media] gspca - ov519: Add the sensor ov2610ae
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 8ab2c452c25e..cda7ee2c8bb4 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -118,6 +118,7 @@ struct sd { | |||
118 | }; | 118 | }; |
119 | enum sensors { | 119 | enum sensors { |
120 | SEN_OV2610, | 120 | SEN_OV2610, |
121 | SEN_OV2610AE, | ||
121 | SEN_OV3610, | 122 | SEN_OV3610, |
122 | SEN_OV6620, | 123 | SEN_OV6620, |
123 | SEN_OV6630, | 124 | SEN_OV6630, |
@@ -239,6 +240,8 @@ static const struct ctrl sd_ctrls[] = { | |||
239 | static const unsigned ctrl_dis[] = { | 240 | static const unsigned ctrl_dis[] = { |
240 | [SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ | 241 | [SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ |
241 | 242 | ||
243 | [SEN_OV2610AE] = (1 << NCTRL) - 1, /* no control */ | ||
244 | |||
242 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ | 245 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ |
243 | 246 | ||
244 | [SEN_OV6620] = (1 << HFLIP) | | 247 | [SEN_OV6620] = (1 << HFLIP) | |
@@ -656,6 +659,24 @@ static const struct ov_i2c_regvals norm_2610[] = { | |||
656 | { 0x12, 0x80 }, /* reset */ | 659 | { 0x12, 0x80 }, /* reset */ |
657 | }; | 660 | }; |
658 | 661 | ||
662 | static const struct ov_i2c_regvals norm_2610ae[] = { | ||
663 | {0x12, 0x80}, /* reset */ | ||
664 | {0x13, 0xcd}, | ||
665 | {0x09, 0x01}, | ||
666 | {0x0d, 0x00}, | ||
667 | {0x11, 0x80}, | ||
668 | {0x12, 0x20}, /* 1600x1200 */ | ||
669 | {0x33, 0x0c}, | ||
670 | {0x35, 0x90}, | ||
671 | {0x36, 0x37}, | ||
672 | /* ms-win traces */ | ||
673 | {0x11, 0x83}, /* clock / 3 ? */ | ||
674 | {0x2d, 0x00}, /* 60 Hz filter */ | ||
675 | {0x24, 0xb0}, /* normal colors */ | ||
676 | {0x25, 0x90}, | ||
677 | {0x10, 0x43}, | ||
678 | }; | ||
679 | |||
659 | static const struct ov_i2c_regvals norm_3620b[] = { | 680 | static const struct ov_i2c_regvals norm_3620b[] = { |
660 | /* | 681 | /* |
661 | * From the datasheet: "Note that after writing to register COMH | 682 | * From the datasheet: "Note that after writing to register COMH |
@@ -2621,6 +2642,9 @@ static void ov_hires_configure(struct sd *sd) | |||
2621 | if (high == 0x96 && low == 0x40) { | 2642 | if (high == 0x96 && low == 0x40) { |
2622 | PDEBUG(D_PROBE, "Sensor is an OV2610"); | 2643 | PDEBUG(D_PROBE, "Sensor is an OV2610"); |
2623 | sd->sensor = SEN_OV2610; | 2644 | sd->sensor = SEN_OV2610; |
2645 | } else if (high == 0x96 && low == 0x41) { | ||
2646 | PDEBUG(D_PROBE, "Sensor is an OV2610AE"); | ||
2647 | sd->sensor = SEN_OV2610AE; | ||
2624 | } else if (high == 0x36 && (low & 0x0f) == 0x00) { | 2648 | } else if (high == 0x36 && (low & 0x0f) == 0x00) { |
2625 | PDEBUG(D_PROBE, "Sensor is an OV3610"); | 2649 | PDEBUG(D_PROBE, "Sensor is an OV3610"); |
2626 | sd->sensor = SEN_OV3610; | 2650 | sd->sensor = SEN_OV3610; |
@@ -3295,15 +3319,22 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3295 | } | 3319 | } |
3296 | break; | 3320 | break; |
3297 | case BRIDGE_OVFX2: | 3321 | case BRIDGE_OVFX2: |
3298 | if (sd->sensor == SEN_OV2610) { | 3322 | switch (sd->sensor) { |
3323 | case SEN_OV2610: | ||
3324 | case SEN_OV2610AE: | ||
3299 | cam->cam_mode = ovfx2_ov2610_mode; | 3325 | cam->cam_mode = ovfx2_ov2610_mode; |
3300 | cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); | 3326 | cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); |
3301 | } else if (sd->sensor == SEN_OV3610) { | 3327 | break; |
3328 | case SEN_OV3610: | ||
3302 | cam->cam_mode = ovfx2_ov3610_mode; | 3329 | cam->cam_mode = ovfx2_ov3610_mode; |
3303 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); | 3330 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); |
3304 | } else if (sd->sif) { | 3331 | break; |
3305 | cam->cam_mode = ov519_sif_mode; | 3332 | default: |
3306 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3333 | if (sd->sif) { |
3334 | cam->cam_mode = ov519_sif_mode; | ||
3335 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | ||
3336 | } | ||
3337 | break; | ||
3307 | } | 3338 | } |
3308 | break; | 3339 | break; |
3309 | case BRIDGE_W9968CF: | 3340 | case BRIDGE_W9968CF: |
@@ -3325,6 +3356,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3325 | /* Enable autogain, autoexpo, awb, bandfilter */ | 3356 | /* Enable autogain, autoexpo, awb, bandfilter */ |
3326 | i2c_w_mask(sd, 0x13, 0x27, 0x27); | 3357 | i2c_w_mask(sd, 0x13, 0x27, 0x27); |
3327 | break; | 3358 | break; |
3359 | case SEN_OV2610AE: | ||
3360 | write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae)); | ||
3361 | |||
3362 | /* enable autoexpo */ | ||
3363 | i2c_w_mask(sd, 0x13, 0x05, 0x05); | ||
3364 | break; | ||
3328 | case SEN_OV3610: | 3365 | case SEN_OV3610: |
3329 | write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); | 3366 | write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); |
3330 | 3367 | ||
@@ -3827,6 +3864,25 @@ static void mode_init_ov_sensor_regs(struct sd *sd) | |||
3827 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | 3864 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); |
3828 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | 3865 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); |
3829 | return; | 3866 | return; |
3867 | case SEN_OV2610AE: { | ||
3868 | u8 v; | ||
3869 | |||
3870 | /* frame rates: | ||
3871 | * 10fps / 5 fps for 1600x1200 | ||
3872 | * 40fps / 20fps for 800x600 | ||
3873 | */ | ||
3874 | v = 80; | ||
3875 | if (qvga) { | ||
3876 | if (sd->frame_rate < 25) | ||
3877 | v = 0x81; | ||
3878 | } else { | ||
3879 | if (sd->frame_rate < 10) | ||
3880 | v = 0x81; | ||
3881 | } | ||
3882 | i2c_w(sd, 0x11, v); | ||
3883 | i2c_w(sd, 0x12, qvga ? 0x60 : 0x20); | ||
3884 | return; | ||
3885 | } | ||
3830 | case SEN_OV3610: | 3886 | case SEN_OV3610: |
3831 | if (qvga) { | 3887 | if (qvga) { |
3832 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); | 3888 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); |
@@ -3975,6 +4031,7 @@ static void set_ov_sensor_window(struct sd *sd) | |||
3975 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ | 4031 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ |
3976 | switch (sd->sensor) { | 4032 | switch (sd->sensor) { |
3977 | case SEN_OV2610: | 4033 | case SEN_OV2610: |
4034 | case SEN_OV2610AE: | ||
3978 | case SEN_OV3610: | 4035 | case SEN_OV3610: |
3979 | case SEN_OV7670: | 4036 | case SEN_OV7670: |
3980 | mode_init_ov_sensor_regs(sd); | 4037 | mode_init_ov_sensor_regs(sd); |