diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-01-09 06:14:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:10:40 -0500 |
commit | 035d3a3d3fb0104bb94dfb78ef70c7ec6f3f4ae4 (patch) | |
tree | 52acf4710af946b6aba177bfbededd3dc7a6611e /drivers/media/video/gspca/ov519.c | |
parent | 859cc4700eebebe346572eb30898dd786a54e7a9 (diff) |
V4L/DVB (13998): gscpa_ov519: Fix 320x240 on ov519 + ov7648
Differentiate between ov7640 and ov7648 and handle the ov7648 320x240
on the ov519 bridge specially to fix r and b being swapped.
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.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index a607622b7348..abd200a947db 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -101,9 +101,10 @@ struct sd { | |||
101 | #define SEN_OV7620 7 | 101 | #define SEN_OV7620 7 |
102 | #define SEN_OV7620AE 8 | 102 | #define SEN_OV7620AE 8 |
103 | #define SEN_OV7640 9 | 103 | #define SEN_OV7640 9 |
104 | #define SEN_OV7670 10 | 104 | #define SEN_OV7648 10 |
105 | #define SEN_OV76BE 11 | 105 | #define SEN_OV7670 11 |
106 | #define SEN_OV8610 12 | 106 | #define SEN_OV76BE 12 |
107 | #define SEN_OV8610 13 | ||
107 | 108 | ||
108 | u8 sensor_addr; | 109 | u8 sensor_addr; |
109 | int sensor_width; | 110 | int sensor_width; |
@@ -2589,7 +2590,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
2589 | break; | 2590 | break; |
2590 | case 0x48: | 2591 | case 0x48: |
2591 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 2592 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
2592 | sd->sensor = SEN_OV7640; /* FIXME */ | 2593 | sd->sensor = SEN_OV7648; |
2593 | break; | 2594 | break; |
2594 | default: | 2595 | default: |
2595 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | 2596 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); |
@@ -3116,7 +3117,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3116 | (1 << OV7670_FREQ_IDX); | 3117 | (1 << OV7670_FREQ_IDX); |
3117 | } | 3118 | } |
3118 | sd->quality = QUALITY_DEF; | 3119 | sd->quality = QUALITY_DEF; |
3119 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) | 3120 | if (sd->sensor == SEN_OV7640 || |
3121 | sd->sensor == SEN_OV7648 || | ||
3122 | sd->sensor == SEN_OV7670) | ||
3120 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; | 3123 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; |
3121 | /* OV8610 Frequency filter control should work but needs testing */ | 3124 | /* OV8610 Frequency filter control should work but needs testing */ |
3122 | if (sd->sensor == SEN_OV8610) | 3125 | if (sd->sensor == SEN_OV8610) |
@@ -3175,6 +3178,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3175 | return -EIO; | 3178 | return -EIO; |
3176 | break; | 3179 | break; |
3177 | case SEN_OV7640: | 3180 | case SEN_OV7640: |
3181 | case SEN_OV7648: | ||
3178 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) | 3182 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) |
3179 | return -EIO; | 3183 | return -EIO; |
3180 | break; | 3184 | break; |
@@ -3250,6 +3254,7 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3250 | case SEN_OV7620: | 3254 | case SEN_OV7620: |
3251 | case SEN_OV7620AE: | 3255 | case SEN_OV7620AE: |
3252 | case SEN_OV7640: | 3256 | case SEN_OV7640: |
3257 | case SEN_OV7648: | ||
3253 | case SEN_OV76BE: | 3258 | case SEN_OV76BE: |
3254 | if (sd->gspca_dev.width == 320) | 3259 | if (sd->gspca_dev.width == 320) |
3255 | interlaced = 1; | 3260 | interlaced = 1; |
@@ -3495,7 +3500,8 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3495 | if (write_regvals(sd, mode_init_519, | 3500 | if (write_regvals(sd, mode_init_519, |
3496 | ARRAY_SIZE(mode_init_519))) | 3501 | ARRAY_SIZE(mode_init_519))) |
3497 | return -EIO; | 3502 | return -EIO; |
3498 | if (sd->sensor == SEN_OV7640) { | 3503 | if (sd->sensor == SEN_OV7640 || |
3504 | sd->sensor == SEN_OV7648) { | ||
3499 | /* Select 8-bit input mode */ | 3505 | /* Select 8-bit input mode */ |
3500 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); | 3506 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); |
3501 | } | 3507 | } |
@@ -3510,6 +3516,9 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3510 | if (sd->sensor == SEN_OV7670 && | 3516 | if (sd->sensor == SEN_OV7670 && |
3511 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) | 3517 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) |
3512 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); | 3518 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); |
3519 | else if (sd->sensor == SEN_OV7648 && | ||
3520 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) | ||
3521 | reg_w(sd, OV519_R12_X_OFFSETL, 0x01); | ||
3513 | else | 3522 | else |
3514 | reg_w(sd, OV519_R12_X_OFFSETL, 0x00); | 3523 | reg_w(sd, OV519_R12_X_OFFSETL, 0x00); |
3515 | reg_w(sd, OV519_R13_X_OFFSETH, 0x00); | 3524 | reg_w(sd, OV519_R13_X_OFFSETH, 0x00); |
@@ -3527,6 +3536,7 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3527 | sd->clockdiv = 0; | 3536 | sd->clockdiv = 0; |
3528 | switch (sd->sensor) { | 3537 | switch (sd->sensor) { |
3529 | case SEN_OV7640: | 3538 | case SEN_OV7640: |
3539 | case SEN_OV7648: | ||
3530 | switch (sd->frame_rate) { | 3540 | switch (sd->frame_rate) { |
3531 | default: | 3541 | default: |
3532 | /* case 30: */ | 3542 | /* case 30: */ |
@@ -3671,13 +3681,18 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3671 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); | 3681 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); |
3672 | break; | 3682 | break; |
3673 | case SEN_OV7640: | 3683 | case SEN_OV7640: |
3684 | case SEN_OV7648: | ||
3674 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3685 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3675 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | 3686 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); |
3676 | /* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ | 3687 | /* The following 5 lines where commented out before with a |
3677 | /* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ | 3688 | comment wondering if they did anything. This was because |
3678 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ | 3689 | the old driver did only 640x480, at 320x240 these 5 writes |
3679 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ | 3690 | *significantly* improve the image quality. */ |
3680 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ | 3691 | i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); |
3692 | i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); | ||
3693 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | ||
3694 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | ||
3695 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | ||
3681 | i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ | 3696 | i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ |
3682 | break; | 3697 | break; |
3683 | case SEN_OV7670: | 3698 | case SEN_OV7670: |
@@ -3809,6 +3824,7 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3809 | vwsbase = vwebase = 0x05; | 3824 | vwsbase = vwebase = 0x05; |
3810 | break; | 3825 | break; |
3811 | case SEN_OV7640: | 3826 | case SEN_OV7640: |
3827 | case SEN_OV7648: | ||
3812 | hwsbase = 0x1a; | 3828 | hwsbase = 0x1a; |
3813 | hwebase = 0x1a; | 3829 | hwebase = 0x1a; |
3814 | vwsbase = vwebase = 0x03; | 3830 | vwsbase = vwebase = 0x03; |
@@ -4112,6 +4128,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4112 | case SEN_OV6630: | 4128 | case SEN_OV6630: |
4113 | case SEN_OV66308AF: | 4129 | case SEN_OV66308AF: |
4114 | case SEN_OV7640: | 4130 | case SEN_OV7640: |
4131 | case SEN_OV7648: | ||
4115 | i2c_w(sd, OV7610_REG_BRT, val); | 4132 | i2c_w(sd, OV7610_REG_BRT, val); |
4116 | break; | 4133 | break; |
4117 | case SEN_OV7620: | 4134 | case SEN_OV7620: |
@@ -4164,6 +4181,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4164 | break; | 4181 | break; |
4165 | } | 4182 | } |
4166 | case SEN_OV7640: | 4183 | case SEN_OV7640: |
4184 | case SEN_OV7648: | ||
4167 | /* Use gain control instead. */ | 4185 | /* Use gain control instead. */ |
4168 | i2c_w(sd, OV7610_REG_GAIN, val >> 2); | 4186 | i2c_w(sd, OV7610_REG_GAIN, val >> 2); |
4169 | break; | 4187 | break; |
@@ -4198,6 +4216,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4198 | i2c_w(sd, OV7610_REG_SAT, val); | 4216 | i2c_w(sd, OV7610_REG_SAT, val); |
4199 | break; | 4217 | break; |
4200 | case SEN_OV7640: | 4218 | case SEN_OV7640: |
4219 | case SEN_OV7648: | ||
4201 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | 4220 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); |
4202 | break; | 4221 | break; |
4203 | case SEN_OV7670: | 4222 | case SEN_OV7670: |
@@ -4210,7 +4229,8 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4210 | 4229 | ||
4211 | static void setautobrightness(struct sd *sd) | 4230 | static void setautobrightness(struct sd *sd) |
4212 | { | 4231 | { |
4213 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || | 4232 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || |
4233 | sd->sensor == SEN_OV7670 || | ||
4214 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4234 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) |
4215 | return; | 4235 | return; |
4216 | 4236 | ||