diff options
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 151 |
1 files changed, 130 insertions, 21 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index b4f965731244..bc4ced6c013b 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -38,6 +38,7 @@ | |||
38 | */ | 38 | */ |
39 | #define MODULE_NAME "ov519" | 39 | #define MODULE_NAME "ov519" |
40 | 40 | ||
41 | #include <linux/input.h> | ||
41 | #include "gspca.h" | 42 | #include "gspca.h" |
42 | 43 | ||
43 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | 44 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); |
@@ -70,6 +71,9 @@ struct sd { | |||
70 | char invert_led; | 71 | char invert_led; |
71 | #define BRIDGE_INVERT_LED 8 | 72 | #define BRIDGE_INVERT_LED 8 |
72 | 73 | ||
74 | char snapshot_pressed; | ||
75 | char snapshot_needs_reset; | ||
76 | |||
73 | /* Determined by sensor type */ | 77 | /* Determined by sensor type */ |
74 | __u8 sif; | 78 | __u8 sif; |
75 | 79 | ||
@@ -99,10 +103,12 @@ struct sd { | |||
99 | #define SEN_OV66308AF 5 | 103 | #define SEN_OV66308AF 5 |
100 | #define SEN_OV7610 6 | 104 | #define SEN_OV7610 6 |
101 | #define SEN_OV7620 7 | 105 | #define SEN_OV7620 7 |
102 | #define SEN_OV7640 8 | 106 | #define SEN_OV7620AE 8 |
103 | #define SEN_OV7670 9 | 107 | #define SEN_OV7640 9 |
104 | #define SEN_OV76BE 10 | 108 | #define SEN_OV7648 10 |
105 | #define SEN_OV8610 11 | 109 | #define SEN_OV7670 11 |
110 | #define SEN_OV76BE 12 | ||
111 | #define SEN_OV8610 13 | ||
106 | 112 | ||
107 | u8 sensor_addr; | 113 | u8 sensor_addr; |
108 | int sensor_width; | 114 | int sensor_width; |
@@ -139,6 +145,7 @@ static void setautobrightness(struct sd *sd); | |||
139 | static void setfreq(struct sd *sd); | 145 | static void setfreq(struct sd *sd); |
140 | 146 | ||
141 | static const struct ctrl sd_ctrls[] = { | 147 | static const struct ctrl sd_ctrls[] = { |
148 | #define BRIGHTNESS_IDX 0 | ||
142 | { | 149 | { |
143 | { | 150 | { |
144 | .id = V4L2_CID_BRIGHTNESS, | 151 | .id = V4L2_CID_BRIGHTNESS, |
@@ -153,6 +160,7 @@ static const struct ctrl sd_ctrls[] = { | |||
153 | .set = sd_setbrightness, | 160 | .set = sd_setbrightness, |
154 | .get = sd_getbrightness, | 161 | .get = sd_getbrightness, |
155 | }, | 162 | }, |
163 | #define CONTRAST_IDX 1 | ||
156 | { | 164 | { |
157 | { | 165 | { |
158 | .id = V4L2_CID_CONTRAST, | 166 | .id = V4L2_CID_CONTRAST, |
@@ -167,6 +175,7 @@ static const struct ctrl sd_ctrls[] = { | |||
167 | .set = sd_setcontrast, | 175 | .set = sd_setcontrast, |
168 | .get = sd_getcontrast, | 176 | .get = sd_getcontrast, |
169 | }, | 177 | }, |
178 | #define COLOR_IDX 2 | ||
170 | { | 179 | { |
171 | { | 180 | { |
172 | .id = V4L2_CID_SATURATION, | 181 | .id = V4L2_CID_SATURATION, |
@@ -2554,7 +2563,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
2554 | /* I don't know what's different about the 76BE yet. */ | 2563 | /* I don't know what's different about the 76BE yet. */ |
2555 | if (i2c_r(sd, 0x15) & 1) { | 2564 | if (i2c_r(sd, 0x15) & 1) { |
2556 | PDEBUG(D_PROBE, "Sensor is an OV7620AE"); | 2565 | PDEBUG(D_PROBE, "Sensor is an OV7620AE"); |
2557 | sd->sensor = SEN_OV7620; | 2566 | sd->sensor = SEN_OV7620AE; |
2558 | } else { | 2567 | } else { |
2559 | PDEBUG(D_PROBE, "Sensor is an OV76BE"); | 2568 | PDEBUG(D_PROBE, "Sensor is an OV76BE"); |
2560 | sd->sensor = SEN_OV76BE; | 2569 | sd->sensor = SEN_OV76BE; |
@@ -2588,7 +2597,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
2588 | break; | 2597 | break; |
2589 | case 0x48: | 2598 | case 0x48: |
2590 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 2599 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
2591 | sd->sensor = SEN_OV7640; /* FIXME */ | 2600 | sd->sensor = SEN_OV7648; |
2592 | break; | 2601 | break; |
2593 | default: | 2602 | default: |
2594 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | 2603 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); |
@@ -2680,6 +2689,36 @@ static void ov51x_led_control(struct sd *sd, int on) | |||
2680 | } | 2689 | } |
2681 | } | 2690 | } |
2682 | 2691 | ||
2692 | static void sd_reset_snapshot(struct gspca_dev *gspca_dev) | ||
2693 | { | ||
2694 | struct sd *sd = (struct sd *) gspca_dev; | ||
2695 | |||
2696 | if (!sd->snapshot_needs_reset) | ||
2697 | return; | ||
2698 | |||
2699 | /* Note it is important that we clear sd->snapshot_needs_reset, | ||
2700 | before actually clearing the snapshot state in the bridge | ||
2701 | otherwise we might race with the pkt_scan interrupt handler */ | ||
2702 | sd->snapshot_needs_reset = 0; | ||
2703 | |||
2704 | switch (sd->bridge) { | ||
2705 | case BRIDGE_OV511: | ||
2706 | case BRIDGE_OV511PLUS: | ||
2707 | reg_w(sd, R51x_SYS_SNAP, 0x02); | ||
2708 | reg_w(sd, R51x_SYS_SNAP, 0x00); | ||
2709 | break; | ||
2710 | case BRIDGE_OV518: | ||
2711 | case BRIDGE_OV518PLUS: | ||
2712 | reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */ | ||
2713 | reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */ | ||
2714 | break; | ||
2715 | case BRIDGE_OV519: | ||
2716 | reg_w(sd, R51x_SYS_RESET, 0x40); | ||
2717 | reg_w(sd, R51x_SYS_RESET, 0x00); | ||
2718 | break; | ||
2719 | } | ||
2720 | } | ||
2721 | |||
2683 | static int ov51x_upload_quan_tables(struct sd *sd) | 2722 | static int ov51x_upload_quan_tables(struct sd *sd) |
2684 | { | 2723 | { |
2685 | const unsigned char yQuanTable511[] = { | 2724 | const unsigned char yQuanTable511[] = { |
@@ -3115,7 +3154,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3115 | (1 << OV7670_FREQ_IDX); | 3154 | (1 << OV7670_FREQ_IDX); |
3116 | } | 3155 | } |
3117 | sd->quality = QUALITY_DEF; | 3156 | sd->quality = QUALITY_DEF; |
3118 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) | 3157 | if (sd->sensor == SEN_OV7640 || |
3158 | sd->sensor == SEN_OV7648) | ||
3159 | gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) | | ||
3160 | (1 << CONTRAST_IDX); | ||
3161 | if (sd->sensor == SEN_OV7670) | ||
3119 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; | 3162 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; |
3120 | /* OV8610 Frequency filter control should work but needs testing */ | 3163 | /* OV8610 Frequency filter control should work but needs testing */ |
3121 | if (sd->sensor == SEN_OV8610) | 3164 | if (sd->sensor == SEN_OV8610) |
@@ -3169,10 +3212,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3169 | return -EIO; | 3212 | return -EIO; |
3170 | break; | 3213 | break; |
3171 | case SEN_OV7620: | 3214 | case SEN_OV7620: |
3215 | case SEN_OV7620AE: | ||
3172 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) | 3216 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) |
3173 | return -EIO; | 3217 | return -EIO; |
3174 | break; | 3218 | break; |
3175 | case SEN_OV7640: | 3219 | case SEN_OV7640: |
3220 | case SEN_OV7648: | ||
3176 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) | 3221 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) |
3177 | return -EIO; | 3222 | return -EIO; |
3178 | break; | 3223 | break; |
@@ -3246,7 +3291,9 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3246 | /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed | 3291 | /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed |
3247 | for more sensors we need to do this for them too */ | 3292 | for more sensors we need to do this for them too */ |
3248 | case SEN_OV7620: | 3293 | case SEN_OV7620: |
3294 | case SEN_OV7620AE: | ||
3249 | case SEN_OV7640: | 3295 | case SEN_OV7640: |
3296 | case SEN_OV7648: | ||
3250 | case SEN_OV76BE: | 3297 | case SEN_OV76BE: |
3251 | if (sd->gspca_dev.width == 320) | 3298 | if (sd->gspca_dev.width == 320) |
3252 | interlaced = 1; | 3299 | interlaced = 1; |
@@ -3377,7 +3424,7 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3377 | 3424 | ||
3378 | if (sd->bridge == BRIDGE_OV518PLUS) { | 3425 | if (sd->bridge == BRIDGE_OV518PLUS) { |
3379 | switch (sd->sensor) { | 3426 | switch (sd->sensor) { |
3380 | case SEN_OV7620: | 3427 | case SEN_OV7620AE: |
3381 | if (sd->gspca_dev.width == 320) { | 3428 | if (sd->gspca_dev.width == 320) { |
3382 | reg_w(sd, 0x20, 0x00); | 3429 | reg_w(sd, 0x20, 0x00); |
3383 | reg_w(sd, 0x21, 0x19); | 3430 | reg_w(sd, 0x21, 0x19); |
@@ -3386,6 +3433,10 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3386 | reg_w(sd, 0x21, 0x1f); | 3433 | reg_w(sd, 0x21, 0x1f); |
3387 | } | 3434 | } |
3388 | break; | 3435 | break; |
3436 | case SEN_OV7620: | ||
3437 | reg_w(sd, 0x20, 0x00); | ||
3438 | reg_w(sd, 0x21, 0x19); | ||
3439 | break; | ||
3389 | default: | 3440 | default: |
3390 | reg_w(sd, 0x21, 0x19); | 3441 | reg_w(sd, 0x21, 0x19); |
3391 | } | 3442 | } |
@@ -3488,7 +3539,8 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3488 | if (write_regvals(sd, mode_init_519, | 3539 | if (write_regvals(sd, mode_init_519, |
3489 | ARRAY_SIZE(mode_init_519))) | 3540 | ARRAY_SIZE(mode_init_519))) |
3490 | return -EIO; | 3541 | return -EIO; |
3491 | if (sd->sensor == SEN_OV7640) { | 3542 | if (sd->sensor == SEN_OV7640 || |
3543 | sd->sensor == SEN_OV7648) { | ||
3492 | /* Select 8-bit input mode */ | 3544 | /* Select 8-bit input mode */ |
3493 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); | 3545 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); |
3494 | } | 3546 | } |
@@ -3503,6 +3555,9 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3503 | if (sd->sensor == SEN_OV7670 && | 3555 | if (sd->sensor == SEN_OV7670 && |
3504 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) | 3556 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) |
3505 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); | 3557 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); |
3558 | else if (sd->sensor == SEN_OV7648 && | ||
3559 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) | ||
3560 | reg_w(sd, OV519_R12_X_OFFSETL, 0x01); | ||
3506 | else | 3561 | else |
3507 | reg_w(sd, OV519_R12_X_OFFSETL, 0x00); | 3562 | reg_w(sd, OV519_R12_X_OFFSETL, 0x00); |
3508 | reg_w(sd, OV519_R13_X_OFFSETH, 0x00); | 3563 | reg_w(sd, OV519_R13_X_OFFSETH, 0x00); |
@@ -3520,6 +3575,7 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3520 | sd->clockdiv = 0; | 3575 | sd->clockdiv = 0; |
3521 | switch (sd->sensor) { | 3576 | switch (sd->sensor) { |
3522 | case SEN_OV7640: | 3577 | case SEN_OV7640: |
3578 | case SEN_OV7648: | ||
3523 | switch (sd->frame_rate) { | 3579 | switch (sd->frame_rate) { |
3524 | default: | 3580 | default: |
3525 | /* case 30: */ | 3581 | /* case 30: */ |
@@ -3649,6 +3705,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3649 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | 3705 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ |
3650 | break; | 3706 | break; |
3651 | case SEN_OV7620: | 3707 | case SEN_OV7620: |
3708 | case SEN_OV7620AE: | ||
3652 | case SEN_OV76BE: | 3709 | case SEN_OV76BE: |
3653 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3710 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3654 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | 3711 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); |
@@ -3663,13 +3720,16 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3663 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); | 3720 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); |
3664 | break; | 3721 | break; |
3665 | case SEN_OV7640: | 3722 | case SEN_OV7640: |
3723 | case SEN_OV7648: | ||
3666 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3724 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3667 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | 3725 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); |
3668 | /* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ | 3726 | /* Setting this undocumented bit in qvga mode removes a very |
3669 | /* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ | 3727 | annoying vertical shaking of the image */ |
3670 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ | 3728 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); |
3671 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ | 3729 | /* Unknown */ |
3672 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ | 3730 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); |
3731 | /* Allow higher automatic gain (to allow higher framerates) */ | ||
3732 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | ||
3673 | i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ | 3733 | i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ |
3674 | break; | 3734 | break; |
3675 | case SEN_OV7670: | 3735 | case SEN_OV7670: |
@@ -3795,11 +3855,13 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3795 | } | 3855 | } |
3796 | break; | 3856 | break; |
3797 | case SEN_OV7620: | 3857 | case SEN_OV7620: |
3858 | case SEN_OV7620AE: | ||
3798 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | 3859 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ |
3799 | hwebase = 0x2f; | 3860 | hwebase = 0x2f; |
3800 | vwsbase = vwebase = 0x05; | 3861 | vwsbase = vwebase = 0x05; |
3801 | break; | 3862 | break; |
3802 | case SEN_OV7640: | 3863 | case SEN_OV7640: |
3864 | case SEN_OV7648: | ||
3803 | hwsbase = 0x1a; | 3865 | hwsbase = 0x1a; |
3804 | hwebase = 0x1a; | 3866 | hwebase = 0x1a; |
3805 | vwsbase = vwebase = 0x03; | 3867 | vwsbase = vwebase = 0x03; |
@@ -3893,6 +3955,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3893 | setautobrightness(sd); | 3955 | setautobrightness(sd); |
3894 | setfreq(sd); | 3956 | setfreq(sd); |
3895 | 3957 | ||
3958 | /* Force clear snapshot state in case the snapshot button was | ||
3959 | pressed while we weren't streaming */ | ||
3960 | sd->snapshot_needs_reset = 1; | ||
3961 | sd_reset_snapshot(gspca_dev); | ||
3962 | sd->snapshot_pressed = 0; | ||
3963 | |||
3896 | ret = ov51x_restart(sd); | 3964 | ret = ov51x_restart(sd); |
3897 | if (ret < 0) | 3965 | if (ret < 0) |
3898 | goto out; | 3966 | goto out; |
@@ -3919,6 +3987,34 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
3919 | w9968cf_stop0(sd); | 3987 | w9968cf_stop0(sd); |
3920 | } | 3988 | } |
3921 | 3989 | ||
3990 | static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) | ||
3991 | { | ||
3992 | struct sd *sd = (struct sd *) gspca_dev; | ||
3993 | |||
3994 | if (sd->snapshot_pressed != state) { | ||
3995 | #ifdef CONFIG_INPUT | ||
3996 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, state); | ||
3997 | input_sync(gspca_dev->input_dev); | ||
3998 | #endif | ||
3999 | if (state) | ||
4000 | sd->snapshot_needs_reset = 1; | ||
4001 | |||
4002 | sd->snapshot_pressed = state; | ||
4003 | } else { | ||
4004 | /* On the ov511 / ov519 we need to reset the button state | ||
4005 | multiple times, as resetting does not work as long as the | ||
4006 | button stays pressed */ | ||
4007 | switch (sd->bridge) { | ||
4008 | case BRIDGE_OV511: | ||
4009 | case BRIDGE_OV511PLUS: | ||
4010 | case BRIDGE_OV519: | ||
4011 | if (state) | ||
4012 | sd->snapshot_needs_reset = 1; | ||
4013 | break; | ||
4014 | } | ||
4015 | } | ||
4016 | } | ||
4017 | |||
3922 | static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | 4018 | static void ov511_pkt_scan(struct gspca_dev *gspca_dev, |
3923 | u8 *in, /* isoc packet */ | 4019 | u8 *in, /* isoc packet */ |
3924 | int len) /* iso packet length */ | 4020 | int len) /* iso packet length */ |
@@ -3940,6 +4036,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | |||
3940 | */ | 4036 | */ |
3941 | if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && | 4037 | if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && |
3942 | (in[8] & 0x08)) { | 4038 | (in[8] & 0x08)) { |
4039 | ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1); | ||
3943 | if (in[8] & 0x80) { | 4040 | if (in[8] & 0x80) { |
3944 | /* Frame end */ | 4041 | /* Frame end */ |
3945 | if ((in[9] + 1) * 8 != gspca_dev->width || | 4042 | if ((in[9] + 1) * 8 != gspca_dev->width || |
@@ -3977,6 +4074,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, | |||
3977 | /* A false positive here is likely, until OVT gives me | 4074 | /* A false positive here is likely, until OVT gives me |
3978 | * the definitive SOF/EOF format */ | 4075 | * the definitive SOF/EOF format */ |
3979 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { | 4076 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { |
4077 | ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1); | ||
3980 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | 4078 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
3981 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); | 4079 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); |
3982 | sd->packet_nr = 0; | 4080 | sd->packet_nr = 0; |
@@ -4024,6 +4122,9 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | |||
4024 | if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { | 4122 | if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { |
4025 | switch (data[3]) { | 4123 | switch (data[3]) { |
4026 | case 0x50: /* start of frame */ | 4124 | case 0x50: /* start of frame */ |
4125 | /* Don't check the button state here, as the state | ||
4126 | usually (always ?) changes at EOF and checking it | ||
4127 | here leads to unnecessary snapshot state resets. */ | ||
4027 | #define HDRSZ 16 | 4128 | #define HDRSZ 16 |
4028 | data += HDRSZ; | 4129 | data += HDRSZ; |
4029 | len -= HDRSZ; | 4130 | len -= HDRSZ; |
@@ -4035,6 +4136,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | |||
4035 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4136 | gspca_dev->last_packet_type = DISCARD_PACKET; |
4036 | return; | 4137 | return; |
4037 | case 0x51: /* end of frame */ | 4138 | case 0x51: /* end of frame */ |
4139 | ov51x_handle_button(gspca_dev, data[11] & 1); | ||
4038 | if (data[9] != 0) | 4140 | if (data[9] != 0) |
4039 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4141 | gspca_dev->last_packet_type = DISCARD_PACKET; |
4040 | gspca_frame_add(gspca_dev, LAST_PACKET, | 4142 | gspca_frame_add(gspca_dev, LAST_PACKET, |
@@ -4103,9 +4205,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4103 | case SEN_OV6630: | 4205 | case SEN_OV6630: |
4104 | case SEN_OV66308AF: | 4206 | case SEN_OV66308AF: |
4105 | case SEN_OV7640: | 4207 | case SEN_OV7640: |
4208 | case SEN_OV7648: | ||
4106 | i2c_w(sd, OV7610_REG_BRT, val); | 4209 | i2c_w(sd, OV7610_REG_BRT, val); |
4107 | break; | 4210 | break; |
4108 | case SEN_OV7620: | 4211 | case SEN_OV7620: |
4212 | case SEN_OV7620AE: | ||
4109 | /* 7620 doesn't like manual changes when in auto mode */ | 4213 | /* 7620 doesn't like manual changes when in auto mode */ |
4110 | if (!sd->autobrightness) | 4214 | if (!sd->autobrightness) |
4111 | i2c_w(sd, OV7610_REG_BRT, val); | 4215 | i2c_w(sd, OV7610_REG_BRT, val); |
@@ -4142,7 +4246,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4142 | i2c_w(sd, 0x64, ctab[val >> 5]); | 4246 | i2c_w(sd, 0x64, ctab[val >> 5]); |
4143 | break; | 4247 | break; |
4144 | } | 4248 | } |
4145 | case SEN_OV7620: { | 4249 | case SEN_OV7620: |
4250 | case SEN_OV7620AE: { | ||
4146 | static const __u8 ctab[] = { | 4251 | static const __u8 ctab[] = { |
4147 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, | 4252 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, |
4148 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff | 4253 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff |
@@ -4152,10 +4257,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4152 | i2c_w(sd, 0x64, ctab[val >> 4]); | 4257 | i2c_w(sd, 0x64, ctab[val >> 4]); |
4153 | break; | 4258 | break; |
4154 | } | 4259 | } |
4155 | case SEN_OV7640: | ||
4156 | /* Use gain control instead. */ | ||
4157 | i2c_w(sd, OV7610_REG_GAIN, val >> 2); | ||
4158 | break; | ||
4159 | case SEN_OV7670: | 4260 | case SEN_OV7670: |
4160 | /* check that this isn't just the same as ov7610 */ | 4261 | /* check that this isn't just the same as ov7610 */ |
4161 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 4262 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); |
@@ -4179,6 +4280,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4179 | i2c_w(sd, OV7610_REG_SAT, val); | 4280 | i2c_w(sd, OV7610_REG_SAT, val); |
4180 | break; | 4281 | break; |
4181 | case SEN_OV7620: | 4282 | case SEN_OV7620: |
4283 | case SEN_OV7620AE: | ||
4182 | /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ | 4284 | /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ |
4183 | /* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); | 4285 | /* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); |
4184 | if (rc < 0) | 4286 | if (rc < 0) |
@@ -4186,6 +4288,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4186 | i2c_w(sd, OV7610_REG_SAT, val); | 4288 | i2c_w(sd, OV7610_REG_SAT, val); |
4187 | break; | 4289 | break; |
4188 | case SEN_OV7640: | 4290 | case SEN_OV7640: |
4291 | case SEN_OV7648: | ||
4189 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | 4292 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); |
4190 | break; | 4293 | break; |
4191 | case SEN_OV7670: | 4294 | case SEN_OV7670: |
@@ -4198,7 +4301,8 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4198 | 4301 | ||
4199 | static void setautobrightness(struct sd *sd) | 4302 | static void setautobrightness(struct sd *sd) |
4200 | { | 4303 | { |
4201 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || | 4304 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || |
4305 | sd->sensor == SEN_OV7670 || | ||
4202 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4306 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) |
4203 | return; | 4307 | return; |
4204 | 4308 | ||
@@ -4475,9 +4579,13 @@ static const struct sd_desc sd_desc = { | |||
4475 | .stopN = sd_stopN, | 4579 | .stopN = sd_stopN, |
4476 | .stop0 = sd_stop0, | 4580 | .stop0 = sd_stop0, |
4477 | .pkt_scan = sd_pkt_scan, | 4581 | .pkt_scan = sd_pkt_scan, |
4582 | .dq_callback = sd_reset_snapshot, | ||
4478 | .querymenu = sd_querymenu, | 4583 | .querymenu = sd_querymenu, |
4479 | .get_jcomp = sd_get_jcomp, | 4584 | .get_jcomp = sd_get_jcomp, |
4480 | .set_jcomp = sd_set_jcomp, | 4585 | .set_jcomp = sd_set_jcomp, |
4586 | #ifdef CONFIG_INPUT | ||
4587 | .other_input = 1, | ||
4588 | #endif | ||
4481 | }; | 4589 | }; |
4482 | 4590 | ||
4483 | /* -- module initialisation -- */ | 4591 | /* -- module initialisation -- */ |
@@ -4494,7 +4602,8 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
4494 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4602 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4495 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, | 4603 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
4496 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, | 4604 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
4497 | {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, | 4605 | {USB_DEVICE(0x054c, 0x0155), |
4606 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | ||
4498 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, | 4607 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, |
4499 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, | 4608 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
4500 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, | 4609 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |